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