//
// Copyright (c) 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.cpp: Implements the State class, encapsulating raw GL state.

#include "libANGLE/State.h"

#include <limits>
#include <string.h>

#include "common/bitset_utils.h"
#include "common/matrix_utils.h"
#include "common/mathutil.h"
#include "libANGLE/Context.h"
#include "libANGLE/Caps.h"
#include "libANGLE/Debug.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/Query.h"
#include "libANGLE/VertexArray.h"
#include "libANGLE/formatutils.h"

namespace
{

GLenum ActiveQueryType(const GLenum type)
{
    return (type == GL_ANY_SAMPLES_PASSED_CONSERVATIVE) ? GL_ANY_SAMPLES_PASSED : type;
}

}  // anonymous namepace

namespace gl
{

State::State()
    : mMaxDrawBuffers(0),
      mMaxCombinedTextureImageUnits(0),
      mDepthClearValue(0),
      mStencilClearValue(0),
      mScissorTest(false),
      mSampleCoverage(false),
      mSampleCoverageValue(0),
      mSampleCoverageInvert(false),
      mStencilRef(0),
      mStencilBackRef(0),
      mLineWidth(0),
      mGenerateMipmapHint(GL_NONE),
      mFragmentShaderDerivativeHint(GL_NONE),
      mBindGeneratesResource(true),
      mClientArraysEnabled(true),
      mNearZ(0),
      mFarZ(0),
      mReadFramebuffer(nullptr),
      mDrawFramebuffer(nullptr),
      mProgram(nullptr),
      mVertexArray(nullptr),
      mActiveSampler(0),
      mPrimitiveRestart(false),
      mMultiSampling(false),
      mSampleAlphaToOne(false),
      mFramebufferSRGB(true),
      mRobustResourceInit(false)
{
}

State::~State()
{
}

void State::initialize(const Caps &caps,
                       const Extensions &extensions,
                       const Version &clientVersion,
                       bool debug,
                       bool bindGeneratesResource,
                       bool clientArraysEnabled,
                       bool robustResourceInit)
{
    mMaxDrawBuffers = caps.maxDrawBuffers;
    mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;

    setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);

    mDepthClearValue = 1.0f;
    mStencilClearValue = 0;

    mScissorTest = false;
    mScissor.x = 0;
    mScissor.y = 0;
    mScissor.width = 0;
    mScissor.height = 0;

    mBlendColor.red = 0;
    mBlendColor.green = 0;
    mBlendColor.blue = 0;
    mBlendColor.alpha = 0;

    mStencilRef = 0;
    mStencilBackRef = 0;

    mSampleCoverage = false;
    mSampleCoverageValue = 1.0f;
    mSampleCoverageInvert = false;
    mGenerateMipmapHint = GL_DONT_CARE;
    mFragmentShaderDerivativeHint = GL_DONT_CARE;

    mBindGeneratesResource = bindGeneratesResource;
    mClientArraysEnabled   = clientArraysEnabled;

    mLineWidth = 1.0f;

    mViewport.x = 0;
    mViewport.y = 0;
    mViewport.width = 0;
    mViewport.height = 0;
    mNearZ = 0.0f;
    mFarZ = 1.0f;

    mBlend.colorMaskRed = true;
    mBlend.colorMaskGreen = true;
    mBlend.colorMaskBlue = true;
    mBlend.colorMaskAlpha = true;

    mActiveSampler = 0;

    mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);

    mUniformBuffers.resize(caps.maxUniformBufferBindings);

    mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
    mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
    if (clientVersion >= Version(3, 0))
    {
        // TODO: These could also be enabled via extension
        mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
        mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
    }
    if (clientVersion >= Version(3, 1))
    {
        mSamplerTextures[GL_TEXTURE_2D_MULTISAMPLE].resize(caps.maxCombinedTextureImageUnits);

        mAtomicCounterBuffers.resize(caps.maxAtomicCounterBufferBindings);
        mShaderStorageBuffers.resize(caps.maxShaderStorageBufferBindings);
    }
    if (extensions.eglImageExternal || extensions.eglStreamConsumerExternal)
    {
        mSamplerTextures[GL_TEXTURE_EXTERNAL_OES].resize(caps.maxCombinedTextureImageUnits);
    }

    mSamplers.resize(caps.maxCombinedTextureImageUnits);

    mActiveQueries[GL_ANY_SAMPLES_PASSED].set(nullptr);
    mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(nullptr);
    mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(nullptr);
    mActiveQueries[GL_TIME_ELAPSED_EXT].set(nullptr);
    mActiveQueries[GL_COMMANDS_COMPLETED_CHROMIUM].set(nullptr);

    mProgram = nullptr;

    mReadFramebuffer = nullptr;
    mDrawFramebuffer = nullptr;

    mPrimitiveRestart = false;

    mDebug.setOutputEnabled(debug);
    mDebug.setMaxLoggedMessages(extensions.maxDebugLoggedMessages);

    if (extensions.framebufferMultisample)
    {
        mMultiSampling = true;
        mSampleAlphaToOne = false;
    }

    mCoverageModulation = GL_NONE;

    angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
    angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
    mPathStencilFunc = GL_ALWAYS;
    mPathStencilRef  = 0;
    mPathStencilMask = std::numeric_limits<GLuint>::max();

    mRobustResourceInit = robustResourceInit;
}

void State::reset(const Context *context)
{
    for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
    {
        TextureBindingVector &textureVector = bindingVec->second;
        for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
        {
            textureVector[textureIdx].set(nullptr);
        }
    }
    for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
    {
        mSamplers[samplerIdx].set(nullptr);
    }

    mArrayBuffer.set(nullptr);
    mDrawIndirectBuffer.set(nullptr);
    mRenderbuffer.set(nullptr);

    if (mProgram)
    {
        mProgram->release(context);
    }
    mProgram = nullptr;

    mTransformFeedback.set(nullptr);

    for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
    {
        i->second.set(nullptr);
    }

    mGenericUniformBuffer.set(nullptr);
    for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
    {
        bufItr->set(nullptr);
    }

    mCopyReadBuffer.set(nullptr);
    mCopyWriteBuffer.set(nullptr);

    mPack.pixelBuffer.set(nullptr);
    mUnpack.pixelBuffer.set(nullptr);

    mGenericAtomicCounterBuffer.set(nullptr);
    for (auto &buf : mAtomicCounterBuffers)
    {
        buf.set(nullptr);
    }

    mGenericShaderStorageBuffer.set(nullptr);
    for (auto &buf : mShaderStorageBuffers)
    {
        buf.set(nullptr);
    }

    mProgram = nullptr;

    angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
    angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
    mPathStencilFunc = GL_ALWAYS;
    mPathStencilRef  = 0;
    mPathStencilMask = std::numeric_limits<GLuint>::max();

    // TODO(jmadill): Is this necessary?
    setAllDirtyBits();
}

const RasterizerState &State::getRasterizerState() const
{
    return mRasterizer;
}

const BlendState &State::getBlendState() const
{
    return mBlend;
}

const DepthStencilState &State::getDepthStencilState() const
{
    return mDepthStencil;
}

void State::setColorClearValue(float red, float green, float blue, float alpha)
{
    mColorClearValue.red = red;
    mColorClearValue.green = green;
    mColorClearValue.blue = blue;
    mColorClearValue.alpha = alpha;
    mDirtyBits.set(DIRTY_BIT_CLEAR_COLOR);
}

void State::setDepthClearValue(float depth)
{
    mDepthClearValue = depth;
    mDirtyBits.set(DIRTY_BIT_CLEAR_DEPTH);
}

