//
// Copyright 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// State.h: Defines the State class, encapsulating raw GL state

#ifndef LIBANGLE_STATE_H_
#define LIBANGLE_STATE_H_

#include <bitset>
#include <memory>

#include "common/Color.h"
#include "common/angleutils.h"
#include "common/bitset_utils.h"
#include "libANGLE/ContextMutex.h"
#include "libANGLE/Debug.h"
#include "libANGLE/GLES1State.h"
#include "libANGLE/HandleAllocator.h"
#include "libANGLE/Overlay.h"
#include "libANGLE/Program.h"
#include "libANGLE/ProgramExecutable.h"
#include "libANGLE/ProgramPipeline.h"
#include "libANGLE/RefCountObject.h"
#include "libANGLE/Renderbuffer.h"
#include "libANGLE/ResourceMap.h"
#include "libANGLE/Sampler.h"
#include "libANGLE/Texture.h"
#include "libANGLE/TransformFeedback.h"
#include "libANGLE/Version.h"
#include "libANGLE/VertexArray.h"
#include "libANGLE/angletypes.h"

namespace egl
{
class ShareGroup;
}  // namespace egl

namespace gl
{
class BufferManager;
struct Caps;
class Context;
class FramebufferManager;
class MemoryObjectManager;
class ProgramPipelineManager;
class Query;
class RenderbufferManager;
class SamplerManager;
class SemaphoreManager;
class ShaderProgramManager;
class SyncManager;
class TextureManager;
class VertexArray;

template <typename T>
using BufferBindingMap     = angle::PackedEnumMap<BufferBinding, T>;
using BoundBufferMap       = BufferBindingMap<BindingPointer<Buffer>>;
using TextureBindingVector = std::vector<BindingPointer<Texture>>;
using TextureBindingMap    = angle::PackedEnumMap<TextureType, TextureBindingVector>;
using ActiveQueryMap       = angle::PackedEnumMap<QueryType, BindingPointer<Query>>;

class ActiveTexturesCache final : angle::NonCopyable
{
  public:
    ActiveTexturesCache();
    ~ActiveTexturesCache();

    Texture *operator[](size_t textureIndex) const { return mTextures[textureIndex]; }

    void clear();
    void set(size_t textureIndex, Texture *texture);
    void reset(size_t textureIndex);
    bool empty() const;
    size_t size() const { return mTextures.size(); }

  private:
    ActiveTextureArray<Texture *> mTextures;
};

namespace state
{
enum DirtyBitType
{
    // Note: process draw framebuffer binding first, so that other dirty bits whose effect
    // depend on the current draw framebuffer are not processed while the old framebuffer is
    // still bound.
    DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING,
    DIRTY_BIT_READ_FRAMEBUFFER_BINDING,
    DIRTY_BIT_SCISSOR_TEST_ENABLED,
    DIRTY_BIT_SCISSOR,
    DIRTY_BIT_VIEWPORT,
    DIRTY_BIT_DEPTH_RANGE,
    DIRTY_BIT_BLEND_ENABLED,
    DIRTY_BIT_BLEND_COLOR,
    DIRTY_BIT_BLEND_FUNCS,
    DIRTY_BIT_BLEND_EQUATIONS,
    DIRTY_BIT_COLOR_MASK,
    DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED,
    DIRTY_BIT_SAMPLE_COVERAGE_ENABLED,
    DIRTY_BIT_SAMPLE_COVERAGE,
    DIRTY_BIT_SAMPLE_MASK_ENABLED,
    DIRTY_BIT_SAMPLE_MASK,
    DIRTY_BIT_DEPTH_TEST_ENABLED,
    DIRTY_BIT_DEPTH_FUNC,
    DIRTY_BIT_DEPTH_MASK,
    DIRTY_BIT_STENCIL_TEST_ENABLED,
    DIRTY_BIT_STENCIL_FUNCS_FRONT,
    DIRTY_BIT_STENCIL_FUNCS_BACK,
    DIRTY_BIT_STENCIL_OPS_FRONT,
    DIRTY_BIT_STENCIL_OPS_BACK,
    DIRTY_BIT_STENCIL_WRITEMASK_FRONT,
    DIRTY_BIT_STENCIL_WRITEMASK_BACK,
    DIRTY_BIT_CULL_FACE_ENABLED,
    DIRTY_BIT_CULL_FACE,
    DIRTY_BIT_FRONT_FACE,
    DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED,
    DIRTY_BIT_POLYGON_OFFSET,
    DIRTY_BIT_RASTERIZER_DISCARD_ENABLED,
    DIRTY_BIT_LINE_WIDTH,
    DIRTY_BIT_PRIMITIVE_RESTART_ENABLED,
    DIRTY_BIT_CLEAR_COLOR,
    DIRTY_BIT_CLEAR_DEPTH,
    DIRTY_BIT_CLEAR_STENCIL,
    DIRTY_BIT_UNPACK_STATE,
    DIRTY_BIT_UNPACK_BUFFER_BINDING,
    DIRTY_BIT_PACK_STATE,
    DIRTY_BIT_PACK_BUFFER_BINDING,
    DIRTY_BIT_DITHER_ENABLED,
    DIRTY_BIT_RENDERBUFFER_BINDING,
    DIRTY_BIT_VERTEX_ARRAY_BINDING,
    DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING,
    DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING,
    // Note: Fine-grained dirty bits for each index could be an optimization.
    DIRTY_BIT_PROGRAM_BINDING,  // Must be before DIRTY_BIT_PROGRAM_EXECUTABLE
    DIRTY_BIT_PROGRAM_EXECUTABLE,
    // Note: Fine-grained dirty bits for each texture/sampler could be an optimization.
    DIRTY_BIT_SAMPLER_BINDINGS,
    DIRTY_BIT_TEXTURE_BINDINGS,
    DIRTY_BIT_IMAGE_BINDINGS,
    DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING,
    DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING,
    DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING,
    // Top-level dirty bit. Also see mUniformBufferBlocksDirtyTypeMask.
    DIRTY_BIT_UNIFORM_BUFFER_BINDINGS,
    DIRTY_BIT_MULTISAMPLING,
    DIRTY_BIT_SAMPLE_ALPHA_TO_ONE,
    DIRTY_BIT_COVERAGE_MODULATION,                  // CHROMIUM_framebuffer_mixed_samples
    DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE,  // GL_EXT_sRGB_write_control
    DIRTY_BIT_CURRENT_VALUES,
    DIRTY_BIT_PROVOKING_VERTEX,
    DIRTY_BIT_SAMPLE_SHADING,
    DIRTY_BIT_PATCH_VERTICES,
    DIRTY_BIT_EXTENDED,  // clip distances, mipmap generation hint, derivative hint,
                         // EXT_clip_control, EXT_depth_clamp

    DIRTY_BIT_INVALID,
    DIRTY_BIT_MAX = DIRTY_BIT_INVALID,
};
static_assert(DIRTY_BIT_MAX <= 64, "State dirty bits must be capped at 64");
using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;

enum ExtendedDirtyBitType
{
    EXTENDED_DIRTY_BIT_CLIP_CONTROL,                  // EXT_clip_control
    EXTENDED_DIRTY_BIT_CLIP_DISTANCES,                // clip distances
    EXTENDED_DIRTY_BIT_DEPTH_CLAMP_ENABLED,           // EXT_depth_clamp
    EXTENDED_DIRTY_BIT_MIPMAP_GENERATION_HINT,        // mipmap generation hint
    EXTENDED_DIRTY_BIT_POLYGON_MODE,                  // NV_polygon_mode
    EXTENDED_DIRTY_BIT_POLYGON_OFFSET_POINT_ENABLED,  // NV_polygon_mode
    EXTENDED_DIRTY_BIT_POLYGON_OFFSET_LINE_ENABLED,   // NV_polygon_mode
    EXTENDED_DIRTY_BIT_SHADER_DERIVATIVE_HINT,        // shader derivative hint
    EXTENDED_DIRTY_BIT_FETCH_PER_SAMPLE_ENABLED,      // FETCH_PER_SAMPLE_ARM
    EXTENDED_DIRTY_BIT_SHADING_RATE_QCOM,             // QCOM_shading_rate
    EXTENDED_DIRTY_BIT_SHADING_RATE_EXT,              // EXT_fragment_shading_rate
    EXTENDED_DIRTY_BIT_LOGIC_OP_ENABLED,              // ANGLE_logic_op
    EXTENDED_DIRTY_BIT_LOGIC_OP,                      // ANGLE_logic_op
    EXTENDED_DIRTY_BIT_BLEND_ADVANCED_COHERENT,       // KHR_blend_operation_advanced_coherent

    EXTENDED_DIRTY_BIT_INVALID,
    EXTENDED_DIRTY_BIT_MAX = EXTENDED_DIRTY_BIT_INVALID,
};
static_assert(EXTENDED_DIRTY_BIT_MAX <= 32, "State extended dirty bits must be capped at 32");
using ExtendedDirtyBits = angle::BitSet32<EXTENDED_DIRTY_BIT_MAX>;

// TODO(jmadill): Consider storing dirty objects in a list instead of by binding.
enum DirtyObjectType
{
    DIRTY_OBJECT_ACTIVE_TEXTURES,  // Top-level dirty bit. Also see mDirtyActiveTextures.
    DIRTY_OBJECT_TEXTURES_INIT,
    DIRTY_OBJECT_IMAGES_INIT,
    DIRTY_OBJECT_READ_ATTACHMENTS,  // Only used if robust resource init is enabled
    DIRTY_OBJECT_DRAW_ATTACHMENTS,  // Only used if robust resource init is enabled
    DIRTY_OBJECT_READ_FRAMEBUFFER,
    DIRTY_OBJECT_DRAW_FRAMEBUFFER,
    DIRTY_OBJECT_VERTEX_ARRAY,
    DIRTY_OBJECT_TEXTURES,  // Top-level dirty bit. Also see mDirtyTextures.
    DIRTY_OBJECT_IMAGES,    // Top-level dirty bit. Also see mDirtyImages.
    DIRTY_OBJECT_SAMPLERS,  // Top-level dirty bit. Also see mDirtySamplers.
    DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT,

