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