void State::setStencilClearValue(int stencil)
{
    mStencilClearValue = stencil;
    mDirtyBits.set(DIRTY_BIT_CLEAR_STENCIL);
}

void State::setColorMask(bool red, bool green, bool blue, bool alpha)
{
    mBlend.colorMaskRed = red;
    mBlend.colorMaskGreen = green;
    mBlend.colorMaskBlue = blue;
    mBlend.colorMaskAlpha = alpha;
    mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
}

void State::setDepthMask(bool mask)
{
    mDepthStencil.depthMask = mask;
    mDirtyBits.set(DIRTY_BIT_DEPTH_MASK);
}

bool State::isRasterizerDiscardEnabled() const
{
    return mRasterizer.rasterizerDiscard;
}

void State::setRasterizerDiscard(bool enabled)
{
    mRasterizer.rasterizerDiscard = enabled;
    mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
}

bool State::isCullFaceEnabled() const
{
    return mRasterizer.cullFace;
}

void State::setCullFace(bool enabled)
{
    mRasterizer.cullFace = enabled;
    mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED);
}

void State::setCullMode(GLenum mode)
{
    mRasterizer.cullMode = mode;
    mDirtyBits.set(DIRTY_BIT_CULL_FACE);
}

void State::setFrontFace(GLenum front)
{
    mRasterizer.frontFace = front;
    mDirtyBits.set(DIRTY_BIT_FRONT_FACE);
}

bool State::isDepthTestEnabled() const
{
    return mDepthStencil.depthTest;
}

void State::setDepthTest(bool enabled)
{
    mDepthStencil.depthTest = enabled;
    mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED);
}

void State::setDepthFunc(GLenum depthFunc)
{
     mDepthStencil.depthFunc = depthFunc;
     mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC);
}

void State::setDepthRange(float zNear, float zFar)
{
    mNearZ = zNear;
    mFarZ = zFar;
    mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE);
}

float State::getNearPlane() const
{
    return mNearZ;
}

float State::getFarPlane() const
{
    return mFarZ;
}

bool State::isBlendEnabled() const
{
    return mBlend.blend;
}

void State::setBlend(bool enabled)
{
    mBlend.blend = enabled;
    mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
}

void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
{
    mBlend.sourceBlendRGB = sourceRGB;
    mBlend.destBlendRGB = destRGB;
    mBlend.sourceBlendAlpha = sourceAlpha;
    mBlend.destBlendAlpha = destAlpha;
    mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
}

void State::setBlendColor(float red, float green, float blue, float alpha)
{
    mBlendColor.red = red;
    mBlendColor.green = green;
    mBlendColor.blue = blue;
    mBlendColor.alpha = alpha;
    mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
}

void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
{
    mBlend.blendEquationRGB = rgbEquation;
    mBlend.blendEquationAlpha = alphaEquation;
    mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
}

const ColorF &State::getBlendColor() const
{
    return mBlendColor;
}

bool State::isStencilTestEnabled() const
{
    return mDepthStencil.stencilTest;
}

void State::setStencilTest(bool enabled)
{
    mDepthStencil.stencilTest = enabled;
    mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
}

void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
{
    mDepthStencil.stencilFunc = stencilFunc;
    mStencilRef = (stencilRef > 0) ? stencilRef : 0;
    mDepthStencil.stencilMask = stencilMask;
    mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
}

void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
{
    mDepthStencil.stencilBackFunc = stencilBackFunc;
    mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
    mDepthStencil.stencilBackMask = stencilBackMask;
    mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
}

void State::setStencilWritemask(GLuint stencilWritemask)
{
    mDepthStencil.stencilWritemask = stencilWritemask;
    mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
}

void State::setStencilBackWritemask(GLuint stencilBackWritemask)
{
    mDepthStencil.stencilBackWritemask = stencilBackWritemask;
    mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
}

void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
{
    mDepthStencil.stencilFail = stencilFail;
    mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
    mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
    mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
}

void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
{
    mDepthStencil.stencilBackFail = stencilBackFail;
    mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
    mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
    mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
}

GLint State::getStencilRef() const
{
    return mStencilRef;
}

GLint State::getStencilBackRef() const
{
    return mStencilBackRef;
}

bool State::isPolygonOffsetFillEnabled() const
{
    return mRasterizer.polygonOffsetFill;
}

void State::setPolygonOffsetFill(bool enabled)
{
    mRasterizer.polygonOffsetFill = enabled;
    mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
}

void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
{
    // An application can pass NaN values here, so handle this gracefully
    mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
    mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
    mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET);
}

bool State::isSampleAlphaToCoverageEnabled() const
{
    return mBlend.sampleAlphaToCoverage;
}

void State::setSampleAlphaToCoverage(bool enabled)
{
    mBlend.sampleAlphaToCoverage = enabled;
    mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
}

bool State::isSampleCoverageEnabled() const
{
    return mSampleCoverage;
}

void State::setSampleCoverage(bool enabled)
{
    mSampleCoverage = enabled;
    mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
}

void State::setSampleCoverageParams(GLclampf value, bool invert)
{
    mSampleCoverageValue = value;
    mSampleCoverageInvert = invert;
    mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE);
}

GLclampf State::getSampleCoverageValue() const
{
    return mSampleCoverageValue;
}

bool State::getSampleCoverageInvert() const
{
    return mSampleCoverageInvert;
}

void State::setSampleAlphaToOne(bool enabled)
{
    mSampleAlphaToOne = enabled;
    mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
}

bool State::isSampleAlphaToOneEnabled() const
{
    return mSampleAlphaToOne;
}

void State::setMultisampling(bool enabled)
{
    mMultiSampling = enabled;
    mDirtyBits.set(DIRTY_BIT_MULTISAMPLING);
}

bool State::isMultisamplingEnabled() const
{
    return mMultiSampling;
}

bool State::isScissorTestEnabled() const
{
    return mScissorTest;
}

void State::setScissorTest(bool enabled)
{
    mScissorTest = enabled;
    mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
}

void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
{
    mScissor.x = x;
    mScissor.y = y;
    mScissor.width = width;
    mScissor.height = height;
    mDirtyBits.set(DIRTY_BIT_SCISSOR);
}

const Rectangle &State::getScissor() const
{
    return mScissor;
}

bool State::isDitherEnabled() const
{
    return mBlend.dither;
}

void State::setDither(bool enabled)
{
    mBlend.dither = enabled;
    mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED);
}

bool State::isPrimitiveRestartEnabled() const
{
    return mPrimitiveRestart;
}

void State::setPrimitiveRestart(bool enabled)
{
    mPrimitiveRestart = enabled;
    mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
}

void State::setEnableFeature(GLenum feature, bool enabled)
{
    switch (feature)
    {
      case GL_MULTISAMPLE_EXT:               setMultisampling(enabled);         break;
      case GL_SAMPLE_ALPHA_TO_ONE_EXT:       setSampleAlphaToOne(enabled);      break;
      case GL_CULL_FACE:                     setCullFace(enabled);              break;
      case GL_POLYGON_OFFSET_FILL:           setPolygonOffsetFill(enabled);     break;
      case GL_SAMPLE_ALPHA_TO_COVERAGE:      setSampleAlphaToCoverage(enabled); break;
      case GL_SAMPLE_COVERAGE:               setSampleCoverage(enabled);        break;
      case GL_SCISSOR_TEST:                  setScissorTest(enabled);           break;
      case GL_STENCIL_TEST:                  setStencilTest(enabled);           break;
      case GL_DEPTH_TEST:                    setDepthTest(enabled);             break;
      case GL_BLEND:                         setBlend(enabled);                 break;
      case GL_DITHER:                        setDither(enabled);                break;
      case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled);      break;
      case GL_RASTERIZER_DISCARD:            setRasterizerDiscard(enabled);     break;
      case GL_SAMPLE_MASK:
          if (enabled)
          {
              // Enabling this feature is not implemented yet.
              UNIMPLEMENTED();
          }
          break;
      case GL_DEBUG_OUTPUT_SYNCHRONOUS:
          mDebug.setOutputSynchronous(enabled);
          break;
      case GL_DEBUG_OUTPUT:
          mDebug.setOutputEnabled(enabled);
          break;
      case GL_FRAMEBUFFER_SRGB_EXT:
          setFramebufferSRGB(enabled);
          break;
      default:                               UNREACHABLE();
    }
}

