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