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