    DIRTY_OBJECT_INVALID,
    DIRTY_OBJECT_MAX = DIRTY_OBJECT_INVALID,
};
using DirtyObjects = angle::BitSet<DIRTY_OBJECT_MAX>;

}  // namespace state

using VertexArrayMap = ResourceMap<VertexArray, VertexArrayID>;

// This class represents the portion of the GL context's state that is purely private to the
// context. Manipulating this state does not affect the other contexts in any way, nor do operations
// in other contexts affect this.
//
// Note that "currently bound X" states do not belong here because unbinding most objects could lead
// to object destruction which in turn may trigger a notification to an observer that may affect
// another context.
class PrivateState : angle::NonCopyable
{
  public:
    PrivateState(const Version &clientVersion,
                 bool debug,
                 bool bindGeneratesResourceCHROMIUM,
                 bool clientArraysEnabled,
                 bool robustResourceInit,
                 bool programBinaryCacheEnabled,
                 bool isExternal);
    ~PrivateState();

    void initialize(Context *context);
    void initializeForCapture(const Context *context);

    void reset();

    const Version &getClientVersion() const { return mClientVersion; }

    bool isWebGL() const { return getExtensions().webglCompatibilityANGLE; }
    bool isWebGL1() const { return isWebGL() && getClientVersion() == ES_2_0; }
    bool isGLES1() const { return getClientVersion() < ES_2_0; }

    const Caps &getCaps() const { return mCaps; }
    const TextureCapsMap &getTextureCaps() const { return mTextureCaps; }
    const Extensions &getExtensions() const { return mExtensions; }
    const Limitations &getLimitations() const { return mLimitations; }

    bool isExternal() const { return mIsExternal; }

    Caps *getMutableCaps() { return &mCaps; }
    TextureCapsMap *getMutableTextureCaps() { return &mTextureCaps; }
    Extensions *getMutableExtensions() { return &mExtensions; }
    Limitations *getMutableLimitations() { return &mLimitations; }

    // State chunk getters
    const RasterizerState &getRasterizerState() const { return mRasterizer; }
    const BlendStateExt &getBlendStateExt() const { return mBlendStateExt; }
    const DepthStencilState &getDepthStencilState() const { return mDepthStencil; }

    // Clear values
    void setColorClearValue(float red, float green, float blue, float alpha);
    void setDepthClearValue(float depth);
    void setStencilClearValue(int stencil);

    const ColorF &getColorClearValue() const { return mColorClearValue; }
    float getDepthClearValue() const { return mDepthClearValue; }
    int getStencilClearValue() const { return mStencilClearValue; }

    // Write mask manipulation
    void setColorMask(bool red, bool green, bool blue, bool alpha);
    void setColorMaskIndexed(bool red, bool green, bool blue, bool alpha, GLuint index);
    void setDepthMask(bool mask);

    // Discard toggle & query
    bool isRasterizerDiscardEnabled() const { return mRasterizer.rasterizerDiscard; }
    void setRasterizerDiscard(bool enabled);

    // Primitive restart
    bool isPrimitiveRestartEnabled() const { return mPrimitiveRestart; }
    void setPrimitiveRestart(bool enabled);

    // FETCH_PER_SAMPLE_ARM
    void setFetchPerSample(bool enabled);

    // Face culling state manipulation
    bool isCullFaceEnabled() const { return mRasterizer.cullFace; }
    void setCullFace(bool enabled);
    void setCullMode(CullFaceMode mode);
    void setFrontFace(GLenum front);

    // EXT_depth_clamp
    bool isDepthClampEnabled() const { return mRasterizer.depthClamp; }
    void setDepthClamp(bool enabled);

    // Depth test state manipulation
    bool isDepthTestEnabled() const { return mDepthStencil.depthTest; }
    bool isDepthWriteEnabled() const { return mDepthStencil.depthTest && mDepthStencil.depthMask; }
    void setDepthTest(bool enabled);
    void setDepthFunc(GLenum depthFunc);
    void setDepthRange(float zNear, float zFar);
    float getNearPlane() const { return mNearZ; }
    float getFarPlane() const { return mFarZ; }

    // EXT_clip_control
    void setClipControl(ClipOrigin origin, ClipDepthMode depth);
    ClipOrigin getClipOrigin() const { return mClipOrigin; }
    ClipDepthMode getClipDepthMode() const { return mClipDepthMode; }
    bool isClipDepthModeZeroToOne() const { return mClipDepthMode == ClipDepthMode::ZeroToOne; }

    // Blend state manipulation
    bool isBlendEnabled() const { return isBlendEnabledIndexed(0); }
    bool isBlendEnabledIndexed(GLuint index) const
    {
        ASSERT(static_cast<size_t>(index) < mBlendStateExt.getDrawBufferCount());
        return isActivelyOverriddenPLSDrawBuffer(index)
                   ? mPLSDeferredBlendEnables.test(index)
                   : mBlendStateExt.getEnabledMask().test(index);
    }
    DrawBufferMask getBlendEnabledDrawBufferMask() const { return mBlendStateExt.getEnabledMask(); }
    void setBlend(bool enabled);
    void setBlendIndexed(bool enabled, GLuint index);
    void setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha);
    void setBlendFactorsIndexed(GLenum sourceRGB,
                                GLenum destRGB,
                                GLenum sourceAlpha,
                                GLenum destAlpha,
                                GLuint index);
    void setBlendColor(float red, float green, float blue, float alpha);
    void setBlendEquation(GLenum rgbEquation, GLenum alphaEquation);
    void setBlendEquationIndexed(GLenum rgbEquation, GLenum alphaEquation, GLuint index);
    const ColorF &getBlendColor() const { return mBlendColor; }

