Home | History | Annotate | Download | only in libGLESv2
      1 #include "precompiled.h"
      2 //
      3 // Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style license that can be
      5 // found in the LICENSE file.
      6 //
      7 
      8 // Context.cpp: Implements the gl::Context class, managing all GL state and performing
      9 // rendering operations. It is the GLES2 specific implementation of EGLContext.
     10 
     11 #include "libGLESv2/Context.h"
     12 
     13 #include "libGLESv2/main.h"
     14 #include "common/utilities.h"
     15 #include "libGLESv2/formatutils.h"
     16 #include "libGLESv2/Buffer.h"
     17 #include "libGLESv2/Fence.h"
     18 #include "libGLESv2/Framebuffer.h"
     19 #include "libGLESv2/Renderbuffer.h"
     20 #include "libGLESv2/Program.h"
     21 #include "libGLESv2/ProgramBinary.h"
     22 #include "libGLESv2/Query.h"
     23 #include "libGLESv2/Texture.h"
     24 #include "libGLESv2/ResourceManager.h"
     25 #include "libGLESv2/renderer/IndexDataManager.h"
     26 #include "libGLESv2/renderer/RenderTarget.h"
     27 #include "libGLESv2/renderer/Renderer.h"
     28 #include "libGLESv2/VertexArray.h"
     29 #include "libGLESv2/Sampler.h"
     30 #include "libGLESv2/validationES.h"
     31 #include "libGLESv2/TransformFeedback.h"
     32 
     33 #include "libEGL/Surface.h"
     34 
     35 #undef near
     36 #undef far
     37 
     38 namespace gl
     39 {
     40 static const char* makeStaticString(const std::string& str)
     41 {
     42     static std::set<std::string> strings;
     43     std::set<std::string>::iterator it = strings.find(str);
     44     if (it != strings.end())
     45       return it->c_str();
     46 
     47     return strings.insert(str).first->c_str();
     48 }
     49 
     50 Context::Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) : mRenderer(renderer)
     51 {
     52     ASSERT(robustAccess == false);   // Unimplemented
     53 
     54     mFenceNVHandleAllocator.setBaseHandle(0);
     55 
     56     setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
     57 
     58     mClientVersion = clientVersion;
     59 
     60     mState.depthClearValue = 1.0f;
     61     mState.stencilClearValue = 0;
     62 
     63     mState.rasterizer.rasterizerDiscard = false;
     64     mState.rasterizer.cullFace = false;
     65     mState.rasterizer.cullMode = GL_BACK;
     66     mState.rasterizer.frontFace = GL_CCW;
     67     mState.rasterizer.polygonOffsetFill = false;
     68     mState.rasterizer.polygonOffsetFactor = 0.0f;
     69     mState.rasterizer.polygonOffsetUnits = 0.0f;
     70     mState.rasterizer.pointDrawMode = false;
     71     mState.rasterizer.multiSample = false;
     72     mState.scissorTest = false;
     73     mState.scissor.x = 0;
     74     mState.scissor.y = 0;
     75     mState.scissor.width = 0;
     76     mState.scissor.height = 0;
     77 
     78     mState.blend.blend = false;
     79     mState.blend.sourceBlendRGB = GL_ONE;
     80     mState.blend.sourceBlendAlpha = GL_ONE;
     81     mState.blend.destBlendRGB = GL_ZERO;
     82     mState.blend.destBlendAlpha = GL_ZERO;
     83     mState.blend.blendEquationRGB = GL_FUNC_ADD;
     84     mState.blend.blendEquationAlpha = GL_FUNC_ADD;
     85     mState.blend.sampleAlphaToCoverage = false;
     86     mState.blend.dither = true;
     87 
     88     mState.blendColor.red = 0;
     89     mState.blendColor.green = 0;
     90     mState.blendColor.blue = 0;
     91     mState.blendColor.alpha = 0;
     92 
     93     mState.depthStencil.depthTest = false;
     94     mState.depthStencil.depthFunc = GL_LESS;
     95     mState.depthStencil.depthMask = true;
     96     mState.depthStencil.stencilTest = false;
     97     mState.depthStencil.stencilFunc = GL_ALWAYS;
     98     mState.depthStencil.stencilMask = -1;
     99     mState.depthStencil.stencilWritemask = -1;
    100     mState.depthStencil.stencilBackFunc = GL_ALWAYS;
    101     mState.depthStencil.stencilBackMask = - 1;
    102     mState.depthStencil.stencilBackWritemask = -1;
    103     mState.depthStencil.stencilFail = GL_KEEP;
    104     mState.depthStencil.stencilPassDepthFail = GL_KEEP;
    105     mState.depthStencil.stencilPassDepthPass = GL_KEEP;
    106     mState.depthStencil.stencilBackFail = GL_KEEP;
    107     mState.depthStencil.stencilBackPassDepthFail = GL_KEEP;
    108     mState.depthStencil.stencilBackPassDepthPass = GL_KEEP;
    109 
    110     mState.stencilRef = 0;
    111     mState.stencilBackRef = 0;
    112 
    113     mState.sampleCoverage = false;
    114     mState.sampleCoverageValue = 1.0f;
    115     mState.sampleCoverageInvert = false;
    116     mState.generateMipmapHint = GL_DONT_CARE;
    117     mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
    118 
    119     mState.lineWidth = 1.0f;
    120 
    121     mState.viewport.x = 0;
    122     mState.viewport.y = 0;
    123     mState.viewport.width = 0;
    124     mState.viewport.height = 0;
    125     mState.zNear = 0.0f;
    126     mState.zFar = 1.0f;
    127 
    128     mState.blend.colorMaskRed = true;
    129     mState.blend.colorMaskGreen = true;
    130     mState.blend.colorMaskBlue = true;
    131     mState.blend.colorMaskAlpha = true;
    132 
    133     const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
    134     for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
    135     {
    136         mState.vertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
    137     }
    138 
    139     if (shareContext != NULL)
    140     {
    141         mResourceManager = shareContext->mResourceManager;
    142         mResourceManager->addRef();
    143     }
    144     else
    145     {
    146         mResourceManager = new ResourceManager(mRenderer);
    147     }
    148 
    149     // [OpenGL ES 2.0.24] section 3.7 page 83:
    150     // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
    151     // and cube map texture state vectors respectively associated with them.
    152     // In order that access to these initial textures not be lost, they are treated as texture
    153     // objects all of whose names are 0.
    154 
    155     mTexture2DZero.set(new Texture2D(mRenderer, 0));
    156     mTextureCubeMapZero.set(new TextureCubeMap(mRenderer, 0));
    157     mTexture3DZero.set(new Texture3D(mRenderer, 0));
    158     mTexture2DArrayZero.set(new Texture2DArray(mRenderer, 0));
    159 
    160     for (unsigned int textureUnit = 0; textureUnit < ArraySize(mState.samplers); textureUnit++)
    161     {
    162         mState.samplers[textureUnit] = 0;
    163     }
    164 
    165     mState.activeSampler = 0;
    166     bindVertexArray(0);
    167     bindArrayBuffer(0);
    168     bindElementArrayBuffer(0);
    169     bindTextureCubeMap(0);
    170     bindTexture2D(0);
    171     bindReadFramebuffer(0);
    172     bindDrawFramebuffer(0);
    173     bindRenderbuffer(0);
    174 
    175     mState.activeQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
    176     mState.activeQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
    177     mState.activeQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);
    178 
    179     bindGenericUniformBuffer(0);
    180     for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
    181     {
    182         bindIndexedUniformBuffer(0, i, 0, -1);
    183     }
    184 
    185     bindGenericTransformFeedbackBuffer(0);
    186     for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
    187     {
    188         bindIndexedTransformFeedbackBuffer(0, i, 0, -1);
    189     }
    190 
    191     bindCopyReadBuffer(0);
    192     bindCopyWriteBuffer(0);
    193     bindPixelPackBuffer(0);
    194     bindPixelUnpackBuffer(0);
    195 
    196     // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
    197     // In the initial state, a default transform feedback object is bound and treated as
    198     // a transform feedback object with a name of zero. That object is bound any time
    199     // BindTransformFeedback is called with id of zero
    200     mTransformFeedbackZero.set(new TransformFeedback(0));
    201     bindTransformFeedback(0);
    202 
    203     mState.currentProgram = 0;
    204     mCurrentProgramBinary.set(NULL);
    205 
    206     mCombinedExtensionsString = NULL;
    207     mRendererString = NULL;
    208 
    209     mInvalidEnum = false;
    210     mInvalidValue = false;
    211     mInvalidOperation = false;
    212     mOutOfMemory = false;
    213     mInvalidFramebufferOperation = false;
    214 
    215     mHasBeenCurrent = false;
    216     mContextLost = false;
    217     mResetStatus = GL_NO_ERROR;
    218     mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
    219     mRobustAccess = robustAccess;
    220 
    221     mSupportsBGRATextures = false;
    222     mSupportsDXT1Textures = false;
    223     mSupportsDXT3Textures = false;
    224     mSupportsDXT5Textures = false;
    225     mSupportsEventQueries = false;
    226     mSupportsOcclusionQueries = false;
    227     mNumCompressedTextureFormats = 0;
    228 }
    229 
    230 Context::~Context()
    231 {
    232     if (mState.currentProgram != 0)
    233     {
    234         Program *programObject = mResourceManager->getProgram(mState.currentProgram);
    235         if (programObject)
    236         {
    237             programObject->release();
    238         }
    239         mState.currentProgram = 0;
    240     }
    241     mCurrentProgramBinary.set(NULL);
    242 
    243     while (!mFramebufferMap.empty())
    244     {
    245         deleteFramebuffer(mFramebufferMap.begin()->first);
    246     }
    247 
    248     while (!mFenceNVMap.empty())
    249     {
    250         deleteFenceNV(mFenceNVMap.begin()->first);
    251     }
    252 
    253     while (!mQueryMap.empty())
    254     {
    255         deleteQuery(mQueryMap.begin()->first);
    256     }
    257 
    258     while (!mVertexArrayMap.empty())
    259     {
    260         deleteVertexArray(mVertexArrayMap.begin()->first);
    261     }
    262 
    263     mTransformFeedbackZero.set(NULL);
    264     while (!mTransformFeedbackMap.empty())
    265     {
    266         deleteTransformFeedback(mTransformFeedbackMap.begin()->first);
    267     }
    268 
    269     for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
    270     {
    271         for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
    272         {
    273             mState.samplerTexture[type][sampler].set(NULL);
    274         }
    275     }
    276 
    277     for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
    278     {
    279         mIncompleteTextures[type].set(NULL);
    280     }
    281 
    282     const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
    283     for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
    284     {
    285         mState.vertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
    286     }
    287 
    288     mState.arrayBuffer.set(NULL);
    289     mState.renderbuffer.set(NULL);
    290 
    291     mState.transformFeedback.set(NULL);
    292 
    293     mTexture2DZero.set(NULL);
    294     mTextureCubeMapZero.set(NULL);
    295     mTexture3DZero.set(NULL);
    296     mTexture2DArrayZero.set(NULL);
    297 
    298     for (State::ActiveQueryMap::iterator i = mState.activeQueries.begin(); i != mState.activeQueries.end(); i++)
    299     {
    300         i->second.set(NULL);
    301     }
    302 
    303     mState.genericUniformBuffer.set(NULL);
    304     for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
    305     {
    306         mState.uniformBuffers[i].set(NULL);
    307     }
    308 
    309     mState.genericTransformFeedbackBuffer.set(NULL);
    310     for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
    311     {
    312         mState.transformFeedbackBuffers[i].set(NULL);
    313     }
    314 
    315     mState.copyReadBuffer.set(NULL);
    316     mState.copyWriteBuffer.set(NULL);
    317 
    318     mState.pack.pixelBuffer.set(NULL);
    319     mState.unpack.pixelBuffer.set(NULL);
    320 
    321     mResourceManager->release();
    322 }
    323 
    324 void Context::makeCurrent(egl::Surface *surface)
    325 {
    326     if (!mHasBeenCurrent)
    327     {
    328         mMajorShaderModel = mRenderer->getMajorShaderModel();
    329         mMaximumPointSize = mRenderer->getMaxPointSize();
    330         mSupportsVertexTexture = mRenderer->getVertexTextureSupport();
    331         mSupportsNonPower2Texture = mRenderer->getNonPower2TextureSupport();
    332         mSupportsInstancing = mRenderer->getInstancingSupport();
    333 
    334         mMaxViewportDimension = mRenderer->getMaxViewportDimension();
    335         mMax2DTextureDimension = std::min(std::min(mRenderer->getMaxTextureWidth(), mRenderer->getMaxTextureHeight()),
    336                                           (int)gl::IMPLEMENTATION_MAX_2D_TEXTURE_SIZE);
    337         mMaxCubeTextureDimension = std::min(mMax2DTextureDimension, (int)gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE);
    338         mMax3DTextureDimension = std::min(std::min(mMax2DTextureDimension, mRenderer->getMaxTextureDepth()),
    339                                           (int)gl::IMPLEMENTATION_MAX_3D_TEXTURE_SIZE);
    340         mMax2DArrayTextureLayers = mRenderer->getMaxTextureArrayLayers();
    341         mMaxRenderbufferDimension = mMax2DTextureDimension;
    342         mMax2DTextureLevel = log2(mMax2DTextureDimension) + 1;
    343         mMaxCubeTextureLevel = log2(mMaxCubeTextureDimension) + 1;
    344         mMax3DTextureLevel = log2(mMax3DTextureDimension) + 1;
    345         mMax2DArrayTextureLevel = log2(mMax2DTextureDimension) + 1;
    346         mMaxTextureAnisotropy = mRenderer->getTextureMaxAnisotropy();
    347         TRACE("Max2DTextureDimension=%d, MaxCubeTextureDimension=%d, Max3DTextureDimension=%d, Max2DArrayTextureLayers = %d, "
    348               "Max2DTextureLevel=%d, MaxCubeTextureLevel=%d, Max3DTextureLevel=%d, Max2DArrayTextureLevel=%d, "
    349               "MaxRenderbufferDimension=%d, MaxTextureAnisotropy=%f",
    350               mMax2DTextureDimension, mMaxCubeTextureDimension, mMax3DTextureDimension, mMax2DArrayTextureLayers,
    351               mMax2DTextureLevel, mMaxCubeTextureLevel, mMax3DTextureLevel, mMax2DArrayTextureLevel,
    352               mMaxRenderbufferDimension, mMaxTextureAnisotropy);
    353 
    354         mSupportsEventQueries = mRenderer->getEventQuerySupport();
    355         mSupportsOcclusionQueries = mRenderer->getOcclusionQuerySupport();
    356         mSupportsBGRATextures = mRenderer->getBGRATextureSupport();
    357         mSupportsDXT1Textures = mRenderer->getDXT1TextureSupport();
    358         mSupportsDXT3Textures = mRenderer->getDXT3TextureSupport();
    359         mSupportsDXT5Textures = mRenderer->getDXT5TextureSupport();
    360         mSupportsFloat32Textures = mRenderer->getFloat32TextureSupport();
    361         mSupportsFloat32LinearFilter = mRenderer->getFloat32TextureFilteringSupport();
    362         mSupportsFloat32RenderableTextures = mRenderer->getFloat32TextureRenderingSupport();
    363         mSupportsFloat16Textures = mRenderer->getFloat16TextureSupport();
    364         mSupportsFloat16LinearFilter = mRenderer->getFloat16TextureFilteringSupport();
    365         mSupportsFloat16RenderableTextures = mRenderer->getFloat16TextureRenderingSupport();
    366         mSupportsLuminanceTextures = mRenderer->getLuminanceTextureSupport();
    367         mSupportsLuminanceAlphaTextures = mRenderer->getLuminanceAlphaTextureSupport();
    368         mSupportsRGTextures = mRenderer->getRGTextureSupport();
    369         mSupportsDepthTextures = mRenderer->getDepthTextureSupport();
    370         mSupportsTextureFilterAnisotropy = mRenderer->getTextureFilterAnisotropySupport();
    371         mSupports32bitIndices = mRenderer->get32BitIndexSupport();
    372         mSupportsPBOs = mRenderer->getPBOSupport();
    373 
    374         mNumCompressedTextureFormats = 0;
    375         if (supportsDXT1Textures())
    376         {
    377             mNumCompressedTextureFormats += 2;
    378         }
    379         if (supportsDXT3Textures())
    380         {
    381             mNumCompressedTextureFormats += 1;
    382         }
    383         if (supportsDXT5Textures())
    384         {
    385             mNumCompressedTextureFormats += 1;
    386         }
    387 
    388         initExtensionString();
    389         initRendererString();
    390 
    391         mState.viewport.x = 0;
    392         mState.viewport.y = 0;
    393         mState.viewport.width = surface->getWidth();
    394         mState.viewport.height = surface->getHeight();
    395 
    396         mState.scissor.x = 0;
    397         mState.scissor.y = 0;
    398         mState.scissor.width = surface->getWidth();
    399         mState.scissor.height = surface->getHeight();
    400 
    401         mHasBeenCurrent = true;
    402     }
    403 
    404     // Wrap the existing swapchain resources into GL objects and assign them to the '0' names
    405     rx::SwapChain *swapchain = surface->getSwapChain();
    406 
    407     Colorbuffer *colorbufferZero = new Colorbuffer(mRenderer, swapchain);
    408     DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(mRenderer, swapchain);
    409     Framebuffer *framebufferZero = new DefaultFramebuffer(mRenderer, colorbufferZero, depthStencilbufferZero);
    410 
    411     setFramebufferZero(framebufferZero);
    412 
    413     // Store the current client version in the renderer
    414     mRenderer->setCurrentClientVersion(mClientVersion);
    415 }
    416 
    417 // NOTE: this function should not assume that this context is current!
    418 void Context::markContextLost()
    419 {
    420     if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
    421         mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
    422     mContextLost = true;
    423 }
    424 
    425 bool Context::isContextLost()
    426 {
    427     return mContextLost;
    428 }
    429 
    430 void Context::setCap(GLenum cap, bool enabled)
    431 {
    432     switch (cap)
    433     {
    434       case GL_CULL_FACE:                     setCullFace(enabled);              break;
    435       case GL_POLYGON_OFFSET_FILL:           setPolygonOffsetFill(enabled);     break;
    436       case GL_SAMPLE_ALPHA_TO_COVERAGE:      setSampleAlphaToCoverage(enabled); break;
    437       case GL_SAMPLE_COVERAGE:               setSampleCoverage(enabled);        break;
    438       case GL_SCISSOR_TEST:                  setScissorTest(enabled);           break;
    439       case GL_STENCIL_TEST:                  setStencilTest(enabled);           break;
    440       case GL_DEPTH_TEST:                    setDepthTest(enabled);             break;
    441       case GL_BLEND:                         setBlend(enabled);                 break;
    442       case GL_DITHER:                        setDither(enabled);                break;
    443       case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED();                   break;
    444       case GL_RASTERIZER_DISCARD:            setRasterizerDiscard(enabled);     break;
    445       default:                               UNREACHABLE();
    446     }
    447 }
    448 
    449 bool Context::getCap(GLenum cap)
    450 {
    451     switch (cap)
    452     {
    453       case GL_CULL_FACE:                     return isCullFaceEnabled();
    454       case GL_POLYGON_OFFSET_FILL:           return isPolygonOffsetFillEnabled();
    455       case GL_SAMPLE_ALPHA_TO_COVERAGE:      return isSampleAlphaToCoverageEnabled();
    456       case GL_SAMPLE_COVERAGE:               return isSampleCoverageEnabled();
    457       case GL_SCISSOR_TEST:                  return isScissorTestEnabled();
    458       case GL_STENCIL_TEST:                  return isStencilTestEnabled();
    459       case GL_DEPTH_TEST:                    return isDepthTestEnabled();
    460       case GL_BLEND:                         return isBlendEnabled();
    461       case GL_DITHER:                        return isDitherEnabled();
    462       case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); return false;
    463       case GL_RASTERIZER_DISCARD:            return isRasterizerDiscardEnabled();
    464       default:                               UNREACHABLE(); return false;
    465     }
    466 }
    467 
    468 void Context::setClearColor(float red, float green, float blue, float alpha)
    469 {
    470     mState.colorClearValue.red = red;
    471     mState.colorClearValue.green = green;
    472     mState.colorClearValue.blue = blue;
    473     mState.colorClearValue.alpha = alpha;
    474 }
    475 
    476 void Context::setClearDepth(float depth)
    477 {
    478     mState.depthClearValue = depth;
    479 }
    480 
    481 void Context::setClearStencil(int stencil)
    482 {
    483     mState.stencilClearValue = stencil;
    484 }
    485 
    486 void Context::setRasterizerDiscard(bool enabled)
    487 {
    488     mState.rasterizer.rasterizerDiscard = enabled;
    489 }
    490 
    491 bool Context::isRasterizerDiscardEnabled() const
    492 {
    493     return mState.rasterizer.rasterizerDiscard;
    494 }
    495 
    496 void Context::setCullFace(bool enabled)
    497 {
    498     mState.rasterizer.cullFace = enabled;
    499 }
    500 
    501 bool Context::isCullFaceEnabled() const
    502 {
    503     return mState.rasterizer.cullFace;
    504 }
    505 
    506 void Context::setCullMode(GLenum mode)
    507 {
    508     mState.rasterizer.cullMode = mode;
    509 }
    510 
    511 void Context::setFrontFace(GLenum front)
    512 {
    513     mState.rasterizer.frontFace = front;
    514 }
    515 
    516 void Context::setDepthTest(bool enabled)
    517 {
    518     mState.depthStencil.depthTest = enabled;
    519 }
    520 
    521 bool Context::isDepthTestEnabled() const
    522 {
    523     return mState.depthStencil.depthTest;
    524 }
    525 
    526 void Context::setDepthFunc(GLenum depthFunc)
    527 {
    528      mState.depthStencil.depthFunc = depthFunc;
    529 }
    530 
    531 void Context::setDepthRange(float zNear, float zFar)
    532 {
    533     mState.zNear = zNear;
    534     mState.zFar = zFar;
    535 }
    536 
    537 void Context::setBlend(bool enabled)
    538 {
    539     mState.blend.blend = enabled;
    540 }
    541 
    542 bool Context::isBlendEnabled() const
    543 {
    544     return mState.blend.blend;
    545 }
    546 
    547 void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
    548 {
    549     mState.blend.sourceBlendRGB = sourceRGB;
    550     mState.blend.destBlendRGB = destRGB;
    551     mState.blend.sourceBlendAlpha = sourceAlpha;
    552     mState.blend.destBlendAlpha = destAlpha;
    553 }
    554 
    555 void Context::setBlendColor(float red, float green, float blue, float alpha)
    556 {
    557     mState.blendColor.red = red;
    558     mState.blendColor.green = green;
    559     mState.blendColor.blue = blue;
    560     mState.blendColor.alpha = alpha;
    561 }
    562 
    563 void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
    564 {
    565     mState.blend.blendEquationRGB = rgbEquation;
    566     mState.blend.blendEquationAlpha = alphaEquation;
    567 }
    568 
    569 void Context::setStencilTest(bool enabled)
    570 {
    571     mState.depthStencil.stencilTest = enabled;
    572 }
    573 
    574 bool Context::isStencilTestEnabled() const
    575 {
    576     return mState.depthStencil.stencilTest;
    577 }
    578 
    579 void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
    580 {
    581     mState.depthStencil.stencilFunc = stencilFunc;
    582     mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
    583     mState.depthStencil.stencilMask = stencilMask;
    584 }
    585 
    586 void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
    587 {
    588     mState.depthStencil.stencilBackFunc = stencilBackFunc;
    589     mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
    590     mState.depthStencil.stencilBackMask = stencilBackMask;
    591 }
    592 
    593 void Context::setStencilWritemask(GLuint stencilWritemask)
    594 {
    595     mState.depthStencil.stencilWritemask = stencilWritemask;
    596 }
    597 
    598 void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
    599 {
    600     mState.depthStencil.stencilBackWritemask = stencilBackWritemask;
    601 }
    602 
    603 void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
    604 {
    605     mState.depthStencil.stencilFail = stencilFail;
    606     mState.depthStencil.stencilPassDepthFail = stencilPassDepthFail;
    607     mState.depthStencil.stencilPassDepthPass = stencilPassDepthPass;
    608 }
    609 
    610 void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
    611 {
    612     mState.depthStencil.stencilBackFail = stencilBackFail;
    613     mState.depthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
    614     mState.depthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
    615 }
    616 
    617 void Context::setPolygonOffsetFill(bool enabled)
    618 {
    619      mState.rasterizer.polygonOffsetFill = enabled;
    620 }
    621 
    622 bool Context::isPolygonOffsetFillEnabled() const
    623 {
    624     return mState.rasterizer.polygonOffsetFill;
    625 }
    626 
    627 void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
    628 {
    629     // An application can pass NaN values here, so handle this gracefully
    630     mState.rasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
    631     mState.rasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
    632 }
    633 
    634 void Context::setSampleAlphaToCoverage(bool enabled)
    635 {
    636     mState.blend.sampleAlphaToCoverage = enabled;
    637 }
    638 
    639 bool Context::isSampleAlphaToCoverageEnabled() const
    640 {
    641     return mState.blend.sampleAlphaToCoverage;
    642 }
    643 
    644 void Context::setSampleCoverage(bool enabled)
    645 {
    646     mState.sampleCoverage = enabled;
    647 }
    648 
    649 bool Context::isSampleCoverageEnabled() const
    650 {
    651     return mState.sampleCoverage;
    652 }
    653 
    654 void Context::setSampleCoverageParams(GLclampf value, bool invert)
    655 {
    656     mState.sampleCoverageValue = value;
    657     mState.sampleCoverageInvert = invert;
    658 }
    659 
    660 void Context::setScissorTest(bool enabled)
    661 {
    662     mState.scissorTest = enabled;
    663 }
    664 
    665 bool Context::isScissorTestEnabled() const
    666 {
    667     return mState.scissorTest;
    668 }
    669 
    670 void Context::setDither(bool enabled)
    671 {
    672     mState.blend.dither = enabled;
    673 }
    674 
    675 bool Context::isDitherEnabled() const
    676 {
    677     return mState.blend.dither;
    678 }
    679 
    680 void Context::setLineWidth(GLfloat width)
    681 {
    682     mState.lineWidth = width;
    683 }
    684 
    685 void Context::setGenerateMipmapHint(GLenum hint)
    686 {
    687     mState.generateMipmapHint = hint;
    688 }
    689 
    690 void Context::setFragmentShaderDerivativeHint(GLenum hint)
    691 {
    692     mState.fragmentShaderDerivativeHint = hint;
    693     // TODO: Propagate the hint to shader translator so we can write
    694     // ddx, ddx_coarse, or ddx_fine depending on the hint.
    695     // Ignore for now. It is valid for implementations to ignore hint.
    696 }
    697 
    698 void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
    699 {
    700     mState.viewport.x = x;
    701     mState.viewport.y = y;
    702     mState.viewport.width = width;
    703     mState.viewport.height = height;
    704 }
    705 
    706 void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
    707 {
    708     mState.scissor.x = x;
    709     mState.scissor.y = y;
    710     mState.scissor.width = width;
    711     mState.scissor.height = height;
    712 }
    713 
    714 void Context::getScissorParams(GLint *x, GLint *y, GLsizei *width, GLsizei *height)
    715 {
    716     *x = mState.scissor.x;
    717     *y = mState.scissor.y;
    718     *width = mState.scissor.width;
    719     *height = mState.scissor.height;
    720 }
    721 
    722 void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
    723 {
    724     mState.blend.colorMaskRed = red;
    725     mState.blend.colorMaskGreen = green;
    726     mState.blend.colorMaskBlue = blue;
    727     mState.blend.colorMaskAlpha = alpha;
    728 }
    729 
    730 void Context::setDepthMask(bool mask)
    731 {
    732     mState.depthStencil.depthMask = mask;
    733 }
    734 
    735 void Context::setActiveSampler(unsigned int active)
    736 {
    737     mState.activeSampler = active;
    738 }
    739 
    740 GLuint Context::getReadFramebufferHandle() const
    741 {
    742     return mState.readFramebuffer;
    743 }
    744 
    745 GLuint Context::getDrawFramebufferHandle() const
    746 {
    747     return mState.drawFramebuffer;
    748 }
    749 
    750 GLuint Context::getRenderbufferHandle() const
    751 {
    752     return mState.renderbuffer.id();
    753 }
    754 
    755 GLuint Context::getVertexArrayHandle() const
    756 {
    757     return mState.vertexArray;
    758 }
    759 
    760 GLuint Context::getSamplerHandle(GLuint textureUnit) const
    761 {
    762     ASSERT(textureUnit < ArraySize(mState.samplers));
    763     return mState.samplers[textureUnit];
    764 }
    765 
    766 unsigned int Context::getActiveSampler() const
    767 {
    768     return mState.activeSampler;
    769 }
    770 
    771 GLuint Context::getArrayBufferHandle() const
    772 {
    773     return mState.arrayBuffer.id();
    774 }
    775 
    776 bool Context::isQueryActive() const
    777 {
    778     for (State::ActiveQueryMap::const_iterator i = mState.activeQueries.begin();
    779          i != mState.activeQueries.end(); i++)
    780     {
    781         if (i->second.get() != NULL)
    782         {
    783             return true;
    784         }
    785     }
    786 
    787     return false;
    788 }
    789 
    790 const Query *Context::getActiveQuery(GLenum target) const
    791 {
    792     // All query types should already exist in the activeQueries map
    793     ASSERT(mState.activeQueries.find(target) != mState.activeQueries.end());
    794 
    795     return mState.activeQueries.at(target).get();
    796 }
    797 
    798 GLuint Context::getActiveQueryId(GLenum target) const
    799 {
    800     const Query *query = getActiveQuery(target);
    801     return (query ? query->id() : 0u);
    802 }
    803 
    804 void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
    805 {
    806     getCurrentVertexArray()->enableAttribute(attribNum, enabled);
    807 }
    808 
    809 const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) const
    810 {
    811     return getCurrentVertexArray()->getVertexAttribute(attribNum);
    812 }
    813 
    814 const VertexAttribCurrentValueData &Context::getVertexAttribCurrentValue(unsigned int attribNum) const
    815 {
    816     ASSERT(attribNum < MAX_VERTEX_ATTRIBS);
    817     return mState.vertexAttribCurrentValues[attribNum];
    818 }
    819 
    820 void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
    821                                    bool pureInteger, GLsizei stride, const void *pointer)
    822 {
    823     getCurrentVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
    824 }
    825 
    826 const void *Context::getVertexAttribPointer(unsigned int attribNum) const
    827 {
    828     return getCurrentVertexArray()->getVertexAttribute(attribNum).mPointer;
    829 }
    830 
    831 void Context::setPackAlignment(GLint alignment)
    832 {
    833     mState.pack.alignment = alignment;
    834 }
    835 
    836 GLint Context::getPackAlignment() const
    837 {
    838     return mState.pack.alignment;
    839 }
    840 
    841 void Context::setUnpackAlignment(GLint alignment)
    842 {
    843     mState.unpack.alignment = alignment;
    844 }
    845 
    846 GLint Context::getUnpackAlignment() const
    847 {
    848     return mState.unpack.alignment;
    849 }
    850 
    851 void Context::setPackReverseRowOrder(bool reverseRowOrder)
    852 {
    853     mState.pack.reverseRowOrder = reverseRowOrder;
    854 }
    855 
    856 bool Context::getPackReverseRowOrder() const
    857 {
    858     return mState.pack.reverseRowOrder;
    859 }
    860 
    861 const PixelUnpackState &Context::getUnpackState() const
    862 {
    863     return mState.unpack;
    864 }
    865 
    866 const PixelPackState &Context::getPackState() const
    867 {
    868     return mState.pack;
    869 }
    870 
    871 GLuint Context::createBuffer()
    872 {
    873     return mResourceManager->createBuffer();
    874 }
    875 
    876 GLuint Context::createProgram()
    877 {
    878     return mResourceManager->createProgram();
    879 }
    880 
    881 GLuint Context::createShader(GLenum type)
    882 {
    883     return mResourceManager->createShader(type);
    884 }
    885 
    886 GLuint Context::createTexture()
    887 {
    888     return mResourceManager->createTexture();
    889 }
    890 
    891 GLuint Context::createRenderbuffer()
    892 {
    893     return mResourceManager->createRenderbuffer();
    894 }
    895 
    896 GLsync Context::createFenceSync(GLenum condition)
    897 {
    898     GLuint handle = mResourceManager->createFenceSync();
    899 
    900     gl::FenceSync *fenceSync = mResourceManager->getFenceSync(handle);
    901     ASSERT(fenceSync);
    902 
    903     fenceSync->set(condition);
    904 
    905     return reinterpret_cast<GLsync>(handle);
    906 }
    907 
    908 GLuint Context::createVertexArray()
    909 {
    910     GLuint handle = mVertexArrayHandleAllocator.allocate();
    911 
    912     // Although the spec states VAO state is not initialized until the object is bound,
    913     // we create it immediately. The resulting behaviour is transparent to the application,
    914     // since it's not currently possible to access the state until the object is bound.
    915     mVertexArrayMap[handle] = new VertexArray(mRenderer, handle);
    916 
    917     return handle;
    918 }
    919 
    920 GLuint Context::createSampler()
    921 {
    922     return mResourceManager->createSampler();
    923 }
    924 
    925 GLuint Context::createTransformFeedback()
    926 {
    927     GLuint handle = mTransformFeedbackAllocator.allocate();
    928     TransformFeedback *transformFeedback = new TransformFeedback(handle);
    929     transformFeedback->addRef();
    930     mTransformFeedbackMap[handle] = transformFeedback;
    931     return handle;
    932 }
    933 
    934 // Returns an unused framebuffer name
    935 GLuint Context::createFramebuffer()
    936 {
    937     GLuint handle = mFramebufferHandleAllocator.allocate();
    938 
    939     mFramebufferMap[handle] = NULL;
    940 
    941     return handle;
    942 }
    943 
    944 GLuint Context::createFenceNV()
    945 {
    946     GLuint handle = mFenceNVHandleAllocator.allocate();
    947 
    948     mFenceNVMap[handle] = new FenceNV(mRenderer);
    949 
    950     return handle;
    951 }
    952 
    953 // Returns an unused query name
    954 GLuint Context::createQuery()
    955 {
    956     GLuint handle = mQueryHandleAllocator.allocate();
    957 
    958     mQueryMap[handle] = NULL;
    959 
    960     return handle;
    961 }
    962 
    963 void Context::deleteBuffer(GLuint buffer)
    964 {
    965     if (mResourceManager->getBuffer(buffer))
    966     {
    967         detachBuffer(buffer);
    968     }
    969 
    970     mResourceManager->deleteBuffer(buffer);
    971 }
    972 
    973 void Context::deleteShader(GLuint shader)
    974 {
    975     mResourceManager->deleteShader(shader);
    976 }
    977 
    978 void Context::deleteProgram(GLuint program)
    979 {
    980     mResourceManager->deleteProgram(program);
    981 }
    982 
    983 void Context::deleteTexture(GLuint texture)
    984 {
    985     if (mResourceManager->getTexture(texture))
    986     {
    987         detachTexture(texture);
    988     }
    989 
    990     mResourceManager->deleteTexture(texture);
    991 }
    992 
    993 void Context::deleteRenderbuffer(GLuint renderbuffer)
    994 {
    995     if (mResourceManager->getRenderbuffer(renderbuffer))
    996     {
    997         detachRenderbuffer(renderbuffer);
    998     }
    999 
   1000     mResourceManager->deleteRenderbuffer(renderbuffer);
   1001 }
   1002 
   1003 void Context::deleteFenceSync(GLsync fenceSync)
   1004 {
   1005     // The spec specifies the underlying Fence object is not deleted until all current
   1006     // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
   1007     // and since our API is currently designed for being called from a single thread, we can delete
   1008     // the fence immediately.
   1009     mResourceManager->deleteFenceSync(reinterpret_cast<GLuint>(fenceSync));
   1010 }
   1011 
   1012 void Context::deleteVertexArray(GLuint vertexArray)
   1013 {
   1014     auto vertexArrayObject = mVertexArrayMap.find(vertexArray);
   1015 
   1016     if (vertexArrayObject != mVertexArrayMap.end())
   1017     {
   1018         detachVertexArray(vertexArray);
   1019 
   1020         mVertexArrayHandleAllocator.release(vertexArrayObject->first);
   1021         delete vertexArrayObject->second;
   1022         mVertexArrayMap.erase(vertexArrayObject);
   1023     }
   1024 }
   1025 
   1026 void Context::deleteSampler(GLuint sampler)
   1027 {
   1028     if (mResourceManager->getSampler(sampler))
   1029     {
   1030         detachSampler(sampler);
   1031     }
   1032 
   1033     mResourceManager->deleteSampler(sampler);
   1034 }
   1035 
   1036 void Context::deleteTransformFeedback(GLuint transformFeedback)
   1037 {
   1038     TransformFeedbackMap::const_iterator iter = mTransformFeedbackMap.find(transformFeedback);
   1039     if (iter != mTransformFeedbackMap.end())
   1040     {
   1041         detachTransformFeedback(transformFeedback);
   1042         mTransformFeedbackAllocator.release(transformFeedback);
   1043         iter->second->release();
   1044         mTransformFeedbackMap.erase(iter);
   1045     }
   1046 }
   1047 
   1048 void Context::deleteFramebuffer(GLuint framebuffer)
   1049 {
   1050     FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
   1051 
   1052     if (framebufferObject != mFramebufferMap.end())
   1053     {
   1054         detachFramebuffer(framebuffer);
   1055 
   1056         mFramebufferHandleAllocator.release(framebufferObject->first);
   1057         delete framebufferObject->second;
   1058         mFramebufferMap.erase(framebufferObject);
   1059     }
   1060 }
   1061 
   1062 void Context::deleteFenceNV(GLuint fence)
   1063 {
   1064     FenceNVMap::iterator fenceObject = mFenceNVMap.find(fence);
   1065 
   1066     if (fenceObject != mFenceNVMap.end())
   1067     {
   1068         mFenceNVHandleAllocator.release(fenceObject->first);
   1069         delete fenceObject->second;
   1070         mFenceNVMap.erase(fenceObject);
   1071     }
   1072 }
   1073 
   1074 void Context::deleteQuery(GLuint query)
   1075 {
   1076     QueryMap::iterator queryObject = mQueryMap.find(query);
   1077     if (queryObject != mQueryMap.end())
   1078     {
   1079         mQueryHandleAllocator.release(queryObject->first);
   1080         if (queryObject->second)
   1081         {
   1082             queryObject->second->release();
   1083         }
   1084         mQueryMap.erase(queryObject);
   1085     }
   1086 }
   1087 
   1088 Buffer *Context::getBuffer(GLuint handle)
   1089 {
   1090     return mResourceManager->getBuffer(handle);
   1091 }
   1092 
   1093 Shader *Context::getShader(GLuint handle) const
   1094 {
   1095     return mResourceManager->getShader(handle);
   1096 }
   1097 
   1098 Program *Context::getProgram(GLuint handle) const
   1099 {
   1100     return mResourceManager->getProgram(handle);
   1101 }
   1102 
   1103 Texture *Context::getTexture(GLuint handle)
   1104 {
   1105     return mResourceManager->getTexture(handle);
   1106 }
   1107 
   1108 FramebufferAttachment *Context::getRenderbuffer(GLuint handle)
   1109 {
   1110     return mResourceManager->getRenderbuffer(handle);
   1111 }
   1112 
   1113 FenceSync *Context::getFenceSync(GLsync handle) const
   1114 {
   1115     return mResourceManager->getFenceSync(reinterpret_cast<GLuint>(handle));
   1116 }
   1117 
   1118 VertexArray *Context::getVertexArray(GLuint handle) const
   1119 {
   1120     auto vertexArray = mVertexArrayMap.find(handle);
   1121 
   1122     if (vertexArray == mVertexArrayMap.end())
   1123     {
   1124         return NULL;
   1125     }
   1126     else
   1127     {
   1128         return vertexArray->second;
   1129     }
   1130 }
   1131 
   1132 Sampler *Context::getSampler(GLuint handle) const
   1133 {
   1134     return mResourceManager->getSampler(handle);
   1135 }
   1136 
   1137 TransformFeedback *Context::getTransformFeedback(GLuint handle) const
   1138 {
   1139     if (handle == 0)
   1140     {
   1141         return mTransformFeedbackZero.get();
   1142     }
   1143     else
   1144     {
   1145         TransformFeedbackMap::const_iterator iter = mTransformFeedbackMap.find(handle);
   1146         return (iter != mTransformFeedbackMap.end()) ? iter->second : NULL;
   1147     }
   1148 }
   1149 
   1150 Framebuffer *Context::getReadFramebuffer()
   1151 {
   1152     return getFramebuffer(mState.readFramebuffer);
   1153 }
   1154 
   1155 Framebuffer *Context::getDrawFramebuffer()
   1156 {
   1157     return mBoundDrawFramebuffer;
   1158 }
   1159 
   1160 VertexArray *Context::getCurrentVertexArray() const
   1161 {
   1162     VertexArray *vao = getVertexArray(mState.vertexArray);
   1163     ASSERT(vao != NULL);
   1164     return vao;
   1165 }
   1166 
   1167 TransformFeedback *Context::getCurrentTransformFeedback() const
   1168 {
   1169     return mState.transformFeedback.get();
   1170 }
   1171 
   1172 bool Context::isSampler(GLuint samplerName) const
   1173 {
   1174     return mResourceManager->isSampler(samplerName);
   1175 }
   1176 
   1177 void Context::bindArrayBuffer(unsigned int buffer)
   1178 {
   1179     mResourceManager->checkBufferAllocation(buffer);
   1180 
   1181     mState.arrayBuffer.set(getBuffer(buffer));
   1182 }
   1183 
   1184 void Context::bindElementArrayBuffer(unsigned int buffer)
   1185 {
   1186     mResourceManager->checkBufferAllocation(buffer);
   1187 
   1188     getCurrentVertexArray()->setElementArrayBuffer(getBuffer(buffer));
   1189 }
   1190 
   1191 void Context::bindTexture2D(GLuint texture)
   1192 {
   1193     mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
   1194 
   1195     mState.samplerTexture[TEXTURE_2D][mState.activeSampler].set(getTexture(texture));
   1196 }
   1197 
   1198 void Context::bindTextureCubeMap(GLuint texture)
   1199 {
   1200     mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
   1201 
   1202     mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].set(getTexture(texture));
   1203 }
   1204 
   1205 void Context::bindTexture3D(GLuint texture)
   1206 {
   1207     mResourceManager->checkTextureAllocation(texture, TEXTURE_3D);
   1208 
   1209     mState.samplerTexture[TEXTURE_3D][mState.activeSampler].set(getTexture(texture));
   1210 }
   1211 
   1212 void Context::bindTexture2DArray(GLuint texture)
   1213 {
   1214     mResourceManager->checkTextureAllocation(texture, TEXTURE_2D_ARRAY);
   1215 
   1216     mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler].set(getTexture(texture));
   1217 }
   1218 
   1219 void Context::bindReadFramebuffer(GLuint framebuffer)
   1220 {
   1221     if (!getFramebuffer(framebuffer))
   1222     {
   1223         mFramebufferMap[framebuffer] = new Framebuffer(mRenderer);
   1224     }
   1225 
   1226     mState.readFramebuffer = framebuffer;
   1227 }
   1228 
   1229 void Context::bindDrawFramebuffer(GLuint framebuffer)
   1230 {
   1231     if (!getFramebuffer(framebuffer))
   1232     {
   1233         mFramebufferMap[framebuffer] = new Framebuffer(mRenderer);
   1234     }
   1235 
   1236     mState.drawFramebuffer = framebuffer;
   1237 
   1238     mBoundDrawFramebuffer = getFramebuffer(framebuffer);
   1239 }
   1240 
   1241 void Context::bindRenderbuffer(GLuint renderbuffer)
   1242 {
   1243     mResourceManager->checkRenderbufferAllocation(renderbuffer);
   1244 
   1245     mState.renderbuffer.set(getRenderbuffer(renderbuffer));
   1246 }
   1247 
   1248 void Context::bindVertexArray(GLuint vertexArray)
   1249 {
   1250     if (!getVertexArray(vertexArray))
   1251     {
   1252         mVertexArrayMap[vertexArray] = new VertexArray(mRenderer, vertexArray);
   1253     }
   1254 
   1255     mState.vertexArray = vertexArray;
   1256 }
   1257 
   1258 void Context::bindSampler(GLuint textureUnit, GLuint sampler)
   1259 {
   1260     ASSERT(textureUnit < ArraySize(mState.samplers));
   1261     mResourceManager->checkSamplerAllocation(sampler);
   1262 
   1263     mState.samplers[textureUnit] = sampler;
   1264 }
   1265 
   1266 void Context::bindGenericUniformBuffer(GLuint buffer)
   1267 {
   1268     mResourceManager->checkBufferAllocation(buffer);
   1269 
   1270     mState.genericUniformBuffer.set(getBuffer(buffer));
   1271 }
   1272 
   1273 void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
   1274 {
   1275     mResourceManager->checkBufferAllocation(buffer);
   1276 
   1277     mState.uniformBuffers[index].set(getBuffer(buffer), offset, size);
   1278 }
   1279 
   1280 void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
   1281 {
   1282     mResourceManager->checkBufferAllocation(buffer);
   1283 
   1284     mState.genericTransformFeedbackBuffer.set(getBuffer(buffer));
   1285 }
   1286 
   1287 void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
   1288 {
   1289     mResourceManager->checkBufferAllocation(buffer);
   1290 
   1291     mState.transformFeedbackBuffers[index].set(getBuffer(buffer), offset, size);
   1292 }
   1293 
   1294 void Context::bindCopyReadBuffer(GLuint buffer)
   1295 {
   1296     mResourceManager->checkBufferAllocation(buffer);
   1297 
   1298     mState.copyReadBuffer.set(getBuffer(buffer));
   1299 }
   1300 
   1301 void Context::bindCopyWriteBuffer(GLuint buffer)
   1302 {
   1303     mResourceManager->checkBufferAllocation(buffer);
   1304 
   1305     mState.copyWriteBuffer.set(getBuffer(buffer));
   1306 }
   1307 
   1308 void Context::bindPixelPackBuffer(GLuint buffer)
   1309 {
   1310     mResourceManager->checkBufferAllocation(buffer);
   1311 
   1312     mState.pack.pixelBuffer.set(getBuffer(buffer));
   1313 }
   1314 
   1315 void Context::bindPixelUnpackBuffer(GLuint buffer)
   1316 {
   1317     mResourceManager->checkBufferAllocation(buffer);
   1318 
   1319     mState.unpack.pixelBuffer.set(getBuffer(buffer));
   1320 }
   1321 
   1322 void Context::useProgram(GLuint program)
   1323 {
   1324     GLuint priorProgram = mState.currentProgram;
   1325     mState.currentProgram = program;               // Must switch before trying to delete, otherwise it only gets flagged.
   1326 
   1327     if (priorProgram != program)
   1328     {
   1329         Program *newProgram = mResourceManager->getProgram(program);
   1330         Program *oldProgram = mResourceManager->getProgram(priorProgram);
   1331         mCurrentProgramBinary.set(NULL);
   1332 
   1333         if (newProgram)
   1334         {
   1335             newProgram->addRef();
   1336             mCurrentProgramBinary.set(newProgram->getProgramBinary());
   1337         }
   1338 
   1339         if (oldProgram)
   1340         {
   1341             oldProgram->release();
   1342         }
   1343     }
   1344 }
   1345 
   1346 void Context::linkProgram(GLuint program)
   1347 {
   1348     Program *programObject = mResourceManager->getProgram(program);
   1349 
   1350     bool linked = programObject->link();
   1351 
   1352     // if the current program was relinked successfully we
   1353     // need to install the new executables
   1354     if (linked && program == mState.currentProgram)
   1355     {
   1356         mCurrentProgramBinary.set(programObject->getProgramBinary());
   1357     }
   1358 }
   1359 
   1360 void Context::setProgramBinary(GLuint program, const void *binary, GLint length)
   1361 {
   1362     Program *programObject = mResourceManager->getProgram(program);
   1363 
   1364     bool loaded = programObject->setProgramBinary(binary, length);
   1365 
   1366     // if the current program was reloaded successfully we
   1367     // need to install the new executables
   1368     if (loaded && program == mState.currentProgram)
   1369     {
   1370         mCurrentProgramBinary.set(programObject->getProgramBinary());
   1371     }
   1372 
   1373 }
   1374 
   1375 void Context::bindTransformFeedback(GLuint transformFeedback)
   1376 {
   1377     TransformFeedback *transformFeedbackObject = getTransformFeedback(transformFeedback);
   1378     mState.transformFeedback.set(transformFeedbackObject);
   1379 }
   1380 
   1381 void Context::beginQuery(GLenum target, GLuint query)
   1382 {
   1383     Query *queryObject = getQuery(query, true, target);
   1384     ASSERT(queryObject);
   1385 
   1386     // set query as active for specified target
   1387     mState.activeQueries[target].set(queryObject);
   1388 
   1389     // begin query
   1390     queryObject->begin();
   1391 }
   1392 
   1393 void Context::endQuery(GLenum target)
   1394 {
   1395     Query *queryObject = mState.activeQueries[target].get();
   1396     ASSERT(queryObject);
   1397 
   1398     queryObject->end();
   1399 
   1400     mState.activeQueries[target].set(NULL);
   1401 }
   1402 
   1403 void Context::setFramebufferZero(Framebuffer *buffer)
   1404 {
   1405     delete mFramebufferMap[0];
   1406     mFramebufferMap[0] = buffer;
   1407     if (mState.drawFramebuffer == 0)
   1408     {
   1409         mBoundDrawFramebuffer = buffer;
   1410     }
   1411 }
   1412 
   1413 void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
   1414 {
   1415     const bool color = gl::IsColorRenderingSupported(internalformat, this);
   1416     const bool depth = gl::IsDepthRenderingSupported(internalformat, this);
   1417     const bool stencil = gl::IsStencilRenderingSupported(internalformat, this);
   1418 
   1419     RenderbufferStorage *renderbuffer = NULL;
   1420 
   1421     if (color)
   1422     {
   1423         renderbuffer = new gl::Colorbuffer(mRenderer,width, height, internalformat, samples);
   1424     }
   1425     else if (depth && stencil)
   1426     {
   1427         renderbuffer = new gl::DepthStencilbuffer(mRenderer, width, height, samples);
   1428     }
   1429     else if (depth)
   1430     {
   1431         renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples);
   1432     }
   1433     else if (stencil)
   1434     {
   1435         renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples);
   1436     }
   1437     else
   1438     {
   1439         UNREACHABLE();
   1440         return;
   1441     }
   1442 
   1443     FramebufferAttachment *renderbufferObject = mState.renderbuffer.get();
   1444     renderbufferObject->setStorage(renderbuffer);
   1445 }
   1446 
   1447 Framebuffer *Context::getFramebuffer(unsigned int handle) const
   1448 {
   1449     FramebufferMap::const_iterator framebuffer = mFramebufferMap.find(handle);
   1450 
   1451     if (framebuffer == mFramebufferMap.end())
   1452     {
   1453         return NULL;
   1454     }
   1455     else
   1456     {
   1457         return framebuffer->second;
   1458     }
   1459 }
   1460 
   1461 FenceNV *Context::getFenceNV(unsigned int handle)
   1462 {
   1463     FenceNVMap::iterator fence = mFenceNVMap.find(handle);
   1464 
   1465     if (fence == mFenceNVMap.end())
   1466     {
   1467         return NULL;
   1468     }
   1469     else
   1470     {
   1471         return fence->second;
   1472     }
   1473 }
   1474 
   1475 Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
   1476 {
   1477     QueryMap::iterator query = mQueryMap.find(handle);
   1478 
   1479     if (query == mQueryMap.end())
   1480     {
   1481         return NULL;
   1482     }
   1483     else
   1484     {
   1485         if (!query->second && create)
   1486         {
   1487             query->second = new Query(mRenderer, type, handle);
   1488             query->second->addRef();
   1489         }
   1490         return query->second;
   1491     }
   1492 }
   1493 
   1494 Buffer *Context::getTargetBuffer(GLenum target) const
   1495 {
   1496     switch (target)
   1497     {
   1498       case GL_ARRAY_BUFFER:              return mState.arrayBuffer.get();
   1499       case GL_COPY_READ_BUFFER:          return mState.copyReadBuffer.get();
   1500       case GL_COPY_WRITE_BUFFER:         return mState.copyWriteBuffer.get();
   1501       case GL_ELEMENT_ARRAY_BUFFER:      return getCurrentVertexArray()->getElementArrayBuffer();
   1502       case GL_PIXEL_PACK_BUFFER:         return mState.pack.pixelBuffer.get();
   1503       case GL_PIXEL_UNPACK_BUFFER:       return mState.unpack.pixelBuffer.get();
   1504       case GL_TRANSFORM_FEEDBACK_BUFFER: return mState.genericTransformFeedbackBuffer.get();
   1505       case GL_UNIFORM_BUFFER:            return mState.genericUniformBuffer.get();
   1506       default: UNREACHABLE();            return NULL;
   1507     }
   1508 }
   1509 
   1510 Buffer *Context::getArrayBuffer()
   1511 {
   1512     return mState.arrayBuffer.get();
   1513 }
   1514 
   1515 Buffer *Context::getElementArrayBuffer() const
   1516 {
   1517     return getCurrentVertexArray()->getElementArrayBuffer();
   1518 }
   1519 
   1520 ProgramBinary *Context::getCurrentProgramBinary()
   1521 {
   1522     return mCurrentProgramBinary.get();
   1523 }
   1524 
   1525 Texture *Context::getTargetTexture(GLenum target) const
   1526 {
   1527     if (!ValidTextureTarget(this, target))
   1528     {
   1529         return NULL;
   1530     }
   1531 
   1532     switch (target)
   1533     {
   1534       case GL_TEXTURE_2D:       return getTexture2D();
   1535       case GL_TEXTURE_CUBE_MAP: return getTextureCubeMap();
   1536       case GL_TEXTURE_3D:       return getTexture3D();
   1537       case GL_TEXTURE_2D_ARRAY: return getTexture2DArray();
   1538       default:                  return NULL;
   1539     }
   1540 }
   1541 
   1542 GLuint Context::getTargetFramebufferHandle(GLenum target) const
   1543 {
   1544     if (!ValidFramebufferTarget(target))
   1545     {
   1546         return GL_INVALID_INDEX;
   1547     }
   1548 
   1549     if (target == GL_READ_FRAMEBUFFER_ANGLE)
   1550     {
   1551         return mState.readFramebuffer;
   1552     }
   1553     else
   1554     {
   1555         return mState.drawFramebuffer;
   1556     }
   1557 }
   1558 
   1559 Framebuffer *Context::getTargetFramebuffer(GLenum target) const
   1560 {
   1561     GLuint framebufferHandle = getTargetFramebufferHandle(target);
   1562     return (framebufferHandle == GL_INVALID_INDEX ? NULL : getFramebuffer(framebufferHandle));
   1563 }
   1564 
   1565 Texture2D *Context::getTexture2D() const
   1566 {
   1567     return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
   1568 }
   1569 
   1570 TextureCubeMap *Context::getTextureCubeMap() const
   1571 {
   1572     return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
   1573 }
   1574 
   1575 Texture3D *Context::getTexture3D() const
   1576 {
   1577     return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D));
   1578 }
   1579 
   1580 Texture2DArray *Context::getTexture2DArray() const
   1581 {
   1582     return static_cast<Texture2DArray*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_ARRAY));
   1583 }
   1584 
   1585 Buffer *Context::getGenericUniformBuffer()
   1586 {
   1587     return mState.genericUniformBuffer.get();
   1588 }
   1589 
   1590 Buffer *Context::getGenericTransformFeedbackBuffer()
   1591 {
   1592     return mState.genericTransformFeedbackBuffer.get();
   1593 }
   1594 
   1595 Buffer *Context::getCopyReadBuffer()
   1596 {
   1597     return mState.copyReadBuffer.get();
   1598 }
   1599 
   1600 Buffer *Context::getCopyWriteBuffer()
   1601 {
   1602     return mState.copyWriteBuffer.get();
   1603 }
   1604 
   1605 Buffer *Context::getPixelPackBuffer()
   1606 {
   1607     return mState.pack.pixelBuffer.get();
   1608 }
   1609 
   1610 Buffer *Context::getPixelUnpackBuffer()
   1611 {
   1612     return mState.unpack.pixelBuffer.get();
   1613 }
   1614 
   1615 Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const
   1616 {
   1617     GLuint texid = mState.samplerTexture[type][sampler].id();
   1618 
   1619     if (texid == 0)   // Special case: 0 refers to different initial textures based on the target
   1620     {
   1621         switch (type)
   1622         {
   1623           default: UNREACHABLE();
   1624           case TEXTURE_2D:       return mTexture2DZero.get();
   1625           case TEXTURE_CUBE:     return mTextureCubeMapZero.get();
   1626           case TEXTURE_3D:       return mTexture3DZero.get();
   1627           case TEXTURE_2D_ARRAY: return mTexture2DArrayZero.get();
   1628         }
   1629     }
   1630 
   1631     return mState.samplerTexture[type][sampler].get();
   1632 }
   1633 
   1634 void Context::getBooleanv(GLenum pname, GLboolean *params)
   1635 {
   1636     switch (pname)
   1637     {
   1638       case GL_SHADER_COMPILER:           *params = GL_TRUE;                             break;
   1639       case GL_SAMPLE_COVERAGE_INVERT:    *params = mState.sampleCoverageInvert;         break;
   1640       case GL_DEPTH_WRITEMASK:           *params = mState.depthStencil.depthMask;       break;
   1641       case GL_COLOR_WRITEMASK:
   1642         params[0] = mState.blend.colorMaskRed;
   1643         params[1] = mState.blend.colorMaskGreen;
   1644         params[2] = mState.blend.colorMaskBlue;
   1645         params[3] = mState.blend.colorMaskAlpha;
   1646         break;
   1647       case GL_CULL_FACE:                 *params = mState.rasterizer.cullFace;          break;
   1648       case GL_POLYGON_OFFSET_FILL:       *params = mState.rasterizer.polygonOffsetFill; break;
   1649       case GL_SAMPLE_ALPHA_TO_COVERAGE:  *params = mState.blend.sampleAlphaToCoverage;  break;
   1650       case GL_SAMPLE_COVERAGE:           *params = mState.sampleCoverage;               break;
   1651       case GL_SCISSOR_TEST:              *params = mState.scissorTest;                  break;
   1652       case GL_STENCIL_TEST:              *params = mState.depthStencil.stencilTest;     break;
   1653       case GL_DEPTH_TEST:                *params = mState.depthStencil.depthTest;       break;
   1654       case GL_BLEND:                     *params = mState.blend.blend;                  break;
   1655       case GL_DITHER:                    *params = mState.blend.dither;                 break;
   1656       case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE;  break;
   1657       case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isStarted(); break;
   1658       case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused();  break;
   1659       default:
   1660         UNREACHABLE();
   1661         break;
   1662     }
   1663 }
   1664 
   1665 void Context::getFloatv(GLenum pname, GLfloat *params)
   1666 {
   1667     // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
   1668     // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
   1669     // GetIntegerv as its native query function. As it would require conversion in any
   1670     // case, this should make no difference to the calling application.
   1671     switch (pname)
   1672     {
   1673       case GL_LINE_WIDTH:               *params = mState.lineWidth;                         break;
   1674       case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;               break;
   1675       case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;                   break;
   1676       case GL_POLYGON_OFFSET_FACTOR:    *params = mState.rasterizer.polygonOffsetFactor;    break;
   1677       case GL_POLYGON_OFFSET_UNITS:     *params = mState.rasterizer.polygonOffsetUnits;     break;
   1678       case GL_ALIASED_LINE_WIDTH_RANGE:
   1679         params[0] = gl::ALIASED_LINE_WIDTH_RANGE_MIN;
   1680         params[1] = gl::ALIASED_LINE_WIDTH_RANGE_MAX;
   1681         break;
   1682       case GL_ALIASED_POINT_SIZE_RANGE:
   1683         params[0] = gl::ALIASED_POINT_SIZE_RANGE_MIN;
   1684         params[1] = getMaximumPointSize();
   1685         break;
   1686       case GL_DEPTH_RANGE:
   1687         params[0] = mState.zNear;
   1688         params[1] = mState.zFar;
   1689         break;
   1690       case GL_COLOR_CLEAR_VALUE:
   1691         params[0] = mState.colorClearValue.red;
   1692         params[1] = mState.colorClearValue.green;
   1693         params[2] = mState.colorClearValue.blue;
   1694         params[3] = mState.colorClearValue.alpha;
   1695         break;
   1696       case GL_BLEND_COLOR:
   1697         params[0] = mState.blendColor.red;
   1698         params[1] = mState.blendColor.green;
   1699         params[2] = mState.blendColor.blue;
   1700         params[3] = mState.blendColor.alpha;
   1701         break;
   1702       case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
   1703         ASSERT(supportsTextureFilterAnisotropy());
   1704         *params = mMaxTextureAnisotropy;
   1705         break;
   1706       default:
   1707         UNREACHABLE();
   1708         break;
   1709     }
   1710 }
   1711 
   1712 void Context::getIntegerv(GLenum pname, GLint *params)
   1713 {
   1714     if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
   1715     {
   1716         unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
   1717         ASSERT(colorAttachment < mRenderer->getMaxRenderTargets());
   1718         Framebuffer *framebuffer = getDrawFramebuffer();
   1719         *params = framebuffer->getDrawBufferState(colorAttachment);
   1720         return;
   1721     }
   1722 
   1723     // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
   1724     // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
   1725     // GetIntegerv as its native query function. As it would require conversion in any
   1726     // case, this should make no difference to the calling application. You may find it in
   1727     // Context::getFloatv.
   1728     switch (pname)
   1729     {
   1730       case GL_MAX_VERTEX_ATTRIBS:                       *params = gl::MAX_VERTEX_ATTRIBS;                               break;
   1731       case GL_MAX_VERTEX_UNIFORM_VECTORS:               *params = mRenderer->getMaxVertexUniformVectors();              break;
   1732       case GL_MAX_VERTEX_UNIFORM_COMPONENTS:            *params = mRenderer->getMaxVertexUniformVectors() * 4;          break;
   1733       case GL_MAX_VARYING_VECTORS:                      *params = mRenderer->getMaxVaryingVectors();                    break;
   1734       case GL_MAX_VARYING_COMPONENTS:                   *params = mRenderer->getMaxVaryingVectors() * 4;                break;
   1735       case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:         *params = mRenderer->getMaxCombinedTextureImageUnits();         break;
   1736       case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:           *params = mRenderer->getMaxVertexTextureImageUnits();           break;
   1737       case GL_MAX_TEXTURE_IMAGE_UNITS:                  *params = gl::MAX_TEXTURE_IMAGE_UNITS;                          break;
   1738       case GL_MAX_FRAGMENT_UNIFORM_VECTORS:             *params = mRenderer->getMaxFragmentUniformVectors();            break;
   1739       case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:          *params = mRenderer->getMaxFragmentUniformVectors() * 4;        break;
   1740       case GL_MAX_RENDERBUFFER_SIZE:                    *params = getMaximumRenderbufferDimension();                    break;
   1741       case GL_MAX_COLOR_ATTACHMENTS_EXT:                *params = mRenderer->getMaxRenderTargets();                     break;
   1742       case GL_MAX_DRAW_BUFFERS_EXT:                     *params = mRenderer->getMaxRenderTargets();                     break;
   1743       case GL_NUM_SHADER_BINARY_FORMATS:                *params = 0;                                                    break;
   1744       case GL_SHADER_BINARY_FORMATS:                    /* no shader binary formats are supported */                    break;
   1745       case GL_ARRAY_BUFFER_BINDING:                     *params = mState.arrayBuffer.id();                              break;
   1746       case GL_ELEMENT_ARRAY_BUFFER_BINDING:             *params = getCurrentVertexArray()->getElementArrayBufferId();   break;
   1747       //case GL_FRAMEBUFFER_BINDING:                    // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
   1748       case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:           *params = mState.drawFramebuffer;                               break;
   1749       case GL_READ_FRAMEBUFFER_BINDING_ANGLE:           *params = mState.readFramebuffer;                               break;
   1750       case GL_RENDERBUFFER_BINDING:                     *params = mState.renderbuffer.id();                             break;
   1751       case GL_VERTEX_ARRAY_BINDING:                     *params = mState.vertexArray;                                   break;
   1752       case GL_CURRENT_PROGRAM:                          *params = mState.currentProgram;                                break;
   1753       case GL_PACK_ALIGNMENT:                           *params = mState.pack.alignment;                                break;
   1754       case GL_PACK_REVERSE_ROW_ORDER_ANGLE:             *params = mState.pack.reverseRowOrder;                          break;
   1755       case GL_UNPACK_ALIGNMENT:                         *params = mState.unpack.alignment;                              break;
   1756       case GL_GENERATE_MIPMAP_HINT:                     *params = mState.generateMipmapHint;                            break;
   1757       case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:      *params = mState.fragmentShaderDerivativeHint;                  break;
   1758       case GL_ACTIVE_TEXTURE:                           *params = (mState.activeSampler + GL_TEXTURE0);                 break;
   1759       case GL_STENCIL_FUNC:                             *params = mState.depthStencil.stencilFunc;                      break;
   1760       case GL_STENCIL_REF:                              *params = mState.stencilRef;                                    break;
   1761       case GL_STENCIL_VALUE_MASK:                       *params = clampToInt(mState.depthStencil.stencilMask);          break;
   1762       case GL_STENCIL_BACK_FUNC:                        *params = mState.depthStencil.stencilBackFunc;                  break;
   1763       case GL_STENCIL_BACK_REF:                         *params = mState.stencilBackRef;                                break;
   1764       case GL_STENCIL_BACK_VALUE_MASK:                  *params = clampToInt(mState.depthStencil.stencilBackMask);      break;
   1765       case GL_STENCIL_FAIL:                             *params = mState.depthStencil.stencilFail;                      break;
   1766       case GL_STENCIL_PASS_DEPTH_FAIL:                  *params = mState.depthStencil.stencilPassDepthFail;             break;
   1767       case GL_STENCIL_PASS_DEPTH_PASS:                  *params = mState.depthStencil.stencilPassDepthPass;             break;
   1768       case GL_STENCIL_BACK_FAIL:                        *params = mState.depthStencil.stencilBackFail;                  break;
   1769       case GL_STENCIL_BACK_PASS_DEPTH_FAIL:             *params = mState.depthStencil.stencilBackPassDepthFail;         break;
   1770       case GL_STENCIL_BACK_PASS_DEPTH_PASS:             *params = mState.depthStencil.stencilBackPassDepthPass;         break;
   1771       case GL_DEPTH_FUNC:                               *params = mState.depthStencil.depthFunc;                        break;
   1772       case GL_BLEND_SRC_RGB:                            *params = mState.blend.sourceBlendRGB;                          break;
   1773       case GL_BLEND_SRC_ALPHA:                          *params = mState.blend.sourceBlendAlpha;                        break;
   1774       case GL_BLEND_DST_RGB:                            *params = mState.blend.destBlendRGB;                            break;
   1775       case GL_BLEND_DST_ALPHA:                          *params = mState.blend.destBlendAlpha;                          break;
   1776       case GL_BLEND_EQUATION_RGB:                       *params = mState.blend.blendEquationRGB;                        break;
   1777       case GL_BLEND_EQUATION_ALPHA:                     *params = mState.blend.blendEquationAlpha;                      break;
   1778       case GL_STENCIL_WRITEMASK:                        *params = clampToInt(mState.depthStencil.stencilWritemask);     break;
   1779       case GL_STENCIL_BACK_WRITEMASK:                   *params = clampToInt(mState.depthStencil.stencilBackWritemask); break;
   1780       case GL_STENCIL_CLEAR_VALUE:                      *params = mState.stencilClearValue;                             break;
   1781       case GL_SUBPIXEL_BITS:                            *params = 4;                                                    break;
   1782       case GL_MAX_TEXTURE_SIZE:                         *params = getMaximum2DTextureDimension();                       break;
   1783       case GL_MAX_CUBE_MAP_TEXTURE_SIZE:                *params = getMaximumCubeTextureDimension();                     break;
   1784       case GL_MAX_3D_TEXTURE_SIZE:                      *params = getMaximum3DTextureDimension();                       break;
   1785       case GL_MAX_ARRAY_TEXTURE_LAYERS:                 *params = getMaximum2DArrayTextureLayers();                     break;
   1786       case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:          *params = getUniformBufferOffsetAlignment();                    break;
   1787       case GL_MAX_UNIFORM_BUFFER_BINDINGS:              *params = getMaximumCombinedUniformBufferBindings();            break;
   1788       case GL_MAX_VERTEX_UNIFORM_BLOCKS:                *params = mRenderer->getMaxVertexShaderUniformBuffers();        break;
   1789       case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:              *params = mRenderer->getMaxFragmentShaderUniformBuffers();      break;
   1790       case GL_MAX_COMBINED_UNIFORM_BLOCKS:              *params = getMaximumCombinedUniformBufferBindings();            break;
   1791       case GL_MAJOR_VERSION:                            *params = mClientVersion;                                       break;
   1792       case GL_MINOR_VERSION:                            *params = 0;                                                    break;
   1793       case GL_MAX_ELEMENTS_INDICES:                     *params = mRenderer->getMaxRecommendedElementsIndices();        break;
   1794       case GL_MAX_ELEMENTS_VERTICES:                    *params = mRenderer->getMaxRecommendedElementsVertices();       break;
   1795       case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mRenderer->getMaxTransformFeedbackInterleavedComponents(); break;
   1796       case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:       *params = mRenderer->getMaxTransformFeedbackBuffers();               break;
   1797       case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:    *params = mRenderer->getMaxTransformFeedbackSeparateComponents();    break;
   1798       case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
   1799         params[0] = mNumCompressedTextureFormats;
   1800         break;
   1801       case GL_MAX_SAMPLES_ANGLE:
   1802         *params = static_cast<GLint>(getMaxSupportedSamples());
   1803         break;
   1804       case GL_SAMPLE_BUFFERS:
   1805       case GL_SAMPLES:
   1806         {
   1807             gl::Framebuffer *framebuffer = getDrawFramebuffer();
   1808             if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
   1809             {
   1810                 switch (pname)
   1811                 {
   1812                   case GL_SAMPLE_BUFFERS:
   1813                     if (framebuffer->getSamples() != 0)
   1814                     {
   1815                         *params = 1;
   1816                     }
   1817                     else
   1818                     {
   1819                         *params = 0;
   1820                     }
   1821                     break;
   1822                   case GL_SAMPLES:
   1823                     *params = framebuffer->getSamples();
   1824                     break;
   1825                 }
   1826             }
   1827             else
   1828             {
   1829                 *params = 0;
   1830             }
   1831         }
   1832         break;
   1833       case GL_IMPLEMENTATION_COLOR_READ_TYPE:
   1834       case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
   1835         {
   1836             GLenum internalFormat, format, type;
   1837             getCurrentReadFormatType(&internalFormat, &format, &type);
   1838             if (pname == GL_IMPLEMENTATION_COLOR_READ_FORMAT)
   1839                 *params = format;
   1840             else
   1841                 *params = type;
   1842         }
   1843         break;
   1844       case GL_MAX_VIEWPORT_DIMS:
   1845         {
   1846             params[0] = mMaxViewportDimension;
   1847             params[1] = mMaxViewportDimension;
   1848         }
   1849         break;
   1850       case GL_COMPRESSED_TEXTURE_FORMATS:
   1851         {
   1852             if (supportsDXT1Textures())
   1853             {
   1854                 *params++ = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
   1855                 *params++ = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
   1856             }
   1857             if (supportsDXT3Textures())
   1858             {
   1859                 *params++ = GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
   1860             }
   1861             if (supportsDXT5Textures())
   1862             {
   1863                 *params++ = GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
   1864             }
   1865         }
   1866         break;
   1867       case GL_VIEWPORT:
   1868         params[0] = mState.viewport.x;
   1869         params[1] = mState.viewport.y;
   1870         params[2] = mState.viewport.width;
   1871         params[3] = mState.viewport.height;
   1872         break;
   1873       case GL_SCISSOR_BOX:
   1874         params[0] = mState.scissor.x;
   1875         params[1] = mState.scissor.y;
   1876         params[2] = mState.scissor.width;
   1877         params[3] = mState.scissor.height;
   1878         break;
   1879       case GL_CULL_FACE_MODE:                   *params = mState.rasterizer.cullMode;   break;
   1880       case GL_FRONT_FACE:                       *params = mState.rasterizer.frontFace;  break;
   1881       case GL_RED_BITS:
   1882       case GL_GREEN_BITS:
   1883       case GL_BLUE_BITS:
   1884       case GL_ALPHA_BITS:
   1885         {
   1886             gl::Framebuffer *framebuffer = getDrawFramebuffer();
   1887             gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
   1888 
   1889             if (colorbuffer)
   1890             {
   1891                 switch (pname)
   1892                 {
   1893                   case GL_RED_BITS:   *params = colorbuffer->getRedSize();      break;
   1894                   case GL_GREEN_BITS: *params = colorbuffer->getGreenSize();    break;
   1895                   case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();     break;
   1896                   case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize();    break;
   1897                 }
   1898             }
   1899             else
   1900             {
   1901                 *params = 0;
   1902             }
   1903         }
   1904         break;
   1905       case GL_DEPTH_BITS:
   1906         {
   1907             gl::Framebuffer *framebuffer = getDrawFramebuffer();
   1908             gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
   1909 
   1910             if (depthbuffer)
   1911             {
   1912                 *params = depthbuffer->getDepthSize();
   1913             }
   1914             else
   1915             {
   1916                 *params = 0;
   1917             }
   1918         }
   1919         break;
   1920       case GL_STENCIL_BITS:
   1921         {
   1922             gl::Framebuffer *framebuffer = getDrawFramebuffer();
   1923             gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
   1924 
   1925             if (stencilbuffer)
   1926             {
   1927                 *params = stencilbuffer->getStencilSize();
   1928             }
   1929             else
   1930             {
   1931                 *params = 0;
   1932             }
   1933         }
   1934         break;
   1935       case GL_TEXTURE_BINDING_2D:
   1936         ASSERT(mState.activeSampler < mRenderer->getMaxCombinedTextureImageUnits());
   1937         *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].id();
   1938         break;
   1939       case GL_TEXTURE_BINDING_CUBE_MAP:
   1940         ASSERT(mState.activeSampler < mRenderer->getMaxCombinedTextureImageUnits());
   1941         *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].id();
   1942         break;
   1943       case GL_TEXTURE_BINDING_3D:
   1944         ASSERT(mState.activeSampler < mRenderer->getMaxCombinedTextureImageUnits());
   1945         *params = mState.samplerTexture[TEXTURE_3D][mState.activeSampler].id();
   1946         break;
   1947       case GL_TEXTURE_BINDING_2D_ARRAY:
   1948         ASSERT(mState.activeSampler < mRenderer->getMaxCombinedTextureImageUnits());
   1949         *params = mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler].id();
   1950         break;
   1951       case GL_RESET_NOTIFICATION_STRATEGY_EXT:
   1952         *params = mResetStrategy;
   1953         break;
   1954       case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
   1955         *params = 1;
   1956         break;
   1957       case GL_PROGRAM_BINARY_FORMATS_OES:
   1958         *params = GL_PROGRAM_BINARY_ANGLE;
   1959         break;
   1960       case GL_UNIFORM_BUFFER_BINDING:
   1961         *params = mState.genericUniformBuffer.id();
   1962         break;
   1963       case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
   1964         *params = mState.genericTransformFeedbackBuffer.id();
   1965         break;
   1966       case GL_COPY_READ_BUFFER_BINDING:
   1967         *params = mState.copyReadBuffer.id();
   1968         break;
   1969       case GL_COPY_WRITE_BUFFER_BINDING:
   1970         *params = mState.copyWriteBuffer.id();
   1971         break;
   1972       case GL_PIXEL_PACK_BUFFER_BINDING:
   1973         *params = mState.pack.pixelBuffer.id();
   1974         break;
   1975       case GL_PIXEL_UNPACK_BUFFER_BINDING:
   1976         *params = mState.unpack.pixelBuffer.id();
   1977         break;
   1978       case GL_NUM_EXTENSIONS:
   1979         *params = static_cast<GLint>(getNumExtensions());
   1980         break;
   1981       default:
   1982         UNREACHABLE();
   1983         break;
   1984     }
   1985 }
   1986 
   1987 void Context::getInteger64v(GLenum pname, GLint64 *params)
   1988 {
   1989     switch (pname)
   1990     {
   1991       case GL_MAX_ELEMENT_INDEX:
   1992         *params = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
   1993         break;
   1994       case GL_MAX_UNIFORM_BLOCK_SIZE:
   1995         *params = static_cast<GLint64>(mRenderer->getMaxUniformBufferSize());
   1996         break;
   1997       case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
   1998         {
   1999             GLint64 uniformBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexShaderUniformBuffers()) * static_cast<GLint64>(mRenderer->getMaxUniformBufferSize() / 4);
   2000             GLint64 defaultBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexUniformVectors() * 4);
   2001             *params = uniformBufferComponents + defaultBufferComponents;
   2002         }
   2003         break;
   2004       case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
   2005         {
   2006             GLint64 uniformBufferComponents = static_cast<GLint64>(mRenderer->getMaxFragmentShaderUniformBuffers()) * static_cast<GLint64>(mRenderer->getMaxUniformBufferSize() / 4);
   2007             GLint64 defaultBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexUniformVectors() * 4);
   2008             *params = uniformBufferComponents + defaultBufferComponents;
   2009         }
   2010         break;
   2011       case GL_MAX_SERVER_WAIT_TIMEOUT:
   2012         // We do not wait for server fence objects internally, so report a max timeout of zero.
   2013         *params = 0;
   2014         break;
   2015       default:
   2016         UNREACHABLE();
   2017         break;
   2018     }
   2019 }
   2020 
   2021 bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
   2022 {
   2023     switch (target)
   2024     {
   2025       case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
   2026         if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
   2027         {
   2028             *data = mState.transformFeedbackBuffers[index].id();
   2029         }
   2030         break;
   2031       case GL_UNIFORM_BUFFER_BINDING:
   2032         if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
   2033         {
   2034             *data = mState.uniformBuffers[index].id();
   2035         }
   2036         break;
   2037       default:
   2038         return false;
   2039     }
   2040 
   2041     return true;
   2042 }
   2043 
   2044 bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
   2045 {
   2046     switch (target)
   2047     {
   2048       case GL_TRANSFORM_FEEDBACK_BUFFER_START:
   2049         if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
   2050         {
   2051             *data = mState.transformFeedbackBuffers[index].getOffset();
   2052         }
   2053         break;
   2054       case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
   2055         if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
   2056         {
   2057             *data = mState.transformFeedbackBuffers[index].getSize();
   2058         }
   2059         break;
   2060       case GL_UNIFORM_BUFFER_START:
   2061         if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
   2062         {
   2063             *data = mState.uniformBuffers[index].getOffset();
   2064         }
   2065         break;
   2066       case GL_UNIFORM_BUFFER_SIZE:
   2067         if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
   2068         {
   2069             *data = mState.uniformBuffers[index].getSize();
   2070         }
   2071         break;
   2072       default:
   2073         return false;
   2074     }
   2075 
   2076     return true;
   2077 }
   2078 
   2079 bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
   2080 {
   2081     if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
   2082     {
   2083         *type = GL_INT;
   2084         *numParams = 1;
   2085         return true;
   2086     }
   2087 
   2088     // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
   2089     // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
   2090     // to the fact that it is stored internally as a float, and so would require conversion
   2091     // if returned from Context::getIntegerv. Since this conversion is already implemented
   2092     // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
   2093     // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
   2094     // application.
   2095     switch (pname)
   2096     {
   2097       case GL_COMPRESSED_TEXTURE_FORMATS:
   2098         {
   2099             *type = GL_INT;
   2100             *numParams = mNumCompressedTextureFormats;
   2101         }
   2102         return true;
   2103       case GL_SHADER_BINARY_FORMATS:
   2104         {
   2105             *type = GL_INT;
   2106             *numParams = 0;
   2107         }
   2108         return true;
   2109       case GL_MAX_VERTEX_ATTRIBS:
   2110       case GL_MAX_VERTEX_UNIFORM_VECTORS:
   2111       case GL_MAX_VARYING_VECTORS:
   2112       case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
   2113       case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
   2114       case GL_MAX_TEXTURE_IMAGE_UNITS:
   2115       case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
   2116       case GL_MAX_RENDERBUFFER_SIZE:
   2117       case GL_MAX_COLOR_ATTACHMENTS_EXT:
   2118       case GL_MAX_DRAW_BUFFERS_EXT:
   2119       case GL_NUM_SHADER_BINARY_FORMATS:
   2120       case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
   2121       case GL_ARRAY_BUFFER_BINDING:
   2122       //case GL_FRAMEBUFFER_BINDING: // equivalent to DRAW_FRAMEBUFFER_BINDING_ANGLE
   2123       case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:
   2124       case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
   2125       case GL_RENDERBUFFER_BINDING:
   2126       case GL_CURRENT_PROGRAM:
   2127       case GL_PACK_ALIGNMENT:
   2128       case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
   2129       case GL_UNPACK_ALIGNMENT:
   2130       case GL_GENERATE_MIPMAP_HINT:
   2131       case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
   2132       case GL_RED_BITS:
   2133       case GL_GREEN_BITS:
   2134       case GL_BLUE_BITS:
   2135       case GL_ALPHA_BITS:
   2136       case GL_DEPTH_BITS:
   2137       case GL_STENCIL_BITS:
   2138       case GL_ELEMENT_ARRAY_BUFFER_BINDING:
   2139       case GL_CULL_FACE_MODE:
   2140       case GL_FRONT_FACE:
   2141       case GL_ACTIVE_TEXTURE:
   2142       case GL_STENCIL_FUNC:
   2143       case GL_STENCIL_VALUE_MASK:
   2144       case GL_STENCIL_REF:
   2145       case GL_STENCIL_FAIL:
   2146       case GL_STENCIL_PASS_DEPTH_FAIL:
   2147       case GL_STENCIL_PASS_DEPTH_PASS:
   2148       case GL_STENCIL_BACK_FUNC:
   2149       case GL_STENCIL_BACK_VALUE_MASK:
   2150       case GL_STENCIL_BACK_REF:
   2151       case GL_STENCIL_BACK_FAIL:
   2152       case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
   2153       case GL_STENCIL_BACK_PASS_DEPTH_PASS:
   2154       case GL_DEPTH_FUNC:
   2155       case GL_BLEND_SRC_RGB:
   2156       case GL_BLEND_SRC_ALPHA:
   2157       case GL_BLEND_DST_RGB:
   2158       case GL_BLEND_DST_ALPHA:
   2159       case GL_BLEND_EQUATION_RGB:
   2160       case GL_BLEND_EQUATION_ALPHA:
   2161       case GL_STENCIL_WRITEMASK:
   2162       case GL_STENCIL_BACK_WRITEMASK:
   2163       case GL_STENCIL_CLEAR_VALUE:
   2164       case GL_SUBPIXEL_BITS:
   2165       case GL_MAX_TEXTURE_SIZE:
   2166       case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
   2167       case GL_SAMPLE_BUFFERS:
   2168       case GL_SAMPLES:
   2169       case GL_IMPLEMENTATION_COLOR_READ_TYPE:
   2170       case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
   2171       case GL_TEXTURE_BINDING_2D:
   2172       case GL_TEXTURE_BINDING_CUBE_MAP:
   2173       case GL_RESET_NOTIFICATION_STRATEGY_EXT:
   2174       case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
   2175       case GL_PROGRAM_BINARY_FORMATS_OES:
   2176         {
   2177             *type = GL_INT;
   2178             *numParams = 1;
   2179         }
   2180         return true;
   2181       case GL_MAX_SAMPLES_ANGLE:
   2182         {
   2183             if (getMaxSupportedSamples() != 0)
   2184             {
   2185                 *type = GL_INT;
   2186                 *numParams = 1;
   2187             }
   2188             else
   2189             {
   2190                 return false;
   2191             }
   2192         }
   2193         return true;
   2194       case GL_PIXEL_PACK_BUFFER_BINDING:
   2195       case GL_PIXEL_UNPACK_BUFFER_BINDING:
   2196         {
   2197             if (supportsPBOs())
   2198             {
   2199                 *type = GL_INT;
   2200                 *numParams = 1;
   2201             }
   2202             else
   2203             {
   2204                 return false;
   2205             }
   2206         }
   2207         return true;
   2208       case GL_MAX_VIEWPORT_DIMS:
   2209         {
   2210             *type = GL_INT;
   2211             *numParams = 2;
   2212         }
   2213         return true;
   2214       case GL_VIEWPORT:
   2215       case GL_SCISSOR_BOX:
   2216         {
   2217             *type = GL_INT;
   2218             *numParams = 4;
   2219         }
   2220         return true;
   2221       case GL_SHADER_COMPILER:
   2222       case GL_SAMPLE_COVERAGE_INVERT:
   2223       case GL_DEPTH_WRITEMASK:
   2224       case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
   2225       case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
   2226       case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
   2227       case GL_SAMPLE_COVERAGE:
   2228       case GL_SCISSOR_TEST:
   2229       case GL_STENCIL_TEST:
   2230       case GL_DEPTH_TEST:
   2231       case GL_BLEND:
   2232       case GL_DITHER:
   2233       case GL_CONTEXT_ROBUST_ACCESS_EXT:
   2234         {
   2235             *type = GL_BOOL;
   2236             *numParams = 1;
   2237         }
   2238         return true;
   2239       case GL_COLOR_WRITEMASK:
   2240         {
   2241             *type = GL_BOOL;
   2242             *numParams = 4;
   2243         }
   2244         return true;
   2245       case GL_POLYGON_OFFSET_FACTOR:
   2246       case GL_POLYGON_OFFSET_UNITS:
   2247       case GL_SAMPLE_COVERAGE_VALUE:
   2248       case GL_DEPTH_CLEAR_VALUE:
   2249       case GL_LINE_WIDTH:
   2250         {
   2251             *type = GL_FLOAT;
   2252             *numParams = 1;
   2253         }
   2254         return true;
   2255       case GL_ALIASED_LINE_WIDTH_RANGE:
   2256       case GL_ALIASED_POINT_SIZE_RANGE:
   2257       case GL_DEPTH_RANGE:
   2258         {
   2259             *type = GL_FLOAT;
   2260             *numParams = 2;
   2261         }
   2262         return true;
   2263       case GL_COLOR_CLEAR_VALUE:
   2264       case GL_BLEND_COLOR:
   2265         {
   2266             *type = GL_FLOAT;
   2267             *numParams = 4;
   2268         }
   2269         return true;
   2270       case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
   2271         if (!supportsTextureFilterAnisotropy())
   2272         {
   2273             return false;
   2274         }
   2275         *type = GL_FLOAT;
   2276         *numParams = 1;
   2277         return true;
   2278     }
   2279 
   2280     if (mClientVersion < 3)
   2281     {
   2282         return false;
   2283     }
   2284 
   2285     // Check for ES3.0+ parameter names
   2286     switch (pname)
   2287     {
   2288       case GL_MAX_UNIFORM_BUFFER_BINDINGS:
   2289       case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
   2290       case GL_UNIFORM_BUFFER_BINDING:
   2291       case GL_TRANSFORM_FEEDBACK_BINDING:
   2292       case GL_COPY_READ_BUFFER_BINDING:
   2293       case GL_COPY_WRITE_BUFFER_BINDING:
   2294       case GL_TEXTURE_BINDING_3D:
   2295       case GL_TEXTURE_BINDING_2D_ARRAY:
   2296       case GL_MAX_3D_TEXTURE_SIZE:
   2297       case GL_MAX_ARRAY_TEXTURE_LAYERS:
   2298       case GL_MAX_VERTEX_UNIFORM_BLOCKS:
   2299       case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
   2300       case GL_MAX_COMBINED_UNIFORM_BLOCKS:
   2301       case GL_MAX_VARYING_COMPONENTS:
   2302       case GL_VERTEX_ARRAY_BINDING:
   2303       case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
   2304       case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
   2305       case GL_NUM_EXTENSIONS:
   2306       case GL_MAJOR_VERSION:
   2307       case GL_MINOR_VERSION:
   2308       case GL_MAX_ELEMENTS_INDICES:
   2309       case GL_MAX_ELEMENTS_VERTICES:
   2310       case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
   2311       case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
   2312       case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
   2313         {
   2314             *type = GL_INT;
   2315             *numParams = 1;
   2316         }
   2317         return true;
   2318 
   2319       case GL_MAX_ELEMENT_INDEX:
   2320       case GL_MAX_UNIFORM_BLOCK_SIZE:
   2321       case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
   2322       case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
   2323       case GL_MAX_SERVER_WAIT_TIMEOUT:
   2324         {
   2325             *type = GL_INT_64_ANGLEX;
   2326             *numParams = 1;
   2327         }
   2328         return true;
   2329 
   2330       case GL_TRANSFORM_FEEDBACK_ACTIVE:
   2331       case GL_TRANSFORM_FEEDBACK_PAUSED:
   2332         {
   2333             *type = GL_BOOL;
   2334             *numParams = 1;
   2335         }
   2336         return true;
   2337     }
   2338 
   2339     return false;
   2340 }
   2341 
   2342 bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams)
   2343 {
   2344     if (mClientVersion < 3)
   2345     {
   2346         return false;
   2347     }
   2348 
   2349     switch (target)
   2350     {
   2351       case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
   2352       case GL_UNIFORM_BUFFER_BINDING:
   2353         {
   2354             *type = GL_INT;
   2355             *numParams = 1;
   2356         }
   2357         return true;
   2358       case GL_TRANSFORM_FEEDBACK_BUFFER_START:
   2359       case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
   2360       case GL_UNIFORM_BUFFER_START:
   2361       case GL_UNIFORM_BUFFER_SIZE:
   2362         {
   2363             *type = GL_INT_64_ANGLEX;
   2364             *numParams = 1;
   2365         }
   2366     }
   2367 
   2368     return false;
   2369 }
   2370 
   2371 // Applies the render target surface, depth stencil surface, viewport rectangle and
   2372 // scissor rectangle to the renderer
   2373 bool Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport)
   2374 {
   2375     Framebuffer *framebufferObject = getDrawFramebuffer();
   2376 
   2377     if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
   2378     {
   2379         return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
   2380     }
   2381 
   2382     mRenderer->applyRenderTarget(framebufferObject);
   2383 
   2384     if (!mRenderer->setViewport(mState.viewport, mState.zNear, mState.zFar, drawMode, mState.rasterizer.frontFace,
   2385                                 ignoreViewport))
   2386     {
   2387         return false;
   2388     }
   2389 
   2390     mRenderer->setScissorRectangle(mState.scissor, mState.scissorTest);
   2391 
   2392     return true;
   2393 }
   2394 
   2395 // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
   2396 void Context::applyState(GLenum drawMode)
   2397 {
   2398     Framebuffer *framebufferObject = getDrawFramebuffer();
   2399     int samples = framebufferObject->getSamples();
   2400 
   2401     mState.rasterizer.pointDrawMode = (drawMode == GL_POINTS);
   2402     mState.rasterizer.multiSample = (samples != 0);
   2403     mRenderer->setRasterizerState(mState.rasterizer);
   2404 
   2405     unsigned int mask = 0;
   2406     if (mState.sampleCoverage)
   2407     {
   2408         if (mState.sampleCoverageValue != 0)
   2409         {
   2410 
   2411             float threshold = 0.5f;
   2412 
   2413             for (int i = 0; i < samples; ++i)
   2414             {
   2415                 mask <<= 1;
   2416 
   2417                 if ((i + 1) * mState.sampleCoverageValue >= threshold)
   2418                 {
   2419                     threshold += 1.0f;
   2420                     mask |= 1;
   2421                 }
   2422             }
   2423         }
   2424 
   2425         if (mState.sampleCoverageInvert)
   2426         {
   2427             mask = ~mask;
   2428         }
   2429     }
   2430     else
   2431     {
   2432         mask = 0xFFFFFFFF;
   2433     }
   2434     mRenderer->setBlendState(framebufferObject, mState.blend, mState.blendColor, mask);
   2435 
   2436     mRenderer->setDepthStencilState(mState.depthStencil, mState.stencilRef, mState.stencilBackRef,
   2437                                     mState.rasterizer.frontFace == GL_CCW);
   2438 }
   2439 
   2440 // Applies the shaders and shader constants to the Direct3D 9 device
   2441 void Context::applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive)
   2442 {
   2443     const VertexAttribute *vertexAttributes = getCurrentVertexArray()->getVertexAttributes();
   2444 
   2445     VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS];
   2446     VertexFormat::GetInputLayout(inputLayout, programBinary, vertexAttributes, mState.vertexAttribCurrentValues);
   2447 
   2448     mRenderer->applyShaders(programBinary, mState.rasterizer.rasterizerDiscard, transformFeedbackActive, inputLayout);
   2449 
   2450     programBinary->applyUniforms();
   2451 }
   2452 
   2453 size_t Context::getCurrentTexturesAndSamplerStates(ProgramBinary *programBinary, SamplerType type, Texture **outTextures,
   2454                                                    TextureType *outTextureTypes, SamplerState *outSamplers)
   2455 {
   2456     size_t samplerRange = programBinary->getUsedSamplerRange(type);
   2457     for (size_t i = 0; i < samplerRange; i++)
   2458     {
   2459         outTextureTypes[i] = programBinary->getSamplerTextureType(type, i);
   2460         GLint textureUnit = programBinary->getSamplerMapping(type, i);   // OpenGL texture image unit index
   2461         if (textureUnit != -1)
   2462         {
   2463             outTextures[i] = getSamplerTexture(textureUnit, outTextureTypes[i]);
   2464             outTextures[i]->getSamplerState(&outSamplers[i]);
   2465             if (mState.samplers[textureUnit] != 0)
   2466             {
   2467                 Sampler *samplerObject = getSampler(mState.samplers[textureUnit]);
   2468                 samplerObject->getState(&outSamplers[i]);
   2469             }
   2470         }
   2471         else
   2472         {
   2473             outTextures[i] = NULL;
   2474         }
   2475     }
   2476 
   2477     return samplerRange;
   2478 }
   2479 
   2480 void Context::generateSwizzles(Texture *textures[], size_t count)
   2481 {
   2482     for (size_t i = 0; i < count; i++)
   2483     {
   2484         if (textures[i] && textures[i]->isSwizzled())
   2485         {
   2486             mRenderer->generateSwizzle(textures[i]);
   2487         }
   2488     }
   2489 }
   2490 
   2491 // For each Direct3D sampler of either the pixel or vertex stage,
   2492 // looks up the corresponding OpenGL texture image unit and texture type,
   2493 // and sets the texture and its addressing/filtering state (or NULL when inactive).
   2494 void Context::applyTextures(SamplerType shaderType, Texture *textures[], TextureType *textureTypes, SamplerState *samplers,
   2495                             size_t textureCount, const FramebufferTextureSerialArray& framebufferSerials,
   2496                             size_t framebufferSerialCount)
   2497 {
   2498     // Range of Direct3D samplers of given sampler type
   2499     size_t samplerCount = (shaderType == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS
   2500                                                         : mRenderer->getMaxVertexTextureImageUnits();
   2501 
   2502     for (size_t samplerIndex = 0; samplerIndex < textureCount; samplerIndex++)
   2503     {
   2504         Texture *texture = textures[samplerIndex];
   2505         const SamplerState &sampler = samplers[samplerIndex];
   2506         TextureType textureType = textureTypes[samplerIndex];
   2507 
   2508         if (texture)
   2509         {
   2510             // TODO: std::binary_search may become unavailable using older versions of GCC
   2511             if (texture->isSamplerComplete(sampler) &&
   2512                 !std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial()))
   2513             {
   2514                 mRenderer->setSamplerState(shaderType, samplerIndex, sampler);
   2515                 mRenderer->setTexture(shaderType, samplerIndex, texture);
   2516                 texture->resetDirty();
   2517             }
   2518             else
   2519             {
   2520                 Texture *incompleteTexture = getIncompleteTexture(textureType);
   2521                 mRenderer->setTexture(shaderType, samplerIndex, incompleteTexture);
   2522                 incompleteTexture->resetDirty();
   2523             }
   2524         }
   2525         else
   2526         {
   2527             mRenderer->setTexture(shaderType, samplerIndex, NULL);
   2528         }
   2529     }
   2530 
   2531     for (size_t samplerIndex = textureCount; samplerIndex < samplerCount; samplerIndex++)
   2532     {
   2533         mRenderer->setTexture(shaderType, samplerIndex, NULL);
   2534     }
   2535 }
   2536 
   2537 bool Context::applyUniformBuffers()
   2538 {
   2539     Program *programObject = getProgram(mState.currentProgram);
   2540     ProgramBinary *programBinary = programObject->getProgramBinary();
   2541 
   2542     std::vector<gl::Buffer*> boundBuffers;
   2543 
   2544     for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++)
   2545     {
   2546         GLuint blockBinding = programObject->getUniformBlockBinding(uniformBlockIndex);
   2547         const OffsetBindingPointer<Buffer>& boundBuffer = mState.uniformBuffers[blockBinding];
   2548         if (boundBuffer.id() == 0)
   2549         {
   2550             // undefined behaviour
   2551             return false;
   2552         }
   2553         else
   2554         {
   2555             gl::Buffer *uniformBuffer = boundBuffer.get();
   2556             ASSERT(uniformBuffer);
   2557             boundBuffers.push_back(uniformBuffer);
   2558         }
   2559     }
   2560 
   2561     return programBinary->applyUniformBuffers(boundBuffers);
   2562 }
   2563 
   2564 bool Context::applyTransformFeedbackBuffers()
   2565 {
   2566     TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
   2567     if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
   2568     {
   2569         Buffer *transformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
   2570         GLintptr transformFeedbackOffsets[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
   2571         for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
   2572         {
   2573             transformFeedbackBuffers[i] = mState.transformFeedbackBuffers[i].get();
   2574             transformFeedbackOffsets[i] = mState.transformFeedbackBuffers[i].getOffset();
   2575         }
   2576         mRenderer->applyTransformFeedbackBuffers(transformFeedbackBuffers, transformFeedbackOffsets);
   2577         return true;
   2578     }
   2579     else
   2580     {
   2581         return false;
   2582     }
   2583 }
   2584 
   2585 void Context::markTransformFeedbackUsage()
   2586 {
   2587     for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
   2588     {
   2589         Buffer *buffer = mState.transformFeedbackBuffers[i].get();
   2590         if (buffer)
   2591         {
   2592             buffer->markTransformFeedbackUsage();
   2593         }
   2594     }
   2595 }
   2596 
   2597 void Context::clear(GLbitfield mask)
   2598 {
   2599     if (isRasterizerDiscardEnabled())
   2600     {
   2601         return;
   2602     }
   2603 
   2604     ClearParameters clearParams = { 0 };
   2605     for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
   2606     {
   2607         clearParams.clearColor[i] = false;
   2608     }
   2609     clearParams.colorFClearValue = mState.colorClearValue;
   2610     clearParams.colorClearType = GL_FLOAT;
   2611     clearParams.colorMaskRed = mState.blend.colorMaskRed;
   2612     clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
   2613     clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
   2614     clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
   2615     clearParams.clearDepth = false;
   2616     clearParams.depthClearValue = mState.depthClearValue;
   2617     clearParams.clearStencil = false;
   2618     clearParams.stencilClearValue = mState.stencilClearValue;
   2619     clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
   2620     clearParams.scissorEnabled = mState.scissorTest;
   2621     clearParams.scissor = mState.scissor;
   2622 
   2623     Framebuffer *framebufferObject = getDrawFramebuffer();
   2624     if (mask & GL_COLOR_BUFFER_BIT)
   2625     {
   2626         if (framebufferObject->hasEnabledColorAttachment())
   2627         {
   2628             for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
   2629             {
   2630                 clearParams.clearColor[i] = true;
   2631             }
   2632         }
   2633     }
   2634 
   2635     if (mask & GL_DEPTH_BUFFER_BIT)
   2636     {
   2637         if (mState.depthStencil.depthMask && framebufferObject->getDepthbufferType() != GL_NONE)
   2638         {
   2639             clearParams.clearDepth = true;
   2640         }
   2641     }
   2642 
   2643     if (mask & GL_STENCIL_BUFFER_BIT)
   2644     {
   2645         if (framebufferObject->getStencilbufferType() != GL_NONE)
   2646         {
   2647             rx::RenderTarget *depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
   2648             if (!depthStencil)
   2649             {
   2650                 ERR("Depth stencil pointer unexpectedly null.");
   2651                 return;
   2652             }
   2653 
   2654             if (gl::GetStencilBits(depthStencil->getActualFormat(), mClientVersion) > 0)
   2655             {
   2656                 clearParams.clearStencil = true;
   2657             }
   2658         }
   2659     }
   2660 
   2661 
   2662     if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
   2663     {
   2664         return;
   2665     }
   2666 
   2667     mRenderer->clear(clearParams, framebufferObject);
   2668 }
   2669 
   2670 void Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values)
   2671 {
   2672     if (isRasterizerDiscardEnabled())
   2673     {
   2674         return;
   2675     }
   2676 
   2677     // glClearBufferfv can be called to clear the color buffer or depth buffer
   2678     ClearParameters clearParams = { 0 };
   2679 
   2680     if (buffer == GL_COLOR)
   2681     {
   2682         for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
   2683         {
   2684             clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
   2685         }
   2686         clearParams.colorFClearValue = ColorF(values[0], values[1], values[2], values[3]);
   2687         clearParams.colorClearType = GL_FLOAT;
   2688     }
   2689     else
   2690     {
   2691         for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
   2692         {
   2693             clearParams.clearColor[i] = false;
   2694         }
   2695         clearParams.colorFClearValue = mState.colorClearValue;
   2696         clearParams.colorClearType = GL_FLOAT;
   2697     }
   2698 
   2699     clearParams.colorMaskRed = mState.blend.colorMaskRed;
   2700     clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
   2701     clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
   2702     clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
   2703 
   2704     if (buffer == GL_DEPTH)
   2705     {
   2706         clearParams.clearDepth = true;
   2707         clearParams.depthClearValue = values[0];
   2708     }
   2709     else
   2710     {
   2711         clearParams.clearDepth = false;
   2712         clearParams.depthClearValue = mState.depthClearValue;
   2713     }
   2714 
   2715     clearParams.clearStencil = false;
   2716     clearParams.stencilClearValue = mState.stencilClearValue;
   2717     clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
   2718     clearParams.scissorEnabled = mState.scissorTest;
   2719     clearParams.scissor = mState.scissor;
   2720 
   2721     if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
   2722     {
   2723         return;
   2724     }
   2725 
   2726     mRenderer->clear(clearParams, getDrawFramebuffer());
   2727 }
   2728 
   2729 void Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values)
   2730 {
   2731     if (isRasterizerDiscardEnabled())
   2732     {
   2733         return;
   2734     }
   2735 
   2736     // glClearBufferuv can only be called to clear a color buffer
   2737     ClearParameters clearParams = { 0 };
   2738     for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
   2739     {
   2740         clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
   2741     }
   2742     clearParams.colorUIClearValue = ColorUI(values[0], values[1], values[2], values[3]);
   2743     clearParams.colorClearType = GL_UNSIGNED_INT;
   2744     clearParams.colorMaskRed = mState.blend.colorMaskRed;
   2745     clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
   2746     clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
   2747     clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
   2748     clearParams.clearDepth = false;
   2749     clearParams.depthClearValue = mState.depthClearValue;
   2750     clearParams.clearStencil = false;
   2751     clearParams.stencilClearValue = mState.stencilClearValue;
   2752     clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
   2753     clearParams.scissorEnabled = mState.scissorTest;
   2754     clearParams.scissor = mState.scissor;
   2755 
   2756     if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
   2757     {
   2758         return;
   2759     }
   2760 
   2761     mRenderer->clear(clearParams, getDrawFramebuffer());
   2762 }
   2763 
   2764 void Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values)
   2765 {
   2766     if (isRasterizerDiscardEnabled())
   2767     {
   2768         return;
   2769     }
   2770 
   2771     // glClearBufferfv can be called to clear the color buffer or stencil buffer
   2772     ClearParameters clearParams = { 0 };
   2773 
   2774     if (buffer == GL_COLOR)
   2775     {
   2776         for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
   2777         {
   2778             clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
   2779         }
   2780         clearParams.colorIClearValue = ColorI(values[0], values[1], values[2], values[3]);
   2781         clearParams.colorClearType = GL_INT;
   2782     }
   2783     else
   2784     {
   2785         for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
   2786         {
   2787             clearParams.clearColor[i] = false;
   2788         }
   2789         clearParams.colorFClearValue = mState.colorClearValue;
   2790         clearParams.colorClearType = GL_FLOAT;
   2791     }
   2792 
   2793     clearParams.colorMaskRed = mState.blend.colorMaskRed;
   2794     clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
   2795     clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
   2796     clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
   2797 
   2798     clearParams.clearDepth = false;
   2799     clearParams.depthClearValue = mState.depthClearValue;
   2800 
   2801     if (buffer == GL_STENCIL)
   2802     {
   2803         clearParams.clearStencil = true;
   2804         clearParams.stencilClearValue = values[1];
   2805     }
   2806     else
   2807     {
   2808         clearParams.clearStencil = false;
   2809         clearParams.stencilClearValue = mState.stencilClearValue;
   2810     }
   2811     clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
   2812 
   2813     clearParams.scissorEnabled = mState.scissorTest;
   2814     clearParams.scissor = mState.scissor;
   2815 
   2816     if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
   2817     {
   2818         return;
   2819     }
   2820 
   2821     mRenderer->clear(clearParams, getDrawFramebuffer());
   2822 }
   2823 
   2824 void Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil)
   2825 {
   2826     if (isRasterizerDiscardEnabled())
   2827     {
   2828         return;
   2829     }
   2830 
   2831     // glClearBufferfi can only be called to clear a depth stencil buffer
   2832     ClearParameters clearParams = { 0 };
   2833     for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
   2834     {
   2835         clearParams.clearColor[i] = false;
   2836     }
   2837     clearParams.colorFClearValue = mState.colorClearValue;
   2838     clearParams.colorClearType = GL_FLOAT;
   2839     clearParams.colorMaskRed = mState.blend.colorMaskRed;
   2840     clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
   2841     clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
   2842     clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
   2843     clearParams.clearDepth = true;
   2844     clearParams.depthClearValue = depth;
   2845     clearParams.clearStencil = true;
   2846     clearParams.stencilClearValue = stencil;
   2847     clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
   2848     clearParams.scissorEnabled = mState.scissorTest;
   2849     clearParams.scissor = mState.scissor;
   2850 
   2851     if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
   2852     {
   2853         return;
   2854     }
   2855 
   2856     mRenderer->clear(clearParams, getDrawFramebuffer());
   2857 }
   2858 
   2859 void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
   2860                          GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
   2861 {
   2862     gl::Framebuffer *framebuffer = getReadFramebuffer();
   2863 
   2864     bool isSized = IsSizedInternalFormat(format, mClientVersion);
   2865     GLenum sizedInternalFormat = (isSized ? format : GetSizedInternalFormat(format, type, mClientVersion));
   2866     GLuint outputPitch = GetRowPitch(sizedInternalFormat, type, mClientVersion, width, mState.pack.alignment);
   2867 
   2868     mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, mState.pack, pixels);
   2869 }
   2870 
   2871 void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
   2872 {
   2873     if (!mState.currentProgram)
   2874     {
   2875         return gl::error(GL_INVALID_OPERATION);
   2876     }
   2877 
   2878     ProgramBinary *programBinary = getCurrentProgramBinary();
   2879     programBinary->applyUniforms();
   2880 
   2881     Texture *vsTextures[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
   2882     TextureType vsTextureTypes[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
   2883     SamplerState vsSamplers[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
   2884     size_t vsTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers);
   2885 
   2886     Texture *psTextures[MAX_TEXTURE_IMAGE_UNITS];
   2887     TextureType psTextureTypes[MAX_TEXTURE_IMAGE_UNITS];
   2888     SamplerState psSamplers[MAX_TEXTURE_IMAGE_UNITS];
   2889     size_t psTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers);
   2890 
   2891     generateSwizzles(vsTextures, vsTextureCount);
   2892     generateSwizzles(psTextures, psTextureCount);
   2893 
   2894     if (!mRenderer->applyPrimitiveType(mode, count))
   2895     {
   2896         return;
   2897     }
   2898 
   2899     if (!applyRenderTarget(mode, false))
   2900     {
   2901         return;
   2902     }
   2903 
   2904     applyState(mode);
   2905 
   2906     GLenum err = mRenderer->applyVertexBuffer(programBinary, getCurrentVertexArray()->getVertexAttributes(), mState.vertexAttribCurrentValues, first, count, instances);
   2907     if (err != GL_NO_ERROR)
   2908     {
   2909         return gl::error(err);
   2910     }
   2911 
   2912     bool transformFeedbackActive = applyTransformFeedbackBuffers();
   2913 
   2914     applyShaders(programBinary, transformFeedbackActive);
   2915 
   2916     FramebufferTextureSerialArray frameBufferSerials;
   2917     size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&frameBufferSerials);
   2918 
   2919     applyTextures(SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers, vsTextureCount, frameBufferSerials, framebufferSerialCount);
   2920     applyTextures(SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers, psTextureCount, frameBufferSerials, framebufferSerialCount);
   2921 
   2922     if (!applyUniformBuffers())
   2923     {
   2924         return;
   2925     }
   2926 
   2927     if (!programBinary->validateSamplers(NULL))
   2928     {
   2929         return gl::error(GL_INVALID_OPERATION);
   2930     }
   2931 
   2932     if (!skipDraw(mode))
   2933     {
   2934         mRenderer->drawArrays(mode, count, instances, transformFeedbackActive);
   2935 
   2936         if (transformFeedbackActive)
   2937         {
   2938             markTransformFeedbackUsage();
   2939         }
   2940     }
   2941 }
   2942 
   2943 void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances)
   2944 {
   2945     if (!mState.currentProgram)
   2946     {
   2947         return gl::error(GL_INVALID_OPERATION);
   2948     }
   2949 
   2950     VertexArray *vao = getCurrentVertexArray();
   2951     if (!indices && !vao->getElementArrayBuffer())
   2952     {
   2953         return gl::error(GL_INVALID_OPERATION);
   2954     }
   2955 
   2956     ProgramBinary *programBinary = getCurrentProgramBinary();
   2957     programBinary->applyUniforms();
   2958 
   2959     Texture *vsTextures[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
   2960     TextureType vsTextureTypes[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
   2961     SamplerState vsSamplers[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
   2962     size_t vsTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers);
   2963 
   2964     Texture *psTextures[MAX_TEXTURE_IMAGE_UNITS];
   2965     TextureType psTextureTypes[MAX_TEXTURE_IMAGE_UNITS];
   2966     SamplerState psSamplers[MAX_TEXTURE_IMAGE_UNITS];
   2967     size_t psTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers);
   2968 
   2969     generateSwizzles(vsTextures, vsTextureCount);
   2970     generateSwizzles(psTextures, psTextureCount);
   2971 
   2972     if (!mRenderer->applyPrimitiveType(mode, count))
   2973     {
   2974         return;
   2975     }
   2976 
   2977     if (!applyRenderTarget(mode, false))
   2978     {
   2979         return;
   2980     }
   2981 
   2982     applyState(mode);
   2983 
   2984     rx::TranslatedIndexData indexInfo;
   2985     GLenum err = mRenderer->applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo);
   2986     if (err != GL_NO_ERROR)
   2987     {
   2988         return gl::error(err);
   2989     }
   2990 
   2991     GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
   2992     err = mRenderer->applyVertexBuffer(programBinary, vao->getVertexAttributes(), mState.vertexAttribCurrentValues, indexInfo.minIndex, vertexCount, instances);
   2993     if (err != GL_NO_ERROR)
   2994     {
   2995         return gl::error(err);
   2996     }
   2997 
   2998     bool transformFeedbackActive = applyTransformFeedbackBuffers();
   2999     // Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation
   3000     // layer.
   3001     ASSERT(!transformFeedbackActive);
   3002 
   3003     applyShaders(programBinary, transformFeedbackActive);
   3004 
   3005     FramebufferTextureSerialArray frameBufferSerials;
   3006     size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&frameBufferSerials);
   3007 
   3008     applyTextures(SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers, vsTextureCount, frameBufferSerials, framebufferSerialCount);
   3009     applyTextures(SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers, psTextureCount, frameBufferSerials, framebufferSerialCount);
   3010 
   3011     if (!applyUniformBuffers())
   3012     {
   3013         return;
   3014     }
   3015 
   3016     if (!programBinary->validateSamplers(NULL))
   3017     {
   3018         return gl::error(GL_INVALID_OPERATION);
   3019     }
   3020 
   3021     if (!skipDraw(mode))
   3022     {
   3023         mRenderer->drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances);
   3024     }
   3025 }
   3026 
   3027 // Implements glFlush when block is false, glFinish when block is true
   3028 void Context::sync(bool block)
   3029 {
   3030     mRenderer->sync(block);
   3031 }
   3032 
   3033 void Context::recordInvalidEnum()
   3034 {
   3035     mInvalidEnum = true;
   3036 }
   3037 
   3038 void Context::recordInvalidValue()
   3039 {
   3040     mInvalidValue = true;
   3041 }
   3042 
   3043 void Context::recordInvalidOperation()
   3044 {
   3045     mInvalidOperation = true;
   3046 }
   3047 
   3048 void Context::recordOutOfMemory()
   3049 {
   3050     mOutOfMemory = true;
   3051 }
   3052 
   3053 void Context::recordInvalidFramebufferOperation()
   3054 {
   3055     mInvalidFramebufferOperation = true;
   3056 }
   3057 
   3058 // Get one of the recorded errors and clear its flag, if any.
   3059 // [OpenGL ES 2.0.24] section 2.5 page 13.
   3060 GLenum Context::getError()
   3061 {
   3062     if (mInvalidEnum)
   3063     {
   3064         mInvalidEnum = false;
   3065 
   3066         return GL_INVALID_ENUM;
   3067     }
   3068 
   3069     if (mInvalidValue)
   3070     {
   3071         mInvalidValue = false;
   3072 
   3073         return GL_INVALID_VALUE;
   3074     }
   3075 
   3076     if (mInvalidOperation)
   3077     {
   3078         mInvalidOperation = false;
   3079 
   3080         return GL_INVALID_OPERATION;
   3081     }
   3082 
   3083     if (mOutOfMemory)
   3084     {
   3085         mOutOfMemory = false;
   3086 
   3087         return GL_OUT_OF_MEMORY;
   3088     }
   3089 
   3090     if (mInvalidFramebufferOperation)
   3091     {
   3092         mInvalidFramebufferOperation = false;
   3093 
   3094         return GL_INVALID_FRAMEBUFFER_OPERATION;
   3095     }
   3096 
   3097     return GL_NO_ERROR;
   3098 }
   3099 
   3100 GLenum Context::getResetStatus()
   3101 {
   3102     if (mResetStatus == GL_NO_ERROR && !mContextLost)
   3103     {
   3104         // mResetStatus will be set by the markContextLost callback
   3105         // in the case a notification is sent
   3106         mRenderer->testDeviceLost(true);
   3107     }
   3108 
   3109     GLenum status = mResetStatus;
   3110 
   3111     if (mResetStatus != GL_NO_ERROR)
   3112     {
   3113         ASSERT(mContextLost);
   3114 
   3115         if (mRenderer->testDeviceResettable())
   3116         {
   3117             mResetStatus = GL_NO_ERROR;
   3118         }
   3119     }
   3120 
   3121     return status;
   3122 }
   3123 
   3124 bool Context::isResetNotificationEnabled()
   3125 {
   3126     return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
   3127 }
   3128 
   3129 int Context::getClientVersion() const
   3130 {
   3131     return mClientVersion;
   3132 }
   3133 
   3134 int Context::getMajorShaderModel() const
   3135 {
   3136     return mMajorShaderModel;
   3137 }
   3138 
   3139 float Context::getMaximumPointSize() const
   3140 {
   3141     return mMaximumPointSize;
   3142 }
   3143 
   3144 unsigned int Context::getMaximumCombinedTextureImageUnits() const
   3145 {
   3146     return mRenderer->getMaxCombinedTextureImageUnits();
   3147 }
   3148 
   3149 unsigned int Context::getMaximumCombinedUniformBufferBindings() const
   3150 {
   3151     return mRenderer->getMaxVertexShaderUniformBuffers() +
   3152            mRenderer->getMaxFragmentShaderUniformBuffers();
   3153 }
   3154 
   3155 int Context::getMaxSupportedSamples() const
   3156 {
   3157     return mRenderer->getMaxSupportedSamples();
   3158 }
   3159 
   3160 GLsizei Context::getMaxSupportedFormatSamples(GLenum internalFormat) const
   3161 {
   3162     return mRenderer->getMaxSupportedFormatSamples(internalFormat);
   3163 }
   3164 
   3165 GLsizei Context::getNumSampleCounts(GLenum internalFormat) const
   3166 {
   3167     return mRenderer->getNumSampleCounts(internalFormat);
   3168 }
   3169 
   3170 void Context::getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const
   3171 {
   3172     mRenderer->getSampleCounts(internalFormat, bufSize, params);
   3173 }
   3174 
   3175 unsigned int Context::getMaxTransformFeedbackBufferBindings() const
   3176 {
   3177     return mRenderer->getMaxTransformFeedbackBuffers();
   3178 }
   3179 
   3180 GLintptr Context::getUniformBufferOffsetAlignment() const
   3181 {
   3182     // setting a large alignment forces uniform buffers to bind with zero offset
   3183     return static_cast<GLintptr>(std::numeric_limits<GLint>::max());
   3184 }
   3185 
   3186 unsigned int Context::getMaximumRenderTargets() const
   3187 {
   3188     return mRenderer->getMaxRenderTargets();
   3189 }
   3190 
   3191 bool Context::supportsEventQueries() const
   3192 {
   3193     return mSupportsEventQueries;
   3194 }
   3195 
   3196 bool Context::supportsOcclusionQueries() const
   3197 {
   3198     return mSupportsOcclusionQueries;
   3199 }
   3200 
   3201 bool Context::supportsBGRATextures() const
   3202 {
   3203     return mSupportsBGRATextures;
   3204 }
   3205 
   3206 bool Context::supportsDXT1Textures() const
   3207 {
   3208     return mSupportsDXT1Textures;
   3209 }
   3210 
   3211 bool Context::supportsDXT3Textures() const
   3212 {
   3213     return mSupportsDXT3Textures;
   3214 }
   3215 
   3216 bool Context::supportsDXT5Textures() const
   3217 {
   3218     return mSupportsDXT5Textures;
   3219 }
   3220 
   3221 bool Context::supportsFloat32Textures() const
   3222 {
   3223     return mSupportsFloat32Textures;
   3224 }
   3225 
   3226 bool Context::supportsFloat32LinearFilter() const
   3227 {
   3228     return mSupportsFloat32LinearFilter;
   3229 }
   3230 
   3231 bool Context::supportsFloat32RenderableTextures() const
   3232 {
   3233     return mSupportsFloat32RenderableTextures;
   3234 }
   3235 
   3236 bool Context::supportsFloat16Textures() const
   3237 {
   3238     return mSupportsFloat16Textures;
   3239 }
   3240 
   3241 bool Context::supportsFloat16LinearFilter() const
   3242 {
   3243     return mSupportsFloat16LinearFilter;
   3244 }
   3245 
   3246 bool Context::supportsFloat16RenderableTextures() const
   3247 {
   3248     return mSupportsFloat16RenderableTextures;
   3249 }
   3250 
   3251 int Context::getMaximumRenderbufferDimension() const
   3252 {
   3253     return mMaxRenderbufferDimension;
   3254 }
   3255 
   3256 int Context::getMaximum2DTextureDimension() const
   3257 {
   3258     return mMax2DTextureDimension;
   3259 }
   3260 
   3261 int Context::getMaximumCubeTextureDimension() const
   3262 {
   3263     return mMaxCubeTextureDimension;
   3264 }
   3265 
   3266 int Context::getMaximum3DTextureDimension() const
   3267 {
   3268     return mMax3DTextureDimension;
   3269 }
   3270 
   3271 int Context::getMaximum2DArrayTextureLayers() const
   3272 {
   3273     return mMax2DArrayTextureLayers;
   3274 }
   3275 
   3276 int Context::getMaximum2DTextureLevel() const
   3277 {
   3278     return mMax2DTextureLevel;
   3279 }
   3280 
   3281 int Context::getMaximumCubeTextureLevel() const
   3282 {
   3283     return mMaxCubeTextureLevel;
   3284 }
   3285 
   3286 int Context::getMaximum3DTextureLevel() const
   3287 {
   3288     return mMax3DTextureLevel;
   3289 }
   3290 
   3291 int Context::getMaximum2DArrayTextureLevel() const
   3292 {
   3293     return mMax2DArrayTextureLevel;
   3294 }
   3295 
   3296 bool Context::supportsLuminanceTextures() const
   3297 {
   3298     return mSupportsLuminanceTextures;
   3299 }
   3300 
   3301 bool Context::supportsLuminanceAlphaTextures() const
   3302 {
   3303     return mSupportsLuminanceAlphaTextures;
   3304 }
   3305 
   3306 bool Context::supportsRGTextures() const
   3307 {
   3308     return mSupportsRGTextures;
   3309 }
   3310 
   3311 bool Context::supportsDepthTextures() const
   3312 {
   3313     return mSupportsDepthTextures;
   3314 }
   3315 
   3316 bool Context::supports32bitIndices() const
   3317 {
   3318     return mSupports32bitIndices;
   3319 }
   3320 
   3321 bool Context::supportsNonPower2Texture() const
   3322 {
   3323     return mSupportsNonPower2Texture;
   3324 }
   3325 
   3326 bool Context::supportsInstancing() const
   3327 {
   3328     return mSupportsInstancing;
   3329 }
   3330 
   3331 bool Context::supportsTextureFilterAnisotropy() const
   3332 {
   3333     return mSupportsTextureFilterAnisotropy;
   3334 }
   3335 
   3336 bool Context::supportsPBOs() const
   3337 {
   3338     return mSupportsPBOs;
   3339 }
   3340 
   3341 float Context::getTextureMaxAnisotropy() const
   3342 {
   3343     return mMaxTextureAnisotropy;
   3344 }
   3345 
   3346 void Context::getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type)
   3347 {
   3348     Framebuffer *framebuffer = getReadFramebuffer();
   3349     ASSERT(framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE);
   3350 
   3351     FramebufferAttachment *attachment = framebuffer->getReadColorbuffer();
   3352     ASSERT(attachment);
   3353 
   3354     *internalFormat = attachment->getActualFormat();
   3355     *format = gl::GetFormat(attachment->getActualFormat(), mClientVersion);
   3356     *type = gl::GetType(attachment->getActualFormat(), mClientVersion);
   3357 }
   3358 
   3359 void Context::detachBuffer(GLuint buffer)
   3360 {
   3361     // [OpenGL ES 2.0.24] section 2.9 page 22:
   3362     // If a buffer object is deleted while it is bound, all bindings to that object in the current context
   3363     // (i.e. in the thread that called Delete-Buffers) are reset to zero.
   3364 
   3365     if (mState.arrayBuffer.id() == buffer)
   3366     {
   3367         mState.arrayBuffer.set(NULL);
   3368     }
   3369 
   3370     // mark as freed among the vertex array objects
   3371     for (auto vaoIt = mVertexArrayMap.begin(); vaoIt != mVertexArrayMap.end(); vaoIt++)
   3372     {
   3373         vaoIt->second->detachBuffer(buffer);
   3374     }
   3375 }
   3376 
   3377 void Context::detachTexture(GLuint texture)
   3378 {
   3379     // [OpenGL ES 2.0.24] section 3.8 page 84:
   3380     // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
   3381     // rebound to texture object zero
   3382 
   3383     for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
   3384     {
   3385         for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
   3386         {
   3387             if (mState.samplerTexture[type][sampler].id() == texture)
   3388             {
   3389                 mState.samplerTexture[type][sampler].set(NULL);
   3390             }
   3391         }
   3392     }
   3393 
   3394     // [OpenGL ES 2.0.24] section 4.4 page 112:
   3395     // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
   3396     // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
   3397     // image was attached in the currently bound framebuffer.
   3398 
   3399     Framebuffer *readFramebuffer = getReadFramebuffer();
   3400     Framebuffer *drawFramebuffer = getDrawFramebuffer();
   3401 
   3402     if (readFramebuffer)
   3403     {
   3404         readFramebuffer->detachTexture(texture);
   3405     }
   3406 
   3407     if (drawFramebuffer && drawFramebuffer != readFramebuffer)
   3408     {
   3409         drawFramebuffer->detachTexture(texture);
   3410     }
   3411 }
   3412 
   3413 void Context::detachFramebuffer(GLuint framebuffer)
   3414 {
   3415     // [OpenGL ES 2.0.24] section 4.4 page 107:
   3416     // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
   3417     // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
   3418 
   3419     if (mState.readFramebuffer == framebuffer)
   3420     {
   3421         bindReadFramebuffer(0);
   3422     }
   3423 
   3424     if (mState.drawFramebuffer == framebuffer)
   3425     {
   3426         bindDrawFramebuffer(0);
   3427     }
   3428 }
   3429 
   3430 void Context::detachRenderbuffer(GLuint renderbuffer)
   3431 {
   3432     // [OpenGL ES 2.0.24] section 4.4 page 109:
   3433     // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
   3434     // had been executed with the target RENDERBUFFER and name of zero.
   3435 
   3436     if (mState.renderbuffer.id() == renderbuffer)
   3437     {
   3438         bindRenderbuffer(0);
   3439     }
   3440 
   3441     // [OpenGL ES 2.0.24] section 4.4 page 111:
   3442     // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
   3443     // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
   3444     // point to which this image was attached in the currently bound framebuffer.
   3445 
   3446     Framebuffer *readFramebuffer = getReadFramebuffer();
   3447     Framebuffer *drawFramebuffer = getDrawFramebuffer();
   3448 
   3449     if (readFramebuffer)
   3450     {
   3451         readFramebuffer->detachRenderbuffer(renderbuffer);
   3452     }
   3453 
   3454     if (drawFramebuffer && drawFramebuffer != readFramebuffer)
   3455     {
   3456         drawFramebuffer->detachRenderbuffer(renderbuffer);
   3457     }
   3458 }
   3459 
   3460 void Context::detachVertexArray(GLuint vertexArray)
   3461 {
   3462     // [OpenGL ES 3.0.2] section 2.10 page 43:
   3463     // If a vertex array object that is currently bound is deleted, the binding
   3464     // for that object reverts to zero and the default vertex array becomes current.
   3465     if (mState.vertexArray == vertexArray)
   3466     {
   3467         bindVertexArray(0);
   3468     }
   3469 }
   3470 
   3471 void Context::detachTransformFeedback(GLuint transformFeedback)
   3472 {
   3473     if (mState.transformFeedback.id() == transformFeedback)
   3474     {
   3475         bindTransformFeedback(0);
   3476     }
   3477 }
   3478 
   3479 void Context::detachSampler(GLuint sampler)
   3480 {
   3481     // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
   3482     // If a sampler object that is currently bound to one or more texture units is
   3483     // deleted, it is as though BindSampler is called once for each texture unit to
   3484     // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
   3485     for (unsigned int textureUnit = 0; textureUnit < ArraySize(mState.samplers); textureUnit++)
   3486     {
   3487         if (mState.samplers[textureUnit] == sampler)
   3488         {
   3489             mState.samplers[textureUnit] = 0;
   3490         }
   3491     }
   3492 }
   3493 
   3494 Texture *Context::getIncompleteTexture(TextureType type)
   3495 {
   3496     Texture *t = mIncompleteTextures[type].get();
   3497 
   3498     if (t == NULL)
   3499     {
   3500         const GLubyte color[] = { 0, 0, 0, 255 };
   3501         const PixelUnpackState incompleteUnpackState(1);
   3502 
   3503         switch (type)
   3504         {
   3505           default:
   3506             UNREACHABLE();
   3507             // default falls through to TEXTURE_2D
   3508 
   3509           case TEXTURE_2D:
   3510             {
   3511                 Texture2D *incomplete2d = new Texture2D(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
   3512                 incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
   3513                 t = incomplete2d;
   3514             }
   3515             break;
   3516 
   3517           case TEXTURE_CUBE:
   3518             {
   3519               TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
   3520 
   3521               incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
   3522               incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
   3523               incompleteCube->setImagePosY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
   3524               incompleteCube->setImageNegY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
   3525               incompleteCube->setImagePosZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
   3526               incompleteCube->setImageNegZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
   3527 
   3528               t = incompleteCube;
   3529             }
   3530             break;
   3531 
   3532           case TEXTURE_3D:
   3533             {
   3534                 Texture3D *incomplete3d = new Texture3D(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
   3535                 incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
   3536 
   3537                 t = incomplete3d;
   3538             }
   3539             break;
   3540 
   3541           case TEXTURE_2D_ARRAY:
   3542             {
   3543                 Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
   3544                 incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
   3545 
   3546                 t = incomplete2darray;
   3547             }
   3548             break;
   3549         }
   3550 
   3551         mIncompleteTextures[type].set(t);
   3552     }
   3553 
   3554     return t;
   3555 }
   3556 
   3557 bool Context::skipDraw(GLenum drawMode)
   3558 {
   3559     if (drawMode == GL_POINTS)
   3560     {
   3561         // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
   3562         // which affects varying interpolation. Since the value of gl_PointSize is
   3563         // undefined when not written, just skip drawing to avoid unexpected results.
   3564         if (!getCurrentProgramBinary()->usesPointSize())
   3565         {
   3566             // This is stictly speaking not an error, but developers should be
   3567             // notified of risking undefined behavior.
   3568             ERR("Point rendering without writing to gl_PointSize.");
   3569 
   3570             return true;
   3571         }
   3572     }
   3573     else if (IsTriangleMode(drawMode))
   3574     {
   3575         if (mState.rasterizer.cullFace && mState.rasterizer.cullMode == GL_FRONT_AND_BACK)
   3576         {
   3577             return true;
   3578         }
   3579     }
   3580 
   3581     return false;
   3582 }
   3583 
   3584 void Context::setVertexAttribf(GLuint index, const GLfloat values[4])
   3585 {
   3586     ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
   3587     mState.vertexAttribCurrentValues[index].setFloatValues(values);
   3588 }
   3589 
   3590 void Context::setVertexAttribu(GLuint index, const GLuint values[4])
   3591 {
   3592     ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
   3593     mState.vertexAttribCurrentValues[index].setUnsignedIntValues(values);
   3594 }
   3595 
   3596 void Context::setVertexAttribi(GLuint index, const GLint values[4])
   3597 {
   3598     ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
   3599     mState.vertexAttribCurrentValues[index].setIntValues(values);
   3600 }
   3601 
   3602 void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
   3603 {
   3604     getCurrentVertexArray()->setVertexAttribDivisor(index, divisor);
   3605 }
   3606 
   3607 void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
   3608 {
   3609     mResourceManager->checkSamplerAllocation(sampler);
   3610 
   3611     Sampler *samplerObject = getSampler(sampler);
   3612     ASSERT(samplerObject);
   3613 
   3614     switch (pname)
   3615     {
   3616       case GL_TEXTURE_MIN_FILTER:    samplerObject->setMinFilter(static_cast<GLenum>(param));       break;
   3617       case GL_TEXTURE_MAG_FILTER:    samplerObject->setMagFilter(static_cast<GLenum>(param));       break;
   3618       case GL_TEXTURE_WRAP_S:        samplerObject->setWrapS(static_cast<GLenum>(param));           break;
   3619       case GL_TEXTURE_WRAP_T:        samplerObject->setWrapT(static_cast<GLenum>(param));           break;
   3620       case GL_TEXTURE_WRAP_R:        samplerObject->setWrapR(static_cast<GLenum>(param));           break;
   3621       case GL_TEXTURE_MIN_LOD:       samplerObject->setMinLod(static_cast<GLfloat>(param));         break;
   3622       case GL_TEXTURE_MAX_LOD:       samplerObject->setMaxLod(static_cast<GLfloat>(param));         break;
   3623       case GL_TEXTURE_COMPARE_MODE:  samplerObject->setComparisonMode(static_cast<GLenum>(param));  break;
   3624       case GL_TEXTURE_COMPARE_FUNC:  samplerObject->setComparisonFunc(static_cast<GLenum>(param));  break;
   3625       default:                       UNREACHABLE(); break;
   3626     }
   3627 }
   3628 
   3629 void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
   3630 {
   3631     mResourceManager->checkSamplerAllocation(sampler);
   3632 
   3633     Sampler *samplerObject = getSampler(sampler);
   3634     ASSERT(samplerObject);
   3635 
   3636     switch (pname)
   3637     {
   3638       case GL_TEXTURE_MIN_FILTER:    samplerObject->setMinFilter(uiround<GLenum>(param));       break;
   3639       case GL_TEXTURE_MAG_FILTER:    samplerObject->setMagFilter(uiround<GLenum>(param));       break;
   3640       case GL_TEXTURE_WRAP_S:        samplerObject->setWrapS(uiround<GLenum>(param));           break;
   3641       case GL_TEXTURE_WRAP_T:        samplerObject->setWrapT(uiround<GLenum>(param));           break;
   3642       case GL_TEXTURE_WRAP_R:        samplerObject->setWrapR(uiround<GLenum>(param));           break;
   3643       case GL_TEXTURE_MIN_LOD:       samplerObject->setMinLod(param);                                      break;
   3644       case GL_TEXTURE_MAX_LOD:       samplerObject->setMaxLod(param);                                      break;
   3645       case GL_TEXTURE_COMPARE_MODE:  samplerObject->setComparisonMode(uiround<GLenum>(param));  break;
   3646       case GL_TEXTURE_COMPARE_FUNC:  samplerObject->setComparisonFunc(uiround<GLenum>(param));  break;
   3647       default:                       UNREACHABLE(); break;
   3648     }
   3649 }
   3650 
   3651 GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
   3652 {
   3653     mResourceManager->checkSamplerAllocation(sampler);
   3654 
   3655     Sampler *samplerObject = getSampler(sampler);
   3656     ASSERT(samplerObject);
   3657 
   3658     switch (pname)
   3659     {
   3660       case GL_TEXTURE_MIN_FILTER:    return static_cast<GLint>(samplerObject->getMinFilter());
   3661       case GL_TEXTURE_MAG_FILTER:    return static_cast<GLint>(samplerObject->getMagFilter());
   3662       case GL_TEXTURE_WRAP_S:        return static_cast<GLint>(samplerObject->getWrapS());
   3663       case GL_TEXTURE_WRAP_T:        return static_cast<GLint>(samplerObject->getWrapT());
   3664       case GL_TEXTURE_WRAP_R:        return static_cast<GLint>(samplerObject->getWrapR());
   3665       case GL_TEXTURE_MIN_LOD:       return uiround<GLint>(samplerObject->getMinLod());
   3666       case GL_TEXTURE_MAX_LOD:       return uiround<GLint>(samplerObject->getMaxLod());
   3667       case GL_TEXTURE_COMPARE_MODE:  return static_cast<GLint>(samplerObject->getComparisonMode());
   3668       case GL_TEXTURE_COMPARE_FUNC:  return static_cast<GLint>(samplerObject->getComparisonFunc());
   3669       default:                       UNREACHABLE(); return 0;
   3670     }
   3671 }
   3672 
   3673 GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
   3674 {
   3675     mResourceManager->checkSamplerAllocation(sampler);
   3676 
   3677     Sampler *samplerObject = getSampler(sampler);
   3678     ASSERT(samplerObject);
   3679 
   3680     switch (pname)
   3681     {
   3682       case GL_TEXTURE_MIN_FILTER:    return static_cast<GLfloat>(samplerObject->getMinFilter());
   3683       case GL_TEXTURE_MAG_FILTER:    return static_cast<GLfloat>(samplerObject->getMagFilter());
   3684       case GL_TEXTURE_WRAP_S:        return static_cast<GLfloat>(samplerObject->getWrapS());
   3685       case GL_TEXTURE_WRAP_T:        return static_cast<GLfloat>(samplerObject->getWrapT());
   3686       case GL_TEXTURE_WRAP_R:        return static_cast<GLfloat>(samplerObject->getWrapR());
   3687       case GL_TEXTURE_MIN_LOD:       return samplerObject->getMinLod();
   3688       case GL_TEXTURE_MAX_LOD:       return samplerObject->getMaxLod();
   3689       case GL_TEXTURE_COMPARE_MODE:  return static_cast<GLfloat>(samplerObject->getComparisonMode());
   3690       case GL_TEXTURE_COMPARE_FUNC:  return static_cast<GLfloat>(samplerObject->getComparisonFunc());
   3691       default:                       UNREACHABLE(); return 0;
   3692     }
   3693 }
   3694 
   3695 // keep list sorted in following order
   3696 // OES extensions
   3697 // EXT extensions
   3698 // Vendor extensions
   3699 void Context::initExtensionString()
   3700 {
   3701     // Do not report extension in GLES 3 contexts for now
   3702     if (mClientVersion == 2)
   3703     {
   3704         // OES extensions
   3705         if (supports32bitIndices())
   3706         {
   3707             mExtensionStringList.push_back("GL_OES_element_index_uint");
   3708         }
   3709 
   3710         mExtensionStringList.push_back("GL_OES_packed_depth_stencil");
   3711         mExtensionStringList.push_back("GL_OES_get_program_binary");
   3712         mExtensionStringList.push_back("GL_OES_rgb8_rgba8");
   3713 
   3714         if (supportsPBOs())
   3715         {
   3716             mExtensionStringList.push_back("NV_pixel_buffer_object");
   3717             mExtensionStringList.push_back("GL_OES_mapbuffer");
   3718             mExtensionStringList.push_back("GL_EXT_map_buffer_range");
   3719         }
   3720 
   3721         if (mRenderer->getDerivativeInstructionSupport())
   3722         {
   3723             mExtensionStringList.push_back("GL_OES_standard_derivatives");
   3724         }
   3725 
   3726         if (supportsFloat16Textures())
   3727         {
   3728             mExtensionStringList.push_back("GL_OES_texture_half_float");
   3729         }
   3730         if (supportsFloat16LinearFilter())
   3731         {
   3732             mExtensionStringList.push_back("GL_OES_texture_half_float_linear");
   3733         }
   3734         if (supportsFloat32Textures())
   3735         {
   3736             mExtensionStringList.push_back("GL_OES_texture_float");
   3737         }
   3738         if (supportsFloat32LinearFilter())
   3739         {
   3740             mExtensionStringList.push_back("GL_OES_texture_float_linear");
   3741         }
   3742 
   3743         if (supportsRGTextures())
   3744         {
   3745             mExtensionStringList.push_back("GL_EXT_texture_rg");
   3746         }
   3747 
   3748         if (supportsNonPower2Texture())
   3749         {
   3750             mExtensionStringList.push_back("GL_OES_texture_npot");
   3751         }
   3752 
   3753         // Multi-vendor (EXT) extensions
   3754         if (supportsOcclusionQueries())
   3755         {
   3756             mExtensionStringList.push_back("GL_EXT_occlusion_query_boolean");
   3757         }
   3758 
   3759         mExtensionStringList.push_back("GL_EXT_read_format_bgra");
   3760         mExtensionStringList.push_back("GL_EXT_robustness");
   3761         mExtensionStringList.push_back("GL_EXT_shader_texture_lod");
   3762 
   3763         if (supportsDXT1Textures())
   3764         {
   3765             mExtensionStringList.push_back("GL_EXT_texture_compression_dxt1");
   3766         }
   3767 
   3768         if (supportsTextureFilterAnisotropy())
   3769         {
   3770             mExtensionStringList.push_back("GL_EXT_texture_filter_anisotropic");
   3771         }
   3772 
   3773         if (supportsBGRATextures())
   3774         {
   3775             mExtensionStringList.push_back("GL_EXT_texture_format_BGRA8888");
   3776         }
   3777 
   3778         if (mRenderer->getMaxRenderTargets() > 1)
   3779         {
   3780             mExtensionStringList.push_back("GL_EXT_draw_buffers");
   3781         }
   3782 
   3783         mExtensionStringList.push_back("GL_EXT_texture_storage");
   3784         mExtensionStringList.push_back("GL_EXT_frag_depth");
   3785         mExtensionStringList.push_back("GL_EXT_blend_minmax");
   3786 
   3787         // ANGLE-specific extensions
   3788         if (supportsDepthTextures())
   3789         {
   3790             mExtensionStringList.push_back("GL_ANGLE_depth_texture");
   3791         }
   3792 
   3793         mExtensionStringList.push_back("GL_ANGLE_framebuffer_blit");
   3794         if (getMaxSupportedSamples() != 0)
   3795         {
   3796             mExtensionStringList.push_back("GL_ANGLE_framebuffer_multisample");
   3797         }
   3798 
   3799         if (supportsInstancing())
   3800         {
   3801             mExtensionStringList.push_back("GL_ANGLE_instanced_arrays");
   3802         }
   3803 
   3804         mExtensionStringList.push_back("GL_ANGLE_pack_reverse_row_order");
   3805 
   3806         if (supportsDXT3Textures())
   3807         {
   3808             mExtensionStringList.push_back("GL_ANGLE_texture_compression_dxt3");
   3809         }
   3810         if (supportsDXT5Textures())
   3811         {
   3812             mExtensionStringList.push_back("GL_ANGLE_texture_compression_dxt5");
   3813         }
   3814 
   3815         mExtensionStringList.push_back("GL_ANGLE_texture_usage");
   3816         mExtensionStringList.push_back("GL_ANGLE_translated_shader_source");
   3817 
   3818         // Other vendor-specific extensions
   3819         if (supportsEventQueries())
   3820         {
   3821             mExtensionStringList.push_back("GL_NV_fence");
   3822         }
   3823     }
   3824 
   3825     if (mClientVersion == 3)
   3826     {
   3827         mExtensionStringList.push_back("GL_EXT_color_buffer_float");
   3828 
   3829         mExtensionStringList.push_back("GL_EXT_read_format_bgra");
   3830 
   3831         if (supportsBGRATextures())
   3832         {
   3833             mExtensionStringList.push_back("GL_EXT_texture_format_BGRA8888");
   3834         }
   3835     }
   3836 
   3837     // Join the extension strings to one long string for use with GetString
   3838     std::stringstream strstr;
   3839     for (unsigned int extensionIndex = 0; extensionIndex < mExtensionStringList.size(); extensionIndex++)
   3840     {
   3841         strstr << mExtensionStringList[extensionIndex];
   3842         strstr << " ";
   3843     }
   3844 
   3845     mCombinedExtensionsString = makeStaticString(strstr.str());
   3846 }
   3847 
   3848 const char *Context::getCombinedExtensionsString() const
   3849 {
   3850     return mCombinedExtensionsString;
   3851 }
   3852 
   3853 const char *Context::getExtensionString(const GLuint index) const
   3854 {
   3855     ASSERT(index < mExtensionStringList.size());
   3856     return mExtensionStringList[index].c_str();
   3857 }
   3858 
   3859 unsigned int Context::getNumExtensions() const
   3860 {
   3861     return mExtensionStringList.size();
   3862 }
   3863 
   3864 void Context::initRendererString()
   3865 {
   3866     std::ostringstream rendererString;
   3867     rendererString << "ANGLE (";
   3868     rendererString << mRenderer->getRendererDescription();
   3869     rendererString << ")";
   3870 
   3871     mRendererString = makeStaticString(rendererString.str());
   3872 }
   3873 
   3874 const char *Context::getRendererString() const
   3875 {
   3876     return mRendererString;
   3877 }
   3878 
   3879 size_t Context::getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray)
   3880 {
   3881     size_t serialCount = 0;
   3882 
   3883     Framebuffer *drawFramebuffer = getDrawFramebuffer();
   3884     for (unsigned int i = 0; i < IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
   3885     {
   3886         FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i);
   3887         if (attachment && attachment->isTexture())
   3888         {
   3889             (*outSerialArray)[serialCount++] = attachment->getTextureSerial();
   3890         }
   3891     }
   3892 
   3893     FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer();
   3894     if (depthStencilAttachment && depthStencilAttachment->isTexture())
   3895     {
   3896         (*outSerialArray)[serialCount++] = depthStencilAttachment->getTextureSerial();
   3897     }
   3898 
   3899     std::sort(outSerialArray->begin(), outSerialArray->begin() + serialCount);
   3900 
   3901     return serialCount;
   3902 }
   3903 
   3904 void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
   3905                               GLbitfield mask, GLenum filter)
   3906 {
   3907     Framebuffer *readFramebuffer = getReadFramebuffer();
   3908     Framebuffer *drawFramebuffer = getDrawFramebuffer();
   3909 
   3910     bool blitRenderTarget = false;
   3911     bool blitDepth = false;
   3912     bool blitStencil = false;
   3913     if ((mask & GL_COLOR_BUFFER_BIT) && readFramebuffer->getReadColorbuffer() && drawFramebuffer->getFirstColorbuffer())
   3914     {
   3915         blitRenderTarget = true;
   3916     }
   3917     if ((mask & GL_STENCIL_BUFFER_BIT) && readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
   3918     {
   3919         blitStencil = true;
   3920     }
   3921     if ((mask & GL_DEPTH_BUFFER_BIT) && readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
   3922     {
   3923         blitDepth = true;
   3924     }
   3925 
   3926     gl::Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
   3927     gl::Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
   3928     if (blitRenderTarget || blitDepth || blitStencil)
   3929     {
   3930         const gl::Rectangle *scissor = mState.scissorTest ? &mState.scissor : NULL;
   3931         mRenderer->blitRect(readFramebuffer, srcRect, drawFramebuffer, dstRect, scissor,
   3932                             blitRenderTarget, blitDepth, blitStencil, filter);
   3933     }
   3934 }
   3935 
   3936 void Context::invalidateFrameBuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments,
   3937                                     GLint x, GLint y, GLsizei width, GLsizei height)
   3938 {
   3939     Framebuffer *frameBuffer = NULL;
   3940     switch (target)
   3941     {
   3942       case GL_FRAMEBUFFER:
   3943       case GL_DRAW_FRAMEBUFFER:
   3944         frameBuffer = getDrawFramebuffer();
   3945         break;
   3946       case GL_READ_FRAMEBUFFER:
   3947         frameBuffer = getReadFramebuffer();
   3948         break;
   3949       default:
   3950         UNREACHABLE();
   3951     }
   3952 
   3953     if (frameBuffer && frameBuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
   3954     {
   3955         for (int i = 0; i < numAttachments; ++i)
   3956         {
   3957             rx::RenderTarget *renderTarget = NULL;
   3958 
   3959             if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT15)
   3960             {
   3961                 gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(attachments[i] - GL_COLOR_ATTACHMENT0);
   3962                 if (attachment)
   3963                 {
   3964                     renderTarget = attachment->getRenderTarget();
   3965                 }
   3966             }
   3967             else if (attachments[i] == GL_COLOR)
   3968             {
   3969                  gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(0);
   3970                  if (attachment)
   3971                  {
   3972                      renderTarget = attachment->getRenderTarget();
   3973                  }
   3974             }
   3975             else
   3976             {
   3977                 gl::FramebufferAttachment *attachment = NULL;
   3978                 switch (attachments[i])
   3979                 {
   3980                   case GL_DEPTH_ATTACHMENT:
   3981                   case GL_DEPTH:
   3982                     attachment = frameBuffer->getDepthbuffer();
   3983                     break;
   3984                   case GL_STENCIL_ATTACHMENT:
   3985                   case GL_STENCIL:
   3986                     attachment = frameBuffer->getStencilbuffer();
   3987                     break;
   3988                   case GL_DEPTH_STENCIL_ATTACHMENT:
   3989                     attachment = frameBuffer->getDepthOrStencilbuffer();
   3990                     break;
   3991                   default:
   3992                     UNREACHABLE();
   3993                 }
   3994 
   3995                 if (attachment)
   3996                 {
   3997                     renderTarget = attachment->getDepthStencil();
   3998                 }
   3999             }
   4000 
   4001             if (renderTarget)
   4002             {
   4003                 renderTarget->invalidate(x, y, width, height);
   4004             }
   4005         }
   4006     }
   4007 }
   4008 
   4009 bool Context::hasMappedBuffer(GLenum target) const
   4010 {
   4011     if (target == GL_ARRAY_BUFFER)
   4012     {
   4013         for (unsigned int attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++)
   4014         {
   4015             const gl::VertexAttribute &vertexAttrib = getVertexAttribState(attribIndex);
   4016             gl::Buffer *boundBuffer = vertexAttrib.mBoundBuffer.get();
   4017             if (vertexAttrib.mArrayEnabled && boundBuffer && boundBuffer->mapped())
   4018             {
   4019                 return true;
   4020             }
   4021         }
   4022     }
   4023     else if (target == GL_ELEMENT_ARRAY_BUFFER)
   4024     {
   4025         Buffer *elementBuffer = getElementArrayBuffer();
   4026         return (elementBuffer && elementBuffer->mapped());
   4027     }
   4028     else if (target == GL_TRANSFORM_FEEDBACK_BUFFER)
   4029     {
   4030         UNIMPLEMENTED();
   4031     }
   4032     else UNREACHABLE();
   4033     return false;
   4034 }
   4035 
   4036 }
   4037 
   4038 extern "C"
   4039 {
   4040 gl::Context *glCreateContext(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
   4041 {
   4042     return new gl::Context(clientVersion, shareContext, renderer, notifyResets, robustAccess);
   4043 }
   4044 
   4045 void glDestroyContext(gl::Context *context)
   4046 {
   4047     delete context;
   4048 
   4049     if (context == gl::getContext())
   4050     {
   4051         gl::makeCurrent(NULL, NULL, NULL);
   4052     }
   4053 }
   4054 
   4055 void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface)
   4056 {
   4057     gl::makeCurrent(context, display, surface);
   4058 }
   4059 
   4060 gl::Context *glGetCurrentContext()
   4061 {
   4062     return gl::getContext();
   4063 }
   4064 
   4065 }
   4066