#include "precompiled.h"
//
// 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 "libGLESv2/State.h"

#include "libGLESv2/Context.h"
#include "libGLESv2/VertexArray.h"
#include "libGLESv2/Query.h"
#include "libGLESv2/Framebuffer.h"
#include "libGLESv2/FramebufferAttachment.h"
#include "libGLESv2/renderer/RenderTarget.h"
#include "libGLESv2/formatutils.h"

namespace gl
{
State::State()
{
    mContext = NULL;

    setClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    mDepthClearValue = 1.0f;
    mStencilClearValue = 0;

    mRasterizer.rasterizerDiscard = false;
    mRasterizer.cullFace = false;
    mRasterizer.cullMode = GL_BACK;
    mRasterizer.frontFace = GL_CCW;
    mRasterizer.polygonOffsetFill = false;
    mRasterizer.polygonOffsetFactor = 0.0f;
    mRasterizer.polygonOffsetUnits = 0.0f;
    mRasterizer.pointDrawMode = false;
    mRasterizer.multiSample = false;
    mScissorTest = false;
    mScissor.x = 0;
    mScissor.y = 0;
    mScissor.width = 0;
    mScissor.height = 0;

    mBlend.blend = false;
    mBlend.sourceBlendRGB = GL_ONE;
    mBlend.sourceBlendAlpha = GL_ONE;
    mBlend.destBlendRGB = GL_ZERO;
    mBlend.destBlendAlpha = GL_ZERO;
    mBlend.blendEquationRGB = GL_FUNC_ADD;
    mBlend.blendEquationAlpha = GL_FUNC_ADD;
    mBlend.sampleAlphaToCoverage = false;
    mBlend.dither = true;

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

    mDepthStencil.depthTest = false;
    mDepthStencil.depthFunc = GL_LESS;
    mDepthStencil.depthMask = true;
    mDepthStencil.stencilTest = false;
    mDepthStencil.stencilFunc = GL_ALWAYS;
    mDepthStencil.stencilMask = -1;
    mDepthStencil.stencilWritemask = -1;
    mDepthStencil.stencilBackFunc = GL_ALWAYS;
    mDepthStencil.stencilBackMask = - 1;
    mDepthStencil.stencilBackWritemask = -1;
    mDepthStencil.stencilFail = GL_KEEP;
    mDepthStencil.stencilPassDepthFail = GL_KEEP;
    mDepthStencil.stencilPassDepthPass = GL_KEEP;
    mDepthStencil.stencilBackFail = GL_KEEP;
    mDepthStencil.stencilBackPassDepthFail = GL_KEEP;
    mDepthStencil.stencilBackPassDepthPass = GL_KEEP;

    mStencilRef = 0;
    mStencilBackRef = 0;

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

    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;

    const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
    for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
    {
        mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
    }

    for (unsigned int textureUnit = 0; textureUnit < ArraySize(mSamplers); textureUnit++)
    {
        mSamplers[textureUnit].set(NULL);
    }

    mActiveSampler = 0;

    mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
    mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
    mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);

    mCurrentProgramId = 0;
    mCurrentProgramBinary.set(NULL);

    mReadFramebuffer = NULL;
    mDrawFramebuffer = NULL;
}

State::~State()
{
    for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
    {
        for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
        {
            mSamplerTexture[type][sampler].set(NULL);
        }
    }

    const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
    for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
    {
        mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
    }

    mArrayBuffer.set(NULL);
    mRenderbuffer.set(NULL);

    mTransformFeedback.set(NULL);

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

    mGenericUniformBuffer.set(NULL);
    for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
    {
        mUniformBuffers[i].set(NULL);
    }

    mGenericTransformFeedbackBuffer.set(NULL);
    for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
    {
        mTransformFeedbackBuffers[i].set(NULL);
    }

    mCopyReadBuffer.set(NULL);
    mCopyWriteBuffer.set(NULL);

    mPack.pixelBuffer.set(NULL);
    mUnpack.pixelBuffer.set(NULL);
}

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

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

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

void State::setClearColor(float red, float green, float blue, float alpha)
{
    mColorClearValue.red = red;
    mColorClearValue.green = green;
    mColorClearValue.blue = blue;
    mColorClearValue.alpha = alpha;
}

void State::setClearDepth(float depth)
{
    mDepthClearValue = depth;
}

void State::setClearStencil(int stencil)
{
    mStencilClearValue = stencil;
}