    // Stencil state maniupulation
    bool isStencilTestEnabled() const { return mDepthStencil.stencilTest; }
    bool isStencilWriteEnabled(GLuint framebufferStencilSize) const
    {
        return mDepthStencil.stencilTest &&
               !(mDepthStencil.isStencilNoOp(framebufferStencilSize) &&
                 mDepthStencil.isStencilBackNoOp(framebufferStencilSize));
    }
    void setStencilTest(bool enabled);
    void setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask);
    void setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask);
    void setStencilWritemask(GLuint stencilWritemask);
    void setStencilBackWritemask(GLuint stencilBackWritemask);
    void setStencilOperations(GLenum stencilFail,
                              GLenum stencilPassDepthFail,
                              GLenum stencilPassDepthPass);
    void setStencilBackOperations(GLenum stencilBackFail,
                                  GLenum stencilBackPassDepthFail,
                                  GLenum stencilBackPassDepthPass);
    GLint getStencilRef() const { return mStencilRef; }
    GLint getStencilBackRef() const { return mStencilBackRef; }

    PolygonMode getPolygonMode() const { return mRasterizer.polygonMode; }
    void setPolygonMode(PolygonMode mode);

    // Depth bias/polygon offset state manipulation
    bool isPolygonOffsetPointEnabled() const { return mRasterizer.polygonOffsetPoint; }
    bool isPolygonOffsetLineEnabled() const { return mRasterizer.polygonOffsetLine; }
    bool isPolygonOffsetFillEnabled() const { return mRasterizer.polygonOffsetFill; }
    bool isPolygonOffsetEnabled() const { return mRasterizer.isPolygonOffsetEnabled(); }
    void setPolygonOffsetPoint(bool enabled);
    void setPolygonOffsetLine(bool enabled);
    void setPolygonOffsetFill(bool enabled);
    void setPolygonOffsetParams(GLfloat factor, GLfloat units, GLfloat clamp);

    // Multisample coverage state manipulation
    bool isSampleAlphaToCoverageEnabled() const { return mSampleAlphaToCoverage; }
    void setSampleAlphaToCoverage(bool enabled);
    bool isSampleCoverageEnabled() const { return mSampleCoverage; }
    void setSampleCoverage(bool enabled);
    void setSampleCoverageParams(GLclampf value, bool invert);
    GLclampf getSampleCoverageValue() const { return mSampleCoverageValue; }
    bool getSampleCoverageInvert() const { return mSampleCoverageInvert; }

    // Multisample mask state manipulation.
    bool isSampleMaskEnabled() const { return mSampleMask; }
    void setSampleMaskEnabled(bool enabled);
    void setSampleMaskParams(GLuint maskNumber, GLbitfield mask);
    GLbitfield getSampleMaskWord(GLuint maskNumber) const
    {
        ASSERT(maskNumber < mMaxSampleMaskWords);
        return mSampleMaskValues[maskNumber];
    }
    SampleMaskArray<GLbitfield> getSampleMaskValues() const { return mSampleMaskValues; }
    GLuint getMaxSampleMaskWords() const { return mMaxSampleMaskWords; }

    // Multisampling/alpha to one manipulation.
    void setSampleAlphaToOne(bool enabled);
    bool isSampleAlphaToOneEnabled() const { return mSampleAlphaToOne; }
    void setMultisampling(bool enabled);
    bool isMultisamplingEnabled() const { return mMultiSampling; }

    void setSampleShading(bool enabled);
    bool isSampleShadingEnabled() const { return mIsSampleShadingEnabled; }
    void setMinSampleShading(float value);
    float getMinSampleShading() const { return mMinSampleShading; }

    // Scissor test state toggle & query
    bool isScissorTestEnabled() const { return mScissorTest; }
    void setScissorTest(bool enabled);
    void setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height);
    const Rectangle &getScissor() const { return mScissor; }

    // Dither state toggle & query
    bool isDitherEnabled() const { return mRasterizer.dither; }
    void setDither(bool enabled);

    // GL_KHR_blend_equation_advanced_coherent
    void setBlendAdvancedCoherent(bool enabled);
    bool isBlendAdvancedCoherentEnabled() const { return mBlendAdvancedCoherent; }

    // GL_CHROMIUM_bind_generates_resource
    bool isBindGeneratesResourceEnabled() const { return mBindGeneratesResource; }

    // GL_ANGLE_client_arrays
    bool areClientArraysEnabled() const { return mClientArraysEnabled; }

    // GL_ANGLE_robust_resource_initialization
    bool isRobustResourceInitEnabled() const { return mRobustResourceInit; }

    // GL_ANGLE_program_cache_control
    bool isProgramBinaryCacheEnabled() const { return mProgramBinaryCacheEnabled; }

    // Viewport state setter/getter
    void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);
    const Rectangle &getViewport() const { return mViewport; }

    // QCOM_shading_rate helpers
    void setShadingRateQCOM(ShadingRate rate);
    ShadingRate getShadingRateQCOM() const { return mShadingRateQCOM; }

    // GL_EXT_fragment_shading_rate helpers
    void setShadingRateEXT(ShadingRate rate);
    ShadingRate getShadingRateEXT() const { return mShadingRateEXT; }
    void setShadingRateCombinerOps(CombinerOp combinerOp0, CombinerOp combinerOp1);
    const std::array<CombinerOp, 2> &getShadingRateCombinerOps() const { return mCombinerOps; }
    bool getFetchPerSample() const { return mFetchPerSample; }

    // Pixel pack state manipulation
    void setPackAlignment(GLint alignment);
    GLint getPackAlignment() const { return mPack.alignment; }
    void setPackReverseRowOrder(bool reverseRowOrder);
    bool getPackReverseRowOrder() const { return mPack.reverseRowOrder; }
    void setPackRowLength(GLint rowLength);
    GLint getPackRowLength() const { return mPack.rowLength; }
    void setPackSkipRows(GLint skipRows);
    GLint getPackSkipRows() const { return mPack.skipRows; }
    void setPackSkipPixels(GLint skipPixels);
    GLint getPackSkipPixels() const { return mPack.skipPixels; }
    const PixelPackState &getPackState() const { return mPack; }
    PixelPackState &getPackState() { return mPack; }

    // Pixel unpack state manipulation
    void setUnpackAlignment(GLint alignment);
    GLint getUnpackAlignment() const { return mUnpack.alignment; }
    void setUnpackRowLength(GLint rowLength);
    GLint getUnpackRowLength() const { return mUnpack.rowLength; }
    void setUnpackImageHeight(GLint imageHeight);
    GLint getUnpackImageHeight() const { return mUnpack.imageHeight; }
    void setUnpackSkipImages(GLint skipImages);
    GLint getUnpackSkipImages() const { return mUnpack.skipImages; }
    void setUnpackSkipRows(GLint skipRows);
    GLint getUnpackSkipRows() const { return mUnpack.skipRows; }
    void setUnpackSkipPixels(GLint skipPixels);
    GLint getUnpackSkipPixels() const { return mUnpack.skipPixels; }
    const PixelUnpackState &getUnpackState() const { return mUnpack; }
    PixelUnpackState &getUnpackState() { return mUnpack; }

    // CHROMIUM_framebuffer_mixed_samples coverage modulation
    void setCoverageModulation(GLenum components);
    GLenum getCoverageModulation() const { return mCoverageModulation; }

    // GL_EXT_sRGB_write_control
    void setFramebufferSRGB(bool sRGB);
    bool getFramebufferSRGB() const { return mFramebufferSRGB; }

    // GL_EXT_tessellation_shader
    void setPatchVertices(GLuint value);
    GLuint getPatchVertices() const { return mPatchVertices; }

    // GL_ANGLE_shader_pixel_local_storage
    void setPixelLocalStorageActivePlanes(GLsizei n);
    GLsizei getPixelLocalStorageActivePlanes() const { return mPixelLocalStorageActivePlanes; }
    // While pixel local storage is active, some draw buffers may be reserved for internal use by
    // PLS and blocked from the client. All draw buffers at or beyond 'firstActivePLSDrawBuffer' are
    // overridden.
    bool hasActivelyOverriddenPLSDrawBuffers(GLint *firstActivePLSDrawBuffer) const;
    bool isActivelyOverriddenPLSDrawBuffer(GLint drawbuffer) const;

    // Line width state setter
    void setLineWidth(GLfloat width);
    float getLineWidth() const { return mLineWidth; }

    void setActiveSampler(unsigned int active);
    unsigned int getActiveSampler() const { return static_cast<unsigned int>(mActiveSampler); }

    // Hint setters
    void setGenerateMipmapHint(GLenum hint);
    GLenum getGenerateMipmapHint() const { return mGenerateMipmapHint; }
    GLenum getFragmentShaderDerivativeHint() const { return mFragmentShaderDerivativeHint; }
    void setFragmentShaderDerivativeHint(GLenum hint);

    ProvokingVertexConvention getProvokingVertex() const { return mProvokingVertex; }
    void setProvokingVertex(ProvokingVertexConvention val)
    {
        mDirtyBits.set(state::DIRTY_BIT_PROVOKING_VERTEX);
        mProvokingVertex = val;
    }

    const VertexAttribCurrentValueData &getVertexAttribCurrentValue(size_t attribNum) const
    {
        ASSERT(attribNum < mVertexAttribCurrentValues.size());
        return mVertexAttribCurrentValues[attribNum];
    }
    const std::vector<VertexAttribCurrentValueData> &getVertexAttribCurrentValues() const
    {
        return mVertexAttribCurrentValues;
    }
    // This actually clears the current value dirty bits.
    // TODO(jmadill): Pass mutable dirty bits into Impl.
    AttributesMask getAndResetDirtyCurrentValues() const;
    ComponentTypeMask getCurrentValuesTypeMask() const { return mCurrentValuesTypeMask; }

    const ClipDistanceEnableBits &getEnabledClipDistances() const { return mClipDistancesEnabled; }
    void setClipDistanceEnable(int idx, bool enable);

    bool noSimultaneousConstantColorAndAlphaBlendFunc() const
    {
        return mNoSimultaneousConstantColorAndAlphaBlendFunc;
    }

    GLfloat getBoundingBoxMinX() const { return mBoundingBoxMinX; }
    GLfloat getBoundingBoxMinY() const { return mBoundingBoxMinY; }
    GLfloat getBoundingBoxMinZ() const { return mBoundingBoxMinZ; }
    GLfloat getBoundingBoxMinW() const { return mBoundingBoxMinW; }
    GLfloat getBoundingBoxMaxX() const { return mBoundingBoxMaxX; }
    GLfloat getBoundingBoxMaxY() const { return mBoundingBoxMaxY; }
    GLfloat getBoundingBoxMaxZ() const { return mBoundingBoxMaxZ; }
    GLfloat getBoundingBoxMaxW() const { return mBoundingBoxMaxW; }
    void setBoundingBox(GLfloat minX,
                        GLfloat minY,
                        GLfloat minZ,
                        GLfloat minW,
                        GLfloat maxX,
                        GLfloat maxY,
                        GLfloat maxZ,
                        GLfloat maxW);

    bool isTextureRectangleEnabled() const { return mTextureRectangleEnabled; }

    DrawBufferMask getBlendFuncConstantAlphaDrawBuffers() const
    {
        return mBlendFuncConstantAlphaDrawBuffers;
    }

    DrawBufferMask getBlendFuncConstantColorDrawBuffers() const
    {
        return mBlendFuncConstantColorDrawBuffers;
    }

    void setLogicOpEnabled(bool enabled);
    bool isLogicOpEnabled() const { return mLogicOpEnabled; }

    void setLogicOp(LogicalOperation opcode);
    LogicalOperation getLogicOp() const { return mLogicOp; }

    // Vertex attrib manipulation
    void setVertexAttribf(GLuint index, const GLfloat values[4]);
    void setVertexAttribu(GLuint index, const GLuint values[4]);
    void setVertexAttribi(GLuint index, const GLint values[4]);

    void setEnableVertexAttribArray(unsigned int attribNum, bool enabled);
    void setVertexArrayPrivate(VertexArrayPrivate *vertexArrayPrivate)
    {
        mVertexArrayPrivate = vertexArrayPrivate;
    }
    VertexArrayPrivate *getVertexArrayPrivate() const { return mVertexArrayPrivate; }

    // QCOM_tiled_rendering
    void setTiledRendering(bool tiledRendering) { mTiledRendering = tiledRendering; }
    bool isTiledRendering() const { return mTiledRendering; }

    // Debug state
    const Debug &getDebug() const { return mDebug; }
    Debug &getDebug() { return mDebug; }

    // GL_ANGLE_blob_cache
    const BlobCacheCallbacks &getBlobCacheCallbacks() const { return mBlobCacheCallbacks; }
    BlobCacheCallbacks &getBlobCacheCallbacks() { return mBlobCacheCallbacks; }

    // Generic state toggle & query
    void setEnableFeature(GLenum feature, bool enabled);
    void setEnableFeatureIndexed(GLenum feature, bool enabled, GLuint index);
    bool getEnableFeature(GLenum feature) const;
    bool getEnableFeatureIndexed(GLenum feature, GLuint index) const;

    // State query functions
    void getBooleanv(GLenum pname, GLboolean *params) const;
    void getFloatv(GLenum pname, GLfloat *params) const;
    void getIntegerv(GLenum pname, GLint *params) const;
    void getIntegeri_v(GLenum target, GLuint index, GLint *data) const;
    void getBooleani_v(GLenum target, GLuint index, GLboolean *data) const;

    GLES1State *getMutableGLES1State() { return &mGLES1State; }
    const GLES1State &gles1() const { return mGLES1State; }

    const state::DirtyBits &getDirtyBits() const { return mDirtyBits; }
    void clearDirtyBits(const state::DirtyBits &bitset) { mDirtyBits &= ~bitset; }
    void setAllDirtyBits()
    {
        mDirtyBits.set();
        mExtendedDirtyBits.set();
        mDirtyCurrentValues = mAllAttribsMask;
    }

    const state::ExtendedDirtyBits &getExtendedDirtyBits() const { return mExtendedDirtyBits; }
    void clearExtendedDirtyBits(const state::ExtendedDirtyBits &bitset)
    {
        mExtendedDirtyBits &= ~bitset;
    }

    const state::DirtyObjects &getDirtyObjects() const { return mDirtyObjects; }
    void clearDirtyObjects() { mDirtyObjects.reset(); }

    void setPerfMonitorActive(bool active) { mIsPerfMonitorActive = active; }
    bool isPerfMonitorActive() const { return mIsPerfMonitorActive; }

    bool allocateVertexID(VertexArrayID *outId)
    {
        if (!mVertexArrayHandleAllocator.allocate(&outId->value))
        {
            return false;
        }
        mVertexArrayMap.assign(*outId, nullptr);
        return true;
    }
    bool isVertexArrayGenerated(VertexArrayID vertexArray) const
    {
        ASSERT(mVertexArrayMap.contains({0}));
        return mVertexArrayMap.contains(vertexArray);
    }
    VertexArray *getVertexArray(VertexArrayID handle) const
    {
        return mVertexArrayMap.query(handle);
    }
    void setVertexArray(VertexArrayID handle, VertexArray *vertexArray)
    {
        ASSERT(getVertexArray(handle) == nullptr);
        ASSERT(vertexArray != nullptr);
        return mVertexArrayMap.assign(handle, vertexArray);
    }
    void eraseVertexArray(VertexArrayID handle, VertexArray **vertexArrayObjectOut)
    {
        if (mVertexArrayMap.erase(handle, vertexArrayObjectOut))
        {
            mVertexArrayHandleAllocator.release(handle.value);
        }
    }
    const VertexArrayMap &getVertexArrayMap() const { return mVertexArrayMap; }

    void setVertexAttribBinding(GLuint attribIndex, GLuint bindingIndex);
    void setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor);
    void setVertexAttribDivisor(GLuint index, GLuint divisor);
    VertexArrayID getVertexArrayId() const;
    void setVertexAttribFormat(GLuint attribIndex,
                               GLint size,
                               VertexAttribType type,
                               bool normalized,
                               bool pureInteger,
                               GLuint relativeOffset);

    GLuint getGroupMarkerCount() const { return mGroupMarkerCount; }
    void incrementGroupMarkers() { mGroupMarkerCount++; }
    void decrementGroupMarkers() { mGroupMarkerCount--; }

  private:
    bool hasConstantColor(GLenum sourceRGB, GLenum destRGB) const;
    bool hasConstantAlpha(GLenum sourceRGB, GLenum destRGB) const;

    const Version mClientVersion;

    // Caps to use for validation
    Caps mCaps;
    TextureCapsMap mTextureCaps;
    Extensions mExtensions;
    Limitations mLimitations;
    const bool mIsExternal;

    ColorF mColorClearValue;
    GLfloat mDepthClearValue;
    int mStencilClearValue;

    RasterizerState mRasterizer;
    bool mScissorTest;
    Rectangle mScissor;

    bool mNoUnclampedBlendColor;

    BlendStateExt mBlendStateExt;
    ColorF mBlendColor;
    bool mSampleAlphaToCoverage;
    bool mSampleCoverage;
    GLfloat mSampleCoverageValue;
    bool mSampleCoverageInvert;
    bool mSampleMask;
    GLuint mMaxSampleMaskWords;
    SampleMaskArray<GLbitfield> mSampleMaskValues;
    bool mIsSampleShadingEnabled;
    float mMinSampleShading;

    DepthStencilState mDepthStencil;
    GLint mStencilRef;
    GLint mStencilBackRef;

    GLfloat mLineWidth;

    GLenum mGenerateMipmapHint;
    GLenum mFragmentShaderDerivativeHint;

    Rectangle mViewport;
    float mNearZ;
    float mFarZ;

    ClipOrigin mClipOrigin;
    ClipDepthMode mClipDepthMode;

    // GL_EXT_debug_marker
    // Keeps track of debug group marker count. Pop calls are ignored if there is no marker to pop.
    GLuint mGroupMarkerCount;

    // GL_ANGLE_provoking_vertex
    ProvokingVertexConvention mProvokingVertex;

    using VertexAttribVector = std::vector<VertexAttribCurrentValueData>;
    VertexAttribVector mVertexAttribCurrentValues;  // From glVertexAttrib
    ComponentTypeMask mCurrentValuesTypeMask;

    // Mask of all attributes that are available to this context: [0, maxVertexAttributes)
    AttributesMask mAllAttribsMask;

    // Texture and sampler bindings
    GLint mActiveSampler;  // Active texture unit selector - GL_TEXTURE0

    PixelUnpackState mUnpack;
    PixelPackState mPack;

    bool mPrimitiveRestart;

    bool mMultiSampling;
    bool mSampleAlphaToOne;

    // GL_KHR_blend_equation_advanced_coherent
    bool mBlendAdvancedCoherent;

    GLenum mCoverageModulation;

    // GL_EXT_sRGB_write_control
    bool mFramebufferSRGB;

    // GL_ANGLE_webgl_compatibility
    bool mTextureRectangleEnabled;

    // GL_ANGLE_logic_op
    bool mLogicOpEnabled;
    LogicalOperation mLogicOp;

    // GL_APPLE_clip_distance / GL_EXT_clip_cull_distance / GL_ANGLE_clip_cull_distance
    ClipDistanceEnableBits mClipDistancesEnabled;

    // GL_EXT_tessellation_shader
    GLuint mPatchVertices;

    // GL_ANGLE_shader_pixel_local_storage
    GLsizei mPixelLocalStorageActivePlanes;
    // Overridden PLS draw buffers require no blend and a full color mask. While PLS is active,
    // defer any updates to these states until it ends.
    DrawBufferMask mPLSDeferredBlendEnables;
    BlendStateExt::ColorMaskStorage::Type mPLSDeferredColorMasks;

    // GLES1 emulation: state specific to GLES1
    GLES1State mGLES1State;

    // OES_draw_buffers_indexed
    DrawBufferMask mBlendFuncConstantAlphaDrawBuffers;
    DrawBufferMask mBlendFuncConstantColorDrawBuffers;
    bool mNoSimultaneousConstantColorAndAlphaBlendFunc;
    // Whether the indexed variants of setBlend* have been called.  If so, the call to the
    // non-indexed variants are not no-oped.
    bool mSetBlendIndexedInvoked;
    bool mSetBlendFactorsIndexedInvoked;
    bool mSetBlendEquationsIndexedInvoked;

    // GL_EXT_primitive_bounding_box
    GLfloat mBoundingBoxMinX;
    GLfloat mBoundingBoxMinY;
    GLfloat mBoundingBoxMinZ;
    GLfloat mBoundingBoxMinW;
    GLfloat mBoundingBoxMaxX;
    GLfloat mBoundingBoxMaxY;
    GLfloat mBoundingBoxMaxZ;
    GLfloat mBoundingBoxMaxW;

    // QCOM_shading_rate
    bool mShadingRatePreserveAspectRatio;
    ShadingRate mShadingRateQCOM;

    // GL_EXT_fragment_shading_rate
    ShadingRate mShadingRateEXT;
    std::array<CombinerOp, 2> mCombinerOps;

    // GL_ARM_shader_framebuffer_fetch
    bool mFetchPerSample;

    // Whether perf monitoring is enabled through GL_AMD_performance_monitor.
    bool mIsPerfMonitorActive;

    // QCOM_tiled_rendering
    bool mTiledRendering;

    const bool mBindGeneratesResource;
    const bool mClientArraysEnabled;
    const bool mRobustResourceInit;
    const bool mProgramBinaryCacheEnabled;

    VertexArrayPrivate *mVertexArrayPrivate;

    Debug mDebug;

    // ANGLE_blob_cache
    BlobCacheCallbacks mBlobCacheCallbacks;

    state::DirtyBits mDirtyBits;
    state::ExtendedDirtyBits mExtendedDirtyBits;
    state::DirtyObjects mDirtyObjects;
    mutable AttributesMask mDirtyCurrentValues;

    VertexArrayMap mVertexArrayMap;
    HandleAllocator mVertexArrayHandleAllocator;
};

