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