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