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     FramebufferTextureSerialSet boundFramebufferTextures = getBoundFramebufferTextureSerials();
   1816 
   1817     // Range of Direct3D samplers of given sampler type
   1818     int samplerCount = (type == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : mRenderer->getMaxVertexTextureImageUnits();
   1819     int samplerRange = programBinary->getUsedSamplerRange(type);
   1820 
   1821     for (int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
   1822     {
   1823         int textureUnit = programBinary->getSamplerMapping(type, samplerIndex);   // OpenGL texture image unit index
   1824 
   1825         if (textureUnit != -1)
   1826         {
   1827             TextureType textureType = programBinary->getSamplerTextureType(type, samplerIndex);
   1828             Texture *texture = getSamplerTexture(textureUnit, textureType);
   1829 
   1830             if (texture->isSamplerComplete() &&
   1831                 boundFramebufferTextures.find(texture->getTextureSerial()) == boundFramebufferTextures.end())
   1832             {
   1833                 SamplerState samplerState;
   1834                 texture->getSamplerState(&samplerState);
   1835                 mRenderer->setSamplerState(type, samplerIndex, samplerState);
   1836 
   1837                 mRenderer->setTexture(type, samplerIndex, texture);
   1838 
   1839                 texture->resetDirty();
   1840             }
   1841             else
   1842             {
   1843                 mRenderer->setTexture(type, samplerIndex, getIncompleteTexture(textureType));
   1844             }
   1845         }
   1846         else
   1847         {
   1848             mRenderer->setTexture(type, samplerIndex, NULL);
   1849         }
   1850     }
   1851 
   1852     for (int samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
   1853     {
   1854         mRenderer->setTexture(type, samplerIndex, NULL);
   1855     }
   1856 }
   1857 
   1858 void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
   1859                          GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
   1860 {
   1861     Framebuffer *framebuffer = getReadFramebuffer();
   1862 
   1863     if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
   1864     {
   1865         return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
   1866     }
   1867 
   1868     if (getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0)
   1869     {
   1870         return gl::error(GL_INVALID_OPERATION);
   1871     }
   1872 
   1873     GLsizei outputPitch = ComputePitch(width, ConvertSizedInternalFormat(format, type), getPackAlignment());
   1874     // sized query sanity check
   1875     if (bufSize)
   1876     {
   1877         int requiredSize = outputPitch * height;
   1878         if (requiredSize > *bufSize)
   1879         {
   1880             return gl::error(GL_INVALID_OPERATION);
   1881         }
   1882     }
   1883 
   1884     mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, getPackReverseRowOrder(), getPackAlignment(), pixels);
   1885 }
   1886 
   1887 void Context::clear(GLbitfield mask)
   1888 {
   1889     Framebuffer *framebufferObject = getDrawFramebuffer();
   1890 
   1891     if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
   1892     {
   1893         return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
   1894     }
   1895 
   1896     DWORD flags = 0;
   1897     GLbitfield finalMask = 0;
   1898 
   1899     if (mask & GL_COLOR_BUFFER_BIT)
   1900     {
   1901         mask &= ~GL_COLOR_BUFFER_BIT;
   1902 
   1903         if (framebufferObject->hasEnabledColorAttachment())
   1904         {
   1905             finalMask |= GL_COLOR_BUFFER_BIT;
   1906         }
   1907     }
   1908 
   1909     if (mask & GL_DEPTH_BUFFER_BIT)
   1910     {
   1911         mask &= ~GL_DEPTH_BUFFER_BIT;
   1912         if (mState.depthStencil.depthMask && framebufferObject->getDepthbufferType() != GL_NONE)
   1913         {
   1914             finalMask |= GL_DEPTH_BUFFER_BIT;
   1915         }
   1916     }
   1917 
   1918     if (mask & GL_STENCIL_BUFFER_BIT)
   1919     {
   1920         mask &= ~GL_STENCIL_BUFFER_BIT;
   1921         if (framebufferObject->getStencilbufferType() != GL_NONE)
   1922         {
   1923             rx::RenderTarget *depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
   1924             if (!depthStencil)
   1925             {
   1926                 ERR("Depth stencil pointer unexpectedly null.");
   1927                 return;
   1928             }
   1929 
   1930             if (GetStencilSize(depthStencil->getActualFormat()) > 0)
   1931             {
   1932                 finalMask |= GL_STENCIL_BUFFER_BIT;
   1933             }
   1934         }
   1935     }
   1936 
   1937     if (mask != 0)
   1938     {
   1939         return gl::error(GL_INVALID_VALUE);
   1940     }
   1941 
   1942     if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
   1943     {
   1944         return;
   1945     }
   1946 
   1947     ClearParameters clearParams;
   1948     clearParams.mask = finalMask;
   1949     clearParams.colorClearValue = mState.colorClearValue;
   1950     clearParams.colorMaskRed = mState.blend.colorMaskRed;
   1951     clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
   1952     clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
   1953     clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
   1954     clearParams.depthClearValue = mState.depthClearValue;
   1955     clearParams.stencilClearValue = mState.stencilClearValue;
   1956     clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
   1957 
   1958     mRenderer->clear(clearParams, framebufferObject);
   1959 }
   1960 
   1961 void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
   1962 {
   1963     if (!mState.currentProgram)
   1964     {
   1965         return gl::error(GL_INVALID_OPERATION);
   1966     }
   1967 
   1968     if (!mRenderer->applyPrimitiveType(mode, count))
   1969     {
   1970         return;
   1971     }
   1972 
   1973     if (!applyRenderTarget(mode, false))
   1974     {
   1975         return;
   1976     }
   1977 
   1978     applyState(mode);
   1979 
   1980     ProgramBinary *programBinary = getCurrentProgramBinary();
   1981 
   1982     GLenum err = mRenderer->applyVertexBuffer(programBinary, mState.vertexAttribute, first, count, instances);
   1983     if (err != GL_NO_ERROR)
   1984     {
   1985         return gl::error(err);
   1986     }
   1987 
   1988     applyShaders();
   1989     applyTextures();
   1990 
   1991     if (!programBinary->validateSamplers(NULL))
   1992     {
   1993         return gl::error(GL_INVALID_OPERATION);
   1994     }
   1995 
   1996     if (!skipDraw(mode))
   1997     {
   1998         mRenderer->drawArrays(mode, count, instances);
   1999     }
   2000 }
   2001 
   2002 void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances)
   2003 {
   2004     if (!mState.currentProgram)
   2005     {
   2006         return gl::error(GL_INVALID_OPERATION);
   2007     }
   2008 
   2009     if (!indices && !mState.elementArrayBuffer)
   2010     {
   2011         return gl::error(GL_INVALID_OPERATION);
   2012     }
   2013 
   2014     if (!mRenderer->applyPrimitiveType(mode, count))
   2015     {
   2016         return;
   2017     }
   2018 
   2019     if (!applyRenderTarget(mode, false))
   2020     {
   2021         return;
   2022     }
   2023 
   2024     applyState(mode);
   2025 
   2026     rx::TranslatedIndexData indexInfo;
   2027     GLenum err = mRenderer->applyIndexBuffer(indices, mState.elementArrayBuffer.get(), count, mode, type, &indexInfo);
   2028     if (err != GL_NO_ERROR)
   2029     {
   2030         return gl::error(err);
   2031     }
   2032 
   2033     ProgramBinary *programBinary = getCurrentProgramBinary();
   2034 
   2035     GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
   2036     err = mRenderer->applyVertexBuffer(programBinary, mState.vertexAttribute, indexInfo.minIndex, vertexCount, instances);
   2037     if (err != GL_NO_ERROR)
   2038     {
   2039         return gl::error(err);
   2040     }
   2041 
   2042     applyShaders();
   2043     applyTextures();
   2044 
   2045     if (!programBinary->validateSamplers(NULL))
   2046     {
   2047         return gl::error(GL_INVALID_OPERATION);
   2048     }
   2049 
   2050     if (!skipDraw(mode))
   2051     {
   2052         mRenderer->drawElements(mode, count, type, indices, mState.elementArrayBuffer.get(), indexInfo, instances);
   2053     }
   2054 }
   2055 
   2056 // Implements glFlush when block is false, glFinish when block is true
   2057 void Context::sync(bool block)
   2058 {
   2059     mRenderer->sync(block);
   2060 }
   2061 
   2062 void Context::recordInvalidEnum()
   2063 {
   2064     mInvalidEnum = true;
   2065 }
   2066 
   2067 void Context::recordInvalidValue()
   2068 {
   2069     mInvalidValue = true;
   2070 }
   2071 
   2072 void Context::recordInvalidOperation()
   2073 {
   2074     mInvalidOperation = true;
   2075 }
   2076 
   2077 void Context::recordOutOfMemory()
   2078 {
   2079     mOutOfMemory = true;
   2080 }
   2081 
   2082 void Context::recordInvalidFramebufferOperation()
   2083 {
   2084     mInvalidFramebufferOperation = true;
   2085 }
   2086 
   2087 // Get one of the recorded errors and clear its flag, if any.
   2088 // [OpenGL ES 2.0.24] section 2.5 page 13.
   2089 GLenum Context::getError()
   2090 {
   2091     if (mInvalidEnum)
   2092     {
   2093         mInvalidEnum = false;
   2094 
   2095         return GL_INVALID_ENUM;
   2096     }
   2097 
   2098     if (mInvalidValue)
   2099     {
   2100         mInvalidValue = false;
   2101 
   2102         return GL_INVALID_VALUE;
   2103     }
   2104 
   2105     if (mInvalidOperation)
   2106     {
   2107         mInvalidOperation = false;
   2108 
   2109         return GL_INVALID_OPERATION;
   2110     }
   2111 
   2112     if (mOutOfMemory)
   2113     {
   2114         mOutOfMemory = false;
   2115 
   2116         return GL_OUT_OF_MEMORY;
   2117     }
   2118 
   2119     if (mInvalidFramebufferOperation)
   2120     {
   2121         mInvalidFramebufferOperation = false;
   2122 
   2123         return GL_INVALID_FRAMEBUFFER_OPERATION;
   2124     }
   2125 
   2126     return GL_NO_ERROR;
   2127 }
   2128 
   2129 GLenum Context::getResetStatus()
   2130 {
   2131     if (mResetStatus == GL_NO_ERROR && !mContextLost)
   2132     {
   2133         // mResetStatus will be set by the markContextLost callback
   2134         // in the case a notification is sent
   2135         mRenderer->testDeviceLost(true);
   2136     }
   2137 
   2138     GLenum status = mResetStatus;
   2139 
   2140     if (mResetStatus != GL_NO_ERROR)
   2141     {
   2142         ASSERT(mContextLost);
   2143 
   2144         if (mRenderer->testDeviceResettable())
   2145         {
   2146             mResetStatus = GL_NO_ERROR;
   2147         }
   2148     }
   2149 
   2150     return status;
   2151 }
   2152 
   2153 bool Context::isResetNotificationEnabled()
   2154 {
   2155     return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
   2156 }
   2157 
   2158 int Context::getMajorShaderModel() const
   2159 {
   2160     return mMajorShaderModel;
   2161 }
   2162 
   2163 float Context::getMaximumPointSize() const
   2164 {
   2165     return mMaximumPointSize;
   2166 }
   2167 
   2168 unsigned int Context::getMaximumCombinedTextureImageUnits() const
   2169 {
   2170     return mRenderer->getMaxCombinedTextureImageUnits();
   2171 }
   2172 
   2173 int Context::getMaxSupportedSamples() const
   2174 {
   2175     return mRenderer->getMaxSupportedSamples();
   2176 }
   2177 
   2178 unsigned int Context::getMaximumRenderTargets() const
   2179 {
   2180     return mRenderer->getMaxRenderTargets();
   2181 }
   2182 
   2183 bool Context::supportsEventQueries() const
   2184 {
   2185     return mSupportsEventQueries;
   2186 }
   2187 
   2188 bool Context::supportsOcclusionQueries() const
   2189 {
   2190     return mSupportsOcclusionQueries;
   2191 }
   2192 
   2193 bool Context::supportsBGRATextures() const
   2194 {
   2195     return mSupportsBGRATextures;
   2196 }
   2197 
   2198 bool Context::supportsDXT1Textures() const
   2199 {
   2200     return mSupportsDXT1Textures;
   2201 }
   2202 
   2203 bool Context::supportsDXT3Textures() const
   2204 {
   2205     return mSupportsDXT3Textures;
   2206 }
   2207 
   2208 bool Context::supportsDXT5Textures() const
   2209 {
   2210     return mSupportsDXT5Textures;
   2211 }
   2212 
   2213 bool Context::supportsFloat32Textures() const
   2214 {
   2215     return mSupportsFloat32Textures;
   2216 }
   2217 
   2218 bool Context::supportsFloat32LinearFilter() const
   2219 {
   2220     return mSupportsFloat32LinearFilter;
   2221 }
   2222 
   2223 bool Context::supportsFloat32RenderableTextures() const
   2224 {
   2225     return mSupportsFloat32RenderableTextures;
   2226 }
   2227 
   2228 bool Context::supportsFloat16Textures() const
   2229 {
   2230     return mSupportsFloat16Textures;
   2231 }
   2232 
   2233 bool Context::supportsFloat16LinearFilter() const
   2234 {
   2235     return mSupportsFloat16LinearFilter;
   2236 }
   2237 
   2238 bool Context::supportsFloat16RenderableTextures() const
   2239 {
   2240     return mSupportsFloat16RenderableTextures;
   2241 }
   2242 
   2243 int Context::getMaximumRenderbufferDimension() const
   2244 {
   2245     return mMaxRenderbufferDimension;
   2246 }
   2247 
   2248 int Context::getMaximumTextureDimension() const
   2249 {
   2250     return mMaxTextureDimension;
   2251 }
   2252 
   2253 int Context::getMaximumCubeTextureDimension() const
   2254 {
   2255     return mMaxCubeTextureDimension;
   2256 }
   2257 
   2258 int Context::getMaximumTextureLevel() const
   2259 {
   2260     return mMaxTextureLevel;
   2261 }
   2262 
   2263 bool Context::supportsLuminanceTextures() const
   2264 {
   2265     return mSupportsLuminanceTextures;
   2266 }
   2267 
   2268 bool Context::supportsLuminanceAlphaTextures() const
   2269 {
   2270     return mSupportsLuminanceAlphaTextures;
   2271 }
   2272 
   2273 bool Context::supportsDepthTextures() const
   2274 {
   2275     return mSupportsDepthTextures;
   2276 }
   2277 
   2278 bool Context::supports32bitIndices() const
   2279 {
   2280     return mSupports32bitIndices;
   2281 }
   2282 
   2283 bool Context::supportsNonPower2Texture() const
   2284 {
   2285     return mSupportsNonPower2Texture;
   2286 }
   2287 
   2288 bool Context::supportsInstancing() const
   2289 {
   2290     return mSupportsInstancing;
   2291 }
   2292 
   2293 bool Context::supportsTextureFilterAnisotropy() const
   2294 {
   2295     return mSupportsTextureFilterAnisotropy;
   2296 }
   2297 
   2298 float Context::getTextureMaxAnisotropy() const
   2299 {
   2300     return mMaxTextureAnisotropy;
   2301 }
   2302 
   2303 bool Context::getCurrentReadFormatType(GLenum *format, GLenum *type)
   2304 {
   2305     Framebuffer *framebuffer = getReadFramebuffer();
   2306     if (!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
   2307     {
   2308         return gl::error(GL_INVALID_OPERATION, false);
   2309     }
   2310 
   2311     Renderbuffer *renderbuffer = framebuffer->getReadColorbuffer();
   2312     if (!renderbuffer)
   2313     {
   2314         return gl::error(GL_INVALID_OPERATION, false);
   2315     }
   2316 
   2317     *format = gl::ExtractFormat(renderbuffer->getActualFormat());
   2318     *type = gl::ExtractType(renderbuffer->getActualFormat());
   2319 
   2320     return true;
   2321 }
   2322 
   2323 void Context::detachBuffer(GLuint buffer)
   2324 {
   2325     // [OpenGL ES 2.0.24] section 2.9 page 22:
   2326     // If a buffer object is deleted while it is bound, all bindings to that object in the current context
   2327     // (i.e. in the thread that called Delete-Buffers) are reset to zero.
   2328 
   2329     if (mState.arrayBuffer.id() == buffer)
   2330     {
   2331         mState.arrayBuffer.set(NULL);
   2332     }
   2333 
   2334     if (mState.elementArrayBuffer.id() == buffer)
   2335     {
   2336         mState.elementArrayBuffer.set(NULL);
   2337     }
   2338 
   2339     for (int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
   2340     {
   2341         if (mState.vertexAttribute[attribute].mBoundBuffer.id() == buffer)
   2342         {
   2343             mState.vertexAttribute[attribute].mBoundBuffer.set(NULL);
   2344         }
   2345     }
   2346 }
   2347 
   2348 void Context::detachTexture(GLuint texture)
   2349 {
   2350     // [OpenGL ES 2.0.24] section 3.8 page 84:
   2351     // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
   2352     // rebound to texture object zero
   2353 
   2354     for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
   2355     {
   2356         for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
   2357         {
   2358             if (mState.samplerTexture[type][sampler].id() == texture)
   2359             {
   2360                 mState.samplerTexture[type][sampler].set(NULL);
   2361             }
   2362         }
   2363     }
   2364 
   2365     // [OpenGL ES 2.0.24] section 4.4 page 112:
   2366     // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
   2367     // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
   2368     // image was attached in the currently bound framebuffer.
   2369 
   2370     Framebuffer *readFramebuffer = getReadFramebuffer();
   2371     Framebuffer *drawFramebuffer = getDrawFramebuffer();
   2372 
   2373     if (readFramebuffer)
   2374     {
   2375         readFramebuffer->detachTexture(texture);
   2376     }
   2377 
   2378     if (drawFramebuffer && drawFramebuffer != readFramebuffer)
   2379     {
   2380         drawFramebuffer->detachTexture(texture);
   2381     }
   2382 }
   2383 
   2384 void Context::detachFramebuffer(GLuint framebuffer)
   2385 {
   2386     // [OpenGL ES 2.0.24] section 4.4 page 107:
   2387     // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
   2388     // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
   2389 
   2390     if (mState.readFramebuffer == framebuffer)
   2391     {
   2392         bindReadFramebuffer(0);
   2393     }
   2394 
   2395     if (mState.drawFramebuffer == framebuffer)
   2396     {
   2397         bindDrawFramebuffer(0);
   2398     }
   2399 }
   2400 
   2401 void Context::detachRenderbuffer(GLuint renderbuffer)
   2402 {
   2403     // [OpenGL ES 2.0.24] section 4.4 page 109:
   2404     // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
   2405     // had been executed with the target RENDERBUFFER and name of zero.
   2406 
   2407     if (mState.renderbuffer.id() == renderbuffer)
   2408     {
   2409         bindRenderbuffer(0);
   2410     }
   2411 
   2412     // [OpenGL ES 2.0.24] section 4.4 page 111:
   2413     // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
   2414     // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
   2415     // point to which this image was attached in the currently bound framebuffer.
   2416 
   2417     Framebuffer *readFramebuffer = getReadFramebuffer();
   2418     Framebuffer *drawFramebuffer = getDrawFramebuffer();
   2419 
   2420     if (readFramebuffer)
   2421     {
   2422         readFramebuffer->detachRenderbuffer(renderbuffer);
   2423     }
   2424 
   2425     if (drawFramebuffer && drawFramebuffer != readFramebuffer)
   2426     {
   2427         drawFramebuffer->detachRenderbuffer(renderbuffer);
   2428     }
   2429 }
   2430 
   2431 Texture *Context::getIncompleteTexture(TextureType type)
   2432 {
   2433     Texture *t = mIncompleteTextures[type].get();
   2434 
   2435     if (t == NULL)
   2436     {
   2437         static const GLubyte color[] = { 0, 0, 0, 255 };
   2438 
   2439         switch (type)
   2440         {
   2441           default:
   2442             UNREACHABLE();
   2443             // default falls through to TEXTURE_2D
   2444 
   2445           case TEXTURE_2D:
   2446             {
   2447                 Texture2D *incomplete2d = new Texture2D(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
   2448                 incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
   2449                 t = incomplete2d;
   2450             }
   2451             break;
   2452 
   2453           case TEXTURE_CUBE:
   2454             {
   2455               TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
   2456 
   2457               incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
   2458               incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
   2459               incompleteCube->setImagePosY(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
   2460               incompleteCube->setImageNegY(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
   2461               incompleteCube->setImagePosZ(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
   2462               incompleteCube->setImageNegZ(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
   2463 
   2464               t = incompleteCube;
   2465             }
   2466             break;
   2467         }
   2468 
   2469         mIncompleteTextures[type].set(t);
   2470     }
   2471 
   2472     return t;
   2473 }
   2474 
   2475 bool Context::skipDraw(GLenum drawMode)
   2476 {
   2477     if (drawMode == GL_POINTS)
   2478     {
   2479         // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
   2480         // which affects varying interpolation. Since the value of gl_PointSize is
   2481         // undefined when not written, just skip drawing to avoid unexpected results.
   2482         if (!getCurrentProgramBinary()->usesPointSize())
   2483         {
   2484             // This is stictly speaking not an error, but developers should be
   2485             // notified of risking undefined behavior.
   2486             ERR("Point rendering without writing to gl_PointSize.");
   2487 
   2488             return true;
   2489         }
   2490     }
   2491     else if (IsTriangleMode(drawMode))
   2492     {
   2493         if (mState.rasterizer.cullFace && mState.rasterizer.cullMode == GL_FRONT_AND_BACK)
   2494         {
   2495             return true;
   2496         }
   2497     }
   2498 
   2499     return false;
   2500 }
   2501 
   2502 void Context::setVertexAttrib(GLuint index, const GLfloat *values)
   2503 {
   2504     ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
   2505 
   2506     mState.vertexAttribute[index].mCurrentValue[0] = values[0];
   2507     mState.vertexAttribute[index].mCurrentValue[1] = values[1];
   2508     mState.vertexAttribute[index].mCurrentValue[2] = values[2];
   2509     mState.vertexAttribute[index].mCurrentValue[3] = values[3];
   2510 }
   2511 
   2512 void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
   2513 {
   2514     ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
   2515 
   2516     mState.vertexAttribute[index].mDivisor = divisor;
   2517 }
   2518 
   2519 // keep list sorted in following order
   2520 // OES extensions
   2521 // EXT extensions
   2522 // Vendor extensions
   2523 void Context::initExtensionString()
   2524 {
   2525     std::string extensionString = "";
   2526 
   2527     // OES extensions
   2528     if (supports32bitIndices())
   2529     {
   2530         extensionString += "GL_OES_element_index_uint ";
   2531     }
   2532 
   2533     extensionString += "GL_OES_packed_depth_stencil ";
   2534     extensionString += "GL_OES_get_program_binary ";
   2535     extensionString += "GL_OES_rgb8_rgba8 ";
   2536     if (mRenderer->getDerivativeInstructionSupport())
   2537     {
   2538         extensionString += "GL_OES_standard_derivatives ";
   2539     }
   2540 
   2541     if (supportsFloat16Textures())
   2542     {
   2543         extensionString += "GL_OES_texture_half_float ";
   2544     }
   2545     if (supportsFloat16LinearFilter())
   2546     {
   2547         extensionString += "GL_OES_texture_half_float_linear ";
   2548     }
   2549     if (supportsFloat32Textures())
   2550     {
   2551         extensionString += "GL_OES_texture_float ";
   2552     }
   2553     if (supportsFloat32LinearFilter())
   2554     {
   2555         extensionString += "GL_OES_texture_float_linear ";
   2556     }
   2557 
   2558     if (supportsNonPower2Texture())
   2559     {
   2560         extensionString += "GL_OES_texture_npot ";
   2561     }
   2562 
   2563     // Multi-vendor (EXT) extensions
   2564     if (supportsOcclusionQueries())
   2565     {
   2566         extensionString += "GL_EXT_occlusion_query_boolean ";
   2567     }
   2568 
   2569     extensionString += "GL_EXT_read_format_bgra ";
   2570     extensionString += "GL_EXT_robustness ";
   2571 
   2572     if (supportsDXT1Textures())
   2573     {
   2574         extensionString += "GL_EXT_texture_compression_dxt1 ";
   2575     }
   2576 
   2577     if (supportsTextureFilterAnisotropy())
   2578     {
   2579         extensionString += "GL_EXT_texture_filter_anisotropic ";
   2580     }
   2581 
   2582     if (supportsBGRATextures())
   2583     {
   2584         extensionString += "GL_EXT_texture_format_BGRA8888 ";
   2585     }
   2586 
   2587     if (mRenderer->getMaxRenderTargets() > 1)
   2588     {
   2589         extensionString += "GL_EXT_draw_buffers ";
   2590     }
   2591 
   2592     extensionString += "GL_EXT_texture_storage ";
   2593     extensionString += "GL_EXT_frag_depth ";
   2594 
   2595     // ANGLE-specific extensions
   2596     if (supportsDepthTextures())
   2597     {
   2598         extensionString += "GL_ANGLE_depth_texture ";
   2599     }
   2600 
   2601     extensionString += "GL_ANGLE_framebuffer_blit ";
   2602     if (getMaxSupportedSamples() != 0)
   2603     {
   2604         extensionString += "GL_ANGLE_framebuffer_multisample ";
   2605     }
   2606 
   2607     if (supportsInstancing())
   2608     {
   2609         extensionString += "GL_ANGLE_instanced_arrays ";
   2610     }
   2611 
   2612     extensionString += "GL_ANGLE_pack_reverse_row_order ";
   2613 
   2614     if (supportsDXT3Textures())
   2615     {
   2616         extensionString += "GL_ANGLE_texture_compression_dxt3 ";
   2617     }
   2618     if (supportsDXT5Textures())
   2619     {
   2620         extensionString += "GL_ANGLE_texture_compression_dxt5 ";
   2621     }
   2622 
   2623     extensionString += "GL_ANGLE_texture_usage ";
   2624     extensionString += "GL_ANGLE_translated_shader_source ";
   2625 
   2626     // Other vendor-specific extensions
   2627     if (supportsEventQueries())
   2628     {
   2629         extensionString += "GL_NV_fence ";
   2630     }
   2631 
   2632     std::string::size_type end = extensionString.find_last_not_of(' ');
   2633     if (end != std::string::npos)
   2634     {
   2635         extensionString.resize(end+1);
   2636     }
   2637 
   2638     mExtensionString = makeStaticString(extensionString);
   2639 }
   2640 
   2641 const char *Context::getExtensionString() const
   2642 {
   2643     return mExtensionString;
   2644 }
   2645 
   2646 void Context::initRendererString()
   2647 {
   2648     std::ostringstream rendererString;
   2649     rendererString << "ANGLE (";
   2650     rendererString << mRenderer->getRendererDescription();
   2651     rendererString << ")";
   2652 
   2653     mRendererString = makeStaticString(rendererString.str());
   2654 }
   2655 
   2656 const char *Context::getRendererString() const
   2657 {
   2658     return mRendererString;
   2659 }
   2660 
   2661 Context::FramebufferTextureSerialSet Context::getBoundFramebufferTextureSerials()
   2662 {
   2663     FramebufferTextureSerialSet set;
   2664 
   2665     Framebuffer *drawFramebuffer = getDrawFramebuffer();
   2666     for (unsigned int i = 0; i < IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
   2667     {
   2668         Renderbuffer *renderBuffer = drawFramebuffer->getColorbuffer(i);
   2669         if (renderBuffer && renderBuffer->getTextureSerial() != 0)
   2670         {
   2671             set.insert(renderBuffer->getTextureSerial());
   2672         }
   2673     }
   2674 
   2675     Renderbuffer *depthStencilBuffer = drawFramebuffer->getDepthOrStencilbuffer();
   2676     if (depthStencilBuffer && depthStencilBuffer->getTextureSerial() != 0)
   2677     {
   2678         set.insert(depthStencilBuffer->getTextureSerial());
   2679     }
   2680 
   2681     return set;
   2682 }
   2683 
   2684 void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
   2685                               GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
   2686                               GLbitfield mask)
   2687 {
   2688     Framebuffer *readFramebuffer = getReadFramebuffer();
   2689     Framebuffer *drawFramebuffer = getDrawFramebuffer();
   2690 
   2691     if (!readFramebuffer || readFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE ||
   2692         !drawFramebuffer || drawFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
   2693     {
   2694         return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
   2695     }
   2696 
   2697     if (drawFramebuffer->getSamples() != 0)
   2698     {
   2699         return gl::error(GL_INVALID_OPERATION);
   2700     }
   2701 
   2702     Renderbuffer *readColorBuffer = readFramebuffer->getReadColorbuffer();
   2703     Renderbuffer *drawColorBuffer = drawFramebuffer->getFirstColorbuffer();
   2704 
   2705     if (drawColorBuffer == NULL)
   2706     {
   2707         ERR("Draw buffers formats don't match, which is not supported in this implementation of BlitFramebufferANGLE");
   2708         return gl::error(GL_INVALID_OPERATION);
   2709     }
   2710 
   2711     int readBufferWidth = readColorBuffer->getWidth();
   2712     int readBufferHeight = readColorBuffer->getHeight();
   2713     int drawBufferWidth = drawColorBuffer->getWidth();
   2714     int drawBufferHeight = drawColorBuffer->getHeight();
   2715 
   2716     Rectangle sourceRect;
   2717     Rectangle destRect;
   2718 
   2719     if (srcX0 < srcX1)
   2720     {
   2721         sourceRect.x = srcX0;
   2722         destRect.x = dstX0;
   2723         sourceRect.width = srcX1 - srcX0;
   2724         destRect.width = dstX1 - dstX0;
   2725     }
   2726     else
   2727     {
   2728         sourceRect.x = srcX1;
   2729         destRect.x = dstX1;
   2730         sourceRect.width = srcX0 - srcX1;
   2731         destRect.width = dstX0 - dstX1;
   2732     }
   2733 
   2734     if (srcY0 < srcY1)
   2735     {
   2736         sourceRect.height = srcY1 - srcY0;
   2737         destRect.height = dstY1 - dstY0;
   2738         sourceRect.y = srcY0;
   2739         destRect.y = dstY0;
   2740     }
   2741     else
   2742     {
   2743         sourceRect.height = srcY0 - srcY1;
   2744         destRect.height = dstY0 - srcY1;
   2745         sourceRect.y = srcY1;
   2746         destRect.y = dstY1;
   2747     }
   2748 
   2749     Rectangle sourceScissoredRect = sourceRect;
   2750     Rectangle destScissoredRect = destRect;
   2751 
   2752     if (mState.scissorTest)
   2753     {
   2754         // Only write to parts of the destination framebuffer which pass the scissor test.
   2755         if (destRect.x < mState.scissor.x)
   2756         {
   2757             int xDiff = mState.scissor.x - destRect.x;
   2758             destScissoredRect.x = mState.scissor.x;
   2759             destScissoredRect.width -= xDiff;
   2760             sourceScissoredRect.x += xDiff;
   2761             sourceScissoredRect.width -= xDiff;
   2762 
   2763         }
   2764 
   2765         if (destRect.x + destRect.width > mState.scissor.x + mState.scissor.width)
   2766         {
   2767             int xDiff = (destRect.x + destRect.width) - (mState.scissor.x + mState.scissor.width);
   2768             destScissoredRect.width -= xDiff;
   2769             sourceScissoredRect.width -= xDiff;
   2770         }
   2771 
   2772         if (destRect.y < mState.scissor.y)
   2773         {
   2774             int yDiff = mState.scissor.y - destRect.y;
   2775             destScissoredRect.y = mState.scissor.y;
   2776             destScissoredRect.height -= yDiff;
   2777             sourceScissoredRect.y += yDiff;
   2778             sourceScissoredRect.height -= yDiff;
   2779         }
   2780 
   2781         if (destRect.y + destRect.height > mState.scissor.y + mState.scissor.height)
   2782         {
   2783             int yDiff = (destRect.y + destRect.height) - (mState.scissor.y + mState.scissor.height);
   2784             destScissoredRect.height  -= yDiff;
   2785             sourceScissoredRect.height -= yDiff;
   2786         }
   2787     }
   2788 
   2789     bool blitRenderTarget = false;
   2790     bool blitDepthStencil = false;
   2791 
   2792     Rectangle sourceTrimmedRect = sourceScissoredRect;
   2793     Rectangle destTrimmedRect = destScissoredRect;
   2794 
   2795     // The source & destination rectangles also may need to be trimmed if they fall out of the bounds of
   2796     // the actual draw and read surfaces.
   2797     if (sourceTrimmedRect.x < 0)
   2798     {
   2799         int xDiff = 0 - sourceTrimmedRect.x;
   2800         sourceTrimmedRect.x = 0;
   2801         sourceTrimmedRect.width -= xDiff;
   2802         destTrimmedRect.x += xDiff;
   2803         destTrimmedRect.width -= xDiff;
   2804     }
   2805 
   2806     if (sourceTrimmedRect.x + sourceTrimmedRect.width > readBufferWidth)
   2807     {
   2808         int xDiff = (sourceTrimmedRect.x + sourceTrimmedRect.width) - readBufferWidth;
   2809         sourceTrimmedRect.width -= xDiff;
   2810         destTrimmedRect.width -= xDiff;
   2811     }
   2812 
   2813     if (sourceTrimmedRect.y < 0)
   2814     {
   2815         int yDiff = 0 - sourceTrimmedRect.y;
   2816         sourceTrimmedRect.y = 0;
   2817         sourceTrimmedRect.height -= yDiff;
   2818         destTrimmedRect.y += yDiff;
   2819         destTrimmedRect.height -= yDiff;
   2820     }
   2821 
   2822     if (sourceTrimmedRect.y + sourceTrimmedRect.height > readBufferHeight)
   2823     {
   2824         int yDiff = (sourceTrimmedRect.y + sourceTrimmedRect.height) - readBufferHeight;
   2825         sourceTrimmedRect.height -= yDiff;
   2826         destTrimmedRect.height -= yDiff;
   2827     }
   2828 
   2829     if (destTrimmedRect.x < 0)
   2830     {
   2831         int xDiff = 0 - destTrimmedRect.x;
   2832         destTrimmedRect.x = 0;
   2833         destTrimmedRect.width -= xDiff;
   2834         sourceTrimmedRect.x += xDiff;
   2835         sourceTrimmedRect.width -= xDiff;
   2836     }
   2837 
   2838     if (destTrimmedRect.x + destTrimmedRect.width > drawBufferWidth)
   2839     {
   2840         int xDiff = (destTrimmedRect.x + destTrimmedRect.width) - drawBufferWidth;
   2841         destTrimmedRect.width -= xDiff;
   2842         sourceTrimmedRect.width -= xDiff;
   2843     }
   2844 
   2845     if (destTrimmedRect.y < 0)
   2846     {
   2847         int yDiff = 0 - destTrimmedRect.y;
   2848         destTrimmedRect.y = 0;
   2849         destTrimmedRect.height -= yDiff;
   2850         sourceTrimmedRect.y += yDiff;
   2851         sourceTrimmedRect.height -= yDiff;
   2852     }
   2853 
   2854     if (destTrimmedRect.y + destTrimmedRect.height > drawBufferHeight)
   2855     {
   2856         int yDiff = (destTrimmedRect.y + destTrimmedRect.height) - drawBufferHeight;
   2857         destTrimmedRect.height -= yDiff;
   2858         sourceTrimmedRect.height -= yDiff;
   2859     }
   2860 
   2861     bool partialBufferCopy = false;
   2862     if (sourceTrimmedRect.height < readBufferHeight ||
   2863         sourceTrimmedRect.width < readBufferWidth ||
   2864         destTrimmedRect.height < drawBufferHeight ||
   2865         destTrimmedRect.width < drawBufferWidth ||
   2866         sourceTrimmedRect.y != 0 || destTrimmedRect.y != 0 || sourceTrimmedRect.x != 0 || destTrimmedRect.x != 0)
   2867     {
   2868         partialBufferCopy = true;
   2869     }
   2870 
   2871     if (mask & GL_COLOR_BUFFER_BIT)
   2872     {
   2873         const GLenum readColorbufferType = readFramebuffer->getReadColorbufferType();
   2874         const bool validReadType = (readColorbufferType == GL_TEXTURE_2D) || (readColorbufferType == GL_RENDERBUFFER);
   2875         bool validDrawType = true;
   2876         bool validDrawFormat = true;
   2877 
   2878         for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
   2879         {
   2880             if (drawFramebuffer->isEnabledColorAttachment(colorAttachment))
   2881             {
   2882                 if (drawFramebuffer->getColorbufferType(colorAttachment) != GL_TEXTURE_2D &&
   2883                     drawFramebuffer->getColorbufferType(colorAttachment) != GL_RENDERBUFFER)
   2884                 {
   2885                     validDrawType = false;
   2886                 }
   2887 
   2888                 if (drawFramebuffer->getColorbuffer(colorAttachment)->getActualFormat() != readColorBuffer->getActualFormat())
   2889                 {
   2890                     validDrawFormat = false;
   2891                 }
   2892             }
   2893         }
   2894 
   2895         if (!validReadType || !validDrawType || !validDrawFormat)
   2896         {
   2897             ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation");
   2898             return gl::error(GL_INVALID_OPERATION);
   2899         }
   2900 
   2901         if (partialBufferCopy && readFramebuffer->getSamples() != 0)
   2902         {
   2903             return gl::error(GL_INVALID_OPERATION);
   2904         }
   2905 
   2906         blitRenderTarget = true;
   2907 
   2908     }
   2909 
   2910     if (mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
   2911     {
   2912         Renderbuffer *readDSBuffer = NULL;
   2913         Renderbuffer *drawDSBuffer = NULL;
   2914 
   2915         // We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have
   2916         // both a depth and stencil buffer, it will be the same buffer.
   2917 
   2918         if (mask & GL_DEPTH_BUFFER_BIT)
   2919         {
   2920             if (readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
   2921             {
   2922                 if (readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() ||
   2923                     readFramebuffer->getDepthbuffer()->getActualFormat() != drawFramebuffer->getDepthbuffer()->getActualFormat())
   2924                 {
   2925                     return gl::error(GL_INVALID_OPERATION);
   2926                 }
   2927 
   2928                 blitDepthStencil = true;
   2929                 readDSBuffer = readFramebuffer->getDepthbuffer();
   2930                 drawDSBuffer = drawFramebuffer->getDepthbuffer();
   2931             }
   2932         }
   2933 
   2934         if (mask & GL_STENCIL_BUFFER_BIT)
   2935         {
   2936             if (readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
   2937             {
   2938                 if (readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() ||
   2939                     readFramebuffer->getStencilbuffer()->getActualFormat() != drawFramebuffer->getStencilbuffer()->getActualFormat())
   2940                 {
   2941                     return gl::error(GL_INVALID_OPERATION);
   2942                 }
   2943 
   2944                 blitDepthStencil = true;
   2945                 readDSBuffer = readFramebuffer->getStencilbuffer();
   2946                 drawDSBuffer = drawFramebuffer->getStencilbuffer();
   2947             }
   2948         }
   2949 
   2950         if (partialBufferCopy)
   2951         {
   2952             ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
   2953             return gl::error(GL_INVALID_OPERATION); // only whole-buffer copies are permitted
   2954         }
   2955 
   2956         if ((drawDSBuffer && drawDSBuffer->getSamples() != 0) ||
   2957             (readDSBuffer && readDSBuffer->getSamples() != 0))
   2958         {
   2959             return gl::error(GL_INVALID_OPERATION);
   2960         }
   2961     }
   2962 
   2963     if (blitRenderTarget || blitDepthStencil)
   2964     {
   2965         mRenderer->blitRect(readFramebuffer, sourceTrimmedRect, drawFramebuffer, destTrimmedRect, blitRenderTarget, blitDepthStencil);
   2966     }
   2967 }
   2968 
   2969 }
   2970 
   2971 extern "C"
   2972 {
   2973 gl::Context *glCreateContext(const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
   2974 {
   2975     return new gl::Context(shareContext, renderer, notifyResets, robustAccess);
   2976 }
   2977 
   2978 void glDestroyContext(gl::Context *context)
   2979 {
   2980     delete context;
   2981 
   2982     if (context == gl::getContext())
   2983     {
   2984         gl::makeCurrent(NULL, NULL, NULL);
   2985     }
   2986 }
   2987 
   2988 void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface)
   2989 {
   2990     gl::makeCurrent(context, display, surface);
   2991 }
   2992 
   2993 gl::Context *glGetCurrentContext()
   2994 {
   2995     return gl::getContext();
   2996 }
   2997 
   2998 }
   2999