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