bool State::getEnableFeature(GLenum feature) const
{
    switch (feature)
    {
      case GL_MULTISAMPLE_EXT:               return isMultisamplingEnabled();
      case GL_SAMPLE_ALPHA_TO_ONE_EXT:       return isSampleAlphaToOneEnabled();
      case GL_CULL_FACE:                     return isCullFaceEnabled();
      case GL_POLYGON_OFFSET_FILL:           return isPolygonOffsetFillEnabled();
      case GL_SAMPLE_ALPHA_TO_COVERAGE:      return isSampleAlphaToCoverageEnabled();
      case GL_SAMPLE_COVERAGE:               return isSampleCoverageEnabled();
      case GL_SCISSOR_TEST:                  return isScissorTestEnabled();
      case GL_STENCIL_TEST:                  return isStencilTestEnabled();
      case GL_DEPTH_TEST:                    return isDepthTestEnabled();
      case GL_BLEND:                         return isBlendEnabled();
      case GL_DITHER:                        return isDitherEnabled();
      case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
      case GL_RASTERIZER_DISCARD:            return isRasterizerDiscardEnabled();
      case GL_SAMPLE_MASK:
          UNIMPLEMENTED();
          return false;
      case GL_DEBUG_OUTPUT_SYNCHRONOUS:
          return mDebug.isOutputSynchronous();
      case GL_DEBUG_OUTPUT:
          return mDebug.isOutputEnabled();
      case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
          return isBindGeneratesResourceEnabled();
      case GL_CLIENT_ARRAYS_ANGLE:
          return areClientArraysEnabled();
      case GL_FRAMEBUFFER_SRGB_EXT:
          return getFramebufferSRGB();
      case GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
          return mRobustResourceInit;
      default:                               UNREACHABLE(); return false;
    }
}

void State::setLineWidth(GLfloat width)
{
    mLineWidth = width;
    mDirtyBits.set(DIRTY_BIT_LINE_WIDTH);
}

float State::getLineWidth() const
{
    return mLineWidth;
}

void State::setGenerateMipmapHint(GLenum hint)
{
    mGenerateMipmapHint = hint;
    mDirtyBits.set(DIRTY_BIT_GENERATE_MIPMAP_HINT);
}

void State::setFragmentShaderDerivativeHint(GLenum hint)
{
    mFragmentShaderDerivativeHint = hint;
    mDirtyBits.set(DIRTY_BIT_SHADER_DERIVATIVE_HINT);
    // TODO: Propagate the hint to shader translator so we can write
    // ddx, ddx_coarse, or ddx_fine depending on the hint.
    // Ignore for now. It is valid for implementations to ignore hint.
}

bool State::isBindGeneratesResourceEnabled() const
{
    return mBindGeneratesResource;
}

bool State::areClientArraysEnabled() const
{
    return mClientArraysEnabled;
}

void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
{
    mViewport.x = x;
    mViewport.y = y;
    mViewport.width = width;
    mViewport.height = height;
    mDirtyBits.set(DIRTY_BIT_VIEWPORT);
}

const Rectangle &State::getViewport() const
{
    return mViewport;
}

void State::setActiveSampler(unsigned int active)
{
    mActiveSampler = active;
}

unsigned int State::getActiveSampler() const
{
    return static_cast<unsigned int>(mActiveSampler);
}

void State::setSamplerTexture(GLenum type, Texture *texture)
{
    mSamplerTextures[type][mActiveSampler].set(texture);
}

Texture *State::getTargetTexture(GLenum target) const
{
    return getSamplerTexture(static_cast<unsigned int>(mActiveSampler), target);
}

Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
{
    const auto it = mSamplerTextures.find(type);
    ASSERT(it != mSamplerTextures.end());
    ASSERT(sampler < it->second.size());
    return it->second[sampler].get();
}

GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
{
    const auto it = mSamplerTextures.find(type);
    ASSERT(it != mSamplerTextures.end());
    ASSERT(sampler < it->second.size());
    return it->second[sampler].id();
}

void State::detachTexture(const Context *context, const TextureMap &zeroTextures, GLuint texture)
{
    // Textures have a detach method on State rather than a simple
    // removeBinding, because the zero/null texture objects are managed
    // separately, and don't have to go through the Context's maps or
    // the ResourceManager.

    // [OpenGL ES 2.0.24] section 3.8 page 84:
    // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
    // rebound to texture object zero

    for (auto &bindingVec : mSamplerTextures)
    {
        GLenum textureType = bindingVec.first;
        TextureBindingVector &textureVector = bindingVec.second;
        for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
        {
            BindingPointer<Texture> &binding = textureVector[textureIdx];
            if (binding.id() == texture)
            {
                auto it = zeroTextures.find(textureType);
                ASSERT(it != zeroTextures.end());
                // Zero textures are the "default" textures instead of NULL
                binding.set(it->second.get());
            }
        }
    }

    // [OpenGL ES 2.0.24] section 4.4 page 112:
    // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
    // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
    // image was attached in the currently bound framebuffer.

    if (mReadFramebuffer)
    {
        mReadFramebuffer->detachTexture(context, texture);
    }

    if (mDrawFramebuffer)
    {
        mDrawFramebuffer->detachTexture(context, texture);
    }
}

void State::initializeZeroTextures(const TextureMap &zeroTextures)
{
    for (const auto &zeroTexture : zeroTextures)
    {
        auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];

        for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
        {
            samplerTextureArray[textureUnit].set(zeroTexture.second.get());
        }
    }
}

void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
{
    mSamplers[textureUnit].set(sampler);
}

GLuint State::getSamplerId(GLuint textureUnit) const
{
    ASSERT(textureUnit < mSamplers.size());
    return mSamplers[textureUnit].id();
}

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

void State::detachSampler(GLuint sampler)
{
    // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
    // If a sampler object that is currently bound to one or more texture units is
    // deleted, it is as though BindSampler is called once for each texture unit to
    // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
    for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
    {
        BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
        if (samplerBinding.id() == sampler)
        {
            samplerBinding.set(nullptr);
        }
    }
}

void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
{
    mRenderbuffer.set(renderbuffer);
}

GLuint State::getRenderbufferId() const
{
    return mRenderbuffer.id();
}

Renderbuffer *State::getCurrentRenderbuffer() const
{
    return mRenderbuffer.get();
}

void State::detachRenderbuffer(const Context *context, GLuint renderbuffer)
{
    // [OpenGL ES 2.0.24] section 4.4 page 109:
    // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
    // had been executed with the target RENDERBUFFER and name of zero.

    if (mRenderbuffer.id() == renderbuffer)
    {
        mRenderbuffer.set(nullptr);
    }

    // [OpenGL ES 2.0.24] section 4.4 page 111:
    // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
    // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
    // point to which this image was attached in the currently bound framebuffer.

    Framebuffer *readFramebuffer = mReadFramebuffer;
    Framebuffer *drawFramebuffer = mDrawFramebuffer;

    if (readFramebuffer)
    {
        readFramebuffer->detachRenderbuffer(context, renderbuffer);
    }

    if (drawFramebuffer && drawFramebuffer != readFramebuffer)
    {
        drawFramebuffer->detachRenderbuffer(context, renderbuffer);
    }

}

