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