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