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