gfx/angle/src/libGLESv2/Context.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 #include "precompiled.h"
     2 //
     3 // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
     4 // Use of this source code is governed by a BSD-style license that can be
     5 // found in the LICENSE file.
     6 //
     8 // Context.cpp: Implements the gl::Context class, managing all GL state and performing
     9 // rendering operations. It is the GLES2 specific implementation of EGLContext.
    11 #include "libGLESv2/Context.h"
    13 #include "libGLESv2/main.h"
    14 #include "libGLESv2/utilities.h"
    15 #include "libGLESv2/Buffer.h"
    16 #include "libGLESv2/Fence.h"
    17 #include "libGLESv2/Framebuffer.h"
    18 #include "libGLESv2/Renderbuffer.h"
    19 #include "libGLESv2/Program.h"
    20 #include "libGLESv2/ProgramBinary.h"
    21 #include "libGLESv2/Query.h"
    22 #include "libGLESv2/Texture.h"
    23 #include "libGLESv2/ResourceManager.h"
    24 #include "libGLESv2/renderer/IndexDataManager.h"
    25 #include "libGLESv2/renderer/RenderTarget.h"
    26 #include "libGLESv2/renderer/Renderer.h"
    28 #include "libEGL/Surface.h"
    30 #undef near
    31 #undef far
    33 namespace gl
    34 {
    35 static const char* makeStaticString(const std::string& str)
    36 {
    37     static std::set<std::string> strings;
    38     std::set<std::string>::iterator it = strings.find(str);
    39     if (it != strings.end())
    40       return it->c_str();
    42     return strings.insert(str).first->c_str();
    43 }
    45 Context::Context(const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) : mRenderer(renderer)
    46 {
    47     ASSERT(robustAccess == false);   // Unimplemented
    49     mFenceHandleAllocator.setBaseHandle(0);
    51     setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    53     mState.depthClearValue = 1.0f;
    54     mState.stencilClearValue = 0;
    56     mState.rasterizer.cullFace = false;
    57     mState.rasterizer.cullMode = GL_BACK;
    58     mState.rasterizer.frontFace = GL_CCW;
    59     mState.rasterizer.polygonOffsetFill = false;
    60     mState.rasterizer.polygonOffsetFactor = 0.0f;
    61     mState.rasterizer.polygonOffsetUnits = 0.0f;
    62     mState.rasterizer.pointDrawMode = false;
    63     mState.rasterizer.multiSample = false;
    64     mState.scissorTest = false;
    65     mState.scissor.x = 0;
    66     mState.scissor.y = 0;
    67     mState.scissor.width = 0;
    68     mState.scissor.height = 0;
    70     mState.blend.blend = false;
    71     mState.blend.sourceBlendRGB = GL_ONE;
    72     mState.blend.sourceBlendAlpha = GL_ONE;
    73     mState.blend.destBlendRGB = GL_ZERO;
    74     mState.blend.destBlendAlpha = GL_ZERO;
    75     mState.blend.blendEquationRGB = GL_FUNC_ADD;
    76     mState.blend.blendEquationAlpha = GL_FUNC_ADD;
    77     mState.blend.sampleAlphaToCoverage = false;
    78     mState.blend.dither = true;
    80     mState.blendColor.red = 0;
    81     mState.blendColor.green = 0;
    82     mState.blendColor.blue = 0;
    83     mState.blendColor.alpha = 0;
    85     mState.depthStencil.depthTest = false;
    86     mState.depthStencil.depthFunc = GL_LESS;
    87     mState.depthStencil.depthMask = true;
    88     mState.depthStencil.stencilTest = false;
    89     mState.depthStencil.stencilFunc = GL_ALWAYS;
    90     mState.depthStencil.stencilMask = -1;
    91     mState.depthStencil.stencilWritemask = -1;
    92     mState.depthStencil.stencilBackFunc = GL_ALWAYS;
    93     mState.depthStencil.stencilBackMask = - 1;
    94     mState.depthStencil.stencilBackWritemask = -1;
    95     mState.depthStencil.stencilFail = GL_KEEP;
    96     mState.depthStencil.stencilPassDepthFail = GL_KEEP;
    97     mState.depthStencil.stencilPassDepthPass = GL_KEEP;
    98     mState.depthStencil.stencilBackFail = GL_KEEP;
    99     mState.depthStencil.stencilBackPassDepthFail = GL_KEEP;
   100     mState.depthStencil.stencilBackPassDepthPass = GL_KEEP;
   102     mState.stencilRef = 0;
   103     mState.stencilBackRef = 0;
   105     mState.sampleCoverage = false;
   106     mState.sampleCoverageValue = 1.0f;
   107     mState.sampleCoverageInvert = false;
   108     mState.generateMipmapHint = GL_DONT_CARE;
   109     mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
   111     mState.lineWidth = 1.0f;
   113     mState.viewport.x = 0;
   114     mState.viewport.y = 0;
   115     mState.viewport.width = 0;
   116     mState.viewport.height = 0;
   117     mState.zNear = 0.0f;
   118     mState.zFar = 1.0f;
   120     mState.blend.colorMaskRed = true;
   121     mState.blend.colorMaskGreen = true;
   122     mState.blend.colorMaskBlue = true;
   123     mState.blend.colorMaskAlpha = true;
   125     if (shareContext != NULL)
   126     {
   127         mResourceManager = shareContext->mResourceManager;
   128         mResourceManager->addRef();
   129     }
   130     else
   131     {
   132         mResourceManager = new ResourceManager(mRenderer);
   133     }
   135     // [OpenGL ES 2.0.24] section 3.7 page 83:
   136     // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
   137     // and cube map texture state vectors respectively associated with them.
   138     // In order that access to these initial textures not be lost, they are treated as texture
   139     // objects all of whose names are 0.
   141     mTexture2DZero.set(new Texture2D(mRenderer, 0));
   142     mTextureCubeMapZero.set(new TextureCubeMap(mRenderer, 0));
   144     mState.activeSampler = 0;
   145     bindArrayBuffer(0);
   146     bindElementArrayBuffer(0);
   147     bindTextureCubeMap(0);
   148     bindTexture2D(0);
   149     bindReadFramebuffer(0);
   150     bindDrawFramebuffer(0);
   151     bindRenderbuffer(0);
   153     mState.currentProgram = 0;
   154     mCurrentProgramBinary.set(NULL);
   156     mState.packAlignment = 4;
   157     mState.unpackAlignment = 4;
   158     mState.packReverseRowOrder = false;
   160     mExtensionString = NULL;
   161     mRendererString = NULL;
   163     mInvalidEnum = false;
   164     mInvalidValue = false;
   165     mInvalidOperation = false;
   166     mOutOfMemory = false;
   167     mInvalidFramebufferOperation = false;
   169     mHasBeenCurrent = false;
   170     mContextLost = false;
   171     mResetStatus = GL_NO_ERROR;
   172     mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
   173     mRobustAccess = robustAccess;
   175     mSupportsBGRATextures = false;
   176     mSupportsDXT1Textures = false;
   177     mSupportsDXT3Textures = false;
   178     mSupportsDXT5Textures = false;
   179     mSupportsEventQueries = false;
   180     mSupportsOcclusionQueries = false;
   181     mNumCompressedTextureFormats = 0;
   182 }
   184 Context::~Context()
   185 {
   186     if (mState.currentProgram != 0)
   187     {
   188         Program *programObject = mResourceManager->getProgram(mState.currentProgram);
   189         if (programObject)
   190         {
   191             programObject->release();
   192         }
   193         mState.currentProgram = 0;
   194     }
   195     mCurrentProgramBinary.set(NULL);
   197     while (!mFramebufferMap.empty())
   198     {
   199         deleteFramebuffer(mFramebufferMap.begin()->first);
   200     }
   202     while (!mFenceMap.empty())
   203     {
   204         deleteFence(mFenceMap.begin()->first);
   205     }
   207     while (!mQueryMap.empty())
   208     {
   209         deleteQuery(mQueryMap.begin()->first);
   210     }
   212     for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
   213     {
   214         for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
   215         {
   216             mState.samplerTexture[type][sampler].set(NULL);
   217         }
   218     }
   220     for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
   221     {
   222         mIncompleteTextures[type].set(NULL);
   223     }
   225     for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
   226     {
   227         mState.vertexAttribute[i].mBoundBuffer.set(NULL);
   228     }
   230     for (int i = 0; i < QUERY_TYPE_COUNT; i++)
   231     {
   232         mState.activeQuery[i].set(NULL);
   233     }
   235     mState.arrayBuffer.set(NULL);
   236     mState.elementArrayBuffer.set(NULL);
   237     mState.renderbuffer.set(NULL);
   239     mTexture2DZero.set(NULL);
   240     mTextureCubeMapZero.set(NULL);
   242     mResourceManager->release();
   243 }
   245 void Context::makeCurrent(egl::Surface *surface)
   246 {
   247     if (!mHasBeenCurrent)
   248     {
   249         mMajorShaderModel = mRenderer->getMajorShaderModel();
   250         mMaximumPointSize = mRenderer->getMaxPointSize();
   251         mSupportsVertexTexture = mRenderer->getVertexTextureSupport();
   252         mSupportsNonPower2Texture = mRenderer->getNonPower2TextureSupport();
   253         mSupportsInstancing = mRenderer->getInstancingSupport();
   255         mMaxViewportDimension = mRenderer->getMaxViewportDimension();
   256         mMaxTextureDimension = std::min(std::min(mRenderer->getMaxTextureWidth(), mRenderer->getMaxTextureHeight()),
   257                                         (int)gl::IMPLEMENTATION_MAX_TEXTURE_SIZE);
   258         mMaxCubeTextureDimension = std::min(mMaxTextureDimension, (int)gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE);
   259         mMaxRenderbufferDimension = mMaxTextureDimension;
   260         mMaxTextureLevel = log2(mMaxTextureDimension) + 1;
   261         mMaxTextureAnisotropy = mRenderer->getTextureMaxAnisotropy();
   262         TRACE("MaxTextureDimension=%d, MaxCubeTextureDimension=%d, MaxRenderbufferDimension=%d, MaxTextureLevel=%d, MaxTextureAnisotropy=%f",
   263               mMaxTextureDimension, mMaxCubeTextureDimension, mMaxRenderbufferDimension, mMaxTextureLevel, mMaxTextureAnisotropy);
   265         mSupportsEventQueries = mRenderer->getEventQuerySupport();
   266         mSupportsOcclusionQueries = mRenderer->getOcclusionQuerySupport();
   267         mSupportsBGRATextures = mRenderer->getBGRATextureSupport();
   268         mSupportsDXT1Textures = mRenderer->getDXT1TextureSupport();
   269         mSupportsDXT3Textures = mRenderer->getDXT3TextureSupport();
   270         mSupportsDXT5Textures = mRenderer->getDXT5TextureSupport();
   271         mSupportsFloat32Textures = mRenderer->getFloat32TextureSupport(&mSupportsFloat32LinearFilter, &mSupportsFloat32RenderableTextures);
   272         mSupportsFloat16Textures = mRenderer->getFloat16TextureSupport(&mSupportsFloat16LinearFilter, &mSupportsFloat16RenderableTextures);
   273         mSupportsLuminanceTextures = mRenderer->getLuminanceTextureSupport();
   274         mSupportsLuminanceAlphaTextures = mRenderer->getLuminanceAlphaTextureSupport();
   275         mSupportsDepthTextures = mRenderer->getDepthTextureSupport();
   276         mSupportsTextureFilterAnisotropy = mRenderer->getTextureFilterAnisotropySupport();
   277         mSupports32bitIndices = mRenderer->get32BitIndexSupport();
   279         mNumCompressedTextureFormats = 0;
   280         if (supportsDXT1Textures())
   281         {
   282             mNumCompressedTextureFormats += 2;
   283         }
   284         if (supportsDXT3Textures())
   285         {
   286             mNumCompressedTextureFormats += 1;
   287         }
   288         if (supportsDXT5Textures())
   289         {
   290             mNumCompressedTextureFormats += 1;
   291         }
   293         initExtensionString();
   294         initRendererString();
   296         mState.viewport.x = 0;
   297         mState.viewport.y = 0;
   298         mState.viewport.width = surface->getWidth();
   299         mState.viewport.height = surface->getHeight();
   301         mState.scissor.x = 0;
   302         mState.scissor.y = 0;
   303         mState.scissor.width = surface->getWidth();
   304         mState.scissor.height = surface->getHeight();
   306         mHasBeenCurrent = true;
   307     }
   309     // Wrap the existing swapchain resources into GL objects and assign them to the '0' names
   310     rx::SwapChain *swapchain = surface->getSwapChain();
   312     Colorbuffer *colorbufferZero = new Colorbuffer(mRenderer, swapchain);
   313     DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(mRenderer, swapchain);
   314     Framebuffer *framebufferZero = new DefaultFramebuffer(mRenderer, colorbufferZero, depthStencilbufferZero);
   316     setFramebufferZero(framebufferZero);
   317 }
   319 // NOTE: this function should not assume that this context is current!
   320 void Context::markContextLost()
   321 {
   322     if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
   323         mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
   324     mContextLost = true;
   325 }
   327 bool Context::isContextLost()
   328 {
   329     return mContextLost;
   330 }
   332 void Context::setClearColor(float red, float green, float blue, float alpha)
   333 {
   334     mState.colorClearValue.red = red;
   335     mState.colorClearValue.green = green;
   336     mState.colorClearValue.blue = blue;
   337     mState.colorClearValue.alpha = alpha;
   338 }
   340 void Context::setClearDepth(float depth)
   341 {
   342     mState.depthClearValue = depth;
   343 }
   345 void Context::setClearStencil(int stencil)
   346 {
   347     mState.stencilClearValue = stencil;
   348 }
   350 void Context::setCullFace(bool enabled)
   351 {
   352     mState.rasterizer.cullFace = enabled;
   353 }
   355 bool Context::isCullFaceEnabled() const
   356 {
   357     return mState.rasterizer.cullFace;
   358 }
   360 void Context::setCullMode(GLenum mode)
   361 {
   362     mState.rasterizer.cullMode = mode;
   363 }
   365 void Context::setFrontFace(GLenum front)
   366 {
   367     mState.rasterizer.frontFace = front;
   368 }
   370 void Context::setDepthTest(bool enabled)
   371 {
   372     mState.depthStencil.depthTest = enabled;
   373 }
   375 bool Context::isDepthTestEnabled() const
   376 {
   377     return mState.depthStencil.depthTest;
   378 }
   380 void Context::setDepthFunc(GLenum depthFunc)
   381 {
   382      mState.depthStencil.depthFunc = depthFunc;
   383 }
   385 void Context::setDepthRange(float zNear, float zFar)
   386 {
   387     mState.zNear = zNear;
   388     mState.zFar = zFar;
   389 }
   391 void Context::setBlend(bool enabled)
   392 {
   393     mState.blend.blend = enabled;
   394 }
   396 bool Context::isBlendEnabled() const
   397 {
   398     return mState.blend.blend;
   399 }
   401 void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
   402 {
   403     mState.blend.sourceBlendRGB = sourceRGB;
   404     mState.blend.destBlendRGB = destRGB;
   405     mState.blend.sourceBlendAlpha = sourceAlpha;
   406     mState.blend.destBlendAlpha = destAlpha;
   407 }
   409 void Context::setBlendColor(float red, float green, float blue, float alpha)
   410 {
   411     mState.blendColor.red = red;
   412     mState.blendColor.green = green;
   413     mState.blendColor.blue = blue;
   414     mState.blendColor.alpha = alpha;
   415 }
   417 void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
   418 {
   419     mState.blend.blendEquationRGB = rgbEquation;
   420     mState.blend.blendEquationAlpha = alphaEquation;
   421 }
   423 void Context::setStencilTest(bool enabled)
   424 {
   425     mState.depthStencil.stencilTest = enabled;
   426 }
   428 bool Context::isStencilTestEnabled() const
   429 {
   430     return mState.depthStencil.stencilTest;
   431 }
   433 void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
   434 {
   435     mState.depthStencil.stencilFunc = stencilFunc;
   436     mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
   437     mState.depthStencil.stencilMask = stencilMask;
   438 }
   440 void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
   441 {
   442     mState.depthStencil.stencilBackFunc = stencilBackFunc;
   443     mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
   444     mState.depthStencil.stencilBackMask = stencilBackMask;
   445 }
   447 void Context::setStencilWritemask(GLuint stencilWritemask)
   448 {
   449     mState.depthStencil.stencilWritemask = stencilWritemask;
   450 }
   452 void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
   453 {
   454     mState.depthStencil.stencilBackWritemask = stencilBackWritemask;
   455 }
   457 void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
   458 {
   459     mState.depthStencil.stencilFail = stencilFail;
   460     mState.depthStencil.stencilPassDepthFail = stencilPassDepthFail;
   461     mState.depthStencil.stencilPassDepthPass = stencilPassDepthPass;
   462 }
   464 void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
   465 {
   466     mState.depthStencil.stencilBackFail = stencilBackFail;
   467     mState.depthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
   468     mState.depthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
   469 }
   471 void Context::setPolygonOffsetFill(bool enabled)
   472 {
   473      mState.rasterizer.polygonOffsetFill = enabled;
   474 }
   476 bool Context::isPolygonOffsetFillEnabled() const
   477 {
   478     return mState.rasterizer.polygonOffsetFill;
   479 }
   481 void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
   482 {
   483     // An application can pass NaN values here, so handle this gracefully
   484     mState.rasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
   485     mState.rasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
   486 }
   488 void Context::setSampleAlphaToCoverage(bool enabled)
   489 {
   490     mState.blend.sampleAlphaToCoverage = enabled;
   491 }
   493 bool Context::isSampleAlphaToCoverageEnabled() const
   494 {
   495     return mState.blend.sampleAlphaToCoverage;
   496 }
   498 void Context::setSampleCoverage(bool enabled)
   499 {
   500     mState.sampleCoverage = enabled;
   501 }
   503 bool Context::isSampleCoverageEnabled() const
   504 {
   505     return mState.sampleCoverage;
   506 }
   508 void Context::setSampleCoverageParams(GLclampf value, bool invert)
   509 {
   510     mState.sampleCoverageValue = value;
   511     mState.sampleCoverageInvert = invert;
   512 }
   514 void Context::setScissorTest(bool enabled)
   515 {
   516     mState.scissorTest = enabled;
   517 }
   519 bool Context::isScissorTestEnabled() const
   520 {
   521     return mState.scissorTest;
   522 }
   524 void Context::setDither(bool enabled)
   525 {
   526     mState.blend.dither = enabled;
   527 }
   529 bool Context::isDitherEnabled() const
   530 {
   531     return mState.blend.dither;
   532 }
   534 void Context::setLineWidth(GLfloat width)
   535 {
   536     mState.lineWidth = width;
   537 }
   539 void Context::setGenerateMipmapHint(GLenum hint)
   540 {
   541     mState.generateMipmapHint = hint;
   542 }
   544 void Context::setFragmentShaderDerivativeHint(GLenum hint)
   545 {
   546     mState.fragmentShaderDerivativeHint = hint;
   547     // TODO: Propagate the hint to shader translator so we can write
   548     // ddx, ddx_coarse, or ddx_fine depending on the hint.
   549     // Ignore for now. It is valid for implementations to ignore hint.
   550 }
   552 void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
   553 {
   554     mState.viewport.x = x;
   555     mState.viewport.y = y;
   556     mState.viewport.width = width;
   557     mState.viewport.height = height;
   558 }
   560 void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
   561 {
   562     mState.scissor.x = x;
   563     mState.scissor.y = y;
   564     mState.scissor.width = width;
   565     mState.scissor.height = height;
   566 }
   568 void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
   569 {
   570     mState.blend.colorMaskRed = red;
   571     mState.blend.colorMaskGreen = green;
   572     mState.blend.colorMaskBlue = blue;
   573     mState.blend.colorMaskAlpha = alpha;
   574 }
   576 void Context::setDepthMask(bool mask)
   577 {
   578     mState.depthStencil.depthMask = mask;
   579 }
   581 void Context::setActiveSampler(unsigned int active)
   582 {
   583     mState.activeSampler = active;
   584 }
   586 GLuint Context::getReadFramebufferHandle() const
   587 {
   588     return mState.readFramebuffer;
   589 }
   591 GLuint Context::getDrawFramebufferHandle() const
   592 {
   593     return mState.drawFramebuffer;
   594 }
   596 GLuint Context::getRenderbufferHandle() const
   597 {
   598     return mState.renderbuffer.id();
   599 }
   601 GLuint Context::getArrayBufferHandle() const
   602 {
   603     return mState.arrayBuffer.id();
   604 }
   606 GLuint Context::getActiveQuery(GLenum target) const
   607 {
   608     Query *queryObject = NULL;
   610     switch (target)
   611     {
   612       case GL_ANY_SAMPLES_PASSED_EXT:
   613         queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED].get();
   614         break;
   615       case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
   616         queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE].get();
   617         break;
   618       default:
   619         ASSERT(false);
   620     }
   622     if (queryObject)
   623     {
   624         return queryObject->id();
   625     }
   626     else
   627     {
   628         return 0;
   629     }
   630 }
   632 void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
   633 {
   634     mState.vertexAttribute[attribNum].mArrayEnabled = enabled;
   635 }
   637 const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
   638 {
   639     return mState.vertexAttribute[attribNum];
   640 }
   642 void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
   643                                    GLsizei stride, const void *pointer)
   644 {
   645     mState.vertexAttribute[attribNum].mBoundBuffer.set(boundBuffer);
   646     mState.vertexAttribute[attribNum].mSize = size;
   647     mState.vertexAttribute[attribNum].mType = type;
   648     mState.vertexAttribute[attribNum].mNormalized = normalized;
   649     mState.vertexAttribute[attribNum].mStride = stride;
   650     mState.vertexAttribute[attribNum].mPointer = pointer;
   651 }
   653 const void *Context::getVertexAttribPointer(unsigned int attribNum) const
   654 {
   655     return mState.vertexAttribute[attribNum].mPointer;
   656 }
   658 void Context::setPackAlignment(GLint alignment)
   659 {
   660     mState.packAlignment = alignment;
   661 }
   663 GLint Context::getPackAlignment() const
   664 {
   665     return mState.packAlignment;
   666 }
   668 void Context::setUnpackAlignment(GLint alignment)
   669 {
   670     mState.unpackAlignment = alignment;
   671 }
   673 GLint Context::getUnpackAlignment() const
   674 {
   675     return mState.unpackAlignment;
   676 }
   678 void Context::setPackReverseRowOrder(bool reverseRowOrder)
   679 {
   680     mState.packReverseRowOrder = reverseRowOrder;
   681 }
   683 bool Context::getPackReverseRowOrder() const
   684 {
   685     return mState.packReverseRowOrder;
   686 }
   688 GLuint Context::createBuffer()
   689 {
   690     return mResourceManager->createBuffer();
   691 }
   693 GLuint Context::createProgram()
   694 {
   695     return mResourceManager->createProgram();
   696 }
   698 GLuint Context::createShader(GLenum type)
   699 {
   700     return mResourceManager->createShader(type);
   701 }
   703 GLuint Context::createTexture()
   704 {
   705     return mResourceManager->createTexture();
   706 }
   708 GLuint Context::createRenderbuffer()
   709 {
   710     return mResourceManager->createRenderbuffer();
   711 }
   713 // Returns an unused framebuffer name
   714 GLuint Context::createFramebuffer()
   715 {
   716     GLuint handle = mFramebufferHandleAllocator.allocate();
   718     mFramebufferMap[handle] = NULL;
   720     return handle;
   721 }
   723 GLuint Context::createFence()
   724 {
   725     GLuint handle = mFenceHandleAllocator.allocate();
   727     mFenceMap[handle] = new Fence(mRenderer);
   729     return handle;
   730 }
   732 // Returns an unused query name
   733 GLuint Context::createQuery()
   734 {
   735     GLuint handle = mQueryHandleAllocator.allocate();
   737     mQueryMap[handle] = NULL;
   739     return handle;
   740 }
   742 void Context::deleteBuffer(GLuint buffer)
   743 {
   744     if (mResourceManager->getBuffer(buffer))
   745     {
   746         detachBuffer(buffer);
   747     }
   749     mResourceManager->deleteBuffer(buffer);
   750 }
   752 void Context::deleteShader(GLuint shader)
   753 {
   754     mResourceManager->deleteShader(shader);
   755 }
   757 void Context::deleteProgram(GLuint program)
   758 {
   759     mResourceManager->deleteProgram(program);
   760 }
   762 void Context::deleteTexture(GLuint texture)
   763 {
   764     if (mResourceManager->getTexture(texture))
   765     {
   766         detachTexture(texture);
   767     }
   769     mResourceManager->deleteTexture(texture);
   770 }
   772 void Context::deleteRenderbuffer(GLuint renderbuffer)
   773 {
   774     if (mResourceManager->getRenderbuffer(renderbuffer))
   775     {
   776         detachRenderbuffer(renderbuffer);
   777     }
   779     mResourceManager->deleteRenderbuffer(renderbuffer);
   780 }
   782 void Context::deleteFramebuffer(GLuint framebuffer)
   783 {
   784     FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
   786     if (framebufferObject != mFramebufferMap.end())
   787     {
   788         detachFramebuffer(framebuffer);
   790         mFramebufferHandleAllocator.release(framebufferObject->first);
   791         delete framebufferObject->second;
   792         mFramebufferMap.erase(framebufferObject);
   793     }
   794 }
   796 void Context::deleteFence(GLuint fence)
   797 {
   798     FenceMap::iterator fenceObject = mFenceMap.find(fence);
   800     if (fenceObject != mFenceMap.end())
   801     {
   802         mFenceHandleAllocator.release(fenceObject->first);
   803         delete fenceObject->second;
   804         mFenceMap.erase(fenceObject);
   805     }
   806 }
   808 void Context::deleteQuery(GLuint query)
   809 {
   810     QueryMap::iterator queryObject = mQueryMap.find(query);
   811     if (queryObject != mQueryMap.end())
   812     {
   813         mQueryHandleAllocator.release(queryObject->first);
   814         if (queryObject->second)
   815         {
   816             queryObject->second->release();
   817         }
   818         mQueryMap.erase(queryObject);
   819     }
   820 }
   822 Buffer *Context::getBuffer(GLuint handle)
   823 {
   824     return mResourceManager->getBuffer(handle);
   825 }
   827 Shader *Context::getShader(GLuint handle)
   828 {
   829     return mResourceManager->getShader(handle);
   830 }
   832 Program *Context::getProgram(GLuint handle)
   833 {
   834     return mResourceManager->getProgram(handle);
   835 }
   837 Texture *Context::getTexture(GLuint handle)
   838 {
   839     return mResourceManager->getTexture(handle);
   840 }
   842 Renderbuffer *Context::getRenderbuffer(GLuint handle)
   843 {
   844     return mResourceManager->getRenderbuffer(handle);
   845 }
   847 Framebuffer *Context::getReadFramebuffer()
   848 {
   849     return getFramebuffer(mState.readFramebuffer);
   850 }
   852 Framebuffer *Context::getDrawFramebuffer()
   853 {
   854     return mBoundDrawFramebuffer;
   855 }
   857 void Context::bindArrayBuffer(unsigned int buffer)
   858 {
   859     mResourceManager->checkBufferAllocation(buffer);
   861     mState.arrayBuffer.set(getBuffer(buffer));
   862 }
   864 void Context::bindElementArrayBuffer(unsigned int buffer)
   865 {
   866     mResourceManager->checkBufferAllocation(buffer);
   868     mState.elementArrayBuffer.set(getBuffer(buffer));
   869 }
   871 void Context::bindTexture2D(GLuint texture)
   872 {
   873     mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
   875     mState.samplerTexture[TEXTURE_2D][mState.activeSampler].set(getTexture(texture));
   876 }
   878 void Context::bindTextureCubeMap(GLuint texture)
   879 {
   880     mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
   882     mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].set(getTexture(texture));
   883 }
   885 void Context::bindReadFramebuffer(GLuint framebuffer)
   886 {
   887     if (!getFramebuffer(framebuffer))
   888     {
   889         mFramebufferMap[framebuffer] = new Framebuffer(mRenderer);
   890     }
   892     mState.readFramebuffer = framebuffer;
   893 }
   895 void Context::bindDrawFramebuffer(GLuint framebuffer)
   896 {
   897     if (!getFramebuffer(framebuffer))
   898     {
   899         mFramebufferMap[framebuffer] = new Framebuffer(mRenderer);
   900     }
   902     mState.drawFramebuffer = framebuffer;
   904     mBoundDrawFramebuffer = getFramebuffer(framebuffer);
   905 }
   907 void Context::bindRenderbuffer(GLuint renderbuffer)
   908 {
   909     mResourceManager->checkRenderbufferAllocation(renderbuffer);
   911     mState.renderbuffer.set(getRenderbuffer(renderbuffer));
   912 }
   914 void Context::useProgram(GLuint program)
   915 {
   916     GLuint priorProgram = mState.currentProgram;
   917     mState.currentProgram = program;               // Must switch before trying to delete, otherwise it only gets flagged.
   919     if (priorProgram != program)
   920     {
   921         Program *newProgram = mResourceManager->getProgram(program);
   922         Program *oldProgram = mResourceManager->getProgram(priorProgram);
   923         mCurrentProgramBinary.set(NULL);
   925         if (newProgram)
   926         {
   927             newProgram->addRef();
   928             mCurrentProgramBinary.set(newProgram->getProgramBinary());
   929         }
   931         if (oldProgram)
   932         {
   933             oldProgram->release();
   934         }
   935     }
   936 }
   938 void Context::linkProgram(GLuint program)
   939 {
   940     Program *programObject = mResourceManager->getProgram(program);
   942     bool linked = programObject->link();
   944     // if the current program was relinked successfully we
   945     // need to install the new executables
   946     if (linked && program == mState.currentProgram)
   947     {
   948         mCurrentProgramBinary.set(programObject->getProgramBinary());
   949     }
   950 }
   952 void Context::setProgramBinary(GLuint program, const void *binary, GLint length)
   953 {
   954     Program *programObject = mResourceManager->getProgram(program);
   956     bool loaded = programObject->setProgramBinary(binary, length);
   958     // if the current program was reloaded successfully we
   959     // need to install the new executables
   960     if (loaded && program == mState.currentProgram)
   961     {
   962         mCurrentProgramBinary.set(programObject->getProgramBinary());
   963     }
   965 }
   967 void Context::beginQuery(GLenum target, GLuint query)
   968 {
   969     // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>  
   970     // of zero, if the active query object name for <target> is non-zero (for the  
   971     // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if  
   972     // the active query for either target is non-zero), if <id> is the name of an 
   973     // existing query object whose type does not match <target>, or if <id> is the
   974     // active query object name for any query type, the error INVALID_OPERATION is
   975     // generated.
   977     // Ensure no other queries are active
   978     // NOTE: If other queries than occlusion are supported, we will need to check
   979     // separately that:
   980     //    a) The query ID passed is not the current active query for any target/type
   981     //    b) There are no active queries for the requested target (and in the case
   982     //       of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
   983     //       no query may be active for either if glBeginQuery targets either.
   984     for (int i = 0; i < QUERY_TYPE_COUNT; i++)
   985     {
   986         if (mState.activeQuery[i].get() != NULL)
   987         {
   988             return gl::error(GL_INVALID_OPERATION);
   989         }
   990     }
   992     QueryType qType;
   993     switch (target)
   994     {
   995       case GL_ANY_SAMPLES_PASSED_EXT: 
   996         qType = QUERY_ANY_SAMPLES_PASSED; 
   997         break;
   998       case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: 
   999         qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE; 
  1000         break;
  1001       default: 
  1002         ASSERT(false);
  1003         return;
  1006     Query *queryObject = getQuery(query, true, target);
  1008     // check that name was obtained with glGenQueries
  1009     if (!queryObject)
  1011         return gl::error(GL_INVALID_OPERATION);
  1014     // check for type mismatch
  1015     if (queryObject->getType() != target)
  1017         return gl::error(GL_INVALID_OPERATION);
  1020     // set query as active for specified target
  1021     mState.activeQuery[qType].set(queryObject);
  1023     // begin query
  1024     queryObject->begin();
  1027 void Context::endQuery(GLenum target)
  1029     QueryType qType;
  1031     switch (target)
  1033       case GL_ANY_SAMPLES_PASSED_EXT: 
  1034         qType = QUERY_ANY_SAMPLES_PASSED; 
  1035         break;
  1036       case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: 
  1037         qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE; 
  1038         break;
  1039       default: 
  1040         ASSERT(false);
  1041         return;
  1044     Query *queryObject = mState.activeQuery[qType].get();
  1046     if (queryObject == NULL)
  1048         return gl::error(GL_INVALID_OPERATION);
  1051     queryObject->end();
  1053     mState.activeQuery[qType].set(NULL);
  1056 void Context::setFramebufferZero(Framebuffer *buffer)
  1058     delete mFramebufferMap[0];
  1059     mFramebufferMap[0] = buffer;
  1060     if (mState.drawFramebuffer == 0)
  1062         mBoundDrawFramebuffer = buffer;
  1066 void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
  1068     RenderbufferStorage *renderbuffer = NULL;
  1069     switch (internalformat)
  1071       case GL_DEPTH_COMPONENT16:
  1072         renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples);
  1073         break;
  1074       case GL_RGBA4:
  1075       case GL_RGB5_A1:
  1076       case GL_RGB565:
  1077       case GL_RGB8_OES:
  1078       case GL_RGBA8_OES:
  1079         renderbuffer = new gl::Colorbuffer(mRenderer,width, height, internalformat, samples);
  1080         break;
  1081       case GL_STENCIL_INDEX8:
  1082         renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples);
  1083         break;
  1084       case GL_DEPTH24_STENCIL8_OES:
  1085         renderbuffer = new gl::DepthStencilbuffer(mRenderer, width, height, samples);
  1086         break;
  1087       default:
  1088         UNREACHABLE(); return;
  1091     Renderbuffer *renderbufferObject = mState.renderbuffer.get();
  1092     renderbufferObject->setStorage(renderbuffer);
  1095 Framebuffer *Context::getFramebuffer(unsigned int handle)
  1097     FramebufferMap::iterator framebuffer = mFramebufferMap.find(handle);
  1099     if (framebuffer == mFramebufferMap.end())
  1101         return NULL;
  1103     else
  1105         return framebuffer->second;
  1109 Fence *Context::getFence(unsigned int handle)
  1111     FenceMap::iterator fence = mFenceMap.find(handle);
  1113     if (fence == mFenceMap.end())
  1115         return NULL;
  1117     else
  1119         return fence->second;
  1123 Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
  1125     QueryMap::iterator query = mQueryMap.find(handle);
  1127     if (query == mQueryMap.end())
  1129         return NULL;
  1131     else
  1133         if (!query->second && create)
  1135             query->second = new Query(mRenderer, type, handle);
  1136             query->second->addRef();
  1138         return query->second;
  1142 Buffer *Context::getArrayBuffer()
  1144     return mState.arrayBuffer.get();
  1147 Buffer *Context::getElementArrayBuffer()
  1149     return mState.elementArrayBuffer.get();
  1152 ProgramBinary *Context::getCurrentProgramBinary()
  1154     return mCurrentProgramBinary.get();
  1157 Texture2D *Context::getTexture2D()
  1159     return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
  1162 TextureCubeMap *Context::getTextureCubeMap()
  1164     return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
  1167 Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)
  1169     GLuint texid = mState.samplerTexture[type][sampler].id();
  1171     if (texid == 0)   // Special case: 0 refers to different initial textures based on the target
  1173         switch (type)
  1175           default: UNREACHABLE();
  1176           case TEXTURE_2D: return mTexture2DZero.get();
  1177           case TEXTURE_CUBE: return mTextureCubeMapZero.get();
  1181     return mState.samplerTexture[type][sampler].get();
  1184 bool Context::getBooleanv(GLenum pname, GLboolean *params)
  1186     switch (pname)
  1188       case GL_SHADER_COMPILER:           *params = GL_TRUE;                             break;
  1189       case GL_SAMPLE_COVERAGE_INVERT:    *params = mState.sampleCoverageInvert;         break;
  1190       case GL_DEPTH_WRITEMASK:           *params = mState.depthStencil.depthMask;       break;
  1191       case GL_COLOR_WRITEMASK:
  1192         params[0] = mState.blend.colorMaskRed;
  1193         params[1] = mState.blend.colorMaskGreen;
  1194         params[2] = mState.blend.colorMaskBlue;
  1195         params[3] = mState.blend.colorMaskAlpha;
  1196         break;
  1197       case GL_CULL_FACE:                 *params = mState.rasterizer.cullFace;          break;
  1198       case GL_POLYGON_OFFSET_FILL:       *params = mState.rasterizer.polygonOffsetFill; break;
  1199       case GL_SAMPLE_ALPHA_TO_COVERAGE:  *params = mState.blend.sampleAlphaToCoverage;  break;
  1200       case GL_SAMPLE_COVERAGE:           *params = mState.sampleCoverage;               break;
  1201       case GL_SCISSOR_TEST:              *params = mState.scissorTest;                  break;
  1202       case GL_STENCIL_TEST:              *params = mState.depthStencil.stencilTest;     break;
  1203       case GL_DEPTH_TEST:                *params = mState.depthStencil.depthTest;       break;
  1204       case GL_BLEND:                     *params = mState.blend.blend;                  break;
  1205       case GL_DITHER:                    *params = mState.blend.dither;                 break;
  1206       case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE;  break;
  1207       default:
  1208         return false;
  1211     return true;
  1214 bool Context::getFloatv(GLenum pname, GLfloat *params)
  1216     // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
  1217     // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
  1218     // GetIntegerv as its native query function. As it would require conversion in any
  1219     // case, this should make no difference to the calling application.
  1220     switch (pname)
  1222       case GL_LINE_WIDTH:               *params = mState.lineWidth;                         break;
  1223       case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;               break;
  1224       case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;                   break;
  1225       case GL_POLYGON_OFFSET_FACTOR:    *params = mState.rasterizer.polygonOffsetFactor;    break;
  1226       case GL_POLYGON_OFFSET_UNITS:     *params = mState.rasterizer.polygonOffsetUnits;     break;
  1227       case GL_ALIASED_LINE_WIDTH_RANGE:
  1228         params[0] = gl::ALIASED_LINE_WIDTH_RANGE_MIN;
  1229         params[1] = gl::ALIASED_LINE_WIDTH_RANGE_MAX;
  1230         break;
  1231       case GL_ALIASED_POINT_SIZE_RANGE:
  1232         params[0] = gl::ALIASED_POINT_SIZE_RANGE_MIN;
  1233         params[1] = getMaximumPointSize();
  1234         break;
  1235       case GL_DEPTH_RANGE:
  1236         params[0] = mState.zNear;
  1237         params[1] = mState.zFar;
  1238         break;
  1239       case GL_COLOR_CLEAR_VALUE:
  1240         params[0] = mState.colorClearValue.red;
  1241         params[1] = mState.colorClearValue.green;
  1242         params[2] = mState.colorClearValue.blue;
  1243         params[3] = mState.colorClearValue.alpha;
  1244         break;
  1245       case GL_BLEND_COLOR:
  1246         params[0] = mState.blendColor.red;
  1247         params[1] = mState.blendColor.green;
  1248         params[2] = mState.blendColor.blue;
  1249         params[3] = mState.blendColor.alpha;
  1250         break;
  1251       case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
  1252         if (!supportsTextureFilterAnisotropy())
  1254             return false;
  1256         *params = mMaxTextureAnisotropy;
  1257         break;
  1258       default:
  1259         return false;
  1262     return true;
  1265 bool Context::getIntegerv(GLenum pname, GLint *params)
  1267     if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
  1269         unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
  1271         if (colorAttachment >= mRenderer->getMaxRenderTargets())
  1273             // return true to stop further operation in the parent call
  1274             return gl::error(GL_INVALID_OPERATION, true);
  1277         Framebuffer *framebuffer = getDrawFramebuffer();
  1279         *params = framebuffer->getDrawBufferState(colorAttachment);
  1280         return true;
  1283     // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
  1284     // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
  1285     // GetIntegerv as its native query function. As it would require conversion in any
  1286     // case, this should make no difference to the calling application. You may find it in 
  1287     // Context::getFloatv.
  1288     switch (pname)
  1290       case GL_MAX_VERTEX_ATTRIBS:               *params = gl::MAX_VERTEX_ATTRIBS;               break;
  1291       case GL_MAX_VERTEX_UNIFORM_VECTORS:       *params = mRenderer->getMaxVertexUniformVectors(); break;
  1292       case GL_MAX_VARYING_VECTORS:              *params = mRenderer->getMaxVaryingVectors();    break;
  1293       case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mRenderer->getMaxCombinedTextureImageUnits(); break;
  1294       case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = mRenderer->getMaxVertexTextureImageUnits(); break;
  1295       case GL_MAX_TEXTURE_IMAGE_UNITS:          *params = gl::MAX_TEXTURE_IMAGE_UNITS;          break;
  1296       case GL_MAX_FRAGMENT_UNIFORM_VECTORS:     *params = mRenderer->getMaxFragmentUniformVectors(); break;
  1297       case GL_MAX_RENDERBUFFER_SIZE:            *params = getMaximumRenderbufferDimension();    break;
  1298       case GL_MAX_COLOR_ATTACHMENTS_EXT:        *params = mRenderer->getMaxRenderTargets();     break;
  1299       case GL_MAX_DRAW_BUFFERS_EXT:             *params = mRenderer->getMaxRenderTargets();     break;
  1300       case GL_NUM_SHADER_BINARY_FORMATS:        *params = 0;                                    break;
  1301       case GL_SHADER_BINARY_FORMATS:      /* no shader binary formats are supported */          break;
  1302       case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer.id();              break;
  1303       case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer.id();       break;
  1304       //case GL_FRAMEBUFFER_BINDING:            // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
  1305       case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:   *params = mState.drawFramebuffer;               break;
  1306       case GL_READ_FRAMEBUFFER_BINDING_ANGLE:   *params = mState.readFramebuffer;               break;
  1307       case GL_RENDERBUFFER_BINDING:             *params = mState.renderbuffer.id();             break;
  1308       case GL_CURRENT_PROGRAM:                  *params = mState.currentProgram;                break;
  1309       case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;
  1310       case GL_PACK_REVERSE_ROW_ORDER_ANGLE:     *params = mState.packReverseRowOrder;           break;
  1311       case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackAlignment;               break;
  1312       case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;
  1313       case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; break;
  1314       case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;
  1315       case GL_STENCIL_FUNC:                     *params = mState.depthStencil.stencilFunc;             break;
  1316       case GL_STENCIL_REF:                      *params = mState.stencilRef;                           break;
  1317       case GL_STENCIL_VALUE_MASK:               *params = mState.depthStencil.stencilMask;             break;
  1318       case GL_STENCIL_BACK_FUNC:                *params = mState.depthStencil.stencilBackFunc;         break;
  1319       case GL_STENCIL_BACK_REF:                 *params = mState.stencilBackRef;                       break;
  1320       case GL_STENCIL_BACK_VALUE_MASK:          *params = mState.depthStencil.stencilBackMask;         break;
  1321       case GL_STENCIL_FAIL:                     *params = mState.depthStencil.stencilFail;             break;
  1322       case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.depthStencil.stencilPassDepthFail;    break;
  1323       case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.depthStencil.stencilPassDepthPass;    break;
  1324       case GL_STENCIL_BACK_FAIL:                *params = mState.depthStencil.stencilBackFail;         break;
  1325       case GL_STENCIL_BACK_PASS_DEPTH_FAIL:     *params = mState.depthStencil.stencilBackPassDepthFail; break;
  1326       case GL_STENCIL_BACK_PASS_DEPTH_PASS:     *params = mState.depthStencil.stencilBackPassDepthPass; break;
  1327       case GL_DEPTH_FUNC:                       *params = mState.depthStencil.depthFunc;               break;
  1328       case GL_BLEND_SRC_RGB:                    *params = mState.blend.sourceBlendRGB;                 break;
  1329       case GL_BLEND_SRC_ALPHA:                  *params = mState.blend.sourceBlendAlpha;               break;
  1330       case GL_BLEND_DST_RGB:                    *params = mState.blend.destBlendRGB;                   break;
  1331       case GL_BLEND_DST_ALPHA:                  *params = mState.blend.destBlendAlpha;                 break;
  1332       case GL_BLEND_EQUATION_RGB:               *params = mState.blend.blendEquationRGB;               break;
  1333       case GL_BLEND_EQUATION_ALPHA:             *params = mState.blend.blendEquationAlpha;             break;
  1334       case GL_STENCIL_WRITEMASK:                *params = mState.depthStencil.stencilWritemask;        break;
  1335       case GL_STENCIL_BACK_WRITEMASK:           *params = mState.depthStencil.stencilBackWritemask;    break;
  1336       case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             break;
  1337       case GL_SUBPIXEL_BITS:                    *params = 4;                                    break;
  1338       case GL_MAX_TEXTURE_SIZE:                 *params = getMaximumTextureDimension();         break;
  1339       case GL_MAX_CUBE_MAP_TEXTURE_SIZE:        *params = getMaximumCubeTextureDimension();     break;
  1340       case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   
  1341         params[0] = mNumCompressedTextureFormats;
  1342         break;
  1343       case GL_MAX_SAMPLES_ANGLE:
  1345             GLsizei maxSamples = getMaxSupportedSamples();
  1346             if (maxSamples != 0)
  1348                 *params = maxSamples;
  1350             else
  1352                 return false;
  1355             break;
  1357       case GL_SAMPLE_BUFFERS:                   
  1358       case GL_SAMPLES:
  1360             gl::Framebuffer *framebuffer = getDrawFramebuffer();
  1361             if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
  1363                 switch (pname)
  1365                   case GL_SAMPLE_BUFFERS:
  1366                     if (framebuffer->getSamples() != 0)
  1368                         *params = 1;
  1370                     else
  1372                         *params = 0;
  1374                     break;
  1375                   case GL_SAMPLES:
  1376                     *params = framebuffer->getSamples();
  1377                     break;
  1380             else 
  1382                 *params = 0;
  1385         break;
  1386       case GL_IMPLEMENTATION_COLOR_READ_TYPE:
  1387       case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
  1389             GLenum format, type;
  1390             if (getCurrentReadFormatType(&format, &type))
  1392                 if (pname == GL_IMPLEMENTATION_COLOR_READ_FORMAT)
  1393                     *params = format;
  1394                 else
  1395                     *params = type;
  1398         break;
  1399       case GL_MAX_VIEWPORT_DIMS:
  1401             params[0] = mMaxViewportDimension;
  1402             params[1] = mMaxViewportDimension;
  1404         break;
  1405       case GL_COMPRESSED_TEXTURE_FORMATS:
  1407             if (supportsDXT1Textures())
  1409                 *params++ = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  1410                 *params++ = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  1412             if (supportsDXT3Textures())
  1414                 *params++ = GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
  1416             if (supportsDXT5Textures())
  1418                 *params++ = GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
  1421         break;
  1422       case GL_VIEWPORT:
  1423         params[0] = mState.viewport.x;
  1424         params[1] = mState.viewport.y;
  1425         params[2] = mState.viewport.width;
  1426         params[3] = mState.viewport.height;
  1427         break;
  1428       case GL_SCISSOR_BOX:
  1429         params[0] = mState.scissor.x;
  1430         params[1] = mState.scissor.y;
  1431         params[2] = mState.scissor.width;
  1432         params[3] = mState.scissor.height;
  1433         break;
  1434       case GL_CULL_FACE_MODE:                   *params = mState.rasterizer.cullMode;   break;
  1435       case GL_FRONT_FACE:                       *params = mState.rasterizer.frontFace;  break;
  1436       case GL_RED_BITS:
  1437       case GL_GREEN_BITS:
  1438       case GL_BLUE_BITS:
  1439       case GL_ALPHA_BITS:
  1441             gl::Framebuffer *framebuffer = getDrawFramebuffer();
  1442             gl::Renderbuffer *colorbuffer = framebuffer->getFirstColorbuffer();
  1444             if (colorbuffer)
  1446                 switch (pname)
  1448                   case GL_RED_BITS:   *params = colorbuffer->getRedSize();      break;
  1449                   case GL_GREEN_BITS: *params = colorbuffer->getGreenSize();    break;
  1450                   case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();     break;
  1451                   case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize();    break;
  1454             else
  1456                 *params = 0;
  1459         break;
  1460       case GL_DEPTH_BITS:
  1462             gl::Framebuffer *framebuffer = getDrawFramebuffer();
  1463             gl::Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
  1465             if (depthbuffer)
  1467                 *params = depthbuffer->getDepthSize();
  1469             else
  1471                 *params = 0;
  1474         break;
  1475       case GL_STENCIL_BITS:
  1477             gl::Framebuffer *framebuffer = getDrawFramebuffer();
  1478             gl::Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
  1480             if (stencilbuffer)
  1482                 *params = stencilbuffer->getStencilSize();
  1484             else
  1486                 *params = 0;
  1489         break;
  1490       case GL_TEXTURE_BINDING_2D:
  1492             if (mState.activeSampler > mRenderer->getMaxCombinedTextureImageUnits() - 1)
  1494                 gl::error(GL_INVALID_OPERATION);
  1495                 return false;
  1498             *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].id();
  1500         break;
  1501       case GL_TEXTURE_BINDING_CUBE_MAP:
  1503             if (mState.activeSampler > mRenderer->getMaxCombinedTextureImageUnits() - 1)
  1505                 gl::error(GL_INVALID_OPERATION);
  1506                 return false;
  1509             *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].id();
  1511         break;
  1512       case GL_RESET_NOTIFICATION_STRATEGY_EXT:
  1513         *params = mResetStrategy;
  1514         break;
  1515       case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
  1516         *params = 1;
  1517         break;
  1518       case GL_PROGRAM_BINARY_FORMATS_OES:
  1519         *params = GL_PROGRAM_BINARY_ANGLE;
  1520         break;
  1521       default:
  1522         return false;
  1525     return true;
  1528 bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
  1530     if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
  1532         *type = GL_INT;
  1533         *numParams = 1;
  1534         return true;
  1537     // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
  1538     // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
  1539     // to the fact that it is stored internally as a float, and so would require conversion
  1540     // if returned from Context::getIntegerv. Since this conversion is already implemented 
  1541     // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
  1542     // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
  1543     // application.
  1544     switch (pname)
  1546       case GL_COMPRESSED_TEXTURE_FORMATS:
  1548             *type = GL_INT;
  1549             *numParams = mNumCompressedTextureFormats;
  1551         break;
  1552       case GL_SHADER_BINARY_FORMATS:
  1554             *type = GL_INT;
  1555             *numParams = 0;
  1557         break;
  1558       case GL_MAX_VERTEX_ATTRIBS:
  1559       case GL_MAX_VERTEX_UNIFORM_VECTORS:
  1560       case GL_MAX_VARYING_VECTORS:
  1561       case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
  1562       case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
  1563       case GL_MAX_TEXTURE_IMAGE_UNITS:
  1564       case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
  1565       case GL_MAX_RENDERBUFFER_SIZE:
  1566       case GL_MAX_COLOR_ATTACHMENTS_EXT:
  1567       case GL_MAX_DRAW_BUFFERS_EXT:
  1568       case GL_NUM_SHADER_BINARY_FORMATS:
  1569       case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
  1570       case GL_ARRAY_BUFFER_BINDING:
  1571       case GL_FRAMEBUFFER_BINDING:
  1572       case GL_RENDERBUFFER_BINDING:
  1573       case GL_CURRENT_PROGRAM:
  1574       case GL_PACK_ALIGNMENT:
  1575       case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
  1576       case GL_UNPACK_ALIGNMENT:
  1577       case GL_GENERATE_MIPMAP_HINT:
  1578       case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
  1579       case GL_RED_BITS:
  1580       case GL_GREEN_BITS:
  1581       case GL_BLUE_BITS:
  1582       case GL_ALPHA_BITS:
  1583       case GL_DEPTH_BITS:
  1584       case GL_STENCIL_BITS:
  1585       case GL_ELEMENT_ARRAY_BUFFER_BINDING:
  1586       case GL_CULL_FACE_MODE:
  1587       case GL_FRONT_FACE:
  1588       case GL_ACTIVE_TEXTURE:
  1589       case GL_STENCIL_FUNC:
  1590       case GL_STENCIL_VALUE_MASK:
  1591       case GL_STENCIL_REF:
  1592       case GL_STENCIL_FAIL:
  1593       case GL_STENCIL_PASS_DEPTH_FAIL:
  1594       case GL_STENCIL_PASS_DEPTH_PASS:
  1595       case GL_STENCIL_BACK_FUNC:
  1596       case GL_STENCIL_BACK_VALUE_MASK:
  1597       case GL_STENCIL_BACK_REF:
  1598       case GL_STENCIL_BACK_FAIL:
  1599       case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
  1600       case GL_STENCIL_BACK_PASS_DEPTH_PASS:
  1601       case GL_DEPTH_FUNC:
  1602       case GL_BLEND_SRC_RGB:
  1603       case GL_BLEND_SRC_ALPHA:
  1604       case GL_BLEND_DST_RGB:
  1605       case GL_BLEND_DST_ALPHA:
  1606       case GL_BLEND_EQUATION_RGB:
  1607       case GL_BLEND_EQUATION_ALPHA:
  1608       case GL_STENCIL_WRITEMASK:
  1609       case GL_STENCIL_BACK_WRITEMASK:
  1610       case GL_STENCIL_CLEAR_VALUE:
  1611       case GL_SUBPIXEL_BITS:
  1612       case GL_MAX_TEXTURE_SIZE:
  1613       case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
  1614       case GL_SAMPLE_BUFFERS:
  1615       case GL_SAMPLES:
  1616       case GL_IMPLEMENTATION_COLOR_READ_TYPE:
  1617       case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
  1618       case GL_TEXTURE_BINDING_2D:
  1619       case GL_TEXTURE_BINDING_CUBE_MAP:
  1620       case GL_RESET_NOTIFICATION_STRATEGY_EXT:
  1621       case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
  1622       case GL_PROGRAM_BINARY_FORMATS_OES:
  1624             *type = GL_INT;
  1625             *numParams = 1;
  1627         break;
  1628       case GL_MAX_SAMPLES_ANGLE:
  1630             if (getMaxSupportedSamples() != 0)
  1632                 *type = GL_INT;
  1633                 *numParams = 1;
  1635             else
  1637                 return false;
  1640         break;
  1641       case GL_MAX_VIEWPORT_DIMS:
  1643             *type = GL_INT;
  1644             *numParams = 2;
  1646         break;
  1647       case GL_VIEWPORT:
  1648       case GL_SCISSOR_BOX:
  1650             *type = GL_INT;
  1651             *numParams = 4;
  1653         break;
  1654       case GL_SHADER_COMPILER:
  1655       case GL_SAMPLE_COVERAGE_INVERT:
  1656       case GL_DEPTH_WRITEMASK:
  1657       case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
  1658       case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
  1659       case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
  1660       case GL_SAMPLE_COVERAGE:
  1661       case GL_SCISSOR_TEST:
  1662       case GL_STENCIL_TEST:
  1663       case GL_DEPTH_TEST:
  1664       case GL_BLEND:
  1665       case GL_DITHER:
  1666       case GL_CONTEXT_ROBUST_ACCESS_EXT:
  1668             *type = GL_BOOL;
  1669             *numParams = 1;
  1671         break;
  1672       case GL_COLOR_WRITEMASK:
  1674             *type = GL_BOOL;
  1675             *numParams = 4;
  1677         break;
  1678       case GL_POLYGON_OFFSET_FACTOR:
  1679       case GL_POLYGON_OFFSET_UNITS:
  1680       case GL_SAMPLE_COVERAGE_VALUE:
  1681       case GL_DEPTH_CLEAR_VALUE:
  1682       case GL_LINE_WIDTH:
  1684             *type = GL_FLOAT;
  1685             *numParams = 1;
  1687         break;
  1688       case GL_ALIASED_LINE_WIDTH_RANGE:
  1689       case GL_ALIASED_POINT_SIZE_RANGE:
  1690       case GL_DEPTH_RANGE:
  1692             *type = GL_FLOAT;
  1693             *numParams = 2;
  1695         break;
  1696       case GL_COLOR_CLEAR_VALUE:
  1697       case GL_BLEND_COLOR:
  1699             *type = GL_FLOAT;
  1700             *numParams = 4;
  1702         break;
  1703       case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
  1704         if (!supportsTextureFilterAnisotropy())
  1706             return false;
  1708         *type = GL_FLOAT;
  1709         *numParams = 1;
  1710         break;
  1711       default:
  1712         return false;
  1715     return true;
  1718 // Applies the render target surface, depth stencil surface, viewport rectangle and
  1719 // scissor rectangle to the renderer
  1720 bool Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport)
  1722     Framebuffer *framebufferObject = getDrawFramebuffer();
  1724     if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
  1726         return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
  1729     mRenderer->applyRenderTarget(framebufferObject);
  1731     if (!mRenderer->setViewport(mState.viewport, mState.zNear, mState.zFar, drawMode, mState.rasterizer.frontFace,
  1732                                 ignoreViewport))
  1734         return false;
  1737     mRenderer->setScissorRectangle(mState.scissor, mState.scissorTest);
  1739     return true;
  1742 // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
  1743 void Context::applyState(GLenum drawMode)
  1745     Framebuffer *framebufferObject = getDrawFramebuffer();
  1746     int samples = framebufferObject->getSamples();
  1748     mState.rasterizer.pointDrawMode = (drawMode == GL_POINTS);
  1749     mState.rasterizer.multiSample = (samples != 0);
  1750     mRenderer->setRasterizerState(mState.rasterizer);
  1752     unsigned int mask = 0;
  1753     if (mState.sampleCoverage)
  1755         if (mState.sampleCoverageValue != 0)
  1758             float threshold = 0.5f;
  1760             for (int i = 0; i < samples; ++i)
  1762                 mask <<= 1;
  1764                 if ((i + 1) * mState.sampleCoverageValue >= threshold)
  1766                     threshold += 1.0f;
  1767                     mask |= 1;
  1772         if (mState.sampleCoverageInvert)
  1774             mask = ~mask;
  1777     else
  1779         mask = 0xFFFFFFFF;
  1781     mRenderer->setBlendState(mState.blend, mState.blendColor, mask);
  1783     mRenderer->setDepthStencilState(mState.depthStencil, mState.stencilRef, mState.stencilBackRef,
  1784                                     mState.rasterizer.frontFace == GL_CCW);
  1787 // Applies the shaders and shader constants to the Direct3D 9 device
  1788 void Context::applyShaders()
  1790     ProgramBinary *programBinary = getCurrentProgramBinary();
  1792     mRenderer->applyShaders(programBinary);
  1794     programBinary->applyUniforms();
  1797 // Applies the textures and sampler states to the Direct3D 9 device
  1798 void Context::applyTextures()
  1800     applyTextures(SAMPLER_PIXEL);
  1802     if (mSupportsVertexTexture)
  1804         applyTextures(SAMPLER_VERTEX);
  1808 // For each Direct3D 9 sampler of either the pixel or vertex stage,
  1809 // looks up the corresponding OpenGL texture image unit and texture type,
  1810 // and sets the texture and its addressing/filtering state (or NULL when inactive).
  1811 void Context::applyTextures(SamplerType type)
  1813     ProgramBinary *programBinary = getCurrentProgramBinary();
  1815     // Range of Direct3D samplers of given sampler type
  1816     int samplerCount = (type == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : mRenderer->getMaxVertexTextureImageUnits();
  1817     int samplerRange = programBinary->getUsedSamplerRange(type);
  1819     for (int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
  1821         int textureUnit = programBinary->getSamplerMapping(type, samplerIndex);   // OpenGL texture image unit index
  1823         if (textureUnit != -1)
  1825             TextureType textureType = programBinary->getSamplerTextureType(type, samplerIndex);
  1826             Texture *texture = getSamplerTexture(textureUnit, textureType);
  1828             if (texture->isSamplerComplete())
  1830                 SamplerState samplerState;
  1831                 texture->getSamplerState(&samplerState);
  1832                 mRenderer->setSamplerState(type, samplerIndex, samplerState);
  1834                 mRenderer->setTexture(type, samplerIndex, texture);
  1836                 texture->resetDirty();
  1838             else
  1840                 mRenderer->setTexture(type, samplerIndex, getIncompleteTexture(textureType));
  1843         else
  1845             mRenderer->setTexture(type, samplerIndex, NULL);
  1849     for (int samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
  1851         mRenderer->setTexture(type, samplerIndex, NULL);
  1855 void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
  1856                          GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
  1858     Framebuffer *framebuffer = getReadFramebuffer();
  1860     if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
  1862         return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
  1865     if (getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0)
  1867         return gl::error(GL_INVALID_OPERATION);
  1870     GLsizei outputPitch = ComputePitch(width, ConvertSizedInternalFormat(format, type), getPackAlignment());
  1871     // sized query sanity check
  1872     if (bufSize)
  1874         int requiredSize = outputPitch * height;
  1875         if (requiredSize > *bufSize)
  1877             return gl::error(GL_INVALID_OPERATION);
  1881     mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, getPackReverseRowOrder(), getPackAlignment(), pixels);
  1884 void Context::clear(GLbitfield mask)
  1886     Framebuffer *framebufferObject = getDrawFramebuffer();
  1888     if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
  1890         return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
  1893     DWORD flags = 0;
  1894     GLbitfield finalMask = 0;
  1896     if (mask & GL_COLOR_BUFFER_BIT)
  1898         mask &= ~GL_COLOR_BUFFER_BIT;
  1900         if (framebufferObject->hasEnabledColorAttachment())
  1902             finalMask |= GL_COLOR_BUFFER_BIT;
  1906     if (mask & GL_DEPTH_BUFFER_BIT)
  1908         mask &= ~GL_DEPTH_BUFFER_BIT;
  1909         if (mState.depthStencil.depthMask && framebufferObject->getDepthbufferType() != GL_NONE)
  1911             finalMask |= GL_DEPTH_BUFFER_BIT;
  1915     if (mask & GL_STENCIL_BUFFER_BIT)
  1917         mask &= ~GL_STENCIL_BUFFER_BIT;
  1918         if (framebufferObject->getStencilbufferType() != GL_NONE)
  1920             rx::RenderTarget *depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
  1921             if (!depthStencil)
  1923                 ERR("Depth stencil pointer unexpectedly null.");
  1924                 return;
  1927             if (GetStencilSize(depthStencil->getActualFormat()) > 0)
  1929                 finalMask |= GL_STENCIL_BUFFER_BIT;
  1934     if (mask != 0)
  1936         return gl::error(GL_INVALID_VALUE);
  1939     if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
  1941         return;
  1944     ClearParameters clearParams;
  1945     clearParams.mask = finalMask;
  1946     clearParams.colorClearValue = mState.colorClearValue;
  1947     clearParams.colorMaskRed = mState.blend.colorMaskRed;
  1948     clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
  1949     clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
  1950     clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
  1951     clearParams.depthClearValue = mState.depthClearValue;
  1952     clearParams.stencilClearValue = mState.stencilClearValue;
  1953     clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
  1955     mRenderer->clear(clearParams, framebufferObject);
  1958 void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
  1960     if (!mState.currentProgram)
  1962         return gl::error(GL_INVALID_OPERATION);
  1965     if (!mRenderer->applyPrimitiveType(mode, count))
  1967         return;
  1970     if (!applyRenderTarget(mode, false))
  1972         return;
  1975     applyState(mode);
  1977     ProgramBinary *programBinary = getCurrentProgramBinary();
  1979     GLenum err = mRenderer->applyVertexBuffer(programBinary, mState.vertexAttribute, first, count, instances);
  1980     if (err != GL_NO_ERROR)
  1982         return gl::error(err);
  1985     applyShaders();
  1986     applyTextures();
  1988     if (!programBinary->validateSamplers(NULL))
  1990         return gl::error(GL_INVALID_OPERATION);
  1993     if (!skipDraw(mode))
  1995         mRenderer->drawArrays(mode, count, instances);
  1999 void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances)
  2001     if (!mState.currentProgram)
  2003         return gl::error(GL_INVALID_OPERATION);
  2006     if (!indices && !mState.elementArrayBuffer)
  2008         return gl::error(GL_INVALID_OPERATION);
  2011     if (!mRenderer->applyPrimitiveType(mode, count))
  2013         return;
  2016     if (!applyRenderTarget(mode, false))
  2018         return;
  2021     applyState(mode);
  2023     rx::TranslatedIndexData indexInfo;
  2024     GLenum err = mRenderer->applyIndexBuffer(indices, mState.elementArrayBuffer.get(), count, mode, type, &indexInfo);
  2025     if (err != GL_NO_ERROR)
  2027         return gl::error(err);
  2030     ProgramBinary *programBinary = getCurrentProgramBinary();
  2032     GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
  2033     err = mRenderer->applyVertexBuffer(programBinary, mState.vertexAttribute, indexInfo.minIndex, vertexCount, instances);
  2034     if (err != GL_NO_ERROR)
  2036         return gl::error(err);
  2039     applyShaders();
  2040     applyTextures();
  2042     if (!programBinary->validateSamplers(NULL))
  2044         return gl::error(GL_INVALID_OPERATION);
  2047     if (!skipDraw(mode))
  2049         mRenderer->drawElements(mode, count, type, indices, mState.elementArrayBuffer.get(), indexInfo, instances);
  2053 // Implements glFlush when block is false, glFinish when block is true
  2054 void Context::sync(bool block)
  2056     mRenderer->sync(block);
  2059 void Context::recordInvalidEnum()
  2061     mInvalidEnum = true;
  2064 void Context::recordInvalidValue()
  2066     mInvalidValue = true;
  2069 void Context::recordInvalidOperation()
  2071     mInvalidOperation = true;
  2074 void Context::recordOutOfMemory()
  2076     mOutOfMemory = true;
  2079 void Context::recordInvalidFramebufferOperation()
  2081     mInvalidFramebufferOperation = true;
  2084 // Get one of the recorded errors and clear its flag, if any.
  2085 // [OpenGL ES 2.0.24] section 2.5 page 13.
  2086 GLenum Context::getError()
  2088     if (mInvalidEnum)
  2090         mInvalidEnum = false;
  2092         return GL_INVALID_ENUM;
  2095     if (mInvalidValue)
  2097         mInvalidValue = false;
  2099         return GL_INVALID_VALUE;
  2102     if (mInvalidOperation)
  2104         mInvalidOperation = false;
  2106         return GL_INVALID_OPERATION;
  2109     if (mOutOfMemory)
  2111         mOutOfMemory = false;
  2113         return GL_OUT_OF_MEMORY;
  2116     if (mInvalidFramebufferOperation)
  2118         mInvalidFramebufferOperation = false;
  2120         return GL_INVALID_FRAMEBUFFER_OPERATION;
  2123     return GL_NO_ERROR;
  2126 GLenum Context::getResetStatus()
  2128     if (mResetStatus == GL_NO_ERROR && !mContextLost)
  2130         // mResetStatus will be set by the markContextLost callback
  2131         // in the case a notification is sent
  2132         mRenderer->testDeviceLost(true);
  2135     GLenum status = mResetStatus;
  2137     if (mResetStatus != GL_NO_ERROR)
  2139         ASSERT(mContextLost);
  2141         if (mRenderer->testDeviceResettable())
  2143             mResetStatus = GL_NO_ERROR;
  2147     return status;
  2150 bool Context::isResetNotificationEnabled()
  2152     return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
  2155 int Context::getMajorShaderModel() const
  2157     return mMajorShaderModel;
  2160 float Context::getMaximumPointSize() const
  2162     return mMaximumPointSize;
  2165 unsigned int Context::getMaximumCombinedTextureImageUnits() const
  2167     return mRenderer->getMaxCombinedTextureImageUnits();
  2170 int Context::getMaxSupportedSamples() const
  2172     return mRenderer->getMaxSupportedSamples();
  2175 unsigned int Context::getMaximumRenderTargets() const
  2177     return mRenderer->getMaxRenderTargets();
  2180 bool Context::supportsEventQueries() const
  2182     return mSupportsEventQueries;
  2185 bool Context::supportsOcclusionQueries() const
  2187     return mSupportsOcclusionQueries;
  2190 bool Context::supportsBGRATextures() const
  2192     return mSupportsBGRATextures;
  2195 bool Context::supportsDXT1Textures() const
  2197     return mSupportsDXT1Textures;
  2200 bool Context::supportsDXT3Textures() const
  2202     return mSupportsDXT3Textures;
  2205 bool Context::supportsDXT5Textures() const
  2207     return mSupportsDXT5Textures;
  2210 bool Context::supportsFloat32Textures() const
  2212     return mSupportsFloat32Textures;
  2215 bool Context::supportsFloat32LinearFilter() const
  2217     return mSupportsFloat32LinearFilter;
  2220 bool Context::supportsFloat32RenderableTextures() const
  2222     return mSupportsFloat32RenderableTextures;
  2225 bool Context::supportsFloat16Textures() const
  2227     return mSupportsFloat16Textures;
  2230 bool Context::supportsFloat16LinearFilter() const
  2232     return mSupportsFloat16LinearFilter;
  2235 bool Context::supportsFloat16RenderableTextures() const
  2237     return mSupportsFloat16RenderableTextures;
  2240 int Context::getMaximumRenderbufferDimension() const
  2242     return mMaxRenderbufferDimension;
  2245 int Context::getMaximumTextureDimension() const
  2247     return mMaxTextureDimension;
  2250 int Context::getMaximumCubeTextureDimension() const
  2252     return mMaxCubeTextureDimension;
  2255 int Context::getMaximumTextureLevel() const
  2257     return mMaxTextureLevel;
  2260 bool Context::supportsLuminanceTextures() const
  2262     return mSupportsLuminanceTextures;
  2265 bool Context::supportsLuminanceAlphaTextures() const
  2267     return mSupportsLuminanceAlphaTextures;
  2270 bool Context::supportsDepthTextures() const
  2272     return mSupportsDepthTextures;
  2275 bool Context::supports32bitIndices() const
  2277     return mSupports32bitIndices;
  2280 bool Context::supportsNonPower2Texture() const
  2282     return mSupportsNonPower2Texture;
  2285 bool Context::supportsInstancing() const
  2287     return mSupportsInstancing;
  2290 bool Context::supportsTextureFilterAnisotropy() const
  2292     return mSupportsTextureFilterAnisotropy;
  2295 float Context::getTextureMaxAnisotropy() const
  2297     return mMaxTextureAnisotropy;
  2300 bool Context::getCurrentReadFormatType(GLenum *format, GLenum *type)
  2302     Framebuffer *framebuffer = getReadFramebuffer();
  2303     if (!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
  2305         return gl::error(GL_INVALID_OPERATION, false);
  2308     Renderbuffer *renderbuffer = framebuffer->getReadColorbuffer();
  2309     if (!renderbuffer)
  2311         return gl::error(GL_INVALID_OPERATION, false);
  2314     *format = gl::ExtractFormat(renderbuffer->getActualFormat()); 
  2315     *type = gl::ExtractType(renderbuffer->getActualFormat());
  2317     return true;
  2320 void Context::detachBuffer(GLuint buffer)
  2322     // [OpenGL ES 2.0.24] section 2.9 page 22:
  2323     // If a buffer object is deleted while it is bound, all bindings to that object in the current context
  2324     // (i.e. in the thread that called Delete-Buffers) are reset to zero.
  2326     if (mState.arrayBuffer.id() == buffer)
  2328         mState.arrayBuffer.set(NULL);
  2331     if (mState.elementArrayBuffer.id() == buffer)
  2333         mState.elementArrayBuffer.set(NULL);
  2336     for (int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
  2338         if (mState.vertexAttribute[attribute].mBoundBuffer.id() == buffer)
  2340             mState.vertexAttribute[attribute].mBoundBuffer.set(NULL);
  2345 void Context::detachTexture(GLuint texture)
  2347     // [OpenGL ES 2.0.24] section 3.8 page 84:
  2348     // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
  2349     // rebound to texture object zero
  2351     for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
  2353         for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
  2355             if (mState.samplerTexture[type][sampler].id() == texture)
  2357                 mState.samplerTexture[type][sampler].set(NULL);
  2362     // [OpenGL ES 2.0.24] section 4.4 page 112:
  2363     // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
  2364     // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
  2365     // image was attached in the currently bound framebuffer.
  2367     Framebuffer *readFramebuffer = getReadFramebuffer();
  2368     Framebuffer *drawFramebuffer = getDrawFramebuffer();
  2370     if (readFramebuffer)
  2372         readFramebuffer->detachTexture(texture);
  2375     if (drawFramebuffer && drawFramebuffer != readFramebuffer)
  2377         drawFramebuffer->detachTexture(texture);
  2381 void Context::detachFramebuffer(GLuint framebuffer)
  2383     // [OpenGL ES 2.0.24] section 4.4 page 107:
  2384     // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
  2385     // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
  2387     if (mState.readFramebuffer == framebuffer)
  2389         bindReadFramebuffer(0);
  2392     if (mState.drawFramebuffer == framebuffer)
  2394         bindDrawFramebuffer(0);
  2398 void Context::detachRenderbuffer(GLuint renderbuffer)
  2400     // [OpenGL ES 2.0.24] section 4.4 page 109:
  2401     // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
  2402     // had been executed with the target RENDERBUFFER and name of zero.
  2404     if (mState.renderbuffer.id() == renderbuffer)
  2406         bindRenderbuffer(0);
  2409     // [OpenGL ES 2.0.24] section 4.4 page 111:
  2410     // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
  2411     // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
  2412     // point to which this image was attached in the currently bound framebuffer.
  2414     Framebuffer *readFramebuffer = getReadFramebuffer();
  2415     Framebuffer *drawFramebuffer = getDrawFramebuffer();
  2417     if (readFramebuffer)
  2419         readFramebuffer->detachRenderbuffer(renderbuffer);
  2422     if (drawFramebuffer && drawFramebuffer != readFramebuffer)
  2424         drawFramebuffer->detachRenderbuffer(renderbuffer);
  2428 Texture *Context::getIncompleteTexture(TextureType type)
  2430     Texture *t = mIncompleteTextures[type].get();
  2432     if (t == NULL)
  2434         static const GLubyte color[] = { 0, 0, 0, 255 };
  2436         switch (type)
  2438           default:
  2439             UNREACHABLE();
  2440             // default falls through to TEXTURE_2D
  2442           case TEXTURE_2D:
  2444                 Texture2D *incomplete2d = new Texture2D(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
  2445                 incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
  2446                 t = incomplete2d;
  2448             break;
  2450           case TEXTURE_CUBE:
  2452               TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
  2454               incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
  2455               incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
  2456               incompleteCube->setImagePosY(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
  2457               incompleteCube->setImageNegY(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
  2458               incompleteCube->setImagePosZ(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
  2459               incompleteCube->setImageNegZ(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
  2461               t = incompleteCube;
  2463             break;
  2466         mIncompleteTextures[type].set(t);
  2469     return t;
  2472 bool Context::skipDraw(GLenum drawMode)
  2474     if (drawMode == GL_POINTS)
  2476         // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
  2477         // which affects varying interpolation. Since the value of gl_PointSize is
  2478         // undefined when not written, just skip drawing to avoid unexpected results.
  2479         if (!getCurrentProgramBinary()->usesPointSize())
  2481             // This is stictly speaking not an error, but developers should be 
  2482             // notified of risking undefined behavior.
  2483             ERR("Point rendering without writing to gl_PointSize.");
  2485             return true;
  2488     else if (IsTriangleMode(drawMode))
  2490         if (mState.rasterizer.cullFace && mState.rasterizer.cullMode == GL_FRONT_AND_BACK)
  2492             return true;
  2496     return false;
  2499 void Context::setVertexAttrib(GLuint index, const GLfloat *values)
  2501     ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
  2503     mState.vertexAttribute[index].mCurrentValue[0] = values[0];
  2504     mState.vertexAttribute[index].mCurrentValue[1] = values[1];
  2505     mState.vertexAttribute[index].mCurrentValue[2] = values[2];
  2506     mState.vertexAttribute[index].mCurrentValue[3] = values[3];
  2509 void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
  2511     ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
  2513     mState.vertexAttribute[index].mDivisor = divisor;
  2516 // keep list sorted in following order
  2517 // OES extensions
  2518 // EXT extensions
  2519 // Vendor extensions
  2520 void Context::initExtensionString()
  2522     std::string extensionString = "";
  2524     // OES extensions
  2525     if (supports32bitIndices())
  2527         extensionString += "GL_OES_element_index_uint ";
  2530     extensionString += "GL_OES_packed_depth_stencil ";
  2531     extensionString += "GL_OES_get_program_binary ";
  2532     extensionString += "GL_OES_rgb8_rgba8 ";
  2533     if (mRenderer->getDerivativeInstructionSupport())
  2535         extensionString += "GL_OES_standard_derivatives ";
  2538     if (supportsFloat16Textures())
  2540         extensionString += "GL_OES_texture_half_float ";
  2542     if (supportsFloat16LinearFilter())
  2544         extensionString += "GL_OES_texture_half_float_linear ";
  2546     if (supportsFloat32Textures())
  2548         extensionString += "GL_OES_texture_float ";
  2550     if (supportsFloat32LinearFilter())
  2552         extensionString += "GL_OES_texture_float_linear ";
  2555     if (supportsNonPower2Texture())
  2557         extensionString += "GL_OES_texture_npot ";
  2560     // Multi-vendor (EXT) extensions
  2561     if (supportsOcclusionQueries())
  2563         extensionString += "GL_EXT_occlusion_query_boolean ";
  2566     extensionString += "GL_EXT_read_format_bgra ";
  2567     extensionString += "GL_EXT_robustness ";
  2569     if (supportsDXT1Textures())
  2571         extensionString += "GL_EXT_texture_compression_dxt1 ";
  2574     if (supportsTextureFilterAnisotropy())
  2576         extensionString += "GL_EXT_texture_filter_anisotropic ";
  2579     if (supportsBGRATextures())
  2581         extensionString += "GL_EXT_texture_format_BGRA8888 ";
  2584     if (mRenderer->getMaxRenderTargets() > 1)
  2586         extensionString += "GL_EXT_draw_buffers ";
  2589     extensionString += "GL_EXT_texture_storage ";
  2590     extensionString += "GL_EXT_frag_depth ";
  2592     // ANGLE-specific extensions
  2593     if (supportsDepthTextures())
  2595         extensionString += "GL_ANGLE_depth_texture ";
  2598     extensionString += "GL_ANGLE_framebuffer_blit ";
  2599     if (getMaxSupportedSamples() != 0)
  2601         extensionString += "GL_ANGLE_framebuffer_multisample ";
  2604     if (supportsInstancing())
  2606         extensionString += "GL_ANGLE_instanced_arrays ";
  2609     extensionString += "GL_ANGLE_pack_reverse_row_order ";
  2611     if (supportsDXT3Textures())
  2613         extensionString += "GL_ANGLE_texture_compression_dxt3 ";
  2615     if (supportsDXT5Textures())
  2617         extensionString += "GL_ANGLE_texture_compression_dxt5 ";
  2620     extensionString += "GL_ANGLE_texture_usage ";
  2621     extensionString += "GL_ANGLE_translated_shader_source ";
  2623     // Other vendor-specific extensions
  2624     if (supportsEventQueries())
  2626         extensionString += "GL_NV_fence ";
  2629     std::string::size_type end = extensionString.find_last_not_of(' ');
  2630     if (end != std::string::npos)
  2632         extensionString.resize(end+1);
  2635     mExtensionString = makeStaticString(extensionString);
  2638 const char *Context::getExtensionString() const
  2640     return mExtensionString;
  2643 void Context::initRendererString()
  2645     std::ostringstream rendererString;
  2646     rendererString << "ANGLE (";
  2647     rendererString << mRenderer->getRendererDescription();
  2648     rendererString << ")";
  2650     mRendererString = makeStaticString(rendererString.str());
  2653 const char *Context::getRendererString() const
  2655     return mRendererString;
  2658 void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 
  2659                               GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
  2660                               GLbitfield mask)
  2662     Framebuffer *readFramebuffer = getReadFramebuffer();
  2663     Framebuffer *drawFramebuffer = getDrawFramebuffer();
  2665     if (!readFramebuffer || readFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE ||
  2666         !drawFramebuffer || drawFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
  2668         return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
  2671     if (drawFramebuffer->getSamples() != 0)
  2673         return gl::error(GL_INVALID_OPERATION);
  2676     Renderbuffer *readColorBuffer = readFramebuffer->getReadColorbuffer();
  2677     Renderbuffer *drawColorBuffer = drawFramebuffer->getFirstColorbuffer();
  2679     if (drawColorBuffer == NULL)
  2681         ERR("Draw buffers formats don't match, which is not supported in this implementation of BlitFramebufferANGLE");
  2682         return gl::error(GL_INVALID_OPERATION);
  2685     int readBufferWidth = readColorBuffer->getWidth();
  2686     int readBufferHeight = readColorBuffer->getHeight();
  2687     int drawBufferWidth = drawColorBuffer->getWidth();
  2688     int drawBufferHeight = drawColorBuffer->getHeight();
  2690     Rectangle sourceRect;
  2691     Rectangle destRect;
  2693     if (srcX0 < srcX1)
  2695         sourceRect.x = srcX0;
  2696         destRect.x = dstX0;
  2697         sourceRect.width = srcX1 - srcX0;
  2698         destRect.width = dstX1 - dstX0;
  2700     else
  2702         sourceRect.x = srcX1;
  2703         destRect.x = dstX1;
  2704         sourceRect.width = srcX0 - srcX1;
  2705         destRect.width = dstX0 - dstX1;
  2708     if (srcY0 < srcY1)
  2710         sourceRect.height = srcY1 - srcY0;
  2711         destRect.height = dstY1 - dstY0;
  2712         sourceRect.y = srcY0;
  2713         destRect.y = dstY0;
  2715     else
  2717         sourceRect.height = srcY0 - srcY1;
  2718         destRect.height = dstY0 - srcY1;
  2719         sourceRect.y = srcY1;
  2720         destRect.y = dstY1;
  2723     Rectangle sourceScissoredRect = sourceRect;
  2724     Rectangle destScissoredRect = destRect;
  2726     if (mState.scissorTest)
  2728         // Only write to parts of the destination framebuffer which pass the scissor test.
  2729         if (destRect.x < mState.scissor.x)
  2731             int xDiff = mState.scissor.x - destRect.x;
  2732             destScissoredRect.x = mState.scissor.x;
  2733             destScissoredRect.width -= xDiff;
  2734             sourceScissoredRect.x += xDiff;
  2735             sourceScissoredRect.width -= xDiff;
  2739         if (destRect.x + destRect.width > mState.scissor.x + mState.scissor.width)
  2741             int xDiff = (destRect.x + destRect.width) - (mState.scissor.x + mState.scissor.width);
  2742             destScissoredRect.width -= xDiff;
  2743             sourceScissoredRect.width -= xDiff;
  2746         if (destRect.y < mState.scissor.y)
  2748             int yDiff = mState.scissor.y - destRect.y;
  2749             destScissoredRect.y = mState.scissor.y;
  2750             destScissoredRect.height -= yDiff;
  2751             sourceScissoredRect.y += yDiff;
  2752             sourceScissoredRect.height -= yDiff;
  2755         if (destRect.y + destRect.height > mState.scissor.y + mState.scissor.height)
  2757             int yDiff = (destRect.y + destRect.height) - (mState.scissor.y + mState.scissor.height);
  2758             destScissoredRect.height  -= yDiff;
  2759             sourceScissoredRect.height -= yDiff;
  2763     bool blitRenderTarget = false;
  2764     bool blitDepthStencil = false;
  2766     Rectangle sourceTrimmedRect = sourceScissoredRect;
  2767     Rectangle destTrimmedRect = destScissoredRect;
  2769     // The source & destination rectangles also may need to be trimmed if they fall out of the bounds of 
  2770     // the actual draw and read surfaces.
  2771     if (sourceTrimmedRect.x < 0)
  2773         int xDiff = 0 - sourceTrimmedRect.x;
  2774         sourceTrimmedRect.x = 0;
  2775         sourceTrimmedRect.width -= xDiff;
  2776         destTrimmedRect.x += xDiff;
  2777         destTrimmedRect.width -= xDiff;
  2780     if (sourceTrimmedRect.x + sourceTrimmedRect.width > readBufferWidth)
  2782         int xDiff = (sourceTrimmedRect.x + sourceTrimmedRect.width) - readBufferWidth;
  2783         sourceTrimmedRect.width -= xDiff;
  2784         destTrimmedRect.width -= xDiff;
  2787     if (sourceTrimmedRect.y < 0)
  2789         int yDiff = 0 - sourceTrimmedRect.y;
  2790         sourceTrimmedRect.y = 0;
  2791         sourceTrimmedRect.height -= yDiff;
  2792         destTrimmedRect.y += yDiff;
  2793         destTrimmedRect.height -= yDiff;
  2796     if (sourceTrimmedRect.y + sourceTrimmedRect.height > readBufferHeight)
  2798         int yDiff = (sourceTrimmedRect.y + sourceTrimmedRect.height) - readBufferHeight;
  2799         sourceTrimmedRect.height -= yDiff;
  2800         destTrimmedRect.height -= yDiff;
  2803     if (destTrimmedRect.x < 0)
  2805         int xDiff = 0 - destTrimmedRect.x;
  2806         destTrimmedRect.x = 0;
  2807         destTrimmedRect.width -= xDiff;
  2808         sourceTrimmedRect.x += xDiff;
  2809         sourceTrimmedRect.width -= xDiff;
  2812     if (destTrimmedRect.x + destTrimmedRect.width > drawBufferWidth)
  2814         int xDiff = (destTrimmedRect.x + destTrimmedRect.width) - drawBufferWidth;
  2815         destTrimmedRect.width -= xDiff;
  2816         sourceTrimmedRect.width -= xDiff;
  2819     if (destTrimmedRect.y < 0)
  2821         int yDiff = 0 - destTrimmedRect.y;
  2822         destTrimmedRect.y = 0;
  2823         destTrimmedRect.height -= yDiff;
  2824         sourceTrimmedRect.y += yDiff;
  2825         sourceTrimmedRect.height -= yDiff;
  2828     if (destTrimmedRect.y + destTrimmedRect.height > drawBufferHeight)
  2830         int yDiff = (destTrimmedRect.y + destTrimmedRect.height) - drawBufferHeight;
  2831         destTrimmedRect.height -= yDiff;
  2832         sourceTrimmedRect.height -= yDiff;
  2835     bool partialBufferCopy = false;
  2836     if (sourceTrimmedRect.height < readBufferHeight ||
  2837         sourceTrimmedRect.width < readBufferWidth || 
  2838         destTrimmedRect.height < drawBufferHeight ||
  2839         destTrimmedRect.width < drawBufferWidth ||
  2840         sourceTrimmedRect.y != 0 || destTrimmedRect.y != 0 || sourceTrimmedRect.x != 0 || destTrimmedRect.x != 0)
  2842         partialBufferCopy = true;
  2845     if (mask & GL_COLOR_BUFFER_BIT)
  2847         const GLenum readColorbufferType = readFramebuffer->getReadColorbufferType();
  2848         const bool validReadType = (readColorbufferType == GL_TEXTURE_2D) || (readColorbufferType == GL_RENDERBUFFER);
  2849         bool validDrawType = true;
  2850         bool validDrawFormat = true;
  2852         for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
  2854             if (drawFramebuffer->isEnabledColorAttachment(colorAttachment))
  2856                 if (drawFramebuffer->getColorbufferType(colorAttachment) != GL_TEXTURE_2D &&
  2857                     drawFramebuffer->getColorbufferType(colorAttachment) != GL_RENDERBUFFER)
  2859                     validDrawType = false;
  2862                 if (drawFramebuffer->getColorbuffer(colorAttachment)->getActualFormat() != readColorBuffer->getActualFormat())
  2864                     validDrawFormat = false;
  2869         if (!validReadType || !validDrawType || !validDrawFormat)
  2871             ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation");
  2872             return gl::error(GL_INVALID_OPERATION);
  2875         if (partialBufferCopy && readFramebuffer->getSamples() != 0)
  2877             return gl::error(GL_INVALID_OPERATION);
  2880         blitRenderTarget = true;
  2884     if (mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
  2886         Renderbuffer *readDSBuffer = NULL;
  2887         Renderbuffer *drawDSBuffer = NULL;
  2889         // We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have
  2890         // both a depth and stencil buffer, it will be the same buffer.
  2892         if (mask & GL_DEPTH_BUFFER_BIT)
  2894             if (readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
  2896                 if (readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() ||
  2897                     readFramebuffer->getDepthbuffer()->getActualFormat() != drawFramebuffer->getDepthbuffer()->getActualFormat())
  2899                     return gl::error(GL_INVALID_OPERATION);
  2902                 blitDepthStencil = true;
  2903                 readDSBuffer = readFramebuffer->getDepthbuffer();
  2904                 drawDSBuffer = drawFramebuffer->getDepthbuffer();
  2908         if (mask & GL_STENCIL_BUFFER_BIT)
  2910             if (readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
  2912                 if (readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() ||
  2913                     readFramebuffer->getStencilbuffer()->getActualFormat() != drawFramebuffer->getStencilbuffer()->getActualFormat())
  2915                     return gl::error(GL_INVALID_OPERATION);
  2918                 blitDepthStencil = true;
  2919                 readDSBuffer = readFramebuffer->getStencilbuffer();
  2920                 drawDSBuffer = drawFramebuffer->getStencilbuffer();
  2924         if (partialBufferCopy)
  2926             ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
  2927             return gl::error(GL_INVALID_OPERATION); // only whole-buffer copies are permitted
  2930         if ((drawDSBuffer && drawDSBuffer->getSamples() != 0) || 
  2931             (readDSBuffer && readDSBuffer->getSamples() != 0))
  2933             return gl::error(GL_INVALID_OPERATION);
  2937     if (blitRenderTarget || blitDepthStencil)
  2939         mRenderer->blitRect(readFramebuffer, sourceTrimmedRect, drawFramebuffer, destTrimmedRect, blitRenderTarget, blitDepthStencil);
  2945 extern "C"
  2947 gl::Context *glCreateContext(const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
  2949     return new gl::Context(shareContext, renderer, notifyResets, robustAccess);
  2952 void glDestroyContext(gl::Context *context)
  2954     delete context;
  2956     if (context == gl::getContext())
  2958         gl::makeCurrent(NULL, NULL, NULL);
  2962 void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface)
  2964     gl::makeCurrent(context, display, surface);
  2967 gl::Context *glGetCurrentContext()
  2969     return gl::getContext();

mercurial