ClearParameters State::getClearParameters(GLbitfield mask) const
{
    ClearParameters clearParams = { 0 };
    for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
    {
        clearParams.clearColor[i] = false;
    }
    clearParams.colorFClearValue = mColorClearValue;
    clearParams.colorClearType = GL_FLOAT;
    clearParams.colorMaskRed = mBlend.colorMaskRed;
    clearParams.colorMaskGreen = mBlend.colorMaskGreen;
    clearParams.colorMaskBlue = mBlend.colorMaskBlue;
    clearParams.colorMaskAlpha = mBlend.colorMaskAlpha;
    clearParams.clearDepth = false;
    clearParams.depthClearValue = mDepthClearValue;
    clearParams.clearStencil = false;
    clearParams.stencilClearValue = mStencilClearValue;
    clearParams.stencilWriteMask = mDepthStencil.stencilWritemask;
    clearParams.scissorEnabled = mScissorTest;
    clearParams.scissor = mScissor;

    const Framebuffer *framebufferObject = getDrawFramebuffer();
    if (mask & GL_COLOR_BUFFER_BIT)
    {
        if (framebufferObject->hasEnabledColorAttachment())
        {
            for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
            {
                clearParams.clearColor[i] = true;
            }
        }
    }

    if (mask & GL_DEPTH_BUFFER_BIT)
    {
        if (mDepthStencil.depthMask && framebufferObject->getDepthbuffer() != NULL)
        {
            clearParams.clearDepth = true;
        }
    }

    if (mask & GL_STENCIL_BUFFER_BIT)
    {
        if (framebufferObject->getStencilbuffer() != NULL)
        {
            rx::RenderTarget *depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
            if (!depthStencil)
            {
                ERR("Depth stencil pointer unexpectedly null.");
                ClearParameters nullClearParam = { 0 };
                return nullClearParam;
            }

            if (GetInternalFormatInfo(depthStencil->getActualFormat()).stencilBits > 0)
            {
                clearParams.clearStencil = true;
            }
        }
    }

    return clearParams;
}

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

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

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

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

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

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

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

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

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

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

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

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

void State::getDepthRange(float *zNear, float *zFar) const
{
    *zNear = mNearZ;
    *zFar = mFarZ;
}

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

void State::setBlend(bool enabled)
{
    mBlend.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;
}

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

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

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

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

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

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

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

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

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

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

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

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;
}

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;
}

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

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

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

void State::setSampleCoverage(bool enabled)
{
    mSampleCoverage = enabled;
}

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

void State::getSampleCoverageParams(GLclampf *value, bool *invert)
{
    ASSERT(value != NULL && invert != NULL);

    *value = mSampleCoverageValue;
    *invert = mSampleCoverageInvert;
}

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

void State::setScissorTest(bool enabled)
{
    mScissorTest = enabled;
}

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

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

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

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

void State::setEnableFeature(GLenum feature, bool enabled)
{
    switch (feature)
    {
      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: UNIMPLEMENTED();                   break;
      case GL_RASTERIZER_DISCARD:            setRasterizerDiscard(enabled);     break;
      default:                               UNREACHABLE();
    }
}

bool State::getEnableFeature(GLenum feature)
{
    switch (feature)
    {
      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: UNIMPLEMENTED(); return false;
      case GL_RASTERIZER_DISCARD:            return isRasterizerDiscardEnabled();
      default:                               UNREACHABLE(); return false;
    }
}

void State::setLineWidth(GLfloat width)
{
    mLineWidth = width;
}

void State::setGenerateMipmapHint(GLenum hint)
{
    mGenerateMipmapHint = hint;
}

void State::setFragmentShaderDerivativeHint(GLenum hint)
{
    mFragmentShaderDerivativeHint = 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.
}

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

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

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

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

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

Texture *State::getSamplerTexture(unsigned int sampler, TextureType type) const
{
    GLuint texid = mSamplerTexture[type][sampler].id();

    if (texid == 0)   // Special case: 0 refers to default textures held by Context
    {
        return NULL;
    }

    return mSamplerTexture[type][sampler].get();
}

GLuint State::getSamplerTextureId(unsigned int sampler, TextureType type) const
{
    return mSamplerTexture[type][sampler].id();
}

void State::detachTexture(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 (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
    {
        for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
        {
            if (mSamplerTexture[type][sampler].id() == texture)
            {
                mSamplerTexture[type][sampler].set(NULL);
            }
        }
    }

    // [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(texture);
    }

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

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

GLuint State::getSamplerId(GLuint textureUnit) const
{
    ASSERT(textureUnit < ArraySize(mSamplers));
    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 (unsigned int textureUnit = 0; textureUnit < ArraySize(mSamplers); textureUnit++)
    {
        if (mSamplers[textureUnit].id() == sampler)
        {
            mSamplers[textureUnit].set(NULL);
        }
    }
}

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

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

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

void State::detachRenderbuffer(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(NULL);
    }

    // [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(renderbuffer);
    }

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

}

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

