Home | History | Annotate | Download | only in libGLESv2
      1 //
      2 // Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // Context.cpp: Implements the gl::Context class, managing all GL state and performing
      8 // rendering operations. It is the GLES2 specific implementation of EGLContext.
      9 
     10 #include "libGLESv2/Context.h"
     11 
     12 #include "libGLESv2/main.h"
     13 #include "common/utilities.h"
     14 #include "common/platform.h"
     15 #include "libGLESv2/formatutils.h"
     16 #include "libGLESv2/Buffer.h"
     17 #include "libGLESv2/Fence.h"
     18 #include "libGLESv2/Framebuffer.h"
     19 #include "libGLESv2/FramebufferAttachment.h"
     20 #include "libGLESv2/Renderbuffer.h"
     21 #include "libGLESv2/Program.h"
     22 #include "libGLESv2/ProgramBinary.h"
     23 #include "libGLESv2/Query.h"
     24 #include "libGLESv2/Texture.h"
     25 #include "libGLESv2/ResourceManager.h"
     26 #include "libGLESv2/renderer/d3d/IndexDataManager.h"
     27 #include "libGLESv2/renderer/Renderer.h"
     28 #include "libGLESv2/VertexArray.h"
     29 #include "libGLESv2/Sampler.h"
     30 #include "libGLESv2/validationES.h"
     31 #include "libGLESv2/TransformFeedback.h"
     32 
     33 #include "libEGL/Surface.h"
     34 
     35 #include <sstream>
     36 
     37 namespace gl
     38 {
     39 
     40 Context::Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
     41     : mRenderer(renderer)
     42 {
     43     ASSERT(robustAccess == false);   // Unimplemented
     44 
     45     initCaps(clientVersion);
     46     mState.initialize(mCaps, clientVersion);
     47 
     48     mClientVersion = clientVersion;
     49 
     50     mFenceNVHandleAllocator.setBaseHandle(0);
     51 
     52     if (shareContext != NULL)
     53     {
     54         mResourceManager = shareContext->mResourceManager;
     55         mResourceManager->addRef();
     56     }
     57     else
     58     {
     59         mResourceManager = new ResourceManager(mRenderer);
     60     }
     61 
     62     // [OpenGL ES 2.0.24] section 3.7 page 83:
     63     // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
     64     // and cube map texture state vectors respectively associated with them.
     65     // In order that access to these initial textures not be lost, they are treated as texture
     66     // objects all of whose names are 0.
     67 
     68     mZeroTextures[GL_TEXTURE_2D].set(new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), 0));
     69     bindTexture(GL_TEXTURE_2D, 0);
     70 
     71     mZeroTextures[GL_TEXTURE_CUBE_MAP].set(new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0));
     72     bindTexture(GL_TEXTURE_CUBE_MAP, 0);
     73 
     74     if (mClientVersion >= 3)
     75     {
     76         // TODO: These could also be enabled via extension
     77         mZeroTextures[GL_TEXTURE_3D].set(new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), 0));
     78         bindTexture(GL_TEXTURE_3D, 0);
     79 
     80         mZeroTextures[GL_TEXTURE_2D_ARRAY].set(new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0));
     81         bindTexture(GL_TEXTURE_2D_ARRAY, 0);
     82     }
     83 
     84     bindVertexArray(0);
     85     bindArrayBuffer(0);
     86     bindElementArrayBuffer(0);
     87 
     88     bindReadFramebuffer(0);
     89     bindDrawFramebuffer(0);
     90     bindRenderbuffer(0);
     91 
     92     bindGenericUniformBuffer(0);
     93     for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
     94     {
     95         bindIndexedUniformBuffer(0, i, 0, -1);
     96     }
     97 
     98     bindGenericTransformFeedbackBuffer(0);
     99     for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
    100     {
    101         bindIndexedTransformFeedbackBuffer(0, i, 0, -1);
    102     }
    103 
    104     bindCopyReadBuffer(0);
    105     bindCopyWriteBuffer(0);
    106     bindPixelPackBuffer(0);
    107     bindPixelUnpackBuffer(0);
    108 
    109     // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
    110     // In the initial state, a default transform feedback object is bound and treated as
    111     // a transform feedback object with a name of zero. That object is bound any time
    112     // BindTransformFeedback is called with id of zero
    113     mTransformFeedbackZero.set(new TransformFeedback(mRenderer->createTransformFeedback(), 0));
    114     bindTransformFeedback(0);
    115 
    116     mHasBeenCurrent = false;
    117     mContextLost = false;
    118     mResetStatus = GL_NO_ERROR;
    119     mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
    120     mRobustAccess = robustAccess;
    121 
    122     mState.setContext(this);
    123 }
    124 
    125 Context::~Context()
    126 {
    127     GLuint currentProgram = mState.getCurrentProgramId();
    128     if (currentProgram != 0)
    129     {
    130         Program *programObject = mResourceManager->getProgram(currentProgram);
    131         if (programObject)
    132         {
    133             programObject->release();
    134         }
    135         currentProgram = 0;
    136     }
    137     mState.setCurrentProgram(0, NULL);
    138 
    139     while (!mFramebufferMap.empty())
    140     {
    141         deleteFramebuffer(mFramebufferMap.begin()->first);
    142     }
    143 
    144     while (!mFenceNVMap.empty())
    145     {
    146         deleteFenceNV(mFenceNVMap.begin()->first);
    147     }
    148 
    149     while (!mQueryMap.empty())
    150     {
    151         deleteQuery(mQueryMap.begin()->first);
    152     }
    153 
    154     while (!mVertexArrayMap.empty())
    155     {
    156         deleteVertexArray(mVertexArrayMap.begin()->first);
    157     }
    158 
    159     mTransformFeedbackZero.set(NULL);
    160     while (!mTransformFeedbackMap.empty())
    161     {
    162         deleteTransformFeedback(mTransformFeedbackMap.begin()->first);
    163     }
    164 
    165     for (TextureMap::iterator i = mIncompleteTextures.begin(); i != mIncompleteTextures.end(); i++)
    166     {
    167         i->second.set(NULL);
    168     }
    169     mIncompleteTextures.clear();
    170 
    171     for (TextureMap::iterator i = mZeroTextures.begin(); i != mZeroTextures.end(); i++)
    172     {
    173         i->second.set(NULL);
    174     }
    175     mZeroTextures.clear();
    176 
    177     mResourceManager->release();
    178 }
    179 
    180 void Context::makeCurrent(egl::Surface *surface)
    181 {
    182     if (!mHasBeenCurrent)
    183     {
    184         initRendererString();
    185         initExtensionStrings();
    186 
    187         mState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
    188         mState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
    189 
    190         mHasBeenCurrent = true;
    191     }
    192 
    193     // Wrap the existing swapchain resources into GL objects and assign them to the '0' names
    194     rx::SwapChain *swapchain = surface->getSwapChain();
    195 
    196     Colorbuffer *colorbufferZero = new Colorbuffer(mRenderer, swapchain);
    197     DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(mRenderer, swapchain);
    198     Framebuffer *framebufferZero = new DefaultFramebuffer(mRenderer, colorbufferZero, depthStencilbufferZero);
    199 
    200     setFramebufferZero(framebufferZero);
    201 
    202     // Store the current client version in the renderer
    203     mRenderer->setCurrentClientVersion(mClientVersion);
    204 }
    205 
    206 // NOTE: this function should not assume that this context is current!
    207 void Context::markContextLost()
    208 {
    209     if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
    210         mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
    211     mContextLost = true;
    212 }
    213 
    214 bool Context::isContextLost()
    215 {
    216     return mContextLost;
    217 }
    218 
    219 GLuint Context::createBuffer()
    220 {
    221     return mResourceManager->createBuffer();
    222 }
    223 
    224 GLuint Context::createProgram()
    225 {
    226     return mResourceManager->createProgram();
    227 }
    228 
    229 GLuint Context::createShader(GLenum type)
    230 {
    231     return mResourceManager->createShader(type);
    232 }
    233 
    234 GLuint Context::createTexture()
    235 {
    236     return mResourceManager->createTexture();
    237 }
    238 
    239 GLuint Context::createRenderbuffer()
    240 {
    241     return mResourceManager->createRenderbuffer();
    242 }
    243 
    244 GLsync Context::createFenceSync(GLenum condition)
    245 {
    246     GLuint handle = mResourceManager->createFenceSync();
    247 
    248     gl::FenceSync *fenceSync = mResourceManager->getFenceSync(handle);
    249     ASSERT(fenceSync);
    250 
    251     fenceSync->set(condition);
    252 
    253     return reinterpret_cast<GLsync>(handle);
    254 }
    255 
    256 GLuint Context::createVertexArray()
    257 {
    258     GLuint handle = mVertexArrayHandleAllocator.allocate();
    259 
    260     // Although the spec states VAO state is not initialized until the object is bound,
    261     // we create it immediately. The resulting behaviour is transparent to the application,
    262     // since it's not currently possible to access the state until the object is bound.
    263     VertexArray *vertexArray = new VertexArray(mRenderer->createVertexArray(), handle, MAX_VERTEX_ATTRIBS);
    264     mVertexArrayMap[handle] = vertexArray;
    265     return handle;
    266 }
    267 
    268 GLuint Context::createSampler()
    269 {
    270     return mResourceManager->createSampler();
    271 }
    272 
    273 GLuint Context::createTransformFeedback()
    274 {
    275     GLuint handle = mTransformFeedbackAllocator.allocate();
    276     TransformFeedback *transformFeedback = new TransformFeedback(mRenderer->createTransformFeedback(), handle);
    277     transformFeedback->addRef();
    278     mTransformFeedbackMap[handle] = transformFeedback;
    279     return handle;
    280 }
    281 
    282 // Returns an unused framebuffer name
    283 GLuint Context::createFramebuffer()
    284 {
    285     GLuint handle = mFramebufferHandleAllocator.allocate();
    286 
    287     mFramebufferMap[handle] = NULL;
    288 
    289     return handle;
    290 }
    291 
    292 GLuint Context::createFenceNV()
    293 {
    294     GLuint handle = mFenceNVHandleAllocator.allocate();
    295 
    296     mFenceNVMap[handle] = new FenceNV(mRenderer);
    297 
    298     return handle;
    299 }
    300 
    301 // Returns an unused query name
    302 GLuint Context::createQuery()
    303 {
    304     GLuint handle = mQueryHandleAllocator.allocate();
    305 
    306     mQueryMap[handle] = NULL;
    307 
    308     return handle;
    309 }
    310 
    311 void Context::deleteBuffer(GLuint buffer)
    312 {
    313     if (mResourceManager->getBuffer(buffer))
    314     {
    315         detachBuffer(buffer);
    316     }
    317 
    318     mResourceManager->deleteBuffer(buffer);
    319 }
    320 
    321 void Context::deleteShader(GLuint shader)
    322 {
    323     mResourceManager->deleteShader(shader);
    324 }
    325 
    326 void Context::deleteProgram(GLuint program)
    327 {
    328     mResourceManager->deleteProgram(program);
    329 }
    330 
    331 void Context::deleteTexture(GLuint texture)
    332 {
    333     if (mResourceManager->getTexture(texture))
    334     {
    335         detachTexture(texture);
    336     }
    337 
    338     mResourceManager->deleteTexture(texture);
    339 }
    340 
    341 void Context::deleteRenderbuffer(GLuint renderbuffer)
    342 {
    343     if (mResourceManager->getRenderbuffer(renderbuffer))
    344     {
    345         detachRenderbuffer(renderbuffer);
    346     }
    347 
    348     mResourceManager->deleteRenderbuffer(renderbuffer);
    349 }
    350 
    351 void Context::deleteFenceSync(GLsync fenceSync)
    352 {
    353     // The spec specifies the underlying Fence object is not deleted until all current
    354     // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
    355     // and since our API is currently designed for being called from a single thread, we can delete
    356     // the fence immediately.
    357     mResourceManager->deleteFenceSync(reinterpret_cast<GLuint>(fenceSync));
    358 }
    359 
    360 void Context::deleteVertexArray(GLuint vertexArray)
    361 {
    362     auto vertexArrayObject = mVertexArrayMap.find(vertexArray);
    363 
    364     if (vertexArrayObject != mVertexArrayMap.end())
    365     {
    366         detachVertexArray(vertexArray);
    367 
    368         mVertexArrayHandleAllocator.release(vertexArrayObject->first);
    369         delete vertexArrayObject->second;
    370         mVertexArrayMap.erase(vertexArrayObject);
    371     }
    372 }
    373 
    374 void Context::deleteSampler(GLuint sampler)
    375 {
    376     if (mResourceManager->getSampler(sampler))
    377     {
    378         detachSampler(sampler);
    379     }
    380 
    381     mResourceManager->deleteSampler(sampler);
    382 }
    383 
    384 void Context::deleteTransformFeedback(GLuint transformFeedback)
    385 {
    386     TransformFeedbackMap::const_iterator iter = mTransformFeedbackMap.find(transformFeedback);
    387     if (iter != mTransformFeedbackMap.end())
    388     {
    389         detachTransformFeedback(transformFeedback);
    390         mTransformFeedbackAllocator.release(transformFeedback);
    391         iter->second->release();
    392         mTransformFeedbackMap.erase(iter);
    393     }
    394 }
    395 
    396 void Context::deleteFramebuffer(GLuint framebuffer)
    397 {
    398     FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
    399 
    400     if (framebufferObject != mFramebufferMap.end())
    401     {
    402         detachFramebuffer(framebuffer);
    403 
    404         mFramebufferHandleAllocator.release(framebufferObject->first);
    405         delete framebufferObject->second;
    406         mFramebufferMap.erase(framebufferObject);
    407     }
    408 }
    409 
    410 void Context::deleteFenceNV(GLuint fence)
    411 {
    412     FenceNVMap::iterator fenceObject = mFenceNVMap.find(fence);
    413 
    414     if (fenceObject != mFenceNVMap.end())
    415     {
    416         mFenceNVHandleAllocator.release(fenceObject->first);
    417         delete fenceObject->second;
    418         mFenceNVMap.erase(fenceObject);
    419     }
    420 }
    421 
    422 void Context::deleteQuery(GLuint query)
    423 {
    424     QueryMap::iterator queryObject = mQueryMap.find(query);
    425     if (queryObject != mQueryMap.end())
    426     {
    427         mQueryHandleAllocator.release(queryObject->first);
    428         if (queryObject->second)
    429         {
    430             queryObject->second->release();
    431         }
    432         mQueryMap.erase(queryObject);
    433     }
    434 }
    435 
    436 Buffer *Context::getBuffer(GLuint handle)
    437 {
    438     return mResourceManager->getBuffer(handle);
    439 }
    440 
    441 Shader *Context::getShader(GLuint handle) const
    442 {
    443     return mResourceManager->getShader(handle);
    444 }
    445 
    446 Program *Context::getProgram(GLuint handle) const
    447 {
    448     return mResourceManager->getProgram(handle);
    449 }
    450 
    451 Texture *Context::getTexture(GLuint handle) const
    452 {
    453     return mResourceManager->getTexture(handle);
    454 }
    455 
    456 Renderbuffer *Context::getRenderbuffer(GLuint handle)
    457 {
    458     return mResourceManager->getRenderbuffer(handle);
    459 }
    460 
    461 FenceSync *Context::getFenceSync(GLsync handle) const
    462 {
    463     return mResourceManager->getFenceSync(reinterpret_cast<GLuint>(handle));
    464 }
    465 
    466 VertexArray *Context::getVertexArray(GLuint handle) const
    467 {
    468     auto vertexArray = mVertexArrayMap.find(handle);
    469 
    470     if (vertexArray == mVertexArrayMap.end())
    471     {
    472         return NULL;
    473     }
    474     else
    475     {
    476         return vertexArray->second;
    477     }
    478 }
    479 
    480 Sampler *Context::getSampler(GLuint handle) const
    481 {
    482     return mResourceManager->getSampler(handle);
    483 }
    484 
    485 TransformFeedback *Context::getTransformFeedback(GLuint handle) const
    486 {
    487     if (handle == 0)
    488     {
    489         return mTransformFeedbackZero.get();
    490     }
    491     else
    492     {
    493         TransformFeedbackMap::const_iterator iter = mTransformFeedbackMap.find(handle);
    494         return (iter != mTransformFeedbackMap.end()) ? iter->second : NULL;
    495     }
    496 }
    497 
    498 bool Context::isSampler(GLuint samplerName) const
    499 {
    500     return mResourceManager->isSampler(samplerName);
    501 }
    502 
    503 void Context::bindArrayBuffer(unsigned int buffer)
    504 {
    505     mResourceManager->checkBufferAllocation(buffer);
    506 
    507     mState.setArrayBufferBinding(getBuffer(buffer));
    508 }
    509 
    510 void Context::bindElementArrayBuffer(unsigned int buffer)
    511 {
    512     mResourceManager->checkBufferAllocation(buffer);
    513 
    514     mState.getVertexArray()->setElementArrayBuffer(getBuffer(buffer));
    515 }
    516 
    517 void Context::bindTexture(GLenum target, GLuint texture)
    518 {
    519     mResourceManager->checkTextureAllocation(texture, target);
    520 
    521     mState.setSamplerTexture(target, getTexture(texture));
    522 }
    523 
    524 void Context::bindReadFramebuffer(GLuint framebuffer)
    525 {
    526     if (!getFramebuffer(framebuffer))
    527     {
    528         mFramebufferMap[framebuffer] = new Framebuffer(mRenderer, framebuffer);
    529     }
    530 
    531     mState.setReadFramebufferBinding(getFramebuffer(framebuffer));
    532 }
    533 
    534 void Context::bindDrawFramebuffer(GLuint framebuffer)
    535 {
    536     if (!getFramebuffer(framebuffer))
    537     {
    538         mFramebufferMap[framebuffer] = new Framebuffer(mRenderer, framebuffer);
    539     }
    540 
    541     mState.setDrawFramebufferBinding(getFramebuffer(framebuffer));
    542 }
    543 
    544 void Context::bindRenderbuffer(GLuint renderbuffer)
    545 {
    546     mResourceManager->checkRenderbufferAllocation(renderbuffer);
    547 
    548     mState.setRenderbufferBinding(getRenderbuffer(renderbuffer));
    549 }
    550 
    551 void Context::bindVertexArray(GLuint vertexArray)
    552 {
    553     if (!getVertexArray(vertexArray))
    554     {
    555         VertexArray *vertexArrayObject = new VertexArray(mRenderer->createVertexArray(), vertexArray, MAX_VERTEX_ATTRIBS);
    556         mVertexArrayMap[vertexArray] = vertexArrayObject;
    557     }
    558 
    559     mState.setVertexArrayBinding(getVertexArray(vertexArray));
    560 }
    561 
    562 void Context::bindSampler(GLuint textureUnit, GLuint sampler)
    563 {
    564     ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
    565     mResourceManager->checkSamplerAllocation(sampler);
    566 
    567     mState.setSamplerBinding(textureUnit, getSampler(sampler));
    568 }
    569 
    570 void Context::bindGenericUniformBuffer(GLuint buffer)
    571 {
    572     mResourceManager->checkBufferAllocation(buffer);
    573 
    574     mState.setGenericUniformBufferBinding(getBuffer(buffer));
    575 }
    576 
    577 void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
    578 {
    579     mResourceManager->checkBufferAllocation(buffer);
    580 
    581     mState.setIndexedUniformBufferBinding(index, getBuffer(buffer), offset, size);
    582 }
    583 
    584 void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
    585 {
    586     mResourceManager->checkBufferAllocation(buffer);
    587 
    588     mState.setGenericTransformFeedbackBufferBinding(getBuffer(buffer));
    589 }
    590 
    591 void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
    592 {
    593     mResourceManager->checkBufferAllocation(buffer);
    594 
    595     mState.setIndexedTransformFeedbackBufferBinding(index, getBuffer(buffer), offset, size);
    596 }
    597 
    598 void Context::bindCopyReadBuffer(GLuint buffer)
    599 {
    600     mResourceManager->checkBufferAllocation(buffer);
    601 
    602     mState.setCopyReadBufferBinding(getBuffer(buffer));
    603 }
    604 
    605 void Context::bindCopyWriteBuffer(GLuint buffer)
    606 {
    607     mResourceManager->checkBufferAllocation(buffer);
    608 
    609     mState.setCopyWriteBufferBinding(getBuffer(buffer));
    610 }
    611 
    612 void Context::bindPixelPackBuffer(GLuint buffer)
    613 {
    614     mResourceManager->checkBufferAllocation(buffer);
    615 
    616     mState.setPixelPackBufferBinding(getBuffer(buffer));
    617 }
    618 
    619 void Context::bindPixelUnpackBuffer(GLuint buffer)
    620 {
    621     mResourceManager->checkBufferAllocation(buffer);
    622 
    623     mState.setPixelUnpackBufferBinding(getBuffer(buffer));
    624 }
    625 
    626 void Context::useProgram(GLuint program)
    627 {
    628     GLuint priorProgramId = mState.getCurrentProgramId();
    629     Program *priorProgram = mResourceManager->getProgram(priorProgramId);
    630 
    631     if (priorProgramId != program)
    632     {
    633         mState.setCurrentProgram(program, mResourceManager->getProgram(program));
    634 
    635         if (priorProgram)
    636         {
    637             priorProgram->release();
    638         }
    639     }
    640 }
    641 
    642 void Context::linkProgram(GLuint program)
    643 {
    644     Program *programObject = mResourceManager->getProgram(program);
    645 
    646     bool linked = programObject->link(getCaps());
    647 
    648     // if the current program was relinked successfully we
    649     // need to install the new executables
    650     if (linked && program == mState.getCurrentProgramId())
    651     {
    652         mState.setCurrentProgramBinary(programObject->getProgramBinary());
    653     }
    654 }
    655 
    656 void Context::setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length)
    657 {
    658     Program *programObject = mResourceManager->getProgram(program);
    659 
    660     bool loaded = programObject->setProgramBinary(binaryFormat, binary, length);
    661 
    662     // if the current program was reloaded successfully we
    663     // need to install the new executables
    664     if (loaded && program == mState.getCurrentProgramId())
    665     {
    666         mState.setCurrentProgramBinary(programObject->getProgramBinary());
    667     }
    668 
    669 }
    670 
    671 void Context::bindTransformFeedback(GLuint transformFeedback)
    672 {
    673     mState.setTransformFeedbackBinding(getTransformFeedback(transformFeedback));
    674 }
    675 
    676 Error Context::beginQuery(GLenum target, GLuint query)
    677 {
    678     Query *queryObject = getQuery(query, true, target);
    679     ASSERT(queryObject);
    680 
    681     // begin query
    682     Error error = queryObject->begin();
    683     if (error.isError())
    684     {
    685         return error;
    686     }
    687 
    688     // set query as active for specified target only if begin succeeded
    689     mState.setActiveQuery(target, queryObject);
    690 
    691     return Error(GL_NO_ERROR);
    692 }
    693 
    694 Error Context::endQuery(GLenum target)
    695 {
    696     Query *queryObject = mState.getActiveQuery(target);
    697     ASSERT(queryObject);
    698 
    699     gl::Error error = queryObject->end();
    700 
    701     // Always unbind the query, even if there was an error. This may delete the query object.
    702     mState.setActiveQuery(target, NULL);
    703 
    704     return error;
    705 }
    706 
    707 void Context::setFramebufferZero(Framebuffer *buffer)
    708 {
    709     // First, check to see if the old default framebuffer
    710     // was set for draw or read framebuffer, and change
    711     // the bindings to point to the new one before deleting it.
    712     if (mState.getDrawFramebuffer()->id() == 0)
    713     {
    714         mState.setDrawFramebufferBinding(buffer);
    715     }
    716 
    717     if (mState.getReadFramebuffer()->id() == 0)
    718     {
    719         mState.setReadFramebufferBinding(buffer);
    720     }
    721 
    722     delete mFramebufferMap[0];
    723     mFramebufferMap[0] = buffer;
    724 }
    725 
    726 void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
    727 {
    728     ASSERT(getTextureCaps().get(internalformat).renderable);
    729 
    730     RenderbufferStorage *renderbuffer = NULL;
    731 
    732     const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
    733     if (formatInfo.depthBits > 0 && formatInfo.stencilBits > 0)
    734     {
    735         renderbuffer = new gl::DepthStencilbuffer(mRenderer, width, height, samples);
    736     }
    737     else if (formatInfo.depthBits > 0)
    738     {
    739         renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples);
    740     }
    741     else if (formatInfo.stencilBits > 0)
    742     {
    743         renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples);
    744     }
    745     else
    746     {
    747         renderbuffer = new gl::Colorbuffer(mRenderer, width, height, internalformat, samples);
    748     }
    749 
    750     mState.getCurrentRenderbuffer()->setStorage(renderbuffer);
    751 }
    752 
    753 Framebuffer *Context::getFramebuffer(unsigned int handle) const
    754 {
    755     FramebufferMap::const_iterator framebuffer = mFramebufferMap.find(handle);
    756 
    757     if (framebuffer == mFramebufferMap.end())
    758     {
    759         return NULL;
    760     }
    761     else
    762     {
    763         return framebuffer->second;
    764     }
    765 }
    766 
    767 FenceNV *Context::getFenceNV(unsigned int handle)
    768 {
    769     FenceNVMap::iterator fence = mFenceNVMap.find(handle);
    770 
    771     if (fence == mFenceNVMap.end())
    772     {
    773         return NULL;
    774     }
    775     else
    776     {
    777         return fence->second;
    778     }
    779 }
    780 
    781 Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
    782 {
    783     QueryMap::iterator query = mQueryMap.find(handle);
    784 
    785     if (query == mQueryMap.end())
    786     {
    787         return NULL;
    788     }
    789     else
    790     {
    791         if (!query->second && create)
    792         {
    793             query->second = new Query(mRenderer->createQuery(type), handle);
    794             query->second->addRef();
    795         }
    796         return query->second;
    797     }
    798 }
    799 
    800 Texture *Context::getTargetTexture(GLenum target) const
    801 {
    802     if (!ValidTextureTarget(this, target))
    803     {
    804         return NULL;
    805     }
    806 
    807     switch (target)
    808     {
    809       case GL_TEXTURE_2D:       return getTexture2D();
    810       case GL_TEXTURE_CUBE_MAP: return getTextureCubeMap();
    811       case GL_TEXTURE_3D:       return getTexture3D();
    812       case GL_TEXTURE_2D_ARRAY: return getTexture2DArray();
    813       default:                  return NULL;
    814     }
    815 }
    816 
    817 Texture2D *Context::getTexture2D() const
    818 {
    819     return static_cast<Texture2D*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_2D));
    820 }
    821 
    822 TextureCubeMap *Context::getTextureCubeMap() const
    823 {
    824     return static_cast<TextureCubeMap*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_CUBE_MAP));
    825 }
    826 
    827 Texture3D *Context::getTexture3D() const
    828 {
    829     return static_cast<Texture3D*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_3D));
    830 }
    831 
    832 Texture2DArray *Context::getTexture2DArray() const
    833 {
    834     return static_cast<Texture2DArray*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_2D_ARRAY));
    835 }
    836 
    837 Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
    838 {
    839     if (mState.getSamplerTextureId(sampler, type) == 0)
    840     {
    841         return mZeroTextures.at(type).get();
    842     }
    843     else
    844     {
    845         return mState.getSamplerTexture(sampler, type);
    846     }
    847 }
    848 
    849 void Context::getBooleanv(GLenum pname, GLboolean *params)
    850 {
    851     switch (pname)
    852     {
    853       case GL_SHADER_COMPILER:           *params = GL_TRUE;                             break;
    854       case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE;  break;
    855       default:
    856         mState.getBooleanv(pname, params);
    857         break;
    858     }
    859 }
    860 
    861 void Context::getFloatv(GLenum pname, GLfloat *params)
    862 {
    863     // Queries about context capabilities and maximums are answered by Context.
    864     // Queries about current GL state values are answered by State.
    865     switch (pname)
    866     {
    867       case GL_ALIASED_LINE_WIDTH_RANGE:
    868         params[0] = mCaps.minAliasedLineWidth;
    869         params[1] = mCaps.maxAliasedLineWidth;
    870         break;
    871       case GL_ALIASED_POINT_SIZE_RANGE:
    872         params[0] = mCaps.minAliasedPointSize;
    873         params[1] = mCaps.maxAliasedPointSize;
    874         break;
    875       case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
    876         ASSERT(mExtensions.textureFilterAnisotropic);
    877         *params = mExtensions.maxTextureAnisotropy;
    878         break;
    879       default:
    880         mState.getFloatv(pname, params);
    881         break;
    882     }
    883 }
    884 
    885 void Context::getIntegerv(GLenum pname, GLint *params)
    886 {
    887     // Queries about context capabilities and maximums are answered by Context.
    888     // Queries about current GL state values are answered by State.
    889 
    890     switch (pname)
    891     {
    892       case GL_MAX_VERTEX_ATTRIBS:                       *params = mCaps.maxVertexAttributes;                            break;
    893       case GL_MAX_VERTEX_UNIFORM_VECTORS:               *params = mCaps.maxVertexUniformVectors;                        break;
    894       case GL_MAX_VERTEX_UNIFORM_COMPONENTS:            *params = mCaps.maxVertexUniformComponents;                     break;
    895       case GL_MAX_VARYING_VECTORS:                      *params = mCaps.maxVaryingVectors;                              break;
    896       case GL_MAX_VARYING_COMPONENTS:                   *params = mCaps.maxVertexOutputComponents;                      break;
    897       case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:         *params = mCaps.maxCombinedTextureImageUnits;                   break;
    898       case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:           *params = mCaps.maxVertexTextureImageUnits;                     break;
    899       case GL_MAX_TEXTURE_IMAGE_UNITS:                  *params = mCaps.maxTextureImageUnits;                           break;
    900       case GL_MAX_FRAGMENT_UNIFORM_VECTORS:             *params = mCaps.maxFragmentUniformVectors;                      break;
    901       case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:          *params = mCaps.maxFragmentInputComponents;                     break;
    902       case GL_MAX_RENDERBUFFER_SIZE:                    *params = mCaps.maxRenderbufferSize;                            break;
    903       case GL_MAX_COLOR_ATTACHMENTS_EXT:                *params = mCaps.maxColorAttachments;                            break;
    904       case GL_MAX_DRAW_BUFFERS_EXT:                     *params = mCaps.maxDrawBuffers;                                 break;
    905       //case GL_FRAMEBUFFER_BINDING:                    // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
    906       case GL_SUBPIXEL_BITS:                            *params = 4;                                                    break;
    907       case GL_MAX_TEXTURE_SIZE:                         *params = mCaps.max2DTextureSize;                               break;
    908       case GL_MAX_CUBE_MAP_TEXTURE_SIZE:                *params = mCaps.maxCubeMapTextureSize;                          break;
    909       case GL_MAX_3D_TEXTURE_SIZE:                      *params = mCaps.max3DTextureSize;                               break;
    910       case GL_MAX_ARRAY_TEXTURE_LAYERS:                 *params = mCaps.maxArrayTextureLayers;                          break;
    911       case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:          *params = mCaps.uniformBufferOffsetAlignment;                   break;
    912       case GL_MAX_UNIFORM_BUFFER_BINDINGS:              *params = mCaps.maxUniformBufferBindings;                       break;
    913       case GL_MAX_VERTEX_UNIFORM_BLOCKS:                *params = mCaps.maxVertexUniformBlocks;                         break;
    914       case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:              *params = mCaps.maxFragmentUniformBlocks;                       break;
    915       case GL_MAX_COMBINED_UNIFORM_BLOCKS:              *params = mCaps.maxCombinedTextureImageUnits;                   break;
    916       case GL_MAJOR_VERSION:                            *params = mClientVersion;                                       break;
    917       case GL_MINOR_VERSION:                            *params = 0;                                                    break;
    918       case GL_MAX_ELEMENTS_INDICES:                     *params = mCaps.maxElementsIndices;                             break;
    919       case GL_MAX_ELEMENTS_VERTICES:                    *params = mCaps.maxElementsVertices;                            break;
    920       case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
    921       case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:       *params = mCaps.maxTransformFeedbackSeparateAttributes;    break;
    922       case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:    *params = mCaps.maxTransformFeedbackSeparateComponents;    break;
    923       case GL_NUM_COMPRESSED_TEXTURE_FORMATS:           *params = mCaps.compressedTextureFormats.size();                break;
    924       case GL_MAX_SAMPLES_ANGLE:                        *params = mExtensions.maxSamples;                               break;
    925       case GL_IMPLEMENTATION_COLOR_READ_TYPE:
    926       case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
    927         {
    928             GLenum internalFormat, format, type;
    929             getCurrentReadFormatType(&internalFormat, &format, &type);
    930             if (pname == GL_IMPLEMENTATION_COLOR_READ_FORMAT)
    931                 *params = format;
    932             else
    933                 *params = type;
    934         }
    935         break;
    936       case GL_MAX_VIEWPORT_DIMS:
    937         {
    938             params[0] = mCaps.maxViewportWidth;
    939             params[1] = mCaps.maxViewportHeight;
    940         }
    941         break;
    942       case GL_COMPRESSED_TEXTURE_FORMATS:
    943         std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
    944         break;
    945       case GL_RESET_NOTIFICATION_STRATEGY_EXT:
    946         *params = mResetStrategy;
    947         break;
    948       case GL_NUM_SHADER_BINARY_FORMATS:
    949         *params = mCaps.shaderBinaryFormats.size();
    950         break;
    951       case GL_SHADER_BINARY_FORMATS:
    952         std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
    953         break;
    954       case GL_NUM_PROGRAM_BINARY_FORMATS:
    955         *params = mCaps.programBinaryFormats.size();
    956         break;
    957       case GL_PROGRAM_BINARY_FORMATS:
    958         std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
    959         break;
    960       case GL_NUM_EXTENSIONS:
    961         *params = static_cast<GLint>(mExtensionStrings.size());
    962         break;
    963       default:
    964         mState.getIntegerv(pname, params);
    965         break;
    966     }
    967 }
    968 
    969 void Context::getInteger64v(GLenum pname, GLint64 *params)
    970 {
    971     // Queries about context capabilities and maximums are answered by Context.
    972     // Queries about current GL state values are answered by State.
    973     switch (pname)
    974     {
    975       case GL_MAX_ELEMENT_INDEX:
    976         *params = mCaps.maxElementIndex;
    977         break;
    978       case GL_MAX_UNIFORM_BLOCK_SIZE:
    979         *params = mCaps.maxUniformBlockSize;
    980         break;
    981       case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
    982         *params = mCaps.maxCombinedVertexUniformComponents;
    983         break;
    984       case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
    985         *params = mCaps.maxCombinedFragmentUniformComponents;
    986         break;
    987       case GL_MAX_SERVER_WAIT_TIMEOUT:
    988         *params = mCaps.maxServerWaitTimeout;
    989         break;
    990       default:
    991         UNREACHABLE();
    992         break;
    993     }
    994 }
    995 
    996 bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
    997 {
    998     // Queries about context capabilities and maximums are answered by Context.
    999     // Queries about current GL state values are answered by State.
   1000     // Indexed integer queries all refer to current state, so this function is a
   1001     // mere passthrough.
   1002     return mState.getIndexedIntegerv(target, index, data);
   1003 }
   1004 
   1005 bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
   1006 {
   1007     // Queries about context capabilities and maximums are answered by Context.
   1008     // Queries about current GL state values are answered by State.
   1009     // Indexed integer queries all refer to current state, so this function is a
   1010     // mere passthrough.
   1011     return mState.getIndexedInteger64v(target, index, data);
   1012 }
   1013 
   1014 bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
   1015 {
   1016     if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
   1017     {
   1018         *type = GL_INT;
   1019         *numParams = 1;
   1020         return true;
   1021     }
   1022 
   1023     // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
   1024     // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
   1025     // to the fact that it is stored internally as a float, and so would require conversion
   1026     // if returned from Context::getIntegerv. Since this conversion is already implemented
   1027     // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
   1028     // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
   1029     // application.
   1030     switch (pname)
   1031     {
   1032       case GL_COMPRESSED_TEXTURE_FORMATS:
   1033         {
   1034             *type = GL_INT;
   1035             *numParams = mCaps.compressedTextureFormats.size();
   1036         }
   1037         return true;
   1038       case GL_PROGRAM_BINARY_FORMATS_OES:
   1039         {
   1040             *type = GL_INT;
   1041             *numParams = mCaps.programBinaryFormats.size();
   1042         }
   1043         return true;
   1044       case GL_SHADER_BINARY_FORMATS:
   1045         {
   1046             *type = GL_INT;
   1047             *numParams = mCaps.shaderBinaryFormats.size();
   1048         }
   1049         return true;
   1050       case GL_MAX_VERTEX_ATTRIBS:
   1051       case GL_MAX_VERTEX_UNIFORM_VECTORS:
   1052       case GL_MAX_VARYING_VECTORS:
   1053       case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
   1054       case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
   1055       case GL_MAX_TEXTURE_IMAGE_UNITS:
   1056       case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
   1057       case GL_MAX_RENDERBUFFER_SIZE:
   1058       case GL_MAX_COLOR_ATTACHMENTS_EXT:
   1059       case GL_MAX_DRAW_BUFFERS_EXT:
   1060       case GL_NUM_SHADER_BINARY_FORMATS:
   1061       case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
   1062       case GL_ARRAY_BUFFER_BINDING:
   1063       //case GL_FRAMEBUFFER_BINDING: // equivalent to DRAW_FRAMEBUFFER_BINDING_ANGLE
   1064       case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:
   1065       case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
   1066       case GL_RENDERBUFFER_BINDING:
   1067       case GL_CURRENT_PROGRAM:
   1068       case GL_PACK_ALIGNMENT:
   1069       case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
   1070       case GL_UNPACK_ALIGNMENT:
   1071       case GL_GENERATE_MIPMAP_HINT:
   1072       case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
   1073       case GL_RED_BITS:
   1074       case GL_GREEN_BITS:
   1075       case GL_BLUE_BITS:
   1076       case GL_ALPHA_BITS:
   1077       case GL_DEPTH_BITS:
   1078       case GL_STENCIL_BITS:
   1079       case GL_ELEMENT_ARRAY_BUFFER_BINDING:
   1080       case GL_CULL_FACE_MODE:
   1081       case GL_FRONT_FACE:
   1082       case GL_ACTIVE_TEXTURE:
   1083       case GL_STENCIL_FUNC:
   1084       case GL_STENCIL_VALUE_MASK:
   1085       case GL_STENCIL_REF:
   1086       case GL_STENCIL_FAIL:
   1087       case GL_STENCIL_PASS_DEPTH_FAIL:
   1088       case GL_STENCIL_PASS_DEPTH_PASS:
   1089       case GL_STENCIL_BACK_FUNC:
   1090       case GL_STENCIL_BACK_VALUE_MASK:
   1091       case GL_STENCIL_BACK_REF:
   1092       case GL_STENCIL_BACK_FAIL:
   1093       case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
   1094       case GL_STENCIL_BACK_PASS_DEPTH_PASS:
   1095       case GL_DEPTH_FUNC:
   1096       case GL_BLEND_SRC_RGB:
   1097       case GL_BLEND_SRC_ALPHA:
   1098       case GL_BLEND_DST_RGB:
   1099       case GL_BLEND_DST_ALPHA:
   1100       case GL_BLEND_EQUATION_RGB:
   1101       case GL_BLEND_EQUATION_ALPHA:
   1102       case GL_STENCIL_WRITEMASK:
   1103       case GL_STENCIL_BACK_WRITEMASK:
   1104       case GL_STENCIL_CLEAR_VALUE:
   1105       case GL_SUBPIXEL_BITS:
   1106       case GL_MAX_TEXTURE_SIZE:
   1107       case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
   1108       case GL_SAMPLE_BUFFERS:
   1109       case GL_SAMPLES:
   1110       case GL_IMPLEMENTATION_COLOR_READ_TYPE:
   1111       case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
   1112       case GL_TEXTURE_BINDING_2D:
   1113       case GL_TEXTURE_BINDING_CUBE_MAP:
   1114       case GL_RESET_NOTIFICATION_STRATEGY_EXT:
   1115       case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
   1116         {
   1117             *type = GL_INT;
   1118             *numParams = 1;
   1119         }
   1120         return true;
   1121       case GL_MAX_SAMPLES_ANGLE:
   1122         {
   1123             if (mExtensions.framebufferMultisample)
   1124             {
   1125                 *type = GL_INT;
   1126                 *numParams = 1;
   1127             }
   1128             else
   1129             {
   1130                 return false;
   1131             }
   1132         }
   1133         return true;
   1134       case GL_PIXEL_PACK_BUFFER_BINDING:
   1135       case GL_PIXEL_UNPACK_BUFFER_BINDING:
   1136         {
   1137             if (mExtensions.pixelBufferObject)
   1138             {
   1139                 *type = GL_INT;
   1140                 *numParams = 1;
   1141             }
   1142             else
   1143             {
   1144                 return false;
   1145             }
   1146         }
   1147         return true;
   1148       case GL_MAX_VIEWPORT_DIMS:
   1149         {
   1150             *type = GL_INT;
   1151             *numParams = 2;
   1152         }
   1153         return true;
   1154       case GL_VIEWPORT:
   1155       case GL_SCISSOR_BOX:
   1156         {
   1157             *type = GL_INT;
   1158             *numParams = 4;
   1159         }
   1160         return true;
   1161       case GL_SHADER_COMPILER:
   1162       case GL_SAMPLE_COVERAGE_INVERT:
   1163       case GL_DEPTH_WRITEMASK:
   1164       case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
   1165       case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
   1166       case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
   1167       case GL_SAMPLE_COVERAGE:
   1168       case GL_SCISSOR_TEST:
   1169       case GL_STENCIL_TEST:
   1170       case GL_DEPTH_TEST:
   1171       case GL_BLEND:
   1172       case GL_DITHER:
   1173       case GL_CONTEXT_ROBUST_ACCESS_EXT:
   1174         {
   1175             *type = GL_BOOL;
   1176             *numParams = 1;
   1177         }
   1178         return true;
   1179       case GL_COLOR_WRITEMASK:
   1180         {
   1181             *type = GL_BOOL;
   1182             *numParams = 4;
   1183         }
   1184         return true;
   1185       case GL_POLYGON_OFFSET_FACTOR:
   1186       case GL_POLYGON_OFFSET_UNITS:
   1187       case GL_SAMPLE_COVERAGE_VALUE:
   1188       case GL_DEPTH_CLEAR_VALUE:
   1189       case GL_LINE_WIDTH:
   1190         {
   1191             *type = GL_FLOAT;
   1192             *numParams = 1;
   1193         }
   1194         return true;
   1195       case GL_ALIASED_LINE_WIDTH_RANGE:
   1196       case GL_ALIASED_POINT_SIZE_RANGE:
   1197       case GL_DEPTH_RANGE:
   1198         {
   1199             *type = GL_FLOAT;
   1200             *numParams = 2;
   1201         }
   1202         return true;
   1203       case GL_COLOR_CLEAR_VALUE:
   1204       case GL_BLEND_COLOR:
   1205         {
   1206             *type = GL_FLOAT;
   1207             *numParams = 4;
   1208         }
   1209         return true;
   1210       case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
   1211         if (!mExtensions.maxTextureAnisotropy)
   1212         {
   1213             return false;
   1214         }
   1215         *type = GL_FLOAT;
   1216         *numParams = 1;
   1217         return true;
   1218     }
   1219 
   1220     if (mClientVersion < 3)
   1221     {
   1222         return false;
   1223     }
   1224 
   1225     // Check for ES3.0+ parameter names
   1226     switch (pname)
   1227     {
   1228       case GL_MAX_UNIFORM_BUFFER_BINDINGS:
   1229       case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
   1230       case GL_UNIFORM_BUFFER_BINDING:
   1231       case GL_TRANSFORM_FEEDBACK_BINDING:
   1232       case GL_COPY_READ_BUFFER_BINDING:
   1233       case GL_COPY_WRITE_BUFFER_BINDING:
   1234       case GL_TEXTURE_BINDING_3D:
   1235       case GL_TEXTURE_BINDING_2D_ARRAY:
   1236       case GL_MAX_3D_TEXTURE_SIZE:
   1237       case GL_MAX_ARRAY_TEXTURE_LAYERS:
   1238       case GL_MAX_VERTEX_UNIFORM_BLOCKS:
   1239       case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
   1240       case GL_MAX_COMBINED_UNIFORM_BLOCKS:
   1241       case GL_MAX_VARYING_COMPONENTS:
   1242       case GL_VERTEX_ARRAY_BINDING:
   1243       case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
   1244       case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
   1245       case GL_NUM_EXTENSIONS:
   1246       case GL_MAJOR_VERSION:
   1247       case GL_MINOR_VERSION:
   1248       case GL_MAX_ELEMENTS_INDICES:
   1249       case GL_MAX_ELEMENTS_VERTICES:
   1250       case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
   1251       case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
   1252       case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
   1253         {
   1254             *type = GL_INT;
   1255             *numParams = 1;
   1256         }
   1257         return true;
   1258 
   1259       case GL_MAX_ELEMENT_INDEX:
   1260       case GL_MAX_UNIFORM_BLOCK_SIZE:
   1261       case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
   1262       case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
   1263       case GL_MAX_SERVER_WAIT_TIMEOUT:
   1264         {
   1265             *type = GL_INT_64_ANGLEX;
   1266             *numParams = 1;
   1267         }
   1268         return true;
   1269 
   1270       case GL_TRANSFORM_FEEDBACK_ACTIVE:
   1271       case GL_TRANSFORM_FEEDBACK_PAUSED:
   1272         {
   1273             *type = GL_BOOL;
   1274             *numParams = 1;
   1275         }
   1276         return true;
   1277     }
   1278 
   1279     return false;
   1280 }
   1281 
   1282 bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams)
   1283 {
   1284     if (mClientVersion < 3)
   1285     {
   1286         return false;
   1287     }
   1288 
   1289     switch (target)
   1290     {
   1291       case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
   1292       case GL_UNIFORM_BUFFER_BINDING:
   1293         {
   1294             *type = GL_INT;
   1295             *numParams = 1;
   1296         }
   1297         return true;
   1298       case GL_TRANSFORM_FEEDBACK_BUFFER_START:
   1299       case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
   1300       case GL_UNIFORM_BUFFER_START:
   1301       case GL_UNIFORM_BUFFER_SIZE:
   1302         {
   1303             *type = GL_INT_64_ANGLEX;
   1304             *numParams = 1;
   1305         }
   1306     }
   1307 
   1308     return false;
   1309 }
   1310 
   1311 // Applies the render target surface, depth stencil surface, viewport rectangle and
   1312 // scissor rectangle to the renderer
   1313 void Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport)
   1314 {
   1315     Framebuffer *framebufferObject = mState.getDrawFramebuffer();
   1316     ASSERT(framebufferObject && framebufferObject->completeness() == GL_FRAMEBUFFER_COMPLETE);
   1317 
   1318     mRenderer->applyRenderTarget(framebufferObject);
   1319 
   1320     float nearZ, farZ;
   1321     mState.getDepthRange(&nearZ, &farZ);
   1322     mRenderer->setViewport(mState.getViewport(), nearZ, farZ, drawMode, mState.getRasterizerState().frontFace,
   1323                            ignoreViewport);
   1324 
   1325     mRenderer->setScissorRectangle(mState.getScissor(), mState.isScissorTestEnabled());
   1326 }
   1327 
   1328 // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
   1329 void Context::applyState(GLenum drawMode)
   1330 {
   1331     Framebuffer *framebufferObject = mState.getDrawFramebuffer();
   1332     int samples = framebufferObject->getSamples();
   1333 
   1334     RasterizerState rasterizer = mState.getRasterizerState();
   1335     rasterizer.pointDrawMode = (drawMode == GL_POINTS);
   1336     rasterizer.multiSample = (samples != 0);
   1337 
   1338     mRenderer->setRasterizerState(rasterizer);
   1339 
   1340     unsigned int mask = 0;
   1341     if (mState.isSampleCoverageEnabled())
   1342     {
   1343         GLclampf coverageValue;
   1344         bool coverageInvert = false;
   1345         mState.getSampleCoverageParams(&coverageValue, &coverageInvert);
   1346         if (coverageValue != 0)
   1347         {
   1348 
   1349             float threshold = 0.5f;
   1350 
   1351             for (int i = 0; i < samples; ++i)
   1352             {
   1353                 mask <<= 1;
   1354 
   1355                 if ((i + 1) * coverageValue >= threshold)
   1356                 {
   1357                     threshold += 1.0f;
   1358                     mask |= 1;
   1359                 }
   1360             }
   1361         }
   1362 
   1363         if (coverageInvert)
   1364         {
   1365             mask = ~mask;
   1366         }
   1367     }
   1368     else
   1369     {
   1370         mask = 0xFFFFFFFF;
   1371     }
   1372     mRenderer->setBlendState(framebufferObject, mState.getBlendState(), mState.getBlendColor(), mask);
   1373 
   1374     mRenderer->setDepthStencilState(mState.getDepthStencilState(), mState.getStencilRef(), mState.getStencilBackRef(),
   1375                                     rasterizer.frontFace == GL_CCW);
   1376 }
   1377 
   1378 // Applies the shaders and shader constants to the Direct3D 9 device
   1379 void Context::applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive)
   1380 {
   1381     const VertexAttribute *vertexAttributes = mState.getVertexArray()->getVertexAttributes();
   1382 
   1383     VertexFormat inputLayout[MAX_VERTEX_ATTRIBS];
   1384     VertexFormat::GetInputLayout(inputLayout, programBinary, vertexAttributes, mState.getVertexAttribCurrentValues());
   1385 
   1386     const Framebuffer *fbo = mState.getDrawFramebuffer();
   1387 
   1388     mRenderer->applyShaders(programBinary, inputLayout, fbo, mState.getRasterizerState().rasterizerDiscard, transformFeedbackActive);
   1389 
   1390     programBinary->applyUniforms();
   1391 }
   1392 
   1393 void Context::generateSwizzles(ProgramBinary *programBinary, SamplerType type)
   1394 {
   1395     size_t samplerRange = programBinary->getUsedSamplerRange(type);
   1396 
   1397     for (size_t i = 0; i < samplerRange; i++)
   1398     {
   1399         GLenum textureType = programBinary->getSamplerTextureType(type, i);
   1400         GLint textureUnit = programBinary->getSamplerMapping(type, i, getCaps());
   1401         if (textureUnit != -1)
   1402         {
   1403             Texture* texture = getSamplerTexture(textureUnit, textureType);
   1404             if (texture->getSamplerState().swizzleRequired())
   1405             {
   1406                 mRenderer->generateSwizzle(texture);
   1407             }
   1408         }
   1409     }
   1410 }
   1411 
   1412 void Context::generateSwizzles(ProgramBinary *programBinary)
   1413 {
   1414     generateSwizzles(programBinary, SAMPLER_VERTEX);
   1415     generateSwizzles(programBinary, SAMPLER_PIXEL);
   1416 }
   1417 
   1418 // For each Direct3D sampler of either the pixel or vertex stage,
   1419 // looks up the corresponding OpenGL texture image unit and texture type,
   1420 // and sets the texture and its addressing/filtering state (or NULL when inactive).
   1421 void Context::applyTextures(ProgramBinary *programBinary, SamplerType shaderType,
   1422                             const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount)
   1423 {
   1424     size_t samplerRange = programBinary->getUsedSamplerRange(shaderType);
   1425     for (size_t samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
   1426     {
   1427         GLenum textureType = programBinary->getSamplerTextureType(shaderType, samplerIndex);
   1428         GLint textureUnit = programBinary->getSamplerMapping(shaderType, samplerIndex, getCaps());
   1429         if (textureUnit != -1)
   1430         {
   1431             SamplerState sampler;
   1432             Texture* texture = getSamplerTexture(textureUnit, textureType);
   1433             texture->getSamplerStateWithNativeOffset(&sampler);
   1434 
   1435             Sampler *samplerObject = mState.getSampler(textureUnit);
   1436             if (samplerObject)
   1437             {
   1438                 samplerObject->getState(&sampler);
   1439             }
   1440 
   1441             // TODO: std::binary_search may become unavailable using older versions of GCC
   1442             if (texture->isSamplerComplete(sampler, mTextureCaps, mExtensions, mClientVersion) &&
   1443                 !std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial()))
   1444             {
   1445                 mRenderer->setSamplerState(shaderType, samplerIndex, sampler);
   1446                 mRenderer->setTexture(shaderType, samplerIndex, texture);
   1447             }
   1448             else
   1449             {
   1450                 // Texture is not sampler complete or it is in use by the framebuffer.  Bind the incomplete texture.
   1451                 Texture *incompleteTexture = getIncompleteTexture(textureType);
   1452                 mRenderer->setTexture(shaderType, samplerIndex, incompleteTexture);
   1453             }
   1454         }
   1455         else
   1456         {
   1457             // No texture bound to this slot even though it is used by the shader, bind a NULL texture
   1458             mRenderer->setTexture(shaderType, samplerIndex, NULL);
   1459         }
   1460     }
   1461 
   1462     // Set all the remaining textures to NULL
   1463     size_t samplerCount = (shaderType == SAMPLER_PIXEL) ? mCaps.maxTextureImageUnits
   1464                                                         : mCaps.maxVertexTextureImageUnits;
   1465     for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
   1466     {
   1467         mRenderer->setTexture(shaderType, samplerIndex, NULL);
   1468     }
   1469 }
   1470 
   1471 void Context::applyTextures(ProgramBinary *programBinary)
   1472 {
   1473     FramebufferTextureSerialArray framebufferSerials;
   1474     size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&framebufferSerials);
   1475 
   1476     applyTextures(programBinary, SAMPLER_VERTEX, framebufferSerials, framebufferSerialCount);
   1477     applyTextures(programBinary, SAMPLER_PIXEL, framebufferSerials, framebufferSerialCount);
   1478 }
   1479 
   1480 bool Context::applyUniformBuffers()
   1481 {
   1482     Program *programObject = getProgram(mState.getCurrentProgramId());
   1483     ProgramBinary *programBinary = programObject->getProgramBinary();
   1484 
   1485     std::vector<Buffer*> boundBuffers;
   1486 
   1487     for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++)
   1488     {
   1489         GLuint blockBinding = programObject->getUniformBlockBinding(uniformBlockIndex);
   1490 
   1491         if (mState.getIndexedUniformBuffer(blockBinding)->id() == 0)
   1492         {
   1493             // undefined behaviour
   1494             return false;
   1495         }
   1496         else
   1497         {
   1498             Buffer *uniformBuffer = mState.getIndexedUniformBuffer(blockBinding);
   1499             ASSERT(uniformBuffer);
   1500             boundBuffers.push_back(uniformBuffer);
   1501         }
   1502     }
   1503 
   1504     return programBinary->applyUniformBuffers(boundBuffers, getCaps());
   1505 }
   1506 
   1507 bool Context::applyTransformFeedbackBuffers()
   1508 {
   1509     TransformFeedback *curTransformFeedback = mState.getCurrentTransformFeedback();
   1510     if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
   1511     {
   1512         Buffer *transformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
   1513         GLintptr transformFeedbackOffsets[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
   1514         for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
   1515         {
   1516             transformFeedbackBuffers[i] = mState.getIndexedTransformFeedbackBuffer(i);
   1517             transformFeedbackOffsets[i] = mState.getIndexedTransformFeedbackBufferOffset(i);
   1518         }
   1519         mRenderer->applyTransformFeedbackBuffers(transformFeedbackBuffers, transformFeedbackOffsets);
   1520         return true;
   1521     }
   1522     else
   1523     {
   1524         return false;
   1525     }
   1526 }
   1527 
   1528 void Context::markTransformFeedbackUsage()
   1529 {
   1530     for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
   1531     {
   1532         Buffer *buffer = mState.getIndexedTransformFeedbackBuffer(i);
   1533         if (buffer)
   1534         {
   1535             buffer->markTransformFeedbackUsage();
   1536         }
   1537     }
   1538 }
   1539 
   1540 Error Context::clear(GLbitfield mask)
   1541 {
   1542     if (mState.isRasterizerDiscardEnabled())
   1543     {
   1544         return Error(GL_NO_ERROR);
   1545     }
   1546 
   1547     ClearParameters clearParams = mState.getClearParameters(mask);
   1548 
   1549     applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
   1550 
   1551     return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
   1552 }
   1553 
   1554 Error Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values)
   1555 {
   1556     if (mState.isRasterizerDiscardEnabled())
   1557     {
   1558         return Error(GL_NO_ERROR);
   1559     }
   1560 
   1561     // glClearBufferfv can be called to clear the color buffer or depth buffer
   1562     ClearParameters clearParams = mState.getClearParameters(0);
   1563 
   1564     if (buffer == GL_COLOR)
   1565     {
   1566         for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
   1567         {
   1568             clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
   1569         }
   1570         clearParams.colorFClearValue = ColorF(values[0], values[1], values[2], values[3]);
   1571         clearParams.colorClearType = GL_FLOAT;
   1572     }
   1573 
   1574     if (buffer == GL_DEPTH)
   1575     {
   1576         clearParams.clearDepth = true;
   1577         clearParams.depthClearValue = values[0];
   1578     }
   1579 
   1580     applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
   1581 
   1582     return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
   1583 }
   1584 
   1585 Error Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values)
   1586 {
   1587     if (mState.isRasterizerDiscardEnabled())
   1588     {
   1589         return Error(GL_NO_ERROR);
   1590     }
   1591 
   1592     // glClearBufferuv can only be called to clear a color buffer
   1593     ClearParameters clearParams = mState.getClearParameters(0);
   1594     for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
   1595     {
   1596         clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
   1597     }
   1598     clearParams.colorUIClearValue = ColorUI(values[0], values[1], values[2], values[3]);
   1599     clearParams.colorClearType = GL_UNSIGNED_INT;
   1600 
   1601     applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
   1602 
   1603     return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
   1604 }
   1605 
   1606 Error Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values)
   1607 {
   1608     if (mState.isRasterizerDiscardEnabled())
   1609     {
   1610         return Error(GL_NO_ERROR);
   1611     }
   1612 
   1613     // glClearBufferfv can be called to clear the color buffer or stencil buffer
   1614     ClearParameters clearParams = mState.getClearParameters(0);
   1615 
   1616     if (buffer == GL_COLOR)
   1617     {
   1618         for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
   1619         {
   1620             clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
   1621         }
   1622         clearParams.colorIClearValue = ColorI(values[0], values[1], values[2], values[3]);
   1623         clearParams.colorClearType = GL_INT;
   1624     }
   1625 
   1626     if (buffer == GL_STENCIL)
   1627     {
   1628         clearParams.clearStencil = true;
   1629         clearParams.stencilClearValue = values[1];
   1630     }
   1631 
   1632     applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
   1633 
   1634     return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
   1635 }
   1636 
   1637 Error Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil)
   1638 {
   1639     if (mState.isRasterizerDiscardEnabled())
   1640     {
   1641         return Error(GL_NO_ERROR);
   1642     }
   1643 
   1644     // glClearBufferfi can only be called to clear a depth stencil buffer
   1645     ClearParameters clearParams = mState.getClearParameters(0);
   1646     clearParams.clearDepth = true;
   1647     clearParams.depthClearValue = depth;
   1648     clearParams.clearStencil = true;
   1649     clearParams.stencilClearValue = stencil;
   1650 
   1651     applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
   1652 
   1653     return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
   1654 }
   1655 
   1656 Error Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
   1657                           GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
   1658 {
   1659     Framebuffer *framebuffer = mState.getReadFramebuffer();
   1660 
   1661     GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
   1662     const InternalFormat &sizedFormatInfo = GetInternalFormatInfo(sizedInternalFormat);
   1663     GLuint outputPitch = sizedFormatInfo.computeRowPitch(type, width, mState.getPackAlignment());
   1664 
   1665     return mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, mState.getPackState(),
   1666                                  reinterpret_cast<uint8_t*>(pixels));
   1667 }
   1668 
   1669 void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
   1670 {
   1671     ASSERT(mState.getCurrentProgramId() != 0);
   1672 
   1673     ProgramBinary *programBinary = mState.getCurrentProgramBinary();
   1674     programBinary->updateSamplerMapping();
   1675 
   1676     generateSwizzles(programBinary);
   1677 
   1678     if (!mRenderer->applyPrimitiveType(mode, count))
   1679     {
   1680         return;
   1681     }
   1682 
   1683     applyRenderTarget(mode, false);
   1684     applyState(mode);
   1685 
   1686     Error error = mRenderer->applyVertexBuffer(programBinary, mState.getVertexArray()->getVertexAttributes(), mState.getVertexAttribCurrentValues(), first, count, instances);
   1687     if (error.isError())
   1688     {
   1689         return gl::error(error.getCode());
   1690     }
   1691 
   1692     bool transformFeedbackActive = applyTransformFeedbackBuffers();
   1693 
   1694     applyShaders(programBinary, transformFeedbackActive);
   1695 
   1696     applyTextures(programBinary);
   1697 
   1698     if (!applyUniformBuffers())
   1699     {
   1700         return;
   1701     }
   1702 
   1703     if (!skipDraw(mode))
   1704     {
   1705         mRenderer->drawArrays(mode, count, instances, transformFeedbackActive);
   1706 
   1707         if (transformFeedbackActive)
   1708         {
   1709             markTransformFeedbackUsage();
   1710         }
   1711     }
   1712 }
   1713 
   1714 void Context::drawElements(GLenum mode, GLsizei count, GLenum type,
   1715                            const GLvoid *indices, GLsizei instances,
   1716                            const rx::RangeUI &indexRange)
   1717 {
   1718     ASSERT(mState.getCurrentProgramId() != 0);
   1719 
   1720     ProgramBinary *programBinary = mState.getCurrentProgramBinary();
   1721     programBinary->updateSamplerMapping();
   1722 
   1723     generateSwizzles(programBinary);
   1724 
   1725     if (!mRenderer->applyPrimitiveType(mode, count))
   1726     {
   1727         return;
   1728     }
   1729 
   1730     applyRenderTarget(mode, false);
   1731     applyState(mode);
   1732 
   1733     VertexArray *vao = mState.getVertexArray();
   1734     rx::TranslatedIndexData indexInfo;
   1735     indexInfo.indexRange = indexRange;
   1736     Error error = mRenderer->applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo);
   1737     if (error.isError())
   1738     {
   1739         return gl::error(error.getCode());
   1740     }
   1741 
   1742     GLsizei vertexCount = indexInfo.indexRange.length() + 1;
   1743     error = mRenderer->applyVertexBuffer(programBinary, vao->getVertexAttributes(),
   1744                                          mState.getVertexAttribCurrentValues(),
   1745                                          indexInfo.indexRange.start, vertexCount, instances);
   1746     if (error.isError())
   1747     {
   1748         return gl::error(error.getCode());
   1749     }
   1750 
   1751     bool transformFeedbackActive = applyTransformFeedbackBuffers();
   1752     // Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation
   1753     // layer.
   1754     ASSERT(!transformFeedbackActive);
   1755 
   1756     applyShaders(programBinary, transformFeedbackActive);
   1757 
   1758     applyTextures(programBinary);
   1759 
   1760     if (!applyUniformBuffers())
   1761     {
   1762         return;
   1763     }
   1764 
   1765     if (!skipDraw(mode))
   1766     {
   1767         mRenderer->drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances);
   1768     }
   1769 }
   1770 
   1771 // Implements glFlush when block is false, glFinish when block is true
   1772 void Context::sync(bool block)
   1773 {
   1774     mRenderer->sync(block);
   1775 }
   1776 
   1777 void Context::recordError(const Error &error)
   1778 {
   1779     if (error.isError())
   1780     {
   1781         mErrors.insert(error.getCode());
   1782     }
   1783 }
   1784 
   1785 // Get one of the recorded errors and clear its flag, if any.
   1786 // [OpenGL ES 2.0.24] section 2.5 page 13.
   1787 GLenum Context::getError()
   1788 {
   1789     if (mErrors.empty())
   1790     {
   1791         return GL_NO_ERROR;
   1792     }
   1793     else
   1794     {
   1795         GLenum error = *mErrors.begin();
   1796         mErrors.erase(mErrors.begin());
   1797         return error;
   1798     }
   1799 }
   1800 
   1801 GLenum Context::getResetStatus()
   1802 {
   1803     if (mResetStatus == GL_NO_ERROR && !mContextLost)
   1804     {
   1805         // mResetStatus will be set by the markContextLost callback
   1806         // in the case a notification is sent
   1807         mRenderer->testDeviceLost(true);
   1808     }
   1809 
   1810     GLenum status = mResetStatus;
   1811 
   1812     if (mResetStatus != GL_NO_ERROR)
   1813     {
   1814         ASSERT(mContextLost);
   1815 
   1816         if (mRenderer->testDeviceResettable())
   1817         {
   1818             mResetStatus = GL_NO_ERROR;
   1819         }
   1820     }
   1821 
   1822     return status;
   1823 }
   1824 
   1825 bool Context::isResetNotificationEnabled()
   1826 {
   1827     return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
   1828 }
   1829 
   1830 int Context::getClientVersion() const
   1831 {
   1832     return mClientVersion;
   1833 }
   1834 
   1835 const Caps &Context::getCaps() const
   1836 {
   1837     return mCaps;
   1838 }
   1839 
   1840 const TextureCapsMap &Context::getTextureCaps() const
   1841 {
   1842     return mTextureCaps;
   1843 }
   1844 
   1845 const Extensions &Context::getExtensions() const
   1846 {
   1847     return mExtensions;
   1848 }
   1849 
   1850 void Context::getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type)
   1851 {
   1852     Framebuffer *framebuffer = mState.getReadFramebuffer();
   1853     ASSERT(framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE);
   1854 
   1855     FramebufferAttachment *attachment = framebuffer->getReadColorbuffer();
   1856     ASSERT(attachment);
   1857 
   1858     GLenum actualFormat = attachment->getActualFormat();
   1859     const InternalFormat &actualFormatInfo = GetInternalFormatInfo(actualFormat);
   1860 
   1861     *internalFormat = actualFormat;
   1862     *format = actualFormatInfo.format;
   1863     *type = actualFormatInfo.type;
   1864 }
   1865 
   1866 void Context::detachTexture(GLuint texture)
   1867 {
   1868     // Simple pass-through to State's detachTexture method, as textures do not require
   1869     // allocation map management either here or in the resource manager at detach time.
   1870     // Zero textures are held by the Context, and we don't attempt to request them from
   1871     // the State.
   1872     mState.detachTexture(texture);
   1873 }
   1874 
   1875 void Context::detachBuffer(GLuint buffer)
   1876 {
   1877     // Buffer detachment is handled by Context, because the buffer must also be
   1878     // attached from any VAOs in existence, and Context holds the VAO map.
   1879 
   1880     // [OpenGL ES 2.0.24] section 2.9 page 22:
   1881     // If a buffer object is deleted while it is bound, all bindings to that object in the current context
   1882     // (i.e. in the thread that called Delete-Buffers) are reset to zero.
   1883 
   1884     mState.removeArrayBufferBinding(buffer);
   1885 
   1886     // mark as freed among the vertex array objects
   1887     for (auto vaoIt = mVertexArrayMap.begin(); vaoIt != mVertexArrayMap.end(); vaoIt++)
   1888     {
   1889         vaoIt->second->detachBuffer(buffer);
   1890     }
   1891 }
   1892 
   1893 void Context::detachFramebuffer(GLuint framebuffer)
   1894 {
   1895     // Framebuffer detachment is handled by Context, because 0 is a valid
   1896     // Framebuffer object, and a pointer to it must be passed from Context
   1897     // to State at binding time.
   1898 
   1899     // [OpenGL ES 2.0.24] section 4.4 page 107:
   1900     // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
   1901     // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
   1902 
   1903     if (mState.removeReadFramebufferBinding(framebuffer))
   1904     {
   1905         bindReadFramebuffer(0);
   1906     }
   1907 
   1908     if (mState.removeDrawFramebufferBinding(framebuffer))
   1909     {
   1910         bindDrawFramebuffer(0);
   1911     }
   1912 }
   1913 
   1914 void Context::detachRenderbuffer(GLuint renderbuffer)
   1915 {
   1916     mState.detachRenderbuffer(renderbuffer);
   1917 }
   1918 
   1919 void Context::detachVertexArray(GLuint vertexArray)
   1920 {
   1921     // Vertex array detachment is handled by Context, because 0 is a valid
   1922     // VAO, and a pointer to it must be passed from Context to State at
   1923     // binding time.
   1924 
   1925     // [OpenGL ES 3.0.2] section 2.10 page 43:
   1926     // If a vertex array object that is currently bound is deleted, the binding
   1927     // for that object reverts to zero and the default vertex array becomes current.
   1928     if (mState.removeVertexArrayBinding(vertexArray))
   1929     {
   1930         bindVertexArray(0);
   1931     }
   1932 }
   1933 
   1934 void Context::detachTransformFeedback(GLuint transformFeedback)
   1935 {
   1936     mState.detachTransformFeedback(transformFeedback);
   1937 }
   1938 
   1939 void Context::detachSampler(GLuint sampler)
   1940 {
   1941     mState.detachSampler(sampler);
   1942 }
   1943 
   1944 Texture *Context::getIncompleteTexture(GLenum type)
   1945 {
   1946     if (mIncompleteTextures.find(type) == mIncompleteTextures.end())
   1947     {
   1948         const GLubyte color[] = { 0, 0, 0, 255 };
   1949         const PixelUnpackState incompleteUnpackState(1);
   1950 
   1951         Texture* t = NULL;
   1952         switch (type)
   1953         {
   1954           default:
   1955             UNREACHABLE();
   1956             // default falls through to TEXTURE_2D
   1957 
   1958           case GL_TEXTURE_2D:
   1959             {
   1960                 Texture2D *incomplete2d = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), Texture::INCOMPLETE_TEXTURE_ID);
   1961                 incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
   1962                 t = incomplete2d;
   1963             }
   1964             break;
   1965 
   1966           case GL_TEXTURE_CUBE_MAP:
   1967             {
   1968               TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), Texture::INCOMPLETE_TEXTURE_ID);
   1969 
   1970               incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
   1971               incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
   1972               incompleteCube->setImagePosY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
   1973               incompleteCube->setImageNegY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
   1974               incompleteCube->setImagePosZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
   1975               incompleteCube->setImageNegZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
   1976 
   1977               t = incompleteCube;
   1978             }
   1979             break;
   1980 
   1981           case GL_TEXTURE_3D:
   1982             {
   1983                 Texture3D *incomplete3d = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), Texture::INCOMPLETE_TEXTURE_ID);
   1984                 incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
   1985 
   1986                 t = incomplete3d;
   1987             }
   1988             break;
   1989 
   1990           case GL_TEXTURE_2D_ARRAY:
   1991             {
   1992                 Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), Texture::INCOMPLETE_TEXTURE_ID);
   1993                 incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
   1994 
   1995                 t = incomplete2darray;
   1996             }
   1997             break;
   1998         }
   1999 
   2000         mIncompleteTextures[type].set(t);
   2001     }
   2002 
   2003     return mIncompleteTextures[type].get();
   2004 }
   2005 
   2006 bool Context::skipDraw(GLenum drawMode)
   2007 {
   2008     if (drawMode == GL_POINTS)
   2009     {
   2010         // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
   2011         // which affects varying interpolation. Since the value of gl_PointSize is
   2012         // undefined when not written, just skip drawing to avoid unexpected results.
   2013         if (!mState.getCurrentProgramBinary()->usesPointSize())
   2014         {
   2015             // This is stictly speaking not an error, but developers should be
   2016             // notified of risking undefined behavior.
   2017             ERR("Point rendering without writing to gl_PointSize.");
   2018 
   2019             return true;
   2020         }
   2021     }
   2022     else if (IsTriangleMode(drawMode))
   2023     {
   2024         if (mState.getRasterizerState().cullFace && mState.getRasterizerState().cullMode == GL_FRONT_AND_BACK)
   2025         {
   2026             return true;
   2027         }
   2028     }
   2029 
   2030     return false;
   2031 }
   2032 
   2033 void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
   2034 {
   2035     mState.getVertexArray()->setVertexAttribDivisor(index, divisor);
   2036 }
   2037 
   2038 void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
   2039 {
   2040     mResourceManager->checkSamplerAllocation(sampler);
   2041 
   2042     Sampler *samplerObject = getSampler(sampler);
   2043     ASSERT(samplerObject);
   2044 
   2045     switch (pname)
   2046     {
   2047       case GL_TEXTURE_MIN_FILTER:    samplerObject->setMinFilter(static_cast<GLenum>(param));       break;
   2048       case GL_TEXTURE_MAG_FILTER:    samplerObject->setMagFilter(static_cast<GLenum>(param));       break;
   2049       case GL_TEXTURE_WRAP_S:        samplerObject->setWrapS(static_cast<GLenum>(param));           break;
   2050       case GL_TEXTURE_WRAP_T:        samplerObject->setWrapT(static_cast<GLenum>(param));           break;
   2051       case GL_TEXTURE_WRAP_R:        samplerObject->setWrapR(static_cast<GLenum>(param));           break;
   2052       case GL_TEXTURE_MIN_LOD:       samplerObject->setMinLod(static_cast<GLfloat>(param));         break;
   2053       case GL_TEXTURE_MAX_LOD:       samplerObject->setMaxLod(static_cast<GLfloat>(param));         break;
   2054       case GL_TEXTURE_COMPARE_MODE:  samplerObject->setComparisonMode(static_cast<GLenum>(param));  break;
   2055       case GL_TEXTURE_COMPARE_FUNC:  samplerObject->setComparisonFunc(static_cast<GLenum>(param));  break;
   2056       default:                       UNREACHABLE(); break;
   2057     }
   2058 }
   2059 
   2060 void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
   2061 {
   2062     mResourceManager->checkSamplerAllocation(sampler);
   2063 
   2064     Sampler *samplerObject = getSampler(sampler);
   2065     ASSERT(samplerObject);
   2066 
   2067     switch (pname)
   2068     {
   2069       case GL_TEXTURE_MIN_FILTER:    samplerObject->setMinFilter(uiround<GLenum>(param));       break;
   2070       case GL_TEXTURE_MAG_FILTER:    samplerObject->setMagFilter(uiround<GLenum>(param));       break;
   2071       case GL_TEXTURE_WRAP_S:        samplerObject->setWrapS(uiround<GLenum>(param));           break;
   2072       case GL_TEXTURE_WRAP_T:        samplerObject->setWrapT(uiround<GLenum>(param));           break;
   2073       case GL_TEXTURE_WRAP_R:        samplerObject->setWrapR(uiround<GLenum>(param));           break;
   2074       case GL_TEXTURE_MIN_LOD:       samplerObject->setMinLod(param);                           break;
   2075       case GL_TEXTURE_MAX_LOD:       samplerObject->setMaxLod(param);                           break;
   2076       case GL_TEXTURE_COMPARE_MODE:  samplerObject->setComparisonMode(uiround<GLenum>(param));  break;
   2077       case GL_TEXTURE_COMPARE_FUNC:  samplerObject->setComparisonFunc(uiround<GLenum>(param));  break;
   2078       default:                       UNREACHABLE(); break;
   2079     }
   2080 }
   2081 
   2082 GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
   2083 {
   2084     mResourceManager->checkSamplerAllocation(sampler);
   2085 
   2086     Sampler *samplerObject = getSampler(sampler);
   2087     ASSERT(samplerObject);
   2088 
   2089     switch (pname)
   2090     {
   2091       case GL_TEXTURE_MIN_FILTER:    return static_cast<GLint>(samplerObject->getMinFilter());
   2092       case GL_TEXTURE_MAG_FILTER:    return static_cast<GLint>(samplerObject->getMagFilter());
   2093       case GL_TEXTURE_WRAP_S:        return static_cast<GLint>(samplerObject->getWrapS());
   2094       case GL_TEXTURE_WRAP_T:        return static_cast<GLint>(samplerObject->getWrapT());
   2095       case GL_TEXTURE_WRAP_R:        return static_cast<GLint>(samplerObject->getWrapR());
   2096       case GL_TEXTURE_MIN_LOD:       return uiround<GLint>(samplerObject->getMinLod());
   2097       case GL_TEXTURE_MAX_LOD:       return uiround<GLint>(samplerObject->getMaxLod());
   2098       case GL_TEXTURE_COMPARE_MODE:  return static_cast<GLint>(samplerObject->getComparisonMode());
   2099       case GL_TEXTURE_COMPARE_FUNC:  return static_cast<GLint>(samplerObject->getComparisonFunc());
   2100       default:                       UNREACHABLE(); return 0;
   2101     }
   2102 }
   2103 
   2104 GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
   2105 {
   2106     mResourceManager->checkSamplerAllocation(sampler);
   2107 
   2108     Sampler *samplerObject = getSampler(sampler);
   2109     ASSERT(samplerObject);
   2110 
   2111     switch (pname)
   2112     {
   2113       case GL_TEXTURE_MIN_FILTER:    return static_cast<GLfloat>(samplerObject->getMinFilter());
   2114       case GL_TEXTURE_MAG_FILTER:    return static_cast<GLfloat>(samplerObject->getMagFilter());
   2115       case GL_TEXTURE_WRAP_S:        return static_cast<GLfloat>(samplerObject->getWrapS());
   2116       case GL_TEXTURE_WRAP_T:        return static_cast<GLfloat>(samplerObject->getWrapT());
   2117       case GL_TEXTURE_WRAP_R:        return static_cast<GLfloat>(samplerObject->getWrapR());
   2118       case GL_TEXTURE_MIN_LOD:       return samplerObject->getMinLod();
   2119       case GL_TEXTURE_MAX_LOD:       return samplerObject->getMaxLod();
   2120       case GL_TEXTURE_COMPARE_MODE:  return static_cast<GLfloat>(samplerObject->getComparisonMode());
   2121       case GL_TEXTURE_COMPARE_FUNC:  return static_cast<GLfloat>(samplerObject->getComparisonFunc());
   2122       default:                       UNREACHABLE(); return 0;
   2123     }
   2124 }
   2125 
   2126 void Context::initRendererString()
   2127 {
   2128     std::ostringstream rendererString;
   2129     rendererString << "ANGLE (";
   2130     rendererString << mRenderer->getRendererDescription();
   2131     rendererString << ")";
   2132 
   2133     mRendererString = MakeStaticString(rendererString.str());
   2134 }
   2135 
   2136 const std::string &Context::getRendererString() const
   2137 {
   2138     return mRendererString;
   2139 }
   2140 
   2141 void Context::initExtensionStrings()
   2142 {
   2143     mExtensionStrings = mExtensions.getStrings();
   2144 
   2145     std::ostringstream combinedStringStream;
   2146     std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
   2147     mExtensionString = combinedStringStream.str();
   2148 }
   2149 
   2150 const std::string &Context::getExtensionString() const
   2151 {
   2152     return mExtensionString;
   2153 }
   2154 
   2155 const std::string &Context::getExtensionString(size_t idx) const
   2156 {
   2157     return mExtensionStrings[idx];
   2158 }
   2159 
   2160 size_t Context::getExtensionStringCount() const
   2161 {
   2162     return mExtensionStrings.size();
   2163 }
   2164 
   2165 size_t Context::getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray)
   2166 {
   2167     size_t serialCount = 0;
   2168 
   2169     Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
   2170     for (unsigned int i = 0; i < IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
   2171     {
   2172         FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i);
   2173         if (attachment && attachment->isTexture())
   2174         {
   2175             Texture *texture = attachment->getTexture();
   2176             (*outSerialArray)[serialCount++] = texture->getTextureSerial();
   2177         }
   2178     }
   2179 
   2180     FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer();
   2181     if (depthStencilAttachment && depthStencilAttachment->isTexture())
   2182     {
   2183         Texture *depthStencilTexture = depthStencilAttachment->getTexture();
   2184         (*outSerialArray)[serialCount++] = depthStencilTexture->getTextureSerial();
   2185     }
   2186 
   2187     std::sort(outSerialArray->begin(), outSerialArray->begin() + serialCount);
   2188 
   2189     return serialCount;
   2190 }
   2191 
   2192 void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
   2193                               GLbitfield mask, GLenum filter)
   2194 {
   2195     Framebuffer *readFramebuffer = mState.getReadFramebuffer();
   2196     Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
   2197 
   2198     bool blitRenderTarget = false;
   2199     bool blitDepth = false;
   2200     bool blitStencil = false;
   2201     if ((mask & GL_COLOR_BUFFER_BIT) && readFramebuffer->getReadColorbuffer() && drawFramebuffer->getFirstColorbuffer())
   2202     {
   2203         blitRenderTarget = true;
   2204     }
   2205     if ((mask & GL_STENCIL_BUFFER_BIT) && readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
   2206     {
   2207         blitStencil = true;
   2208     }
   2209     if ((mask & GL_DEPTH_BUFFER_BIT) && readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
   2210     {
   2211         blitDepth = true;
   2212     }
   2213 
   2214     Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
   2215     Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
   2216     if (blitRenderTarget || blitDepth || blitStencil)
   2217     {
   2218         const Rectangle *scissor = mState.isScissorTestEnabled() ? &mState.getScissor() : NULL;
   2219         mRenderer->blitRect(readFramebuffer, srcRect, drawFramebuffer, dstRect, scissor,
   2220                             blitRenderTarget, blitDepth, blitStencil, filter);
   2221     }
   2222 }
   2223 
   2224 void Context::releaseShaderCompiler()
   2225 {
   2226     mRenderer->releaseShaderCompiler();
   2227 }
   2228 
   2229 void Context::initCaps(GLuint clientVersion)
   2230 {
   2231     mCaps = mRenderer->getRendererCaps();
   2232 
   2233     mExtensions = mRenderer->getRendererExtensions();
   2234 
   2235     if (clientVersion < 3)
   2236     {
   2237         // Disable ES3+ extensions
   2238         mExtensions.colorBufferFloat = false;
   2239     }
   2240 
   2241     if (clientVersion > 2)
   2242     {
   2243         // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
   2244         //mExtensions.sRGB = false;
   2245     }
   2246 
   2247     // Apply implementation limits
   2248     mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
   2249     mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
   2250     mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
   2251 
   2252     mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
   2253 
   2254     GLuint maxSamples = 0;
   2255     mCaps.compressedTextureFormats.clear();
   2256 
   2257     const TextureCapsMap &rendererFormats = mRenderer->getRendererTextureCaps();
   2258     for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
   2259     {
   2260         GLenum format = i->first;
   2261         TextureCaps formatCaps = i->second;
   2262 
   2263         const InternalFormat &formatInfo = GetInternalFormatInfo(format);
   2264         if (formatCaps.texturable && formatInfo.textureSupport(clientVersion, mExtensions))
   2265         {
   2266             // Update the format caps based on the client version and extensions
   2267             formatCaps.renderable = formatInfo.renderSupport(clientVersion, mExtensions);
   2268             formatCaps.filterable = formatInfo.filterSupport(clientVersion, mExtensions);
   2269 
   2270             // OpenGL ES does not support multisampling with integer formats
   2271             if (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
   2272             {
   2273                 formatCaps.sampleCounts.clear();
   2274             }
   2275             maxSamples = std::max(maxSamples, formatCaps.getMaxSamples());
   2276 
   2277             if (formatInfo.compressed)
   2278             {
   2279                 mCaps.compressedTextureFormats.push_back(format);
   2280             }
   2281 
   2282             mTextureCaps.insert(format, formatCaps);
   2283         }
   2284     }
   2285 
   2286     mExtensions.maxSamples = maxSamples;
   2287 }
   2288 
   2289 }
   2290 
   2291 extern "C"
   2292 {
   2293 gl::Context *glCreateContext(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
   2294 {
   2295     return new gl::Context(clientVersion, shareContext, renderer, notifyResets, robustAccess);
   2296 }
   2297 
   2298 void glDestroyContext(gl::Context *context)
   2299 {
   2300     delete context;
   2301 
   2302     if (context == gl::getContext())
   2303     {
   2304         gl::makeCurrent(NULL, NULL, NULL);
   2305     }
   2306 }
   2307 
   2308 void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface)
   2309 {
   2310     gl::makeCurrent(context, display, surface);
   2311 }
   2312 
   2313 gl::Context *glGetCurrentContext()
   2314 {
   2315     return gl::getContext();
   2316 }
   2317 
   2318 }
   2319