// This class represents all of the GL context's state.
class State : angle::NonCopyable
{
  public:
    State(const State *shareContextState,
          egl::ShareGroup *shareGroup,
          TextureManager *shareTextures,
          SemaphoreManager *shareSemaphores,
          egl::ContextMutex *contextMutex,
          const OverlayType *overlay,
          const Version &clientVersion,
          bool debug,
          bool bindGeneratesResourceCHROMIUM,
          bool clientArraysEnabled,
          bool robustResourceInit,
          bool programBinaryCacheEnabled,
          EGLenum contextPriority,
          bool hasRobustAccess,
          bool hasProtectedContent,
          bool isExternal,
          bool passthroughShaders);
    ~State();

    void initialize(Context *context);
    void reset(const Context *context);

    // Getters
    ContextID getContextID() const { return mID; }
    EGLenum getContextPriority() const { return mContextPriority; }
    bool hasRobustAccess() const { return mHasRobustAccess; }
    bool hasProtectedContent() const { return mHasProtectedContent; }
    bool isDebugContext() const { return mIsDebugContext; }
    const Version &getClientVersion() const { return mPrivateState.getClientVersion(); }
    egl::ShareGroup *getShareGroup() const { return mShareGroup; }

    bool isWebGL() const { return mPrivateState.isWebGL(); }
    bool isWebGL1() const { return mPrivateState.isWebGL1(); }
    bool isGLES1() const { return mPrivateState.isGLES1(); }

    const Caps &getCaps() const { return mPrivateState.getCaps(); }
    const TextureCapsMap &getTextureCaps() const { return mPrivateState.getTextureCaps(); }
    const Extensions &getExtensions() const { return mPrivateState.getExtensions(); }
    const Limitations &getLimitations() const { return mPrivateState.getLimitations(); }

    bool isExternal() const { return mPrivateState.isExternal(); }

    bool usesPassthroughShaders() const { return mPassthroughShaders; }

