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