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