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