    Caps *getMutableCaps() { return mPrivateState.getMutableCaps(); }
    TextureCapsMap *getMutableTextureCaps() { return mPrivateState.getMutableTextureCaps(); }
    Extensions *getMutableExtensions() { return mPrivateState.getMutableExtensions(); }
    Limitations *getMutableLimitations() { return mPrivateState.getMutableLimitations(); }

    GLuint getGroupMarkerCount() const { return mPrivateState.getGroupMarkerCount(); }
    void incrementGroupMarkers() { mPrivateState.incrementGroupMarkers(); }
    void decrementGroupMarkers() { mPrivateState.decrementGroupMarkers(); }

    const TextureCaps &getTextureCap(GLenum internalFormat) const
    {
        return getTextureCaps().get(internalFormat);
    }

    bool allActiveDrawBufferChannelsMasked() const;
    bool anyActiveDrawBufferChannelMasked() const;

    // Texture binding & active texture unit manipulation
    void setSamplerTexture(const Context *context, TextureType type, Texture *texture);
    Texture *getTargetTexture(TextureType type) const
    {
        return getSamplerTexture(getActiveSampler(), type);
    }

    Texture *getSamplerTexture(unsigned int sampler, TextureType type) const
    {
        ASSERT(sampler < mSamplerTextures[type].size());
        return mSamplerTextures[type][sampler].get();
    }

    TextureID getSamplerTextureId(unsigned int sampler, TextureType type) const;
    void detachTexture(Context *context, const TextureMap &zeroTextures, TextureID texture);
    void initializeZeroTextures(const Context *context, const TextureMap &zeroTextures);

    void invalidateTextureBindings(TextureType type);

    bool isTextureBoundToActivePLS(TextureID) const;

    // Sampler object binding manipulation
    void setSamplerBinding(const Context *context, GLuint textureUnit, Sampler *sampler);
    SamplerID getSamplerId(GLuint textureUnit) const
    {
        ASSERT(textureUnit < mSamplers.size());
        return mSamplers[textureUnit].id();
    }

    Sampler *getSampler(GLuint textureUnit) const { return mSamplers[textureUnit].get(); }

    const SamplerBindingVector &getSamplers() const { return mSamplers; }

    void detachSampler(const Context *context, SamplerID sampler);

    // Renderbuffer binding manipulation
    void setRenderbufferBinding(const Context *context, Renderbuffer *renderbuffer);
    RenderbufferID getRenderbufferId() const { return mRenderbuffer.id(); }
    Renderbuffer *getCurrentRenderbuffer() const { return mRenderbuffer.get(); }
    void detachRenderbuffer(Context *context, RenderbufferID renderbuffer);

    // Framebuffer binding manipulation
    void setReadFramebufferBinding(Framebuffer *framebuffer);
    void setDrawFramebufferBinding(Framebuffer *framebuffer);
    Framebuffer *getTargetFramebuffer(GLenum target) const;
    Framebuffer *getReadFramebuffer() const { return mReadFramebuffer; }
    Framebuffer *getDrawFramebuffer() const { return mDrawFramebuffer; }
    Framebuffer *getDefaultFramebuffer() const;

    bool removeReadFramebufferBinding(FramebufferID framebuffer);
    bool removeDrawFramebufferBinding(FramebufferID framebuffer);

    // Vertex array object binding manipulation
    void setVertexArrayBinding(const Context *context, VertexArray *vertexArray);
    bool removeVertexArrayBinding(const Context *context, VertexArrayID vertexArray);
    VertexArrayID getVertexArrayId() const;
    VertexArray *getVertexArray() const
    {
        ASSERT(mVertexArray != nullptr);
        return mVertexArray;
    }

    // If both a Program and a ProgramPipeline are bound, the Program will
    // always override the ProgramPipeline.
    ProgramExecutable *getProgramExecutable() const { return mExecutable.get(); }
    void ensureNoPendingLink(const Context *context) const
    {
        if (mProgram)
        {
            mProgram->resolveLink(context);
        }
        else if (mProgramPipeline.get())
        {
            mProgramPipeline->resolveLink(context);
        }
    }
    ProgramExecutable *getLinkedProgramExecutable(const Context *context) const
    {
        ensureNoPendingLink(context);
        return mExecutable.get();
    }

    // Program binding manipulation
    angle::Result setProgram(const Context *context, Program *newProgram);

    Program *getProgram() const
    {
        ASSERT(!mProgram || !mProgram->isLinking());
        return mProgram;
    }

    ANGLE_INLINE Program *getLinkedProgram(const Context *context) const
    {
        if (ANGLE_LIKELY(mProgram))
        {
            mProgram->resolveLink(context);
        }
        return mProgram;
    }

    ProgramPipeline *getProgramPipeline() const { return mProgramPipeline.get(); }

    ProgramPipeline *getLinkedProgramPipeline(const Context *context) const
    {
        if (mProgramPipeline.get())
        {
            mProgramPipeline->resolveLink(context);
        }
        return mProgramPipeline.get();
    }

    // Transform feedback object (not buffer) binding manipulation
    void setTransformFeedbackBinding(const Context *context, TransformFeedback *transformFeedback);
    TransformFeedback *getCurrentTransformFeedback() const { return mTransformFeedback.get(); }

    ANGLE_INLINE bool isTransformFeedbackActive() const
    {
        TransformFeedback *curTransformFeedback = mTransformFeedback.get();
        return curTransformFeedback && curTransformFeedback->isActive();
    }
    ANGLE_INLINE bool isTransformFeedbackActiveUnpaused() const
    {
        TransformFeedback *curTransformFeedback = mTransformFeedback.get();
        return curTransformFeedback && curTransformFeedback->isActive() &&
               !curTransformFeedback->isPaused();
    }

    bool removeTransformFeedbackBinding(const Context *context,
                                        TransformFeedbackID transformFeedback);

    // Query binding manipulation
    bool isQueryActive(QueryType type) const;
    bool isQueryActive(Query *query) const;
    void setActiveQuery(const Context *context, QueryType type, Query *query);
    QueryID getActiveQueryId(QueryType type) const;
    Query *getActiveQuery(QueryType type) const;

    // Program Pipeline binding manipulation
    angle::Result setProgramPipelineBinding(const Context *context, ProgramPipeline *pipeline);
    void detachProgramPipeline(const Context *context, ProgramPipelineID pipeline);

    //// Typed buffer binding point manipulation ////
    ANGLE_INLINE void setBufferBinding(const Context *context, BufferBinding target, Buffer *buffer)
    {
        (this->*(kBufferSetters[target]))(context, buffer);
    }

    ANGLE_INLINE Buffer *getTargetBuffer(BufferBinding target) const
    {
        switch (target)
        {
            case BufferBinding::ElementArray:
                return getVertexArray()->getElementArrayBuffer();
            default:
                return mBoundBuffers[target].get();
        }
    }

    ANGLE_INLINE Buffer *getArrayBuffer() const { return getTargetBuffer(BufferBinding::Array); }

    angle::Result setIndexedBufferBinding(const Context *context,
                                          BufferBinding target,
                                          GLuint index,
                                          Buffer *buffer,
                                          GLintptr offset,
                                          GLsizeiptr size);

    size_t getAtomicCounterBufferCount() const { return mAtomicCounterBuffers.size(); }

    ANGLE_INLINE bool hasValidAtomicCounterBuffer() const
    {
        return mBoundAtomicCounterBuffersMask.any();
    }

    const OffsetBindingPointer<Buffer> &getIndexedUniformBuffer(size_t index) const;
    const OffsetBindingPointer<Buffer> &getIndexedAtomicCounterBuffer(size_t index) const;
    const OffsetBindingPointer<Buffer> &getIndexedShaderStorageBuffer(size_t index) const;

    const angle::BitSet<gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS> &getUniformBuffersMask()
        const
    {
        return mBoundUniformBuffersMask;
    }
    const angle::BitSet<gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS> &
    getAtomicCounterBuffersMask() const
    {
        return mBoundAtomicCounterBuffersMask;
    }
    const angle::BitSet<gl::IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS> &
    getShaderStorageBuffersMask() const
    {
        return mBoundShaderStorageBuffersMask;
    }

    // Detach a buffer from all bindings
    angle::Result detachBuffer(Context *context, const Buffer *buffer);

    ANGLE_INLINE void setVertexAttribPointer(const Context *context,
                                             unsigned int attribNum,
                                             Buffer *boundBuffer,
                                             GLint size,
                                             VertexAttribType type,
                                             bool normalized,
                                             GLsizei stride,
                                             const void *pointer,
                                             bool *isVertexAttribDirtyOut)
    {
        ASSERT(isVertexAttribDirtyOut);
        mVertexArray->setVertexAttribPointer(context, attribNum, boundBuffer, size, type,
                                             normalized, stride, pointer, isVertexAttribDirtyOut);
        if (*isVertexAttribDirtyOut)
        {
            mDirtyObjects.set(state::DIRTY_OBJECT_VERTEX_ARRAY);
        }
    }

    ANGLE_INLINE void setVertexAttribIPointer(const Context *context,
                                              unsigned int attribNum,
                                              Buffer *boundBuffer,
                                              GLint size,
                                              VertexAttribType type,
                                              GLsizei stride,
                                              const void *pointer,
                                              bool *isVertexAttribDirtyOut)
    {
        ASSERT(isVertexAttribDirtyOut);
        mVertexArray->setVertexAttribIPointer(context, attribNum, boundBuffer, size, type, stride,
                                              pointer, isVertexAttribDirtyOut);
        if (*isVertexAttribDirtyOut)
        {
            mDirtyObjects.set(state::DIRTY_OBJECT_VERTEX_ARRAY);
        }
    }

    const void *getVertexAttribPointer(unsigned int attribNum) const;

    void bindVertexBuffer(const Context *context,
                          GLuint bindingIndex,
                          Buffer *boundBuffer,
                          GLintptr offset,
                          GLsizei stride);

