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