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