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