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