void State::setReadFramebufferBinding(Framebuffer *framebuffer)
{
    if (mReadFramebuffer == framebuffer)
        return;

    mReadFramebuffer = framebuffer;
    mDirtyBits.set(DIRTY_BIT_READ_FRAMEBUFFER_BINDING);

    if (mReadFramebuffer && mReadFramebuffer->hasAnyDirtyBit())
    {
        mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
    }
}

void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
{
    if (mDrawFramebuffer == framebuffer)
        return;

    mDrawFramebuffer = framebuffer;
    mDirtyBits.set(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);

    if (mDrawFramebuffer && mDrawFramebuffer->hasAnyDirtyBit())
    {
        mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
    }
}

Framebuffer *State::getTargetFramebuffer(GLenum target) const
{
    switch (target)
    {
        case GL_READ_FRAMEBUFFER_ANGLE:
            return mReadFramebuffer;
        case GL_DRAW_FRAMEBUFFER_ANGLE:
        case GL_FRAMEBUFFER:
            return mDrawFramebuffer;
        default:
            UNREACHABLE();
            return nullptr;
    }
}

Framebuffer *State::getReadFramebuffer() const
{
    return mReadFramebuffer;
}

Framebuffer *State::getDrawFramebuffer() const
{
    return mDrawFramebuffer;
}

bool State::removeReadFramebufferBinding(GLuint framebuffer)
{
    if (mReadFramebuffer != nullptr &&
        mReadFramebuffer->id() == framebuffer)
    {
        setReadFramebufferBinding(nullptr);
        return true;
    }

    return false;
}

bool State::removeDrawFramebufferBinding(GLuint framebuffer)
{
    if (mReadFramebuffer != nullptr &&
        mDrawFramebuffer->id() == framebuffer)
    {
        setDrawFramebufferBinding(nullptr);
        return true;
    }

    return false;
}

void State::setVertexArrayBinding(VertexArray *vertexArray)
{
    mVertexArray = vertexArray;
    mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);

    if (mVertexArray && mVertexArray->hasAnyDirtyBit())
    {
        mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
    }
}

GLuint State::getVertexArrayId() const
{
    ASSERT(mVertexArray != nullptr);
    return mVertexArray->id();
}

VertexArray *State::getVertexArray() const
{
    ASSERT(mVertexArray != nullptr);
    return mVertexArray;
}

bool State::removeVertexArrayBinding(GLuint vertexArray)
{
    if (mVertexArray->id() == vertexArray)
    {
        mVertexArray = nullptr;
        mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
        mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
        return true;
    }

    return false;
}

void State::setElementArrayBuffer(Buffer *buffer)
{
    getVertexArray()->setElementArrayBuffer(buffer);
    mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
}

void State::bindVertexBuffer(GLuint bindingIndex,
                             Buffer *boundBuffer,
                             GLintptr offset,
                             GLsizei stride)
{
    getVertexArray()->bindVertexBuffer(bindingIndex, boundBuffer, offset, stride);
    mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
}

void State::setVertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
{
    getVertexArray()->setVertexAttribBinding(attribIndex, bindingIndex);
    mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
}

void State::setVertexAttribFormat(GLuint attribIndex,
                                  GLint size,
                                  GLenum type,
                                  bool normalized,
                                  bool pureInteger,
                                  GLuint relativeOffset)
{
    getVertexArray()->setVertexAttribFormat(attribIndex, size, type, normalized, pureInteger,
                                            relativeOffset);
    mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
}

void State::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
{
    getVertexArray()->setVertexBindingDivisor(bindingIndex, divisor);
    mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
}

void State::setProgram(const Context *context, Program *newProgram)
{
    if (mProgram != newProgram)
    {
        if (mProgram)
        {
            mProgram->release(context);
        }

        mProgram = newProgram;

        if (mProgram)
        {
            newProgram->addRef();
        }
    }
}

Program *State::getProgram() const
{
    return mProgram;
}

void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
{
    mTransformFeedback.set(transformFeedback);
}

TransformFeedback *State::getCurrentTransformFeedback() const
{
    return mTransformFeedback.get();
}

bool State::isTransformFeedbackActiveUnpaused() const
{
    gl::TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
    return curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused();
}

bool State::removeTransformFeedbackBinding(GLuint transformFeedback)
{
    if (mTransformFeedback.id() == transformFeedback)
    {
        mTransformFeedback.set(nullptr);
        return true;
    }

    return false;
}

bool State::isQueryActive(const GLenum type) const
{
    for (auto &iter : mActiveQueries)
    {
        const Query *query = iter.second.get();
        if (query != nullptr && ActiveQueryType(query->getType()) == ActiveQueryType(type))
        {
            return true;
        }
    }

    return false;
}

bool State::isQueryActive(Query *query) const
{
    for (auto &iter : mActiveQueries)
    {
        if (iter.second.get() == query)
        {
            return true;
        }
    }

    return false;
}

void State::setActiveQuery(GLenum target, Query *query)
{
    mActiveQueries[target].set(query);
}

GLuint State::getActiveQueryId(GLenum target) const
{
    const Query *query = getActiveQuery(target);
    return (query ? query->id() : 0u);
}

Query *State::getActiveQuery(GLenum target) const
{
    const auto it = mActiveQueries.find(target);

    // All query types should already exist in the activeQueries map
    ASSERT(it != mActiveQueries.end());

    return it->second.get();
}

void State::setArrayBufferBinding(Buffer *buffer)
{
    mArrayBuffer.set(buffer);
}

GLuint State::getArrayBufferId() const
{
    return mArrayBuffer.id();
}

void State::setDrawIndirectBufferBinding(Buffer *buffer)
{
    mDrawIndirectBuffer.set(buffer);
    mDirtyBits.set(DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING);
}

void State::setGenericUniformBufferBinding(Buffer *buffer)
{
    mGenericUniformBuffer.set(buffer);
}

void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
{
    mUniformBuffers[index].set(buffer, offset, size);
}

const OffsetBindingPointer<Buffer> &State::getIndexedUniformBuffer(size_t index) const
{
    ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
    return mUniformBuffers[index];
}

void State::setGenericAtomicCounterBufferBinding(Buffer *buffer)
{
    mGenericAtomicCounterBuffer.set(buffer);
}

void State::setIndexedAtomicCounterBufferBinding(GLuint index,
                                                 Buffer *buffer,
                                                 GLintptr offset,
                                                 GLsizeiptr size)
{
    ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
    mAtomicCounterBuffers[index].set(buffer, offset, size);
}

const OffsetBindingPointer<Buffer> &State::getIndexedAtomicCounterBuffer(size_t index) const
{
    ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
    return mAtomicCounterBuffers[index];
}

void State::setGenericShaderStorageBufferBinding(Buffer *buffer)
{
    mGenericShaderStorageBuffer.set(buffer);
}

void State::setIndexedShaderStorageBufferBinding(GLuint index,
                                                 Buffer *buffer,
                                                 GLintptr offset,
                                                 GLsizeiptr size)
{
    ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
    mShaderStorageBuffers[index].set(buffer, offset, size);
}

const OffsetBindingPointer<Buffer> &State::getIndexedShaderStorageBuffer(size_t index) const
{
    ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
    return mShaderStorageBuffers[index];
}

