tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

State.h (50955B)


      1 //
      2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // State.h: Defines the State class, encapsulating raw GL state
      8 
      9 #ifndef LIBANGLE_STATE_H_
     10 #define LIBANGLE_STATE_H_
     11 
     12 #include <bitset>
     13 #include <memory>
     14 
     15 #include "common/Color.h"
     16 #include "common/angleutils.h"
     17 #include "common/bitset_utils.h"
     18 #include "libANGLE/Debug.h"
     19 #include "libANGLE/GLES1State.h"
     20 #include "libANGLE/Overlay.h"
     21 #include "libANGLE/Program.h"
     22 #include "libANGLE/ProgramExecutable.h"
     23 #include "libANGLE/ProgramPipeline.h"
     24 #include "libANGLE/RefCountObject.h"
     25 #include "libANGLE/Renderbuffer.h"
     26 #include "libANGLE/Sampler.h"
     27 #include "libANGLE/Texture.h"
     28 #include "libANGLE/TransformFeedback.h"
     29 #include "libANGLE/Version.h"
     30 #include "libANGLE/VertexArray.h"
     31 #include "libANGLE/angletypes.h"
     32 
     33 namespace egl
     34 {
     35 class ShareGroup;
     36 }  // namespace egl
     37 
     38 namespace gl
     39 {
     40 class BufferManager;
     41 struct Caps;
     42 class Context;
     43 class FramebufferManager;
     44 class MemoryObjectManager;
     45 class ProgramPipelineManager;
     46 class Query;
     47 class RenderbufferManager;
     48 class SamplerManager;
     49 class SemaphoreManager;
     50 class ShaderProgramManager;
     51 class SyncManager;
     52 class TextureManager;
     53 class VertexArray;
     54 
     55 static constexpr Version ES_1_0 = Version(1, 0);
     56 static constexpr Version ES_1_1 = Version(1, 1);
     57 static constexpr Version ES_2_0 = Version(2, 0);
     58 static constexpr Version ES_3_0 = Version(3, 0);
     59 static constexpr Version ES_3_1 = Version(3, 1);
     60 static constexpr Version ES_3_2 = Version(3, 2);
     61 
     62 template <typename T>
     63 using BufferBindingMap     = angle::PackedEnumMap<BufferBinding, T>;
     64 using BoundBufferMap       = BufferBindingMap<BindingPointer<Buffer>>;
     65 using TextureBindingVector = std::vector<BindingPointer<Texture>>;
     66 using TextureBindingMap    = angle::PackedEnumMap<TextureType, TextureBindingVector>;
     67 using ActiveQueryMap       = angle::PackedEnumMap<QueryType, BindingPointer<Query>>;
     68 
     69 class ActiveTexturesCache final : angle::NonCopyable
     70 {
     71  public:
     72    ActiveTexturesCache();
     73    ~ActiveTexturesCache();
     74 
     75    Texture *operator[](size_t textureIndex) const { return mTextures[textureIndex]; }
     76 
     77    void clear();
     78    void set(size_t textureIndex, Texture *texture);
     79    void reset(size_t textureIndex);
     80    bool empty() const;
     81    size_t size() const { return mTextures.size(); }
     82 
     83  private:
     84    ActiveTextureArray<Texture *> mTextures;
     85 };
     86 
     87 class State : angle::NonCopyable
     88 {
     89  public:
     90    State(const State *shareContextState,
     91          egl::ShareGroup *shareGroup,
     92          TextureManager *shareTextures,
     93          SemaphoreManager *shareSemaphores,
     94          const OverlayType *overlay,
     95          const EGLenum clientType,
     96          const Version &clientVersion,
     97          EGLint profileMask,
     98          bool debug,
     99          bool bindGeneratesResourceCHROMIUM,
    100          bool clientArraysEnabled,
    101          bool robustResourceInit,
    102          bool programBinaryCacheEnabled,
    103          EGLenum contextPriority,
    104          bool hasRobustAccess,
    105          bool hasProtectedContent);
    106    ~State();
    107 
    108    void initialize(Context *context);
    109    void reset(const Context *context);
    110 
    111    // Getters
    112    ContextID getContextID() const { return mID; }
    113    EGLenum getClientType() const { return mClientType; }
    114    EGLint getProfileMask() const { return mProfileMask; }
    115    EGLenum getContextPriority() const { return mContextPriority; }
    116    bool hasRobustAccess() const { return mHasRobustAccess; }
    117    bool hasProtectedContent() const { return mHasProtectedContent; }
    118    bool isDebugContext() const { return mIsDebugContext; }
    119    GLint getClientMajorVersion() const { return mClientVersion.major; }
    120    GLint getClientMinorVersion() const { return mClientVersion.minor; }
    121    const Version &getClientVersion() const { return mClientVersion; }
    122    const Caps &getCaps() const { return mCaps; }
    123    const TextureCapsMap &getTextureCaps() const { return mTextureCaps; }
    124    const Extensions &getExtensions() const { return mExtensions; }
    125    const Limitations &getLimitations() const { return mLimitations; }
    126    egl::ShareGroup *getShareGroup() const { return mShareGroup; }
    127 
    128    bool isWebGL() const { return mExtensions.webglCompatibilityANGLE; }
    129 
    130    bool isWebGL1() const { return (isWebGL() && mClientVersion.major == 2); }
    131 
    132    bool isGLES1() const { return mClientVersion < ES_2_0; }
    133 
    134    const TextureCaps &getTextureCap(GLenum internalFormat) const
    135    {
    136        return mTextureCaps.get(internalFormat);
    137    }
    138 
    139    // State chunk getters
    140    bool allActiveDrawBufferChannelsMasked() const;
    141    bool anyActiveDrawBufferChannelMasked() const;
    142    const RasterizerState &getRasterizerState() const;
    143    const BlendState &getBlendState() const { return mBlendState; }
    144    const BlendStateExt &getBlendStateExt() const { return mBlendStateExt; }
    145    const DepthStencilState &getDepthStencilState() const;
    146 
    147    // Clear behavior setters & state parameter block generation function
    148    void setColorClearValue(float red, float green, float blue, float alpha);
    149    void setDepthClearValue(float depth);
    150    void setStencilClearValue(int stencil);
    151 
    152    const ColorF &getColorClearValue() const { return mColorClearValue; }
    153    float getDepthClearValue() const { return mDepthClearValue; }
    154    int getStencilClearValue() const { return mStencilClearValue; }
    155 
    156    // Write mask manipulation
    157    void setColorMask(bool red, bool green, bool blue, bool alpha);
    158    void setColorMaskIndexed(bool red, bool green, bool blue, bool alpha, GLuint index);
    159    void setDepthMask(bool mask);
    160 
    161    // Discard toggle & query
    162    bool isRasterizerDiscardEnabled() const { return mRasterizer.rasterizerDiscard; }
    163    void setRasterizerDiscard(bool enabled);
    164 
    165    // Primitive restart
    166    bool isPrimitiveRestartEnabled() const { return mPrimitiveRestart; }
    167    void setPrimitiveRestart(bool enabled);
    168 
    169    // Face culling state manipulation
    170    bool isCullFaceEnabled() const { return mRasterizer.cullFace; }
    171    void setCullFace(bool enabled);
    172    void setCullMode(CullFaceMode mode);
    173    void setFrontFace(GLenum front);
    174 
    175    // Depth test state manipulation
    176    bool isDepthTestEnabled() const { return mDepthStencil.depthTest; }
    177    bool isDepthWriteEnabled() const { return mDepthStencil.depthTest && mDepthStencil.depthMask; }
    178    void setDepthTest(bool enabled);
    179    void setDepthFunc(GLenum depthFunc);
    180    void setDepthRange(float zNear, float zFar);
    181    float getNearPlane() const { return mNearZ; }
    182    float getFarPlane() const { return mFarZ; }
    183 
    184    // Clip control extension
    185    void setClipControl(GLenum origin, GLenum depth);
    186    bool isClipControlDepthZeroToOne() const { return mClipControlDepth == GL_ZERO_TO_ONE_EXT; }
    187    gl::ClipSpaceOrigin getClipSpaceOrigin() const
    188    {
    189        return mClipControlOrigin == GL_UPPER_LEFT_EXT ? ClipSpaceOrigin::UpperLeft
    190                                                       : ClipSpaceOrigin::LowerLeft;
    191    }
    192 
    193    // Blend state manipulation
    194    bool isBlendEnabled() const { return mBlendStateExt.getEnabledMask().test(0); }
    195    bool isBlendEnabledIndexed(GLuint index) const
    196    {
    197        ASSERT(static_cast<size_t>(index) < mBlendStateExt.getDrawBufferCount());
    198        return mBlendStateExt.getEnabledMask().test(index);
    199    }
    200    DrawBufferMask getBlendEnabledDrawBufferMask() const { return mBlendStateExt.getEnabledMask(); }
    201    void setBlend(bool enabled);
    202    void setBlendIndexed(bool enabled, GLuint index);
    203    void setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha);
    204    void setBlendFactorsIndexed(GLenum sourceRGB,
    205                                GLenum destRGB,
    206                                GLenum sourceAlpha,
    207                                GLenum destAlpha,
    208                                GLuint index);
    209    void setBlendColor(float red, float green, float blue, float alpha);
    210    void setBlendEquation(GLenum rgbEquation, GLenum alphaEquation);
    211    void setBlendEquationIndexed(GLenum rgbEquation, GLenum alphaEquation, GLuint index);
    212    const ColorF &getBlendColor() const { return mBlendColor; }
    213 
    214    // Stencil state maniupulation
    215    bool isStencilTestEnabled() const { return mDepthStencil.stencilTest; }
    216    void setStencilTest(bool enabled);
    217    void setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask);
    218    void setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask);
    219    void setStencilWritemask(GLuint stencilWritemask);
    220    void setStencilBackWritemask(GLuint stencilBackWritemask);
    221    void setStencilOperations(GLenum stencilFail,
    222                              GLenum stencilPassDepthFail,
    223                              GLenum stencilPassDepthPass);
    224    void setStencilBackOperations(GLenum stencilBackFail,
    225                                  GLenum stencilBackPassDepthFail,
    226                                  GLenum stencilBackPassDepthPass);
    227    GLint getStencilRef() const { return mStencilRef; }
    228    GLint getStencilBackRef() const { return mStencilBackRef; }
    229 
    230    // Depth bias/polygon offset state manipulation
    231    bool isPolygonOffsetFillEnabled() const { return mRasterizer.polygonOffsetFill; }
    232    void setPolygonOffsetFill(bool enabled);
    233    void setPolygonOffsetParams(GLfloat factor, GLfloat units);
    234 
    235    // Multisample coverage state manipulation
    236    bool isSampleAlphaToCoverageEnabled() const { return mSampleAlphaToCoverage; }
    237    void setSampleAlphaToCoverage(bool enabled);
    238    bool isSampleCoverageEnabled() const { return mSampleCoverage; }
    239    void setSampleCoverage(bool enabled);
    240    void setSampleCoverageParams(GLclampf value, bool invert);
    241    GLclampf getSampleCoverageValue() const { return mSampleCoverageValue; }
    242    bool getSampleCoverageInvert() const { return mSampleCoverageInvert; }
    243 
    244    // Multisample mask state manipulation.
    245    bool isSampleMaskEnabled() const { return mSampleMask; }
    246    void setSampleMaskEnabled(bool enabled);
    247    void setSampleMaskParams(GLuint maskNumber, GLbitfield mask);
    248    GLbitfield getSampleMaskWord(GLuint maskNumber) const
    249    {
    250        ASSERT(maskNumber < mMaxSampleMaskWords);
    251        return mSampleMaskValues[maskNumber];
    252    }
    253    SampleMaskArray<GLbitfield> getSampleMaskValues() const { return mSampleMaskValues; }
    254    GLuint getMaxSampleMaskWords() const { return mMaxSampleMaskWords; }
    255 
    256    // Multisampling/alpha to one manipulation.
    257    void setSampleAlphaToOne(bool enabled);
    258    bool isSampleAlphaToOneEnabled() const { return mSampleAlphaToOne; }
    259    void setMultisampling(bool enabled);
    260    bool isMultisamplingEnabled() const { return mMultiSampling; }
    261 
    262    void setSampleShading(bool enabled);
    263    bool isSampleShadingEnabled() const { return mIsSampleShadingEnabled; }
    264    void setMinSampleShading(float value);
    265    float getMinSampleShading() const { return mMinSampleShading; }
    266 
    267    // Scissor test state toggle & query
    268    bool isScissorTestEnabled() const { return mScissorTest; }
    269    void setScissorTest(bool enabled);
    270    void setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height);
    271    const Rectangle &getScissor() const { return mScissor; }
    272 
    273    // Dither state toggle & query
    274    bool isDitherEnabled() const { return mRasterizer.dither; }
    275    void setDither(bool enabled);
    276 
    277    // Generic state toggle & query
    278    void setEnableFeature(GLenum feature, bool enabled);
    279    void setEnableFeatureIndexed(GLenum feature, bool enabled, GLuint index);
    280    bool getEnableFeature(GLenum feature) const;
    281    bool getEnableFeatureIndexed(GLenum feature, GLuint index) const;
    282 
    283    // Line width state setter
    284    void setLineWidth(GLfloat width);
    285    float getLineWidth() const { return mLineWidth; }
    286 
    287    // Hint setters
    288    void setGenerateMipmapHint(GLenum hint);
    289    GLenum getGenerateMipmapHint() const;
    290    void setTextureFilteringHint(GLenum hint);
    291    GLenum getTextureFilteringHint() const;
    292    GLenum getFragmentShaderDerivativeHint() const { return mFragmentShaderDerivativeHint; }
    293    void setFragmentShaderDerivativeHint(GLenum hint);
    294 
    295    // GL_CHROMIUM_bind_generates_resource
    296    bool isBindGeneratesResourceEnabled() const { return mBindGeneratesResource; }
    297 
    298    // GL_ANGLE_client_arrays
    299    bool areClientArraysEnabled() const { return mClientArraysEnabled; }
    300 
    301    // Viewport state setter/getter
    302    void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);
    303    const Rectangle &getViewport() const { return mViewport; }
    304 
    305    // Texture binding & active texture unit manipulation
    306    void setActiveSampler(unsigned int active);
    307    unsigned int getActiveSampler() const { return static_cast<unsigned int>(mActiveSampler); }
    308 
    309    void setSamplerTexture(const Context *context, TextureType type, Texture *texture);
    310    Texture *getTargetTexture(TextureType type) const;
    311 
    312    Texture *getSamplerTexture(unsigned int sampler, TextureType type) const
    313    {
    314        ASSERT(sampler < mSamplerTextures[type].size());
    315        return mSamplerTextures[type][sampler].get();
    316    }
    317 
    318    TextureID getSamplerTextureId(unsigned int sampler, TextureType type) const;
    319    void detachTexture(const Context *context, const TextureMap &zeroTextures, TextureID texture);
    320    void initializeZeroTextures(const Context *context, const TextureMap &zeroTextures);
    321 
    322    void invalidateTextureBindings(TextureType type);
    323 
    324    // Sampler object binding manipulation
    325    void setSamplerBinding(const Context *context, GLuint textureUnit, Sampler *sampler);
    326    SamplerID getSamplerId(GLuint textureUnit) const
    327    {
    328        ASSERT(textureUnit < mSamplers.size());
    329        return mSamplers[textureUnit].id();
    330    }
    331 
    332    Sampler *getSampler(GLuint textureUnit) const { return mSamplers[textureUnit].get(); }
    333 
    334    const SamplerBindingVector &getSamplers() const { return mSamplers; }
    335 
    336    void detachSampler(const Context *context, SamplerID sampler);
    337 
    338    // Renderbuffer binding manipulation
    339    void setRenderbufferBinding(const Context *context, Renderbuffer *renderbuffer);
    340    RenderbufferID getRenderbufferId() const { return mRenderbuffer.id(); }
    341    Renderbuffer *getCurrentRenderbuffer() const { return mRenderbuffer.get(); }
    342    void detachRenderbuffer(const Context *context, RenderbufferID renderbuffer);
    343 
    344    // Framebuffer binding manipulation
    345    void setReadFramebufferBinding(Framebuffer *framebuffer);
    346    void setDrawFramebufferBinding(Framebuffer *framebuffer);
    347    Framebuffer *getTargetFramebuffer(GLenum target) const;
    348    Framebuffer *getReadFramebuffer() const { return mReadFramebuffer; }
    349    Framebuffer *getDrawFramebuffer() const { return mDrawFramebuffer; }
    350    Framebuffer *getDefaultFramebuffer() const;
    351 
    352    bool removeReadFramebufferBinding(FramebufferID framebuffer);
    353    bool removeDrawFramebufferBinding(FramebufferID framebuffer);
    354 
    355    // Vertex array object binding manipulation
    356    void setVertexArrayBinding(const Context *context, VertexArray *vertexArray);
    357    bool removeVertexArrayBinding(const Context *context, VertexArrayID vertexArray);
    358    VertexArrayID getVertexArrayId() const;
    359 
    360    VertexArray *getVertexArray() const
    361    {
    362        ASSERT(mVertexArray != nullptr);
    363        return mVertexArray;
    364    }
    365 
    366    // QCOM_shading_rate helpers
    367    void setShadingRate(GLenum rate);
    368    ShadingRate getShadingRate() const { return mShadingRate; }
    369 
    370    // If both a Program and a ProgramPipeline are bound, the Program will
    371    // always override the ProgramPipeline.
    372    ProgramExecutable *getProgramExecutable() const { return mExecutable; }
    373    ProgramExecutable *getLinkedProgramExecutable(const Context *context) const
    374    {
    375        if (mProgram)
    376        {
    377            mProgram->resolveLink(context);
    378        }
    379        else if (mProgramPipeline.get())
    380        {
    381            mProgramPipeline->resolveLink(context);
    382        }
    383        return mExecutable;
    384    }
    385 
    386    // Program binding manipulation
    387    angle::Result setProgram(const Context *context, Program *newProgram);
    388 
    389    Program *getProgram() const
    390    {
    391        ASSERT(!mProgram || !mProgram->isLinking());
    392        return mProgram;
    393    }
    394 
    395    Program *getLinkedProgram(const Context *context) const
    396    {
    397        if (mProgram)
    398        {
    399            mProgram->resolveLink(context);
    400        }
    401        return mProgram;
    402    }
    403 
    404    ProgramPipeline *getProgramPipeline() const { return mProgramPipeline.get(); }
    405 
    406    ProgramPipeline *getLinkedProgramPipeline(const Context *context) const
    407    {
    408        if (mProgramPipeline.get())
    409        {
    410            mProgramPipeline->resolveLink(context);
    411        }
    412        return mProgramPipeline.get();
    413    }
    414 
    415    // Transform feedback object (not buffer) binding manipulation
    416    void setTransformFeedbackBinding(const Context *context, TransformFeedback *transformFeedback);
    417    TransformFeedback *getCurrentTransformFeedback() const { return mTransformFeedback.get(); }
    418 
    419    ANGLE_INLINE bool isTransformFeedbackActive() const
    420    {
    421        TransformFeedback *curTransformFeedback = mTransformFeedback.get();
    422        return curTransformFeedback && curTransformFeedback->isActive();
    423    }
    424    ANGLE_INLINE bool isTransformFeedbackActiveUnpaused() const
    425    {
    426        TransformFeedback *curTransformFeedback = mTransformFeedback.get();
    427        return curTransformFeedback && curTransformFeedback->isActive() &&
    428               !curTransformFeedback->isPaused();
    429    }
    430 
    431    bool removeTransformFeedbackBinding(const Context *context,
    432                                        TransformFeedbackID transformFeedback);
    433 
    434    // Query binding manipulation
    435    bool isQueryActive(QueryType type) const;
    436    bool isQueryActive(Query *query) const;
    437    void setActiveQuery(const Context *context, QueryType type, Query *query);
    438    QueryID getActiveQueryId(QueryType type) const;
    439    Query *getActiveQuery(QueryType type) const;
    440 
    441    // Program Pipeline binding manipulation
    442    angle::Result setProgramPipelineBinding(const Context *context, ProgramPipeline *pipeline);
    443    void detachProgramPipeline(const Context *context, ProgramPipelineID pipeline);
    444 
    445    //// Typed buffer binding point manipulation ////
    446    ANGLE_INLINE void setBufferBinding(const Context *context, BufferBinding target, Buffer *buffer)
    447    {
    448        (this->*(kBufferSetters[target]))(context, buffer);
    449    }
    450 
    451    ANGLE_INLINE Buffer *getTargetBuffer(BufferBinding target) const
    452    {
    453        switch (target)
    454        {
    455            case BufferBinding::ElementArray:
    456                return getVertexArray()->getElementArrayBuffer();
    457            default:
    458                return mBoundBuffers[target].get();
    459        }
    460    }
    461 
    462    ANGLE_INLINE Buffer *getArrayBuffer() const { return getTargetBuffer(BufferBinding::Array); }
    463 
    464    angle::Result setIndexedBufferBinding(const Context *context,
    465                                          BufferBinding target,
    466                                          GLuint index,
    467                                          Buffer *buffer,
    468                                          GLintptr offset,
    469                                          GLsizeiptr size);
    470 
    471    size_t getAtomicCounterBufferCount() const { return mAtomicCounterBuffers.size(); }
    472 
    473    ANGLE_INLINE bool hasValidAtomicCounterBuffer() const
    474    {
    475        return mBoundAtomicCounterBuffersMask.any();
    476    }
    477 
    478    const OffsetBindingPointer<Buffer> &getIndexedUniformBuffer(size_t index) const;
    479    const OffsetBindingPointer<Buffer> &getIndexedAtomicCounterBuffer(size_t index) const;
    480    const OffsetBindingPointer<Buffer> &getIndexedShaderStorageBuffer(size_t index) const;
    481 
    482    const angle::BitSet<gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS> &getUniformBuffersMask()
    483        const
    484    {
    485        return mBoundUniformBuffersMask;
    486    }
    487    const angle::BitSet<gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>
    488        &getAtomicCounterBuffersMask() const
    489    {
    490        return mBoundAtomicCounterBuffersMask;
    491    }
    492    const angle::BitSet<gl::IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>
    493        &getShaderStorageBuffersMask() const
    494    {
    495        return mBoundShaderStorageBuffersMask;
    496    }
    497 
    498    // Detach a buffer from all bindings
    499    angle::Result detachBuffer(Context *context, const Buffer *buffer);
    500 
    501    // Vertex attrib manipulation
    502    void setEnableVertexAttribArray(unsigned int attribNum, bool enabled);
    503    void setVertexAttribf(GLuint index, const GLfloat values[4]);
    504    void setVertexAttribu(GLuint index, const GLuint values[4]);
    505    void setVertexAttribi(GLuint index, const GLint values[4]);
    506 
    507    ANGLE_INLINE void setVertexAttribPointer(const Context *context,
    508                                             unsigned int attribNum,
    509                                             Buffer *boundBuffer,
    510                                             GLint size,
    511                                             VertexAttribType type,
    512                                             bool normalized,
    513                                             GLsizei stride,
    514                                             const void *pointer)
    515    {
    516        mVertexArray->setVertexAttribPointer(context, attribNum, boundBuffer, size, type,
    517                                             normalized, stride, pointer);
    518        mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
    519    }
    520 
    521    ANGLE_INLINE void setVertexAttribIPointer(const Context *context,
    522                                              unsigned int attribNum,
    523                                              Buffer *boundBuffer,
    524                                              GLint size,
    525                                              VertexAttribType type,
    526                                              GLsizei stride,
    527                                              const void *pointer)
    528    {
    529        mVertexArray->setVertexAttribIPointer(context, attribNum, boundBuffer, size, type, stride,
    530                                              pointer);
    531        mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
    532    }
    533 
    534    void setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor);
    535    const VertexAttribCurrentValueData &getVertexAttribCurrentValue(size_t attribNum) const
    536    {
    537        ASSERT(attribNum < mVertexAttribCurrentValues.size());
    538        return mVertexAttribCurrentValues[attribNum];
    539    }
    540 
    541    const std::vector<VertexAttribCurrentValueData> &getVertexAttribCurrentValues() const
    542    {
    543        return mVertexAttribCurrentValues;
    544    }
    545 
    546    const void *getVertexAttribPointer(unsigned int attribNum) const;
    547 
    548    void bindVertexBuffer(const Context *context,
    549                          GLuint bindingIndex,
    550                          Buffer *boundBuffer,
    551                          GLintptr offset,
    552                          GLsizei stride);
    553    void setVertexAttribFormat(GLuint attribIndex,
    554                               GLint size,
    555                               VertexAttribType type,
    556                               bool normalized,
    557                               bool pureInteger,
    558                               GLuint relativeOffset);
    559 
    560    void setVertexAttribBinding(const Context *context, GLuint attribIndex, GLuint bindingIndex)
    561    {
    562        mVertexArray->setVertexAttribBinding(context, attribIndex, bindingIndex);
    563        mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
    564    }
    565 
    566    void setVertexBindingDivisor(const Context *context, GLuint bindingIndex, GLuint divisor);
    567 
    568    // Pixel pack state manipulation
    569    void setPackAlignment(GLint alignment);
    570    GLint getPackAlignment() const { return mPack.alignment; }
    571    void setPackReverseRowOrder(bool reverseRowOrder);
    572    bool getPackReverseRowOrder() const { return mPack.reverseRowOrder; }
    573    void setPackRowLength(GLint rowLength);
    574    GLint getPackRowLength() const { return mPack.rowLength; }
    575    void setPackSkipRows(GLint skipRows);
    576    GLint getPackSkipRows() const { return mPack.skipRows; }
    577    void setPackSkipPixels(GLint skipPixels);
    578    GLint getPackSkipPixels() const { return mPack.skipPixels; }
    579    const PixelPackState &getPackState() const { return mPack; }
    580    PixelPackState &getPackState() { return mPack; }
    581 
    582    // Pixel unpack state manipulation
    583    void setUnpackAlignment(GLint alignment);
    584    GLint getUnpackAlignment() const { return mUnpack.alignment; }
    585    void setUnpackRowLength(GLint rowLength);
    586    GLint getUnpackRowLength() const { return mUnpack.rowLength; }
    587    void setUnpackImageHeight(GLint imageHeight);
    588    GLint getUnpackImageHeight() const { return mUnpack.imageHeight; }
    589    void setUnpackSkipImages(GLint skipImages);
    590    GLint getUnpackSkipImages() const { return mUnpack.skipImages; }
    591    void setUnpackSkipRows(GLint skipRows);
    592    GLint getUnpackSkipRows() const { return mUnpack.skipRows; }
    593    void setUnpackSkipPixels(GLint skipPixels);
    594    GLint getUnpackSkipPixels() const { return mUnpack.skipPixels; }
    595    const PixelUnpackState &getUnpackState() const { return mUnpack; }
    596    PixelUnpackState &getUnpackState() { return mUnpack; }
    597 
    598    // Debug state
    599    const Debug &getDebug() const { return mDebug; }
    600    Debug &getDebug() { return mDebug; }
    601 
    602    // CHROMIUM_framebuffer_mixed_samples coverage modulation
    603    void setCoverageModulation(GLenum components);
    604    GLenum getCoverageModulation() const { return mCoverageModulation; }
    605 
    606    // GL_EXT_sRGB_write_control
    607    void setFramebufferSRGB(bool sRGB);
    608    bool getFramebufferSRGB() const { return mFramebufferSRGB; }
    609 
    610    // GL_KHR_parallel_shader_compile
    611    void setMaxShaderCompilerThreads(GLuint count);
    612    GLuint getMaxShaderCompilerThreads() const { return mMaxShaderCompilerThreads; }
    613 
    614    // GL_EXT_tessellation_shader
    615    void setPatchVertices(GLuint value);
    616    GLuint getPatchVertices() const { return mPatchVertices; }
    617 
    618    // GL_ANGLE_shader_pixel_local_storage
    619    void setPixelLocalStorageActive(bool active);
    620    bool getPixelLocalStorageActive() const { return mPixelLocalStorageActive; }
    621 
    622    // State query functions
    623    void getBooleanv(GLenum pname, GLboolean *params) const;
    624    void getFloatv(GLenum pname, GLfloat *params) const;
    625    angle::Result getIntegerv(const Context *context, GLenum pname, GLint *params) const;
    626    void getPointerv(const Context *context, GLenum pname, void **params) const;
    627    void getIntegeri_v(const Context *context, GLenum target, GLuint index, GLint *data) const;
    628    void getInteger64i_v(GLenum target, GLuint index, GLint64 *data) const;
    629    void getBooleani_v(GLenum target, GLuint index, GLboolean *data) const;
    630 
    631    bool isRobustResourceInitEnabled() const { return mRobustResourceInit; }
    632 
    633    bool isDrawFramebufferBindingDirty() const
    634    {
    635        return mDirtyBits.test(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
    636    }
    637 
    638    // Sets the dirty bit for the program executable.
    639    angle::Result onProgramExecutableChange(const Context *context, Program *program);
    640    // Sets the dirty bit for the program pipeline executable.
    641    angle::Result onProgramPipelineExecutableChange(const Context *context);
    642 
    643    enum DirtyBitType
    644    {
    645        // Note: process draw framebuffer binding first, so that other dirty bits whose effect
    646        // depend on the current draw framebuffer are not processed while the old framebuffer is
    647        // still bound.
    648        DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING,
    649        DIRTY_BIT_READ_FRAMEBUFFER_BINDING,
    650        DIRTY_BIT_SCISSOR_TEST_ENABLED,
    651        DIRTY_BIT_SCISSOR,
    652        DIRTY_BIT_VIEWPORT,
    653        DIRTY_BIT_DEPTH_RANGE,
    654        DIRTY_BIT_BLEND_ENABLED,
    655        DIRTY_BIT_BLEND_COLOR,
    656        DIRTY_BIT_BLEND_FUNCS,
    657        DIRTY_BIT_BLEND_EQUATIONS,
    658        DIRTY_BIT_COLOR_MASK,
    659        DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED,
    660        DIRTY_BIT_SAMPLE_COVERAGE_ENABLED,
    661        DIRTY_BIT_SAMPLE_COVERAGE,
    662        DIRTY_BIT_SAMPLE_MASK_ENABLED,
    663        DIRTY_BIT_SAMPLE_MASK,
    664        DIRTY_BIT_DEPTH_TEST_ENABLED,
    665        DIRTY_BIT_DEPTH_FUNC,
    666        DIRTY_BIT_DEPTH_MASK,
    667        DIRTY_BIT_STENCIL_TEST_ENABLED,
    668        DIRTY_BIT_STENCIL_FUNCS_FRONT,
    669        DIRTY_BIT_STENCIL_FUNCS_BACK,
    670        DIRTY_BIT_STENCIL_OPS_FRONT,
    671        DIRTY_BIT_STENCIL_OPS_BACK,
    672        DIRTY_BIT_STENCIL_WRITEMASK_FRONT,
    673        DIRTY_BIT_STENCIL_WRITEMASK_BACK,
    674        DIRTY_BIT_CULL_FACE_ENABLED,
    675        DIRTY_BIT_CULL_FACE,
    676        DIRTY_BIT_FRONT_FACE,
    677        DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED,
    678        DIRTY_BIT_POLYGON_OFFSET,
    679        DIRTY_BIT_RASTERIZER_DISCARD_ENABLED,
    680        DIRTY_BIT_LINE_WIDTH,
    681        DIRTY_BIT_PRIMITIVE_RESTART_ENABLED,
    682        DIRTY_BIT_CLEAR_COLOR,
    683        DIRTY_BIT_CLEAR_DEPTH,
    684        DIRTY_BIT_CLEAR_STENCIL,
    685        DIRTY_BIT_UNPACK_STATE,
    686        DIRTY_BIT_UNPACK_BUFFER_BINDING,
    687        DIRTY_BIT_PACK_STATE,
    688        DIRTY_BIT_PACK_BUFFER_BINDING,
    689        DIRTY_BIT_DITHER_ENABLED,
    690        DIRTY_BIT_RENDERBUFFER_BINDING,
    691        DIRTY_BIT_VERTEX_ARRAY_BINDING,
    692        DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING,
    693        DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING,
    694        // TODO(jmadill): Fine-grained dirty bits for each index.
    695        DIRTY_BIT_PROGRAM_BINDING,  // Must be before DIRTY_BIT_PROGRAM_EXECUTABLE
    696        DIRTY_BIT_PROGRAM_EXECUTABLE,
    697        // TODO(jmadill): Fine-grained dirty bits for each texture/sampler.
    698        DIRTY_BIT_SAMPLER_BINDINGS,
    699        DIRTY_BIT_TEXTURE_BINDINGS,
    700        DIRTY_BIT_IMAGE_BINDINGS,
    701        DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING,
    702        DIRTY_BIT_UNIFORM_BUFFER_BINDINGS,
    703        DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING,
    704        DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING,
    705        DIRTY_BIT_MULTISAMPLING,
    706        DIRTY_BIT_SAMPLE_ALPHA_TO_ONE,
    707        DIRTY_BIT_COVERAGE_MODULATION,                  // CHROMIUM_framebuffer_mixed_samples
    708        DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE,  // GL_EXT_sRGB_write_control
    709        DIRTY_BIT_CURRENT_VALUES,
    710        DIRTY_BIT_PROVOKING_VERTEX,
    711        DIRTY_BIT_SAMPLE_SHADING,
    712        DIRTY_BIT_PATCH_VERTICES,
    713        DIRTY_BIT_EXTENDED,  // clip distances, mipmap generation hint, derivative hint,
    714                             // EXT_clip_control
    715        DIRTY_BIT_INVALID,
    716        DIRTY_BIT_MAX = DIRTY_BIT_INVALID,
    717    };
    718 
    719    static_assert(DIRTY_BIT_MAX <= 64, "State dirty bits must be capped at 64");
    720 
    721    enum ExtendedDirtyBitType
    722    {
    723        EXTENDED_DIRTY_BIT_CLIP_CONTROL,            // EXT_clip_control
    724        EXTENDED_DIRTY_BIT_CLIP_DISTANCES,          // clip distances
    725        EXTENDED_DIRTY_BIT_MIPMAP_GENERATION_HINT,  // mipmap generation hint
    726        EXTENDED_DIRTY_BIT_SHADER_DERIVATIVE_HINT,  // shader derivative hint
    727        EXTENDED_DIRTY_BIT_SHADING_RATE,            // QCOM_shading_rate
    728        EXTENDED_DIRTY_BIT_LOGIC_OP_ENABLED,        // ANGLE_logic_op
    729        EXTENDED_DIRTY_BIT_LOGIC_OP,                // ANGLE_logic_op
    730        EXTENDED_DIRTY_BIT_INVALID,
    731        EXTENDED_DIRTY_BIT_MAX = EXTENDED_DIRTY_BIT_INVALID,
    732    };
    733 
    734    static_assert(EXTENDED_DIRTY_BIT_MAX <= 32, "State extended dirty bits must be capped at 32");
    735 
    736    // TODO(jmadill): Consider storing dirty objects in a list instead of by binding.
    737    enum DirtyObjectType
    738    {
    739        DIRTY_OBJECT_ACTIVE_TEXTURES,  // Top-level dirty bit. Also see mDirtyActiveTextures.
    740        DIRTY_OBJECT_TEXTURES_INIT,
    741        DIRTY_OBJECT_IMAGES_INIT,
    742        DIRTY_OBJECT_READ_ATTACHMENTS,
    743        DIRTY_OBJECT_DRAW_ATTACHMENTS,
    744        DIRTY_OBJECT_READ_FRAMEBUFFER,
    745        DIRTY_OBJECT_DRAW_FRAMEBUFFER,
    746        DIRTY_OBJECT_VERTEX_ARRAY,
    747        DIRTY_OBJECT_TEXTURES,  // Top-level dirty bit. Also see mDirtyTextures.
    748        DIRTY_OBJECT_IMAGES,    // Top-level dirty bit. Also see mDirtyImages.
    749        DIRTY_OBJECT_SAMPLERS,  // Top-level dirty bit. Also see mDirtySamplers.
    750        DIRTY_OBJECT_PROGRAM,
    751        DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT,
    752        DIRTY_OBJECT_UNKNOWN,
    753        DIRTY_OBJECT_MAX = DIRTY_OBJECT_UNKNOWN,
    754    };
    755 
    756    using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
    757    const DirtyBits &getDirtyBits() const { return mDirtyBits; }
    758    void clearDirtyBits() { mDirtyBits.reset(); }
    759    void clearDirtyBits(const DirtyBits &bitset) { mDirtyBits &= ~bitset; }
    760    void setAllDirtyBits()
    761    {
    762        mDirtyBits.set();
    763        mExtendedDirtyBits.set();
    764        mDirtyCurrentValues.set();
    765    }
    766 
    767    using ExtendedDirtyBits = angle::BitSet32<EXTENDED_DIRTY_BIT_MAX>;
    768    const ExtendedDirtyBits &getExtendedDirtyBits() const { return mExtendedDirtyBits; }
    769    // TODO(https://anglebug.com/5631): Handle extended dirty bits on non-vulkan backends
    770    ExtendedDirtyBits getAndResetExtendedDirtyBits() const;
    771    void clearExtendedDirtyBits() { mExtendedDirtyBits.reset(); }
    772 
    773    using DirtyObjects = angle::BitSet<DIRTY_OBJECT_MAX>;
    774    void clearDirtyObjects() { mDirtyObjects.reset(); }
    775    void setAllDirtyObjects() { mDirtyObjects.set(); }
    776    angle::Result syncDirtyObjects(const Context *context,
    777                                   const DirtyObjects &bitset,
    778                                   Command command);
    779    angle::Result syncDirtyObject(const Context *context, GLenum target);
    780    void setObjectDirty(GLenum target);
    781    void setTextureDirty(size_t textureUnitIndex);
    782    void setSamplerDirty(size_t samplerIndex);
    783 
    784    ANGLE_INLINE void setReadFramebufferDirty()
    785    {
    786        mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
    787        mDirtyObjects.set(DIRTY_OBJECT_READ_ATTACHMENTS);
    788    }
    789 
    790    ANGLE_INLINE void setDrawFramebufferDirty()
    791    {
    792        mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
    793        mDirtyObjects.set(DIRTY_OBJECT_DRAW_ATTACHMENTS);
    794    }
    795 
    796    // This actually clears the current value dirty bits.
    797    // TODO(jmadill): Pass mutable dirty bits into Impl.
    798    AttributesMask getAndResetDirtyCurrentValues() const;
    799 
    800    void setImageUnit(const Context *context,
    801                      size_t unit,
    802                      Texture *texture,
    803                      GLint level,
    804                      GLboolean layered,
    805                      GLint layer,
    806                      GLenum access,
    807                      GLenum format);
    808 
    809    const ImageUnit &getImageUnit(size_t unit) const { return mImageUnits[unit]; }
    810    const ActiveTexturesCache &getActiveTexturesCache() const { return mActiveTexturesCache; }
    811    ComponentTypeMask getCurrentValuesTypeMask() const { return mCurrentValuesTypeMask; }
    812 
    813    // "onActiveTextureChange" is called when a texture binding changes.
    814    void onActiveTextureChange(const Context *context, size_t textureUnit);
    815 
    816    // "onActiveTextureStateChange" is called when the Texture changed but the binding did not.
    817    void onActiveTextureStateChange(const Context *context, size_t textureUnit);
    818 
    819    void onImageStateChange(const Context *context, size_t unit);
    820 
    821    void onUniformBufferStateChange(size_t uniformBufferIndex);
    822    void onAtomicCounterBufferStateChange(size_t atomicCounterBufferIndex);
    823    void onShaderStorageBufferStateChange(size_t shaderStorageBufferIndex);
    824 
    825    bool isCurrentTransformFeedback(const TransformFeedback *tf) const
    826    {
    827        return tf == mTransformFeedback.get();
    828    }
    829    bool isCurrentVertexArray(const VertexArray *va) const { return va == mVertexArray; }
    830 
    831    GLES1State &gles1() { return mGLES1State; }
    832    const GLES1State &gles1() const { return mGLES1State; }
    833 
    834    // Helpers for setting bound buffers. They should all have the same signature.
    835    // Not meant to be called externally. Used for local helpers in State.cpp.
    836    template <BufferBinding Target>
    837    void setGenericBufferBindingWithBit(const Context *context, Buffer *buffer);
    838 
    839    template <BufferBinding Target>
    840    void setGenericBufferBinding(const Context *context, Buffer *buffer);
    841 
    842    using BufferBindingSetter = void (State::*)(const Context *, Buffer *);
    843 
    844    ANGLE_INLINE bool validateSamplerFormats() const
    845    {
    846        return (!mExecutable || !(mTexturesIncompatibleWithSamplers.intersects(
    847                                    mExecutable->getActiveSamplersMask())));
    848    }
    849 
    850    ProvokingVertexConvention getProvokingVertex() const { return mProvokingVertex; }
    851    void setProvokingVertex(ProvokingVertexConvention val)
    852    {
    853        mDirtyBits.set(State::DIRTY_BIT_PROVOKING_VERTEX);
    854        mProvokingVertex = val;
    855    }
    856 
    857    ANGLE_INLINE void setReadFramebufferBindingDirty()
    858    {
    859        mDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
    860    }
    861 
    862    ANGLE_INLINE void setDrawFramebufferBindingDirty()
    863    {
    864        mDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
    865    }
    866 
    867    using ClipDistanceEnableBits = angle::BitSet32<IMPLEMENTATION_MAX_CLIP_DISTANCES>;
    868    const ClipDistanceEnableBits &getEnabledClipDistances() const { return mClipDistancesEnabled; }
    869    void setClipDistanceEnable(int idx, bool enable);
    870 
    871    const OverlayType *getOverlay() const { return mOverlay; }
    872 
    873    // Not for general use.
    874    const BufferManager &getBufferManagerForCapture() const { return *mBufferManager; }
    875    const BoundBufferMap &getBoundBuffersForCapture() const { return mBoundBuffers; }
    876    const TextureManager &getTextureManagerForCapture() const { return *mTextureManager; }
    877    const TextureBindingMap &getBoundTexturesForCapture() const { return mSamplerTextures; }
    878    const RenderbufferManager &getRenderbufferManagerForCapture() const
    879    {
    880        return *mRenderbufferManager;
    881    }
    882    const FramebufferManager &getFramebufferManagerForCapture() const
    883    {
    884        return *mFramebufferManager;
    885    }
    886    const ShaderProgramManager &getShaderProgramManagerForCapture() const
    887    {
    888        return *mShaderProgramManager;
    889    }
    890    const SyncManager &getSyncManagerForCapture() const { return *mSyncManager; }
    891    const SamplerManager &getSamplerManagerForCapture() const { return *mSamplerManager; }
    892    const ProgramPipelineManager *getProgramPipelineManagerForCapture() const
    893    {
    894        return mProgramPipelineManager;
    895    }
    896    const SamplerBindingVector &getSamplerBindingsForCapture() const { return mSamplers; }
    897    const ActiveQueryMap &getActiveQueriesForCapture() const { return mActiveQueries; }
    898    void initializeForCapture(const Context *context);
    899 
    900    bool hasConstantAlphaBlendFunc() const
    901    {
    902        return (mBlendFuncConstantAlphaDrawBuffers & mBlendStateExt.getEnabledMask()).any();
    903    }
    904 
    905    bool hasSimultaneousConstantColorAndAlphaBlendFunc() const
    906    {
    907        return (mBlendFuncConstantColorDrawBuffers & mBlendStateExt.getEnabledMask()).any() &&
    908               hasConstantAlphaBlendFunc();
    909    }
    910 
    911    bool noSimultaneousConstantColorAndAlphaBlendFunc() const
    912    {
    913        return mNoSimultaneousConstantColorAndAlphaBlendFunc;
    914    }
    915 
    916    const BufferVector &getOffsetBindingPointerUniformBuffers() const { return mUniformBuffers; }
    917 
    918    const BufferVector &getOffsetBindingPointerAtomicCounterBuffers() const
    919    {
    920        return mAtomicCounterBuffers;
    921    }
    922 
    923    const BufferVector &getOffsetBindingPointerShaderStorageBuffers() const
    924    {
    925        return mShaderStorageBuffers;
    926    }
    927 
    928    ActiveTextureMask getTexturesIncompatibleWithSamplers() const
    929    {
    930        return mTexturesIncompatibleWithSamplers;
    931    }
    932 
    933    bool isProgramBinaryCacheEnabled() const { return mProgramBinaryCacheEnabled; }
    934 
    935    bool isTextureRectangleEnabled() const { return mTextureRectangleEnabled; }
    936 
    937    DrawBufferMask getBlendFuncConstantAlphaDrawBuffers() const
    938    {
    939        return mBlendFuncConstantAlphaDrawBuffers;
    940    }
    941 
    942    DrawBufferMask getBlendFuncConstantColorDrawBuffers() const
    943    {
    944        return mBlendFuncConstantColorDrawBuffers;
    945    }
    946 
    947    const std::vector<ImageUnit> &getImageUnits() const { return mImageUnits; }
    948 
    949    bool hasDisplayTextureShareGroup() const { return mDisplayTextureShareGroup; }
    950 
    951    void setLogicOpEnabled(bool enabled);
    952    bool isLogicOpEnabled() const { return mLogicOpEnabled; }
    953 
    954    void setLogicOp(LogicalOperation opcode);
    955    LogicalOperation getLogicOp() const { return mLogicOp; }
    956 
    957  private:
    958    friend class Context;
    959 
    960    void unsetActiveTextures(const ActiveTextureMask &textureMask);
    961    void setActiveTextureDirty(size_t textureIndex, Texture *texture);
    962    void updateTextureBinding(const Context *context, size_t textureIndex, Texture *texture);
    963    void updateActiveTextureStateOnSync(const Context *context,
    964                                        size_t textureIndex,
    965                                        const Sampler *sampler,
    966                                        Texture *texture);
    967    Texture *getTextureForActiveSampler(TextureType type, size_t index);
    968 
    969    bool hasConstantColor(GLenum sourceRGB, GLenum destRGB) const;
    970    bool hasConstantAlpha(GLenum sourceRGB, GLenum destRGB) const;
    971 
    972    // Functions to synchronize dirty states
    973    angle::Result syncActiveTextures(const Context *context, Command command);
    974    angle::Result syncTexturesInit(const Context *context, Command command);
    975    angle::Result syncImagesInit(const Context *context, Command command);
    976    angle::Result syncReadAttachments(const Context *context, Command command);
    977    angle::Result syncDrawAttachments(const Context *context, Command command);
    978    angle::Result syncReadFramebuffer(const Context *context, Command command);
    979    angle::Result syncDrawFramebuffer(const Context *context, Command command);
    980    angle::Result syncVertexArray(const Context *context, Command command);
    981    angle::Result syncTextures(const Context *context, Command command);
    982    angle::Result syncImages(const Context *context, Command command);
    983    angle::Result syncSamplers(const Context *context, Command command);
    984    angle::Result syncProgram(const Context *context, Command command);
    985    angle::Result syncProgramPipelineObject(const Context *context, Command command);
    986 
    987    using DirtyObjectHandler = angle::Result (State::*)(const Context *context, Command command);
    988 
    989    static constexpr DirtyObjectHandler kDirtyObjectHandlers[DIRTY_OBJECT_MAX] = {
    990        &State::syncActiveTextures,
    991        &State::syncTexturesInit,
    992        &State::syncImagesInit,
    993        &State::syncReadAttachments,
    994        &State::syncDrawAttachments,
    995        &State::syncReadFramebuffer,
    996        &State::syncDrawFramebuffer,
    997        &State::syncVertexArray,
    998        &State::syncTextures,
    999        &State::syncImages,
   1000        &State::syncSamplers,
   1001        &State::syncProgram,
   1002        &State::syncProgramPipelineObject};
   1003 
   1004    // Robust init must happen before Framebuffer init for the Vulkan back-end.
   1005    static_assert(DIRTY_OBJECT_ACTIVE_TEXTURES < DIRTY_OBJECT_TEXTURES_INIT, "init order");
   1006    static_assert(DIRTY_OBJECT_TEXTURES_INIT < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order");
   1007    static_assert(DIRTY_OBJECT_IMAGES_INIT < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order");
   1008    static_assert(DIRTY_OBJECT_DRAW_ATTACHMENTS < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order");
   1009    static_assert(DIRTY_OBJECT_READ_ATTACHMENTS < DIRTY_OBJECT_READ_FRAMEBUFFER, "init order");
   1010 
   1011    static_assert(DIRTY_OBJECT_ACTIVE_TEXTURES == 0, "check DIRTY_OBJECT_ACTIVE_TEXTURES index");
   1012    static_assert(DIRTY_OBJECT_TEXTURES_INIT == 1, "check DIRTY_OBJECT_TEXTURES_INIT index");
   1013    static_assert(DIRTY_OBJECT_IMAGES_INIT == 2, "check DIRTY_OBJECT_IMAGES_INIT index");
   1014    static_assert(DIRTY_OBJECT_READ_ATTACHMENTS == 3, "check DIRTY_OBJECT_READ_ATTACHMENTS index");
   1015    static_assert(DIRTY_OBJECT_DRAW_ATTACHMENTS == 4, "check DIRTY_OBJECT_DRAW_ATTACHMENTS index");
   1016    static_assert(DIRTY_OBJECT_READ_FRAMEBUFFER == 5, "check DIRTY_OBJECT_READ_FRAMEBUFFER index");
   1017    static_assert(DIRTY_OBJECT_DRAW_FRAMEBUFFER == 6, "check DIRTY_OBJECT_DRAW_FRAMEBUFFER index");
   1018    static_assert(DIRTY_OBJECT_VERTEX_ARRAY == 7, "check DIRTY_OBJECT_VERTEX_ARRAY index");
   1019    static_assert(DIRTY_OBJECT_TEXTURES == 8, "check DIRTY_OBJECT_TEXTURES index");
   1020    static_assert(DIRTY_OBJECT_IMAGES == 9, "check DIRTY_OBJECT_IMAGES index");
   1021    static_assert(DIRTY_OBJECT_SAMPLERS == 10, "check DIRTY_OBJECT_SAMPLERS index");
   1022    static_assert(DIRTY_OBJECT_PROGRAM == 11, "check DIRTY_OBJECT_PROGRAM index");
   1023    static_assert(DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT == 12,
   1024                  "check DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT index");
   1025 
   1026    // Dispatch table for buffer update functions.
   1027    static const angle::PackedEnumMap<BufferBinding, BufferBindingSetter> kBufferSetters;
   1028 
   1029    ContextID mID;
   1030 
   1031    EGLenum mClientType;
   1032    EGLint mProfileMask;
   1033    EGLenum mContextPriority;
   1034    bool mHasRobustAccess;
   1035    bool mHasProtectedContent;
   1036    bool mIsDebugContext;
   1037    Version mClientVersion;
   1038 
   1039    // Caps to use for validation
   1040    Caps mCaps;
   1041    TextureCapsMap mTextureCaps;
   1042    Extensions mExtensions;
   1043    Limitations mLimitations;
   1044 
   1045    egl::ShareGroup *mShareGroup;
   1046 
   1047    // Resource managers.
   1048    BufferManager *mBufferManager;
   1049    ShaderProgramManager *mShaderProgramManager;
   1050    TextureManager *mTextureManager;
   1051    RenderbufferManager *mRenderbufferManager;
   1052    SamplerManager *mSamplerManager;
   1053    SyncManager *mSyncManager;
   1054    FramebufferManager *mFramebufferManager;
   1055    ProgramPipelineManager *mProgramPipelineManager;
   1056    MemoryObjectManager *mMemoryObjectManager;
   1057    SemaphoreManager *mSemaphoreManager;
   1058 
   1059    ColorF mColorClearValue;
   1060    GLfloat mDepthClearValue;
   1061    int mStencilClearValue;
   1062 
   1063    RasterizerState mRasterizer;
   1064    bool mScissorTest;
   1065    Rectangle mScissor;
   1066 
   1067    bool mNoUnclampedBlendColor;
   1068 
   1069    BlendState mBlendState;  // Buffer zero blend state legacy struct
   1070    BlendStateExt mBlendStateExt;
   1071    ColorF mBlendColor;
   1072    bool mSampleAlphaToCoverage;
   1073    bool mSampleCoverage;
   1074    GLfloat mSampleCoverageValue;
   1075    bool mSampleCoverageInvert;
   1076    bool mSampleMask;
   1077    GLuint mMaxSampleMaskWords;
   1078    SampleMaskArray<GLbitfield> mSampleMaskValues;
   1079    bool mIsSampleShadingEnabled;
   1080    float mMinSampleShading;
   1081 
   1082    DepthStencilState mDepthStencil;
   1083    GLint mStencilRef;
   1084    GLint mStencilBackRef;
   1085 
   1086    GLfloat mLineWidth;
   1087 
   1088    GLenum mGenerateMipmapHint;
   1089    GLenum mTextureFilteringHint;
   1090    GLenum mFragmentShaderDerivativeHint;
   1091 
   1092    const bool mBindGeneratesResource;
   1093    const bool mClientArraysEnabled;
   1094 
   1095    Rectangle mViewport;
   1096    float mNearZ;
   1097    float mFarZ;
   1098 
   1099    GLenum mClipControlOrigin;
   1100    GLenum mClipControlDepth;
   1101 
   1102    Framebuffer *mReadFramebuffer;
   1103    Framebuffer *mDrawFramebuffer;
   1104    BindingPointer<Renderbuffer> mRenderbuffer;
   1105    Program *mProgram;
   1106    BindingPointer<ProgramPipeline> mProgramPipeline;
   1107    ProgramExecutable *mExecutable;
   1108 
   1109    // GL_ANGLE_provoking_vertex
   1110    ProvokingVertexConvention mProvokingVertex;
   1111 
   1112    using VertexAttribVector = std::vector<VertexAttribCurrentValueData>;
   1113    VertexAttribVector mVertexAttribCurrentValues;  // From glVertexAttrib
   1114    VertexArray *mVertexArray;
   1115    ComponentTypeMask mCurrentValuesTypeMask;
   1116 
   1117    // Texture and sampler bindings
   1118    GLint mActiveSampler;  // Active texture unit selector - GL_TEXTURE0
   1119 
   1120    TextureBindingMap mSamplerTextures;
   1121 
   1122    // Active Textures Cache
   1123    // ---------------------
   1124    // The active textures cache gives ANGLE components access to a complete array of textures
   1125    // on a draw call. gl::State implements angle::Observer and watches gl::Texture for state
   1126    // changes via the onSubjectStateChange method above. We update the cache before draws.
   1127    // See Observer.h and the design doc linked there for more info on Subject/Observer events.
   1128    //
   1129    // On state change events (re-binding textures, samplers, programs etc) we clear the cache
   1130    // and flag dirty bits. nullptr indicates unbound or incomplete.
   1131    ActiveTexturesCache mActiveTexturesCache;
   1132    std::vector<angle::ObserverBinding> mCompleteTextureBindings;
   1133 
   1134    ActiveTextureMask mTexturesIncompatibleWithSamplers;
   1135 
   1136    SamplerBindingVector mSamplers;
   1137 
   1138    // It would be nice to merge the image and observer binding. Same for textures.
   1139    std::vector<ImageUnit> mImageUnits;
   1140 
   1141    ActiveQueryMap mActiveQueries;
   1142 
   1143    // Stores the currently bound buffer for each binding point. It has an entry for the element
   1144    // array buffer but it should not be used. Instead this bind point is owned by the current
   1145    // vertex array object.
   1146    BoundBufferMap mBoundBuffers;
   1147 
   1148    BufferVector mUniformBuffers;
   1149    BufferVector mAtomicCounterBuffers;
   1150    BufferVector mShaderStorageBuffers;
   1151 
   1152    angle::BitSet<gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS> mBoundUniformBuffersMask;
   1153    angle::BitSet<gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>
   1154        mBoundAtomicCounterBuffersMask;
   1155    angle::BitSet<gl::IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>
   1156        mBoundShaderStorageBuffersMask;
   1157 
   1158    BindingPointer<TransformFeedback> mTransformFeedback;
   1159 
   1160    PixelUnpackState mUnpack;
   1161    PixelPackState mPack;
   1162 
   1163    bool mPrimitiveRestart;
   1164 
   1165    Debug mDebug;
   1166 
   1167    bool mMultiSampling;
   1168    bool mSampleAlphaToOne;
   1169 
   1170    GLenum mCoverageModulation;
   1171 
   1172    // GL_EXT_sRGB_write_control
   1173    bool mFramebufferSRGB;
   1174 
   1175    // GL_ANGLE_robust_resource_initialization
   1176    const bool mRobustResourceInit;
   1177 
   1178    // GL_ANGLE_program_cache_control
   1179    const bool mProgramBinaryCacheEnabled;
   1180 
   1181    // GL_ANGLE_webgl_compatibility
   1182    bool mTextureRectangleEnabled;
   1183 
   1184    // GL_ANGLE_logic_op
   1185    bool mLogicOpEnabled;
   1186    LogicalOperation mLogicOp;
   1187 
   1188    // GL_KHR_parallel_shader_compile
   1189    GLuint mMaxShaderCompilerThreads;
   1190 
   1191    // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance
   1192    ClipDistanceEnableBits mClipDistancesEnabled;
   1193 
   1194    // GL_EXT_tessellation_shader
   1195    GLuint mPatchVertices;
   1196 
   1197    // GL_ANGLE_shader_pixel_local_storage
   1198    bool mPixelLocalStorageActive;
   1199 
   1200    // GLES1 emulation: state specific to GLES1
   1201    GLES1State mGLES1State;
   1202 
   1203    DirtyBits mDirtyBits;
   1204    mutable ExtendedDirtyBits mExtendedDirtyBits;
   1205    DirtyObjects mDirtyObjects;
   1206    mutable AttributesMask mDirtyCurrentValues;
   1207    ActiveTextureMask mDirtyActiveTextures;
   1208    ActiveTextureMask mDirtyTextures;
   1209    ActiveTextureMask mDirtySamplers;
   1210    ImageUnitMask mDirtyImages;
   1211 
   1212    // The Overlay object, used by the backend to render the overlay.
   1213    const OverlayType *mOverlay;
   1214 
   1215    // OES_draw_buffers_indexed
   1216    DrawBufferMask mBlendFuncConstantAlphaDrawBuffers;
   1217    DrawBufferMask mBlendFuncConstantColorDrawBuffers;
   1218    bool mNoSimultaneousConstantColorAndAlphaBlendFunc;
   1219    // Whether the indexed variants of setBlend* have been called.  If so, the call to the
   1220    // non-indexed variants are not no-oped.
   1221    bool mSetBlendIndexedInvoked;
   1222    bool mSetBlendFactorsIndexedInvoked;
   1223    bool mSetBlendEquationsIndexedInvoked;
   1224    bool mDisplayTextureShareGroup;
   1225 
   1226    // GL_EXT_primitive_bounding_box
   1227    GLfloat mBoundingBoxMinX;
   1228    GLfloat mBoundingBoxMinY;
   1229    GLfloat mBoundingBoxMinZ;
   1230    GLfloat mBoundingBoxMinW;
   1231    GLfloat mBoundingBoxMaxX;
   1232    GLfloat mBoundingBoxMaxY;
   1233    GLfloat mBoundingBoxMaxZ;
   1234    GLfloat mBoundingBoxMaxW;
   1235 
   1236    // QCOM_shading_rate
   1237    bool mShadingRatePreserveAspectRatio;
   1238    ShadingRate mShadingRate;
   1239 };
   1240 
   1241 ANGLE_INLINE angle::Result State::syncDirtyObjects(const Context *context,
   1242                                                   const DirtyObjects &bitset,
   1243                                                   Command command)
   1244 {
   1245    const DirtyObjects &dirtyObjects = mDirtyObjects & bitset;
   1246 
   1247    for (size_t dirtyObject : dirtyObjects)
   1248    {
   1249        ANGLE_TRY((this->*kDirtyObjectHandlers[dirtyObject])(context, command));
   1250    }
   1251 
   1252    mDirtyObjects &= ~dirtyObjects;
   1253    return angle::Result::Continue;
   1254 }
   1255 
   1256 }  // namespace gl
   1257 
   1258 #endif  // LIBANGLE_STATE_H_