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