void State::setCopyReadBufferBinding(Buffer *buffer)
{
    mCopyReadBuffer.set(buffer);
}

void State::setCopyWriteBufferBinding(Buffer *buffer)
{
    mCopyWriteBuffer.set(buffer);
}

void State::setPixelPackBufferBinding(Buffer *buffer)
{
    mPack.pixelBuffer.set(buffer);
    mDirtyBits.set(DIRTY_BIT_PACK_BUFFER_BINDING);
}

void State::setPixelUnpackBufferBinding(Buffer *buffer)
{
    mUnpack.pixelBuffer.set(buffer);
    mDirtyBits.set(DIRTY_BIT_UNPACK_BUFFER_BINDING);
}

Buffer *State::getTargetBuffer(GLenum target) const
{
    switch (target)
    {
      case GL_ARRAY_BUFFER:              return mArrayBuffer.get();
      case GL_COPY_READ_BUFFER:          return mCopyReadBuffer.get();
      case GL_COPY_WRITE_BUFFER:         return mCopyWriteBuffer.get();
      case GL_ELEMENT_ARRAY_BUFFER:      return getVertexArray()->getElementArrayBuffer().get();
      case GL_PIXEL_PACK_BUFFER:         return mPack.pixelBuffer.get();
      case GL_PIXEL_UNPACK_BUFFER:       return mUnpack.pixelBuffer.get();
      case GL_TRANSFORM_FEEDBACK_BUFFER: return mTransformFeedback->getGenericBuffer().get();
      case GL_UNIFORM_BUFFER:            return mGenericUniformBuffer.get();
      case GL_ATOMIC_COUNTER_BUFFER:
          return mGenericAtomicCounterBuffer.get();
      case GL_SHADER_STORAGE_BUFFER:
          return mGenericShaderStorageBuffer.get();
      case GL_DRAW_INDIRECT_BUFFER:
          return mDrawIndirectBuffer.get();
      default:
          UNREACHABLE();
          return nullptr;
    }
}

void State::detachBuffer(GLuint bufferName)
{
    BindingPointer<Buffer> *buffers[] = {
        &mArrayBuffer,        &mGenericAtomicCounterBuffer, &mCopyReadBuffer,
        &mCopyWriteBuffer,    &mDrawIndirectBuffer,         &mPack.pixelBuffer,
        &mUnpack.pixelBuffer, &mGenericUniformBuffer,       &mGenericShaderStorageBuffer};
    for (auto buffer : buffers)
    {
        if (buffer->id() == bufferName)
        {
            buffer->set(nullptr);
        }
    }

    TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
    if (curTransformFeedback)
    {
        curTransformFeedback->detachBuffer(bufferName);
    }

    getVertexArray()->detachBuffer(bufferName);
}

void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
{
    getVertexArray()->enableAttribute(attribNum, enabled);
    mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
}

void State::setVertexAttribf(GLuint index, const GLfloat values[4])
{
    ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
    mVertexAttribCurrentValues[index].setFloatValues(values);
    mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
}

void State::setVertexAttribu(GLuint index, const GLuint values[4])
{
    ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
    mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
    mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
}

void State::setVertexAttribi(GLuint index, const GLint values[4])
{
    ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
    mVertexAttribCurrentValues[index].setIntValues(values);
    mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
}

void State::setVertexAttribState(unsigned int attribNum,
                                 Buffer *boundBuffer,
                                 GLint size,
                                 GLenum type,
                                 bool normalized,
                                 bool pureInteger,
                                 GLsizei stride,
                                 const void *pointer)
{
    getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
    mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
}

void State::setVertexAttribDivisor(GLuint index, GLuint divisor)
{
    getVertexArray()->setVertexAttribDivisor(index, divisor);
    mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
}

const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(size_t attribNum) const
{
    ASSERT(attribNum < mVertexAttribCurrentValues.size());
    return mVertexAttribCurrentValues[attribNum];
}

const void *State::getVertexAttribPointer(unsigned int attribNum) const
{
    return getVertexArray()->getVertexAttribute(attribNum).pointer;
}

void State::setPackAlignment(GLint alignment)
{
    mPack.alignment = alignment;
    mDirtyBits.set(DIRTY_BIT_PACK_ALIGNMENT);
}

GLint State::getPackAlignment() const
{
    return mPack.alignment;
}

void State::setPackReverseRowOrder(bool reverseRowOrder)
{
    mPack.reverseRowOrder = reverseRowOrder;
    mDirtyBits.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
}

bool State::getPackReverseRowOrder() const
{
    return mPack.reverseRowOrder;
}

void State::setPackRowLength(GLint rowLength)
{
    mPack.rowLength = rowLength;
    mDirtyBits.set(DIRTY_BIT_PACK_ROW_LENGTH);
}

GLint State::getPackRowLength() const
{
    return mPack.rowLength;
}

void State::setPackSkipRows(GLint skipRows)
{
    mPack.skipRows = skipRows;
    mDirtyBits.set(DIRTY_BIT_PACK_SKIP_ROWS);
}

GLint State::getPackSkipRows() const
{
    return mPack.skipRows;
}

void State::setPackSkipPixels(GLint skipPixels)
{
    mPack.skipPixels = skipPixels;
    mDirtyBits.set(DIRTY_BIT_PACK_SKIP_PIXELS);
}

GLint State::getPackSkipPixels() const
{
    return mPack.skipPixels;
}

const PixelPackState &State::getPackState() const
{
    return mPack;
}

PixelPackState &State::getPackState()
{
    return mPack;
}

void State::setUnpackAlignment(GLint alignment)
{
    mUnpack.alignment = alignment;
    mDirtyBits.set(DIRTY_BIT_UNPACK_ALIGNMENT);
}

GLint State::getUnpackAlignment() const
{
    return mUnpack.alignment;
}

void State::setUnpackRowLength(GLint rowLength)
{
    mUnpack.rowLength = rowLength;
    mDirtyBits.set(DIRTY_BIT_UNPACK_ROW_LENGTH);
}

GLint State::getUnpackRowLength() const
{
    return mUnpack.rowLength;
}

void State::setUnpackImageHeight(GLint imageHeight)
{
    mUnpack.imageHeight = imageHeight;
    mDirtyBits.set(DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
}

GLint State::getUnpackImageHeight() const
{
    return mUnpack.imageHeight;
}

void State::setUnpackSkipImages(GLint skipImages)
{
    mUnpack.skipImages = skipImages;
    mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_IMAGES);
}

GLint State::getUnpackSkipImages() const
{
    return mUnpack.skipImages;
}

void State::setUnpackSkipRows(GLint skipRows)
{
    mUnpack.skipRows = skipRows;
    mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_ROWS);
}

GLint State::getUnpackSkipRows() const
{
    return mUnpack.skipRows;
}

void State::setUnpackSkipPixels(GLint skipPixels)
{
    mUnpack.skipPixels = skipPixels;
    mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_PIXELS);
}

GLint State::getUnpackSkipPixels() const
{
    return mUnpack.skipPixels;
}

const PixelUnpackState &State::getUnpackState() const
{
    return mUnpack;
}

PixelUnpackState &State::getUnpackState()
{
    return mUnpack;
}

const Debug &State::getDebug() const
{
    return mDebug;
}

Debug &State::getDebug()
{
    return mDebug;
}

void State::setCoverageModulation(GLenum components)
{
    mCoverageModulation = components;
    mDirtyBits.set(DIRTY_BIT_COVERAGE_MODULATION);
}

GLenum State::getCoverageModulation() const
{
    return mCoverageModulation;
}

