Home | History | Annotate | Download | only in libGLESv2
      1 //
      2 // Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // State.cpp: Implements the State class, encapsulating raw GL state.
      8 
      9 #include "libGLESv2/State.h"
     10 
     11 #include "libGLESv2/Context.h"
     12 #include "libGLESv2/Caps.h"
     13 #include "libGLESv2/VertexArray.h"
     14 #include "libGLESv2/Query.h"
     15 #include "libGLESv2/Framebuffer.h"
     16 #include "libGLESv2/FramebufferAttachment.h"
     17 #include "libGLESv2/renderer/RenderTarget.h"
     18 #include "libGLESv2/formatutils.h"
     19 
     20 namespace gl
     21 {
     22 
     23 State::State()
     24 {
     25 }
     26 
     27 State::~State()
     28 {
     29     reset();
     30 }
     31 
     32 void State::initialize(const Caps& caps, GLuint clientVersion)
     33 {
     34     mContext = NULL;
     35 
     36     setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
     37 
     38     mDepthClearValue = 1.0f;
     39     mStencilClearValue = 0;
     40 
     41     mRasterizer.rasterizerDiscard = false;
     42     mRasterizer.cullFace = false;
     43     mRasterizer.cullMode = GL_BACK;
     44     mRasterizer.frontFace = GL_CCW;
     45     mRasterizer.polygonOffsetFill = false;
     46     mRasterizer.polygonOffsetFactor = 0.0f;
     47     mRasterizer.polygonOffsetUnits = 0.0f;
     48     mRasterizer.pointDrawMode = false;
     49     mRasterizer.multiSample = false;
     50     mScissorTest = false;
     51     mScissor.x = 0;
     52     mScissor.y = 0;
     53     mScissor.width = 0;
     54     mScissor.height = 0;
     55 
     56     mBlend.blend = false;
     57     mBlend.sourceBlendRGB = GL_ONE;
     58     mBlend.sourceBlendAlpha = GL_ONE;
     59     mBlend.destBlendRGB = GL_ZERO;
     60     mBlend.destBlendAlpha = GL_ZERO;
     61     mBlend.blendEquationRGB = GL_FUNC_ADD;
     62     mBlend.blendEquationAlpha = GL_FUNC_ADD;
     63     mBlend.sampleAlphaToCoverage = false;
     64     mBlend.dither = true;
     65 
     66     mBlendColor.red = 0;
     67     mBlendColor.green = 0;
     68     mBlendColor.blue = 0;
     69     mBlendColor.alpha = 0;
     70 
     71     mDepthStencil.depthTest = false;
     72     mDepthStencil.depthFunc = GL_LESS;
     73     mDepthStencil.depthMask = true;
     74     mDepthStencil.stencilTest = false;
     75     mDepthStencil.stencilFunc = GL_ALWAYS;
     76     mDepthStencil.stencilMask = -1;
     77     mDepthStencil.stencilWritemask = -1;
     78     mDepthStencil.stencilBackFunc = GL_ALWAYS;
     79     mDepthStencil.stencilBackMask = -1;
     80     mDepthStencil.stencilBackWritemask = -1;
     81     mDepthStencil.stencilFail = GL_KEEP;
     82     mDepthStencil.stencilPassDepthFail = GL_KEEP;
     83     mDepthStencil.stencilPassDepthPass = GL_KEEP;
     84     mDepthStencil.stencilBackFail = GL_KEEP;
     85     mDepthStencil.stencilBackPassDepthFail = GL_KEEP;
     86     mDepthStencil.stencilBackPassDepthPass = GL_KEEP;
     87 
     88     mStencilRef = 0;
     89     mStencilBackRef = 0;
     90 
     91     mSampleCoverage = false;
     92     mSampleCoverageValue = 1.0f;
     93     mSampleCoverageInvert = false;
     94     mGenerateMipmapHint = GL_DONT_CARE;
     95     mFragmentShaderDerivativeHint = GL_DONT_CARE;
     96 
     97     mLineWidth = 1.0f;
     98 
     99     mViewport.x = 0;
    100     mViewport.y = 0;
    101     mViewport.width = 0;
    102     mViewport.height = 0;
    103     mNearZ = 0.0f;
    104     mFarZ = 1.0f;
    105 
    106     mBlend.colorMaskRed = true;
    107     mBlend.colorMaskGreen = true;
    108     mBlend.colorMaskBlue = true;
    109     mBlend.colorMaskAlpha = true;
    110 
    111     mActiveSampler = 0;
    112 
    113     const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
    114     for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
    115     {
    116         mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
    117     }
    118 
    119     mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
    120     mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
    121     if (clientVersion >= 3)
    122     {
    123         // TODO: These could also be enabled via extension
    124         mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
    125         mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
    126     }
    127 
    128     mSamplers.resize(caps.maxCombinedTextureImageUnits);
    129 
    130     mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
    131     mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
    132     mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);
    133 
    134     mCurrentProgramId = 0;
    135     mCurrentProgramBinary.set(NULL);
    136 
    137     mReadFramebuffer = NULL;
    138     mDrawFramebuffer = NULL;
    139 }
    140 
    141 void State::reset()
    142 {
    143     for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
    144     {
    145         TextureBindingVector &textureVector = bindingVec->second;
    146         for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
    147         {
    148             textureVector[textureIdx].set(NULL);
    149         }
    150     }
    151     for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
    152     {
    153         mSamplers[samplerIdx].set(NULL);
    154     }
    155 
    156     const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
    157     for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
    158     {
    159         mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
    160     }
    161 
    162     mArrayBuffer.set(NULL);
    163     mRenderbuffer.set(NULL);
    164 
    165     mTransformFeedback.set(NULL);
    166 
    167     for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
    168     {
    169         i->second.set(NULL);
    170     }
    171 
    172     mGenericUniformBuffer.set(NULL);
    173     for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
    174     {
    175         mUniformBuffers[i].set(NULL);
    176     }
    177 
    178     mGenericTransformFeedbackBuffer.set(NULL);
    179     for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
    180     {
    181         mTransformFeedbackBuffers[i].set(NULL);
    182     }
    183 
    184     mCopyReadBuffer.set(NULL);
    185     mCopyWriteBuffer.set(NULL);
    186 
    187     mPack.pixelBuffer.set(NULL);
    188     mUnpack.pixelBuffer.set(NULL);
    189 }
    190 
    191 const RasterizerState &State::getRasterizerState() const
    192 {
    193     return mRasterizer;
    194 }
    195 
    196 const BlendState &State::getBlendState() const
    197 {
    198     return mBlend;
    199 }
    200 
    201 const DepthStencilState &State::getDepthStencilState() const
    202 {
    203     return mDepthStencil;
    204 }
    205 
    206 void State::setClearColor(float red, float green, float blue, float alpha)
    207 {
    208     mColorClearValue.red = red;
    209     mColorClearValue.green = green;
    210     mColorClearValue.blue = blue;
    211     mColorClearValue.alpha = alpha;
    212 }
    213 
    214 void State::setClearDepth(float depth)
    215 {
    216     mDepthClearValue = depth;
    217 }
    218 
    219 void State::setClearStencil(int stencil)
    220 {
    221     mStencilClearValue = stencil;
    222 }
    223 
    224 ClearParameters State::getClearParameters(GLbitfield mask) const
    225 {
    226     ClearParameters clearParams = { 0 };
    227     for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
    228     {
    229         clearParams.clearColor[i] = false;
    230     }
    231     clearParams.colorFClearValue = mColorClearValue;
    232     clearParams.colorClearType = GL_FLOAT;
    233     clearParams.colorMaskRed = mBlend.colorMaskRed;
    234     clearParams.colorMaskGreen = mBlend.colorMaskGreen;
    235     clearParams.colorMaskBlue = mBlend.colorMaskBlue;
    236     clearParams.colorMaskAlpha = mBlend.colorMaskAlpha;
    237     clearParams.clearDepth = false;
    238     clearParams.depthClearValue = mDepthClearValue;
    239     clearParams.clearStencil = false;
    240     clearParams.stencilClearValue = mStencilClearValue;
    241     clearParams.stencilWriteMask = mDepthStencil.stencilWritemask;
    242     clearParams.scissorEnabled = mScissorTest;
    243     clearParams.scissor = mScissor;
    244 
    245     const Framebuffer *framebufferObject = getDrawFramebuffer();
    246     if (mask & GL_COLOR_BUFFER_BIT)
    247     {
    248         if (framebufferObject->hasEnabledColorAttachment())
    249         {
    250             for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
    251             {
    252                 clearParams.clearColor[i] = true;
    253             }
    254         }
    255     }
    256 
    257     if (mask & GL_DEPTH_BUFFER_BIT)
    258     {
    259         if (mDepthStencil.depthMask && framebufferObject->getDepthbuffer() != NULL)
    260         {
    261             clearParams.clearDepth = true;
    262         }
    263     }
    264 
    265     if (mask & GL_STENCIL_BUFFER_BIT)
    266     {
    267         if (framebufferObject->getStencilbuffer() != NULL)
    268         {
    269             GLenum stencilActualFormat = framebufferObject->getStencilbuffer()->getActualFormat();
    270             if (GetInternalFormatInfo(stencilActualFormat).stencilBits > 0)
    271             {
    272                 clearParams.clearStencil = true;
    273             }
    274         }
    275     }
    276 
    277     return clearParams;
    278 }
    279 
    280 void State::setColorMask(bool red, bool green, bool blue, bool alpha)
    281 {
    282     mBlend.colorMaskRed = red;
    283     mBlend.colorMaskGreen = green;
    284     mBlend.colorMaskBlue = blue;
    285     mBlend.colorMaskAlpha = alpha;
    286 }
    287 
    288 void State::setDepthMask(bool mask)
    289 {
    290     mDepthStencil.depthMask = mask;
    291 }
    292 
    293 bool State::isRasterizerDiscardEnabled() const
    294 {
    295     return mRasterizer.rasterizerDiscard;
    296 }
    297 
    298 void State::setRasterizerDiscard(bool enabled)
    299 {
    300     mRasterizer.rasterizerDiscard = enabled;
    301 }
    302 
    303 bool State::isCullFaceEnabled() const
    304 {
    305     return mRasterizer.cullFace;
    306 }
    307 
    308 void State::setCullFace(bool enabled)
    309 {
    310     mRasterizer.cullFace = enabled;
    311 }
    312 
    313 void State::setCullMode(GLenum mode)
    314 {
    315     mRasterizer.cullMode = mode;
    316 }
    317 
    318 void State::setFrontFace(GLenum front)
    319 {
    320     mRasterizer.frontFace = front;
    321 }
    322 
    323 bool State::isDepthTestEnabled() const
    324 {
    325     return mDepthStencil.depthTest;
    326 }
    327 
    328 void State::setDepthTest(bool enabled)
    329 {
    330     mDepthStencil.depthTest = enabled;
    331 }
    332 
    333 void State::setDepthFunc(GLenum depthFunc)
    334 {
    335      mDepthStencil.depthFunc = depthFunc;
    336 }
    337 
    338 void State::setDepthRange(float zNear, float zFar)
    339 {
    340     mNearZ = zNear;
    341     mFarZ = zFar;
    342 }
    343 
    344 void State::getDepthRange(float *zNear, float *zFar) const
    345 {
    346     *zNear = mNearZ;
    347     *zFar = mFarZ;
    348 }
    349 
    350 bool State::isBlendEnabled() const
    351 {
    352     return mBlend.blend;
    353 }
    354 
    355 void State::setBlend(bool enabled)
    356 {
    357     mBlend.blend = enabled;
    358 }
    359 
    360 void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
    361 {
    362     mBlend.sourceBlendRGB = sourceRGB;
    363     mBlend.destBlendRGB = destRGB;
    364     mBlend.sourceBlendAlpha = sourceAlpha;
    365     mBlend.destBlendAlpha = destAlpha;
    366 }
    367 
    368 void State::setBlendColor(float red, float green, float blue, float alpha)
    369 {
    370     mBlendColor.red = red;
    371     mBlendColor.green = green;
    372     mBlendColor.blue = blue;
    373     mBlendColor.alpha = alpha;
    374 }
    375 
    376 void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
    377 {
    378     mBlend.blendEquationRGB = rgbEquation;
    379     mBlend.blendEquationAlpha = alphaEquation;
    380 }
    381 
    382 const ColorF &State::getBlendColor() const
    383 {
    384     return mBlendColor;
    385 }
    386 
    387 bool State::isStencilTestEnabled() const
    388 {
    389     return mDepthStencil.stencilTest;
    390 }
    391 
    392 void State::setStencilTest(bool enabled)
    393 {
    394     mDepthStencil.stencilTest = enabled;
    395 }
    396 
    397 void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
    398 {
    399     mDepthStencil.stencilFunc = stencilFunc;
    400     mStencilRef = (stencilRef > 0) ? stencilRef : 0;
    401     mDepthStencil.stencilMask = stencilMask;
    402 }
    403 
    404 void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
    405 {
    406     mDepthStencil.stencilBackFunc = stencilBackFunc;
    407     mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
    408     mDepthStencil.stencilBackMask = stencilBackMask;
    409 }
    410 
    411 void State::setStencilWritemask(GLuint stencilWritemask)
    412 {
    413     mDepthStencil.stencilWritemask = stencilWritemask;
    414 }
    415 
    416 void State::setStencilBackWritemask(GLuint stencilBackWritemask)
    417 {
    418     mDepthStencil.stencilBackWritemask = stencilBackWritemask;
    419 }
    420 
    421 void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
    422 {
    423     mDepthStencil.stencilFail = stencilFail;
    424     mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
    425     mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
    426 }
    427 
    428 void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
    429 {
    430     mDepthStencil.stencilBackFail = stencilBackFail;
    431     mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
    432     mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
    433 }
    434 
    435 GLint State::getStencilRef() const
    436 {
    437     return mStencilRef;
    438 }
    439 
    440 GLint State::getStencilBackRef() const
    441 {
    442     return mStencilBackRef;
    443 }
    444 
    445 bool State::isPolygonOffsetFillEnabled() const
    446 {
    447     return mRasterizer.polygonOffsetFill;
    448 }
    449 
    450 void State::setPolygonOffsetFill(bool enabled)
    451 {
    452      mRasterizer.polygonOffsetFill = enabled;
    453 }
    454 
    455 void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
    456 {
    457     // An application can pass NaN values here, so handle this gracefully
    458     mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
    459     mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
    460 }
    461 
    462 bool State::isSampleAlphaToCoverageEnabled() const
    463 {
    464     return mBlend.sampleAlphaToCoverage;
    465 }
    466 
    467 void State::setSampleAlphaToCoverage(bool enabled)
    468 {
    469     mBlend.sampleAlphaToCoverage = enabled;
    470 }
    471 
    472 bool State::isSampleCoverageEnabled() const
    473 {
    474     return mSampleCoverage;
    475 }
    476 
    477 void State::setSampleCoverage(bool enabled)
    478 {
    479     mSampleCoverage = enabled;
    480 }
    481 
    482 void State::setSampleCoverageParams(GLclampf value, bool invert)
    483 {
    484     mSampleCoverageValue = value;
    485     mSampleCoverageInvert = invert;
    486 }
    487 
    488 void State::getSampleCoverageParams(GLclampf *value, bool *invert)
    489 {
    490     ASSERT(value != NULL && invert != NULL);
    491 
    492     *value = mSampleCoverageValue;
    493     *invert = mSampleCoverageInvert;
    494 }
    495 
    496 bool State::isScissorTestEnabled() const
    497 {
    498     return mScissorTest;
    499 }
    500 
    501 void State::setScissorTest(bool enabled)
    502 {
    503     mScissorTest = enabled;
    504 }
    505 
    506 void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
    507 {
    508     mScissor.x = x;
    509     mScissor.y = y;
    510     mScissor.width = width;
    511     mScissor.height = height;
    512 }
    513 
    514 const Rectangle &State::getScissor() const
    515 {
    516     return mScissor;
    517 }
    518 
    519 bool State::isDitherEnabled() const
    520 {
    521     return mBlend.dither;
    522 }
    523 
    524 void State::setDither(bool enabled)
    525 {
    526     mBlend.dither = enabled;
    527 }
    528 
    529 void State::setEnableFeature(GLenum feature, bool enabled)
    530 {
    531     switch (feature)
    532     {
    533       case GL_CULL_FACE:                     setCullFace(enabled);              break;
    534       case GL_POLYGON_OFFSET_FILL:           setPolygonOffsetFill(enabled);     break;
    535       case GL_SAMPLE_ALPHA_TO_COVERAGE:      setSampleAlphaToCoverage(enabled); break;
    536       case GL_SAMPLE_COVERAGE:               setSampleCoverage(enabled);        break;
    537       case GL_SCISSOR_TEST:                  setScissorTest(enabled);           break;
    538       case GL_STENCIL_TEST:                  setStencilTest(enabled);           break;
    539       case GL_DEPTH_TEST:                    setDepthTest(enabled);             break;
    540       case GL_BLEND:                         setBlend(enabled);                 break;
    541       case GL_DITHER:                        setDither(enabled);                break;
    542       case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED();                   break;
    543       case GL_RASTERIZER_DISCARD:            setRasterizerDiscard(enabled);     break;
    544       default:                               UNREACHABLE();
    545     }
    546 }
    547 
    548 bool State::getEnableFeature(GLenum feature)
    549 {
    550     switch (feature)
    551     {
    552       case GL_CULL_FACE:                     return isCullFaceEnabled();
    553       case GL_POLYGON_OFFSET_FILL:           return isPolygonOffsetFillEnabled();
    554       case GL_SAMPLE_ALPHA_TO_COVERAGE:      return isSampleAlphaToCoverageEnabled();
    555       case GL_SAMPLE_COVERAGE:               return isSampleCoverageEnabled();
    556       case GL_SCISSOR_TEST:                  return isScissorTestEnabled();
    557       case GL_STENCIL_TEST:                  return isStencilTestEnabled();
    558       case GL_DEPTH_TEST:                    return isDepthTestEnabled();
    559       case GL_BLEND:                         return isBlendEnabled();
    560       case GL_DITHER:                        return isDitherEnabled();
    561       case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); return false;
    562       case GL_RASTERIZER_DISCARD:            return isRasterizerDiscardEnabled();
    563       default:                               UNREACHABLE(); return false;
    564     }
    565 }
    566 
    567 void State::setLineWidth(GLfloat width)
    568 {
    569     mLineWidth = width;
    570 }
    571 
    572 void State::setGenerateMipmapHint(GLenum hint)
    573 {
    574     mGenerateMipmapHint = hint;
    575 }
    576 
    577 void State::setFragmentShaderDerivativeHint(GLenum hint)
    578 {
    579     mFragmentShaderDerivativeHint = hint;
    580     // TODO: Propagate the hint to shader translator so we can write
    581     // ddx, ddx_coarse, or ddx_fine depending on the hint.
    582     // Ignore for now. It is valid for implementations to ignore hint.
    583 }
    584 
    585 void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
    586 {
    587     mViewport.x = x;
    588     mViewport.y = y;
    589     mViewport.width = width;
    590     mViewport.height = height;
    591 }
    592 
    593 const Rectangle &State::getViewport() const
    594 {
    595     return mViewport;
    596 }
    597 
    598 void State::setActiveSampler(unsigned int active)
    599 {
    600     mActiveSampler = active;
    601 }
    602 
    603 unsigned int State::getActiveSampler() const
    604 {
    605     return mActiveSampler;
    606 }
    607 
    608 void State::setSamplerTexture(GLenum type, Texture *texture)
    609 {
    610     mSamplerTextures[type][mActiveSampler].set(texture);
    611 }
    612 
    613 Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
    614 {
    615     const BindingPointer<Texture>& binding = mSamplerTextures.at(type)[sampler];
    616 
    617     if (binding.id() == 0)   // Special case: 0 refers to default textures held by Context
    618     {
    619         return NULL;
    620     }
    621 
    622     return binding.get();
    623 }
    624 
    625 GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
    626 {
    627     return mSamplerTextures.at(type)[sampler].id();
    628 }
    629 
    630 void State::detachTexture(GLuint texture)
    631 {
    632     // Textures have a detach method on State rather than a simple
    633     // removeBinding, because the zero/null texture objects are managed
    634     // separately, and don't have to go through the Context's maps or
    635     // the ResourceManager.
    636 
    637     // [OpenGL ES 2.0.24] section 3.8 page 84:
    638     // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
    639     // rebound to texture object zero
    640 
    641     for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
    642     {
    643         TextureBindingVector &textureVector = bindingVec->second;
    644         for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
    645         {
    646             BindingPointer<Texture> &binding = textureVector[textureIdx];
    647             if (binding.id() == texture)
    648             {
    649                 binding.set(NULL);
    650             }
    651         }
    652     }
    653 
    654     // [OpenGL ES 2.0.24] section 4.4 page 112:
    655     // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
    656     // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
    657     // image was attached in the currently bound framebuffer.
    658 
    659     if (mReadFramebuffer)
    660     {
    661         mReadFramebuffer->detachTexture(texture);
    662     }
    663 
    664     if (mDrawFramebuffer)
    665     {
    666         mDrawFramebuffer->detachTexture(texture);
    667     }
    668 }
    669 
    670 void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
    671 {
    672     mSamplers[textureUnit].set(sampler);
    673 }
    674 
    675 GLuint State::getSamplerId(GLuint textureUnit) const
    676 {
    677     ASSERT(textureUnit < mSamplers.size());
    678     return mSamplers[textureUnit].id();
    679 }
    680 
    681 Sampler *State::getSampler(GLuint textureUnit) const
    682 {
    683     return mSamplers[textureUnit].get();
    684 }
    685 
    686 void State::detachSampler(GLuint sampler)
    687 {
    688     // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
    689     // If a sampler object that is currently bound to one or more texture units is
    690     // deleted, it is as though BindSampler is called once for each texture unit to
    691     // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
    692     for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
    693     {
    694         BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
    695         if (samplerBinding.id() == sampler)
    696         {
    697             samplerBinding.set(NULL);
    698         }
    699     }
    700 }
    701 
    702 void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
    703 {
    704     mRenderbuffer.set(renderbuffer);
    705 }
    706 
    707 GLuint State::getRenderbufferId() const
    708 {
    709     return mRenderbuffer.id();
    710 }
    711 
    712 Renderbuffer *State::getCurrentRenderbuffer()
    713 {
    714     return mRenderbuffer.get();
    715 }
    716 
    717 void State::detachRenderbuffer(GLuint renderbuffer)
    718 {
    719     // [OpenGL ES 2.0.24] section 4.4 page 109:
    720     // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
    721     // had been executed with the target RENDERBUFFER and name of zero.
    722 
    723     if (mRenderbuffer.id() == renderbuffer)
    724     {
    725         mRenderbuffer.set(NULL);
    726     }
    727 
    728     // [OpenGL ES 2.0.24] section 4.4 page 111:
    729     // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
    730     // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
    731     // point to which this image was attached in the currently bound framebuffer.
    732 
    733     Framebuffer *readFramebuffer = mReadFramebuffer;
    734     Framebuffer *drawFramebuffer = mDrawFramebuffer;
    735 
    736     if (readFramebuffer)
    737     {
    738         readFramebuffer->detachRenderbuffer(renderbuffer);
    739     }
    740 
    741     if (drawFramebuffer && drawFramebuffer != readFramebuffer)
    742     {
    743         drawFramebuffer->detachRenderbuffer(renderbuffer);
    744     }
    745 
    746 }
    747 
    748 void State::setReadFramebufferBinding(Framebuffer *framebuffer)
    749 {
    750     mReadFramebuffer = framebuffer;
    751 }
    752 
    753 void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
    754 {
    755     mDrawFramebuffer = framebuffer;
    756 }
    757 
    758 Framebuffer *State::getTargetFramebuffer(GLenum target) const
    759 {
    760     switch (target)
    761     {
    762     case GL_READ_FRAMEBUFFER_ANGLE:  return mReadFramebuffer;
    763     case GL_DRAW_FRAMEBUFFER_ANGLE:
    764     case GL_FRAMEBUFFER:             return mDrawFramebuffer;
    765     default:                         UNREACHABLE(); return NULL;
    766     }
    767 }
    768 
    769 Framebuffer *State::getReadFramebuffer()
    770 {
    771     return mReadFramebuffer;
    772 }
    773 
    774 Framebuffer *State::getDrawFramebuffer()
    775 {
    776     return mDrawFramebuffer;
    777 }
    778 
    779 const Framebuffer *State::getReadFramebuffer() const
    780 {
    781     return mReadFramebuffer;
    782 }
    783 
    784 const Framebuffer *State::getDrawFramebuffer() const
    785 {
    786     return mDrawFramebuffer;
    787 }
    788 
    789 bool State::removeReadFramebufferBinding(GLuint framebuffer)
    790 {
    791     if (mReadFramebuffer->id() == framebuffer)
    792     {
    793         mReadFramebuffer = NULL;
    794         return true;
    795     }
    796 
    797     return false;
    798 }
    799 
    800 bool State::removeDrawFramebufferBinding(GLuint framebuffer)
    801 {
    802     if (mDrawFramebuffer->id() == framebuffer)
    803     {
    804         mDrawFramebuffer = NULL;
    805         return true;
    806     }
    807 
    808     return false;
    809 }
    810 
    811 void State::setVertexArrayBinding(VertexArray *vertexArray)
    812 {
    813     mVertexArray = vertexArray;
    814 }
    815 
    816 GLuint State::getVertexArrayId() const
    817 {
    818     ASSERT(mVertexArray != NULL);
    819     return mVertexArray->id();
    820 }
    821 
    822 VertexArray *State::getVertexArray() const
    823 {
    824     ASSERT(mVertexArray != NULL);
    825     return mVertexArray;
    826 }
    827 
    828 bool State::removeVertexArrayBinding(GLuint vertexArray)
    829 {
    830     if (mVertexArray->id() == vertexArray)
    831     {
    832         mVertexArray = NULL;
    833         return true;
    834     }
    835 
    836     return false;
    837 }
    838 
    839 void State::setCurrentProgram(GLuint programId, Program *newProgram)
    840 {
    841     mCurrentProgramId = programId; // set new ID before trying to delete program binary; otherwise it will only be flagged for deletion
    842     mCurrentProgramBinary.set(NULL);
    843 
    844     if (newProgram)
    845     {
    846         newProgram->addRef();
    847         mCurrentProgramBinary.set(newProgram->getProgramBinary());
    848     }
    849 }
    850 
    851 void State::setCurrentProgramBinary(ProgramBinary *binary)
    852 {
    853     mCurrentProgramBinary.set(binary);
    854 }
    855 
    856 GLuint State::getCurrentProgramId() const
    857 {
    858     return mCurrentProgramId;
    859 }
    860 
    861 ProgramBinary *State::getCurrentProgramBinary() const
    862 {
    863     return mCurrentProgramBinary.get();
    864 }
    865 
    866 void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
    867 {
    868     mTransformFeedback.set(transformFeedback);
    869 }
    870 
    871 TransformFeedback *State::getCurrentTransformFeedback() const
    872 {
    873     return mTransformFeedback.get();
    874 }
    875 
    876 void State::detachTransformFeedback(GLuint transformFeedback)
    877 {
    878     if (mTransformFeedback.id() == transformFeedback)
    879     {
    880         mTransformFeedback.set(NULL);
    881     }
    882 }
    883 
    884 bool State::isQueryActive() const
    885 {
    886     for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin();
    887         i != mActiveQueries.end(); i++)
    888     {
    889         if (i->second.get() != NULL)
    890         {
    891             return true;
    892         }
    893     }
    894 
    895     return false;
    896 }
    897 
    898 void State::setActiveQuery(GLenum target, Query *query)
    899 {
    900     mActiveQueries[target].set(query);
    901 }
    902 
    903 GLuint State::getActiveQueryId(GLenum target) const
    904 {
    905     const Query *query = getActiveQuery(target);
    906     return (query ? query->id() : 0u);
    907 }
    908 
    909 Query *State::getActiveQuery(GLenum target) const
    910 {
    911     // All query types should already exist in the activeQueries map
    912     ASSERT(mActiveQueries.find(target) != mActiveQueries.end());
    913 
    914     return mActiveQueries.at(target).get();
    915 }
    916 
    917 void State::setArrayBufferBinding(Buffer *buffer)
    918 {
    919     mArrayBuffer.set(buffer);
    920 }
    921 
    922 GLuint State::getArrayBufferId() const
    923 {
    924     return mArrayBuffer.id();
    925 }
    926 
    927 bool State::removeArrayBufferBinding(GLuint buffer)
    928 {
    929     if (mArrayBuffer.id() == buffer)
    930     {
    931         mArrayBuffer.set(NULL);
    932         return true;
    933     }
    934 
    935     return false;
    936 }
    937 
    938 void State::setGenericUniformBufferBinding(Buffer *buffer)
    939 {
    940     mGenericUniformBuffer.set(buffer);
    941 }
    942 
    943 void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
    944 {
    945     mUniformBuffers[index].set(buffer, offset, size);
    946 }
    947 
    948 GLuint State::getIndexedUniformBufferId(GLuint index) const
    949 {
    950     ASSERT(index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS);
    951 
    952     return mUniformBuffers[index].id();
    953 }
    954 
    955 Buffer *State::getIndexedUniformBuffer(GLuint index) const
    956 {
    957     ASSERT(index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS);
    958 
    959     return mUniformBuffers[index].get();
    960 }
    961 
    962 void State::setGenericTransformFeedbackBufferBinding(Buffer *buffer)
    963 {
    964     mGenericTransformFeedbackBuffer.set(buffer);
    965 }
    966 
    967 void State::setIndexedTransformFeedbackBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
    968 {
    969     mTransformFeedbackBuffers[index].set(buffer, offset, size);
    970 }
    971 
    972 GLuint State::getIndexedTransformFeedbackBufferId(GLuint index) const
    973 {
    974     ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
    975 
    976     return mTransformFeedbackBuffers[index].id();
    977 }
    978 
    979 Buffer *State::getIndexedTransformFeedbackBuffer(GLuint index) const
    980 {
    981     ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
    982 
    983     return mTransformFeedbackBuffers[index].get();
    984 }
    985 
    986 GLuint State::getIndexedTransformFeedbackBufferOffset(GLuint index) const
    987 {
    988     ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
    989 
    990     return mTransformFeedbackBuffers[index].getOffset();
    991 }
    992 
    993 void State::setCopyReadBufferBinding(Buffer *buffer)
    994 {
    995     mCopyReadBuffer.set(buffer);
    996 }
    997 
    998 void State::setCopyWriteBufferBinding(Buffer *buffer)
    999 {
   1000     mCopyWriteBuffer.set(buffer);
   1001 }
   1002 
   1003 void State::setPixelPackBufferBinding(Buffer *buffer)
   1004 {
   1005     mPack.pixelBuffer.set(buffer);
   1006 }
   1007 
   1008 void State::setPixelUnpackBufferBinding(Buffer *buffer)
   1009 {
   1010     mUnpack.pixelBuffer.set(buffer);
   1011 }
   1012 
   1013 Buffer *State::getTargetBuffer(GLenum target) const
   1014 {
   1015     switch (target)
   1016     {
   1017       case GL_ARRAY_BUFFER:              return mArrayBuffer.get();
   1018       case GL_COPY_READ_BUFFER:          return mCopyReadBuffer.get();
   1019       case GL_COPY_WRITE_BUFFER:         return mCopyWriteBuffer.get();
   1020       case GL_ELEMENT_ARRAY_BUFFER:      return getVertexArray()->getElementArrayBuffer();
   1021       case GL_PIXEL_PACK_BUFFER:         return mPack.pixelBuffer.get();
   1022       case GL_PIXEL_UNPACK_BUFFER:       return mUnpack.pixelBuffer.get();
   1023       case GL_TRANSFORM_FEEDBACK_BUFFER: return mGenericTransformFeedbackBuffer.get();
   1024       case GL_UNIFORM_BUFFER:            return mGenericUniformBuffer.get();
   1025       default: UNREACHABLE();            return NULL;
   1026     }
   1027 }
   1028 
   1029 void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
   1030 {
   1031     getVertexArray()->enableAttribute(attribNum, enabled);
   1032 }
   1033 
   1034 void State::setVertexAttribf(GLuint index, const GLfloat values[4])
   1035 {
   1036     ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
   1037     mVertexAttribCurrentValues[index].setFloatValues(values);
   1038 }
   1039 
   1040 void State::setVertexAttribu(GLuint index, const GLuint values[4])
   1041 {
   1042     ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
   1043     mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
   1044 }
   1045 
   1046 void State::setVertexAttribi(GLuint index, const GLint values[4])
   1047 {
   1048     ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
   1049     mVertexAttribCurrentValues[index].setIntValues(values);
   1050 }
   1051 
   1052 void State::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
   1053     bool pureInteger, GLsizei stride, const void *pointer)
   1054 {
   1055     getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
   1056 }
   1057 
   1058 const VertexAttribute &State::getVertexAttribState(unsigned int attribNum) const
   1059 {
   1060     return getVertexArray()->getVertexAttribute(attribNum);
   1061 }
   1062 
   1063 const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
   1064 {
   1065     ASSERT(attribNum < MAX_VERTEX_ATTRIBS);
   1066     return mVertexAttribCurrentValues[attribNum];
   1067 }
   1068 
   1069 const VertexAttribCurrentValueData *State::getVertexAttribCurrentValues() const
   1070 {
   1071     return mVertexAttribCurrentValues;
   1072 }
   1073 
   1074 const void *State::getVertexAttribPointer(unsigned int attribNum) const
   1075 {
   1076     return getVertexArray()->getVertexAttribute(attribNum).pointer;
   1077 }
   1078 
   1079 void State::setPackAlignment(GLint alignment)
   1080 {
   1081     mPack.alignment = alignment;
   1082 }
   1083 
   1084 GLint State::getPackAlignment() const
   1085 {
   1086     return mPack.alignment;
   1087 }
   1088 
   1089 void State::setPackReverseRowOrder(bool reverseRowOrder)
   1090 {
   1091     mPack.reverseRowOrder = reverseRowOrder;
   1092 }
   1093 
   1094 bool State::getPackReverseRowOrder() const
   1095 {
   1096     return mPack.reverseRowOrder;
   1097 }
   1098 
   1099 const PixelPackState &State::getPackState() const
   1100 {
   1101     return mPack;
   1102 }
   1103 
   1104 void State::setUnpackAlignment(GLint alignment)
   1105 {
   1106     mUnpack.alignment = alignment;
   1107 }
   1108 
   1109 GLint State::getUnpackAlignment() const
   1110 {
   1111     return mUnpack.alignment;
   1112 }
   1113 
   1114 const PixelUnpackState &State::getUnpackState() const
   1115 {
   1116     return mUnpack;
   1117 }
   1118 
   1119 void State::getBooleanv(GLenum pname, GLboolean *params)
   1120 {
   1121     switch (pname)
   1122     {
   1123       case GL_SAMPLE_COVERAGE_INVERT:    *params = mSampleCoverageInvert;         break;
   1124       case GL_DEPTH_WRITEMASK:           *params = mDepthStencil.depthMask;       break;
   1125       case GL_COLOR_WRITEMASK:
   1126         params[0] = mBlend.colorMaskRed;
   1127         params[1] = mBlend.colorMaskGreen;
   1128         params[2] = mBlend.colorMaskBlue;
   1129         params[3] = mBlend.colorMaskAlpha;
   1130         break;
   1131       case GL_CULL_FACE:                 *params = mRasterizer.cullFace;          break;
   1132       case GL_POLYGON_OFFSET_FILL:       *params = mRasterizer.polygonOffsetFill; break;
   1133       case GL_SAMPLE_ALPHA_TO_COVERAGE:  *params = mBlend.sampleAlphaToCoverage;  break;
   1134       case GL_SAMPLE_COVERAGE:           *params = mSampleCoverage;               break;
   1135       case GL_SCISSOR_TEST:              *params = mScissorTest;                  break;
   1136       case GL_STENCIL_TEST:              *params = mDepthStencil.stencilTest;     break;
   1137       case GL_DEPTH_TEST:                *params = mDepthStencil.depthTest;       break;
   1138       case GL_BLEND:                     *params = mBlend.blend;                  break;
   1139       case GL_DITHER:                    *params = mBlend.dither;                 break;
   1140       case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isStarted(); break;
   1141       case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused();  break;
   1142       default:
   1143         UNREACHABLE();
   1144         break;
   1145     }
   1146 }
   1147 
   1148 void State::getFloatv(GLenum pname, GLfloat *params)
   1149 {
   1150     // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
   1151     // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
   1152     // GetIntegerv as its native query function. As it would require conversion in any
   1153     // case, this should make no difference to the calling application.
   1154     switch (pname)
   1155     {
   1156       case GL_LINE_WIDTH:               *params = mLineWidth;                         break;
   1157       case GL_SAMPLE_COVERAGE_VALUE:    *params = mSampleCoverageValue;               break;
   1158       case GL_DEPTH_CLEAR_VALUE:        *params = mDepthClearValue;                   break;
   1159       case GL_POLYGON_OFFSET_FACTOR:    *params = mRasterizer.polygonOffsetFactor;    break;
   1160       case GL_POLYGON_OFFSET_UNITS:     *params = mRasterizer.polygonOffsetUnits;     break;
   1161       case GL_DEPTH_RANGE:
   1162         params[0] = mNearZ;
   1163         params[1] = mFarZ;
   1164         break;
   1165       case GL_COLOR_CLEAR_VALUE:
   1166         params[0] = mColorClearValue.red;
   1167         params[1] = mColorClearValue.green;
   1168         params[2] = mColorClearValue.blue;
   1169         params[3] = mColorClearValue.alpha;
   1170         break;
   1171       case GL_BLEND_COLOR:
   1172         params[0] = mBlendColor.red;
   1173         params[1] = mBlendColor.green;
   1174         params[2] = mBlendColor.blue;
   1175         params[3] = mBlendColor.alpha;
   1176         break;
   1177       default:
   1178         UNREACHABLE();
   1179         break;
   1180     }
   1181 }
   1182 
   1183 void State::getIntegerv(GLenum pname, GLint *params)
   1184 {
   1185     if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
   1186     {
   1187         unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
   1188         ASSERT(colorAttachment < mContext->getCaps().maxDrawBuffers);
   1189         Framebuffer *framebuffer = mDrawFramebuffer;
   1190         *params = framebuffer->getDrawBufferState(colorAttachment);
   1191         return;
   1192     }
   1193 
   1194     // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
   1195     // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
   1196     // GetIntegerv as its native query function. As it would require conversion in any
   1197     // case, this should make no difference to the calling application. You may find it in
   1198     // State::getFloatv.
   1199     switch (pname)
   1200     {
   1201       case GL_ARRAY_BUFFER_BINDING:                     *params = mArrayBuffer.id();                              break;
   1202       case GL_ELEMENT_ARRAY_BUFFER_BINDING:             *params = getVertexArray()->getElementArrayBufferId();    break;
   1203         //case GL_FRAMEBUFFER_BINDING:                    // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
   1204       case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:           *params = mDrawFramebuffer->id();                         break;
   1205       case GL_READ_FRAMEBUFFER_BINDING_ANGLE:           *params = mReadFramebuffer->id();                         break;
   1206       case GL_RENDERBUFFER_BINDING:                     *params = mRenderbuffer.id();                             break;
   1207       case GL_VERTEX_ARRAY_BINDING:                     *params = mVertexArray->id();                             break;
   1208       case GL_CURRENT_PROGRAM:                          *params = mCurrentProgramId;                              break;
   1209       case GL_PACK_ALIGNMENT:                           *params = mPack.alignment;                                break;
   1210       case GL_PACK_REVERSE_ROW_ORDER_ANGLE:             *params = mPack.reverseRowOrder;                          break;
   1211       case GL_UNPACK_ALIGNMENT:                         *params = mUnpack.alignment;                              break;
   1212       case GL_GENERATE_MIPMAP_HINT:                     *params = mGenerateMipmapHint;                            break;
   1213       case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:      *params = mFragmentShaderDerivativeHint;                  break;
   1214       case GL_ACTIVE_TEXTURE:                           *params = (mActiveSampler + GL_TEXTURE0);                 break;
   1215       case GL_STENCIL_FUNC:                             *params = mDepthStencil.stencilFunc;                      break;
   1216       case GL_STENCIL_REF:                              *params = mStencilRef;                                    break;
   1217       case GL_STENCIL_VALUE_MASK:                       *params = clampToInt(mDepthStencil.stencilMask);          break;
   1218       case GL_STENCIL_BACK_FUNC:                        *params = mDepthStencil.stencilBackFunc;                  break;
   1219       case GL_STENCIL_BACK_REF:                         *params = mStencilBackRef;                                break;
   1220       case GL_STENCIL_BACK_VALUE_MASK:                  *params = clampToInt(mDepthStencil.stencilBackMask);      break;
   1221       case GL_STENCIL_FAIL:                             *params = mDepthStencil.stencilFail;                      break;
   1222       case GL_STENCIL_PASS_DEPTH_FAIL:                  *params = mDepthStencil.stencilPassDepthFail;             break;
   1223       case GL_STENCIL_PASS_DEPTH_PASS:                  *params = mDepthStencil.stencilPassDepthPass;             break;
   1224       case GL_STENCIL_BACK_FAIL:                        *params = mDepthStencil.stencilBackFail;                  break;
   1225       case GL_STENCIL_BACK_PASS_DEPTH_FAIL:             *params = mDepthStencil.stencilBackPassDepthFail;         break;
   1226       case GL_STENCIL_BACK_PASS_DEPTH_PASS:             *params = mDepthStencil.stencilBackPassDepthPass;         break;
   1227       case GL_DEPTH_FUNC:                               *params = mDepthStencil.depthFunc;                        break;
   1228       case GL_BLEND_SRC_RGB:                            *params = mBlend.sourceBlendRGB;                          break;
   1229       case GL_BLEND_SRC_ALPHA:                          *params = mBlend.sourceBlendAlpha;                        break;
   1230       case GL_BLEND_DST_RGB:                            *params = mBlend.destBlendRGB;                            break;
   1231       case GL_BLEND_DST_ALPHA:                          *params = mBlend.destBlendAlpha;                          break;
   1232       case GL_BLEND_EQUATION_RGB:                       *params = mBlend.blendEquationRGB;                        break;
   1233       case GL_BLEND_EQUATION_ALPHA:                     *params = mBlend.blendEquationAlpha;                      break;
   1234       case GL_STENCIL_WRITEMASK:                        *params = clampToInt(mDepthStencil.stencilWritemask);     break;
   1235       case GL_STENCIL_BACK_WRITEMASK:                   *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
   1236       case GL_STENCIL_CLEAR_VALUE:                      *params = mStencilClearValue;                             break;
   1237       case GL_SAMPLE_BUFFERS:
   1238       case GL_SAMPLES:
   1239         {
   1240             gl::Framebuffer *framebuffer = mDrawFramebuffer;
   1241             if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
   1242             {
   1243                 switch (pname)
   1244                 {
   1245                   case GL_SAMPLE_BUFFERS:
   1246                     if (framebuffer->getSamples() != 0)
   1247                     {
   1248                         *params = 1;
   1249                     }
   1250                     else
   1251                     {
   1252                         *params = 0;
   1253                     }
   1254                     break;
   1255                   case GL_SAMPLES:
   1256                     *params = framebuffer->getSamples();
   1257                     break;
   1258                 }
   1259             }
   1260             else
   1261             {
   1262                 *params = 0;
   1263             }
   1264         }
   1265         break;
   1266       case GL_VIEWPORT:
   1267         params[0] = mViewport.x;
   1268         params[1] = mViewport.y;
   1269         params[2] = mViewport.width;
   1270         params[3] = mViewport.height;
   1271         break;
   1272       case GL_SCISSOR_BOX:
   1273         params[0] = mScissor.x;
   1274         params[1] = mScissor.y;
   1275         params[2] = mScissor.width;
   1276         params[3] = mScissor.height;
   1277         break;
   1278       case GL_CULL_FACE_MODE:                   *params = mRasterizer.cullMode;   break;
   1279       case GL_FRONT_FACE:                       *params = mRasterizer.frontFace;  break;
   1280       case GL_RED_BITS:
   1281       case GL_GREEN_BITS:
   1282       case GL_BLUE_BITS:
   1283       case GL_ALPHA_BITS:
   1284         {
   1285             gl::Framebuffer *framebuffer = getDrawFramebuffer();
   1286             gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
   1287 
   1288             if (colorbuffer)
   1289             {
   1290                 switch (pname)
   1291                 {
   1292                 case GL_RED_BITS:   *params = colorbuffer->getRedSize();      break;
   1293                 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize();    break;
   1294                 case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();     break;
   1295                 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize();    break;
   1296                 }
   1297             }
   1298             else
   1299             {
   1300                 *params = 0;
   1301             }
   1302         }
   1303         break;
   1304       case GL_DEPTH_BITS:
   1305         {
   1306             gl::Framebuffer *framebuffer = getDrawFramebuffer();
   1307             gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
   1308 
   1309             if (depthbuffer)
   1310             {
   1311                 *params = depthbuffer->getDepthSize();
   1312             }
   1313             else
   1314             {
   1315                 *params = 0;
   1316             }
   1317         }
   1318         break;
   1319       case GL_STENCIL_BITS:
   1320         {
   1321             gl::Framebuffer *framebuffer = getDrawFramebuffer();
   1322             gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
   1323 
   1324             if (stencilbuffer)
   1325             {
   1326                 *params = stencilbuffer->getStencilSize();
   1327             }
   1328             else
   1329             {
   1330                 *params = 0;
   1331             }
   1332         }
   1333         break;
   1334       case GL_TEXTURE_BINDING_2D:
   1335         ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
   1336         *params = mSamplerTextures.at(GL_TEXTURE_2D)[mActiveSampler].id();
   1337         break;
   1338       case GL_TEXTURE_BINDING_CUBE_MAP:
   1339         ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
   1340         *params = mSamplerTextures.at(GL_TEXTURE_CUBE_MAP)[mActiveSampler].id();
   1341         break;
   1342       case GL_TEXTURE_BINDING_3D:
   1343         ASSERT(mActiveSampler <mContext->getCaps().maxCombinedTextureImageUnits);
   1344         *params = mSamplerTextures.at(GL_TEXTURE_3D)[mActiveSampler].id();
   1345         break;
   1346       case GL_TEXTURE_BINDING_2D_ARRAY:
   1347         ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
   1348         *params = mSamplerTextures.at(GL_TEXTURE_2D_ARRAY)[mActiveSampler].id();
   1349         break;
   1350       case GL_UNIFORM_BUFFER_BINDING:
   1351         *params = mGenericUniformBuffer.id();
   1352         break;
   1353       case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
   1354         *params = mGenericTransformFeedbackBuffer.id();
   1355         break;
   1356       case GL_COPY_READ_BUFFER_BINDING:
   1357         *params = mCopyReadBuffer.id();
   1358         break;
   1359       case GL_COPY_WRITE_BUFFER_BINDING:
   1360         *params = mCopyWriteBuffer.id();
   1361         break;
   1362       case GL_PIXEL_PACK_BUFFER_BINDING:
   1363         *params = mPack.pixelBuffer.id();
   1364         break;
   1365       case GL_PIXEL_UNPACK_BUFFER_BINDING:
   1366         *params = mUnpack.pixelBuffer.id();
   1367         break;
   1368       default:
   1369         UNREACHABLE();
   1370         break;
   1371     }
   1372 }
   1373 
   1374 bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
   1375 {
   1376     switch (target)
   1377     {
   1378       case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
   1379         if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
   1380         {
   1381             *data = mTransformFeedbackBuffers[index].id();
   1382         }
   1383         break;
   1384       case GL_UNIFORM_BUFFER_BINDING:
   1385         if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
   1386         {
   1387             *data = mUniformBuffers[index].id();
   1388         }
   1389         break;
   1390       default:
   1391         return false;
   1392     }
   1393 
   1394     return true;
   1395 }
   1396 
   1397 bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
   1398 {
   1399     switch (target)
   1400     {
   1401       case GL_TRANSFORM_FEEDBACK_BUFFER_START:
   1402         if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
   1403         {
   1404             *data = mTransformFeedbackBuffers[index].getOffset();
   1405         }
   1406         break;
   1407       case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
   1408         if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
   1409         {
   1410             *data = mTransformFeedbackBuffers[index].getSize();
   1411         }
   1412         break;
   1413       case GL_UNIFORM_BUFFER_START:
   1414         if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
   1415         {
   1416             *data = mUniformBuffers[index].getOffset();
   1417         }
   1418         break;
   1419       case GL_UNIFORM_BUFFER_SIZE:
   1420         if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
   1421         {
   1422             *data = mUniformBuffers[index].getSize();
   1423         }
   1424         break;
   1425       default:
   1426         return false;
   1427     }
   1428 
   1429     return true;
   1430 }
   1431 
   1432 bool State::hasMappedBuffer(GLenum target) const
   1433 {
   1434     if (target == GL_ARRAY_BUFFER)
   1435     {
   1436         for (unsigned int attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++)
   1437         {
   1438             const gl::VertexAttribute &vertexAttrib = getVertexAttribState(attribIndex);
   1439             gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
   1440             if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
   1441             {
   1442                 return true;
   1443             }
   1444         }
   1445 
   1446         return false;
   1447     }
   1448     else
   1449     {
   1450         Buffer *buffer = getTargetBuffer(target);
   1451         return (buffer && buffer->isMapped());
   1452     }
   1453 }
   1454 
   1455 }
   1456