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