void State::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
{
    if (matrixMode == GL_PATH_MODELVIEW_CHROMIUM)
    {
        memcpy(mPathMatrixMV, matrix, 16 * sizeof(GLfloat));
        mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_MATRIX_MV);
    }
    else if (matrixMode == GL_PATH_PROJECTION_CHROMIUM)
    {
        memcpy(mPathMatrixProj, matrix, 16 * sizeof(GLfloat));
        mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_MATRIX_PROJ);
    }
    else
    {
        UNREACHABLE();
    }
}

const GLfloat *State::getPathRenderingMatrix(GLenum which) const
{
    if (which == GL_PATH_MODELVIEW_MATRIX_CHROMIUM)
    {
        return mPathMatrixMV;
    }
    else if (which == GL_PATH_PROJECTION_MATRIX_CHROMIUM)
    {
        return mPathMatrixProj;
    }

    UNREACHABLE();
    return nullptr;
}

void State::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
{
    mPathStencilFunc = func;
    mPathStencilRef  = ref;
    mPathStencilMask = mask;
    mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_STENCIL_STATE);
}

GLenum State::getPathStencilFunc() const
{
    return mPathStencilFunc;
}

GLint State::getPathStencilRef() const
{
    return mPathStencilRef;
}

GLuint State::getPathStencilMask() const
{
    return mPathStencilMask;
}

void State::setFramebufferSRGB(bool sRGB)
{
    mFramebufferSRGB = sRGB;
    mDirtyBits.set(DIRTY_BIT_FRAMEBUFFER_SRGB);
}

bool State::getFramebufferSRGB() const
{
    return mFramebufferSRGB;
}

void State::getBooleanv(GLenum pname, GLboolean *params)
{
    switch (pname)
    {
      case GL_SAMPLE_COVERAGE_INVERT:    *params = mSampleCoverageInvert;         break;
      case GL_DEPTH_WRITEMASK:           *params = mDepthStencil.depthMask;       break;
      case GL_COLOR_WRITEMASK:
        params[0] = mBlend.colorMaskRed;
        params[1] = mBlend.colorMaskGreen;
        params[2] = mBlend.colorMaskBlue;
        params[3] = mBlend.colorMaskAlpha;
        break;
      case GL_CULL_FACE:                 *params = mRasterizer.cullFace;          break;
      case GL_POLYGON_OFFSET_FILL:       *params = mRasterizer.polygonOffsetFill; break;
      case GL_SAMPLE_ALPHA_TO_COVERAGE:  *params = mBlend.sampleAlphaToCoverage;  break;
      case GL_SAMPLE_COVERAGE:           *params = mSampleCoverage;               break;
      case GL_SCISSOR_TEST:              *params = mScissorTest;                  break;
      case GL_STENCIL_TEST:              *params = mDepthStencil.stencilTest;     break;
      case GL_DEPTH_TEST:                *params = mDepthStencil.depthTest;       break;
      case GL_BLEND:                     *params = mBlend.blend;                  break;
      case GL_DITHER:                    *params = mBlend.dither;                 break;
      case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE; break;
      case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE; break;
      case GL_PRIMITIVE_RESTART_FIXED_INDEX:
          *params = mPrimitiveRestart;
          break;
      case GL_RASTERIZER_DISCARD:
          *params = isRasterizerDiscardEnabled() ? GL_TRUE : GL_FALSE;
          break;
      case GL_DEBUG_OUTPUT_SYNCHRONOUS:
          *params = mDebug.isOutputSynchronous() ? GL_TRUE : GL_FALSE;
          break;
      case GL_DEBUG_OUTPUT:
          *params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE;
          break;
      case GL_MULTISAMPLE_EXT:
          *params = mMultiSampling;
          break;
      case GL_SAMPLE_ALPHA_TO_ONE_EXT:
          *params = mSampleAlphaToOne;
          break;
      case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
          *params = isBindGeneratesResourceEnabled() ? GL_TRUE : GL_FALSE;
          break;
      case GL_CLIENT_ARRAYS_ANGLE:
          *params = areClientArraysEnabled() ? GL_TRUE : GL_FALSE;
          break;
      case GL_FRAMEBUFFER_SRGB_EXT:
          *params = getFramebufferSRGB() ? GL_TRUE : GL_FALSE;
          break;
      case GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
          *params = mRobustResourceInit ? GL_TRUE : GL_FALSE;
          break;
      default:
        UNREACHABLE();
        break;
    }
}

void State::getFloatv(GLenum pname, GLfloat *params)
{
    // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
    // GetIntegerv as its native query function. As it would require conversion in any
    // case, this should make no difference to the calling application.
    switch (pname)
    {
      case GL_LINE_WIDTH:               *params = mLineWidth;                         break;
      case GL_SAMPLE_COVERAGE_VALUE:    *params = mSampleCoverageValue;               break;
      case GL_DEPTH_CLEAR_VALUE:        *params = mDepthClearValue;                   break;
      case GL_POLYGON_OFFSET_FACTOR:    *params = mRasterizer.polygonOffsetFactor;    break;
      case GL_POLYGON_OFFSET_UNITS:     *params = mRasterizer.polygonOffsetUnits;     break;
      case GL_DEPTH_RANGE:
        params[0] = mNearZ;
        params[1] = mFarZ;
        break;
      case GL_COLOR_CLEAR_VALUE:
        params[0] = mColorClearValue.red;
        params[1] = mColorClearValue.green;
        params[2] = mColorClearValue.blue;
        params[3] = mColorClearValue.alpha;
        break;
      case GL_BLEND_COLOR:
        params[0] = mBlendColor.red;
        params[1] = mBlendColor.green;
        params[2] = mBlendColor.blue;
        params[3] = mBlendColor.alpha;
        break;
      case GL_MULTISAMPLE_EXT:
        *params = static_cast<GLfloat>(mMultiSampling);
        break;
      case GL_SAMPLE_ALPHA_TO_ONE_EXT:
        *params = static_cast<GLfloat>(mSampleAlphaToOne);
      case GL_COVERAGE_MODULATION_CHROMIUM:
          params[0] = static_cast<GLfloat>(mCoverageModulation);
          break;
      default:
        UNREACHABLE();
        break;
    }
}

