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