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 38 namespace gl 39 { 40 static 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 50 Context::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 230 Context::~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 324 void 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! 418 void Context::markContextLost() 419 { 420 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT) 421 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT; 422 mContextLost = true; 423 } 424 425 bool Context::isContextLost() 426 { 427 return mContextLost; 428 } 429 430 void 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 449 bool 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 468 void 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 476 void Context::setClearDepth(float depth) 477 { 478 mState.depthClearValue = depth; 479 } 480 481 void Context::setClearStencil(int stencil) 482 { 483 mState.stencilClearValue = stencil; 484 } 485 486 void Context::setRasterizerDiscard(bool enabled) 487 { 488 mState.rasterizer.rasterizerDiscard = enabled; 489 } 490 491 bool Context::isRasterizerDiscardEnabled() const 492 { 493 return mState.rasterizer.rasterizerDiscard; 494 } 495 496 void Context::setCullFace(bool enabled) 497 { 498 mState.rasterizer.cullFace = enabled; 499 } 500 501 bool Context::isCullFaceEnabled() const 502 { 503 return mState.rasterizer.cullFace; 504 } 505 506 void Context::setCullMode(GLenum mode) 507 { 508 mState.rasterizer.cullMode = mode; 509 } 510 511 void Context::setFrontFace(GLenum front) 512 { 513 mState.rasterizer.frontFace = front; 514 } 515 516 void Context::setDepthTest(bool enabled) 517 { 518 mState.depthStencil.depthTest = enabled; 519 } 520 521 bool Context::isDepthTestEnabled() const 522 { 523 return mState.depthStencil.depthTest; 524 } 525 526 void Context::setDepthFunc(GLenum depthFunc) 527 { 528 mState.depthStencil.depthFunc = depthFunc; 529 } 530 531 void Context::setDepthRange(float zNear, float zFar) 532 { 533 mState.zNear = zNear; 534 mState.zFar = zFar; 535 } 536 537 void Context::setBlend(bool enabled) 538 { 539 mState.blend.blend = enabled; 540 } 541 542 bool Context::isBlendEnabled() const 543 { 544 return mState.blend.blend; 545 } 546 547 void 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 555 void 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 563 void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation) 564 { 565 mState.blend.blendEquationRGB = rgbEquation; 566 mState.blend.blendEquationAlpha = alphaEquation; 567 } 568 569 void Context::setStencilTest(bool enabled) 570 { 571 mState.depthStencil.stencilTest = enabled; 572 } 573 574 bool Context::isStencilTestEnabled() const 575 { 576 return mState.depthStencil.stencilTest; 577 } 578 579 void 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 586 void 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 593 void Context::setStencilWritemask(GLuint stencilWritemask) 594 { 595 mState.depthStencil.stencilWritemask = stencilWritemask; 596 } 597 598 void Context::setStencilBackWritemask(GLuint stencilBackWritemask) 599 { 600 mState.depthStencil.stencilBackWritemask = stencilBackWritemask; 601 } 602 603 void 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 610 void 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 617 void Context::setPolygonOffsetFill(bool enabled) 618 { 619 mState.rasterizer.polygonOffsetFill = enabled; 620 } 621 622 bool Context::isPolygonOffsetFillEnabled() const 623 { 624 return mState.rasterizer.polygonOffsetFill; 625 } 626 627 void 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 634 void Context::setSampleAlphaToCoverage(bool enabled) 635 { 636 mState.blend.sampleAlphaToCoverage = enabled; 637 } 638 639 bool Context::isSampleAlphaToCoverageEnabled() const 640 { 641 return mState.blend.sampleAlphaToCoverage; 642 } 643 644 void Context::setSampleCoverage(bool enabled) 645 { 646 mState.sampleCoverage = enabled; 647 } 648 649 bool Context::isSampleCoverageEnabled() const 650 { 651 return mState.sampleCoverage; 652 } 653 654 void Context::setSampleCoverageParams(GLclampf value, bool invert) 655 { 656 mState.sampleCoverageValue = value; 657 mState.sampleCoverageInvert = invert; 658 } 659 660 void Context::setScissorTest(bool enabled) 661 { 662 mState.scissorTest = enabled; 663 } 664 665 bool Context::isScissorTestEnabled() const 666 { 667 return mState.scissorTest; 668 } 669 670 void Context::setDither(bool enabled) 671 { 672 mState.blend.dither = enabled; 673 } 674 675 bool Context::isDitherEnabled() const 676 { 677 return mState.blend.dither; 678 } 679 680 void Context::setLineWidth(GLfloat width) 681 { 682 mState.lineWidth = width; 683 } 684 685 void Context::setGenerateMipmapHint(GLenum hint) 686 { 687 mState.generateMipmapHint = hint; 688 } 689 690 void 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 698 void 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 706 void 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 714 void 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 722 void 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 730 void Context::setDepthMask(bool mask) 731 { 732 mState.depthStencil.depthMask = mask; 733 } 734 735 void Context::setActiveSampler(unsigned int active) 736 { 737 mState.activeSampler = active; 738 } 739 740 GLuint Context::getReadFramebufferHandle() const 741 { 742 return mState.readFramebuffer; 743 } 744 745 GLuint Context::getDrawFramebufferHandle() const 746 { 747 return mState.drawFramebuffer; 748 } 749 750 GLuint Context::getRenderbufferHandle() const 751 { 752 return mState.renderbuffer.id(); 753 } 754 755 GLuint Context::getVertexArrayHandle() const 756 { 757 return mState.vertexArray; 758 } 759 760 GLuint Context::getSamplerHandle(GLuint textureUnit) const 761 { 762 ASSERT(textureUnit < ArraySize(mState.samplers)); 763 return mState.samplers[textureUnit]; 764 } 765 766 unsigned int Context::getActiveSampler() const 767 { 768 return mState.activeSampler; 769 } 770 771 GLuint Context::getArrayBufferHandle() const 772 { 773 return mState.arrayBuffer.id(); 774 } 775 776 bool 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 790 const 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 798 GLuint Context::getActiveQueryId(GLenum target) const 799 { 800 const Query *query = getActiveQuery(target); 801 return (query ? query->id() : 0u); 802 } 803 804 void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled) 805 { 806 getCurrentVertexArray()->enableAttribute(attribNum, enabled); 807 } 808 809 const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) const 810 { 811 return getCurrentVertexArray()->getVertexAttribute(attribNum); 812 } 813 814 const VertexAttribCurrentValueData &Context::getVertexAttribCurrentValue(unsigned int attribNum) const 815 { 816 ASSERT(attribNum < MAX_VERTEX_ATTRIBS); 817 return mState.vertexAttribCurrentValues[attribNum]; 818 } 819 820 void 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 826 const void *Context::getVertexAttribPointer(unsigned int attribNum) const 827 { 828 return getCurrentVertexArray()->getVertexAttribute(attribNum).mPointer; 829 } 830 831 void Context::setPackAlignment(GLint alignment) 832 { 833 mState.pack.alignment = alignment; 834 } 835 836 GLint Context::getPackAlignment() const 837 { 838 return mState.pack.alignment; 839 } 840 841 void Context::setUnpackAlignment(GLint alignment) 842 { 843 mState.unpack.alignment = alignment; 844 } 845 846 GLint Context::getUnpackAlignment() const 847 { 848 return mState.unpack.alignment; 849 } 850 851 void Context::setPackReverseRowOrder(bool reverseRowOrder) 852 { 853 mState.pack.reverseRowOrder = reverseRowOrder; 854 } 855 856 bool Context::getPackReverseRowOrder() const 857 { 858 return mState.pack.reverseRowOrder; 859 } 860 861 const PixelUnpackState &Context::getUnpackState() const 862 { 863 return mState.unpack; 864 } 865 866 const PixelPackState &Context::getPackState() const 867 { 868 return mState.pack; 869 } 870 871 GLuint Context::createBuffer() 872 { 873 return mResourceManager->createBuffer(); 874 } 875 876 GLuint Context::createProgram() 877 { 878 return mResourceManager->createProgram(); 879 } 880 881 GLuint Context::createShader(GLenum type) 882 { 883 return mResourceManager->createShader(type); 884 } 885 886 GLuint Context::createTexture() 887 { 888 return mResourceManager->createTexture(); 889 } 890 891 GLuint Context::createRenderbuffer() 892 { 893 return mResourceManager->createRenderbuffer(); 894 } 895 896 GLsync 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 908 GLuint 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 920 GLuint Context::createSampler() 921 { 922 return mResourceManager->createSampler(); 923 } 924 925 GLuint 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 935 GLuint Context::createFramebuffer() 936 { 937 GLuint handle = mFramebufferHandleAllocator.allocate(); 938 939 mFramebufferMap[handle] = NULL; 940 941 return handle; 942 } 943 944 GLuint 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 954 GLuint Context::createQuery() 955 { 956 GLuint handle = mQueryHandleAllocator.allocate(); 957 958 mQueryMap[handle] = NULL; 959 960 return handle; 961 } 962 963 void Context::deleteBuffer(GLuint buffer) 964 { 965 if (mResourceManager->getBuffer(buffer)) 966 { 967 detachBuffer(buffer); 968 } 969 970 mResourceManager->deleteBuffer(buffer); 971 } 972 973 void Context::deleteShader(GLuint shader) 974 { 975 mResourceManager->deleteShader(shader); 976 } 977 978 void Context::deleteProgram(GLuint program) 979 { 980 mResourceManager->deleteProgram(program); 981 } 982 983 void Context::deleteTexture(GLuint texture) 984 { 985 if (mResourceManager->getTexture(texture)) 986 { 987 detachTexture(texture); 988 } 989 990 mResourceManager->deleteTexture(texture); 991 } 992 993 void Context::deleteRenderbuffer(GLuint renderbuffer) 994 { 995 if (mResourceManager->getRenderbuffer(renderbuffer)) 996 { 997 detachRenderbuffer(renderbuffer); 998 } 999 1000 mResourceManager->deleteRenderbuffer(renderbuffer); 1001 } 1002 1003 void 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 1012 void 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 1026 void Context::deleteSampler(GLuint sampler) 1027 { 1028 if (mResourceManager->getSampler(sampler)) 1029 { 1030 detachSampler(sampler); 1031 } 1032 1033 mResourceManager->deleteSampler(sampler); 1034 } 1035 1036 void 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 1048 void 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 1062 void 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 1074 void 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 1088 Buffer *Context::getBuffer(GLuint handle) 1089 { 1090 return mResourceManager->getBuffer(handle); 1091 } 1092 1093 Shader *Context::getShader(GLuint handle) const 1094 { 1095 return mResourceManager->getShader(handle); 1096 } 1097 1098 Program *Context::getProgram(GLuint handle) const 1099 { 1100 return mResourceManager->getProgram(handle); 1101 } 1102 1103 Texture *Context::getTexture(GLuint handle) 1104 { 1105 return mResourceManager->getTexture(handle); 1106 } 1107 1108 FramebufferAttachment *Context::getRenderbuffer(GLuint handle) 1109 { 1110 return mResourceManager->getRenderbuffer(handle); 1111 } 1112 1113 FenceSync *Context::getFenceSync(GLsync handle) const 1114 { 1115 return mResourceManager->getFenceSync(reinterpret_cast<GLuint>(handle)); 1116 } 1117 1118 VertexArray *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 1132 Sampler *Context::getSampler(GLuint handle) const 1133 { 1134 return mResourceManager->getSampler(handle); 1135 } 1136 1137 TransformFeedback *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 1150 Framebuffer *Context::getReadFramebuffer() 1151 { 1152 return getFramebuffer(mState.readFramebuffer); 1153 } 1154 1155 Framebuffer *Context::getDrawFramebuffer() 1156 { 1157 return mBoundDrawFramebuffer; 1158 } 1159 1160 VertexArray *Context::getCurrentVertexArray() const 1161 { 1162 VertexArray *vao = getVertexArray(mState.vertexArray); 1163 ASSERT(vao != NULL); 1164 return vao; 1165 } 1166 1167 TransformFeedback *Context::getCurrentTransformFeedback() const 1168 { 1169 return mState.transformFeedback.get(); 1170 } 1171 1172 bool Context::isSampler(GLuint samplerName) const 1173 { 1174 return mResourceManager->isSampler(samplerName); 1175 } 1176 1177 void Context::bindArrayBuffer(unsigned int buffer) 1178 { 1179 mResourceManager->checkBufferAllocation(buffer); 1180 1181 mState.arrayBuffer.set(getBuffer(buffer)); 1182 } 1183 1184 void Context::bindElementArrayBuffer(unsigned int buffer) 1185 { 1186 mResourceManager->checkBufferAllocation(buffer); 1187 1188 getCurrentVertexArray()->setElementArrayBuffer(getBuffer(buffer)); 1189 } 1190 1191 void Context::bindTexture2D(GLuint texture) 1192 { 1193 mResourceManager->checkTextureAllocation(texture, TEXTURE_2D); 1194 1195 mState.samplerTexture[TEXTURE_2D][mState.activeSampler].set(getTexture(texture)); 1196 } 1197 1198 void Context::bindTextureCubeMap(GLuint texture) 1199 { 1200 mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE); 1201 1202 mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].set(getTexture(texture)); 1203 } 1204 1205 void Context::bindTexture3D(GLuint texture) 1206 { 1207 mResourceManager->checkTextureAllocation(texture, TEXTURE_3D); 1208 1209 mState.samplerTexture[TEXTURE_3D][mState.activeSampler].set(getTexture(texture)); 1210 } 1211 1212 void 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 1219 void Context::bindReadFramebuffer(GLuint framebuffer) 1220 { 1221 if (!getFramebuffer(framebuffer)) 1222 { 1223 mFramebufferMap[framebuffer] = new Framebuffer(mRenderer); 1224 } 1225 1226 mState.readFramebuffer = framebuffer; 1227 } 1228 1229 void 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 1241 void Context::bindRenderbuffer(GLuint renderbuffer) 1242 { 1243 mResourceManager->checkRenderbufferAllocation(renderbuffer); 1244 1245 mState.renderbuffer.set(getRenderbuffer(renderbuffer)); 1246 } 1247 1248 void 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 1258 void 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 1266 void Context::bindGenericUniformBuffer(GLuint buffer) 1267 { 1268 mResourceManager->checkBufferAllocation(buffer); 1269 1270 mState.genericUniformBuffer.set(getBuffer(buffer)); 1271 } 1272 1273 void 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 1280 void Context::bindGenericTransformFeedbackBuffer(GLuint buffer) 1281 { 1282 mResourceManager->checkBufferAllocation(buffer); 1283 1284 mState.genericTransformFeedbackBuffer.set(getBuffer(buffer)); 1285 } 1286 1287 void 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 1294 void Context::bindCopyReadBuffer(GLuint buffer) 1295 { 1296 mResourceManager->checkBufferAllocation(buffer); 1297 1298 mState.copyReadBuffer.set(getBuffer(buffer)); 1299 } 1300 1301 void Context::bindCopyWriteBuffer(GLuint buffer) 1302 { 1303 mResourceManager->checkBufferAllocation(buffer); 1304 1305 mState.copyWriteBuffer.set(getBuffer(buffer)); 1306 } 1307 1308 void Context::bindPixelPackBuffer(GLuint buffer) 1309 { 1310 mResourceManager->checkBufferAllocation(buffer); 1311 1312 mState.pack.pixelBuffer.set(getBuffer(buffer)); 1313 } 1314 1315 void Context::bindPixelUnpackBuffer(GLuint buffer) 1316 { 1317 mResourceManager->checkBufferAllocation(buffer); 1318 1319 mState.unpack.pixelBuffer.set(getBuffer(buffer)); 1320 } 1321 1322 void 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 1346 void 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 1360 void 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 1375 void Context::bindTransformFeedback(GLuint transformFeedback) 1376 { 1377 TransformFeedback *transformFeedbackObject = getTransformFeedback(transformFeedback); 1378 mState.transformFeedback.set(transformFeedbackObject); 1379 } 1380 1381 void 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 1393 void 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 1403 void 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 1413 void 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 1447 Framebuffer *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 1461 FenceNV *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 1475 Query *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 1494 Buffer *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 1510 Buffer *Context::getArrayBuffer() 1511 { 1512 return mState.arrayBuffer.get(); 1513 } 1514 1515 Buffer *Context::getElementArrayBuffer() const 1516 { 1517 return getCurrentVertexArray()->getElementArrayBuffer(); 1518 } 1519 1520 ProgramBinary *Context::getCurrentProgramBinary() 1521 { 1522 return mCurrentProgramBinary.get(); 1523 } 1524 1525 Texture *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 1542 GLuint 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 1559 Framebuffer *Context::getTargetFramebuffer(GLenum target) const 1560 { 1561 GLuint framebufferHandle = getTargetFramebufferHandle(target); 1562 return (framebufferHandle == GL_INVALID_INDEX ? NULL : getFramebuffer(framebufferHandle)); 1563 } 1564 1565 Texture2D *Context::getTexture2D() const 1566 { 1567 return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D)); 1568 } 1569 1570 TextureCubeMap *Context::getTextureCubeMap() const 1571 { 1572 return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE)); 1573 } 1574 1575 Texture3D *Context::getTexture3D() const 1576 { 1577 return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D)); 1578 } 1579 1580 Texture2DArray *Context::getTexture2DArray() const 1581 { 1582 return static_cast<Texture2DArray*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_ARRAY)); 1583 } 1584 1585 Buffer *Context::getGenericUniformBuffer() 1586 { 1587 return mState.genericUniformBuffer.get(); 1588 } 1589 1590 Buffer *Context::getGenericTransformFeedbackBuffer() 1591 { 1592 return mState.genericTransformFeedbackBuffer.get(); 1593 } 1594 1595 Buffer *Context::getCopyReadBuffer() 1596 { 1597 return mState.copyReadBuffer.get(); 1598 } 1599 1600 Buffer *Context::getCopyWriteBuffer() 1601 { 1602 return mState.copyWriteBuffer.get(); 1603 } 1604 1605 Buffer *Context::getPixelPackBuffer() 1606 { 1607 return mState.pack.pixelBuffer.get(); 1608 } 1609 1610 Buffer *Context::getPixelUnpackBuffer() 1611 { 1612 return mState.unpack.pixelBuffer.get(); 1613 } 1614 1615 Texture *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 1634 void 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 1665 void 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 1712 void 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 1987 void 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 2021 bool 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 2044 bool 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 2079 bool 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 2342 bool 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 2373 bool 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 2396 void 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 2441 void 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 2453 size_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 2480 void 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). 2494 void 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 2537 bool 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 2564 bool 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 2585 void 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 2597 void 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 2670 void 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 2729 void 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 2764 void 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 2824 void 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 2859 void 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 2871 void 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 2943 void 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 3028 void Context::sync(bool block) 3029 { 3030 mRenderer->sync(block); 3031 } 3032 3033 void Context::recordInvalidEnum() 3034 { 3035 mInvalidEnum = true; 3036 } 3037 3038 void Context::recordInvalidValue() 3039 { 3040 mInvalidValue = true; 3041 } 3042 3043 void Context::recordInvalidOperation() 3044 { 3045 mInvalidOperation = true; 3046 } 3047 3048 void Context::recordOutOfMemory() 3049 { 3050 mOutOfMemory = true; 3051 } 3052 3053 void 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. 3060 GLenum 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 3100 GLenum 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 3124 bool Context::isResetNotificationEnabled() 3125 { 3126 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT); 3127 } 3128 3129 int Context::getClientVersion() const 3130 { 3131 return mClientVersion; 3132 } 3133 3134 int Context::getMajorShaderModel() const 3135 { 3136 return mMajorShaderModel; 3137 } 3138 3139 float Context::getMaximumPointSize() const 3140 { 3141 return mMaximumPointSize; 3142 } 3143 3144 unsigned int Context::getMaximumCombinedTextureImageUnits() const 3145 { 3146 return mRenderer->getMaxCombinedTextureImageUnits(); 3147 } 3148 3149 unsigned int Context::getMaximumCombinedUniformBufferBindings() const 3150 { 3151 return mRenderer->getMaxVertexShaderUniformBuffers() + 3152 mRenderer->getMaxFragmentShaderUniformBuffers(); 3153 } 3154 3155 int Context::getMaxSupportedSamples() const 3156 { 3157 return mRenderer->getMaxSupportedSamples(); 3158 } 3159 3160 GLsizei Context::getMaxSupportedFormatSamples(GLenum internalFormat) const 3161 { 3162 return mRenderer->getMaxSupportedFormatSamples(internalFormat); 3163 } 3164 3165 GLsizei Context::getNumSampleCounts(GLenum internalFormat) const 3166 { 3167 return mRenderer->getNumSampleCounts(internalFormat); 3168 } 3169 3170 void Context::getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const 3171 { 3172 mRenderer->getSampleCounts(internalFormat, bufSize, params); 3173 } 3174 3175 unsigned int Context::getMaxTransformFeedbackBufferBindings() const 3176 { 3177 return mRenderer->getMaxTransformFeedbackBuffers(); 3178 } 3179 3180 GLintptr 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 3186 unsigned int Context::getMaximumRenderTargets() const 3187 { 3188 return mRenderer->getMaxRenderTargets(); 3189 } 3190 3191 bool Context::supportsEventQueries() const 3192 { 3193 return mSupportsEventQueries; 3194 } 3195 3196 bool Context::supportsOcclusionQueries() const 3197 { 3198 return mSupportsOcclusionQueries; 3199 } 3200 3201 bool Context::supportsBGRATextures() const 3202 { 3203 return mSupportsBGRATextures; 3204 } 3205 3206 bool Context::supportsDXT1Textures() const 3207 { 3208 return mSupportsDXT1Textures; 3209 } 3210 3211 bool Context::supportsDXT3Textures() const 3212 { 3213 return mSupportsDXT3Textures; 3214 } 3215 3216 bool Context::supportsDXT5Textures() const 3217 { 3218 return mSupportsDXT5Textures; 3219 } 3220 3221 bool Context::supportsFloat32Textures() const 3222 { 3223 return mSupportsFloat32Textures; 3224 } 3225 3226 bool Context::supportsFloat32LinearFilter() const 3227 { 3228 return mSupportsFloat32LinearFilter; 3229 } 3230 3231 bool Context::supportsFloat32RenderableTextures() const 3232 { 3233 return mSupportsFloat32RenderableTextures; 3234 } 3235 3236 bool Context::supportsFloat16Textures() const 3237 { 3238 return mSupportsFloat16Textures; 3239 } 3240 3241 bool Context::supportsFloat16LinearFilter() const 3242 { 3243 return mSupportsFloat16LinearFilter; 3244 } 3245 3246 bool Context::supportsFloat16RenderableTextures() const 3247 { 3248 return mSupportsFloat16RenderableTextures; 3249 } 3250 3251 int Context::getMaximumRenderbufferDimension() const 3252 { 3253 return mMaxRenderbufferDimension; 3254 } 3255 3256 int Context::getMaximum2DTextureDimension() const 3257 { 3258 return mMax2DTextureDimension; 3259 } 3260 3261 int Context::getMaximumCubeTextureDimension() const 3262 { 3263 return mMaxCubeTextureDimension; 3264 } 3265 3266 int Context::getMaximum3DTextureDimension() const 3267 { 3268 return mMax3DTextureDimension; 3269 } 3270 3271 int Context::getMaximum2DArrayTextureLayers() const 3272 { 3273 return mMax2DArrayTextureLayers; 3274 } 3275 3276 int Context::getMaximum2DTextureLevel() const 3277 { 3278 return mMax2DTextureLevel; 3279 } 3280 3281 int Context::getMaximumCubeTextureLevel() const 3282 { 3283 return mMaxCubeTextureLevel; 3284 } 3285 3286 int Context::getMaximum3DTextureLevel() const 3287 { 3288 return mMax3DTextureLevel; 3289 } 3290 3291 int Context::getMaximum2DArrayTextureLevel() const 3292 { 3293 return mMax2DArrayTextureLevel; 3294 } 3295 3296 bool Context::supportsLuminanceTextures() const 3297 { 3298 return mSupportsLuminanceTextures; 3299 } 3300 3301 bool Context::supportsLuminanceAlphaTextures() const 3302 { 3303 return mSupportsLuminanceAlphaTextures; 3304 } 3305 3306 bool Context::supportsRGTextures() const 3307 { 3308 return mSupportsRGTextures; 3309 } 3310 3311 bool Context::supportsDepthTextures() const 3312 { 3313 return mSupportsDepthTextures; 3314 } 3315 3316 bool Context::supports32bitIndices() const 3317 { 3318 return mSupports32bitIndices; 3319 } 3320 3321 bool Context::supportsNonPower2Texture() const 3322 { 3323 return mSupportsNonPower2Texture; 3324 } 3325 3326 bool Context::supportsInstancing() const 3327 { 3328 return mSupportsInstancing; 3329 } 3330 3331 bool Context::supportsTextureFilterAnisotropy() const 3332 { 3333 return mSupportsTextureFilterAnisotropy; 3334 } 3335 3336 bool Context::supportsPBOs() const 3337 { 3338 return mSupportsPBOs; 3339 } 3340 3341 float Context::getTextureMaxAnisotropy() const 3342 { 3343 return mMaxTextureAnisotropy; 3344 } 3345 3346 void 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 3359 void 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 3377 void 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 3413 void 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 3430 void 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 3460 void 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 3471 void Context::detachTransformFeedback(GLuint transformFeedback) 3472 { 3473 if (mState.transformFeedback.id() == transformFeedback) 3474 { 3475 bindTransformFeedback(0); 3476 } 3477 } 3478 3479 void 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 3494 Texture *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 3557 bool 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 3584 void Context::setVertexAttribf(GLuint index, const GLfloat values[4]) 3585 { 3586 ASSERT(index < gl::MAX_VERTEX_ATTRIBS); 3587 mState.vertexAttribCurrentValues[index].setFloatValues(values); 3588 } 3589 3590 void Context::setVertexAttribu(GLuint index, const GLuint values[4]) 3591 { 3592 ASSERT(index < gl::MAX_VERTEX_ATTRIBS); 3593 mState.vertexAttribCurrentValues[index].setUnsignedIntValues(values); 3594 } 3595 3596 void Context::setVertexAttribi(GLuint index, const GLint values[4]) 3597 { 3598 ASSERT(index < gl::MAX_VERTEX_ATTRIBS); 3599 mState.vertexAttribCurrentValues[index].setIntValues(values); 3600 } 3601 3602 void Context::setVertexAttribDivisor(GLuint index, GLuint divisor) 3603 { 3604 getCurrentVertexArray()->setVertexAttribDivisor(index, divisor); 3605 } 3606 3607 void 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 3629 void 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 3651 GLint 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 3673 GLfloat 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 3699 void 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 3848 const char *Context::getCombinedExtensionsString() const 3849 { 3850 return mCombinedExtensionsString; 3851 } 3852 3853 const char *Context::getExtensionString(const GLuint index) const 3854 { 3855 ASSERT(index < mExtensionStringList.size()); 3856 return mExtensionStringList[index].c_str(); 3857 } 3858 3859 unsigned int Context::getNumExtensions() const 3860 { 3861 return mExtensionStringList.size(); 3862 } 3863 3864 void Context::initRendererString() 3865 { 3866 std::ostringstream rendererString; 3867 rendererString << "ANGLE ("; 3868 rendererString << mRenderer->getRendererDescription(); 3869 rendererString << ")"; 3870 3871 mRendererString = makeStaticString(rendererString.str()); 3872 } 3873 3874 const char *Context::getRendererString() const 3875 { 3876 return mRendererString; 3877 } 3878 3879 size_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 3904 void 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 3936 void 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 4009 bool 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 4038 extern "C" 4039 { 4040 gl::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 4045 void glDestroyContext(gl::Context *context) 4046 { 4047 delete context; 4048 4049 if (context == gl::getContext()) 4050 { 4051 gl::makeCurrent(NULL, NULL, NULL); 4052 } 4053 } 4054 4055 void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface) 4056 { 4057 gl::makeCurrent(context, display, surface); 4058 } 4059 4060 gl::Context *glGetCurrentContext() 4061 { 4062 return gl::getContext(); 4063 } 4064 4065 } 4066