void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
{
    mDrawFramebuffer = 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 NULL;
    }
}

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

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

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

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

bool State::removeReadFramebufferBinding(GLuint framebuffer)
{
    if (mReadFramebuffer->id() == framebuffer)
    {
        mReadFramebuffer = NULL;
        return true;
    }

    return false;
}

bool State::removeDrawFramebufferBinding(GLuint framebuffer)
{
    if (mDrawFramebuffer->id() == framebuffer)
    {
        mDrawFramebuffer = NULL;
        return true;
    }

    return false;
}

void State::setVertexArrayBinding(VertexArray *vertexArray)
{
    mVertexArray = vertexArray;
}

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

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

bool State::removeVertexArrayBinding(GLuint vertexArray)
{
    if (mVertexArray->id() == vertexArray)
    {
        mVertexArray = NULL;
        return true;
    }

    return false;
}

void State::setCurrentProgram(GLuint programId, Program *newProgram)
{
    mCurrentProgramId = programId; // set new ID before trying to delete program binary; otherwise it will only be flagged for deletion
    mCurrentProgramBinary.set(NULL);

    if (newProgram)
    {
        newProgram->addRef();
        mCurrentProgramBinary.set(newProgram->getProgramBinary());
    }
}

void State::setCurrentProgramBinary(ProgramBinary *binary)
{
    mCurrentProgramBinary.set(binary);
}

GLuint State::getCurrentProgramId() const
{
    return mCurrentProgramId;
}

ProgramBinary *State::getCurrentProgramBinary() const
{
    return mCurrentProgramBinary.get();
}

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

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

void State::detachTransformFeedback(GLuint transformFeedback)
{
    if (mTransformFeedback.id() == transformFeedback)
    {
        mTransformFeedback.set(NULL);
    }
}

bool State::isQueryActive() const
{
    for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin();
        i != mActiveQueries.end(); i++)
    {
        if (i->second.get() != NULL)
        {
            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
{
    // All query types should already exist in the activeQueries map
    ASSERT(mActiveQueries.find(target) != mActiveQueries.end());

    return mActiveQueries.at(target).get();
}

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

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

bool State::removeArrayBufferBinding(GLuint buffer)
{
    if (mArrayBuffer.id() == buffer)
    {
        mArrayBuffer.set(NULL);
        return true;
    }

    return false;
}

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);
}

GLuint State::getIndexedUniformBufferId(GLuint index) const
{
    ASSERT(index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS);

    return mUniformBuffers[index].id();
}

Buffer *State::getIndexedUniformBuffer(GLuint index) const
{
    ASSERT(index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS);

    return mUniformBuffers[index].get();
}

void State::setGenericTransformFeedbackBufferBinding(Buffer *buffer)
{
    mGenericTransformFeedbackBuffer.set(buffer);
}

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

GLuint State::getIndexedTransformFeedbackBufferId(GLuint index) const
{
    ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);

    return mTransformFeedbackBuffers[index].id();
}

Buffer *State::getIndexedTransformFeedbackBuffer(GLuint index) const
{
    ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);

    return mTransformFeedbackBuffers[index].get();
}

GLuint State::getIndexedTransformFeedbackBufferOffset(GLuint index) const
{
    ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);

    return mTransformFeedbackBuffers[index].getOffset();
}

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);
}

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

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();
      case GL_PIXEL_PACK_BUFFER:         return mPack.pixelBuffer.get();
      case GL_PIXEL_UNPACK_BUFFER:       return mUnpack.pixelBuffer.get();
      case GL_TRANSFORM_FEEDBACK_BUFFER: return mGenericTransformFeedbackBuffer.get();
      case GL_UNIFORM_BUFFER:            return mGenericUniformBuffer.get();
      default: UNREACHABLE();            return NULL;
    }
}

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

void State::setVertexAttribf(GLuint index, const GLfloat values[4])
{
    ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
    mVertexAttribCurrentValues[index].setFloatValues(values);
}

void State::setVertexAttribu(GLuint index, const GLuint values[4])
{
    ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
    mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
}

void State::setVertexAttribi(GLuint index, const GLint values[4])
{
    ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
    mVertexAttribCurrentValues[index].setIntValues(values);
}

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);
}

const VertexAttribute &State::getVertexAttribState(unsigned int attribNum) const
{
    return getVertexArray()->getVertexAttribute(attribNum);
}