    // State query functions
    void getBooleanv(GLenum pname, GLboolean *params) const;
    void getFloatv(GLenum pname, GLfloat *params) const { mPrivateState.getFloatv(pname, params); }
    angle::Result getIntegerv(const Context *context, GLenum pname, GLint *params) const;
    void getPointerv(const Context *context, GLenum pname, void **params) const;
    void getIntegeri_v(GLenum target, GLuint index, GLint *data) const;
    void getInteger64i_v(GLenum target, GLuint index, GLint64 *data) const;
    void getBooleani_v(GLenum target, GLuint index, GLboolean *data) const;

    bool isDrawFramebufferBindingDirty() const
    {
        return mDirtyBits.test(state::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
    }

    // Sets the dirty bit for the program executable.
    angle::Result installProgramExecutable(const Context *context);
    // Sets the dirty bit for the program pipeline executable.
    angle::Result installProgramPipelineExecutable(const Context *context);

    const state::DirtyBits getDirtyBits() const
    {
        return mDirtyBits | mPrivateState.getDirtyBits();
    }
    void clearDirtyBits(const state::DirtyBits &bitset)
    {
        mDirtyBits &= ~bitset;
        mPrivateState.clearDirtyBits(bitset);
    }
    void setAllDirtyBits()
    {
        mDirtyBits.set();
        mExtendedDirtyBits.set();
        mPrivateState.setAllDirtyBits();
    }

    const state::ExtendedDirtyBits getExtendedDirtyBits() const
    {
        return mExtendedDirtyBits | mPrivateState.getExtendedDirtyBits();
    }
    void clearExtendedDirtyBits(const state::ExtendedDirtyBits &bitset)
    {
        mExtendedDirtyBits &= ~bitset;
        mPrivateState.clearExtendedDirtyBits(bitset);
    }

    void clearDirtyObjects()
    {
        mDirtyObjects.reset();
        mPrivateState.clearDirtyObjects();
    }
    void setAllDirtyObjects()
    {
        mDirtyObjects.set();
        if (!isRobustResourceInitEnabled())
        {
            mDirtyObjects.reset(state::DIRTY_OBJECT_READ_ATTACHMENTS);
            mDirtyObjects.reset(state::DIRTY_OBJECT_DRAW_ATTACHMENTS);
        }
    }
    angle::Result syncDirtyObjects(const Context *context,
                                   const state::DirtyObjects &bitset,
                                   Command command);
    angle::Result syncDirtyObject(const Context *context, GLenum target, Command command);
    void setObjectDirty(GLenum target);
    void setTextureDirty(size_t textureUnitIndex);
    void setSamplerDirty(size_t samplerIndex);

    ANGLE_INLINE void setReadFramebufferDirty()
    {
        mDirtyObjects.set(state::DIRTY_OBJECT_READ_FRAMEBUFFER);
        if (isRobustResourceInitEnabled())
        {
            mDirtyObjects.set(state::DIRTY_OBJECT_READ_ATTACHMENTS);
        }
    }

    ANGLE_INLINE void setDrawFramebufferDirty()
    {
        mDirtyObjects.set(state::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
        if (isRobustResourceInitEnabled())
        {
            mDirtyObjects.set(state::DIRTY_OBJECT_DRAW_ATTACHMENTS);
        }
    }

    void setImageUnit(const Context *context,
                      size_t unit,
                      Texture *texture,
                      GLint level,
                      GLboolean layered,
                      GLint layer,
                      GLenum access,
                      GLenum format);

    const ImageUnit &getImageUnit(size_t unit) const { return mImageUnits[unit]; }
    const ActiveTexturesCache &getActiveTexturesCache() const { return mActiveTexturesCache; }

    // "onActiveTextureChange" is called when a texture binding changes.
    void onActiveTextureChange(const Context *context, size_t textureUnit);

    // "onActiveTextureStateChange" is called when the Texture changed but the binding did not.
    void onActiveTextureStateChange(const Context *context, size_t textureUnit);

    void onImageStateChange(const Context *context, size_t unit);

    void onUniformBufferStateChange(size_t uniformBufferIndex, angle::SubjectMessage message);
    void onAtomicCounterBufferStateChange(size_t atomicCounterBufferIndex);
    void onShaderStorageBufferStateChange(size_t shaderStorageBufferIndex);

    bool isCurrentTransformFeedback(const TransformFeedback *tf) const
    {
        return tf == mTransformFeedback.get();
    }
    bool isCurrentVertexArray(const VertexArray *va) const { return va == mVertexArray; }

    // Helpers for setting bound buffers. They should all have the same signature.
    // Not meant to be called externally. Used for local helpers in State.cpp.
    template <BufferBinding Target>
    void setGenericBufferBindingWithBit(const Context *context, Buffer *buffer);

    template <BufferBinding Target>
    void setGenericBufferBinding(const Context *context, Buffer *buffer);

    using BufferBindingSetter = void (State::*)(const Context *, Buffer *);

    ANGLE_INLINE bool validateSamplerFormats() const
    {
        return (!mExecutable || !(mTexturesIncompatibleWithSamplers.intersects(
                                    mExecutable->getActiveSamplersMask())));
    }

    ANGLE_INLINE void setReadFramebufferBindingDirty()
    {
        mDirtyBits.set(state::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
    }

    ANGLE_INLINE void setDrawFramebufferBindingDirty()
    {
        mDirtyBits.set(state::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
    }

    const OverlayType *getOverlay() const { return mOverlay; }

    // Not for general use.
    const BufferManager &getBufferManagerForCapture() const { return *mBufferManager; }
    const BoundBufferMap &getBoundBuffersForCapture() const { return mBoundBuffers; }
    const TextureManager &getTextureManagerForCapture() const { return *mTextureManager; }
    const TextureBindingMap &getBoundTexturesForCapture() const { return mSamplerTextures; }
    const RenderbufferManager &getRenderbufferManagerForCapture() const
    {
        return *mRenderbufferManager;
    }
    const FramebufferManager &getFramebufferManagerForCapture() const
    {
        return *mFramebufferManager;
    }
    const ShaderProgramManager &getShaderProgramManagerForCapture() const
    {
        return *mShaderProgramManager;
    }
    const SyncManager &getSyncManagerForCapture() const { return *mSyncManager; }
    const SamplerManager &getSamplerManagerForCapture() const { return *mSamplerManager; }
    const ProgramPipelineManager *getProgramPipelineManagerForCapture() const
    {
        return mProgramPipelineManager;
    }
    const SamplerBindingVector &getSamplerBindingsForCapture() const { return mSamplers; }
    const ActiveQueryMap &getActiveQueriesForCapture() const { return mActiveQueries; }
    void initializeForCapture(const Context *context);

    bool hasConstantAlphaBlendFunc() const
    {
        return (getBlendFuncConstantAlphaDrawBuffers() & getBlendStateExt().getEnabledMask()).any();
    }

    bool hasSimultaneousConstantColorAndAlphaBlendFunc() const
    {
        return (getBlendFuncConstantColorDrawBuffers() & getBlendStateExt().getEnabledMask())
                   .any() &&
               hasConstantAlphaBlendFunc();
    }

    const BufferVector &getOffsetBindingPointerUniformBuffers() const { return mUniformBuffers; }

    const BufferVector &getOffsetBindingPointerAtomicCounterBuffers() const
    {
        return mAtomicCounterBuffers;
    }

    const BufferVector &getOffsetBindingPointerShaderStorageBuffers() const
    {
        return mShaderStorageBuffers;
    }

    ActiveTextureMask getTexturesIncompatibleWithSamplers() const
    {
        return mTexturesIncompatibleWithSamplers;
    }

    const std::vector<ImageUnit> &getImageUnits() const { return mImageUnits; }

    bool hasDisplayTextureShareGroup() const { return mDisplayTextureShareGroup; }

    // GL_KHR_parallel_shader_compile
    void setMaxShaderCompilerThreads(GLuint count);
    GLuint getMaxShaderCompilerThreads() const { return mMaxShaderCompilerThreads; }

    // Convenience functions that forward to context-private state.
    const RasterizerState &getRasterizerState() const { return mPrivateState.getRasterizerState(); }
    const BlendStateExt &getBlendStateExt() const { return mPrivateState.getBlendStateExt(); }
    const DepthStencilState &getDepthStencilState() const
    {
        return mPrivateState.getDepthStencilState();
    }
    const ColorF &getColorClearValue() const { return mPrivateState.getColorClearValue(); }
    float getDepthClearValue() const { return mPrivateState.getDepthClearValue(); }
    int getStencilClearValue() const { return mPrivateState.getStencilClearValue(); }
    bool isRasterizerDiscardEnabled() const { return mPrivateState.isRasterizerDiscardEnabled(); }
    bool isPrimitiveRestartEnabled() const { return mPrivateState.isPrimitiveRestartEnabled(); }
    bool isCullFaceEnabled() const { return mPrivateState.isCullFaceEnabled(); }
    bool isDepthClampEnabled() const { return mPrivateState.isDepthClampEnabled(); }
    bool isDepthTestEnabled() const { return mPrivateState.isDepthTestEnabled(); }
    bool isDepthWriteEnabled() const { return mPrivateState.isDepthWriteEnabled(); }
    float getNearPlane() const { return mPrivateState.getNearPlane(); }
    float getFarPlane() const { return mPrivateState.getFarPlane(); }
    ClipOrigin getClipOrigin() const { return mPrivateState.getClipOrigin(); }
    ClipDepthMode getClipDepthMode() const { return mPrivateState.getClipDepthMode(); }
    bool isClipDepthModeZeroToOne() const { return mPrivateState.isClipDepthModeZeroToOne(); }
    bool isBlendEnabled() const { return mPrivateState.isBlendEnabled(); }
    bool isBlendEnabledIndexed(GLuint index) const
    {
        return mPrivateState.isBlendEnabledIndexed(index);
    }
    DrawBufferMask getBlendEnabledDrawBufferMask() const
    {
        return mPrivateState.getBlendEnabledDrawBufferMask();
    }
    const ColorF &getBlendColor() const { return mPrivateState.getBlendColor(); }
    bool isStencilTestEnabled() const { return mPrivateState.isStencilTestEnabled(); }
    bool isBlendAdvancedCoherentEnabled() const
    {
        return mPrivateState.isBlendAdvancedCoherentEnabled();
    }
    bool isStencilWriteEnabled(GLuint framebufferStencilSize) const
    {
        return mPrivateState.isStencilWriteEnabled(framebufferStencilSize);
    }
    GLint getStencilRef() const { return mPrivateState.getStencilRef(); }
    GLint getStencilBackRef() const { return mPrivateState.getStencilBackRef(); }
    PolygonMode getPolygonMode() const { return mPrivateState.getPolygonMode(); }
    bool isPolygonOffsetPointEnabled() const { return mPrivateState.isPolygonOffsetPointEnabled(); }
    bool isPolygonOffsetLineEnabled() const { return mPrivateState.isPolygonOffsetLineEnabled(); }
    bool isPolygonOffsetFillEnabled() const { return mPrivateState.isPolygonOffsetFillEnabled(); }
    bool isPolygonOffsetEnabled() const { return mPrivateState.isPolygonOffsetEnabled(); }
    bool isSampleAlphaToCoverageEnabled() const
    {
        return mPrivateState.isSampleAlphaToCoverageEnabled();
    }
    bool isSampleCoverageEnabled() const { return mPrivateState.isSampleCoverageEnabled(); }
    GLclampf getSampleCoverageValue() const { return mPrivateState.getSampleCoverageValue(); }
    bool getSampleCoverageInvert() const { return mPrivateState.getSampleCoverageInvert(); }
    bool isSampleMaskEnabled() const { return mPrivateState.isSampleMaskEnabled(); }
    GLbitfield getSampleMaskWord(GLuint maskNumber) const
    {
        return mPrivateState.getSampleMaskWord(maskNumber);
    }
    SampleMaskArray<GLbitfield> getSampleMaskValues() const
    {
        return mPrivateState.getSampleMaskValues();
    }
    GLuint getMaxSampleMaskWords() const { return mPrivateState.getMaxSampleMaskWords(); }
    bool isSampleAlphaToOneEnabled() const { return mPrivateState.isSampleAlphaToOneEnabled(); }
    bool isMultisamplingEnabled() const { return mPrivateState.isMultisamplingEnabled(); }
    bool isSampleShadingEnabled() const { return mPrivateState.isSampleShadingEnabled(); }
    float getMinSampleShading() const { return mPrivateState.getMinSampleShading(); }
    bool isScissorTestEnabled() const { return mPrivateState.isScissorTestEnabled(); }
    const Rectangle &getScissor() const { return mPrivateState.getScissor(); }
    bool isDitherEnabled() const { return mPrivateState.isDitherEnabled(); }
    bool isBindGeneratesResourceEnabled() const
    {
        return mPrivateState.isBindGeneratesResourceEnabled();
    }
    bool areClientArraysEnabled() const { return mPrivateState.areClientArraysEnabled(); }
    bool isRobustResourceInitEnabled() const { return mPrivateState.isRobustResourceInitEnabled(); }
    bool isProgramBinaryCacheEnabled() const { return mPrivateState.isProgramBinaryCacheEnabled(); }
    const Rectangle &getViewport() const { return mPrivateState.getViewport(); }
    ShadingRate getShadingRateQCOM() const { return mPrivateState.getShadingRateQCOM(); }
    ShadingRate getShadingRateEXT() const { return mPrivateState.getShadingRateEXT(); }
    bool getFetchPerSample() const { return mPrivateState.getFetchPerSample(); }
    const std::array<CombinerOp, 2> &getShadingRateCombinerOps() const
    {
        return mPrivateState.getShadingRateCombinerOps();
    }
    GLint getPackAlignment() const { return mPrivateState.getPackAlignment(); }
    bool getPackReverseRowOrder() const { return mPrivateState.getPackReverseRowOrder(); }
    GLint getPackRowLength() const { return mPrivateState.getPackRowLength(); }
    GLint getPackSkipRows() const { return mPrivateState.getPackSkipRows(); }
    GLint getPackSkipPixels() const { return mPrivateState.getPackSkipPixels(); }
    const PixelPackState &getPackState() const { return mPrivateState.getPackState(); }
    PixelPackState &getPackState() { return mPrivateState.getPackState(); }
    GLint getUnpackAlignment() const { return mPrivateState.getUnpackAlignment(); }
    GLint getUnpackRowLength() const { return mPrivateState.getUnpackRowLength(); }
    GLint getUnpackImageHeight() const { return mPrivateState.getUnpackImageHeight(); }
    GLint getUnpackSkipImages() const { return mPrivateState.getUnpackSkipImages(); }
    GLint getUnpackSkipRows() const { return mPrivateState.getUnpackSkipRows(); }
    GLint getUnpackSkipPixels() const { return mPrivateState.getUnpackSkipPixels(); }
    const PixelUnpackState &getUnpackState() const { return mPrivateState.getUnpackState(); }
    PixelUnpackState &getUnpackState() { return mPrivateState.getUnpackState(); }
    GLenum getCoverageModulation() const { return mPrivateState.getCoverageModulation(); }
    bool getFramebufferSRGB() const { return mPrivateState.getFramebufferSRGB(); }
    GLuint getPatchVertices() const { return mPrivateState.getPatchVertices(); }
    GLsizei getPixelLocalStorageActivePlanes() const
    {
        return mPrivateState.getPixelLocalStorageActivePlanes();
    }
    float getLineWidth() const { return mPrivateState.getLineWidth(); }
    unsigned int getActiveSampler() const { return mPrivateState.getActiveSampler(); }
    GLenum getGenerateMipmapHint() const { return mPrivateState.getGenerateMipmapHint(); }
    GLenum getFragmentShaderDerivativeHint() const
    {
        return mPrivateState.getFragmentShaderDerivativeHint();
    }
    ProvokingVertexConvention getProvokingVertex() const
    {
        return mPrivateState.getProvokingVertex();
    }
    const VertexAttribCurrentValueData &getVertexAttribCurrentValue(size_t attribNum) const
    {
        return mPrivateState.getVertexAttribCurrentValue(attribNum);
    }
    const std::vector<VertexAttribCurrentValueData> &getVertexAttribCurrentValues() const
    {
        return mPrivateState.getVertexAttribCurrentValues();
    }
    AttributesMask getAndResetDirtyCurrentValues() const
    {
        return mPrivateState.getAndResetDirtyCurrentValues();
    }
    ComponentTypeMask getCurrentValuesTypeMask() const
    {
        return mPrivateState.getCurrentValuesTypeMask();
    }
    const ClipDistanceEnableBits &getEnabledClipDistances() const
    {
        return mPrivateState.getEnabledClipDistances();
    }
    bool noSimultaneousConstantColorAndAlphaBlendFunc() const
    {
        return mPrivateState.noSimultaneousConstantColorAndAlphaBlendFunc();
    }
    GLfloat getBoundingBoxMinX() const { return mPrivateState.getBoundingBoxMinX(); }
    GLfloat getBoundingBoxMinY() const { return mPrivateState.getBoundingBoxMinY(); }
    GLfloat getBoundingBoxMinZ() const { return mPrivateState.getBoundingBoxMinZ(); }
    GLfloat getBoundingBoxMinW() const { return mPrivateState.getBoundingBoxMinW(); }
    GLfloat getBoundingBoxMaxX() const { return mPrivateState.getBoundingBoxMaxX(); }
    GLfloat getBoundingBoxMaxY() const { return mPrivateState.getBoundingBoxMaxY(); }
    GLfloat getBoundingBoxMaxZ() const { return mPrivateState.getBoundingBoxMaxZ(); }
    GLfloat getBoundingBoxMaxW() const { return mPrivateState.getBoundingBoxMaxW(); }
    bool isTextureRectangleEnabled() const { return mPrivateState.isTextureRectangleEnabled(); }
    DrawBufferMask getBlendFuncConstantAlphaDrawBuffers() const
    {
        return mPrivateState.getBlendFuncConstantAlphaDrawBuffers();
    }
    DrawBufferMask getBlendFuncConstantColorDrawBuffers() const
    {
        return mPrivateState.getBlendFuncConstantColorDrawBuffers();
    }
    bool isLogicOpEnabled() const { return mPrivateState.isLogicOpEnabled(); }
    LogicalOperation getLogicOp() const { return mPrivateState.getLogicOp(); }
    bool isPerfMonitorActive() const { return mPrivateState.isPerfMonitorActive(); }
    const Debug &getDebug() const { return mPrivateState.getDebug(); }
    Debug &getDebug() { return mPrivateState.getDebug(); }
    const BlobCacheCallbacks &getBlobCacheCallbacks() const
    {
        return mPrivateState.getBlobCacheCallbacks();
    }
    BlobCacheCallbacks &getBlobCacheCallbacks() { return mPrivateState.getBlobCacheCallbacks(); }
    bool getEnableFeature(GLenum feature) const { return mPrivateState.getEnableFeature(feature); }
    bool getEnableFeatureIndexed(GLenum feature, GLuint index) const
    {
        return mPrivateState.getEnableFeatureIndexed(feature, index);
    }
    ProgramUniformBlockMask getAndResetDirtyUniformBlocks() const
    {
        ProgramUniformBlockMask dirtyBits = mDirtyUniformBlocks;
        mDirtyUniformBlocks.reset();
        return dirtyBits;
    }
    BufferDirtyTypeBitMask getAndResetUniformBufferBlocksDirtyTypeMask() const
    {
        BufferDirtyTypeBitMask dirtyTypeMask = mUniformBufferBlocksDirtyTypeMask;
        mUniformBufferBlocksDirtyTypeMask.reset();
        return dirtyTypeMask;
    }
    const PrivateState &privateState() const { return mPrivateState; }
    const GLES1State &gles1() const { return mPrivateState.gles1(); }

    // Used by the capture/replay tool to create state.
    PrivateState *getMutablePrivateStateForCapture() { return &mPrivateState; }

  private:
    friend class Context;

    // Used only by the entry points to set private state without holding the share group lock.
    PrivateState *getMutablePrivateState() { return &mPrivateState; }
    GLES1State *getMutableGLES1State() { return mPrivateState.getMutableGLES1State(); }

    angle::Result installProgramPipelineExecutableIfNotAlready(const Context *context);
    angle::Result onExecutableChange(const Context *context);

    void unsetActiveTextures(const ActiveTextureMask &textureMask);
    void setActiveTextureDirty(size_t textureIndex, Texture *texture);
    void updateTextureBinding(const Context *context, size_t textureIndex, Texture *texture);
    void updateActiveTextureStateOnSync(const Context *context,
                                        size_t textureIndex,
                                        const Sampler *sampler,
                                        Texture *texture);
    Texture *getTextureForActiveSampler(TextureType type, size_t index);

    // Functions to synchronize dirty states
    angle::Result syncActiveTextures(const Context *context, Command command);
    angle::Result syncTexturesInit(const Context *context, Command command);
    angle::Result syncImagesInit(const Context *context, Command command);
    angle::Result syncReadAttachments(const Context *context, Command command);
    angle::Result syncDrawAttachments(const Context *context, Command command);
    angle::Result syncReadFramebuffer(const Context *context, Command command);
    angle::Result syncDrawFramebuffer(const Context *context, Command command);
    angle::Result syncVertexArray(const Context *context, Command command);
    angle::Result syncTextures(const Context *context, Command command);
    angle::Result syncImages(const Context *context, Command command);
    angle::Result syncSamplers(const Context *context, Command command);
    angle::Result syncProgramPipelineObject(const Context *context, Command command);

    using DirtyObjectHandler = angle::Result (State::*)(const Context *context, Command command);
    using DirtyObjectHandlerArray = std::array<DirtyObjectHandler, state::DIRTY_OBJECT_MAX>;

    static constexpr DirtyObjectHandlerArray MakeDirtyObjectHandlers()
    {
        // Work around C++'s lack of array element support in designated initializers
        // This function cannot be a lambda due to MSVC C++17 limitations b/330910097#comment5
        DirtyObjectHandlerArray handlers{};

        handlers[state::DIRTY_OBJECT_ACTIVE_TEXTURES]         = &State::syncActiveTextures;
        handlers[state::DIRTY_OBJECT_TEXTURES_INIT]           = &State::syncTexturesInit;
        handlers[state::DIRTY_OBJECT_IMAGES_INIT]             = &State::syncImagesInit;
        handlers[state::DIRTY_OBJECT_READ_ATTACHMENTS]        = &State::syncReadAttachments;
        handlers[state::DIRTY_OBJECT_DRAW_ATTACHMENTS]        = &State::syncDrawAttachments;
        handlers[state::DIRTY_OBJECT_READ_FRAMEBUFFER]        = &State::syncReadFramebuffer;
        handlers[state::DIRTY_OBJECT_DRAW_FRAMEBUFFER]        = &State::syncDrawFramebuffer;
        handlers[state::DIRTY_OBJECT_VERTEX_ARRAY]            = &State::syncVertexArray;
        handlers[state::DIRTY_OBJECT_TEXTURES]                = &State::syncTextures;
        handlers[state::DIRTY_OBJECT_IMAGES]                  = &State::syncImages;
        handlers[state::DIRTY_OBJECT_SAMPLERS]                = &State::syncSamplers;
        handlers[state::DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT] = &State::syncProgramPipelineObject;

        return handlers;
    }

    angle::Result dirtyObjectHandler(size_t dirtyObject, const Context *context, Command command)
    {
        static constexpr DirtyObjectHandlerArray handlers = MakeDirtyObjectHandlers();

        // Fail with static_assert if any handler is missing.
        constexpr auto existEmptyHandler = []() constexpr {
            for (auto handler : handlers)
            {
                if (handler == nullptr)
                {
                    return true;
                }
            }
            return false;
        };

        static_assert(!existEmptyHandler(), "MakeDirtyObjectHandlers missing a handler");

        return (this->*handlers[dirtyObject])(context, command);
    }

    // Robust init must happen before Framebuffer init for the Vulkan back-end.  If deferred clears
    // can be made to work in the Vulkan back-end such that textures could be sync'ed before the
    // framebuffer, then TEXTURES_INIT and IMAGES_INIT can be removed since robust init happens
    // during texture sync as well.
    static_assert(state::DIRTY_OBJECT_ACTIVE_TEXTURES < state::DIRTY_OBJECT_TEXTURES_INIT,
                  "init order");
    static_assert(state::DIRTY_OBJECT_TEXTURES_INIT < state::DIRTY_OBJECT_DRAW_FRAMEBUFFER,
                  "init order");
    static_assert(state::DIRTY_OBJECT_IMAGES_INIT < state::DIRTY_OBJECT_DRAW_FRAMEBUFFER,
                  "init order");
    static_assert(state::DIRTY_OBJECT_DRAW_ATTACHMENTS < state::DIRTY_OBJECT_DRAW_FRAMEBUFFER,
                  "init order");
    static_assert(state::DIRTY_OBJECT_READ_ATTACHMENTS < state::DIRTY_OBJECT_READ_FRAMEBUFFER,
                  "init order");

    // Dispatch table for buffer update functions.
    static const angle::PackedEnumMap<BufferBinding, BufferBindingSetter> kBufferSetters;

    ContextID mID;

    EGLenum mContextPriority;
    bool mHasRobustAccess;
    bool mHasProtectedContent;
    bool mIsDebugContext;
    bool mPassthroughShaders;

    egl::ShareGroup *mShareGroup;
    mutable egl::ContextMutex mContextMutex;

    // Resource managers.
    BufferManager *mBufferManager;
    ShaderProgramManager *mShaderProgramManager;
    TextureManager *mTextureManager;
    RenderbufferManager *mRenderbufferManager;
    SamplerManager *mSamplerManager;
    SyncManager *mSyncManager;
    FramebufferManager *mFramebufferManager;
    ProgramPipelineManager *mProgramPipelineManager;
    MemoryObjectManager *mMemoryObjectManager;
    SemaphoreManager *mSemaphoreManager;

    Framebuffer *mReadFramebuffer;
    Framebuffer *mDrawFramebuffer;
    BindingPointer<Renderbuffer> mRenderbuffer;
    Program *mProgram;
    BindingPointer<ProgramPipeline> mProgramPipeline;
    // The _installed_ executable.  Note that this may be different from the program's (or the
    // program pipeline's) executable, as they may have been unsuccessfully relinked.
    SharedProgramExecutable mExecutable;

    VertexArray *mVertexArray;

    TextureBindingMap mSamplerTextures;

    // Active Textures Cache
    // ---------------------
    // The active textures cache gives ANGLE components access to a complete array of textures
    // on a draw call. gl::State implements angle::Observer and watches gl::Texture for state
    // changes via the onSubjectStateChange method above. We update the cache before draws.
    // See Observer.h and the design doc linked there for more info on Subject/Observer events.
    //
    // On state change events (re-binding textures, samplers, programs etc) we clear the cache
    // and flag dirty bits. nullptr indicates unbound or incomplete.
    ActiveTexturesCache mActiveTexturesCache;
    std::vector<angle::ObserverBinding> mCompleteTextureBindings;

    ActiveTextureMask mTexturesIncompatibleWithSamplers;

    SamplerBindingVector mSamplers;

    // It would be nice to merge the image and observer binding. Same for textures.
    std::vector<ImageUnit> mImageUnits;

    ActiveQueryMap mActiveQueries;

    // Stores the currently bound buffer for each binding point. It has an entry for the element
    // array buffer but it should not be used. Instead this bind point is owned by the current
    // vertex array object.
    BoundBufferMap mBoundBuffers;

    BufferVector mUniformBuffers;
    BufferVector mAtomicCounterBuffers;
    BufferVector mShaderStorageBuffers;

    angle::BitSet<gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS> mBoundUniformBuffersMask;
    angle::BitSet<gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>
        mBoundAtomicCounterBuffersMask;
    angle::BitSet<gl::IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>
        mBoundShaderStorageBuffersMask;

    BindingPointer<TransformFeedback> mTransformFeedback;

    bool mDisplayTextureShareGroup;

    // GL_KHR_parallel_shader_compile
    GLuint mMaxShaderCompilerThreads;

    // The Overlay object, used by the backend to render the overlay.
    const OverlayType *mOverlay;

    state::DirtyBits mDirtyBits;
    state::ExtendedDirtyBits mExtendedDirtyBits;
    state::DirtyObjects mDirtyObjects;
    ActiveTextureMask mDirtyActiveTextures;
    ActiveTextureMask mDirtyTextures;
    ActiveTextureMask mDirtySamplers;
    ImageUnitMask mDirtyImages;
    // Tracks uniform blocks that need reprocessing, for example because their mapped bindings have
    // changed, or buffers in their mapped bindings have changed.  This is in State because every
    // context needs to react to such changes.
    mutable ProgramUniformBlockMask mDirtyUniformBlocks;
    // Fine grained dirty type for uniform buffers.
    mutable BufferDirtyTypeBitMask mUniformBufferBlocksDirtyTypeMask;

    PrivateState mPrivateState;
};

ANGLE_INLINE angle::Result State::syncDirtyObjects(const Context *context,
                                                   const state::DirtyObjects &bitset,
                                                   Command command)
{
    // Accumulate any dirty objects that might have been set due to context-private state changes.
    mDirtyObjects |= mPrivateState.getDirtyObjects();
    mPrivateState.clearDirtyObjects();

    ASSERT(isRobustResourceInitEnabled() ||
           (!mDirtyObjects.test(state::DIRTY_OBJECT_DRAW_ATTACHMENTS) &&
            !mDirtyObjects.test(state::DIRTY_OBJECT_READ_ATTACHMENTS)));

    const state::DirtyObjects &dirtyObjects = mDirtyObjects & bitset;

    for (size_t dirtyObject : dirtyObjects)
    {
        ANGLE_TRY(dirtyObjectHandler(dirtyObject, context, command));
    }

    mDirtyObjects &= ~dirtyObjects;

    return angle::Result::Continue;
}

}  // namespace gl

#endif  // LIBANGLE_STATE_H_
