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