Home | History | Annotate | Download | only in libGLESv2
      1 #include "precompiled.h"
      2 //
      3 // Copyright (c) 2002-2013 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 "libGLESv2/utilities.h"
     15 #include "libGLESv2/Buffer.h"
     16 #include "libGLESv2/Fence.h"
     17 #include "libGLESv2/Framebuffer.h"
     18 #include "libGLESv2/Renderbuffer.h"
     19 #include "libGLESv2/Program.h"
     20 #include "libGLESv2/ProgramBinary.h"
     21 #include "libGLESv2/Query.h"
     22 #include "libGLESv2/Texture.h"
     23 #include "libGLESv2/ResourceManager.h"
     24 #include "libGLESv2/renderer/IndexDataManager.h"
     25 #include "libGLESv2/renderer/RenderTarget.h"
     26 #include "libGLESv2/renderer/Renderer.h"
     27 
     28 #include "libEGL/Surface.h"
     29 
     30 #undef near
     31 #undef far
     32 
     33 namespace gl
     34 {
     35 static const char* makeStaticString(const std::string& str)
     36 {
     37     static std::set<std::string> strings;
     38     std::set<std::string>::iterator it = strings.find(str);
     39     if (it != strings.end())
     40       return it->c_str();
     41 
     42     return strings.insert(str).first->c_str();
     43 }
     44 
     45 Context::Context(const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) : mRenderer(renderer)
     46 {
     47     ASSERT(robustAccess == false);   // Unimplemented
     48 
     49     mFenceHandleAllocator.setBaseHandle(0);
     50 
     51     setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
     52 
     53     mState.depthClearValue = 1.0f;
     54     mState.stencilClearValue = 0;
     55 
     56     mState.rasterizer.cullFace = false;
     57     mState.rasterizer.cullMode = GL_BACK;
     58     mState.rasterizer.frontFace = GL_CCW;
     59     mState.rasterizer.polygonOffsetFill = false;
     60     mState.rasterizer.polygonOffsetFactor = 0.0f;
     61     mState.rasterizer.polygonOffsetUnits = 0.0f;
     62     mState.rasterizer.pointDrawMode = false;
     63     mState.rasterizer.multiSample = false;
     64     mState.scissorTest = false;
     65     mState.scissor.x = 0;
     66     mState.scissor.y = 0;
     67     mState.scissor.width = 0;
     68     mState.scissor.height = 0;
     69 
     70     mState.blend.blend = false;
     71     mState.blend.sourceBlendRGB = GL_ONE;
     72     mState.blend.sourceBlendAlpha = GL_ONE;
     73     mState.blend.destBlendRGB = GL_ZERO;
     74     mState.blend.destBlendAlpha = GL_ZERO;
     75     mState.blend.blendEquationRGB = GL_FUNC_ADD;
     76     mState.blend.blendEquationAlpha = GL_FUNC_ADD;
     77     mState.blend.sampleAlphaToCoverage = false;
     78     mState.blend.dither = true;
     79 
     80     mState.blendColor.red = 0;
     81     mState.blendColor.green = 0;
     82     mState.blendColor.blue = 0;
     83     mState.blendColor.alpha = 0;
     84 
     85     mState.depthStencil.depthTest = false;
     86     mState.depthStencil.depthFunc = GL_LESS;
     87     mState.depthStencil.depthMask = true;
     88     mState.depthStencil.stencilTest = false;
     89     mState.depthStencil.stencilFunc = GL_ALWAYS;
     90     mState.depthStencil.stencilMask = -1;
     91     mState.depthStencil.stencilWritemask = -1;
     92     mState.depthStencil.stencilBackFunc = GL_ALWAYS;
     93     mState.depthStencil.stencilBackMask = - 1;
     94     mState.depthStencil.stencilBackWritemask = -1;
     95     mState.depthStencil.stencilFail = GL_KEEP;
     96     mState.depthStencil.stencilPassDepthFail = GL_KEEP;
     97     mState.depthStencil.stencilPassDepthPass = GL_KEEP;
     98     mState.depthStencil.stencilBackFail = GL_KEEP;
     99     mState.depthStencil.stencilBackPassDepthFail = GL_KEEP;
    100     mState.depthStencil.stencilBackPassDepthPass = GL_KEEP;
    101 
    102     mState.stencilRef = 0;
    103     mState.stencilBackRef = 0;
    104 
    105     mState.sampleCoverage = false;
    106     mState.sampleCoverageValue = 1.0f;
    107     mState.sampleCoverageInvert = false;
    108     mState.generateMipmapHint = GL_DONT_CARE;
    109     mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
    110 
    111     mState.lineWidth = 1.0f;
    112 
    113     mState.viewport.x = 0;
    114     mState.viewport.y = 0;
    115     mState.viewport.width = 0;
    116     mState.viewport.height = 0;
    117     mState.zNear = 0.0f;
    118     mState.zFar = 1.0f;
    119 
    120     mState.blend.colorMaskRed = true;
    121     mState.blend.colorMaskGreen = true;
    122     mState.blend.colorMaskBlue = true;
    123     mState.blend.colorMaskAlpha = true;
    124 
    125     if (shareContext != NULL)
    126     {
    127         mResourceManager = shareContext->mResourceManager;
    128         mResourceManager->addRef();
    129     }
    130     else
    131     {
    132         mResourceManager = new ResourceManager(mRenderer);
    133     }
    134 
    135     // [OpenGL ES 2.0.24] section 3.7 page 83:
    136     // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
    137     // and cube map texture state vectors respectively associated with them.
    138     // In order that access to these initial textures not be lost, they are treated as texture
    139     // objects all of whose names are 0.
    140 
    141     mTexture2DZero.set(new Texture2D(mRenderer, 0));
    142     mTextureCubeMapZero.set(new TextureCubeMap(mRenderer, 0));
    143 
    144     mState.activeSampler = 0;
    145     bindArrayBuffer(0);
    146     bindElementArrayBuffer(0);
    147     bindTextureCubeMap(0);
    148     bindTexture2D(0);
    149     bindReadFramebuffer(0);
    150     bindDrawFramebuffer(0);
    151     bindRenderbuffer(0);
    152 
    153     mState.currentProgram = 0;
    154     mCurrentProgramBinary.set(NULL);
    155 
    156     mState.packAlignment = 4;
    157     mState.unpackAlignment = 4;
    158     mState.packReverseRowOrder = false;
    159 
    160     mExtensionString = NULL;
    161     mRendererString = NULL;
    162 
    163     mInvalidEnum = false;
    164     mInvalidValue = false;
    165     mInvalidOperation = false;
    166     mOutOfMemory = false;
    167     mInvalidFramebufferOperation = false;
    168 
    169     mHasBeenCurrent = false;
    170     mContextLost = false;
    171     mResetStatus = GL_NO_ERROR;
    172     mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
    173     mRobustAccess = robustAccess;
    174 
    175     mSupportsBGRATextures = false;
    176     mSupportsDXT1Textures = false;
    177     mSupportsDXT3Textures = false;
    178     mSupportsDXT5Textures = false;
    179     mSupportsEventQueries = false;
    180     mSupportsOcclusionQueries = false;
    181     mNumCompressedTextureFormats = 0;
    182 }
    183 
    184 Context::~Context()
    185 {
    186     if (mState.currentProgram != 0)
    187     {
    188         Program *programObject = mResourceManager->getProgram(mState.currentProgram);
    189         if (programObject)
    190         {
    191             programObject->release();
    192         }
    193         mState.currentProgram = 0;
    194     }
    195     mCurrentProgramBinary.set(NULL);
    196 
    197     while (!mFramebufferMap.empty())
    198     {
    199         deleteFramebuffer(mFramebufferMap.begin()->first);
    200     }
    201 
    202     while (!mFenceMap.empty())
    203     {
    204         deleteFence(mFenceMap.begin()->first);
    205     }
    206 
    207     while (!mQueryMap.empty())
    208     {
    209         deleteQuery(mQueryMap.begin()->first);
    210     }
    211 
    212     for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
    213     {
    214         for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
    215         {
    216             mState.samplerTexture[type][sampler].set(NULL);
    217         }
    218     }
    219 
    220     for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
    221     {
    222         mIncompleteTextures[type].set(NULL);
    223     }
    224 
    225     for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
    226     {
    227         mState.vertexAttribute[i].mBoundBuffer.set(NULL);
    228     }
    229 
    230     for (int i = 0; i < QUERY_TYPE_COUNT; i++)
    231     {
    232         mState.activeQuery[i].set(NULL);
    233     }
    234 
    235     mState.arrayBuffer.set(NULL);
    236     mState.elementArrayBuffer.set(NULL);
    237     mState.renderbuffer.set(NULL);
    238 
    239     mTexture2DZero.set(NULL);
    240     mTextureCubeMapZero.set(NULL);
    241 
    242     mResourceManager->release();
    243 }
    244 
    245 void Context::makeCurrent(egl::Surface *surface)
    246 {
    247     if (!mHasBeenCurrent)
    248     {
    249         mMajorShaderModel = mRenderer->getMajorShaderModel();
    250         mMaximumPointSize = mRenderer->getMaxPointSize();
    251         mSupportsVertexTexture = mRenderer->getVertexTextureSupport();
    252         mSupportsNonPower2Texture = mRenderer->getNonPower2TextureSupport();
    253         mSupportsInstancing = mRenderer->getInstancingSupport();
    254 
    255         mMaxViewportDimension = mRenderer->getMaxViewportDimension();
    256         mMaxTextureDimension = std::min(std::min(mRenderer->getMaxTextureWidth(), mRenderer->getMaxTextureHeight()),
    257                                         (int)gl::IMPLEMENTATION_MAX_TEXTURE_SIZE);
    258         mMaxCubeTextureDimension = std::min(mMaxTextureDimension, (int)gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE);
    259         mMaxRenderbufferDimension = mMaxTextureDimension;
    260         mMaxTextureLevel = log2(mMaxTextureDimension) + 1;
    261         mMaxTextureAnisotropy = mRenderer->getTextureMaxAnisotropy();
    262         TRACE("MaxTextureDimension=%d, MaxCubeTextureDimension=%d, MaxRenderbufferDimension=%d, MaxTextureLevel=%d, MaxTextureAnisotropy=%f",
    263               mMaxTextureDimension, mMaxCubeTextureDimension, mMaxRenderbufferDimension, mMaxTextureLevel, mMaxTextureAnisotropy);
    264 
    265         mSupportsEventQueries = mRenderer->getEventQuerySupport();
    266         mSupportsOcclusionQueries = mRenderer->getOcclusionQuerySupport();
    267         mSupportsBGRATextures = mRenderer->getBGRATextureSupport();
    268         mSupportsDXT1Textures = mRenderer->getDXT1TextureSupport();
    269         mSupportsDXT3Textures = mRenderer->getDXT3TextureSupport();
    270         mSupportsDXT5Textures = mRenderer->getDXT5TextureSupport();
    271         mSupportsFloat32Textures = mRenderer->getFloat32TextureSupport(&mSupportsFloat32LinearFilter, &mSupportsFloat32RenderableTextures);
    272         mSupportsFloat16Textures = mRenderer->getFloat16TextureSupport(&mSupportsFloat16LinearFilter, &mSupportsFloat16RenderableTextures);
    273         mSupportsLuminanceTextures = mRenderer->getLuminanceTextureSupport();
    274         mSupportsLuminanceAlphaTextures = mRenderer->getLuminanceAlphaTextureSupport();
    275         mSupportsDepthTextures = mRenderer->getDepthTextureSupport();
    276         mSupportsTextureFilterAnisotropy = mRenderer->getTextureFilterAnisotropySupport();
    277         mSupports32bitIndices = mRenderer->get32BitIndexSupport();
    278 
    279         mNumCompressedTextureFormats = 0;
    280         if (supportsDXT1Textures())
    281         {
    282             mNumCompressedTextureFormats += 2;
    283         }
    284         if (supportsDXT3Textures())
    285         {
    286             mNumCompressedTextureFormats += 1;
    287         }
    288         if (supportsDXT5Textures())
    289         {
    290             mNumCompressedTextureFormats += 1;
    291         }
    292 
    293         initExtensionString();
    294         initRendererString();
    295 
    296         mState.viewport.x = 0;
    297         mState.viewport.y = 0;
    298         mState.viewport.width = surface->getWidth();
    299         mState.viewport.height = surface->getHeight();
    300 
    301         mState.scissor.x = 0;
    302         mState.scissor.y = 0;
    303         mState.scissor.width = surface->getWidth();
    304         mState.scissor.height = surface->getHeight();
    305 
    306         mHasBeenCurrent = true;
    307     }
    308 
    309     // Wrap the existing swapchain resources into GL objects and assign them to the '0' names
    310     rx::SwapChain *swapchain = surface->getSwapChain();
    311 
    312     Colorbuffer *colorbufferZero = new Colorbuffer(mRenderer, swapchain);
    313     DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(mRenderer, swapchain);
    314     Framebuffer *framebufferZero = new DefaultFramebuffer(mRenderer, colorbufferZero, depthStencilbufferZero);
    315 
    316     setFramebufferZero(framebufferZero);
    317 }
    318 
    319 // NOTE: this function should not assume that this context is current!
    320 void Context::markContextLost()
    321 {
    322     if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
    323         mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
    324     mContextLost = true;
    325 }
    326 
    327 bool Context::isContextLost()
    328 {
    329     return mContextLost;
    330 }
    331 
    332 void Context::setClearColor(float red, float green, float blue, float alpha)
    333 {
    334     mState.colorClearValue.red = red;
    335     mState.colorClearValue.green = green;
    336     mState.colorClearValue.blue = blue;
    337     mState.colorClearValue.alpha = alpha;
    338 }
    339 
    340 void Context::setClearDepth(float depth)
    341 {
    342     mState.depthClearValue = depth;
    343 }
    344 
    345 void Context::setClearStencil(int stencil)
    346 {
    347     mState.stencilClearValue = stencil;
    348 }
    349 
    350 void Context::setCullFace(bool enabled)
    351 {
    352     mState.rasterizer.cullFace = enabled;
    353 }
    354 
    355 bool Context::isCullFaceEnabled() const
    356 {
    357     return mState.rasterizer.cullFace;
    358 }
    359 
    360 void Context::setCullMode(GLenum mode)
    361 {
    362     mState.rasterizer.cullMode = mode;
    363 }
    364 
    365 void Context::setFrontFace(GLenum front)
    366 {
    367     mState.rasterizer.frontFace = front;
    368 }
    369 
    370 void Context::setDepthTest(bool enabled)
    371 {
    372     mState.depthStencil.depthTest = enabled;
    373 }
    374 
    375 bool Context::isDepthTestEnabled() const
    376 {
    377     return mState.depthStencil.depthTest;
    378 }
    379 
    380 void Context::setDepthFunc(GLenum depthFunc)
    381 {
    382      mState.depthStencil.depthFunc = depthFunc;
    383 }
    384 
    385 void Context::setDepthRange(float zNear, float zFar)
    386 {
    387     mState.zNear = zNear;
    388     mState.zFar = zFar;
    389 }
    390 
    391 void Context::setBlend(bool enabled)
    392 {
    393     mState.blend.blend = enabled;
    394 }
    395 
    396 bool Context::isBlendEnabled() const
    397 {
    398     return mState.blend.blend;
    399 }
    400 
    401 void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
    402 {
    403     mState.blend.sourceBlendRGB = sourceRGB;
    404     mState.blend.destBlendRGB = destRGB;
    405     mState.blend.sourceBlendAlpha = sourceAlpha;
    406     mState.blend.destBlendAlpha = destAlpha;
    407 }
    408 
    409 void Context::setBlendColor(float red, float green, float blue, float alpha)
    410 {
    411     mState.blendColor.red = red;
    412     mState.blendColor.green = green;
    413     mState.blendColor.blue = blue;
    414     mState.blendColor.alpha = alpha;
    415 }
    416 
    417 void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
    418 {
    419     mState.blend.blendEquationRGB = rgbEquation;
    420     mState.blend.blendEquationAlpha = alphaEquation;
    421 }
    422 
    423 void Context::setStencilTest(bool enabled)
    424 {
    425     mState.depthStencil.stencilTest = enabled;
    426 }
    427 
    428 bool Context::isStencilTestEnabled() const
    429 {
    430     return mState.depthStencil.stencilTest;
    431 }
    432 
    433 void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
    434 {
    435     mState.depthStencil.stencilFunc = stencilFunc;
    436     mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
    437     mState.depthStencil.stencilMask = stencilMask;
    438 }
    439 
    440 void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
    441 {
    442     mState.depthStencil.stencilBackFunc = stencilBackFunc;
    443     mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
    444     mState.depthStencil.stencilBackMask = stencilBackMask;
    445 }
    446 
    447 void Context::setStencilWritemask(GLuint stencilWritemask)
    448 {
    449     mState.depthStencil.stencilWritemask = stencilWritemask;
    450 }
    451 
    452 void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
    453 {
    454     mState.depthStencil.stencilBackWritemask = stencilBackWritemask;
    455 }
    456 
    457 void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
    458 {
    459     mState.depthStencil.stencilFail = stencilFail;
    460     mState.depthStencil.stencilPassDepthFail = stencilPassDepthFail;
    461     mState.depthStencil.stencilPassDepthPass = stencilPassDepthPass;
    462 }
    463 
    464 void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
    465 {
    466     mState.depthStencil.stencilBackFail = stencilBackFail;
    467     mState.depthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
    468     mState.depthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
    469 }
    470 
    471 void Context::setPolygonOffsetFill(bool enabled)
    472 {
    473      mState.rasterizer.polygonOffsetFill = enabled;
    474 }
    475 
    476 bool Context::isPolygonOffsetFillEnabled() const
    477 {
    478     return mState.rasterizer.polygonOffsetFill;
    479 }
    480 
    481 void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
    482 {
    483     // An application can pass NaN values here, so handle this gracefully
    484     mState.rasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
    485     mState.rasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
    486 }
    487 
    488 void Context::setSampleAlphaToCoverage(bool enabled)
    489 {
    490     mState.blend.sampleAlphaToCoverage = enabled;
    491 }
    492 
    493 bool Context::isSampleAlphaToCoverageEnabled() const
    494 {
    495     return mState.blend.sampleAlphaToCoverage;
    496 }
    497 
    498 void Context::setSampleCoverage(bool enabled)
    499 {
    500     mState.sampleCoverage = enabled;
    501 }
    502 
    503 bool Context::isSampleCoverageEnabled() const
    504 {
    505     return mState.sampleCoverage;
    506 }
    507 
    508 void Context::setSampleCoverageParams(GLclampf value, bool invert)
    509 {
    510     mState.sampleCoverageValue = value;
    511     mState.sampleCoverageInvert = invert;
    512 }
    513 
    514 void Context::setScissorTest(bool enabled)
    515 {
    516     mState.scissorTest = enabled;
    517 }
    518 
    519 bool Context::isScissorTestEnabled() const
    520 {
    521     return mState.scissorTest;
    522 }
    523 
    524 void Context::setDither(bool enabled)
    525 {
    526     mState.blend.dither = enabled;
    527 }
    528 
    529 bool Context::isDitherEnabled() const
    530 {
    531     return mState.blend.dither;
    532 }
    533 
    534 void Context::setLineWidth(GLfloat width)
    535 {
    536     mState.lineWidth = width;
    537 }
    538 
    539 void Context::setGenerateMipmapHint(GLenum hint)
    540 {
    541     mState.generateMipmapHint = hint;
    542 }
    543 
    544 void Context::setFragmentShaderDerivativeHint(GLenum hint)
    545 {
    546     mState.fragmentShaderDerivativeHint = hint;
    547     // TODO: Propagate the hint to shader translator so we can write
    548     // ddx, ddx_coarse, or ddx_fine depending on the hint.
    549     // Ignore for now. It is valid for implementations to ignore hint.
    550 }
    551 
    552 void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
    553 {
    554     mState.viewport.x = x;
    555     mState.viewport.y = y;
    556     mState.viewport.width = width;
    557     mState.viewport.height = height;
    558 }
    559 
    560 void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
    561 {
    562     mState.scissor.x = x;
    563     mState.scissor.y = y;
    564     mState.scissor.width = width;
    565     mState.scissor.height = height;
    566 }
    567 
    568 void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
    569 {
    570     mState.blend.colorMaskRed = red;
    571     mState.blend.colorMaskGreen = green;
    572     mState.blend.colorMaskBlue = blue;
    573     mState.blend.colorMaskAlpha = alpha;
    574 }
    575 
    576 void Context::setDepthMask(bool mask)
    577 {
    578     mState.depthStencil.depthMask = mask;
    579 }
    580 
    581 void Context::setActiveSampler(unsigned int active)
    582 {
    583     mState.activeSampler = active;
    584 }
    585 
    586 GLuint Context::getReadFramebufferHandle() const
    587 {
    588     return mState.readFramebuffer;
    589 }
    590 
    591 GLuint Context::getDrawFramebufferHandle() const
    592 {
    593     return mState.drawFramebuffer;
    594 }
    595 
    596 GLuint Context::getRenderbufferHandle() const
    597 {
    598     return mState.renderbuffer.id();
    599 }
    600 
    601 GLuint Context::getArrayBufferHandle() const
    602 {
    603     return mState.arrayBuffer.id();
    604 }
    605 
    606 GLuint Context::getActiveQuery(GLenum target) const
    607 {
    608     Query *queryObject = NULL;
    609 
    610     switch (target)
    611     {
    612       case GL_ANY_SAMPLES_PASSED_EXT:
    613         queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED].get();
    614         break;
    615       case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
    616         queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE].get();
    617         break;
    618       default:
    619         ASSERT(false);
    620     }
    621 
    622     if (queryObject)
    623     {
    624         return queryObject->id();
    625     }
    626     else
    627     {
    628         return 0;
    629     }
    630 }
    631 
    632 void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
    633 {
    634     mState.vertexAttribute[attribNum].mArrayEnabled = enabled;
    635 }
    636 
    637 const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
    638 {
    639     return mState.vertexAttribute[attribNum];
    640 }
    641 
    642 void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
    643                                    GLsizei stride, const void *pointer)
    644 {
    645     mState.vertexAttribute[attribNum].mBoundBuffer.set(boundBuffer);
    646     mState.vertexAttribute[attribNum].mSize = size;
    647     mState.vertexAttribute[attribNum].mType = type;
    648     mState.vertexAttribute[attribNum].mNormalized = normalized;
    649     mState.vertexAttribute[attribNum].mStride = stride;
    650     mState.vertexAttribute[attribNum].mPointer = pointer;
    651 }
    652 
    653 const void *Context::getVertexAttribPointer(unsigned int attribNum) const
    654 {
    655     return mState.vertexAttribute[attribNum].mPointer;
    656 }
    657 
    658 void Context::setPackAlignment(GLint alignment)
    659 {
    660     mState.packAlignment = alignment;
    661 }
    662 
    663 GLint Context::getPackAlignment() const
    664 {
    665     return mState.packAlignment;
    666 }
    667 
    668 void Context::setUnpackAlignment(GLint alignment)
    669 {
    670     mState.unpackAlignment = alignment;
    671 }
    672 
    673 GLint Context::getUnpackAlignment() const
    674 {
    675     return mState.unpackAlignment;
    676 }
    677 
    678 void Context::setPackReverseRowOrder(bool reverseRowOrder)
    679 {
    680     mState.packReverseRowOrder = reverseRowOrder;
    681 }
    682 
    683 bool Context::getPackReverseRowOrder() const
    684 {
    685     return mState.packReverseRowOrder;
    686 }
    687 
    688 GLuint Context::createBuffer()
    689 {
    690     return mResourceManager->createBuffer();
    691 }
    692 
    693 GLuint Context::createProgram()
    694 {
    695     return mResourceManager->createProgram();
    696 }
    697 
    698 GLuint Context::createShader(GLenum type)
    699 {
    700     return mResourceManager->createShader(type);
    701 }
    702 
    703 GLuint Context::createTexture()
    704 {
    705     return mResourceManager->createTexture();
    706 }
    707 
    708 GLuint Context::createRenderbuffer()
    709 {
    710     return mResourceManager->createRenderbuffer();
    711 }
    712 
    713 // Returns an unused framebuffer name
    714 GLuint Context::createFramebuffer()
    715 {
    716     GLuint handle = mFramebufferHandleAllocator.allocate();
    717 
    718     mFramebufferMap[handle] = NULL;
    719 
    720     return handle;
    721 }
    722 
    723 GLuint Context::createFence()
    724 {
    725     GLuint handle = mFenceHandleAllocator.allocate();
    726 
    727     mFenceMap[handle] = new Fence(mRenderer);
    728 
    729     return handle;
    730 }
    731 
    732 // Returns an unused query name
    733 GLuint Context::createQuery()
    734 {
    735     GLuint handle = mQueryHandleAllocator.allocate();
    736 
    737     mQueryMap[handle] = NULL;
    738 
    739     return handle;
    740 }
    741 
    742 void Context::deleteBuffer(GLuint buffer)
    743 {
    744     if (mResourceManager->getBuffer(buffer))
    745     {
    746         detachBuffer(buffer);
    747     }
    748 
    749     mResourceManager->deleteBuffer(buffer);
    750 }
    751 
    752 void Context::deleteShader(GLuint shader)
    753 {
    754     mResourceManager->deleteShader(shader);
    755 }
    756 
    757 void Context::deleteProgram(GLuint program)
    758 {
    759     mResourceManager->deleteProgram(program);
    760 }
    761 
    762 void Context::deleteTexture(GLuint texture)
    763 {
    764     if (mResourceManager->getTexture(texture))
    765     {
    766         detachTexture(texture);
    767     }
    768 
    769     mResourceManager->deleteTexture(texture);
    770 }
    771 
    772 void Context::deleteRenderbuffer(GLuint renderbuffer)
    773 {
    774     if (mResourceManager->getRenderbuffer(renderbuffer))
    775     {
    776         detachRenderbuffer(renderbuffer);
    777     }
    778 
    779     mResourceManager->deleteRenderbuffer(renderbuffer);
    780 }
    781 
    782 void Context::deleteFramebuffer(GLuint framebuffer)
    783 {
    784     FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
    785 
    786     if (framebufferObject != mFramebufferMap.end())
    787     {
    788         detachFramebuffer(framebuffer);
    789 
    790         mFramebufferHandleAllocator.release(framebufferObject->first);
    791         delete framebufferObject->second;
    792         mFramebufferMap.erase(framebufferObject);
    793     }
    794 }
    795 
    796 void Context::deleteFence(GLuint fence)
    797 {
    798     FenceMap::iterator fenceObject = mFenceMap.find(fence);
    799 
    800     if (fenceObject != mFenceMap.end())
    801     {
    802         mFenceHandleAllocator.release(fenceObject->first);
    803         delete fenceObject->second;
    804         mFenceMap.erase(fenceObject);
    805     }
    806 }
    807 
    808 void Context::deleteQuery(GLuint query)
    809 {
    810     QueryMap::iterator queryObject = mQueryMap.find(query);
    811     if (queryObject != mQueryMap.end())
    812     {
    813         mQueryHandleAllocator.release(queryObject->first);
    814         if (queryObject->second)
    815         {
    816             queryObject->second->release();
    817         }
    818         mQueryMap.erase(queryObject);
    819     }
    820 }
    821 
    822 Buffer *Context::getBuffer(GLuint handle)
    823 {
    824     return mResourceManager->getBuffer(handle);
    825 }
    826 
    827 Shader *Context::getShader(GLuint handle)
    828 {
    829     return mResourceManager->getShader(handle);
    830 }
    831 
    832 Program *Context::getProgram(GLuint handle)
    833 {
    834     return mResourceManager->getProgram(handle);
    835 }
    836 
    837 Texture *Context::getTexture(GLuint handle)
    838 {
    839     return mResourceManager->getTexture(handle);
    840 }
    841 
    842 Renderbuffer *Context::getRenderbuffer(GLuint handle)
    843 {
    844     return mResourceManager->getRenderbuffer(handle);
    845 }
    846 
    847 Framebuffer *Context::getReadFramebuffer()
    848 {
    849     return getFramebuffer(mState.readFramebuffer);
    850 }
    851 
    852 Framebuffer *Context::getDrawFramebuffer()
    853 {
    854     return mBoundDrawFramebuffer;
    855 }
    856 
    857 void Context::bindArrayBuffer(unsigned int buffer)
    858 {
    859     mResourceManager->checkBufferAllocation(buffer);
    860 
    861     mState.arrayBuffer.set(getBuffer(buffer));
    862 }
    863 
    864 void Context::bindElementArrayBuffer(unsigned int buffer)
    865 {
    866     mResourceManager->checkBufferAllocation(buffer);
    867 
    868     mState.elementArrayBuffer.set(getBuffer(buffer));
    869 }
    870 
    871 void Context::bindTexture2D(GLuint texture)
    872 {
    873     mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
    874 
    875     mState.samplerTexture[TEXTURE_2D][mState.activeSampler].set(getTexture(texture));
    876 }
    877 
    878 void Context::bindTextureCubeMap(GLuint texture)
    879 {
    880     mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
    881 
    882     mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].set(getTexture(texture));
    883 }
    884 
    885 void Context::bindReadFramebuffer(GLuint framebuffer)
    886 {
    887     if (!getFramebuffer(framebuffer))
    888     {
    889         mFramebufferMap[framebuffer] = new Framebuffer(mRenderer);
    890     }
    891 
    892     mState.readFramebuffer = framebuffer;
    893 }
    894 
    895 void Context::bindDrawFramebuffer(GLuint framebuffer)
    896 {
    897     if (!getFramebuffer(framebuffer))
    898     {
    899         mFramebufferMap[framebuffer] = new Framebuffer(mRenderer);
    900     }
    901 
    902     mState.drawFramebuffer = framebuffer;
    903 
    904     mBoundDrawFramebuffer = getFramebuffer(framebuffer);
    905 }
    906 
    907 void Context::bindRenderbuffer(GLuint renderbuffer)
    908 {
    909     mResourceManager->checkRenderbufferAllocation(renderbuffer);
    910 
    911     mState.renderbuffer.set(getRenderbuffer(renderbuffer));
    912 }
    913 
    914 void Context::useProgram(GLuint program)
    915 {
    916     GLuint priorProgram = mState.currentProgram;
    917     mState.currentProgram = program;               // Must switch before trying to delete, otherwise it only gets flagged.
    918 
    919     if (priorProgram != program)
    920     {
    921         Program *newProgram = mResourceManager->getProgram(program);
    922         Program *oldProgram = mResourceManager->getProgram(priorProgram);
    923         mCurrentProgramBinary.set(NULL);
    924 
    925         if (newProgram)
    926         {
    927             newProgram->addRef();
    928             mCurrentProgramBinary.set(newProgram->getProgramBinary());
    929         }
    930 
    931         if (oldProgram)
    932         {
    933             oldProgram->release();
    934         }
    935     }
    936 }
    937 
    938 void Context::linkProgram(GLuint program)
    939 {
    940     Program *programObject = mResourceManager->getProgram(program);
    941 
    942     bool linked = programObject->link();
    943 
    944     // if the current program was relinked successfully we
    945     // need to install the new executables
    946     if (linked && program == mState.currentProgram)
    947     {
    948         mCurrentProgramBinary.set(programObject->getProgramBinary());
    949     }
    950 }
    951 
    952 void Context::setProgramBinary(GLuint program, const void *binary, GLint length)
    953 {
    954     Program *programObject = mResourceManager->getProgram(program);
    955 
    956     bool loaded = programObject->setProgramBinary(binary, length);
    957 
    958     // if the current program was reloaded successfully we
    959     // need to install the new executables
    960     if (loaded && program == mState.currentProgram)
    961     {
    962         mCurrentProgramBinary.set(programObject->getProgramBinary());
    963     }
    964 
    965 }
    966 
    967 void Context::beginQuery(GLenum target, GLuint query)
    968 {
    969     // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
    970     // of zero, if the active query object name for <target> is non-zero (for the
    971     // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
    972     // the active query for either target is non-zero), if <id> is the name of an
    973     // existing query object whose type does not match <target>, or if <id> is the
    974     // active query object name for any query type, the error INVALID_OPERATION is
    975     // generated.
    976 
    977     // Ensure no other queries are active
    978     // NOTE: If other queries than occlusion are supported, we will need to check
    979     // separately that:
    980     //    a) The query ID passed is not the current active query for any target/type
    981     //    b) There are no active queries for the requested target (and in the case
    982     //       of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
    983     //       no query may be active for either if glBeginQuery targets either.
    984     for (int i = 0; i < QUERY_TYPE_COUNT; i++)
    985     {
    986         if (mState.activeQuery[i].get() != NULL)
    987         {
    988             return gl::error(GL_INVALID_OPERATION);
    989         }
    990     }
    991 
    992     QueryType qType;
    993     switch (target)
    994     {
    995       case GL_ANY_SAMPLES_PASSED_EXT:
    996         qType = QUERY_ANY_SAMPLES_PASSED;
    997         break;
    998       case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
    999         qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
   1000         break;
   1001       default:
   1002         ASSERT(false);
   1003         return;
   1004     }
   1005 
   1006     Query *queryObject = getQuery(query, true, target);
   1007 
   1008     // check that name was obtained with glGenQueries
   1009     if (!queryObject)
   1010     {
   1011         return gl::error(GL_INVALID_OPERATION);
   1012     }
   1013 
   1014     // check for type mismatch
   1015     if (queryObject->getType() != target)
   1016     {
   1017         return gl::error(GL_INVALID_OPERATION);
   1018     }
   1019 
   1020     // set query as active for specified target
   1021     mState.activeQuery[qType].set(queryObject);
   1022 
   1023     // begin query
   1024     queryObject->begin();
   1025 }
   1026 
   1027 void Context::endQuery(GLenum target)
   1028 {
   1029     QueryType qType;
   1030 
   1031     switch (target)
   1032     {
   1033       case GL_ANY_SAMPLES_PASSED_EXT:
   1034         qType = QUERY_ANY_SAMPLES_PASSED;
   1035         break;
   1036       case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
   1037         qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
   1038         break;
   1039       default:
   1040         ASSERT(false);
   1041         return;
   1042     }
   1043 
   1044     Query *queryObject = mState.activeQuery[qType].get();
   1045 
   1046     if (queryObject == NULL)
   1047     {
   1048         return gl::error(GL_INVALID_OPERATION);
   1049     }
   1050 
   1051     queryObject->end();
   1052 
   1053     mState.activeQuery[qType].set(NULL);
   1054 }
   1055 
   1056 void Context::setFramebufferZero(Framebuffer *buffer)
   1057 {
   1058     delete mFramebufferMap[0];
   1059     mFramebufferMap[0] = buffer;
   1060     if (mState.drawFramebuffer == 0)
   1061     {
   1062         mBoundDrawFramebuffer = buffer;
   1063     }
   1064 }
   1065 
   1066 void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
   1067 {
   1068     RenderbufferStorage *renderbuffer = NULL;
   1069     switch (internalformat)
   1070     {
   1071       case GL_DEPTH_COMPONENT16:
   1072         renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples);
   1073         break;
   1074       case GL_RGBA4:
   1075       case GL_RGB5_A1:
   1076       case GL_RGB565:
   1077       case GL_RGB8_OES:
   1078       case GL_RGBA8_OES:
   1079         renderbuffer = new gl::Colorbuffer(mRenderer,width, height, internalformat, samples);
   1080         break;
   1081       case GL_STENCIL_INDEX8:
   1082         renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples);
   1083         break;
   1084       case GL_DEPTH24_STENCIL8_OES:
   1085         renderbuffer = new gl::DepthStencilbuffer(mRenderer, width, height, samples);
   1086         break;
   1087       default:
   1088         UNREACHABLE(); return;
   1089     }
   1090 
   1091     Renderbuffer *renderbufferObject = mState.renderbuffer.get();
   1092     renderbufferObject->setStorage(renderbuffer);
   1093 }
   1094 
   1095 Framebuffer *Context::getFramebuffer(unsigned int handle)
   1096 {
   1097     FramebufferMap::iterator framebuffer = mFramebufferMap.find(handle);
   1098 
   1099     if (framebuffer == mFramebufferMap.end())
   1100     {
   1101         return NULL;
   1102     }
   1103     else
   1104     {
   1105         return framebuffer->second;
   1106     }
   1107 }
   1108 
   1109 Fence *Context::getFence(unsigned int handle)
   1110 {
   1111     FenceMap::iterator fence = mFenceMap.find(handle);
   1112 
   1113     if (fence == mFenceMap.end())
   1114     {
   1115         return NULL;
   1116     }
   1117     else
   1118     {
   1119         return fence->second;
   1120     }
   1121 }
   1122 
   1123 Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
   1124 {
   1125     QueryMap::iterator query = mQueryMap.find(handle);
   1126 
   1127     if (query == mQueryMap.end())
   1128     {
   1129         return NULL;
   1130     }
   1131     else
   1132     {
   1133         if (!query->second && create)
   1134         {
   1135             query->second = new Query(mRenderer, type, handle);
   1136             query->second->addRef();
   1137         }
   1138         return query->second;
   1139     }
   1140 }
   1141 
   1142 Buffer *Context::getArrayBuffer()
   1143 {
   1144     return mState.arrayBuffer.get();
   1145 }
   1146 
   1147 Buffer *Context::getElementArrayBuffer()
   1148 {
   1149     return mState.elementArrayBuffer.get();
   1150 }
   1151 
   1152 ProgramBinary *Context::getCurrentProgramBinary()
   1153 {
   1154     return mCurrentProgramBinary.get();
   1155 }
   1156 
   1157 Texture2D *Context::getTexture2D()
   1158 {
   1159     return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
   1160 }
   1161 
   1162 TextureCubeMap *Context::getTextureCubeMap()
   1163 {
   1164     return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
   1165 }
   1166 
   1167 Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)
   1168 {
   1169     GLuint texid = mState.samplerTexture[type][sampler].id();
   1170 
   1171     if (texid == 0)   // Special case: 0 refers to different initial textures based on the target
   1172     {
   1173         switch (type)
   1174         {
   1175           default: UNREACHABLE();
   1176           case TEXTURE_2D: return mTexture2DZero.get();
   1177           case TEXTURE_CUBE: return mTextureCubeMapZero.get();
   1178         }
   1179     }
   1180 
   1181     return mState.samplerTexture[type][sampler].get();
   1182 }
   1183 
   1184 bool Context::getBooleanv(GLenum pname, GLboolean *params)
   1185 {
   1186     switch (pname)
   1187     {
   1188       case GL_SHADER_COMPILER:           *params = GL_TRUE;                             break;
   1189       case GL_SAMPLE_COVERAGE_INVERT:    *params = mState.sampleCoverageInvert;         break;
   1190       case GL_DEPTH_WRITEMASK:           *params = mState.depthStencil.depthMask;       break;
   1191       case GL_COLOR_WRITEMASK:
   1192         params[0] = mState.blend.colorMaskRed;
   1193         params[1] = mState.blend.colorMaskGreen;
   1194         params[2] = mState.blend.colorMaskBlue;
   1195         params[3] = mState.blend.colorMaskAlpha;
   1196         break;
   1197       case GL_CULL_FACE:                 *params = mState.rasterizer.cullFace;          break;
   1198       case GL_POLYGON_OFFSET_FILL:       *params = mState.rasterizer.polygonOffsetFill; break;
   1199       case GL_SAMPLE_ALPHA_TO_COVERAGE:  *params = mState.blend.sampleAlphaToCoverage;  break;
   1200       case GL_SAMPLE_COVERAGE:           *params = mState.sampleCoverage;               break;
   1201       case GL_SCISSOR_TEST:              *params = mState.scissorTest;                  break;
   1202       case GL_STENCIL_TEST:              *params = mState.depthStencil.stencilTest;     break;
   1203       case GL_DEPTH_TEST:                *params = mState.depthStencil.depthTest;       break;
   1204       case GL_BLEND:                     *params = mState.blend.blend;                  break;
   1205       case GL_DITHER:                    *params = mState.blend.dither;                 break;
   1206       case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE;  break;
   1207       default:
   1208         return false;
   1209     }
   1210 
   1211     return true;
   1212 }
   1213 
   1214 bool Context::getFloatv(GLenum pname, GLfloat *params)
   1215 {
   1216     // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
   1217     // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
   1218     // GetIntegerv as its native query function. As it would require conversion in any
   1219     // case, this should make no difference to the calling application.
   1220     switch (pname)
   1221     {
   1222       case GL_LINE_WIDTH:               *params = mState.lineWidth;                         break;
   1223       case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;               break;
   1224       case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;                   break;
   1225       case GL_POLYGON_OFFSET_FACTOR:    *params = mState.rasterizer.polygonOffsetFactor;    break;
   1226       case GL_POLYGON_OFFSET_UNITS:     *params = mState.rasterizer.polygonOffsetUnits;     break;
   1227       case GL_ALIASED_LINE_WIDTH_RANGE:
   1228         params[0] = gl::ALIASED_LINE_WIDTH_RANGE_MIN;
   1229         params[1] = gl::ALIASED_LINE_WIDTH_RANGE_MAX;
   1230         break;
   1231       case GL_ALIASED_POINT_SIZE_RANGE:
   1232         params[0] = gl::ALIASED_POINT_SIZE_RANGE_MIN;
   1233         params[1] = getMaximumPointSize();
   1234         break;
   1235       case GL_DEPTH_RANGE:
   1236         params[0] = mState.zNear;
   1237         params[1] = mState.zFar;
   1238         break;
   1239       case GL_COLOR_CLEAR_VALUE:
   1240         params[0] = mState.colorClearValue.red;
   1241         params[1] = mState.colorClearValue.green;
   1242         params[2] = mState.colorClearValue.blue;
   1243         params[3] = mState.colorClearValue.alpha;
   1244         break;
   1245       case GL_BLEND_COLOR:
   1246         params[0] = mState.blendColor.red;
   1247         params[1] = mState.blendColor.green;
   1248         params[2] = mState.blendColor.blue;
   1249         params[3] = mState.blendColor.alpha;
   1250         break;
   1251       case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
   1252         if (!supportsTextureFilterAnisotropy())
   1253         {
   1254             return false;
   1255         }
   1256         *params = mMaxTextureAnisotropy;
   1257         break;
   1258       default:
   1259         return false;
   1260     }
   1261 
   1262     return true;
   1263 }
   1264 
   1265 bool Context::getIntegerv(GLenum pname, GLint *params)
   1266 {
   1267     if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
   1268     {
   1269         unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
   1270 
   1271         if (colorAttachment >= mRenderer->getMaxRenderTargets())
   1272         {
   1273             // return true to stop further operation in the parent call
   1274             return gl::error(GL_INVALID_OPERATION, true);
   1275         }
   1276 
   1277         Framebuffer *framebuffer = getDrawFramebuffer();
   1278 
   1279         *params = framebuffer->getDrawBufferState(colorAttachment);
   1280         return true;
   1281     }
   1282 
   1283     // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
   1284     // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
   1285     // GetIntegerv as its native query function. As it would require conversion in any
   1286     // case, this should make no difference to the calling application. You may find it in
   1287     // Context::getFloatv.
   1288     switch (pname)
   1289     {
   1290       case GL_MAX_VERTEX_ATTRIBS:               *params = gl::MAX_VERTEX_ATTRIBS;               break;
   1291       case GL_MAX_VERTEX_UNIFORM_VECTORS:       *params = mRenderer->getMaxVertexUniformVectors(); break;
   1292       case GL_MAX_VARYING_VECTORS:              *params = mRenderer->getMaxVaryingVectors();    break;
   1293       case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mRenderer->getMaxCombinedTextureImageUnits(); break;
   1294       case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = mRenderer->getMaxVertexTextureImageUnits(); break;
   1295       case GL_MAX_TEXTURE_IMAGE_UNITS:          *params = gl::MAX_TEXTURE_IMAGE_UNITS;          break;
   1296       case GL_MAX_FRAGMENT_UNIFORM_VECTORS:     *params = mRenderer->getMaxFragmentUniformVectors(); break;
   1297       case GL_MAX_RENDERBUFFER_SIZE:            *params = getMaximumRenderbufferDimension();    break;
   1298       case GL_MAX_COLOR_ATTACHMENTS_EXT:        *params = mRenderer->getMaxRenderTargets();     break;
   1299       case GL_MAX_DRAW_BUFFERS_EXT:             *params = mRenderer->getMaxRenderTargets();     break;
   1300       case GL_NUM_SHADER_BINARY_FORMATS:        *params = 0;                                    break;
   1301       case GL_SHADER_BINARY_FORMATS:      /* no shader binary formats are supported */          break;
   1302       case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer.id();              break;
   1303       case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer.id();       break;
   1304       //case GL_FRAMEBUFFER_BINDING:            // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
   1305       case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:   *params = mState.drawFramebuffer;               break;
   1306       case GL_READ_FRAMEBUFFER_BINDING_ANGLE:   *params = mState.readFramebuffer;               break;
   1307       case GL_RENDERBUFFER_BINDING:             *params = mState.renderbuffer.id();             break;
   1308       case GL_CURRENT_PROGRAM:                  *params = mState.currentProgram;                break;
   1309       case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;
   1310       case GL_PACK_REVERSE_ROW_ORDER_ANGLE:     *params = mState.packReverseRowOrder;           break;
   1311       case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackAlignment;               break;
   1312       case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;
   1313       case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; break;
   1314       case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;
   1315       case GL_STENCIL_FUNC:                     *params = mState.depthStencil.stencilFunc;             break;
   1316       case GL_STENCIL_REF:                      *params = mState.stencilRef;                           break;
   1317       case GL_STENCIL_VALUE_MASK:               *params = mState.depthStencil.stencilMask;             break;
   1318       case GL_STENCIL_BACK_FUNC:                *params = mState.depthStencil.stencilBackFunc;         break;
   1319       case GL_STENCIL_BACK_REF:                 *params = mState.stencilBackRef;                       break;
   1320       case GL_STENCIL_BACK_VALUE_MASK:          *params = mState.depthStencil.stencilBackMask;         break;
   1321       case GL_STENCIL_FAIL:                     *params = mState.depthStencil.stencilFail;             break;
   1322       case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.depthStencil.stencilPassDepthFail;    break;
   1323       case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.depthStencil.stencilPassDepthPass;    break;
   1324       case GL_STENCIL_BACK_FAIL:                *params = mState.depthStencil.stencilBackFail;         break;
   1325       case GL_STENCIL_BACK_PASS_DEPTH_FAIL:     *params = mState.depthStencil.stencilBackPassDepthFail; break;
   1326       case GL_STENCIL_BACK_PASS_DEPTH_PASS:     *params = mState.depthStencil.stencilBackPassDepthPass; break;
   1327       case GL_DEPTH_FUNC:                       *params = mState.depthStencil.depthFunc;               break;
   1328       case GL_BLEND_SRC_RGB:                    *params = mState.blend.sourceBlendRGB;                 break;
   1329       case GL_BLEND_SRC_ALPHA:                  *params = mState.blend.sourceBlendAlpha;               break;
   1330       case GL_BLEND_DST_RGB:                    *params = mState.blend.destBlendRGB;                   break;
   1331       case GL_BLEND_DST_ALPHA:                  *params = mState.blend.destBlendAlpha;                 break;
   1332       case GL_BLEND_EQUATION_RGB:               *params = mState.blend.blendEquationRGB;               break;
   1333       case GL_BLEND_EQUATION_ALPHA:             *params = mState.blend.blendEquationAlpha;             break;
   1334       case GL_STENCIL_WRITEMASK:                *params = mState.depthStencil.stencilWritemask;        break;
   1335       case GL_STENCIL_BACK_WRITEMASK:           *params = mState.depthStencil.stencilBackWritemask;    break;
   1336       case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             break;
   1337       case GL_SUBPIXEL_BITS:                    *params = 4;                                    break;
   1338       case GL_MAX_TEXTURE_SIZE:                 *params = getMaximumTextureDimension();         break;
   1339       case GL_MAX_CUBE_MAP_TEXTURE_SIZE:        *params = getMaximumCubeTextureDimension();     break;
   1340       case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
   1341         params[0] = mNumCompressedTextureFormats;
   1342         break;
   1343       case GL_MAX_SAMPLES_ANGLE:
   1344         {
   1345             GLsizei maxSamples = getMaxSupportedSamples();
   1346             if (maxSamples != 0)
   1347             {
   1348                 *params = maxSamples;
   1349             }
   1350             else
   1351             {
   1352                 return false;
   1353             }
   1354 
   1355             break;
   1356         }
   1357       case GL_SAMPLE_BUFFERS:
   1358       case GL_SAMPLES:
   1359         {
   1360             gl::Framebuffer *framebuffer = getDrawFramebuffer();
   1361             if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
   1362             {
   1363                 switch (pname)
   1364                 {
   1365                   case GL_SAMPLE_BUFFERS:
   1366                     if (framebuffer->getSamples() != 0)
   1367                     {
   1368                         *params = 1;
   1369                     }
   1370                     else
   1371                     {
   1372                         *params = 0;
   1373                     }
   1374                     break;
   1375                   case GL_SAMPLES:
   1376                     *params = framebuffer->getSamples();
   1377                     break;
   1378                 }
   1379             }
   1380             else
   1381             {
   1382                 *params = 0;
   1383             }
   1384         }
   1385         break;
   1386       case GL_IMPLEMENTATION_COLOR_READ_TYPE:
   1387       case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
   1388         {
   1389             GLenum format, type;
   1390             if (getCurrentReadFormatType(&format, &type))
   1391             {
   1392                 if (pname == GL_IMPLEMENTATION_COLOR_READ_FORMAT)
   1393                     *params = format;
   1394                 else
   1395                     *params = type;
   1396             }
   1397         }
   1398         break;
   1399       case GL_MAX_VIEWPORT_DIMS:
   1400         {
   1401             params[0] = mMaxViewportDimension;
   1402             params[1] = mMaxViewportDimension;
   1403         }
   1404         break;
   1405       case GL_COMPRESSED_TEXTURE_FORMATS:
   1406         {
   1407             if (supportsDXT1Textures())
   1408             {
   1409                 *params++ = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
   1410                 *params++ = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
   1411             }
   1412             if (supportsDXT3Textures())
   1413             {
   1414                 *params++ = GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
   1415             }
   1416             if (supportsDXT5Textures())
   1417             {
   1418                 *params++ = GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
   1419             }
   1420         }
   1421         break;
   1422       case GL_VIEWPORT:
   1423         params[0] = mState.viewport.x;
   1424         params[1] = mState.viewport.y;
   1425         params[2] = mState.viewport.width;
   1426         params[3] = mState.viewport.height;
   1427         break;
   1428       case GL_SCISSOR_BOX:
   1429         params[0] = mState.scissor.x;
   1430         params[1] = mState.scissor.y;
   1431         params[2] = mState.scissor.width;
   1432         params[3] = mState.scissor.height;
   1433         break;
   1434       case GL_CULL_FACE_MODE:                   *params = mState.rasterizer.cullMode;   break;
   1435       case GL_FRONT_FACE:                       *params = mState.rasterizer.frontFace;  break;
   1436       case GL_RED_BITS:
   1437       case GL_GREEN_BITS:
   1438       case GL_BLUE_BITS:
   1439       case GL_ALPHA_BITS:
   1440         {
   1441             gl::Framebuffer *framebuffer = getDrawFramebuffer();
   1442             gl::Renderbuffer *colorbuffer = framebuffer->getFirstColorbuffer();
   1443 
   1444             if (colorbuffer)
   1445             {
   1446                 switch (pname)
   1447                 {
   1448                   case GL_RED_BITS:   *params = colorbuffer->getRedSize();      break;
   1449                   case GL_GREEN_BITS: *params = colorbuffer->getGreenSize();    break;
   1450                   case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();     break;
   1451                   case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize();    break;
   1452                 }
   1453             }
   1454             else
   1455             {
   1456                 *params = 0;
   1457             }
   1458         }
   1459         break;
   1460       case GL_DEPTH_BITS:
   1461         {
   1462             gl::Framebuffer *framebuffer = getDrawFramebuffer();
   1463             gl::Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
   1464 
   1465             if (depthbuffer)
   1466             {
   1467                 *params = depthbuffer->getDepthSize();
   1468             }
   1469             else
   1470             {
   1471                 *params = 0;
   1472             }
   1473         }
   1474         break;
   1475       case GL_STENCIL_BITS:
   1476         {
   1477             gl::Framebuffer *framebuffer = getDrawFramebuffer();
   1478             gl::Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
   1479 
   1480             if (stencilbuffer)
   1481             {
   1482                 *params = stencilbuffer->getStencilSize();
   1483             }
   1484             else
   1485             {
   1486                 *params = 0;
   1487             }
   1488         }
   1489         break;
   1490       case GL_TEXTURE_BINDING_2D:
   1491         {
   1492             if (mState.activeSampler > mRenderer->getMaxCombinedTextureImageUnits() - 1)
   1493             {
   1494                 gl::error(GL_INVALID_OPERATION);
   1495                 return false;
   1496             }
   1497 
   1498             *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].id();
   1499         }
   1500         break;
   1501       case GL_TEXTURE_BINDING_CUBE_MAP:
   1502         {
   1503             if (mState.activeSampler > mRenderer->getMaxCombinedTextureImageUnits() - 1)
   1504             {
   1505                 gl::error(GL_INVALID_OPERATION);
   1506                 return false;
   1507             }
   1508 
   1509             *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].id();
   1510         }
   1511         break;
   1512       case GL_RESET_NOTIFICATION_STRATEGY_EXT:
   1513         *params = mResetStrategy;
   1514         break;
   1515       case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
   1516         *params = 1;
   1517         break;
   1518       case GL_PROGRAM_BINARY_FORMATS_OES:
   1519         *params = GL_PROGRAM_BINARY_ANGLE;
   1520         break;
   1521       default:
   1522         return false;
   1523     }
   1524 
   1525     return true;
   1526 }
   1527 
   1528 bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
   1529 {
   1530     if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
   1531     {
   1532         *type = GL_INT;
   1533         *numParams = 1;
   1534         return true;
   1535     }
   1536 
   1537     // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
   1538     // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
   1539     // to the fact that it is stored internally as a float, and so would require conversion
   1540     // if returned from Context::getIntegerv. Since this conversion is already implemented
   1541     // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
   1542     // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
   1543     // application.
   1544     switch (pname)
   1545     {
   1546       case GL_COMPRESSED_TEXTURE_FORMATS:
   1547         {
   1548             *type = GL_INT;
   1549             *numParams = mNumCompressedTextureFormats;
   1550         }
   1551         break;
   1552       case GL_SHADER_BINARY_FORMATS:
   1553         {
   1554             *type = GL_INT;
   1555             *numParams = 0;
   1556         }
   1557         break;
   1558       case GL_MAX_VERTEX_ATTRIBS:
   1559       case GL_MAX_VERTEX_UNIFORM_VECTORS:
   1560       case GL_MAX_VARYING_VECTORS:
   1561       case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
   1562       case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
   1563       case GL_MAX_TEXTURE_IMAGE_UNITS:
   1564       case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
   1565       case GL_MAX_RENDERBUFFER_SIZE:
   1566       case GL_MAX_COLOR_ATTACHMENTS_EXT:
   1567       case GL_MAX_DRAW_BUFFERS_EXT:
   1568       case GL_NUM_SHADER_BINARY_FORMATS:
   1569       case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
   1570       case GL_ARRAY_BUFFER_BINDING:
   1571       case GL_FRAMEBUFFER_BINDING:
   1572       case GL_RENDERBUFFER_BINDING:
   1573       case GL_CURRENT_PROGRAM:
   1574       case GL_PACK_ALIGNMENT:
   1575       case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
   1576       case GL_UNPACK_ALIGNMENT:
   1577       case GL_GENERATE_MIPMAP_HINT:
   1578       case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
   1579       case GL_RED_BITS:
   1580       case GL_GREEN_BITS:
   1581       case GL_BLUE_BITS:
   1582       case GL_ALPHA_BITS:
   1583       case GL_DEPTH_BITS:
   1584       case GL_STENCIL_BITS:
   1585       case GL_ELEMENT_ARRAY_BUFFER_BINDING:
   1586       case GL_CULL_FACE_MODE:
   1587       case GL_FRONT_FACE:
   1588       case GL_ACTIVE_TEXTURE:
   1589       case GL_STENCIL_FUNC:
   1590       case GL_STENCIL_VALUE_MASK:
   1591       case GL_STENCIL_REF:
   1592       case GL_STENCIL_FAIL:
   1593       case GL_STENCIL_PASS_DEPTH_FAIL:
   1594       case GL_STENCIL_PASS_DEPTH_PASS:
   1595       case GL_STENCIL_BACK_FUNC:
   1596       case GL_STENCIL_BACK_VALUE_MASK:
   1597       case GL_STENCIL_BACK_REF:
   1598       case GL_STENCIL_BACK_FAIL:
   1599       case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
   1600       case GL_STENCIL_BACK_PASS_DEPTH_PASS:
   1601       case GL_DEPTH_FUNC:
   1602       case GL_BLEND_SRC_RGB:
   1603       case GL_BLEND_SRC_ALPHA:
   1604       case GL_BLEND_DST_RGB:
   1605       case GL_BLEND_DST_ALPHA:
   1606       case GL_BLEND_EQUATION_RGB:
   1607       case GL_BLEND_EQUATION_ALPHA:
   1608       case GL_STENCIL_WRITEMASK:
   1609       case GL_STENCIL_BACK_WRITEMASK:
   1610       case GL_STENCIL_CLEAR_VALUE:
   1611       case GL_SUBPIXEL_BITS:
   1612       case GL_MAX_TEXTURE_SIZE:
   1613       case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
   1614       case GL_SAMPLE_BUFFERS:
   1615       case GL_SAMPLES:
   1616       case GL_IMPLEMENTATION_COLOR_READ_TYPE:
   1617       case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
   1618       case GL_TEXTURE_BINDING_2D:
   1619       case GL_TEXTURE_BINDING_CUBE_MAP:
   1620       case GL_RESET_NOTIFICATION_STRATEGY_EXT:
   1621       case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
   1622       case GL_PROGRAM_BINARY_FORMATS_OES:
   1623         {
   1624             *type = GL_INT;
   1625             *numParams = 1;
   1626         }
   1627         break;
   1628       case GL_MAX_SAMPLES_ANGLE:
   1629         {
   1630             if (getMaxSupportedSamples() != 0)
   1631             {
   1632                 *type = GL_INT;
   1633                 *numParams = 1;
   1634             }
   1635             else
   1636             {
   1637                 return false;
   1638             }
   1639         }
   1640         break;
   1641       case GL_MAX_VIEWPORT_DIMS:
   1642         {
   1643             *type = GL_INT;
   1644             *numParams = 2;
   1645         }
   1646         break;
   1647       case GL_VIEWPORT:
   1648       case GL_SCISSOR_BOX:
   1649         {
   1650             *type = GL_INT;
   1651             *numParams = 4;
   1652         }
   1653         break;
   1654       case GL_SHADER_COMPILER:
   1655       case GL_SAMPLE_COVERAGE_INVERT:
   1656       case GL_DEPTH_WRITEMASK:
   1657       case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
   1658       case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
   1659       case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
   1660       case GL_SAMPLE_COVERAGE:
   1661       case GL_SCISSOR_TEST:
   1662       case GL_STENCIL_TEST:
   1663       case GL_DEPTH_TEST:
   1664       case GL_BLEND:
   1665       case GL_DITHER:
   1666       case GL_CONTEXT_ROBUST_ACCESS_EXT:
   1667         {
   1668             *type = GL_BOOL;
   1669             *numParams = 1;
   1670         }
   1671         break;
   1672       case GL_COLOR_WRITEMASK:
   1673         {
   1674             *type = GL_BOOL;
   1675             *numParams = 4;
   1676         }
   1677         break;
   1678       case GL_POLYGON_OFFSET_FACTOR:
   1679       case GL_POLYGON_OFFSET_UNITS:
   1680       case GL_SAMPLE_COVERAGE_VALUE:
   1681       case GL_DEPTH_CLEAR_VALUE:
   1682       case GL_LINE_WIDTH:
   1683         {
   1684             *type = GL_FLOAT;
   1685             *numParams = 1;
   1686         }
   1687         break;
   1688       case GL_ALIASED_LINE_WIDTH_RANGE:
   1689       case GL_ALIASED_POINT_SIZE_RANGE:
   1690       case GL_DEPTH_RANGE:
   1691         {
   1692             *type = GL_FLOAT;
   1693             *numParams = 2;
   1694         }
   1695         break;
   1696       case GL_COLOR_CLEAR_VALUE:
   1697       case GL_BLEND_COLOR:
   1698         {
   1699             *type = GL_FLOAT;
   1700             *numParams = 4;
   1701         }
   1702         break;
   1703       case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
   1704         if (!supportsTextureFilterAnisotropy())
   1705         {
   1706             return false;
   1707         }
   1708         *type = GL_FLOAT;
   1709         *numParams = 1;
   1710         break;
   1711       default:
   1712         return false;
   1713     }
   1714 
   1715     return true;
   1716 }
   1717 
   1718 // Applies the render target surface, depth stencil surface, viewport rectangle and
   1719 // scissor rectangle to the renderer
   1720 bool Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport)
   1721 {
   1722     Framebuffer *framebufferObject = getDrawFramebuffer();
   1723 
   1724     if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
   1725     {
   1726         return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
   1727     }
   1728 
   1729     mRenderer->applyRenderTarget(framebufferObject);
   1730 
   1731     if (!mRenderer->setViewport(mState.viewport, mState.zNear, mState.zFar, drawMode, mState.rasterizer.frontFace,
   1732                                 ignoreViewport))
   1733     {
   1734         return false;
   1735     }
   1736 
   1737     mRenderer->setScissorRectangle(mState.scissor, mState.scissorTest);
   1738 
   1739     return true;
   1740 }
   1741 
   1742 // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
   1743 void Context::applyState(GLenum drawMode)
   1744 {
   1745     Framebuffer *framebufferObject = getDrawFramebuffer();
   1746     int samples = framebufferObject->getSamples();
   1747 
   1748     mState.rasterizer.pointDrawMode = (drawMode == GL_POINTS);
   1749     mState.rasterizer.multiSample = (samples != 0);
   1750     mRenderer->setRasterizerState(mState.rasterizer);
   1751 
   1752     unsigned int mask = 0;
   1753     if (mState.sampleCoverage)
   1754     {
   1755         if (mState.sampleCoverageValue != 0)
   1756         {
   1757 
   1758             float threshold = 0.5f;
   1759 
   1760             for (int i = 0; i < samples; ++i)
   1761             {
   1762                 mask <<= 1;
   1763 
   1764                 if ((i + 1) * mState.sampleCoverageValue >= threshold)
   1765                 {
   1766                     threshold += 1.0f;
   1767                     mask |= 1;
   1768                 }
   1769             }
   1770         }
   1771 
   1772         if (mState.sampleCoverageInvert)
   1773         {
   1774             mask = ~mask;
   1775         }
   1776     }
   1777     else
   1778     {
   1779         mask = 0xFFFFFFFF;
   1780     }
   1781     mRenderer->setBlendState(mState.blend, mState.blendColor, mask);
   1782 
   1783     mRenderer->setDepthStencilState(mState.depthStencil, mState.stencilRef, mState.stencilBackRef,
   1784                                     mState.rasterizer.frontFace == GL_CCW);
   1785 }
   1786 
   1787 // Applies the shaders and shader constants to the Direct3D 9 device
   1788 void Context::applyShaders()
   1789 {
   1790     ProgramBinary *programBinary = getCurrentProgramBinary();
   1791 
   1792     mRenderer->applyShaders(programBinary);
   1793 
   1794     programBinary->applyUniforms();
   1795 }
   1796 
   1797 // Applies the textures and sampler states to the Direct3D 9 device
   1798 void Context::applyTextures()
   1799 {
   1800     applyTextures(SAMPLER_PIXEL);
   1801 
   1802     if (mSupportsVertexTexture)
   1803     {
   1804         applyTextures(SAMPLER_VERTEX);
   1805     }
   1806 }
   1807 
   1808 // For each Direct3D 9 sampler of either the pixel or vertex stage,
   1809 // looks up the corresponding OpenGL texture image unit and texture type,
   1810 // and sets the texture and its addressing/filtering state (or NULL when inactive).
   1811 void Context::applyTextures(SamplerType type)
   1812 {
   1813     ProgramBinary *programBinary = getCurrentProgramBinary();
   1814 
   1815     // Range of Direct3D samplers of given sampler type
   1816     int samplerCount = (type == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : mRenderer->getMaxVertexTextureImageUnits();
   1817     int samplerRange = programBinary->getUsedSamplerRange(type);
   1818 
   1819     for (int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
   1820     {
   1821         int textureUnit = programBinary->getSamplerMapping(type, samplerIndex);   // OpenGL texture image unit index
   1822 
   1823         if (textureUnit != -1)
   1824         {
   1825             TextureType textureType = programBinary->getSamplerTextureType(type, samplerIndex);
   1826             Texture *texture = getSamplerTexture(textureUnit, textureType);
   1827 
   1828             if (texture->isSamplerComplete())
   1829             {
   1830                 SamplerState samplerState;
   1831                 texture->getSamplerState(&samplerState);
   1832                 mRenderer->setSamplerState(type, samplerIndex, samplerState);
   1833 
   1834                 mRenderer->setTexture(type, samplerIndex, texture);
   1835 
   1836                 texture->resetDirty();
   1837             }
   1838             else
   1839             {
   1840                 mRenderer->setTexture(type, samplerIndex, getIncompleteTexture(textureType));
   1841             }
   1842         }
   1843         else
   1844         {
   1845             mRenderer->setTexture(type, samplerIndex, NULL);
   1846         }
   1847     }
   1848 
   1849     for (int samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
   1850     {
   1851         mRenderer->setTexture(type, samplerIndex, NULL);
   1852     }
   1853 }
   1854 
   1855 void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
   1856                          GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
   1857 {
   1858     Framebuffer *framebuffer = getReadFramebuffer();
   1859 
   1860     if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
   1861     {
   1862         return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
   1863     }
   1864 
   1865     if (getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0)
   1866     {
   1867         return gl::error(GL_INVALID_OPERATION);
   1868     }
   1869 
   1870     GLsizei outputPitch = ComputePitch(width, ConvertSizedInternalFormat(format, type), getPackAlignment());
   1871     // sized query sanity check
   1872     if (bufSize)
   1873     {
   1874         int requiredSize = outputPitch * height;
   1875         if (requiredSize > *bufSize)
   1876         {
   1877             return gl::error(GL_INVALID_OPERATION);
   1878         }
   1879     }
   1880 
   1881     mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, getPackReverseRowOrder(), getPackAlignment(), pixels);
   1882 }
   1883 
   1884 void Context::clear(GLbitfield mask)
   1885 {
   1886     Framebuffer *framebufferObject = getDrawFramebuffer();
   1887 
   1888     if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
   1889     {
   1890         return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
   1891     }
   1892 
   1893     DWORD flags = 0;
   1894     GLbitfield finalMask = 0;
   1895 
   1896     if (mask & GL_COLOR_BUFFER_BIT)
   1897     {
   1898         mask &= ~GL_COLOR_BUFFER_BIT;
   1899 
   1900         if (framebufferObject->hasEnabledColorAttachment())
   1901         {
   1902             finalMask |= GL_COLOR_BUFFER_BIT;
   1903         }
   1904     }
   1905 
   1906     if (mask & GL_DEPTH_BUFFER_BIT)
   1907     {
   1908         mask &= ~GL_DEPTH_BUFFER_BIT;
   1909         if (mState.depthStencil.depthMask && framebufferObject->getDepthbufferType() != GL_NONE)
   1910         {
   1911             finalMask |= GL_DEPTH_BUFFER_BIT;
   1912         }
   1913     }
   1914 
   1915     if (mask & GL_STENCIL_BUFFER_BIT)
   1916     {
   1917         mask &= ~GL_STENCIL_BUFFER_BIT;
   1918         if (framebufferObject->getStencilbufferType() != GL_NONE)
   1919         {
   1920             rx::RenderTarget *depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
   1921             if (!depthStencil)
   1922             {
   1923                 ERR("Depth stencil pointer unexpectedly null.");
   1924                 return;
   1925             }
   1926 
   1927             if (GetStencilSize(depthStencil->getActualFormat()) > 0)
   1928             {
   1929                 finalMask |= GL_STENCIL_BUFFER_BIT;
   1930             }
   1931         }
   1932     }
   1933 
   1934     if (mask != 0)
   1935     {
   1936         return gl::error(GL_INVALID_VALUE);
   1937     }
   1938 
   1939     if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
   1940     {
   1941         return;
   1942     }
   1943 
   1944     ClearParameters clearParams;
   1945     clearParams.mask = finalMask;
   1946     clearParams.colorClearValue = mState.colorClearValue;
   1947     clearParams.colorMaskRed = mState.blend.colorMaskRed;
   1948     clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
   1949     clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
   1950     clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
   1951     clearParams.depthClearValue = mState.depthClearValue;
   1952     clearParams.stencilClearValue = mState.stencilClearValue;
   1953     clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
   1954 
   1955     mRenderer->clear(clearParams, framebufferObject);
   1956 }
   1957 
   1958 void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
   1959 {
   1960     if (!mState.currentProgram)
   1961     {
   1962         return gl::error(GL_INVALID_OPERATION);
   1963     }
   1964 
   1965     if (!mRenderer->applyPrimitiveType(mode, count))
   1966     {
   1967         return;
   1968     }
   1969 
   1970     if (!applyRenderTarget(mode, false))
   1971     {
   1972         return;
   1973     }
   1974 
   1975     applyState(mode);
   1976 
   1977     ProgramBinary *programBinary = getCurrentProgramBinary();
   1978 
   1979     GLenum err = mRenderer->applyVertexBuffer(programBinary, mState.vertexAttribute, first, count, instances);
   1980     if (err != GL_NO_ERROR)
   1981     {
   1982         return gl::error(err);
   1983     }
   1984 
   1985     applyShaders();
   1986     applyTextures();
   1987 
   1988     if (!programBinary->validateSamplers(NULL))
   1989     {
   1990         return gl::error(GL_INVALID_OPERATION);
   1991     }
   1992 
   1993     if (!skipDraw(mode))
   1994     {
   1995         mRenderer->drawArrays(mode, count, instances);
   1996     }
   1997 }
   1998 
   1999 void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances)
   2000 {
   2001     if (!mState.currentProgram)
   2002     {
   2003         return gl::error(GL_INVALID_OPERATION);
   2004     }
   2005 
   2006     if (!indices && !mState.elementArrayBuffer)
   2007     {
   2008         return gl::error(GL_INVALID_OPERATION);
   2009     }
   2010 
   2011     if (!mRenderer->applyPrimitiveType(mode, count))
   2012     {
   2013         return;
   2014     }
   2015 
   2016     if (!applyRenderTarget(mode, false))
   2017     {
   2018         return;
   2019     }
   2020 
   2021     applyState(mode);
   2022 
   2023     rx::TranslatedIndexData indexInfo;
   2024     GLenum err = mRenderer->applyIndexBuffer(indices, mState.elementArrayBuffer.get(), count, mode, type, &indexInfo);
   2025     if (err != GL_NO_ERROR)
   2026     {
   2027         return gl::error(err);
   2028     }
   2029 
   2030     ProgramBinary *programBinary = getCurrentProgramBinary();
   2031 
   2032     GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
   2033     err = mRenderer->applyVertexBuffer(programBinary, mState.vertexAttribute, indexInfo.minIndex, vertexCount, instances);
   2034     if (err != GL_NO_ERROR)
   2035     {
   2036         return gl::error(err);
   2037     }
   2038 
   2039     applyShaders();
   2040     applyTextures();
   2041 
   2042     if (!programBinary->validateSamplers(NULL))
   2043     {
   2044         return gl::error(GL_INVALID_OPERATION);
   2045     }
   2046 
   2047     if (!skipDraw(mode))
   2048     {
   2049         mRenderer->drawElements(mode, count, type, indices, mState.elementArrayBuffer.get(), indexInfo, instances);
   2050     }
   2051 }
   2052 
   2053 // Implements glFlush when block is false, glFinish when block is true
   2054 void Context::sync(bool block)
   2055 {
   2056     mRenderer->sync(block);
   2057 }
   2058 
   2059 void Context::recordInvalidEnum()
   2060 {
   2061     mInvalidEnum = true;
   2062 }
   2063 
   2064 void Context::recordInvalidValue()
   2065 {
   2066     mInvalidValue = true;
   2067 }
   2068 
   2069 void Context::recordInvalidOperation()
   2070 {
   2071     mInvalidOperation = true;
   2072 }
   2073 
   2074 void Context::recordOutOfMemory()
   2075 {
   2076     mOutOfMemory = true;
   2077 }
   2078 
   2079 void Context::recordInvalidFramebufferOperation()
   2080 {
   2081     mInvalidFramebufferOperation = true;
   2082 }
   2083 
   2084 // Get one of the recorded errors and clear its flag, if any.
   2085 // [OpenGL ES 2.0.24] section 2.5 page 13.
   2086 GLenum Context::getError()
   2087 {
   2088     if (mInvalidEnum)
   2089     {
   2090         mInvalidEnum = false;
   2091 
   2092         return GL_INVALID_ENUM;
   2093     }
   2094 
   2095     if (mInvalidValue)
   2096     {
   2097         mInvalidValue = false;
   2098 
   2099         return GL_INVALID_VALUE;
   2100     }
   2101 
   2102     if (mInvalidOperation)
   2103     {
   2104         mInvalidOperation = false;
   2105 
   2106         return GL_INVALID_OPERATION;
   2107     }
   2108 
   2109     if (mOutOfMemory)
   2110     {
   2111         mOutOfMemory = false;
   2112 
   2113         return GL_OUT_OF_MEMORY;
   2114     }
   2115 
   2116     if (mInvalidFramebufferOperation)
   2117     {
   2118         mInvalidFramebufferOperation = false;
   2119 
   2120         return GL_INVALID_FRAMEBUFFER_OPERATION;
   2121     }
   2122 
   2123     return GL_NO_ERROR;
   2124 }
   2125 
   2126 GLenum Context::getResetStatus()
   2127 {
   2128     if (mResetStatus == GL_NO_ERROR && !mContextLost)
   2129     {
   2130         // mResetStatus will be set by the markContextLost callback
   2131         // in the case a notification is sent
   2132         mRenderer->testDeviceLost(true);
   2133     }
   2134 
   2135     GLenum status = mResetStatus;
   2136 
   2137     if (mResetStatus != GL_NO_ERROR)
   2138     {
   2139         ASSERT(mContextLost);
   2140 
   2141         if (mRenderer->testDeviceResettable())
   2142         {
   2143             mResetStatus = GL_NO_ERROR;
   2144         }
   2145     }
   2146 
   2147     return status;
   2148 }
   2149 
   2150 bool Context::isResetNotificationEnabled()
   2151 {
   2152     return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
   2153 }
   2154 
   2155 int Context::getMajorShaderModel() const
   2156 {
   2157     return mMajorShaderModel;
   2158 }
   2159 
   2160 float Context::getMaximumPointSize() const
   2161 {
   2162     return mMaximumPointSize;
   2163 }
   2164 
   2165 unsigned int Context::getMaximumCombinedTextureImageUnits() const
   2166 {
   2167     return mRenderer->getMaxCombinedTextureImageUnits();
   2168 }
   2169 
   2170 int Context::getMaxSupportedSamples() const
   2171 {
   2172     return mRenderer->getMaxSupportedSamples();
   2173 }
   2174 
   2175 unsigned int Context::getMaximumRenderTargets() const
   2176 {
   2177     return mRenderer->getMaxRenderTargets();
   2178 }
   2179 
   2180 bool Context::supportsEventQueries() const
   2181 {
   2182     return mSupportsEventQueries;
   2183 }
   2184 
   2185 bool Context::supportsOcclusionQueries() const
   2186 {
   2187     return mSupportsOcclusionQueries;
   2188 }
   2189 
   2190 bool Context::supportsBGRATextures() const
   2191 {
   2192     return mSupportsBGRATextures;
   2193 }
   2194 
   2195 bool Context::supportsDXT1Textures() const
   2196 {
   2197     return mSupportsDXT1Textures;
   2198 }
   2199 
   2200 bool Context::supportsDXT3Textures() const
   2201 {
   2202     return mSupportsDXT3Textures;
   2203 }
   2204 
   2205 bool Context::supportsDXT5Textures() const
   2206 {
   2207     return mSupportsDXT5Textures;
   2208 }
   2209 
   2210 bool Context::supportsFloat32Textures() const
   2211 {
   2212     return mSupportsFloat32Textures;
   2213 }
   2214 
   2215 bool Context::supportsFloat32LinearFilter() const
   2216 {
   2217     return mSupportsFloat32LinearFilter;
   2218 }
   2219 
   2220 bool Context::supportsFloat32RenderableTextures() const
   2221 {
   2222     return mSupportsFloat32RenderableTextures;
   2223 }
   2224 
   2225 bool Context::supportsFloat16Textures() const
   2226 {
   2227     return mSupportsFloat16Textures;
   2228 }
   2229 
   2230 bool Context::supportsFloat16LinearFilter() const
   2231 {
   2232     return mSupportsFloat16LinearFilter;
   2233 }
   2234 
   2235 bool Context::supportsFloat16RenderableTextures() const
   2236 {
   2237     return mSupportsFloat16RenderableTextures;
   2238 }
   2239 
   2240 int Context::getMaximumRenderbufferDimension() const
   2241 {
   2242     return mMaxRenderbufferDimension;
   2243 }
   2244 
   2245 int Context::getMaximumTextureDimension() const
   2246 {
   2247     return mMaxTextureDimension;
   2248 }
   2249 
   2250 int Context::getMaximumCubeTextureDimension() const
   2251 {
   2252     return mMaxCubeTextureDimension;
   2253 }
   2254 
   2255 int Context::getMaximumTextureLevel() const
   2256 {
   2257     return mMaxTextureLevel;
   2258 }
   2259 
   2260 bool Context::supportsLuminanceTextures() const
   2261 {
   2262     return mSupportsLuminanceTextures;
   2263 }
   2264 
   2265 bool Context::supportsLuminanceAlphaTextures() const
   2266 {
   2267     return mSupportsLuminanceAlphaTextures;
   2268 }
   2269 
   2270 bool Context::supportsDepthTextures() const
   2271 {
   2272     return mSupportsDepthTextures;
   2273 }
   2274 
   2275 bool Context::supports32bitIndices() const
   2276 {
   2277     return mSupports32bitIndices;
   2278 }
   2279 
   2280 bool Context::supportsNonPower2Texture() const
   2281 {
   2282     return mSupportsNonPower2Texture;
   2283 }
   2284 
   2285 bool Context::supportsInstancing() const
   2286 {
   2287     return mSupportsInstancing;
   2288 }
   2289 
   2290 bool Context::supportsTextureFilterAnisotropy() const
   2291 {
   2292     return mSupportsTextureFilterAnisotropy;
   2293 }
   2294 
   2295 float Context::getTextureMaxAnisotropy() const
   2296 {
   2297     return mMaxTextureAnisotropy;
   2298 }
   2299 
   2300 bool Context::getCurrentReadFormatType(GLenum *format, GLenum *type)
   2301 {
   2302     Framebuffer *framebuffer = getReadFramebuffer();
   2303     if (!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
   2304     {
   2305         return gl::error(GL_INVALID_OPERATION, false);
   2306     }
   2307 
   2308     Renderbuffer *renderbuffer = framebuffer->getReadColorbuffer();
   2309     if (!renderbuffer)
   2310     {
   2311         return gl::error(GL_INVALID_OPERATION, false);
   2312     }
   2313 
   2314     *format = gl::ExtractFormat(renderbuffer->getActualFormat());
   2315     *type = gl::ExtractType(renderbuffer->getActualFormat());
   2316 
   2317     return true;
   2318 }
   2319 
   2320 void Context::detachBuffer(GLuint buffer)
   2321 {
   2322     // [OpenGL ES 2.0.24] section 2.9 page 22:
   2323     // If a buffer object is deleted while it is bound, all bindings to that object in the current context
   2324     // (i.e. in the thread that called Delete-Buffers) are reset to zero.
   2325 
   2326     if (mState.arrayBuffer.id() == buffer)
   2327     {
   2328         mState.arrayBuffer.set(NULL);
   2329     }
   2330 
   2331     if (mState.elementArrayBuffer.id() == buffer)
   2332     {
   2333         mState.elementArrayBuffer.set(NULL);
   2334     }
   2335 
   2336     for (int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
   2337     {
   2338         if (mState.vertexAttribute[attribute].mBoundBuffer.id() == buffer)
   2339         {
   2340             mState.vertexAttribute[attribute].mBoundBuffer.set(NULL);
   2341         }
   2342     }
   2343 }
   2344 
   2345 void Context::detachTexture(GLuint texture)
   2346 {
   2347     // [OpenGL ES 2.0.24] section 3.8 page 84:
   2348     // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
   2349     // rebound to texture object zero
   2350 
   2351     for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
   2352     {
   2353         for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
   2354         {
   2355             if (mState.samplerTexture[type][sampler].id() == texture)
   2356             {
   2357                 mState.samplerTexture[type][sampler].set(NULL);
   2358             }
   2359         }
   2360     }
   2361 
   2362     // [OpenGL ES 2.0.24] section 4.4 page 112:
   2363     // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
   2364     // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
   2365     // image was attached in the currently bound framebuffer.
   2366 
   2367     Framebuffer *readFramebuffer = getReadFramebuffer();
   2368     Framebuffer *drawFramebuffer = getDrawFramebuffer();
   2369 
   2370     if (readFramebuffer)
   2371     {
   2372         readFramebuffer->detachTexture(texture);
   2373     }
   2374 
   2375     if (drawFramebuffer && drawFramebuffer != readFramebuffer)
   2376     {
   2377         drawFramebuffer->detachTexture(texture);
   2378     }
   2379 }
   2380 
   2381 void Context::detachFramebuffer(GLuint framebuffer)
   2382 {
   2383     // [OpenGL ES 2.0.24] section 4.4 page 107:
   2384     // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
   2385     // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
   2386 
   2387     if (mState.readFramebuffer == framebuffer)
   2388     {
   2389         bindReadFramebuffer(0);
   2390     }
   2391 
   2392     if (mState.drawFramebuffer == framebuffer)
   2393     {
   2394         bindDrawFramebuffer(0);
   2395     }
   2396 }
   2397 
   2398 void Context::detachRenderbuffer(GLuint renderbuffer)
   2399 {
   2400     // [OpenGL ES 2.0.24] section 4.4 page 109:
   2401     // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
   2402     // had been executed with the target RENDERBUFFER and name of zero.
   2403 
   2404     if (mState.renderbuffer.id() == renderbuffer)
   2405     {
   2406         bindRenderbuffer(0);
   2407     }
   2408 
   2409     // [OpenGL ES 2.0.24] section 4.4 page 111:
   2410     // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
   2411     // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
   2412     // point to which this image was attached in the currently bound framebuffer.
   2413 
   2414     Framebuffer *readFramebuffer = getReadFramebuffer();
   2415     Framebuffer *drawFramebuffer = getDrawFramebuffer();
   2416 
   2417     if (readFramebuffer)
   2418     {
   2419         readFramebuffer->detachRenderbuffer(renderbuffer);
   2420     }
   2421 
   2422     if (drawFramebuffer && drawFramebuffer != readFramebuffer)
   2423     {
   2424         drawFramebuffer->detachRenderbuffer(renderbuffer);
   2425     }
   2426 }
   2427 
   2428 Texture *Context::getIncompleteTexture(TextureType type)
   2429 {
   2430     Texture *t = mIncompleteTextures[type].get();
   2431 
   2432     if (t == NULL)
   2433     {
   2434         static const GLubyte color[] = { 0, 0, 0, 255 };
   2435 
   2436         switch (type)
   2437         {
   2438           default:
   2439             UNREACHABLE();
   2440             // default falls through to TEXTURE_2D
   2441 
   2442           case TEXTURE_2D:
   2443             {
   2444                 Texture2D *incomplete2d = new Texture2D(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
   2445                 incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
   2446                 t = incomplete2d;
   2447             }
   2448             break;
   2449 
   2450           case TEXTURE_CUBE:
   2451             {
   2452               TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
   2453 
   2454               incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
   2455               incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
   2456               incompleteCube->setImagePosY(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
   2457               incompleteCube->setImageNegY(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
   2458               incompleteCube->setImagePosZ(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
   2459               incompleteCube->setImageNegZ(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
   2460 
   2461               t = incompleteCube;
   2462             }
   2463             break;
   2464         }
   2465 
   2466         mIncompleteTextures[type].set(t);
   2467     }
   2468 
   2469     return t;
   2470 }
   2471 
   2472 bool Context::skipDraw(GLenum drawMode)
   2473 {
   2474     if (drawMode == GL_POINTS)
   2475     {
   2476         // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
   2477         // which affects varying interpolation. Since the value of gl_PointSize is
   2478         // undefined when not written, just skip drawing to avoid unexpected results.
   2479         if (!getCurrentProgramBinary()->usesPointSize())
   2480         {
   2481             // This is stictly speaking not an error, but developers should be
   2482             // notified of risking undefined behavior.
   2483             ERR("Point rendering without writing to gl_PointSize.");
   2484 
   2485             return true;
   2486         }
   2487     }
   2488     else if (IsTriangleMode(drawMode))
   2489     {
   2490         if (mState.rasterizer.cullFace && mState.rasterizer.cullMode == GL_FRONT_AND_BACK)
   2491         {
   2492             return true;
   2493         }
   2494     }
   2495 
   2496     return false;
   2497 }
   2498 
   2499 void Context::setVertexAttrib(GLuint index, const GLfloat *values)
   2500 {
   2501     ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
   2502 
   2503     mState.vertexAttribute[index].mCurrentValue[0] = values[0];
   2504     mState.vertexAttribute[index].mCurrentValue[1] = values[1];
   2505     mState.vertexAttribute[index].mCurrentValue[2] = values[2];
   2506     mState.vertexAttribute[index].mCurrentValue[3] = values[3];
   2507 }
   2508 
   2509 void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
   2510 {
   2511     ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
   2512 
   2513     mState.vertexAttribute[index].mDivisor = divisor;
   2514 }
   2515 
   2516 // keep list sorted in following order
   2517 // OES extensions
   2518 // EXT extensions
   2519 // Vendor extensions
   2520 void Context::initExtensionString()
   2521 {
   2522     std::string extensionString = "";
   2523 
   2524     // OES extensions
   2525     if (supports32bitIndices())
   2526     {
   2527         extensionString += "GL_OES_element_index_uint ";
   2528     }
   2529 
   2530     extensionString += "GL_OES_packed_depth_stencil ";
   2531     extensionString += "GL_OES_get_program_binary ";
   2532     extensionString += "GL_OES_rgb8_rgba8 ";
   2533     if (mRenderer->getDerivativeInstructionSupport())
   2534     {
   2535         extensionString += "GL_OES_standard_derivatives ";
   2536     }
   2537 
   2538     if (supportsFloat16Textures())
   2539     {
   2540         extensionString += "GL_OES_texture_half_float ";
   2541     }
   2542     if (supportsFloat16LinearFilter())
   2543     {
   2544         extensionString += "GL_OES_texture_half_float_linear ";
   2545     }
   2546     if (supportsFloat32Textures())
   2547     {
   2548         extensionString += "GL_OES_texture_float ";
   2549     }
   2550     if (supportsFloat32LinearFilter())
   2551     {
   2552         extensionString += "GL_OES_texture_float_linear ";
   2553     }
   2554 
   2555     if (supportsNonPower2Texture())
   2556     {
   2557         extensionString += "GL_OES_texture_npot ";
   2558     }
   2559 
   2560     // Multi-vendor (EXT) extensions
   2561     if (supportsOcclusionQueries())
   2562     {
   2563         extensionString += "GL_EXT_occlusion_query_boolean ";
   2564     }
   2565 
   2566     extensionString += "GL_EXT_read_format_bgra ";
   2567     extensionString += "GL_EXT_robustness ";
   2568 
   2569     if (supportsDXT1Textures())
   2570     {
   2571         extensionString += "GL_EXT_texture_compression_dxt1 ";
   2572     }
   2573 
   2574     if (supportsTextureFilterAnisotropy())
   2575     {
   2576         extensionString += "GL_EXT_texture_filter_anisotropic ";
   2577     }
   2578 
   2579     if (supportsBGRATextures())
   2580     {
   2581         extensionString += "GL_EXT_texture_format_BGRA8888 ";
   2582     }
   2583 
   2584     if (mRenderer->getMaxRenderTargets() > 1)
   2585     {
   2586         extensionString += "GL_EXT_draw_buffers ";
   2587     }
   2588 
   2589     extensionString += "GL_EXT_texture_storage ";
   2590     extensionString += "GL_EXT_frag_depth ";
   2591 
   2592     // ANGLE-specific extensions
   2593     if (supportsDepthTextures())
   2594     {
   2595         extensionString += "GL_ANGLE_depth_texture ";
   2596     }
   2597 
   2598     extensionString += "GL_ANGLE_framebuffer_blit ";
   2599     if (getMaxSupportedSamples() != 0)
   2600     {
   2601         extensionString += "GL_ANGLE_framebuffer_multisample ";
   2602     }
   2603 
   2604     if (supportsInstancing())
   2605     {
   2606         extensionString += "GL_ANGLE_instanced_arrays ";
   2607     }
   2608 
   2609     extensionString += "GL_ANGLE_pack_reverse_row_order ";
   2610 
   2611     if (supportsDXT3Textures())
   2612     {
   2613         extensionString += "GL_ANGLE_texture_compression_dxt3 ";
   2614     }
   2615     if (supportsDXT5Textures())
   2616     {
   2617         extensionString += "GL_ANGLE_texture_compression_dxt5 ";
   2618     }
   2619 
   2620     extensionString += "GL_ANGLE_texture_usage ";
   2621     extensionString += "GL_ANGLE_translated_shader_source ";
   2622 
   2623     // Other vendor-specific extensions
   2624     if (supportsEventQueries())
   2625     {
   2626         extensionString += "GL_NV_fence ";
   2627     }
   2628 
   2629     std::string::size_type end = extensionString.find_last_not_of(' ');
   2630     if (end != std::string::npos)
   2631     {
   2632         extensionString.resize(end+1);
   2633     }
   2634 
   2635     mExtensionString = makeStaticString(extensionString);
   2636 }
   2637 
   2638 const char *Context::getExtensionString() const
   2639 {
   2640     return mExtensionString;
   2641 }
   2642 
   2643 void Context::initRendererString()
   2644 {
   2645     std::ostringstream rendererString;
   2646     rendererString << "ANGLE (";
   2647     rendererString << mRenderer->getRendererDescription();
   2648     rendererString << ")";
   2649 
   2650     mRendererString = makeStaticString(rendererString.str());
   2651 }
   2652 
   2653 const char *Context::getRendererString() const
   2654 {
   2655     return mRendererString;
   2656 }
   2657 
   2658 void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
   2659                               GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
   2660                               GLbitfield mask)
   2661 {
   2662     Framebuffer *readFramebuffer = getReadFramebuffer();
   2663     Framebuffer *drawFramebuffer = getDrawFramebuffer();
   2664 
   2665     if (!readFramebuffer || readFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE ||
   2666         !drawFramebuffer || drawFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
   2667     {
   2668         return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
   2669     }
   2670 
   2671     if (drawFramebuffer->getSamples() != 0)
   2672     {
   2673         return gl::error(GL_INVALID_OPERATION);
   2674     }
   2675 
   2676     Renderbuffer *readColorBuffer = readFramebuffer->getReadColorbuffer();
   2677     Renderbuffer *drawColorBuffer = drawFramebuffer->getFirstColorbuffer();
   2678 
   2679     if (drawColorBuffer == NULL)
   2680     {
   2681         ERR("Draw buffers formats don't match, which is not supported in this implementation of BlitFramebufferANGLE");
   2682         return gl::error(GL_INVALID_OPERATION);
   2683     }
   2684 
   2685     int readBufferWidth = readColorBuffer->getWidth();
   2686     int readBufferHeight = readColorBuffer->getHeight();
   2687     int drawBufferWidth = drawColorBuffer->getWidth();
   2688     int drawBufferHeight = drawColorBuffer->getHeight();
   2689 
   2690     Rectangle sourceRect;
   2691     Rectangle destRect;
   2692 
   2693     if (srcX0 < srcX1)
   2694     {
   2695         sourceRect.x = srcX0;
   2696         destRect.x = dstX0;
   2697         sourceRect.width = srcX1 - srcX0;
   2698         destRect.width = dstX1 - dstX0;
   2699     }
   2700     else
   2701     {
   2702         sourceRect.x = srcX1;
   2703         destRect.x = dstX1;
   2704         sourceRect.width = srcX0 - srcX1;
   2705         destRect.width = dstX0 - dstX1;
   2706     }
   2707 
   2708     if (srcY0 < srcY1)
   2709     {
   2710         sourceRect.height = srcY1 - srcY0;
   2711         destRect.height = dstY1 - dstY0;
   2712         sourceRect.y = srcY0;
   2713         destRect.y = dstY0;
   2714     }
   2715     else
   2716     {
   2717         sourceRect.height = srcY0 - srcY1;
   2718         destRect.height = dstY0 - srcY1;
   2719         sourceRect.y = srcY1;
   2720         destRect.y = dstY1;
   2721     }
   2722 
   2723     Rectangle sourceScissoredRect = sourceRect;
   2724     Rectangle destScissoredRect = destRect;
   2725 
   2726     if (mState.scissorTest)
   2727     {
   2728         // Only write to parts of the destination framebuffer which pass the scissor test.
   2729         if (destRect.x < mState.scissor.x)
   2730         {
   2731             int xDiff = mState.scissor.x - destRect.x;
   2732             destScissoredRect.x = mState.scissor.x;
   2733             destScissoredRect.width -= xDiff;
   2734             sourceScissoredRect.x += xDiff;
   2735             sourceScissoredRect.width -= xDiff;
   2736 
   2737         }
   2738 
   2739         if (destRect.x + destRect.width > mState.scissor.x + mState.scissor.width)
   2740         {
   2741             int xDiff = (destRect.x + destRect.width) - (mState.scissor.x + mState.scissor.width);
   2742             destScissoredRect.width -= xDiff;
   2743             sourceScissoredRect.width -= xDiff;
   2744         }
   2745 
   2746         if (destRect.y < mState.scissor.y)
   2747         {
   2748             int yDiff = mState.scissor.y - destRect.y;
   2749             destScissoredRect.y = mState.scissor.y;
   2750             destScissoredRect.height -= yDiff;
   2751             sourceScissoredRect.y += yDiff;
   2752             sourceScissoredRect.height -= yDiff;
   2753         }
   2754 
   2755         if (destRect.y + destRect.height > mState.scissor.y + mState.scissor.height)
   2756         {
   2757             int yDiff = (destRect.y + destRect.height) - (mState.scissor.y + mState.scissor.height);
   2758             destScissoredRect.height  -= yDiff;
   2759             sourceScissoredRect.height -= yDiff;
   2760         }
   2761     }
   2762 
   2763     bool blitRenderTarget = false;
   2764     bool blitDepthStencil = false;
   2765 
   2766     Rectangle sourceTrimmedRect = sourceScissoredRect;
   2767     Rectangle destTrimmedRect = destScissoredRect;
   2768 
   2769     // The source & destination rectangles also may need to be trimmed if they fall out of the bounds of
   2770     // the actual draw and read surfaces.
   2771     if (sourceTrimmedRect.x < 0)
   2772     {
   2773         int xDiff = 0 - sourceTrimmedRect.x;
   2774         sourceTrimmedRect.x = 0;
   2775         sourceTrimmedRect.width -= xDiff;
   2776         destTrimmedRect.x += xDiff;
   2777         destTrimmedRect.width -= xDiff;
   2778     }
   2779 
   2780     if (sourceTrimmedRect.x + sourceTrimmedRect.width > readBufferWidth)
   2781     {
   2782         int xDiff = (sourceTrimmedRect.x + sourceTrimmedRect.width) - readBufferWidth;
   2783         sourceTrimmedRect.width -= xDiff;
   2784         destTrimmedRect.width -= xDiff;
   2785     }
   2786 
   2787     if (sourceTrimmedRect.y < 0)
   2788     {
   2789         int yDiff = 0 - sourceTrimmedRect.y;
   2790         sourceTrimmedRect.y = 0;
   2791         sourceTrimmedRect.height -= yDiff;
   2792         destTrimmedRect.y += yDiff;
   2793         destTrimmedRect.height -= yDiff;
   2794     }
   2795 
   2796     if (sourceTrimmedRect.y + sourceTrimmedRect.height > readBufferHeight)
   2797     {
   2798         int yDiff = (sourceTrimmedRect.y + sourceTrimmedRect.height) - readBufferHeight;
   2799         sourceTrimmedRect.height -= yDiff;
   2800         destTrimmedRect.height -= yDiff;
   2801     }
   2802 
   2803     if (destTrimmedRect.x < 0)
   2804     {
   2805         int xDiff = 0 - destTrimmedRect.x;
   2806         destTrimmedRect.x = 0;
   2807         destTrimmedRect.width -= xDiff;
   2808         sourceTrimmedRect.x += xDiff;
   2809         sourceTrimmedRect.width -= xDiff;
   2810     }
   2811 
   2812     if (destTrimmedRect.x + destTrimmedRect.width > drawBufferWidth)
   2813     {
   2814         int xDiff = (destTrimmedRect.x + destTrimmedRect.width) - drawBufferWidth;
   2815         destTrimmedRect.width -= xDiff;
   2816         sourceTrimmedRect.width -= xDiff;
   2817     }
   2818 
   2819     if (destTrimmedRect.y < 0)
   2820     {
   2821         int yDiff = 0 - destTrimmedRect.y;
   2822         destTrimmedRect.y = 0;
   2823         destTrimmedRect.height -= yDiff;
   2824         sourceTrimmedRect.y += yDiff;
   2825         sourceTrimmedRect.height -= yDiff;
   2826     }
   2827 
   2828     if (destTrimmedRect.y + destTrimmedRect.height > drawBufferHeight)
   2829     {
   2830         int yDiff = (destTrimmedRect.y + destTrimmedRect.height) - drawBufferHeight;
   2831         destTrimmedRect.height -= yDiff;
   2832         sourceTrimmedRect.height -= yDiff;
   2833     }
   2834 
   2835     bool partialBufferCopy = false;
   2836     if (sourceTrimmedRect.height < readBufferHeight ||
   2837         sourceTrimmedRect.width < readBufferWidth ||
   2838         destTrimmedRect.height < drawBufferHeight ||
   2839         destTrimmedRect.width < drawBufferWidth ||
   2840         sourceTrimmedRect.y != 0 || destTrimmedRect.y != 0 || sourceTrimmedRect.x != 0 || destTrimmedRect.x != 0)
   2841     {
   2842         partialBufferCopy = true;
   2843     }
   2844 
   2845     if (mask & GL_COLOR_BUFFER_BIT)
   2846     {
   2847         const GLenum readColorbufferType = readFramebuffer->getReadColorbufferType();
   2848         const bool validReadType = (readColorbufferType == GL_TEXTURE_2D) || (readColorbufferType == GL_RENDERBUFFER);
   2849         bool validDrawType = true;
   2850         bool validDrawFormat = true;
   2851 
   2852         for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
   2853         {
   2854             if (drawFramebuffer->isEnabledColorAttachment(colorAttachment))
   2855             {
   2856                 if (drawFramebuffer->getColorbufferType(colorAttachment) != GL_TEXTURE_2D &&
   2857                     drawFramebuffer->getColorbufferType(colorAttachment) != GL_RENDERBUFFER)
   2858                 {
   2859                     validDrawType = false;
   2860                 }
   2861 
   2862                 if (drawFramebuffer->getColorbuffer(colorAttachment)->getActualFormat() != readColorBuffer->getActualFormat())
   2863                 {
   2864                     validDrawFormat = false;
   2865                 }
   2866             }
   2867         }
   2868 
   2869         if (!validReadType || !validDrawType || !validDrawFormat)
   2870         {
   2871             ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation");
   2872             return gl::error(GL_INVALID_OPERATION);
   2873         }
   2874 
   2875         if (partialBufferCopy && readFramebuffer->getSamples() != 0)
   2876         {
   2877             return gl::error(GL_INVALID_OPERATION);
   2878         }
   2879 
   2880         blitRenderTarget = true;
   2881 
   2882     }
   2883 
   2884     if (mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
   2885     {
   2886         Renderbuffer *readDSBuffer = NULL;
   2887         Renderbuffer *drawDSBuffer = NULL;
   2888 
   2889         // We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have
   2890         // both a depth and stencil buffer, it will be the same buffer.
   2891 
   2892         if (mask & GL_DEPTH_BUFFER_BIT)
   2893         {
   2894             if (readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
   2895             {
   2896                 if (readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() ||
   2897                     readFramebuffer->getDepthbuffer()->getActualFormat() != drawFramebuffer->getDepthbuffer()->getActualFormat())
   2898                 {
   2899                     return gl::error(GL_INVALID_OPERATION);
   2900                 }
   2901 
   2902                 blitDepthStencil = true;
   2903                 readDSBuffer = readFramebuffer->getDepthbuffer();
   2904                 drawDSBuffer = drawFramebuffer->getDepthbuffer();
   2905             }
   2906         }
   2907 
   2908         if (mask & GL_STENCIL_BUFFER_BIT)
   2909         {
   2910             if (readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
   2911             {
   2912                 if (readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() ||
   2913                     readFramebuffer->getStencilbuffer()->getActualFormat() != drawFramebuffer->getStencilbuffer()->getActualFormat())
   2914                 {
   2915                     return gl::error(GL_INVALID_OPERATION);
   2916                 }
   2917 
   2918                 blitDepthStencil = true;
   2919                 readDSBuffer = readFramebuffer->getStencilbuffer();
   2920                 drawDSBuffer = drawFramebuffer->getStencilbuffer();
   2921             }
   2922         }
   2923 
   2924         if (partialBufferCopy)
   2925         {
   2926             ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
   2927             return gl::error(GL_INVALID_OPERATION); // only whole-buffer copies are permitted
   2928         }
   2929 
   2930         if ((drawDSBuffer && drawDSBuffer->getSamples() != 0) ||
   2931             (readDSBuffer && readDSBuffer->getSamples() != 0))
   2932         {
   2933             return gl::error(GL_INVALID_OPERATION);
   2934         }
   2935     }
   2936 
   2937     if (blitRenderTarget || blitDepthStencil)
   2938     {
   2939         mRenderer->blitRect(readFramebuffer, sourceTrimmedRect, drawFramebuffer, destTrimmedRect, blitRenderTarget, blitDepthStencil);
   2940     }
   2941 }
   2942 
   2943 }
   2944 
   2945 extern "C"
   2946 {
   2947 gl::Context *glCreateContext(const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
   2948 {
   2949     return new gl::Context(shareContext, renderer, notifyResets, robustAccess);
   2950 }
   2951 
   2952 void glDestroyContext(gl::Context *context)
   2953 {
   2954     delete context;
   2955 
   2956     if (context == gl::getContext())
   2957     {
   2958         gl::makeCurrent(NULL, NULL, NULL);
   2959     }
   2960 }
   2961 
   2962 void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface)
   2963 {
   2964     gl::makeCurrent(context, display, surface);
   2965 }
   2966 
   2967 gl::Context *glGetCurrentContext()
   2968 {
   2969     return gl::getContext();
   2970 }
   2971 
   2972 }
   2973