void State::getIntegerv(const Context *context, GLenum pname, GLint *params)
{
    if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
    {
        unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
        ASSERT(colorAttachment < mMaxDrawBuffers);
        Framebuffer *framebuffer = mDrawFramebuffer;
        *params = framebuffer->getDrawBufferState(colorAttachment);
        return;
    }

    // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
    // GetIntegerv as its native query function. As it would require conversion in any
    // case, this should make no difference to the calling application. You may find it in
    // State::getFloatv.
    switch (pname)
    {
      case GL_ARRAY_BUFFER_BINDING:                     *params = mArrayBuffer.id();                              break;
      case GL_DRAW_INDIRECT_BUFFER_BINDING:
          *params = mDrawIndirectBuffer.id();
          break;
      case GL_ELEMENT_ARRAY_BUFFER_BINDING:             *params = getVertexArray()->getElementArrayBuffer().id(); break;
        //case GL_FRAMEBUFFER_BINDING:                    // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
      case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:           *params = mDrawFramebuffer->id();                         break;
      case GL_READ_FRAMEBUFFER_BINDING_ANGLE:           *params = mReadFramebuffer->id();                         break;
      case GL_RENDERBUFFER_BINDING:                     *params = mRenderbuffer.id();                             break;
      case GL_VERTEX_ARRAY_BINDING:                     *params = mVertexArray->id();                             break;
      case GL_CURRENT_PROGRAM:                          *params = mProgram ? mProgram->id() : 0;                  break;
      case GL_PACK_ALIGNMENT:                           *params = mPack.alignment;                                break;
      case GL_PACK_REVERSE_ROW_ORDER_ANGLE:             *params = mPack.reverseRowOrder;                          break;
      case GL_PACK_ROW_LENGTH:
          *params = mPack.rowLength;
          break;
      case GL_PACK_SKIP_ROWS:
          *params = mPack.skipRows;
          break;
      case GL_PACK_SKIP_PIXELS:
          *params = mPack.skipPixels;
          break;
      case GL_UNPACK_ALIGNMENT:                         *params = mUnpack.alignment;                              break;
      case GL_UNPACK_ROW_LENGTH:                        *params = mUnpack.rowLength;                              break;
      case GL_UNPACK_IMAGE_HEIGHT:
          *params = mUnpack.imageHeight;
          break;
      case GL_UNPACK_SKIP_IMAGES:
          *params = mUnpack.skipImages;
          break;
      case GL_UNPACK_SKIP_ROWS:
          *params = mUnpack.skipRows;
          break;
      case GL_UNPACK_SKIP_PIXELS:
          *params = mUnpack.skipPixels;
          break;
      case GL_GENERATE_MIPMAP_HINT:                     *params = mGenerateMipmapHint;                            break;
      case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:      *params = mFragmentShaderDerivativeHint;                  break;
      case GL_ACTIVE_TEXTURE:
          *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
          break;
      case GL_STENCIL_FUNC:                             *params = mDepthStencil.stencilFunc;                      break;
      case GL_STENCIL_REF:                              *params = mStencilRef;                                    break;
      case GL_STENCIL_VALUE_MASK:                       *params = clampToInt(mDepthStencil.stencilMask);          break;
      case GL_STENCIL_BACK_FUNC:                        *params = mDepthStencil.stencilBackFunc;                  break;
      case GL_STENCIL_BACK_REF:                         *params = mStencilBackRef;                                break;
      case GL_STENCIL_BACK_VALUE_MASK:                  *params = clampToInt(mDepthStencil.stencilBackMask);      break;
      case GL_STENCIL_FAIL:                             *params = mDepthStencil.stencilFail;                      break;
      case GL_STENCIL_PASS_DEPTH_FAIL:                  *params = mDepthStencil.stencilPassDepthFail;             break;
      case GL_STENCIL_PASS_DEPTH_PASS:                  *params = mDepthStencil.stencilPassDepthPass;             break;
      case GL_STENCIL_BACK_FAIL:                        *params = mDepthStencil.stencilBackFail;                  break;
      case GL_STENCIL_BACK_PASS_DEPTH_FAIL:             *params = mDepthStencil.stencilBackPassDepthFail;         break;
      case GL_STENCIL_BACK_PASS_DEPTH_PASS:             *params = mDepthStencil.stencilBackPassDepthPass;         break;
      case GL_DEPTH_FUNC:                               *params = mDepthStencil.depthFunc;                        break;
      case GL_BLEND_SRC_RGB:                            *params = mBlend.sourceBlendRGB;                          break;
      case GL_BLEND_SRC_ALPHA:                          *params = mBlend.sourceBlendAlpha;                        break;
      case GL_BLEND_DST_RGB:                            *params = mBlend.destBlendRGB;                            break;
      case GL_BLEND_DST_ALPHA:                          *params = mBlend.destBlendAlpha;                          break;
      case GL_BLEND_EQUATION_RGB:                       *params = mBlend.blendEquationRGB;                        break;
      case GL_BLEND_EQUATION_ALPHA:                     *params = mBlend.blendEquationAlpha;                      break;
      case GL_STENCIL_WRITEMASK:                        *params = clampToInt(mDepthStencil.stencilWritemask);     break;
      case GL_STENCIL_BACK_WRITEMASK:                   *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
      case GL_STENCIL_CLEAR_VALUE:                      *params = mStencilClearValue;                             break;
      case GL_IMPLEMENTATION_COLOR_READ_TYPE:           *params = mReadFramebuffer->getImplementationColorReadType();   break;
      case GL_IMPLEMENTATION_COLOR_READ_FORMAT:         *params = mReadFramebuffer->getImplementationColorReadFormat(); break;
      case GL_SAMPLE_BUFFERS:
      case GL_SAMPLES:
        {
            gl::Framebuffer *framebuffer = mDrawFramebuffer;
            if (framebuffer->checkStatus(context) == GL_FRAMEBUFFER_COMPLETE)
            {
                switch (pname)
                {
                  case GL_SAMPLE_BUFFERS:
                      if (framebuffer->getSamples(context) != 0)
                      {
                          *params = 1;
                    }
                    else
                    {
                        *params = 0;
                    }
                    break;
                  case GL_SAMPLES:
                      *params = framebuffer->getSamples(context);
                      break;
                }
            }
            else
            {
                *params = 0;
            }
        }
        break;
      case GL_VIEWPORT:
        params[0] = mViewport.x;
        params[1] = mViewport.y;
        params[2] = mViewport.width;
        params[3] = mViewport.height;
        break;
      case GL_SCISSOR_BOX:
        params[0] = mScissor.x;
        params[1] = mScissor.y;
        params[2] = mScissor.width;
        params[3] = mScissor.height;
        break;
      case GL_CULL_FACE_MODE:                   *params = mRasterizer.cullMode;   break;
      case GL_FRONT_FACE:                       *params = mRasterizer.frontFace;  break;
      case GL_RED_BITS:
      case GL_GREEN_BITS:
      case GL_BLUE_BITS:
      case GL_ALPHA_BITS:
        {
            gl::Framebuffer *framebuffer = getDrawFramebuffer();
            const gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();

            if (colorbuffer)
            {
                switch (pname)
                {
                case GL_RED_BITS:   *params = colorbuffer->getRedSize();      break;
                case GL_GREEN_BITS: *params = colorbuffer->getGreenSize();    break;
                case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();     break;
                case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize();    break;
                }
            }
            else
            {
                *params = 0;
            }
        }
        break;
      case GL_DEPTH_BITS:
        {
            const gl::Framebuffer *framebuffer = getDrawFramebuffer();
            const gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();

            if (depthbuffer)
            {
                *params = depthbuffer->getDepthSize();
            }
            else
            {
                *params = 0;
            }
        }
        break;
      case GL_STENCIL_BITS:
        {
            const gl::Framebuffer *framebuffer = getDrawFramebuffer();
            const gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();

            if (stencilbuffer)
            {
                *params = stencilbuffer->getStencilSize();
            }
            else
            {
                *params = 0;
            }
        }
        break;
      case GL_TEXTURE_BINDING_2D:
        ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
        *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D);
        break;
      case GL_TEXTURE_BINDING_CUBE_MAP:
        ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
        *params =
            getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_CUBE_MAP);
        break;
      case GL_TEXTURE_BINDING_3D:
        ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
        *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_3D);
        break;
      case GL_TEXTURE_BINDING_2D_ARRAY:
        ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
        *params =
            getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D_ARRAY);
        break;
      case GL_TEXTURE_BINDING_EXTERNAL_OES:
          ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
          *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
                                        GL_TEXTURE_EXTERNAL_OES);
          break;
      case GL_UNIFORM_BUFFER_BINDING:
        *params = mGenericUniformBuffer.id();
        break;
      case GL_TRANSFORM_FEEDBACK_BINDING:
        *params = mTransformFeedback.id();
        break;
      case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
        *params = mTransformFeedback->getGenericBuffer().id();
        break;
      case GL_COPY_READ_BUFFER_BINDING:
        *params = mCopyReadBuffer.id();
        break;
      case GL_COPY_WRITE_BUFFER_BINDING:
        *params = mCopyWriteBuffer.id();
        break;
      case GL_PIXEL_PACK_BUFFER_BINDING:
        *params = mPack.pixelBuffer.id();
        break;
      case GL_PIXEL_UNPACK_BUFFER_BINDING:
        *params = mUnpack.pixelBuffer.id();
        break;
      case GL_READ_BUFFER:
          *params = mReadFramebuffer->getReadBufferState();
          break;
      case GL_SAMPLER_BINDING:
          ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
          *params = getSamplerId(static_cast<GLuint>(mActiveSampler));
          break;
      case GL_DEBUG_LOGGED_MESSAGES:
          *params = static_cast<GLint>(mDebug.getMessageCount());
          break;
      case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
          *params = static_cast<GLint>(mDebug.getNextMessageLength());
          break;
      case GL_DEBUG_GROUP_STACK_DEPTH:
          *params = static_cast<GLint>(mDebug.getGroupStackDepth());
          break;
      case GL_MULTISAMPLE_EXT:
          *params = static_cast<GLint>(mMultiSampling);
          break;
      case GL_SAMPLE_ALPHA_TO_ONE_EXT:
          *params = static_cast<GLint>(mSampleAlphaToOne);
      case GL_COVERAGE_MODULATION_CHROMIUM:
          *params = static_cast<GLint>(mCoverageModulation);
          break;
      case GL_ATOMIC_COUNTER_BUFFER_BINDING:
          *params = mGenericAtomicCounterBuffer.id();
          break;
      case GL_SHADER_STORAGE_BUFFER_BINDING:
          *params = mGenericShaderStorageBuffer.id();
          break;
      default:
        UNREACHABLE();
        break;
    }
}

