• 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 
601     // Sets the dirty bit for the program executable.
602     angle::Result onProgramExecutableChange(const Context *context, Program *program);
603     // Sets the dirty bit for the program pipeline executable.
604     angle::Result onProgramPipelineExecutableChange(const Context *context);
605 
606     enum DirtyBitType
607     {
608         // Note: process draw framebuffer binding first, so that other dirty bits whose effect
609         // depend on the current draw framebuffer are not processed while the old framebuffer is
610         // still bound.
611         DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING,
612         DIRTY_BIT_READ_FRAMEBUFFER_BINDING,
613         DIRTY_BIT_SCISSOR_TEST_ENABLED,
614         DIRTY_BIT_SCISSOR,
615         DIRTY_BIT_VIEWPORT,
616         DIRTY_BIT_DEPTH_RANGE,
617         DIRTY_BIT_BLEND_ENABLED,
618         DIRTY_BIT_BLEND_COLOR,
619         DIRTY_BIT_BLEND_FUNCS,
620         DIRTY_BIT_BLEND_EQUATIONS,
621         DIRTY_BIT_COLOR_MASK,
622         DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED,
623         DIRTY_BIT_SAMPLE_COVERAGE_ENABLED,
624         DIRTY_BIT_SAMPLE_COVERAGE,
625         DIRTY_BIT_SAMPLE_MASK_ENABLED,
626         DIRTY_BIT_SAMPLE_MASK,
627         DIRTY_BIT_DEPTH_TEST_ENABLED,
628         DIRTY_BIT_DEPTH_FUNC,
629         DIRTY_BIT_DEPTH_MASK,
630         DIRTY_BIT_STENCIL_TEST_ENABLED,
631         DIRTY_BIT_STENCIL_FUNCS_FRONT,
632         DIRTY_BIT_STENCIL_FUNCS_BACK,
633         DIRTY_BIT_STENCIL_OPS_FRONT,
634         DIRTY_BIT_STENCIL_OPS_BACK,
635         DIRTY_BIT_STENCIL_WRITEMASK_FRONT,
636         DIRTY_BIT_STENCIL_WRITEMASK_BACK,
637         DIRTY_BIT_CULL_FACE_ENABLED,
638         DIRTY_BIT_CULL_FACE,
639         DIRTY_BIT_FRONT_FACE,
640         DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED,
641         DIRTY_BIT_POLYGON_OFFSET,
642         DIRTY_BIT_RASTERIZER_DISCARD_ENABLED,
643         DIRTY_BIT_LINE_WIDTH,
644         DIRTY_BIT_PRIMITIVE_RESTART_ENABLED,
645         DIRTY_BIT_CLEAR_COLOR,
646         DIRTY_BIT_CLEAR_DEPTH,
647         DIRTY_BIT_CLEAR_STENCIL,
648         DIRTY_BIT_UNPACK_STATE,
649         DIRTY_BIT_UNPACK_BUFFER_BINDING,
650         DIRTY_BIT_PACK_STATE,
651         DIRTY_BIT_PACK_BUFFER_BINDING,
652         DIRTY_BIT_DITHER_ENABLED,
653         DIRTY_BIT_RENDERBUFFER_BINDING,
654         DIRTY_BIT_VERTEX_ARRAY_BINDING,
655         DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING,
656         DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING,
657         // TODO(jmadill): Fine-grained dirty bits for each index.
658         DIRTY_BIT_PROGRAM_BINDING,  // Must be before DIRTY_BIT_PROGRAM_EXECUTABLE
659         DIRTY_BIT_PROGRAM_EXECUTABLE,
660         // TODO(jmadill): Fine-grained dirty bits for each texture/sampler.
661         DIRTY_BIT_SAMPLER_BINDINGS,
662         DIRTY_BIT_TEXTURE_BINDINGS,
663         DIRTY_BIT_IMAGE_BINDINGS,
664         DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING,
665         DIRTY_BIT_UNIFORM_BUFFER_BINDINGS,
666         DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING,
667         DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING,
668         DIRTY_BIT_MULTISAMPLING,
669         DIRTY_BIT_SAMPLE_ALPHA_TO_ONE,
670         DIRTY_BIT_COVERAGE_MODULATION,                  // CHROMIUM_framebuffer_mixed_samples
671         DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE,  // GL_EXT_sRGB_write_control
672         DIRTY_BIT_CURRENT_VALUES,
673         DIRTY_BIT_PROVOKING_VERTEX,
674         DIRTY_BIT_SAMPLE_SHADING,
675         DIRTY_BIT_PATCH_VERTICES,
676         DIRTY_BIT_EXTENDED,  // clip distances, mipmap generation hint, derivative hint,
677                              // EXT_clip_control
678         DIRTY_BIT_INVALID,
679         DIRTY_BIT_MAX = DIRTY_BIT_INVALID,
680     };
681 
682     static_assert(DIRTY_BIT_MAX <= 64, "State dirty bits must be capped at 64");
683 
684     enum ExtendedDirtyBitType
685     {
686         EXTENDED_DIRTY_BIT_CLIP_CONTROL,            // EXT_clip_control
687         EXTENDED_DIRTY_BIT_CLIP_DISTANCES,          // clip distances
688         EXTENDED_DIRTY_BIT_MIPMAP_GENERATION_HINT,  // mipmap generation hint
689         EXTENDED_DIRTY_BIT_SHADER_DERIVATIVE_HINT,  // shader derivative hint
690         EXTENDED_DIRTY_BIT_INVALID,
691         EXTENDED_DIRTY_BIT_MAX = EXTENDED_DIRTY_BIT_INVALID,
692     };
693 
694     static_assert(EXTENDED_DIRTY_BIT_MAX <= 32, "State extended dirty bits must be capped at 32");
695 
696     // TODO(jmadill): Consider storing dirty objects in a list instead of by binding.
697     enum DirtyObjectType
698     {
699         DIRTY_OBJECT_ACTIVE_TEXTURES,  // Top-level dirty bit. Also see mDirtyActiveTextures.
700         DIRTY_OBJECT_TEXTURES_INIT,
701         DIRTY_OBJECT_IMAGES_INIT,
702         DIRTY_OBJECT_READ_ATTACHMENTS,
703         DIRTY_OBJECT_DRAW_ATTACHMENTS,
704         DIRTY_OBJECT_READ_FRAMEBUFFER,
705         DIRTY_OBJECT_DRAW_FRAMEBUFFER,
706         DIRTY_OBJECT_VERTEX_ARRAY,
707         DIRTY_OBJECT_TEXTURES,  // Top-level dirty bit. Also see mDirtyTextures.
708         DIRTY_OBJECT_IMAGES,    // Top-level dirty bit. Also see mDirtyImages.
709         DIRTY_OBJECT_SAMPLERS,  // Top-level dirty bit. Also see mDirtySamplers.
710         DIRTY_OBJECT_PROGRAM,
711         DIRTY_OBJECT_UNKNOWN,
712         DIRTY_OBJECT_MAX = DIRTY_OBJECT_UNKNOWN,
713     };
714 
715     using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
getDirtyBits()716     const DirtyBits &getDirtyBits() const { return mDirtyBits; }
clearDirtyBits()717     void clearDirtyBits() { mDirtyBits.reset(); }
clearDirtyBits(const DirtyBits & bitset)718     void clearDirtyBits(const DirtyBits &bitset) { mDirtyBits &= ~bitset; }
setAllDirtyBits()719     void setAllDirtyBits()
720     {
721         mDirtyBits.set();
722         mDirtyCurrentValues.set();
723     }
724 
725     using ExtendedDirtyBits = angle::BitSet32<EXTENDED_DIRTY_BIT_MAX>;
getExtendedDirtyBits()726     const ExtendedDirtyBits &getExtendedDirtyBits() const { return mExtendedDirtyBits; }
727     // TODO(https://anglebug.com/5631): Handle extended dirty bits on non-vulkan backends
728     ExtendedDirtyBits getAndResetExtendedDirtyBits() const;
clearExtendedDirtyBits()729     void clearExtendedDirtyBits() { mExtendedDirtyBits.reset(); }
730 
731     using DirtyObjects = angle::BitSet<DIRTY_OBJECT_MAX>;
clearDirtyObjects()732     void clearDirtyObjects() { mDirtyObjects.reset(); }
setAllDirtyObjects()733     void setAllDirtyObjects() { mDirtyObjects.set(); }
734     angle::Result syncDirtyObjects(const Context *context,
735                                    const DirtyObjects &bitset,
736                                    Command command);
737     angle::Result syncDirtyObject(const Context *context, GLenum target);
738     void setObjectDirty(GLenum target);
739     void setTextureDirty(size_t textureUnitIndex);
740     void setSamplerDirty(size_t samplerIndex);
741 
setReadFramebufferDirty()742     ANGLE_INLINE void setReadFramebufferDirty()
743     {
744         mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
745         mDirtyObjects.set(DIRTY_OBJECT_READ_ATTACHMENTS);
746     }
747 
setDrawFramebufferDirty()748     ANGLE_INLINE void setDrawFramebufferDirty()
749     {
750         mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
751         mDirtyObjects.set(DIRTY_OBJECT_DRAW_ATTACHMENTS);
752     }
753 
754     // This actually clears the current value dirty bits.
755     // TODO(jmadill): Pass mutable dirty bits into Impl.
756     AttributesMask getAndResetDirtyCurrentValues() const;
757 
758     void setImageUnit(const Context *context,
759                       size_t unit,
760                       Texture *texture,
761                       GLint level,
762                       GLboolean layered,
763                       GLint layer,
764                       GLenum access,
765                       GLenum format);
766 
getImageUnit(size_t unit)767     const ImageUnit &getImageUnit(size_t unit) const { return mImageUnits[unit]; }
getActiveTexturesCache()768     const ActiveTexturesCache &getActiveTexturesCache() const { return mActiveTexturesCache; }
getCurrentValuesTypeMask()769     ComponentTypeMask getCurrentValuesTypeMask() const { return mCurrentValuesTypeMask; }
770 
771     // "onActiveTextureChange" is called when a texture binding changes.
772     void onActiveTextureChange(const Context *context, size_t textureUnit);
773 
774     // "onActiveTextureStateChange" is called when the Texture changed but the binding did not.
775     void onActiveTextureStateChange(const Context *context, size_t textureUnit);
776 
777     void onImageStateChange(const Context *context, size_t unit);
778 
779     void onUniformBufferStateChange(size_t uniformBufferIndex);
780     void onAtomicCounterBufferStateChange(size_t atomicCounterBufferIndex);
781     void onShaderStorageBufferStateChange(size_t shaderStorageBufferIndex);
782 
isCurrentTransformFeedback(const TransformFeedback * tf)783     bool isCurrentTransformFeedback(const TransformFeedback *tf) const
784     {
785         return tf == mTransformFeedback.get();
786     }
isCurrentVertexArray(const VertexArray * va)787     bool isCurrentVertexArray(const VertexArray *va) const { return va == mVertexArray; }
788 
gles1()789     GLES1State &gles1() { return mGLES1State; }
gles1()790     const GLES1State &gles1() const { return mGLES1State; }
791 
792     // Helpers for setting bound buffers. They should all have the same signature.
793     // Not meant to be called externally. Used for local helpers in State.cpp.
794     template <BufferBinding Target>
795     void setGenericBufferBindingWithBit(const Context *context, Buffer *buffer);
796 
797     template <BufferBinding Target>
798     void setGenericBufferBinding(const Context *context, Buffer *buffer);
799 
800     using BufferBindingSetter = void (State::*)(const Context *, Buffer *);
801 
validateSamplerFormats()802     ANGLE_INLINE bool validateSamplerFormats() const
803     {
804         return (!mExecutable || !(mTexturesIncompatibleWithSamplers.intersects(
805                                     mExecutable->getActiveSamplersMask())));
806     }
807 
getProvokingVertex()808     ProvokingVertexConvention getProvokingVertex() const { return mProvokingVertex; }
setProvokingVertex(ProvokingVertexConvention val)809     void setProvokingVertex(ProvokingVertexConvention val)
810     {
811         mDirtyBits.set(State::DIRTY_BIT_PROVOKING_VERTEX);
812         mProvokingVertex = val;
813     }
814 
setReadFramebufferBindingDirty()815     ANGLE_INLINE void setReadFramebufferBindingDirty()
816     {
817         mDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
818     }
819 
setDrawFramebufferBindingDirty()820     ANGLE_INLINE void setDrawFramebufferBindingDirty()
821     {
822         mDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
823     }
824 
825     using ClipDistanceEnableBits = angle::BitSet32<IMPLEMENTATION_MAX_CLIP_DISTANCES>;
getEnabledClipDistances()826     const ClipDistanceEnableBits &getEnabledClipDistances() const { return mClipDistancesEnabled; }
827     void setClipDistanceEnable(int idx, bool enable);
828 
getOverlay()829     const OverlayType *getOverlay() const { return mOverlay; }
830 
831     // Not for general use.
getBufferManagerForCapture()832     const BufferManager &getBufferManagerForCapture() const { return *mBufferManager; }
getBoundBuffersForCapture()833     const BoundBufferMap &getBoundBuffersForCapture() const { return mBoundBuffers; }
getTextureManagerForCapture()834     const TextureManager &getTextureManagerForCapture() const { return *mTextureManager; }
getBoundTexturesForCapture()835     const TextureBindingMap &getBoundTexturesForCapture() const { return mSamplerTextures; }
getRenderbufferManagerForCapture()836     const RenderbufferManager &getRenderbufferManagerForCapture() const
837     {
838         return *mRenderbufferManager;
839     }
getFramebufferManagerForCapture()840     const FramebufferManager &getFramebufferManagerForCapture() const
841     {
842         return *mFramebufferManager;
843     }
getShaderProgramManagerForCapture()844     const ShaderProgramManager &getShaderProgramManagerForCapture() const
845     {
846         return *mShaderProgramManager;
847     }
getSyncManagerForCapture()848     const SyncManager &getSyncManagerForCapture() const { return *mSyncManager; }
getSamplerManagerForCapture()849     const SamplerManager &getSamplerManagerForCapture() const { return *mSamplerManager; }
getProgramPipelineManagerForCapture()850     const ProgramPipelineManager *getProgramPipelineManagerForCapture() const
851     {
852         return mProgramPipelineManager;
853     }
getSamplerBindingsForCapture()854     const SamplerBindingVector &getSamplerBindingsForCapture() const { return mSamplers; }
getActiveQueriesForCapture()855     const ActiveQueryMap &getActiveQueriesForCapture() const { return mActiveQueries; }
856     void initializeForCapture(const Context *context);
857 
hasConstantAlphaBlendFunc()858     bool hasConstantAlphaBlendFunc() const
859     {
860         return (mBlendFuncConstantAlphaDrawBuffers & mBlendStateExt.mEnabledMask).any();
861     }
862 
hasSimultaneousConstantColorAndAlphaBlendFunc()863     bool hasSimultaneousConstantColorAndAlphaBlendFunc() const
864     {
865         return (mBlendFuncConstantColorDrawBuffers & mBlendStateExt.mEnabledMask).any() &&
866                hasConstantAlphaBlendFunc();
867     }
868 
noSimultaneousConstantColorAndAlphaBlendFunc()869     bool noSimultaneousConstantColorAndAlphaBlendFunc() const
870     {
871         return mNoSimultaneousConstantColorAndAlphaBlendFunc;
872     }
873 
canEnableEarlyFragmentTestsOptimization()874     bool canEnableEarlyFragmentTestsOptimization() const
875     {
876         return !isSampleAlphaToCoverageEnabled();
877     }
878 
getOffsetBindingPointerUniformBuffers()879     const BufferVector &getOffsetBindingPointerUniformBuffers() const { return mUniformBuffers; }
880 
getOffsetBindingPointerAtomicCounterBuffers()881     const BufferVector &getOffsetBindingPointerAtomicCounterBuffers() const
882     {
883         return mAtomicCounterBuffers;
884     }
885 
getOffsetBindingPointerShaderStorageBuffers()886     const BufferVector &getOffsetBindingPointerShaderStorageBuffers() const
887     {
888         return mShaderStorageBuffers;
889     }
890 
getTexturesIncompatibleWithSamplers()891     ActiveTextureMask getTexturesIncompatibleWithSamplers() const
892     {
893         return mTexturesIncompatibleWithSamplers;
894     }
895 
isProgramBinaryCacheEnabled()896     bool isProgramBinaryCacheEnabled() const { return mProgramBinaryCacheEnabled; }
897 
isTextureRectangleEnabled()898     bool isTextureRectangleEnabled() const { return mTextureRectangleEnabled; }
899 
getBlendFuncConstantAlphaDrawBuffers()900     DrawBufferMask getBlendFuncConstantAlphaDrawBuffers() const
901     {
902         return mBlendFuncConstantAlphaDrawBuffers;
903     }
904 
getBlendFuncConstantColorDrawBuffers()905     DrawBufferMask getBlendFuncConstantColorDrawBuffers() const
906     {
907         return mBlendFuncConstantColorDrawBuffers;
908     }
909 
getImageUnits()910     const std::vector<ImageUnit> &getImageUnits() const { return mImageUnits; }
911 
912   private:
913     friend class Context;
914 
915     void unsetActiveTextures(const ActiveTextureMask &textureMask);
916     void setActiveTextureDirty(size_t textureIndex, Texture *texture);
917     void updateTextureBinding(const Context *context, size_t textureIndex, Texture *texture);
918     void updateActiveTextureStateOnSync(const Context *context,
919                                         size_t textureIndex,
920                                         const Sampler *sampler,
921                                         Texture *texture);
922     Texture *getTextureForActiveSampler(TextureType type, size_t index);
923 
924     bool hasConstantColor(GLenum sourceRGB, GLenum destRGB) const;
925     bool hasConstantAlpha(GLenum sourceRGB, GLenum destRGB) const;
926 
927     // Functions to synchronize dirty states
928     angle::Result syncActiveTextures(const Context *context, Command command);
929     angle::Result syncTexturesInit(const Context *context, Command command);
930     angle::Result syncImagesInit(const Context *context, Command command);
931     angle::Result syncReadAttachments(const Context *context, Command command);
932     angle::Result syncDrawAttachments(const Context *context, Command command);
933     angle::Result syncReadFramebuffer(const Context *context, Command command);
934     angle::Result syncDrawFramebuffer(const Context *context, Command command);
935     angle::Result syncVertexArray(const Context *context, Command command);
936     angle::Result syncTextures(const Context *context, Command command);
937     angle::Result syncImages(const Context *context, Command command);
938     angle::Result syncSamplers(const Context *context, Command command);
939     angle::Result syncProgram(const Context *context, Command command);
940 
941     using DirtyObjectHandler = angle::Result (State::*)(const Context *context, Command command);
942 
943     static constexpr DirtyObjectHandler kDirtyObjectHandlers[DIRTY_OBJECT_MAX] = {
944         &State::syncActiveTextures,  &State::syncTexturesInit,    &State::syncImagesInit,
945         &State::syncReadAttachments, &State::syncDrawAttachments, &State::syncReadFramebuffer,
946         &State::syncDrawFramebuffer, &State::syncVertexArray,     &State::syncTextures,
947         &State::syncImages,          &State::syncSamplers,        &State::syncProgram};
948 
949     // Robust init must happen before Framebuffer init for the Vulkan back-end.
950     static_assert(DIRTY_OBJECT_ACTIVE_TEXTURES < DIRTY_OBJECT_TEXTURES_INIT, "init order");
951     static_assert(DIRTY_OBJECT_TEXTURES_INIT < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order");
952     static_assert(DIRTY_OBJECT_IMAGES_INIT < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order");
953     static_assert(DIRTY_OBJECT_DRAW_ATTACHMENTS < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order");
954     static_assert(DIRTY_OBJECT_READ_ATTACHMENTS < DIRTY_OBJECT_READ_FRAMEBUFFER, "init order");
955 
956     static_assert(DIRTY_OBJECT_ACTIVE_TEXTURES == 0, "check DIRTY_OBJECT_ACTIVE_TEXTURES index");
957     static_assert(DIRTY_OBJECT_TEXTURES_INIT == 1, "check DIRTY_OBJECT_TEXTURES_INIT index");
958     static_assert(DIRTY_OBJECT_IMAGES_INIT == 2, "check DIRTY_OBJECT_IMAGES_INIT index");
959     static_assert(DIRTY_OBJECT_READ_ATTACHMENTS == 3, "check DIRTY_OBJECT_READ_ATTACHMENTS index");
960     static_assert(DIRTY_OBJECT_DRAW_ATTACHMENTS == 4, "check DIRTY_OBJECT_DRAW_ATTACHMENTS index");
961     static_assert(DIRTY_OBJECT_READ_FRAMEBUFFER == 5, "check DIRTY_OBJECT_READ_FRAMEBUFFER index");
962     static_assert(DIRTY_OBJECT_DRAW_FRAMEBUFFER == 6, "check DIRTY_OBJECT_DRAW_FRAMEBUFFER index");
963     static_assert(DIRTY_OBJECT_VERTEX_ARRAY == 7, "check DIRTY_OBJECT_VERTEX_ARRAY index");
964     static_assert(DIRTY_OBJECT_TEXTURES == 8, "check DIRTY_OBJECT_TEXTURES index");
965     static_assert(DIRTY_OBJECT_IMAGES == 9, "check DIRTY_OBJECT_IMAGES index");
966     static_assert(DIRTY_OBJECT_SAMPLERS == 10, "check DIRTY_OBJECT_SAMPLERS index");
967     static_assert(DIRTY_OBJECT_PROGRAM == 11, "check DIRTY_OBJECT_PROGRAM index");
968 
969     // Dispatch table for buffer update functions.
970     static const angle::PackedEnumMap<BufferBinding, BufferBindingSetter> kBufferSetters;
971 
972     ContextID mID;
973 
974     EGLenum mClientType;
975     EGLenum mContextPriority;
976     bool mHasProtectedContent;
977     Version mClientVersion;
978 
979     // Caps to use for validation
980     Caps mCaps;
981     TextureCapsMap mTextureCaps;
982     Extensions mExtensions;
983     Limitations mLimitations;
984 
985     egl::ShareGroup *mShareGroup;
986 
987     // Resource managers.
988     BufferManager *mBufferManager;
989     ShaderProgramManager *mShaderProgramManager;
990     TextureManager *mTextureManager;
991     RenderbufferManager *mRenderbufferManager;
992     SamplerManager *mSamplerManager;
993     SyncManager *mSyncManager;
994     FramebufferManager *mFramebufferManager;
995     ProgramPipelineManager *mProgramPipelineManager;
996     MemoryObjectManager *mMemoryObjectManager;
997     SemaphoreManager *mSemaphoreManager;
998 
999     ColorF mColorClearValue;
1000     GLfloat mDepthClearValue;
1001     int mStencilClearValue;
1002 
1003     RasterizerState mRasterizer;
1004     bool mScissorTest;
1005     Rectangle mScissor;
1006 
1007     BlendState mBlendState;  // Buffer zero blend state legacy struct
1008     BlendStateExt mBlendStateExt;
1009     ColorF mBlendColor;
1010     bool mSampleAlphaToCoverage;
1011     bool mSampleCoverage;
1012     GLfloat mSampleCoverageValue;
1013     bool mSampleCoverageInvert;
1014     bool mSampleMask;
1015     GLuint mMaxSampleMaskWords;
1016     std::array<GLbitfield, MAX_SAMPLE_MASK_WORDS> mSampleMaskValues;
1017     bool mIsSampleShadingEnabled;
1018     float mMinSampleShading;
1019 
1020     DepthStencilState mDepthStencil;
1021     GLint mStencilRef;
1022     GLint mStencilBackRef;
1023 
1024     GLfloat mLineWidth;
1025 
1026     GLenum mGenerateMipmapHint;
1027     GLenum mTextureFilteringHint;
1028     GLenum mFragmentShaderDerivativeHint;
1029 
1030     const bool mBindGeneratesResource;
1031     const bool mClientArraysEnabled;
1032 
1033     Rectangle mViewport;
1034     float mNearZ;
1035     float mFarZ;
1036 
1037     GLenum mClipControlOrigin;
1038     GLenum mClipControlDepth;
1039 
1040     Framebuffer *mReadFramebuffer;
1041     Framebuffer *mDrawFramebuffer;
1042     BindingPointer<Renderbuffer> mRenderbuffer;
1043     Program *mProgram;
1044     BindingPointer<ProgramPipeline> mProgramPipeline;
1045     ProgramExecutable *mExecutable;
1046 
1047     // GL_ANGLE_provoking_vertex
1048     ProvokingVertexConvention mProvokingVertex;
1049 
1050     using VertexAttribVector = std::vector<VertexAttribCurrentValueData>;
1051     VertexAttribVector mVertexAttribCurrentValues;  // From glVertexAttrib
1052     VertexArray *mVertexArray;
1053     ComponentTypeMask mCurrentValuesTypeMask;
1054 
1055     // Texture and sampler bindings
1056     GLint mActiveSampler;  // Active texture unit selector - GL_TEXTURE0
1057 
1058     TextureBindingMap mSamplerTextures;
1059 
1060     // Active Textures Cache
1061     // ---------------------
1062     // The active textures cache gives ANGLE components access to a complete array of textures
1063     // on a draw call. gl::State implements angle::Observer and watches gl::Texture for state
1064     // changes via the onSubjectStateChange method above. We update the cache before draws.
1065     // See Observer.h and the design doc linked there for more info on Subject/Observer events.
1066     //
1067     // On state change events (re-binding textures, samplers, programs etc) we clear the cache
1068     // and flag dirty bits. nullptr indicates unbound or incomplete.
1069     ActiveTexturesCache mActiveTexturesCache;
1070     std::vector<angle::ObserverBinding> mCompleteTextureBindings;
1071 
1072     ActiveTextureMask mTexturesIncompatibleWithSamplers;
1073 
1074     SamplerBindingVector mSamplers;
1075 
1076     // It would be nice to merge the image and observer binding. Same for textures.
1077     std::vector<ImageUnit> mImageUnits;
1078 
1079     ActiveQueryMap mActiveQueries;
1080 
1081     // Stores the currently bound buffer for each binding point. It has an entry for the element
1082     // array buffer but it should not be used. Instead this bind point is owned by the current
1083     // vertex array object.
1084     BoundBufferMap mBoundBuffers;
1085 
1086     BufferVector mUniformBuffers;
1087     BufferVector mAtomicCounterBuffers;
1088     BufferVector mShaderStorageBuffers;
1089 
1090     angle::BitSet<gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS> mBoundUniformBuffersMask;
1091     angle::BitSet<gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>
1092         mBoundAtomicCounterBuffersMask;
1093     angle::BitSet<gl::IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>
1094         mBoundShaderStorageBuffersMask;
1095 
1096     BindingPointer<TransformFeedback> mTransformFeedback;
1097 
1098     PixelUnpackState mUnpack;
1099     PixelPackState mPack;
1100 
1101     bool mPrimitiveRestart;
1102 
1103     Debug mDebug;
1104 
1105     bool mMultiSampling;
1106     bool mSampleAlphaToOne;
1107 
1108     GLenum mCoverageModulation;
1109 
1110     // GL_EXT_sRGB_write_control
1111     bool mFramebufferSRGB;
1112 
1113     // GL_ANGLE_robust_resource_initialization
1114     const bool mRobustResourceInit;
1115 
1116     // GL_ANGLE_program_cache_control
1117     const bool mProgramBinaryCacheEnabled;
1118 
1119     // GL_ANGLE_webgl_compatibility
1120     bool mTextureRectangleEnabled;
1121 
1122     // GL_KHR_parallel_shader_compile
1123     GLuint mMaxShaderCompilerThreads;
1124 
1125     // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance
1126     ClipDistanceEnableBits mClipDistancesEnabled;
1127 
1128     // GL_EXT_tessellation_shader
1129     GLuint mPatchVertices;
1130 
1131     // GLES1 emulation: state specific to GLES1
1132     GLES1State mGLES1State;
1133 
1134     DirtyBits mDirtyBits;
1135     mutable ExtendedDirtyBits mExtendedDirtyBits;
1136     DirtyObjects mDirtyObjects;
1137     mutable AttributesMask mDirtyCurrentValues;
1138     ActiveTextureMask mDirtyActiveTextures;
1139     ActiveTextureMask mDirtyTextures;
1140     ActiveTextureMask mDirtySamplers;
1141     ImageUnitMask mDirtyImages;
1142 
1143     // The Overlay object, used by the backend to render the overlay.
1144     const OverlayType *mOverlay;
1145 
1146     // OES_draw_buffers_indexed
1147     DrawBufferMask mBlendFuncConstantAlphaDrawBuffers;
1148     DrawBufferMask mBlendFuncConstantColorDrawBuffers;
1149     bool mNoSimultaneousConstantColorAndAlphaBlendFunc;
1150     // Whether the indexed variants of setBlend* have been called.  If so, the call to the
1151     // non-indexed variants are not no-oped.
1152     bool mSetBlendIndexedInvoked;
1153     bool mSetBlendFactorsIndexedInvoked;
1154     bool mSetBlendEquationsIndexedInvoked;
1155 
1156     // GL_EXT_primitive_bounding_box
1157     GLfloat mBoundingBoxMinX;
1158     GLfloat mBoundingBoxMinY;
1159     GLfloat mBoundingBoxMinZ;
1160     GLfloat mBoundingBoxMinW;
1161     GLfloat mBoundingBoxMaxX;
1162     GLfloat mBoundingBoxMaxY;
1163     GLfloat mBoundingBoxMaxZ;
1164     GLfloat mBoundingBoxMaxW;
1165 };
1166 
syncDirtyObjects(const Context * context,const DirtyObjects & bitset,Command command)1167 ANGLE_INLINE angle::Result State::syncDirtyObjects(const Context *context,
1168                                                    const DirtyObjects &bitset,
1169                                                    Command command)
1170 {
1171     const DirtyObjects &dirtyObjects = mDirtyObjects & bitset;
1172 
1173     for (size_t dirtyObject : dirtyObjects)
1174     {
1175         ANGLE_TRY((this->*kDirtyObjectHandlers[dirtyObject])(context, command));
1176     }
1177 
1178     mDirtyObjects &= ~dirtyObjects;
1179     return angle::Result::Continue;
1180 }
1181 
1182 }  // namespace gl
1183 
1184 #endif  // LIBANGLE_STATE_H_
1185