const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
{
    ASSERT(attribNum < MAX_VERTEX_ATTRIBS);
    return mVertexAttribCurrentValues[attribNum];
}

const VertexAttribCurrentValueData *State::getVertexAttribCurrentValues() const
{
    return mVertexAttribCurrentValues;
}

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

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

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

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

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

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

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

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

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

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()->isStarted(); break;
      case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused();  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;
      default:
        UNREACHABLE();
        break;
    }
}

void State::getIntegerv(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 < mContext->getCaps().maxDrawBuffers);
        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_ELEMENT_ARRAY_BUFFER_BINDING:             *params = getVertexArray()->getElementArrayBufferId();    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 = mCurrentProgramId;                              break;
      case GL_PACK_ALIGNMENT:                           *params = mPack.alignment;                                break;
      case GL_PACK_REVERSE_ROW_ORDER_ANGLE:             *params = mPack.reverseRowOrder;                          break;
      case GL_UNPACK_ALIGNMENT:                         *params = mUnpack.alignment;                              break;
      case GL_GENERATE_MIPMAP_HINT:                     *params = mGenerateMipmapHint;                            break;
      case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:      *params = mFragmentShaderDerivativeHint;                  break;
      case GL_ACTIVE_TEXTURE:                           *params = (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_SAMPLE_BUFFERS:
      case GL_SAMPLES:
        {
            gl::Framebuffer *framebuffer = mDrawFramebuffer;
            if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
            {
                switch (pname)
                {
                  case GL_SAMPLE_BUFFERS:
                    if (framebuffer->getSamples() != 0)
                    {
                        *params = 1;
                    }
                    else
                    {
                        *params = 0;
                    }
                    break;
                  case GL_SAMPLES:
                    *params = framebuffer->getSamples();
                    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();
            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:
        {
            gl::Framebuffer *framebuffer = getDrawFramebuffer();
            gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();

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

            if (stencilbuffer)
            {
                *params = stencilbuffer->getStencilSize();
            }
            else
            {
                *params = 0;
            }
        }
        break;
      case GL_TEXTURE_BINDING_2D:
        ASSERT(mActiveSampler < mContext->getMaximumCombinedTextureImageUnits());
        *params = mSamplerTexture[TEXTURE_2D][mActiveSampler].id();
        break;
      case GL_TEXTURE_BINDING_CUBE_MAP:
        ASSERT(mActiveSampler < mContext->getMaximumCombinedTextureImageUnits());
        *params = mSamplerTexture[TEXTURE_CUBE][mActiveSampler].id();
        break;
      case GL_TEXTURE_BINDING_3D:
        ASSERT(mActiveSampler < mContext->getMaximumCombinedTextureImageUnits());
        *params = mSamplerTexture[TEXTURE_3D][mActiveSampler].id();
        break;
      case GL_TEXTURE_BINDING_2D_ARRAY:
        ASSERT(mActiveSampler < mContext->getMaximumCombinedTextureImageUnits());
        *params = mSamplerTexture[TEXTURE_2D_ARRAY][mActiveSampler].id();
        break;
      case GL_UNIFORM_BUFFER_BINDING:
        *params = mGenericUniformBuffer.id();
        break;
      case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
        *params = mGenericTransformFeedbackBuffer.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;
      default:
        UNREACHABLE();
        break;
    }
}

bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
{
    switch (target)
    {
      case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
        if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
        {
            *data = mTransformFeedbackBuffers[index].id();
        }
        break;
      case GL_UNIFORM_BUFFER_BINDING:
        if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
        {
            *data = mUniformBuffers[index].id();
        }
        break;
      default:
        return false;
    }

    return true;
}

bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
{
    switch (target)
    {
      case GL_TRANSFORM_FEEDBACK_BUFFER_START:
        if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
        {
            *data = mTransformFeedbackBuffers[index].getOffset();
        }
        break;
      case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
        if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
        {
            *data = mTransformFeedbackBuffers[index].getSize();
        }
        break;
      case GL_UNIFORM_BUFFER_START:
        if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
        {
            *data = mUniformBuffers[index].getOffset();
        }
        break;
      case GL_UNIFORM_BUFFER_SIZE:
        if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
        {
            *data = mUniformBuffers[index].getSize();
        }
        break;
      default:
        return false;
    }

    return true;
}

bool State::hasMappedBuffer(GLenum target) const
{
    if (target == GL_ARRAY_BUFFER)
    {
        for (unsigned int attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++)
        {
            const gl::VertexAttribute &vertexAttrib = getVertexAttribState(attribIndex);
            gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
            if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
            {
                return true;
            }
        }

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

}