void State::getPointerv(GLenum pname, void **params) const
{
    switch (pname)
    {
        case GL_DEBUG_CALLBACK_FUNCTION:
            *params = reinterpret_cast<void *>(mDebug.getCallback());
            break;
        case GL_DEBUG_CALLBACK_USER_PARAM:
            *params = const_cast<void *>(mDebug.getUserParam());
            break;
        default:
            UNREACHABLE();
            break;
    }
}

void State::getIntegeri_v(GLenum target, GLuint index, GLint *data)
{
    switch (target)
    {
      case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
          ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
          *data = mTransformFeedback->getIndexedBuffer(index).id();
          break;
      case GL_UNIFORM_BUFFER_BINDING:
          ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
          *data = mUniformBuffers[index].id();
          break;
      case GL_ATOMIC_COUNTER_BUFFER_BINDING:
          ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
          *data = mAtomicCounterBuffers[index].id();
          break;
      case GL_SHADER_STORAGE_BUFFER_BINDING:
          ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
          *data = mShaderStorageBuffers[index].id();
          break;
      case GL_VERTEX_BINDING_BUFFER:
          ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
          *data = mVertexArray->getVertexBinding(index).buffer.id();
          break;
      case GL_VERTEX_BINDING_DIVISOR:
          ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
          *data = mVertexArray->getVertexBinding(index).divisor;
          break;
      case GL_VERTEX_BINDING_OFFSET:
          ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
          *data = static_cast<GLuint>(mVertexArray->getVertexBinding(index).offset);
          break;
      case GL_VERTEX_BINDING_STRIDE:
          ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
          *data = mVertexArray->getVertexBinding(index).stride;
          break;
      default:
          UNREACHABLE();
          break;
    }
}

void State::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
{
    switch (target)
    {
      case GL_TRANSFORM_FEEDBACK_BUFFER_START:
          ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
          *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
          break;
      case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
          ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
          *data = mTransformFeedback->getIndexedBuffer(index).getSize();
          break;
      case GL_UNIFORM_BUFFER_START:
          ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
          *data = mUniformBuffers[index].getOffset();
          break;
      case GL_UNIFORM_BUFFER_SIZE:
          ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
          *data = mUniformBuffers[index].getSize();
          break;
      case GL_ATOMIC_COUNTER_BUFFER_START:
          ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
          *data = mAtomicCounterBuffers[index].getOffset();
          break;
      case GL_ATOMIC_COUNTER_BUFFER_SIZE:
          ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
          *data = mAtomicCounterBuffers[index].getSize();
          break;
      case GL_SHADER_STORAGE_BUFFER_START:
          ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
          *data = mShaderStorageBuffers[index].getOffset();
          break;
      case GL_SHADER_STORAGE_BUFFER_SIZE:
          ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
          *data = mShaderStorageBuffers[index].getSize();
          break;
      default:
          UNREACHABLE();
          break;
    }
}

void State::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
{
    UNREACHABLE();
}

bool State::hasMappedBuffer(GLenum target) const
{
    if (target == GL_ARRAY_BUFFER)
    {
        const VertexArray *vao     = getVertexArray();
        const auto &vertexAttribs = vao->getVertexAttributes();
        const auto &vertexBindings = vao->getVertexBindings();
        size_t maxEnabledAttrib = vao->getMaxEnabledAttribute();
        for (size_t attribIndex = 0; attribIndex < maxEnabledAttrib; attribIndex++)
        {
            const gl::VertexAttribute &vertexAttrib = vertexAttribs[attribIndex];
            auto *boundBuffer = vertexBindings[vertexAttrib.bindingIndex].buffer.get();
            if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
            {
                return true;
            }
        }

        return false;
    }
    else
    {
        Buffer *buffer = getTargetBuffer(target);
        return (buffer && buffer->isMapped());
    }
}

void State::syncDirtyObjects(const Context *context)
{
    if (!mDirtyObjects.any())
        return;

    syncDirtyObjects(context, mDirtyObjects);
}

void State::syncDirtyObjects(const Context *context, const DirtyObjects &bitset)
{
    for (auto dirtyObject : bitset)
    {
        switch (dirtyObject)
        {
            case DIRTY_OBJECT_READ_FRAMEBUFFER:
                ASSERT(mReadFramebuffer);
                mReadFramebuffer->syncState(context);
                break;
            case DIRTY_OBJECT_DRAW_FRAMEBUFFER:
                ASSERT(mDrawFramebuffer);
                mDrawFramebuffer->syncState(context);
                break;
            case DIRTY_OBJECT_VERTEX_ARRAY:
                ASSERT(mVertexArray);
                mVertexArray->syncImplState(context);
                break;
            case DIRTY_OBJECT_PROGRAM:
                // TODO(jmadill): implement this
                break;
            default:
                UNREACHABLE();
                break;
        }
    }

    mDirtyObjects &= ~bitset;
}

void State::syncDirtyObject(const Context *context, GLenum target)
{
    DirtyObjects localSet;

    switch (target)
    {
        case GL_READ_FRAMEBUFFER:
            localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
            break;
        case GL_DRAW_FRAMEBUFFER:
            localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
            break;
        case GL_FRAMEBUFFER:
            localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
            localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
            break;
        case GL_VERTEX_ARRAY:
            localSet.set(DIRTY_OBJECT_VERTEX_ARRAY);
            break;
        case GL_PROGRAM:
            localSet.set(DIRTY_OBJECT_PROGRAM);
            break;
    }

    syncDirtyObjects(context, localSet);
}

void State::setObjectDirty(GLenum target)
{
    switch (target)
    {
        case GL_READ_FRAMEBUFFER:
            mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
            break;
        case GL_DRAW_FRAMEBUFFER:
            mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
            break;
        case GL_FRAMEBUFFER:
            mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
            mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
            break;
        case GL_VERTEX_ARRAY:
            mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
            break;
        case GL_PROGRAM:
            mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
            break;
    }
}

}  // namespace gl
