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