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