1 // 2 // Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // State.cpp: Implements the State class, encapsulating raw GL state. 8 9 #include "libGLESv2/State.h" 10 11 #include "libGLESv2/Context.h" 12 #include "libGLESv2/Caps.h" 13 #include "libGLESv2/VertexArray.h" 14 #include "libGLESv2/Query.h" 15 #include "libGLESv2/Framebuffer.h" 16 #include "libGLESv2/FramebufferAttachment.h" 17 #include "libGLESv2/renderer/RenderTarget.h" 18 #include "libGLESv2/formatutils.h" 19 20 namespace gl 21 { 22 23 State::State() 24 { 25 } 26 27 State::~State() 28 { 29 reset(); 30 } 31 32 void State::initialize(const Caps& caps, GLuint clientVersion) 33 { 34 mContext = NULL; 35 36 setClearColor(0.0f, 0.0f, 0.0f, 0.0f); 37 38 mDepthClearValue = 1.0f; 39 mStencilClearValue = 0; 40 41 mRasterizer.rasterizerDiscard = false; 42 mRasterizer.cullFace = false; 43 mRasterizer.cullMode = GL_BACK; 44 mRasterizer.frontFace = GL_CCW; 45 mRasterizer.polygonOffsetFill = false; 46 mRasterizer.polygonOffsetFactor = 0.0f; 47 mRasterizer.polygonOffsetUnits = 0.0f; 48 mRasterizer.pointDrawMode = false; 49 mRasterizer.multiSample = false; 50 mScissorTest = false; 51 mScissor.x = 0; 52 mScissor.y = 0; 53 mScissor.width = 0; 54 mScissor.height = 0; 55 56 mBlend.blend = false; 57 mBlend.sourceBlendRGB = GL_ONE; 58 mBlend.sourceBlendAlpha = GL_ONE; 59 mBlend.destBlendRGB = GL_ZERO; 60 mBlend.destBlendAlpha = GL_ZERO; 61 mBlend.blendEquationRGB = GL_FUNC_ADD; 62 mBlend.blendEquationAlpha = GL_FUNC_ADD; 63 mBlend.sampleAlphaToCoverage = false; 64 mBlend.dither = true; 65 66 mBlendColor.red = 0; 67 mBlendColor.green = 0; 68 mBlendColor.blue = 0; 69 mBlendColor.alpha = 0; 70 71 mDepthStencil.depthTest = false; 72 mDepthStencil.depthFunc = GL_LESS; 73 mDepthStencil.depthMask = true; 74 mDepthStencil.stencilTest = false; 75 mDepthStencil.stencilFunc = GL_ALWAYS; 76 mDepthStencil.stencilMask = -1; 77 mDepthStencil.stencilWritemask = -1; 78 mDepthStencil.stencilBackFunc = GL_ALWAYS; 79 mDepthStencil.stencilBackMask = -1; 80 mDepthStencil.stencilBackWritemask = -1; 81 mDepthStencil.stencilFail = GL_KEEP; 82 mDepthStencil.stencilPassDepthFail = GL_KEEP; 83 mDepthStencil.stencilPassDepthPass = GL_KEEP; 84 mDepthStencil.stencilBackFail = GL_KEEP; 85 mDepthStencil.stencilBackPassDepthFail = GL_KEEP; 86 mDepthStencil.stencilBackPassDepthPass = GL_KEEP; 87 88 mStencilRef = 0; 89 mStencilBackRef = 0; 90 91 mSampleCoverage = false; 92 mSampleCoverageValue = 1.0f; 93 mSampleCoverageInvert = false; 94 mGenerateMipmapHint = GL_DONT_CARE; 95 mFragmentShaderDerivativeHint = GL_DONT_CARE; 96 97 mLineWidth = 1.0f; 98 99 mViewport.x = 0; 100 mViewport.y = 0; 101 mViewport.width = 0; 102 mViewport.height = 0; 103 mNearZ = 0.0f; 104 mFarZ = 1.0f; 105 106 mBlend.colorMaskRed = true; 107 mBlend.colorMaskGreen = true; 108 mBlend.colorMaskBlue = true; 109 mBlend.colorMaskAlpha = true; 110 111 mActiveSampler = 0; 112 113 const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f }; 114 for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++) 115 { 116 mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues); 117 } 118 119 mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits); 120 mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits); 121 if (clientVersion >= 3) 122 { 123 // TODO: These could also be enabled via extension 124 mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits); 125 mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits); 126 } 127 128 mSamplers.resize(caps.maxCombinedTextureImageUnits); 129 130 mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL); 131 mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL); 132 mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL); 133 134 mCurrentProgramId = 0; 135 mCurrentProgramBinary.set(NULL); 136 137 mReadFramebuffer = NULL; 138 mDrawFramebuffer = NULL; 139 } 140 141 void State::reset() 142 { 143 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++) 144 { 145 TextureBindingVector &textureVector = bindingVec->second; 146 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++) 147 { 148 textureVector[textureIdx].set(NULL); 149 } 150 } 151 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++) 152 { 153 mSamplers[samplerIdx].set(NULL); 154 } 155 156 const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f }; 157 for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++) 158 { 159 mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues); 160 } 161 162 mArrayBuffer.set(NULL); 163 mRenderbuffer.set(NULL); 164 165 mTransformFeedback.set(NULL); 166 167 for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++) 168 { 169 i->second.set(NULL); 170 } 171 172 mGenericUniformBuffer.set(NULL); 173 for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++) 174 { 175 mUniformBuffers[i].set(NULL); 176 } 177 178 mGenericTransformFeedbackBuffer.set(NULL); 179 for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) 180 { 181 mTransformFeedbackBuffers[i].set(NULL); 182 } 183 184 mCopyReadBuffer.set(NULL); 185 mCopyWriteBuffer.set(NULL); 186 187 mPack.pixelBuffer.set(NULL); 188 mUnpack.pixelBuffer.set(NULL); 189 } 190 191 const RasterizerState &State::getRasterizerState() const 192 { 193 return mRasterizer; 194 } 195 196 const BlendState &State::getBlendState() const 197 { 198 return mBlend; 199 } 200 201 const DepthStencilState &State::getDepthStencilState() const 202 { 203 return mDepthStencil; 204 } 205 206 void State::setClearColor(float red, float green, float blue, float alpha) 207 { 208 mColorClearValue.red = red; 209 mColorClearValue.green = green; 210 mColorClearValue.blue = blue; 211 mColorClearValue.alpha = alpha; 212 } 213 214 void State::setClearDepth(float depth) 215 { 216 mDepthClearValue = depth; 217 } 218 219 void State::setClearStencil(int stencil) 220 { 221 mStencilClearValue = stencil; 222 } 223 224 ClearParameters State::getClearParameters(GLbitfield mask) const 225 { 226 ClearParameters clearParams = { 0 }; 227 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) 228 { 229 clearParams.clearColor[i] = false; 230 } 231 clearParams.colorFClearValue = mColorClearValue; 232 clearParams.colorClearType = GL_FLOAT; 233 clearParams.colorMaskRed = mBlend.colorMaskRed; 234 clearParams.colorMaskGreen = mBlend.colorMaskGreen; 235 clearParams.colorMaskBlue = mBlend.colorMaskBlue; 236 clearParams.colorMaskAlpha = mBlend.colorMaskAlpha; 237 clearParams.clearDepth = false; 238 clearParams.depthClearValue = mDepthClearValue; 239 clearParams.clearStencil = false; 240 clearParams.stencilClearValue = mStencilClearValue; 241 clearParams.stencilWriteMask = mDepthStencil.stencilWritemask; 242 clearParams.scissorEnabled = mScissorTest; 243 clearParams.scissor = mScissor; 244 245 const Framebuffer *framebufferObject = getDrawFramebuffer(); 246 if (mask & GL_COLOR_BUFFER_BIT) 247 { 248 if (framebufferObject->hasEnabledColorAttachment()) 249 { 250 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) 251 { 252 clearParams.clearColor[i] = true; 253 } 254 } 255 } 256 257 if (mask & GL_DEPTH_BUFFER_BIT) 258 { 259 if (mDepthStencil.depthMask && framebufferObject->getDepthbuffer() != NULL) 260 { 261 clearParams.clearDepth = true; 262 } 263 } 264 265 if (mask & GL_STENCIL_BUFFER_BIT) 266 { 267 if (framebufferObject->getStencilbuffer() != NULL) 268 { 269 GLenum stencilActualFormat = framebufferObject->getStencilbuffer()->getActualFormat(); 270 if (GetInternalFormatInfo(stencilActualFormat).stencilBits > 0) 271 { 272 clearParams.clearStencil = true; 273 } 274 } 275 } 276 277 return clearParams; 278 } 279 280 void State::setColorMask(bool red, bool green, bool blue, bool alpha) 281 { 282 mBlend.colorMaskRed = red; 283 mBlend.colorMaskGreen = green; 284 mBlend.colorMaskBlue = blue; 285 mBlend.colorMaskAlpha = alpha; 286 } 287 288 void State::setDepthMask(bool mask) 289 { 290 mDepthStencil.depthMask = mask; 291 } 292 293 bool State::isRasterizerDiscardEnabled() const 294 { 295 return mRasterizer.rasterizerDiscard; 296 } 297 298 void State::setRasterizerDiscard(bool enabled) 299 { 300 mRasterizer.rasterizerDiscard = enabled; 301 } 302 303 bool State::isCullFaceEnabled() const 304 { 305 return mRasterizer.cullFace; 306 } 307 308 void State::setCullFace(bool enabled) 309 { 310 mRasterizer.cullFace = enabled; 311 } 312 313 void State::setCullMode(GLenum mode) 314 { 315 mRasterizer.cullMode = mode; 316 } 317 318 void State::setFrontFace(GLenum front) 319 { 320 mRasterizer.frontFace = front; 321 } 322 323 bool State::isDepthTestEnabled() const 324 { 325 return mDepthStencil.depthTest; 326 } 327 328 void State::setDepthTest(bool enabled) 329 { 330 mDepthStencil.depthTest = enabled; 331 } 332 333 void State::setDepthFunc(GLenum depthFunc) 334 { 335 mDepthStencil.depthFunc = depthFunc; 336 } 337 338 void State::setDepthRange(float zNear, float zFar) 339 { 340 mNearZ = zNear; 341 mFarZ = zFar; 342 } 343 344 void State::getDepthRange(float *zNear, float *zFar) const 345 { 346 *zNear = mNearZ; 347 *zFar = mFarZ; 348 } 349 350 bool State::isBlendEnabled() const 351 { 352 return mBlend.blend; 353 } 354 355 void State::setBlend(bool enabled) 356 { 357 mBlend.blend = enabled; 358 } 359 360 void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha) 361 { 362 mBlend.sourceBlendRGB = sourceRGB; 363 mBlend.destBlendRGB = destRGB; 364 mBlend.sourceBlendAlpha = sourceAlpha; 365 mBlend.destBlendAlpha = destAlpha; 366 } 367 368 void State::setBlendColor(float red, float green, float blue, float alpha) 369 { 370 mBlendColor.red = red; 371 mBlendColor.green = green; 372 mBlendColor.blue = blue; 373 mBlendColor.alpha = alpha; 374 } 375 376 void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation) 377 { 378 mBlend.blendEquationRGB = rgbEquation; 379 mBlend.blendEquationAlpha = alphaEquation; 380 } 381 382 const ColorF &State::getBlendColor() const 383 { 384 return mBlendColor; 385 } 386 387 bool State::isStencilTestEnabled() const 388 { 389 return mDepthStencil.stencilTest; 390 } 391 392 void State::setStencilTest(bool enabled) 393 { 394 mDepthStencil.stencilTest = enabled; 395 } 396 397 void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask) 398 { 399 mDepthStencil.stencilFunc = stencilFunc; 400 mStencilRef = (stencilRef > 0) ? stencilRef : 0; 401 mDepthStencil.stencilMask = stencilMask; 402 } 403 404 void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask) 405 { 406 mDepthStencil.stencilBackFunc = stencilBackFunc; 407 mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0; 408 mDepthStencil.stencilBackMask = stencilBackMask; 409 } 410 411 void State::setStencilWritemask(GLuint stencilWritemask) 412 { 413 mDepthStencil.stencilWritemask = stencilWritemask; 414 } 415 416 void State::setStencilBackWritemask(GLuint stencilBackWritemask) 417 { 418 mDepthStencil.stencilBackWritemask = stencilBackWritemask; 419 } 420 421 void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass) 422 { 423 mDepthStencil.stencilFail = stencilFail; 424 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail; 425 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass; 426 } 427 428 void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass) 429 { 430 mDepthStencil.stencilBackFail = stencilBackFail; 431 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail; 432 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass; 433 } 434 435 GLint State::getStencilRef() const 436 { 437 return mStencilRef; 438 } 439 440 GLint State::getStencilBackRef() const 441 { 442 return mStencilBackRef; 443 } 444 445 bool State::isPolygonOffsetFillEnabled() const 446 { 447 return mRasterizer.polygonOffsetFill; 448 } 449 450 void State::setPolygonOffsetFill(bool enabled) 451 { 452 mRasterizer.polygonOffsetFill = enabled; 453 } 454 455 void State::setPolygonOffsetParams(GLfloat factor, GLfloat units) 456 { 457 // An application can pass NaN values here, so handle this gracefully 458 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor; 459 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units; 460 } 461 462 bool State::isSampleAlphaToCoverageEnabled() const 463 { 464 return mBlend.sampleAlphaToCoverage; 465 } 466 467 void State::setSampleAlphaToCoverage(bool enabled) 468 { 469 mBlend.sampleAlphaToCoverage = enabled; 470 } 471 472 bool State::isSampleCoverageEnabled() const 473 { 474 return mSampleCoverage; 475 } 476 477 void State::setSampleCoverage(bool enabled) 478 { 479 mSampleCoverage = enabled; 480 } 481 482 void State::setSampleCoverageParams(GLclampf value, bool invert) 483 { 484 mSampleCoverageValue = value; 485 mSampleCoverageInvert = invert; 486 } 487 488 void State::getSampleCoverageParams(GLclampf *value, bool *invert) 489 { 490 ASSERT(value != NULL && invert != NULL); 491 492 *value = mSampleCoverageValue; 493 *invert = mSampleCoverageInvert; 494 } 495 496 bool State::isScissorTestEnabled() const 497 { 498 return mScissorTest; 499 } 500 501 void State::setScissorTest(bool enabled) 502 { 503 mScissorTest = enabled; 504 } 505 506 void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height) 507 { 508 mScissor.x = x; 509 mScissor.y = y; 510 mScissor.width = width; 511 mScissor.height = height; 512 } 513 514 const Rectangle &State::getScissor() const 515 { 516 return mScissor; 517 } 518 519 bool State::isDitherEnabled() const 520 { 521 return mBlend.dither; 522 } 523 524 void State::setDither(bool enabled) 525 { 526 mBlend.dither = enabled; 527 } 528 529 void State::setEnableFeature(GLenum feature, bool enabled) 530 { 531 switch (feature) 532 { 533 case GL_CULL_FACE: setCullFace(enabled); break; 534 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break; 535 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break; 536 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break; 537 case GL_SCISSOR_TEST: setScissorTest(enabled); break; 538 case GL_STENCIL_TEST: setStencilTest(enabled); break; 539 case GL_DEPTH_TEST: setDepthTest(enabled); break; 540 case GL_BLEND: setBlend(enabled); break; 541 case GL_DITHER: setDither(enabled); break; 542 case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); break; 543 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break; 544 default: UNREACHABLE(); 545 } 546 } 547 548 bool State::getEnableFeature(GLenum feature) 549 { 550 switch (feature) 551 { 552 case GL_CULL_FACE: return isCullFaceEnabled(); 553 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled(); 554 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled(); 555 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled(); 556 case GL_SCISSOR_TEST: return isScissorTestEnabled(); 557 case GL_STENCIL_TEST: return isStencilTestEnabled(); 558 case GL_DEPTH_TEST: return isDepthTestEnabled(); 559 case GL_BLEND: return isBlendEnabled(); 560 case GL_DITHER: return isDitherEnabled(); 561 case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); return false; 562 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled(); 563 default: UNREACHABLE(); return false; 564 } 565 } 566 567 void State::setLineWidth(GLfloat width) 568 { 569 mLineWidth = width; 570 } 571 572 void State::setGenerateMipmapHint(GLenum hint) 573 { 574 mGenerateMipmapHint = hint; 575 } 576 577 void State::setFragmentShaderDerivativeHint(GLenum hint) 578 { 579 mFragmentShaderDerivativeHint = hint; 580 // TODO: Propagate the hint to shader translator so we can write 581 // ddx, ddx_coarse, or ddx_fine depending on the hint. 582 // Ignore for now. It is valid for implementations to ignore hint. 583 } 584 585 void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height) 586 { 587 mViewport.x = x; 588 mViewport.y = y; 589 mViewport.width = width; 590 mViewport.height = height; 591 } 592 593 const Rectangle &State::getViewport() const 594 { 595 return mViewport; 596 } 597 598 void State::setActiveSampler(unsigned int active) 599 { 600 mActiveSampler = active; 601 } 602 603 unsigned int State::getActiveSampler() const 604 { 605 return mActiveSampler; 606 } 607 608 void State::setSamplerTexture(GLenum type, Texture *texture) 609 { 610 mSamplerTextures[type][mActiveSampler].set(texture); 611 } 612 613 Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const 614 { 615 const BindingPointer<Texture>& binding = mSamplerTextures.at(type)[sampler]; 616 617 if (binding.id() == 0) // Special case: 0 refers to default textures held by Context 618 { 619 return NULL; 620 } 621 622 return binding.get(); 623 } 624 625 GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const 626 { 627 return mSamplerTextures.at(type)[sampler].id(); 628 } 629 630 void State::detachTexture(GLuint texture) 631 { 632 // Textures have a detach method on State rather than a simple 633 // removeBinding, because the zero/null texture objects are managed 634 // separately, and don't have to go through the Context's maps or 635 // the ResourceManager. 636 637 // [OpenGL ES 2.0.24] section 3.8 page 84: 638 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are 639 // rebound to texture object zero 640 641 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++) 642 { 643 TextureBindingVector &textureVector = bindingVec->second; 644 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++) 645 { 646 BindingPointer<Texture> &binding = textureVector[textureIdx]; 647 if (binding.id() == texture) 648 { 649 binding.set(NULL); 650 } 651 } 652 } 653 654 // [OpenGL ES 2.0.24] section 4.4 page 112: 655 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is 656 // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this 657 // image was attached in the currently bound framebuffer. 658 659 if (mReadFramebuffer) 660 { 661 mReadFramebuffer->detachTexture(texture); 662 } 663 664 if (mDrawFramebuffer) 665 { 666 mDrawFramebuffer->detachTexture(texture); 667 } 668 } 669 670 void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler) 671 { 672 mSamplers[textureUnit].set(sampler); 673 } 674 675 GLuint State::getSamplerId(GLuint textureUnit) const 676 { 677 ASSERT(textureUnit < mSamplers.size()); 678 return mSamplers[textureUnit].id(); 679 } 680 681 Sampler *State::getSampler(GLuint textureUnit) const 682 { 683 return mSamplers[textureUnit].get(); 684 } 685 686 void State::detachSampler(GLuint sampler) 687 { 688 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124: 689 // If a sampler object that is currently bound to one or more texture units is 690 // deleted, it is as though BindSampler is called once for each texture unit to 691 // which the sampler is bound, with unit set to the texture unit and sampler set to zero. 692 for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++) 693 { 694 BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit]; 695 if (samplerBinding.id() == sampler) 696 { 697 samplerBinding.set(NULL); 698 } 699 } 700 } 701 702 void State::setRenderbufferBinding(Renderbuffer *renderbuffer) 703 { 704 mRenderbuffer.set(renderbuffer); 705 } 706 707 GLuint State::getRenderbufferId() const 708 { 709 return mRenderbuffer.id(); 710 } 711 712 Renderbuffer *State::getCurrentRenderbuffer() 713 { 714 return mRenderbuffer.get(); 715 } 716 717 void State::detachRenderbuffer(GLuint renderbuffer) 718 { 719 // [OpenGL ES 2.0.24] section 4.4 page 109: 720 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer 721 // had been executed with the target RENDERBUFFER and name of zero. 722 723 if (mRenderbuffer.id() == renderbuffer) 724 { 725 mRenderbuffer.set(NULL); 726 } 727 728 // [OpenGL ES 2.0.24] section 4.4 page 111: 729 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer, 730 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment 731 // point to which this image was attached in the currently bound framebuffer. 732 733 Framebuffer *readFramebuffer = mReadFramebuffer; 734 Framebuffer *drawFramebuffer = mDrawFramebuffer; 735 736 if (readFramebuffer) 737 { 738 readFramebuffer->detachRenderbuffer(renderbuffer); 739 } 740 741 if (drawFramebuffer && drawFramebuffer != readFramebuffer) 742 { 743 drawFramebuffer->detachRenderbuffer(renderbuffer); 744 } 745 746 } 747 748 void State::setReadFramebufferBinding(Framebuffer *framebuffer) 749 { 750 mReadFramebuffer = framebuffer; 751 } 752 753 void State::setDrawFramebufferBinding(Framebuffer *framebuffer) 754 { 755 mDrawFramebuffer = framebuffer; 756 } 757 758 Framebuffer *State::getTargetFramebuffer(GLenum target) const 759 { 760 switch (target) 761 { 762 case GL_READ_FRAMEBUFFER_ANGLE: return mReadFramebuffer; 763 case GL_DRAW_FRAMEBUFFER_ANGLE: 764 case GL_FRAMEBUFFER: return mDrawFramebuffer; 765 default: UNREACHABLE(); return NULL; 766 } 767 } 768 769 Framebuffer *State::getReadFramebuffer() 770 { 771 return mReadFramebuffer; 772 } 773 774 Framebuffer *State::getDrawFramebuffer() 775 { 776 return mDrawFramebuffer; 777 } 778 779 const Framebuffer *State::getReadFramebuffer() const 780 { 781 return mReadFramebuffer; 782 } 783 784 const Framebuffer *State::getDrawFramebuffer() const 785 { 786 return mDrawFramebuffer; 787 } 788 789 bool State::removeReadFramebufferBinding(GLuint framebuffer) 790 { 791 if (mReadFramebuffer->id() == framebuffer) 792 { 793 mReadFramebuffer = NULL; 794 return true; 795 } 796 797 return false; 798 } 799 800 bool State::removeDrawFramebufferBinding(GLuint framebuffer) 801 { 802 if (mDrawFramebuffer->id() == framebuffer) 803 { 804 mDrawFramebuffer = NULL; 805 return true; 806 } 807 808 return false; 809 } 810 811 void State::setVertexArrayBinding(VertexArray *vertexArray) 812 { 813 mVertexArray = vertexArray; 814 } 815 816 GLuint State::getVertexArrayId() const 817 { 818 ASSERT(mVertexArray != NULL); 819 return mVertexArray->id(); 820 } 821 822 VertexArray *State::getVertexArray() const 823 { 824 ASSERT(mVertexArray != NULL); 825 return mVertexArray; 826 } 827 828 bool State::removeVertexArrayBinding(GLuint vertexArray) 829 { 830 if (mVertexArray->id() == vertexArray) 831 { 832 mVertexArray = NULL; 833 return true; 834 } 835 836 return false; 837 } 838 839 void State::setCurrentProgram(GLuint programId, Program *newProgram) 840 { 841 mCurrentProgramId = programId; // set new ID before trying to delete program binary; otherwise it will only be flagged for deletion 842 mCurrentProgramBinary.set(NULL); 843 844 if (newProgram) 845 { 846 newProgram->addRef(); 847 mCurrentProgramBinary.set(newProgram->getProgramBinary()); 848 } 849 } 850 851 void State::setCurrentProgramBinary(ProgramBinary *binary) 852 { 853 mCurrentProgramBinary.set(binary); 854 } 855 856 GLuint State::getCurrentProgramId() const 857 { 858 return mCurrentProgramId; 859 } 860 861 ProgramBinary *State::getCurrentProgramBinary() const 862 { 863 return mCurrentProgramBinary.get(); 864 } 865 866 void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback) 867 { 868 mTransformFeedback.set(transformFeedback); 869 } 870 871 TransformFeedback *State::getCurrentTransformFeedback() const 872 { 873 return mTransformFeedback.get(); 874 } 875 876 void State::detachTransformFeedback(GLuint transformFeedback) 877 { 878 if (mTransformFeedback.id() == transformFeedback) 879 { 880 mTransformFeedback.set(NULL); 881 } 882 } 883 884 bool State::isQueryActive() const 885 { 886 for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin(); 887 i != mActiveQueries.end(); i++) 888 { 889 if (i->second.get() != NULL) 890 { 891 return true; 892 } 893 } 894 895 return false; 896 } 897 898 void State::setActiveQuery(GLenum target, Query *query) 899 { 900 mActiveQueries[target].set(query); 901 } 902 903 GLuint State::getActiveQueryId(GLenum target) const 904 { 905 const Query *query = getActiveQuery(target); 906 return (query ? query->id() : 0u); 907 } 908 909 Query *State::getActiveQuery(GLenum target) const 910 { 911 // All query types should already exist in the activeQueries map 912 ASSERT(mActiveQueries.find(target) != mActiveQueries.end()); 913 914 return mActiveQueries.at(target).get(); 915 } 916 917 void State::setArrayBufferBinding(Buffer *buffer) 918 { 919 mArrayBuffer.set(buffer); 920 } 921 922 GLuint State::getArrayBufferId() const 923 { 924 return mArrayBuffer.id(); 925 } 926 927 bool State::removeArrayBufferBinding(GLuint buffer) 928 { 929 if (mArrayBuffer.id() == buffer) 930 { 931 mArrayBuffer.set(NULL); 932 return true; 933 } 934 935 return false; 936 } 937 938 void State::setGenericUniformBufferBinding(Buffer *buffer) 939 { 940 mGenericUniformBuffer.set(buffer); 941 } 942 943 void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size) 944 { 945 mUniformBuffers[index].set(buffer, offset, size); 946 } 947 948 GLuint State::getIndexedUniformBufferId(GLuint index) const 949 { 950 ASSERT(index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS); 951 952 return mUniformBuffers[index].id(); 953 } 954 955 Buffer *State::getIndexedUniformBuffer(GLuint index) const 956 { 957 ASSERT(index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS); 958 959 return mUniformBuffers[index].get(); 960 } 961 962 void State::setGenericTransformFeedbackBufferBinding(Buffer *buffer) 963 { 964 mGenericTransformFeedbackBuffer.set(buffer); 965 } 966 967 void State::setIndexedTransformFeedbackBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size) 968 { 969 mTransformFeedbackBuffers[index].set(buffer, offset, size); 970 } 971 972 GLuint State::getIndexedTransformFeedbackBufferId(GLuint index) const 973 { 974 ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS); 975 976 return mTransformFeedbackBuffers[index].id(); 977 } 978 979 Buffer *State::getIndexedTransformFeedbackBuffer(GLuint index) const 980 { 981 ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS); 982 983 return mTransformFeedbackBuffers[index].get(); 984 } 985 986 GLuint State::getIndexedTransformFeedbackBufferOffset(GLuint index) const 987 { 988 ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS); 989 990 return mTransformFeedbackBuffers[index].getOffset(); 991 } 992 993 void State::setCopyReadBufferBinding(Buffer *buffer) 994 { 995 mCopyReadBuffer.set(buffer); 996 } 997 998 void State::setCopyWriteBufferBinding(Buffer *buffer) 999 { 1000 mCopyWriteBuffer.set(buffer); 1001 } 1002 1003 void State::setPixelPackBufferBinding(Buffer *buffer) 1004 { 1005 mPack.pixelBuffer.set(buffer); 1006 } 1007 1008 void State::setPixelUnpackBufferBinding(Buffer *buffer) 1009 { 1010 mUnpack.pixelBuffer.set(buffer); 1011 } 1012 1013 Buffer *State::getTargetBuffer(GLenum target) const 1014 { 1015 switch (target) 1016 { 1017 case GL_ARRAY_BUFFER: return mArrayBuffer.get(); 1018 case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get(); 1019 case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get(); 1020 case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer(); 1021 case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get(); 1022 case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get(); 1023 case GL_TRANSFORM_FEEDBACK_BUFFER: return mGenericTransformFeedbackBuffer.get(); 1024 case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get(); 1025 default: UNREACHABLE(); return NULL; 1026 } 1027 } 1028 1029 void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled) 1030 { 1031 getVertexArray()->enableAttribute(attribNum, enabled); 1032 } 1033 1034 void State::setVertexAttribf(GLuint index, const GLfloat values[4]) 1035 { 1036 ASSERT(index < gl::MAX_VERTEX_ATTRIBS); 1037 mVertexAttribCurrentValues[index].setFloatValues(values); 1038 } 1039 1040 void State::setVertexAttribu(GLuint index, const GLuint values[4]) 1041 { 1042 ASSERT(index < gl::MAX_VERTEX_ATTRIBS); 1043 mVertexAttribCurrentValues[index].setUnsignedIntValues(values); 1044 } 1045 1046 void State::setVertexAttribi(GLuint index, const GLint values[4]) 1047 { 1048 ASSERT(index < gl::MAX_VERTEX_ATTRIBS); 1049 mVertexAttribCurrentValues[index].setIntValues(values); 1050 } 1051 1052 void State::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized, 1053 bool pureInteger, GLsizei stride, const void *pointer) 1054 { 1055 getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer); 1056 } 1057 1058 const VertexAttribute &State::getVertexAttribState(unsigned int attribNum) const 1059 { 1060 return getVertexArray()->getVertexAttribute(attribNum); 1061 } 1062 1063 const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const 1064 { 1065 ASSERT(attribNum < MAX_VERTEX_ATTRIBS); 1066 return mVertexAttribCurrentValues[attribNum]; 1067 } 1068 1069 const VertexAttribCurrentValueData *State::getVertexAttribCurrentValues() const 1070 { 1071 return mVertexAttribCurrentValues; 1072 } 1073 1074 const void *State::getVertexAttribPointer(unsigned int attribNum) const 1075 { 1076 return getVertexArray()->getVertexAttribute(attribNum).pointer; 1077 } 1078 1079 void State::setPackAlignment(GLint alignment) 1080 { 1081 mPack.alignment = alignment; 1082 } 1083 1084 GLint State::getPackAlignment() const 1085 { 1086 return mPack.alignment; 1087 } 1088 1089 void State::setPackReverseRowOrder(bool reverseRowOrder) 1090 { 1091 mPack.reverseRowOrder = reverseRowOrder; 1092 } 1093 1094 bool State::getPackReverseRowOrder() const 1095 { 1096 return mPack.reverseRowOrder; 1097 } 1098 1099 const PixelPackState &State::getPackState() const 1100 { 1101 return mPack; 1102 } 1103 1104 void State::setUnpackAlignment(GLint alignment) 1105 { 1106 mUnpack.alignment = alignment; 1107 } 1108 1109 GLint State::getUnpackAlignment() const 1110 { 1111 return mUnpack.alignment; 1112 } 1113 1114 const PixelUnpackState &State::getUnpackState() const 1115 { 1116 return mUnpack; 1117 } 1118 1119 void State::getBooleanv(GLenum pname, GLboolean *params) 1120 { 1121 switch (pname) 1122 { 1123 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break; 1124 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break; 1125 case GL_COLOR_WRITEMASK: 1126 params[0] = mBlend.colorMaskRed; 1127 params[1] = mBlend.colorMaskGreen; 1128 params[2] = mBlend.colorMaskBlue; 1129 params[3] = mBlend.colorMaskAlpha; 1130 break; 1131 case GL_CULL_FACE: *params = mRasterizer.cullFace; break; 1132 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break; 1133 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break; 1134 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break; 1135 case GL_SCISSOR_TEST: *params = mScissorTest; break; 1136 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break; 1137 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break; 1138 case GL_BLEND: *params = mBlend.blend; break; 1139 case GL_DITHER: *params = mBlend.dither; break; 1140 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isStarted(); break; 1141 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused(); break; 1142 default: 1143 UNREACHABLE(); 1144 break; 1145 } 1146 } 1147 1148 void State::getFloatv(GLenum pname, GLfloat *params) 1149 { 1150 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation 1151 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names 1152 // GetIntegerv as its native query function. As it would require conversion in any 1153 // case, this should make no difference to the calling application. 1154 switch (pname) 1155 { 1156 case GL_LINE_WIDTH: *params = mLineWidth; break; 1157 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break; 1158 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break; 1159 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break; 1160 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break; 1161 case GL_DEPTH_RANGE: 1162 params[0] = mNearZ; 1163 params[1] = mFarZ; 1164 break; 1165 case GL_COLOR_CLEAR_VALUE: 1166 params[0] = mColorClearValue.red; 1167 params[1] = mColorClearValue.green; 1168 params[2] = mColorClearValue.blue; 1169 params[3] = mColorClearValue.alpha; 1170 break; 1171 case GL_BLEND_COLOR: 1172 params[0] = mBlendColor.red; 1173 params[1] = mBlendColor.green; 1174 params[2] = mBlendColor.blue; 1175 params[3] = mBlendColor.alpha; 1176 break; 1177 default: 1178 UNREACHABLE(); 1179 break; 1180 } 1181 } 1182 1183 void State::getIntegerv(GLenum pname, GLint *params) 1184 { 1185 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT) 1186 { 1187 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT); 1188 ASSERT(colorAttachment < mContext->getCaps().maxDrawBuffers); 1189 Framebuffer *framebuffer = mDrawFramebuffer; 1190 *params = framebuffer->getDrawBufferState(colorAttachment); 1191 return; 1192 } 1193 1194 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation 1195 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names 1196 // GetIntegerv as its native query function. As it would require conversion in any 1197 // case, this should make no difference to the calling application. You may find it in 1198 // State::getFloatv. 1199 switch (pname) 1200 { 1201 case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break; 1202 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBufferId(); break; 1203 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 1204 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break; 1205 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break; 1206 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break; 1207 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break; 1208 case GL_CURRENT_PROGRAM: *params = mCurrentProgramId; break; 1209 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break; 1210 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break; 1211 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break; 1212 case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break; 1213 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break; 1214 case GL_ACTIVE_TEXTURE: *params = (mActiveSampler + GL_TEXTURE0); break; 1215 case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break; 1216 case GL_STENCIL_REF: *params = mStencilRef; break; 1217 case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break; 1218 case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break; 1219 case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break; 1220 case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break; 1221 case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break; 1222 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break; 1223 case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break; 1224 case GL_STENCIL_BACK_FAIL: *params = mDepthStencil.stencilBackFail; break; 1225 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilBackPassDepthFail; break; 1226 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mDepthStencil.stencilBackPassDepthPass; break; 1227 case GL_DEPTH_FUNC: *params = mDepthStencil.depthFunc; break; 1228 case GL_BLEND_SRC_RGB: *params = mBlend.sourceBlendRGB; break; 1229 case GL_BLEND_SRC_ALPHA: *params = mBlend.sourceBlendAlpha; break; 1230 case GL_BLEND_DST_RGB: *params = mBlend.destBlendRGB; break; 1231 case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break; 1232 case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break; 1233 case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break; 1234 case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break; 1235 case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break; 1236 case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break; 1237 case GL_SAMPLE_BUFFERS: 1238 case GL_SAMPLES: 1239 { 1240 gl::Framebuffer *framebuffer = mDrawFramebuffer; 1241 if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE) 1242 { 1243 switch (pname) 1244 { 1245 case GL_SAMPLE_BUFFERS: 1246 if (framebuffer->getSamples() != 0) 1247 { 1248 *params = 1; 1249 } 1250 else 1251 { 1252 *params = 0; 1253 } 1254 break; 1255 case GL_SAMPLES: 1256 *params = framebuffer->getSamples(); 1257 break; 1258 } 1259 } 1260 else 1261 { 1262 *params = 0; 1263 } 1264 } 1265 break; 1266 case GL_VIEWPORT: 1267 params[0] = mViewport.x; 1268 params[1] = mViewport.y; 1269 params[2] = mViewport.width; 1270 params[3] = mViewport.height; 1271 break; 1272 case GL_SCISSOR_BOX: 1273 params[0] = mScissor.x; 1274 params[1] = mScissor.y; 1275 params[2] = mScissor.width; 1276 params[3] = mScissor.height; 1277 break; 1278 case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break; 1279 case GL_FRONT_FACE: *params = mRasterizer.frontFace; break; 1280 case GL_RED_BITS: 1281 case GL_GREEN_BITS: 1282 case GL_BLUE_BITS: 1283 case GL_ALPHA_BITS: 1284 { 1285 gl::Framebuffer *framebuffer = getDrawFramebuffer(); 1286 gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer(); 1287 1288 if (colorbuffer) 1289 { 1290 switch (pname) 1291 { 1292 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break; 1293 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break; 1294 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break; 1295 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break; 1296 } 1297 } 1298 else 1299 { 1300 *params = 0; 1301 } 1302 } 1303 break; 1304 case GL_DEPTH_BITS: 1305 { 1306 gl::Framebuffer *framebuffer = getDrawFramebuffer(); 1307 gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer(); 1308 1309 if (depthbuffer) 1310 { 1311 *params = depthbuffer->getDepthSize(); 1312 } 1313 else 1314 { 1315 *params = 0; 1316 } 1317 } 1318 break; 1319 case GL_STENCIL_BITS: 1320 { 1321 gl::Framebuffer *framebuffer = getDrawFramebuffer(); 1322 gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer(); 1323 1324 if (stencilbuffer) 1325 { 1326 *params = stencilbuffer->getStencilSize(); 1327 } 1328 else 1329 { 1330 *params = 0; 1331 } 1332 } 1333 break; 1334 case GL_TEXTURE_BINDING_2D: 1335 ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits); 1336 *params = mSamplerTextures.at(GL_TEXTURE_2D)[mActiveSampler].id(); 1337 break; 1338 case GL_TEXTURE_BINDING_CUBE_MAP: 1339 ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits); 1340 *params = mSamplerTextures.at(GL_TEXTURE_CUBE_MAP)[mActiveSampler].id(); 1341 break; 1342 case GL_TEXTURE_BINDING_3D: 1343 ASSERT(mActiveSampler <mContext->getCaps().maxCombinedTextureImageUnits); 1344 *params = mSamplerTextures.at(GL_TEXTURE_3D)[mActiveSampler].id(); 1345 break; 1346 case GL_TEXTURE_BINDING_2D_ARRAY: 1347 ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits); 1348 *params = mSamplerTextures.at(GL_TEXTURE_2D_ARRAY)[mActiveSampler].id(); 1349 break; 1350 case GL_UNIFORM_BUFFER_BINDING: 1351 *params = mGenericUniformBuffer.id(); 1352 break; 1353 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: 1354 *params = mGenericTransformFeedbackBuffer.id(); 1355 break; 1356 case GL_COPY_READ_BUFFER_BINDING: 1357 *params = mCopyReadBuffer.id(); 1358 break; 1359 case GL_COPY_WRITE_BUFFER_BINDING: 1360 *params = mCopyWriteBuffer.id(); 1361 break; 1362 case GL_PIXEL_PACK_BUFFER_BINDING: 1363 *params = mPack.pixelBuffer.id(); 1364 break; 1365 case GL_PIXEL_UNPACK_BUFFER_BINDING: 1366 *params = mUnpack.pixelBuffer.id(); 1367 break; 1368 default: 1369 UNREACHABLE(); 1370 break; 1371 } 1372 } 1373 1374 bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data) 1375 { 1376 switch (target) 1377 { 1378 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: 1379 if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS) 1380 { 1381 *data = mTransformFeedbackBuffers[index].id(); 1382 } 1383 break; 1384 case GL_UNIFORM_BUFFER_BINDING: 1385 if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS) 1386 { 1387 *data = mUniformBuffers[index].id(); 1388 } 1389 break; 1390 default: 1391 return false; 1392 } 1393 1394 return true; 1395 } 1396 1397 bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data) 1398 { 1399 switch (target) 1400 { 1401 case GL_TRANSFORM_FEEDBACK_BUFFER_START: 1402 if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS) 1403 { 1404 *data = mTransformFeedbackBuffers[index].getOffset(); 1405 } 1406 break; 1407 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: 1408 if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS) 1409 { 1410 *data = mTransformFeedbackBuffers[index].getSize(); 1411 } 1412 break; 1413 case GL_UNIFORM_BUFFER_START: 1414 if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS) 1415 { 1416 *data = mUniformBuffers[index].getOffset(); 1417 } 1418 break; 1419 case GL_UNIFORM_BUFFER_SIZE: 1420 if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS) 1421 { 1422 *data = mUniformBuffers[index].getSize(); 1423 } 1424 break; 1425 default: 1426 return false; 1427 } 1428 1429 return true; 1430 } 1431 1432 bool State::hasMappedBuffer(GLenum target) const 1433 { 1434 if (target == GL_ARRAY_BUFFER) 1435 { 1436 for (unsigned int attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++) 1437 { 1438 const gl::VertexAttribute &vertexAttrib = getVertexAttribState(attribIndex); 1439 gl::Buffer *boundBuffer = vertexAttrib.buffer.get(); 1440 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped()) 1441 { 1442 return true; 1443 } 1444 } 1445 1446 return false; 1447 } 1448 else 1449 { 1450 Buffer *buffer = getTargetBuffer(target); 1451 return (buffer && buffer->isMapped()); 1452 } 1453 } 1454 1455 } 1456