1 //
2 // Copyright 2014 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 // State.cpp: Implements the State class, encapsulating raw GL state.
8
9 #include "libANGLE/State.h"
10
11 #include <string.h>
12 #include <limits>
13
14 #include "common/bitset_utils.h"
15 #include "common/mathutil.h"
16 #include "common/matrix_utils.h"
17 #include "libANGLE/Buffer.h"
18 #include "libANGLE/Caps.h"
19 #include "libANGLE/Context.h"
20 #include "libANGLE/Debug.h"
21 #include "libANGLE/Framebuffer.h"
22 #include "libANGLE/FramebufferAttachment.h"
23 #include "libANGLE/Query.h"
24 #include "libANGLE/VertexArray.h"
25 #include "libANGLE/formatutils.h"
26 #include "libANGLE/queryconversions.h"
27 #include "libANGLE/queryutils.h"
28 #include "libANGLE/renderer/ContextImpl.h"
29 #include "libANGLE/renderer/TextureImpl.h"
30
31 namespace gl
32 {
33
34 namespace
35 {
GetAlternativeQueryType(QueryType type,QueryType * alternativeType)36 bool GetAlternativeQueryType(QueryType type, QueryType *alternativeType)
37 {
38 switch (type)
39 {
40 case QueryType::AnySamples:
41 *alternativeType = QueryType::AnySamplesConservative;
42 return true;
43 case QueryType::AnySamplesConservative:
44 *alternativeType = QueryType::AnySamples;
45 return true;
46 default:
47 return false;
48 }
49 }
50
51 // Mapping from a buffer binding type to a dirty bit type.
52 constexpr angle::PackedEnumMap<BufferBinding, size_t> kBufferBindingDirtyBits = {{
53 {BufferBinding::AtomicCounter, State::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING},
54 {BufferBinding::DispatchIndirect, State::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING},
55 {BufferBinding::DrawIndirect, State::DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING},
56 {BufferBinding::PixelPack, State::DIRTY_BIT_PACK_BUFFER_BINDING},
57 {BufferBinding::PixelUnpack, State::DIRTY_BIT_UNPACK_BUFFER_BINDING},
58 {BufferBinding::ShaderStorage, State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING},
59 {BufferBinding::Uniform, State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS},
60 }};
61
62 // Returns a buffer binding function depending on if a dirty bit is set.
63 template <BufferBinding Target>
GetBufferBindingSetter()64 constexpr std::pair<BufferBinding, State::BufferBindingSetter> GetBufferBindingSetter()
65 {
66 return std::make_pair(Target, kBufferBindingDirtyBits[Target] != 0
67 ? &State::setGenericBufferBindingWithBit<Target>
68 : &State::setGenericBufferBinding<Target>);
69 }
70
71 template <typename T>
72 using ContextStateMember = T *(State::*);
73
74 template <typename T>
AllocateOrGetSharedResourceManager(const State * shareContextState,ContextStateMember<T> member,T * shareResources=nullptr)75 T *AllocateOrGetSharedResourceManager(const State *shareContextState,
76 ContextStateMember<T> member,
77 T *shareResources = nullptr)
78 {
79 if (shareContextState)
80 {
81 T *resourceManager = (*shareContextState).*member;
82 ASSERT(!resourceManager || resourceManager == shareResources || !shareResources);
83 resourceManager->addRef();
84 return resourceManager;
85 }
86 else if (shareResources)
87 {
88 shareResources->addRef();
89 return shareResources;
90 }
91 else
92 {
93 return new T();
94 }
95 }
96
97 // TODO(https://anglebug.com/3889): Remove this helper function after blink and chromium part
98 // refactory done.
IsTextureCompatibleWithSampler(TextureType texture,TextureType sampler)99 bool IsTextureCompatibleWithSampler(TextureType texture, TextureType sampler)
100 {
101 if (sampler == texture)
102 {
103 return true;
104 }
105
106 if (sampler == TextureType::VideoImage)
107 {
108 if (texture == TextureType::VideoImage || texture == TextureType::_2D)
109 {
110 return true;
111 }
112 }
113
114 return false;
115 }
116
117 uint32_t gIDCounter = 1;
118 } // namespace
119
120 template <typename BindingT, typename... ArgsT>
UpdateNonTFBufferBindingWebGL(const Context * context,BindingT * binding,Buffer * buffer,ArgsT...args)121 ANGLE_INLINE void UpdateNonTFBufferBindingWebGL(const Context *context,
122 BindingT *binding,
123 Buffer *buffer,
124 ArgsT... args)
125 {
126 Buffer *oldBuffer = binding->get();
127 if (oldBuffer)
128 {
129 oldBuffer->onNonTFBindingChanged(-1);
130 oldBuffer->release(context);
131 }
132 binding->assign(buffer, args...);
133 if (buffer)
134 {
135 buffer->addRef();
136 buffer->onNonTFBindingChanged(1);
137 }
138 }
139
140 template <typename BindingT, typename... ArgsT>
UpdateTFBufferBindingWebGL(const Context * context,BindingT * binding,bool indexed,ArgsT...args)141 void UpdateTFBufferBindingWebGL(const Context *context,
142 BindingT *binding,
143 bool indexed,
144 ArgsT... args)
145 {
146 if (binding->get())
147 (*binding)->onTFBindingChanged(context, false, indexed);
148 binding->set(context, args...);
149 if (binding->get())
150 (*binding)->onTFBindingChanged(context, true, indexed);
151 }
152
UpdateBufferBinding(const Context * context,BindingPointer<Buffer> * binding,Buffer * buffer,BufferBinding target)153 void UpdateBufferBinding(const Context *context,
154 BindingPointer<Buffer> *binding,
155 Buffer *buffer,
156 BufferBinding target)
157 {
158 if (context->isWebGL())
159 {
160 if (target == BufferBinding::TransformFeedback)
161 {
162 UpdateTFBufferBindingWebGL(context, binding, false, buffer);
163 }
164 else
165 {
166 UpdateNonTFBufferBindingWebGL(context, binding, buffer);
167 }
168 }
169 else
170 {
171 binding->set(context, buffer);
172 }
173 }
174
UpdateIndexedBufferBinding(const Context * context,OffsetBindingPointer<Buffer> * binding,Buffer * buffer,BufferBinding target,GLintptr offset,GLsizeiptr size)175 void UpdateIndexedBufferBinding(const Context *context,
176 OffsetBindingPointer<Buffer> *binding,
177 Buffer *buffer,
178 BufferBinding target,
179 GLintptr offset,
180 GLsizeiptr size)
181 {
182 if (context->isWebGL())
183 {
184 if (target == BufferBinding::TransformFeedback)
185 {
186 UpdateTFBufferBindingWebGL(context, binding, true, buffer, offset, size);
187 }
188 else
189 {
190 UpdateNonTFBufferBindingWebGL(context, binding, buffer, offset, size);
191 }
192 }
193 else
194 {
195 binding->set(context, buffer, offset, size);
196 }
197 }
198
199 // These template functions must be defined before they are instantiated in kBufferSetters.
200 template <BufferBinding Target>
setGenericBufferBindingWithBit(const Context * context,Buffer * buffer)201 void State::setGenericBufferBindingWithBit(const Context *context, Buffer *buffer)
202 {
203 if (context->isWebGL())
204 {
205 UpdateNonTFBufferBindingWebGL(context, &mBoundBuffers[Target], buffer);
206 }
207 else
208 {
209 mBoundBuffers[Target].set(context, buffer);
210 }
211 mDirtyBits.set(kBufferBindingDirtyBits[Target]);
212 }
213
214 template <BufferBinding Target>
setGenericBufferBinding(const Context * context,Buffer * buffer)215 void State::setGenericBufferBinding(const Context *context, Buffer *buffer)
216 {
217 if (context->isWebGL())
218 {
219 UpdateNonTFBufferBindingWebGL(context, &mBoundBuffers[Target], buffer);
220 }
221 else
222 {
223 mBoundBuffers[Target].set(context, buffer);
224 }
225 }
226
227 template <>
setGenericBufferBinding(const Context * context,Buffer * buffer)228 void State::setGenericBufferBinding<BufferBinding::TransformFeedback>(const Context *context,
229 Buffer *buffer)
230 {
231 if (context->isWebGL())
232 {
233 UpdateTFBufferBindingWebGL(context, &mBoundBuffers[BufferBinding::TransformFeedback], false,
234 buffer);
235 }
236 else
237 {
238 mBoundBuffers[BufferBinding::TransformFeedback].set(context, buffer);
239 }
240 }
241
242 template <>
setGenericBufferBinding(const Context * context,Buffer * buffer)243 void State::setGenericBufferBinding<BufferBinding::ElementArray>(const Context *context,
244 Buffer *buffer)
245 {
246 Buffer *oldBuffer = mVertexArray->mState.mElementArrayBuffer.get();
247 if (oldBuffer)
248 {
249 oldBuffer->removeObserver(&mVertexArray->mState.mElementArrayBuffer);
250 oldBuffer->removeContentsObserver(mVertexArray, kElementArrayBufferIndex);
251 if (context->isWebGL())
252 {
253 oldBuffer->onNonTFBindingChanged(-1);
254 }
255 oldBuffer->release(context);
256 }
257 mVertexArray->mState.mElementArrayBuffer.assign(buffer);
258 if (buffer)
259 {
260 buffer->addObserver(&mVertexArray->mState.mElementArrayBuffer);
261 buffer->addContentsObserver(mVertexArray, kElementArrayBufferIndex);
262 if (context->isWebGL())
263 {
264 buffer->onNonTFBindingChanged(1);
265 }
266 buffer->addRef();
267 }
268 mVertexArray->mDirtyBits.set(VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
269 mVertexArray->mIndexRangeCache.invalidate();
270 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
271 }
272
273 const angle::PackedEnumMap<BufferBinding, State::BufferBindingSetter> State::kBufferSetters = {{
274 GetBufferBindingSetter<BufferBinding::Array>(),
275 GetBufferBindingSetter<BufferBinding::AtomicCounter>(),
276 GetBufferBindingSetter<BufferBinding::CopyRead>(),
277 GetBufferBindingSetter<BufferBinding::CopyWrite>(),
278 GetBufferBindingSetter<BufferBinding::DispatchIndirect>(),
279 GetBufferBindingSetter<BufferBinding::DrawIndirect>(),
280 GetBufferBindingSetter<BufferBinding::ElementArray>(),
281 GetBufferBindingSetter<BufferBinding::PixelPack>(),
282 GetBufferBindingSetter<BufferBinding::PixelUnpack>(),
283 GetBufferBindingSetter<BufferBinding::ShaderStorage>(),
284 GetBufferBindingSetter<BufferBinding::Texture>(),
285 GetBufferBindingSetter<BufferBinding::TransformFeedback>(),
286 GetBufferBindingSetter<BufferBinding::Uniform>(),
287 }};
288
ActiveTexturesCache()289 ActiveTexturesCache::ActiveTexturesCache() : mTextures{} {}
290
~ActiveTexturesCache()291 ActiveTexturesCache::~ActiveTexturesCache()
292 {
293 ASSERT(empty());
294 }
295
clear()296 void ActiveTexturesCache::clear()
297 {
298 for (size_t textureIndex = 0; textureIndex < mTextures.size(); ++textureIndex)
299 {
300 reset(textureIndex);
301 }
302 }
303
empty() const304 bool ActiveTexturesCache::empty() const
305 {
306 for (Texture *texture : mTextures)
307 {
308 if (texture)
309 {
310 return false;
311 }
312 }
313
314 return true;
315 }
316
reset(size_t textureIndex)317 ANGLE_INLINE void ActiveTexturesCache::reset(size_t textureIndex)
318 {
319 if (mTextures[textureIndex])
320 {
321 mTextures[textureIndex] = nullptr;
322 }
323 }
324
set(size_t textureIndex,Texture * texture)325 ANGLE_INLINE void ActiveTexturesCache::set(size_t textureIndex, Texture *texture)
326 {
327 ASSERT(texture);
328 mTextures[textureIndex] = texture;
329 }
330
State(const State * shareContextState,egl::ShareGroup * shareGroup,TextureManager * shareTextures,SemaphoreManager * shareSemaphores,const OverlayType * overlay,const EGLenum clientType,const Version & clientVersion,bool debug,bool bindGeneratesResourceCHROMIUM,bool clientArraysEnabled,bool robustResourceInit,bool programBinaryCacheEnabled,EGLenum contextPriority,bool hasProtectedContent)331 State::State(const State *shareContextState,
332 egl::ShareGroup *shareGroup,
333 TextureManager *shareTextures,
334 SemaphoreManager *shareSemaphores,
335 const OverlayType *overlay,
336 const EGLenum clientType,
337 const Version &clientVersion,
338 bool debug,
339 bool bindGeneratesResourceCHROMIUM,
340 bool clientArraysEnabled,
341 bool robustResourceInit,
342 bool programBinaryCacheEnabled,
343 EGLenum contextPriority,
344 bool hasProtectedContent)
345 : mID({gIDCounter++}),
346 mClientType(clientType),
347 mContextPriority(contextPriority),
348 mHasProtectedContent(hasProtectedContent),
349 mClientVersion(clientVersion),
350 mShareGroup(shareGroup),
351 mBufferManager(AllocateOrGetSharedResourceManager(shareContextState, &State::mBufferManager)),
352 mShaderProgramManager(
353 AllocateOrGetSharedResourceManager(shareContextState, &State::mShaderProgramManager)),
354 mTextureManager(AllocateOrGetSharedResourceManager(shareContextState,
355 &State::mTextureManager,
356 shareTextures)),
357 mRenderbufferManager(
358 AllocateOrGetSharedResourceManager(shareContextState, &State::mRenderbufferManager)),
359 mSamplerManager(
360 AllocateOrGetSharedResourceManager(shareContextState, &State::mSamplerManager)),
361 mSyncManager(AllocateOrGetSharedResourceManager(shareContextState, &State::mSyncManager)),
362 mFramebufferManager(new FramebufferManager()),
363 mProgramPipelineManager(new ProgramPipelineManager()),
364 mMemoryObjectManager(
365 AllocateOrGetSharedResourceManager(shareContextState, &State::mMemoryObjectManager)),
366 mSemaphoreManager(AllocateOrGetSharedResourceManager(shareContextState,
367 &State::mSemaphoreManager,
368 shareSemaphores)),
369 mDepthClearValue(0),
370 mStencilClearValue(0),
371 mScissorTest(false),
372 mSampleAlphaToCoverage(false),
373 mSampleCoverage(false),
374 mSampleCoverageValue(0),
375 mSampleCoverageInvert(false),
376 mSampleMask(false),
377 mMaxSampleMaskWords(0),
378 mIsSampleShadingEnabled(false),
379 mMinSampleShading(0.0f),
380 mStencilRef(0),
381 mStencilBackRef(0),
382 mLineWidth(0),
383 mGenerateMipmapHint(GL_NONE),
384 mTextureFilteringHint(GL_NONE),
385 mFragmentShaderDerivativeHint(GL_NONE),
386 mBindGeneratesResource(bindGeneratesResourceCHROMIUM),
387 mClientArraysEnabled(clientArraysEnabled),
388 mNearZ(0),
389 mFarZ(0),
390 mReadFramebuffer(nullptr),
391 mDrawFramebuffer(nullptr),
392 mProgram(nullptr),
393 mExecutable(nullptr),
394 mProvokingVertex(gl::ProvokingVertexConvention::LastVertexConvention),
395 mVertexArray(nullptr),
396 mActiveSampler(0),
397 mPrimitiveRestart(false),
398 mDebug(debug),
399 mMultiSampling(false),
400 mSampleAlphaToOne(false),
401 mFramebufferSRGB(true),
402 mRobustResourceInit(robustResourceInit),
403 mProgramBinaryCacheEnabled(programBinaryCacheEnabled),
404 mTextureRectangleEnabled(true),
405 mMaxShaderCompilerThreads(std::numeric_limits<GLuint>::max()),
406 mPatchVertices(3),
407 mOverlay(overlay),
408 mNoSimultaneousConstantColorAndAlphaBlendFunc(false),
409 mSetBlendIndexedInvoked(false),
410 mSetBlendFactorsIndexedInvoked(false),
411 mSetBlendEquationsIndexedInvoked(false),
412 mBoundingBoxMinX(-1.0f),
413 mBoundingBoxMinY(-1.0f),
414 mBoundingBoxMinZ(-1.0f),
415 mBoundingBoxMinW(1.0f),
416 mBoundingBoxMaxX(1.0f),
417 mBoundingBoxMaxY(1.0f),
418 mBoundingBoxMaxZ(1.0f),
419 mBoundingBoxMaxW(1.0f)
420 {}
421
~State()422 State::~State() {}
423
initialize(Context * context)424 void State::initialize(Context *context)
425 {
426 const Extensions &nativeExtensions = context->getImplementation()->getNativeExtensions();
427 const Version &clientVersion = context->getClientVersion();
428
429 mBlendStateExt = BlendStateExt(mCaps.maxDrawBuffers);
430
431 setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
432
433 mDepthClearValue = 1.0f;
434 mStencilClearValue = 0;
435
436 mScissorTest = false;
437 mScissor.x = 0;
438 mScissor.y = 0;
439 mScissor.width = 0;
440 mScissor.height = 0;
441
442 mBlendColor.red = 0;
443 mBlendColor.green = 0;
444 mBlendColor.blue = 0;
445 mBlendColor.alpha = 0;
446
447 mStencilRef = 0;
448 mStencilBackRef = 0;
449
450 mSampleCoverage = false;
451 mSampleCoverageValue = 1.0f;
452 mSampleCoverageInvert = false;
453
454 mMaxSampleMaskWords = static_cast<GLuint>(mCaps.maxSampleMaskWords);
455 mSampleMask = false;
456 mSampleMaskValues.fill(~GLbitfield(0));
457
458 mGenerateMipmapHint = GL_DONT_CARE;
459 mTextureFilteringHint = GL_DONT_CARE;
460 mFragmentShaderDerivativeHint = GL_DONT_CARE;
461
462 mLineWidth = 1.0f;
463
464 mViewport.x = 0;
465 mViewport.y = 0;
466 mViewport.width = 0;
467 mViewport.height = 0;
468 mNearZ = 0.0f;
469 mFarZ = 1.0f;
470
471 mClipControlOrigin = GL_LOWER_LEFT_EXT;
472 mClipControlDepth = GL_NEGATIVE_ONE_TO_ONE_EXT;
473
474 mActiveSampler = 0;
475
476 mVertexAttribCurrentValues.resize(mCaps.maxVertexAttributes);
477
478 // Set all indexes in state attributes type mask to float (default)
479 for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
480 {
481 SetComponentTypeMask(ComponentType::Float, i, &mCurrentValuesTypeMask);
482 }
483
484 mUniformBuffers.resize(mCaps.maxUniformBufferBindings);
485
486 mSamplerTextures[TextureType::_2D].resize(mCaps.maxCombinedTextureImageUnits);
487 mSamplerTextures[TextureType::CubeMap].resize(mCaps.maxCombinedTextureImageUnits);
488 if (clientVersion >= Version(3, 0) || nativeExtensions.texture3DOES)
489 {
490 mSamplerTextures[TextureType::_3D].resize(mCaps.maxCombinedTextureImageUnits);
491 }
492 if (clientVersion >= Version(3, 0))
493 {
494 mSamplerTextures[TextureType::_2DArray].resize(mCaps.maxCombinedTextureImageUnits);
495 }
496 if (clientVersion >= Version(3, 1) || nativeExtensions.textureMultisampleANGLE)
497 {
498 mSamplerTextures[TextureType::_2DMultisample].resize(mCaps.maxCombinedTextureImageUnits);
499 }
500 if (clientVersion >= Version(3, 1))
501 {
502 mSamplerTextures[TextureType::_2DMultisampleArray].resize(
503 mCaps.maxCombinedTextureImageUnits);
504
505 mAtomicCounterBuffers.resize(mCaps.maxAtomicCounterBufferBindings);
506 mShaderStorageBuffers.resize(mCaps.maxShaderStorageBufferBindings);
507 mImageUnits.resize(mCaps.maxImageUnits);
508 }
509 if (clientVersion >= Version(3, 2) || mExtensions.textureCubeMapArrayAny())
510 {
511 mSamplerTextures[TextureType::CubeMapArray].resize(mCaps.maxCombinedTextureImageUnits);
512 }
513 if (clientVersion >= Version(3, 2) || mExtensions.textureBufferAny())
514 {
515 mSamplerTextures[TextureType::Buffer].resize(mCaps.maxCombinedTextureImageUnits);
516 }
517 if (nativeExtensions.textureRectangleANGLE)
518 {
519 mSamplerTextures[TextureType::Rectangle].resize(mCaps.maxCombinedTextureImageUnits);
520 }
521 if (nativeExtensions.EGLImageExternalOES || nativeExtensions.EGLStreamConsumerExternalNV)
522 {
523 mSamplerTextures[TextureType::External].resize(mCaps.maxCombinedTextureImageUnits);
524 }
525 if (nativeExtensions.videoTextureWEBGL)
526 {
527 mSamplerTextures[TextureType::VideoImage].resize(mCaps.maxCombinedTextureImageUnits);
528 }
529 mCompleteTextureBindings.reserve(mCaps.maxCombinedTextureImageUnits);
530 for (int32_t textureIndex = 0; textureIndex < mCaps.maxCombinedTextureImageUnits;
531 ++textureIndex)
532 {
533 mCompleteTextureBindings.emplace_back(context, textureIndex);
534 }
535
536 mSamplers.resize(mCaps.maxCombinedTextureImageUnits);
537
538 for (QueryType type : angle::AllEnums<QueryType>())
539 {
540 mActiveQueries[type].set(context, nullptr);
541 }
542
543 mProgram = nullptr;
544 mExecutable = nullptr;
545
546 mReadFramebuffer = nullptr;
547 mDrawFramebuffer = nullptr;
548
549 mPrimitiveRestart = false;
550
551 mDebug.setMaxLoggedMessages(mCaps.maxDebugLoggedMessages);
552
553 mMultiSampling = true;
554 mSampleAlphaToOne = false;
555
556 mCoverageModulation = GL_NONE;
557
558 mNoSimultaneousConstantColorAndAlphaBlendFunc =
559 context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
560 context->getExtensions().webglCompatibilityANGLE;
561
562 // GLES1 emulation: Initialize state for GLES1 if version applies
563 // TODO(http://anglebug.com/3745): When on desktop client only do this in compatibility profile
564 if (clientVersion < Version(2, 0) || mClientType == EGL_OPENGL_API)
565 {
566 mGLES1State.initialize(context, this);
567 }
568 }
569
reset(const Context * context)570 void State::reset(const Context *context)
571 {
572 // Force a sync so clear doesn't end up dereferencing stale pointers.
573 (void)syncActiveTextures(context, Command::Other);
574 mActiveTexturesCache.clear();
575
576 for (TextureBindingVector &bindingVec : mSamplerTextures)
577 {
578 for (BindingPointer<Texture> &texBinding : bindingVec)
579 {
580 texBinding.set(context, nullptr);
581 }
582 }
583 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
584 {
585 mSamplers[samplerIdx].set(context, nullptr);
586 }
587
588 for (ImageUnit &imageUnit : mImageUnits)
589 {
590 imageUnit.texture.set(context, nullptr);
591 imageUnit.level = 0;
592 imageUnit.layered = false;
593 imageUnit.layer = 0;
594 imageUnit.access = GL_READ_ONLY;
595 imageUnit.format = GL_R32UI;
596 }
597
598 mRenderbuffer.set(context, nullptr);
599
600 for (BufferBinding type : angle::AllEnums<BufferBinding>())
601 {
602 UpdateBufferBinding(context, &mBoundBuffers[type], nullptr, type);
603 }
604
605 if (mProgram)
606 {
607 mProgram->release(context);
608 }
609 mProgram = nullptr;
610 mProgramPipeline.set(context, nullptr);
611 mExecutable = nullptr;
612
613 if (mTransformFeedback.get())
614 {
615 mTransformFeedback->onBindingChanged(context, false);
616 }
617 mTransformFeedback.set(context, nullptr);
618
619 for (QueryType type : angle::AllEnums<QueryType>())
620 {
621 mActiveQueries[type].set(context, nullptr);
622 }
623
624 for (OffsetBindingPointer<Buffer> &buf : mUniformBuffers)
625 {
626 UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::Uniform, 0, 0);
627 }
628 mBoundUniformBuffersMask.reset();
629
630 for (OffsetBindingPointer<Buffer> &buf : mAtomicCounterBuffers)
631 {
632 UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::AtomicCounter, 0, 0);
633 }
634 mBoundAtomicCounterBuffersMask.reset();
635
636 for (OffsetBindingPointer<Buffer> &buf : mShaderStorageBuffers)
637 {
638 UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::ShaderStorage, 0, 0);
639 }
640 mBoundShaderStorageBuffersMask.reset();
641
642 mClipDistancesEnabled.reset();
643
644 setAllDirtyBits();
645 }
646
unsetActiveTextures(const ActiveTextureMask & textureMask)647 ANGLE_INLINE void State::unsetActiveTextures(const ActiveTextureMask &textureMask)
648 {
649 // Unset any relevant bound textures.
650 for (size_t textureIndex : textureMask)
651 {
652 mActiveTexturesCache.reset(textureIndex);
653 mCompleteTextureBindings[textureIndex].reset();
654 }
655 }
656
updateActiveTextureStateOnSync(const Context * context,size_t textureIndex,const Sampler * sampler,Texture * texture)657 ANGLE_INLINE void State::updateActiveTextureStateOnSync(const Context *context,
658 size_t textureIndex,
659 const Sampler *sampler,
660 Texture *texture)
661 {
662 if (!texture || !texture->isSamplerComplete(context, sampler))
663 {
664 mActiveTexturesCache.reset(textureIndex);
665 }
666 else
667 {
668 mActiveTexturesCache.set(textureIndex, texture);
669 }
670
671 mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
672 }
673
setActiveTextureDirty(size_t textureIndex,Texture * texture)674 ANGLE_INLINE void State::setActiveTextureDirty(size_t textureIndex, Texture *texture)
675 {
676 mDirtyObjects.set(DIRTY_OBJECT_ACTIVE_TEXTURES);
677 mDirtyActiveTextures.set(textureIndex);
678
679 if (!texture)
680 {
681 return;
682 }
683
684 if (texture->hasAnyDirtyBit())
685 {
686 setTextureDirty(textureIndex);
687 }
688
689 if (mRobustResourceInit && texture->initState() == InitState::MayNeedInit)
690 {
691 mDirtyObjects.set(DIRTY_OBJECT_TEXTURES_INIT);
692 }
693
694 // This cache is updated immediately because we use the cache in the validation layer.
695 // If we defer the update until syncState it's too late and we've already passed validation.
696 if (texture && mExecutable)
697 {
698 // It is invalid to try to sample a non-yuv texture with a yuv sampler.
699 mTexturesIncompatibleWithSamplers[textureIndex] =
700 mExecutable->getActiveYUVSamplers().test(textureIndex) && !texture->isYUV();
701
702 if (isWebGL())
703 {
704 const Sampler *sampler = mSamplers[textureIndex].get();
705 const SamplerState &samplerState =
706 sampler ? sampler->getSamplerState() : texture->getSamplerState();
707 if (!texture->getTextureState().compatibleWithSamplerFormatForWebGL(
708 mExecutable->getSamplerFormatForTextureUnitIndex(textureIndex), samplerState))
709 {
710 mTexturesIncompatibleWithSamplers[textureIndex] = true;
711 }
712 }
713 }
714 else
715 {
716 mTexturesIncompatibleWithSamplers[textureIndex] = false;
717 }
718 }
719
updateTextureBinding(const Context * context,size_t textureIndex,Texture * texture)720 ANGLE_INLINE void State::updateTextureBinding(const Context *context,
721 size_t textureIndex,
722 Texture *texture)
723 {
724 mCompleteTextureBindings[textureIndex].bind(texture);
725 mActiveTexturesCache.reset(textureIndex);
726 setActiveTextureDirty(textureIndex, texture);
727 }
728
hasConstantColor(GLenum sourceRGB,GLenum destRGB) const729 ANGLE_INLINE bool State::hasConstantColor(GLenum sourceRGB, GLenum destRGB) const
730 {
731 return sourceRGB == GL_CONSTANT_COLOR || sourceRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
732 destRGB == GL_CONSTANT_COLOR || destRGB == GL_ONE_MINUS_CONSTANT_COLOR;
733 }
734
hasConstantAlpha(GLenum sourceRGB,GLenum destRGB) const735 ANGLE_INLINE bool State::hasConstantAlpha(GLenum sourceRGB, GLenum destRGB) const
736 {
737 return sourceRGB == GL_CONSTANT_ALPHA || sourceRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
738 destRGB == GL_CONSTANT_ALPHA || destRGB == GL_ONE_MINUS_CONSTANT_ALPHA;
739 }
740
getRasterizerState() const741 const RasterizerState &State::getRasterizerState() const
742 {
743 return mRasterizer;
744 }
745
getDepthStencilState() const746 const DepthStencilState &State::getDepthStencilState() const
747 {
748 return mDepthStencil;
749 }
750
setColorClearValue(float red,float green,float blue,float alpha)751 void State::setColorClearValue(float red, float green, float blue, float alpha)
752 {
753 mColorClearValue.red = red;
754 mColorClearValue.green = green;
755 mColorClearValue.blue = blue;
756 mColorClearValue.alpha = alpha;
757 mDirtyBits.set(DIRTY_BIT_CLEAR_COLOR);
758 }
759
setDepthClearValue(float depth)760 void State::setDepthClearValue(float depth)
761 {
762 mDepthClearValue = depth;
763 mDirtyBits.set(DIRTY_BIT_CLEAR_DEPTH);
764 }
765
setStencilClearValue(int stencil)766 void State::setStencilClearValue(int stencil)
767 {
768 mStencilClearValue = stencil;
769 mDirtyBits.set(DIRTY_BIT_CLEAR_STENCIL);
770 }
771
setColorMask(bool red,bool green,bool blue,bool alpha)772 void State::setColorMask(bool red, bool green, bool blue, bool alpha)
773 {
774 mBlendState.colorMaskRed = red;
775 mBlendState.colorMaskGreen = green;
776 mBlendState.colorMaskBlue = blue;
777 mBlendState.colorMaskAlpha = alpha;
778
779 mBlendStateExt.setColorMask(red, green, blue, alpha);
780 mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
781 }
782
setColorMaskIndexed(bool red,bool green,bool blue,bool alpha,GLuint index)783 void State::setColorMaskIndexed(bool red, bool green, bool blue, bool alpha, GLuint index)
784 {
785 mBlendStateExt.setColorMaskIndexed(index, red, green, blue, alpha);
786 mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
787 }
788
allActiveDrawBufferChannelsMasked() const789 bool State::allActiveDrawBufferChannelsMasked() const
790 {
791 // Compare current color mask with all-disabled color mask, while ignoring disabled draw
792 // buffers.
793 return (mBlendStateExt.compareColorMask(0) & mDrawFramebuffer->getDrawBufferMask()).none();
794 }
795
anyActiveDrawBufferChannelMasked() const796 bool State::anyActiveDrawBufferChannelMasked() const
797 {
798 // Compare current color mask with all-enabled color mask, while ignoring disabled draw
799 // buffers.
800 return (mBlendStateExt.compareColorMask(mBlendStateExt.mMaxColorMask) &
801 mDrawFramebuffer->getDrawBufferMask())
802 .any();
803 }
804
setDepthMask(bool mask)805 void State::setDepthMask(bool mask)
806 {
807 if (mDepthStencil.depthMask != mask)
808 {
809 mDepthStencil.depthMask = mask;
810 mDirtyBits.set(DIRTY_BIT_DEPTH_MASK);
811 }
812 }
813
setRasterizerDiscard(bool enabled)814 void State::setRasterizerDiscard(bool enabled)
815 {
816 if (mRasterizer.rasterizerDiscard != enabled)
817 {
818 mRasterizer.rasterizerDiscard = enabled;
819 mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
820 }
821 }
822
setCullFace(bool enabled)823 void State::setCullFace(bool enabled)
824 {
825 if (mRasterizer.cullFace != enabled)
826 {
827 mRasterizer.cullFace = enabled;
828 mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED);
829 }
830 }
831
setCullMode(CullFaceMode mode)832 void State::setCullMode(CullFaceMode mode)
833 {
834 if (mRasterizer.cullMode != mode)
835 {
836 mRasterizer.cullMode = mode;
837 mDirtyBits.set(DIRTY_BIT_CULL_FACE);
838 }
839 }
840
setFrontFace(GLenum front)841 void State::setFrontFace(GLenum front)
842 {
843 if (mRasterizer.frontFace != front)
844 {
845 mRasterizer.frontFace = front;
846 mDirtyBits.set(DIRTY_BIT_FRONT_FACE);
847 }
848 }
849
setDepthTest(bool enabled)850 void State::setDepthTest(bool enabled)
851 {
852 if (mDepthStencil.depthTest != enabled)
853 {
854 mDepthStencil.depthTest = enabled;
855 mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED);
856 }
857 }
858
setDepthFunc(GLenum depthFunc)859 void State::setDepthFunc(GLenum depthFunc)
860 {
861 if (mDepthStencil.depthFunc != depthFunc)
862 {
863 mDepthStencil.depthFunc = depthFunc;
864 mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC);
865 }
866 }
867
setDepthRange(float zNear,float zFar)868 void State::setDepthRange(float zNear, float zFar)
869 {
870 if (mNearZ != zNear || mFarZ != zFar)
871 {
872 mNearZ = zNear;
873 mFarZ = zFar;
874 mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE);
875 }
876 }
877
setClipControl(GLenum origin,GLenum depth)878 void State::setClipControl(GLenum origin, GLenum depth)
879 {
880 bool updated = false;
881 if (mClipControlOrigin != origin)
882 {
883 mClipControlOrigin = origin;
884 updated = true;
885 }
886
887 if (mClipControlDepth != depth)
888 {
889 mClipControlDepth = depth;
890 updated = true;
891 }
892
893 if (updated)
894 {
895 mDirtyBits.set(DIRTY_BIT_EXTENDED);
896 mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_CLIP_CONTROL);
897 }
898 }
899
setBlend(bool enabled)900 void State::setBlend(bool enabled)
901 {
902 if (mSetBlendIndexedInvoked || mBlendState.blend != enabled)
903 {
904 mBlendState.blend = enabled;
905
906 mSetBlendIndexedInvoked = false;
907 mBlendStateExt.setEnabled(enabled);
908 mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
909 }
910 }
911
setBlendIndexed(bool enabled,GLuint index)912 void State::setBlendIndexed(bool enabled, GLuint index)
913 {
914 mSetBlendIndexedInvoked = true;
915 mBlendStateExt.setEnabledIndexed(index, enabled);
916 mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
917 }
918
setBlendFactors(GLenum sourceRGB,GLenum destRGB,GLenum sourceAlpha,GLenum destAlpha)919 void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
920 {
921 if (!mSetBlendFactorsIndexedInvoked && mBlendState.sourceBlendRGB == sourceRGB &&
922 mBlendState.destBlendRGB == destRGB && mBlendState.sourceBlendAlpha == sourceAlpha &&
923 mBlendState.destBlendAlpha == destAlpha)
924 {
925 return;
926 }
927
928 mBlendState.sourceBlendRGB = sourceRGB;
929 mBlendState.destBlendRGB = destRGB;
930 mBlendState.sourceBlendAlpha = sourceAlpha;
931 mBlendState.destBlendAlpha = destAlpha;
932
933 if (mNoSimultaneousConstantColorAndAlphaBlendFunc)
934 {
935 if (hasConstantColor(sourceRGB, destRGB))
936 {
937 mBlendFuncConstantColorDrawBuffers.set();
938 }
939 else
940 {
941 mBlendFuncConstantColorDrawBuffers.reset();
942 }
943
944 if (hasConstantAlpha(sourceRGB, destRGB))
945 {
946 mBlendFuncConstantAlphaDrawBuffers.set();
947 }
948 else
949 {
950 mBlendFuncConstantAlphaDrawBuffers.reset();
951 }
952 }
953
954 mSetBlendFactorsIndexedInvoked = false;
955 mBlendStateExt.setFactors(sourceRGB, destRGB, sourceAlpha, destAlpha);
956 mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
957 }
958
setBlendFactorsIndexed(GLenum sourceRGB,GLenum destRGB,GLenum sourceAlpha,GLenum destAlpha,GLuint index)959 void State::setBlendFactorsIndexed(GLenum sourceRGB,
960 GLenum destRGB,
961 GLenum sourceAlpha,
962 GLenum destAlpha,
963 GLuint index)
964 {
965 if (mNoSimultaneousConstantColorAndAlphaBlendFunc)
966 {
967 mBlendFuncConstantColorDrawBuffers.set(index, hasConstantColor(sourceRGB, destRGB));
968 mBlendFuncConstantAlphaDrawBuffers.set(index, hasConstantAlpha(sourceRGB, destRGB));
969 }
970
971 mSetBlendFactorsIndexedInvoked = true;
972 mBlendStateExt.setFactorsIndexed(index, sourceRGB, destRGB, sourceAlpha, destAlpha);
973 mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
974 }
975
setBlendColor(float red,float green,float blue,float alpha)976 void State::setBlendColor(float red, float green, float blue, float alpha)
977 {
978 // In ES2 without render-to-float extensions, BlendColor clamps to [0,1] on store.
979 // On ES3+, or with render-to-float exts enabled, it does not clamp on store.
980 const bool isES2 = mClientVersion.major == 2;
981 const bool hasFloatBlending =
982 mExtensions.colorBufferFloatEXT || mExtensions.colorBufferHalfFloatEXT ||
983 mExtensions.colorBufferFloatRgbCHROMIUM || mExtensions.colorBufferFloatRgbaCHROMIUM;
984 if (isES2 && !hasFloatBlending)
985 {
986 red = clamp01(red);
987 green = clamp01(green);
988 blue = clamp01(blue);
989 alpha = clamp01(alpha);
990 }
991
992 if (mBlendColor.red != red || mBlendColor.green != green || mBlendColor.blue != blue ||
993 mBlendColor.alpha != alpha)
994 {
995 mBlendColor.red = red;
996 mBlendColor.green = green;
997 mBlendColor.blue = blue;
998 mBlendColor.alpha = alpha;
999 mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
1000 }
1001 }
1002
setBlendEquation(GLenum rgbEquation,GLenum alphaEquation)1003 void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
1004 {
1005 if (mSetBlendEquationsIndexedInvoked || mBlendState.blendEquationRGB != rgbEquation ||
1006 mBlendState.blendEquationAlpha != alphaEquation)
1007 {
1008 mBlendState.blendEquationRGB = rgbEquation;
1009 mBlendState.blendEquationAlpha = alphaEquation;
1010
1011 mSetBlendEquationsIndexedInvoked = false;
1012 mBlendStateExt.setEquations(rgbEquation, alphaEquation);
1013 mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
1014 }
1015 }
1016
setBlendEquationIndexed(GLenum rgbEquation,GLenum alphaEquation,GLuint index)1017 void State::setBlendEquationIndexed(GLenum rgbEquation, GLenum alphaEquation, GLuint index)
1018 {
1019 mSetBlendEquationsIndexedInvoked = true;
1020 mBlendStateExt.setEquationsIndexed(index, rgbEquation, alphaEquation);
1021 mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
1022 }
1023
setStencilTest(bool enabled)1024 void State::setStencilTest(bool enabled)
1025 {
1026 if (mDepthStencil.stencilTest != enabled)
1027 {
1028 mDepthStencil.stencilTest = enabled;
1029 mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
1030 }
1031 }
1032
setStencilParams(GLenum stencilFunc,GLint stencilRef,GLuint stencilMask)1033 void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
1034 {
1035 if (mDepthStencil.stencilFunc != stencilFunc || mStencilRef != stencilRef ||
1036 mDepthStencil.stencilMask != stencilMask)
1037 {
1038 mDepthStencil.stencilFunc = stencilFunc;
1039 mStencilRef = stencilRef;
1040 mDepthStencil.stencilMask = stencilMask;
1041 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
1042 }
1043 }
1044
setStencilBackParams(GLenum stencilBackFunc,GLint stencilBackRef,GLuint stencilBackMask)1045 void State::setStencilBackParams(GLenum stencilBackFunc,
1046 GLint stencilBackRef,
1047 GLuint stencilBackMask)
1048 {
1049 if (mDepthStencil.stencilBackFunc != stencilBackFunc || mStencilBackRef != stencilBackRef ||
1050 mDepthStencil.stencilBackMask != stencilBackMask)
1051 {
1052 mDepthStencil.stencilBackFunc = stencilBackFunc;
1053 mStencilBackRef = stencilBackRef;
1054 mDepthStencil.stencilBackMask = stencilBackMask;
1055 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
1056 }
1057 }
1058
setStencilWritemask(GLuint stencilWritemask)1059 void State::setStencilWritemask(GLuint stencilWritemask)
1060 {
1061 if (mDepthStencil.stencilWritemask != stencilWritemask)
1062 {
1063 mDepthStencil.stencilWritemask = stencilWritemask;
1064 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
1065 }
1066 }
1067
setStencilBackWritemask(GLuint stencilBackWritemask)1068 void State::setStencilBackWritemask(GLuint stencilBackWritemask)
1069 {
1070 if (mDepthStencil.stencilBackWritemask != stencilBackWritemask)
1071 {
1072 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
1073 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
1074 }
1075 }
1076
setStencilOperations(GLenum stencilFail,GLenum stencilPassDepthFail,GLenum stencilPassDepthPass)1077 void State::setStencilOperations(GLenum stencilFail,
1078 GLenum stencilPassDepthFail,
1079 GLenum stencilPassDepthPass)
1080 {
1081 if (mDepthStencil.stencilFail != stencilFail ||
1082 mDepthStencil.stencilPassDepthFail != stencilPassDepthFail ||
1083 mDepthStencil.stencilPassDepthPass != stencilPassDepthPass)
1084 {
1085 mDepthStencil.stencilFail = stencilFail;
1086 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
1087 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
1088 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
1089 }
1090 }
1091
setStencilBackOperations(GLenum stencilBackFail,GLenum stencilBackPassDepthFail,GLenum stencilBackPassDepthPass)1092 void State::setStencilBackOperations(GLenum stencilBackFail,
1093 GLenum stencilBackPassDepthFail,
1094 GLenum stencilBackPassDepthPass)
1095 {
1096 if (mDepthStencil.stencilBackFail != stencilBackFail ||
1097 mDepthStencil.stencilBackPassDepthFail != stencilBackPassDepthFail ||
1098 mDepthStencil.stencilBackPassDepthPass != stencilBackPassDepthPass)
1099 {
1100 mDepthStencil.stencilBackFail = stencilBackFail;
1101 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
1102 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
1103 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
1104 }
1105 }
1106
setPolygonOffsetFill(bool enabled)1107 void State::setPolygonOffsetFill(bool enabled)
1108 {
1109 if (mRasterizer.polygonOffsetFill != enabled)
1110 {
1111 mRasterizer.polygonOffsetFill = enabled;
1112 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
1113 }
1114 }
1115
setPolygonOffsetParams(GLfloat factor,GLfloat units)1116 void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
1117 {
1118 // An application can pass NaN values here, so handle this gracefully
1119 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
1120 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
1121 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET);
1122 }
1123
setSampleAlphaToCoverage(bool enabled)1124 void State::setSampleAlphaToCoverage(bool enabled)
1125 {
1126 if (mSampleAlphaToCoverage != enabled)
1127 {
1128 mSampleAlphaToCoverage = enabled;
1129 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
1130 }
1131 }
1132
setSampleCoverage(bool enabled)1133 void State::setSampleCoverage(bool enabled)
1134 {
1135 if (mSampleCoverage != enabled)
1136 {
1137 mSampleCoverage = enabled;
1138 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
1139 }
1140 }
1141
setSampleCoverageParams(GLclampf value,bool invert)1142 void State::setSampleCoverageParams(GLclampf value, bool invert)
1143 {
1144 mSampleCoverageValue = value;
1145 mSampleCoverageInvert = invert;
1146 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE);
1147 }
1148
setSampleMaskEnabled(bool enabled)1149 void State::setSampleMaskEnabled(bool enabled)
1150 {
1151 if (mSampleMask != enabled)
1152 {
1153 mSampleMask = enabled;
1154 mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK_ENABLED);
1155 }
1156 }
1157
setSampleMaskParams(GLuint maskNumber,GLbitfield mask)1158 void State::setSampleMaskParams(GLuint maskNumber, GLbitfield mask)
1159 {
1160 ASSERT(maskNumber < mMaxSampleMaskWords);
1161 mSampleMaskValues[maskNumber] = mask;
1162 // TODO(jmadill): Use a child dirty bit if we ever use more than two words.
1163 mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK);
1164 }
1165
setSampleAlphaToOne(bool enabled)1166 void State::setSampleAlphaToOne(bool enabled)
1167 {
1168 if (mSampleAlphaToOne != enabled)
1169 {
1170 mSampleAlphaToOne = enabled;
1171 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
1172 }
1173 }
1174
setMultisampling(bool enabled)1175 void State::setMultisampling(bool enabled)
1176 {
1177 if (mMultiSampling != enabled)
1178 {
1179 mMultiSampling = enabled;
1180 mDirtyBits.set(DIRTY_BIT_MULTISAMPLING);
1181 }
1182 }
1183
setSampleShading(bool enabled)1184 void State::setSampleShading(bool enabled)
1185 {
1186 if (mIsSampleShadingEnabled != enabled)
1187 {
1188 mIsSampleShadingEnabled = enabled;
1189 mMinSampleShading = (enabled) ? 1.0f : mMinSampleShading;
1190 mDirtyBits.set(DIRTY_BIT_SAMPLE_SHADING);
1191 }
1192 }
1193
setMinSampleShading(float value)1194 void State::setMinSampleShading(float value)
1195 {
1196 value = gl::clamp01(value);
1197
1198 if (mMinSampleShading != value)
1199 {
1200 mMinSampleShading = value;
1201 mDirtyBits.set(DIRTY_BIT_SAMPLE_SHADING);
1202 }
1203 }
1204
setScissorTest(bool enabled)1205 void State::setScissorTest(bool enabled)
1206 {
1207 if (mScissorTest != enabled)
1208 {
1209 mScissorTest = enabled;
1210 mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
1211 }
1212 }
1213
setScissorParams(GLint x,GLint y,GLsizei width,GLsizei height)1214 void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
1215 {
1216 // Skip if same scissor info
1217 if (mScissor.x != x || mScissor.y != y || mScissor.width != width || mScissor.height != height)
1218 {
1219 mScissor.x = x;
1220 mScissor.y = y;
1221 mScissor.width = width;
1222 mScissor.height = height;
1223 mDirtyBits.set(DIRTY_BIT_SCISSOR);
1224 }
1225 }
1226
setDither(bool enabled)1227 void State::setDither(bool enabled)
1228 {
1229 if (mRasterizer.dither != enabled)
1230 {
1231 mRasterizer.dither = enabled;
1232 mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED);
1233 }
1234 }
1235
setPrimitiveRestart(bool enabled)1236 void State::setPrimitiveRestart(bool enabled)
1237 {
1238 if (mPrimitiveRestart != enabled)
1239 {
1240 mPrimitiveRestart = enabled;
1241 mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
1242 }
1243 }
1244
setClipDistanceEnable(int idx,bool enable)1245 void State::setClipDistanceEnable(int idx, bool enable)
1246 {
1247 if (enable)
1248 {
1249 mClipDistancesEnabled.set(idx);
1250 }
1251 else
1252 {
1253 mClipDistancesEnabled.reset(idx);
1254 }
1255
1256 mDirtyBits.set(DIRTY_BIT_EXTENDED);
1257 mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_CLIP_DISTANCES);
1258 }
1259
setEnableFeature(GLenum feature,bool enabled)1260 void State::setEnableFeature(GLenum feature, bool enabled)
1261 {
1262 switch (feature)
1263 {
1264 case GL_MULTISAMPLE_EXT:
1265 setMultisampling(enabled);
1266 return;
1267 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1268 setSampleAlphaToOne(enabled);
1269 return;
1270 case GL_CULL_FACE:
1271 setCullFace(enabled);
1272 return;
1273 case GL_POLYGON_OFFSET_FILL:
1274 setPolygonOffsetFill(enabled);
1275 return;
1276 case GL_SAMPLE_ALPHA_TO_COVERAGE:
1277 setSampleAlphaToCoverage(enabled);
1278 return;
1279 case GL_SAMPLE_COVERAGE:
1280 setSampleCoverage(enabled);
1281 return;
1282 case GL_SCISSOR_TEST:
1283 setScissorTest(enabled);
1284 return;
1285 case GL_STENCIL_TEST:
1286 setStencilTest(enabled);
1287 return;
1288 case GL_DEPTH_TEST:
1289 setDepthTest(enabled);
1290 return;
1291 case GL_BLEND:
1292 setBlend(enabled);
1293 return;
1294 case GL_DITHER:
1295 setDither(enabled);
1296 return;
1297 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1298 setPrimitiveRestart(enabled);
1299 return;
1300 case GL_RASTERIZER_DISCARD:
1301 setRasterizerDiscard(enabled);
1302 return;
1303 case GL_SAMPLE_MASK:
1304 setSampleMaskEnabled(enabled);
1305 return;
1306 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1307 mDebug.setOutputSynchronous(enabled);
1308 return;
1309 case GL_DEBUG_OUTPUT:
1310 mDebug.setOutputEnabled(enabled);
1311 return;
1312 case GL_FRAMEBUFFER_SRGB_EXT:
1313 setFramebufferSRGB(enabled);
1314 return;
1315 case GL_TEXTURE_RECTANGLE_ANGLE:
1316 mTextureRectangleEnabled = enabled;
1317 return;
1318 case GL_SAMPLE_SHADING:
1319 setSampleShading(enabled);
1320 return;
1321 // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance
1322 case GL_CLIP_DISTANCE0_EXT:
1323 case GL_CLIP_DISTANCE1_EXT:
1324 case GL_CLIP_DISTANCE2_EXT:
1325 case GL_CLIP_DISTANCE3_EXT:
1326 case GL_CLIP_DISTANCE4_EXT:
1327 case GL_CLIP_DISTANCE5_EXT:
1328 case GL_CLIP_DISTANCE6_EXT:
1329 case GL_CLIP_DISTANCE7_EXT:
1330 // NOTE(hqle): These enums are conflicted with GLES1's enums, need
1331 // to do additional check here:
1332 if (mClientVersion.major >= 2)
1333 {
1334 setClipDistanceEnable(feature - GL_CLIP_DISTANCE0_EXT, enabled);
1335 return;
1336 }
1337 }
1338
1339 ASSERT(mClientVersion.major == 1);
1340
1341 // GLES1 emulation. Need to separate from main switch due to conflict enum between
1342 // GL_CLIP_DISTANCE0_EXT & GL_CLIP_PLANE0
1343 switch (feature)
1344 {
1345 case GL_ALPHA_TEST:
1346 mGLES1State.mAlphaTestEnabled = enabled;
1347 break;
1348 case GL_TEXTURE_2D:
1349 mGLES1State.mTexUnitEnables[mActiveSampler].set(TextureType::_2D, enabled);
1350 break;
1351 case GL_TEXTURE_CUBE_MAP:
1352 mGLES1State.mTexUnitEnables[mActiveSampler].set(TextureType::CubeMap, enabled);
1353 break;
1354 case GL_LIGHTING:
1355 mGLES1State.mLightingEnabled = enabled;
1356 break;
1357 case GL_LIGHT0:
1358 case GL_LIGHT1:
1359 case GL_LIGHT2:
1360 case GL_LIGHT3:
1361 case GL_LIGHT4:
1362 case GL_LIGHT5:
1363 case GL_LIGHT6:
1364 case GL_LIGHT7:
1365 mGLES1State.mLights[feature - GL_LIGHT0].enabled = enabled;
1366 break;
1367 case GL_NORMALIZE:
1368 mGLES1State.mNormalizeEnabled = enabled;
1369 break;
1370 case GL_RESCALE_NORMAL:
1371 mGLES1State.mRescaleNormalEnabled = enabled;
1372 break;
1373 case GL_COLOR_MATERIAL:
1374 mGLES1State.mColorMaterialEnabled = enabled;
1375 break;
1376 case GL_CLIP_PLANE0:
1377 case GL_CLIP_PLANE1:
1378 case GL_CLIP_PLANE2:
1379 case GL_CLIP_PLANE3:
1380 case GL_CLIP_PLANE4:
1381 case GL_CLIP_PLANE5:
1382 mGLES1State.mClipPlanes[feature - GL_CLIP_PLANE0].enabled = enabled;
1383 break;
1384 case GL_FOG:
1385 mGLES1State.mFogEnabled = enabled;
1386 break;
1387 case GL_POINT_SMOOTH:
1388 mGLES1State.mPointSmoothEnabled = enabled;
1389 break;
1390 case GL_LINE_SMOOTH:
1391 mGLES1State.mLineSmoothEnabled = enabled;
1392 break;
1393 case GL_POINT_SPRITE_OES:
1394 mGLES1State.mPointSpriteEnabled = enabled;
1395 break;
1396 case GL_COLOR_LOGIC_OP:
1397 mGLES1State.mLogicOpEnabled = enabled;
1398 break;
1399 default:
1400 UNREACHABLE();
1401 }
1402 }
1403
setEnableFeatureIndexed(GLenum feature,bool enabled,GLuint index)1404 void State::setEnableFeatureIndexed(GLenum feature, bool enabled, GLuint index)
1405 {
1406 switch (feature)
1407 {
1408 case GL_BLEND:
1409 setBlendIndexed(enabled, index);
1410 break;
1411 default:
1412 UNREACHABLE();
1413 }
1414 }
1415
getEnableFeature(GLenum feature) const1416 bool State::getEnableFeature(GLenum feature) const
1417 {
1418 switch (feature)
1419 {
1420 case GL_MULTISAMPLE_EXT:
1421 return isMultisamplingEnabled();
1422 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1423 return isSampleAlphaToOneEnabled();
1424 case GL_CULL_FACE:
1425 return isCullFaceEnabled();
1426 case GL_POLYGON_OFFSET_FILL:
1427 return isPolygonOffsetFillEnabled();
1428 case GL_SAMPLE_ALPHA_TO_COVERAGE:
1429 return isSampleAlphaToCoverageEnabled();
1430 case GL_SAMPLE_COVERAGE:
1431 return isSampleCoverageEnabled();
1432 case GL_SCISSOR_TEST:
1433 return isScissorTestEnabled();
1434 case GL_STENCIL_TEST:
1435 return isStencilTestEnabled();
1436 case GL_DEPTH_TEST:
1437 return isDepthTestEnabled();
1438 case GL_BLEND:
1439 return isBlendEnabled();
1440 case GL_DITHER:
1441 return isDitherEnabled();
1442 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1443 return isPrimitiveRestartEnabled();
1444 case GL_RASTERIZER_DISCARD:
1445 return isRasterizerDiscardEnabled();
1446 case GL_SAMPLE_MASK:
1447 return isSampleMaskEnabled();
1448 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1449 return mDebug.isOutputSynchronous();
1450 case GL_DEBUG_OUTPUT:
1451 return mDebug.isOutputEnabled();
1452 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
1453 return isBindGeneratesResourceEnabled();
1454 case GL_CLIENT_ARRAYS_ANGLE:
1455 return areClientArraysEnabled();
1456 case GL_FRAMEBUFFER_SRGB_EXT:
1457 return getFramebufferSRGB();
1458 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
1459 return mRobustResourceInit;
1460 case GL_PROGRAM_CACHE_ENABLED_ANGLE:
1461 return mProgramBinaryCacheEnabled;
1462 case GL_TEXTURE_RECTANGLE_ANGLE:
1463 return mTextureRectangleEnabled;
1464 case GL_SAMPLE_SHADING:
1465 return isSampleShadingEnabled();
1466 // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance
1467 case GL_CLIP_DISTANCE0_EXT:
1468 case GL_CLIP_DISTANCE1_EXT:
1469 case GL_CLIP_DISTANCE2_EXT:
1470 case GL_CLIP_DISTANCE3_EXT:
1471 case GL_CLIP_DISTANCE4_EXT:
1472 case GL_CLIP_DISTANCE5_EXT:
1473 case GL_CLIP_DISTANCE6_EXT:
1474 case GL_CLIP_DISTANCE7_EXT:
1475 if (mClientVersion.major >= 2)
1476 {
1477 // If GLES version is 1, the GL_CLIP_DISTANCE0_EXT enum will be used as
1478 // GL_CLIP_PLANE0 instead.
1479 return mClipDistancesEnabled.test(feature - GL_CLIP_DISTANCE0_EXT);
1480 }
1481 break;
1482 }
1483
1484 ASSERT(mClientVersion.major == 1);
1485
1486 switch (feature)
1487 {
1488 // GLES1 emulation
1489 case GL_ALPHA_TEST:
1490 return mGLES1State.mAlphaTestEnabled;
1491 case GL_VERTEX_ARRAY:
1492 return mGLES1State.mVertexArrayEnabled;
1493 case GL_NORMAL_ARRAY:
1494 return mGLES1State.mNormalArrayEnabled;
1495 case GL_COLOR_ARRAY:
1496 return mGLES1State.mColorArrayEnabled;
1497 case GL_POINT_SIZE_ARRAY_OES:
1498 return mGLES1State.mPointSizeArrayEnabled;
1499 case GL_TEXTURE_COORD_ARRAY:
1500 return mGLES1State.mTexCoordArrayEnabled[mGLES1State.mClientActiveTexture];
1501 case GL_TEXTURE_2D:
1502 return mGLES1State.isTextureTargetEnabled(getActiveSampler(), TextureType::_2D);
1503 case GL_TEXTURE_CUBE_MAP:
1504 return mGLES1State.isTextureTargetEnabled(getActiveSampler(), TextureType::CubeMap);
1505 case GL_LIGHTING:
1506 return mGLES1State.mLightingEnabled;
1507 case GL_LIGHT0:
1508 case GL_LIGHT1:
1509 case GL_LIGHT2:
1510 case GL_LIGHT3:
1511 case GL_LIGHT4:
1512 case GL_LIGHT5:
1513 case GL_LIGHT6:
1514 case GL_LIGHT7:
1515 return mGLES1State.mLights[feature - GL_LIGHT0].enabled;
1516 case GL_NORMALIZE:
1517 return mGLES1State.mNormalizeEnabled;
1518 case GL_RESCALE_NORMAL:
1519 return mGLES1State.mRescaleNormalEnabled;
1520 case GL_COLOR_MATERIAL:
1521 return mGLES1State.mColorMaterialEnabled;
1522 case GL_CLIP_PLANE0:
1523 case GL_CLIP_PLANE1:
1524 case GL_CLIP_PLANE2:
1525 case GL_CLIP_PLANE3:
1526 case GL_CLIP_PLANE4:
1527 case GL_CLIP_PLANE5:
1528 return mGLES1State.mClipPlanes[feature - GL_CLIP_PLANE0].enabled;
1529 case GL_FOG:
1530 return mGLES1State.mFogEnabled;
1531 case GL_POINT_SMOOTH:
1532 return mGLES1State.mPointSmoothEnabled;
1533 case GL_LINE_SMOOTH:
1534 return mGLES1State.mLineSmoothEnabled;
1535 case GL_POINT_SPRITE_OES:
1536 return mGLES1State.mPointSpriteEnabled;
1537 case GL_COLOR_LOGIC_OP:
1538 return mGLES1State.mLogicOpEnabled;
1539 default:
1540 UNREACHABLE();
1541 return false;
1542 }
1543 }
1544
getEnableFeatureIndexed(GLenum feature,GLuint index) const1545 bool State::getEnableFeatureIndexed(GLenum feature, GLuint index) const
1546 {
1547 switch (feature)
1548 {
1549 case GL_BLEND:
1550 return isBlendEnabledIndexed(index);
1551 default:
1552 UNREACHABLE();
1553 return false;
1554 }
1555 }
1556
setLineWidth(GLfloat width)1557 void State::setLineWidth(GLfloat width)
1558 {
1559 mLineWidth = width;
1560 mDirtyBits.set(DIRTY_BIT_LINE_WIDTH);
1561 }
1562
setGenerateMipmapHint(GLenum hint)1563 void State::setGenerateMipmapHint(GLenum hint)
1564 {
1565 mGenerateMipmapHint = hint;
1566 mDirtyBits.set(DIRTY_BIT_EXTENDED);
1567 mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_MIPMAP_GENERATION_HINT);
1568 }
1569
getGenerateMipmapHint() const1570 GLenum State::getGenerateMipmapHint() const
1571 {
1572 return mGenerateMipmapHint;
1573 }
1574
setTextureFilteringHint(GLenum hint)1575 void State::setTextureFilteringHint(GLenum hint)
1576 {
1577 mTextureFilteringHint = hint;
1578 // Note: we don't add a dirty bit for this flag as it's not expected to be toggled at
1579 // runtime.
1580 }
1581
getTextureFilteringHint() const1582 GLenum State::getTextureFilteringHint() const
1583 {
1584 return mTextureFilteringHint;
1585 }
1586
setFragmentShaderDerivativeHint(GLenum hint)1587 void State::setFragmentShaderDerivativeHint(GLenum hint)
1588 {
1589 mFragmentShaderDerivativeHint = hint;
1590 mDirtyBits.set(DIRTY_BIT_EXTENDED);
1591 mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_SHADER_DERIVATIVE_HINT);
1592 // TODO: Propagate the hint to shader translator so we can write
1593 // ddx, ddx_coarse, or ddx_fine depending on the hint.
1594 // Ignore for now. It is valid for implementations to ignore hint.
1595 }
1596
setViewportParams(GLint x,GLint y,GLsizei width,GLsizei height)1597 void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
1598 {
1599 // Skip if same viewport info
1600 if (mViewport.x != x || mViewport.y != y || mViewport.width != width ||
1601 mViewport.height != height)
1602 {
1603 mViewport.x = x;
1604 mViewport.y = y;
1605 mViewport.width = width;
1606 mViewport.height = height;
1607 mDirtyBits.set(DIRTY_BIT_VIEWPORT);
1608 }
1609 }
1610
setActiveSampler(unsigned int active)1611 void State::setActiveSampler(unsigned int active)
1612 {
1613 mActiveSampler = active;
1614 }
1615
setSamplerTexture(const Context * context,TextureType type,Texture * texture)1616 void State::setSamplerTexture(const Context *context, TextureType type, Texture *texture)
1617 {
1618 if (mExecutable && mExecutable->getActiveSamplersMask()[mActiveSampler] &&
1619 IsTextureCompatibleWithSampler(type, mExecutable->getActiveSamplerTypes()[mActiveSampler]))
1620 {
1621 updateTextureBinding(context, mActiveSampler, texture);
1622 }
1623
1624 mSamplerTextures[type][mActiveSampler].set(context, texture);
1625
1626 mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
1627 }
1628
getTargetTexture(TextureType type) const1629 Texture *State::getTargetTexture(TextureType type) const
1630 {
1631 return getSamplerTexture(static_cast<unsigned int>(mActiveSampler), type);
1632 }
1633
getSamplerTextureId(unsigned int sampler,TextureType type) const1634 TextureID State::getSamplerTextureId(unsigned int sampler, TextureType type) const
1635 {
1636 ASSERT(sampler < mSamplerTextures[type].size());
1637 return mSamplerTextures[type][sampler].id();
1638 }
1639
detachTexture(const Context * context,const TextureMap & zeroTextures,TextureID texture)1640 void State::detachTexture(const Context *context, const TextureMap &zeroTextures, TextureID texture)
1641 {
1642 // Textures have a detach method on State rather than a simple
1643 // removeBinding, because the zero/null texture objects are managed
1644 // separately, and don't have to go through the Context's maps or
1645 // the ResourceManager.
1646
1647 // [OpenGL ES 2.0.24] section 3.8 page 84:
1648 // If a texture object is deleted, it is as if all texture units which are bound to that texture
1649 // object are rebound to texture object zero
1650
1651 for (TextureType type : angle::AllEnums<TextureType>())
1652 {
1653 TextureBindingVector &textureVector = mSamplerTextures[type];
1654
1655 for (size_t bindingIndex = 0; bindingIndex < textureVector.size(); ++bindingIndex)
1656 {
1657 BindingPointer<Texture> &binding = textureVector[bindingIndex];
1658 if (binding.id() == texture)
1659 {
1660 // Zero textures are the "default" textures instead of NULL
1661 Texture *zeroTexture = zeroTextures[type].get();
1662 ASSERT(zeroTexture != nullptr);
1663 if (mCompleteTextureBindings[bindingIndex].getSubject() == binding.get())
1664 {
1665 updateTextureBinding(context, bindingIndex, zeroTexture);
1666 }
1667 binding.set(context, zeroTexture);
1668 }
1669 }
1670 }
1671
1672 for (auto &bindingImageUnit : mImageUnits)
1673 {
1674 if (bindingImageUnit.texture.id() == texture)
1675 {
1676 bindingImageUnit.texture.set(context, nullptr);
1677 bindingImageUnit.level = 0;
1678 bindingImageUnit.layered = false;
1679 bindingImageUnit.layer = 0;
1680 bindingImageUnit.access = GL_READ_ONLY;
1681 bindingImageUnit.format = GL_R32UI;
1682 }
1683 }
1684
1685 // [OpenGL ES 2.0.24] section 4.4 page 112:
1686 // If a texture object is deleted while its image is attached to the currently bound
1687 // framebuffer, then it is as if Texture2DAttachment had been called, with a texture of 0, for
1688 // each attachment point to which this image was attached in the currently bound framebuffer.
1689
1690 if (mReadFramebuffer && mReadFramebuffer->detachTexture(context, texture))
1691 {
1692 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
1693 }
1694
1695 if (mDrawFramebuffer && mDrawFramebuffer->detachTexture(context, texture))
1696 {
1697 setDrawFramebufferDirty();
1698 }
1699 }
1700
initializeZeroTextures(const Context * context,const TextureMap & zeroTextures)1701 void State::initializeZeroTextures(const Context *context, const TextureMap &zeroTextures)
1702 {
1703 for (TextureType type : angle::AllEnums<TextureType>())
1704 {
1705 for (size_t textureUnit = 0; textureUnit < mSamplerTextures[type].size(); ++textureUnit)
1706 {
1707 mSamplerTextures[type][textureUnit].set(context, zeroTextures[type].get());
1708 }
1709 }
1710 }
1711
invalidateTextureBindings(TextureType type)1712 void State::invalidateTextureBindings(TextureType type)
1713 {
1714 mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
1715 }
1716
setSamplerBinding(const Context * context,GLuint textureUnit,Sampler * sampler)1717 void State::setSamplerBinding(const Context *context, GLuint textureUnit, Sampler *sampler)
1718 {
1719 if (mSamplers[textureUnit].get() == sampler)
1720 {
1721 return;
1722 }
1723
1724 mSamplers[textureUnit].set(context, sampler);
1725 mDirtyBits.set(DIRTY_BIT_SAMPLER_BINDINGS);
1726 // This is overly conservative as it assumes the sampler has never been bound.
1727 setSamplerDirty(textureUnit);
1728 onActiveTextureChange(context, textureUnit);
1729 }
1730
detachSampler(const Context * context,SamplerID sampler)1731 void State::detachSampler(const Context *context, SamplerID sampler)
1732 {
1733 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
1734 // If a sampler object that is currently bound to one or more texture units is
1735 // deleted, it is as though BindSampler is called once for each texture unit to
1736 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
1737 for (size_t i = 0; i < mSamplers.size(); i++)
1738 {
1739 if (mSamplers[i].id() == sampler)
1740 {
1741 setSamplerBinding(context, static_cast<GLuint>(i), nullptr);
1742 }
1743 }
1744 }
1745
setRenderbufferBinding(const Context * context,Renderbuffer * renderbuffer)1746 void State::setRenderbufferBinding(const Context *context, Renderbuffer *renderbuffer)
1747 {
1748 mRenderbuffer.set(context, renderbuffer);
1749 mDirtyBits.set(DIRTY_BIT_RENDERBUFFER_BINDING);
1750 }
1751
detachRenderbuffer(const Context * context,RenderbufferID renderbuffer)1752 void State::detachRenderbuffer(const Context *context, RenderbufferID renderbuffer)
1753 {
1754 // [OpenGL ES 2.0.24] section 4.4 page 109:
1755 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though
1756 // BindRenderbuffer had been executed with the target RENDERBUFFER and name of zero.
1757
1758 if (mRenderbuffer.id() == renderbuffer)
1759 {
1760 setRenderbufferBinding(context, nullptr);
1761 }
1762
1763 // [OpenGL ES 2.0.24] section 4.4 page 111:
1764 // If a renderbuffer object is deleted while its image is attached to the currently bound
1765 // framebuffer, then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of
1766 // 0, for each attachment point to which this image was attached in the currently bound
1767 // framebuffer.
1768
1769 Framebuffer *readFramebuffer = mReadFramebuffer;
1770 Framebuffer *drawFramebuffer = mDrawFramebuffer;
1771
1772 if (readFramebuffer && readFramebuffer->detachRenderbuffer(context, renderbuffer))
1773 {
1774 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
1775 }
1776
1777 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
1778 {
1779 if (drawFramebuffer->detachRenderbuffer(context, renderbuffer))
1780 {
1781 setDrawFramebufferDirty();
1782 }
1783 }
1784 }
1785
setReadFramebufferBinding(Framebuffer * framebuffer)1786 void State::setReadFramebufferBinding(Framebuffer *framebuffer)
1787 {
1788 if (mReadFramebuffer == framebuffer)
1789 return;
1790
1791 mReadFramebuffer = framebuffer;
1792 mDirtyBits.set(DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
1793
1794 if (mReadFramebuffer && mReadFramebuffer->hasAnyDirtyBit())
1795 {
1796 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
1797 }
1798 }
1799
setDrawFramebufferBinding(Framebuffer * framebuffer)1800 void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
1801 {
1802 if (mDrawFramebuffer == framebuffer)
1803 return;
1804
1805 mDrawFramebuffer = framebuffer;
1806 mDirtyBits.set(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
1807
1808 if (mDrawFramebuffer)
1809 {
1810 mDrawFramebuffer->setWriteControlMode(getFramebufferSRGB() ? SrgbWriteControlMode::Default
1811 : SrgbWriteControlMode::Linear);
1812
1813 if (mDrawFramebuffer->hasAnyDirtyBit())
1814 {
1815 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
1816 }
1817
1818 if (mRobustResourceInit && mDrawFramebuffer->hasResourceThatNeedsInit())
1819 {
1820 mDirtyObjects.set(DIRTY_OBJECT_DRAW_ATTACHMENTS);
1821 }
1822 }
1823 }
1824
getTargetFramebuffer(GLenum target) const1825 Framebuffer *State::getTargetFramebuffer(GLenum target) const
1826 {
1827 switch (target)
1828 {
1829 case GL_READ_FRAMEBUFFER_ANGLE:
1830 return mReadFramebuffer;
1831 case GL_DRAW_FRAMEBUFFER_ANGLE:
1832 case GL_FRAMEBUFFER:
1833 return mDrawFramebuffer;
1834 default:
1835 UNREACHABLE();
1836 return nullptr;
1837 }
1838 }
1839
getDefaultFramebuffer() const1840 Framebuffer *State::getDefaultFramebuffer() const
1841 {
1842 return mFramebufferManager->getDefaultFramebuffer();
1843 }
1844
removeReadFramebufferBinding(FramebufferID framebuffer)1845 bool State::removeReadFramebufferBinding(FramebufferID framebuffer)
1846 {
1847 if (mReadFramebuffer != nullptr && mReadFramebuffer->id() == framebuffer)
1848 {
1849 setReadFramebufferBinding(nullptr);
1850 return true;
1851 }
1852
1853 return false;
1854 }
1855
removeDrawFramebufferBinding(FramebufferID framebuffer)1856 bool State::removeDrawFramebufferBinding(FramebufferID framebuffer)
1857 {
1858 if (mReadFramebuffer != nullptr && mDrawFramebuffer->id() == framebuffer)
1859 {
1860 setDrawFramebufferBinding(nullptr);
1861 return true;
1862 }
1863
1864 return false;
1865 }
1866
setVertexArrayBinding(const Context * context,VertexArray * vertexArray)1867 void State::setVertexArrayBinding(const Context *context, VertexArray *vertexArray)
1868 {
1869 if (mVertexArray == vertexArray)
1870 {
1871 return;
1872 }
1873
1874 if (context->isWebGL())
1875 {
1876 if (mVertexArray)
1877 {
1878 mVertexArray->onBindingChanged(context, -1);
1879 }
1880 if (vertexArray)
1881 {
1882 vertexArray->onBindingChanged(context, 1);
1883 }
1884 }
1885
1886 mVertexArray = vertexArray;
1887 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
1888
1889 if (mVertexArray && mVertexArray->hasAnyDirtyBit())
1890 {
1891 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1892 }
1893 }
1894
removeVertexArrayBinding(const Context * context,VertexArrayID vertexArray)1895 bool State::removeVertexArrayBinding(const Context *context, VertexArrayID vertexArray)
1896 {
1897 if (mVertexArray && mVertexArray->id().value == vertexArray.value)
1898 {
1899 mVertexArray->onBindingChanged(context, -1);
1900 mVertexArray = nullptr;
1901 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
1902 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1903 return true;
1904 }
1905
1906 return false;
1907 }
1908
getVertexArrayId() const1909 VertexArrayID State::getVertexArrayId() const
1910 {
1911 ASSERT(mVertexArray != nullptr);
1912 return mVertexArray->id();
1913 }
1914
bindVertexBuffer(const Context * context,GLuint bindingIndex,Buffer * boundBuffer,GLintptr offset,GLsizei stride)1915 void State::bindVertexBuffer(const Context *context,
1916 GLuint bindingIndex,
1917 Buffer *boundBuffer,
1918 GLintptr offset,
1919 GLsizei stride)
1920 {
1921 getVertexArray()->bindVertexBuffer(context, bindingIndex, boundBuffer, offset, stride);
1922 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1923 }
1924
setVertexAttribFormat(GLuint attribIndex,GLint size,VertexAttribType type,bool normalized,bool pureInteger,GLuint relativeOffset)1925 void State::setVertexAttribFormat(GLuint attribIndex,
1926 GLint size,
1927 VertexAttribType type,
1928 bool normalized,
1929 bool pureInteger,
1930 GLuint relativeOffset)
1931 {
1932 getVertexArray()->setVertexAttribFormat(attribIndex, size, type, normalized, pureInteger,
1933 relativeOffset);
1934 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1935 }
1936
setVertexBindingDivisor(const Context * context,GLuint bindingIndex,GLuint divisor)1937 void State::setVertexBindingDivisor(const Context *context, GLuint bindingIndex, GLuint divisor)
1938 {
1939 getVertexArray()->setVertexBindingDivisor(context, bindingIndex, divisor);
1940 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1941 }
1942
setProgram(const Context * context,Program * newProgram)1943 angle::Result State::setProgram(const Context *context, Program *newProgram)
1944 {
1945 if (newProgram && !newProgram->isLinked())
1946 {
1947 // Protect against applications that disable validation and try to use a program that was
1948 // not successfully linked.
1949 WARN() << "Attempted to use a program that was not successfully linked";
1950 return angle::Result::Continue;
1951 }
1952
1953 if (mProgram != newProgram)
1954 {
1955 if (mProgram)
1956 {
1957 unsetActiveTextures(mExecutable->getActiveSamplersMask());
1958 mProgram->release(context);
1959 }
1960
1961 mProgram = newProgram;
1962 mExecutable = nullptr;
1963
1964 if (mProgram)
1965 {
1966 mExecutable = &mProgram->getExecutable();
1967 newProgram->addRef();
1968 ANGLE_TRY(onProgramExecutableChange(context, newProgram));
1969 }
1970 else if (mProgramPipeline.get())
1971 {
1972 mExecutable = &mProgramPipeline->getExecutable();
1973 }
1974
1975 // Note that rendering is undefined if glUseProgram(0) is called. But ANGLE will generate
1976 // an error if the app tries to draw in this case.
1977
1978 mDirtyBits.set(DIRTY_BIT_PROGRAM_BINDING);
1979 }
1980
1981 return angle::Result::Continue;
1982 }
1983
setTransformFeedbackBinding(const Context * context,TransformFeedback * transformFeedback)1984 void State::setTransformFeedbackBinding(const Context *context,
1985 TransformFeedback *transformFeedback)
1986 {
1987 if (transformFeedback == mTransformFeedback.get())
1988 return;
1989 if (mTransformFeedback.get())
1990 mTransformFeedback->onBindingChanged(context, false);
1991 mTransformFeedback.set(context, transformFeedback);
1992 if (mTransformFeedback.get())
1993 mTransformFeedback->onBindingChanged(context, true);
1994 mDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING);
1995 }
1996
removeTransformFeedbackBinding(const Context * context,TransformFeedbackID transformFeedback)1997 bool State::removeTransformFeedbackBinding(const Context *context,
1998 TransformFeedbackID transformFeedback)
1999 {
2000 if (mTransformFeedback.id() == transformFeedback)
2001 {
2002 if (mTransformFeedback.get())
2003 mTransformFeedback->onBindingChanged(context, false);
2004 mTransformFeedback.set(context, nullptr);
2005 return true;
2006 }
2007
2008 return false;
2009 }
2010
setProgramPipelineBinding(const Context * context,ProgramPipeline * pipeline)2011 angle::Result State::setProgramPipelineBinding(const Context *context, ProgramPipeline *pipeline)
2012 {
2013 if (mProgramPipeline.get() == pipeline)
2014 {
2015 return angle::Result::Continue;
2016 }
2017
2018 if (mProgramPipeline.get())
2019 {
2020 unsetActiveTextures(mProgramPipeline->getExecutable().getActiveSamplersMask());
2021 }
2022
2023 mProgramPipeline.set(context, pipeline);
2024 mDirtyBits.set(DIRTY_BIT_PROGRAM_BINDING);
2025
2026 // A bound Program always overrides the ProgramPipeline, so only update the
2027 // current ProgramExecutable if there isn't currently a Program bound.
2028 if (!mProgram)
2029 {
2030 if (mProgramPipeline.get())
2031 {
2032 mExecutable = &mProgramPipeline->getExecutable();
2033 }
2034 else
2035 {
2036 mExecutable = nullptr;
2037 }
2038 }
2039
2040 return angle::Result::Continue;
2041 }
2042
detachProgramPipeline(const Context * context,ProgramPipelineID pipeline)2043 void State::detachProgramPipeline(const Context *context, ProgramPipelineID pipeline)
2044 {
2045 mProgramPipeline.set(context, nullptr);
2046
2047 // A bound Program always overrides the ProgramPipeline, so only update the
2048 // current ProgramExecutable if there isn't currently a Program bound.
2049 if (!mProgram)
2050 {
2051 mExecutable = nullptr;
2052 }
2053 }
2054
isQueryActive(QueryType type) const2055 bool State::isQueryActive(QueryType type) const
2056 {
2057 const Query *query = mActiveQueries[type].get();
2058 if (query != nullptr)
2059 {
2060 return true;
2061 }
2062
2063 QueryType alternativeType;
2064 if (GetAlternativeQueryType(type, &alternativeType))
2065 {
2066 query = mActiveQueries[alternativeType].get();
2067 return query != nullptr;
2068 }
2069
2070 return false;
2071 }
2072
isQueryActive(Query * query) const2073 bool State::isQueryActive(Query *query) const
2074 {
2075 for (auto &queryPointer : mActiveQueries)
2076 {
2077 if (queryPointer.get() == query)
2078 {
2079 return true;
2080 }
2081 }
2082
2083 return false;
2084 }
2085
setActiveQuery(const Context * context,QueryType type,Query * query)2086 void State::setActiveQuery(const Context *context, QueryType type, Query *query)
2087 {
2088 mActiveQueries[type].set(context, query);
2089 }
2090
getActiveQueryId(QueryType type) const2091 QueryID State::getActiveQueryId(QueryType type) const
2092 {
2093 const Query *query = getActiveQuery(type);
2094 if (query)
2095 {
2096 return query->id();
2097 }
2098 return {0};
2099 }
2100
getActiveQuery(QueryType type) const2101 Query *State::getActiveQuery(QueryType type) const
2102 {
2103 return mActiveQueries[type].get();
2104 }
2105
setIndexedBufferBinding(const Context * context,BufferBinding target,GLuint index,Buffer * buffer,GLintptr offset,GLsizeiptr size)2106 angle::Result State::setIndexedBufferBinding(const Context *context,
2107 BufferBinding target,
2108 GLuint index,
2109 Buffer *buffer,
2110 GLintptr offset,
2111 GLsizeiptr size)
2112 {
2113 setBufferBinding(context, target, buffer);
2114
2115 switch (target)
2116 {
2117 case BufferBinding::TransformFeedback:
2118 ANGLE_TRY(mTransformFeedback->bindIndexedBuffer(context, index, buffer, offset, size));
2119 setBufferBinding(context, target, buffer);
2120 break;
2121 case BufferBinding::Uniform:
2122 mBoundUniformBuffersMask.set(index, buffer != nullptr);
2123 UpdateIndexedBufferBinding(context, &mUniformBuffers[index], buffer, target, offset,
2124 size);
2125 break;
2126 case BufferBinding::AtomicCounter:
2127 mBoundAtomicCounterBuffersMask.set(index, buffer != nullptr);
2128 UpdateIndexedBufferBinding(context, &mAtomicCounterBuffers[index], buffer, target,
2129 offset, size);
2130 break;
2131 case BufferBinding::ShaderStorage:
2132 mBoundShaderStorageBuffersMask.set(index, buffer != nullptr);
2133 UpdateIndexedBufferBinding(context, &mShaderStorageBuffers[index], buffer, target,
2134 offset, size);
2135 break;
2136 default:
2137 UNREACHABLE();
2138 break;
2139 }
2140
2141 return angle::Result::Continue;
2142 }
2143
getIndexedUniformBuffer(size_t index) const2144 const OffsetBindingPointer<Buffer> &State::getIndexedUniformBuffer(size_t index) const
2145 {
2146 ASSERT(index < mUniformBuffers.size());
2147 return mUniformBuffers[index];
2148 }
2149
getIndexedAtomicCounterBuffer(size_t index) const2150 const OffsetBindingPointer<Buffer> &State::getIndexedAtomicCounterBuffer(size_t index) const
2151 {
2152 ASSERT(index < mAtomicCounterBuffers.size());
2153 return mAtomicCounterBuffers[index];
2154 }
2155
getIndexedShaderStorageBuffer(size_t index) const2156 const OffsetBindingPointer<Buffer> &State::getIndexedShaderStorageBuffer(size_t index) const
2157 {
2158 ASSERT(index < mShaderStorageBuffers.size());
2159 return mShaderStorageBuffers[index];
2160 }
2161
detachBuffer(Context * context,const Buffer * buffer)2162 angle::Result State::detachBuffer(Context *context, const Buffer *buffer)
2163 {
2164 BufferID bufferID = buffer->id();
2165 for (gl::BufferBinding target : angle::AllEnums<BufferBinding>())
2166 {
2167 if (mBoundBuffers[target].id() == bufferID)
2168 {
2169 UpdateBufferBinding(context, &mBoundBuffers[target], nullptr, target);
2170 }
2171 }
2172
2173 TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
2174 if (curTransformFeedback)
2175 {
2176 ANGLE_TRY(curTransformFeedback->detachBuffer(context, bufferID));
2177 //angle CVE-2022-0975
2178 if (isTransformFeedbackActiveUnpaused())
2179 {
2180 context->getStateCache().onActiveTransformFeedbackChange(context);
2181 }
2182 }
2183
2184 if (getVertexArray()->detachBuffer(context, bufferID))
2185 {
2186 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
2187 context->getStateCache().onVertexArrayStateChange(context);
2188 }
2189
2190 for (size_t uniformBufferIndex : mBoundUniformBuffersMask)
2191 {
2192 OffsetBindingPointer<Buffer> &binding = mUniformBuffers[uniformBufferIndex];
2193
2194 if (binding.id() == bufferID)
2195 {
2196 UpdateIndexedBufferBinding(context, &binding, nullptr, BufferBinding::Uniform, 0, 0);
2197 mBoundUniformBuffersMask.reset(uniformBufferIndex);
2198 }
2199 }
2200
2201 for (size_t atomicCounterBufferIndex : mBoundAtomicCounterBuffersMask)
2202 {
2203 OffsetBindingPointer<Buffer> &binding = mAtomicCounterBuffers[atomicCounterBufferIndex];
2204
2205 if (binding.id() == bufferID)
2206 {
2207 UpdateIndexedBufferBinding(context, &binding, nullptr, BufferBinding::AtomicCounter, 0,
2208 0);
2209 mBoundAtomicCounterBuffersMask.reset(atomicCounterBufferIndex);
2210 }
2211 }
2212
2213 for (size_t shaderStorageBufferIndex : mBoundShaderStorageBuffersMask)
2214 {
2215 OffsetBindingPointer<Buffer> &binding = mShaderStorageBuffers[shaderStorageBufferIndex];
2216
2217 if (binding.id() == bufferID)
2218 {
2219 UpdateIndexedBufferBinding(context, &binding, nullptr, BufferBinding::ShaderStorage, 0,
2220 0);
2221 mBoundShaderStorageBuffersMask.reset(shaderStorageBufferIndex);
2222 }
2223 }
2224
2225 return angle::Result::Continue;
2226 }
2227
setEnableVertexAttribArray(unsigned int attribNum,bool enabled)2228 void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
2229 {
2230 getVertexArray()->enableAttribute(attribNum, enabled);
2231 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
2232 }
2233
setVertexAttribf(GLuint index,const GLfloat values[4])2234 void State::setVertexAttribf(GLuint index, const GLfloat values[4])
2235 {
2236 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
2237 mVertexAttribCurrentValues[index].setFloatValues(values);
2238 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
2239 mDirtyCurrentValues.set(index);
2240 SetComponentTypeMask(ComponentType::Float, index, &mCurrentValuesTypeMask);
2241 }
2242
setVertexAttribu(GLuint index,const GLuint values[4])2243 void State::setVertexAttribu(GLuint index, const GLuint values[4])
2244 {
2245 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
2246 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
2247 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
2248 mDirtyCurrentValues.set(index);
2249 SetComponentTypeMask(ComponentType::UnsignedInt, index, &mCurrentValuesTypeMask);
2250 }
2251
setVertexAttribi(GLuint index,const GLint values[4])2252 void State::setVertexAttribi(GLuint index, const GLint values[4])
2253 {
2254 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
2255 mVertexAttribCurrentValues[index].setIntValues(values);
2256 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
2257 mDirtyCurrentValues.set(index);
2258 SetComponentTypeMask(ComponentType::Int, index, &mCurrentValuesTypeMask);
2259 }
2260
setVertexAttribDivisor(const Context * context,GLuint index,GLuint divisor)2261 void State::setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor)
2262 {
2263 getVertexArray()->setVertexAttribDivisor(context, index, divisor);
2264 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
2265 }
2266
getVertexAttribPointer(unsigned int attribNum) const2267 const void *State::getVertexAttribPointer(unsigned int attribNum) const
2268 {
2269 return getVertexArray()->getVertexAttribute(attribNum).pointer;
2270 }
2271
setPackAlignment(GLint alignment)2272 void State::setPackAlignment(GLint alignment)
2273 {
2274 mPack.alignment = alignment;
2275 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
2276 }
2277
setPackReverseRowOrder(bool reverseRowOrder)2278 void State::setPackReverseRowOrder(bool reverseRowOrder)
2279 {
2280 mPack.reverseRowOrder = reverseRowOrder;
2281 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
2282 }
2283
setPackRowLength(GLint rowLength)2284 void State::setPackRowLength(GLint rowLength)
2285 {
2286 mPack.rowLength = rowLength;
2287 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
2288 }
2289
setPackSkipRows(GLint skipRows)2290 void State::setPackSkipRows(GLint skipRows)
2291 {
2292 mPack.skipRows = skipRows;
2293 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
2294 }
2295
setPackSkipPixels(GLint skipPixels)2296 void State::setPackSkipPixels(GLint skipPixels)
2297 {
2298 mPack.skipPixels = skipPixels;
2299 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
2300 }
2301
setUnpackAlignment(GLint alignment)2302 void State::setUnpackAlignment(GLint alignment)
2303 {
2304 mUnpack.alignment = alignment;
2305 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2306 }
2307
setUnpackRowLength(GLint rowLength)2308 void State::setUnpackRowLength(GLint rowLength)
2309 {
2310 mUnpack.rowLength = rowLength;
2311 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2312 }
2313
setUnpackImageHeight(GLint imageHeight)2314 void State::setUnpackImageHeight(GLint imageHeight)
2315 {
2316 mUnpack.imageHeight = imageHeight;
2317 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2318 }
2319
setUnpackSkipImages(GLint skipImages)2320 void State::setUnpackSkipImages(GLint skipImages)
2321 {
2322 mUnpack.skipImages = skipImages;
2323 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2324 }
2325
setUnpackSkipRows(GLint skipRows)2326 void State::setUnpackSkipRows(GLint skipRows)
2327 {
2328 mUnpack.skipRows = skipRows;
2329 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2330 }
2331
setUnpackSkipPixels(GLint skipPixels)2332 void State::setUnpackSkipPixels(GLint skipPixels)
2333 {
2334 mUnpack.skipPixels = skipPixels;
2335 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2336 }
2337
setCoverageModulation(GLenum components)2338 void State::setCoverageModulation(GLenum components)
2339 {
2340 if (mCoverageModulation != components)
2341 {
2342 mCoverageModulation = components;
2343 mDirtyBits.set(DIRTY_BIT_COVERAGE_MODULATION);
2344 }
2345 }
2346
setFramebufferSRGB(bool sRGB)2347 void State::setFramebufferSRGB(bool sRGB)
2348 {
2349 if (mFramebufferSRGB != sRGB)
2350 {
2351 mFramebufferSRGB = sRGB;
2352 mDirtyBits.set(DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE);
2353 setDrawFramebufferDirty();
2354 }
2355 }
2356
setMaxShaderCompilerThreads(GLuint count)2357 void State::setMaxShaderCompilerThreads(GLuint count)
2358 {
2359 mMaxShaderCompilerThreads = count;
2360 }
2361
setPatchVertices(GLuint value)2362 void State::setPatchVertices(GLuint value)
2363 {
2364 if (mPatchVertices != value)
2365 {
2366 mPatchVertices = value;
2367 mDirtyBits.set(DIRTY_BIT_PATCH_VERTICES);
2368 }
2369 }
2370
getBooleanv(GLenum pname,GLboolean * params) const2371 void State::getBooleanv(GLenum pname, GLboolean *params) const
2372 {
2373 switch (pname)
2374 {
2375 case GL_SAMPLE_COVERAGE_INVERT:
2376 *params = mSampleCoverageInvert;
2377 break;
2378 case GL_DEPTH_WRITEMASK:
2379 *params = mDepthStencil.depthMask;
2380 break;
2381 case GL_COLOR_WRITEMASK:
2382 {
2383 // non-indexed get returns the state of draw buffer zero
2384 bool r, g, b, a;
2385 mBlendStateExt.getColorMaskIndexed(0, &r, &g, &b, &a);
2386 params[0] = r;
2387 params[1] = g;
2388 params[2] = b;
2389 params[3] = a;
2390 break;
2391 }
2392 case GL_CULL_FACE:
2393 *params = mRasterizer.cullFace;
2394 break;
2395 case GL_POLYGON_OFFSET_FILL:
2396 *params = mRasterizer.polygonOffsetFill;
2397 break;
2398 case GL_SAMPLE_ALPHA_TO_COVERAGE:
2399 *params = mSampleAlphaToCoverage;
2400 break;
2401 case GL_SAMPLE_COVERAGE:
2402 *params = mSampleCoverage;
2403 break;
2404 case GL_SAMPLE_MASK:
2405 *params = mSampleMask;
2406 break;
2407 case GL_SCISSOR_TEST:
2408 *params = mScissorTest;
2409 break;
2410 case GL_STENCIL_TEST:
2411 *params = mDepthStencil.stencilTest;
2412 break;
2413 case GL_DEPTH_TEST:
2414 *params = mDepthStencil.depthTest;
2415 break;
2416 case GL_BLEND:
2417 // non-indexed get returns the state of draw buffer zero
2418 *params = mBlendStateExt.mEnabledMask.test(0);
2419 break;
2420 case GL_DITHER:
2421 *params = mRasterizer.dither;
2422 break;
2423 case GL_TRANSFORM_FEEDBACK_ACTIVE:
2424 *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE;
2425 break;
2426 case GL_TRANSFORM_FEEDBACK_PAUSED:
2427 *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE;
2428 break;
2429 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
2430 *params = mPrimitiveRestart;
2431 break;
2432 case GL_RASTERIZER_DISCARD:
2433 *params = isRasterizerDiscardEnabled() ? GL_TRUE : GL_FALSE;
2434 break;
2435 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
2436 *params = mDebug.isOutputSynchronous() ? GL_TRUE : GL_FALSE;
2437 break;
2438 case GL_DEBUG_OUTPUT:
2439 *params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE;
2440 break;
2441 case GL_MULTISAMPLE_EXT:
2442 *params = mMultiSampling;
2443 break;
2444 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
2445 *params = mSampleAlphaToOne;
2446 break;
2447 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
2448 *params = isBindGeneratesResourceEnabled() ? GL_TRUE : GL_FALSE;
2449 break;
2450 case GL_CLIENT_ARRAYS_ANGLE:
2451 *params = areClientArraysEnabled() ? GL_TRUE : GL_FALSE;
2452 break;
2453 case GL_FRAMEBUFFER_SRGB_EXT:
2454 *params = getFramebufferSRGB() ? GL_TRUE : GL_FALSE;
2455 break;
2456 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
2457 *params = mRobustResourceInit ? GL_TRUE : GL_FALSE;
2458 break;
2459 case GL_PROGRAM_CACHE_ENABLED_ANGLE:
2460 *params = mProgramBinaryCacheEnabled ? GL_TRUE : GL_FALSE;
2461 break;
2462 case GL_TEXTURE_RECTANGLE_ANGLE:
2463 *params = mTextureRectangleEnabled ? GL_TRUE : GL_FALSE;
2464 break;
2465 case GL_LIGHT_MODEL_TWO_SIDE:
2466 *params = IsLightModelTwoSided(&mGLES1State);
2467 break;
2468 case GL_SAMPLE_SHADING:
2469 *params = mIsSampleShadingEnabled;
2470 break;
2471 case GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED:
2472 *params = isPrimitiveRestartEnabled() && getExtensions().tessellationShaderEXT;
2473 break;
2474 // 2.2.2 Data Conversions For State Query Commands, in GLES 3.2 spec.
2475 // If a command returning boolean data is called, such as GetBooleanv, a floating-point or
2476 // integer value converts to FALSE if and only if it is zero. Otherwise it converts to TRUE.
2477 // GL_EXT_clip_control
2478 case GL_CLIP_ORIGIN_EXT:
2479 *params = GL_TRUE;
2480 break;
2481 case GL_CLIP_DEPTH_MODE_EXT:
2482 *params = GL_TRUE;
2483 break;
2484 case GL_ROBUST_FRAGMENT_SHADER_OUTPUT_ANGLE:
2485 *params = mExtensions.robustFragmentShaderOutputANGLE ? GL_TRUE : GL_FALSE;
2486 break;
2487 default:
2488 UNREACHABLE();
2489 break;
2490 }
2491 }
2492
getFloatv(GLenum pname,GLfloat * params) const2493 void State::getFloatv(GLenum pname, GLfloat *params) const
2494 {
2495 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
2496 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
2497 // GetIntegerv as its native query function. As it would require conversion in any
2498 // case, this should make no difference to the calling application.
2499 switch (pname)
2500 {
2501 case GL_LINE_WIDTH:
2502 *params = mLineWidth;
2503 break;
2504 case GL_SAMPLE_COVERAGE_VALUE:
2505 *params = mSampleCoverageValue;
2506 break;
2507 case GL_DEPTH_CLEAR_VALUE:
2508 *params = mDepthClearValue;
2509 break;
2510 case GL_POLYGON_OFFSET_FACTOR:
2511 *params = mRasterizer.polygonOffsetFactor;
2512 break;
2513 case GL_POLYGON_OFFSET_UNITS:
2514 *params = mRasterizer.polygonOffsetUnits;
2515 break;
2516 case GL_DEPTH_RANGE:
2517 params[0] = mNearZ;
2518 params[1] = mFarZ;
2519 break;
2520 case GL_COLOR_CLEAR_VALUE:
2521 params[0] = mColorClearValue.red;
2522 params[1] = mColorClearValue.green;
2523 params[2] = mColorClearValue.blue;
2524 params[3] = mColorClearValue.alpha;
2525 break;
2526 case GL_BLEND_COLOR:
2527 params[0] = mBlendColor.red;
2528 params[1] = mBlendColor.green;
2529 params[2] = mBlendColor.blue;
2530 params[3] = mBlendColor.alpha;
2531 break;
2532 case GL_MULTISAMPLE_EXT:
2533 *params = static_cast<GLfloat>(mMultiSampling);
2534 break;
2535 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
2536 *params = static_cast<GLfloat>(mSampleAlphaToOne);
2537 break;
2538 case GL_COVERAGE_MODULATION_CHROMIUM:
2539 params[0] = static_cast<GLfloat>(mCoverageModulation);
2540 break;
2541 case GL_ALPHA_TEST_REF:
2542 *params = mGLES1State.mAlphaTestRef;
2543 break;
2544 case GL_CURRENT_COLOR:
2545 {
2546 const auto &color = mGLES1State.mCurrentColor;
2547 params[0] = color.red;
2548 params[1] = color.green;
2549 params[2] = color.blue;
2550 params[3] = color.alpha;
2551 break;
2552 }
2553 case GL_CURRENT_NORMAL:
2554 {
2555 const auto &normal = mGLES1State.mCurrentNormal;
2556 params[0] = normal[0];
2557 params[1] = normal[1];
2558 params[2] = normal[2];
2559 break;
2560 }
2561 case GL_CURRENT_TEXTURE_COORDS:
2562 {
2563 const auto &texcoord = mGLES1State.mCurrentTextureCoords[mActiveSampler];
2564 params[0] = texcoord.s;
2565 params[1] = texcoord.t;
2566 params[2] = texcoord.r;
2567 params[3] = texcoord.q;
2568 break;
2569 }
2570 case GL_MODELVIEW_MATRIX:
2571 memcpy(params, mGLES1State.mModelviewMatrices.back().constData(), 16 * sizeof(GLfloat));
2572 break;
2573 case GL_PROJECTION_MATRIX:
2574 memcpy(params, mGLES1State.mProjectionMatrices.back().constData(),
2575 16 * sizeof(GLfloat));
2576 break;
2577 case GL_TEXTURE_MATRIX:
2578 memcpy(params, mGLES1State.mTextureMatrices[mActiveSampler].back().constData(),
2579 16 * sizeof(GLfloat));
2580 break;
2581 case GL_LIGHT_MODEL_AMBIENT:
2582 GetLightModelParameters(&mGLES1State, pname, params);
2583 break;
2584 case GL_FOG_MODE:
2585 case GL_FOG_DENSITY:
2586 case GL_FOG_START:
2587 case GL_FOG_END:
2588 case GL_FOG_COLOR:
2589 GetFogParameters(&mGLES1State, pname, params);
2590 break;
2591 case GL_POINT_SIZE:
2592 GetPointSize(&mGLES1State, params);
2593 break;
2594 case GL_POINT_SIZE_MIN:
2595 case GL_POINT_SIZE_MAX:
2596 case GL_POINT_FADE_THRESHOLD_SIZE:
2597 case GL_POINT_DISTANCE_ATTENUATION:
2598 GetPointParameter(&mGLES1State, FromGLenum<PointParameter>(pname), params);
2599 break;
2600 case GL_MIN_SAMPLE_SHADING_VALUE:
2601 *params = mMinSampleShading;
2602 break;
2603 // 2.2.2 Data Conversions For State Query Commands, in GLES 3.2 spec.
2604 // If a command returning floating-point data is called, such as GetFloatv, ... An integer
2605 // value is coerced to floating-point.
2606 case GL_CLIP_ORIGIN_EXT:
2607 *params = static_cast<float>(mClipControlOrigin);
2608 break;
2609 case GL_CLIP_DEPTH_MODE_EXT:
2610 *params = static_cast<float>(mClipControlDepth);
2611 break;
2612 default:
2613 UNREACHABLE();
2614 break;
2615 }
2616 }
2617
getIntegerv(const Context * context,GLenum pname,GLint * params) const2618 angle::Result State::getIntegerv(const Context *context, GLenum pname, GLint *params) const
2619 {
2620 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
2621 {
2622 size_t drawBuffer = (pname - GL_DRAW_BUFFER0_EXT);
2623 ASSERT(drawBuffer < static_cast<size_t>(mCaps.maxDrawBuffers));
2624 Framebuffer *framebuffer = mDrawFramebuffer;
2625 // The default framebuffer may have fewer draw buffer states than a user-created one. The
2626 // user is always allowed to query up to GL_MAX_DRAWBUFFERS so just return GL_NONE here if
2627 // the draw buffer is out of range for this framebuffer.
2628 *params = drawBuffer < framebuffer->getDrawbufferStateCount()
2629 ? framebuffer->getDrawBufferState(drawBuffer)
2630 : GL_NONE;
2631 return angle::Result::Continue;
2632 }
2633
2634 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
2635 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
2636 // GetIntegerv as its native query function. As it would require conversion in any
2637 // case, this should make no difference to the calling application. You may find it in
2638 // State::getFloatv.
2639 switch (pname)
2640 {
2641 case GL_ARRAY_BUFFER_BINDING:
2642 *params = mBoundBuffers[BufferBinding::Array].id().value;
2643 break;
2644 case GL_DRAW_INDIRECT_BUFFER_BINDING:
2645 *params = mBoundBuffers[BufferBinding::DrawIndirect].id().value;
2646 break;
2647 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2648 {
2649 Buffer *elementArrayBuffer = getVertexArray()->getElementArrayBuffer();
2650 *params = elementArrayBuffer ? elementArrayBuffer->id().value : 0;
2651 break;
2652 }
2653 case GL_DRAW_FRAMEBUFFER_BINDING:
2654 static_assert(GL_DRAW_FRAMEBUFFER_BINDING == GL_DRAW_FRAMEBUFFER_BINDING_ANGLE,
2655 "Enum mismatch");
2656 *params = mDrawFramebuffer->id().value;
2657 break;
2658 case GL_READ_FRAMEBUFFER_BINDING:
2659 static_assert(GL_READ_FRAMEBUFFER_BINDING == GL_READ_FRAMEBUFFER_BINDING_ANGLE,
2660 "Enum mismatch");
2661 *params = mReadFramebuffer->id().value;
2662 break;
2663 case GL_RENDERBUFFER_BINDING:
2664 *params = mRenderbuffer.id().value;
2665 break;
2666 case GL_VERTEX_ARRAY_BINDING:
2667 *params = mVertexArray->id().value;
2668 break;
2669 case GL_CURRENT_PROGRAM:
2670 *params = mProgram ? mProgram->id().value : 0;
2671 break;
2672 case GL_PACK_ALIGNMENT:
2673 *params = mPack.alignment;
2674 break;
2675 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
2676 *params = mPack.reverseRowOrder;
2677 break;
2678 case GL_PACK_ROW_LENGTH:
2679 *params = mPack.rowLength;
2680 break;
2681 case GL_PACK_SKIP_ROWS:
2682 *params = mPack.skipRows;
2683 break;
2684 case GL_PACK_SKIP_PIXELS:
2685 *params = mPack.skipPixels;
2686 break;
2687 case GL_UNPACK_ALIGNMENT:
2688 *params = mUnpack.alignment;
2689 break;
2690 case GL_UNPACK_ROW_LENGTH:
2691 *params = mUnpack.rowLength;
2692 break;
2693 case GL_UNPACK_IMAGE_HEIGHT:
2694 *params = mUnpack.imageHeight;
2695 break;
2696 case GL_UNPACK_SKIP_IMAGES:
2697 *params = mUnpack.skipImages;
2698 break;
2699 case GL_UNPACK_SKIP_ROWS:
2700 *params = mUnpack.skipRows;
2701 break;
2702 case GL_UNPACK_SKIP_PIXELS:
2703 *params = mUnpack.skipPixels;
2704 break;
2705 case GL_GENERATE_MIPMAP_HINT:
2706 *params = mGenerateMipmapHint;
2707 break;
2708 case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
2709 *params = mTextureFilteringHint;
2710 break;
2711 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
2712 *params = mFragmentShaderDerivativeHint;
2713 break;
2714 case GL_ACTIVE_TEXTURE:
2715 *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
2716 break;
2717 case GL_STENCIL_FUNC:
2718 *params = mDepthStencil.stencilFunc;
2719 break;
2720 case GL_STENCIL_REF:
2721 *params = mStencilRef;
2722 break;
2723 case GL_STENCIL_VALUE_MASK:
2724 *params = CastMaskValue(mDepthStencil.stencilMask);
2725 break;
2726 case GL_STENCIL_BACK_FUNC:
2727 *params = mDepthStencil.stencilBackFunc;
2728 break;
2729 case GL_STENCIL_BACK_REF:
2730 *params = mStencilBackRef;
2731 break;
2732 case GL_STENCIL_BACK_VALUE_MASK:
2733 *params = CastMaskValue(mDepthStencil.stencilBackMask);
2734 break;
2735 case GL_STENCIL_FAIL:
2736 *params = mDepthStencil.stencilFail;
2737 break;
2738 case GL_STENCIL_PASS_DEPTH_FAIL:
2739 *params = mDepthStencil.stencilPassDepthFail;
2740 break;
2741 case GL_STENCIL_PASS_DEPTH_PASS:
2742 *params = mDepthStencil.stencilPassDepthPass;
2743 break;
2744 case GL_STENCIL_BACK_FAIL:
2745 *params = mDepthStencil.stencilBackFail;
2746 break;
2747 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
2748 *params = mDepthStencil.stencilBackPassDepthFail;
2749 break;
2750 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
2751 *params = mDepthStencil.stencilBackPassDepthPass;
2752 break;
2753 case GL_DEPTH_FUNC:
2754 *params = mDepthStencil.depthFunc;
2755 break;
2756 case GL_BLEND_SRC_RGB:
2757 // non-indexed get returns the state of draw buffer zero
2758 *params = mBlendStateExt.getSrcColorIndexed(0);
2759 break;
2760 case GL_BLEND_SRC_ALPHA:
2761 *params = mBlendStateExt.getSrcAlphaIndexed(0);
2762 break;
2763 case GL_BLEND_DST_RGB:
2764 *params = mBlendStateExt.getDstColorIndexed(0);
2765 break;
2766 case GL_BLEND_DST_ALPHA:
2767 *params = mBlendStateExt.getDstAlphaIndexed(0);
2768 break;
2769 case GL_BLEND_EQUATION_RGB:
2770 *params = mBlendStateExt.getEquationColorIndexed(0);
2771 break;
2772 case GL_BLEND_EQUATION_ALPHA:
2773 *params = mBlendStateExt.getEquationAlphaIndexed(0);
2774 break;
2775 case GL_STENCIL_WRITEMASK:
2776 *params = CastMaskValue(mDepthStencil.stencilWritemask);
2777 break;
2778 case GL_STENCIL_BACK_WRITEMASK:
2779 *params = CastMaskValue(mDepthStencil.stencilBackWritemask);
2780 break;
2781 case GL_STENCIL_CLEAR_VALUE:
2782 *params = mStencilClearValue;
2783 break;
2784 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2785 *params = mReadFramebuffer->getImplementationColorReadType(context);
2786 break;
2787 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
2788 *params = mReadFramebuffer->getImplementationColorReadFormat(context);
2789 break;
2790 case GL_SAMPLE_BUFFERS:
2791 case GL_SAMPLES:
2792 {
2793 Framebuffer *framebuffer = mDrawFramebuffer;
2794 if (framebuffer->isComplete(context))
2795 {
2796 GLint samples = framebuffer->getSamples(context);
2797 switch (pname)
2798 {
2799 case GL_SAMPLE_BUFFERS:
2800 if (samples != 0)
2801 {
2802 *params = 1;
2803 }
2804 else
2805 {
2806 *params = 0;
2807 }
2808 break;
2809 case GL_SAMPLES:
2810 *params = samples;
2811 break;
2812 }
2813 }
2814 else
2815 {
2816 *params = 0;
2817 }
2818 }
2819 break;
2820 case GL_VIEWPORT:
2821 params[0] = mViewport.x;
2822 params[1] = mViewport.y;
2823 params[2] = mViewport.width;
2824 params[3] = mViewport.height;
2825 break;
2826 case GL_SCISSOR_BOX:
2827 params[0] = mScissor.x;
2828 params[1] = mScissor.y;
2829 params[2] = mScissor.width;
2830 params[3] = mScissor.height;
2831 break;
2832 case GL_CULL_FACE_MODE:
2833 *params = ToGLenum(mRasterizer.cullMode);
2834 break;
2835 case GL_FRONT_FACE:
2836 *params = mRasterizer.frontFace;
2837 break;
2838 case GL_RED_BITS:
2839 case GL_GREEN_BITS:
2840 case GL_BLUE_BITS:
2841 case GL_ALPHA_BITS:
2842 {
2843 Framebuffer *framebuffer = getDrawFramebuffer();
2844 const FramebufferAttachment *colorbuffer = framebuffer->getFirstColorAttachment();
2845
2846 if (colorbuffer)
2847 {
2848 switch (pname)
2849 {
2850 case GL_RED_BITS:
2851 *params = colorbuffer->getRedSize();
2852 break;
2853 case GL_GREEN_BITS:
2854 *params = colorbuffer->getGreenSize();
2855 break;
2856 case GL_BLUE_BITS:
2857 *params = colorbuffer->getBlueSize();
2858 break;
2859 case GL_ALPHA_BITS:
2860 *params = colorbuffer->getAlphaSize();
2861 break;
2862 }
2863 }
2864 else
2865 {
2866 *params = 0;
2867 }
2868 }
2869 break;
2870 case GL_DEPTH_BITS:
2871 {
2872 const Framebuffer *framebuffer = getDrawFramebuffer();
2873 const FramebufferAttachment *depthbuffer = framebuffer->getDepthAttachment();
2874
2875 if (depthbuffer)
2876 {
2877 *params = depthbuffer->getDepthSize();
2878 }
2879 else
2880 {
2881 *params = 0;
2882 }
2883 }
2884 break;
2885 case GL_STENCIL_BITS:
2886 {
2887 const Framebuffer *framebuffer = getDrawFramebuffer();
2888 const FramebufferAttachment *stencilbuffer = framebuffer->getStencilAttachment();
2889
2890 if (stencilbuffer)
2891 {
2892 *params = stencilbuffer->getStencilSize();
2893 }
2894 else
2895 {
2896 *params = 0;
2897 }
2898 }
2899 break;
2900 case GL_TEXTURE_BINDING_2D:
2901 ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2902 *params =
2903 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::_2D)
2904 .value;
2905 break;
2906 case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
2907 ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2908 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2909 TextureType::Rectangle)
2910 .value;
2911 break;
2912 case GL_TEXTURE_BINDING_CUBE_MAP:
2913 ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2914 *params =
2915 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::CubeMap)
2916 .value;
2917 break;
2918 case GL_TEXTURE_BINDING_3D:
2919 ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2920 *params =
2921 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::_3D)
2922 .value;
2923 break;
2924 case GL_TEXTURE_BINDING_2D_ARRAY:
2925 ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2926 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2927 TextureType::_2DArray)
2928 .value;
2929 break;
2930 case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
2931 ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2932 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2933 TextureType::_2DMultisample)
2934 .value;
2935 break;
2936 case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
2937 ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2938 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2939 TextureType::_2DMultisampleArray)
2940 .value;
2941 break;
2942 case GL_TEXTURE_BINDING_CUBE_MAP_ARRAY:
2943 ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2944 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2945 TextureType::CubeMapArray)
2946 .value;
2947 break;
2948 case GL_TEXTURE_BINDING_EXTERNAL_OES:
2949 ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2950 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2951 TextureType::External)
2952 .value;
2953 break;
2954
2955 // GL_OES_texture_buffer
2956 case GL_TEXTURE_BINDING_BUFFER:
2957 ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2958 *params =
2959 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::Buffer)
2960 .value;
2961 break;
2962 case GL_TEXTURE_BUFFER_BINDING:
2963 *params = mBoundBuffers[BufferBinding::Texture].id().value;
2964 break;
2965
2966 case GL_UNIFORM_BUFFER_BINDING:
2967 *params = mBoundBuffers[BufferBinding::Uniform].id().value;
2968 break;
2969 case GL_TRANSFORM_FEEDBACK_BINDING:
2970 *params = mTransformFeedback.id().value;
2971 break;
2972 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2973 *params = mBoundBuffers[BufferBinding::TransformFeedback].id().value;
2974 break;
2975 case GL_COPY_READ_BUFFER_BINDING:
2976 *params = mBoundBuffers[BufferBinding::CopyRead].id().value;
2977 break;
2978 case GL_COPY_WRITE_BUFFER_BINDING:
2979 *params = mBoundBuffers[BufferBinding::CopyWrite].id().value;
2980 break;
2981 case GL_PIXEL_PACK_BUFFER_BINDING:
2982 *params = mBoundBuffers[BufferBinding::PixelPack].id().value;
2983 break;
2984 case GL_PIXEL_UNPACK_BUFFER_BINDING:
2985 *params = mBoundBuffers[BufferBinding::PixelUnpack].id().value;
2986 break;
2987
2988 case GL_READ_BUFFER:
2989 *params = mReadFramebuffer->getReadBufferState();
2990 break;
2991 case GL_SAMPLER_BINDING:
2992 ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2993 *params = getSamplerId(static_cast<GLuint>(mActiveSampler)).value;
2994 break;
2995 case GL_DEBUG_LOGGED_MESSAGES:
2996 *params = static_cast<GLint>(mDebug.getMessageCount());
2997 break;
2998 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
2999 *params = static_cast<GLint>(mDebug.getNextMessageLength());
3000 break;
3001 case GL_DEBUG_GROUP_STACK_DEPTH:
3002 *params = static_cast<GLint>(mDebug.getGroupStackDepth());
3003 break;
3004 case GL_MULTISAMPLE_EXT:
3005 *params = static_cast<GLint>(mMultiSampling);
3006 break;
3007 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
3008 *params = static_cast<GLint>(mSampleAlphaToOne);
3009 break;
3010 case GL_COVERAGE_MODULATION_CHROMIUM:
3011 *params = static_cast<GLint>(mCoverageModulation);
3012 break;
3013 case GL_ATOMIC_COUNTER_BUFFER_BINDING:
3014 *params = mBoundBuffers[BufferBinding::AtomicCounter].id().value;
3015 break;
3016 case GL_SHADER_STORAGE_BUFFER_BINDING:
3017 *params = mBoundBuffers[BufferBinding::ShaderStorage].id().value;
3018 break;
3019 case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
3020 *params = mBoundBuffers[BufferBinding::DispatchIndirect].id().value;
3021 break;
3022 case GL_ALPHA_TEST_FUNC:
3023 *params = ToGLenum(mGLES1State.mAlphaTestFunc);
3024 break;
3025 case GL_CLIENT_ACTIVE_TEXTURE:
3026 *params = mGLES1State.mClientActiveTexture + GL_TEXTURE0;
3027 break;
3028 case GL_MATRIX_MODE:
3029 *params = ToGLenum(mGLES1State.mMatrixMode);
3030 break;
3031 case GL_SHADE_MODEL:
3032 *params = ToGLenum(mGLES1State.mShadeModel);
3033 break;
3034 case GL_MODELVIEW_STACK_DEPTH:
3035 case GL_PROJECTION_STACK_DEPTH:
3036 case GL_TEXTURE_STACK_DEPTH:
3037 *params = mGLES1State.getCurrentMatrixStackDepth(pname);
3038 break;
3039 case GL_LOGIC_OP_MODE:
3040 *params = ToGLenum(mGLES1State.mLogicOp);
3041 break;
3042 case GL_BLEND_SRC:
3043 // non-indexed get returns the state of draw buffer zero
3044 *params = mBlendStateExt.getSrcColorIndexed(0);
3045 break;
3046 case GL_BLEND_DST:
3047 *params = mBlendStateExt.getDstColorIndexed(0);
3048 break;
3049 case GL_PERSPECTIVE_CORRECTION_HINT:
3050 case GL_POINT_SMOOTH_HINT:
3051 case GL_LINE_SMOOTH_HINT:
3052 case GL_FOG_HINT:
3053 *params = mGLES1State.getHint(pname);
3054 break;
3055
3056 // GL_ANGLE_provoking_vertex
3057 case GL_PROVOKING_VERTEX:
3058 *params = ToGLenum(mProvokingVertex);
3059 break;
3060
3061 case GL_PROGRAM_PIPELINE_BINDING:
3062 {
3063 ProgramPipeline *pipeline = getProgramPipeline();
3064 if (pipeline)
3065 {
3066 *params = pipeline->id().value;
3067 }
3068 else
3069 {
3070 *params = 0;
3071 }
3072 break;
3073 }
3074 case GL_PATCH_VERTICES:
3075 *params = mPatchVertices;
3076 break;
3077
3078 // GL_EXT_clip_control
3079 case GL_CLIP_ORIGIN_EXT:
3080 *params = mClipControlOrigin;
3081 break;
3082 case GL_CLIP_DEPTH_MODE_EXT:
3083 *params = mClipControlDepth;
3084 break;
3085 default:
3086 UNREACHABLE();
3087 break;
3088 }
3089
3090 return angle::Result::Continue;
3091 }
3092
getPointerv(const Context * context,GLenum pname,void ** params) const3093 void State::getPointerv(const Context *context, GLenum pname, void **params) const
3094 {
3095 switch (pname)
3096 {
3097 case GL_DEBUG_CALLBACK_FUNCTION:
3098 *params = reinterpret_cast<void *>(mDebug.getCallback());
3099 break;
3100 case GL_DEBUG_CALLBACK_USER_PARAM:
3101 *params = const_cast<void *>(mDebug.getUserParam());
3102 break;
3103 case GL_VERTEX_ARRAY_POINTER:
3104 case GL_NORMAL_ARRAY_POINTER:
3105 case GL_COLOR_ARRAY_POINTER:
3106 case GL_TEXTURE_COORD_ARRAY_POINTER:
3107 case GL_POINT_SIZE_ARRAY_POINTER_OES:
3108 QueryVertexAttribPointerv(getVertexArray()->getVertexAttribute(
3109 context->vertexArrayIndex(ParamToVertexArrayType(pname))),
3110 GL_VERTEX_ATTRIB_ARRAY_POINTER, params);
3111 return;
3112 default:
3113 UNREACHABLE();
3114 break;
3115 }
3116 }
3117
getIntegeri_v(GLenum target,GLuint index,GLint * data) const3118 void State::getIntegeri_v(GLenum target, GLuint index, GLint *data) const
3119 {
3120 switch (target)
3121 {
3122 case GL_BLEND_SRC_RGB:
3123 ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3124 *data = mBlendStateExt.getSrcColorIndexed(index);
3125 break;
3126 case GL_BLEND_SRC_ALPHA:
3127 ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3128 *data = mBlendStateExt.getSrcAlphaIndexed(index);
3129 break;
3130 case GL_BLEND_DST_RGB:
3131 ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3132 *data = mBlendStateExt.getDstColorIndexed(index);
3133 break;
3134 case GL_BLEND_DST_ALPHA:
3135 ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3136 *data = mBlendStateExt.getDstAlphaIndexed(index);
3137 break;
3138 case GL_BLEND_EQUATION_RGB:
3139 ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3140 *data = mBlendStateExt.getEquationColorIndexed(index);
3141 break;
3142 case GL_BLEND_EQUATION_ALPHA:
3143 ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3144 *data = mBlendStateExt.getEquationAlphaIndexed(index);
3145 break;
3146 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
3147 ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
3148 *data = mTransformFeedback->getIndexedBuffer(index).id().value;
3149 break;
3150 case GL_UNIFORM_BUFFER_BINDING:
3151 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
3152 *data = mUniformBuffers[index].id().value;
3153 break;
3154 case GL_ATOMIC_COUNTER_BUFFER_BINDING:
3155 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
3156 *data = mAtomicCounterBuffers[index].id().value;
3157 break;
3158 case GL_SHADER_STORAGE_BUFFER_BINDING:
3159 ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
3160 *data = mShaderStorageBuffers[index].id().value;
3161 break;
3162 case GL_VERTEX_BINDING_BUFFER:
3163 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
3164 *data = mVertexArray->getVertexBinding(index).getBuffer().id().value;
3165 break;
3166 case GL_VERTEX_BINDING_DIVISOR:
3167 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
3168 *data = mVertexArray->getVertexBinding(index).getDivisor();
3169 break;
3170 case GL_VERTEX_BINDING_OFFSET:
3171 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
3172 *data = static_cast<GLuint>(mVertexArray->getVertexBinding(index).getOffset());
3173 break;
3174 case GL_VERTEX_BINDING_STRIDE:
3175 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
3176 *data = mVertexArray->getVertexBinding(index).getStride();
3177 break;
3178 case GL_SAMPLE_MASK_VALUE:
3179 ASSERT(static_cast<size_t>(index) < mSampleMaskValues.size());
3180 *data = mSampleMaskValues[index];
3181 break;
3182 case GL_IMAGE_BINDING_NAME:
3183 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3184 *data = mImageUnits[index].texture.id().value;
3185 break;
3186 case GL_IMAGE_BINDING_LEVEL:
3187 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3188 *data = mImageUnits[index].level;
3189 break;
3190 case GL_IMAGE_BINDING_LAYER:
3191 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3192 *data = mImageUnits[index].layer;
3193 break;
3194 case GL_IMAGE_BINDING_ACCESS:
3195 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3196 *data = mImageUnits[index].access;
3197 break;
3198 case GL_IMAGE_BINDING_FORMAT:
3199 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3200 *data = mImageUnits[index].format;
3201 break;
3202 default:
3203 UNREACHABLE();
3204 break;
3205 }
3206 }
3207
getInteger64i_v(GLenum target,GLuint index,GLint64 * data) const3208 void State::getInteger64i_v(GLenum target, GLuint index, GLint64 *data) const
3209 {
3210 switch (target)
3211 {
3212 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
3213 ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
3214 *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
3215 break;
3216 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
3217 ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
3218 *data = mTransformFeedback->getIndexedBuffer(index).getSize();
3219 break;
3220 case GL_UNIFORM_BUFFER_START:
3221 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
3222 *data = mUniformBuffers[index].getOffset();
3223 break;
3224 case GL_UNIFORM_BUFFER_SIZE:
3225 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
3226 *data = mUniformBuffers[index].getSize();
3227 break;
3228 case GL_ATOMIC_COUNTER_BUFFER_START:
3229 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
3230 *data = mAtomicCounterBuffers[index].getOffset();
3231 break;
3232 case GL_ATOMIC_COUNTER_BUFFER_SIZE:
3233 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
3234 *data = mAtomicCounterBuffers[index].getSize();
3235 break;
3236 case GL_SHADER_STORAGE_BUFFER_START:
3237 ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
3238 *data = mShaderStorageBuffers[index].getOffset();
3239 break;
3240 case GL_SHADER_STORAGE_BUFFER_SIZE:
3241 ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
3242 *data = mShaderStorageBuffers[index].getSize();
3243 break;
3244 default:
3245 UNREACHABLE();
3246 break;
3247 }
3248 }
3249
getBooleani_v(GLenum target,GLuint index,GLboolean * data) const3250 void State::getBooleani_v(GLenum target, GLuint index, GLboolean *data) const
3251 {
3252 switch (target)
3253 {
3254 case GL_COLOR_WRITEMASK:
3255 {
3256 ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3257 bool r, g, b, a;
3258 mBlendStateExt.getColorMaskIndexed(index, &r, &g, &b, &a);
3259 data[0] = r;
3260 data[1] = g;
3261 data[2] = b;
3262 data[3] = a;
3263 break;
3264 }
3265 case GL_IMAGE_BINDING_LAYERED:
3266 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3267 *data = mImageUnits[index].layered;
3268 break;
3269 default:
3270 UNREACHABLE();
3271 break;
3272 }
3273 }
3274
3275 // TODO(http://anglebug.com/3889): Remove this helper function after blink and chromium part
3276 // refactor done.
getTextureForActiveSampler(TextureType type,size_t index)3277 Texture *State::getTextureForActiveSampler(TextureType type, size_t index)
3278 {
3279 if (type != TextureType::VideoImage)
3280 {
3281 return mSamplerTextures[type][index].get();
3282 }
3283
3284 ASSERT(type == TextureType::VideoImage);
3285
3286 Texture *candidateTexture = mSamplerTextures[type][index].get();
3287 if (candidateTexture->getWidth(TextureTarget::VideoImage, 0) == 0 ||
3288 candidateTexture->getHeight(TextureTarget::VideoImage, 0) == 0 ||
3289 candidateTexture->getDepth(TextureTarget::VideoImage, 0) == 0)
3290 {
3291 return mSamplerTextures[TextureType::_2D][index].get();
3292 }
3293
3294 return mSamplerTextures[type][index].get();
3295 }
3296
syncActiveTextures(const Context * context,Command command)3297 angle::Result State::syncActiveTextures(const Context *context, Command command)
3298 {
3299 if (mDirtyActiveTextures.none())
3300 {
3301 return angle::Result::Continue;
3302 }
3303
3304 for (size_t textureUnit : mDirtyActiveTextures)
3305 {
3306 if (mExecutable)
3307 {
3308 TextureType type = mExecutable->getActiveSamplerTypes()[textureUnit];
3309 Texture *activeTexture = (type != TextureType::InvalidEnum)
3310 ? getTextureForActiveSampler(type, textureUnit)
3311 : nullptr;
3312 const Sampler *sampler = mSamplers[textureUnit].get();
3313
3314 updateActiveTextureStateOnSync(context, textureUnit, sampler, activeTexture);
3315 }
3316 }
3317
3318 mDirtyActiveTextures.reset();
3319 return angle::Result::Continue;
3320 }
3321
syncTexturesInit(const Context * context,Command command)3322 angle::Result State::syncTexturesInit(const Context *context, Command command)
3323 {
3324 ASSERT(mRobustResourceInit);
3325
3326 if (!mProgram)
3327 return angle::Result::Continue;
3328
3329 for (size_t textureUnitIndex : mExecutable->getActiveSamplersMask())
3330 {
3331 Texture *texture = mActiveTexturesCache[textureUnitIndex];
3332 if (texture)
3333 {
3334 ANGLE_TRY(texture->ensureInitialized(context));
3335 }
3336 }
3337 return angle::Result::Continue;
3338 }
3339
syncImagesInit(const Context * context,Command command)3340 angle::Result State::syncImagesInit(const Context *context, Command command)
3341 {
3342 ASSERT(mRobustResourceInit);
3343 ASSERT(mExecutable);
3344 for (size_t imageUnitIndex : mExecutable->getActiveImagesMask())
3345 {
3346 Texture *texture = mImageUnits[imageUnitIndex].texture.get();
3347 if (texture)
3348 {
3349 ANGLE_TRY(texture->ensureInitialized(context));
3350 }
3351 }
3352 return angle::Result::Continue;
3353 }
3354
syncReadAttachments(const Context * context,Command command)3355 angle::Result State::syncReadAttachments(const Context *context, Command command)
3356 {
3357 ASSERT(mReadFramebuffer);
3358 ASSERT(mRobustResourceInit);
3359 return mReadFramebuffer->ensureReadAttachmentsInitialized(context);
3360 }
3361
syncDrawAttachments(const Context * context,Command command)3362 angle::Result State::syncDrawAttachments(const Context *context, Command command)
3363 {
3364 ASSERT(mDrawFramebuffer);
3365 ASSERT(mRobustResourceInit);
3366 return mDrawFramebuffer->ensureDrawAttachmentsInitialized(context);
3367 }
3368
syncReadFramebuffer(const Context * context,Command command)3369 angle::Result State::syncReadFramebuffer(const Context *context, Command command)
3370 {
3371 ASSERT(mReadFramebuffer);
3372 return mReadFramebuffer->syncState(context, GL_READ_FRAMEBUFFER, command);
3373 }
3374
syncDrawFramebuffer(const Context * context,Command command)3375 angle::Result State::syncDrawFramebuffer(const Context *context, Command command)
3376 {
3377 ASSERT(mDrawFramebuffer);
3378 mDrawFramebuffer->setWriteControlMode(context->getState().getFramebufferSRGB()
3379 ? SrgbWriteControlMode::Default
3380 : SrgbWriteControlMode::Linear);
3381 return mDrawFramebuffer->syncState(context, GL_DRAW_FRAMEBUFFER, command);
3382 }
3383
syncTextures(const Context * context,Command command)3384 angle::Result State::syncTextures(const Context *context, Command command)
3385 {
3386 if (mDirtyTextures.none())
3387 return angle::Result::Continue;
3388
3389 for (size_t textureIndex : mDirtyTextures)
3390 {
3391 Texture *texture = mActiveTexturesCache[textureIndex];
3392 if (texture && texture->hasAnyDirtyBit())
3393 {
3394 ANGLE_TRY(texture->syncState(context, Command::Other));
3395 }
3396 }
3397
3398 mDirtyTextures.reset();
3399 return angle::Result::Continue;
3400 }
3401
syncImages(const Context * context,Command command)3402 angle::Result State::syncImages(const Context *context, Command command)
3403 {
3404 if (mDirtyImages.none())
3405 return angle::Result::Continue;
3406
3407 for (size_t imageUnitIndex : mDirtyImages)
3408 {
3409 Texture *texture = mImageUnits[imageUnitIndex].texture.get();
3410 if (texture && texture->hasAnyDirtyBit())
3411 {
3412 ANGLE_TRY(texture->syncState(context, Command::Other));
3413 }
3414 }
3415
3416 mDirtyImages.reset();
3417 return angle::Result::Continue;
3418 }
3419
syncSamplers(const Context * context,Command command)3420 angle::Result State::syncSamplers(const Context *context, Command command)
3421 {
3422 if (mDirtySamplers.none())
3423 return angle::Result::Continue;
3424
3425 for (size_t samplerIndex : mDirtySamplers)
3426 {
3427 BindingPointer<Sampler> &sampler = mSamplers[samplerIndex];
3428 if (sampler.get() && sampler->isDirty())
3429 {
3430 ANGLE_TRY(sampler->syncState(context));
3431 }
3432 }
3433
3434 mDirtySamplers.reset();
3435
3436 return angle::Result::Continue;
3437 }
3438
syncVertexArray(const Context * context,Command command)3439 angle::Result State::syncVertexArray(const Context *context, Command command)
3440 {
3441 ASSERT(mVertexArray);
3442 return mVertexArray->syncState(context);
3443 }
3444
syncProgram(const Context * context,Command command)3445 angle::Result State::syncProgram(const Context *context, Command command)
3446 {
3447 // There may not be a program if the calling application only uses program pipelines.
3448 if (mProgram)
3449 {
3450 return mProgram->syncState(context);
3451 }
3452 return angle::Result::Continue;
3453 }
3454
syncDirtyObject(const Context * context,GLenum target)3455 angle::Result State::syncDirtyObject(const Context *context, GLenum target)
3456 {
3457 DirtyObjects localSet;
3458
3459 switch (target)
3460 {
3461 case GL_READ_FRAMEBUFFER:
3462 localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
3463 break;
3464 case GL_DRAW_FRAMEBUFFER:
3465 localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
3466 break;
3467 case GL_FRAMEBUFFER:
3468 localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
3469 localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
3470 break;
3471 case GL_VERTEX_ARRAY:
3472 localSet.set(DIRTY_OBJECT_VERTEX_ARRAY);
3473 break;
3474 case GL_TEXTURE:
3475 localSet.set(DIRTY_OBJECT_TEXTURES);
3476 break;
3477 case GL_SAMPLER:
3478 localSet.set(DIRTY_OBJECT_SAMPLERS);
3479 break;
3480 case GL_PROGRAM:
3481 localSet.set(DIRTY_OBJECT_PROGRAM);
3482 break;
3483 }
3484
3485 return syncDirtyObjects(context, localSet, Command::Other);
3486 }
3487
setObjectDirty(GLenum target)3488 void State::setObjectDirty(GLenum target)
3489 {
3490 switch (target)
3491 {
3492 case GL_READ_FRAMEBUFFER:
3493 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
3494 break;
3495 case GL_DRAW_FRAMEBUFFER:
3496 setDrawFramebufferDirty();
3497 break;
3498 case GL_FRAMEBUFFER:
3499 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
3500 setDrawFramebufferDirty();
3501 break;
3502 case GL_VERTEX_ARRAY:
3503 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
3504 break;
3505 case GL_PROGRAM:
3506 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
3507 break;
3508 default:
3509 break;
3510 }
3511 }
3512
onProgramExecutableChange(const Context * context,Program * program)3513 angle::Result State::onProgramExecutableChange(const Context *context, Program *program)
3514 {
3515 // OpenGL Spec:
3516 // "If LinkProgram or ProgramBinary successfully re-links a program object
3517 // that was already in use as a result of a previous call to UseProgram, then the
3518 // generated executable code will be installed as part of the current rendering state."
3519 ASSERT(program->isLinked());
3520
3521 // If this Program is currently active, we need to update the State's pointer to the current
3522 // ProgramExecutable if we just changed it.
3523 if (mProgram == program)
3524 {
3525 mExecutable = &program->getExecutable();
3526 }
3527
3528 mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE);
3529
3530 if (program->hasAnyDirtyBit())
3531 {
3532 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
3533 }
3534
3535 // Set any bound textures.
3536 const ProgramExecutable &executable = program->getExecutable();
3537 const ActiveTextureTypeArray &textureTypes = executable.getActiveSamplerTypes();
3538 for (size_t textureIndex : executable.getActiveSamplersMask())
3539 {
3540 TextureType type = textureTypes[textureIndex];
3541
3542 // This can happen if there is a conflicting texture type.
3543 if (type == TextureType::InvalidEnum)
3544 continue;
3545
3546 Texture *texture = getTextureForActiveSampler(type, textureIndex);
3547 updateTextureBinding(context, textureIndex, texture);
3548 }
3549
3550 for (size_t imageUnitIndex : executable.getActiveImagesMask())
3551 {
3552 Texture *image = mImageUnits[imageUnitIndex].texture.get();
3553 if (!image)
3554 continue;
3555
3556 if (image->hasAnyDirtyBit())
3557 {
3558 ANGLE_TRY(image->syncState(context, Command::Other));
3559 }
3560
3561 if (mRobustResourceInit && image->initState() == InitState::MayNeedInit)
3562 {
3563 mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT);
3564 }
3565 }
3566
3567 return angle::Result::Continue;
3568 }
3569
onProgramPipelineExecutableChange(const Context * context)3570 angle::Result State::onProgramPipelineExecutableChange(const Context *context)
3571 {
3572 mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE);
3573
3574 // Set any bound textures.
3575 const ProgramExecutable &executable = mProgramPipeline->getExecutable();
3576 const ActiveTextureTypeArray &textureTypes = executable.getActiveSamplerTypes();
3577
3578 for (size_t textureIndex : executable.getActiveSamplersMask())
3579 {
3580 TextureType type = textureTypes[textureIndex];
3581
3582 // This can happen if there is a conflicting texture type.
3583 if (type == TextureType::InvalidEnum)
3584 continue;
3585
3586 Texture *texture = getTextureForActiveSampler(type, textureIndex);
3587 updateTextureBinding(context, textureIndex, texture);
3588 }
3589
3590 for (size_t imageUnitIndex : executable.getActiveImagesMask())
3591 {
3592 Texture *image = mImageUnits[imageUnitIndex].texture.get();
3593 if (!image)
3594 continue;
3595
3596 if (image->hasAnyDirtyBit())
3597 {
3598 ANGLE_TRY(image->syncState(context, Command::Other));
3599 }
3600
3601 if (mRobustResourceInit && image->initState() == InitState::MayNeedInit)
3602 {
3603 mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT);
3604 }
3605 }
3606
3607 return angle::Result::Continue;
3608 }
3609
setTextureDirty(size_t textureUnitIndex)3610 void State::setTextureDirty(size_t textureUnitIndex)
3611 {
3612 mDirtyObjects.set(DIRTY_OBJECT_TEXTURES);
3613 mDirtyTextures.set(textureUnitIndex);
3614 }
3615
setSamplerDirty(size_t samplerIndex)3616 void State::setSamplerDirty(size_t samplerIndex)
3617 {
3618 mDirtyObjects.set(DIRTY_OBJECT_SAMPLERS);
3619 mDirtySamplers.set(samplerIndex);
3620 }
3621
setImageUnit(const Context * context,size_t unit,Texture * texture,GLint level,GLboolean layered,GLint layer,GLenum access,GLenum format)3622 void State::setImageUnit(const Context *context,
3623 size_t unit,
3624 Texture *texture,
3625 GLint level,
3626 GLboolean layered,
3627 GLint layer,
3628 GLenum access,
3629 GLenum format)
3630 {
3631 ASSERT(!mImageUnits.empty());
3632
3633 ImageUnit &imageUnit = mImageUnits[unit];
3634
3635 if (texture)
3636 {
3637 texture->onBindAsImageTexture();
3638 }
3639 imageUnit.texture.set(context, texture);
3640 imageUnit.level = level;
3641 imageUnit.layered = layered;
3642 imageUnit.layer = layer;
3643 imageUnit.access = access;
3644 imageUnit.format = format;
3645 mDirtyBits.set(DIRTY_BIT_IMAGE_BINDINGS);
3646
3647 onImageStateChange(context, unit);
3648 }
3649
3650 // Handle a dirty texture event.
onActiveTextureChange(const Context * context,size_t textureUnit)3651 void State::onActiveTextureChange(const Context *context, size_t textureUnit)
3652 {
3653 if (mExecutable)
3654 {
3655 TextureType type = mExecutable->getActiveSamplerTypes()[textureUnit];
3656 Texture *activeTexture = (type != TextureType::InvalidEnum)
3657 ? getTextureForActiveSampler(type, textureUnit)
3658 : nullptr;
3659 updateTextureBinding(context, textureUnit, activeTexture);
3660
3661 mExecutable->onStateChange(angle::SubjectMessage::ProgramTextureOrImageBindingChanged);
3662 }
3663 }
3664
onActiveTextureStateChange(const Context * context,size_t textureUnit)3665 void State::onActiveTextureStateChange(const Context *context, size_t textureUnit)
3666 {
3667 if (mExecutable)
3668 {
3669 TextureType type = mExecutable->getActiveSamplerTypes()[textureUnit];
3670 Texture *activeTexture = (type != TextureType::InvalidEnum)
3671 ? getTextureForActiveSampler(type, textureUnit)
3672 : nullptr;
3673 setActiveTextureDirty(textureUnit, activeTexture);
3674 }
3675 }
3676
onImageStateChange(const Context * context,size_t unit)3677 void State::onImageStateChange(const Context *context, size_t unit)
3678 {
3679 if (mExecutable)
3680 {
3681 const ImageUnit &image = mImageUnits[unit];
3682
3683 // Have nothing to do here if no texture bound
3684 if (!image.texture.get())
3685 return;
3686
3687 if (image.texture->hasAnyDirtyBit())
3688 {
3689 mDirtyImages.set(unit);
3690 mDirtyObjects.set(DIRTY_OBJECT_IMAGES);
3691 }
3692
3693 if (mRobustResourceInit && image.texture->initState() == InitState::MayNeedInit)
3694 {
3695 mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT);
3696 }
3697
3698 mExecutable->onStateChange(angle::SubjectMessage::ProgramTextureOrImageBindingChanged);
3699 }
3700 }
3701
onUniformBufferStateChange(size_t uniformBufferIndex)3702 void State::onUniformBufferStateChange(size_t uniformBufferIndex)
3703 {
3704 // This could be represented by a different dirty bit. Using the same one keeps it simple.
3705 mDirtyBits.set(DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
3706 }
3707
onAtomicCounterBufferStateChange(size_t atomicCounterBufferIndex)3708 void State::onAtomicCounterBufferStateChange(size_t atomicCounterBufferIndex)
3709 {
3710 mDirtyBits.set(DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING);
3711 }
3712
onShaderStorageBufferStateChange(size_t shaderStorageBufferIndex)3713 void State::onShaderStorageBufferStateChange(size_t shaderStorageBufferIndex)
3714 {
3715 mDirtyBits.set(DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING);
3716 }
3717
getAndResetDirtyCurrentValues() const3718 AttributesMask State::getAndResetDirtyCurrentValues() const
3719 {
3720 AttributesMask retVal = mDirtyCurrentValues;
3721 mDirtyCurrentValues.reset();
3722 return retVal;
3723 }
3724
getAndResetExtendedDirtyBits() const3725 State::ExtendedDirtyBits State::getAndResetExtendedDirtyBits() const
3726 {
3727 ExtendedDirtyBits retVal = mExtendedDirtyBits;
3728 mExtendedDirtyBits.reset();
3729 return retVal;
3730 }
3731
initializeForCapture(const Context * context)3732 void State::initializeForCapture(const Context *context)
3733 {
3734 mCaps = context->getCaps();
3735 mExtensions = context->getExtensions();
3736
3737 // This little kludge gets around the frame capture "constness". It should be safe because
3738 // nothing in the context is modified in a non-compatible way during capture.
3739 Context *mutableContext = const_cast<Context *>(context);
3740 initialize(mutableContext);
3741 }
3742
3743 constexpr State::DirtyObjectHandler State::kDirtyObjectHandlers[DIRTY_OBJECT_MAX];
3744
3745 } // namespace gl
3746