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