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