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.h: Defines the State class, encapsulating raw GL state
8 
9 #ifndef LIBANGLE_STATE_H_
10 #define LIBANGLE_STATE_H_
11 
12 #include <bitset>
13 #include <memory>
14 
15 #include "common/Color.h"
16 #include "common/angleutils.h"
17 #include "common/bitset_utils.h"
18 #include "libANGLE/Debug.h"
19 #include "libANGLE/GLES1State.h"
20 #include "libANGLE/Overlay.h"
21 #include "libANGLE/Program.h"
22 #include "libANGLE/ProgramExecutable.h"
23 #include "libANGLE/ProgramPipeline.h"
24 #include "libANGLE/RefCountObject.h"
25 #include "libANGLE/Renderbuffer.h"
26 #include "libANGLE/Sampler.h"
27 #include "libANGLE/Texture.h"
28 #include "libANGLE/TransformFeedback.h"
29 #include "libANGLE/Version.h"
30 #include "libANGLE/VertexArray.h"
31 #include "libANGLE/angletypes.h"
32 
33 namespace egl
34 {
35 class ShareGroup;
36 }  // namespace egl
37 
38 namespace gl
39 {
40 class BufferManager;
41 struct Caps;
42 class Context;
43 class FramebufferManager;
44 class MemoryObjectManager;
45 class ProgramPipelineManager;
46 class Query;
47 class RenderbufferManager;
48 class SamplerManager;
49 class SemaphoreManager;
50 class ShaderProgramManager;
51 class SyncManager;
52 class TextureManager;
53 class VertexArray;
54 
55 static constexpr Version ES_1_0 = Version(1, 0);
56 static constexpr Version ES_1_1 = Version(1, 1);
57 static constexpr Version ES_2_0 = Version(2, 0);
58 static constexpr Version ES_3_0 = Version(3, 0);
59 static constexpr Version ES_3_1 = Version(3, 1);
60 static constexpr Version ES_3_2 = Version(3, 2);
61 
62 template <typename T>
63 using BufferBindingMap     = angle::PackedEnumMap<BufferBinding, T>;
64 using BoundBufferMap       = BufferBindingMap<BindingPointer<Buffer>>;
65 using SamplerBindingVector = std::vector<BindingPointer<Sampler>>;
66 using TextureBindingVector = std::vector<BindingPointer<Texture>>;
67 using TextureBindingMap    = angle::PackedEnumMap<TextureType, TextureBindingVector>;
68 using ActiveQueryMap       = angle::PackedEnumMap<QueryType, BindingPointer<Query>>;
69 using BufferVector         = std::vector<OffsetBindingPointer<Buffer>>;
70 
71 class ActiveTexturesCache final : angle::NonCopyable
72 {
73   public:
74     ActiveTexturesCache();
75     ~ActiveTexturesCache();
76 
77     Texture *operator[](size_t textureIndex) const { return mTextures[textureIndex]; }
78 
79     void clear();
80     void set(size_t textureIndex, Texture *texture);
81     void reset(size_t textureIndex);
82     bool empty() const;
83 
84   private:
85     ActiveTextureArray<Texture *> mTextures;
86 };
87 
88 class State : angle::NonCopyable
89 {
90   public:
91     State(const State *shareContextState,
92           egl::ShareGroup *shareGroup,
93           TextureManager *shareTextures,
94           SemaphoreManager *shareSemaphores,
95           const OverlayType *overlay,
96           const EGLenum clientType,
97           const Version &clientVersion,
98           bool debug,
99           bool bindGeneratesResource,
100           bool clientArraysEnabled,
101           bool robustResourceInit,
102           bool programBinaryCacheEnabled,
103           EGLenum contextPriority,
104           bool hasProtectedContent);
105     ~State();
106 
107     void initialize(Context *context);
108     void reset(const Context *context);
109 
110     // Getters
getContextID()111     ContextID getContextID() const { return mID; }
getClientType()112     EGLenum getClientType() const { return mClientType; }
getContextPriority()113     EGLenum getContextPriority() const { return mContextPriority; }
hasProtectedContent()114     bool hasProtectedContent() const { return mHasProtectedContent; }
getClientMajorVersion()115     GLint getClientMajorVersion() const { return mClientVersion.major; }
getClientMinorVersion()116     GLint getClientMinorVersion() const { return mClientVersion.minor; }
getClientVersion()117     const Version &getClientVersion() const { return mClientVersion; }
getCaps()118     const Caps &getCaps() const { return mCaps; }
getTextureCaps()119     const TextureCapsMap &getTextureCaps() const { return mTextureCaps; }
getExtensions()120     const Extensions &getExtensions() const { return mExtensions; }
getLimitations()121     const Limitations &getLimitations() const { return mLimitations; }
getShareGroup()122     egl::ShareGroup *getShareGroup() const { return mShareGroup; }
123 
isWebGL()124     bool isWebGL() const { return mExtensions.webglCompatibility; }
125 
isWebGL1()126     bool isWebGL1() const { return (isWebGL() && mClientVersion.major == 2); }
127 
getTextureCap(GLenum internalFormat)128     const TextureCaps &getTextureCap(GLenum internalFormat) const
129     {
130         return mTextureCaps.get(internalFormat);
131     }
132 
133     // State chunk getters
134     bool allActiveDrawBufferChannelsMasked() const;
135     bool anyActiveDrawBufferChannelMasked() const;
136     const RasterizerState &getRasterizerState() const;
getBlendState()137     const BlendState &getBlendState() const { return mBlendState; }
getBlendStateExt()138     const BlendStateExt &getBlendStateExt() const { return mBlendStateExt; }
139     const DepthStencilState &getDepthStencilState() const;
140 
141     // Clear behavior setters & state parameter block generation function
142     void setColorClearValue(float red, float green, float blue, float alpha);
143     void setDepthClearValue(float depth);
144     void setStencilClearValue(int stencil);
145 
getColorClearValue()146     const ColorF &getColorClearValue() const { return mColorClearValue; }
getDepthClearValue()147     float getDepthClearValue() const { return mDepthClearValue; }
getStencilClearValue()148     int getStencilClearValue() const { return mStencilClearValue; }
149 
150     // Write mask manipulation
151     void setColorMask(bool red, bool green, bool blue, bool alpha);
152     void setColorMaskIndexed(bool red, bool green, bool blue, bool alpha, GLuint index);
153     void setDepthMask(bool mask);
154 
155     // Discard toggle & query
isRasterizerDiscardEnabled()156     bool isRasterizerDiscardEnabled() const { return mRasterizer.rasterizerDiscard; }
157     void setRasterizerDiscard(bool enabled);
158 
159     // Primitive restart
isPrimitiveRestartEnabled()160     bool isPrimitiveRestartEnabled() const { return mPrimitiveRestart; }
161     void setPrimitiveRestart(bool enabled);
162 
163     // Face culling state manipulation
isCullFaceEnabled()164     bool isCullFaceEnabled() const { return mRasterizer.cullFace; }
165     void setCullFace(bool enabled);
166     void setCullMode(CullFaceMode mode);
167     void setFrontFace(GLenum front);
168 
169     // Depth test state manipulation
isDepthTestEnabled()170     bool isDepthTestEnabled() const { return mDepthStencil.depthTest; }
isDepthWriteEnabled()171     bool isDepthWriteEnabled() const { return mDepthStencil.depthTest && mDepthStencil.depthMask; }
172     void setDepthTest(bool enabled);
173     void setDepthFunc(GLenum depthFunc);
174     void setDepthRange(float zNear, float zFar);
getNearPlane()175     float getNearPlane() const { return mNearZ; }
getFarPlane()176     float getFarPlane() const { return mFarZ; }
177 
178     // Clip control extension
179     void setClipControl(GLenum origin, GLenum depth);
isClipControlDepthZeroToOne()180     bool isClipControlDepthZeroToOne() const { return mClipControlDepth == GL_ZERO_TO_ONE_EXT; }
getClipSpaceOrigin()181     gl::ClipSpaceOrigin getClipSpaceOrigin() const
182     {
183         return mClipControlOrigin == GL_UPPER_LEFT_EXT ? ClipSpaceOrigin::UpperLeft
184                                                        : ClipSpaceOrigin::LowerLeft;
185     }
186 
187     // Blend state manipulation
isBlendEnabled()188     bool isBlendEnabled() const { return mBlendStateExt.mEnabledMask.test(0); }
isBlendEnabledIndexed(GLuint index)189     bool isBlendEnabledIndexed(GLuint index) const
190     {
191         ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
192         return mBlendStateExt.mEnabledMask.test(index);
193     }
getBlendEnabledDrawBufferMask()194     DrawBufferMask getBlendEnabledDrawBufferMask() const { return mBlendStateExt.mEnabledMask; }
195     void setBlend(bool enabled);
196     void setBlendIndexed(bool enabled, GLuint index);
197     void setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha);
198     void setBlendFactorsIndexed(GLenum sourceRGB,
199                                 GLenum destRGB,
200                                 GLenum sourceAlpha,
201                                 GLenum destAlpha,
202                                 GLuint index);
203     void setBlendColor(float red, float green, float blue, float alpha);
204     void setBlendEquation(GLenum rgbEquation, GLenum alphaEquation);
205     void setBlendEquationIndexed(GLenum rgbEquation, GLenum alphaEquation, GLuint index);
getBlendColor()206     const ColorF &getBlendColor() const { return mBlendColor; }
207 
208     // Stencil state maniupulation
isStencilTestEnabled()209     bool isStencilTestEnabled() const { return mDepthStencil.stencilTest; }
210     void setStencilTest(bool enabled);
211     void setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask);
212     void setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask);
213     void setStencilWritemask(GLuint stencilWritemask);
214     void setStencilBackWritemask(GLuint stencilBackWritemask);
215     void setStencilOperations(GLenum stencilFail,
216                               GLenum stencilPassDepthFail,
217                               GLenum stencilPassDepthPass);
218     void setStencilBackOperations(GLenum stencilBackFail,
219                                   GLenum stencilBackPassDepthFail,
220                                   GLenum stencilBackPassDepthPass);
getStencilRef()221     GLint getStencilRef() const { return mStencilRef; }
getStencilBackRef()222     GLint getStencilBackRef() const { return mStencilBackRef; }
223 
224     // Depth bias/polygon offset state manipulation
isPolygonOffsetFillEnabled()225     bool isPolygonOffsetFillEnabled() const { return mRasterizer.polygonOffsetFill; }
226     void setPolygonOffsetFill(bool enabled);
227     void setPolygonOffsetParams(GLfloat factor, GLfloat units);
228 
229     // Multisample coverage state manipulation
isSampleAlphaToCoverageEnabled()230     bool isSampleAlphaToCoverageEnabled() const { return mSampleAlphaToCoverage; }
231     void setSampleAlphaToCoverage(bool enabled);
isSampleCoverageEnabled()232     bool isSampleCoverageEnabled() const { return mSampleCoverage; }
233     void setSampleCoverage(bool enabled);
234     void setSampleCoverageParams(GLclampf value, bool invert);
getSampleCoverageValue()235     GLclampf getSampleCoverageValue() const { return mSampleCoverageValue; }
getSampleCoverageInvert()236     bool getSampleCoverageInvert() const { return mSampleCoverageInvert; }
237 
238     // Multisample mask state manipulation.
isSampleMaskEnabled()239     bool isSampleMaskEnabled() const { return mSampleMask; }
240     void setSampleMaskEnabled(bool enabled);
241     void setSampleMaskParams(GLuint maskNumber, GLbitfield mask);
getSampleMaskWord(GLuint maskNumber)242     GLbitfield getSampleMaskWord(GLuint maskNumber) const
243     {
244         ASSERT(maskNumber < mMaxSampleMaskWords);
245         return mSampleMaskValues[maskNumber];
246     }
getSampleMaskValues()247     std::array<GLbitfield, MAX_SAMPLE_MASK_WORDS> getSampleMaskValues() const
248     {
249         return mSampleMaskValues;
250     }
getMaxSampleMaskWords()251     GLuint getMaxSampleMaskWords() const { return mMaxSampleMaskWords; }
252 
253     // Multisampling/alpha to one manipulation.
254     void setSampleAlphaToOne(bool enabled);
isSampleAlphaToOneEnabled()255     bool isSampleAlphaToOneEnabled() const { return mSampleAlphaToOne; }
256     void setMultisampling(bool enabled);
isMultisamplingEnabled()257     bool isMultisamplingEnabled() const { return mMultiSampling; }
258 
259     void setSampleShading(bool enabled);
isSampleShadingEnabled()260     bool isSampleShadingEnabled() const { return mIsSampleShadingEnabled; }
261     void setMinSampleShading(float value);
getMinSampleShading()262     float getMinSampleShading() const { return mMinSampleShading; }
263 
264     // Scissor test state toggle & query
isScissorTestEnabled()265     bool isScissorTestEnabled() const { return mScissorTest; }
266     void setScissorTest(bool enabled);
267     void setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height);
getScissor()268     const Rectangle &getScissor() const { return mScissor; }
269 
270     // Dither state toggle & query
isDitherEnabled()271     bool isDitherEnabled() const { return mRasterizer.dither; }
272     void setDither(bool enabled);
273 
274     // Generic state toggle & query
275     void setEnableFeature(GLenum feature, bool enabled);
276     void setEnableFeatureIndexed(GLenum feature, bool enabled, GLuint index);
277     bool getEnableFeature(GLenum feature) const;
278     bool getEnableFeatureIndexed(GLenum feature, GLuint index) const;
279 
280     // Line width state setter
281     void setLineWidth(GLfloat width);
getLineWidth()282     float getLineWidth() const { return mLineWidth; }
283 
284     // Hint setters
285     void setGenerateMipmapHint(GLenum hint);
286     GLenum getGenerateMipmapHint() const;
287     void setTextureFilteringHint(GLenum hint);
288     GLenum getTextureFilteringHint() const;
getFragmentShaderDerivativeHint()289     GLenum getFragmentShaderDerivativeHint() const { return mFragmentShaderDerivativeHint; }
290     void setFragmentShaderDerivativeHint(GLenum hint);
291 
292     // GL_CHROMIUM_bind_generates_resource
isBindGeneratesResourceEnabled()293     bool isBindGeneratesResourceEnabled() const { return mBindGeneratesResource; }
294 
295     // GL_ANGLE_client_arrays
areClientArraysEnabled()296     bool areClientArraysEnabled() const { return mClientArraysEnabled; }
297 
298     // Viewport state setter/getter
299     void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);
getViewport()300     const Rectangle &getViewport() const { return mViewport; }
301 
302     // Texture binding & active texture unit manipulation
303     void setActiveSampler(unsigned int active);
getActiveSampler()304     unsigned int getActiveSampler() const { return static_cast<unsigned int>(mActiveSampler); }
305 
306     void setSamplerTexture(const Context *context, TextureType type, Texture *texture);
307     Texture *getTargetTexture(TextureType type) const;
308 
getSamplerTexture(unsigned int sampler,TextureType type)309     Texture *getSamplerTexture(unsigned int sampler, TextureType type) const
310     {
311         ASSERT(sampler < mSamplerTextures[type].size());
312         return mSamplerTextures[type][sampler].get();
313     }
314 
315     TextureID getSamplerTextureId(unsigned int sampler, TextureType type) const;
316     void detachTexture(const Context *context, const TextureMap &zeroTextures, TextureID texture);
317     void initializeZeroTextures(const Context *context, const TextureMap &zeroTextures);
318 
319     void invalidateTextureBindings(TextureType type);
320 
321     // Sampler object binding manipulation
322     void setSamplerBinding(const Context *context, GLuint textureUnit, Sampler *sampler);
getSamplerId(GLuint textureUnit)323     SamplerID getSamplerId(GLuint textureUnit) const
324     {
325         ASSERT(textureUnit < mSamplers.size());
326         return mSamplers[textureUnit].id();
327     }
328 
getSampler(GLuint textureUnit)329     Sampler *getSampler(GLuint textureUnit) const { return mSamplers[textureUnit].get(); }
330 
getSamplers()331     const SamplerBindingVector &getSamplers() const { return mSamplers; }
332 
333     void detachSampler(const Context *context, SamplerID sampler);
334 
335     // Renderbuffer binding manipulation
336     void setRenderbufferBinding(const Context *context, Renderbuffer *renderbuffer);
getRenderbufferId()337     RenderbufferID getRenderbufferId() const { return mRenderbuffer.id(); }
getCurrentRenderbuffer()338     Renderbuffer *getCurrentRenderbuffer() const { return mRenderbuffer.get(); }
339     void detachRenderbuffer(const Context *context, RenderbufferID renderbuffer);
340 
341     // Framebuffer binding manipulation
342     void setReadFramebufferBinding(Framebuffer *framebuffer);
343     void setDrawFramebufferBinding(Framebuffer *framebuffer);
344     Framebuffer *getTargetFramebuffer(GLenum target) const;
getReadFramebuffer()345     Framebuffer *getReadFramebuffer() const { return mReadFramebuffer; }
getDrawFramebuffer()346     Framebuffer *getDrawFramebuffer() const { return mDrawFramebuffer; }
347     Framebuffer *getDefaultFramebuffer() const;
348 
349     bool removeReadFramebufferBinding(FramebufferID framebuffer);
350     bool removeDrawFramebufferBinding(FramebufferID framebuffer);
351 
352     // Vertex array object binding manipulation
353     void setVertexArrayBinding(const Context *context, VertexArray *vertexArray);
354     bool removeVertexArrayBinding(const Context *context, VertexArrayID vertexArray);
355     VertexArrayID getVertexArrayId() const;
356 
getVertexArray()357     VertexArray *getVertexArray() const
358     {
359         ASSERT(mVertexArray != nullptr);
360         return mVertexArray;
361     }
362 
363     // If both a Program and a ProgramPipeline are bound, the Program will
364     // always override the ProgramPipeline.
getProgramExecutable()365     const ProgramExecutable *getProgramExecutable() const { return mExecutable; }
366 
367     // Program binding manipulation
368     angle::Result setProgram(const Context *context, Program *newProgram);
369 
getProgram()370     Program *getProgram() const
371     {
372         ASSERT(!mProgram || !mProgram->isLinking());
373         return mProgram;
374     }
375 
getLinkedProgram(const Context * context)376     Program *getLinkedProgram(const Context *context) const
377     {
378         if (mProgram)
379         {
380             mProgram->resolveLink(context);
381         }
382         return mProgram;
383     }
384 
getProgramPipeline()385     ProgramPipeline *getProgramPipeline() const { return mProgramPipeline.get(); }
386 
387     // Transform feedback object (not buffer) binding manipulation
388     void setTransformFeedbackBinding(const Context *context, TransformFeedback *transformFeedback);
getCurrentTransformFeedback()389     TransformFeedback *getCurrentTransformFeedback() const { return mTransformFeedback.get(); }
390 
isTransformFeedbackActive()391     ANGLE_INLINE bool isTransformFeedbackActive() const
392     {
393         TransformFeedback *curTransformFeedback = mTransformFeedback.get();
394         return curTransformFeedback && curTransformFeedback->isActive();
395     }
isTransformFeedbackActiveUnpaused()396     ANGLE_INLINE bool isTransformFeedbackActiveUnpaused() const
397     {
398         TransformFeedback *curTransformFeedback = mTransformFeedback.get();
399         return curTransformFeedback && curTransformFeedback->isActive() &&
400                !curTransformFeedback->isPaused();
401     }
402 
403     bool removeTransformFeedbackBinding(const Context *context,
404                                         TransformFeedbackID transformFeedback);
405 
406     // Query binding manipulation
407     bool isQueryActive(QueryType type) const;
408     bool isQueryActive(Query *query) const;
409     void setActiveQuery(const Context *context, QueryType type, Query *query);
410     QueryID getActiveQueryId(QueryType type) const;
411     Query *getActiveQuery(QueryType type) const;
412 
413     // Program Pipeline binding manipulation
414     angle::Result useProgramStages(const Context *context,
415                                    ProgramPipeline *programPipeline,
416                                    GLbitfield stages,
417                                    Program *shaderProgram);
418     angle::Result setProgramPipelineBinding(const Context *context, ProgramPipeline *pipeline);
419     void detachProgramPipeline(const Context *context, ProgramPipelineID pipeline);
420 
421     //// Typed buffer binding point manipulation ////
setBufferBinding(const Context * context,BufferBinding target,Buffer * buffer)422     ANGLE_INLINE void setBufferBinding(const Context *context, BufferBinding target, Buffer *buffer)
423     {
424         (this->*(kBufferSetters[target]))(context, buffer);
425     }
426 
getTargetBuffer(BufferBinding target)427     ANGLE_INLINE Buffer *getTargetBuffer(BufferBinding target) const
428     {
429         switch (target)
430         {
431             case BufferBinding::ElementArray:
432                 return getVertexArray()->getElementArrayBuffer();
433             default:
434                 return mBoundBuffers[target].get();
435         }
436     }
437 
getArrayBuffer()438     ANGLE_INLINE Buffer *getArrayBuffer() const { return getTargetBuffer(BufferBinding::Array); }
439 
440     angle::Result setIndexedBufferBinding(const Context *context,
441                                           BufferBinding target,
442                                           GLuint index,
443                                           Buffer *buffer,
444                                           GLintptr offset,
445                                           GLsizeiptr size);
446 
getAtomicCounterBufferCount()447     size_t getAtomicCounterBufferCount() const { return mAtomicCounterBuffers.size(); }
448 
hasValidAtomicCounterBuffer()449     ANGLE_INLINE bool hasValidAtomicCounterBuffer() const
450     {
451         return mBoundAtomicCounterBuffersMask.any();
452     }
453 
454     const OffsetBindingPointer<Buffer> &getIndexedUniformBuffer(size_t index) const;
455     const OffsetBindingPointer<Buffer> &getIndexedAtomicCounterBuffer(size_t index) const;
456     const OffsetBindingPointer<Buffer> &getIndexedShaderStorageBuffer(size_t index) const;
457 
getUniformBuffersMask()458     const angle::BitSet<gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS> &getUniformBuffersMask()
459         const
460     {
461         return mBoundUniformBuffersMask;
462     }
463     const angle::BitSet<gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>
getAtomicCounterBuffersMask()464         &getAtomicCounterBuffersMask() const
465     {
466         return mBoundAtomicCounterBuffersMask;
467     }
468     const angle::BitSet<gl::IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>
getShaderStorageBuffersMask()469         &getShaderStorageBuffersMask() const
470     {
471         return mBoundShaderStorageBuffersMask;
472     }
473 
474     // Detach a buffer from all bindings
475     angle::Result detachBuffer(Context *context, const Buffer *buffer);
476 
477     // Vertex attrib manipulation
478     void setEnableVertexAttribArray(unsigned int attribNum, bool enabled);
479     void setVertexAttribf(GLuint index, const GLfloat values[4]);
480     void setVertexAttribu(GLuint index, const GLuint values[4]);
481     void setVertexAttribi(GLuint index, const GLint values[4]);
482 
setVertexAttribPointer(const Context * context,unsigned int attribNum,Buffer * boundBuffer,GLint size,VertexAttribType type,bool normalized,GLsizei stride,const void * pointer)483     ANGLE_INLINE void setVertexAttribPointer(const Context *context,
484                                              unsigned int attribNum,
485                                              Buffer *boundBuffer,
486                                              GLint size,
487                                              VertexAttribType type,
488                                              bool normalized,
489                                              GLsizei stride,
490                                              const void *pointer)
491     {
492         mVertexArray->setVertexAttribPointer(context, attribNum, boundBuffer, size, type,
493                                              normalized, stride, pointer);
494         mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
495     }
496 
setVertexAttribIPointer(const Context * context,unsigned int attribNum,Buffer * boundBuffer,GLint size,VertexAttribType type,GLsizei stride,const void * pointer)497     ANGLE_INLINE void setVertexAttribIPointer(const Context *context,
498                                               unsigned int attribNum,
499                                               Buffer *boundBuffer,
500                                               GLint size,
501                                               VertexAttribType type,
502                                               GLsizei stride,
503                                               const void *pointer)
504     {
505         mVertexArray->setVertexAttribIPointer(context, attribNum, boundBuffer, size, type, stride,
506                                               pointer);
507         mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
508     }
509 
510     void setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor);
getVertexAttribCurrentValue(size_t attribNum)511     const VertexAttribCurrentValueData &getVertexAttribCurrentValue(size_t attribNum) const
512     {
513         ASSERT(attribNum < mVertexAttribCurrentValues.size());
514         return mVertexAttribCurrentValues[attribNum];
515     }
516 
getVertexAttribCurrentValues()517     const std::vector<VertexAttribCurrentValueData> &getVertexAttribCurrentValues() const
518     {
519         return mVertexAttribCurrentValues;
520     }
521 
522     const void *getVertexAttribPointer(unsigned int attribNum) const;
523 
524     void bindVertexBuffer(const Context *context,
525                           GLuint bindingIndex,
526                           Buffer *boundBuffer,
527                           GLintptr offset,
528                           GLsizei stride);
529     void setVertexAttribFormat(GLuint attribIndex,
530                                GLint size,
531                                VertexAttribType type,
532                                bool normalized,
533                                bool pureInteger,
534                                GLuint relativeOffset);
535 
setVertexAttribBinding(const Context * context,GLuint attribIndex,GLuint bindingIndex)536     void setVertexAttribBinding(const Context *context, GLuint attribIndex, GLuint bindingIndex)
537     {
538         mVertexArray->setVertexAttribBinding(context, attribIndex, bindingIndex);
539         mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
540     }
541 
542     void setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor);
543 
544     // Pixel pack state manipulation
545     void setPackAlignment(GLint alignment);
getPackAlignment()546     GLint getPackAlignment() const { return mPack.alignment; }
547     void setPackReverseRowOrder(bool reverseRowOrder);
getPackReverseRowOrder()548     bool getPackReverseRowOrder() const { return mPack.reverseRowOrder; }
549     void setPackRowLength(GLint rowLength);
getPackRowLength()550     GLint getPackRowLength() const { return mPack.rowLength; }
551     void setPackSkipRows(GLint skipRows);
getPackSkipRows()552     GLint getPackSkipRows() const { return mPack.skipRows; }
553     void setPackSkipPixels(GLint skipPixels);
getPackSkipPixels()554     GLint getPackSkipPixels() const { return mPack.skipPixels; }
getPackState()555     const PixelPackState &getPackState() const { return mPack; }
getPackState()556     PixelPackState &getPackState() { return mPack; }
557 
558     // Pixel unpack state manipulation
559     void setUnpackAlignment(GLint alignment);
getUnpackAlignment()560     GLint getUnpackAlignment() const { return mUnpack.alignment; }
561     void setUnpackRowLength(GLint rowLength);
getUnpackRowLength()562     GLint getUnpackRowLength() const { return mUnpack.rowLength; }
563     void setUnpackImageHeight(GLint imageHeight);
getUnpackImageHeight()564     GLint getUnpackImageHeight() const { return mUnpack.imageHeight; }
565     void setUnpackSkipImages(GLint skipImages);
getUnpackSkipImages()566     GLint getUnpackSkipImages() const { return mUnpack.skipImages; }
567     void setUnpackSkipRows(GLint skipRows);
getUnpackSkipRows()568     GLint getUnpackSkipRows() const { return mUnpack.skipRows; }
569     void setUnpackSkipPixels(GLint skipPixels);
getUnpackSkipPixels()570     GLint getUnpackSkipPixels() const { return mUnpack.skipPixels; }
getUnpackState()571     const PixelUnpackState &getUnpackState() const { return mUnpack; }
getUnpackState()572     PixelUnpackState &getUnpackState() { return mUnpack; }
573 
574     // Debug state
getDebug()575     const Debug &getDebug() const { return mDebug; }
getDebug()576     Debug &getDebug() { return mDebug; }
577 
578     // CHROMIUM_framebuffer_mixed_samples coverage modulation
579     void setCoverageModulation(GLenum components);
getCoverageModulation()580     GLenum getCoverageModulation() const { return mCoverageModulation; }
581 
582     // GL_EXT_sRGB_write_control
583     void setFramebufferSRGB(bool sRGB);
getFramebufferSRGB()584     bool getFramebufferSRGB() const { return mFramebufferSRGB; }
585 
586     // GL_KHR_parallel_shader_compile
587     void setMaxShaderCompilerThreads(GLuint count);
getMaxShaderCompilerThreads()588     GLuint getMaxShaderCompilerThreads() const { return mMaxShaderCompilerThreads; }
589 
590     // GL_EXT_tessellation_shader
591     void setPatchVertices(GLuint value);
getPatchVertices()592     GLuint getPatchVertices() const { return mPatchVertices; }
593 
594     // State query functions
595     void getBooleanv(GLenum pname, GLboolean *params) const;
596     void getFloatv(GLenum pname, GLfloat *params) const;
597     angle::Result getIntegerv(const Context *context, GLenum pname, GLint *params) const;
598     void getPointerv(const Context *context, GLenum pname, void **params) const;
599     void getIntegeri_v(GLenum target, GLuint index, GLint *data) const;
600     void getInteger64i_v(GLenum target, GLuint index, GLint64 *data) const;
601     void getBooleani_v(GLenum target, GLuint index, GLboolean *data) const;
602 
isRobustResourceInitEnabled()603     bool isRobustResourceInitEnabled() const { return mRobustResourceInit; }
604 
605     // Sets the dirty bit for the program executable.
606     angle::Result onProgramExecutableChange(const Context *context, Program *program);
607     // Sets the dirty bit for the program pipeline executable.
608     angle::Result onProgramPipelineExecutableChange(const Context *context,
609                                                     ProgramPipeline *program);
610 
611     enum DirtyBitType
612     {
613         // Note: process draw framebuffer binding first, so that other dirty bits whose effect
614         // depend on the current draw framebuffer are not processed while the old framebuffer is
615         // still bound.
616         DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING,
617         DIRTY_BIT_READ_FRAMEBUFFER_BINDING,
618         DIRTY_BIT_SCISSOR_TEST_ENABLED,
619         DIRTY_BIT_SCISSOR,
620         DIRTY_BIT_VIEWPORT,
621         DIRTY_BIT_DEPTH_RANGE,
622         DIRTY_BIT_BLEND_ENABLED,
623         DIRTY_BIT_BLEND_COLOR,
624         DIRTY_BIT_BLEND_FUNCS,
625         DIRTY_BIT_BLEND_EQUATIONS,
626         DIRTY_BIT_COLOR_MASK,
627         DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED,
628         DIRTY_BIT_SAMPLE_COVERAGE_ENABLED,
629         DIRTY_BIT_SAMPLE_COVERAGE,
630         DIRTY_BIT_SAMPLE_MASK_ENABLED,
631         DIRTY_BIT_SAMPLE_MASK,
632         DIRTY_BIT_DEPTH_TEST_ENABLED,
633         DIRTY_BIT_DEPTH_FUNC,
634         DIRTY_BIT_DEPTH_MASK,
635         DIRTY_BIT_STENCIL_TEST_ENABLED,
636         DIRTY_BIT_STENCIL_FUNCS_FRONT,
637         DIRTY_BIT_STENCIL_FUNCS_BACK,
638         DIRTY_BIT_STENCIL_OPS_FRONT,
639         DIRTY_BIT_STENCIL_OPS_BACK,
640         DIRTY_BIT_STENCIL_WRITEMASK_FRONT,
641         DIRTY_BIT_STENCIL_WRITEMASK_BACK,
642         DIRTY_BIT_CULL_FACE_ENABLED,
643         DIRTY_BIT_CULL_FACE,
644         DIRTY_BIT_FRONT_FACE,
645         DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED,
646         DIRTY_BIT_POLYGON_OFFSET,
647         DIRTY_BIT_RASTERIZER_DISCARD_ENABLED,
648         DIRTY_BIT_LINE_WIDTH,
649         DIRTY_BIT_PRIMITIVE_RESTART_ENABLED,
650         DIRTY_BIT_CLEAR_COLOR,
651         DIRTY_BIT_CLEAR_DEPTH,
652         DIRTY_BIT_CLEAR_STENCIL,
653         DIRTY_BIT_UNPACK_STATE,
654         DIRTY_BIT_UNPACK_BUFFER_BINDING,
655         DIRTY_BIT_PACK_STATE,
656         DIRTY_BIT_PACK_BUFFER_BINDING,
657         DIRTY_BIT_DITHER_ENABLED,
658         DIRTY_BIT_RENDERBUFFER_BINDING,
659         DIRTY_BIT_VERTEX_ARRAY_BINDING,
660         DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING,
661         DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING,
662         // TODO(jmadill): Fine-grained dirty bits for each index.
663         DIRTY_BIT_PROGRAM_BINDING,  // Must be before DIRTY_BIT_PROGRAM_EXECUTABLE
664         DIRTY_BIT_PROGRAM_EXECUTABLE,
665         // TODO(jmadill): Fine-grained dirty bits for each texture/sampler.
666         DIRTY_BIT_SAMPLER_BINDINGS,
667         DIRTY_BIT_TEXTURE_BINDINGS,
668         DIRTY_BIT_IMAGE_BINDINGS,
669         DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING,
670         DIRTY_BIT_UNIFORM_BUFFER_BINDINGS,
671         DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING,
672         DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING,
673         DIRTY_BIT_MULTISAMPLING,
674         DIRTY_BIT_SAMPLE_ALPHA_TO_ONE,
675         DIRTY_BIT_COVERAGE_MODULATION,                  // CHROMIUM_framebuffer_mixed_samples
676         DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE,  // GL_EXT_sRGB_write_control
677         DIRTY_BIT_CURRENT_VALUES,
678         DIRTY_BIT_PROVOKING_VERTEX,
679         DIRTY_BIT_SAMPLE_SHADING,
680         DIRTY_BIT_PATCH_VERTICES,
681         DIRTY_BIT_EXTENDED,  // clip distances, mipmap generation hint, derivative hint,
682                              // EXT_clip_control
683         DIRTY_BIT_INVALID,
684         DIRTY_BIT_MAX = DIRTY_BIT_INVALID,
685     };
686 
687     static_assert(DIRTY_BIT_MAX <= 64, "State dirty bits must be capped at 64");
688 
689     enum ExtendedDirtyBitType
690     {
691         EXTENDED_DIRTY_BIT_CLIP_CONTROL,            // EXT_clip_control
692         EXTENDED_DIRTY_BIT_CLIP_DISTANCES,          // clip distances
693         EXTENDED_DIRTY_BIT_MIPMAP_GENERATION_HINT,  // mipmap generation hint
694         EXTENDED_DIRTY_BIT_SHADER_DERIVATIVE_HINT,  // shader derivative hint
695         EXTENDED_DIRTY_BIT_INVALID,
696         EXTENDED_DIRTY_BIT_MAX = EXTENDED_DIRTY_BIT_INVALID,
697     };
698 
699     static_assert(EXTENDED_DIRTY_BIT_MAX <= 32, "State extended dirty bits must be capped at 32");
700 
701     // TODO(jmadill): Consider storing dirty objects in a list instead of by binding.
702     enum DirtyObjectType
703     {
704         DIRTY_OBJECT_ACTIVE_TEXTURES,  // Top-level dirty bit. Also see mDirtyActiveTextures.
705         DIRTY_OBJECT_TEXTURES_INIT,
706         DIRTY_OBJECT_IMAGES_INIT,
707         DIRTY_OBJECT_READ_ATTACHMENTS,
708         DIRTY_OBJECT_DRAW_ATTACHMENTS,
709         DIRTY_OBJECT_VERTEX_ARRAY,
710         DIRTY_OBJECT_TEXTURES,  // Top-level dirty bit. Also see mDirtyTextures.
711         DIRTY_OBJECT_IMAGES,    // Top-level dirty bit. Also see mDirtyImages.
712         DIRTY_OBJECT_SAMPLERS,  // Top-level dirty bit. Also see mDirtySamplers.
713         DIRTY_OBJECT_READ_FRAMEBUFFER,
714         DIRTY_OBJECT_DRAW_FRAMEBUFFER,
715         DIRTY_OBJECT_PROGRAM,
716         DIRTY_OBJECT_UNKNOWN,
717         DIRTY_OBJECT_MAX = DIRTY_OBJECT_UNKNOWN,
718     };
719 
720     using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
getDirtyBits()721     const DirtyBits &getDirtyBits() const { return mDirtyBits; }
clearDirtyBits()722     void clearDirtyBits() { mDirtyBits.reset(); }
clearDirtyBits(const DirtyBits & bitset)723     void clearDirtyBits(const DirtyBits &bitset) { mDirtyBits &= ~bitset; }
setAllDirtyBits()724     void setAllDirtyBits()
725     {
726         mDirtyBits.set();
727         mDirtyCurrentValues.set();
728     }
729 
730     using ExtendedDirtyBits = angle::BitSet32<EXTENDED_DIRTY_BIT_MAX>;
getExtendedDirtyBits()731     const ExtendedDirtyBits &getExtendedDirtyBits() const { return mExtendedDirtyBits; }
732     // TODO(https://anglebug.com/5631): Handle extended dirty bits on non-vulkan backends
733     ExtendedDirtyBits getAndResetExtendedDirtyBits() const;
clearExtendedDirtyBits()734     void clearExtendedDirtyBits() { mExtendedDirtyBits.reset(); }
735 
736     using DirtyObjects = angle::BitSet<DIRTY_OBJECT_MAX>;
clearDirtyObjects()737     void clearDirtyObjects() { mDirtyObjects.reset(); }
setAllDirtyObjects()738     void setAllDirtyObjects() { mDirtyObjects.set(); }
739     angle::Result syncDirtyObjects(const Context *context,
740                                    const DirtyObjects &bitset,
741                                    Command command);
742     angle::Result syncDirtyObject(const Context *context, GLenum target);
743     void setObjectDirty(GLenum target);
744     void setTextureDirty(size_t textureUnitIndex);
745     void setSamplerDirty(size_t samplerIndex);
746 
setReadFramebufferDirty()747     ANGLE_INLINE void setReadFramebufferDirty()
748     {
749         mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
750         mDirtyObjects.set(DIRTY_OBJECT_READ_ATTACHMENTS);
751     }
752 
setDrawFramebufferDirty()753     ANGLE_INLINE void setDrawFramebufferDirty()
754     {
755         mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
756         mDirtyObjects.set(DIRTY_OBJECT_DRAW_ATTACHMENTS);
757     }
758 
759     // This actually clears the current value dirty bits.
760     // TODO(jmadill): Pass mutable dirty bits into Impl.
761     AttributesMask getAndResetDirtyCurrentValues() const;
762 
763     void setImageUnit(const Context *context,
764                       size_t unit,
765                       Texture *texture,
766                       GLint level,
767                       GLboolean layered,
768                       GLint layer,
769                       GLenum access,
770                       GLenum format);
771 
getImageUnit(size_t unit)772     const ImageUnit &getImageUnit(size_t unit) const { return mImageUnits[unit]; }
getActiveTexturesCache()773     const ActiveTexturesCache &getActiveTexturesCache() const { return mActiveTexturesCache; }
getCurrentValuesTypeMask()774     ComponentTypeMask getCurrentValuesTypeMask() const { return mCurrentValuesTypeMask; }
775 
776     // "onActiveTextureChange" is called when a texture binding changes.
777     void onActiveTextureChange(const Context *context, size_t textureUnit);
778 
779     // "onActiveTextureStateChange" is called when the Texture changed but the binding did not.
780     void onActiveTextureStateChange(const Context *context, size_t textureUnit);
781 
782     void onImageStateChange(const Context *context, size_t unit);
783 
784     void onUniformBufferStateChange(size_t uniformBufferIndex);
785 
isCurrentTransformFeedback(const TransformFeedback * tf)786     bool isCurrentTransformFeedback(const TransformFeedback *tf) const
787     {
788         return tf == mTransformFeedback.get();
789     }
isCurrentVertexArray(const VertexArray * va)790     bool isCurrentVertexArray(const VertexArray *va) const { return va == mVertexArray; }
791 
gles1()792     GLES1State &gles1() { return mGLES1State; }
gles1()793     const GLES1State &gles1() const { return mGLES1State; }
794 
795     // Helpers for setting bound buffers. They should all have the same signature.
796     // Not meant to be called externally. Used for local helpers in State.cpp.
797     template <BufferBinding Target>
798     void setGenericBufferBindingWithBit(const Context *context, Buffer *buffer);
799 
800     template <BufferBinding Target>
801     void setGenericBufferBinding(const Context *context, Buffer *buffer);
802 
803     using BufferBindingSetter = void (State::*)(const Context *, Buffer *);
804 
validateSamplerFormats()805     ANGLE_INLINE bool validateSamplerFormats() const
806     {
807         return (!mExecutable || !(mTexturesIncompatibleWithSamplers.intersects(
808                                     mExecutable->getActiveSamplersMask())));
809     }
810 
getProvokingVertex()811     ProvokingVertexConvention getProvokingVertex() const { return mProvokingVertex; }
setProvokingVertex(ProvokingVertexConvention val)812     void setProvokingVertex(ProvokingVertexConvention val)
813     {
814         mDirtyBits.set(State::DIRTY_BIT_PROVOKING_VERTEX);
815         mProvokingVertex = val;
816     }
817 
setReadFramebufferBindingDirty()818     ANGLE_INLINE void setReadFramebufferBindingDirty()
819     {
820         mDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
821     }
822 
setDrawFramebufferBindingDirty()823     ANGLE_INLINE void setDrawFramebufferBindingDirty()
824     {
825         mDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
826     }
827 
828     using ClipDistanceEnableBits = angle::BitSet32<IMPLEMENTATION_MAX_CLIP_DISTANCES>;
getEnabledClipDistances()829     const ClipDistanceEnableBits &getEnabledClipDistances() const { return mClipDistancesEnabled; }
830     void setClipDistanceEnable(int idx, bool enable);
831 
getOverlay()832     const OverlayType *getOverlay() const { return mOverlay; }
833 
834     // Not for general use.
getBufferManagerForCapture()835     const BufferManager &getBufferManagerForCapture() const { return *mBufferManager; }
getBoundBuffersForCapture()836     const BoundBufferMap &getBoundBuffersForCapture() const { return mBoundBuffers; }
getTextureManagerForCapture()837     const TextureManager &getTextureManagerForCapture() const { return *mTextureManager; }
getBoundTexturesForCapture()838     const TextureBindingMap &getBoundTexturesForCapture() const { return mSamplerTextures; }
getRenderbufferManagerForCapture()839     const RenderbufferManager &getRenderbufferManagerForCapture() const
840     {
841         return *mRenderbufferManager;
842     }
getFramebufferManagerForCapture()843     const FramebufferManager &getFramebufferManagerForCapture() const
844     {
845         return *mFramebufferManager;
846     }
getShaderProgramManagerForCapture()847     const ShaderProgramManager &getShaderProgramManagerForCapture() const
848     {
849         return *mShaderProgramManager;
850     }
getSyncManagerForCapture()851     const SyncManager &getSyncManagerForCapture() const { return *mSyncManager; }
getSamplerManagerForCapture()852     const SamplerManager &getSamplerManagerForCapture() const { return *mSamplerManager; }
getSamplerBindingsForCapture()853     const SamplerBindingVector &getSamplerBindingsForCapture() const { return mSamplers; }
854 
getActiveQueriesForCapture()855     const ActiveQueryMap &getActiveQueriesForCapture() const { return mActiveQueries; }
856 
hasConstantAlphaBlendFunc()857     bool hasConstantAlphaBlendFunc() const
858     {
859         return (mBlendFuncConstantAlphaDrawBuffers & mBlendStateExt.mEnabledMask).any();
860     }
861 
hasSimultaneousConstantColorAndAlphaBlendFunc()862     bool hasSimultaneousConstantColorAndAlphaBlendFunc() const
863     {
864         return (mBlendFuncConstantColorDrawBuffers & mBlendStateExt.mEnabledMask).any() &&
865                hasConstantAlphaBlendFunc();
866     }
867 
noSimultaneousConstantColorAndAlphaBlendFunc()868     bool noSimultaneousConstantColorAndAlphaBlendFunc() const
869     {
870         return mNoSimultaneousConstantColorAndAlphaBlendFunc;
871     }
872 
canEnableEarlyFragmentTestsOptimization()873     bool canEnableEarlyFragmentTestsOptimization() const
874     {
875         return !isSampleAlphaToCoverageEnabled();
876     }
877 
getOffsetBindingPointerUniformBuffers()878     const BufferVector &getOffsetBindingPointerUniformBuffers() const { return mUniformBuffers; }
879 
getOffsetBindingPointerAtomicCounterBuffers()880     const BufferVector &getOffsetBindingPointerAtomicCounterBuffers() const
881     {
882         return mAtomicCounterBuffers;
883     }
884 
getOffsetBindingPointerShaderStorageBuffers()885     const BufferVector &getOffsetBindingPointerShaderStorageBuffers() const
886     {
887         return mShaderStorageBuffers;
888     }
889 
getTexturesIncompatibleWithSamplers()890     ActiveTextureMask getTexturesIncompatibleWithSamplers() const
891     {
892         return mTexturesIncompatibleWithSamplers;
893     }
894 
isProgramBinaryCacheEnabled()895     bool isProgramBinaryCacheEnabled() const { return mProgramBinaryCacheEnabled; }
896 
isTextureRectangleEnabled()897     bool isTextureRectangleEnabled() const { return mTextureRectangleEnabled; }
898 
getBlendFuncConstantAlphaDrawBuffers()899     DrawBufferMask getBlendFuncConstantAlphaDrawBuffers() const
900     {
901         return mBlendFuncConstantAlphaDrawBuffers;
902     }
903 
getBlendFuncConstantColorDrawBuffers()904     DrawBufferMask getBlendFuncConstantColorDrawBuffers() const
905     {
906         return mBlendFuncConstantColorDrawBuffers;
907     }
908 
getImageUnits()909     const std::vector<ImageUnit> &getImageUnits() const { return mImageUnits; }
910 
getProgramPipelineManagerForCapture()911     const ProgramPipelineManager *getProgramPipelineManagerForCapture() const
912     {
913         return mProgramPipelineManager;
914     }
915 
916   private:
917     friend class Context;
918 
919     void unsetActiveTextures(const ActiveTextureMask &textureMask);
920     void setActiveTextureDirty(size_t textureIndex, Texture *texture);
921     void updateTextureBinding(const Context *context, size_t textureIndex, Texture *texture);
922     void updateActiveTextureStateOnSync(const Context *context,
923                                         size_t textureIndex,
924                                         const Sampler *sampler,
925                                         Texture *texture);
926     Texture *getTextureForActiveSampler(TextureType type, size_t index);
927 
928     bool hasConstantColor(GLenum sourceRGB, GLenum destRGB) const;
929     bool hasConstantAlpha(GLenum sourceRGB, GLenum destRGB) const;
930 
931     // Functions to synchronize dirty states
932     angle::Result syncActiveTextures(const Context *context, Command command);
933     angle::Result syncTexturesInit(const Context *context, Command command);
934     angle::Result syncImagesInit(const Context *context, Command command);
935     angle::Result syncReadAttachments(const Context *context, Command command);
936     angle::Result syncDrawAttachments(const Context *context, Command command);
937     angle::Result syncReadFramebuffer(const Context *context, Command command);
938     angle::Result syncDrawFramebuffer(const Context *context, Command command);
939     angle::Result syncVertexArray(const Context *context, Command command);
940     angle::Result syncTextures(const Context *context, Command command);
941     angle::Result syncImages(const Context *context, Command command);
942     angle::Result syncSamplers(const Context *context, Command command);
943     angle::Result syncProgram(const Context *context, Command command);
944 
945     using DirtyObjectHandler = angle::Result (State::*)(const Context *context, Command command);
946     static constexpr DirtyObjectHandler kDirtyObjectHandlers[DIRTY_OBJECT_MAX] = {
947         &State::syncActiveTextures,  &State::syncTexturesInit,    &State::syncImagesInit,
948         &State::syncReadAttachments, &State::syncDrawAttachments, &State::syncVertexArray,
949         &State::syncTextures,        &State::syncImages,          &State::syncSamplers,
950         &State::syncReadFramebuffer, &State::syncDrawFramebuffer, &State::syncProgram};
951 
952     // Robust init must happen before Framebuffer init for the Vulkan back-end.
953     static_assert(DIRTY_OBJECT_ACTIVE_TEXTURES < DIRTY_OBJECT_TEXTURES_INIT, "init order");
954     static_assert(DIRTY_OBJECT_TEXTURES_INIT < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order");
955     static_assert(DIRTY_OBJECT_IMAGES_INIT < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order");
956     static_assert(DIRTY_OBJECT_DRAW_ATTACHMENTS < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order");
957     static_assert(DIRTY_OBJECT_READ_ATTACHMENTS < DIRTY_OBJECT_READ_FRAMEBUFFER, "init order");
958 
959     static_assert(DIRTY_OBJECT_ACTIVE_TEXTURES == 0, "check DIRTY_OBJECT_ACTIVE_TEXTURES index");
960     static_assert(DIRTY_OBJECT_TEXTURES_INIT == 1, "check DIRTY_OBJECT_TEXTURES_INIT index");
961     static_assert(DIRTY_OBJECT_IMAGES_INIT == 2, "check DIRTY_OBJECT_IMAGES_INIT index");
962     static_assert(DIRTY_OBJECT_READ_ATTACHMENTS == 3, "check DIRTY_OBJECT_READ_ATTACHMENTS index");
963     static_assert(DIRTY_OBJECT_DRAW_ATTACHMENTS == 4, "check DIRTY_OBJECT_DRAW_ATTACHMENTS index");
964     static_assert(DIRTY_OBJECT_VERTEX_ARRAY == 5, "check DIRTY_OBJECT_VERTEX_ARRAY index");
965     static_assert(DIRTY_OBJECT_TEXTURES == 6, "check DIRTY_OBJECT_TEXTURES index");
966     static_assert(DIRTY_OBJECT_IMAGES == 7, "check DIRTY_OBJECT_IMAGES index");
967     static_assert(DIRTY_OBJECT_SAMPLERS == 8, "check DIRTY_OBJECT_SAMPLERS index");
968     static_assert(DIRTY_OBJECT_READ_FRAMEBUFFER == 9, "check DIRTY_OBJECT_READ_FRAMEBUFFER index");
969     static_assert(DIRTY_OBJECT_DRAW_FRAMEBUFFER == 10, "check DIRTY_OBJECT_DRAW_FRAMEBUFFER index");
970     static_assert(DIRTY_OBJECT_PROGRAM == 11, "check DIRTY_OBJECT_PROGRAM index");
971 
972     // Container (FBO) object must handled after the texture so that if texture code adds dirty bit
973     // to container object, they will be picked up in the same draw call.
974     static_assert(DIRTY_OBJECT_TEXTURES < DIRTY_OBJECT_READ_FRAMEBUFFER,
975                   "State::syncDirtyObjects order");
976     static_assert(DIRTY_OBJECT_TEXTURES < DIRTY_OBJECT_DRAW_FRAMEBUFFER,
977                   "State::syncDirtyObjects order");
978 
979     // Dispatch table for buffer update functions.
980     static const angle::PackedEnumMap<BufferBinding, BufferBindingSetter> kBufferSetters;
981 
982     ContextID mID;
983 
984     EGLenum mClientType;
985     EGLenum mContextPriority;
986     bool mHasProtectedContent;
987     Version mClientVersion;
988 
989     // Caps to use for validation
990     Caps mCaps;
991     TextureCapsMap mTextureCaps;
992     Extensions mExtensions;
993     Limitations mLimitations;
994 
995     egl::ShareGroup *mShareGroup;
996 
997     // Resource managers.
998     BufferManager *mBufferManager;
999     ShaderProgramManager *mShaderProgramManager;
1000     TextureManager *mTextureManager;
1001     RenderbufferManager *mRenderbufferManager;
1002     SamplerManager *mSamplerManager;
1003     SyncManager *mSyncManager;
1004     FramebufferManager *mFramebufferManager;
1005     ProgramPipelineManager *mProgramPipelineManager;
1006     MemoryObjectManager *mMemoryObjectManager;
1007     SemaphoreManager *mSemaphoreManager;
1008 
1009     // Cached values from Context's caps
1010     GLuint mMaxDrawBuffers;
1011     GLuint mMaxCombinedTextureImageUnits;
1012 
1013     ColorF mColorClearValue;
1014     GLfloat mDepthClearValue;
1015     int mStencilClearValue;
1016 
1017     RasterizerState mRasterizer;
1018     bool mScissorTest;
1019     Rectangle mScissor;
1020 
1021     BlendState mBlendState;  // Buffer zero blend state legacy struct
1022     BlendStateExt mBlendStateExt;
1023     ColorF mBlendColor;
1024     bool mSampleAlphaToCoverage;
1025     bool mSampleCoverage;
1026     GLfloat mSampleCoverageValue;
1027     bool mSampleCoverageInvert;
1028     bool mSampleMask;
1029     GLuint mMaxSampleMaskWords;
1030     std::array<GLbitfield, MAX_SAMPLE_MASK_WORDS> mSampleMaskValues;
1031     bool mIsSampleShadingEnabled;
1032     float mMinSampleShading;
1033 
1034     DepthStencilState mDepthStencil;
1035     GLint mStencilRef;
1036     GLint mStencilBackRef;
1037 
1038     GLfloat mLineWidth;
1039 
1040     GLenum mGenerateMipmapHint;
1041     GLenum mTextureFilteringHint;
1042     GLenum mFragmentShaderDerivativeHint;
1043 
1044     const bool mBindGeneratesResource;
1045     const bool mClientArraysEnabled;
1046 
1047     Rectangle mViewport;
1048     float mNearZ;
1049     float mFarZ;
1050 
1051     GLenum mClipControlOrigin;
1052     GLenum mClipControlDepth;
1053 
1054     Framebuffer *mReadFramebuffer;
1055     Framebuffer *mDrawFramebuffer;
1056     BindingPointer<Renderbuffer> mRenderbuffer;
1057     Program *mProgram;
1058     BindingPointer<ProgramPipeline> mProgramPipeline;
1059     ProgramExecutable *mExecutable;
1060 
1061     // GL_ANGLE_provoking_vertex
1062     ProvokingVertexConvention mProvokingVertex;
1063 
1064     using VertexAttribVector = std::vector<VertexAttribCurrentValueData>;
1065     VertexAttribVector mVertexAttribCurrentValues;  // From glVertexAttrib
1066     VertexArray *mVertexArray;
1067     ComponentTypeMask mCurrentValuesTypeMask;
1068 
1069     // Texture and sampler bindings
1070     size_t mActiveSampler;  // Active texture unit selector - GL_TEXTURE0
1071 
1072     TextureBindingMap mSamplerTextures;
1073 
1074     // Active Textures Cache
1075     // ---------------------
1076     // The active textures cache gives ANGLE components access to a complete array of textures
1077     // on a draw call. gl::State implements angle::Observer and watches gl::Texture for state
1078     // changes via the onSubjectStateChange method above. We update the cache before draws.
1079     // See Observer.h and the design doc linked there for more info on Subject/Observer events.
1080     //
1081     // On state change events (re-binding textures, samplers, programs etc) we clear the cache
1082     // and flag dirty bits. nullptr indicates unbound or incomplete.
1083     ActiveTexturesCache mActiveTexturesCache;
1084     std::vector<angle::ObserverBinding> mCompleteTextureBindings;
1085 
1086     ActiveTextureMask mTexturesIncompatibleWithSamplers;
1087 
1088     SamplerBindingVector mSamplers;
1089 
1090     // It would be nice to merge the image and observer binding. Same for textures.
1091     std::vector<ImageUnit> mImageUnits;
1092 
1093     ActiveQueryMap mActiveQueries;
1094 
1095     // Stores the currently bound buffer for each binding point. It has an entry for the element
1096     // array buffer but it should not be used. Instead this bind point is owned by the current
1097     // vertex array object.
1098     BoundBufferMap mBoundBuffers;
1099 
1100     BufferVector mUniformBuffers;
1101     BufferVector mAtomicCounterBuffers;
1102     BufferVector mShaderStorageBuffers;
1103 
1104     angle::BitSet<gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS> mBoundUniformBuffersMask;
1105     angle::BitSet<gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>
1106         mBoundAtomicCounterBuffersMask;
1107     angle::BitSet<gl::IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>
1108         mBoundShaderStorageBuffersMask;
1109 
1110     BindingPointer<TransformFeedback> mTransformFeedback;
1111 
1112     PixelUnpackState mUnpack;
1113     PixelPackState mPack;
1114 
1115     bool mPrimitiveRestart;
1116 
1117     Debug mDebug;
1118 
1119     bool mMultiSampling;
1120     bool mSampleAlphaToOne;
1121 
1122     GLenum mCoverageModulation;
1123 
1124     // GL_EXT_sRGB_write_control
1125     bool mFramebufferSRGB;
1126 
1127     // GL_ANGLE_robust_resource_initialization
1128     const bool mRobustResourceInit;
1129 
1130     // GL_ANGLE_program_cache_control
1131     const bool mProgramBinaryCacheEnabled;
1132 
1133     // GL_ANGLE_webgl_compatibility
1134     bool mTextureRectangleEnabled;
1135 
1136     // GL_KHR_parallel_shader_compile
1137     GLuint mMaxShaderCompilerThreads;
1138 
1139     // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance
1140     ClipDistanceEnableBits mClipDistancesEnabled;
1141 
1142     // GL_EXT_tessellation_shader
1143     GLuint mPatchVertices;
1144 
1145     // GLES1 emulation: state specific to GLES1
1146     GLES1State mGLES1State;
1147 
1148     DirtyBits mDirtyBits;
1149     mutable ExtendedDirtyBits mExtendedDirtyBits;
1150     DirtyObjects mDirtyObjects;
1151     mutable AttributesMask mDirtyCurrentValues;
1152     ActiveTextureMask mDirtyActiveTextures;
1153     ActiveTextureMask mDirtyTextures;
1154     ActiveTextureMask mDirtySamplers;
1155     ImageUnitMask mDirtyImages;
1156 
1157     // The Overlay object, used by the backend to render the overlay.
1158     const OverlayType *mOverlay;
1159 
1160     // OES_draw_buffers_indexed
1161     DrawBufferMask mBlendFuncConstantAlphaDrawBuffers;
1162     DrawBufferMask mBlendFuncConstantColorDrawBuffers;
1163     bool mNoSimultaneousConstantColorAndAlphaBlendFunc;
1164 };
1165 
syncDirtyObjects(const Context * context,const DirtyObjects & bitset,Command command)1166 ANGLE_INLINE angle::Result State::syncDirtyObjects(const Context *context,
1167                                                    const DirtyObjects &bitset,
1168                                                    Command command)
1169 {
1170     const DirtyObjects &dirtyObjects = mDirtyObjects & bitset;
1171 
1172     for (size_t dirtyObject : dirtyObjects)
1173     {
1174         ANGLE_TRY((this->*kDirtyObjectHandlers[dirtyObject])(context, command));
1175     }
1176 
1177     mDirtyObjects &= ~dirtyObjects;
1178     return angle::Result::Continue;
1179 }
1180 
1181 }  // namespace gl
1182 
1183 #endif  // LIBANGLE_STATE_H_
1184