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