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