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