• 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.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 bindGeneratesResourceCHROMIUM,
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.webglCompatibilityANGLE; }
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 setProgramPipelineBinding(const Context *context, ProgramPipeline *pipeline);
415     void detachProgramPipeline(const Context *context, ProgramPipelineID pipeline);
416 
417     //// Typed buffer binding point manipulation ////
setBufferBinding(const Context * context,BufferBinding target,Buffer * buffer)418     ANGLE_INLINE void setBufferBinding(const Context *context, BufferBinding target, Buffer *buffer)
419     {
420         (this->*(kBufferSetters[target]))(context, buffer);
421     }
422 
getTargetBuffer(BufferBinding target)423     ANGLE_INLINE Buffer *getTargetBuffer(BufferBinding target) const
424     {
425         switch (target)
426         {
427             case BufferBinding::ElementArray:
428                 return getVertexArray()->getElementArrayBuffer();
429             default:
430                 return mBoundBuffers[target].get();
431         }
432     }
433 
getArrayBuffer()434     ANGLE_INLINE Buffer *getArrayBuffer() const { return getTargetBuffer(BufferBinding::Array); }
435 
436     angle::Result setIndexedBufferBinding(const Context *context,
437                                           BufferBinding target,
438                                           GLuint index,
439                                           Buffer *buffer,
440                                           GLintptr offset,
441                                           GLsizeiptr size);
442 
getAtomicCounterBufferCount()443     size_t getAtomicCounterBufferCount() const { return mAtomicCounterBuffers.size(); }
444 
hasValidAtomicCounterBuffer()445     ANGLE_INLINE bool hasValidAtomicCounterBuffer() const
446     {
447         return mBoundAtomicCounterBuffersMask.any();
448     }
449 
450     const OffsetBindingPointer<Buffer> &getIndexedUniformBuffer(size_t index) const;
451     const OffsetBindingPointer<Buffer> &getIndexedAtomicCounterBuffer(size_t index) const;
452     const OffsetBindingPointer<Buffer> &getIndexedShaderStorageBuffer(size_t index) const;
453 
getUniformBuffersMask()454     const angle::BitSet<gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS> &getUniformBuffersMask()
455         const
456     {
457         return mBoundUniformBuffersMask;
458     }
459     const angle::BitSet<gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>
getAtomicCounterBuffersMask()460         &getAtomicCounterBuffersMask() const
461     {
462         return mBoundAtomicCounterBuffersMask;
463     }
464     const angle::BitSet<gl::IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>
getShaderStorageBuffersMask()465         &getShaderStorageBuffersMask() const
466     {
467         return mBoundShaderStorageBuffersMask;
468     }
469 
470     // Detach a buffer from all bindings
471     angle::Result detachBuffer(Context *context, const Buffer *buffer);
472 
473     // Vertex attrib manipulation
474     void setEnableVertexAttribArray(unsigned int attribNum, bool enabled);
475     void setVertexAttribf(GLuint index, const GLfloat values[4]);
476     void setVertexAttribu(GLuint index, const GLuint values[4]);
477     void setVertexAttribi(GLuint index, const GLint values[4]);
478 
setVertexAttribPointer(const Context * context,unsigned int attribNum,Buffer * boundBuffer,GLint size,VertexAttribType type,bool normalized,GLsizei stride,const void * pointer)479     ANGLE_INLINE void setVertexAttribPointer(const Context *context,
480                                              unsigned int attribNum,
481                                              Buffer *boundBuffer,
482                                              GLint size,
483                                              VertexAttribType type,
484                                              bool normalized,
485                                              GLsizei stride,
486                                              const void *pointer)
487     {
488         mVertexArray->setVertexAttribPointer(context, attribNum, boundBuffer, size, type,
489                                              normalized, stride, pointer);
490         mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
491     }
492 
setVertexAttribIPointer(const Context * context,unsigned int attribNum,Buffer * boundBuffer,GLint size,VertexAttribType type,GLsizei stride,const void * pointer)493     ANGLE_INLINE void setVertexAttribIPointer(const Context *context,
494                                               unsigned int attribNum,
495                                               Buffer *boundBuffer,
496                                               GLint size,
497                                               VertexAttribType type,
498                                               GLsizei stride,
499                                               const void *pointer)
500     {
501         mVertexArray->setVertexAttribIPointer(context, attribNum, boundBuffer, size, type, stride,
502                                               pointer);
503         mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
504     }
505 
506     void setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor);
getVertexAttribCurrentValue(size_t attribNum)507     const VertexAttribCurrentValueData &getVertexAttribCurrentValue(size_t attribNum) const
508     {
509         ASSERT(attribNum < mVertexAttribCurrentValues.size());
510         return mVertexAttribCurrentValues[attribNum];
511     }
512 
getVertexAttribCurrentValues()513     const std::vector<VertexAttribCurrentValueData> &getVertexAttribCurrentValues() const
514     {
515         return mVertexAttribCurrentValues;
516     }
517 
518     const void *getVertexAttribPointer(unsigned int attribNum) const;
519 
520     void bindVertexBuffer(const Context *context,
521                           GLuint bindingIndex,
522                           Buffer *boundBuffer,
523                           GLintptr offset,
524                           GLsizei stride);
525     void setVertexAttribFormat(GLuint attribIndex,
526                                GLint size,
527                                VertexAttribType type,
528                                bool normalized,
529                                bool pureInteger,
530                                GLuint relativeOffset);
531 
setVertexAttribBinding(const Context * context,GLuint attribIndex,GLuint bindingIndex)532     void setVertexAttribBinding(const Context *context, GLuint attribIndex, GLuint bindingIndex)
533     {
534         mVertexArray->setVertexAttribBinding(context, attribIndex, bindingIndex);
535         mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
536     }
537 
538     void setVertexBindingDivisor(const Context *context, GLuint bindingIndex, GLuint divisor);
539 
540     // Pixel pack state manipulation
541     void setPackAlignment(GLint alignment);
getPackAlignment()542     GLint getPackAlignment() const { return mPack.alignment; }
543     void setPackReverseRowOrder(bool reverseRowOrder);
getPackReverseRowOrder()544     bool getPackReverseRowOrder() const { return mPack.reverseRowOrder; }
545     void setPackRowLength(GLint rowLength);
getPackRowLength()546     GLint getPackRowLength() const { return mPack.rowLength; }
547     void setPackSkipRows(GLint skipRows);
getPackSkipRows()548     GLint getPackSkipRows() const { return mPack.skipRows; }
549     void setPackSkipPixels(GLint skipPixels);
getPackSkipPixels()550     GLint getPackSkipPixels() const { return mPack.skipPixels; }
getPackState()551     const PixelPackState &getPackState() const { return mPack; }
getPackState()552     PixelPackState &getPackState() { return mPack; }
553 
554     // Pixel unpack state manipulation
555     void setUnpackAlignment(GLint alignment);
getUnpackAlignment()556     GLint getUnpackAlignment() const { return mUnpack.alignment; }
557     void setUnpackRowLength(GLint rowLength);
getUnpackRowLength()558     GLint getUnpackRowLength() const { return mUnpack.rowLength; }
559     void setUnpackImageHeight(GLint imageHeight);
getUnpackImageHeight()560     GLint getUnpackImageHeight() const { return mUnpack.imageHeight; }
561     void setUnpackSkipImages(GLint skipImages);
getUnpackSkipImages()562     GLint getUnpackSkipImages() const { return mUnpack.skipImages; }
563     void setUnpackSkipRows(GLint skipRows);
getUnpackSkipRows()564     GLint getUnpackSkipRows() const { return mUnpack.skipRows; }
565     void setUnpackSkipPixels(GLint skipPixels);
getUnpackSkipPixels()566     GLint getUnpackSkipPixels() const { return mUnpack.skipPixels; }
getUnpackState()567     const PixelUnpackState &getUnpackState() const { return mUnpack; }
getUnpackState()568     PixelUnpackState &getUnpackState() { return mUnpack; }
569 
570     // Debug state
getDebug()571     const Debug &getDebug() const { return mDebug; }
getDebug()572     Debug &getDebug() { return mDebug; }
573 
574     // CHROMIUM_framebuffer_mixed_samples coverage modulation
575     void setCoverageModulation(GLenum components);
getCoverageModulation()576     GLenum getCoverageModulation() const { return mCoverageModulation; }
577 
578     // GL_EXT_sRGB_write_control
579     void setFramebufferSRGB(bool sRGB);
getFramebufferSRGB()580     bool getFramebufferSRGB() const { return mFramebufferSRGB; }
581 
582     // GL_KHR_parallel_shader_compile
583     void setMaxShaderCompilerThreads(GLuint count);
getMaxShaderCompilerThreads()584     GLuint getMaxShaderCompilerThreads() const { return mMaxShaderCompilerThreads; }
585 
586     // GL_EXT_tessellation_shader
587     void setPatchVertices(GLuint value);
getPatchVertices()588     GLuint getPatchVertices() const { return mPatchVertices; }
589 
590     // State query functions
591     void getBooleanv(GLenum pname, GLboolean *params) const;
592     void getFloatv(GLenum pname, GLfloat *params) const;
593     angle::Result getIntegerv(const Context *context, GLenum pname, GLint *params) const;
594     void getPointerv(const Context *context, GLenum pname, void **params) const;
595     void getIntegeri_v(GLenum target, GLuint index, GLint *data) const;
596     void getInteger64i_v(GLenum target, GLuint index, GLint64 *data) const;
597     void getBooleani_v(GLenum target, GLuint index, GLboolean *data) const;
598 
isRobustResourceInitEnabled()599     bool isRobustResourceInitEnabled() const { return mRobustResourceInit; }
600 
isDrawFramebufferBindingDirty()601     bool isDrawFramebufferBindingDirty() const
602     {
603         return mDirtyBits.test(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
604     }
605 
606     // Sets the dirty bit for the program executable.
607     angle::Result onProgramExecutableChange(const Context *context, Program *program);
608     // Sets the dirty bit for the program pipeline executable.
609     angle::Result onProgramPipelineExecutableChange(const Context *context);
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_READ_FRAMEBUFFER,
710         DIRTY_OBJECT_DRAW_FRAMEBUFFER,
711         DIRTY_OBJECT_VERTEX_ARRAY,
712         DIRTY_OBJECT_TEXTURES,  // Top-level dirty bit. Also see mDirtyTextures.
713         DIRTY_OBJECT_IMAGES,    // Top-level dirty bit. Also see mDirtyImages.
714         DIRTY_OBJECT_SAMPLERS,  // Top-level dirty bit. Also see mDirtySamplers.
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     void onAtomicCounterBufferStateChange(size_t atomicCounterBufferIndex);
786     void onShaderStorageBufferStateChange(size_t shaderStorageBufferIndex);
787 
isCurrentTransformFeedback(const TransformFeedback * tf)788     bool isCurrentTransformFeedback(const TransformFeedback *tf) const
789     {
790         return tf == mTransformFeedback.get();
791     }
isCurrentVertexArray(const VertexArray * va)792     bool isCurrentVertexArray(const VertexArray *va) const { return va == mVertexArray; }
793 
gles1()794     GLES1State &gles1() { return mGLES1State; }
gles1()795     const GLES1State &gles1() const { return mGLES1State; }
796 
797     // Helpers for setting bound buffers. They should all have the same signature.
798     // Not meant to be called externally. Used for local helpers in State.cpp.
799     template <BufferBinding Target>
800     void setGenericBufferBindingWithBit(const Context *context, Buffer *buffer);
801 
802     template <BufferBinding Target>
803     void setGenericBufferBinding(const Context *context, Buffer *buffer);
804 
805     using BufferBindingSetter = void (State::*)(const Context *, Buffer *);
806 
validateSamplerFormats()807     ANGLE_INLINE bool validateSamplerFormats() const
808     {
809         return (!mExecutable || !(mTexturesIncompatibleWithSamplers.intersects(
810                                     mExecutable->getActiveSamplersMask())));
811     }
812 
getProvokingVertex()813     ProvokingVertexConvention getProvokingVertex() const { return mProvokingVertex; }
setProvokingVertex(ProvokingVertexConvention val)814     void setProvokingVertex(ProvokingVertexConvention val)
815     {
816         mDirtyBits.set(State::DIRTY_BIT_PROVOKING_VERTEX);
817         mProvokingVertex = val;
818     }
819 
setReadFramebufferBindingDirty()820     ANGLE_INLINE void setReadFramebufferBindingDirty()
821     {
822         mDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
823     }
824 
setDrawFramebufferBindingDirty()825     ANGLE_INLINE void setDrawFramebufferBindingDirty()
826     {
827         mDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
828     }
829 
830     using ClipDistanceEnableBits = angle::BitSet32<IMPLEMENTATION_MAX_CLIP_DISTANCES>;
getEnabledClipDistances()831     const ClipDistanceEnableBits &getEnabledClipDistances() const { return mClipDistancesEnabled; }
832     void setClipDistanceEnable(int idx, bool enable);
833 
getOverlay()834     const OverlayType *getOverlay() const { return mOverlay; }
835 
836     // Not for general use.
getBufferManagerForCapture()837     const BufferManager &getBufferManagerForCapture() const { return *mBufferManager; }
getBoundBuffersForCapture()838     const BoundBufferMap &getBoundBuffersForCapture() const { return mBoundBuffers; }
getTextureManagerForCapture()839     const TextureManager &getTextureManagerForCapture() const { return *mTextureManager; }
getBoundTexturesForCapture()840     const TextureBindingMap &getBoundTexturesForCapture() const { return mSamplerTextures; }
getRenderbufferManagerForCapture()841     const RenderbufferManager &getRenderbufferManagerForCapture() const
842     {
843         return *mRenderbufferManager;
844     }
getFramebufferManagerForCapture()845     const FramebufferManager &getFramebufferManagerForCapture() const
846     {
847         return *mFramebufferManager;
848     }
getShaderProgramManagerForCapture()849     const ShaderProgramManager &getShaderProgramManagerForCapture() const
850     {
851         return *mShaderProgramManager;
852     }
getSyncManagerForCapture()853     const SyncManager &getSyncManagerForCapture() const { return *mSyncManager; }
getSamplerManagerForCapture()854     const SamplerManager &getSamplerManagerForCapture() const { return *mSamplerManager; }
getProgramPipelineManagerForCapture()855     const ProgramPipelineManager *getProgramPipelineManagerForCapture() const
856     {
857         return mProgramPipelineManager;
858     }
getSamplerBindingsForCapture()859     const SamplerBindingVector &getSamplerBindingsForCapture() const { return mSamplers; }
getActiveQueriesForCapture()860     const ActiveQueryMap &getActiveQueriesForCapture() const { return mActiveQueries; }
861     void initializeForCapture(const Context *context);
862 
hasConstantAlphaBlendFunc()863     bool hasConstantAlphaBlendFunc() const
864     {
865         return (mBlendFuncConstantAlphaDrawBuffers & mBlendStateExt.mEnabledMask).any();
866     }
867 
hasSimultaneousConstantColorAndAlphaBlendFunc()868     bool hasSimultaneousConstantColorAndAlphaBlendFunc() const
869     {
870         return (mBlendFuncConstantColorDrawBuffers & mBlendStateExt.mEnabledMask).any() &&
871                hasConstantAlphaBlendFunc();
872     }
873 
noSimultaneousConstantColorAndAlphaBlendFunc()874     bool noSimultaneousConstantColorAndAlphaBlendFunc() const
875     {
876         return mNoSimultaneousConstantColorAndAlphaBlendFunc;
877     }
878 
canEnableEarlyFragmentTestsOptimization()879     bool canEnableEarlyFragmentTestsOptimization() const
880     {
881         return !isSampleAlphaToCoverageEnabled();
882     }
883 
getOffsetBindingPointerUniformBuffers()884     const BufferVector &getOffsetBindingPointerUniformBuffers() const { return mUniformBuffers; }
885 
getOffsetBindingPointerAtomicCounterBuffers()886     const BufferVector &getOffsetBindingPointerAtomicCounterBuffers() const
887     {
888         return mAtomicCounterBuffers;
889     }
890 
getOffsetBindingPointerShaderStorageBuffers()891     const BufferVector &getOffsetBindingPointerShaderStorageBuffers() const
892     {
893         return mShaderStorageBuffers;
894     }
895 
getTexturesIncompatibleWithSamplers()896     ActiveTextureMask getTexturesIncompatibleWithSamplers() const
897     {
898         return mTexturesIncompatibleWithSamplers;
899     }
900 
isProgramBinaryCacheEnabled()901     bool isProgramBinaryCacheEnabled() const { return mProgramBinaryCacheEnabled; }
902 
isTextureRectangleEnabled()903     bool isTextureRectangleEnabled() const { return mTextureRectangleEnabled; }
904 
getBlendFuncConstantAlphaDrawBuffers()905     DrawBufferMask getBlendFuncConstantAlphaDrawBuffers() const
906     {
907         return mBlendFuncConstantAlphaDrawBuffers;
908     }
909 
getBlendFuncConstantColorDrawBuffers()910     DrawBufferMask getBlendFuncConstantColorDrawBuffers() const
911     {
912         return mBlendFuncConstantColorDrawBuffers;
913     }
914 
getImageUnits()915     const std::vector<ImageUnit> &getImageUnits() const { return mImageUnits; }
916 
917   private:
918     friend class Context;
919 
920     void unsetActiveTextures(const ActiveTextureMask &textureMask);
921     void setActiveTextureDirty(size_t textureIndex, Texture *texture);
922     void updateTextureBinding(const Context *context, size_t textureIndex, Texture *texture);
923     void updateActiveTextureStateOnSync(const Context *context,
924                                         size_t textureIndex,
925                                         const Sampler *sampler,
926                                         Texture *texture);
927     Texture *getTextureForActiveSampler(TextureType type, size_t index);
928 
929     bool hasConstantColor(GLenum sourceRGB, GLenum destRGB) const;
930     bool hasConstantAlpha(GLenum sourceRGB, GLenum destRGB) const;
931 
932     // Functions to synchronize dirty states
933     angle::Result syncActiveTextures(const Context *context, Command command);
934     angle::Result syncTexturesInit(const Context *context, Command command);
935     angle::Result syncImagesInit(const Context *context, Command command);
936     angle::Result syncReadAttachments(const Context *context, Command command);
937     angle::Result syncDrawAttachments(const Context *context, Command command);
938     angle::Result syncReadFramebuffer(const Context *context, Command command);
939     angle::Result syncDrawFramebuffer(const Context *context, Command command);
940     angle::Result syncVertexArray(const Context *context, Command command);
941     angle::Result syncTextures(const Context *context, Command command);
942     angle::Result syncImages(const Context *context, Command command);
943     angle::Result syncSamplers(const Context *context, Command command);
944     angle::Result syncProgram(const Context *context, Command command);
945 
946     using DirtyObjectHandler = angle::Result (State::*)(const Context *context, Command command);
947 
948     static constexpr DirtyObjectHandler kDirtyObjectHandlers[DIRTY_OBJECT_MAX] = {
949         &State::syncActiveTextures,  &State::syncTexturesInit,    &State::syncImagesInit,
950         &State::syncReadAttachments, &State::syncDrawAttachments, &State::syncReadFramebuffer,
951         &State::syncDrawFramebuffer, &State::syncVertexArray,     &State::syncTextures,
952         &State::syncImages,          &State::syncSamplers,        &State::syncProgram};
953 
954     // Robust init must happen before Framebuffer init for the Vulkan back-end.
955     static_assert(DIRTY_OBJECT_ACTIVE_TEXTURES < DIRTY_OBJECT_TEXTURES_INIT, "init order");
956     static_assert(DIRTY_OBJECT_TEXTURES_INIT < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order");
957     static_assert(DIRTY_OBJECT_IMAGES_INIT < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order");
958     static_assert(DIRTY_OBJECT_DRAW_ATTACHMENTS < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order");
959     static_assert(DIRTY_OBJECT_READ_ATTACHMENTS < DIRTY_OBJECT_READ_FRAMEBUFFER, "init order");
960 
961     static_assert(DIRTY_OBJECT_ACTIVE_TEXTURES == 0, "check DIRTY_OBJECT_ACTIVE_TEXTURES index");
962     static_assert(DIRTY_OBJECT_TEXTURES_INIT == 1, "check DIRTY_OBJECT_TEXTURES_INIT index");
963     static_assert(DIRTY_OBJECT_IMAGES_INIT == 2, "check DIRTY_OBJECT_IMAGES_INIT index");
964     static_assert(DIRTY_OBJECT_READ_ATTACHMENTS == 3, "check DIRTY_OBJECT_READ_ATTACHMENTS index");
965     static_assert(DIRTY_OBJECT_DRAW_ATTACHMENTS == 4, "check DIRTY_OBJECT_DRAW_ATTACHMENTS index");
966     static_assert(DIRTY_OBJECT_READ_FRAMEBUFFER == 5, "check DIRTY_OBJECT_READ_FRAMEBUFFER index");
967     static_assert(DIRTY_OBJECT_DRAW_FRAMEBUFFER == 6, "check DIRTY_OBJECT_DRAW_FRAMEBUFFER index");
968     static_assert(DIRTY_OBJECT_VERTEX_ARRAY == 7, "check DIRTY_OBJECT_VERTEX_ARRAY index");
969     static_assert(DIRTY_OBJECT_TEXTURES == 8, "check DIRTY_OBJECT_TEXTURES index");
970     static_assert(DIRTY_OBJECT_IMAGES == 9, "check DIRTY_OBJECT_IMAGES index");
971     static_assert(DIRTY_OBJECT_SAMPLERS == 10, "check DIRTY_OBJECT_SAMPLERS index");
972     static_assert(DIRTY_OBJECT_PROGRAM == 11, "check DIRTY_OBJECT_PROGRAM index");
973 
974     // Dispatch table for buffer update functions.
975     static const angle::PackedEnumMap<BufferBinding, BufferBindingSetter> kBufferSetters;
976 
977     ContextID mID;
978 
979     EGLenum mClientType;
980     EGLenum mContextPriority;
981     bool mHasProtectedContent;
982     Version mClientVersion;
983 
984     // Caps to use for validation
985     Caps mCaps;
986     TextureCapsMap mTextureCaps;
987     Extensions mExtensions;
988     Limitations mLimitations;
989 
990     egl::ShareGroup *mShareGroup;
991 
992     // Resource managers.
993     BufferManager *mBufferManager;
994     ShaderProgramManager *mShaderProgramManager;
995     TextureManager *mTextureManager;
996     RenderbufferManager *mRenderbufferManager;
997     SamplerManager *mSamplerManager;
998     SyncManager *mSyncManager;
999     FramebufferManager *mFramebufferManager;
1000     ProgramPipelineManager *mProgramPipelineManager;
1001     MemoryObjectManager *mMemoryObjectManager;
1002     SemaphoreManager *mSemaphoreManager;
1003 
1004     ColorF mColorClearValue;
1005     GLfloat mDepthClearValue;
1006     int mStencilClearValue;
1007 
1008     RasterizerState mRasterizer;
1009     bool mScissorTest;
1010     Rectangle mScissor;
1011 
1012     BlendState mBlendState;  // Buffer zero blend state legacy struct
1013     BlendStateExt mBlendStateExt;
1014     ColorF mBlendColor;
1015     bool mSampleAlphaToCoverage;
1016     bool mSampleCoverage;
1017     GLfloat mSampleCoverageValue;
1018     bool mSampleCoverageInvert;
1019     bool mSampleMask;
1020     GLuint mMaxSampleMaskWords;
1021     std::array<GLbitfield, MAX_SAMPLE_MASK_WORDS> mSampleMaskValues;
1022     bool mIsSampleShadingEnabled;
1023     float mMinSampleShading;
1024 
1025     DepthStencilState mDepthStencil;
1026     GLint mStencilRef;
1027     GLint mStencilBackRef;
1028 
1029     GLfloat mLineWidth;
1030 
1031     GLenum mGenerateMipmapHint;
1032     GLenum mTextureFilteringHint;
1033     GLenum mFragmentShaderDerivativeHint;
1034 
1035     const bool mBindGeneratesResource;
1036     const bool mClientArraysEnabled;
1037 
1038     Rectangle mViewport;
1039     float mNearZ;
1040     float mFarZ;
1041 
1042     GLenum mClipControlOrigin;
1043     GLenum mClipControlDepth;
1044 
1045     Framebuffer *mReadFramebuffer;
1046     Framebuffer *mDrawFramebuffer;
1047     BindingPointer<Renderbuffer> mRenderbuffer;
1048     Program *mProgram;
1049     BindingPointer<ProgramPipeline> mProgramPipeline;
1050     ProgramExecutable *mExecutable;
1051 
1052     // GL_ANGLE_provoking_vertex
1053     ProvokingVertexConvention mProvokingVertex;
1054 
1055     using VertexAttribVector = std::vector<VertexAttribCurrentValueData>;
1056     VertexAttribVector mVertexAttribCurrentValues;  // From glVertexAttrib
1057     VertexArray *mVertexArray;
1058     ComponentTypeMask mCurrentValuesTypeMask;
1059 
1060     // Texture and sampler bindings
1061     GLint mActiveSampler;  // Active texture unit selector - GL_TEXTURE0
1062 
1063     TextureBindingMap mSamplerTextures;
1064 
1065     // Active Textures Cache
1066     // ---------------------
1067     // The active textures cache gives ANGLE components access to a complete array of textures
1068     // on a draw call. gl::State implements angle::Observer and watches gl::Texture for state
1069     // changes via the onSubjectStateChange method above. We update the cache before draws.
1070     // See Observer.h and the design doc linked there for more info on Subject/Observer events.
1071     //
1072     // On state change events (re-binding textures, samplers, programs etc) we clear the cache
1073     // and flag dirty bits. nullptr indicates unbound or incomplete.
1074     ActiveTexturesCache mActiveTexturesCache;
1075     std::vector<angle::ObserverBinding> mCompleteTextureBindings;
1076 
1077     ActiveTextureMask mTexturesIncompatibleWithSamplers;
1078 
1079     SamplerBindingVector mSamplers;
1080 
1081     // It would be nice to merge the image and observer binding. Same for textures.
1082     std::vector<ImageUnit> mImageUnits;
1083 
1084     ActiveQueryMap mActiveQueries;
1085 
1086     // Stores the currently bound buffer for each binding point. It has an entry for the element
1087     // array buffer but it should not be used. Instead this bind point is owned by the current
1088     // vertex array object.
1089     BoundBufferMap mBoundBuffers;
1090 
1091     BufferVector mUniformBuffers;
1092     BufferVector mAtomicCounterBuffers;
1093     BufferVector mShaderStorageBuffers;
1094 
1095     angle::BitSet<gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS> mBoundUniformBuffersMask;
1096     angle::BitSet<gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>
1097         mBoundAtomicCounterBuffersMask;
1098     angle::BitSet<gl::IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>
1099         mBoundShaderStorageBuffersMask;
1100 
1101     BindingPointer<TransformFeedback> mTransformFeedback;
1102 
1103     PixelUnpackState mUnpack;
1104     PixelPackState mPack;
1105 
1106     bool mPrimitiveRestart;
1107 
1108     Debug mDebug;
1109 
1110     bool mMultiSampling;
1111     bool mSampleAlphaToOne;
1112 
1113     GLenum mCoverageModulation;
1114 
1115     // GL_EXT_sRGB_write_control
1116     bool mFramebufferSRGB;
1117 
1118     // GL_ANGLE_robust_resource_initialization
1119     const bool mRobustResourceInit;
1120 
1121     // GL_ANGLE_program_cache_control
1122     const bool mProgramBinaryCacheEnabled;
1123 
1124     // GL_ANGLE_webgl_compatibility
1125     bool mTextureRectangleEnabled;
1126 
1127     // GL_KHR_parallel_shader_compile
1128     GLuint mMaxShaderCompilerThreads;
1129 
1130     // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance
1131     ClipDistanceEnableBits mClipDistancesEnabled;
1132 
1133     // GL_EXT_tessellation_shader
1134     GLuint mPatchVertices;
1135 
1136     // GLES1 emulation: state specific to GLES1
1137     GLES1State mGLES1State;
1138 
1139     DirtyBits mDirtyBits;
1140     mutable ExtendedDirtyBits mExtendedDirtyBits;
1141     DirtyObjects mDirtyObjects;
1142     mutable AttributesMask mDirtyCurrentValues;
1143     ActiveTextureMask mDirtyActiveTextures;
1144     ActiveTextureMask mDirtyTextures;
1145     ActiveTextureMask mDirtySamplers;
1146     ImageUnitMask mDirtyImages;
1147 
1148     // The Overlay object, used by the backend to render the overlay.
1149     const OverlayType *mOverlay;
1150 
1151     // OES_draw_buffers_indexed
1152     DrawBufferMask mBlendFuncConstantAlphaDrawBuffers;
1153     DrawBufferMask mBlendFuncConstantColorDrawBuffers;
1154     bool mNoSimultaneousConstantColorAndAlphaBlendFunc;
1155     // Whether the indexed variants of setBlend* have been called.  If so, the call to the
1156     // non-indexed variants are not no-oped.
1157     bool mSetBlendIndexedInvoked;
1158     bool mSetBlendFactorsIndexedInvoked;
1159     bool mSetBlendEquationsIndexedInvoked;
1160 
1161     // GL_EXT_primitive_bounding_box
1162     GLfloat mBoundingBoxMinX;
1163     GLfloat mBoundingBoxMinY;
1164     GLfloat mBoundingBoxMinZ;
1165     GLfloat mBoundingBoxMinW;
1166     GLfloat mBoundingBoxMaxX;
1167     GLfloat mBoundingBoxMaxY;
1168     GLfloat mBoundingBoxMaxZ;
1169     GLfloat mBoundingBoxMaxW;
1170 };
1171 
syncDirtyObjects(const Context * context,const DirtyObjects & bitset,Command command)1172 ANGLE_INLINE angle::Result State::syncDirtyObjects(const Context *context,
1173                                                    const DirtyObjects &bitset,
1174                                                    Command command)
1175 {
1176     const DirtyObjects &dirtyObjects = mDirtyObjects & bitset;
1177 
1178     for (size_t dirtyObject : dirtyObjects)
1179     {
1180         ANGLE_TRY((this->*kDirtyObjectHandlers[dirtyObject])(context, command));
1181     }
1182 
1183     mDirtyObjects &= ~dirtyObjects;
1184     return angle::Result::Continue;
1185 }
1186 
1187 }  // namespace gl
1188 
1189 #endif  // LIBANGLE_STATE_H_
1190