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