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