• 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     }
2178 
2179     if (getVertexArray()->detachBuffer(context, bufferID))
2180     {
2181         mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
2182         context->getStateCache().onVertexArrayStateChange(context);
2183     }
2184 
2185     for (size_t uniformBufferIndex : mBoundUniformBuffersMask)
2186     {
2187         OffsetBindingPointer<Buffer> &binding = mUniformBuffers[uniformBufferIndex];
2188 
2189         if (binding.id() == bufferID)
2190         {
2191             UpdateIndexedBufferBinding(context, &binding, nullptr, BufferBinding::Uniform, 0, 0);
2192             mBoundUniformBuffersMask.reset(uniformBufferIndex);
2193         }
2194     }
2195 
2196     for (size_t atomicCounterBufferIndex : mBoundAtomicCounterBuffersMask)
2197     {
2198         OffsetBindingPointer<Buffer> &binding = mAtomicCounterBuffers[atomicCounterBufferIndex];
2199 
2200         if (binding.id() == bufferID)
2201         {
2202             UpdateIndexedBufferBinding(context, &binding, nullptr, BufferBinding::AtomicCounter, 0,
2203                                        0);
2204             mBoundAtomicCounterBuffersMask.reset(atomicCounterBufferIndex);
2205         }
2206     }
2207 
2208     for (size_t shaderStorageBufferIndex : mBoundShaderStorageBuffersMask)
2209     {
2210         OffsetBindingPointer<Buffer> &binding = mShaderStorageBuffers[shaderStorageBufferIndex];
2211 
2212         if (binding.id() == bufferID)
2213         {
2214             UpdateIndexedBufferBinding(context, &binding, nullptr, BufferBinding::ShaderStorage, 0,
2215                                        0);
2216             mBoundShaderStorageBuffersMask.reset(shaderStorageBufferIndex);
2217         }
2218     }
2219 
2220     return angle::Result::Continue;
2221 }
2222 
setEnableVertexAttribArray(unsigned int attribNum,bool enabled)2223 void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
2224 {
2225     getVertexArray()->enableAttribute(attribNum, enabled);
2226     mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
2227 }
2228 
setVertexAttribf(GLuint index,const GLfloat values[4])2229 void State::setVertexAttribf(GLuint index, const GLfloat values[4])
2230 {
2231     ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
2232     mVertexAttribCurrentValues[index].setFloatValues(values);
2233     mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
2234     mDirtyCurrentValues.set(index);
2235     SetComponentTypeMask(ComponentType::Float, index, &mCurrentValuesTypeMask);
2236 }
2237 
setVertexAttribu(GLuint index,const GLuint values[4])2238 void State::setVertexAttribu(GLuint index, const GLuint values[4])
2239 {
2240     ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
2241     mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
2242     mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
2243     mDirtyCurrentValues.set(index);
2244     SetComponentTypeMask(ComponentType::UnsignedInt, index, &mCurrentValuesTypeMask);
2245 }
2246 
setVertexAttribi(GLuint index,const GLint values[4])2247 void State::setVertexAttribi(GLuint index, const GLint values[4])
2248 {
2249     ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
2250     mVertexAttribCurrentValues[index].setIntValues(values);
2251     mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
2252     mDirtyCurrentValues.set(index);
2253     SetComponentTypeMask(ComponentType::Int, index, &mCurrentValuesTypeMask);
2254 }
2255 
setVertexAttribDivisor(const Context * context,GLuint index,GLuint divisor)2256 void State::setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor)
2257 {
2258     getVertexArray()->setVertexAttribDivisor(context, index, divisor);
2259     mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
2260 }
2261 
getVertexAttribPointer(unsigned int attribNum) const2262 const void *State::getVertexAttribPointer(unsigned int attribNum) const
2263 {
2264     return getVertexArray()->getVertexAttribute(attribNum).pointer;
2265 }
2266 
setPackAlignment(GLint alignment)2267 void State::setPackAlignment(GLint alignment)
2268 {
2269     mPack.alignment = alignment;
2270     mDirtyBits.set(DIRTY_BIT_PACK_STATE);
2271 }
2272 
setPackReverseRowOrder(bool reverseRowOrder)2273 void State::setPackReverseRowOrder(bool reverseRowOrder)
2274 {
2275     mPack.reverseRowOrder = reverseRowOrder;
2276     mDirtyBits.set(DIRTY_BIT_PACK_STATE);
2277 }
2278 
setPackRowLength(GLint rowLength)2279 void State::setPackRowLength(GLint rowLength)
2280 {
2281     mPack.rowLength = rowLength;
2282     mDirtyBits.set(DIRTY_BIT_PACK_STATE);
2283 }
2284 
setPackSkipRows(GLint skipRows)2285 void State::setPackSkipRows(GLint skipRows)
2286 {
2287     mPack.skipRows = skipRows;
2288     mDirtyBits.set(DIRTY_BIT_PACK_STATE);
2289 }
2290 
setPackSkipPixels(GLint skipPixels)2291 void State::setPackSkipPixels(GLint skipPixels)
2292 {
2293     mPack.skipPixels = skipPixels;
2294     mDirtyBits.set(DIRTY_BIT_PACK_STATE);
2295 }
2296 
setUnpackAlignment(GLint alignment)2297 void State::setUnpackAlignment(GLint alignment)
2298 {
2299     mUnpack.alignment = alignment;
2300     mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2301 }
2302 
setUnpackRowLength(GLint rowLength)2303 void State::setUnpackRowLength(GLint rowLength)
2304 {
2305     mUnpack.rowLength = rowLength;
2306     mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2307 }
2308 
setUnpackImageHeight(GLint imageHeight)2309 void State::setUnpackImageHeight(GLint imageHeight)
2310 {
2311     mUnpack.imageHeight = imageHeight;
2312     mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2313 }
2314 
setUnpackSkipImages(GLint skipImages)2315 void State::setUnpackSkipImages(GLint skipImages)
2316 {
2317     mUnpack.skipImages = skipImages;
2318     mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2319 }
2320 
setUnpackSkipRows(GLint skipRows)2321 void State::setUnpackSkipRows(GLint skipRows)
2322 {
2323     mUnpack.skipRows = skipRows;
2324     mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2325 }
2326 
setUnpackSkipPixels(GLint skipPixels)2327 void State::setUnpackSkipPixels(GLint skipPixels)
2328 {
2329     mUnpack.skipPixels = skipPixels;
2330     mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2331 }
2332 
setCoverageModulation(GLenum components)2333 void State::setCoverageModulation(GLenum components)
2334 {
2335     if (mCoverageModulation != components)
2336     {
2337         mCoverageModulation = components;
2338         mDirtyBits.set(DIRTY_BIT_COVERAGE_MODULATION);
2339     }
2340 }
2341 
setFramebufferSRGB(bool sRGB)2342 void State::setFramebufferSRGB(bool sRGB)
2343 {
2344     if (mFramebufferSRGB != sRGB)
2345     {
2346         mFramebufferSRGB = sRGB;
2347         mDirtyBits.set(DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE);
2348         setDrawFramebufferDirty();
2349     }
2350 }
2351 
setMaxShaderCompilerThreads(GLuint count)2352 void State::setMaxShaderCompilerThreads(GLuint count)
2353 {
2354     mMaxShaderCompilerThreads = count;
2355 }
2356 
setPatchVertices(GLuint value)2357 void State::setPatchVertices(GLuint value)
2358 {
2359     if (mPatchVertices != value)
2360     {
2361         mPatchVertices = value;
2362         mDirtyBits.set(DIRTY_BIT_PATCH_VERTICES);
2363     }
2364 }
2365 
getBooleanv(GLenum pname,GLboolean * params) const2366 void State::getBooleanv(GLenum pname, GLboolean *params) const
2367 {
2368     switch (pname)
2369     {
2370         case GL_SAMPLE_COVERAGE_INVERT:
2371             *params = mSampleCoverageInvert;
2372             break;
2373         case GL_DEPTH_WRITEMASK:
2374             *params = mDepthStencil.depthMask;
2375             break;
2376         case GL_COLOR_WRITEMASK:
2377         {
2378             // non-indexed get returns the state of draw buffer zero
2379             bool r, g, b, a;
2380             mBlendStateExt.getColorMaskIndexed(0, &r, &g, &b, &a);
2381             params[0] = r;
2382             params[1] = g;
2383             params[2] = b;
2384             params[3] = a;
2385             break;
2386         }
2387         case GL_CULL_FACE:
2388             *params = mRasterizer.cullFace;
2389             break;
2390         case GL_POLYGON_OFFSET_FILL:
2391             *params = mRasterizer.polygonOffsetFill;
2392             break;
2393         case GL_SAMPLE_ALPHA_TO_COVERAGE:
2394             *params = mSampleAlphaToCoverage;
2395             break;
2396         case GL_SAMPLE_COVERAGE:
2397             *params = mSampleCoverage;
2398             break;
2399         case GL_SAMPLE_MASK:
2400             *params = mSampleMask;
2401             break;
2402         case GL_SCISSOR_TEST:
2403             *params = mScissorTest;
2404             break;
2405         case GL_STENCIL_TEST:
2406             *params = mDepthStencil.stencilTest;
2407             break;
2408         case GL_DEPTH_TEST:
2409             *params = mDepthStencil.depthTest;
2410             break;
2411         case GL_BLEND:
2412             // non-indexed get returns the state of draw buffer zero
2413             *params = mBlendStateExt.mEnabledMask.test(0);
2414             break;
2415         case GL_DITHER:
2416             *params = mRasterizer.dither;
2417             break;
2418         case GL_TRANSFORM_FEEDBACK_ACTIVE:
2419             *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE;
2420             break;
2421         case GL_TRANSFORM_FEEDBACK_PAUSED:
2422             *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE;
2423             break;
2424         case GL_PRIMITIVE_RESTART_FIXED_INDEX:
2425             *params = mPrimitiveRestart;
2426             break;
2427         case GL_RASTERIZER_DISCARD:
2428             *params = isRasterizerDiscardEnabled() ? GL_TRUE : GL_FALSE;
2429             break;
2430         case GL_DEBUG_OUTPUT_SYNCHRONOUS:
2431             *params = mDebug.isOutputSynchronous() ? GL_TRUE : GL_FALSE;
2432             break;
2433         case GL_DEBUG_OUTPUT:
2434             *params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE;
2435             break;
2436         case GL_MULTISAMPLE_EXT:
2437             *params = mMultiSampling;
2438             break;
2439         case GL_SAMPLE_ALPHA_TO_ONE_EXT:
2440             *params = mSampleAlphaToOne;
2441             break;
2442         case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
2443             *params = isBindGeneratesResourceEnabled() ? GL_TRUE : GL_FALSE;
2444             break;
2445         case GL_CLIENT_ARRAYS_ANGLE:
2446             *params = areClientArraysEnabled() ? GL_TRUE : GL_FALSE;
2447             break;
2448         case GL_FRAMEBUFFER_SRGB_EXT:
2449             *params = getFramebufferSRGB() ? GL_TRUE : GL_FALSE;
2450             break;
2451         case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
2452             *params = mRobustResourceInit ? GL_TRUE : GL_FALSE;
2453             break;
2454         case GL_PROGRAM_CACHE_ENABLED_ANGLE:
2455             *params = mProgramBinaryCacheEnabled ? GL_TRUE : GL_FALSE;
2456             break;
2457         case GL_TEXTURE_RECTANGLE_ANGLE:
2458             *params = mTextureRectangleEnabled ? GL_TRUE : GL_FALSE;
2459             break;
2460         case GL_LIGHT_MODEL_TWO_SIDE:
2461             *params = IsLightModelTwoSided(&mGLES1State);
2462             break;
2463         case GL_SAMPLE_SHADING:
2464             *params = mIsSampleShadingEnabled;
2465             break;
2466         case GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED:
2467             *params = isPrimitiveRestartEnabled() && getExtensions().tessellationShaderEXT;
2468             break;
2469         // 2.2.2 Data Conversions For State Query Commands, in GLES 3.2 spec.
2470         // If a command returning boolean data is called, such as GetBooleanv, a floating-point or
2471         // integer value converts to FALSE if and only if it is zero. Otherwise it converts to TRUE.
2472         // GL_EXT_clip_control
2473         case GL_CLIP_ORIGIN_EXT:
2474             *params = GL_TRUE;
2475             break;
2476         case GL_CLIP_DEPTH_MODE_EXT:
2477             *params = GL_TRUE;
2478             break;
2479         case GL_ROBUST_FRAGMENT_SHADER_OUTPUT_ANGLE:
2480             *params = mExtensions.robustFragmentShaderOutputANGLE ? GL_TRUE : GL_FALSE;
2481             break;
2482         default:
2483             UNREACHABLE();
2484             break;
2485     }
2486 }
2487 
getFloatv(GLenum pname,GLfloat * params) const2488 void State::getFloatv(GLenum pname, GLfloat *params) const
2489 {
2490     // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
2491     // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
2492     // GetIntegerv as its native query function. As it would require conversion in any
2493     // case, this should make no difference to the calling application.
2494     switch (pname)
2495     {
2496         case GL_LINE_WIDTH:
2497             *params = mLineWidth;
2498             break;
2499         case GL_SAMPLE_COVERAGE_VALUE:
2500             *params = mSampleCoverageValue;
2501             break;
2502         case GL_DEPTH_CLEAR_VALUE:
2503             *params = mDepthClearValue;
2504             break;
2505         case GL_POLYGON_OFFSET_FACTOR:
2506             *params = mRasterizer.polygonOffsetFactor;
2507             break;
2508         case GL_POLYGON_OFFSET_UNITS:
2509             *params = mRasterizer.polygonOffsetUnits;
2510             break;
2511         case GL_DEPTH_RANGE:
2512             params[0] = mNearZ;
2513             params[1] = mFarZ;
2514             break;
2515         case GL_COLOR_CLEAR_VALUE:
2516             params[0] = mColorClearValue.red;
2517             params[1] = mColorClearValue.green;
2518             params[2] = mColorClearValue.blue;
2519             params[3] = mColorClearValue.alpha;
2520             break;
2521         case GL_BLEND_COLOR:
2522             params[0] = mBlendColor.red;
2523             params[1] = mBlendColor.green;
2524             params[2] = mBlendColor.blue;
2525             params[3] = mBlendColor.alpha;
2526             break;
2527         case GL_MULTISAMPLE_EXT:
2528             *params = static_cast<GLfloat>(mMultiSampling);
2529             break;
2530         case GL_SAMPLE_ALPHA_TO_ONE_EXT:
2531             *params = static_cast<GLfloat>(mSampleAlphaToOne);
2532             break;
2533         case GL_COVERAGE_MODULATION_CHROMIUM:
2534             params[0] = static_cast<GLfloat>(mCoverageModulation);
2535             break;
2536         case GL_ALPHA_TEST_REF:
2537             *params = mGLES1State.mAlphaTestRef;
2538             break;
2539         case GL_CURRENT_COLOR:
2540         {
2541             const auto &color = mGLES1State.mCurrentColor;
2542             params[0]         = color.red;
2543             params[1]         = color.green;
2544             params[2]         = color.blue;
2545             params[3]         = color.alpha;
2546             break;
2547         }
2548         case GL_CURRENT_NORMAL:
2549         {
2550             const auto &normal = mGLES1State.mCurrentNormal;
2551             params[0]          = normal[0];
2552             params[1]          = normal[1];
2553             params[2]          = normal[2];
2554             break;
2555         }
2556         case GL_CURRENT_TEXTURE_COORDS:
2557         {
2558             const auto &texcoord = mGLES1State.mCurrentTextureCoords[mActiveSampler];
2559             params[0]            = texcoord.s;
2560             params[1]            = texcoord.t;
2561             params[2]            = texcoord.r;
2562             params[3]            = texcoord.q;
2563             break;
2564         }
2565         case GL_MODELVIEW_MATRIX:
2566             memcpy(params, mGLES1State.mModelviewMatrices.back().constData(), 16 * sizeof(GLfloat));
2567             break;
2568         case GL_PROJECTION_MATRIX:
2569             memcpy(params, mGLES1State.mProjectionMatrices.back().constData(),
2570                    16 * sizeof(GLfloat));
2571             break;
2572         case GL_TEXTURE_MATRIX:
2573             memcpy(params, mGLES1State.mTextureMatrices[mActiveSampler].back().constData(),
2574                    16 * sizeof(GLfloat));
2575             break;
2576         case GL_LIGHT_MODEL_AMBIENT:
2577             GetLightModelParameters(&mGLES1State, pname, params);
2578             break;
2579         case GL_FOG_MODE:
2580         case GL_FOG_DENSITY:
2581         case GL_FOG_START:
2582         case GL_FOG_END:
2583         case GL_FOG_COLOR:
2584             GetFogParameters(&mGLES1State, pname, params);
2585             break;
2586         case GL_POINT_SIZE:
2587             GetPointSize(&mGLES1State, params);
2588             break;
2589         case GL_POINT_SIZE_MIN:
2590         case GL_POINT_SIZE_MAX:
2591         case GL_POINT_FADE_THRESHOLD_SIZE:
2592         case GL_POINT_DISTANCE_ATTENUATION:
2593             GetPointParameter(&mGLES1State, FromGLenum<PointParameter>(pname), params);
2594             break;
2595         case GL_MIN_SAMPLE_SHADING_VALUE:
2596             *params = mMinSampleShading;
2597             break;
2598         // 2.2.2 Data Conversions For State Query Commands, in GLES 3.2 spec.
2599         // If a command returning floating-point data is called, such as GetFloatv, ... An integer
2600         // value is coerced to floating-point.
2601         case GL_CLIP_ORIGIN_EXT:
2602             *params = static_cast<float>(mClipControlOrigin);
2603             break;
2604         case GL_CLIP_DEPTH_MODE_EXT:
2605             *params = static_cast<float>(mClipControlDepth);
2606             break;
2607         default:
2608             UNREACHABLE();
2609             break;
2610     }
2611 }
2612 
getIntegerv(const Context * context,GLenum pname,GLint * params) const2613 angle::Result State::getIntegerv(const Context *context, GLenum pname, GLint *params) const
2614 {
2615     if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
2616     {
2617         size_t drawBuffer = (pname - GL_DRAW_BUFFER0_EXT);
2618         ASSERT(drawBuffer < static_cast<size_t>(mCaps.maxDrawBuffers));
2619         Framebuffer *framebuffer = mDrawFramebuffer;
2620         // The default framebuffer may have fewer draw buffer states than a user-created one. The
2621         // user is always allowed to query up to GL_MAX_DRAWBUFFERS so just return GL_NONE here if
2622         // the draw buffer is out of range for this framebuffer.
2623         *params = drawBuffer < framebuffer->getDrawbufferStateCount()
2624                       ? framebuffer->getDrawBufferState(drawBuffer)
2625                       : GL_NONE;
2626         return angle::Result::Continue;
2627     }
2628 
2629     // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
2630     // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
2631     // GetIntegerv as its native query function. As it would require conversion in any
2632     // case, this should make no difference to the calling application. You may find it in
2633     // State::getFloatv.
2634     switch (pname)
2635     {
2636         case GL_ARRAY_BUFFER_BINDING:
2637             *params = mBoundBuffers[BufferBinding::Array].id().value;
2638             break;
2639         case GL_DRAW_INDIRECT_BUFFER_BINDING:
2640             *params = mBoundBuffers[BufferBinding::DrawIndirect].id().value;
2641             break;
2642         case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2643         {
2644             Buffer *elementArrayBuffer = getVertexArray()->getElementArrayBuffer();
2645             *params                    = elementArrayBuffer ? elementArrayBuffer->id().value : 0;
2646             break;
2647         }
2648         case GL_DRAW_FRAMEBUFFER_BINDING:
2649             static_assert(GL_DRAW_FRAMEBUFFER_BINDING == GL_DRAW_FRAMEBUFFER_BINDING_ANGLE,
2650                           "Enum mismatch");
2651             *params = mDrawFramebuffer->id().value;
2652             break;
2653         case GL_READ_FRAMEBUFFER_BINDING:
2654             static_assert(GL_READ_FRAMEBUFFER_BINDING == GL_READ_FRAMEBUFFER_BINDING_ANGLE,
2655                           "Enum mismatch");
2656             *params = mReadFramebuffer->id().value;
2657             break;
2658         case GL_RENDERBUFFER_BINDING:
2659             *params = mRenderbuffer.id().value;
2660             break;
2661         case GL_VERTEX_ARRAY_BINDING:
2662             *params = mVertexArray->id().value;
2663             break;
2664         case GL_CURRENT_PROGRAM:
2665             *params = mProgram ? mProgram->id().value : 0;
2666             break;
2667         case GL_PACK_ALIGNMENT:
2668             *params = mPack.alignment;
2669             break;
2670         case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
2671             *params = mPack.reverseRowOrder;
2672             break;
2673         case GL_PACK_ROW_LENGTH:
2674             *params = mPack.rowLength;
2675             break;
2676         case GL_PACK_SKIP_ROWS:
2677             *params = mPack.skipRows;
2678             break;
2679         case GL_PACK_SKIP_PIXELS:
2680             *params = mPack.skipPixels;
2681             break;
2682         case GL_UNPACK_ALIGNMENT:
2683             *params = mUnpack.alignment;
2684             break;
2685         case GL_UNPACK_ROW_LENGTH:
2686             *params = mUnpack.rowLength;
2687             break;
2688         case GL_UNPACK_IMAGE_HEIGHT:
2689             *params = mUnpack.imageHeight;
2690             break;
2691         case GL_UNPACK_SKIP_IMAGES:
2692             *params = mUnpack.skipImages;
2693             break;
2694         case GL_UNPACK_SKIP_ROWS:
2695             *params = mUnpack.skipRows;
2696             break;
2697         case GL_UNPACK_SKIP_PIXELS:
2698             *params = mUnpack.skipPixels;
2699             break;
2700         case GL_GENERATE_MIPMAP_HINT:
2701             *params = mGenerateMipmapHint;
2702             break;
2703         case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
2704             *params = mTextureFilteringHint;
2705             break;
2706         case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
2707             *params = mFragmentShaderDerivativeHint;
2708             break;
2709         case GL_ACTIVE_TEXTURE:
2710             *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
2711             break;
2712         case GL_STENCIL_FUNC:
2713             *params = mDepthStencil.stencilFunc;
2714             break;
2715         case GL_STENCIL_REF:
2716             *params = mStencilRef;
2717             break;
2718         case GL_STENCIL_VALUE_MASK:
2719             *params = CastMaskValue(mDepthStencil.stencilMask);
2720             break;
2721         case GL_STENCIL_BACK_FUNC:
2722             *params = mDepthStencil.stencilBackFunc;
2723             break;
2724         case GL_STENCIL_BACK_REF:
2725             *params = mStencilBackRef;
2726             break;
2727         case GL_STENCIL_BACK_VALUE_MASK:
2728             *params = CastMaskValue(mDepthStencil.stencilBackMask);
2729             break;
2730         case GL_STENCIL_FAIL:
2731             *params = mDepthStencil.stencilFail;
2732             break;
2733         case GL_STENCIL_PASS_DEPTH_FAIL:
2734             *params = mDepthStencil.stencilPassDepthFail;
2735             break;
2736         case GL_STENCIL_PASS_DEPTH_PASS:
2737             *params = mDepthStencil.stencilPassDepthPass;
2738             break;
2739         case GL_STENCIL_BACK_FAIL:
2740             *params = mDepthStencil.stencilBackFail;
2741             break;
2742         case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
2743             *params = mDepthStencil.stencilBackPassDepthFail;
2744             break;
2745         case GL_STENCIL_BACK_PASS_DEPTH_PASS:
2746             *params = mDepthStencil.stencilBackPassDepthPass;
2747             break;
2748         case GL_DEPTH_FUNC:
2749             *params = mDepthStencil.depthFunc;
2750             break;
2751         case GL_BLEND_SRC_RGB:
2752             // non-indexed get returns the state of draw buffer zero
2753             *params = mBlendStateExt.getSrcColorIndexed(0);
2754             break;
2755         case GL_BLEND_SRC_ALPHA:
2756             *params = mBlendStateExt.getSrcAlphaIndexed(0);
2757             break;
2758         case GL_BLEND_DST_RGB:
2759             *params = mBlendStateExt.getDstColorIndexed(0);
2760             break;
2761         case GL_BLEND_DST_ALPHA:
2762             *params = mBlendStateExt.getDstAlphaIndexed(0);
2763             break;
2764         case GL_BLEND_EQUATION_RGB:
2765             *params = mBlendStateExt.getEquationColorIndexed(0);
2766             break;
2767         case GL_BLEND_EQUATION_ALPHA:
2768             *params = mBlendStateExt.getEquationAlphaIndexed(0);
2769             break;
2770         case GL_STENCIL_WRITEMASK:
2771             *params = CastMaskValue(mDepthStencil.stencilWritemask);
2772             break;
2773         case GL_STENCIL_BACK_WRITEMASK:
2774             *params = CastMaskValue(mDepthStencil.stencilBackWritemask);
2775             break;
2776         case GL_STENCIL_CLEAR_VALUE:
2777             *params = mStencilClearValue;
2778             break;
2779         case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2780             *params = mReadFramebuffer->getImplementationColorReadType(context);
2781             break;
2782         case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
2783             *params = mReadFramebuffer->getImplementationColorReadFormat(context);
2784             break;
2785         case GL_SAMPLE_BUFFERS:
2786         case GL_SAMPLES:
2787         {
2788             Framebuffer *framebuffer = mDrawFramebuffer;
2789             if (framebuffer->isComplete(context))
2790             {
2791                 GLint samples = framebuffer->getSamples(context);
2792                 switch (pname)
2793                 {
2794                     case GL_SAMPLE_BUFFERS:
2795                         if (samples != 0)
2796                         {
2797                             *params = 1;
2798                         }
2799                         else
2800                         {
2801                             *params = 0;
2802                         }
2803                         break;
2804                     case GL_SAMPLES:
2805                         *params = samples;
2806                         break;
2807                 }
2808             }
2809             else
2810             {
2811                 *params = 0;
2812             }
2813         }
2814         break;
2815         case GL_VIEWPORT:
2816             params[0] = mViewport.x;
2817             params[1] = mViewport.y;
2818             params[2] = mViewport.width;
2819             params[3] = mViewport.height;
2820             break;
2821         case GL_SCISSOR_BOX:
2822             params[0] = mScissor.x;
2823             params[1] = mScissor.y;
2824             params[2] = mScissor.width;
2825             params[3] = mScissor.height;
2826             break;
2827         case GL_CULL_FACE_MODE:
2828             *params = ToGLenum(mRasterizer.cullMode);
2829             break;
2830         case GL_FRONT_FACE:
2831             *params = mRasterizer.frontFace;
2832             break;
2833         case GL_RED_BITS:
2834         case GL_GREEN_BITS:
2835         case GL_BLUE_BITS:
2836         case GL_ALPHA_BITS:
2837         {
2838             Framebuffer *framebuffer                 = getDrawFramebuffer();
2839             const FramebufferAttachment *colorbuffer = framebuffer->getFirstColorAttachment();
2840 
2841             if (colorbuffer)
2842             {
2843                 switch (pname)
2844                 {
2845                     case GL_RED_BITS:
2846                         *params = colorbuffer->getRedSize();
2847                         break;
2848                     case GL_GREEN_BITS:
2849                         *params = colorbuffer->getGreenSize();
2850                         break;
2851                     case GL_BLUE_BITS:
2852                         *params = colorbuffer->getBlueSize();
2853                         break;
2854                     case GL_ALPHA_BITS:
2855                         *params = colorbuffer->getAlphaSize();
2856                         break;
2857                 }
2858             }
2859             else
2860             {
2861                 *params = 0;
2862             }
2863         }
2864         break;
2865         case GL_DEPTH_BITS:
2866         {
2867             const Framebuffer *framebuffer           = getDrawFramebuffer();
2868             const FramebufferAttachment *depthbuffer = framebuffer->getDepthAttachment();
2869 
2870             if (depthbuffer)
2871             {
2872                 *params = depthbuffer->getDepthSize();
2873             }
2874             else
2875             {
2876                 *params = 0;
2877             }
2878         }
2879         break;
2880         case GL_STENCIL_BITS:
2881         {
2882             const Framebuffer *framebuffer             = getDrawFramebuffer();
2883             const FramebufferAttachment *stencilbuffer = framebuffer->getStencilAttachment();
2884 
2885             if (stencilbuffer)
2886             {
2887                 *params = stencilbuffer->getStencilSize();
2888             }
2889             else
2890             {
2891                 *params = 0;
2892             }
2893         }
2894         break;
2895         case GL_TEXTURE_BINDING_2D:
2896             ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2897             *params =
2898                 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::_2D)
2899                     .value;
2900             break;
2901         case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
2902             ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2903             *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2904                                           TextureType::Rectangle)
2905                           .value;
2906             break;
2907         case GL_TEXTURE_BINDING_CUBE_MAP:
2908             ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2909             *params =
2910                 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::CubeMap)
2911                     .value;
2912             break;
2913         case GL_TEXTURE_BINDING_3D:
2914             ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2915             *params =
2916                 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::_3D)
2917                     .value;
2918             break;
2919         case GL_TEXTURE_BINDING_2D_ARRAY:
2920             ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2921             *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2922                                           TextureType::_2DArray)
2923                           .value;
2924             break;
2925         case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
2926             ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2927             *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2928                                           TextureType::_2DMultisample)
2929                           .value;
2930             break;
2931         case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
2932             ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2933             *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2934                                           TextureType::_2DMultisampleArray)
2935                           .value;
2936             break;
2937         case GL_TEXTURE_BINDING_CUBE_MAP_ARRAY:
2938             ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2939             *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2940                                           TextureType::CubeMapArray)
2941                           .value;
2942             break;
2943         case GL_TEXTURE_BINDING_EXTERNAL_OES:
2944             ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2945             *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2946                                           TextureType::External)
2947                           .value;
2948             break;
2949 
2950         // GL_OES_texture_buffer
2951         case GL_TEXTURE_BINDING_BUFFER:
2952             ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2953             *params =
2954                 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::Buffer)
2955                     .value;
2956             break;
2957         case GL_TEXTURE_BUFFER_BINDING:
2958             *params = mBoundBuffers[BufferBinding::Texture].id().value;
2959             break;
2960 
2961         case GL_UNIFORM_BUFFER_BINDING:
2962             *params = mBoundBuffers[BufferBinding::Uniform].id().value;
2963             break;
2964         case GL_TRANSFORM_FEEDBACK_BINDING:
2965             *params = mTransformFeedback.id().value;
2966             break;
2967         case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2968             *params = mBoundBuffers[BufferBinding::TransformFeedback].id().value;
2969             break;
2970         case GL_COPY_READ_BUFFER_BINDING:
2971             *params = mBoundBuffers[BufferBinding::CopyRead].id().value;
2972             break;
2973         case GL_COPY_WRITE_BUFFER_BINDING:
2974             *params = mBoundBuffers[BufferBinding::CopyWrite].id().value;
2975             break;
2976         case GL_PIXEL_PACK_BUFFER_BINDING:
2977             *params = mBoundBuffers[BufferBinding::PixelPack].id().value;
2978             break;
2979         case GL_PIXEL_UNPACK_BUFFER_BINDING:
2980             *params = mBoundBuffers[BufferBinding::PixelUnpack].id().value;
2981             break;
2982 
2983         case GL_READ_BUFFER:
2984             *params = mReadFramebuffer->getReadBufferState();
2985             break;
2986         case GL_SAMPLER_BINDING:
2987             ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2988             *params = getSamplerId(static_cast<GLuint>(mActiveSampler)).value;
2989             break;
2990         case GL_DEBUG_LOGGED_MESSAGES:
2991             *params = static_cast<GLint>(mDebug.getMessageCount());
2992             break;
2993         case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
2994             *params = static_cast<GLint>(mDebug.getNextMessageLength());
2995             break;
2996         case GL_DEBUG_GROUP_STACK_DEPTH:
2997             *params = static_cast<GLint>(mDebug.getGroupStackDepth());
2998             break;
2999         case GL_MULTISAMPLE_EXT:
3000             *params = static_cast<GLint>(mMultiSampling);
3001             break;
3002         case GL_SAMPLE_ALPHA_TO_ONE_EXT:
3003             *params = static_cast<GLint>(mSampleAlphaToOne);
3004             break;
3005         case GL_COVERAGE_MODULATION_CHROMIUM:
3006             *params = static_cast<GLint>(mCoverageModulation);
3007             break;
3008         case GL_ATOMIC_COUNTER_BUFFER_BINDING:
3009             *params = mBoundBuffers[BufferBinding::AtomicCounter].id().value;
3010             break;
3011         case GL_SHADER_STORAGE_BUFFER_BINDING:
3012             *params = mBoundBuffers[BufferBinding::ShaderStorage].id().value;
3013             break;
3014         case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
3015             *params = mBoundBuffers[BufferBinding::DispatchIndirect].id().value;
3016             break;
3017         case GL_ALPHA_TEST_FUNC:
3018             *params = ToGLenum(mGLES1State.mAlphaTestFunc);
3019             break;
3020         case GL_CLIENT_ACTIVE_TEXTURE:
3021             *params = mGLES1State.mClientActiveTexture + GL_TEXTURE0;
3022             break;
3023         case GL_MATRIX_MODE:
3024             *params = ToGLenum(mGLES1State.mMatrixMode);
3025             break;
3026         case GL_SHADE_MODEL:
3027             *params = ToGLenum(mGLES1State.mShadeModel);
3028             break;
3029         case GL_MODELVIEW_STACK_DEPTH:
3030         case GL_PROJECTION_STACK_DEPTH:
3031         case GL_TEXTURE_STACK_DEPTH:
3032             *params = mGLES1State.getCurrentMatrixStackDepth(pname);
3033             break;
3034         case GL_LOGIC_OP_MODE:
3035             *params = ToGLenum(mGLES1State.mLogicOp);
3036             break;
3037         case GL_BLEND_SRC:
3038             // non-indexed get returns the state of draw buffer zero
3039             *params = mBlendStateExt.getSrcColorIndexed(0);
3040             break;
3041         case GL_BLEND_DST:
3042             *params = mBlendStateExt.getDstColorIndexed(0);
3043             break;
3044         case GL_PERSPECTIVE_CORRECTION_HINT:
3045         case GL_POINT_SMOOTH_HINT:
3046         case GL_LINE_SMOOTH_HINT:
3047         case GL_FOG_HINT:
3048             *params = mGLES1State.getHint(pname);
3049             break;
3050 
3051         // GL_ANGLE_provoking_vertex
3052         case GL_PROVOKING_VERTEX:
3053             *params = ToGLenum(mProvokingVertex);
3054             break;
3055 
3056         case GL_PROGRAM_PIPELINE_BINDING:
3057         {
3058             ProgramPipeline *pipeline = getProgramPipeline();
3059             if (pipeline)
3060             {
3061                 *params = pipeline->id().value;
3062             }
3063             else
3064             {
3065                 *params = 0;
3066             }
3067             break;
3068         }
3069         case GL_PATCH_VERTICES:
3070             *params = mPatchVertices;
3071             break;
3072 
3073         // GL_EXT_clip_control
3074         case GL_CLIP_ORIGIN_EXT:
3075             *params = mClipControlOrigin;
3076             break;
3077         case GL_CLIP_DEPTH_MODE_EXT:
3078             *params = mClipControlDepth;
3079             break;
3080         default:
3081             UNREACHABLE();
3082             break;
3083     }
3084 
3085     return angle::Result::Continue;
3086 }
3087 
getPointerv(const Context * context,GLenum pname,void ** params) const3088 void State::getPointerv(const Context *context, GLenum pname, void **params) const
3089 {
3090     switch (pname)
3091     {
3092         case GL_DEBUG_CALLBACK_FUNCTION:
3093             *params = reinterpret_cast<void *>(mDebug.getCallback());
3094             break;
3095         case GL_DEBUG_CALLBACK_USER_PARAM:
3096             *params = const_cast<void *>(mDebug.getUserParam());
3097             break;
3098         case GL_VERTEX_ARRAY_POINTER:
3099         case GL_NORMAL_ARRAY_POINTER:
3100         case GL_COLOR_ARRAY_POINTER:
3101         case GL_TEXTURE_COORD_ARRAY_POINTER:
3102         case GL_POINT_SIZE_ARRAY_POINTER_OES:
3103             QueryVertexAttribPointerv(getVertexArray()->getVertexAttribute(
3104                                           context->vertexArrayIndex(ParamToVertexArrayType(pname))),
3105                                       GL_VERTEX_ATTRIB_ARRAY_POINTER, params);
3106             return;
3107         default:
3108             UNREACHABLE();
3109             break;
3110     }
3111 }
3112 
getIntegeri_v(GLenum target,GLuint index,GLint * data) const3113 void State::getIntegeri_v(GLenum target, GLuint index, GLint *data) const
3114 {
3115     switch (target)
3116     {
3117         case GL_BLEND_SRC_RGB:
3118             ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3119             *data = mBlendStateExt.getSrcColorIndexed(index);
3120             break;
3121         case GL_BLEND_SRC_ALPHA:
3122             ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3123             *data = mBlendStateExt.getSrcAlphaIndexed(index);
3124             break;
3125         case GL_BLEND_DST_RGB:
3126             ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3127             *data = mBlendStateExt.getDstColorIndexed(index);
3128             break;
3129         case GL_BLEND_DST_ALPHA:
3130             ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3131             *data = mBlendStateExt.getDstAlphaIndexed(index);
3132             break;
3133         case GL_BLEND_EQUATION_RGB:
3134             ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3135             *data = mBlendStateExt.getEquationColorIndexed(index);
3136             break;
3137         case GL_BLEND_EQUATION_ALPHA:
3138             ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3139             *data = mBlendStateExt.getEquationAlphaIndexed(index);
3140             break;
3141         case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
3142             ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
3143             *data = mTransformFeedback->getIndexedBuffer(index).id().value;
3144             break;
3145         case GL_UNIFORM_BUFFER_BINDING:
3146             ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
3147             *data = mUniformBuffers[index].id().value;
3148             break;
3149         case GL_ATOMIC_COUNTER_BUFFER_BINDING:
3150             ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
3151             *data = mAtomicCounterBuffers[index].id().value;
3152             break;
3153         case GL_SHADER_STORAGE_BUFFER_BINDING:
3154             ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
3155             *data = mShaderStorageBuffers[index].id().value;
3156             break;
3157         case GL_VERTEX_BINDING_BUFFER:
3158             ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
3159             *data = mVertexArray->getVertexBinding(index).getBuffer().id().value;
3160             break;
3161         case GL_VERTEX_BINDING_DIVISOR:
3162             ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
3163             *data = mVertexArray->getVertexBinding(index).getDivisor();
3164             break;
3165         case GL_VERTEX_BINDING_OFFSET:
3166             ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
3167             *data = static_cast<GLuint>(mVertexArray->getVertexBinding(index).getOffset());
3168             break;
3169         case GL_VERTEX_BINDING_STRIDE:
3170             ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
3171             *data = mVertexArray->getVertexBinding(index).getStride();
3172             break;
3173         case GL_SAMPLE_MASK_VALUE:
3174             ASSERT(static_cast<size_t>(index) < mSampleMaskValues.size());
3175             *data = mSampleMaskValues[index];
3176             break;
3177         case GL_IMAGE_BINDING_NAME:
3178             ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3179             *data = mImageUnits[index].texture.id().value;
3180             break;
3181         case GL_IMAGE_BINDING_LEVEL:
3182             ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3183             *data = mImageUnits[index].level;
3184             break;
3185         case GL_IMAGE_BINDING_LAYER:
3186             ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3187             *data = mImageUnits[index].layer;
3188             break;
3189         case GL_IMAGE_BINDING_ACCESS:
3190             ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3191             *data = mImageUnits[index].access;
3192             break;
3193         case GL_IMAGE_BINDING_FORMAT:
3194             ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3195             *data = mImageUnits[index].format;
3196             break;
3197         default:
3198             UNREACHABLE();
3199             break;
3200     }
3201 }
3202 
getInteger64i_v(GLenum target,GLuint index,GLint64 * data) const3203 void State::getInteger64i_v(GLenum target, GLuint index, GLint64 *data) const
3204 {
3205     switch (target)
3206     {
3207         case GL_TRANSFORM_FEEDBACK_BUFFER_START:
3208             ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
3209             *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
3210             break;
3211         case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
3212             ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
3213             *data = mTransformFeedback->getIndexedBuffer(index).getSize();
3214             break;
3215         case GL_UNIFORM_BUFFER_START:
3216             ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
3217             *data = mUniformBuffers[index].getOffset();
3218             break;
3219         case GL_UNIFORM_BUFFER_SIZE:
3220             ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
3221             *data = mUniformBuffers[index].getSize();
3222             break;
3223         case GL_ATOMIC_COUNTER_BUFFER_START:
3224             ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
3225             *data = mAtomicCounterBuffers[index].getOffset();
3226             break;
3227         case GL_ATOMIC_COUNTER_BUFFER_SIZE:
3228             ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
3229             *data = mAtomicCounterBuffers[index].getSize();
3230             break;
3231         case GL_SHADER_STORAGE_BUFFER_START:
3232             ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
3233             *data = mShaderStorageBuffers[index].getOffset();
3234             break;
3235         case GL_SHADER_STORAGE_BUFFER_SIZE:
3236             ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
3237             *data = mShaderStorageBuffers[index].getSize();
3238             break;
3239         default:
3240             UNREACHABLE();
3241             break;
3242     }
3243 }
3244 
getBooleani_v(GLenum target,GLuint index,GLboolean * data) const3245 void State::getBooleani_v(GLenum target, GLuint index, GLboolean *data) const
3246 {
3247     switch (target)
3248     {
3249         case GL_COLOR_WRITEMASK:
3250         {
3251             ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3252             bool r, g, b, a;
3253             mBlendStateExt.getColorMaskIndexed(index, &r, &g, &b, &a);
3254             data[0] = r;
3255             data[1] = g;
3256             data[2] = b;
3257             data[3] = a;
3258             break;
3259         }
3260         case GL_IMAGE_BINDING_LAYERED:
3261             ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3262             *data = mImageUnits[index].layered;
3263             break;
3264         default:
3265             UNREACHABLE();
3266             break;
3267     }
3268 }
3269 
3270 // TODO(http://anglebug.com/3889): Remove this helper function after blink and chromium part
3271 // refactor done.
getTextureForActiveSampler(TextureType type,size_t index)3272 Texture *State::getTextureForActiveSampler(TextureType type, size_t index)
3273 {
3274     if (type != TextureType::VideoImage)
3275     {
3276         return mSamplerTextures[type][index].get();
3277     }
3278 
3279     ASSERT(type == TextureType::VideoImage);
3280 
3281     Texture *candidateTexture = mSamplerTextures[type][index].get();
3282     if (candidateTexture->getWidth(TextureTarget::VideoImage, 0) == 0 ||
3283         candidateTexture->getHeight(TextureTarget::VideoImage, 0) == 0 ||
3284         candidateTexture->getDepth(TextureTarget::VideoImage, 0) == 0)
3285     {
3286         return mSamplerTextures[TextureType::_2D][index].get();
3287     }
3288 
3289     return mSamplerTextures[type][index].get();
3290 }
3291 
syncActiveTextures(const Context * context,Command command)3292 angle::Result State::syncActiveTextures(const Context *context, Command command)
3293 {
3294     if (mDirtyActiveTextures.none())
3295     {
3296         return angle::Result::Continue;
3297     }
3298 
3299     for (size_t textureUnit : mDirtyActiveTextures)
3300     {
3301         if (mExecutable)
3302         {
3303             TextureType type       = mExecutable->getActiveSamplerTypes()[textureUnit];
3304             Texture *activeTexture = (type != TextureType::InvalidEnum)
3305                                          ? getTextureForActiveSampler(type, textureUnit)
3306                                          : nullptr;
3307             const Sampler *sampler = mSamplers[textureUnit].get();
3308 
3309             updateActiveTextureStateOnSync(context, textureUnit, sampler, activeTexture);
3310         }
3311     }
3312 
3313     mDirtyActiveTextures.reset();
3314     return angle::Result::Continue;
3315 }
3316 
syncTexturesInit(const Context * context,Command command)3317 angle::Result State::syncTexturesInit(const Context *context, Command command)
3318 {
3319     ASSERT(mRobustResourceInit);
3320 
3321     if (!mProgram)
3322         return angle::Result::Continue;
3323 
3324     for (size_t textureUnitIndex : mExecutable->getActiveSamplersMask())
3325     {
3326         Texture *texture = mActiveTexturesCache[textureUnitIndex];
3327         if (texture)
3328         {
3329             ANGLE_TRY(texture->ensureInitialized(context));
3330         }
3331     }
3332     return angle::Result::Continue;
3333 }
3334 
syncImagesInit(const Context * context,Command command)3335 angle::Result State::syncImagesInit(const Context *context, Command command)
3336 {
3337     ASSERT(mRobustResourceInit);
3338     ASSERT(mExecutable);
3339     for (size_t imageUnitIndex : mExecutable->getActiveImagesMask())
3340     {
3341         Texture *texture = mImageUnits[imageUnitIndex].texture.get();
3342         if (texture)
3343         {
3344             ANGLE_TRY(texture->ensureInitialized(context));
3345         }
3346     }
3347     return angle::Result::Continue;
3348 }
3349 
syncReadAttachments(const Context * context,Command command)3350 angle::Result State::syncReadAttachments(const Context *context, Command command)
3351 {
3352     ASSERT(mReadFramebuffer);
3353     ASSERT(mRobustResourceInit);
3354     return mReadFramebuffer->ensureReadAttachmentsInitialized(context);
3355 }
3356 
syncDrawAttachments(const Context * context,Command command)3357 angle::Result State::syncDrawAttachments(const Context *context, Command command)
3358 {
3359     ASSERT(mDrawFramebuffer);
3360     ASSERT(mRobustResourceInit);
3361     return mDrawFramebuffer->ensureDrawAttachmentsInitialized(context);
3362 }
3363 
syncReadFramebuffer(const Context * context,Command command)3364 angle::Result State::syncReadFramebuffer(const Context *context, Command command)
3365 {
3366     ASSERT(mReadFramebuffer);
3367     return mReadFramebuffer->syncState(context, GL_READ_FRAMEBUFFER, command);
3368 }
3369 
syncDrawFramebuffer(const Context * context,Command command)3370 angle::Result State::syncDrawFramebuffer(const Context *context, Command command)
3371 {
3372     ASSERT(mDrawFramebuffer);
3373     mDrawFramebuffer->setWriteControlMode(context->getState().getFramebufferSRGB()
3374                                               ? SrgbWriteControlMode::Default
3375                                               : SrgbWriteControlMode::Linear);
3376     return mDrawFramebuffer->syncState(context, GL_DRAW_FRAMEBUFFER, command);
3377 }
3378 
syncTextures(const Context * context,Command command)3379 angle::Result State::syncTextures(const Context *context, Command command)
3380 {
3381     if (mDirtyTextures.none())
3382         return angle::Result::Continue;
3383 
3384     for (size_t textureIndex : mDirtyTextures)
3385     {
3386         Texture *texture = mActiveTexturesCache[textureIndex];
3387         if (texture && texture->hasAnyDirtyBit())
3388         {
3389             ANGLE_TRY(texture->syncState(context, Command::Other));
3390         }
3391     }
3392 
3393     mDirtyTextures.reset();
3394     return angle::Result::Continue;
3395 }
3396 
syncImages(const Context * context,Command command)3397 angle::Result State::syncImages(const Context *context, Command command)
3398 {
3399     if (mDirtyImages.none())
3400         return angle::Result::Continue;
3401 
3402     for (size_t imageUnitIndex : mDirtyImages)
3403     {
3404         Texture *texture = mImageUnits[imageUnitIndex].texture.get();
3405         if (texture && texture->hasAnyDirtyBit())
3406         {
3407             ANGLE_TRY(texture->syncState(context, Command::Other));
3408         }
3409     }
3410 
3411     mDirtyImages.reset();
3412     return angle::Result::Continue;
3413 }
3414 
syncSamplers(const Context * context,Command command)3415 angle::Result State::syncSamplers(const Context *context, Command command)
3416 {
3417     if (mDirtySamplers.none())
3418         return angle::Result::Continue;
3419 
3420     for (size_t samplerIndex : mDirtySamplers)
3421     {
3422         BindingPointer<Sampler> &sampler = mSamplers[samplerIndex];
3423         if (sampler.get() && sampler->isDirty())
3424         {
3425             ANGLE_TRY(sampler->syncState(context));
3426         }
3427     }
3428 
3429     mDirtySamplers.reset();
3430 
3431     return angle::Result::Continue;
3432 }
3433 
syncVertexArray(const Context * context,Command command)3434 angle::Result State::syncVertexArray(const Context *context, Command command)
3435 {
3436     ASSERT(mVertexArray);
3437     return mVertexArray->syncState(context);
3438 }
3439 
syncProgram(const Context * context,Command command)3440 angle::Result State::syncProgram(const Context *context, Command command)
3441 {
3442     // There may not be a program if the calling application only uses program pipelines.
3443     if (mProgram)
3444     {
3445         return mProgram->syncState(context);
3446     }
3447     return angle::Result::Continue;
3448 }
3449 
syncDirtyObject(const Context * context,GLenum target)3450 angle::Result State::syncDirtyObject(const Context *context, GLenum target)
3451 {
3452     DirtyObjects localSet;
3453 
3454     switch (target)
3455     {
3456         case GL_READ_FRAMEBUFFER:
3457             localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
3458             break;
3459         case GL_DRAW_FRAMEBUFFER:
3460             localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
3461             break;
3462         case GL_FRAMEBUFFER:
3463             localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
3464             localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
3465             break;
3466         case GL_VERTEX_ARRAY:
3467             localSet.set(DIRTY_OBJECT_VERTEX_ARRAY);
3468             break;
3469         case GL_TEXTURE:
3470             localSet.set(DIRTY_OBJECT_TEXTURES);
3471             break;
3472         case GL_SAMPLER:
3473             localSet.set(DIRTY_OBJECT_SAMPLERS);
3474             break;
3475         case GL_PROGRAM:
3476             localSet.set(DIRTY_OBJECT_PROGRAM);
3477             break;
3478     }
3479 
3480     return syncDirtyObjects(context, localSet, Command::Other);
3481 }
3482 
setObjectDirty(GLenum target)3483 void State::setObjectDirty(GLenum target)
3484 {
3485     switch (target)
3486     {
3487         case GL_READ_FRAMEBUFFER:
3488             mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
3489             break;
3490         case GL_DRAW_FRAMEBUFFER:
3491             setDrawFramebufferDirty();
3492             break;
3493         case GL_FRAMEBUFFER:
3494             mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
3495             setDrawFramebufferDirty();
3496             break;
3497         case GL_VERTEX_ARRAY:
3498             mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
3499             break;
3500         case GL_PROGRAM:
3501             mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
3502             break;
3503         default:
3504             break;
3505     }
3506 }
3507 
onProgramExecutableChange(const Context * context,Program * program)3508 angle::Result State::onProgramExecutableChange(const Context *context, Program *program)
3509 {
3510     // OpenGL Spec:
3511     // "If LinkProgram or ProgramBinary successfully re-links a program object
3512     //  that was already in use as a result of a previous call to UseProgram, then the
3513     //  generated executable code will be installed as part of the current rendering state."
3514     ASSERT(program->isLinked());
3515 
3516     // If this Program is currently active, we need to update the State's pointer to the current
3517     // ProgramExecutable if we just changed it.
3518     if (mProgram == program)
3519     {
3520         mExecutable = &program->getExecutable();
3521     }
3522 
3523     mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE);
3524 
3525     if (program->hasAnyDirtyBit())
3526     {
3527         mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
3528     }
3529 
3530     // Set any bound textures.
3531     const ProgramExecutable &executable        = program->getExecutable();
3532     const ActiveTextureTypeArray &textureTypes = executable.getActiveSamplerTypes();
3533     for (size_t textureIndex : executable.getActiveSamplersMask())
3534     {
3535         TextureType type = textureTypes[textureIndex];
3536 
3537         // This can happen if there is a conflicting texture type.
3538         if (type == TextureType::InvalidEnum)
3539             continue;
3540 
3541         Texture *texture = getTextureForActiveSampler(type, textureIndex);
3542         updateTextureBinding(context, textureIndex, texture);
3543     }
3544 
3545     for (size_t imageUnitIndex : executable.getActiveImagesMask())
3546     {
3547         Texture *image = mImageUnits[imageUnitIndex].texture.get();
3548         if (!image)
3549             continue;
3550 
3551         if (image->hasAnyDirtyBit())
3552         {
3553             ANGLE_TRY(image->syncState(context, Command::Other));
3554         }
3555 
3556         if (mRobustResourceInit && image->initState() == InitState::MayNeedInit)
3557         {
3558             mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT);
3559         }
3560     }
3561 
3562     return angle::Result::Continue;
3563 }
3564 
onProgramPipelineExecutableChange(const Context * context)3565 angle::Result State::onProgramPipelineExecutableChange(const Context *context)
3566 {
3567     mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE);
3568 
3569     // Set any bound textures.
3570     const ProgramExecutable &executable        = mProgramPipeline->getExecutable();
3571     const ActiveTextureTypeArray &textureTypes = executable.getActiveSamplerTypes();
3572 
3573     for (size_t textureIndex : executable.getActiveSamplersMask())
3574     {
3575         TextureType type = textureTypes[textureIndex];
3576 
3577         // This can happen if there is a conflicting texture type.
3578         if (type == TextureType::InvalidEnum)
3579             continue;
3580 
3581         Texture *texture = getTextureForActiveSampler(type, textureIndex);
3582         updateTextureBinding(context, textureIndex, texture);
3583     }
3584 
3585     for (size_t imageUnitIndex : executable.getActiveImagesMask())
3586     {
3587         Texture *image = mImageUnits[imageUnitIndex].texture.get();
3588         if (!image)
3589             continue;
3590 
3591         if (image->hasAnyDirtyBit())
3592         {
3593             ANGLE_TRY(image->syncState(context, Command::Other));
3594         }
3595 
3596         if (mRobustResourceInit && image->initState() == InitState::MayNeedInit)
3597         {
3598             mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT);
3599         }
3600     }
3601 
3602     return angle::Result::Continue;
3603 }
3604 
setTextureDirty(size_t textureUnitIndex)3605 void State::setTextureDirty(size_t textureUnitIndex)
3606 {
3607     mDirtyObjects.set(DIRTY_OBJECT_TEXTURES);
3608     mDirtyTextures.set(textureUnitIndex);
3609 }
3610 
setSamplerDirty(size_t samplerIndex)3611 void State::setSamplerDirty(size_t samplerIndex)
3612 {
3613     mDirtyObjects.set(DIRTY_OBJECT_SAMPLERS);
3614     mDirtySamplers.set(samplerIndex);
3615 }
3616 
setImageUnit(const Context * context,size_t unit,Texture * texture,GLint level,GLboolean layered,GLint layer,GLenum access,GLenum format)3617 void State::setImageUnit(const Context *context,
3618                          size_t unit,
3619                          Texture *texture,
3620                          GLint level,
3621                          GLboolean layered,
3622                          GLint layer,
3623                          GLenum access,
3624                          GLenum format)
3625 {
3626     ASSERT(!mImageUnits.empty());
3627 
3628     ImageUnit &imageUnit = mImageUnits[unit];
3629 
3630     if (texture)
3631     {
3632         texture->onBindAsImageTexture();
3633     }
3634     imageUnit.texture.set(context, texture);
3635     imageUnit.level   = level;
3636     imageUnit.layered = layered;
3637     imageUnit.layer   = layer;
3638     imageUnit.access  = access;
3639     imageUnit.format  = format;
3640     mDirtyBits.set(DIRTY_BIT_IMAGE_BINDINGS);
3641 
3642     onImageStateChange(context, unit);
3643 }
3644 
3645 // Handle a dirty texture event.
onActiveTextureChange(const Context * context,size_t textureUnit)3646 void State::onActiveTextureChange(const Context *context, size_t textureUnit)
3647 {
3648     if (mExecutable)
3649     {
3650         TextureType type       = mExecutable->getActiveSamplerTypes()[textureUnit];
3651         Texture *activeTexture = (type != TextureType::InvalidEnum)
3652                                      ? getTextureForActiveSampler(type, textureUnit)
3653                                      : nullptr;
3654         updateTextureBinding(context, textureUnit, activeTexture);
3655 
3656         mExecutable->onStateChange(angle::SubjectMessage::ProgramTextureOrImageBindingChanged);
3657     }
3658 }
3659 
onActiveTextureStateChange(const Context * context,size_t textureUnit)3660 void State::onActiveTextureStateChange(const Context *context, size_t textureUnit)
3661 {
3662     if (mExecutable)
3663     {
3664         TextureType type       = mExecutable->getActiveSamplerTypes()[textureUnit];
3665         Texture *activeTexture = (type != TextureType::InvalidEnum)
3666                                      ? getTextureForActiveSampler(type, textureUnit)
3667                                      : nullptr;
3668         setActiveTextureDirty(textureUnit, activeTexture);
3669     }
3670 }
3671 
onImageStateChange(const Context * context,size_t unit)3672 void State::onImageStateChange(const Context *context, size_t unit)
3673 {
3674     if (mExecutable)
3675     {
3676         const ImageUnit &image = mImageUnits[unit];
3677 
3678         // Have nothing to do here if no texture bound
3679         if (!image.texture.get())
3680             return;
3681 
3682         if (image.texture->hasAnyDirtyBit())
3683         {
3684             mDirtyImages.set(unit);
3685             mDirtyObjects.set(DIRTY_OBJECT_IMAGES);
3686         }
3687 
3688         if (mRobustResourceInit && image.texture->initState() == InitState::MayNeedInit)
3689         {
3690             mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT);
3691         }
3692 
3693         mExecutable->onStateChange(angle::SubjectMessage::ProgramTextureOrImageBindingChanged);
3694     }
3695 }
3696 
onUniformBufferStateChange(size_t uniformBufferIndex)3697 void State::onUniformBufferStateChange(size_t uniformBufferIndex)
3698 {
3699     // This could be represented by a different dirty bit. Using the same one keeps it simple.
3700     mDirtyBits.set(DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
3701 }
3702 
onAtomicCounterBufferStateChange(size_t atomicCounterBufferIndex)3703 void State::onAtomicCounterBufferStateChange(size_t atomicCounterBufferIndex)
3704 {
3705     mDirtyBits.set(DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING);
3706 }
3707 
onShaderStorageBufferStateChange(size_t shaderStorageBufferIndex)3708 void State::onShaderStorageBufferStateChange(size_t shaderStorageBufferIndex)
3709 {
3710     mDirtyBits.set(DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING);
3711 }
3712 
getAndResetDirtyCurrentValues() const3713 AttributesMask State::getAndResetDirtyCurrentValues() const
3714 {
3715     AttributesMask retVal = mDirtyCurrentValues;
3716     mDirtyCurrentValues.reset();
3717     return retVal;
3718 }
3719 
getAndResetExtendedDirtyBits() const3720 State::ExtendedDirtyBits State::getAndResetExtendedDirtyBits() const
3721 {
3722     ExtendedDirtyBits retVal = mExtendedDirtyBits;
3723     mExtendedDirtyBits.reset();
3724     return retVal;
3725 }
3726 
initializeForCapture(const Context * context)3727 void State::initializeForCapture(const Context *context)
3728 {
3729     mCaps       = context->getCaps();
3730     mExtensions = context->getExtensions();
3731 
3732     // This little kludge gets around the frame capture "constness". It should be safe because
3733     // nothing in the context is modified in a non-compatible way during capture.
3734     Context *mutableContext = const_cast<Context *>(context);
3735     initialize(mutableContext);
3736 }
3737 
3738 constexpr State::DirtyObjectHandler State::kDirtyObjectHandlers[DIRTY_OBJECT_MAX];
3739 
3740 }  // namespace gl
3741