1 //
2 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // Context.cpp: Implements the gl::Context class, managing all GL state and performing
8 // rendering operations. It is the GLES2 specific implementation of EGLContext.
9
10 #include "libANGLE/Context.h"
11 #include "libANGLE/Context.inl.h"
12
13 #include <string.h>
14 #include <iterator>
15 #include <sstream>
16 #include <vector>
17
18 #include "common/PackedEnums.h"
19 #include "common/matrix_utils.h"
20 #include "common/platform.h"
21 #include "common/utilities.h"
22 #include "common/version.h"
23 #include "libANGLE/Buffer.h"
24 #include "libANGLE/Compiler.h"
25 #include "libANGLE/Display.h"
26 #include "libANGLE/Fence.h"
27 #include "libANGLE/FrameCapture.h"
28 #include "libANGLE/Framebuffer.h"
29 #include "libANGLE/FramebufferAttachment.h"
30 #include "libANGLE/MemoryObject.h"
31 #include "libANGLE/Program.h"
32 #include "libANGLE/ProgramPipeline.h"
33 #include "libANGLE/Query.h"
34 #include "libANGLE/Renderbuffer.h"
35 #include "libANGLE/ResourceManager.h"
36 #include "libANGLE/Sampler.h"
37 #include "libANGLE/Semaphore.h"
38 #include "libANGLE/Surface.h"
39 #include "libANGLE/Texture.h"
40 #include "libANGLE/TransformFeedback.h"
41 #include "libANGLE/VertexArray.h"
42 #include "libANGLE/formatutils.h"
43 #include "libANGLE/queryconversions.h"
44 #include "libANGLE/queryutils.h"
45 #include "libANGLE/renderer/DisplayImpl.h"
46 #include "libANGLE/renderer/Format.h"
47 #include "libANGLE/validationES.h"
48
49 namespace gl
50 {
51 namespace
52 {
53 template <typename T>
GetQueryObjectParameter(const Context * context,Query * query,GLenum pname,T * params)54 angle::Result GetQueryObjectParameter(const Context *context, Query *query, GLenum pname, T *params)
55 {
56 ASSERT(query != nullptr || pname == GL_QUERY_RESULT_AVAILABLE_EXT);
57
58 switch (pname)
59 {
60 case GL_QUERY_RESULT_EXT:
61 return query->getResult(context, params);
62 case GL_QUERY_RESULT_AVAILABLE_EXT:
63 {
64 bool available = false;
65 if (context->isContextLost())
66 {
67 available = true;
68 }
69 else
70 {
71 ANGLE_TRY(query->isResultAvailable(context, &available));
72 }
73 *params = CastFromStateValue<T>(pname, static_cast<GLuint>(available));
74 return angle::Result::Continue;
75 }
76 default:
77 UNREACHABLE();
78 return angle::Result::Stop;
79 }
80 }
81
82 // Attribute map queries.
GetClientMajorVersion(const egl::AttributeMap & attribs)83 EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
84 {
85 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
86 }
87
GetClientMinorVersion(const egl::AttributeMap & attribs)88 EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
89 {
90 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
91 }
92
GetBackwardCompatibleContext(const egl::AttributeMap & attribs)93 bool GetBackwardCompatibleContext(const egl::AttributeMap &attribs)
94 {
95 return attribs.get(EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE, EGL_TRUE) == EGL_TRUE;
96 }
97
GetClientVersion(egl::Display * display,const egl::AttributeMap & attribs)98 Version GetClientVersion(egl::Display *display, const egl::AttributeMap &attribs)
99 {
100 Version requestedVersion =
101 Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
102 if (GetBackwardCompatibleContext(attribs))
103 {
104 if (requestedVersion.major == 1)
105 {
106 // If the user requests an ES1 context, we cannot return an ES 2+ context.
107 return Version(1, 1);
108 }
109 else
110 {
111 // Always up the version to at least the max conformant version this display supports.
112 // Only return a higher client version if requested.
113 return std::max(display->getImplementation()->getMaxConformantESVersion(),
114 requestedVersion);
115 }
116 }
117 else
118 {
119 return requestedVersion;
120 }
121 }
122
GetResetStrategy(const egl::AttributeMap & attribs)123 GLenum GetResetStrategy(const egl::AttributeMap &attribs)
124 {
125 EGLAttrib attrib =
126 attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_NO_RESET_NOTIFICATION);
127 switch (attrib)
128 {
129 case EGL_NO_RESET_NOTIFICATION:
130 return GL_NO_RESET_NOTIFICATION_EXT;
131 case EGL_LOSE_CONTEXT_ON_RESET:
132 return GL_LOSE_CONTEXT_ON_RESET_EXT;
133 default:
134 UNREACHABLE();
135 return GL_NONE;
136 }
137 }
138
GetRobustAccess(const egl::AttributeMap & attribs)139 bool GetRobustAccess(const egl::AttributeMap &attribs)
140 {
141 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
142 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
143 0);
144 }
145
GetDebug(const egl::AttributeMap & attribs)146 bool GetDebug(const egl::AttributeMap &attribs)
147 {
148 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
149 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
150 }
151
GetNoError(const egl::AttributeMap & attribs)152 bool GetNoError(const egl::AttributeMap &attribs)
153 {
154 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
155 }
156
GetWebGLContext(const egl::AttributeMap & attribs)157 bool GetWebGLContext(const egl::AttributeMap &attribs)
158 {
159 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
160 }
161
GetExtensionsEnabled(const egl::AttributeMap & attribs,bool webGLContext)162 bool GetExtensionsEnabled(const egl::AttributeMap &attribs, bool webGLContext)
163 {
164 // If the context is WebGL, extensions are disabled by default
165 EGLAttrib defaultValue = webGLContext ? EGL_FALSE : EGL_TRUE;
166 return (attribs.get(EGL_EXTENSIONS_ENABLED_ANGLE, defaultValue) == EGL_TRUE);
167 }
168
GetBindGeneratesResource(const egl::AttributeMap & attribs)169 bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
170 {
171 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
172 }
173
GetClientArraysEnabled(const egl::AttributeMap & attribs)174 bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
175 {
176 return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
177 }
178
GetRobustResourceInit(const egl::AttributeMap & attribs)179 bool GetRobustResourceInit(const egl::AttributeMap &attribs)
180 {
181 return (attribs.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
182 }
183
GetContextPriority(const egl::AttributeMap & attribs)184 EGLenum GetContextPriority(const egl::AttributeMap &attribs)
185 {
186 return static_cast<EGLenum>(
187 attribs.getAsInt(EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_MEDIUM_IMG));
188 }
189
GetObjectLabelFromPointer(GLsizei length,const GLchar * label)190 std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
191 {
192 std::string labelName;
193 if (label != nullptr)
194 {
195 size_t labelLength = length < 0 ? strlen(label) : length;
196 labelName = std::string(label, labelLength);
197 }
198 return labelName;
199 }
200
GetObjectLabelBase(const std::string & objectLabel,GLsizei bufSize,GLsizei * length,GLchar * label)201 void GetObjectLabelBase(const std::string &objectLabel,
202 GLsizei bufSize,
203 GLsizei *length,
204 GLchar *label)
205 {
206 size_t writeLength = objectLabel.length();
207 if (label != nullptr && bufSize > 0)
208 {
209 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
210 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
211 label[writeLength] = '\0';
212 }
213
214 if (length != nullptr)
215 {
216 *length = static_cast<GLsizei>(writeLength);
217 }
218 }
219
220 // The rest default to false.
221 constexpr angle::PackedEnumMap<PrimitiveMode, bool, angle::EnumSize<PrimitiveMode>() + 1>
222 kValidBasicDrawModes = {{
223 {PrimitiveMode::Points, true},
224 {PrimitiveMode::Lines, true},
225 {PrimitiveMode::LineLoop, true},
226 {PrimitiveMode::LineStrip, true},
227 {PrimitiveMode::Triangles, true},
228 {PrimitiveMode::TriangleStrip, true},
229 {PrimitiveMode::TriangleFan, true},
230 }};
231
232 enum SubjectIndexes : angle::SubjectIndex
233 {
234 kTexture0SubjectIndex = 0,
235 kTextureMaxSubjectIndex = kTexture0SubjectIndex + IMPLEMENTATION_MAX_ACTIVE_TEXTURES,
236 kImage0SubjectIndex = kTextureMaxSubjectIndex,
237 kImageMaxSubjectIndex = kImage0SubjectIndex + IMPLEMENTATION_MAX_IMAGE_UNITS,
238 kUniformBuffer0SubjectIndex = kImageMaxSubjectIndex,
239 kUniformBufferMaxSubjectIndex =
240 kUniformBuffer0SubjectIndex + IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS,
241 kSampler0SubjectIndex = kUniformBufferMaxSubjectIndex,
242 kSamplerMaxSubjectIndex = kSampler0SubjectIndex + IMPLEMENTATION_MAX_ACTIVE_TEXTURES,
243 kVertexArraySubjectIndex = kSamplerMaxSubjectIndex,
244 kReadFramebufferSubjectIndex,
245 kDrawFramebufferSubjectIndex
246 };
247 } // anonymous namespace
248
Context(egl::Display * display,const egl::Config * config,const Context * shareContext,TextureManager * shareTextures,MemoryProgramCache * memoryProgramCache,const EGLenum clientType,const egl::AttributeMap & attribs,const egl::DisplayExtensions & displayExtensions,const egl::ClientExtensions & clientExtensions)249 Context::Context(egl::Display *display,
250 const egl::Config *config,
251 const Context *shareContext,
252 TextureManager *shareTextures,
253 MemoryProgramCache *memoryProgramCache,
254 const EGLenum clientType,
255 const egl::AttributeMap &attribs,
256 const egl::DisplayExtensions &displayExtensions,
257 const egl::ClientExtensions &clientExtensions)
258 : mState(shareContext ? &shareContext->mState : nullptr,
259 shareTextures,
260 &mOverlay,
261 clientType,
262 GetClientVersion(display, attribs),
263 GetDebug(attribs),
264 GetBindGeneratesResource(attribs),
265 GetClientArraysEnabled(attribs),
266 GetRobustResourceInit(attribs),
267 memoryProgramCache != nullptr,
268 GetContextPriority(attribs)),
269 mShared(shareContext != nullptr),
270 mSkipValidation(GetNoError(attribs)),
271 mDisplayTextureShareGroup(shareTextures != nullptr),
272 mErrors(this),
273 mImplementation(display->getImplementation()
274 ->createContext(mState, &mErrors, config, shareContext, attribs)),
275 mLabel(nullptr),
276 mCompiler(),
277 mConfig(config),
278 mHasBeenCurrent(false),
279 mContextLost(false),
280 mResetStatus(GraphicsResetStatus::NoError),
281 mContextLostForced(false),
282 mResetStrategy(GetResetStrategy(attribs)),
283 mRobustAccess(GetRobustAccess(attribs)),
284 mSurfacelessSupported(displayExtensions.surfacelessContext),
285 mExplicitContextAvailable(clientExtensions.explicitContext),
286 mCurrentDrawSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
287 mCurrentReadSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
288 mDisplay(static_cast<egl::Display *>(EGL_NO_DISPLAY)),
289 mWebGLContext(GetWebGLContext(attribs)),
290 mBufferAccessValidationEnabled(false),
291 mExtensionsEnabled(GetExtensionsEnabled(attribs, mWebGLContext)),
292 mMemoryProgramCache(memoryProgramCache),
293 mVertexArrayObserverBinding(this, kVertexArraySubjectIndex),
294 mDrawFramebufferObserverBinding(this, kDrawFramebufferSubjectIndex),
295 mReadFramebufferObserverBinding(this, kReadFramebufferSubjectIndex),
296 mThreadPool(nullptr),
297 mFrameCapture(new angle::FrameCapture),
298 mOverlay(mImplementation.get())
299 {
300 for (angle::SubjectIndex uboIndex = kUniformBuffer0SubjectIndex;
301 uboIndex < kUniformBufferMaxSubjectIndex; ++uboIndex)
302 {
303 mUniformBufferObserverBindings.emplace_back(this, uboIndex);
304 }
305
306 for (angle::SubjectIndex samplerIndex = kSampler0SubjectIndex;
307 samplerIndex < kSamplerMaxSubjectIndex; ++samplerIndex)
308 {
309 mSamplerObserverBindings.emplace_back(this, samplerIndex);
310 }
311
312 for (angle::SubjectIndex imageIndex = kImage0SubjectIndex; imageIndex < kImageMaxSubjectIndex;
313 ++imageIndex)
314 {
315 mImageObserverBindings.emplace_back(this, imageIndex);
316 }
317 }
318
initialize()319 void Context::initialize()
320 {
321 mImplementation->setMemoryProgramCache(mMemoryProgramCache);
322
323 initCaps();
324
325 if (mDisplay->getFrontendFeatures().syncFramebufferBindingsOnTexImage.enabled)
326 {
327 mTexImageDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
328 mTexImageDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
329 }
330
331 mState.initialize(this);
332
333 mFenceNVHandleAllocator.setBaseHandle(0);
334
335 // [OpenGL ES 2.0.24] section 3.7 page 83:
336 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have two-dimensional
337 // and cube map texture state vectors respectively associated with them.
338 // In order that access to these initial textures not be lost, they are treated as texture
339 // objects all of whose names are 0.
340
341 Texture *zeroTexture2D = new Texture(mImplementation.get(), {0}, TextureType::_2D);
342 mZeroTextures[TextureType::_2D].set(this, zeroTexture2D);
343
344 Texture *zeroTextureCube = new Texture(mImplementation.get(), {0}, TextureType::CubeMap);
345 mZeroTextures[TextureType::CubeMap].set(this, zeroTextureCube);
346
347 if (getClientVersion() >= Version(3, 0) || mSupportedExtensions.texture3DOES)
348 {
349 Texture *zeroTexture3D = new Texture(mImplementation.get(), {0}, TextureType::_3D);
350 mZeroTextures[TextureType::_3D].set(this, zeroTexture3D);
351 }
352 if (getClientVersion() >= Version(3, 0))
353 {
354 Texture *zeroTexture2DArray =
355 new Texture(mImplementation.get(), {0}, TextureType::_2DArray);
356 mZeroTextures[TextureType::_2DArray].set(this, zeroTexture2DArray);
357 }
358 if (getClientVersion() >= Version(3, 1) || mSupportedExtensions.textureMultisample)
359 {
360 Texture *zeroTexture2DMultisample =
361 new Texture(mImplementation.get(), {0}, TextureType::_2DMultisample);
362 mZeroTextures[TextureType::_2DMultisample].set(this, zeroTexture2DMultisample);
363 }
364 if (getClientVersion() >= Version(3, 1))
365 {
366 Texture *zeroTexture2DMultisampleArray =
367 new Texture(mImplementation.get(), {0}, TextureType::_2DMultisampleArray);
368 mZeroTextures[TextureType::_2DMultisampleArray].set(this, zeroTexture2DMultisampleArray);
369
370 for (int i = 0; i < mState.mCaps.maxAtomicCounterBufferBindings; i++)
371 {
372 bindBufferRange(BufferBinding::AtomicCounter, i, {0}, 0, 0);
373 }
374
375 for (int i = 0; i < mState.mCaps.maxShaderStorageBufferBindings; i++)
376 {
377 bindBufferRange(BufferBinding::ShaderStorage, i, {0}, 0, 0);
378 }
379 }
380
381 if (mSupportedExtensions.textureRectangle)
382 {
383 Texture *zeroTextureRectangle =
384 new Texture(mImplementation.get(), {0}, TextureType::Rectangle);
385 mZeroTextures[TextureType::Rectangle].set(this, zeroTextureRectangle);
386 }
387
388 if (mSupportedExtensions.eglImageExternalOES ||
389 mSupportedExtensions.eglStreamConsumerExternalNV)
390 {
391 Texture *zeroTextureExternal =
392 new Texture(mImplementation.get(), {0}, TextureType::External);
393 mZeroTextures[TextureType::External].set(this, zeroTextureExternal);
394 }
395
396 // This may change native TEXTURE_2D, TEXTURE_EXTERNAL_OES and TEXTURE_RECTANGLE,
397 // binding states. Ensure state manager is aware of this when binding
398 // this texture type.
399 if (mSupportedExtensions.webglVideoTexture)
400 {
401 Texture *zeroTextureVideoImage =
402 new Texture(mImplementation.get(), {0}, TextureType::VideoImage);
403 mZeroTextures[TextureType::VideoImage].set(this, zeroTextureVideoImage);
404 }
405
406 mState.initializeZeroTextures(this, mZeroTextures);
407
408 bindVertexArray({0});
409
410 if (getClientVersion() >= Version(3, 0))
411 {
412 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
413 // In the initial state, a default transform feedback object is bound and treated as
414 // a transform feedback object with a name of zero. That object is bound any time
415 // BindTransformFeedback is called with id of zero
416 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, {0});
417 }
418
419 for (auto type : angle::AllEnums<BufferBinding>())
420 {
421 bindBuffer(type, {0});
422 }
423
424 bindRenderbuffer(GL_RENDERBUFFER, {0});
425
426 for (int i = 0; i < mState.mCaps.maxUniformBufferBindings; i++)
427 {
428 bindBufferRange(BufferBinding::Uniform, i, {0}, 0, -1);
429 }
430
431 // Initialize GLES1 renderer if appropriate.
432 if (getClientVersion() < Version(2, 0))
433 {
434 mGLES1Renderer.reset(new GLES1Renderer());
435 }
436
437 // Initialize dirty bit masks
438 mAllDirtyBits.set();
439
440 mDrawDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
441 mDrawDirtyObjects.set(State::DIRTY_OBJECT_VERTEX_ARRAY);
442 mDrawDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES);
443 mDrawDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM);
444 mDrawDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM_PIPELINE);
445 mDrawDirtyObjects.set(State::DIRTY_OBJECT_SAMPLERS);
446 mDrawDirtyObjects.set(State::DIRTY_OBJECT_IMAGES);
447
448 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_STATE);
449 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
450 // No dirty objects.
451
452 // Readpixels uses the pack state and read FBO
453 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_STATE);
454 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
455 mReadPixelsDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
456 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
457
458 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
459 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
460 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
461 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
462 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
463 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
464 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
465 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
466 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
467 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
468 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
469 mClearDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
470
471 // We sync the draw Framebuffer manually in prepareForClear to allow the clear calls to do
472 // more custom handling for robust resource init.
473
474 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
475 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
476 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
477 mBlitDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
478 mBlitDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
479 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
480 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
481
482 mComputeDirtyBits.set(State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING);
483 mComputeDirtyBits.set(State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
484 mComputeDirtyBits.set(State::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING);
485 mComputeDirtyBits.set(State::DIRTY_BIT_PROGRAM_BINDING);
486 mComputeDirtyBits.set(State::DIRTY_BIT_PROGRAM_EXECUTABLE);
487 mComputeDirtyBits.set(State::DIRTY_BIT_TEXTURE_BINDINGS);
488 mComputeDirtyBits.set(State::DIRTY_BIT_SAMPLER_BINDINGS);
489 mComputeDirtyBits.set(State::DIRTY_BIT_IMAGE_BINDINGS);
490 mComputeDirtyBits.set(State::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING);
491 mComputeDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES);
492 mComputeDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM);
493 mComputeDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM_PIPELINE);
494 mComputeDirtyObjects.set(State::DIRTY_OBJECT_IMAGES);
495 mComputeDirtyObjects.set(State::DIRTY_OBJECT_SAMPLERS);
496
497 mCopyImageDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
498 mCopyImageDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
499
500 ANGLE_CONTEXT_TRY(mImplementation->initialize());
501
502 // Initialize overlay after implementation is initialized.
503 ANGLE_CONTEXT_TRY(mOverlay.init(this));
504 }
505
onDestroy(const egl::Display * display)506 egl::Error Context::onDestroy(const egl::Display *display)
507 {
508 // Dump frame capture if enabled.
509 mFrameCapture->onEndFrame(this);
510
511 if (mGLES1Renderer)
512 {
513 mGLES1Renderer->onDestroy(this, &mState);
514 }
515
516 ANGLE_TRY(unMakeCurrent(display));
517
518 for (auto fence : mFenceNVMap)
519 {
520 if (fence.second)
521 {
522 fence.second->onDestroy(this);
523 }
524 SafeDelete(fence.second);
525 }
526 mFenceNVMap.clear();
527
528 for (auto query : mQueryMap)
529 {
530 if (query.second != nullptr)
531 {
532 query.second->release(this);
533 }
534 }
535 mQueryMap.clear();
536
537 for (auto vertexArray : mVertexArrayMap)
538 {
539 if (vertexArray.second)
540 {
541 vertexArray.second->onDestroy(this);
542 }
543 }
544 mVertexArrayMap.clear();
545
546 for (auto transformFeedback : mTransformFeedbackMap)
547 {
548 if (transformFeedback.second != nullptr)
549 {
550 transformFeedback.second->release(this);
551 }
552 }
553 mTransformFeedbackMap.clear();
554
555 for (BindingPointer<Texture> &zeroTexture : mZeroTextures)
556 {
557 if (zeroTexture.get() != nullptr)
558 {
559 zeroTexture.set(this, nullptr);
560 }
561 }
562
563 releaseShaderCompiler();
564
565 mState.reset(this);
566
567 mState.mBufferManager->release(this);
568 // mProgramPipelineManager must be before mShaderProgramManager to give each
569 // PPO the chance to release any references they have to the Programs that
570 // are bound to them before the Programs are released()'ed.
571 mState.mProgramPipelineManager->release(this);
572 mState.mShaderProgramManager->release(this);
573 mState.mTextureManager->release(this);
574 mState.mRenderbufferManager->release(this);
575 mState.mSamplerManager->release(this);
576 mState.mSyncManager->release(this);
577 mState.mFramebufferManager->release(this);
578 mState.mMemoryObjectManager->release(this);
579 mState.mSemaphoreManager->release(this);
580
581 mThreadPool.reset();
582
583 mImplementation->onDestroy(this);
584
585 mOverlay.destroy(this);
586
587 return egl::NoError();
588 }
589
~Context()590 Context::~Context() {}
591
setLabel(EGLLabelKHR label)592 void Context::setLabel(EGLLabelKHR label)
593 {
594 mLabel = label;
595 }
596
getLabel() const597 EGLLabelKHR Context::getLabel() const
598 {
599 return mLabel;
600 }
601
makeCurrent(egl::Display * display,egl::Surface * drawSurface,egl::Surface * readSurface)602 egl::Error Context::makeCurrent(egl::Display *display,
603 egl::Surface *drawSurface,
604 egl::Surface *readSurface)
605 {
606 mDisplay = display;
607
608 if (!mHasBeenCurrent)
609 {
610 initialize();
611 initRendererString();
612 initVersionStrings();
613 initExtensionStrings();
614
615 int width = 0;
616 int height = 0;
617 if (drawSurface != nullptr)
618 {
619 width = drawSurface->getWidth();
620 height = drawSurface->getHeight();
621 }
622
623 mState.setViewportParams(0, 0, width, height);
624 mState.setScissorParams(0, 0, width, height);
625
626 mHasBeenCurrent = true;
627 }
628
629 // TODO(jmadill): Rework this when we support ContextImpl
630 mState.setAllDirtyBits();
631 mState.setAllDirtyObjects();
632
633 ANGLE_TRY(setDefaultFramebuffer(drawSurface, readSurface));
634
635 // Notify the renderer of a context switch.
636 angle::Result implResult = mImplementation->onMakeCurrent(this);
637
638 // If the implementation fails onMakeCurrent, unset the default framebuffer.
639 if (implResult != angle::Result::Continue)
640 {
641 ANGLE_TRY(unsetDefaultFramebuffer());
642 return angle::ResultToEGL(implResult);
643 }
644
645 return egl::NoError();
646 }
647
unMakeCurrent(const egl::Display * display)648 egl::Error Context::unMakeCurrent(const egl::Display *display)
649 {
650 ANGLE_TRY(unsetDefaultFramebuffer());
651
652 ANGLE_TRY(angle::ResultToEGL(mImplementation->onUnMakeCurrent(this)));
653
654 // Return the scratch buffers to the display so they can be shared with other contexts while
655 // this one is not current.
656 if (mScratchBuffer.valid())
657 {
658 mDisplay->returnScratchBuffer(mScratchBuffer.release());
659 }
660 if (mZeroFilledBuffer.valid())
661 {
662 mDisplay->returnZeroFilledBuffer(mZeroFilledBuffer.release());
663 }
664
665 return egl::NoError();
666 }
667
createBuffer()668 BufferID Context::createBuffer()
669 {
670 return mState.mBufferManager->createBuffer();
671 }
672
createProgram()673 GLuint Context::createProgram()
674 {
675 return mState.mShaderProgramManager->createProgram(mImplementation.get()).value;
676 }
677
createShader(ShaderType type)678 GLuint Context::createShader(ShaderType type)
679 {
680 return mState.mShaderProgramManager
681 ->createShader(mImplementation.get(), mState.mLimitations, type)
682 .value;
683 }
684
createTexture()685 TextureID Context::createTexture()
686 {
687 return mState.mTextureManager->createTexture();
688 }
689
createRenderbuffer()690 RenderbufferID Context::createRenderbuffer()
691 {
692 return mState.mRenderbufferManager->createRenderbuffer();
693 }
694
695 // Returns an unused framebuffer name
createFramebuffer()696 FramebufferID Context::createFramebuffer()
697 {
698 return mState.mFramebufferManager->createFramebuffer();
699 }
700
genFencesNV(GLsizei n,FenceNVID * fences)701 void Context::genFencesNV(GLsizei n, FenceNVID *fences)
702 {
703 for (int i = 0; i < n; i++)
704 {
705 GLuint handle = mFenceNVHandleAllocator.allocate();
706 mFenceNVMap.assign({handle}, new FenceNV(mImplementation.get()));
707 fences[i] = {handle};
708 }
709 }
710
createProgramPipeline()711 ProgramPipelineID Context::createProgramPipeline()
712 {
713 return mState.mProgramPipelineManager->createProgramPipeline();
714 }
715
createShaderProgramv(ShaderType type,GLsizei count,const GLchar * const * strings)716 GLuint Context::createShaderProgramv(ShaderType type, GLsizei count, const GLchar *const *strings)
717 {
718 const ShaderProgramID shaderID = FromGL<ShaderProgramID>(createShader(type));
719 if (shaderID.value)
720 {
721 Shader *shaderObject = getShader(shaderID);
722 ASSERT(shaderObject);
723 shaderObject->setSource(count, strings, nullptr);
724 shaderObject->compile(this);
725 const ShaderProgramID programID = FromGL<ShaderProgramID>(createProgram());
726 if (programID.value)
727 {
728 gl::Program *programObject = getProgramNoResolveLink(programID);
729 ASSERT(programObject);
730
731 if (shaderObject->isCompiled())
732 {
733 // As per Khronos issue 2261:
734 // https://gitlab.khronos.org/Tracker/vk-gl-cts/issues/2261
735 // We must wait to mark the program separable until it's successfully compiled.
736 programObject->setSeparable(true);
737
738 programObject->attachShader(this, shaderObject);
739
740 if (programObject->link(this) != angle::Result::Continue)
741 {
742 deleteShader(shaderID);
743 deleteProgram(programID);
744 return 0u;
745 }
746 if (onProgramLink(programObject) != angle::Result::Continue)
747 {
748 deleteShader(shaderID);
749 deleteProgram(programID);
750 return 0u;
751 }
752
753 // Need to manually resolveLink(), since onProgramLink() doesn't think the program
754 // is in use. For the normal glDetachShader() API call path, this is done during
755 // ValidateDetachShader() via gl::GetValidProgram().
756 programObject->resolveLink(this);
757 programObject->detachShader(this, shaderObject);
758 }
759
760 InfoLog &programInfoLog = programObject->getExecutable().getInfoLog();
761 programInfoLog << shaderObject->getInfoLogString();
762 }
763
764 deleteShader(shaderID);
765
766 return programID.value;
767 }
768
769 return 0u;
770 }
771
createMemoryObject()772 MemoryObjectID Context::createMemoryObject()
773 {
774 return mState.mMemoryObjectManager->createMemoryObject(mImplementation.get());
775 }
776
createSemaphore()777 SemaphoreID Context::createSemaphore()
778 {
779 return mState.mSemaphoreManager->createSemaphore(mImplementation.get());
780 }
781
deleteBuffer(BufferID bufferName)782 void Context::deleteBuffer(BufferID bufferName)
783 {
784 Buffer *buffer = mState.mBufferManager->getBuffer(bufferName);
785 if (buffer)
786 {
787 detachBuffer(buffer);
788 }
789
790 mState.mBufferManager->deleteObject(this, bufferName);
791 }
792
deleteShader(ShaderProgramID shader)793 void Context::deleteShader(ShaderProgramID shader)
794 {
795 mState.mShaderProgramManager->deleteShader(this, shader);
796 }
797
deleteProgram(ShaderProgramID program)798 void Context::deleteProgram(ShaderProgramID program)
799 {
800 mState.mShaderProgramManager->deleteProgram(this, program);
801 }
802
deleteTexture(TextureID texture)803 void Context::deleteTexture(TextureID texture)
804 {
805 if (mState.mTextureManager->getTexture(texture))
806 {
807 detachTexture(texture);
808 }
809
810 mState.mTextureManager->deleteObject(this, texture);
811 }
812
deleteRenderbuffer(RenderbufferID renderbuffer)813 void Context::deleteRenderbuffer(RenderbufferID renderbuffer)
814 {
815 if (mState.mRenderbufferManager->getRenderbuffer(renderbuffer))
816 {
817 detachRenderbuffer(renderbuffer);
818 }
819
820 mState.mRenderbufferManager->deleteObject(this, renderbuffer);
821 }
822
deleteSync(GLsync sync)823 void Context::deleteSync(GLsync sync)
824 {
825 // The spec specifies the underlying Fence object is not deleted until all current
826 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
827 // and since our API is currently designed for being called from a single thread, we can delete
828 // the fence immediately.
829 mState.mSyncManager->deleteObject(this, static_cast<GLuint>(reinterpret_cast<uintptr_t>(sync)));
830 }
831
deleteProgramPipeline(ProgramPipelineID pipelineID)832 void Context::deleteProgramPipeline(ProgramPipelineID pipelineID)
833 {
834 ProgramPipeline *pipeline = mState.mProgramPipelineManager->getProgramPipeline(pipelineID);
835 if (pipeline)
836 {
837 detachProgramPipeline(pipelineID);
838 }
839
840 mState.mProgramPipelineManager->deleteObject(this, pipelineID);
841 }
842
deleteMemoryObject(MemoryObjectID memoryObject)843 void Context::deleteMemoryObject(MemoryObjectID memoryObject)
844 {
845 mState.mMemoryObjectManager->deleteMemoryObject(this, memoryObject);
846 }
847
deleteSemaphore(SemaphoreID semaphore)848 void Context::deleteSemaphore(SemaphoreID semaphore)
849 {
850 mState.mSemaphoreManager->deleteSemaphore(this, semaphore);
851 }
852
853 // GL_CHROMIUM_lose_context
loseContext(GraphicsResetStatus current,GraphicsResetStatus other)854 void Context::loseContext(GraphicsResetStatus current, GraphicsResetStatus other)
855 {
856 // TODO(geofflang): mark the rest of the share group lost. Requires access to the entire share
857 // group from a context. http://anglebug.com/3379
858 markContextLost(current);
859 }
860
deleteFramebuffer(FramebufferID framebuffer)861 void Context::deleteFramebuffer(FramebufferID framebuffer)
862 {
863 if (mState.mFramebufferManager->getFramebuffer(framebuffer))
864 {
865 detachFramebuffer(framebuffer);
866 }
867
868 mState.mFramebufferManager->deleteObject(this, framebuffer);
869 }
870
deleteFencesNV(GLsizei n,const FenceNVID * fences)871 void Context::deleteFencesNV(GLsizei n, const FenceNVID *fences)
872 {
873 for (int i = 0; i < n; i++)
874 {
875 FenceNVID fence = fences[i];
876
877 FenceNV *fenceObject = nullptr;
878 if (mFenceNVMap.erase(fence, &fenceObject))
879 {
880 mFenceNVHandleAllocator.release(fence.value);
881 if (fenceObject)
882 {
883 fenceObject->onDestroy(this);
884 }
885 delete fenceObject;
886 }
887 }
888 }
889
getBuffer(BufferID handle) const890 Buffer *Context::getBuffer(BufferID handle) const
891 {
892 return mState.mBufferManager->getBuffer(handle);
893 }
894
getRenderbuffer(RenderbufferID handle) const895 Renderbuffer *Context::getRenderbuffer(RenderbufferID handle) const
896 {
897 return mState.mRenderbufferManager->getRenderbuffer(handle);
898 }
899
getContextPriority() const900 EGLenum Context::getContextPriority() const
901 {
902 return egl::ToEGLenum(mImplementation->getContextPriority());
903 }
904
getSync(GLsync handle) const905 Sync *Context::getSync(GLsync handle) const
906 {
907 return mState.mSyncManager->getSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
908 }
909
getVertexArray(VertexArrayID handle) const910 VertexArray *Context::getVertexArray(VertexArrayID handle) const
911 {
912 return mVertexArrayMap.query(handle);
913 }
914
getSampler(SamplerID handle) const915 Sampler *Context::getSampler(SamplerID handle) const
916 {
917 return mState.mSamplerManager->getSampler(handle);
918 }
919
getTransformFeedback(TransformFeedbackID handle) const920 TransformFeedback *Context::getTransformFeedback(TransformFeedbackID handle) const
921 {
922 return mTransformFeedbackMap.query(handle);
923 }
924
getProgramPipeline(ProgramPipelineID handle) const925 ProgramPipeline *Context::getProgramPipeline(ProgramPipelineID handle) const
926 {
927 return mState.mProgramPipelineManager->getProgramPipeline(handle);
928 }
929
getLabeledObject(GLenum identifier,GLuint name) const930 gl::LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
931 {
932 switch (identifier)
933 {
934 case GL_BUFFER:
935 return getBuffer({name});
936 case GL_SHADER:
937 return getShader({name});
938 case GL_PROGRAM:
939 return getProgramNoResolveLink({name});
940 case GL_VERTEX_ARRAY:
941 return getVertexArray({name});
942 case GL_QUERY:
943 return getQuery({name});
944 case GL_TRANSFORM_FEEDBACK:
945 return getTransformFeedback({name});
946 case GL_SAMPLER:
947 return getSampler({name});
948 case GL_TEXTURE:
949 return getTexture({name});
950 case GL_RENDERBUFFER:
951 return getRenderbuffer({name});
952 case GL_FRAMEBUFFER:
953 return getFramebuffer({name});
954 case GL_PROGRAM_PIPELINE:
955 return getProgramPipeline({name});
956 default:
957 UNREACHABLE();
958 return nullptr;
959 }
960 }
961
getLabeledObjectFromPtr(const void * ptr) const962 gl::LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
963 {
964 return getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
965 }
966
objectLabel(GLenum identifier,GLuint name,GLsizei length,const GLchar * label)967 void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
968 {
969 gl::LabeledObject *object = getLabeledObject(identifier, name);
970 ASSERT(object != nullptr);
971
972 std::string labelName = GetObjectLabelFromPointer(length, label);
973 object->setLabel(this, labelName);
974
975 // TODO(jmadill): Determine if the object is dirty based on 'name'. Conservatively assume the
976 // specified object is active until we do this.
977 mState.setObjectDirty(identifier);
978 }
979
objectPtrLabel(const void * ptr,GLsizei length,const GLchar * label)980 void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
981 {
982 gl::LabeledObject *object = getLabeledObjectFromPtr(ptr);
983 ASSERT(object != nullptr);
984
985 std::string labelName = GetObjectLabelFromPointer(length, label);
986 object->setLabel(this, labelName);
987 }
988
getObjectLabel(GLenum identifier,GLuint name,GLsizei bufSize,GLsizei * length,GLchar * label)989 void Context::getObjectLabel(GLenum identifier,
990 GLuint name,
991 GLsizei bufSize,
992 GLsizei *length,
993 GLchar *label)
994 {
995 gl::LabeledObject *object = getLabeledObject(identifier, name);
996 ASSERT(object != nullptr);
997
998 const std::string &objectLabel = object->getLabel();
999 GetObjectLabelBase(objectLabel, bufSize, length, label);
1000 }
1001
getObjectPtrLabel(const void * ptr,GLsizei bufSize,GLsizei * length,GLchar * label)1002 void Context::getObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label)
1003 {
1004 gl::LabeledObject *object = getLabeledObjectFromPtr(ptr);
1005 ASSERT(object != nullptr);
1006
1007 const std::string &objectLabel = object->getLabel();
1008 GetObjectLabelBase(objectLabel, bufSize, length, label);
1009 }
1010
isSampler(SamplerID samplerName) const1011 GLboolean Context::isSampler(SamplerID samplerName) const
1012 {
1013 return mState.mSamplerManager->isSampler(samplerName);
1014 }
1015
bindTexture(TextureType target,TextureID handle)1016 void Context::bindTexture(TextureType target, TextureID handle)
1017 {
1018 Texture *texture = nullptr;
1019
1020 if (handle.value == 0)
1021 {
1022 texture = mZeroTextures[target].get();
1023 }
1024 else
1025 {
1026 texture =
1027 mState.mTextureManager->checkTextureAllocation(mImplementation.get(), handle, target);
1028 }
1029
1030 ASSERT(texture);
1031 mState.setSamplerTexture(this, target, texture);
1032 mStateCache.onActiveTextureChange(this);
1033 }
1034
bindReadFramebuffer(FramebufferID framebufferHandle)1035 void Context::bindReadFramebuffer(FramebufferID framebufferHandle)
1036 {
1037 Framebuffer *framebuffer = mState.mFramebufferManager->checkFramebufferAllocation(
1038 mImplementation.get(), mState.mCaps, framebufferHandle, mState.getContextID());
1039 mState.setReadFramebufferBinding(framebuffer);
1040 mReadFramebufferObserverBinding.bind(framebuffer);
1041 }
1042
bindDrawFramebuffer(FramebufferID framebufferHandle)1043 void Context::bindDrawFramebuffer(FramebufferID framebufferHandle)
1044 {
1045 Framebuffer *framebuffer = mState.mFramebufferManager->checkFramebufferAllocation(
1046 mImplementation.get(), mState.mCaps, framebufferHandle, mState.getContextID());
1047 mState.setDrawFramebufferBinding(framebuffer);
1048 mDrawFramebufferObserverBinding.bind(framebuffer);
1049 mStateCache.onDrawFramebufferChange(this);
1050 }
1051
bindVertexArray(VertexArrayID vertexArrayHandle)1052 void Context::bindVertexArray(VertexArrayID vertexArrayHandle)
1053 {
1054 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
1055 mState.setVertexArrayBinding(this, vertexArray);
1056 mVertexArrayObserverBinding.bind(vertexArray);
1057 mStateCache.onVertexArrayBindingChange(this);
1058 }
1059
bindVertexBuffer(GLuint bindingIndex,BufferID bufferHandle,GLintptr offset,GLsizei stride)1060 void Context::bindVertexBuffer(GLuint bindingIndex,
1061 BufferID bufferHandle,
1062 GLintptr offset,
1063 GLsizei stride)
1064 {
1065 Buffer *buffer =
1066 mState.mBufferManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
1067 mState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
1068 mStateCache.onVertexArrayStateChange(this);
1069 }
1070
bindSampler(GLuint textureUnit,SamplerID samplerHandle)1071 void Context::bindSampler(GLuint textureUnit, SamplerID samplerHandle)
1072 {
1073 ASSERT(textureUnit < static_cast<GLuint>(mState.mCaps.maxCombinedTextureImageUnits));
1074 Sampler *sampler =
1075 mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
1076 mState.setSamplerBinding(this, textureUnit, sampler);
1077 mSamplerObserverBindings[textureUnit].bind(sampler);
1078 mStateCache.onActiveTextureChange(this);
1079 }
1080
bindImageTexture(GLuint unit,TextureID texture,GLint level,GLboolean layered,GLint layer,GLenum access,GLenum format)1081 void Context::bindImageTexture(GLuint unit,
1082 TextureID texture,
1083 GLint level,
1084 GLboolean layered,
1085 GLint layer,
1086 GLenum access,
1087 GLenum format)
1088 {
1089 Texture *tex = mState.mTextureManager->getTexture(texture);
1090 mState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
1091 mImageObserverBindings[unit].bind(tex);
1092 }
1093
useProgram(ShaderProgramID program)1094 void Context::useProgram(ShaderProgramID program)
1095 {
1096 ANGLE_CONTEXT_TRY(mState.setProgram(this, getProgramResolveLink(program)));
1097 mStateCache.onProgramExecutableChange(this);
1098 }
1099
useProgramStages(ProgramPipelineID pipeline,GLbitfield stages,ShaderProgramID program)1100 void Context::useProgramStages(ProgramPipelineID pipeline,
1101 GLbitfield stages,
1102 ShaderProgramID program)
1103 {
1104 Program *shaderProgram = getProgramNoResolveLink(program);
1105 ProgramPipeline *programPipeline =
1106 mState.mProgramPipelineManager->checkProgramPipelineAllocation(mImplementation.get(),
1107 pipeline);
1108
1109 ASSERT(programPipeline);
1110 ANGLE_CONTEXT_TRY(mState.useProgramStages(this, programPipeline, stages, shaderProgram));
1111 mStateCache.onProgramExecutableChange(this);
1112 }
1113
bindTransformFeedback(GLenum target,TransformFeedbackID transformFeedbackHandle)1114 void Context::bindTransformFeedback(GLenum target, TransformFeedbackID transformFeedbackHandle)
1115 {
1116 ASSERT(target == GL_TRANSFORM_FEEDBACK);
1117 TransformFeedback *transformFeedback =
1118 checkTransformFeedbackAllocation(transformFeedbackHandle);
1119 mState.setTransformFeedbackBinding(this, transformFeedback);
1120 }
1121
bindProgramPipeline(ProgramPipelineID pipelineHandle)1122 void Context::bindProgramPipeline(ProgramPipelineID pipelineHandle)
1123 {
1124 ProgramPipeline *pipeline = mState.mProgramPipelineManager->checkProgramPipelineAllocation(
1125 mImplementation.get(), pipelineHandle);
1126 ANGLE_CONTEXT_TRY(mState.setProgramPipelineBinding(this, pipeline));
1127 }
1128
beginQuery(QueryType target,QueryID query)1129 void Context::beginQuery(QueryType target, QueryID query)
1130 {
1131 Query *queryObject = getOrCreateQuery(query, target);
1132 ASSERT(queryObject);
1133
1134 // begin query
1135 ANGLE_CONTEXT_TRY(queryObject->begin(this));
1136
1137 // set query as active for specified target only if begin succeeded
1138 mState.setActiveQuery(this, target, queryObject);
1139 mStateCache.onQueryChange(this);
1140 }
1141
endQuery(QueryType target)1142 void Context::endQuery(QueryType target)
1143 {
1144 Query *queryObject = mState.getActiveQuery(target);
1145 ASSERT(queryObject);
1146
1147 // Intentionally don't call try here. We don't want an early return.
1148 (void)(queryObject->end(this));
1149
1150 // Always unbind the query, even if there was an error. This may delete the query object.
1151 mState.setActiveQuery(this, target, nullptr);
1152 mStateCache.onQueryChange(this);
1153 }
1154
queryCounter(QueryID id,QueryType target)1155 void Context::queryCounter(QueryID id, QueryType target)
1156 {
1157 ASSERT(target == QueryType::Timestamp);
1158
1159 Query *queryObject = getOrCreateQuery(id, target);
1160 ASSERT(queryObject);
1161
1162 ANGLE_CONTEXT_TRY(queryObject->queryCounter(this));
1163 }
1164
getQueryiv(QueryType target,GLenum pname,GLint * params)1165 void Context::getQueryiv(QueryType target, GLenum pname, GLint *params)
1166 {
1167 switch (pname)
1168 {
1169 case GL_CURRENT_QUERY_EXT:
1170 params[0] = mState.getActiveQueryId(target).value;
1171 break;
1172 case GL_QUERY_COUNTER_BITS_EXT:
1173 switch (target)
1174 {
1175 case QueryType::TimeElapsed:
1176 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1177 break;
1178 case QueryType::Timestamp:
1179 params[0] = getExtensions().queryCounterBitsTimestamp;
1180 break;
1181 default:
1182 UNREACHABLE();
1183 params[0] = 0;
1184 break;
1185 }
1186 break;
1187 default:
1188 UNREACHABLE();
1189 return;
1190 }
1191 }
1192
getQueryivRobust(QueryType target,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)1193 void Context::getQueryivRobust(QueryType target,
1194 GLenum pname,
1195 GLsizei bufSize,
1196 GLsizei *length,
1197 GLint *params)
1198 {
1199 getQueryiv(target, pname, params);
1200 }
1201
getUnsignedBytev(GLenum pname,GLubyte * data)1202 void Context::getUnsignedBytev(GLenum pname, GLubyte *data)
1203 {
1204 UNIMPLEMENTED();
1205 }
1206
getUnsignedBytei_v(GLenum target,GLuint index,GLubyte * data)1207 void Context::getUnsignedBytei_v(GLenum target, GLuint index, GLubyte *data)
1208 {
1209 UNIMPLEMENTED();
1210 }
1211
getQueryObjectiv(QueryID id,GLenum pname,GLint * params)1212 void Context::getQueryObjectiv(QueryID id, GLenum pname, GLint *params)
1213 {
1214 ANGLE_CONTEXT_TRY(GetQueryObjectParameter(this, getQuery(id), pname, params));
1215 }
1216
getQueryObjectivRobust(QueryID id,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)1217 void Context::getQueryObjectivRobust(QueryID id,
1218 GLenum pname,
1219 GLsizei bufSize,
1220 GLsizei *length,
1221 GLint *params)
1222 {
1223 getQueryObjectiv(id, pname, params);
1224 }
1225
getQueryObjectuiv(QueryID id,GLenum pname,GLuint * params)1226 void Context::getQueryObjectuiv(QueryID id, GLenum pname, GLuint *params)
1227 {
1228 ANGLE_CONTEXT_TRY(GetQueryObjectParameter(this, getQuery(id), pname, params));
1229 }
1230
getQueryObjectuivRobust(QueryID id,GLenum pname,GLsizei bufSize,GLsizei * length,GLuint * params)1231 void Context::getQueryObjectuivRobust(QueryID id,
1232 GLenum pname,
1233 GLsizei bufSize,
1234 GLsizei *length,
1235 GLuint *params)
1236 {
1237 getQueryObjectuiv(id, pname, params);
1238 }
1239
getQueryObjecti64v(QueryID id,GLenum pname,GLint64 * params)1240 void Context::getQueryObjecti64v(QueryID id, GLenum pname, GLint64 *params)
1241 {
1242 ANGLE_CONTEXT_TRY(GetQueryObjectParameter(this, getQuery(id), pname, params));
1243 }
1244
getQueryObjecti64vRobust(QueryID id,GLenum pname,GLsizei bufSize,GLsizei * length,GLint64 * params)1245 void Context::getQueryObjecti64vRobust(QueryID id,
1246 GLenum pname,
1247 GLsizei bufSize,
1248 GLsizei *length,
1249 GLint64 *params)
1250 {
1251 getQueryObjecti64v(id, pname, params);
1252 }
1253
getQueryObjectui64v(QueryID id,GLenum pname,GLuint64 * params)1254 void Context::getQueryObjectui64v(QueryID id, GLenum pname, GLuint64 *params)
1255 {
1256 ANGLE_CONTEXT_TRY(GetQueryObjectParameter(this, getQuery(id), pname, params));
1257 }
1258
getQueryObjectui64vRobust(QueryID id,GLenum pname,GLsizei bufSize,GLsizei * length,GLuint64 * params)1259 void Context::getQueryObjectui64vRobust(QueryID id,
1260 GLenum pname,
1261 GLsizei bufSize,
1262 GLsizei *length,
1263 GLuint64 *params)
1264 {
1265 getQueryObjectui64v(id, pname, params);
1266 }
1267
getFramebuffer(FramebufferID handle) const1268 Framebuffer *Context::getFramebuffer(FramebufferID handle) const
1269 {
1270 return mState.mFramebufferManager->getFramebuffer(handle);
1271 }
1272
getFenceNV(FenceNVID handle) const1273 FenceNV *Context::getFenceNV(FenceNVID handle) const
1274 {
1275 return mFenceNVMap.query(handle);
1276 }
1277
getOrCreateQuery(QueryID handle,QueryType type)1278 Query *Context::getOrCreateQuery(QueryID handle, QueryType type)
1279 {
1280 if (!mQueryMap.contains(handle))
1281 {
1282 return nullptr;
1283 }
1284
1285 Query *query = mQueryMap.query(handle);
1286 if (!query)
1287 {
1288 ASSERT(type != QueryType::InvalidEnum);
1289 query = new Query(mImplementation.get(), type, handle);
1290 query->addRef();
1291 mQueryMap.assign(handle, query);
1292 }
1293 return query;
1294 }
1295
getQuery(QueryID handle) const1296 Query *Context::getQuery(QueryID handle) const
1297 {
1298 return mQueryMap.query(handle);
1299 }
1300
getTextureByType(TextureType type) const1301 Texture *Context::getTextureByType(TextureType type) const
1302 {
1303 ASSERT(ValidTextureTarget(this, type) || ValidTextureExternalTarget(this, type));
1304 return mState.getTargetTexture(type);
1305 }
1306
getTextureByTarget(TextureTarget target) const1307 Texture *Context::getTextureByTarget(TextureTarget target) const
1308 {
1309 return getTextureByType(TextureTargetToType(target));
1310 }
1311
getSamplerTexture(unsigned int sampler,TextureType type) const1312 Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const
1313 {
1314 return mState.getSamplerTexture(sampler, type);
1315 }
1316
getCompiler() const1317 Compiler *Context::getCompiler() const
1318 {
1319 if (mCompiler.get() == nullptr)
1320 {
1321 mCompiler.set(this, new Compiler(mImplementation.get(), mState));
1322 }
1323 return mCompiler.get();
1324 }
1325
getBooleanvImpl(GLenum pname,GLboolean * params) const1326 void Context::getBooleanvImpl(GLenum pname, GLboolean *params) const
1327 {
1328 switch (pname)
1329 {
1330 case GL_SHADER_COMPILER:
1331 *params = GL_TRUE;
1332 break;
1333 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1334 *params = ConvertToGLBoolean(mRobustAccess);
1335 break;
1336
1337 default:
1338 mState.getBooleanv(pname, params);
1339 break;
1340 }
1341 }
1342
getFloatvImpl(GLenum pname,GLfloat * params) const1343 void Context::getFloatvImpl(GLenum pname, GLfloat *params) const
1344 {
1345 // Queries about context capabilities and maximums are answered by Context.
1346 // Queries about current GL state values are answered by State.
1347 switch (pname)
1348 {
1349 case GL_ALIASED_LINE_WIDTH_RANGE:
1350 params[0] = mState.mCaps.minAliasedLineWidth;
1351 params[1] = mState.mCaps.maxAliasedLineWidth;
1352 break;
1353 case GL_ALIASED_POINT_SIZE_RANGE:
1354 params[0] = mState.mCaps.minAliasedPointSize;
1355 params[1] = mState.mCaps.maxAliasedPointSize;
1356 break;
1357 case GL_SMOOTH_POINT_SIZE_RANGE:
1358 params[0] = mState.mCaps.minSmoothPointSize;
1359 params[1] = mState.mCaps.maxSmoothPointSize;
1360 break;
1361 case GL_SMOOTH_LINE_WIDTH_RANGE:
1362 params[0] = mState.mCaps.minSmoothLineWidth;
1363 params[1] = mState.mCaps.maxSmoothLineWidth;
1364 break;
1365 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1366 ASSERT(mState.mExtensions.textureFilterAnisotropic);
1367 *params = mState.mExtensions.maxTextureAnisotropy;
1368 break;
1369 case GL_MAX_TEXTURE_LOD_BIAS:
1370 *params = mState.mCaps.maxLODBias;
1371 break;
1372 default:
1373 mState.getFloatv(pname, params);
1374 break;
1375 }
1376 }
1377
getIntegervImpl(GLenum pname,GLint * params) const1378 void Context::getIntegervImpl(GLenum pname, GLint *params) const
1379 {
1380 // Queries about context capabilities and maximums are answered by Context.
1381 // Queries about current GL state values are answered by State.
1382
1383 switch (pname)
1384 {
1385 case GL_MAX_VERTEX_ATTRIBS:
1386 *params = mState.mCaps.maxVertexAttributes;
1387 break;
1388 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1389 *params = mState.mCaps.maxVertexUniformVectors;
1390 break;
1391 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1392 *params = mState.mCaps.maxShaderUniformComponents[ShaderType::Vertex];
1393 break;
1394 case GL_MAX_VARYING_VECTORS:
1395 *params = mState.mCaps.maxVaryingVectors;
1396 break;
1397 case GL_MAX_VARYING_COMPONENTS:
1398 *params = mState.mCaps.maxVaryingVectors * 4;
1399 break;
1400 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1401 *params = mState.mCaps.maxCombinedTextureImageUnits;
1402 break;
1403 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1404 *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::Vertex];
1405 break;
1406 case GL_MAX_TEXTURE_IMAGE_UNITS:
1407 *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::Fragment];
1408 break;
1409 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1410 *params = mState.mCaps.maxFragmentUniformVectors;
1411 break;
1412 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1413 *params = mState.mCaps.maxShaderUniformComponents[ShaderType::Fragment];
1414 break;
1415 case GL_MAX_RENDERBUFFER_SIZE:
1416 *params = mState.mCaps.maxRenderbufferSize;
1417 break;
1418 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1419 *params = mState.mCaps.maxColorAttachments;
1420 break;
1421 case GL_MAX_DRAW_BUFFERS_EXT:
1422 *params = mState.mCaps.maxDrawBuffers;
1423 break;
1424 case GL_SUBPIXEL_BITS:
1425 *params = mState.mCaps.subPixelBits;
1426 break;
1427 case GL_MAX_TEXTURE_SIZE:
1428 *params = mState.mCaps.max2DTextureSize;
1429 break;
1430 case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
1431 *params = mState.mCaps.maxRectangleTextureSize;
1432 break;
1433 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1434 *params = mState.mCaps.maxCubeMapTextureSize;
1435 break;
1436 case GL_MAX_3D_TEXTURE_SIZE:
1437 *params = mState.mCaps.max3DTextureSize;
1438 break;
1439 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1440 *params = mState.mCaps.maxArrayTextureLayers;
1441 break;
1442 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1443 *params = mState.mCaps.uniformBufferOffsetAlignment;
1444 break;
1445 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1446 *params = mState.mCaps.maxUniformBufferBindings;
1447 break;
1448 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1449 *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::Vertex];
1450 break;
1451 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1452 *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::Fragment];
1453 break;
1454 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1455 *params = mState.mCaps.maxCombinedUniformBlocks;
1456 break;
1457 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1458 *params = mState.mCaps.maxVertexOutputComponents;
1459 break;
1460 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1461 *params = mState.mCaps.maxFragmentInputComponents;
1462 break;
1463 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1464 *params = mState.mCaps.minProgramTexelOffset;
1465 break;
1466 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1467 *params = mState.mCaps.maxProgramTexelOffset;
1468 break;
1469 case GL_MAJOR_VERSION:
1470 *params = getClientVersion().major;
1471 break;
1472 case GL_MINOR_VERSION:
1473 *params = getClientVersion().minor;
1474 break;
1475 case GL_MAX_ELEMENTS_INDICES:
1476 *params = mState.mCaps.maxElementsIndices;
1477 break;
1478 case GL_MAX_ELEMENTS_VERTICES:
1479 *params = mState.mCaps.maxElementsVertices;
1480 break;
1481 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1482 *params = mState.mCaps.maxTransformFeedbackInterleavedComponents;
1483 break;
1484 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1485 *params = mState.mCaps.maxTransformFeedbackSeparateAttributes;
1486 break;
1487 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1488 *params = mState.mCaps.maxTransformFeedbackSeparateComponents;
1489 break;
1490 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1491 *params = static_cast<GLint>(mState.mCaps.compressedTextureFormats.size());
1492 break;
1493 case GL_MAX_SAMPLES_ANGLE:
1494 *params = mState.mCaps.maxSamples;
1495 break;
1496 case GL_MAX_VIEWPORT_DIMS:
1497 {
1498 params[0] = mState.mCaps.maxViewportWidth;
1499 params[1] = mState.mCaps.maxViewportHeight;
1500 }
1501 break;
1502 case GL_COMPRESSED_TEXTURE_FORMATS:
1503 std::copy(mState.mCaps.compressedTextureFormats.begin(),
1504 mState.mCaps.compressedTextureFormats.end(), params);
1505 break;
1506 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1507 *params = mResetStrategy;
1508 break;
1509 case GL_NUM_SHADER_BINARY_FORMATS:
1510 *params = static_cast<GLint>(mState.mCaps.shaderBinaryFormats.size());
1511 break;
1512 case GL_SHADER_BINARY_FORMATS:
1513 std::copy(mState.mCaps.shaderBinaryFormats.begin(),
1514 mState.mCaps.shaderBinaryFormats.end(), params);
1515 break;
1516 case GL_NUM_PROGRAM_BINARY_FORMATS:
1517 *params = static_cast<GLint>(mState.mCaps.programBinaryFormats.size());
1518 break;
1519 case GL_PROGRAM_BINARY_FORMATS:
1520 std::copy(mState.mCaps.programBinaryFormats.begin(),
1521 mState.mCaps.programBinaryFormats.end(), params);
1522 break;
1523 case GL_NUM_EXTENSIONS:
1524 *params = static_cast<GLint>(mExtensionStrings.size());
1525 break;
1526
1527 // Desktop client flags
1528 case GL_CONTEXT_FLAGS:
1529 ASSERT(getClientType() == EGL_OPENGL_API);
1530 *params = 0;
1531 break;
1532 case GL_CONTEXT_PROFILE_MASK:
1533 ASSERT(getClientType() == EGL_OPENGL_API);
1534 *params = GL_CONTEXT_COMPATIBILITY_PROFILE_BIT;
1535 break;
1536
1537 // GL_ANGLE_request_extension
1538 case GL_NUM_REQUESTABLE_EXTENSIONS_ANGLE:
1539 *params = static_cast<GLint>(mRequestableExtensionStrings.size());
1540 break;
1541
1542 // GL_KHR_debug
1543 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1544 *params = mState.mExtensions.maxDebugMessageLength;
1545 break;
1546 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1547 *params = mState.mExtensions.maxDebugLoggedMessages;
1548 break;
1549 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1550 *params = mState.mExtensions.maxDebugGroupStackDepth;
1551 break;
1552 case GL_MAX_LABEL_LENGTH:
1553 *params = mState.mExtensions.maxLabelLength;
1554 break;
1555
1556 // GL_OVR_multiview2
1557 case GL_MAX_VIEWS_OVR:
1558 *params = mState.mExtensions.maxViews;
1559 break;
1560
1561 // GL_EXT_disjoint_timer_query
1562 case GL_GPU_DISJOINT_EXT:
1563 *params = mImplementation->getGPUDisjoint();
1564 break;
1565 case GL_MAX_FRAMEBUFFER_WIDTH:
1566 *params = mState.mCaps.maxFramebufferWidth;
1567 break;
1568 case GL_MAX_FRAMEBUFFER_HEIGHT:
1569 *params = mState.mCaps.maxFramebufferHeight;
1570 break;
1571 case GL_MAX_FRAMEBUFFER_SAMPLES:
1572 *params = mState.mCaps.maxFramebufferSamples;
1573 break;
1574 case GL_MAX_SAMPLE_MASK_WORDS:
1575 *params = mState.mCaps.maxSampleMaskWords;
1576 break;
1577 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1578 *params = mState.mCaps.maxColorTextureSamples;
1579 break;
1580 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1581 *params = mState.mCaps.maxDepthTextureSamples;
1582 break;
1583 case GL_MAX_INTEGER_SAMPLES:
1584 *params = mState.mCaps.maxIntegerSamples;
1585 break;
1586 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1587 *params = mState.mCaps.maxVertexAttribRelativeOffset;
1588 break;
1589 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1590 *params = mState.mCaps.maxVertexAttribBindings;
1591 break;
1592 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1593 *params = mState.mCaps.maxVertexAttribStride;
1594 break;
1595 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1596 *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::Vertex];
1597 break;
1598 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1599 *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::Vertex];
1600 break;
1601 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1602 *params = mState.mCaps.maxShaderImageUniforms[ShaderType::Vertex];
1603 break;
1604 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1605 *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::Vertex];
1606 break;
1607 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1608 *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::Fragment];
1609 break;
1610 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1611 *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::Fragment];
1612 break;
1613 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1614 *params = mState.mCaps.maxShaderImageUniforms[ShaderType::Fragment];
1615 break;
1616 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1617 *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::Fragment];
1618 break;
1619 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1620 *params = mState.mCaps.minProgramTextureGatherOffset;
1621 break;
1622 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1623 *params = mState.mCaps.maxProgramTextureGatherOffset;
1624 break;
1625 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1626 *params = mState.mCaps.maxComputeWorkGroupInvocations;
1627 break;
1628 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1629 *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::Compute];
1630 break;
1631 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1632 *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::Compute];
1633 break;
1634 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1635 *params = mState.mCaps.maxComputeSharedMemorySize;
1636 break;
1637 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1638 *params = mState.mCaps.maxShaderUniformComponents[ShaderType::Compute];
1639 break;
1640 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1641 *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::Compute];
1642 break;
1643 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1644 *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::Compute];
1645 break;
1646 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1647 *params = mState.mCaps.maxShaderImageUniforms[ShaderType::Compute];
1648 break;
1649 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1650 *params = static_cast<GLint>(
1651 mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::Compute]);
1652 break;
1653 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1654 *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::Compute];
1655 break;
1656 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1657 *params = mState.mCaps.maxCombinedShaderOutputResources;
1658 break;
1659 case GL_MAX_UNIFORM_LOCATIONS:
1660 *params = mState.mCaps.maxUniformLocations;
1661 break;
1662 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1663 *params = mState.mCaps.maxAtomicCounterBufferBindings;
1664 break;
1665 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1666 *params = mState.mCaps.maxAtomicCounterBufferSize;
1667 break;
1668 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1669 *params = mState.mCaps.maxCombinedAtomicCounterBuffers;
1670 break;
1671 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1672 *params = mState.mCaps.maxCombinedAtomicCounters;
1673 break;
1674 case GL_MAX_IMAGE_UNITS:
1675 *params = mState.mCaps.maxImageUnits;
1676 break;
1677 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1678 *params = mState.mCaps.maxCombinedImageUniforms;
1679 break;
1680 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1681 *params = mState.mCaps.maxShaderStorageBufferBindings;
1682 break;
1683 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1684 *params = mState.mCaps.maxCombinedShaderStorageBlocks;
1685 break;
1686 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1687 *params = mState.mCaps.shaderStorageBufferOffsetAlignment;
1688 break;
1689
1690 // GL_EXT_geometry_shader
1691 case GL_MAX_FRAMEBUFFER_LAYERS_EXT:
1692 *params = mState.mCaps.maxFramebufferLayers;
1693 break;
1694 case GL_LAYER_PROVOKING_VERTEX_EXT:
1695 *params = mState.mCaps.layerProvokingVertex;
1696 break;
1697 case GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT:
1698 *params = mState.mCaps.maxShaderUniformComponents[ShaderType::Geometry];
1699 break;
1700 case GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT:
1701 *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::Geometry];
1702 break;
1703 case GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT:
1704 *params = static_cast<GLint>(
1705 mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::Geometry]);
1706 break;
1707 case GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT:
1708 *params = mState.mCaps.maxGeometryInputComponents;
1709 break;
1710 case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT:
1711 *params = mState.mCaps.maxGeometryOutputComponents;
1712 break;
1713 case GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT:
1714 *params = mState.mCaps.maxGeometryOutputVertices;
1715 break;
1716 case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT:
1717 *params = mState.mCaps.maxGeometryTotalOutputComponents;
1718 break;
1719 case GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT:
1720 *params = mState.mCaps.maxGeometryShaderInvocations;
1721 break;
1722 case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT:
1723 *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::Geometry];
1724 break;
1725 case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT:
1726 *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::Geometry];
1727 break;
1728 case GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT:
1729 *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::Geometry];
1730 break;
1731 case GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT:
1732 *params = mState.mCaps.maxShaderImageUniforms[ShaderType::Geometry];
1733 break;
1734 case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT:
1735 *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::Geometry];
1736 break;
1737 // GLES1 emulation: Caps queries
1738 case GL_MAX_TEXTURE_UNITS:
1739 *params = mState.mCaps.maxMultitextureUnits;
1740 break;
1741 case GL_MAX_MODELVIEW_STACK_DEPTH:
1742 *params = mState.mCaps.maxModelviewMatrixStackDepth;
1743 break;
1744 case GL_MAX_PROJECTION_STACK_DEPTH:
1745 *params = mState.mCaps.maxProjectionMatrixStackDepth;
1746 break;
1747 case GL_MAX_TEXTURE_STACK_DEPTH:
1748 *params = mState.mCaps.maxTextureMatrixStackDepth;
1749 break;
1750 case GL_MAX_LIGHTS:
1751 *params = mState.mCaps.maxLights;
1752 break;
1753 case GL_MAX_CLIP_PLANES:
1754 *params = mState.mCaps.maxClipPlanes;
1755 break;
1756 // GLES1 emulation: Vertex attribute queries
1757 case GL_VERTEX_ARRAY_BUFFER_BINDING:
1758 case GL_NORMAL_ARRAY_BUFFER_BINDING:
1759 case GL_COLOR_ARRAY_BUFFER_BINDING:
1760 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
1761 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
1762 getIntegerVertexAttribImpl(pname, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, params);
1763 break;
1764 case GL_VERTEX_ARRAY_STRIDE:
1765 case GL_NORMAL_ARRAY_STRIDE:
1766 case GL_COLOR_ARRAY_STRIDE:
1767 case GL_POINT_SIZE_ARRAY_STRIDE_OES:
1768 case GL_TEXTURE_COORD_ARRAY_STRIDE:
1769 getIntegerVertexAttribImpl(pname, GL_VERTEX_ATTRIB_ARRAY_STRIDE, params);
1770 break;
1771 case GL_VERTEX_ARRAY_SIZE:
1772 case GL_COLOR_ARRAY_SIZE:
1773 case GL_TEXTURE_COORD_ARRAY_SIZE:
1774 getIntegerVertexAttribImpl(pname, GL_VERTEX_ATTRIB_ARRAY_SIZE, params);
1775 break;
1776 case GL_VERTEX_ARRAY_TYPE:
1777 case GL_COLOR_ARRAY_TYPE:
1778 case GL_NORMAL_ARRAY_TYPE:
1779 case GL_POINT_SIZE_ARRAY_TYPE_OES:
1780 case GL_TEXTURE_COORD_ARRAY_TYPE:
1781 getIntegerVertexAttribImpl(pname, GL_VERTEX_ATTRIB_ARRAY_TYPE, params);
1782 break;
1783
1784 // GL_KHR_parallel_shader_compile
1785 case GL_MAX_SHADER_COMPILER_THREADS_KHR:
1786 *params = mState.getMaxShaderCompilerThreads();
1787 break;
1788
1789 // GL_EXT_blend_func_extended
1790 case GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT:
1791 *params = mState.mExtensions.maxDualSourceDrawBuffers;
1792 break;
1793
1794 default:
1795 ANGLE_CONTEXT_TRY(mState.getIntegerv(this, pname, params));
1796 break;
1797 }
1798 }
1799
getIntegerVertexAttribImpl(GLenum pname,GLenum attribpname,GLint * params) const1800 void Context::getIntegerVertexAttribImpl(GLenum pname, GLenum attribpname, GLint *params) const
1801 {
1802 getVertexAttribivImpl(static_cast<GLuint>(vertexArrayIndex(ParamToVertexArrayType(pname))),
1803 attribpname, params);
1804 }
1805
getInteger64vImpl(GLenum pname,GLint64 * params) const1806 void Context::getInteger64vImpl(GLenum pname, GLint64 *params) const
1807 {
1808 // Queries about context capabilities and maximums are answered by Context.
1809 // Queries about current GL state values are answered by State.
1810 switch (pname)
1811 {
1812 case GL_MAX_ELEMENT_INDEX:
1813 *params = mState.mCaps.maxElementIndex;
1814 break;
1815 case GL_MAX_UNIFORM_BLOCK_SIZE:
1816 *params = mState.mCaps.maxUniformBlockSize;
1817 break;
1818 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1819 *params = mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::Vertex];
1820 break;
1821 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1822 *params = mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::Fragment];
1823 break;
1824 case GL_MAX_SERVER_WAIT_TIMEOUT:
1825 *params = mState.mCaps.maxServerWaitTimeout;
1826 break;
1827
1828 // GL_EXT_disjoint_timer_query
1829 case GL_TIMESTAMP_EXT:
1830 *params = mImplementation->getTimestamp();
1831 break;
1832
1833 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1834 *params = mState.mCaps.maxShaderStorageBlockSize;
1835 break;
1836 default:
1837 UNREACHABLE();
1838 break;
1839 }
1840 }
1841
getPointerv(GLenum pname,void ** params)1842 void Context::getPointerv(GLenum pname, void **params)
1843 {
1844 mState.getPointerv(this, pname, params);
1845 }
1846
getPointervRobustANGLERobust(GLenum pname,GLsizei bufSize,GLsizei * length,void ** params)1847 void Context::getPointervRobustANGLERobust(GLenum pname,
1848 GLsizei bufSize,
1849 GLsizei *length,
1850 void **params)
1851 {
1852 UNIMPLEMENTED();
1853 }
1854
getIntegeri_v(GLenum target,GLuint index,GLint * data)1855 void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
1856 {
1857 // Queries about context capabilities and maximums are answered by Context.
1858 // Queries about current GL state values are answered by State.
1859
1860 GLenum nativeType;
1861 unsigned int numParams;
1862 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1863 ASSERT(queryStatus);
1864
1865 if (nativeType == GL_INT)
1866 {
1867 switch (target)
1868 {
1869 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1870 ASSERT(index < 3u);
1871 *data = mState.mCaps.maxComputeWorkGroupCount[index];
1872 break;
1873 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1874 ASSERT(index < 3u);
1875 *data = mState.mCaps.maxComputeWorkGroupSize[index];
1876 break;
1877 default:
1878 mState.getIntegeri_v(target, index, data);
1879 }
1880 }
1881 else
1882 {
1883 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1884 }
1885 }
1886
getIntegeri_vRobust(GLenum target,GLuint index,GLsizei bufSize,GLsizei * length,GLint * data)1887 void Context::getIntegeri_vRobust(GLenum target,
1888 GLuint index,
1889 GLsizei bufSize,
1890 GLsizei *length,
1891 GLint *data)
1892 {
1893 getIntegeri_v(target, index, data);
1894 }
1895
getInteger64i_v(GLenum target,GLuint index,GLint64 * data)1896 void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
1897 {
1898 // Queries about context capabilities and maximums are answered by Context.
1899 // Queries about current GL state values are answered by State.
1900
1901 GLenum nativeType;
1902 unsigned int numParams;
1903 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1904 ASSERT(queryStatus);
1905
1906 if (nativeType == GL_INT_64_ANGLEX)
1907 {
1908 mState.getInteger64i_v(target, index, data);
1909 }
1910 else
1911 {
1912 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1913 }
1914 }
1915
getInteger64i_vRobust(GLenum target,GLuint index,GLsizei bufSize,GLsizei * length,GLint64 * data)1916 void Context::getInteger64i_vRobust(GLenum target,
1917 GLuint index,
1918 GLsizei bufSize,
1919 GLsizei *length,
1920 GLint64 *data)
1921 {
1922 getInteger64i_v(target, index, data);
1923 }
1924
getBooleani_v(GLenum target,GLuint index,GLboolean * data)1925 void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1926 {
1927 // Queries about context capabilities and maximums are answered by Context.
1928 // Queries about current GL state values are answered by State.
1929
1930 GLenum nativeType;
1931 unsigned int numParams;
1932 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1933 ASSERT(queryStatus);
1934
1935 if (nativeType == GL_BOOL)
1936 {
1937 mState.getBooleani_v(target, index, data);
1938 }
1939 else
1940 {
1941 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1942 }
1943 }
1944
getBooleani_vRobust(GLenum target,GLuint index,GLsizei bufSize,GLsizei * length,GLboolean * data)1945 void Context::getBooleani_vRobust(GLenum target,
1946 GLuint index,
1947 GLsizei bufSize,
1948 GLsizei *length,
1949 GLboolean *data)
1950 {
1951 getBooleani_v(target, index, data);
1952 }
1953
getBufferParameteriv(BufferBinding target,GLenum pname,GLint * params)1954 void Context::getBufferParameteriv(BufferBinding target, GLenum pname, GLint *params)
1955 {
1956 Buffer *buffer = mState.getTargetBuffer(target);
1957 QueryBufferParameteriv(buffer, pname, params);
1958 }
1959
getBufferParameterivRobust(BufferBinding target,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)1960 void Context::getBufferParameterivRobust(BufferBinding target,
1961 GLenum pname,
1962 GLsizei bufSize,
1963 GLsizei *length,
1964 GLint *params)
1965 {
1966 getBufferParameteriv(target, pname, params);
1967 }
1968
getFramebufferAttachmentParameteriv(GLenum target,GLenum attachment,GLenum pname,GLint * params)1969 void Context::getFramebufferAttachmentParameteriv(GLenum target,
1970 GLenum attachment,
1971 GLenum pname,
1972 GLint *params)
1973 {
1974 const Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
1975 QueryFramebufferAttachmentParameteriv(this, framebuffer, attachment, pname, params);
1976 }
1977
getFramebufferAttachmentParameterivRobust(GLenum target,GLenum attachment,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)1978 void Context::getFramebufferAttachmentParameterivRobust(GLenum target,
1979 GLenum attachment,
1980 GLenum pname,
1981 GLsizei bufSize,
1982 GLsizei *length,
1983 GLint *params)
1984 {
1985 getFramebufferAttachmentParameteriv(target, attachment, pname, params);
1986 }
1987
getRenderbufferParameteriv(GLenum target,GLenum pname,GLint * params)1988 void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1989 {
1990 Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer();
1991 QueryRenderbufferiv(this, renderbuffer, pname, params);
1992 }
1993
getRenderbufferParameterivRobust(GLenum target,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)1994 void Context::getRenderbufferParameterivRobust(GLenum target,
1995 GLenum pname,
1996 GLsizei bufSize,
1997 GLsizei *length,
1998 GLint *params)
1999 {
2000 getRenderbufferParameteriv(target, pname, params);
2001 }
2002
texBuffer(GLenum target,GLenum internalformat,BufferID buffer)2003 void Context::texBuffer(GLenum target, GLenum internalformat, BufferID buffer)
2004 {
2005 UNIMPLEMENTED();
2006 }
2007
texBufferRange(GLenum target,GLenum internalformat,BufferID buffer,GLintptr offset,GLsizeiptr size)2008 void Context::texBufferRange(GLenum target,
2009 GLenum internalformat,
2010 BufferID buffer,
2011 GLintptr offset,
2012 GLsizeiptr size)
2013 {
2014 UNIMPLEMENTED();
2015 }
2016
getTexParameterfv(TextureType target,GLenum pname,GLfloat * params)2017 void Context::getTexParameterfv(TextureType target, GLenum pname, GLfloat *params)
2018 {
2019 const Texture *const texture = getTextureByType(target);
2020 QueryTexParameterfv(this, texture, pname, params);
2021 }
2022
getTexParameterfvRobust(TextureType target,GLenum pname,GLsizei bufSize,GLsizei * length,GLfloat * params)2023 void Context::getTexParameterfvRobust(TextureType target,
2024 GLenum pname,
2025 GLsizei bufSize,
2026 GLsizei *length,
2027 GLfloat *params)
2028 {
2029 getTexParameterfv(target, pname, params);
2030 }
2031
getTexParameteriv(TextureType target,GLenum pname,GLint * params)2032 void Context::getTexParameteriv(TextureType target, GLenum pname, GLint *params)
2033 {
2034 const Texture *const texture = getTextureByType(target);
2035 QueryTexParameteriv(this, texture, pname, params);
2036 }
2037
getTexParameterIiv(TextureType target,GLenum pname,GLint * params)2038 void Context::getTexParameterIiv(TextureType target, GLenum pname, GLint *params)
2039 {
2040 const Texture *const texture = getTextureByType(target);
2041 QueryTexParameterIiv(this, texture, pname, params);
2042 }
2043
getTexParameterIuiv(TextureType target,GLenum pname,GLuint * params)2044 void Context::getTexParameterIuiv(TextureType target, GLenum pname, GLuint *params)
2045 {
2046 const Texture *const texture = getTextureByType(target);
2047 QueryTexParameterIuiv(this, texture, pname, params);
2048 }
2049
getTexParameterivRobust(TextureType target,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)2050 void Context::getTexParameterivRobust(TextureType target,
2051 GLenum pname,
2052 GLsizei bufSize,
2053 GLsizei *length,
2054 GLint *params)
2055 {
2056 getTexParameteriv(target, pname, params);
2057 }
2058
getTexParameterIivRobust(TextureType target,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)2059 void Context::getTexParameterIivRobust(TextureType target,
2060 GLenum pname,
2061 GLsizei bufSize,
2062 GLsizei *length,
2063 GLint *params)
2064 {
2065 UNIMPLEMENTED();
2066 }
2067
getTexParameterIuivRobust(TextureType target,GLenum pname,GLsizei bufSize,GLsizei * length,GLuint * params)2068 void Context::getTexParameterIuivRobust(TextureType target,
2069 GLenum pname,
2070 GLsizei bufSize,
2071 GLsizei *length,
2072 GLuint *params)
2073 {
2074 UNIMPLEMENTED();
2075 }
2076
getTexLevelParameteriv(TextureTarget target,GLint level,GLenum pname,GLint * params)2077 void Context::getTexLevelParameteriv(TextureTarget target, GLint level, GLenum pname, GLint *params)
2078 {
2079 Texture *texture = getTextureByTarget(target);
2080 QueryTexLevelParameteriv(texture, target, level, pname, params);
2081 }
2082
getTexLevelParameterivRobust(TextureTarget target,GLint level,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)2083 void Context::getTexLevelParameterivRobust(TextureTarget target,
2084 GLint level,
2085 GLenum pname,
2086 GLsizei bufSize,
2087 GLsizei *length,
2088 GLint *params)
2089 {
2090 UNIMPLEMENTED();
2091 }
2092
getTexLevelParameterfv(TextureTarget target,GLint level,GLenum pname,GLfloat * params)2093 void Context::getTexLevelParameterfv(TextureTarget target,
2094 GLint level,
2095 GLenum pname,
2096 GLfloat *params)
2097 {
2098 Texture *texture = getTextureByTarget(target);
2099 QueryTexLevelParameterfv(texture, target, level, pname, params);
2100 }
2101
getTexLevelParameterfvRobust(TextureTarget target,GLint level,GLenum pname,GLsizei bufSize,GLsizei * length,GLfloat * params)2102 void Context::getTexLevelParameterfvRobust(TextureTarget target,
2103 GLint level,
2104 GLenum pname,
2105 GLsizei bufSize,
2106 GLsizei *length,
2107 GLfloat *params)
2108 {
2109 UNIMPLEMENTED();
2110 }
2111
texParameterf(TextureType target,GLenum pname,GLfloat param)2112 void Context::texParameterf(TextureType target, GLenum pname, GLfloat param)
2113 {
2114 Texture *const texture = getTextureByType(target);
2115 SetTexParameterf(this, texture, pname, param);
2116 }
2117
texParameterfv(TextureType target,GLenum pname,const GLfloat * params)2118 void Context::texParameterfv(TextureType target, GLenum pname, const GLfloat *params)
2119 {
2120 Texture *const texture = getTextureByType(target);
2121 SetTexParameterfv(this, texture, pname, params);
2122 }
2123
texParameterfvRobust(TextureType target,GLenum pname,GLsizei bufSize,const GLfloat * params)2124 void Context::texParameterfvRobust(TextureType target,
2125 GLenum pname,
2126 GLsizei bufSize,
2127 const GLfloat *params)
2128 {
2129 texParameterfv(target, pname, params);
2130 }
2131
texParameteri(TextureType target,GLenum pname,GLint param)2132 void Context::texParameteri(TextureType target, GLenum pname, GLint param)
2133 {
2134 Texture *const texture = getTextureByType(target);
2135 SetTexParameteri(this, texture, pname, param);
2136 }
2137
texParameteriv(TextureType target,GLenum pname,const GLint * params)2138 void Context::texParameteriv(TextureType target, GLenum pname, const GLint *params)
2139 {
2140 Texture *const texture = getTextureByType(target);
2141 SetTexParameteriv(this, texture, pname, params);
2142 }
2143
texParameterIiv(TextureType target,GLenum pname,const GLint * params)2144 void Context::texParameterIiv(TextureType target, GLenum pname, const GLint *params)
2145 {
2146 Texture *const texture = getTextureByType(target);
2147 SetTexParameterIiv(this, texture, pname, params);
2148 }
2149
texParameterIuiv(TextureType target,GLenum pname,const GLuint * params)2150 void Context::texParameterIuiv(TextureType target, GLenum pname, const GLuint *params)
2151 {
2152 Texture *const texture = getTextureByType(target);
2153 SetTexParameterIuiv(this, texture, pname, params);
2154 }
2155
texParameterivRobust(TextureType target,GLenum pname,GLsizei bufSize,const GLint * params)2156 void Context::texParameterivRobust(TextureType target,
2157 GLenum pname,
2158 GLsizei bufSize,
2159 const GLint *params)
2160 {
2161 texParameteriv(target, pname, params);
2162 }
2163
texParameterIivRobust(TextureType target,GLenum pname,GLsizei bufSize,const GLint * params)2164 void Context::texParameterIivRobust(TextureType target,
2165 GLenum pname,
2166 GLsizei bufSize,
2167 const GLint *params)
2168 {
2169 UNIMPLEMENTED();
2170 }
2171
texParameterIuivRobust(TextureType target,GLenum pname,GLsizei bufSize,const GLuint * params)2172 void Context::texParameterIuivRobust(TextureType target,
2173 GLenum pname,
2174 GLsizei bufSize,
2175 const GLuint *params)
2176 {
2177 UNIMPLEMENTED();
2178 }
2179
drawArraysInstanced(PrimitiveMode mode,GLint first,GLsizei count,GLsizei instanceCount)2180 void Context::drawArraysInstanced(PrimitiveMode mode,
2181 GLint first,
2182 GLsizei count,
2183 GLsizei instanceCount)
2184 {
2185 // No-op if count draws no primitives for given mode
2186 if (noopDrawInstanced(mode, count, instanceCount))
2187 {
2188 return;
2189 }
2190
2191 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
2192 ANGLE_CONTEXT_TRY(
2193 mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
2194 MarkTransformFeedbackBufferUsage(this, count, instanceCount);
2195 MarkShaderStorageBufferUsage(this);
2196 }
2197
drawElementsInstanced(PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLsizei instances)2198 void Context::drawElementsInstanced(PrimitiveMode mode,
2199 GLsizei count,
2200 DrawElementsType type,
2201 const void *indices,
2202 GLsizei instances)
2203 {
2204 // No-op if count draws no primitives for given mode
2205 if (noopDrawInstanced(mode, count, instances))
2206 {
2207 return;
2208 }
2209
2210 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
2211 ANGLE_CONTEXT_TRY(
2212 mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances));
2213 MarkShaderStorageBufferUsage(this);
2214 }
2215
drawElementsBaseVertex(PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLint basevertex)2216 void Context::drawElementsBaseVertex(PrimitiveMode mode,
2217 GLsizei count,
2218 DrawElementsType type,
2219 const void *indices,
2220 GLint basevertex)
2221 {
2222 // No-op if count draws no primitives for given mode
2223 if (noopDraw(mode, count))
2224 {
2225 return;
2226 }
2227
2228 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
2229 ANGLE_CONTEXT_TRY(
2230 mImplementation->drawElementsBaseVertex(this, mode, count, type, indices, basevertex));
2231 MarkShaderStorageBufferUsage(this);
2232 }
2233
drawElementsInstancedBaseVertex(PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLsizei instancecount,GLint basevertex)2234 void Context::drawElementsInstancedBaseVertex(PrimitiveMode mode,
2235 GLsizei count,
2236 DrawElementsType type,
2237 const void *indices,
2238 GLsizei instancecount,
2239 GLint basevertex)
2240 {
2241 // No-op if count draws no primitives for given mode
2242 if (noopDrawInstanced(mode, count, instancecount))
2243 {
2244 return;
2245 }
2246
2247 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
2248 ANGLE_CONTEXT_TRY(mImplementation->drawElementsInstancedBaseVertex(
2249 this, mode, count, type, indices, instancecount, basevertex));
2250 MarkShaderStorageBufferUsage(this);
2251 }
2252
drawRangeElements(PrimitiveMode mode,GLuint start,GLuint end,GLsizei count,DrawElementsType type,const void * indices)2253 void Context::drawRangeElements(PrimitiveMode mode,
2254 GLuint start,
2255 GLuint end,
2256 GLsizei count,
2257 DrawElementsType type,
2258 const void *indices)
2259 {
2260 // No-op if count draws no primitives for given mode
2261 if (noopDraw(mode, count))
2262 {
2263 return;
2264 }
2265
2266 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
2267 ANGLE_CONTEXT_TRY(
2268 mImplementation->drawRangeElements(this, mode, start, end, count, type, indices));
2269 MarkShaderStorageBufferUsage(this);
2270 }
2271
drawRangeElementsBaseVertex(PrimitiveMode mode,GLuint start,GLuint end,GLsizei count,DrawElementsType type,const void * indices,GLint basevertex)2272 void Context::drawRangeElementsBaseVertex(PrimitiveMode mode,
2273 GLuint start,
2274 GLuint end,
2275 GLsizei count,
2276 DrawElementsType type,
2277 const void *indices,
2278 GLint basevertex)
2279 {
2280 // No-op if count draws no primitives for given mode
2281 if (noopDraw(mode, count))
2282 {
2283 return;
2284 }
2285
2286 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
2287 ANGLE_CONTEXT_TRY(mImplementation->drawRangeElementsBaseVertex(this, mode, start, end, count,
2288 type, indices, basevertex));
2289 MarkShaderStorageBufferUsage(this);
2290 }
2291
drawArraysIndirect(PrimitiveMode mode,const void * indirect)2292 void Context::drawArraysIndirect(PrimitiveMode mode, const void *indirect)
2293 {
2294 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
2295 ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect));
2296 MarkShaderStorageBufferUsage(this);
2297 }
2298
drawElementsIndirect(PrimitiveMode mode,DrawElementsType type,const void * indirect)2299 void Context::drawElementsIndirect(PrimitiveMode mode, DrawElementsType type, const void *indirect)
2300 {
2301 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
2302 ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect));
2303 MarkShaderStorageBufferUsage(this);
2304 }
2305
flush()2306 void Context::flush()
2307 {
2308 ANGLE_CONTEXT_TRY(mImplementation->flush(this));
2309 }
2310
finish()2311 void Context::finish()
2312 {
2313 ANGLE_CONTEXT_TRY(mImplementation->finish(this));
2314 }
2315
insertEventMarker(GLsizei length,const char * marker)2316 void Context::insertEventMarker(GLsizei length, const char *marker)
2317 {
2318 ASSERT(mImplementation);
2319 ANGLE_CONTEXT_TRY(mImplementation->insertEventMarker(length, marker));
2320 }
2321
pushGroupMarker(GLsizei length,const char * marker)2322 void Context::pushGroupMarker(GLsizei length, const char *marker)
2323 {
2324 ASSERT(mImplementation);
2325
2326 if (marker == nullptr)
2327 {
2328 // From the EXT_debug_marker spec,
2329 // "If <marker> is null then an empty string is pushed on the stack."
2330 ANGLE_CONTEXT_TRY(mImplementation->pushGroupMarker(length, ""));
2331 }
2332 else
2333 {
2334 ANGLE_CONTEXT_TRY(mImplementation->pushGroupMarker(length, marker));
2335 }
2336 }
2337
popGroupMarker()2338 void Context::popGroupMarker()
2339 {
2340 ASSERT(mImplementation);
2341 ANGLE_CONTEXT_TRY(mImplementation->popGroupMarker());
2342 }
2343
bindUniformLocation(ShaderProgramID program,UniformLocation location,const GLchar * name)2344 void Context::bindUniformLocation(ShaderProgramID program,
2345 UniformLocation location,
2346 const GLchar *name)
2347 {
2348 Program *programObject = getProgramResolveLink(program);
2349 ASSERT(programObject);
2350
2351 programObject->bindUniformLocation(location, name);
2352 }
2353
coverageModulation(GLenum components)2354 void Context::coverageModulation(GLenum components)
2355 {
2356 mState.setCoverageModulation(components);
2357 }
2358
getProgramResourceIndex(ShaderProgramID program,GLenum programInterface,const GLchar * name)2359 GLuint Context::getProgramResourceIndex(ShaderProgramID program,
2360 GLenum programInterface,
2361 const GLchar *name)
2362 {
2363 const Program *programObject = getProgramResolveLink(program);
2364 return QueryProgramResourceIndex(programObject, programInterface, name);
2365 }
2366
getProgramResourceName(ShaderProgramID program,GLenum programInterface,GLuint index,GLsizei bufSize,GLsizei * length,GLchar * name)2367 void Context::getProgramResourceName(ShaderProgramID program,
2368 GLenum programInterface,
2369 GLuint index,
2370 GLsizei bufSize,
2371 GLsizei *length,
2372 GLchar *name)
2373 {
2374 const Program *programObject = getProgramResolveLink(program);
2375 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2376 }
2377
getProgramResourceLocation(ShaderProgramID program,GLenum programInterface,const GLchar * name)2378 GLint Context::getProgramResourceLocation(ShaderProgramID program,
2379 GLenum programInterface,
2380 const GLchar *name)
2381 {
2382 const Program *programObject = getProgramResolveLink(program);
2383 return QueryProgramResourceLocation(programObject, programInterface, name);
2384 }
2385
getProgramResourceiv(ShaderProgramID program,GLenum programInterface,GLuint index,GLsizei propCount,const GLenum * props,GLsizei bufSize,GLsizei * length,GLint * params)2386 void Context::getProgramResourceiv(ShaderProgramID program,
2387 GLenum programInterface,
2388 GLuint index,
2389 GLsizei propCount,
2390 const GLenum *props,
2391 GLsizei bufSize,
2392 GLsizei *length,
2393 GLint *params)
2394 {
2395 const Program *programObject = getProgramResolveLink(program);
2396 QueryProgramResourceiv(programObject, programInterface, index, propCount, props, bufSize,
2397 length, params);
2398 }
2399
getProgramInterfaceiv(ShaderProgramID program,GLenum programInterface,GLenum pname,GLint * params)2400 void Context::getProgramInterfaceiv(ShaderProgramID program,
2401 GLenum programInterface,
2402 GLenum pname,
2403 GLint *params)
2404 {
2405 const Program *programObject = getProgramResolveLink(program);
2406 QueryProgramInterfaceiv(programObject, programInterface, pname, params);
2407 }
2408
getProgramInterfaceivRobust(ShaderProgramID program,GLenum programInterface,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)2409 void Context::getProgramInterfaceivRobust(ShaderProgramID program,
2410 GLenum programInterface,
2411 GLenum pname,
2412 GLsizei bufSize,
2413 GLsizei *length,
2414 GLint *params)
2415 {
2416 UNIMPLEMENTED();
2417 }
2418
handleError(GLenum errorCode,const char * message,const char * file,const char * function,unsigned int line)2419 void Context::handleError(GLenum errorCode,
2420 const char *message,
2421 const char *file,
2422 const char *function,
2423 unsigned int line)
2424 {
2425 mErrors.handleError(errorCode, message, file, function, line);
2426 }
2427
validationError(GLenum errorCode,const char * message) const2428 void Context::validationError(GLenum errorCode, const char *message) const
2429 {
2430 const_cast<Context *>(this)->mErrors.validationError(errorCode, message);
2431 }
2432
2433 // Get one of the recorded errors and clear its flag, if any.
2434 // [OpenGL ES 2.0.24] section 2.5 page 13.
getError()2435 GLenum Context::getError()
2436 {
2437 if (mErrors.empty())
2438 {
2439 return GL_NO_ERROR;
2440 }
2441 else
2442 {
2443 return mErrors.popError();
2444 }
2445 }
2446
2447 // NOTE: this function should not assume that this context is current!
markContextLost(GraphicsResetStatus status)2448 void Context::markContextLost(GraphicsResetStatus status)
2449 {
2450 ASSERT(status != GraphicsResetStatus::NoError);
2451 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
2452 {
2453 mResetStatus = status;
2454 mContextLostForced = true;
2455 }
2456 setContextLost();
2457 }
2458
setContextLost()2459 void Context::setContextLost()
2460 {
2461 mContextLost = true;
2462
2463 // Stop skipping validation, since many implementation entrypoint assume they can't
2464 // be called when lost, or with null object arguments, etc.
2465 mSkipValidation = false;
2466 }
2467
getGraphicsResetStatus()2468 GLenum Context::getGraphicsResetStatus()
2469 {
2470 // Even if the application doesn't want to know about resets, we want to know
2471 // as it will allow us to skip all the calls.
2472 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
2473 {
2474 if (!isContextLost() && mImplementation->getResetStatus() != GraphicsResetStatus::NoError)
2475 {
2476 setContextLost();
2477 }
2478
2479 // EXT_robustness, section 2.6: If the reset notification behavior is
2480 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2481 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2482 return GL_NO_ERROR;
2483 }
2484
2485 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2486 // status should be returned at least once, and GL_NO_ERROR should be returned
2487 // once the device has finished resetting.
2488 if (!isContextLost())
2489 {
2490 ASSERT(mResetStatus == GraphicsResetStatus::NoError);
2491 mResetStatus = mImplementation->getResetStatus();
2492
2493 if (mResetStatus != GraphicsResetStatus::NoError)
2494 {
2495 setContextLost();
2496 }
2497 }
2498 else if (!mContextLostForced && mResetStatus != GraphicsResetStatus::NoError)
2499 {
2500 // If markContextLost was used to mark the context lost then
2501 // assume that is not recoverable, and continue to report the
2502 // lost reset status for the lifetime of this context.
2503 mResetStatus = mImplementation->getResetStatus();
2504 }
2505
2506 return ToGLenum(mResetStatus);
2507 }
2508
isResetNotificationEnabled()2509 bool Context::isResetNotificationEnabled()
2510 {
2511 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2512 }
2513
getConfig() const2514 const egl::Config *Context::getConfig() const
2515 {
2516 return mConfig;
2517 }
2518
getClientType() const2519 EGLenum Context::getClientType() const
2520 {
2521 return mState.getClientType();
2522 }
2523
getRenderBuffer() const2524 EGLenum Context::getRenderBuffer() const
2525 {
2526 const Framebuffer *framebuffer =
2527 mState.mFramebufferManager->getFramebuffer(Framebuffer::kDefaultDrawFramebufferHandle);
2528 if (framebuffer == nullptr)
2529 {
2530 return EGL_NONE;
2531 }
2532
2533 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(this, GL_BACK);
2534 ASSERT(backAttachment != nullptr);
2535 return backAttachment->getSurface()->getRenderBuffer();
2536 }
2537
checkVertexArrayAllocation(VertexArrayID vertexArrayHandle)2538 VertexArray *Context::checkVertexArrayAllocation(VertexArrayID vertexArrayHandle)
2539 {
2540 // Only called after a prior call to Gen.
2541 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2542 if (!vertexArray)
2543 {
2544 vertexArray =
2545 new VertexArray(mImplementation.get(), vertexArrayHandle,
2546 mState.mCaps.maxVertexAttributes, mState.mCaps.maxVertexAttribBindings);
2547 vertexArray->setBufferAccessValidationEnabled(mBufferAccessValidationEnabled);
2548
2549 mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
2550 }
2551
2552 return vertexArray;
2553 }
2554
checkTransformFeedbackAllocation(TransformFeedbackID transformFeedbackHandle)2555 TransformFeedback *Context::checkTransformFeedbackAllocation(
2556 TransformFeedbackID transformFeedbackHandle)
2557 {
2558 // Only called after a prior call to Gen.
2559 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2560 if (!transformFeedback)
2561 {
2562 transformFeedback =
2563 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mState.mCaps);
2564 transformFeedback->addRef();
2565 mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
2566 }
2567
2568 return transformFeedback;
2569 }
2570
isVertexArrayGenerated(VertexArrayID vertexArray) const2571 bool Context::isVertexArrayGenerated(VertexArrayID vertexArray) const
2572 {
2573 ASSERT(mVertexArrayMap.contains({0}));
2574 return mVertexArrayMap.contains(vertexArray);
2575 }
2576
isTransformFeedbackGenerated(TransformFeedbackID transformFeedback) const2577 bool Context::isTransformFeedbackGenerated(TransformFeedbackID transformFeedback) const
2578 {
2579 ASSERT(mTransformFeedbackMap.contains({0}));
2580 return mTransformFeedbackMap.contains(transformFeedback);
2581 }
2582
detachTexture(TextureID texture)2583 void Context::detachTexture(TextureID texture)
2584 {
2585 // The State cannot unbind image observers itself, they are owned by the Context
2586 Texture *tex = mState.mTextureManager->getTexture(texture);
2587 for (auto &imageBinding : mImageObserverBindings)
2588 {
2589 if (imageBinding.getSubject() == tex)
2590 {
2591 imageBinding.reset();
2592 }
2593 }
2594
2595 // Simple pass-through to State's detachTexture method, as textures do not require
2596 // allocation map management either here or in the resource manager at detach time.
2597 // Zero textures are held by the Context, and we don't attempt to request them from
2598 // the State.
2599 mState.detachTexture(this, mZeroTextures, texture);
2600 }
2601
detachBuffer(Buffer * buffer)2602 void Context::detachBuffer(Buffer *buffer)
2603 {
2604 // Simple pass-through to State's detachBuffer method, since
2605 // only buffer attachments to container objects that are bound to the current context
2606 // should be detached. And all those are available in State.
2607
2608 // [OpenGL ES 3.2] section 5.1.2 page 45:
2609 // Attachments to unbound container objects, such as
2610 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2611 // are not affected and continue to act as references on the deleted object
2612 ANGLE_CONTEXT_TRY(mState.detachBuffer(this, buffer));
2613 }
2614
detachFramebuffer(FramebufferID framebuffer)2615 void Context::detachFramebuffer(FramebufferID framebuffer)
2616 {
2617 // Framebuffer detachment is handled by Context, because 0 is a valid
2618 // Framebuffer object, and a pointer to it must be passed from Context
2619 // to State at binding time.
2620
2621 // [OpenGL ES 2.0.24] section 4.4 page 107:
2622 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2623 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2624 // zero.
2625
2626 if (mState.removeReadFramebufferBinding(framebuffer) && framebuffer.value != 0)
2627 {
2628 bindReadFramebuffer({0});
2629 }
2630
2631 if (mState.removeDrawFramebufferBinding(framebuffer) && framebuffer.value != 0)
2632 {
2633 bindDrawFramebuffer({0});
2634 }
2635 }
2636
detachRenderbuffer(RenderbufferID renderbuffer)2637 void Context::detachRenderbuffer(RenderbufferID renderbuffer)
2638 {
2639 mState.detachRenderbuffer(this, renderbuffer);
2640 }
2641
detachVertexArray(VertexArrayID vertexArray)2642 void Context::detachVertexArray(VertexArrayID vertexArray)
2643 {
2644 // Vertex array detachment is handled by Context, because 0 is a valid
2645 // VAO, and a pointer to it must be passed from Context to State at
2646 // binding time.
2647
2648 // [OpenGL ES 3.0.2] section 2.10 page 43:
2649 // If a vertex array object that is currently bound is deleted, the binding
2650 // for that object reverts to zero and the default vertex array becomes current.
2651 if (mState.removeVertexArrayBinding(this, vertexArray))
2652 {
2653 bindVertexArray({0});
2654 }
2655 }
2656
detachTransformFeedback(TransformFeedbackID transformFeedback)2657 void Context::detachTransformFeedback(TransformFeedbackID transformFeedback)
2658 {
2659 // Transform feedback detachment is handled by Context, because 0 is a valid
2660 // transform feedback, and a pointer to it must be passed from Context to State at
2661 // binding time.
2662
2663 // The OpenGL specification doesn't mention what should happen when the currently bound
2664 // transform feedback object is deleted. Since it is a container object, we treat it like
2665 // VAOs and FBOs and set the current bound transform feedback back to 0.
2666 if (mState.removeTransformFeedbackBinding(this, transformFeedback))
2667 {
2668 bindTransformFeedback(GL_TRANSFORM_FEEDBACK, {0});
2669 }
2670 }
2671
detachSampler(SamplerID sampler)2672 void Context::detachSampler(SamplerID sampler)
2673 {
2674 mState.detachSampler(this, sampler);
2675 }
2676
detachProgramPipeline(ProgramPipelineID pipeline)2677 void Context::detachProgramPipeline(ProgramPipelineID pipeline)
2678 {
2679 mState.detachProgramPipeline(this, pipeline);
2680 }
2681
vertexAttribDivisor(GLuint index,GLuint divisor)2682 void Context::vertexAttribDivisor(GLuint index, GLuint divisor)
2683 {
2684 mState.setVertexAttribDivisor(this, index, divisor);
2685 mStateCache.onVertexArrayStateChange(this);
2686 }
2687
samplerParameteri(SamplerID sampler,GLenum pname,GLint param)2688 void Context::samplerParameteri(SamplerID sampler, GLenum pname, GLint param)
2689 {
2690 Sampler *const samplerObject =
2691 mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
2692 SetSamplerParameteri(this, samplerObject, pname, param);
2693 }
2694
samplerParameteriv(SamplerID sampler,GLenum pname,const GLint * param)2695 void Context::samplerParameteriv(SamplerID sampler, GLenum pname, const GLint *param)
2696 {
2697 Sampler *const samplerObject =
2698 mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
2699 SetSamplerParameteriv(this, samplerObject, pname, param);
2700 }
2701
samplerParameterIiv(SamplerID sampler,GLenum pname,const GLint * param)2702 void Context::samplerParameterIiv(SamplerID sampler, GLenum pname, const GLint *param)
2703 {
2704 Sampler *const samplerObject =
2705 mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
2706 SetSamplerParameterIiv(this, samplerObject, pname, param);
2707 }
2708
samplerParameterIuiv(SamplerID sampler,GLenum pname,const GLuint * param)2709 void Context::samplerParameterIuiv(SamplerID sampler, GLenum pname, const GLuint *param)
2710 {
2711 Sampler *const samplerObject =
2712 mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
2713 SetSamplerParameterIuiv(this, samplerObject, pname, param);
2714 }
2715
samplerParameterivRobust(SamplerID sampler,GLenum pname,GLsizei bufSize,const GLint * param)2716 void Context::samplerParameterivRobust(SamplerID sampler,
2717 GLenum pname,
2718 GLsizei bufSize,
2719 const GLint *param)
2720 {
2721 samplerParameteriv(sampler, pname, param);
2722 }
2723
samplerParameterIivRobust(SamplerID sampler,GLenum pname,GLsizei bufSize,const GLint * param)2724 void Context::samplerParameterIivRobust(SamplerID sampler,
2725 GLenum pname,
2726 GLsizei bufSize,
2727 const GLint *param)
2728 {
2729 UNIMPLEMENTED();
2730 }
2731
samplerParameterIuivRobust(SamplerID sampler,GLenum pname,GLsizei bufSize,const GLuint * param)2732 void Context::samplerParameterIuivRobust(SamplerID sampler,
2733 GLenum pname,
2734 GLsizei bufSize,
2735 const GLuint *param)
2736 {
2737 UNIMPLEMENTED();
2738 }
2739
samplerParameterf(SamplerID sampler,GLenum pname,GLfloat param)2740 void Context::samplerParameterf(SamplerID sampler, GLenum pname, GLfloat param)
2741 {
2742 Sampler *const samplerObject =
2743 mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
2744 SetSamplerParameterf(this, samplerObject, pname, param);
2745 }
2746
samplerParameterfv(SamplerID sampler,GLenum pname,const GLfloat * param)2747 void Context::samplerParameterfv(SamplerID sampler, GLenum pname, const GLfloat *param)
2748 {
2749 Sampler *const samplerObject =
2750 mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
2751 SetSamplerParameterfv(this, samplerObject, pname, param);
2752 }
2753
samplerParameterfvRobust(SamplerID sampler,GLenum pname,GLsizei bufSize,const GLfloat * param)2754 void Context::samplerParameterfvRobust(SamplerID sampler,
2755 GLenum pname,
2756 GLsizei bufSize,
2757 const GLfloat *param)
2758 {
2759 samplerParameterfv(sampler, pname, param);
2760 }
2761
getSamplerParameteriv(SamplerID sampler,GLenum pname,GLint * params)2762 void Context::getSamplerParameteriv(SamplerID sampler, GLenum pname, GLint *params)
2763 {
2764 const Sampler *const samplerObject =
2765 mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
2766 QuerySamplerParameteriv(samplerObject, pname, params);
2767 }
2768
getSamplerParameterIiv(SamplerID sampler,GLenum pname,GLint * params)2769 void Context::getSamplerParameterIiv(SamplerID sampler, GLenum pname, GLint *params)
2770 {
2771 const Sampler *const samplerObject =
2772 mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
2773 QuerySamplerParameterIiv(samplerObject, pname, params);
2774 }
2775
getSamplerParameterIuiv(SamplerID sampler,GLenum pname,GLuint * params)2776 void Context::getSamplerParameterIuiv(SamplerID sampler, GLenum pname, GLuint *params)
2777 {
2778 const Sampler *const samplerObject =
2779 mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
2780 QuerySamplerParameterIuiv(samplerObject, pname, params);
2781 }
2782
getSamplerParameterivRobust(SamplerID sampler,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)2783 void Context::getSamplerParameterivRobust(SamplerID sampler,
2784 GLenum pname,
2785 GLsizei bufSize,
2786 GLsizei *length,
2787 GLint *params)
2788 {
2789 getSamplerParameteriv(sampler, pname, params);
2790 }
2791
getSamplerParameterIivRobust(SamplerID sampler,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)2792 void Context::getSamplerParameterIivRobust(SamplerID sampler,
2793 GLenum pname,
2794 GLsizei bufSize,
2795 GLsizei *length,
2796 GLint *params)
2797 {
2798 UNIMPLEMENTED();
2799 }
2800
getSamplerParameterIuivRobust(SamplerID sampler,GLenum pname,GLsizei bufSize,GLsizei * length,GLuint * params)2801 void Context::getSamplerParameterIuivRobust(SamplerID sampler,
2802 GLenum pname,
2803 GLsizei bufSize,
2804 GLsizei *length,
2805 GLuint *params)
2806 {
2807 UNIMPLEMENTED();
2808 }
2809
getSamplerParameterfv(SamplerID sampler,GLenum pname,GLfloat * params)2810 void Context::getSamplerParameterfv(SamplerID sampler, GLenum pname, GLfloat *params)
2811 {
2812 const Sampler *const samplerObject =
2813 mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
2814 QuerySamplerParameterfv(samplerObject, pname, params);
2815 }
2816
getSamplerParameterfvRobust(SamplerID sampler,GLenum pname,GLsizei bufSize,GLsizei * length,GLfloat * params)2817 void Context::getSamplerParameterfvRobust(SamplerID sampler,
2818 GLenum pname,
2819 GLsizei bufSize,
2820 GLsizei *length,
2821 GLfloat *params)
2822 {
2823 getSamplerParameterfv(sampler, pname, params);
2824 }
2825
programParameteri(ShaderProgramID program,GLenum pname,GLint value)2826 void Context::programParameteri(ShaderProgramID program, GLenum pname, GLint value)
2827 {
2828 gl::Program *programObject = getProgramResolveLink(program);
2829 SetProgramParameteri(programObject, pname, value);
2830 }
2831
initRendererString()2832 void Context::initRendererString()
2833 {
2834 std::ostringstream rendererString;
2835 rendererString << "ANGLE (";
2836 rendererString << mImplementation->getRendererDescription();
2837 rendererString << ")";
2838
2839 mRendererString = MakeStaticString(rendererString.str());
2840 }
2841
initVersionStrings()2842 void Context::initVersionStrings()
2843 {
2844 const Version &clientVersion = getClientVersion();
2845
2846 std::ostringstream versionString;
2847 if (getClientType() == EGL_OPENGL_ES_API)
2848 {
2849 versionString << "OpenGL ES ";
2850 }
2851 versionString << clientVersion.major << "." << clientVersion.minor << ".0 (ANGLE "
2852 << ANGLE_VERSION_STRING << ")";
2853 mVersionString = MakeStaticString(versionString.str());
2854
2855 std::ostringstream shadingLanguageVersionString;
2856 if (getClientType() == EGL_OPENGL_ES_API)
2857 {
2858 shadingLanguageVersionString << "OpenGL ES GLSL ES ";
2859 }
2860 else
2861 {
2862 ASSERT(getClientType() == EGL_OPENGL_API);
2863 shadingLanguageVersionString << "OpenGL GLSL ";
2864 }
2865 shadingLanguageVersionString << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2866 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2867 << ")";
2868 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
2869 }
2870
initExtensionStrings()2871 void Context::initExtensionStrings()
2872 {
2873 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2874 std::ostringstream combinedStringStream;
2875 std::copy(strings.begin(), strings.end(),
2876 std::ostream_iterator<const char *>(combinedStringStream, " "));
2877 return MakeStaticString(combinedStringStream.str());
2878 };
2879
2880 mExtensionStrings.clear();
2881 for (const auto &extensionString : mState.mExtensions.getStrings())
2882 {
2883 mExtensionStrings.push_back(MakeStaticString(extensionString));
2884 }
2885 mExtensionString = mergeExtensionStrings(mExtensionStrings);
2886
2887 mRequestableExtensionStrings.clear();
2888 for (const auto &extensionInfo : GetExtensionInfoMap())
2889 {
2890 if (extensionInfo.second.Requestable &&
2891 !(mState.mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2892 mSupportedExtensions.*(extensionInfo.second.ExtensionsMember))
2893 {
2894 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2895 }
2896 }
2897 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
2898 }
2899
getString(GLenum name)2900 const GLubyte *Context::getString(GLenum name)
2901 {
2902 return static_cast<const Context *>(this)->getString(name);
2903 }
2904
getStringi(GLenum name,GLuint index)2905 const GLubyte *Context::getStringi(GLenum name, GLuint index)
2906 {
2907 return static_cast<const Context *>(this)->getStringi(name, index);
2908 }
2909
getString(GLenum name) const2910 const GLubyte *Context::getString(GLenum name) const
2911 {
2912 switch (name)
2913 {
2914 case GL_VENDOR:
2915 return reinterpret_cast<const GLubyte *>("Google Inc.");
2916
2917 case GL_RENDERER:
2918 return reinterpret_cast<const GLubyte *>(mRendererString);
2919
2920 case GL_VERSION:
2921 return reinterpret_cast<const GLubyte *>(mVersionString);
2922
2923 case GL_SHADING_LANGUAGE_VERSION:
2924 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2925
2926 case GL_EXTENSIONS:
2927 return reinterpret_cast<const GLubyte *>(mExtensionString);
2928
2929 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2930 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2931
2932 default:
2933 UNREACHABLE();
2934 return nullptr;
2935 }
2936 }
2937
getStringi(GLenum name,GLuint index) const2938 const GLubyte *Context::getStringi(GLenum name, GLuint index) const
2939 {
2940 switch (name)
2941 {
2942 case GL_EXTENSIONS:
2943 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2944
2945 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2946 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2947
2948 default:
2949 UNREACHABLE();
2950 return nullptr;
2951 }
2952 }
2953
getExtensionStringCount() const2954 size_t Context::getExtensionStringCount() const
2955 {
2956 return mExtensionStrings.size();
2957 }
2958
isExtensionRequestable(const char * name) const2959 bool Context::isExtensionRequestable(const char *name) const
2960 {
2961 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2962 auto extension = extensionInfos.find(name);
2963
2964 return extension != extensionInfos.end() && extension->second.Requestable &&
2965 mSupportedExtensions.*(extension->second.ExtensionsMember);
2966 }
2967
isExtensionDisablable(const char * name) const2968 bool Context::isExtensionDisablable(const char *name) const
2969 {
2970 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2971 auto extension = extensionInfos.find(name);
2972
2973 return extension != extensionInfos.end() && extension->second.Disablable &&
2974 mSupportedExtensions.*(extension->second.ExtensionsMember);
2975 }
2976
requestExtension(const char * name)2977 void Context::requestExtension(const char *name)
2978 {
2979 setExtensionEnabled(name, true);
2980 }
disableExtension(const char * name)2981 void Context::disableExtension(const char *name)
2982 {
2983 setExtensionEnabled(name, false);
2984 }
2985
setExtensionEnabled(const char * name,bool enabled)2986 void Context::setExtensionEnabled(const char *name, bool enabled)
2987 {
2988 // OVR_multiview is implicitly enabled when OVR_multiview2 is enabled
2989 if (strcmp(name, "GL_OVR_multiview2") == 0)
2990 {
2991 setExtensionEnabled("GL_OVR_multiview", enabled);
2992 }
2993 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2994 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2995 const auto &extension = extensionInfos.at(name);
2996 ASSERT(extension.Requestable);
2997 ASSERT(isExtensionRequestable(name));
2998
2999 if (mState.mExtensions.*(extension.ExtensionsMember) == enabled)
3000 {
3001 // No change
3002 return;
3003 }
3004
3005 mState.mExtensions.*(extension.ExtensionsMember) = enabled;
3006
3007 reinitializeAfterExtensionsChanged();
3008 }
3009
reinitializeAfterExtensionsChanged()3010 void Context::reinitializeAfterExtensionsChanged()
3011 {
3012 updateCaps();
3013 initExtensionStrings();
3014
3015 // Release the shader compiler so it will be re-created with the requested extensions enabled.
3016 releaseShaderCompiler();
3017
3018 // Invalidate all textures and framebuffer. Some extensions make new formats renderable or
3019 // sampleable.
3020 mState.mTextureManager->signalAllTexturesDirty();
3021 for (auto &zeroTexture : mZeroTextures)
3022 {
3023 if (zeroTexture.get() != nullptr)
3024 {
3025 zeroTexture->signalDirtyStorage(InitState::Initialized);
3026 }
3027 }
3028
3029 mState.mFramebufferManager->invalidateFramebufferCompletenessCache();
3030 }
3031
getRequestableExtensionStringCount() const3032 size_t Context::getRequestableExtensionStringCount() const
3033 {
3034 return mRequestableExtensionStrings.size();
3035 }
3036
beginTransformFeedback(PrimitiveMode primitiveMode)3037 void Context::beginTransformFeedback(PrimitiveMode primitiveMode)
3038 {
3039 TransformFeedback *transformFeedback = mState.getCurrentTransformFeedback();
3040 ASSERT(transformFeedback != nullptr);
3041 ASSERT(!transformFeedback->isPaused());
3042
3043 // TODO: http://anglebug.com/3570: Handle PPOs
3044 ANGLE_CONTEXT_TRY(transformFeedback->begin(this, primitiveMode, mState.getProgram()));
3045 mStateCache.onActiveTransformFeedbackChange(this);
3046 }
3047
hasActiveTransformFeedback(ShaderProgramID program) const3048 bool Context::hasActiveTransformFeedback(ShaderProgramID program) const
3049 {
3050 for (auto pair : mTransformFeedbackMap)
3051 {
3052 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
3053 {
3054 return true;
3055 }
3056 }
3057 return false;
3058 }
3059
generateSupportedExtensions() const3060 Extensions Context::generateSupportedExtensions() const
3061 {
3062 Extensions supportedExtensions = mImplementation->getNativeExtensions();
3063
3064 // Explicitly enable GL_KHR_parallel_shader_compile
3065 supportedExtensions.parallelShaderCompile = true;
3066
3067 if (getClientVersion() < ES_2_0)
3068 {
3069 // Default extensions for GLES1
3070 supportedExtensions.pointSizeArrayOES = true;
3071 supportedExtensions.textureCubeMapOES = true;
3072 supportedExtensions.pointSpriteOES = true;
3073 supportedExtensions.drawTextureOES = true;
3074 supportedExtensions.parallelShaderCompile = false;
3075 supportedExtensions.texture3DOES = false;
3076 }
3077
3078 if (getClientVersion() < ES_3_0)
3079 {
3080 // Disable ES3+ extensions
3081 supportedExtensions.colorBufferFloat = false;
3082 supportedExtensions.eglImageExternalEssl3OES = false;
3083 supportedExtensions.textureNorm16 = false;
3084 supportedExtensions.multiview = false;
3085 supportedExtensions.multiview2 = false;
3086 supportedExtensions.maxViews = 1u;
3087 supportedExtensions.copyTexture3d = false;
3088 supportedExtensions.textureMultisample = false;
3089 supportedExtensions.drawBuffersIndexedEXT = false;
3090 supportedExtensions.drawBuffersIndexedOES = false;
3091
3092 // Requires glCompressedTexImage3D
3093 supportedExtensions.textureCompressionASTCOES = false;
3094
3095 // Don't expose GL_EXT_texture_sRGB_decode without sRGB texture support
3096 if (!supportedExtensions.sRGB)
3097 {
3098 supportedExtensions.textureSRGBDecode = false;
3099 }
3100
3101 // Don't expose GL_OES_texture_float_linear without full legacy float texture support
3102 // The renderer may report OES_texture_float_linear without OES_texture_float
3103 // This is valid in a GLES 3.0 context, but not in a GLES 2.0 context
3104 if (!(supportedExtensions.textureFloatOES && supportedExtensions.textureHalfFloat))
3105 {
3106 supportedExtensions.textureFloatLinearOES = false;
3107 supportedExtensions.textureHalfFloatLinear = false;
3108 }
3109
3110 // Because of the difference in the SNORM to FLOAT conversion formula
3111 // between GLES 2.0 and 3.0, vertex type 10_10_10_2 is disabled
3112 // when the context version is lower than 3.0
3113 supportedExtensions.vertexAttribType1010102OES = false;
3114 }
3115
3116 if (getClientVersion() < ES_3_1)
3117 {
3118 // Disable ES3.1+ extensions
3119 supportedExtensions.geometryShader = false;
3120
3121 // TODO(http://anglebug.com/2775): Multisample arrays could be supported on ES 3.0 as well
3122 // once 2D multisample texture extension is exposed there.
3123 supportedExtensions.textureStorageMultisample2DArrayOES = false;
3124 }
3125
3126 if (getClientVersion() > ES_2_0)
3127 {
3128 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
3129 // supportedExtensions.sRGB = false;
3130
3131 // If colorBufferFloat is disabled but colorBufferHalfFloat is enabled, then we will expose
3132 // some floating-point formats as color buffer targets but reject blits between fixed-point
3133 // and floating-point formats (this behavior is only enabled in colorBufferFloat, and must
3134 // be rejected if only colorBufferHalfFloat is enabled).
3135 // dEQP does not check for this, and will assume that floating-point and fixed-point formats
3136 // can be blit onto each other if the format is available.
3137 // We require colorBufferFloat to be present in order to enable colorBufferHalfFloat, so
3138 // that blitting is always allowed if the requested formats are exposed and have the correct
3139 // feature capabilities
3140 if (!supportedExtensions.colorBufferFloat)
3141 {
3142 supportedExtensions.colorBufferHalfFloat = false;
3143 }
3144
3145 // Disable support for CHROMIUM_color_buffer_float_rgb[a] in ES 3.0+, these extensions are
3146 // non-conformant in ES 3.0 and superseded by EXT_color_buffer_float.
3147 supportedExtensions.colorBufferFloatRGB = false;
3148 supportedExtensions.colorBufferFloatRGBA = false;
3149 }
3150
3151 // Some extensions are always available because they are implemented in the GL layer.
3152 supportedExtensions.bindUniformLocation = true;
3153 supportedExtensions.vertexArrayObjectOES = true;
3154 supportedExtensions.bindGeneratesResource = true;
3155 supportedExtensions.clientArrays = true;
3156 supportedExtensions.requestExtension = true;
3157 supportedExtensions.multiDraw = true;
3158
3159 // Enable the no error extension if the context was created with the flag.
3160 supportedExtensions.noError = mSkipValidation;
3161
3162 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
3163 supportedExtensions.surfacelessContextOES = mSurfacelessSupported;
3164
3165 // Explicitly enable GL_KHR_debug
3166 supportedExtensions.debug = true;
3167 supportedExtensions.maxDebugMessageLength = 1024;
3168 supportedExtensions.maxDebugLoggedMessages = 1024;
3169 supportedExtensions.maxDebugGroupStackDepth = 1024;
3170 supportedExtensions.maxLabelLength = 1024;
3171
3172 // Explicitly enable GL_ANGLE_robust_client_memory if the context supports validation.
3173 supportedExtensions.robustClientMemory = !mSkipValidation;
3174
3175 // Determine robust resource init availability from EGL.
3176 supportedExtensions.robustResourceInitialization = mState.isRobustResourceInitEnabled();
3177
3178 // mState.mExtensions.robustBufferAccessBehavior is true only if robust access is true and the
3179 // backend supports it.
3180 supportedExtensions.robustBufferAccessBehavior =
3181 mRobustAccess && supportedExtensions.robustBufferAccessBehavior;
3182
3183 // Enable the cache control query unconditionally.
3184 supportedExtensions.programCacheControl = true;
3185
3186 // Enable EGL_ANGLE_explicit_context subextensions
3187 if (mExplicitContextAvailable)
3188 {
3189 // GL_ANGLE_explicit_context_gles1
3190 supportedExtensions.explicitContextGles1 = true;
3191 // GL_ANGLE_explicit_context
3192 supportedExtensions.explicitContext = true;
3193 }
3194
3195 // If EGL_KHR_fence_sync is not enabled, don't expose GL_OES_EGL_sync.
3196 ASSERT(mDisplay);
3197 if (!mDisplay->getExtensions().fenceSync)
3198 {
3199 supportedExtensions.eglSyncOES = false;
3200 }
3201
3202 supportedExtensions.memorySize = true;
3203
3204 // GL_CHROMIUM_lose_context is implemented in the frontend
3205 supportedExtensions.loseContextCHROMIUM = true;
3206
3207 // The ASTC texture extensions have dependency requirements.
3208 if (supportedExtensions.textureCompressionASTCHDRKHR ||
3209 supportedExtensions.textureCompressionSliced3dASTCKHR)
3210 {
3211 // GL_KHR_texture_compression_astc_hdr cannot be exposed without also exposing
3212 // GL_KHR_texture_compression_astc_ldr
3213 ASSERT(supportedExtensions.textureCompressionASTCLDRKHR);
3214 }
3215
3216 if (supportedExtensions.textureCompressionASTCOES)
3217 {
3218 // GL_OES_texture_compression_astc cannot be exposed without also exposing
3219 // GL_KHR_texture_compression_astc_ldr and GL_KHR_texture_compression_astc_hdr
3220 ASSERT(supportedExtensions.textureCompressionASTCLDRKHR);
3221 ASSERT(supportedExtensions.textureCompressionASTCHDRKHR);
3222 }
3223
3224 return supportedExtensions;
3225 }
3226
initCaps()3227 void Context::initCaps()
3228 {
3229 mState.mCaps = mImplementation->getNativeCaps();
3230
3231 mSupportedExtensions = generateSupportedExtensions();
3232 mState.mExtensions = mSupportedExtensions;
3233
3234 mState.mLimitations = mImplementation->getNativeLimitations();
3235
3236 // GLES1 emulation: Initialize caps (Table 6.20 / 6.22 in the ES 1.1 spec)
3237 if (getClientType() == EGL_OPENGL_API || getClientVersion() < Version(2, 0))
3238 {
3239 mState.mCaps.maxMultitextureUnits = 4;
3240 mState.mCaps.maxClipPlanes = 6;
3241 mState.mCaps.maxLights = 8;
3242 mState.mCaps.maxModelviewMatrixStackDepth = Caps::GlobalMatrixStackDepth;
3243 mState.mCaps.maxProjectionMatrixStackDepth = Caps::GlobalMatrixStackDepth;
3244 mState.mCaps.maxTextureMatrixStackDepth = Caps::GlobalMatrixStackDepth;
3245 mState.mCaps.minSmoothPointSize = 1.0f;
3246 mState.mCaps.maxSmoothPointSize = 1.0f;
3247 mState.mCaps.minSmoothLineWidth = 1.0f;
3248 mState.mCaps.maxSmoothLineWidth = 1.0f;
3249 }
3250
3251 // If we're capturing application calls for replay, don't expose any binary formats to prevent
3252 // traces from trying to use cached results
3253 if (getFrameCapture()->enabled())
3254 {
3255 INFO() << "Limiting binary format support count to zero while FrameCapture enabled"
3256 << std::endl;
3257 mState.mCaps.shaderBinaryFormats.clear();
3258 mState.mCaps.programBinaryFormats.clear();
3259 }
3260
3261 #if 0
3262 // This logging can generate a lot of spam in test suites that create many contexts
3263 # define ANGLE_LOG_LIMITED_CAP(cap, limit) \
3264 INFO() << "Limiting " << #cap << " to implementation limit " << (limit) << " (was " \
3265 << (cap) << ")."
3266 #else
3267 # define ANGLE_LOG_LIMITED_CAP(cap, limit)
3268 #endif
3269
3270 #define ANGLE_LIMIT_CAP(cap, limit) \
3271 do \
3272 { \
3273 if ((cap) > (limit)) \
3274 { \
3275 ANGLE_LOG_LIMITED_CAP(cap, limit); \
3276 (cap) = (limit); \
3277 } \
3278 } while (0)
3279
3280 // Apply/Verify implementation limits
3281 ANGLE_LIMIT_CAP(mState.mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
3282 ANGLE_LIMIT_CAP(mState.mCaps.maxVertexAttribStride,
3283 static_cast<GLint>(limits::kMaxVertexAttribStride));
3284
3285 ASSERT(mState.mCaps.minAliasedPointSize >= 1.0f);
3286
3287 if (getClientVersion() < ES_3_1)
3288 {
3289 mState.mCaps.maxVertexAttribBindings = mState.mCaps.maxVertexAttributes;
3290 }
3291 else
3292 {
3293 ANGLE_LIMIT_CAP(mState.mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
3294 }
3295
3296 ANGLE_LIMIT_CAP(mState.mCaps.max2DTextureSize, IMPLEMENTATION_MAX_2D_TEXTURE_SIZE);
3297 ANGLE_LIMIT_CAP(mState.mCaps.maxCubeMapTextureSize, IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE);
3298 ANGLE_LIMIT_CAP(mState.mCaps.max3DTextureSize, IMPLEMENTATION_MAX_3D_TEXTURE_SIZE);
3299 ANGLE_LIMIT_CAP(mState.mCaps.maxArrayTextureLayers, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS);
3300 ANGLE_LIMIT_CAP(mState.mCaps.maxRectangleTextureSize, IMPLEMENTATION_MAX_2D_TEXTURE_SIZE);
3301
3302 ANGLE_LIMIT_CAP(mState.mCaps.maxShaderUniformBlocks[ShaderType::Vertex],
3303 IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
3304 ANGLE_LIMIT_CAP(mState.mCaps.maxShaderUniformBlocks[ShaderType::Geometry],
3305 IMPLEMENTATION_MAX_GEOMETRY_SHADER_UNIFORM_BUFFERS);
3306 ANGLE_LIMIT_CAP(mState.mCaps.maxShaderUniformBlocks[ShaderType::Fragment],
3307 IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS);
3308 ANGLE_LIMIT_CAP(mState.mCaps.maxShaderUniformBlocks[ShaderType::Compute],
3309 IMPLEMENTATION_MAX_COMPUTE_SHADER_UNIFORM_BUFFERS);
3310 ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedUniformBlocks,
3311 IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS);
3312 ANGLE_LIMIT_CAP(mState.mCaps.maxUniformBufferBindings,
3313 IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS);
3314
3315 ANGLE_LIMIT_CAP(mState.mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
3316 ANGLE_LIMIT_CAP(mState.mCaps.maxFragmentInputComponents,
3317 IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
3318
3319 ANGLE_LIMIT_CAP(mState.mCaps.maxTransformFeedbackInterleavedComponents,
3320 IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
3321 ANGLE_LIMIT_CAP(mState.mCaps.maxTransformFeedbackSeparateAttributes,
3322 IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);
3323 ANGLE_LIMIT_CAP(mState.mCaps.maxTransformFeedbackSeparateComponents,
3324 IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS);
3325
3326 // Limit textures as well, so we can use fast bitsets with texture bindings.
3327 ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedTextureImageUnits, IMPLEMENTATION_MAX_ACTIVE_TEXTURES);
3328 for (ShaderType shaderType : AllShaderTypes())
3329 {
3330 ANGLE_LIMIT_CAP(mState.mCaps.maxShaderTextureImageUnits[shaderType],
3331 IMPLEMENTATION_MAX_SHADER_TEXTURES);
3332 }
3333
3334 ANGLE_LIMIT_CAP(mState.mCaps.maxImageUnits, IMPLEMENTATION_MAX_IMAGE_UNITS);
3335 ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedImageUniforms, IMPLEMENTATION_MAX_IMAGE_UNITS);
3336 for (ShaderType shaderType : AllShaderTypes())
3337 {
3338 ANGLE_LIMIT_CAP(mState.mCaps.maxShaderImageUniforms[shaderType],
3339 IMPLEMENTATION_MAX_IMAGE_UNITS);
3340 }
3341
3342 for (ShaderType shaderType : AllShaderTypes())
3343 {
3344 ANGLE_LIMIT_CAP(mState.mCaps.maxShaderAtomicCounterBuffers[shaderType],
3345 IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFERS);
3346 }
3347 ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedAtomicCounterBuffers,
3348 IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFERS);
3349
3350 for (ShaderType shaderType : AllShaderTypes())
3351 {
3352 ANGLE_LIMIT_CAP(mState.mCaps.maxShaderStorageBlocks[shaderType],
3353 IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
3354 }
3355 ANGLE_LIMIT_CAP(mState.mCaps.maxShaderStorageBufferBindings,
3356 IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
3357 ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedShaderStorageBlocks,
3358 IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
3359
3360 ANGLE_LIMIT_CAP(mState.mCaps.maxSampleMaskWords, MAX_SAMPLE_MASK_WORDS);
3361
3362 #undef ANGLE_LIMIT_CAP
3363 #undef ANGLE_LOG_CAP_LIMIT
3364
3365 // WebGL compatibility
3366 mState.mExtensions.webglCompatibility = mWebGLContext;
3367 for (const auto &extensionInfo : GetExtensionInfoMap())
3368 {
3369 // If the user has requested that extensions start disabled and they are requestable,
3370 // disable them.
3371 if (!mExtensionsEnabled && extensionInfo.second.Requestable)
3372 {
3373 mState.mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
3374 }
3375 }
3376
3377 // Generate texture caps
3378 updateCaps();
3379 }
3380
updateCaps()3381 void Context::updateCaps()
3382 {
3383 mState.mCaps.compressedTextureFormats.clear();
3384 mState.mTextureCaps.clear();
3385
3386 for (GLenum sizedInternalFormat : GetAllSizedInternalFormats())
3387 {
3388 TextureCaps formatCaps = mImplementation->getNativeTextureCaps().get(sizedInternalFormat);
3389 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
3390
3391 // Update the format caps based on the client version and extensions.
3392 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
3393 // ES3.
3394 formatCaps.texturable = formatCaps.texturable &&
3395 formatInfo.textureSupport(getClientVersion(), mState.mExtensions);
3396 formatCaps.filterable = formatCaps.filterable &&
3397 formatInfo.filterSupport(getClientVersion(), mState.mExtensions);
3398 formatCaps.textureAttachment =
3399 formatCaps.textureAttachment &&
3400 formatInfo.textureAttachmentSupport(getClientVersion(), mState.mExtensions);
3401 formatCaps.renderbuffer =
3402 formatCaps.renderbuffer &&
3403 formatInfo.renderbufferSupport(getClientVersion(), mState.mExtensions);
3404 formatCaps.blendable =
3405 formatCaps.blendable && formatInfo.blendSupport(getClientVersion(), mState.mExtensions);
3406
3407 // OpenGL ES does not support multisampling with non-rendererable formats
3408 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
3409 if (!formatCaps.renderbuffer ||
3410 (getClientVersion() < ES_3_1 && !mSupportedExtensions.textureMultisample &&
3411 formatInfo.isInt()))
3412 {
3413 formatCaps.sampleCounts.clear();
3414 }
3415 else
3416 {
3417 // We may have limited the max samples for some required renderbuffer formats due to
3418 // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
3419 GLuint formatMaxSamples = formatCaps.getMaxSamples();
3420
3421 // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
3422 // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
3423 // exception of signed and unsigned integer formats."
3424 if (!formatInfo.isInt() && formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
3425 {
3426 ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
3427 mState.mCaps.maxSamples =
3428 std::min(static_cast<GLuint>(mState.mCaps.maxSamples), formatMaxSamples);
3429 }
3430
3431 // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
3432 if (getClientVersion() >= ES_3_1 || mSupportedExtensions.textureMultisample)
3433 {
3434 // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
3435 // in these required formats with up to the value of MAX_SAMPLES multisamples, with
3436 // the exception that the signed and unsigned integer formats are required only to
3437 // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
3438 // multisamples, which must be at least one."
3439 if (formatInfo.isInt())
3440 {
3441 mState.mCaps.maxIntegerSamples = std::min(
3442 static_cast<GLuint>(mState.mCaps.maxIntegerSamples), formatMaxSamples);
3443 }
3444
3445 // GLES 3.1 section 19.3.1.
3446 if (formatCaps.texturable)
3447 {
3448 if (formatInfo.depthBits > 0)
3449 {
3450 mState.mCaps.maxDepthTextureSamples =
3451 std::min(static_cast<GLuint>(mState.mCaps.maxDepthTextureSamples),
3452 formatMaxSamples);
3453 }
3454 else if (formatInfo.redBits > 0)
3455 {
3456 mState.mCaps.maxColorTextureSamples =
3457 std::min(static_cast<GLuint>(mState.mCaps.maxColorTextureSamples),
3458 formatMaxSamples);
3459 }
3460 }
3461 }
3462 }
3463
3464 if (formatCaps.texturable && formatInfo.compressed)
3465 {
3466 mState.mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
3467 }
3468
3469 mState.mTextureCaps.insert(sizedInternalFormat, formatCaps);
3470 }
3471
3472 // If program binary is disabled, blank out the memory cache pointer.
3473 if (!mSupportedExtensions.getProgramBinaryOES)
3474 {
3475 mMemoryProgramCache = nullptr;
3476 }
3477
3478 // Compute which buffer types are allowed
3479 mValidBufferBindings.reset();
3480 mValidBufferBindings.set(BufferBinding::ElementArray);
3481 mValidBufferBindings.set(BufferBinding::Array);
3482
3483 if (mState.mExtensions.pixelBufferObjectNV || getClientVersion() >= ES_3_0)
3484 {
3485 mValidBufferBindings.set(BufferBinding::PixelPack);
3486 mValidBufferBindings.set(BufferBinding::PixelUnpack);
3487 }
3488
3489 if (getClientVersion() >= ES_3_0)
3490 {
3491 mValidBufferBindings.set(BufferBinding::CopyRead);
3492 mValidBufferBindings.set(BufferBinding::CopyWrite);
3493 mValidBufferBindings.set(BufferBinding::TransformFeedback);
3494 mValidBufferBindings.set(BufferBinding::Uniform);
3495 }
3496
3497 if (getClientVersion() >= ES_3_1)
3498 {
3499 mValidBufferBindings.set(BufferBinding::AtomicCounter);
3500 mValidBufferBindings.set(BufferBinding::ShaderStorage);
3501 mValidBufferBindings.set(BufferBinding::DrawIndirect);
3502 mValidBufferBindings.set(BufferBinding::DispatchIndirect);
3503 }
3504
3505 mThreadPool = angle::WorkerThreadPool::Create(mState.mExtensions.parallelShaderCompile);
3506
3507 // Reinitialize some dirty bits that depend on extensions.
3508 if (mState.isRobustResourceInitEnabled())
3509 {
3510 mDrawDirtyObjects.set(State::DIRTY_OBJECT_DRAW_ATTACHMENTS);
3511 mDrawDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES_INIT);
3512 mDrawDirtyObjects.set(State::DIRTY_OBJECT_IMAGES_INIT);
3513 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_ATTACHMENTS);
3514 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_ATTACHMENTS);
3515 mComputeDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES_INIT);
3516 mComputeDirtyObjects.set(State::DIRTY_OBJECT_IMAGES_INIT);
3517 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_ATTACHMENTS);
3518 mCopyImageDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
3519 mCopyImageDirtyObjects.set(State::DIRTY_OBJECT_READ_ATTACHMENTS);
3520 }
3521
3522 // We need to validate buffer bounds if we are in a WebGL or robust access context and the
3523 // back-end does not support robust buffer access behaviour.
3524 mBufferAccessValidationEnabled =
3525 (!mSupportedExtensions.robustBufferAccessBehavior && (mState.isWebGL() || mRobustAccess));
3526
3527 // Cache this in the VertexArrays. They need to check it in state change notifications.
3528 for (auto vaoIter : mVertexArrayMap)
3529 {
3530 VertexArray *vao = vaoIter.second;
3531 vao->setBufferAccessValidationEnabled(mBufferAccessValidationEnabled);
3532 }
3533
3534 // Reinitialize state cache after extension changes.
3535 mStateCache.initialize(this);
3536 }
3537
noopDrawInstanced(PrimitiveMode mode,GLsizei count,GLsizei instanceCount)3538 bool Context::noopDrawInstanced(PrimitiveMode mode, GLsizei count, GLsizei instanceCount)
3539 {
3540 return (instanceCount == 0) || noopDraw(mode, count);
3541 }
3542
prepareForClear(GLbitfield mask)3543 angle::Result Context::prepareForClear(GLbitfield mask)
3544 {
3545 // Sync the draw framebuffer manually after the clear attachments.
3546 ASSERT(mClearDirtyObjects.none());
3547 ANGLE_TRY(mState.getDrawFramebuffer()->ensureClearAttachmentsInitialized(this, mask));
3548 ANGLE_TRY(mState.syncDirtyObject(this, GL_DRAW_FRAMEBUFFER));
3549 ANGLE_TRY(syncDirtyBits(mClearDirtyBits));
3550 return angle::Result::Continue;
3551 }
3552
prepareForClearBuffer(GLenum buffer,GLint drawbuffer)3553 angle::Result Context::prepareForClearBuffer(GLenum buffer, GLint drawbuffer)
3554 {
3555 // Sync the draw framebuffer manually after the clear attachments.
3556 ASSERT(mClearDirtyObjects.none());
3557 ANGLE_TRY(mState.getDrawFramebuffer()->ensureClearBufferAttachmentsInitialized(this, buffer,
3558 drawbuffer));
3559 ANGLE_TRY(mState.syncDirtyObject(this, GL_DRAW_FRAMEBUFFER));
3560 ANGLE_TRY(syncDirtyBits(mClearDirtyBits));
3561 return angle::Result::Continue;
3562 }
3563
prepareForCopyImage()3564 ANGLE_INLINE angle::Result Context::prepareForCopyImage()
3565 {
3566 ANGLE_TRY(syncDirtyObjects(mCopyImageDirtyObjects));
3567 return syncDirtyBits(mCopyImageDirtyBits);
3568 }
3569
prepareForDispatch()3570 ANGLE_INLINE angle::Result Context::prepareForDispatch()
3571 {
3572 ANGLE_TRY(syncDirtyObjects(mComputeDirtyObjects));
3573 return syncDirtyBits(mComputeDirtyBits);
3574 }
3575
syncState(const State::DirtyBits & bitMask,const State::DirtyObjects & objectMask)3576 angle::Result Context::syncState(const State::DirtyBits &bitMask,
3577 const State::DirtyObjects &objectMask)
3578 {
3579 ANGLE_TRY(syncDirtyObjects(objectMask));
3580 ANGLE_TRY(syncDirtyBits(bitMask));
3581 return angle::Result::Continue;
3582 }
3583
blitFramebuffer(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)3584 void Context::blitFramebuffer(GLint srcX0,
3585 GLint srcY0,
3586 GLint srcX1,
3587 GLint srcY1,
3588 GLint dstX0,
3589 GLint dstY0,
3590 GLint dstX1,
3591 GLint dstY1,
3592 GLbitfield mask,
3593 GLenum filter)
3594 {
3595 if (mask == 0)
3596 {
3597 // ES3.0 spec, section 4.3.2 specifies that a mask of zero is valid and no
3598 // buffers are copied.
3599 return;
3600 }
3601
3602 Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
3603 ASSERT(drawFramebuffer);
3604
3605 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
3606 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
3607
3608 if (dstArea.width == 0 || dstArea.height == 0)
3609 {
3610 return;
3611 }
3612
3613 ANGLE_CONTEXT_TRY(syncStateForBlit());
3614
3615 ANGLE_CONTEXT_TRY(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
3616 }
3617
clear(GLbitfield mask)3618 void Context::clear(GLbitfield mask)
3619 {
3620 ANGLE_CONTEXT_TRY(prepareForClear(mask));
3621 ANGLE_CONTEXT_TRY(mState.getDrawFramebuffer()->clear(this, mask));
3622 }
3623
clearBufferfv(GLenum buffer,GLint drawbuffer,const GLfloat * values)3624 void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
3625 {
3626 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
3627 const FramebufferAttachment *attachment = nullptr;
3628 if (buffer == GL_DEPTH)
3629 {
3630 attachment = framebufferObject->getDepthAttachment();
3631 }
3632 if (buffer == GL_COLOR &&
3633 static_cast<size_t>(drawbuffer) < framebufferObject->getNumColorAttachments())
3634 {
3635 attachment = framebufferObject->getColorAttachment(drawbuffer);
3636 }
3637 // It's not an error to try to clear a non-existent buffer, but it's a no-op. We early out so
3638 // that the backend doesn't need to take this case into account.
3639 if (!attachment)
3640 {
3641 return;
3642 }
3643 ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
3644 ANGLE_CONTEXT_TRY(framebufferObject->clearBufferfv(this, buffer, drawbuffer, values));
3645 }
3646
clearBufferuiv(GLenum buffer,GLint drawbuffer,const GLuint * values)3647 void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
3648 {
3649 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
3650 const FramebufferAttachment *attachment = nullptr;
3651 if (buffer == GL_COLOR &&
3652 static_cast<size_t>(drawbuffer) < framebufferObject->getNumColorAttachments())
3653 {
3654 attachment = framebufferObject->getColorAttachment(drawbuffer);
3655 }
3656 // It's not an error to try to clear a non-existent buffer, but it's a no-op. We early out so
3657 // that the backend doesn't need to take this case into account.
3658 if (!attachment)
3659 {
3660 return;
3661 }
3662 ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
3663 ANGLE_CONTEXT_TRY(framebufferObject->clearBufferuiv(this, buffer, drawbuffer, values));
3664 }
3665
clearBufferiv(GLenum buffer,GLint drawbuffer,const GLint * values)3666 void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
3667 {
3668 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
3669 const FramebufferAttachment *attachment = nullptr;
3670 if (buffer == GL_STENCIL)
3671 {
3672 attachment = framebufferObject->getStencilAttachment();
3673 }
3674 if (buffer == GL_COLOR &&
3675 static_cast<size_t>(drawbuffer) < framebufferObject->getNumColorAttachments())
3676 {
3677 attachment = framebufferObject->getColorAttachment(drawbuffer);
3678 }
3679 // It's not an error to try to clear a non-existent buffer, but it's a no-op. We early out so
3680 // that the backend doesn't need to take this case into account.
3681 if (!attachment)
3682 {
3683 return;
3684 }
3685 ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
3686 ANGLE_CONTEXT_TRY(framebufferObject->clearBufferiv(this, buffer, drawbuffer, values));
3687 }
3688
clearBufferfi(GLenum buffer,GLint drawbuffer,GLfloat depth,GLint stencil)3689 void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
3690 {
3691 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
3692 ASSERT(framebufferObject);
3693
3694 // If a buffer is not present, the clear has no effect
3695 if (framebufferObject->getDepthAttachment() == nullptr &&
3696 framebufferObject->getStencilAttachment() == nullptr)
3697 {
3698 return;
3699 }
3700
3701 ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
3702 ANGLE_CONTEXT_TRY(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
3703 }
3704
readPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,void * pixels)3705 void Context::readPixels(GLint x,
3706 GLint y,
3707 GLsizei width,
3708 GLsizei height,
3709 GLenum format,
3710 GLenum type,
3711 void *pixels)
3712 {
3713 if (width == 0 || height == 0)
3714 {
3715 return;
3716 }
3717
3718 ANGLE_CONTEXT_TRY(syncStateForReadPixels());
3719
3720 Framebuffer *readFBO = mState.getReadFramebuffer();
3721 ASSERT(readFBO);
3722
3723 Rectangle area(x, y, width, height);
3724 ANGLE_CONTEXT_TRY(readFBO->readPixels(this, area, format, type, pixels));
3725 }
3726
readPixelsRobust(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,GLsizei * length,GLsizei * columns,GLsizei * rows,void * pixels)3727 void Context::readPixelsRobust(GLint x,
3728 GLint y,
3729 GLsizei width,
3730 GLsizei height,
3731 GLenum format,
3732 GLenum type,
3733 GLsizei bufSize,
3734 GLsizei *length,
3735 GLsizei *columns,
3736 GLsizei *rows,
3737 void *pixels)
3738 {
3739 readPixels(x, y, width, height, format, type, pixels);
3740 }
3741
readnPixelsRobust(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,GLsizei * length,GLsizei * columns,GLsizei * rows,void * data)3742 void Context::readnPixelsRobust(GLint x,
3743 GLint y,
3744 GLsizei width,
3745 GLsizei height,
3746 GLenum format,
3747 GLenum type,
3748 GLsizei bufSize,
3749 GLsizei *length,
3750 GLsizei *columns,
3751 GLsizei *rows,
3752 void *data)
3753 {
3754 readPixels(x, y, width, height, format, type, data);
3755 }
3756
copyTexImage2D(TextureTarget target,GLint level,GLenum internalformat,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)3757 void Context::copyTexImage2D(TextureTarget target,
3758 GLint level,
3759 GLenum internalformat,
3760 GLint x,
3761 GLint y,
3762 GLsizei width,
3763 GLsizei height,
3764 GLint border)
3765 {
3766 ANGLE_CONTEXT_TRY(prepareForCopyImage());
3767
3768 Rectangle sourceArea(x, y, width, height);
3769
3770 Framebuffer *framebuffer = mState.getReadFramebuffer();
3771 Texture *texture = getTextureByTarget(target);
3772 ANGLE_CONTEXT_TRY(
3773 texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
3774 }
3775
copyTexSubImage2D(TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height)3776 void Context::copyTexSubImage2D(TextureTarget target,
3777 GLint level,
3778 GLint xoffset,
3779 GLint yoffset,
3780 GLint x,
3781 GLint y,
3782 GLsizei width,
3783 GLsizei height)
3784 {
3785 if (width == 0 || height == 0)
3786 {
3787 return;
3788 }
3789
3790 ANGLE_CONTEXT_TRY(prepareForCopyImage());
3791
3792 Offset destOffset(xoffset, yoffset, 0);
3793 Rectangle sourceArea(x, y, width, height);
3794
3795 ImageIndex index = ImageIndex::MakeFromTarget(target, level, 1);
3796
3797 Framebuffer *framebuffer = mState.getReadFramebuffer();
3798 Texture *texture = getTextureByTarget(target);
3799 ANGLE_CONTEXT_TRY(texture->copySubImage(this, index, destOffset, sourceArea, framebuffer));
3800 }
3801
copyTexSubImage3D(TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height)3802 void Context::copyTexSubImage3D(TextureTarget target,
3803 GLint level,
3804 GLint xoffset,
3805 GLint yoffset,
3806 GLint zoffset,
3807 GLint x,
3808 GLint y,
3809 GLsizei width,
3810 GLsizei height)
3811 {
3812 if (width == 0 || height == 0)
3813 {
3814 return;
3815 }
3816
3817 ANGLE_CONTEXT_TRY(prepareForCopyImage());
3818
3819 Offset destOffset(xoffset, yoffset, zoffset);
3820 Rectangle sourceArea(x, y, width, height);
3821
3822 ImageIndex index = ImageIndex::MakeFromType(TextureTargetToType(target), level, zoffset);
3823
3824 Framebuffer *framebuffer = mState.getReadFramebuffer();
3825 Texture *texture = getTextureByTarget(target);
3826 ANGLE_CONTEXT_TRY(texture->copySubImage(this, index, destOffset, sourceArea, framebuffer));
3827 }
3828
copyImageSubData(GLuint srcName,GLenum srcTarget,GLint srcLevel,GLint srcX,GLint srcY,GLint srcZ,GLuint dstName,GLenum dstTarget,GLint dstLevel,GLint dstX,GLint dstY,GLint dstZ,GLsizei srcWidth,GLsizei srcHeight,GLsizei srcDepth)3829 void Context::copyImageSubData(GLuint srcName,
3830 GLenum srcTarget,
3831 GLint srcLevel,
3832 GLint srcX,
3833 GLint srcY,
3834 GLint srcZ,
3835 GLuint dstName,
3836 GLenum dstTarget,
3837 GLint dstLevel,
3838 GLint dstX,
3839 GLint dstY,
3840 GLint dstZ,
3841 GLsizei srcWidth,
3842 GLsizei srcHeight,
3843 GLsizei srcDepth)
3844 {
3845 UNIMPLEMENTED();
3846 }
3847
framebufferTexture2D(GLenum target,GLenum attachment,TextureTarget textarget,TextureID texture,GLint level)3848 void Context::framebufferTexture2D(GLenum target,
3849 GLenum attachment,
3850 TextureTarget textarget,
3851 TextureID texture,
3852 GLint level)
3853 {
3854 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
3855 ASSERT(framebuffer);
3856
3857 if (texture.value != 0)
3858 {
3859 Texture *textureObj = getTexture(texture);
3860 ImageIndex index = ImageIndex::MakeFromTarget(textarget, level, 1);
3861 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
3862 }
3863 else
3864 {
3865 framebuffer->resetAttachment(this, attachment);
3866 }
3867
3868 mState.setObjectDirty(target);
3869 }
3870
framebufferTexture3D(GLenum target,GLenum attachment,TextureTarget textargetPacked,TextureID texture,GLint level,GLint zoffset)3871 void Context::framebufferTexture3D(GLenum target,
3872 GLenum attachment,
3873 TextureTarget textargetPacked,
3874 TextureID texture,
3875 GLint level,
3876 GLint zoffset)
3877 {
3878 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
3879 ASSERT(framebuffer);
3880
3881 if (texture.value != 0)
3882 {
3883 Texture *textureObj = getTexture(texture);
3884 ImageIndex index = ImageIndex::Make3D(level, zoffset);
3885 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
3886 }
3887 else
3888 {
3889 framebuffer->resetAttachment(this, attachment);
3890 }
3891
3892 mState.setObjectDirty(target);
3893 }
3894
framebufferRenderbuffer(GLenum target,GLenum attachment,GLenum renderbuffertarget,RenderbufferID renderbuffer)3895 void Context::framebufferRenderbuffer(GLenum target,
3896 GLenum attachment,
3897 GLenum renderbuffertarget,
3898 RenderbufferID renderbuffer)
3899 {
3900 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
3901 ASSERT(framebuffer);
3902
3903 if (renderbuffer.value != 0)
3904 {
3905 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
3906 GLsizei rbSamples = renderbufferObject->getSamples();
3907
3908 framebuffer->setAttachmentMultisample(this, GL_RENDERBUFFER, attachment, gl::ImageIndex(),
3909 renderbufferObject, rbSamples);
3910 }
3911 else
3912 {
3913 framebuffer->resetAttachment(this, attachment);
3914 }
3915
3916 mState.setObjectDirty(target);
3917 }
3918
framebufferTextureLayer(GLenum target,GLenum attachment,TextureID texture,GLint level,GLint layer)3919 void Context::framebufferTextureLayer(GLenum target,
3920 GLenum attachment,
3921 TextureID texture,
3922 GLint level,
3923 GLint layer)
3924 {
3925 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
3926 ASSERT(framebuffer);
3927
3928 if (texture.value != 0)
3929 {
3930 Texture *textureObject = getTexture(texture);
3931 ImageIndex index = ImageIndex::MakeFromType(textureObject->getType(), level, layer);
3932 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
3933 }
3934 else
3935 {
3936 framebuffer->resetAttachment(this, attachment);
3937 }
3938
3939 mState.setObjectDirty(target);
3940 }
3941
framebufferTextureMultiview(GLenum target,GLenum attachment,TextureID texture,GLint level,GLint baseViewIndex,GLsizei numViews)3942 void Context::framebufferTextureMultiview(GLenum target,
3943 GLenum attachment,
3944 TextureID texture,
3945 GLint level,
3946 GLint baseViewIndex,
3947 GLsizei numViews)
3948 {
3949 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
3950 ASSERT(framebuffer);
3951
3952 if (texture.value != 0)
3953 {
3954 Texture *textureObj = getTexture(texture);
3955
3956 ImageIndex index;
3957 if (textureObj->getType() == TextureType::_2DArray)
3958 {
3959 index = ImageIndex::Make2DArrayRange(level, baseViewIndex, numViews);
3960 }
3961 else
3962 {
3963 ASSERT(textureObj->getType() == TextureType::_2DMultisampleArray);
3964 ASSERT(level == 0);
3965 index = ImageIndex::Make2DMultisampleArrayRange(baseViewIndex, numViews);
3966 }
3967 framebuffer->setAttachmentMultiview(this, GL_TEXTURE, attachment, index, textureObj,
3968 numViews, baseViewIndex);
3969 }
3970 else
3971 {
3972 framebuffer->resetAttachment(this, attachment);
3973 }
3974
3975 mState.setObjectDirty(target);
3976 }
3977
framebufferTexture(GLenum target,GLenum attachment,TextureID texture,GLint level)3978 void Context::framebufferTexture(GLenum target, GLenum attachment, TextureID texture, GLint level)
3979 {
3980 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
3981 ASSERT(framebuffer);
3982
3983 if (texture.value != 0)
3984 {
3985 Texture *textureObj = getTexture(texture);
3986
3987 ImageIndex index = ImageIndex::MakeFromType(
3988 textureObj->getType(), level, ImageIndex::kEntireLevel, ImageIndex::kEntireLevel);
3989 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
3990 }
3991 else
3992 {
3993 framebuffer->resetAttachment(this, attachment);
3994 }
3995
3996 mState.setObjectDirty(target);
3997 }
3998
drawBuffers(GLsizei n,const GLenum * bufs)3999 void Context::drawBuffers(GLsizei n, const GLenum *bufs)
4000 {
4001 Framebuffer *framebuffer = mState.getDrawFramebuffer();
4002 ASSERT(framebuffer);
4003 framebuffer->setDrawBuffers(n, bufs);
4004 mState.setDrawFramebufferDirty();
4005 mStateCache.onDrawFramebufferChange(this);
4006 }
4007
readBuffer(GLenum mode)4008 void Context::readBuffer(GLenum mode)
4009 {
4010 Framebuffer *readFBO = mState.getReadFramebuffer();
4011 readFBO->setReadBuffer(mode);
4012 mState.setObjectDirty(GL_READ_FRAMEBUFFER);
4013 }
4014
discardFramebuffer(GLenum target,GLsizei numAttachments,const GLenum * attachments)4015 void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
4016 {
4017 // Only sync the FBO
4018 ANGLE_CONTEXT_TRY(mState.syncDirtyObject(this, target));
4019
4020 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
4021 ASSERT(framebuffer);
4022
4023 // The specification isn't clear what should be done when the framebuffer isn't complete.
4024 // We leave it up to the framebuffer implementation to decide what to do.
4025 ANGLE_CONTEXT_TRY(framebuffer->discard(this, numAttachments, attachments));
4026 }
4027
invalidateFramebuffer(GLenum target,GLsizei numAttachments,const GLenum * attachments)4028 void Context::invalidateFramebuffer(GLenum target,
4029 GLsizei numAttachments,
4030 const GLenum *attachments)
4031 {
4032 // Only sync the FBO
4033 ANGLE_CONTEXT_TRY(mState.syncDirtyObject(this, target));
4034
4035 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
4036 ASSERT(framebuffer);
4037
4038 if (!framebuffer->isComplete(this))
4039 {
4040 return;
4041 }
4042
4043 ANGLE_CONTEXT_TRY(framebuffer->invalidate(this, numAttachments, attachments));
4044 }
4045
invalidateSubFramebuffer(GLenum target,GLsizei numAttachments,const GLenum * attachments,GLint x,GLint y,GLsizei width,GLsizei height)4046 void Context::invalidateSubFramebuffer(GLenum target,
4047 GLsizei numAttachments,
4048 const GLenum *attachments,
4049 GLint x,
4050 GLint y,
4051 GLsizei width,
4052 GLsizei height)
4053 {
4054 // Only sync the FBO
4055 ANGLE_CONTEXT_TRY(mState.syncDirtyObject(this, target));
4056
4057 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
4058 ASSERT(framebuffer);
4059
4060 if (!framebuffer->isComplete(this))
4061 {
4062 return;
4063 }
4064
4065 Rectangle area(x, y, width, height);
4066 ANGLE_CONTEXT_TRY(framebuffer->invalidateSub(this, numAttachments, attachments, area));
4067 }
4068
texImage2D(TextureTarget target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const void * pixels)4069 void Context::texImage2D(TextureTarget target,
4070 GLint level,
4071 GLint internalformat,
4072 GLsizei width,
4073 GLsizei height,
4074 GLint border,
4075 GLenum format,
4076 GLenum type,
4077 const void *pixels)
4078 {
4079 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4080
4081 gl::Buffer *unpackBuffer = mState.getTargetBuffer(gl::BufferBinding::PixelUnpack);
4082
4083 Extents size(width, height, 1);
4084 Texture *texture = getTextureByTarget(target);
4085 ANGLE_CONTEXT_TRY(texture->setImage(this, mState.getUnpackState(), unpackBuffer, target, level,
4086 internalformat, size, format, type,
4087 static_cast<const uint8_t *>(pixels)));
4088 }
4089
texImage2DRobust(TextureTarget target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,GLsizei bufSize,const void * pixels)4090 void Context::texImage2DRobust(TextureTarget target,
4091 GLint level,
4092 GLint internalformat,
4093 GLsizei width,
4094 GLsizei height,
4095 GLint border,
4096 GLenum format,
4097 GLenum type,
4098 GLsizei bufSize,
4099 const void *pixels)
4100 {
4101 texImage2D(target, level, internalformat, width, height, border, format, type, pixels);
4102 }
4103
texImage3D(TextureTarget target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,const void * pixels)4104 void Context::texImage3D(TextureTarget target,
4105 GLint level,
4106 GLint internalformat,
4107 GLsizei width,
4108 GLsizei height,
4109 GLsizei depth,
4110 GLint border,
4111 GLenum format,
4112 GLenum type,
4113 const void *pixels)
4114 {
4115 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4116
4117 gl::Buffer *unpackBuffer = mState.getTargetBuffer(gl::BufferBinding::PixelUnpack);
4118
4119 Extents size(width, height, depth);
4120 Texture *texture = getTextureByTarget(target);
4121 ANGLE_CONTEXT_TRY(texture->setImage(this, mState.getUnpackState(), unpackBuffer, target, level,
4122 internalformat, size, format, type,
4123 static_cast<const uint8_t *>(pixels)));
4124 }
4125
texImage3DRobust(TextureTarget target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,GLsizei bufSize,const void * pixels)4126 void Context::texImage3DRobust(TextureTarget target,
4127 GLint level,
4128 GLint internalformat,
4129 GLsizei width,
4130 GLsizei height,
4131 GLsizei depth,
4132 GLint border,
4133 GLenum format,
4134 GLenum type,
4135 GLsizei bufSize,
4136 const void *pixels)
4137 {
4138 texImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
4139 }
4140
texSubImage2D(TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const void * pixels)4141 void Context::texSubImage2D(TextureTarget target,
4142 GLint level,
4143 GLint xoffset,
4144 GLint yoffset,
4145 GLsizei width,
4146 GLsizei height,
4147 GLenum format,
4148 GLenum type,
4149 const void *pixels)
4150 {
4151 // Zero sized uploads are valid but no-ops
4152 if (width == 0 || height == 0)
4153 {
4154 return;
4155 }
4156
4157 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4158
4159 Box area(xoffset, yoffset, 0, width, height, 1);
4160 Texture *texture = getTextureByTarget(target);
4161
4162 gl::Buffer *unpackBuffer = mState.getTargetBuffer(gl::BufferBinding::PixelUnpack);
4163
4164 ANGLE_CONTEXT_TRY(texture->setSubImage(this, mState.getUnpackState(), unpackBuffer, target,
4165 level, area, format, type,
4166 static_cast<const uint8_t *>(pixels)));
4167 }
4168
texSubImage2DRobust(TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,const void * pixels)4169 void Context::texSubImage2DRobust(TextureTarget target,
4170 GLint level,
4171 GLint xoffset,
4172 GLint yoffset,
4173 GLsizei width,
4174 GLsizei height,
4175 GLenum format,
4176 GLenum type,
4177 GLsizei bufSize,
4178 const void *pixels)
4179 {
4180 texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
4181 }
4182
texSubImage3D(TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const void * pixels)4183 void Context::texSubImage3D(TextureTarget target,
4184 GLint level,
4185 GLint xoffset,
4186 GLint yoffset,
4187 GLint zoffset,
4188 GLsizei width,
4189 GLsizei height,
4190 GLsizei depth,
4191 GLenum format,
4192 GLenum type,
4193 const void *pixels)
4194 {
4195 // Zero sized uploads are valid but no-ops
4196 if (width == 0 || height == 0 || depth == 0)
4197 {
4198 return;
4199 }
4200
4201 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4202
4203 Box area(xoffset, yoffset, zoffset, width, height, depth);
4204 Texture *texture = getTextureByTarget(target);
4205
4206 gl::Buffer *unpackBuffer = mState.getTargetBuffer(gl::BufferBinding::PixelUnpack);
4207
4208 ANGLE_CONTEXT_TRY(texture->setSubImage(this, mState.getUnpackState(), unpackBuffer, target,
4209 level, area, format, type,
4210 static_cast<const uint8_t *>(pixels)));
4211 }
4212
texSubImage3DRobust(TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,GLsizei bufSize,const void * pixels)4213 void Context::texSubImage3DRobust(TextureTarget target,
4214 GLint level,
4215 GLint xoffset,
4216 GLint yoffset,
4217 GLint zoffset,
4218 GLsizei width,
4219 GLsizei height,
4220 GLsizei depth,
4221 GLenum format,
4222 GLenum type,
4223 GLsizei bufSize,
4224 const void *pixels)
4225 {
4226 texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type,
4227 pixels);
4228 }
4229
compressedTexImage2D(TextureTarget target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,const void * data)4230 void Context::compressedTexImage2D(TextureTarget target,
4231 GLint level,
4232 GLenum internalformat,
4233 GLsizei width,
4234 GLsizei height,
4235 GLint border,
4236 GLsizei imageSize,
4237 const void *data)
4238 {
4239 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4240
4241 Extents size(width, height, 1);
4242 Texture *texture = getTextureByTarget(target);
4243 ANGLE_CONTEXT_TRY(texture->setCompressedImage(this, mState.getUnpackState(), target, level,
4244 internalformat, size, imageSize,
4245 static_cast<const uint8_t *>(data)));
4246 }
4247
compressedTexImage2DRobust(TextureTarget target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,GLsizei dataSize,const GLvoid * data)4248 void Context::compressedTexImage2DRobust(TextureTarget target,
4249 GLint level,
4250 GLenum internalformat,
4251 GLsizei width,
4252 GLsizei height,
4253 GLint border,
4254 GLsizei imageSize,
4255 GLsizei dataSize,
4256 const GLvoid *data)
4257 {
4258 compressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
4259 }
4260
compressedTexImage3D(TextureTarget target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei imageSize,const void * data)4261 void Context::compressedTexImage3D(TextureTarget target,
4262 GLint level,
4263 GLenum internalformat,
4264 GLsizei width,
4265 GLsizei height,
4266 GLsizei depth,
4267 GLint border,
4268 GLsizei imageSize,
4269 const void *data)
4270 {
4271 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4272
4273 Extents size(width, height, depth);
4274 Texture *texture = getTextureByTarget(target);
4275 ANGLE_CONTEXT_TRY(texture->setCompressedImage(this, mState.getUnpackState(), target, level,
4276 internalformat, size, imageSize,
4277 static_cast<const uint8_t *>(data)));
4278 }
4279
compressedTexImage3DRobust(TextureTarget target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei imageSize,GLsizei dataSize,const GLvoid * data)4280 void Context::compressedTexImage3DRobust(TextureTarget target,
4281 GLint level,
4282 GLenum internalformat,
4283 GLsizei width,
4284 GLsizei height,
4285 GLsizei depth,
4286 GLint border,
4287 GLsizei imageSize,
4288 GLsizei dataSize,
4289 const GLvoid *data)
4290 {
4291 compressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize,
4292 data);
4293 }
4294
compressedTexSubImage2D(TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,const void * data)4295 void Context::compressedTexSubImage2D(TextureTarget target,
4296 GLint level,
4297 GLint xoffset,
4298 GLint yoffset,
4299 GLsizei width,
4300 GLsizei height,
4301 GLenum format,
4302 GLsizei imageSize,
4303 const void *data)
4304 {
4305 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4306
4307 Box area(xoffset, yoffset, 0, width, height, 1);
4308 Texture *texture = getTextureByTarget(target);
4309 ANGLE_CONTEXT_TRY(texture->setCompressedSubImage(this, mState.getUnpackState(), target, level,
4310 area, format, imageSize,
4311 static_cast<const uint8_t *>(data)));
4312 }
4313
compressedTexSubImage2DRobust(TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,GLsizei dataSize,const GLvoid * data)4314 void Context::compressedTexSubImage2DRobust(TextureTarget target,
4315 GLint level,
4316 GLint xoffset,
4317 GLint yoffset,
4318 GLsizei width,
4319 GLsizei height,
4320 GLenum format,
4321 GLsizei imageSize,
4322 GLsizei dataSize,
4323 const GLvoid *data)
4324 {
4325 compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize,
4326 data);
4327 }
4328
compressedTexSubImage3D(TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei imageSize,const void * data)4329 void Context::compressedTexSubImage3D(TextureTarget target,
4330 GLint level,
4331 GLint xoffset,
4332 GLint yoffset,
4333 GLint zoffset,
4334 GLsizei width,
4335 GLsizei height,
4336 GLsizei depth,
4337 GLenum format,
4338 GLsizei imageSize,
4339 const void *data)
4340 {
4341 // Zero sized uploads are valid but no-ops
4342 if (width == 0 || height == 0)
4343 {
4344 return;
4345 }
4346
4347 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4348
4349 Box area(xoffset, yoffset, zoffset, width, height, depth);
4350 Texture *texture = getTextureByTarget(target);
4351 ANGLE_CONTEXT_TRY(texture->setCompressedSubImage(this, mState.getUnpackState(), target, level,
4352 area, format, imageSize,
4353 static_cast<const uint8_t *>(data)));
4354 }
4355
compressedTexSubImage3DRobust(TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei imageSize,GLsizei dataSize,const GLvoid * data)4356 void Context::compressedTexSubImage3DRobust(TextureTarget target,
4357 GLint level,
4358 GLint xoffset,
4359 GLint yoffset,
4360 GLint zoffset,
4361 GLsizei width,
4362 GLsizei height,
4363 GLsizei depth,
4364 GLenum format,
4365 GLsizei imageSize,
4366 GLsizei dataSize,
4367 const GLvoid *data)
4368 {
4369 compressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format,
4370 imageSize, data);
4371 }
4372
generateMipmap(TextureType target)4373 void Context::generateMipmap(TextureType target)
4374 {
4375 Texture *texture = getTextureByType(target);
4376 ANGLE_CONTEXT_TRY(texture->generateMipmap(this));
4377 }
4378
copyTexture(TextureID sourceId,GLint sourceLevel,TextureTarget destTarget,TextureID destId,GLint destLevel,GLint internalFormat,GLenum destType,GLboolean unpackFlipY,GLboolean unpackPremultiplyAlpha,GLboolean unpackUnmultiplyAlpha)4379 void Context::copyTexture(TextureID sourceId,
4380 GLint sourceLevel,
4381 TextureTarget destTarget,
4382 TextureID destId,
4383 GLint destLevel,
4384 GLint internalFormat,
4385 GLenum destType,
4386 GLboolean unpackFlipY,
4387 GLboolean unpackPremultiplyAlpha,
4388 GLboolean unpackUnmultiplyAlpha)
4389 {
4390 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4391
4392 gl::Texture *sourceTexture = getTexture(sourceId);
4393 gl::Texture *destTexture = getTexture(destId);
4394 ANGLE_CONTEXT_TRY(
4395 destTexture->copyTexture(this, destTarget, destLevel, internalFormat, destType, sourceLevel,
4396 ConvertToBool(unpackFlipY), ConvertToBool(unpackPremultiplyAlpha),
4397 ConvertToBool(unpackUnmultiplyAlpha), sourceTexture));
4398 }
4399
copySubTexture(TextureID sourceId,GLint sourceLevel,TextureTarget destTarget,TextureID destId,GLint destLevel,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height,GLboolean unpackFlipY,GLboolean unpackPremultiplyAlpha,GLboolean unpackUnmultiplyAlpha)4400 void Context::copySubTexture(TextureID sourceId,
4401 GLint sourceLevel,
4402 TextureTarget destTarget,
4403 TextureID destId,
4404 GLint destLevel,
4405 GLint xoffset,
4406 GLint yoffset,
4407 GLint x,
4408 GLint y,
4409 GLsizei width,
4410 GLsizei height,
4411 GLboolean unpackFlipY,
4412 GLboolean unpackPremultiplyAlpha,
4413 GLboolean unpackUnmultiplyAlpha)
4414 {
4415 // Zero sized copies are valid but no-ops
4416 if (width == 0 || height == 0)
4417 {
4418 return;
4419 }
4420
4421 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4422
4423 gl::Texture *sourceTexture = getTexture(sourceId);
4424 gl::Texture *destTexture = getTexture(destId);
4425 Offset offset(xoffset, yoffset, 0);
4426 Box box(x, y, 0, width, height, 1);
4427 ANGLE_CONTEXT_TRY(destTexture->copySubTexture(
4428 this, destTarget, destLevel, offset, sourceLevel, box, ConvertToBool(unpackFlipY),
4429 ConvertToBool(unpackPremultiplyAlpha), ConvertToBool(unpackUnmultiplyAlpha),
4430 sourceTexture));
4431 }
4432
copyTexture3D(TextureID sourceId,GLint sourceLevel,TextureTarget destTarget,TextureID destId,GLint destLevel,GLint internalFormat,GLenum destType,GLboolean unpackFlipY,GLboolean unpackPremultiplyAlpha,GLboolean unpackUnmultiplyAlpha)4433 void Context::copyTexture3D(TextureID sourceId,
4434 GLint sourceLevel,
4435 TextureTarget destTarget,
4436 TextureID destId,
4437 GLint destLevel,
4438 GLint internalFormat,
4439 GLenum destType,
4440 GLboolean unpackFlipY,
4441 GLboolean unpackPremultiplyAlpha,
4442 GLboolean unpackUnmultiplyAlpha)
4443 {
4444 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4445
4446 Texture *sourceTexture = getTexture(sourceId);
4447 Texture *destTexture = getTexture(destId);
4448 ANGLE_CONTEXT_TRY(
4449 destTexture->copyTexture(this, destTarget, destLevel, internalFormat, destType, sourceLevel,
4450 ConvertToBool(unpackFlipY), ConvertToBool(unpackPremultiplyAlpha),
4451 ConvertToBool(unpackUnmultiplyAlpha), sourceTexture));
4452 }
4453
copySubTexture3D(TextureID sourceId,GLint sourceLevel,TextureTarget destTarget,TextureID destId,GLint destLevel,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLint z,GLsizei width,GLsizei height,GLsizei depth,GLboolean unpackFlipY,GLboolean unpackPremultiplyAlpha,GLboolean unpackUnmultiplyAlpha)4454 void Context::copySubTexture3D(TextureID sourceId,
4455 GLint sourceLevel,
4456 TextureTarget destTarget,
4457 TextureID destId,
4458 GLint destLevel,
4459 GLint xoffset,
4460 GLint yoffset,
4461 GLint zoffset,
4462 GLint x,
4463 GLint y,
4464 GLint z,
4465 GLsizei width,
4466 GLsizei height,
4467 GLsizei depth,
4468 GLboolean unpackFlipY,
4469 GLboolean unpackPremultiplyAlpha,
4470 GLboolean unpackUnmultiplyAlpha)
4471 {
4472 // Zero sized copies are valid but no-ops
4473 if (width == 0 || height == 0 || depth == 0)
4474 {
4475 return;
4476 }
4477
4478 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4479
4480 Texture *sourceTexture = getTexture(sourceId);
4481 Texture *destTexture = getTexture(destId);
4482 Offset offset(xoffset, yoffset, zoffset);
4483 Box box(x, y, z, width, height, depth);
4484 ANGLE_CONTEXT_TRY(destTexture->copySubTexture(
4485 this, destTarget, destLevel, offset, sourceLevel, box, ConvertToBool(unpackFlipY),
4486 ConvertToBool(unpackPremultiplyAlpha), ConvertToBool(unpackUnmultiplyAlpha),
4487 sourceTexture));
4488 }
4489
compressedCopyTexture(TextureID sourceId,TextureID destId)4490 void Context::compressedCopyTexture(TextureID sourceId, TextureID destId)
4491 {
4492 ANGLE_CONTEXT_TRY(syncStateForTexImage());
4493
4494 gl::Texture *sourceTexture = getTexture(sourceId);
4495 gl::Texture *destTexture = getTexture(destId);
4496 ANGLE_CONTEXT_TRY(destTexture->copyCompressedTexture(this, sourceTexture));
4497 }
4498
getBufferPointerv(BufferBinding target,GLenum pname,void ** params)4499 void Context::getBufferPointerv(BufferBinding target, GLenum pname, void **params)
4500 {
4501 Buffer *buffer = mState.getTargetBuffer(target);
4502 ASSERT(buffer);
4503
4504 QueryBufferPointerv(buffer, pname, params);
4505 }
4506
getBufferPointervRobust(BufferBinding target,GLenum pname,GLsizei bufSize,GLsizei * length,void ** params)4507 void Context::getBufferPointervRobust(BufferBinding target,
4508 GLenum pname,
4509 GLsizei bufSize,
4510 GLsizei *length,
4511 void **params)
4512 {
4513 getBufferPointerv(target, pname, params);
4514 }
4515
mapBuffer(BufferBinding target,GLenum access)4516 void *Context::mapBuffer(BufferBinding target, GLenum access)
4517 {
4518 Buffer *buffer = mState.getTargetBuffer(target);
4519 ASSERT(buffer);
4520
4521 if (buffer->map(this, access) == angle::Result::Stop)
4522 {
4523 return nullptr;
4524 }
4525
4526 return buffer->getMapPointer();
4527 }
4528
unmapBuffer(BufferBinding target)4529 GLboolean Context::unmapBuffer(BufferBinding target)
4530 {
4531 Buffer *buffer = mState.getTargetBuffer(target);
4532 ASSERT(buffer);
4533
4534 GLboolean result;
4535 if (buffer->unmap(this, &result) == angle::Result::Stop)
4536 {
4537 return GL_FALSE;
4538 }
4539
4540 return result;
4541 }
4542
mapBufferRange(BufferBinding target,GLintptr offset,GLsizeiptr length,GLbitfield access)4543 void *Context::mapBufferRange(BufferBinding target,
4544 GLintptr offset,
4545 GLsizeiptr length,
4546 GLbitfield access)
4547 {
4548 Buffer *buffer = mState.getTargetBuffer(target);
4549 ASSERT(buffer);
4550
4551 if (buffer->mapRange(this, offset, length, access) == angle::Result::Stop)
4552 {
4553 return nullptr;
4554 }
4555
4556 return buffer->getMapPointer();
4557 }
4558
flushMappedBufferRange(BufferBinding,GLintptr,GLsizeiptr)4559 void Context::flushMappedBufferRange(BufferBinding /*target*/,
4560 GLintptr /*offset*/,
4561 GLsizeiptr /*length*/)
4562 {
4563 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
4564 }
4565
syncStateForReadPixels()4566 angle::Result Context::syncStateForReadPixels()
4567 {
4568 return syncState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
4569 }
4570
syncStateForTexImage()4571 angle::Result Context::syncStateForTexImage()
4572 {
4573 return syncState(mTexImageDirtyBits, mTexImageDirtyObjects);
4574 }
4575
syncStateForBlit()4576 angle::Result Context::syncStateForBlit()
4577 {
4578 return syncState(mBlitDirtyBits, mBlitDirtyObjects);
4579 }
4580
activeShaderProgram(ProgramPipelineID pipeline,ShaderProgramID program)4581 void Context::activeShaderProgram(ProgramPipelineID pipeline, ShaderProgramID program)
4582 {
4583 Program *shaderProgram = getProgramNoResolveLink(program);
4584 ProgramPipeline *programPipeline =
4585 mState.mProgramPipelineManager->checkProgramPipelineAllocation(mImplementation.get(),
4586 pipeline);
4587 ASSERT(programPipeline);
4588
4589 programPipeline->activeShaderProgram(shaderProgram);
4590 }
4591
activeTexture(GLenum texture)4592 void Context::activeTexture(GLenum texture)
4593 {
4594 mState.setActiveSampler(texture - GL_TEXTURE0);
4595 }
4596
blendBarrier()4597 void Context::blendBarrier()
4598 {
4599 UNIMPLEMENTED();
4600 }
4601
blendColor(GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)4602 void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
4603 {
4604 mState.setBlendColor(red, green, blue, alpha);
4605 }
4606
blendEquation(GLenum mode)4607 void Context::blendEquation(GLenum mode)
4608 {
4609 mState.setBlendEquation(mode, mode);
4610 }
4611
blendEquationi(GLuint buf,GLenum mode)4612 void Context::blendEquationi(GLuint buf, GLenum mode)
4613 {
4614 mState.setBlendEquationIndexed(mode, mode, buf);
4615 }
4616
blendEquationSeparate(GLenum modeRGB,GLenum modeAlpha)4617 void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
4618 {
4619 mState.setBlendEquation(modeRGB, modeAlpha);
4620 }
4621
blendEquationSeparatei(GLuint buf,GLenum modeRGB,GLenum modeAlpha)4622 void Context::blendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeAlpha)
4623 {
4624 mState.setBlendEquationIndexed(modeRGB, modeAlpha, buf);
4625 }
4626
blendFunc(GLenum sfactor,GLenum dfactor)4627 void Context::blendFunc(GLenum sfactor, GLenum dfactor)
4628 {
4629 mState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
4630 }
4631
blendFunci(GLuint buf,GLenum src,GLenum dst)4632 void Context::blendFunci(GLuint buf, GLenum src, GLenum dst)
4633 {
4634 mState.setBlendFactorsIndexed(src, dst, src, dst, buf);
4635
4636 if (mState.noSimultaneousConstantColorAndAlphaBlendFunc())
4637 {
4638 mStateCache.onBlendFuncIndexedChange(this);
4639 }
4640 }
4641
blendFuncSeparate(GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)4642 void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
4643 {
4644 mState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
4645 }
4646
blendFuncSeparatei(GLuint buf,GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)4647 void Context::blendFuncSeparatei(GLuint buf,
4648 GLenum srcRGB,
4649 GLenum dstRGB,
4650 GLenum srcAlpha,
4651 GLenum dstAlpha)
4652 {
4653 mState.setBlendFactorsIndexed(srcRGB, dstRGB, srcAlpha, dstAlpha, buf);
4654
4655 if (mState.noSimultaneousConstantColorAndAlphaBlendFunc())
4656 {
4657 mStateCache.onBlendFuncIndexedChange(this);
4658 }
4659 }
4660
clearColor(GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)4661 void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
4662 {
4663 mState.setColorClearValue(red, green, blue, alpha);
4664 }
4665
clearDepthf(GLfloat depth)4666 void Context::clearDepthf(GLfloat depth)
4667 {
4668 mState.setDepthClearValue(clamp01(depth));
4669 }
4670
clearStencil(GLint s)4671 void Context::clearStencil(GLint s)
4672 {
4673 mState.setStencilClearValue(s);
4674 }
4675
colorMask(GLboolean red,GLboolean green,GLboolean blue,GLboolean alpha)4676 void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
4677 {
4678 mState.setColorMask(ConvertToBool(red), ConvertToBool(green), ConvertToBool(blue),
4679 ConvertToBool(alpha));
4680 mStateCache.onColorMaskChange(this);
4681 }
4682
colorMaski(GLuint index,GLboolean r,GLboolean g,GLboolean b,GLboolean a)4683 void Context::colorMaski(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a)
4684 {
4685 mState.setColorMaskIndexed(ConvertToBool(r), ConvertToBool(g), ConvertToBool(b),
4686 ConvertToBool(a), index);
4687 mStateCache.onColorMaskChange(this);
4688 }
4689
cullFace(CullFaceMode mode)4690 void Context::cullFace(CullFaceMode mode)
4691 {
4692 mState.setCullMode(mode);
4693 }
4694
depthFunc(GLenum func)4695 void Context::depthFunc(GLenum func)
4696 {
4697 mState.setDepthFunc(func);
4698 }
4699
depthMask(GLboolean flag)4700 void Context::depthMask(GLboolean flag)
4701 {
4702 mState.setDepthMask(ConvertToBool(flag));
4703 }
4704
depthRangef(GLfloat zNear,GLfloat zFar)4705 void Context::depthRangef(GLfloat zNear, GLfloat zFar)
4706 {
4707 mState.setDepthRange(clamp01(zNear), clamp01(zFar));
4708 }
4709
disable(GLenum cap)4710 void Context::disable(GLenum cap)
4711 {
4712 mState.setEnableFeature(cap, false);
4713 mStateCache.onContextCapChange(this);
4714 }
4715
disablei(GLenum target,GLuint index)4716 void Context::disablei(GLenum target, GLuint index)
4717 {
4718 mState.setEnableFeatureIndexed(target, false, index);
4719 mStateCache.onContextCapChange(this);
4720 }
4721
disableVertexAttribArray(GLuint index)4722 void Context::disableVertexAttribArray(GLuint index)
4723 {
4724 mState.setEnableVertexAttribArray(index, false);
4725 mStateCache.onVertexArrayStateChange(this);
4726 }
4727
enable(GLenum cap)4728 void Context::enable(GLenum cap)
4729 {
4730 mState.setEnableFeature(cap, true);
4731 mStateCache.onContextCapChange(this);
4732 }
4733
enablei(GLenum target,GLuint index)4734 void Context::enablei(GLenum target, GLuint index)
4735 {
4736 mState.setEnableFeatureIndexed(target, true, index);
4737 mStateCache.onContextCapChange(this);
4738 }
4739
enableVertexAttribArray(GLuint index)4740 void Context::enableVertexAttribArray(GLuint index)
4741 {
4742 mState.setEnableVertexAttribArray(index, true);
4743 mStateCache.onVertexArrayStateChange(this);
4744 }
4745
frontFace(GLenum mode)4746 void Context::frontFace(GLenum mode)
4747 {
4748 mState.setFrontFace(mode);
4749 }
4750
hint(GLenum target,GLenum mode)4751 void Context::hint(GLenum target, GLenum mode)
4752 {
4753 switch (target)
4754 {
4755 case GL_GENERATE_MIPMAP_HINT:
4756 mState.setGenerateMipmapHint(mode);
4757 break;
4758
4759 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4760 mState.setFragmentShaderDerivativeHint(mode);
4761 break;
4762
4763 case GL_PERSPECTIVE_CORRECTION_HINT:
4764 case GL_POINT_SMOOTH_HINT:
4765 case GL_LINE_SMOOTH_HINT:
4766 case GL_FOG_HINT:
4767 mState.gles1().setHint(target, mode);
4768 break;
4769 default:
4770 UNREACHABLE();
4771 return;
4772 }
4773 }
4774
lineWidth(GLfloat width)4775 void Context::lineWidth(GLfloat width)
4776 {
4777 mState.setLineWidth(width);
4778 }
4779
pixelStorei(GLenum pname,GLint param)4780 void Context::pixelStorei(GLenum pname, GLint param)
4781 {
4782 switch (pname)
4783 {
4784 case GL_UNPACK_ALIGNMENT:
4785 mState.setUnpackAlignment(param);
4786 break;
4787
4788 case GL_PACK_ALIGNMENT:
4789 mState.setPackAlignment(param);
4790 break;
4791
4792 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
4793 mState.setPackReverseRowOrder(param != 0);
4794 break;
4795
4796 case GL_UNPACK_ROW_LENGTH:
4797 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
4798 mState.setUnpackRowLength(param);
4799 break;
4800
4801 case GL_UNPACK_IMAGE_HEIGHT:
4802 ASSERT(getClientMajorVersion() >= 3);
4803 mState.setUnpackImageHeight(param);
4804 break;
4805
4806 case GL_UNPACK_SKIP_IMAGES:
4807 ASSERT(getClientMajorVersion() >= 3);
4808 mState.setUnpackSkipImages(param);
4809 break;
4810
4811 case GL_UNPACK_SKIP_ROWS:
4812 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
4813 mState.setUnpackSkipRows(param);
4814 break;
4815
4816 case GL_UNPACK_SKIP_PIXELS:
4817 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
4818 mState.setUnpackSkipPixels(param);
4819 break;
4820
4821 case GL_PACK_ROW_LENGTH:
4822 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
4823 mState.setPackRowLength(param);
4824 break;
4825
4826 case GL_PACK_SKIP_ROWS:
4827 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
4828 mState.setPackSkipRows(param);
4829 break;
4830
4831 case GL_PACK_SKIP_PIXELS:
4832 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
4833 mState.setPackSkipPixels(param);
4834 break;
4835
4836 default:
4837 UNREACHABLE();
4838 return;
4839 }
4840 }
4841
polygonOffset(GLfloat factor,GLfloat units)4842 void Context::polygonOffset(GLfloat factor, GLfloat units)
4843 {
4844 mState.setPolygonOffsetParams(factor, units);
4845 }
4846
sampleCoverage(GLfloat value,GLboolean invert)4847 void Context::sampleCoverage(GLfloat value, GLboolean invert)
4848 {
4849 mState.setSampleCoverageParams(clamp01(value), ConvertToBool(invert));
4850 }
4851
sampleMaski(GLuint maskNumber,GLbitfield mask)4852 void Context::sampleMaski(GLuint maskNumber, GLbitfield mask)
4853 {
4854 mState.setSampleMaskParams(maskNumber, mask);
4855 }
4856
scissor(GLint x,GLint y,GLsizei width,GLsizei height)4857 void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
4858 {
4859 mState.setScissorParams(x, y, width, height);
4860 }
4861
stencilFuncSeparate(GLenum face,GLenum func,GLint ref,GLuint mask)4862 void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4863 {
4864 GLint clampedRef = gl::clamp(ref, 0, std::numeric_limits<uint8_t>::max());
4865 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4866 {
4867 mState.setStencilParams(func, clampedRef, mask);
4868 }
4869
4870 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4871 {
4872 mState.setStencilBackParams(func, clampedRef, mask);
4873 }
4874
4875 mStateCache.onStencilStateChange(this);
4876 }
4877
stencilMaskSeparate(GLenum face,GLuint mask)4878 void Context::stencilMaskSeparate(GLenum face, GLuint mask)
4879 {
4880 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4881 {
4882 mState.setStencilWritemask(mask);
4883 }
4884
4885 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4886 {
4887 mState.setStencilBackWritemask(mask);
4888 }
4889
4890 mStateCache.onStencilStateChange(this);
4891 }
4892
stencilOpSeparate(GLenum face,GLenum fail,GLenum zfail,GLenum zpass)4893 void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4894 {
4895 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4896 {
4897 mState.setStencilOperations(fail, zfail, zpass);
4898 }
4899
4900 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4901 {
4902 mState.setStencilBackOperations(fail, zfail, zpass);
4903 }
4904 }
4905
vertexAttrib1f(GLuint index,GLfloat x)4906 void Context::vertexAttrib1f(GLuint index, GLfloat x)
4907 {
4908 GLfloat vals[4] = {x, 0, 0, 1};
4909 mState.setVertexAttribf(index, vals);
4910 mStateCache.onDefaultVertexAttributeChange(this);
4911 }
4912
vertexAttrib1fv(GLuint index,const GLfloat * values)4913 void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
4914 {
4915 GLfloat vals[4] = {values[0], 0, 0, 1};
4916 mState.setVertexAttribf(index, vals);
4917 mStateCache.onDefaultVertexAttributeChange(this);
4918 }
4919
vertexAttrib2f(GLuint index,GLfloat x,GLfloat y)4920 void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4921 {
4922 GLfloat vals[4] = {x, y, 0, 1};
4923 mState.setVertexAttribf(index, vals);
4924 mStateCache.onDefaultVertexAttributeChange(this);
4925 }
4926
vertexAttrib2fv(GLuint index,const GLfloat * values)4927 void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
4928 {
4929 GLfloat vals[4] = {values[0], values[1], 0, 1};
4930 mState.setVertexAttribf(index, vals);
4931 mStateCache.onDefaultVertexAttributeChange(this);
4932 }
4933
vertexAttrib3f(GLuint index,GLfloat x,GLfloat y,GLfloat z)4934 void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4935 {
4936 GLfloat vals[4] = {x, y, z, 1};
4937 mState.setVertexAttribf(index, vals);
4938 mStateCache.onDefaultVertexAttributeChange(this);
4939 }
4940
vertexAttrib3fv(GLuint index,const GLfloat * values)4941 void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
4942 {
4943 GLfloat vals[4] = {values[0], values[1], values[2], 1};
4944 mState.setVertexAttribf(index, vals);
4945 mStateCache.onDefaultVertexAttributeChange(this);
4946 }
4947
vertexAttrib4f(GLuint index,GLfloat x,GLfloat y,GLfloat z,GLfloat w)4948 void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4949 {
4950 GLfloat vals[4] = {x, y, z, w};
4951 mState.setVertexAttribf(index, vals);
4952 mStateCache.onDefaultVertexAttributeChange(this);
4953 }
4954
vertexAttrib4fv(GLuint index,const GLfloat * values)4955 void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
4956 {
4957 mState.setVertexAttribf(index, values);
4958 mStateCache.onDefaultVertexAttributeChange(this);
4959 }
4960
vertexAttribPointer(GLuint index,GLint size,VertexAttribType type,GLboolean normalized,GLsizei stride,const void * ptr)4961 void Context::vertexAttribPointer(GLuint index,
4962 GLint size,
4963 VertexAttribType type,
4964 GLboolean normalized,
4965 GLsizei stride,
4966 const void *ptr)
4967 {
4968 mState.setVertexAttribPointer(this, index, mState.getTargetBuffer(BufferBinding::Array), size,
4969 type, ConvertToBool(normalized), stride, ptr);
4970 mStateCache.onVertexArrayStateChange(this);
4971 }
4972
vertexAttribFormat(GLuint attribIndex,GLint size,VertexAttribType type,GLboolean normalized,GLuint relativeOffset)4973 void Context::vertexAttribFormat(GLuint attribIndex,
4974 GLint size,
4975 VertexAttribType type,
4976 GLboolean normalized,
4977 GLuint relativeOffset)
4978 {
4979 mState.setVertexAttribFormat(attribIndex, size, type, ConvertToBool(normalized), false,
4980 relativeOffset);
4981 mStateCache.onVertexArrayFormatChange(this);
4982 }
4983
vertexAttribIFormat(GLuint attribIndex,GLint size,VertexAttribType type,GLuint relativeOffset)4984 void Context::vertexAttribIFormat(GLuint attribIndex,
4985 GLint size,
4986 VertexAttribType type,
4987 GLuint relativeOffset)
4988 {
4989 mState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
4990 mStateCache.onVertexArrayFormatChange(this);
4991 }
4992
vertexAttribBinding(GLuint attribIndex,GLuint bindingIndex)4993 void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
4994 {
4995 mState.setVertexAttribBinding(this, attribIndex, bindingIndex);
4996 mStateCache.onVertexArrayStateChange(this);
4997 }
4998
vertexBindingDivisor(GLuint bindingIndex,GLuint divisor)4999 void Context::vertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
5000 {
5001 mState.setVertexBindingDivisor(bindingIndex, divisor);
5002 mStateCache.onVertexArrayFormatChange(this);
5003 }
5004
viewport(GLint x,GLint y,GLsizei width,GLsizei height)5005 void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
5006 {
5007 mState.setViewportParams(x, y, width, height);
5008 }
5009
vertexAttribIPointer(GLuint index,GLint size,VertexAttribType type,GLsizei stride,const void * pointer)5010 void Context::vertexAttribIPointer(GLuint index,
5011 GLint size,
5012 VertexAttribType type,
5013 GLsizei stride,
5014 const void *pointer)
5015 {
5016 mState.setVertexAttribIPointer(this, index, mState.getTargetBuffer(BufferBinding::Array), size,
5017 type, stride, pointer);
5018 mStateCache.onVertexArrayStateChange(this);
5019 }
5020
vertexAttribI4i(GLuint index,GLint x,GLint y,GLint z,GLint w)5021 void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
5022 {
5023 GLint vals[4] = {x, y, z, w};
5024 mState.setVertexAttribi(index, vals);
5025 mStateCache.onDefaultVertexAttributeChange(this);
5026 }
5027
vertexAttribI4ui(GLuint index,GLuint x,GLuint y,GLuint z,GLuint w)5028 void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
5029 {
5030 GLuint vals[4] = {x, y, z, w};
5031 mState.setVertexAttribu(index, vals);
5032 mStateCache.onDefaultVertexAttributeChange(this);
5033 }
5034
vertexAttribI4iv(GLuint index,const GLint * v)5035 void Context::vertexAttribI4iv(GLuint index, const GLint *v)
5036 {
5037 mState.setVertexAttribi(index, v);
5038 mStateCache.onDefaultVertexAttributeChange(this);
5039 }
5040
vertexAttribI4uiv(GLuint index,const GLuint * v)5041 void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
5042 {
5043 mState.setVertexAttribu(index, v);
5044 mStateCache.onDefaultVertexAttributeChange(this);
5045 }
5046
getVertexAttribivImpl(GLuint index,GLenum pname,GLint * params) const5047 void Context::getVertexAttribivImpl(GLuint index, GLenum pname, GLint *params) const
5048 {
5049 const VertexAttribCurrentValueData ¤tValues =
5050 getState().getVertexAttribCurrentValue(index);
5051 const VertexArray *vao = getState().getVertexArray();
5052 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
5053 currentValues, pname, params);
5054 }
5055
getVertexAttribiv(GLuint index,GLenum pname,GLint * params)5056 void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
5057 {
5058 return getVertexAttribivImpl(index, pname, params);
5059 }
5060
getVertexAttribivRobust(GLuint index,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)5061 void Context::getVertexAttribivRobust(GLuint index,
5062 GLenum pname,
5063 GLsizei bufSize,
5064 GLsizei *length,
5065 GLint *params)
5066 {
5067 getVertexAttribiv(index, pname, params);
5068 }
5069
getVertexAttribfv(GLuint index,GLenum pname,GLfloat * params)5070 void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
5071 {
5072 const VertexAttribCurrentValueData ¤tValues =
5073 getState().getVertexAttribCurrentValue(index);
5074 const VertexArray *vao = getState().getVertexArray();
5075 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
5076 currentValues, pname, params);
5077 }
5078
getVertexAttribfvRobust(GLuint index,GLenum pname,GLsizei bufSize,GLsizei * length,GLfloat * params)5079 void Context::getVertexAttribfvRobust(GLuint index,
5080 GLenum pname,
5081 GLsizei bufSize,
5082 GLsizei *length,
5083 GLfloat *params)
5084 {
5085 getVertexAttribfv(index, pname, params);
5086 }
5087
getVertexAttribIiv(GLuint index,GLenum pname,GLint * params)5088 void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
5089 {
5090 const VertexAttribCurrentValueData ¤tValues =
5091 getState().getVertexAttribCurrentValue(index);
5092 const VertexArray *vao = getState().getVertexArray();
5093 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
5094 currentValues, pname, params);
5095 }
5096
getVertexAttribIivRobust(GLuint index,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)5097 void Context::getVertexAttribIivRobust(GLuint index,
5098 GLenum pname,
5099 GLsizei bufSize,
5100 GLsizei *length,
5101 GLint *params)
5102 {
5103 getVertexAttribIiv(index, pname, params);
5104 }
5105
getVertexAttribIuiv(GLuint index,GLenum pname,GLuint * params)5106 void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
5107 {
5108 const VertexAttribCurrentValueData ¤tValues =
5109 getState().getVertexAttribCurrentValue(index);
5110 const VertexArray *vao = getState().getVertexArray();
5111 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
5112 currentValues, pname, params);
5113 }
5114
getVertexAttribIuivRobust(GLuint index,GLenum pname,GLsizei bufSize,GLsizei * length,GLuint * params)5115 void Context::getVertexAttribIuivRobust(GLuint index,
5116 GLenum pname,
5117 GLsizei bufSize,
5118 GLsizei *length,
5119 GLuint *params)
5120 {
5121 getVertexAttribIuiv(index, pname, params);
5122 }
5123
getVertexAttribPointerv(GLuint index,GLenum pname,void ** pointer)5124 void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
5125 {
5126 const VertexAttribute &attrib = getState().getVertexArray()->getVertexAttribute(index);
5127 QueryVertexAttribPointerv(attrib, pname, pointer);
5128 }
5129
getVertexAttribPointervRobust(GLuint index,GLenum pname,GLsizei bufSize,GLsizei * length,void ** pointer)5130 void Context::getVertexAttribPointervRobust(GLuint index,
5131 GLenum pname,
5132 GLsizei bufSize,
5133 GLsizei *length,
5134 void **pointer)
5135 {
5136 getVertexAttribPointerv(index, pname, pointer);
5137 }
5138
debugMessageControl(GLenum source,GLenum type,GLenum severity,GLsizei count,const GLuint * ids,GLboolean enabled)5139 void Context::debugMessageControl(GLenum source,
5140 GLenum type,
5141 GLenum severity,
5142 GLsizei count,
5143 const GLuint *ids,
5144 GLboolean enabled)
5145 {
5146 std::vector<GLuint> idVector(ids, ids + count);
5147 mState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
5148 ConvertToBool(enabled));
5149 }
5150
debugMessageInsert(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar * buf)5151 void Context::debugMessageInsert(GLenum source,
5152 GLenum type,
5153 GLuint id,
5154 GLenum severity,
5155 GLsizei length,
5156 const GLchar *buf)
5157 {
5158 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
5159 mState.getDebug().insertMessage(source, type, id, severity, std::move(msg), gl::LOG_INFO);
5160 }
5161
debugMessageCallback(GLDEBUGPROCKHR callback,const void * userParam)5162 void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
5163 {
5164 mState.getDebug().setCallback(callback, userParam);
5165 }
5166
getDebugMessageLog(GLuint count,GLsizei bufSize,GLenum * sources,GLenum * types,GLuint * ids,GLenum * severities,GLsizei * lengths,GLchar * messageLog)5167 GLuint Context::getDebugMessageLog(GLuint count,
5168 GLsizei bufSize,
5169 GLenum *sources,
5170 GLenum *types,
5171 GLuint *ids,
5172 GLenum *severities,
5173 GLsizei *lengths,
5174 GLchar *messageLog)
5175 {
5176 return static_cast<GLuint>(mState.getDebug().getMessages(count, bufSize, sources, types, ids,
5177 severities, lengths, messageLog));
5178 }
5179
pushDebugGroup(GLenum source,GLuint id,GLsizei length,const GLchar * message)5180 void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
5181 {
5182 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
5183 ANGLE_CONTEXT_TRY(mImplementation->pushDebugGroup(this, source, id, msg));
5184 mState.getDebug().pushGroup(source, id, std::move(msg));
5185 }
5186
popDebugGroup()5187 void Context::popDebugGroup()
5188 {
5189 mState.getDebug().popGroup();
5190 ANGLE_CONTEXT_TRY(mImplementation->popDebugGroup(this));
5191 }
5192
primitiveBoundingBox(GLfloat minX,GLfloat minY,GLfloat minZ,GLfloat minW,GLfloat maxX,GLfloat maxY,GLfloat maxZ,GLfloat maxW)5193 void Context::primitiveBoundingBox(GLfloat minX,
5194 GLfloat minY,
5195 GLfloat minZ,
5196 GLfloat minW,
5197 GLfloat maxX,
5198 GLfloat maxY,
5199 GLfloat maxZ,
5200 GLfloat maxW)
5201 {
5202 UNIMPLEMENTED();
5203 }
5204
bufferData(BufferBinding target,GLsizeiptr size,const void * data,BufferUsage usage)5205 void Context::bufferData(BufferBinding target, GLsizeiptr size, const void *data, BufferUsage usage)
5206 {
5207 Buffer *buffer = mState.getTargetBuffer(target);
5208 ASSERT(buffer);
5209 ANGLE_CONTEXT_TRY(buffer->bufferData(this, target, data, size, usage));
5210 }
5211
bufferSubData(BufferBinding target,GLintptr offset,GLsizeiptr size,const void * data)5212 void Context::bufferSubData(BufferBinding target,
5213 GLintptr offset,
5214 GLsizeiptr size,
5215 const void *data)
5216 {
5217 if (data == nullptr || size == 0)
5218 {
5219 return;
5220 }
5221
5222 Buffer *buffer = mState.getTargetBuffer(target);
5223 ASSERT(buffer);
5224 ANGLE_CONTEXT_TRY(buffer->bufferSubData(this, target, data, size, offset));
5225 }
5226
attachShader(ShaderProgramID program,ShaderProgramID shader)5227 void Context::attachShader(ShaderProgramID program, ShaderProgramID shader)
5228 {
5229 Program *programObject = mState.mShaderProgramManager->getProgram(program);
5230 Shader *shaderObject = mState.mShaderProgramManager->getShader(shader);
5231 ASSERT(programObject && shaderObject);
5232 programObject->attachShader(this, shaderObject);
5233 }
5234
copyBufferSubData(BufferBinding readTarget,BufferBinding writeTarget,GLintptr readOffset,GLintptr writeOffset,GLsizeiptr size)5235 void Context::copyBufferSubData(BufferBinding readTarget,
5236 BufferBinding writeTarget,
5237 GLintptr readOffset,
5238 GLintptr writeOffset,
5239 GLsizeiptr size)
5240 {
5241 // if size is zero, the copy is a successful no-op
5242 if (size == 0)
5243 {
5244 return;
5245 }
5246
5247 // TODO(jmadill): cache these.
5248 Buffer *readBuffer = mState.getTargetBuffer(readTarget);
5249 Buffer *writeBuffer = mState.getTargetBuffer(writeTarget);
5250
5251 ANGLE_CONTEXT_TRY(
5252 writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
5253 }
5254
bindAttribLocation(ShaderProgramID program,GLuint index,const GLchar * name)5255 void Context::bindAttribLocation(ShaderProgramID program, GLuint index, const GLchar *name)
5256 {
5257 // Ideally we could share the program query with the validation layer if possible.
5258 Program *programObject = getProgramResolveLink(program);
5259 ASSERT(programObject);
5260 programObject->bindAttributeLocation(index, name);
5261 }
5262
bindBufferBase(BufferBinding target,GLuint index,BufferID buffer)5263 void Context::bindBufferBase(BufferBinding target, GLuint index, BufferID buffer)
5264 {
5265 bindBufferRange(target, index, buffer, 0, 0);
5266 }
5267
bindBufferRange(BufferBinding target,GLuint index,BufferID buffer,GLintptr offset,GLsizeiptr size)5268 void Context::bindBufferRange(BufferBinding target,
5269 GLuint index,
5270 BufferID buffer,
5271 GLintptr offset,
5272 GLsizeiptr size)
5273 {
5274 Buffer *object = mState.mBufferManager->checkBufferAllocation(mImplementation.get(), buffer);
5275 ANGLE_CONTEXT_TRY(mState.setIndexedBufferBinding(this, target, index, object, offset, size));
5276 if (target == BufferBinding::Uniform)
5277 {
5278 mUniformBufferObserverBindings[index].bind(object);
5279 mStateCache.onUniformBufferStateChange(this);
5280 }
5281 else
5282 {
5283 mStateCache.onBufferBindingChange(this);
5284 }
5285 }
5286
bindFramebuffer(GLenum target,FramebufferID framebuffer)5287 void Context::bindFramebuffer(GLenum target, FramebufferID framebuffer)
5288 {
5289 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
5290 {
5291 bindReadFramebuffer(framebuffer);
5292 }
5293
5294 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
5295 {
5296 bindDrawFramebuffer(framebuffer);
5297 }
5298 }
5299
bindRenderbuffer(GLenum target,RenderbufferID renderbuffer)5300 void Context::bindRenderbuffer(GLenum target, RenderbufferID renderbuffer)
5301 {
5302 ASSERT(target == GL_RENDERBUFFER);
5303 Renderbuffer *object = mState.mRenderbufferManager->checkRenderbufferAllocation(
5304 mImplementation.get(), renderbuffer);
5305 mState.setRenderbufferBinding(this, object);
5306 }
5307
texStorage2DMultisample(TextureType target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,GLboolean fixedsamplelocations)5308 void Context::texStorage2DMultisample(TextureType target,
5309 GLsizei samples,
5310 GLenum internalformat,
5311 GLsizei width,
5312 GLsizei height,
5313 GLboolean fixedsamplelocations)
5314 {
5315 Extents size(width, height, 1);
5316 Texture *texture = getTextureByType(target);
5317 ANGLE_CONTEXT_TRY(texture->setStorageMultisample(this, target, samples, internalformat, size,
5318 ConvertToBool(fixedsamplelocations)));
5319 }
5320
texStorage3DMultisample(TextureType target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedsamplelocations)5321 void Context::texStorage3DMultisample(TextureType target,
5322 GLsizei samples,
5323 GLenum internalformat,
5324 GLsizei width,
5325 GLsizei height,
5326 GLsizei depth,
5327 GLboolean fixedsamplelocations)
5328 {
5329 Extents size(width, height, depth);
5330 Texture *texture = getTextureByType(target);
5331 ANGLE_CONTEXT_TRY(texture->setStorageMultisample(this, target, samples, internalformat, size,
5332 ConvertToBool(fixedsamplelocations)));
5333 }
5334
texImage2DExternal(TextureTarget target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type)5335 void Context::texImage2DExternal(TextureTarget target,
5336 GLint level,
5337 GLint internalformat,
5338 GLsizei width,
5339 GLsizei height,
5340 GLint border,
5341 GLenum format,
5342 GLenum type)
5343 {
5344 Extents size(width, height, 1);
5345 Texture *texture = getTextureByTarget(target);
5346 ANGLE_CONTEXT_TRY(
5347 texture->setImageExternal(this, target, level, internalformat, size, format, type));
5348 }
5349
invalidateTexture(TextureType target)5350 void Context::invalidateTexture(TextureType target)
5351 {
5352 mImplementation->invalidateTexture(target);
5353 mState.invalidateTexture(target);
5354 }
5355
getMultisamplefv(GLenum pname,GLuint index,GLfloat * val)5356 void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
5357 {
5358 // According to spec 3.1 Table 20.49: Framebuffer Dependent Values,
5359 // the sample position should be queried by DRAW_FRAMEBUFFER.
5360 ANGLE_CONTEXT_TRY(mState.syncDirtyObject(this, GL_DRAW_FRAMEBUFFER));
5361 const Framebuffer *framebuffer = mState.getDrawFramebuffer();
5362
5363 switch (pname)
5364 {
5365 case GL_SAMPLE_POSITION:
5366 ANGLE_CONTEXT_TRY(framebuffer->getSamplePosition(this, index, val));
5367 break;
5368 default:
5369 UNREACHABLE();
5370 }
5371 }
5372
getMultisamplefvRobust(GLenum pname,GLuint index,GLsizei bufSize,GLsizei * length,GLfloat * val)5373 void Context::getMultisamplefvRobust(GLenum pname,
5374 GLuint index,
5375 GLsizei bufSize,
5376 GLsizei *length,
5377 GLfloat *val)
5378 {
5379 UNIMPLEMENTED();
5380 }
5381
renderbufferStorage(GLenum target,GLenum internalformat,GLsizei width,GLsizei height)5382 void Context::renderbufferStorage(GLenum target,
5383 GLenum internalformat,
5384 GLsizei width,
5385 GLsizei height)
5386 {
5387 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
5388 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
5389
5390 Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer();
5391 ANGLE_CONTEXT_TRY(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
5392 }
5393
renderbufferStorageMultisample(GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)5394 void Context::renderbufferStorageMultisample(GLenum target,
5395 GLsizei samples,
5396 GLenum internalformat,
5397 GLsizei width,
5398 GLsizei height)
5399 {
5400 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
5401 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
5402
5403 Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer();
5404 ANGLE_CONTEXT_TRY(
5405 renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height));
5406 }
5407
framebufferTexture2DMultisample(GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level,GLsizei samples)5408 void Context::framebufferTexture2DMultisample(GLenum target,
5409 GLenum attachment,
5410 GLenum textarget,
5411 GLuint texture,
5412 GLint level,
5413 GLsizei samples)
5414 {
5415 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
5416 ASSERT(framebuffer);
5417
5418 if (texture != 0)
5419 {
5420 TextureTarget textargetPacked = FromGLenum<TextureTarget>(textarget);
5421 TextureID texturePacked = FromGL<TextureID>(texture);
5422 Texture *textureObj = getTexture(texturePacked);
5423 ImageIndex index = ImageIndex::MakeFromTarget(textargetPacked, level, 1);
5424 framebuffer->setAttachmentMultisample(this, GL_TEXTURE, attachment, index, textureObj,
5425 samples);
5426 }
5427 else
5428 {
5429 framebuffer->resetAttachment(this, attachment);
5430 }
5431
5432 mState.setObjectDirty(target);
5433 }
5434
getSynciv(GLsync sync,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * values)5435 void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
5436 {
5437 const Sync *syncObject = nullptr;
5438 if (!isContextLost())
5439 {
5440 syncObject = getSync(sync);
5441 }
5442 ANGLE_CONTEXT_TRY(QuerySynciv(this, syncObject, pname, bufSize, length, values));
5443 }
5444
getFramebufferParameteriv(GLenum target,GLenum pname,GLint * params)5445 void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
5446 {
5447 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
5448 QueryFramebufferParameteriv(framebuffer, pname, params);
5449 }
5450
getFramebufferParameterivRobust(GLenum target,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)5451 void Context::getFramebufferParameterivRobust(GLenum target,
5452 GLenum pname,
5453 GLsizei bufSize,
5454 GLsizei *length,
5455 GLint *params)
5456 {
5457 UNIMPLEMENTED();
5458 }
5459
framebufferParameteri(GLenum target,GLenum pname,GLint param)5460 void Context::framebufferParameteri(GLenum target, GLenum pname, GLint param)
5461 {
5462 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
5463 SetFramebufferParameteri(this, framebuffer, pname, param);
5464 }
5465
getScratchBuffer(size_t requstedSizeBytes,angle::MemoryBuffer ** scratchBufferOut) const5466 bool Context::getScratchBuffer(size_t requstedSizeBytes,
5467 angle::MemoryBuffer **scratchBufferOut) const
5468 {
5469 if (!mScratchBuffer.valid())
5470 {
5471 mScratchBuffer = mDisplay->requestScratchBuffer();
5472 }
5473
5474 ASSERT(mScratchBuffer.valid());
5475 return mScratchBuffer.value().get(requstedSizeBytes, scratchBufferOut);
5476 }
5477
getScratchBuffer() const5478 angle::ScratchBuffer *Context::getScratchBuffer() const
5479 {
5480 if (!mScratchBuffer.valid())
5481 {
5482 mScratchBuffer = mDisplay->requestScratchBuffer();
5483 }
5484
5485 ASSERT(mScratchBuffer.valid());
5486 return &mScratchBuffer.value();
5487 }
5488
getZeroFilledBuffer(size_t requstedSizeBytes,angle::MemoryBuffer ** zeroBufferOut) const5489 bool Context::getZeroFilledBuffer(size_t requstedSizeBytes,
5490 angle::MemoryBuffer **zeroBufferOut) const
5491 {
5492 if (!mZeroFilledBuffer.valid())
5493 {
5494 mZeroFilledBuffer = mDisplay->requestZeroFilledBuffer();
5495 }
5496
5497 ASSERT(mZeroFilledBuffer.valid());
5498 return mZeroFilledBuffer.value().getInitialized(requstedSizeBytes, zeroBufferOut, 0);
5499 }
5500
dispatchCompute(GLuint numGroupsX,GLuint numGroupsY,GLuint numGroupsZ)5501 void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
5502 {
5503 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
5504 {
5505 return;
5506 }
5507
5508 ANGLE_CONTEXT_TRY(prepareForDispatch());
5509 ANGLE_CONTEXT_TRY(mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ));
5510
5511 MarkShaderStorageBufferUsage(this);
5512 }
5513
dispatchComputeIndirect(GLintptr indirect)5514 void Context::dispatchComputeIndirect(GLintptr indirect)
5515 {
5516 ANGLE_CONTEXT_TRY(prepareForDispatch());
5517 ANGLE_CONTEXT_TRY(mImplementation->dispatchComputeIndirect(this, indirect));
5518
5519 MarkShaderStorageBufferUsage(this);
5520 }
5521
texStorage2D(TextureType target,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height)5522 void Context::texStorage2D(TextureType target,
5523 GLsizei levels,
5524 GLenum internalFormat,
5525 GLsizei width,
5526 GLsizei height)
5527 {
5528 Extents size(width, height, 1);
5529 Texture *texture = getTextureByType(target);
5530 ANGLE_CONTEXT_TRY(texture->setStorage(this, target, levels, internalFormat, size));
5531 }
5532
texStorage3D(TextureType target,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth)5533 void Context::texStorage3D(TextureType target,
5534 GLsizei levels,
5535 GLenum internalFormat,
5536 GLsizei width,
5537 GLsizei height,
5538 GLsizei depth)
5539 {
5540 Extents size(width, height, depth);
5541 Texture *texture = getTextureByType(target);
5542 ANGLE_CONTEXT_TRY(texture->setStorage(this, target, levels, internalFormat, size));
5543 }
5544
memoryBarrier(GLbitfield barriers)5545 void Context::memoryBarrier(GLbitfield barriers)
5546 {
5547 ANGLE_CONTEXT_TRY(mImplementation->memoryBarrier(this, barriers));
5548 }
5549
memoryBarrierByRegion(GLbitfield barriers)5550 void Context::memoryBarrierByRegion(GLbitfield barriers)
5551 {
5552 ANGLE_CONTEXT_TRY(mImplementation->memoryBarrierByRegion(this, barriers));
5553 }
5554
multiDrawArrays(PrimitiveMode mode,const GLint * firsts,const GLsizei * counts,GLsizei drawcount)5555 void Context::multiDrawArrays(PrimitiveMode mode,
5556 const GLint *firsts,
5557 const GLsizei *counts,
5558 GLsizei drawcount)
5559 {
5560 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
5561 Program *programObject = mState.getLinkedProgram(this);
5562 const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
5563 if (hasDrawID)
5564 {
5565 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
5566 {
5567 if (noopDraw(mode, counts[drawID]))
5568 {
5569 continue;
5570 }
5571 programObject->setDrawIDUniform(drawID);
5572 ANGLE_CONTEXT_TRY(
5573 mImplementation->drawArrays(this, mode, firsts[drawID], counts[drawID]));
5574 MarkTransformFeedbackBufferUsage(this, counts[drawID], 1);
5575 MarkShaderStorageBufferUsage(this);
5576 }
5577 }
5578 else
5579 {
5580 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
5581 {
5582 if (noopDraw(mode, counts[drawID]))
5583 {
5584 continue;
5585 }
5586 ANGLE_CONTEXT_TRY(
5587 mImplementation->drawArrays(this, mode, firsts[drawID], counts[drawID]));
5588 MarkTransformFeedbackBufferUsage(this, counts[drawID], 1);
5589 MarkShaderStorageBufferUsage(this);
5590 }
5591 }
5592 }
5593
multiDrawArraysInstanced(PrimitiveMode mode,const GLint * firsts,const GLsizei * counts,const GLsizei * instanceCounts,GLsizei drawcount)5594 void Context::multiDrawArraysInstanced(PrimitiveMode mode,
5595 const GLint *firsts,
5596 const GLsizei *counts,
5597 const GLsizei *instanceCounts,
5598 GLsizei drawcount)
5599 {
5600 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
5601 Program *programObject = mState.getLinkedProgram(this);
5602 const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
5603 if (hasDrawID)
5604 {
5605 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
5606 {
5607 if (noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID]))
5608 {
5609 continue;
5610 }
5611 programObject->setDrawIDUniform(drawID);
5612 ANGLE_CONTEXT_TRY(mImplementation->drawArraysInstanced(
5613 this, mode, firsts[drawID], counts[drawID], instanceCounts[drawID]));
5614 MarkTransformFeedbackBufferUsage(this, counts[drawID], instanceCounts[drawID]);
5615 MarkShaderStorageBufferUsage(this);
5616 }
5617 }
5618 else
5619 {
5620 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
5621 {
5622 if (noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID]))
5623 {
5624 continue;
5625 }
5626 ANGLE_CONTEXT_TRY(mImplementation->drawArraysInstanced(
5627 this, mode, firsts[drawID], counts[drawID], instanceCounts[drawID]));
5628 MarkTransformFeedbackBufferUsage(this, counts[drawID], instanceCounts[drawID]);
5629 MarkShaderStorageBufferUsage(this);
5630 }
5631 }
5632 }
5633
multiDrawElements(PrimitiveMode mode,const GLsizei * counts,DrawElementsType type,const GLvoid * const * indices,GLsizei drawcount)5634 void Context::multiDrawElements(PrimitiveMode mode,
5635 const GLsizei *counts,
5636 DrawElementsType type,
5637 const GLvoid *const *indices,
5638 GLsizei drawcount)
5639 {
5640 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
5641 Program *programObject = mState.getLinkedProgram(this);
5642 const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
5643 if (hasDrawID)
5644 {
5645 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
5646 {
5647 if (noopDraw(mode, counts[drawID]))
5648 {
5649 continue;
5650 }
5651 programObject->setDrawIDUniform(drawID);
5652 ANGLE_CONTEXT_TRY(
5653 mImplementation->drawElements(this, mode, counts[drawID], type, indices[drawID]));
5654 MarkShaderStorageBufferUsage(this);
5655 }
5656 }
5657 else
5658 {
5659 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
5660 {
5661 if (noopDraw(mode, counts[drawID]))
5662 {
5663 continue;
5664 }
5665 ANGLE_CONTEXT_TRY(
5666 mImplementation->drawElements(this, mode, counts[drawID], type, indices[drawID]));
5667 MarkShaderStorageBufferUsage(this);
5668 }
5669 }
5670 }
5671
multiDrawElementsInstanced(PrimitiveMode mode,const GLsizei * counts,DrawElementsType type,const GLvoid * const * indices,const GLsizei * instanceCounts,GLsizei drawcount)5672 void Context::multiDrawElementsInstanced(PrimitiveMode mode,
5673 const GLsizei *counts,
5674 DrawElementsType type,
5675 const GLvoid *const *indices,
5676 const GLsizei *instanceCounts,
5677 GLsizei drawcount)
5678 {
5679 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
5680 Program *programObject = mState.getLinkedProgram(this);
5681 const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
5682 if (hasDrawID)
5683 {
5684 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
5685 {
5686 if (noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID]))
5687 {
5688 continue;
5689 }
5690 programObject->setDrawIDUniform(drawID);
5691 ANGLE_CONTEXT_TRY(mImplementation->drawElementsInstanced(
5692 this, mode, counts[drawID], type, indices[drawID], instanceCounts[drawID]));
5693 MarkShaderStorageBufferUsage(this);
5694 }
5695 }
5696 else
5697 {
5698 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
5699 {
5700 if (noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID]))
5701 {
5702 continue;
5703 }
5704 ANGLE_CONTEXT_TRY(mImplementation->drawElementsInstanced(
5705 this, mode, counts[drawID], type, indices[drawID], instanceCounts[drawID]));
5706 MarkShaderStorageBufferUsage(this);
5707 }
5708 }
5709 }
5710
5711 namespace
5712 {
5713
5714 // RAII object making sure reset uniforms is called no matter whether there's an error in draw calls
5715 class ResetBaseVertexBaseInstance : angle::NonCopyable
5716 {
5717 public:
ResetBaseVertexBaseInstance(Program * programObject,bool resetBaseVertex,bool resetBaseInstance)5718 ResetBaseVertexBaseInstance(Program *programObject,
5719 bool resetBaseVertex,
5720 bool resetBaseInstance)
5721 : mProgramObject(programObject),
5722 mResetBaseVertex(resetBaseVertex),
5723 mResetBaseInstance(resetBaseInstance)
5724 {}
5725
~ResetBaseVertexBaseInstance()5726 ~ResetBaseVertexBaseInstance()
5727 {
5728 if (mProgramObject)
5729 {
5730 // Reset emulated uniforms to zero to avoid affecting other draw calls
5731 if (mResetBaseVertex)
5732 {
5733 mProgramObject->setBaseVertexUniform(0);
5734 }
5735
5736 if (mResetBaseInstance)
5737 {
5738 mProgramObject->setBaseInstanceUniform(0);
5739 }
5740 }
5741 }
5742
5743 private:
5744 Program *mProgramObject;
5745 bool mResetBaseVertex;
5746 bool mResetBaseInstance;
5747 };
5748
5749 } // anonymous namespace
5750
drawArraysInstancedBaseInstance(PrimitiveMode mode,GLint first,GLsizei count,GLsizei instanceCount,GLuint baseInstance)5751 void Context::drawArraysInstancedBaseInstance(PrimitiveMode mode,
5752 GLint first,
5753 GLsizei count,
5754 GLsizei instanceCount,
5755 GLuint baseInstance)
5756 {
5757 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
5758 Program *programObject = mState.getLinkedProgram(this);
5759
5760 if (noopDraw(mode, count))
5761 {
5762 return;
5763 }
5764
5765 const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform();
5766 if (hasBaseInstance)
5767 {
5768 programObject->setBaseInstanceUniform(baseInstance);
5769 }
5770
5771 ResetBaseVertexBaseInstance resetUniforms(programObject, false, hasBaseInstance);
5772
5773 // The input gl_InstanceID does not follow the baseinstance. gl_InstanceID always falls on
5774 // the half-open range [0, instancecount). No need to set other stuff. Except for Vulkan.
5775
5776 ANGLE_CONTEXT_TRY(mImplementation->drawArraysInstancedBaseInstance(
5777 this, mode, first, count, instanceCount, baseInstance));
5778 MarkTransformFeedbackBufferUsage(this, count, 1);
5779 }
5780
drawElementsInstancedBaseVertexBaseInstance(PrimitiveMode mode,GLsizei count,DrawElementsType type,const GLvoid * indices,GLsizei instanceCounts,GLint baseVertex,GLuint baseInstance)5781 void Context::drawElementsInstancedBaseVertexBaseInstance(PrimitiveMode mode,
5782 GLsizei count,
5783 DrawElementsType type,
5784 const GLvoid *indices,
5785 GLsizei instanceCounts,
5786 GLint baseVertex,
5787 GLuint baseInstance)
5788 {
5789 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
5790 Program *programObject = mState.getLinkedProgram(this);
5791
5792 if (noopDraw(mode, count))
5793 {
5794 return;
5795 }
5796
5797 const bool hasBaseVertex = programObject && programObject->hasBaseVertexUniform();
5798 if (hasBaseVertex)
5799 {
5800 programObject->setBaseVertexUniform(baseVertex);
5801 }
5802
5803 const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform();
5804 if (hasBaseInstance)
5805 {
5806 programObject->setBaseInstanceUniform(baseInstance);
5807 }
5808
5809 ResetBaseVertexBaseInstance resetUniforms(programObject, hasBaseVertex, hasBaseInstance);
5810
5811 ANGLE_CONTEXT_TRY(mImplementation->drawElementsInstancedBaseVertexBaseInstance(
5812 this, mode, count, type, indices, instanceCounts, baseVertex, baseInstance));
5813 }
5814
5815 #define SET_DRAW_ID_UNIFORM_0(drawID) \
5816 {}
5817 #define SET_DRAW_ID_UNIFORM_1(drawID) programObject->setDrawIDUniform(drawID);
5818 #define SET_DRAW_ID_UNIFORM(cond) SET_DRAW_ID_UNIFORM_##cond
5819
5820 #define SET_BASE_VERTEX_UNIFORM_0(baseVertex) \
5821 {}
5822 #define SET_BASE_VERTEX_UNIFORM_1(baseVertex) programObject->setBaseVertexUniform(baseVertex);
5823 #define SET_BASE_VERTEX_UNIFORM(cond) SET_BASE_VERTEX_UNIFORM_##cond
5824
5825 #define SET_BASE_INSTANCE_UNIFORM_0(baseInstance) \
5826 {}
5827 #define SET_BASE_INSTANCE_UNIFORM_1(baseInstance) \
5828 programObject->setBaseInstanceUniform(baseInstance);
5829 #define SET_BASE_INSTANCE_UNIFORM(cond) SET_BASE_INSTANCE_UNIFORM_##cond
5830
5831 #define MULTI_DRAW_ARRAYS_BLOCK(hasDrawID, hasBaseInstance) \
5832 for (GLsizei drawID = 0; drawID < drawcount; ++drawID) \
5833 { \
5834 if (noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID])) \
5835 { \
5836 continue; \
5837 } \
5838 SET_DRAW_ID_UNIFORM(hasDrawID)(drawID); \
5839 SET_BASE_INSTANCE_UNIFORM(hasBaseInstance)(baseInstances[drawID]); \
5840 ANGLE_CONTEXT_TRY(mImplementation->drawArraysInstancedBaseInstance( \
5841 this, mode, firsts[drawID], counts[drawID], instanceCounts[drawID], \
5842 baseInstances[drawID])); \
5843 MarkTransformFeedbackBufferUsage(this, counts[drawID], instanceCounts[drawID]); \
5844 }
5845
5846 #define MULTI_DRAW_ELEMENTS_BLOCK(hasDrawID, hasBaseVertex, hasBaseInstance) \
5847 for (GLsizei drawID = 0; drawID < drawcount; ++drawID) \
5848 { \
5849 if (noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID])) \
5850 { \
5851 continue; \
5852 } \
5853 SET_DRAW_ID_UNIFORM(hasDrawID)(drawID); \
5854 SET_BASE_VERTEX_UNIFORM(hasBaseVertex)(baseVertices[drawID]); \
5855 SET_BASE_INSTANCE_UNIFORM(hasBaseInstance)(baseInstances[drawID]); \
5856 ANGLE_CONTEXT_TRY(mImplementation->drawElementsInstancedBaseVertexBaseInstance( \
5857 this, mode, counts[drawID], type, indices[drawID], instanceCounts[drawID], \
5858 baseVertices[drawID], baseInstances[drawID])); \
5859 }
5860
multiDrawArraysInstancedBaseInstance(PrimitiveMode mode,const GLint * firsts,const GLsizei * counts,const GLsizei * instanceCounts,const GLuint * baseInstances,GLsizei drawcount)5861 void Context::multiDrawArraysInstancedBaseInstance(PrimitiveMode mode,
5862 const GLint *firsts,
5863 const GLsizei *counts,
5864 const GLsizei *instanceCounts,
5865 const GLuint *baseInstances,
5866 GLsizei drawcount)
5867 {
5868 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
5869 Program *programObject = mState.getLinkedProgram(this);
5870 const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform();
5871 const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
5872
5873 ResetBaseVertexBaseInstance resetUniforms(programObject, false, hasBaseInstance);
5874
5875 if (hasDrawID && hasBaseInstance)
5876 {
5877 MULTI_DRAW_ARRAYS_BLOCK(1, 1)
5878 }
5879 else if (hasDrawID)
5880 {
5881 MULTI_DRAW_ARRAYS_BLOCK(1, 0)
5882 }
5883 else if (hasBaseInstance)
5884 {
5885 MULTI_DRAW_ARRAYS_BLOCK(0, 1)
5886 }
5887 else
5888 {
5889 MULTI_DRAW_ARRAYS_BLOCK(0, 0)
5890 }
5891 }
5892
multiDrawElementsInstancedBaseVertexBaseInstance(PrimitiveMode mode,const GLsizei * counts,DrawElementsType type,const GLvoid * const * indices,const GLsizei * instanceCounts,const GLint * baseVertices,const GLuint * baseInstances,GLsizei drawcount)5893 void Context::multiDrawElementsInstancedBaseVertexBaseInstance(PrimitiveMode mode,
5894 const GLsizei *counts,
5895 DrawElementsType type,
5896 const GLvoid *const *indices,
5897 const GLsizei *instanceCounts,
5898 const GLint *baseVertices,
5899 const GLuint *baseInstances,
5900 GLsizei drawcount)
5901 {
5902 ANGLE_CONTEXT_TRY(prepareForDraw(mode));
5903 Program *programObject = mState.getLinkedProgram(this);
5904 const bool hasBaseVertex = programObject && programObject->hasBaseVertexUniform();
5905 const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform();
5906 const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
5907
5908 ResetBaseVertexBaseInstance resetUniforms(programObject, hasBaseVertex, hasBaseInstance);
5909
5910 if (hasDrawID)
5911 {
5912 if (hasBaseVertex)
5913 {
5914 if (hasBaseInstance)
5915 {
5916 MULTI_DRAW_ELEMENTS_BLOCK(1, 1, 1)
5917 }
5918 else
5919 {
5920 MULTI_DRAW_ELEMENTS_BLOCK(1, 1, 0)
5921 }
5922 }
5923 else
5924 {
5925 if (hasBaseInstance)
5926 {
5927 MULTI_DRAW_ELEMENTS_BLOCK(1, 0, 1)
5928 }
5929 else
5930 {
5931 MULTI_DRAW_ELEMENTS_BLOCK(1, 0, 0)
5932 }
5933 }
5934 }
5935 else
5936 {
5937 if (hasBaseVertex)
5938 {
5939 if (hasBaseInstance)
5940 {
5941 MULTI_DRAW_ELEMENTS_BLOCK(0, 1, 1)
5942 }
5943 else
5944 {
5945 MULTI_DRAW_ELEMENTS_BLOCK(0, 1, 0)
5946 }
5947 }
5948 else
5949 {
5950 if (hasBaseInstance)
5951 {
5952 MULTI_DRAW_ELEMENTS_BLOCK(0, 0, 1)
5953 }
5954 else
5955 {
5956 MULTI_DRAW_ELEMENTS_BLOCK(0, 0, 0)
5957 }
5958 }
5959 }
5960 }
5961
provokingVertex(ProvokingVertexConvention provokeMode)5962 void Context::provokingVertex(ProvokingVertexConvention provokeMode)
5963 {
5964 mState.setProvokingVertex(provokeMode);
5965 }
5966
checkFramebufferStatus(GLenum target)5967 GLenum Context::checkFramebufferStatus(GLenum target)
5968 {
5969 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
5970 ASSERT(framebuffer);
5971 return framebuffer->checkStatus(this);
5972 }
5973
compileShader(ShaderProgramID shader)5974 void Context::compileShader(ShaderProgramID shader)
5975 {
5976 Shader *shaderObject = GetValidShader(this, shader);
5977 if (!shaderObject)
5978 {
5979 return;
5980 }
5981 shaderObject->compile(this);
5982 }
5983
deleteBuffers(GLsizei n,const BufferID * buffers)5984 void Context::deleteBuffers(GLsizei n, const BufferID *buffers)
5985 {
5986 for (int i = 0; i < n; i++)
5987 {
5988 deleteBuffer(buffers[i]);
5989 }
5990 }
5991
deleteFramebuffers(GLsizei n,const FramebufferID * framebuffers)5992 void Context::deleteFramebuffers(GLsizei n, const FramebufferID *framebuffers)
5993 {
5994 for (int i = 0; i < n; i++)
5995 {
5996 if (framebuffers[i].value != 0)
5997 {
5998 deleteFramebuffer(framebuffers[i]);
5999 }
6000 }
6001 }
6002
deleteRenderbuffers(GLsizei n,const RenderbufferID * renderbuffers)6003 void Context::deleteRenderbuffers(GLsizei n, const RenderbufferID *renderbuffers)
6004 {
6005 for (int i = 0; i < n; i++)
6006 {
6007 deleteRenderbuffer(renderbuffers[i]);
6008 }
6009 }
6010
deleteTextures(GLsizei n,const TextureID * textures)6011 void Context::deleteTextures(GLsizei n, const TextureID *textures)
6012 {
6013 for (int i = 0; i < n; i++)
6014 {
6015 if (textures[i].value != 0)
6016 {
6017 deleteTexture(textures[i]);
6018 }
6019 }
6020 }
6021
detachShader(ShaderProgramID program,ShaderProgramID shader)6022 void Context::detachShader(ShaderProgramID program, ShaderProgramID shader)
6023 {
6024 Program *programObject = getProgramNoResolveLink(program);
6025 ASSERT(programObject);
6026
6027 Shader *shaderObject = getShader(shader);
6028 ASSERT(shaderObject);
6029
6030 programObject->detachShader(this, shaderObject);
6031 }
6032
genBuffers(GLsizei n,BufferID * buffers)6033 void Context::genBuffers(GLsizei n, BufferID *buffers)
6034 {
6035 for (int i = 0; i < n; i++)
6036 {
6037 buffers[i] = createBuffer();
6038 }
6039 }
6040
genFramebuffers(GLsizei n,FramebufferID * framebuffers)6041 void Context::genFramebuffers(GLsizei n, FramebufferID *framebuffers)
6042 {
6043 for (int i = 0; i < n; i++)
6044 {
6045 framebuffers[i] = createFramebuffer();
6046 }
6047 }
6048
genRenderbuffers(GLsizei n,RenderbufferID * renderbuffers)6049 void Context::genRenderbuffers(GLsizei n, RenderbufferID *renderbuffers)
6050 {
6051 for (int i = 0; i < n; i++)
6052 {
6053 renderbuffers[i] = createRenderbuffer();
6054 }
6055 }
6056
genTextures(GLsizei n,TextureID * textures)6057 void Context::genTextures(GLsizei n, TextureID *textures)
6058 {
6059 for (int i = 0; i < n; i++)
6060 {
6061 textures[i] = createTexture();
6062 }
6063 }
6064
getActiveAttrib(ShaderProgramID program,GLuint index,GLsizei bufsize,GLsizei * length,GLint * size,GLenum * type,GLchar * name)6065 void Context::getActiveAttrib(ShaderProgramID program,
6066 GLuint index,
6067 GLsizei bufsize,
6068 GLsizei *length,
6069 GLint *size,
6070 GLenum *type,
6071 GLchar *name)
6072 {
6073 Program *programObject = getProgramResolveLink(program);
6074 ASSERT(programObject);
6075 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
6076 }
6077
getActiveUniform(ShaderProgramID program,GLuint index,GLsizei bufsize,GLsizei * length,GLint * size,GLenum * type,GLchar * name)6078 void Context::getActiveUniform(ShaderProgramID program,
6079 GLuint index,
6080 GLsizei bufsize,
6081 GLsizei *length,
6082 GLint *size,
6083 GLenum *type,
6084 GLchar *name)
6085 {
6086 Program *programObject = getProgramResolveLink(program);
6087 ASSERT(programObject);
6088 programObject->getActiveUniform(index, bufsize, length, size, type, name);
6089 }
6090
getAttachedShaders(ShaderProgramID program,GLsizei maxcount,GLsizei * count,ShaderProgramID * shaders)6091 void Context::getAttachedShaders(ShaderProgramID program,
6092 GLsizei maxcount,
6093 GLsizei *count,
6094 ShaderProgramID *shaders)
6095 {
6096 Program *programObject = getProgramNoResolveLink(program);
6097 ASSERT(programObject);
6098 programObject->getAttachedShaders(maxcount, count, shaders);
6099 }
6100
getAttribLocation(ShaderProgramID program,const GLchar * name)6101 GLint Context::getAttribLocation(ShaderProgramID program, const GLchar *name)
6102 {
6103 Program *programObject = getProgramResolveLink(program);
6104 ASSERT(programObject);
6105 return programObject->getAttributeLocation(name);
6106 }
6107
getBooleanv(GLenum pname,GLboolean * params)6108 void Context::getBooleanv(GLenum pname, GLboolean *params)
6109 {
6110 GLenum nativeType;
6111 unsigned int numParams = 0;
6112 getQueryParameterInfo(pname, &nativeType, &numParams);
6113
6114 if (nativeType == GL_BOOL)
6115 {
6116 getBooleanvImpl(pname, params);
6117 }
6118 else
6119 {
6120 CastStateValues(this, nativeType, pname, numParams, params);
6121 }
6122 }
6123
getBooleanvRobust(GLenum pname,GLsizei bufSize,GLsizei * length,GLboolean * params)6124 void Context::getBooleanvRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLboolean *params)
6125 {
6126 getBooleanv(pname, params);
6127 }
6128
getFloatv(GLenum pname,GLfloat * params)6129 void Context::getFloatv(GLenum pname, GLfloat *params)
6130 {
6131 GLenum nativeType;
6132 unsigned int numParams = 0;
6133 getQueryParameterInfo(pname, &nativeType, &numParams);
6134
6135 if (nativeType == GL_FLOAT)
6136 {
6137 getFloatvImpl(pname, params);
6138 }
6139 else
6140 {
6141 CastStateValues(this, nativeType, pname, numParams, params);
6142 }
6143 }
6144
getFloatvRobust(GLenum pname,GLsizei bufSize,GLsizei * length,GLfloat * params)6145 void Context::getFloatvRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params)
6146 {
6147 getFloatv(pname, params);
6148 }
6149
getIntegerv(GLenum pname,GLint * params)6150 void Context::getIntegerv(GLenum pname, GLint *params)
6151 {
6152 GLenum nativeType;
6153 unsigned int numParams = 0;
6154 getQueryParameterInfo(pname, &nativeType, &numParams);
6155
6156 if (nativeType == GL_INT)
6157 {
6158 getIntegervImpl(pname, params);
6159 }
6160 else
6161 {
6162 CastStateValues(this, nativeType, pname, numParams, params);
6163 }
6164 }
6165
getIntegervRobust(GLenum pname,GLsizei bufSize,GLsizei * length,GLint * data)6166 void Context::getIntegervRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLint *data)
6167 {
6168 getIntegerv(pname, data);
6169 }
6170
getProgramiv(ShaderProgramID program,GLenum pname,GLint * params)6171 void Context::getProgramiv(ShaderProgramID program, GLenum pname, GLint *params)
6172 {
6173 // Don't resolve link if checking the link completion status.
6174 Program *programObject = getProgramNoResolveLink(program);
6175 if (!isContextLost() && pname != GL_COMPLETION_STATUS_KHR)
6176 {
6177 programObject = getProgramResolveLink(program);
6178 }
6179 ASSERT(programObject);
6180 QueryProgramiv(this, programObject, pname, params);
6181 }
6182
getProgramivRobust(ShaderProgramID program,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)6183 void Context::getProgramivRobust(ShaderProgramID program,
6184 GLenum pname,
6185 GLsizei bufSize,
6186 GLsizei *length,
6187 GLint *params)
6188 {
6189 getProgramiv(program, pname, params);
6190 }
6191
getProgramPipelineiv(ProgramPipelineID pipeline,GLenum pname,GLint * params)6192 void Context::getProgramPipelineiv(ProgramPipelineID pipeline, GLenum pname, GLint *params)
6193 {
6194 ProgramPipeline *programPipeline = nullptr;
6195 if (!mContextLost)
6196 {
6197 programPipeline = getProgramPipeline(pipeline);
6198 }
6199 QueryProgramPipelineiv(this, programPipeline, pname, params);
6200 }
6201
getMemoryObject(MemoryObjectID handle) const6202 MemoryObject *Context::getMemoryObject(MemoryObjectID handle) const
6203 {
6204 return mState.mMemoryObjectManager->getMemoryObject(handle);
6205 }
6206
getSemaphore(SemaphoreID handle) const6207 Semaphore *Context::getSemaphore(SemaphoreID handle) const
6208 {
6209 return mState.mSemaphoreManager->getSemaphore(handle);
6210 }
6211
getProgramInfoLog(ShaderProgramID program,GLsizei bufsize,GLsizei * length,GLchar * infolog)6212 void Context::getProgramInfoLog(ShaderProgramID program,
6213 GLsizei bufsize,
6214 GLsizei *length,
6215 GLchar *infolog)
6216 {
6217 Program *programObject = getProgramResolveLink(program);
6218 ASSERT(programObject);
6219 programObject->getExecutable().getInfoLog(bufsize, length, infolog);
6220 }
6221
getProgramPipelineInfoLog(ProgramPipelineID pipeline,GLsizei bufSize,GLsizei * length,GLchar * infoLog)6222 void Context::getProgramPipelineInfoLog(ProgramPipelineID pipeline,
6223 GLsizei bufSize,
6224 GLsizei *length,
6225 GLchar *infoLog)
6226 {
6227 ProgramPipeline *programPipeline = getProgramPipeline(pipeline);
6228 if (programPipeline)
6229 {
6230 programPipeline->getExecutable().getInfoLog(bufSize, length, infoLog);
6231 }
6232 else
6233 {
6234 *length = 0;
6235 *infoLog = '\0';
6236 }
6237 }
6238
getShaderiv(ShaderProgramID shader,GLenum pname,GLint * params)6239 void Context::getShaderiv(ShaderProgramID shader, GLenum pname, GLint *params)
6240 {
6241 Shader *shaderObject = nullptr;
6242 if (!isContextLost())
6243 {
6244 shaderObject = getShader(shader);
6245 ASSERT(shaderObject);
6246 }
6247 QueryShaderiv(this, shaderObject, pname, params);
6248 }
6249
getShaderivRobust(ShaderProgramID shader,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)6250 void Context::getShaderivRobust(ShaderProgramID shader,
6251 GLenum pname,
6252 GLsizei bufSize,
6253 GLsizei *length,
6254 GLint *params)
6255 {
6256 getShaderiv(shader, pname, params);
6257 }
6258
getShaderInfoLog(ShaderProgramID shader,GLsizei bufsize,GLsizei * length,GLchar * infolog)6259 void Context::getShaderInfoLog(ShaderProgramID shader,
6260 GLsizei bufsize,
6261 GLsizei *length,
6262 GLchar *infolog)
6263 {
6264 Shader *shaderObject = getShader(shader);
6265 ASSERT(shaderObject);
6266 shaderObject->getInfoLog(bufsize, length, infolog);
6267 }
6268
getShaderPrecisionFormat(GLenum shadertype,GLenum precisiontype,GLint * range,GLint * precision)6269 void Context::getShaderPrecisionFormat(GLenum shadertype,
6270 GLenum precisiontype,
6271 GLint *range,
6272 GLint *precision)
6273 {
6274 // TODO(jmadill): Compute shaders.
6275
6276 switch (shadertype)
6277 {
6278 case GL_VERTEX_SHADER:
6279 switch (precisiontype)
6280 {
6281 case GL_LOW_FLOAT:
6282 mState.mCaps.vertexLowpFloat.get(range, precision);
6283 break;
6284 case GL_MEDIUM_FLOAT:
6285 mState.mCaps.vertexMediumpFloat.get(range, precision);
6286 break;
6287 case GL_HIGH_FLOAT:
6288 mState.mCaps.vertexHighpFloat.get(range, precision);
6289 break;
6290
6291 case GL_LOW_INT:
6292 mState.mCaps.vertexLowpInt.get(range, precision);
6293 break;
6294 case GL_MEDIUM_INT:
6295 mState.mCaps.vertexMediumpInt.get(range, precision);
6296 break;
6297 case GL_HIGH_INT:
6298 mState.mCaps.vertexHighpInt.get(range, precision);
6299 break;
6300
6301 default:
6302 UNREACHABLE();
6303 return;
6304 }
6305 break;
6306
6307 case GL_FRAGMENT_SHADER:
6308 switch (precisiontype)
6309 {
6310 case GL_LOW_FLOAT:
6311 mState.mCaps.fragmentLowpFloat.get(range, precision);
6312 break;
6313 case GL_MEDIUM_FLOAT:
6314 mState.mCaps.fragmentMediumpFloat.get(range, precision);
6315 break;
6316 case GL_HIGH_FLOAT:
6317 mState.mCaps.fragmentHighpFloat.get(range, precision);
6318 break;
6319
6320 case GL_LOW_INT:
6321 mState.mCaps.fragmentLowpInt.get(range, precision);
6322 break;
6323 case GL_MEDIUM_INT:
6324 mState.mCaps.fragmentMediumpInt.get(range, precision);
6325 break;
6326 case GL_HIGH_INT:
6327 mState.mCaps.fragmentHighpInt.get(range, precision);
6328 break;
6329
6330 default:
6331 UNREACHABLE();
6332 return;
6333 }
6334 break;
6335
6336 default:
6337 UNREACHABLE();
6338 return;
6339 }
6340 }
6341
getShaderSource(ShaderProgramID shader,GLsizei bufsize,GLsizei * length,GLchar * source)6342 void Context::getShaderSource(ShaderProgramID shader,
6343 GLsizei bufsize,
6344 GLsizei *length,
6345 GLchar *source)
6346 {
6347 Shader *shaderObject = getShader(shader);
6348 ASSERT(shaderObject);
6349 shaderObject->getSource(bufsize, length, source);
6350 }
6351
getUniformfv(ShaderProgramID program,UniformLocation location,GLfloat * params)6352 void Context::getUniformfv(ShaderProgramID program, UniformLocation location, GLfloat *params)
6353 {
6354 Program *programObject = getProgramResolveLink(program);
6355 ASSERT(programObject);
6356 programObject->getUniformfv(this, location, params);
6357 }
6358
getUniformfvRobust(ShaderProgramID program,UniformLocation location,GLsizei bufSize,GLsizei * length,GLfloat * params)6359 void Context::getUniformfvRobust(ShaderProgramID program,
6360 UniformLocation location,
6361 GLsizei bufSize,
6362 GLsizei *length,
6363 GLfloat *params)
6364 {
6365 getUniformfv(program, location, params);
6366 }
6367
getUniformiv(ShaderProgramID program,UniformLocation location,GLint * params)6368 void Context::getUniformiv(ShaderProgramID program, UniformLocation location, GLint *params)
6369 {
6370 Program *programObject = getProgramResolveLink(program);
6371 ASSERT(programObject);
6372 programObject->getUniformiv(this, location, params);
6373 }
6374
getUniformivRobust(ShaderProgramID program,UniformLocation location,GLsizei bufSize,GLsizei * length,GLint * params)6375 void Context::getUniformivRobust(ShaderProgramID program,
6376 UniformLocation location,
6377 GLsizei bufSize,
6378 GLsizei *length,
6379 GLint *params)
6380 {
6381 getUniformiv(program, location, params);
6382 }
6383
getUniformLocation(ShaderProgramID program,const GLchar * name)6384 GLint Context::getUniformLocation(ShaderProgramID program, const GLchar *name)
6385 {
6386 Program *programObject = getProgramResolveLink(program);
6387 ASSERT(programObject);
6388 return programObject->getUniformLocation(name).value;
6389 }
6390
isBuffer(BufferID buffer) const6391 GLboolean Context::isBuffer(BufferID buffer) const
6392 {
6393 if (buffer.value == 0)
6394 {
6395 return GL_FALSE;
6396 }
6397
6398 return ConvertToGLBoolean(getBuffer(buffer));
6399 }
6400
isEnabled(GLenum cap) const6401 GLboolean Context::isEnabled(GLenum cap) const
6402 {
6403 return mState.getEnableFeature(cap);
6404 }
6405
isEnabledi(GLenum target,GLuint index) const6406 GLboolean Context::isEnabledi(GLenum target, GLuint index) const
6407 {
6408 return mState.getEnableFeatureIndexed(target, index);
6409 }
6410
isFramebuffer(FramebufferID framebuffer) const6411 GLboolean Context::isFramebuffer(FramebufferID framebuffer) const
6412 {
6413 if (framebuffer.value == 0)
6414 {
6415 return GL_FALSE;
6416 }
6417
6418 return ConvertToGLBoolean(getFramebuffer(framebuffer));
6419 }
6420
isProgram(ShaderProgramID program) const6421 GLboolean Context::isProgram(ShaderProgramID program) const
6422 {
6423 if (program.value == 0)
6424 {
6425 return GL_FALSE;
6426 }
6427
6428 return ConvertToGLBoolean(getProgramNoResolveLink(program));
6429 }
6430
isRenderbuffer(RenderbufferID renderbuffer) const6431 GLboolean Context::isRenderbuffer(RenderbufferID renderbuffer) const
6432 {
6433 if (renderbuffer.value == 0)
6434 {
6435 return GL_FALSE;
6436 }
6437
6438 return ConvertToGLBoolean(getRenderbuffer(renderbuffer));
6439 }
6440
isShader(ShaderProgramID shader) const6441 GLboolean Context::isShader(ShaderProgramID shader) const
6442 {
6443 if (shader.value == 0)
6444 {
6445 return GL_FALSE;
6446 }
6447
6448 return ConvertToGLBoolean(getShader(shader));
6449 }
6450
isTexture(TextureID texture) const6451 GLboolean Context::isTexture(TextureID texture) const
6452 {
6453 if (texture.value == 0)
6454 {
6455 return GL_FALSE;
6456 }
6457
6458 return ConvertToGLBoolean(getTexture(texture));
6459 }
6460
linkProgram(ShaderProgramID program)6461 void Context::linkProgram(ShaderProgramID program)
6462 {
6463 Program *programObject = getProgramNoResolveLink(program);
6464 ASSERT(programObject);
6465 ANGLE_CONTEXT_TRY(programObject->link(this));
6466 ANGLE_CONTEXT_TRY(onProgramLink(programObject));
6467 }
6468
releaseShaderCompiler()6469 void Context::releaseShaderCompiler()
6470 {
6471 mCompiler.set(this, nullptr);
6472 }
6473
shaderBinary(GLsizei n,const ShaderProgramID * shaders,GLenum binaryformat,const void * binary,GLsizei length)6474 void Context::shaderBinary(GLsizei n,
6475 const ShaderProgramID *shaders,
6476 GLenum binaryformat,
6477 const void *binary,
6478 GLsizei length)
6479 {
6480 // No binary shader formats are supported.
6481 UNIMPLEMENTED();
6482 }
6483
bindFragDataLocationIndexed(ShaderProgramID program,GLuint colorNumber,GLuint index,const char * name)6484 void Context::bindFragDataLocationIndexed(ShaderProgramID program,
6485 GLuint colorNumber,
6486 GLuint index,
6487 const char *name)
6488 {
6489 Program *programObject = getProgramNoResolveLink(program);
6490 programObject->bindFragmentOutputLocation(colorNumber, name);
6491 programObject->bindFragmentOutputIndex(index, name);
6492 }
6493
bindFragDataLocation(ShaderProgramID program,GLuint colorNumber,const char * name)6494 void Context::bindFragDataLocation(ShaderProgramID program, GLuint colorNumber, const char *name)
6495 {
6496 bindFragDataLocationIndexed(program, colorNumber, 0u, name);
6497 }
6498
getFragDataIndex(ShaderProgramID program,const char * name)6499 int Context::getFragDataIndex(ShaderProgramID program, const char *name)
6500 {
6501 Program *programObject = getProgramResolveLink(program);
6502 return programObject->getFragDataIndex(name);
6503 }
6504
getProgramResourceLocationIndex(ShaderProgramID program,GLenum programInterface,const char * name)6505 int Context::getProgramResourceLocationIndex(ShaderProgramID program,
6506 GLenum programInterface,
6507 const char *name)
6508 {
6509 Program *programObject = getProgramResolveLink(program);
6510 ASSERT(programInterface == GL_PROGRAM_OUTPUT);
6511 return programObject->getFragDataIndex(name);
6512 }
6513
shaderSource(ShaderProgramID shader,GLsizei count,const GLchar * const * string,const GLint * length)6514 void Context::shaderSource(ShaderProgramID shader,
6515 GLsizei count,
6516 const GLchar *const *string,
6517 const GLint *length)
6518 {
6519 Shader *shaderObject = getShader(shader);
6520 ASSERT(shaderObject);
6521 shaderObject->setSource(count, string, length);
6522 }
6523
stencilFunc(GLenum func,GLint ref,GLuint mask)6524 void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
6525 {
6526 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
6527 }
6528
stencilMask(GLuint mask)6529 void Context::stencilMask(GLuint mask)
6530 {
6531 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
6532 }
6533
stencilOp(GLenum fail,GLenum zfail,GLenum zpass)6534 void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
6535 {
6536 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
6537 }
6538
patchParameteri(GLenum pname,GLint value)6539 void Context::patchParameteri(GLenum pname, GLint value)
6540 {
6541 UNIMPLEMENTED();
6542 }
6543
getActiveLinkedProgram() const6544 Program *Context::getActiveLinkedProgram() const
6545 {
6546 Program *program = mState.getLinkedProgram(this);
6547 if (!program)
6548 {
6549 ProgramPipeline *programPipelineObject = mState.getProgramPipeline();
6550 if (programPipelineObject)
6551 {
6552 program = programPipelineObject->getLinkedActiveShaderProgram(this);
6553 }
6554 }
6555
6556 return program;
6557 }
6558
uniform1f(UniformLocation location,GLfloat x)6559 void Context::uniform1f(UniformLocation location, GLfloat x)
6560 {
6561 Program *program = getActiveLinkedProgram();
6562 program->setUniform1fv(location, 1, &x);
6563 }
6564
uniform1fv(UniformLocation location,GLsizei count,const GLfloat * v)6565 void Context::uniform1fv(UniformLocation location, GLsizei count, const GLfloat *v)
6566 {
6567 Program *program = getActiveLinkedProgram();
6568 program->setUniform1fv(location, count, v);
6569 }
6570
setUniform1iImpl(Program * program,UniformLocation location,GLsizei count,const GLint * v)6571 void Context::setUniform1iImpl(Program *program,
6572 UniformLocation location,
6573 GLsizei count,
6574 const GLint *v)
6575 {
6576 program->setUniform1iv(this, location, count, v);
6577 }
6578
onSamplerUniformChange(size_t textureUnitIndex)6579 void Context::onSamplerUniformChange(size_t textureUnitIndex)
6580 {
6581 mState.onActiveTextureChange(this, textureUnitIndex);
6582 mStateCache.onActiveTextureChange(this);
6583 }
6584
uniform1i(UniformLocation location,GLint x)6585 void Context::uniform1i(UniformLocation location, GLint x)
6586 {
6587 Program *program = getActiveLinkedProgram();
6588 setUniform1iImpl(program, location, 1, &x);
6589 }
6590
uniform1iv(UniformLocation location,GLsizei count,const GLint * v)6591 void Context::uniform1iv(UniformLocation location, GLsizei count, const GLint *v)
6592 {
6593 Program *program = getActiveLinkedProgram();
6594 setUniform1iImpl(program, location, count, v);
6595 }
6596
uniform2f(UniformLocation location,GLfloat x,GLfloat y)6597 void Context::uniform2f(UniformLocation location, GLfloat x, GLfloat y)
6598 {
6599 GLfloat xy[2] = {x, y};
6600 Program *program = getActiveLinkedProgram();
6601 program->setUniform2fv(location, 1, xy);
6602 }
6603
uniform2fv(UniformLocation location,GLsizei count,const GLfloat * v)6604 void Context::uniform2fv(UniformLocation location, GLsizei count, const GLfloat *v)
6605 {
6606 Program *program = getActiveLinkedProgram();
6607 program->setUniform2fv(location, count, v);
6608 }
6609
uniform2i(UniformLocation location,GLint x,GLint y)6610 void Context::uniform2i(UniformLocation location, GLint x, GLint y)
6611 {
6612 GLint xy[2] = {x, y};
6613 Program *program = getActiveLinkedProgram();
6614 program->setUniform2iv(location, 1, xy);
6615 }
6616
uniform2iv(UniformLocation location,GLsizei count,const GLint * v)6617 void Context::uniform2iv(UniformLocation location, GLsizei count, const GLint *v)
6618 {
6619 Program *program = getActiveLinkedProgram();
6620 program->setUniform2iv(location, count, v);
6621 }
6622
uniform3f(UniformLocation location,GLfloat x,GLfloat y,GLfloat z)6623 void Context::uniform3f(UniformLocation location, GLfloat x, GLfloat y, GLfloat z)
6624 {
6625 GLfloat xyz[3] = {x, y, z};
6626 Program *program = getActiveLinkedProgram();
6627 program->setUniform3fv(location, 1, xyz);
6628 }
6629
uniform3fv(UniformLocation location,GLsizei count,const GLfloat * v)6630 void Context::uniform3fv(UniformLocation location, GLsizei count, const GLfloat *v)
6631 {
6632 Program *program = getActiveLinkedProgram();
6633 program->setUniform3fv(location, count, v);
6634 }
6635
uniform3i(UniformLocation location,GLint x,GLint y,GLint z)6636 void Context::uniform3i(UniformLocation location, GLint x, GLint y, GLint z)
6637 {
6638 GLint xyz[3] = {x, y, z};
6639 Program *program = getActiveLinkedProgram();
6640 program->setUniform3iv(location, 1, xyz);
6641 }
6642
uniform3iv(UniformLocation location,GLsizei count,const GLint * v)6643 void Context::uniform3iv(UniformLocation location, GLsizei count, const GLint *v)
6644 {
6645 Program *program = getActiveLinkedProgram();
6646 program->setUniform3iv(location, count, v);
6647 }
6648
uniform4f(UniformLocation location,GLfloat x,GLfloat y,GLfloat z,GLfloat w)6649 void Context::uniform4f(UniformLocation location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6650 {
6651 GLfloat xyzw[4] = {x, y, z, w};
6652 Program *program = getActiveLinkedProgram();
6653 program->setUniform4fv(location, 1, xyzw);
6654 }
6655
uniform4fv(UniformLocation location,GLsizei count,const GLfloat * v)6656 void Context::uniform4fv(UniformLocation location, GLsizei count, const GLfloat *v)
6657 {
6658 Program *program = getActiveLinkedProgram();
6659 program->setUniform4fv(location, count, v);
6660 }
6661
uniform4i(UniformLocation location,GLint x,GLint y,GLint z,GLint w)6662 void Context::uniform4i(UniformLocation location, GLint x, GLint y, GLint z, GLint w)
6663 {
6664 GLint xyzw[4] = {x, y, z, w};
6665 Program *program = getActiveLinkedProgram();
6666 program->setUniform4iv(location, 1, xyzw);
6667 }
6668
uniform4iv(UniformLocation location,GLsizei count,const GLint * v)6669 void Context::uniform4iv(UniformLocation location, GLsizei count, const GLint *v)
6670 {
6671 Program *program = getActiveLinkedProgram();
6672 program->setUniform4iv(location, count, v);
6673 }
6674
uniformMatrix2fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)6675 void Context::uniformMatrix2fv(UniformLocation location,
6676 GLsizei count,
6677 GLboolean transpose,
6678 const GLfloat *value)
6679 {
6680 Program *program = getActiveLinkedProgram();
6681 program->setUniformMatrix2fv(location, count, transpose, value);
6682 }
6683
uniformMatrix3fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)6684 void Context::uniformMatrix3fv(UniformLocation location,
6685 GLsizei count,
6686 GLboolean transpose,
6687 const GLfloat *value)
6688 {
6689 Program *program = getActiveLinkedProgram();
6690 program->setUniformMatrix3fv(location, count, transpose, value);
6691 }
6692
uniformMatrix4fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)6693 void Context::uniformMatrix4fv(UniformLocation location,
6694 GLsizei count,
6695 GLboolean transpose,
6696 const GLfloat *value)
6697 {
6698 Program *program = getActiveLinkedProgram();
6699 program->setUniformMatrix4fv(location, count, transpose, value);
6700 }
6701
validateProgram(ShaderProgramID program)6702 void Context::validateProgram(ShaderProgramID program)
6703 {
6704 Program *programObject = getProgramResolveLink(program);
6705 ASSERT(programObject);
6706 programObject->validate(mState.mCaps);
6707 }
6708
validateProgramPipeline(ProgramPipelineID pipeline)6709 void Context::validateProgramPipeline(ProgramPipelineID pipeline)
6710 {
6711 ProgramPipeline *programPipeline =
6712 mState.mProgramPipelineManager->checkProgramPipelineAllocation(mImplementation.get(),
6713 pipeline);
6714 ASSERT(programPipeline);
6715
6716 programPipeline->validate(this);
6717 }
6718
getProgramBinary(ShaderProgramID program,GLsizei bufSize,GLsizei * length,GLenum * binaryFormat,void * binary)6719 void Context::getProgramBinary(ShaderProgramID program,
6720 GLsizei bufSize,
6721 GLsizei *length,
6722 GLenum *binaryFormat,
6723 void *binary)
6724 {
6725 Program *programObject = getProgramResolveLink(program);
6726 ASSERT(programObject != nullptr);
6727
6728 ANGLE_CONTEXT_TRY(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
6729 }
6730
programBinary(ShaderProgramID program,GLenum binaryFormat,const void * binary,GLsizei length)6731 void Context::programBinary(ShaderProgramID program,
6732 GLenum binaryFormat,
6733 const void *binary,
6734 GLsizei length)
6735 {
6736 Program *programObject = getProgramResolveLink(program);
6737 ASSERT(programObject != nullptr);
6738
6739 ANGLE_CONTEXT_TRY(programObject->loadBinary(this, binaryFormat, binary, length));
6740 ANGLE_CONTEXT_TRY(onProgramLink(programObject));
6741 }
6742
uniform1ui(UniformLocation location,GLuint v0)6743 void Context::uniform1ui(UniformLocation location, GLuint v0)
6744 {
6745 Program *program = getActiveLinkedProgram();
6746 program->setUniform1uiv(location, 1, &v0);
6747 }
6748
uniform2ui(UniformLocation location,GLuint v0,GLuint v1)6749 void Context::uniform2ui(UniformLocation location, GLuint v0, GLuint v1)
6750 {
6751 Program *program = getActiveLinkedProgram();
6752 const GLuint xy[] = {v0, v1};
6753 program->setUniform2uiv(location, 1, xy);
6754 }
6755
uniform3ui(UniformLocation location,GLuint v0,GLuint v1,GLuint v2)6756 void Context::uniform3ui(UniformLocation location, GLuint v0, GLuint v1, GLuint v2)
6757 {
6758 Program *program = getActiveLinkedProgram();
6759 const GLuint xyz[] = {v0, v1, v2};
6760 program->setUniform3uiv(location, 1, xyz);
6761 }
6762
uniform4ui(UniformLocation location,GLuint v0,GLuint v1,GLuint v2,GLuint v3)6763 void Context::uniform4ui(UniformLocation location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
6764 {
6765 Program *program = getActiveLinkedProgram();
6766 const GLuint xyzw[] = {v0, v1, v2, v3};
6767 program->setUniform4uiv(location, 1, xyzw);
6768 }
6769
uniform1uiv(UniformLocation location,GLsizei count,const GLuint * value)6770 void Context::uniform1uiv(UniformLocation location, GLsizei count, const GLuint *value)
6771 {
6772 Program *program = getActiveLinkedProgram();
6773 program->setUniform1uiv(location, count, value);
6774 }
uniform2uiv(UniformLocation location,GLsizei count,const GLuint * value)6775 void Context::uniform2uiv(UniformLocation location, GLsizei count, const GLuint *value)
6776 {
6777 Program *program = getActiveLinkedProgram();
6778 program->setUniform2uiv(location, count, value);
6779 }
6780
uniform3uiv(UniformLocation location,GLsizei count,const GLuint * value)6781 void Context::uniform3uiv(UniformLocation location, GLsizei count, const GLuint *value)
6782 {
6783 Program *program = getActiveLinkedProgram();
6784 program->setUniform3uiv(location, count, value);
6785 }
6786
uniform4uiv(UniformLocation location,GLsizei count,const GLuint * value)6787 void Context::uniform4uiv(UniformLocation location, GLsizei count, const GLuint *value)
6788 {
6789 Program *program = getActiveLinkedProgram();
6790 program->setUniform4uiv(location, count, value);
6791 }
6792
genQueries(GLsizei n,QueryID * ids)6793 void Context::genQueries(GLsizei n, QueryID *ids)
6794 {
6795 for (GLsizei i = 0; i < n; i++)
6796 {
6797 QueryID handle = QueryID{mQueryHandleAllocator.allocate()};
6798 mQueryMap.assign(handle, nullptr);
6799 ids[i] = handle;
6800 }
6801 }
6802
deleteQueries(GLsizei n,const QueryID * ids)6803 void Context::deleteQueries(GLsizei n, const QueryID *ids)
6804 {
6805 for (int i = 0; i < n; i++)
6806 {
6807 QueryID query = ids[i];
6808
6809 Query *queryObject = nullptr;
6810 if (mQueryMap.erase(query, &queryObject))
6811 {
6812 mQueryHandleAllocator.release(query.value);
6813 if (queryObject)
6814 {
6815 queryObject->release(this);
6816 }
6817 }
6818 }
6819 }
6820
isQueryGenerated(QueryID query) const6821 bool Context::isQueryGenerated(QueryID query) const
6822 {
6823 return mQueryMap.contains(query);
6824 }
6825
isQuery(QueryID id) const6826 GLboolean Context::isQuery(QueryID id) const
6827 {
6828 return ConvertToGLBoolean(getQuery(id) != nullptr);
6829 }
6830
uniformMatrix2x3fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)6831 void Context::uniformMatrix2x3fv(UniformLocation location,
6832 GLsizei count,
6833 GLboolean transpose,
6834 const GLfloat *value)
6835 {
6836 Program *program = getActiveLinkedProgram();
6837 program->setUniformMatrix2x3fv(location, count, transpose, value);
6838 }
6839
uniformMatrix3x2fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)6840 void Context::uniformMatrix3x2fv(UniformLocation location,
6841 GLsizei count,
6842 GLboolean transpose,
6843 const GLfloat *value)
6844 {
6845 Program *program = getActiveLinkedProgram();
6846 program->setUniformMatrix3x2fv(location, count, transpose, value);
6847 }
6848
uniformMatrix2x4fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)6849 void Context::uniformMatrix2x4fv(UniformLocation location,
6850 GLsizei count,
6851 GLboolean transpose,
6852 const GLfloat *value)
6853 {
6854 Program *program = getActiveLinkedProgram();
6855 program->setUniformMatrix2x4fv(location, count, transpose, value);
6856 }
6857
uniformMatrix4x2fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)6858 void Context::uniformMatrix4x2fv(UniformLocation location,
6859 GLsizei count,
6860 GLboolean transpose,
6861 const GLfloat *value)
6862 {
6863 Program *program = getActiveLinkedProgram();
6864 program->setUniformMatrix4x2fv(location, count, transpose, value);
6865 }
6866
uniformMatrix3x4fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)6867 void Context::uniformMatrix3x4fv(UniformLocation location,
6868 GLsizei count,
6869 GLboolean transpose,
6870 const GLfloat *value)
6871 {
6872 Program *program = getActiveLinkedProgram();
6873 program->setUniformMatrix3x4fv(location, count, transpose, value);
6874 }
6875
uniformMatrix4x3fv(UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)6876 void Context::uniformMatrix4x3fv(UniformLocation location,
6877 GLsizei count,
6878 GLboolean transpose,
6879 const GLfloat *value)
6880 {
6881 Program *program = getActiveLinkedProgram();
6882 program->setUniformMatrix4x3fv(location, count, transpose, value);
6883 }
6884
deleteVertexArrays(GLsizei n,const VertexArrayID * arrays)6885 void Context::deleteVertexArrays(GLsizei n, const VertexArrayID *arrays)
6886 {
6887 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
6888 {
6889 VertexArrayID vertexArray = arrays[arrayIndex];
6890
6891 if (arrays[arrayIndex].value != 0)
6892 {
6893 VertexArray *vertexArrayObject = nullptr;
6894 if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
6895 {
6896 if (vertexArrayObject != nullptr)
6897 {
6898 detachVertexArray(vertexArray);
6899 vertexArrayObject->onDestroy(this);
6900 }
6901
6902 mVertexArrayHandleAllocator.release(vertexArray.value);
6903 }
6904 }
6905 }
6906 }
6907
genVertexArrays(GLsizei n,VertexArrayID * arrays)6908 void Context::genVertexArrays(GLsizei n, VertexArrayID *arrays)
6909 {
6910 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
6911 {
6912 VertexArrayID vertexArray = {mVertexArrayHandleAllocator.allocate()};
6913 mVertexArrayMap.assign(vertexArray, nullptr);
6914 arrays[arrayIndex] = vertexArray;
6915 }
6916 }
6917
isVertexArray(VertexArrayID array) const6918 GLboolean Context::isVertexArray(VertexArrayID array) const
6919 {
6920 if (array.value == 0)
6921 {
6922 return GL_FALSE;
6923 }
6924
6925 VertexArray *vao = getVertexArray(array);
6926 return ConvertToGLBoolean(vao != nullptr);
6927 }
6928
endTransformFeedback()6929 void Context::endTransformFeedback()
6930 {
6931 TransformFeedback *transformFeedback = mState.getCurrentTransformFeedback();
6932 ANGLE_CONTEXT_TRY(transformFeedback->end(this));
6933 mStateCache.onActiveTransformFeedbackChange(this);
6934 }
6935
transformFeedbackVaryings(ShaderProgramID program,GLsizei count,const GLchar * const * varyings,GLenum bufferMode)6936 void Context::transformFeedbackVaryings(ShaderProgramID program,
6937 GLsizei count,
6938 const GLchar *const *varyings,
6939 GLenum bufferMode)
6940 {
6941 Program *programObject = getProgramResolveLink(program);
6942 ASSERT(programObject);
6943 programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
6944 }
6945
getTransformFeedbackVarying(ShaderProgramID program,GLuint index,GLsizei bufSize,GLsizei * length,GLsizei * size,GLenum * type,GLchar * name)6946 void Context::getTransformFeedbackVarying(ShaderProgramID program,
6947 GLuint index,
6948 GLsizei bufSize,
6949 GLsizei *length,
6950 GLsizei *size,
6951 GLenum *type,
6952 GLchar *name)
6953 {
6954 Program *programObject = getProgramResolveLink(program);
6955 ASSERT(programObject);
6956 programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
6957 }
6958
deleteTransformFeedbacks(GLsizei n,const TransformFeedbackID * ids)6959 void Context::deleteTransformFeedbacks(GLsizei n, const TransformFeedbackID *ids)
6960 {
6961 for (int i = 0; i < n; i++)
6962 {
6963 TransformFeedbackID transformFeedback = ids[i];
6964 if (transformFeedback.value == 0)
6965 {
6966 continue;
6967 }
6968
6969 TransformFeedback *transformFeedbackObject = nullptr;
6970 if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
6971 {
6972 if (transformFeedbackObject != nullptr)
6973 {
6974 detachTransformFeedback(transformFeedback);
6975 transformFeedbackObject->release(this);
6976 }
6977
6978 mTransformFeedbackHandleAllocator.release(transformFeedback.value);
6979 }
6980 }
6981 }
6982
genTransformFeedbacks(GLsizei n,TransformFeedbackID * ids)6983 void Context::genTransformFeedbacks(GLsizei n, TransformFeedbackID *ids)
6984 {
6985 for (int i = 0; i < n; i++)
6986 {
6987 TransformFeedbackID transformFeedback = {mTransformFeedbackHandleAllocator.allocate()};
6988 mTransformFeedbackMap.assign(transformFeedback, nullptr);
6989 ids[i] = transformFeedback;
6990 }
6991 }
6992
isTransformFeedback(TransformFeedbackID id) const6993 GLboolean Context::isTransformFeedback(TransformFeedbackID id) const
6994 {
6995 if (id.value == 0)
6996 {
6997 // The 3.0.4 spec [section 6.1.11] states that if ID is zero, IsTransformFeedback
6998 // returns FALSE
6999 return GL_FALSE;
7000 }
7001
7002 const TransformFeedback *transformFeedback = getTransformFeedback(id);
7003 return ConvertToGLBoolean(transformFeedback != nullptr);
7004 }
7005
pauseTransformFeedback()7006 void Context::pauseTransformFeedback()
7007 {
7008 TransformFeedback *transformFeedback = mState.getCurrentTransformFeedback();
7009 ANGLE_CONTEXT_TRY(transformFeedback->pause(this));
7010 mStateCache.onActiveTransformFeedbackChange(this);
7011 }
7012
resumeTransformFeedback()7013 void Context::resumeTransformFeedback()
7014 {
7015 TransformFeedback *transformFeedback = mState.getCurrentTransformFeedback();
7016 ANGLE_CONTEXT_TRY(transformFeedback->resume(this));
7017 mStateCache.onActiveTransformFeedbackChange(this);
7018 }
7019
getUniformuiv(ShaderProgramID program,UniformLocation location,GLuint * params)7020 void Context::getUniformuiv(ShaderProgramID program, UniformLocation location, GLuint *params)
7021 {
7022 const Program *programObject = getProgramResolveLink(program);
7023 programObject->getUniformuiv(this, location, params);
7024 }
7025
getUniformuivRobust(ShaderProgramID program,UniformLocation location,GLsizei bufSize,GLsizei * length,GLuint * params)7026 void Context::getUniformuivRobust(ShaderProgramID program,
7027 UniformLocation location,
7028 GLsizei bufSize,
7029 GLsizei *length,
7030 GLuint *params)
7031 {
7032 getUniformuiv(program, location, params);
7033 }
7034
getFragDataLocation(ShaderProgramID program,const GLchar * name)7035 GLint Context::getFragDataLocation(ShaderProgramID program, const GLchar *name)
7036 {
7037 const Program *programObject = getProgramResolveLink(program);
7038 return programObject->getFragDataLocation(name);
7039 }
7040
getUniformIndices(ShaderProgramID program,GLsizei uniformCount,const GLchar * const * uniformNames,GLuint * uniformIndices)7041 void Context::getUniformIndices(ShaderProgramID program,
7042 GLsizei uniformCount,
7043 const GLchar *const *uniformNames,
7044 GLuint *uniformIndices)
7045 {
7046 const Program *programObject = getProgramResolveLink(program);
7047 if (!programObject->isLinked())
7048 {
7049 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
7050 {
7051 uniformIndices[uniformId] = GL_INVALID_INDEX;
7052 }
7053 }
7054 else
7055 {
7056 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
7057 {
7058 uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]);
7059 }
7060 }
7061 }
7062
getActiveUniformsiv(ShaderProgramID program,GLsizei uniformCount,const GLuint * uniformIndices,GLenum pname,GLint * params)7063 void Context::getActiveUniformsiv(ShaderProgramID program,
7064 GLsizei uniformCount,
7065 const GLuint *uniformIndices,
7066 GLenum pname,
7067 GLint *params)
7068 {
7069 const Program *programObject = getProgramResolveLink(program);
7070 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
7071 {
7072 const GLuint index = uniformIndices[uniformId];
7073 params[uniformId] = GetUniformResourceProperty(programObject, index, pname);
7074 }
7075 }
7076
getUniformBlockIndex(ShaderProgramID program,const GLchar * uniformBlockName)7077 GLuint Context::getUniformBlockIndex(ShaderProgramID program, const GLchar *uniformBlockName)
7078 {
7079 const Program *programObject = getProgramResolveLink(program);
7080 return programObject->getUniformBlockIndex(uniformBlockName);
7081 }
7082
getActiveUniformBlockiv(ShaderProgramID program,GLuint uniformBlockIndex,GLenum pname,GLint * params)7083 void Context::getActiveUniformBlockiv(ShaderProgramID program,
7084 GLuint uniformBlockIndex,
7085 GLenum pname,
7086 GLint *params)
7087 {
7088 const Program *programObject = getProgramResolveLink(program);
7089 QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
7090 }
7091
getActiveUniformBlockivRobust(ShaderProgramID program,GLuint uniformBlockIndex,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)7092 void Context::getActiveUniformBlockivRobust(ShaderProgramID program,
7093 GLuint uniformBlockIndex,
7094 GLenum pname,
7095 GLsizei bufSize,
7096 GLsizei *length,
7097 GLint *params)
7098 {
7099 getActiveUniformBlockiv(program, uniformBlockIndex, pname, params);
7100 }
7101
getActiveUniformBlockName(ShaderProgramID program,GLuint uniformBlockIndex,GLsizei bufSize,GLsizei * length,GLchar * uniformBlockName)7102 void Context::getActiveUniformBlockName(ShaderProgramID program,
7103 GLuint uniformBlockIndex,
7104 GLsizei bufSize,
7105 GLsizei *length,
7106 GLchar *uniformBlockName)
7107 {
7108 const Program *programObject = getProgramResolveLink(program);
7109 programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
7110 }
7111
uniformBlockBinding(ShaderProgramID program,GLuint uniformBlockIndex,GLuint uniformBlockBinding)7112 void Context::uniformBlockBinding(ShaderProgramID program,
7113 GLuint uniformBlockIndex,
7114 GLuint uniformBlockBinding)
7115 {
7116 Program *programObject = getProgramResolveLink(program);
7117 programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
7118
7119 // Note: If the Program is shared between Contexts we would be better using Observer/Subject.
7120 if (programObject->isInUse())
7121 {
7122 mState.setObjectDirty(GL_PROGRAM);
7123 mStateCache.onUniformBufferStateChange(this);
7124 }
7125 }
7126
fenceSync(GLenum condition,GLbitfield flags)7127 GLsync Context::fenceSync(GLenum condition, GLbitfield flags)
7128 {
7129 GLuint handle = mState.mSyncManager->createSync(mImplementation.get());
7130 GLsync syncHandle = reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
7131
7132 Sync *syncObject = getSync(syncHandle);
7133 if (syncObject->set(this, condition, flags) == angle::Result::Stop)
7134 {
7135 deleteSync(syncHandle);
7136 return nullptr;
7137 }
7138
7139 return syncHandle;
7140 }
7141
isSync(GLsync sync) const7142 GLboolean Context::isSync(GLsync sync) const
7143 {
7144 return (getSync(sync) != nullptr);
7145 }
7146
clientWaitSync(GLsync sync,GLbitfield flags,GLuint64 timeout)7147 GLenum Context::clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
7148 {
7149 Sync *syncObject = getSync(sync);
7150
7151 GLenum result = GL_WAIT_FAILED;
7152 if (syncObject->clientWait(this, flags, timeout, &result) == angle::Result::Stop)
7153 {
7154 return GL_WAIT_FAILED;
7155 }
7156 return result;
7157 }
7158
waitSync(GLsync sync,GLbitfield flags,GLuint64 timeout)7159 void Context::waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
7160 {
7161 Sync *syncObject = getSync(sync);
7162 ANGLE_CONTEXT_TRY(syncObject->serverWait(this, flags, timeout));
7163 }
7164
getInteger64v(GLenum pname,GLint64 * params)7165 void Context::getInteger64v(GLenum pname, GLint64 *params)
7166 {
7167 GLenum nativeType = GL_NONE;
7168 unsigned int numParams = 0;
7169 getQueryParameterInfo(pname, &nativeType, &numParams);
7170
7171 if (nativeType == GL_INT_64_ANGLEX)
7172 {
7173 getInteger64vImpl(pname, params);
7174 }
7175 else
7176 {
7177 CastStateValues(this, nativeType, pname, numParams, params);
7178 }
7179 }
7180
getInteger64vRobust(GLenum pname,GLsizei bufSize,GLsizei * length,GLint64 * data)7181 void Context::getInteger64vRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *data)
7182 {
7183 getInteger64v(pname, data);
7184 }
7185
getBufferParameteri64v(BufferBinding target,GLenum pname,GLint64 * params)7186 void Context::getBufferParameteri64v(BufferBinding target, GLenum pname, GLint64 *params)
7187 {
7188 Buffer *buffer = mState.getTargetBuffer(target);
7189 QueryBufferParameteri64v(buffer, pname, params);
7190 }
7191
getBufferParameteri64vRobust(BufferBinding target,GLenum pname,GLsizei bufSize,GLsizei * length,GLint64 * params)7192 void Context::getBufferParameteri64vRobust(BufferBinding target,
7193 GLenum pname,
7194 GLsizei bufSize,
7195 GLsizei *length,
7196 GLint64 *params)
7197 {
7198 getBufferParameteri64v(target, pname, params);
7199 }
7200
genSamplers(GLsizei count,SamplerID * samplers)7201 void Context::genSamplers(GLsizei count, SamplerID *samplers)
7202 {
7203 for (int i = 0; i < count; i++)
7204 {
7205 samplers[i] = mState.mSamplerManager->createSampler();
7206 }
7207 }
7208
deleteSamplers(GLsizei count,const SamplerID * samplers)7209 void Context::deleteSamplers(GLsizei count, const SamplerID *samplers)
7210 {
7211 for (int i = 0; i < count; i++)
7212 {
7213 SamplerID sampler = samplers[i];
7214
7215 if (mState.mSamplerManager->getSampler(sampler))
7216 {
7217 detachSampler(sampler);
7218 }
7219
7220 mState.mSamplerManager->deleteObject(this, sampler);
7221 }
7222 }
7223
minSampleShading(GLfloat value)7224 void Context::minSampleShading(GLfloat value)
7225 {
7226 UNIMPLEMENTED();
7227 }
7228
getInternalformativ(GLenum target,GLenum internalformat,GLenum pname,GLsizei bufSize,GLint * params)7229 void Context::getInternalformativ(GLenum target,
7230 GLenum internalformat,
7231 GLenum pname,
7232 GLsizei bufSize,
7233 GLint *params)
7234 {
7235 const TextureCaps &formatCaps = mState.mTextureCaps.get(internalformat);
7236 QueryInternalFormativ(formatCaps, pname, bufSize, params);
7237 }
7238
getInternalformativRobust(GLenum target,GLenum internalformat,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * params)7239 void Context::getInternalformativRobust(GLenum target,
7240 GLenum internalformat,
7241 GLenum pname,
7242 GLsizei bufSize,
7243 GLsizei *length,
7244 GLint *params)
7245 {
7246 getInternalformativ(target, internalformat, pname, bufSize, params);
7247 }
7248
programUniform1i(ShaderProgramID program,UniformLocation location,GLint v0)7249 void Context::programUniform1i(ShaderProgramID program, UniformLocation location, GLint v0)
7250 {
7251 programUniform1iv(program, location, 1, &v0);
7252 }
7253
programUniform2i(ShaderProgramID program,UniformLocation location,GLint v0,GLint v1)7254 void Context::programUniform2i(ShaderProgramID program,
7255 UniformLocation location,
7256 GLint v0,
7257 GLint v1)
7258 {
7259 GLint xy[2] = {v0, v1};
7260 programUniform2iv(program, location, 1, xy);
7261 }
7262
programUniform3i(ShaderProgramID program,UniformLocation location,GLint v0,GLint v1,GLint v2)7263 void Context::programUniform3i(ShaderProgramID program,
7264 UniformLocation location,
7265 GLint v0,
7266 GLint v1,
7267 GLint v2)
7268 {
7269 GLint xyz[3] = {v0, v1, v2};
7270 programUniform3iv(program, location, 1, xyz);
7271 }
7272
programUniform4i(ShaderProgramID program,UniformLocation location,GLint v0,GLint v1,GLint v2,GLint v3)7273 void Context::programUniform4i(ShaderProgramID program,
7274 UniformLocation location,
7275 GLint v0,
7276 GLint v1,
7277 GLint v2,
7278 GLint v3)
7279 {
7280 GLint xyzw[4] = {v0, v1, v2, v3};
7281 programUniform4iv(program, location, 1, xyzw);
7282 }
7283
programUniform1ui(ShaderProgramID program,UniformLocation location,GLuint v0)7284 void Context::programUniform1ui(ShaderProgramID program, UniformLocation location, GLuint v0)
7285 {
7286 programUniform1uiv(program, location, 1, &v0);
7287 }
7288
programUniform2ui(ShaderProgramID program,UniformLocation location,GLuint v0,GLuint v1)7289 void Context::programUniform2ui(ShaderProgramID program,
7290 UniformLocation location,
7291 GLuint v0,
7292 GLuint v1)
7293 {
7294 GLuint xy[2] = {v0, v1};
7295 programUniform2uiv(program, location, 1, xy);
7296 }
7297
programUniform3ui(ShaderProgramID program,UniformLocation location,GLuint v0,GLuint v1,GLuint v2)7298 void Context::programUniform3ui(ShaderProgramID program,
7299 UniformLocation location,
7300 GLuint v0,
7301 GLuint v1,
7302 GLuint v2)
7303 {
7304 GLuint xyz[3] = {v0, v1, v2};
7305 programUniform3uiv(program, location, 1, xyz);
7306 }
7307
programUniform4ui(ShaderProgramID program,UniformLocation location,GLuint v0,GLuint v1,GLuint v2,GLuint v3)7308 void Context::programUniform4ui(ShaderProgramID program,
7309 UniformLocation location,
7310 GLuint v0,
7311 GLuint v1,
7312 GLuint v2,
7313 GLuint v3)
7314 {
7315 GLuint xyzw[4] = {v0, v1, v2, v3};
7316 programUniform4uiv(program, location, 1, xyzw);
7317 }
7318
programUniform1f(ShaderProgramID program,UniformLocation location,GLfloat v0)7319 void Context::programUniform1f(ShaderProgramID program, UniformLocation location, GLfloat v0)
7320 {
7321 programUniform1fv(program, location, 1, &v0);
7322 }
7323
programUniform2f(ShaderProgramID program,UniformLocation location,GLfloat v0,GLfloat v1)7324 void Context::programUniform2f(ShaderProgramID program,
7325 UniformLocation location,
7326 GLfloat v0,
7327 GLfloat v1)
7328 {
7329 GLfloat xy[2] = {v0, v1};
7330 programUniform2fv(program, location, 1, xy);
7331 }
7332
programUniform3f(ShaderProgramID program,UniformLocation location,GLfloat v0,GLfloat v1,GLfloat v2)7333 void Context::programUniform3f(ShaderProgramID program,
7334 UniformLocation location,
7335 GLfloat v0,
7336 GLfloat v1,
7337 GLfloat v2)
7338 {
7339 GLfloat xyz[3] = {v0, v1, v2};
7340 programUniform3fv(program, location, 1, xyz);
7341 }
7342
programUniform4f(ShaderProgramID program,UniformLocation location,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)7343 void Context::programUniform4f(ShaderProgramID program,
7344 UniformLocation location,
7345 GLfloat v0,
7346 GLfloat v1,
7347 GLfloat v2,
7348 GLfloat v3)
7349 {
7350 GLfloat xyzw[4] = {v0, v1, v2, v3};
7351 programUniform4fv(program, location, 1, xyzw);
7352 }
7353
programUniform1iv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)7354 void Context::programUniform1iv(ShaderProgramID program,
7355 UniformLocation location,
7356 GLsizei count,
7357 const GLint *value)
7358 {
7359 Program *programObject = getProgramResolveLink(program);
7360 ASSERT(programObject);
7361 setUniform1iImpl(programObject, location, count, value);
7362 }
7363
programUniform2iv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)7364 void Context::programUniform2iv(ShaderProgramID program,
7365 UniformLocation location,
7366 GLsizei count,
7367 const GLint *value)
7368 {
7369 Program *programObject = getProgramResolveLink(program);
7370 ASSERT(programObject);
7371 programObject->setUniform2iv(location, count, value);
7372 }
7373
programUniform3iv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)7374 void Context::programUniform3iv(ShaderProgramID program,
7375 UniformLocation location,
7376 GLsizei count,
7377 const GLint *value)
7378 {
7379 Program *programObject = getProgramResolveLink(program);
7380 ASSERT(programObject);
7381 programObject->setUniform3iv(location, count, value);
7382 }
7383
programUniform4iv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)7384 void Context::programUniform4iv(ShaderProgramID program,
7385 UniformLocation location,
7386 GLsizei count,
7387 const GLint *value)
7388 {
7389 Program *programObject = getProgramResolveLink(program);
7390 ASSERT(programObject);
7391 programObject->setUniform4iv(location, count, value);
7392 }
7393
programUniform1uiv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)7394 void Context::programUniform1uiv(ShaderProgramID program,
7395 UniformLocation location,
7396 GLsizei count,
7397 const GLuint *value)
7398 {
7399 Program *programObject = getProgramResolveLink(program);
7400 ASSERT(programObject);
7401 programObject->setUniform1uiv(location, count, value);
7402 }
7403
programUniform2uiv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)7404 void Context::programUniform2uiv(ShaderProgramID program,
7405 UniformLocation location,
7406 GLsizei count,
7407 const GLuint *value)
7408 {
7409 Program *programObject = getProgramResolveLink(program);
7410 ASSERT(programObject);
7411 programObject->setUniform2uiv(location, count, value);
7412 }
7413
programUniform3uiv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)7414 void Context::programUniform3uiv(ShaderProgramID program,
7415 UniformLocation location,
7416 GLsizei count,
7417 const GLuint *value)
7418 {
7419 Program *programObject = getProgramResolveLink(program);
7420 ASSERT(programObject);
7421 programObject->setUniform3uiv(location, count, value);
7422 }
7423
programUniform4uiv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)7424 void Context::programUniform4uiv(ShaderProgramID program,
7425 UniformLocation location,
7426 GLsizei count,
7427 const GLuint *value)
7428 {
7429 Program *programObject = getProgramResolveLink(program);
7430 ASSERT(programObject);
7431 programObject->setUniform4uiv(location, count, value);
7432 }
7433
programUniform1fv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)7434 void Context::programUniform1fv(ShaderProgramID program,
7435 UniformLocation location,
7436 GLsizei count,
7437 const GLfloat *value)
7438 {
7439 Program *programObject = getProgramResolveLink(program);
7440 ASSERT(programObject);
7441 programObject->setUniform1fv(location, count, value);
7442 }
7443
programUniform2fv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)7444 void Context::programUniform2fv(ShaderProgramID program,
7445 UniformLocation location,
7446 GLsizei count,
7447 const GLfloat *value)
7448 {
7449 Program *programObject = getProgramResolveLink(program);
7450 ASSERT(programObject);
7451 programObject->setUniform2fv(location, count, value);
7452 }
7453
programUniform3fv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)7454 void Context::programUniform3fv(ShaderProgramID program,
7455 UniformLocation location,
7456 GLsizei count,
7457 const GLfloat *value)
7458 {
7459 Program *programObject = getProgramResolveLink(program);
7460 ASSERT(programObject);
7461 programObject->setUniform3fv(location, count, value);
7462 }
7463
programUniform4fv(ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)7464 void Context::programUniform4fv(ShaderProgramID program,
7465 UniformLocation location,
7466 GLsizei count,
7467 const GLfloat *value)
7468 {
7469 Program *programObject = getProgramResolveLink(program);
7470 ASSERT(programObject);
7471 programObject->setUniform4fv(location, count, value);
7472 }
7473
programUniformMatrix2fv(ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)7474 void Context::programUniformMatrix2fv(ShaderProgramID program,
7475 UniformLocation location,
7476 GLsizei count,
7477 GLboolean transpose,
7478 const GLfloat *value)
7479 {
7480 Program *programObject = getProgramResolveLink(program);
7481 ASSERT(programObject);
7482 programObject->setUniformMatrix2fv(location, count, transpose, value);
7483 }
7484
programUniformMatrix3fv(ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)7485 void Context::programUniformMatrix3fv(ShaderProgramID program,
7486 UniformLocation location,
7487 GLsizei count,
7488 GLboolean transpose,
7489 const GLfloat *value)
7490 {
7491 Program *programObject = getProgramResolveLink(program);
7492 ASSERT(programObject);
7493 programObject->setUniformMatrix3fv(location, count, transpose, value);
7494 }
7495
programUniformMatrix4fv(ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)7496 void Context::programUniformMatrix4fv(ShaderProgramID program,
7497 UniformLocation location,
7498 GLsizei count,
7499 GLboolean transpose,
7500 const GLfloat *value)
7501 {
7502 Program *programObject = getProgramResolveLink(program);
7503 ASSERT(programObject);
7504 programObject->setUniformMatrix4fv(location, count, transpose, value);
7505 }
7506
programUniformMatrix2x3fv(ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)7507 void Context::programUniformMatrix2x3fv(ShaderProgramID program,
7508 UniformLocation location,
7509 GLsizei count,
7510 GLboolean transpose,
7511 const GLfloat *value)
7512 {
7513 Program *programObject = getProgramResolveLink(program);
7514 ASSERT(programObject);
7515 programObject->setUniformMatrix2x3fv(location, count, transpose, value);
7516 }
7517
programUniformMatrix3x2fv(ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)7518 void Context::programUniformMatrix3x2fv(ShaderProgramID program,
7519 UniformLocation location,
7520 GLsizei count,
7521 GLboolean transpose,
7522 const GLfloat *value)
7523 {
7524 Program *programObject = getProgramResolveLink(program);
7525 ASSERT(programObject);
7526 programObject->setUniformMatrix3x2fv(location, count, transpose, value);
7527 }
7528
programUniformMatrix2x4fv(ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)7529 void Context::programUniformMatrix2x4fv(ShaderProgramID program,
7530 UniformLocation location,
7531 GLsizei count,
7532 GLboolean transpose,
7533 const GLfloat *value)
7534 {
7535 Program *programObject = getProgramResolveLink(program);
7536 ASSERT(programObject);
7537 programObject->setUniformMatrix2x4fv(location, count, transpose, value);
7538 }
7539
programUniformMatrix4x2fv(ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)7540 void Context::programUniformMatrix4x2fv(ShaderProgramID program,
7541 UniformLocation location,
7542 GLsizei count,
7543 GLboolean transpose,
7544 const GLfloat *value)
7545 {
7546 Program *programObject = getProgramResolveLink(program);
7547 ASSERT(programObject);
7548 programObject->setUniformMatrix4x2fv(location, count, transpose, value);
7549 }
7550
programUniformMatrix3x4fv(ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)7551 void Context::programUniformMatrix3x4fv(ShaderProgramID program,
7552 UniformLocation location,
7553 GLsizei count,
7554 GLboolean transpose,
7555 const GLfloat *value)
7556 {
7557 Program *programObject = getProgramResolveLink(program);
7558 ASSERT(programObject);
7559 programObject->setUniformMatrix3x4fv(location, count, transpose, value);
7560 }
7561
programUniformMatrix4x3fv(ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)7562 void Context::programUniformMatrix4x3fv(ShaderProgramID program,
7563 UniformLocation location,
7564 GLsizei count,
7565 GLboolean transpose,
7566 const GLfloat *value)
7567 {
7568 Program *programObject = getProgramResolveLink(program);
7569 ASSERT(programObject);
7570 programObject->setUniformMatrix4x3fv(location, count, transpose, value);
7571 }
7572
isCurrentTransformFeedback(const TransformFeedback * tf) const7573 bool Context::isCurrentTransformFeedback(const TransformFeedback *tf) const
7574 {
7575 return mState.isCurrentTransformFeedback(tf);
7576 }
7577
genProgramPipelines(GLsizei count,ProgramPipelineID * pipelines)7578 void Context::genProgramPipelines(GLsizei count, ProgramPipelineID *pipelines)
7579 {
7580 for (int i = 0; i < count; i++)
7581 {
7582 pipelines[i] = createProgramPipeline();
7583 }
7584 }
7585
deleteProgramPipelines(GLsizei count,const ProgramPipelineID * pipelines)7586 void Context::deleteProgramPipelines(GLsizei count, const ProgramPipelineID *pipelines)
7587 {
7588 for (int i = 0; i < count; i++)
7589 {
7590 if (pipelines[i].value != 0)
7591 {
7592 deleteProgramPipeline(pipelines[i]);
7593 }
7594 }
7595 }
7596
isProgramPipeline(ProgramPipelineID pipeline) const7597 GLboolean Context::isProgramPipeline(ProgramPipelineID pipeline) const
7598 {
7599 if (pipeline.value == 0)
7600 {
7601 return GL_FALSE;
7602 }
7603
7604 if (getProgramPipeline(pipeline))
7605 {
7606 return GL_TRUE;
7607 }
7608
7609 return GL_FALSE;
7610 }
7611
finishFenceNV(FenceNVID fence)7612 void Context::finishFenceNV(FenceNVID fence)
7613 {
7614 FenceNV *fenceObject = getFenceNV(fence);
7615
7616 ASSERT(fenceObject && fenceObject->isSet());
7617 ANGLE_CONTEXT_TRY(fenceObject->finish(this));
7618 }
7619
getFenceivNV(FenceNVID fence,GLenum pname,GLint * params)7620 void Context::getFenceivNV(FenceNVID fence, GLenum pname, GLint *params)
7621 {
7622 FenceNV *fenceObject = getFenceNV(fence);
7623
7624 ASSERT(fenceObject && fenceObject->isSet());
7625
7626 switch (pname)
7627 {
7628 case GL_FENCE_STATUS_NV:
7629 {
7630 // GL_NV_fence spec:
7631 // Once the status of a fence has been finished (via FinishFenceNV) or tested and
7632 // the returned status is TRUE (via either TestFenceNV or GetFenceivNV querying the
7633 // FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
7634 GLboolean status = GL_TRUE;
7635 if (fenceObject->getStatus() != GL_TRUE)
7636 {
7637 ANGLE_CONTEXT_TRY(fenceObject->test(this, &status));
7638 }
7639 *params = status;
7640 break;
7641 }
7642
7643 case GL_FENCE_CONDITION_NV:
7644 {
7645 *params = static_cast<GLint>(fenceObject->getCondition());
7646 break;
7647 }
7648
7649 default:
7650 UNREACHABLE();
7651 }
7652 }
7653
getTranslatedShaderSource(ShaderProgramID shader,GLsizei bufsize,GLsizei * length,GLchar * source)7654 void Context::getTranslatedShaderSource(ShaderProgramID shader,
7655 GLsizei bufsize,
7656 GLsizei *length,
7657 GLchar *source)
7658 {
7659 Shader *shaderObject = getShader(shader);
7660 ASSERT(shaderObject);
7661 shaderObject->getTranslatedSourceWithDebugInfo(bufsize, length, source);
7662 }
7663
getnUniformfv(ShaderProgramID program,UniformLocation location,GLsizei bufSize,GLfloat * params)7664 void Context::getnUniformfv(ShaderProgramID program,
7665 UniformLocation location,
7666 GLsizei bufSize,
7667 GLfloat *params)
7668 {
7669 Program *programObject = getProgramResolveLink(program);
7670 ASSERT(programObject);
7671
7672 programObject->getUniformfv(this, location, params);
7673 }
7674
getnUniformfvRobust(ShaderProgramID program,UniformLocation location,GLsizei bufSize,GLsizei * length,GLfloat * params)7675 void Context::getnUniformfvRobust(ShaderProgramID program,
7676 UniformLocation location,
7677 GLsizei bufSize,
7678 GLsizei *length,
7679 GLfloat *params)
7680 {
7681 UNIMPLEMENTED();
7682 }
7683
getnUniformiv(ShaderProgramID program,UniformLocation location,GLsizei bufSize,GLint * params)7684 void Context::getnUniformiv(ShaderProgramID program,
7685 UniformLocation location,
7686 GLsizei bufSize,
7687 GLint *params)
7688 {
7689 Program *programObject = getProgramResolveLink(program);
7690 ASSERT(programObject);
7691
7692 programObject->getUniformiv(this, location, params);
7693 }
7694
getnUniformivRobust(ShaderProgramID program,UniformLocation location,GLsizei bufSize,GLsizei * length,GLint * params)7695 void Context::getnUniformivRobust(ShaderProgramID program,
7696 UniformLocation location,
7697 GLsizei bufSize,
7698 GLsizei *length,
7699 GLint *params)
7700 {
7701 UNIMPLEMENTED();
7702 }
7703
getnUniformuivRobust(ShaderProgramID program,UniformLocation location,GLsizei bufSize,GLsizei * length,GLuint * params)7704 void Context::getnUniformuivRobust(ShaderProgramID program,
7705 UniformLocation location,
7706 GLsizei bufSize,
7707 GLsizei *length,
7708 GLuint *params)
7709 {
7710 UNIMPLEMENTED();
7711 }
7712
isFenceNV(FenceNVID fence) const7713 GLboolean Context::isFenceNV(FenceNVID fence) const
7714 {
7715 FenceNV *fenceObject = getFenceNV(fence);
7716
7717 if (fenceObject == nullptr)
7718 {
7719 return GL_FALSE;
7720 }
7721
7722 // GL_NV_fence spec:
7723 // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an
7724 // existing fence.
7725 return fenceObject->isSet();
7726 }
7727
readnPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,void * data)7728 void Context::readnPixels(GLint x,
7729 GLint y,
7730 GLsizei width,
7731 GLsizei height,
7732 GLenum format,
7733 GLenum type,
7734 GLsizei bufSize,
7735 void *data)
7736 {
7737 return readPixels(x, y, width, height, format, type, data);
7738 }
7739
setFenceNV(FenceNVID fence,GLenum condition)7740 void Context::setFenceNV(FenceNVID fence, GLenum condition)
7741 {
7742 ASSERT(condition == GL_ALL_COMPLETED_NV);
7743
7744 FenceNV *fenceObject = getFenceNV(fence);
7745 ASSERT(fenceObject != nullptr);
7746 ANGLE_CONTEXT_TRY(fenceObject->set(this, condition));
7747 }
7748
testFenceNV(FenceNVID fence)7749 GLboolean Context::testFenceNV(FenceNVID fence)
7750 {
7751 FenceNV *fenceObject = getFenceNV(fence);
7752
7753 ASSERT(fenceObject != nullptr);
7754 ASSERT(fenceObject->isSet() == GL_TRUE);
7755
7756 GLboolean result = GL_TRUE;
7757 if (fenceObject->test(this, &result) == angle::Result::Stop)
7758 {
7759 return GL_TRUE;
7760 }
7761
7762 return result;
7763 }
7764
deleteMemoryObjects(GLsizei n,const MemoryObjectID * memoryObjects)7765 void Context::deleteMemoryObjects(GLsizei n, const MemoryObjectID *memoryObjects)
7766 {
7767 for (int i = 0; i < n; i++)
7768 {
7769 deleteMemoryObject(memoryObjects[i]);
7770 }
7771 }
7772
isMemoryObject(MemoryObjectID memoryObject) const7773 GLboolean Context::isMemoryObject(MemoryObjectID memoryObject) const
7774 {
7775 if (memoryObject.value == 0)
7776 {
7777 return GL_FALSE;
7778 }
7779
7780 return ConvertToGLBoolean(getMemoryObject(memoryObject));
7781 }
7782
createMemoryObjects(GLsizei n,MemoryObjectID * memoryObjects)7783 void Context::createMemoryObjects(GLsizei n, MemoryObjectID *memoryObjects)
7784 {
7785 for (int i = 0; i < n; i++)
7786 {
7787 memoryObjects[i] = createMemoryObject();
7788 }
7789 }
7790
memoryObjectParameteriv(MemoryObjectID memory,GLenum pname,const GLint * params)7791 void Context::memoryObjectParameteriv(MemoryObjectID memory, GLenum pname, const GLint *params)
7792 {
7793 MemoryObject *memoryObject = getMemoryObject(memory);
7794 ASSERT(memoryObject);
7795 ANGLE_CONTEXT_TRY(SetMemoryObjectParameteriv(this, memoryObject, pname, params));
7796 }
7797
getMemoryObjectParameteriv(MemoryObjectID memory,GLenum pname,GLint * params)7798 void Context::getMemoryObjectParameteriv(MemoryObjectID memory, GLenum pname, GLint *params)
7799 {
7800 const MemoryObject *memoryObject = getMemoryObject(memory);
7801 ASSERT(memoryObject);
7802 QueryMemoryObjectParameteriv(memoryObject, pname, params);
7803 }
7804
texStorageMem2D(TextureType target,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,MemoryObjectID memory,GLuint64 offset)7805 void Context::texStorageMem2D(TextureType target,
7806 GLsizei levels,
7807 GLenum internalFormat,
7808 GLsizei width,
7809 GLsizei height,
7810 MemoryObjectID memory,
7811 GLuint64 offset)
7812 {
7813 MemoryObject *memoryObject = getMemoryObject(memory);
7814 ASSERT(memoryObject);
7815 Extents size(width, height, 1);
7816 Texture *texture = getTextureByType(target);
7817 ANGLE_CONTEXT_TRY(texture->setStorageExternalMemory(this, target, levels, internalFormat, size,
7818 memoryObject, offset));
7819 }
7820
texStorageMem2DMultisample(TextureType target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLboolean fixedSampleLocations,MemoryObjectID memory,GLuint64 offset)7821 void Context::texStorageMem2DMultisample(TextureType target,
7822 GLsizei samples,
7823 GLenum internalFormat,
7824 GLsizei width,
7825 GLsizei height,
7826 GLboolean fixedSampleLocations,
7827 MemoryObjectID memory,
7828 GLuint64 offset)
7829 {
7830 UNIMPLEMENTED();
7831 }
7832
texStorageMem3D(TextureType target,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,MemoryObjectID memory,GLuint64 offset)7833 void Context::texStorageMem3D(TextureType target,
7834 GLsizei levels,
7835 GLenum internalFormat,
7836 GLsizei width,
7837 GLsizei height,
7838 GLsizei depth,
7839 MemoryObjectID memory,
7840 GLuint64 offset)
7841 {
7842 UNIMPLEMENTED();
7843 }
7844
texStorageMem3DMultisample(TextureType target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedSampleLocations,MemoryObjectID memory,GLuint64 offset)7845 void Context::texStorageMem3DMultisample(TextureType target,
7846 GLsizei samples,
7847 GLenum internalFormat,
7848 GLsizei width,
7849 GLsizei height,
7850 GLsizei depth,
7851 GLboolean fixedSampleLocations,
7852 MemoryObjectID memory,
7853 GLuint64 offset)
7854 {
7855 UNIMPLEMENTED();
7856 }
7857
bufferStorageMem(TextureType target,GLsizeiptr size,MemoryObjectID memory,GLuint64 offset)7858 void Context::bufferStorageMem(TextureType target,
7859 GLsizeiptr size,
7860 MemoryObjectID memory,
7861 GLuint64 offset)
7862 {
7863 UNIMPLEMENTED();
7864 }
7865
importMemoryFd(MemoryObjectID memory,GLuint64 size,HandleType handleType,GLint fd)7866 void Context::importMemoryFd(MemoryObjectID memory, GLuint64 size, HandleType handleType, GLint fd)
7867 {
7868 MemoryObject *memoryObject = getMemoryObject(memory);
7869 ASSERT(memoryObject != nullptr);
7870 ANGLE_CONTEXT_TRY(memoryObject->importFd(this, size, handleType, fd));
7871 }
7872
importMemoryZirconHandle(MemoryObjectID memory,GLuint64 size,HandleType handleType,GLuint handle)7873 void Context::importMemoryZirconHandle(MemoryObjectID memory,
7874 GLuint64 size,
7875 HandleType handleType,
7876 GLuint handle)
7877 {
7878 MemoryObject *memoryObject = getMemoryObject(memory);
7879 ASSERT(memoryObject != nullptr);
7880 ANGLE_CONTEXT_TRY(memoryObject->importZirconHandle(this, size, handleType, handle));
7881 }
7882
genSemaphores(GLsizei n,SemaphoreID * semaphores)7883 void Context::genSemaphores(GLsizei n, SemaphoreID *semaphores)
7884 {
7885 for (int i = 0; i < n; i++)
7886 {
7887 semaphores[i] = createSemaphore();
7888 }
7889 }
7890
deleteSemaphores(GLsizei n,const SemaphoreID * semaphores)7891 void Context::deleteSemaphores(GLsizei n, const SemaphoreID *semaphores)
7892 {
7893 for (int i = 0; i < n; i++)
7894 {
7895 deleteSemaphore(semaphores[i]);
7896 }
7897 }
7898
isSemaphore(SemaphoreID semaphore) const7899 GLboolean Context::isSemaphore(SemaphoreID semaphore) const
7900 {
7901 if (semaphore.value == 0)
7902 {
7903 return GL_FALSE;
7904 }
7905
7906 return ConvertToGLBoolean(getSemaphore(semaphore));
7907 }
7908
semaphoreParameterui64v(SemaphoreID semaphore,GLenum pname,const GLuint64 * params)7909 void Context::semaphoreParameterui64v(SemaphoreID semaphore, GLenum pname, const GLuint64 *params)
7910 {
7911 UNIMPLEMENTED();
7912 }
7913
getSemaphoreParameterui64v(SemaphoreID semaphore,GLenum pname,GLuint64 * params)7914 void Context::getSemaphoreParameterui64v(SemaphoreID semaphore, GLenum pname, GLuint64 *params)
7915 {
7916 UNIMPLEMENTED();
7917 }
7918
waitSemaphore(SemaphoreID semaphoreHandle,GLuint numBufferBarriers,const BufferID * buffers,GLuint numTextureBarriers,const TextureID * textures,const GLenum * srcLayouts)7919 void Context::waitSemaphore(SemaphoreID semaphoreHandle,
7920 GLuint numBufferBarriers,
7921 const BufferID *buffers,
7922 GLuint numTextureBarriers,
7923 const TextureID *textures,
7924 const GLenum *srcLayouts)
7925 {
7926 Semaphore *semaphore = getSemaphore(semaphoreHandle);
7927 ASSERT(semaphore);
7928
7929 BufferBarrierVector bufferBarriers(numBufferBarriers);
7930 for (GLuint bufferBarrierIdx = 0; bufferBarrierIdx < numBufferBarriers; bufferBarrierIdx++)
7931 {
7932 bufferBarriers[bufferBarrierIdx] = getBuffer(buffers[bufferBarrierIdx]);
7933 }
7934
7935 TextureBarrierVector textureBarriers(numTextureBarriers);
7936 for (GLuint textureBarrierIdx = 0; textureBarrierIdx < numTextureBarriers; textureBarrierIdx++)
7937 {
7938 textureBarriers[textureBarrierIdx].texture = getTexture(textures[textureBarrierIdx]);
7939 textureBarriers[textureBarrierIdx].layout = srcLayouts[textureBarrierIdx];
7940 }
7941
7942 ANGLE_CONTEXT_TRY(semaphore->wait(this, bufferBarriers, textureBarriers));
7943 }
7944
signalSemaphore(SemaphoreID semaphoreHandle,GLuint numBufferBarriers,const BufferID * buffers,GLuint numTextureBarriers,const TextureID * textures,const GLenum * dstLayouts)7945 void Context::signalSemaphore(SemaphoreID semaphoreHandle,
7946 GLuint numBufferBarriers,
7947 const BufferID *buffers,
7948 GLuint numTextureBarriers,
7949 const TextureID *textures,
7950 const GLenum *dstLayouts)
7951 {
7952 Semaphore *semaphore = getSemaphore(semaphoreHandle);
7953 ASSERT(semaphore);
7954
7955 BufferBarrierVector bufferBarriers(numBufferBarriers);
7956 for (GLuint bufferBarrierIdx = 0; bufferBarrierIdx < numBufferBarriers; bufferBarrierIdx++)
7957 {
7958 bufferBarriers[bufferBarrierIdx] = getBuffer(buffers[bufferBarrierIdx]);
7959 }
7960
7961 TextureBarrierVector textureBarriers(numTextureBarriers);
7962 for (GLuint textureBarrierIdx = 0; textureBarrierIdx < numTextureBarriers; textureBarrierIdx++)
7963 {
7964 textureBarriers[textureBarrierIdx].texture = getTexture(textures[textureBarrierIdx]);
7965 textureBarriers[textureBarrierIdx].layout = dstLayouts[textureBarrierIdx];
7966 }
7967
7968 ANGLE_CONTEXT_TRY(semaphore->signal(this, bufferBarriers, textureBarriers));
7969 }
7970
importSemaphoreFd(SemaphoreID semaphore,HandleType handleType,GLint fd)7971 void Context::importSemaphoreFd(SemaphoreID semaphore, HandleType handleType, GLint fd)
7972 {
7973 Semaphore *semaphoreObject = getSemaphore(semaphore);
7974 ASSERT(semaphoreObject != nullptr);
7975 ANGLE_CONTEXT_TRY(semaphoreObject->importFd(this, handleType, fd));
7976 }
7977
importSemaphoreZirconHandle(SemaphoreID semaphore,HandleType handleType,GLuint handle)7978 void Context::importSemaphoreZirconHandle(SemaphoreID semaphore,
7979 HandleType handleType,
7980 GLuint handle)
7981 {
7982 Semaphore *semaphoreObject = getSemaphore(semaphore);
7983 ASSERT(semaphoreObject != nullptr);
7984 ANGLE_CONTEXT_TRY(semaphoreObject->importZirconHandle(this, handleType, handle));
7985 }
7986
eGLImageTargetTexture2D(TextureType target,GLeglImageOES image)7987 void Context::eGLImageTargetTexture2D(TextureType target, GLeglImageOES image)
7988 {
7989 Texture *texture = getTextureByType(target);
7990 egl::Image *imageObject = static_cast<egl::Image *>(image);
7991 ANGLE_CONTEXT_TRY(texture->setEGLImageTarget(this, target, imageObject));
7992 }
7993
eGLImageTargetRenderbufferStorage(GLenum target,GLeglImageOES image)7994 void Context::eGLImageTargetRenderbufferStorage(GLenum target, GLeglImageOES image)
7995 {
7996 Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer();
7997 egl::Image *imageObject = static_cast<egl::Image *>(image);
7998 ANGLE_CONTEXT_TRY(renderbuffer->setStorageEGLImageTarget(this, imageObject));
7999 }
8000
texStorage1D(GLenum target,GLsizei levels,GLenum internalformat,GLsizei width)8001 void Context::texStorage1D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width)
8002 {
8003 UNIMPLEMENTED();
8004 }
8005
getQueryParameterInfo(GLenum pname,GLenum * type,unsigned int * numParams) const8006 bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const
8007 {
8008 return GetQueryParameterInfo(mState, pname, type, numParams);
8009 }
8010
getIndexedQueryParameterInfo(GLenum target,GLenum * type,unsigned int * numParams) const8011 bool Context::getIndexedQueryParameterInfo(GLenum target,
8012 GLenum *type,
8013 unsigned int *numParams) const
8014 {
8015 if (getClientVersion() < Version(3, 0))
8016 {
8017 return false;
8018 }
8019
8020 switch (target)
8021 {
8022 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
8023 case GL_UNIFORM_BUFFER_BINDING:
8024 {
8025 *type = GL_INT;
8026 *numParams = 1;
8027 return true;
8028 }
8029 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
8030 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
8031 case GL_UNIFORM_BUFFER_START:
8032 case GL_UNIFORM_BUFFER_SIZE:
8033 {
8034 *type = GL_INT_64_ANGLEX;
8035 *numParams = 1;
8036 return true;
8037 }
8038 }
8039
8040 if (mSupportedExtensions.drawBuffersIndexedAny())
8041 {
8042 switch (target)
8043 {
8044 case GL_BLEND_SRC_RGB:
8045 case GL_BLEND_SRC_ALPHA:
8046 case GL_BLEND_DST_RGB:
8047 case GL_BLEND_DST_ALPHA:
8048 case GL_BLEND_EQUATION_RGB:
8049 case GL_BLEND_EQUATION_ALPHA:
8050 {
8051 *type = GL_INT;
8052 *numParams = 1;
8053 return true;
8054 }
8055 case GL_COLOR_WRITEMASK:
8056 {
8057 *type = GL_BOOL;
8058 *numParams = 4;
8059 return true;
8060 }
8061 }
8062 }
8063
8064 if (getClientVersion() < Version(3, 1))
8065 {
8066 return false;
8067 }
8068
8069 switch (target)
8070 {
8071 case GL_IMAGE_BINDING_LAYERED:
8072 {
8073 *type = GL_BOOL;
8074 *numParams = 1;
8075 return true;
8076 }
8077 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
8078 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
8079 case GL_ATOMIC_COUNTER_BUFFER_BINDING:
8080 case GL_SHADER_STORAGE_BUFFER_BINDING:
8081 case GL_VERTEX_BINDING_BUFFER:
8082 case GL_VERTEX_BINDING_DIVISOR:
8083 case GL_VERTEX_BINDING_OFFSET:
8084 case GL_VERTEX_BINDING_STRIDE:
8085 case GL_SAMPLE_MASK_VALUE:
8086 case GL_IMAGE_BINDING_NAME:
8087 case GL_IMAGE_BINDING_LEVEL:
8088 case GL_IMAGE_BINDING_LAYER:
8089 case GL_IMAGE_BINDING_ACCESS:
8090 case GL_IMAGE_BINDING_FORMAT:
8091 {
8092 *type = GL_INT;
8093 *numParams = 1;
8094 return true;
8095 }
8096 case GL_ATOMIC_COUNTER_BUFFER_START:
8097 case GL_ATOMIC_COUNTER_BUFFER_SIZE:
8098 case GL_SHADER_STORAGE_BUFFER_START:
8099 case GL_SHADER_STORAGE_BUFFER_SIZE:
8100 {
8101 *type = GL_INT_64_ANGLEX;
8102 *numParams = 1;
8103 return true;
8104 }
8105 }
8106
8107 return false;
8108 }
8109
getProgramNoResolveLink(ShaderProgramID handle) const8110 Program *Context::getProgramNoResolveLink(ShaderProgramID handle) const
8111 {
8112 return mState.mShaderProgramManager->getProgram(handle);
8113 }
8114
getShader(ShaderProgramID handle) const8115 Shader *Context::getShader(ShaderProgramID handle) const
8116 {
8117 return mState.mShaderProgramManager->getShader(handle);
8118 }
8119
getFrontendFeatures() const8120 const angle::FrontendFeatures &Context::getFrontendFeatures() const
8121 {
8122 return mDisplay->getFrontendFeatures();
8123 }
8124
isRenderbufferGenerated(RenderbufferID renderbuffer) const8125 bool Context::isRenderbufferGenerated(RenderbufferID renderbuffer) const
8126 {
8127 return mState.mRenderbufferManager->isHandleGenerated(renderbuffer);
8128 }
8129
isFramebufferGenerated(FramebufferID framebuffer) const8130 bool Context::isFramebufferGenerated(FramebufferID framebuffer) const
8131 {
8132 return mState.mFramebufferManager->isHandleGenerated(framebuffer);
8133 }
8134
isProgramPipelineGenerated(ProgramPipelineID pipeline) const8135 bool Context::isProgramPipelineGenerated(ProgramPipelineID pipeline) const
8136 {
8137 return mState.mProgramPipelineManager->isHandleGenerated(pipeline);
8138 }
8139
usingDisplayTextureShareGroup() const8140 bool Context::usingDisplayTextureShareGroup() const
8141 {
8142 return mDisplayTextureShareGroup;
8143 }
8144
getConvertedRenderbufferFormat(GLenum internalformat) const8145 GLenum Context::getConvertedRenderbufferFormat(GLenum internalformat) const
8146 {
8147 if (mState.mExtensions.webglCompatibility && mState.mClientVersion.major == 2 &&
8148 internalformat == GL_DEPTH_STENCIL)
8149 {
8150 return GL_DEPTH24_STENCIL8;
8151 }
8152 if (getClientType() == EGL_OPENGL_API && internalformat == GL_DEPTH_COMPONENT)
8153 {
8154 return GL_DEPTH_COMPONENT24;
8155 }
8156 return internalformat;
8157 }
8158
maxShaderCompilerThreads(GLuint count)8159 void Context::maxShaderCompilerThreads(GLuint count)
8160 {
8161 GLuint oldCount = mState.getMaxShaderCompilerThreads();
8162 mState.setMaxShaderCompilerThreads(count);
8163 // A count of zero specifies a request for no parallel compiling or linking.
8164 if ((oldCount == 0 || count == 0) && (oldCount != 0 || count != 0))
8165 {
8166 mThreadPool = angle::WorkerThreadPool::Create(count > 0);
8167 }
8168 mThreadPool->setMaxThreads(count);
8169 mImplementation->setMaxShaderCompilerThreads(count);
8170 }
8171
isGLES1() const8172 bool Context::isGLES1() const
8173 {
8174 return mState.getClientVersion() < Version(2, 0);
8175 }
8176
onSubjectStateChange(angle::SubjectIndex index,angle::SubjectMessage message)8177 void Context::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
8178 {
8179 switch (index)
8180 {
8181 case kVertexArraySubjectIndex:
8182 switch (message)
8183 {
8184 case angle::SubjectMessage::ContentsChanged:
8185 mState.setObjectDirty(GL_VERTEX_ARRAY);
8186 mStateCache.onVertexArrayBufferContentsChange(this);
8187 break;
8188 case angle::SubjectMessage::SubjectMapped:
8189 case angle::SubjectMessage::SubjectUnmapped:
8190 case angle::SubjectMessage::BindingChanged:
8191 mStateCache.onVertexArrayBufferStateChange(this);
8192 break;
8193 default:
8194 break;
8195 }
8196 break;
8197
8198 case kReadFramebufferSubjectIndex:
8199 ASSERT(message == angle::SubjectMessage::DirtyBitsFlagged);
8200 mState.setReadFramebufferDirty();
8201 break;
8202
8203 case kDrawFramebufferSubjectIndex:
8204 ASSERT(message == angle::SubjectMessage::DirtyBitsFlagged);
8205 mState.setDrawFramebufferDirty();
8206 mStateCache.onDrawFramebufferChange(this);
8207 break;
8208
8209 default:
8210 if (index < kTextureMaxSubjectIndex)
8211 {
8212 if (message != angle::SubjectMessage::ContentsChanged &&
8213 message != angle::SubjectMessage::BindingChanged)
8214 {
8215 mState.onActiveTextureStateChange(this, index);
8216 mStateCache.onActiveTextureChange(this);
8217 }
8218 }
8219 else if (index < kImageMaxSubjectIndex)
8220 {
8221 mState.onImageStateChange(this, index - kImage0SubjectIndex);
8222 if (message == angle::SubjectMessage::ContentsChanged)
8223 {
8224 mState.mDirtyBits.set(State::DirtyBitType::DIRTY_BIT_IMAGE_BINDINGS);
8225 }
8226 }
8227 else if (index < kUniformBufferMaxSubjectIndex)
8228 {
8229 mState.onUniformBufferStateChange(index - kUniformBuffer0SubjectIndex);
8230 mStateCache.onUniformBufferStateChange(this);
8231 }
8232 else
8233 {
8234 ASSERT(index < kSamplerMaxSubjectIndex);
8235 mState.setSamplerDirty(index - kSampler0SubjectIndex);
8236 mState.onActiveTextureStateChange(this, index - kSampler0SubjectIndex);
8237 }
8238 break;
8239 }
8240 }
8241
onProgramLink(Program * programObject)8242 angle::Result Context::onProgramLink(Program *programObject)
8243 {
8244 // Don't parallel link a program which is active in any GL contexts. With this assumption, we
8245 // don't need to worry that:
8246 // 1. Draw calls after link use the new executable code or the old one depending on the link
8247 // result.
8248 // 2. When a backend program, e.g., ProgramD3D is linking, other backend classes like
8249 // StateManager11, Renderer11, etc., may have a chance to make unexpected calls to
8250 // ProgramD3D.
8251 if (programObject->isInUse())
8252 {
8253 programObject->resolveLink(this);
8254 if (programObject->isLinked())
8255 {
8256 ANGLE_TRY(mState.onProgramExecutableChange(this, programObject));
8257 }
8258 mStateCache.onProgramExecutableChange(this);
8259 }
8260
8261 // TODO(http://anglebug.com/4559): Use the Subject/Observer pattern for
8262 // Programs in PPOs so we can remove this.
8263 // Need to mark any PPOs that this Program is bound to as dirty
8264 bool foundPipeline = false;
8265 for (ResourceMap<ProgramPipeline, ProgramPipelineID>::Iterator ppoIterator =
8266 mState.mProgramPipelineManager->begin();
8267 ppoIterator != mState.mProgramPipelineManager->end(); ++ppoIterator)
8268 {
8269 ProgramPipeline *pipeline = ppoIterator->second;
8270 pipeline->setDirtyBit(ProgramPipeline::DirtyBitType::DIRTY_BIT_PROGRAM_STAGE);
8271 foundPipeline = true;
8272 }
8273 // Also need to make sure the PPO dirty bits get handled by marking the PPO
8274 // objects dirty.
8275 if (foundPipeline)
8276 {
8277 mState.mDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM_PIPELINE);
8278 }
8279
8280 return angle::Result::Continue;
8281 }
8282
setDefaultFramebuffer(egl::Surface * drawSurface,egl::Surface * readSurface)8283 egl::Error Context::setDefaultFramebuffer(egl::Surface *drawSurface, egl::Surface *readSurface)
8284 {
8285 ASSERT(mCurrentDrawSurface == nullptr);
8286 ASSERT(mCurrentReadSurface == nullptr);
8287
8288 Framebuffer *newDefaultFramebuffer = nullptr;
8289
8290 mCurrentDrawSurface = drawSurface;
8291 mCurrentReadSurface = readSurface;
8292
8293 if (drawSurface != nullptr)
8294 {
8295 ANGLE_TRY(drawSurface->makeCurrent(this));
8296 newDefaultFramebuffer = drawSurface->createDefaultFramebuffer(this, readSurface);
8297 }
8298 else
8299 {
8300 newDefaultFramebuffer = new Framebuffer(this, mImplementation.get(), readSurface);
8301 }
8302 ASSERT(newDefaultFramebuffer);
8303
8304 if (readSurface && (drawSurface != readSurface))
8305 {
8306 ANGLE_TRY(readSurface->makeCurrent(this));
8307 }
8308
8309 // Update default framebuffer, the binding of the previous default
8310 // framebuffer (or lack of) will have a nullptr.
8311 mState.mFramebufferManager->setDefaultFramebuffer(newDefaultFramebuffer);
8312 if (mState.getDrawFramebuffer() == nullptr)
8313 {
8314 bindDrawFramebuffer(newDefaultFramebuffer->id());
8315 }
8316 if (mState.getReadFramebuffer() == nullptr)
8317 {
8318 bindReadFramebuffer(newDefaultFramebuffer->id());
8319 }
8320
8321 return egl::NoError();
8322 }
8323
unsetDefaultFramebuffer()8324 egl::Error Context::unsetDefaultFramebuffer()
8325 {
8326 gl::Framebuffer *defaultFramebuffer =
8327 mState.mFramebufferManager->getFramebuffer(Framebuffer::kDefaultDrawFramebufferHandle);
8328
8329 // Remove the default framebuffer
8330 if (mState.getReadFramebuffer() == defaultFramebuffer)
8331 {
8332 mState.setReadFramebufferBinding(nullptr);
8333 mReadFramebufferObserverBinding.bind(nullptr);
8334 }
8335
8336 if (mState.getDrawFramebuffer() == defaultFramebuffer)
8337 {
8338 mState.setDrawFramebufferBinding(nullptr);
8339 mDrawFramebufferObserverBinding.bind(nullptr);
8340 }
8341
8342 if (defaultFramebuffer)
8343 {
8344 defaultFramebuffer->onDestroy(this);
8345 delete defaultFramebuffer;
8346 }
8347
8348 mState.mFramebufferManager->setDefaultFramebuffer(nullptr);
8349
8350 // Always unset the current surface, even if setIsCurrent fails.
8351 egl::Surface *drawSurface = mCurrentDrawSurface;
8352 egl::Surface *readSurface = mCurrentReadSurface;
8353 mCurrentDrawSurface = nullptr;
8354 mCurrentReadSurface = nullptr;
8355 if (drawSurface)
8356 {
8357 ANGLE_TRY(drawSurface->unMakeCurrent(this));
8358 }
8359 if (drawSurface != readSurface)
8360 {
8361 ANGLE_TRY(readSurface->unMakeCurrent(this));
8362 }
8363
8364 return egl::NoError();
8365 }
8366
onPostSwap() const8367 void Context::onPostSwap() const
8368 {
8369 // Dump frame capture if enabled.
8370 mFrameCapture->onEndFrame(this);
8371 }
8372
getTexImage(TextureTarget target,GLint level,GLenum format,GLenum type,void * pixels)8373 void Context::getTexImage(TextureTarget target,
8374 GLint level,
8375 GLenum format,
8376 GLenum type,
8377 void *pixels)
8378 {
8379 Texture *texture = getTextureByTarget(target);
8380 Buffer *packBuffer = mState.getTargetBuffer(BufferBinding::PixelPack);
8381 ANGLE_CONTEXT_TRY(texture->getTexImage(this, mState.getPackState(), packBuffer, target, level,
8382 format, type, pixels));
8383 }
8384
getRenderbufferImage(GLenum target,GLenum format,GLenum type,void * pixels)8385 void Context::getRenderbufferImage(GLenum target, GLenum format, GLenum type, void *pixels)
8386 {
8387 Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer();
8388 Buffer *packBuffer = mState.getTargetBuffer(BufferBinding::PixelPack);
8389 ANGLE_CONTEXT_TRY(renderbuffer->getRenderbufferImage(this, mState.getPackState(), packBuffer,
8390 format, type, pixels));
8391 }
8392
8393 // ErrorSet implementation.
ErrorSet(Context * context)8394 ErrorSet::ErrorSet(Context *context) : mContext(context) {}
8395
8396 ErrorSet::~ErrorSet() = default;
8397
handleError(GLenum errorCode,const char * message,const char * file,const char * function,unsigned int line)8398 void ErrorSet::handleError(GLenum errorCode,
8399 const char *message,
8400 const char *file,
8401 const char *function,
8402 unsigned int line)
8403 {
8404 if (errorCode == GL_OUT_OF_MEMORY &&
8405 mContext->getGraphicsResetStrategy() == GL_LOSE_CONTEXT_ON_RESET_EXT &&
8406 mContext->getDisplay()->getFrontendFeatures().loseContextOnOutOfMemory.enabled)
8407 {
8408 mContext->markContextLost(GraphicsResetStatus::UnknownContextReset);
8409 }
8410
8411 std::stringstream errorStream;
8412 errorStream << "Error: " << gl::FmtHex(errorCode) << ", in " << file << ", " << function << ":"
8413 << line << ". " << message;
8414
8415 std::string formattedMessage = errorStream.str();
8416
8417 // Process the error, but log it with WARN severity so it shows up in logs.
8418 ASSERT(errorCode != GL_NO_ERROR);
8419 mErrors.insert(errorCode);
8420
8421 mContext->getState().getDebug().insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR,
8422 errorCode, GL_DEBUG_SEVERITY_HIGH, message,
8423 gl::LOG_WARN);
8424 }
8425
validationError(GLenum errorCode,const char * message)8426 void ErrorSet::validationError(GLenum errorCode, const char *message)
8427 {
8428 ASSERT(errorCode != GL_NO_ERROR);
8429 mErrors.insert(errorCode);
8430
8431 mContext->getState().getDebug().insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR,
8432 errorCode, GL_DEBUG_SEVERITY_HIGH, message,
8433 gl::LOG_INFO);
8434 }
8435
empty() const8436 bool ErrorSet::empty() const
8437 {
8438 return mErrors.empty();
8439 }
8440
popError()8441 GLenum ErrorSet::popError()
8442 {
8443 ASSERT(!empty());
8444 GLenum error = *mErrors.begin();
8445 mErrors.erase(mErrors.begin());
8446 return error;
8447 }
8448
8449 // StateCache implementation.
StateCache()8450 StateCache::StateCache()
8451 : mCachedHasAnyEnabledClientAttrib(false),
8452 mCachedNonInstancedVertexElementLimit(0),
8453 mCachedInstancedVertexElementLimit(0),
8454 mCachedBasicDrawStatesError(kInvalidPointer),
8455 mCachedBasicDrawElementsError(kInvalidPointer),
8456 mCachedTransformFeedbackActiveUnpaused(false)
8457 {}
8458
8459 StateCache::~StateCache() = default;
8460
updateVertexElementLimits(Context * context)8461 ANGLE_INLINE void StateCache::updateVertexElementLimits(Context *context)
8462 {
8463 if (context->isBufferAccessValidationEnabled())
8464 {
8465 updateVertexElementLimitsImpl(context);
8466 }
8467 }
8468
initialize(Context * context)8469 void StateCache::initialize(Context *context)
8470 {
8471 updateValidDrawModes(context);
8472 updateValidBindTextureTypes(context);
8473 updateValidDrawElementsTypes(context);
8474 updateBasicDrawStatesError();
8475 updateBasicDrawElementsError();
8476 updateVertexAttribTypesValidation(context);
8477 }
8478
updateActiveAttribsMask(Context * context)8479 void StateCache::updateActiveAttribsMask(Context *context)
8480 {
8481 bool isGLES1 = context->isGLES1();
8482 const State &glState = context->getState();
8483
8484 if (!isGLES1 && !glState.getProgramExecutable())
8485 {
8486 mCachedActiveBufferedAttribsMask = AttributesMask();
8487 mCachedActiveClientAttribsMask = AttributesMask();
8488 mCachedActiveDefaultAttribsMask = AttributesMask();
8489 return;
8490 }
8491
8492 AttributesMask activeAttribs =
8493 isGLES1 ? glState.gles1().getActiveAttributesMask()
8494 : glState.getProgramExecutable()->getActiveAttribLocationsMask();
8495
8496 const VertexArray *vao = glState.getVertexArray();
8497 ASSERT(vao);
8498
8499 const AttributesMask &clientAttribs = vao->getClientAttribsMask();
8500 const AttributesMask &enabledAttribs = vao->getEnabledAttributesMask();
8501 const AttributesMask &activeEnabled = activeAttribs & enabledAttribs;
8502
8503 mCachedActiveClientAttribsMask = activeEnabled & clientAttribs;
8504 mCachedActiveBufferedAttribsMask = activeEnabled & ~clientAttribs;
8505 mCachedActiveDefaultAttribsMask = activeAttribs & ~enabledAttribs;
8506 mCachedHasAnyEnabledClientAttrib = (clientAttribs & enabledAttribs).any();
8507 }
8508
updateVertexElementLimitsImpl(Context * context)8509 void StateCache::updateVertexElementLimitsImpl(Context *context)
8510 {
8511 ASSERT(context->isBufferAccessValidationEnabled());
8512
8513 const VertexArray *vao = context->getState().getVertexArray();
8514
8515 mCachedNonInstancedVertexElementLimit = std::numeric_limits<GLint64>::max();
8516 mCachedInstancedVertexElementLimit = std::numeric_limits<GLint64>::max();
8517
8518 // VAO can be null on Context startup. If we make this computation lazier we could ASSERT.
8519 // If there are no buffered attributes then we should not limit the draw call count.
8520 if (!vao || !mCachedActiveBufferedAttribsMask.any())
8521 {
8522 return;
8523 }
8524
8525 const auto &vertexAttribs = vao->getVertexAttributes();
8526 const auto &vertexBindings = vao->getVertexBindings();
8527
8528 for (size_t attributeIndex : mCachedActiveBufferedAttribsMask)
8529 {
8530 const VertexAttribute &attrib = vertexAttribs[attributeIndex];
8531
8532 const VertexBinding &binding = vertexBindings[attrib.bindingIndex];
8533 ASSERT(context->isGLES1() ||
8534 context->getState().getProgramExecutable()->isAttribLocationActive(attributeIndex));
8535
8536 GLint64 limit = attrib.getCachedElementLimit();
8537 if (binding.getDivisor() > 0)
8538 {
8539 mCachedInstancedVertexElementLimit =
8540 std::min(mCachedInstancedVertexElementLimit, limit);
8541 }
8542 else
8543 {
8544 mCachedNonInstancedVertexElementLimit =
8545 std::min(mCachedNonInstancedVertexElementLimit, limit);
8546 }
8547 }
8548 }
8549
updateBasicDrawStatesError()8550 void StateCache::updateBasicDrawStatesError()
8551 {
8552 mCachedBasicDrawStatesError = kInvalidPointer;
8553 }
8554
updateBasicDrawElementsError()8555 void StateCache::updateBasicDrawElementsError()
8556 {
8557 mCachedBasicDrawElementsError = kInvalidPointer;
8558 }
8559
getBasicDrawStatesErrorImpl(const Context * context) const8560 intptr_t StateCache::getBasicDrawStatesErrorImpl(const Context *context) const
8561 {
8562 ASSERT(mCachedBasicDrawStatesError == kInvalidPointer);
8563 mCachedBasicDrawStatesError = reinterpret_cast<intptr_t>(ValidateDrawStates(context));
8564 return mCachedBasicDrawStatesError;
8565 }
8566
getBasicDrawElementsErrorImpl(const Context * context) const8567 intptr_t StateCache::getBasicDrawElementsErrorImpl(const Context *context) const
8568 {
8569 ASSERT(mCachedBasicDrawElementsError == kInvalidPointer);
8570 mCachedBasicDrawElementsError = reinterpret_cast<intptr_t>(ValidateDrawElementsStates(context));
8571 return mCachedBasicDrawElementsError;
8572 }
8573
onVertexArrayBindingChange(Context * context)8574 void StateCache::onVertexArrayBindingChange(Context *context)
8575 {
8576 updateActiveAttribsMask(context);
8577 updateVertexElementLimits(context);
8578 updateBasicDrawStatesError();
8579 }
8580
onProgramExecutableChange(Context * context)8581 void StateCache::onProgramExecutableChange(Context *context)
8582 {
8583 updateActiveAttribsMask(context);
8584 updateVertexElementLimits(context);
8585 updateBasicDrawStatesError();
8586 updateValidDrawModes(context);
8587 updateActiveShaderStorageBufferIndices(context);
8588 }
8589
onVertexArrayFormatChange(Context * context)8590 void StateCache::onVertexArrayFormatChange(Context *context)
8591 {
8592 updateVertexElementLimits(context);
8593 }
8594
onVertexArrayBufferContentsChange(Context * context)8595 void StateCache::onVertexArrayBufferContentsChange(Context *context)
8596 {
8597 updateVertexElementLimits(context);
8598 updateBasicDrawStatesError();
8599 }
8600
onVertexArrayStateChange(Context * context)8601 void StateCache::onVertexArrayStateChange(Context *context)
8602 {
8603 updateActiveAttribsMask(context);
8604 updateVertexElementLimits(context);
8605 updateBasicDrawStatesError();
8606 }
8607
onVertexArrayBufferStateChange(Context * context)8608 void StateCache::onVertexArrayBufferStateChange(Context *context)
8609 {
8610 updateBasicDrawStatesError();
8611 updateBasicDrawElementsError();
8612 }
8613
onGLES1ClientStateChange(Context * context)8614 void StateCache::onGLES1ClientStateChange(Context *context)
8615 {
8616 updateActiveAttribsMask(context);
8617 }
8618
onDrawFramebufferChange(Context * context)8619 void StateCache::onDrawFramebufferChange(Context *context)
8620 {
8621 updateBasicDrawStatesError();
8622 }
8623
onContextCapChange(Context * context)8624 void StateCache::onContextCapChange(Context *context)
8625 {
8626 updateBasicDrawStatesError();
8627 }
8628
onStencilStateChange(Context * context)8629 void StateCache::onStencilStateChange(Context *context)
8630 {
8631 updateBasicDrawStatesError();
8632 }
8633
onDefaultVertexAttributeChange(Context * context)8634 void StateCache::onDefaultVertexAttributeChange(Context *context)
8635 {
8636 updateBasicDrawStatesError();
8637 }
8638
onActiveTextureChange(Context * context)8639 void StateCache::onActiveTextureChange(Context *context)
8640 {
8641 updateBasicDrawStatesError();
8642 }
8643
onQueryChange(Context * context)8644 void StateCache::onQueryChange(Context *context)
8645 {
8646 updateBasicDrawStatesError();
8647 }
8648
onActiveTransformFeedbackChange(Context * context)8649 void StateCache::onActiveTransformFeedbackChange(Context *context)
8650 {
8651 updateTransformFeedbackActiveUnpaused(context);
8652 updateBasicDrawStatesError();
8653 updateBasicDrawElementsError();
8654 updateValidDrawModes(context);
8655 }
8656
onUniformBufferStateChange(Context * context)8657 void StateCache::onUniformBufferStateChange(Context *context)
8658 {
8659 updateBasicDrawStatesError();
8660 }
8661
onColorMaskChange(Context * context)8662 void StateCache::onColorMaskChange(Context *context)
8663 {
8664 updateBasicDrawStatesError();
8665 }
8666
onBlendFuncIndexedChange(Context * context)8667 void StateCache::onBlendFuncIndexedChange(Context *context)
8668 {
8669 updateBasicDrawStatesError();
8670 }
8671
setValidDrawModes(bool pointsOK,bool linesOK,bool trisOK,bool lineAdjOK,bool triAdjOK)8672 void StateCache::setValidDrawModes(bool pointsOK,
8673 bool linesOK,
8674 bool trisOK,
8675 bool lineAdjOK,
8676 bool triAdjOK)
8677 {
8678 mCachedValidDrawModes[PrimitiveMode::Points] = pointsOK;
8679 mCachedValidDrawModes[PrimitiveMode::Lines] = linesOK;
8680 mCachedValidDrawModes[PrimitiveMode::LineStrip] = linesOK;
8681 mCachedValidDrawModes[PrimitiveMode::LineLoop] = linesOK;
8682 mCachedValidDrawModes[PrimitiveMode::Triangles] = trisOK;
8683 mCachedValidDrawModes[PrimitiveMode::TriangleFan] = trisOK;
8684 mCachedValidDrawModes[PrimitiveMode::TriangleStrip] = trisOK;
8685 mCachedValidDrawModes[PrimitiveMode::LinesAdjacency] = lineAdjOK;
8686 mCachedValidDrawModes[PrimitiveMode::LineStripAdjacency] = lineAdjOK;
8687 mCachedValidDrawModes[PrimitiveMode::TrianglesAdjacency] = triAdjOK;
8688 mCachedValidDrawModes[PrimitiveMode::TriangleStripAdjacency] = triAdjOK;
8689 }
8690
updateValidDrawModes(Context * context)8691 void StateCache::updateValidDrawModes(Context *context)
8692 {
8693 const State &state = context->getState();
8694 Program *program = state.getProgram();
8695
8696 if (mCachedTransformFeedbackActiveUnpaused)
8697 {
8698 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
8699
8700 // ES Spec 3.0 validation text:
8701 // When transform feedback is active and not paused, all geometric primitives generated must
8702 // match the value of primitiveMode passed to BeginTransformFeedback. The error
8703 // INVALID_OPERATION is generated by DrawArrays and DrawArraysInstanced if mode is not
8704 // identical to primitiveMode. The error INVALID_OPERATION is also generated by
8705 // DrawElements, DrawElementsInstanced, and DrawRangeElements while transform feedback is
8706 // active and not paused, regardless of mode. Any primitive type may be used while transform
8707 // feedback is paused.
8708 if (!context->getExtensions().geometryShader)
8709 {
8710 mCachedValidDrawModes.fill(false);
8711 mCachedValidDrawModes[curTransformFeedback->getPrimitiveMode()] = true;
8712 return;
8713 }
8714
8715 // EXT_geometry_shader validation text:
8716 // When transform feedback is active and not paused, all geometric primitives generated must
8717 // be compatible with the value of <primitiveMode> passed to BeginTransformFeedback. If a
8718 // geometry shader is active, the type of primitive emitted by that shader is used instead
8719 // of the <mode> parameter passed to drawing commands for the purposes of this error check.
8720 // Any primitive type may be used while transform feedback is paused.
8721 bool pointsOK = curTransformFeedback->getPrimitiveMode() == PrimitiveMode::Points;
8722 bool linesOK = curTransformFeedback->getPrimitiveMode() == PrimitiveMode::Lines;
8723 bool trisOK = curTransformFeedback->getPrimitiveMode() == PrimitiveMode::Triangles;
8724
8725 setValidDrawModes(pointsOK, linesOK, trisOK, false, false);
8726 return;
8727 }
8728
8729 const ProgramExecutable *programExecutable = context->getState().getProgramExecutable();
8730 if (!programExecutable || !programExecutable->hasLinkedShaderStage(ShaderType::Geometry))
8731 {
8732 mCachedValidDrawModes = kValidBasicDrawModes;
8733 return;
8734 }
8735
8736 ASSERT(programExecutable->hasLinkedShaderStage(ShaderType::Geometry));
8737 PrimitiveMode gsMode = program->getGeometryShaderInputPrimitiveType();
8738
8739 bool pointsOK = gsMode == PrimitiveMode::Points;
8740 bool linesOK = gsMode == PrimitiveMode::Lines;
8741 bool trisOK = gsMode == PrimitiveMode::Triangles;
8742 bool lineAdjOK = gsMode == PrimitiveMode::LinesAdjacency;
8743 bool triAdjOK = gsMode == PrimitiveMode::TrianglesAdjacency;
8744
8745 setValidDrawModes(pointsOK, linesOK, trisOK, lineAdjOK, triAdjOK);
8746 }
8747
updateValidBindTextureTypes(Context * context)8748 void StateCache::updateValidBindTextureTypes(Context *context)
8749 {
8750 const Extensions &exts = context->getExtensions();
8751 bool isGLES3 = context->getClientMajorVersion() >= 3;
8752 bool isGLES31 = context->getClientVersion() >= Version(3, 1);
8753
8754 mCachedValidBindTextureTypes = {{
8755 {TextureType::_2D, true},
8756 {TextureType::_2DArray, isGLES3},
8757 {TextureType::_2DMultisample, isGLES31 || exts.textureMultisample},
8758 {TextureType::_2DMultisampleArray, exts.textureStorageMultisample2DArrayOES},
8759 {TextureType::_3D, isGLES3 || exts.texture3DOES},
8760 {TextureType::External, exts.eglImageExternalOES || exts.eglStreamConsumerExternalNV},
8761 {TextureType::Rectangle, exts.textureRectangle},
8762 {TextureType::CubeMap, true},
8763 {TextureType::VideoImage, exts.webglVideoTexture},
8764 }};
8765 }
8766
updateValidDrawElementsTypes(Context * context)8767 void StateCache::updateValidDrawElementsTypes(Context *context)
8768 {
8769 bool supportsUint =
8770 (context->getClientMajorVersion() >= 3 || context->getExtensions().elementIndexUintOES);
8771
8772 mCachedValidDrawElementsTypes = {{
8773 {DrawElementsType::UnsignedByte, true},
8774 {DrawElementsType::UnsignedShort, true},
8775 {DrawElementsType::UnsignedInt, supportsUint},
8776 }};
8777 }
8778
updateTransformFeedbackActiveUnpaused(Context * context)8779 void StateCache::updateTransformFeedbackActiveUnpaused(Context *context)
8780 {
8781 TransformFeedback *xfb = context->getState().getCurrentTransformFeedback();
8782 mCachedTransformFeedbackActiveUnpaused = xfb && xfb->isActive() && !xfb->isPaused();
8783 }
8784
updateVertexAttribTypesValidation(Context * context)8785 void StateCache::updateVertexAttribTypesValidation(Context *context)
8786 {
8787 VertexAttribTypeCase halfFloatValidity = (context->getExtensions().vertexHalfFloatOES)
8788 ? VertexAttribTypeCase::Valid
8789 : VertexAttribTypeCase::Invalid;
8790
8791 VertexAttribTypeCase vertexType1010102Validity =
8792 (context->getExtensions().vertexAttribType1010102OES) ? VertexAttribTypeCase::ValidSize3or4
8793 : VertexAttribTypeCase::Invalid;
8794
8795 if (context->getClientMajorVersion() <= 2)
8796 {
8797 mCachedVertexAttribTypesValidation = {{
8798 {VertexAttribType::Byte, VertexAttribTypeCase::Valid},
8799 {VertexAttribType::Short, VertexAttribTypeCase::Valid},
8800 {VertexAttribType::UnsignedByte, VertexAttribTypeCase::Valid},
8801 {VertexAttribType::UnsignedShort, VertexAttribTypeCase::Valid},
8802 {VertexAttribType::Float, VertexAttribTypeCase::Valid},
8803 {VertexAttribType::Fixed, VertexAttribTypeCase::Valid},
8804 {VertexAttribType::HalfFloatOES, halfFloatValidity},
8805 }};
8806 }
8807 else
8808 {
8809 mCachedVertexAttribTypesValidation = {{
8810 {VertexAttribType::Byte, VertexAttribTypeCase::Valid},
8811 {VertexAttribType::Short, VertexAttribTypeCase::Valid},
8812 {VertexAttribType::Int, VertexAttribTypeCase::Valid},
8813 {VertexAttribType::UnsignedByte, VertexAttribTypeCase::Valid},
8814 {VertexAttribType::UnsignedShort, VertexAttribTypeCase::Valid},
8815 {VertexAttribType::UnsignedInt, VertexAttribTypeCase::Valid},
8816 {VertexAttribType::Float, VertexAttribTypeCase::Valid},
8817 {VertexAttribType::HalfFloat, VertexAttribTypeCase::Valid},
8818 {VertexAttribType::Fixed, VertexAttribTypeCase::Valid},
8819 {VertexAttribType::Int2101010, VertexAttribTypeCase::ValidSize4Only},
8820 {VertexAttribType::HalfFloatOES, halfFloatValidity},
8821 {VertexAttribType::UnsignedInt2101010, VertexAttribTypeCase::ValidSize4Only},
8822 {VertexAttribType::Int1010102, vertexType1010102Validity},
8823 {VertexAttribType::UnsignedInt1010102, vertexType1010102Validity},
8824 }};
8825
8826 mCachedIntegerVertexAttribTypesValidation = {{
8827 {VertexAttribType::Byte, VertexAttribTypeCase::Valid},
8828 {VertexAttribType::Short, VertexAttribTypeCase::Valid},
8829 {VertexAttribType::Int, VertexAttribTypeCase::Valid},
8830 {VertexAttribType::UnsignedByte, VertexAttribTypeCase::Valid},
8831 {VertexAttribType::UnsignedShort, VertexAttribTypeCase::Valid},
8832 {VertexAttribType::UnsignedInt, VertexAttribTypeCase::Valid},
8833 }};
8834 }
8835 }
8836
updateActiveShaderStorageBufferIndices(Context * context)8837 void StateCache::updateActiveShaderStorageBufferIndices(Context *context)
8838 {
8839 mCachedActiveShaderStorageBufferIndices.reset();
8840 Program *program = context->getState().getProgram();
8841 if (program)
8842 {
8843 for (const InterfaceBlock &block : program->getState().getShaderStorageBlocks())
8844 {
8845 mCachedActiveShaderStorageBufferIndices.set(block.binding);
8846 }
8847 }
8848 }
8849 } // namespace gl
8850