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