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