Context.cpp revision 2d234afa7ac85f8d88491035da551efc61f16892
1// SwiftShader Software Renderer 2// 3// Copyright(c) 2005-2013 TransGaming Inc. 4// 5// All rights reserved. No part of this software may be copied, distributed, transmitted, 6// transcribed, stored in a retrieval system, translated into any human or computer 7// language by any means, or disclosed to third parties without the explicit written 8// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express 9// or implied, including but not limited to any patent rights, are granted to you. 10// 11 12// Context.cpp: Implements the es2::Context class, managing all GL state and performing 13// rendering operations. It is the GLES2 specific implementation of EGLContext. 14 15#include "Context.h" 16 17#include "main.h" 18#include "mathutil.h" 19#include "utilities.h" 20#include "ResourceManager.h" 21#include "Buffer.h" 22#include "Fence.h" 23#include "Framebuffer.h" 24#include "Program.h" 25#include "Query.h" 26#include "Renderbuffer.h" 27#include "Sampler.h" 28#include "Shader.h" 29#include "Texture.h" 30#include "TransformFeedback.h" 31#include "VertexArray.h" 32#include "VertexDataManager.h" 33#include "IndexDataManager.h" 34#include "libEGL/Display.h" 35#include "libEGL/Surface.h" 36#include "Common/Half.hpp" 37 38#include <EGL/eglext.h> 39 40#undef near 41#undef far 42 43namespace es2 44{ 45Context::Context(const egl::Config *config, const Context *shareContext, EGLint clientVersion) 46 : mConfig(config), clientVersion(clientVersion) 47{ 48 sw::Context *context = new sw::Context(); 49 device = new es2::Device(context); 50 51 mFenceNameSpace.setBaseHandle(0); 52 53 setClearColor(0.0f, 0.0f, 0.0f, 0.0f); 54 55 mState.depthClearValue = 1.0f; 56 mState.stencilClearValue = 0; 57 58 mState.cullFace = false; 59 mState.cullMode = GL_BACK; 60 mState.frontFace = GL_CCW; 61 mState.depthTest = false; 62 mState.depthFunc = GL_LESS; 63 mState.blend = false; 64 mState.sourceBlendRGB = GL_ONE; 65 mState.sourceBlendAlpha = GL_ONE; 66 mState.destBlendRGB = GL_ZERO; 67 mState.destBlendAlpha = GL_ZERO; 68 mState.blendEquationRGB = GL_FUNC_ADD; 69 mState.blendEquationAlpha = GL_FUNC_ADD; 70 mState.blendColor.red = 0; 71 mState.blendColor.green = 0; 72 mState.blendColor.blue = 0; 73 mState.blendColor.alpha = 0; 74 mState.stencilTest = false; 75 mState.stencilFunc = GL_ALWAYS; 76 mState.stencilRef = 0; 77 mState.stencilMask = -1; 78 mState.stencilWritemask = -1; 79 mState.stencilBackFunc = GL_ALWAYS; 80 mState.stencilBackRef = 0; 81 mState.stencilBackMask = - 1; 82 mState.stencilBackWritemask = -1; 83 mState.stencilFail = GL_KEEP; 84 mState.stencilPassDepthFail = GL_KEEP; 85 mState.stencilPassDepthPass = GL_KEEP; 86 mState.stencilBackFail = GL_KEEP; 87 mState.stencilBackPassDepthFail = GL_KEEP; 88 mState.stencilBackPassDepthPass = GL_KEEP; 89 mState.polygonOffsetFill = false; 90 mState.polygonOffsetFactor = 0.0f; 91 mState.polygonOffsetUnits = 0.0f; 92 mState.sampleAlphaToCoverage = false; 93 mState.sampleCoverage = false; 94 mState.sampleCoverageValue = 1.0f; 95 mState.sampleCoverageInvert = false; 96 mState.scissorTest = false; 97 mState.dither = true; 98 mState.primitiveRestartFixedIndex = false; 99 mState.rasterizerDiscard = false; 100 mState.generateMipmapHint = GL_DONT_CARE; 101 mState.fragmentShaderDerivativeHint = GL_DONT_CARE; 102 103 mState.lineWidth = 1.0f; 104 105 mState.viewportX = 0; 106 mState.viewportY = 0; 107 mState.viewportWidth = config->mDisplayMode.width; 108 mState.viewportHeight = config->mDisplayMode.height; 109 mState.zNear = 0.0f; 110 mState.zFar = 1.0f; 111 112 mState.scissorX = 0; 113 mState.scissorY = 0; 114 mState.scissorWidth = config->mDisplayMode.width; 115 mState.scissorHeight = config->mDisplayMode.height; 116 117 mState.colorMaskRed = true; 118 mState.colorMaskGreen = true; 119 mState.colorMaskBlue = true; 120 mState.colorMaskAlpha = true; 121 mState.depthMask = true; 122 123 if(shareContext != NULL) 124 { 125 mResourceManager = shareContext->mResourceManager; 126 mResourceManager->addRef(); 127 } 128 else 129 { 130 mResourceManager = new ResourceManager(); 131 } 132 133 // [OpenGL ES 2.0.24] section 3.7 page 83: 134 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional 135 // and cube map texture state vectors respectively associated with them. 136 // In order that access to these initial textures not be lost, they are treated as texture 137 // objects all of whose names are 0. 138 139 mTexture2DZero = new Texture2D(0); 140 mTexture3DZero = new Texture3D(0); 141 mTextureCubeMapZero = new TextureCubeMap(0); 142 mTextureExternalZero = new TextureExternal(0); 143 144 mState.transformFeedback = new TransformFeedback(0); 145 mTransformFeedbackMap[0] = mState.transformFeedback; 146 147 mState.activeSampler = 0; 148 bindArrayBuffer(0); 149 bindElementArrayBuffer(0); 150 bindTextureCubeMap(0); 151 bindTexture2D(0); 152 bindReadFramebuffer(0); 153 bindDrawFramebuffer(0); 154 bindRenderbuffer(0); 155 156 mState.currentProgram = 0; 157 158 mState.packAlignment = 4; 159 mState.unpackAlignment = 4; 160 161 mVertexDataManager = NULL; 162 mIndexDataManager = NULL; 163 164 mInvalidEnum = false; 165 mInvalidValue = false; 166 mInvalidOperation = false; 167 mOutOfMemory = false; 168 mInvalidFramebufferOperation = false; 169 170 mHasBeenCurrent = false; 171 172 markAllStateDirty(); 173} 174 175Context::~Context() 176{ 177 if(mState.currentProgram != 0) 178 { 179 Program *programObject = mResourceManager->getProgram(mState.currentProgram); 180 if(programObject) 181 { 182 programObject->release(); 183 } 184 mState.currentProgram = 0; 185 } 186 187 while(!mFramebufferMap.empty()) 188 { 189 deleteFramebuffer(mFramebufferMap.begin()->first); 190 } 191 192 while(!mFenceMap.empty()) 193 { 194 deleteFence(mFenceMap.begin()->first); 195 } 196 197 while(!mQueryMap.empty()) 198 { 199 deleteQuery(mQueryMap.begin()->first); 200 } 201 202 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++) 203 { 204 for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++) 205 { 206 mState.samplerTexture[type][sampler] = NULL; 207 } 208 } 209 210 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 211 { 212 mState.vertexAttribute[i].mBoundBuffer = NULL; 213 } 214 215 for(int i = 0; i < QUERY_TYPE_COUNT; i++) 216 { 217 mState.activeQuery[i] = NULL; 218 } 219 220 mState.arrayBuffer = NULL; 221 mState.elementArrayBuffer = NULL; 222 mState.renderbuffer = NULL; 223 224 mTexture2DZero = NULL; 225 mTexture3DZero = NULL; 226 mTextureCubeMapZero = NULL; 227 mTextureExternalZero = NULL; 228 229 delete mVertexDataManager; 230 delete mIndexDataManager; 231 232 mResourceManager->release(); 233 delete device; 234} 235 236void Context::makeCurrent(egl::Surface *surface) 237{ 238 if(!mHasBeenCurrent) 239 { 240 mVertexDataManager = new VertexDataManager(this); 241 mIndexDataManager = new IndexDataManager(); 242 243 mState.viewportX = 0; 244 mState.viewportY = 0; 245 mState.viewportWidth = surface->getWidth(); 246 mState.viewportHeight = surface->getHeight(); 247 248 mState.scissorX = 0; 249 mState.scissorY = 0; 250 mState.scissorWidth = surface->getWidth(); 251 mState.scissorHeight = surface->getHeight(); 252 253 mHasBeenCurrent = true; 254 } 255 256 // Wrap the existing resources into GL objects and assign them to the '0' names 257 egl::Image *defaultRenderTarget = surface->getRenderTarget(); 258 egl::Image *depthStencil = surface->getDepthStencil(); 259 260 Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget); 261 DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil); 262 Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero); 263 264 setFramebufferZero(framebufferZero); 265 266 if(defaultRenderTarget) 267 { 268 defaultRenderTarget->release(); 269 } 270 271 if(depthStencil) 272 { 273 depthStencil->release(); 274 } 275 276 markAllStateDirty(); 277} 278 279void Context::destroy() 280{ 281 delete this; 282} 283 284EGLint Context::getClientVersion() 285{ 286 return clientVersion; 287} 288 289// This function will set all of the state-related dirty flags, so that all state is set during next pre-draw. 290void Context::markAllStateDirty() 291{ 292 mAppliedProgramSerial = 0; 293 294 mDepthStateDirty = true; 295 mMaskStateDirty = true; 296 mBlendStateDirty = true; 297 mStencilStateDirty = true; 298 mPolygonOffsetStateDirty = true; 299 mSampleStateDirty = true; 300 mDitherStateDirty = true; 301 mFrontFaceDirty = true; 302} 303 304void Context::setClearColor(float red, float green, float blue, float alpha) 305{ 306 mState.colorClearValue.red = red; 307 mState.colorClearValue.green = green; 308 mState.colorClearValue.blue = blue; 309 mState.colorClearValue.alpha = alpha; 310} 311 312void Context::setClearDepth(float depth) 313{ 314 mState.depthClearValue = depth; 315} 316 317void Context::setClearStencil(int stencil) 318{ 319 mState.stencilClearValue = stencil; 320} 321 322void Context::setCullFace(bool enabled) 323{ 324 mState.cullFace = enabled; 325} 326 327bool Context::isCullFaceEnabled() const 328{ 329 return mState.cullFace; 330} 331 332void Context::setCullMode(GLenum mode) 333{ 334 mState.cullMode = mode; 335} 336 337void Context::setFrontFace(GLenum front) 338{ 339 if(mState.frontFace != front) 340 { 341 mState.frontFace = front; 342 mFrontFaceDirty = true; 343 } 344} 345 346void Context::setDepthTest(bool enabled) 347{ 348 if(mState.depthTest != enabled) 349 { 350 mState.depthTest = enabled; 351 mDepthStateDirty = true; 352 } 353} 354 355bool Context::isDepthTestEnabled() const 356{ 357 return mState.depthTest; 358} 359 360void Context::setDepthFunc(GLenum depthFunc) 361{ 362 if(mState.depthFunc != depthFunc) 363 { 364 mState.depthFunc = depthFunc; 365 mDepthStateDirty = true; 366 } 367} 368 369void Context::setDepthRange(float zNear, float zFar) 370{ 371 mState.zNear = zNear; 372 mState.zFar = zFar; 373} 374 375void Context::setBlend(bool enabled) 376{ 377 if(mState.blend != enabled) 378 { 379 mState.blend = enabled; 380 mBlendStateDirty = true; 381 } 382} 383 384bool Context::isBlendEnabled() const 385{ 386 return mState.blend; 387} 388 389void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha) 390{ 391 if(mState.sourceBlendRGB != sourceRGB || 392 mState.sourceBlendAlpha != sourceAlpha || 393 mState.destBlendRGB != destRGB || 394 mState.destBlendAlpha != destAlpha) 395 { 396 mState.sourceBlendRGB = sourceRGB; 397 mState.destBlendRGB = destRGB; 398 mState.sourceBlendAlpha = sourceAlpha; 399 mState.destBlendAlpha = destAlpha; 400 mBlendStateDirty = true; 401 } 402} 403 404void Context::setBlendColor(float red, float green, float blue, float alpha) 405{ 406 if(mState.blendColor.red != red || 407 mState.blendColor.green != green || 408 mState.blendColor.blue != blue || 409 mState.blendColor.alpha != alpha) 410 { 411 mState.blendColor.red = red; 412 mState.blendColor.green = green; 413 mState.blendColor.blue = blue; 414 mState.blendColor.alpha = alpha; 415 mBlendStateDirty = true; 416 } 417} 418 419void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation) 420{ 421 if(mState.blendEquationRGB != rgbEquation || 422 mState.blendEquationAlpha != alphaEquation) 423 { 424 mState.blendEquationRGB = rgbEquation; 425 mState.blendEquationAlpha = alphaEquation; 426 mBlendStateDirty = true; 427 } 428} 429 430void Context::setStencilTest(bool enabled) 431{ 432 if(mState.stencilTest != enabled) 433 { 434 mState.stencilTest = enabled; 435 mStencilStateDirty = true; 436 } 437} 438 439bool Context::isStencilTestEnabled() const 440{ 441 return mState.stencilTest; 442} 443 444void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask) 445{ 446 if(mState.stencilFunc != stencilFunc || 447 mState.stencilRef != stencilRef || 448 mState.stencilMask != stencilMask) 449 { 450 mState.stencilFunc = stencilFunc; 451 mState.stencilRef = (stencilRef > 0) ? stencilRef : 0; 452 mState.stencilMask = stencilMask; 453 mStencilStateDirty = true; 454 } 455} 456 457void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask) 458{ 459 if(mState.stencilBackFunc != stencilBackFunc || 460 mState.stencilBackRef != stencilBackRef || 461 mState.stencilBackMask != stencilBackMask) 462 { 463 mState.stencilBackFunc = stencilBackFunc; 464 mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0; 465 mState.stencilBackMask = stencilBackMask; 466 mStencilStateDirty = true; 467 } 468} 469 470void Context::setStencilWritemask(GLuint stencilWritemask) 471{ 472 if(mState.stencilWritemask != stencilWritemask) 473 { 474 mState.stencilWritemask = stencilWritemask; 475 mStencilStateDirty = true; 476 } 477} 478 479void Context::setStencilBackWritemask(GLuint stencilBackWritemask) 480{ 481 if(mState.stencilBackWritemask != stencilBackWritemask) 482 { 483 mState.stencilBackWritemask = stencilBackWritemask; 484 mStencilStateDirty = true; 485 } 486} 487 488void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass) 489{ 490 if(mState.stencilFail != stencilFail || 491 mState.stencilPassDepthFail != stencilPassDepthFail || 492 mState.stencilPassDepthPass != stencilPassDepthPass) 493 { 494 mState.stencilFail = stencilFail; 495 mState.stencilPassDepthFail = stencilPassDepthFail; 496 mState.stencilPassDepthPass = stencilPassDepthPass; 497 mStencilStateDirty = true; 498 } 499} 500 501void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass) 502{ 503 if(mState.stencilBackFail != stencilBackFail || 504 mState.stencilBackPassDepthFail != stencilBackPassDepthFail || 505 mState.stencilBackPassDepthPass != stencilBackPassDepthPass) 506 { 507 mState.stencilBackFail = stencilBackFail; 508 mState.stencilBackPassDepthFail = stencilBackPassDepthFail; 509 mState.stencilBackPassDepthPass = stencilBackPassDepthPass; 510 mStencilStateDirty = true; 511 } 512} 513 514void Context::setPolygonOffsetFill(bool enabled) 515{ 516 if(mState.polygonOffsetFill != enabled) 517 { 518 mState.polygonOffsetFill = enabled; 519 mPolygonOffsetStateDirty = true; 520 } 521} 522 523bool Context::isPolygonOffsetFillEnabled() const 524{ 525 return mState.polygonOffsetFill; 526} 527 528void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units) 529{ 530 if(mState.polygonOffsetFactor != factor || 531 mState.polygonOffsetUnits != units) 532 { 533 mState.polygonOffsetFactor = factor; 534 mState.polygonOffsetUnits = units; 535 mPolygonOffsetStateDirty = true; 536 } 537} 538 539void Context::setSampleAlphaToCoverage(bool enabled) 540{ 541 if(mState.sampleAlphaToCoverage != enabled) 542 { 543 mState.sampleAlphaToCoverage = enabled; 544 mSampleStateDirty = true; 545 } 546} 547 548bool Context::isSampleAlphaToCoverageEnabled() const 549{ 550 return mState.sampleAlphaToCoverage; 551} 552 553void Context::setSampleCoverage(bool enabled) 554{ 555 if(mState.sampleCoverage != enabled) 556 { 557 mState.sampleCoverage = enabled; 558 mSampleStateDirty = true; 559 } 560} 561 562bool Context::isSampleCoverageEnabled() const 563{ 564 return mState.sampleCoverage; 565} 566 567void Context::setSampleCoverageParams(GLclampf value, bool invert) 568{ 569 if(mState.sampleCoverageValue != value || 570 mState.sampleCoverageInvert != invert) 571 { 572 mState.sampleCoverageValue = value; 573 mState.sampleCoverageInvert = invert; 574 mSampleStateDirty = true; 575 } 576} 577 578void Context::setScissorTest(bool enabled) 579{ 580 mState.scissorTest = enabled; 581} 582 583bool Context::isScissorTestEnabled() const 584{ 585 return mState.scissorTest; 586} 587 588void Context::setDither(bool enabled) 589{ 590 if(mState.dither != enabled) 591 { 592 mState.dither = enabled; 593 mDitherStateDirty = true; 594 } 595} 596 597bool Context::isDitherEnabled() const 598{ 599 return mState.dither; 600} 601 602void Context::setPrimitiveRestartFixedIndex(bool enabled) 603{ 604 UNIMPLEMENTED(); 605 mState.primitiveRestartFixedIndex = enabled; 606} 607 608bool Context::isPrimitiveRestartFixedIndexEnabled() const 609{ 610 return mState.primitiveRestartFixedIndex; 611} 612 613void Context::setRasterizerDiscard(bool enabled) 614{ 615 UNIMPLEMENTED(); 616 mState.rasterizerDiscard = enabled; 617} 618 619bool Context::isRasterizerDiscardEnabled() const 620{ 621 return mState.rasterizerDiscard; 622} 623 624void Context::setLineWidth(GLfloat width) 625{ 626 mState.lineWidth = width; 627 device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX)); 628} 629 630void Context::setGenerateMipmapHint(GLenum hint) 631{ 632 mState.generateMipmapHint = hint; 633} 634 635void Context::setFragmentShaderDerivativeHint(GLenum hint) 636{ 637 mState.fragmentShaderDerivativeHint = hint; 638 // TODO: Propagate the hint to shader translator so we can write 639 // ddx, ddx_coarse, or ddx_fine depending on the hint. 640 // Ignore for now. It is valid for implementations to ignore hint. 641} 642 643void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height) 644{ 645 mState.viewportX = x; 646 mState.viewportY = y; 647 mState.viewportWidth = width; 648 mState.viewportHeight = height; 649} 650 651void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height) 652{ 653 mState.scissorX = x; 654 mState.scissorY = y; 655 mState.scissorWidth = width; 656 mState.scissorHeight = height; 657} 658 659void Context::setColorMask(bool red, bool green, bool blue, bool alpha) 660{ 661 if(mState.colorMaskRed != red || mState.colorMaskGreen != green || 662 mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha) 663 { 664 mState.colorMaskRed = red; 665 mState.colorMaskGreen = green; 666 mState.colorMaskBlue = blue; 667 mState.colorMaskAlpha = alpha; 668 mMaskStateDirty = true; 669 } 670} 671 672void Context::setDepthMask(bool mask) 673{ 674 if(mState.depthMask != mask) 675 { 676 mState.depthMask = mask; 677 mMaskStateDirty = true; 678 } 679} 680 681void Context::setActiveSampler(unsigned int active) 682{ 683 mState.activeSampler = active; 684} 685 686GLuint Context::getReadFramebufferName() const 687{ 688 return mState.readFramebuffer; 689} 690 691GLuint Context::getDrawFramebufferName() const 692{ 693 return mState.drawFramebuffer; 694} 695 696GLuint Context::getRenderbufferName() const 697{ 698 return mState.renderbuffer.name(); 699} 700 701GLuint Context::getArrayBufferName() const 702{ 703 return mState.arrayBuffer.name(); 704} 705 706GLuint Context::getActiveQuery(GLenum target) const 707{ 708 Query *queryObject = NULL; 709 710 switch(target) 711 { 712 case GL_ANY_SAMPLES_PASSED_EXT: 713 queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED]; 714 break; 715 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: 716 queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE]; 717 break; 718 default: 719 ASSERT(false); 720 } 721 722 if(queryObject) 723 { 724 return queryObject->name; 725 } 726 727 return 0; 728} 729 730void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled) 731{ 732 mState.vertexAttribute[attribNum].mArrayEnabled = enabled; 733} 734 735const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) 736{ 737 return mState.vertexAttribute[attribNum]; 738} 739 740void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized, 741 GLsizei stride, const void *pointer) 742{ 743 mState.vertexAttribute[attribNum].mBoundBuffer = boundBuffer; 744 mState.vertexAttribute[attribNum].mSize = size; 745 mState.vertexAttribute[attribNum].mType = type; 746 mState.vertexAttribute[attribNum].mNormalized = normalized; 747 mState.vertexAttribute[attribNum].mStride = stride; 748 mState.vertexAttribute[attribNum].mPointer = pointer; 749} 750 751const void *Context::getVertexAttribPointer(unsigned int attribNum) const 752{ 753 return mState.vertexAttribute[attribNum].mPointer; 754} 755 756const VertexAttributeArray &Context::getVertexAttributes() 757{ 758 return mState.vertexAttribute; 759} 760 761void Context::setPackAlignment(GLint alignment) 762{ 763 mState.packAlignment = alignment; 764} 765 766GLint Context::getPackAlignment() const 767{ 768 return mState.packAlignment; 769} 770 771void Context::setUnpackAlignment(GLint alignment) 772{ 773 mState.unpackAlignment = alignment; 774} 775 776GLint Context::getUnpackAlignment() const 777{ 778 return mState.unpackAlignment; 779} 780 781GLuint Context::createBuffer() 782{ 783 return mResourceManager->createBuffer(); 784} 785 786GLuint Context::createProgram() 787{ 788 return mResourceManager->createProgram(); 789} 790 791GLuint Context::createShader(GLenum type) 792{ 793 return mResourceManager->createShader(type); 794} 795 796GLuint Context::createTexture() 797{ 798 return mResourceManager->createTexture(); 799} 800 801GLuint Context::createRenderbuffer() 802{ 803 return mResourceManager->createRenderbuffer(); 804} 805 806// Returns an unused framebuffer name 807GLuint Context::createFramebuffer() 808{ 809 GLuint handle = mFramebufferNameSpace.allocate(); 810 811 mFramebufferMap[handle] = NULL; 812 813 return handle; 814} 815 816GLuint Context::createFence() 817{ 818 GLuint handle = mFenceNameSpace.allocate(); 819 820 mFenceMap[handle] = new Fence; 821 822 return handle; 823} 824 825// Returns an unused query name 826GLuint Context::createQuery() 827{ 828 GLuint handle = mQueryNameSpace.allocate(); 829 830 mQueryMap[handle] = NULL; 831 832 return handle; 833} 834 835// Returns an unused vertex array name 836GLuint Context::createVertexArray() 837{ 838 GLuint handle = mVertexArrayNameSpace.allocate(); 839 840 mVertexArrayMap[handle] = NULL; 841 842 return handle; 843} 844 845// Returns an unused transform feedback name 846GLuint Context::createTransformFeedback() 847{ 848 GLuint handle = mTransformFeedbackNameSpace.allocate(); 849 850 mTransformFeedbackMap[handle] = NULL; 851 852 return handle; 853} 854 855// Returns an unused sampler name 856GLuint Context::createSampler() 857{ 858 GLuint handle = mSamplerNameSpace.allocate(); 859 860 mSamplerMap[handle] = NULL; 861 862 return handle; 863} 864 865void Context::deleteBuffer(GLuint buffer) 866{ 867 if(mResourceManager->getBuffer(buffer)) 868 { 869 detachBuffer(buffer); 870 } 871 872 mResourceManager->deleteBuffer(buffer); 873} 874 875void Context::deleteShader(GLuint shader) 876{ 877 mResourceManager->deleteShader(shader); 878} 879 880void Context::deleteProgram(GLuint program) 881{ 882 mResourceManager->deleteProgram(program); 883} 884 885void Context::deleteTexture(GLuint texture) 886{ 887 if(mResourceManager->getTexture(texture)) 888 { 889 detachTexture(texture); 890 } 891 892 mResourceManager->deleteTexture(texture); 893} 894 895void Context::deleteRenderbuffer(GLuint renderbuffer) 896{ 897 if(mResourceManager->getRenderbuffer(renderbuffer)) 898 { 899 detachRenderbuffer(renderbuffer); 900 } 901 902 mResourceManager->deleteRenderbuffer(renderbuffer); 903} 904 905void Context::deleteFramebuffer(GLuint framebuffer) 906{ 907 FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer); 908 909 if(framebufferObject != mFramebufferMap.end()) 910 { 911 detachFramebuffer(framebuffer); 912 913 mFramebufferNameSpace.release(framebufferObject->first); 914 delete framebufferObject->second; 915 mFramebufferMap.erase(framebufferObject); 916 } 917} 918 919void Context::deleteFence(GLuint fence) 920{ 921 FenceMap::iterator fenceObject = mFenceMap.find(fence); 922 923 if(fenceObject != mFenceMap.end()) 924 { 925 mFenceNameSpace.release(fenceObject->first); 926 delete fenceObject->second; 927 mFenceMap.erase(fenceObject); 928 } 929} 930 931void Context::deleteQuery(GLuint query) 932{ 933 QueryMap::iterator queryObject = mQueryMap.find(query); 934 935 if(queryObject != mQueryMap.end()) 936 { 937 mQueryNameSpace.release(queryObject->first); 938 939 if(queryObject->second) 940 { 941 queryObject->second->release(); 942 } 943 944 mQueryMap.erase(queryObject); 945 } 946} 947 948void Context::deleteVertexArray(GLuint vertexArray) 949{ 950 VertexArrayMap::iterator vertexArrayObject = mVertexArrayMap.find(vertexArray); 951 952 if(vertexArrayObject != mVertexArrayMap.end()) 953 { 954 mVertexArrayNameSpace.release(vertexArrayObject->first); 955 956 if(vertexArrayObject->second) 957 { 958 vertexArrayObject->second->release(); 959 } 960 961 mVertexArrayMap.erase(vertexArrayObject); 962 } 963} 964 965void Context::deleteTransformFeedback(GLuint transformFeedback) 966{ 967 TransformFeedbackMap::iterator transformFeedbackObject = mTransformFeedbackMap.find(transformFeedback); 968 969 if(transformFeedbackObject != mTransformFeedbackMap.end()) 970 { 971 mTransformFeedbackNameSpace.release(transformFeedbackObject->first); 972 973 if(transformFeedbackObject->second) 974 { 975 transformFeedbackObject->second->release(); 976 } 977 978 mTransformFeedbackMap.erase(transformFeedbackObject); 979 } 980} 981 982void Context::deleteSampler(GLuint sampler) 983{ 984 SamplerMap::iterator samplerObject = mSamplerMap.find(sampler); 985 986 if(samplerObject != mSamplerMap.end()) 987 { 988 mSamplerNameSpace.release(samplerObject->first); 989 990 if(samplerObject->second) 991 { 992 samplerObject->second->release(); 993 } 994 995 mSamplerMap.erase(samplerObject); 996 } 997} 998 999Buffer *Context::getBuffer(GLuint handle) 1000{ 1001 return mResourceManager->getBuffer(handle); 1002} 1003 1004Shader *Context::getShader(GLuint handle) 1005{ 1006 return mResourceManager->getShader(handle); 1007} 1008 1009Program *Context::getProgram(GLuint handle) 1010{ 1011 return mResourceManager->getProgram(handle); 1012} 1013 1014Texture *Context::getTexture(GLuint handle) 1015{ 1016 return mResourceManager->getTexture(handle); 1017} 1018 1019Renderbuffer *Context::getRenderbuffer(GLuint handle) 1020{ 1021 return mResourceManager->getRenderbuffer(handle); 1022} 1023 1024Framebuffer *Context::getReadFramebuffer() 1025{ 1026 return getFramebuffer(mState.readFramebuffer); 1027} 1028 1029Framebuffer *Context::getDrawFramebuffer() 1030{ 1031 return getFramebuffer(mState.drawFramebuffer); 1032} 1033 1034void Context::bindArrayBuffer(unsigned int buffer) 1035{ 1036 mResourceManager->checkBufferAllocation(buffer); 1037 1038 mState.arrayBuffer = getBuffer(buffer); 1039} 1040 1041void Context::bindElementArrayBuffer(unsigned int buffer) 1042{ 1043 mResourceManager->checkBufferAllocation(buffer); 1044 1045 mState.elementArrayBuffer = getBuffer(buffer); 1046} 1047 1048void Context::bindTexture2D(GLuint texture) 1049{ 1050 mResourceManager->checkTextureAllocation(texture, TEXTURE_2D); 1051 1052 mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture); 1053} 1054 1055void Context::bindTextureCubeMap(GLuint texture) 1056{ 1057 mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE); 1058 1059 mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler] = getTexture(texture); 1060} 1061 1062void Context::bindTextureExternal(GLuint texture) 1063{ 1064 mResourceManager->checkTextureAllocation(texture, TEXTURE_EXTERNAL); 1065 1066 mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler] = getTexture(texture); 1067} 1068 1069void Context::bindTexture3D(GLuint texture) 1070{ 1071 mResourceManager->checkTextureAllocation(texture, TEXTURE_3D); 1072 1073 mState.samplerTexture[TEXTURE_3D][mState.activeSampler] = getTexture(texture); 1074} 1075 1076void Context::bindReadFramebuffer(GLuint framebuffer) 1077{ 1078 if(!getFramebuffer(framebuffer)) 1079 { 1080 mFramebufferMap[framebuffer] = new Framebuffer(); 1081 } 1082 1083 mState.readFramebuffer = framebuffer; 1084} 1085 1086void Context::bindDrawFramebuffer(GLuint framebuffer) 1087{ 1088 if(!getFramebuffer(framebuffer)) 1089 { 1090 mFramebufferMap[framebuffer] = new Framebuffer(); 1091 } 1092 1093 mState.drawFramebuffer = framebuffer; 1094} 1095 1096void Context::bindRenderbuffer(GLuint renderbuffer) 1097{ 1098 mState.renderbuffer = getRenderbuffer(renderbuffer); 1099} 1100 1101bool Context::bindVertexArray(GLuint array) 1102{ 1103 VertexArray* vertexArray = getVertexArray(array); 1104 1105 if(vertexArray) 1106 { 1107 mState.vertexArray = vertexArray; 1108 } 1109 1110 return !!vertexArray; 1111} 1112 1113bool Context::bindTransformFeedback(GLuint id) 1114{ 1115 TransformFeedback* transformFeedback = getTransformFeedback(id); 1116 1117 if(transformFeedback) 1118 { 1119 mState.transformFeedback = transformFeedback; 1120 return true; 1121 } 1122 1123 return false; 1124} 1125 1126bool Context::bindSampler(GLuint unit, GLuint sampler) 1127{ 1128 Sampler* samplerObject = getSampler(sampler); 1129 1130 if(sampler) 1131 { 1132 mState.sampler[unit] = samplerObject; 1133 } 1134 1135 return !!samplerObject; 1136} 1137 1138void Context::useProgram(GLuint program) 1139{ 1140 GLuint priorProgram = mState.currentProgram; 1141 mState.currentProgram = program; // Must switch before trying to delete, otherwise it only gets flagged. 1142 1143 if(priorProgram != program) 1144 { 1145 Program *newProgram = mResourceManager->getProgram(program); 1146 Program *oldProgram = mResourceManager->getProgram(priorProgram); 1147 1148 if(newProgram) 1149 { 1150 newProgram->addRef(); 1151 } 1152 1153 if(oldProgram) 1154 { 1155 oldProgram->release(); 1156 } 1157 } 1158} 1159 1160void Context::beginQuery(GLenum target, GLuint query) 1161{ 1162 // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id> 1163 // of zero, if the active query object name for <target> is non-zero (for the 1164 // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if 1165 // the active query for either target is non-zero), if <id> is the name of an 1166 // existing query object whose type does not match <target>, or if <id> is the 1167 // active query object name for any query type, the error INVALID_OPERATION is 1168 // generated. 1169 1170 // Ensure no other queries are active 1171 // NOTE: If other queries than occlusion are supported, we will need to check 1172 // separately that: 1173 // a) The query ID passed is not the current active query for any target/type 1174 // b) There are no active queries for the requested target (and in the case 1175 // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, 1176 // no query may be active for either if glBeginQuery targets either. 1177 for(int i = 0; i < QUERY_TYPE_COUNT; i++) 1178 { 1179 if(mState.activeQuery[i] != NULL) 1180 { 1181 return error(GL_INVALID_OPERATION); 1182 } 1183 } 1184 1185 QueryType qType; 1186 switch(target) 1187 { 1188 case GL_ANY_SAMPLES_PASSED_EXT: 1189 qType = QUERY_ANY_SAMPLES_PASSED; 1190 break; 1191 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: 1192 qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE; 1193 break; 1194 default: 1195 ASSERT(false); 1196 } 1197 1198 Query *queryObject = getQuery(query, true, target); 1199 1200 // Check that name was obtained with glGenQueries 1201 if(!queryObject) 1202 { 1203 return error(GL_INVALID_OPERATION); 1204 } 1205 1206 // Check for type mismatch 1207 if(queryObject->getType() != target) 1208 { 1209 return error(GL_INVALID_OPERATION); 1210 } 1211 1212 // Set query as active for specified target 1213 mState.activeQuery[qType] = queryObject; 1214 1215 // Begin query 1216 queryObject->begin(); 1217} 1218 1219void Context::endQuery(GLenum target) 1220{ 1221 QueryType qType; 1222 1223 switch(target) 1224 { 1225 case GL_ANY_SAMPLES_PASSED_EXT: 1226 qType = QUERY_ANY_SAMPLES_PASSED; 1227 break; 1228 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: 1229 qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE; 1230 break; 1231 default: 1232 ASSERT(false); 1233 } 1234 1235 Query *queryObject = mState.activeQuery[qType]; 1236 1237 if(queryObject == NULL) 1238 { 1239 return error(GL_INVALID_OPERATION); 1240 } 1241 1242 queryObject->end(); 1243 1244 mState.activeQuery[qType] = NULL; 1245} 1246 1247void Context::setFramebufferZero(Framebuffer *buffer) 1248{ 1249 delete mFramebufferMap[0]; 1250 mFramebufferMap[0] = buffer; 1251} 1252 1253void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer) 1254{ 1255 Renderbuffer *renderbufferObject = mState.renderbuffer; 1256 renderbufferObject->setStorage(renderbuffer); 1257} 1258 1259Framebuffer *Context::getFramebuffer(unsigned int handle) 1260{ 1261 FramebufferMap::iterator framebuffer = mFramebufferMap.find(handle); 1262 1263 if(framebuffer == mFramebufferMap.end()) 1264 { 1265 return NULL; 1266 } 1267 else 1268 { 1269 return framebuffer->second; 1270 } 1271} 1272 1273Fence *Context::getFence(unsigned int handle) 1274{ 1275 FenceMap::iterator fence = mFenceMap.find(handle); 1276 1277 if(fence == mFenceMap.end()) 1278 { 1279 return NULL; 1280 } 1281 else 1282 { 1283 return fence->second; 1284 } 1285} 1286 1287Query *Context::getQuery(unsigned int handle, bool create, GLenum type) 1288{ 1289 QueryMap::iterator query = mQueryMap.find(handle); 1290 1291 if(query == mQueryMap.end()) 1292 { 1293 return NULL; 1294 } 1295 else 1296 { 1297 if(!query->second && create) 1298 { 1299 query->second = new Query(handle, type); 1300 query->second->addRef(); 1301 } 1302 1303 return query->second; 1304 } 1305} 1306 1307VertexArray *Context::getVertexArray(GLuint array) 1308{ 1309 VertexArrayMap::iterator vertexArray = mVertexArrayMap.find(array); 1310 1311 return (vertexArray == mVertexArrayMap.end()) ? NULL : vertexArray->second; 1312} 1313 1314TransformFeedback *Context::getTransformFeedback(GLuint transformFeedback) 1315{ 1316 TransformFeedbackMap::iterator transformFeedbackObject = mTransformFeedbackMap.find(transformFeedback); 1317 1318 return (transformFeedbackObject == mTransformFeedbackMap.end()) ? NULL : transformFeedbackObject->second; 1319} 1320 1321Sampler *Context::getSampler(GLuint sampler) 1322{ 1323 SamplerMap::iterator samplerObject = mSamplerMap.find(sampler); 1324 1325 return (samplerObject == mSamplerMap.end()) ? NULL : samplerObject->second; 1326} 1327 1328Buffer *Context::getArrayBuffer() 1329{ 1330 return mState.arrayBuffer; 1331} 1332 1333Buffer *Context::getElementArrayBuffer() 1334{ 1335 return mState.elementArrayBuffer; 1336} 1337 1338Program *Context::getCurrentProgram() 1339{ 1340 return mResourceManager->getProgram(mState.currentProgram); 1341} 1342 1343Texture2D *Context::getTexture2D() 1344{ 1345 return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D)); 1346} 1347 1348Texture3D *Context::getTexture3D() 1349{ 1350 return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D)); 1351} 1352 1353TextureCubeMap *Context::getTextureCubeMap() 1354{ 1355 return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE)); 1356} 1357 1358TextureExternal *Context::getTextureExternal() 1359{ 1360 return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL)); 1361} 1362 1363Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) 1364{ 1365 GLuint texid = mState.samplerTexture[type][sampler].name(); 1366 1367 if(texid == 0) // Special case: 0 refers to different initial textures based on the target 1368 { 1369 switch (type) 1370 { 1371 case TEXTURE_2D: return mTexture2DZero; 1372 case TEXTURE_3D: return mTexture3DZero; 1373 case TEXTURE_CUBE: return mTextureCubeMapZero; 1374 case TEXTURE_EXTERNAL: return mTextureExternalZero; 1375 default: UNREACHABLE(); 1376 } 1377 } 1378 1379 return mState.samplerTexture[type][sampler]; 1380} 1381 1382bool Context::getBooleanv(GLenum pname, GLboolean *params) 1383{ 1384 switch (pname) 1385 { 1386 case GL_SHADER_COMPILER: *params = GL_TRUE; break; 1387 case GL_SAMPLE_COVERAGE_INVERT: *params = mState.sampleCoverageInvert; break; 1388 case GL_DEPTH_WRITEMASK: *params = mState.depthMask; break; 1389 case GL_COLOR_WRITEMASK: 1390 params[0] = mState.colorMaskRed; 1391 params[1] = mState.colorMaskGreen; 1392 params[2] = mState.colorMaskBlue; 1393 params[3] = mState.colorMaskAlpha; 1394 break; 1395 case GL_CULL_FACE: *params = mState.cullFace; break; 1396 case GL_POLYGON_OFFSET_FILL: *params = mState.polygonOffsetFill; break; 1397 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverage; break; 1398 case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverage; break; 1399 case GL_SCISSOR_TEST: *params = mState.scissorTest; break; 1400 case GL_STENCIL_TEST: *params = mState.stencilTest; break; 1401 case GL_DEPTH_TEST: *params = mState.depthTest; break; 1402 case GL_BLEND: *params = mState.blend; break; 1403 case GL_DITHER: *params = mState.dither; break; 1404 case GL_PRIMITIVE_RESTART_FIXED_INDEX: *params = mState.primitiveRestartFixedIndex; break; 1405 case GL_RASTERIZER_DISCARD: *params = mState.rasterizerDiscard; break; 1406 case GL_TRANSFORM_FEEDBACK_ACTIVE: 1407 if(mState.transformFeedback) 1408 { 1409 *params = mState.transformFeedback->isActive(); 1410 break; 1411 } 1412 else return false; 1413 case GL_TRANSFORM_FEEDBACK_PAUSED: 1414 if(mState.transformFeedback) 1415 { 1416 *params = mState.transformFeedback->isPaused(); 1417 break; 1418 } 1419 else return false; 1420 default: 1421 return false; 1422 } 1423 1424 return true; 1425} 1426 1427bool Context::getFloatv(GLenum pname, GLfloat *params) 1428{ 1429 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation 1430 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names 1431 // GetIntegerv as its native query function. As it would require conversion in any 1432 // case, this should make no difference to the calling application. 1433 switch (pname) 1434 { 1435 case GL_LINE_WIDTH: *params = mState.lineWidth; break; 1436 case GL_SAMPLE_COVERAGE_VALUE: *params = mState.sampleCoverageValue; break; 1437 case GL_DEPTH_CLEAR_VALUE: *params = mState.depthClearValue; break; 1438 case GL_POLYGON_OFFSET_FACTOR: *params = mState.polygonOffsetFactor; break; 1439 case GL_POLYGON_OFFSET_UNITS: *params = mState.polygonOffsetUnits; break; 1440 case GL_ALIASED_LINE_WIDTH_RANGE: 1441 params[0] = ALIASED_LINE_WIDTH_RANGE_MIN; 1442 params[1] = ALIASED_LINE_WIDTH_RANGE_MAX; 1443 break; 1444 case GL_ALIASED_POINT_SIZE_RANGE: 1445 params[0] = ALIASED_POINT_SIZE_RANGE_MIN; 1446 params[1] = ALIASED_POINT_SIZE_RANGE_MAX; 1447 break; 1448 case GL_DEPTH_RANGE: 1449 params[0] = mState.zNear; 1450 params[1] = mState.zFar; 1451 break; 1452 case GL_COLOR_CLEAR_VALUE: 1453 params[0] = mState.colorClearValue.red; 1454 params[1] = mState.colorClearValue.green; 1455 params[2] = mState.colorClearValue.blue; 1456 params[3] = mState.colorClearValue.alpha; 1457 break; 1458 case GL_BLEND_COLOR: 1459 params[0] = mState.blendColor.red; 1460 params[1] = mState.blendColor.green; 1461 params[2] = mState.blendColor.blue; 1462 params[3] = mState.blendColor.alpha; 1463 break; 1464 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: 1465 *params = MAX_TEXTURE_MAX_ANISOTROPY; 1466 break; 1467 default: 1468 return false; 1469 } 1470 1471 return true; 1472} 1473 1474bool Context::getIntegerv(GLenum pname, GLint *params) 1475{ 1476 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation 1477 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names 1478 // GetIntegerv as its native query function. As it would require conversion in any 1479 // case, this should make no difference to the calling application. You may find it in 1480 // Context::getFloatv. 1481 switch (pname) 1482 { 1483 case GL_MAX_VERTEX_ATTRIBS: *params = MAX_VERTEX_ATTRIBS; break; 1484 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = MAX_VERTEX_UNIFORM_VECTORS; break; 1485 case GL_MAX_VARYING_VECTORS: *params = MAX_VARYING_VECTORS; break; 1486 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = MAX_COMBINED_TEXTURE_IMAGE_UNITS; break; 1487 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = MAX_VERTEX_TEXTURE_IMAGE_UNITS; break; 1488 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = MAX_TEXTURE_IMAGE_UNITS; break; 1489 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = MAX_FRAGMENT_UNIFORM_VECTORS; break; 1490 case GL_MAX_RENDERBUFFER_SIZE: *params = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; break; 1491 case GL_NUM_SHADER_BINARY_FORMATS: *params = 0; break; 1492 case GL_SHADER_BINARY_FORMATS: /* no shader binary formats are supported */ break; 1493 case GL_ARRAY_BUFFER_BINDING: *params = mState.arrayBuffer.name(); break; 1494 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = mState.elementArrayBuffer.name(); break; 1495// case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 1496 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mState.drawFramebuffer; break; 1497 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mState.readFramebuffer; break; 1498 case GL_RENDERBUFFER_BINDING: *params = mState.renderbuffer.name(); break; 1499 case GL_CURRENT_PROGRAM: *params = mState.currentProgram; break; 1500 case GL_PACK_ALIGNMENT: *params = mState.packAlignment; break; 1501 case GL_UNPACK_ALIGNMENT: *params = mState.unpackAlignment; break; 1502 case GL_GENERATE_MIPMAP_HINT: *params = mState.generateMipmapHint; break; 1503 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; break; 1504 case GL_ACTIVE_TEXTURE: *params = (mState.activeSampler + GL_TEXTURE0); break; 1505 case GL_STENCIL_FUNC: *params = mState.stencilFunc; break; 1506 case GL_STENCIL_REF: *params = mState.stencilRef; break; 1507 case GL_STENCIL_VALUE_MASK: *params = mState.stencilMask; break; 1508 case GL_STENCIL_BACK_FUNC: *params = mState.stencilBackFunc; break; 1509 case GL_STENCIL_BACK_REF: *params = mState.stencilBackRef; break; 1510 case GL_STENCIL_BACK_VALUE_MASK: *params = mState.stencilBackMask; break; 1511 case GL_STENCIL_FAIL: *params = mState.stencilFail; break; 1512 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mState.stencilPassDepthFail; break; 1513 case GL_STENCIL_PASS_DEPTH_PASS: *params = mState.stencilPassDepthPass; break; 1514 case GL_STENCIL_BACK_FAIL: *params = mState.stencilBackFail; break; 1515 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mState.stencilBackPassDepthFail; break; 1516 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mState.stencilBackPassDepthPass; break; 1517 case GL_DEPTH_FUNC: *params = mState.depthFunc; break; 1518 case GL_BLEND_SRC_RGB: *params = mState.sourceBlendRGB; break; 1519 case GL_BLEND_SRC_ALPHA: *params = mState.sourceBlendAlpha; break; 1520 case GL_BLEND_DST_RGB: *params = mState.destBlendRGB; break; 1521 case GL_BLEND_DST_ALPHA: *params = mState.destBlendAlpha; break; 1522 case GL_BLEND_EQUATION_RGB: *params = mState.blendEquationRGB; break; 1523 case GL_BLEND_EQUATION_ALPHA: *params = mState.blendEquationAlpha; break; 1524 case GL_STENCIL_WRITEMASK: *params = mState.stencilWritemask; break; 1525 case GL_STENCIL_BACK_WRITEMASK: *params = mState.stencilBackWritemask; break; 1526 case GL_STENCIL_CLEAR_VALUE: *params = mState.stencilClearValue; break; 1527 case GL_SUBPIXEL_BITS: *params = 4; break; 1528 case GL_MAX_TEXTURE_SIZE: *params = IMPLEMENTATION_MAX_TEXTURE_SIZE; break; 1529 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE; break; 1530 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: *params = NUM_COMPRESSED_TEXTURE_FORMATS; break; 1531 case GL_MAX_SAMPLES_ANGLE: *params = IMPLEMENTATION_MAX_SAMPLES; break; 1532 case GL_SAMPLE_BUFFERS: 1533 case GL_SAMPLES: 1534 { 1535 Framebuffer *framebuffer = getDrawFramebuffer(); 1536 int width, height, samples; 1537 1538 if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE) 1539 { 1540 switch(pname) 1541 { 1542 case GL_SAMPLE_BUFFERS: 1543 if(samples > 1) 1544 { 1545 *params = 1; 1546 } 1547 else 1548 { 1549 *params = 0; 1550 } 1551 break; 1552 case GL_SAMPLES: 1553 *params = samples & ~1; 1554 break; 1555 } 1556 } 1557 else 1558 { 1559 *params = 0; 1560 } 1561 } 1562 break; 1563 case GL_IMPLEMENTATION_COLOR_READ_TYPE: 1564 { 1565 Framebuffer *framebuffer = getReadFramebuffer(); 1566 *params = framebuffer->getImplementationColorReadType(); 1567 } 1568 break; 1569 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: 1570 { 1571 Framebuffer *framebuffer = getReadFramebuffer(); 1572 *params = framebuffer->getImplementationColorReadFormat(); 1573 } 1574 break; 1575 case GL_MAX_VIEWPORT_DIMS: 1576 { 1577 int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; 1578 params[0] = maxDimension; 1579 params[1] = maxDimension; 1580 } 1581 break; 1582 case GL_COMPRESSED_TEXTURE_FORMATS: 1583 { 1584 for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++) 1585 { 1586 params[i] = compressedTextureFormats[i]; 1587 } 1588 } 1589 break; 1590 case GL_VIEWPORT: 1591 params[0] = mState.viewportX; 1592 params[1] = mState.viewportY; 1593 params[2] = mState.viewportWidth; 1594 params[3] = mState.viewportHeight; 1595 break; 1596 case GL_SCISSOR_BOX: 1597 params[0] = mState.scissorX; 1598 params[1] = mState.scissorY; 1599 params[2] = mState.scissorWidth; 1600 params[3] = mState.scissorHeight; 1601 break; 1602 case GL_CULL_FACE_MODE: *params = mState.cullMode; break; 1603 case GL_FRONT_FACE: *params = mState.frontFace; break; 1604 case GL_RED_BITS: 1605 case GL_GREEN_BITS: 1606 case GL_BLUE_BITS: 1607 case GL_ALPHA_BITS: 1608 { 1609 Framebuffer *framebuffer = getDrawFramebuffer(); 1610 Renderbuffer *colorbuffer = framebuffer->getColorbuffer(); 1611 1612 if(colorbuffer) 1613 { 1614 switch (pname) 1615 { 1616 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break; 1617 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break; 1618 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break; 1619 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break; 1620 } 1621 } 1622 else 1623 { 1624 *params = 0; 1625 } 1626 } 1627 break; 1628 case GL_DEPTH_BITS: 1629 { 1630 Framebuffer *framebuffer = getDrawFramebuffer(); 1631 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer(); 1632 1633 if(depthbuffer) 1634 { 1635 *params = depthbuffer->getDepthSize(); 1636 } 1637 else 1638 { 1639 *params = 0; 1640 } 1641 } 1642 break; 1643 case GL_STENCIL_BITS: 1644 { 1645 Framebuffer *framebuffer = getDrawFramebuffer(); 1646 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer(); 1647 1648 if(stencilbuffer) 1649 { 1650 *params = stencilbuffer->getStencilSize(); 1651 } 1652 else 1653 { 1654 *params = 0; 1655 } 1656 } 1657 break; 1658 case GL_TEXTURE_BINDING_2D: 1659 { 1660 if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) 1661 { 1662 error(GL_INVALID_OPERATION); 1663 return false; 1664 } 1665 1666 *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name(); 1667 } 1668 break; 1669 case GL_TEXTURE_BINDING_CUBE_MAP: 1670 { 1671 if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) 1672 { 1673 error(GL_INVALID_OPERATION); 1674 return false; 1675 } 1676 1677 *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name(); 1678 } 1679 break; 1680 case GL_TEXTURE_BINDING_EXTERNAL_OES: 1681 { 1682 if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) 1683 { 1684 error(GL_INVALID_OPERATION); 1685 return false; 1686 } 1687 1688 *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name(); 1689 } 1690 break; 1691 case GL_TEXTURE_BINDING_3D_OES: 1692 case GL_TEXTURE_BINDING_2D_ARRAY: // GLES 3.0 1693 { 1694 if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) 1695 { 1696 error(GL_INVALID_OPERATION); 1697 return false; 1698 } 1699 1700 *params = mState.samplerTexture[TEXTURE_3D][mState.activeSampler].name(); 1701 } 1702 break; 1703 case GL_COPY_READ_BUFFER_BINDING: // name, initially 0 1704 UNIMPLEMENTED(); 1705 *params = 0; 1706 break; 1707 case GL_COPY_WRITE_BUFFER_BINDING: // name, initially 0 1708 UNIMPLEMENTED(); 1709 *params = 0; 1710 break; 1711 case GL_DRAW_BUFFER0: // symbolic constant, initial value is GL_BACK 1712 UNIMPLEMENTED(); 1713 *params = GL_BACK; 1714 break; 1715 case GL_DRAW_BUFFER1: // symbolic constant, initial value is GL_NONE 1716 case GL_DRAW_BUFFER2: 1717 case GL_DRAW_BUFFER3: 1718 case GL_DRAW_BUFFER4: 1719 case GL_DRAW_BUFFER5: 1720 case GL_DRAW_BUFFER6: 1721 case GL_DRAW_BUFFER7: 1722 case GL_DRAW_BUFFER8: 1723 case GL_DRAW_BUFFER9: 1724 case GL_DRAW_BUFFER10: 1725 case GL_DRAW_BUFFER11: 1726 case GL_DRAW_BUFFER12: 1727 case GL_DRAW_BUFFER13: 1728 case GL_DRAW_BUFFER14: 1729 case GL_DRAW_BUFFER15: 1730 UNIMPLEMENTED(); 1731 *params = GL_NONE; 1732 break; 1733 case GL_MAJOR_VERSION: // integer, at least 3 1734 UNIMPLEMENTED(); 1735 *params = 3; 1736 break; 1737 case GL_MAX_3D_TEXTURE_SIZE: // GLint, at least 2048 1738 UNIMPLEMENTED(); 1739 *params = 2048; 1740 break; 1741 case GL_MAX_ARRAY_TEXTURE_LAYERS: // GLint, at least 2048 1742 UNIMPLEMENTED(); 1743 *params = 2048; 1744 break; 1745 case GL_MAX_COLOR_ATTACHMENTS: // integer, at least 8 1746 UNIMPLEMENTED(); 1747 *params = IMPLEMENTATION_MAX_COLOR_ATTACHMENTS; 1748 break; 1749 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: // integer, at least 50048 1750 UNIMPLEMENTED(); 1751 *params = MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS; 1752 break; 1753 case GL_MAX_COMBINED_UNIFORM_BLOCKS: // integer, at least 70 1754 UNIMPLEMENTED(); 1755 *params = 70; 1756 break; 1757 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: // integer, at least 50176 1758 UNIMPLEMENTED(); 1759 *params = MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS; 1760 break; 1761 case GL_MAX_DRAW_BUFFERS: // integer, at least 8 1762 UNIMPLEMENTED(); 1763 *params = IMPLEMENTATION_MAX_DRAW_BUFFERS; 1764 break; 1765 case GL_MAX_ELEMENT_INDEX: // integer, at least 16777215 1766 UNIMPLEMENTED(); 1767 *params = 16777215; 1768 break; 1769 case GL_MAX_ELEMENTS_INDICES: // integer 1770 UNIMPLEMENTED(); 1771 *params = 0; 1772 break; 1773 case GL_MAX_ELEMENTS_VERTICES: // integer 1774 UNIMPLEMENTED(); 1775 *params = 0; 1776 break; 1777 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: // integer, at least 128 1778 UNIMPLEMENTED(); 1779 *params = 128; 1780 break; 1781 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: // integer, at least 12 1782 UNIMPLEMENTED(); 1783 *params = 12; 1784 break; 1785 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: // integer, at least 1024 1786 UNIMPLEMENTED(); 1787 *params = 1024; 1788 break; 1789 case GL_MAX_PROGRAM_TEXEL_OFFSET: // integer, minimum is 7 1790 UNIMPLEMENTED(); 1791 *params = 7; 1792 break; 1793 case GL_MAX_SERVER_WAIT_TIMEOUT: // integer 1794 UNIMPLEMENTED(); 1795 *params = 0; 1796 break; 1797 case GL_MAX_TEXTURE_LOD_BIAS: // integer, at least 2.0 1798 UNIMPLEMENTED(); 1799 *params = 2; 1800 break; 1801 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: // integer, at least 64 1802 UNIMPLEMENTED(); 1803 *params = 64; 1804 break; 1805 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: // integer, at least 4 1806 UNIMPLEMENTED(); 1807 *params = IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS; 1808 break; 1809 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: // integer, at least 4 1810 UNIMPLEMENTED(); 1811 *params = 4; 1812 break; 1813 case GL_MAX_UNIFORM_BLOCK_SIZE: // integer, at least 16384 1814 UNIMPLEMENTED(); 1815 *params = 16384; 1816 break; 1817 case GL_MAX_UNIFORM_BUFFER_BINDINGS: // integer, at least 36 1818 UNIMPLEMENTED(); 1819 *params = IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS; 1820 break; 1821 case GL_MAX_VARYING_COMPONENTS: // integer, at least 60 1822 UNIMPLEMENTED(); 1823 *params = 60; 1824 break; 1825 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: // integer, at least 64 1826 UNIMPLEMENTED(); 1827 *params = 64; 1828 break; 1829 case GL_MAX_VERTEX_UNIFORM_BLOCKS: // integer, at least 12 1830 UNIMPLEMENTED(); 1831 *params = 12; 1832 break; 1833 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: // integer, at least 1024 1834 UNIMPLEMENTED(); 1835 *params = 1024; 1836 break; 1837 case GL_MIN_PROGRAM_TEXEL_OFFSET: // integer, maximum is -8 1838 UNIMPLEMENTED(); 1839 *params = -8; 1840 break; 1841 case GL_MINOR_VERSION: // integer 1842 UNIMPLEMENTED(); 1843 *params = 0; 1844 break; 1845 case GL_NUM_EXTENSIONS: // integer 1846 UNIMPLEMENTED(); 1847 *params = 0; 1848 break; 1849 case GL_NUM_PROGRAM_BINARY_FORMATS: // integer, at least 0 1850 UNIMPLEMENTED(); 1851 *params = 0; 1852 break; 1853 case GL_PACK_ROW_LENGTH: // integer, initially 0 1854 UNIMPLEMENTED(); 1855 *params = 0; 1856 break; 1857 case GL_PACK_SKIP_PIXELS: // integer, initially 0 1858 UNIMPLEMENTED(); 1859 *params = 0; 1860 break; 1861 case GL_PACK_SKIP_ROWS: // integer, initially 0 1862 UNIMPLEMENTED(); 1863 *params = 0; 1864 break; 1865 case GL_PIXEL_PACK_BUFFER_BINDING: // integer, initially 0 1866 UNIMPLEMENTED(); 1867 *params = 0; 1868 break; 1869 case GL_PIXEL_UNPACK_BUFFER_BINDING: // integer, initially 0 1870 UNIMPLEMENTED(); 1871 *params = 0; 1872 break; 1873 case GL_PROGRAM_BINARY_FORMATS: // integer[GL_NUM_PROGRAM_BINARY_FORMATS] 1874 UNIMPLEMENTED(); 1875 *params = 0; 1876 break; 1877 case GL_READ_BUFFER: // symbolic constant, initial value is GL_BACK 1878 UNIMPLEMENTED(); 1879 *params = GL_BACK; 1880 break; 1881 case GL_SAMPLER_BINDING: // GLint, default 0 1882 UNIMPLEMENTED(); 1883 *params = 0; 1884 break; 1885 case GL_UNIFORM_BUFFER_BINDING: // name, initially 0 1886 UNIMPLEMENTED(); 1887 *params = 0; 1888 break; 1889 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: // integer, defaults to 1 1890 UNIMPLEMENTED(); 1891 *params = IMPLEMENTATION_UNIFORM_BUFFER_OFFSET_ALIGNMENT; 1892 break; 1893 case GL_UNIFORM_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0 1894 UNIMPLEMENTED(); 1895 *params = 0; 1896 break; 1897 case GL_UNIFORM_BUFFER_START: // indexed[n] 64-bit integer, initially 0 1898 UNIMPLEMENTED(); 1899 *params = 0; 1900 break; 1901 case GL_UNPACK_IMAGE_HEIGHT: // integer, initially 0 1902 UNIMPLEMENTED(); 1903 *params = 0; 1904 break; 1905 case GL_UNPACK_ROW_LENGTH: // integer, initially 0 1906 UNIMPLEMENTED(); 1907 *params = 0; 1908 break; 1909 case GL_UNPACK_SKIP_IMAGES: // integer, initially 0 1910 UNIMPLEMENTED(); 1911 *params = 0; 1912 break; 1913 case GL_UNPACK_SKIP_PIXELS: // integer, initially 0 1914 UNIMPLEMENTED(); 1915 *params = 0; 1916 break; 1917 case GL_UNPACK_SKIP_ROWS: // integer, initially 0 1918 UNIMPLEMENTED(); 1919 *params = 0; 1920 break; 1921 case GL_VERTEX_ARRAY_BINDING: // GLint, initially 0 1922 UNIMPLEMENTED(); 1923 *params = 0; 1924 break; 1925 default: 1926 return false; 1927 } 1928 1929 return true; 1930} 1931 1932bool Context::getTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param) 1933{ 1934 UNIMPLEMENTED(); 1935 1936 switch(pname) 1937 { 1938 case GL_TRANSFORM_FEEDBACK_BINDING: // GLint, initially 0 1939 *param = 0; 1940 break; 1941 case GL_TRANSFORM_FEEDBACK_ACTIVE: // boolean, initially GL_FALSE 1942 if(mState.transformFeedback) 1943 { 1944 *param = mState.transformFeedback->isActive(); 1945 break; 1946 } 1947 else return false; 1948 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: // name, initially 0 1949 if(mState.transformFeedback && mState.transformFeedback->getGenericBuffer()) 1950 { 1951 *param = mState.transformFeedback->getGenericBuffer()->name; 1952 break; 1953 } 1954 else return false; 1955 case GL_TRANSFORM_FEEDBACK_PAUSED: // boolean, initially GL_FALSE 1956 if(mState.transformFeedback) 1957 { 1958 *param = mState.transformFeedback->isPaused(); 1959 break; 1960 } 1961 else return false; 1962 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0 1963 if(mState.transformFeedback && mState.transformFeedback->getGenericBuffer()) 1964 { 1965 *param = mState.transformFeedback->getGenericBuffer()->size(); 1966 break; 1967 } 1968 else return false; 1969 case GL_TRANSFORM_FEEDBACK_BUFFER_START: // indexed[n] 64-bit integer, initially 0 1970 *param = 0; 1971 break; 1972 default: 1973 return false; 1974 } 1975 1976 return true; 1977} 1978 1979bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) 1980{ 1981 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation 1982 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due 1983 // to the fact that it is stored internally as a float, and so would require conversion 1984 // if returned from Context::getIntegerv. Since this conversion is already implemented 1985 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we 1986 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling 1987 // application. 1988 switch (pname) 1989 { 1990 case GL_COMPRESSED_TEXTURE_FORMATS: 1991 { 1992 *type = GL_INT; 1993 *numParams = NUM_COMPRESSED_TEXTURE_FORMATS; 1994 } 1995 break; 1996 case GL_SHADER_BINARY_FORMATS: 1997 { 1998 *type = GL_INT; 1999 *numParams = 0; 2000 } 2001 break; 2002 case GL_MAX_VERTEX_ATTRIBS: 2003 case GL_MAX_VERTEX_UNIFORM_VECTORS: 2004 case GL_MAX_VARYING_VECTORS: 2005 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: 2006 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: 2007 case GL_MAX_TEXTURE_IMAGE_UNITS: 2008 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: 2009 case GL_MAX_RENDERBUFFER_SIZE: 2010 case GL_NUM_SHADER_BINARY_FORMATS: 2011 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: 2012 case GL_ARRAY_BUFFER_BINDING: 2013 case GL_FRAMEBUFFER_BINDING: 2014 case GL_RENDERBUFFER_BINDING: 2015 case GL_CURRENT_PROGRAM: 2016 case GL_PACK_ALIGNMENT: 2017 case GL_UNPACK_ALIGNMENT: 2018 case GL_GENERATE_MIPMAP_HINT: 2019 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: 2020 case GL_RED_BITS: 2021 case GL_GREEN_BITS: 2022 case GL_BLUE_BITS: 2023 case GL_ALPHA_BITS: 2024 case GL_DEPTH_BITS: 2025 case GL_STENCIL_BITS: 2026 case GL_ELEMENT_ARRAY_BUFFER_BINDING: 2027 case GL_CULL_FACE_MODE: 2028 case GL_FRONT_FACE: 2029 case GL_ACTIVE_TEXTURE: 2030 case GL_STENCIL_FUNC: 2031 case GL_STENCIL_VALUE_MASK: 2032 case GL_STENCIL_REF: 2033 case GL_STENCIL_FAIL: 2034 case GL_STENCIL_PASS_DEPTH_FAIL: 2035 case GL_STENCIL_PASS_DEPTH_PASS: 2036 case GL_STENCIL_BACK_FUNC: 2037 case GL_STENCIL_BACK_VALUE_MASK: 2038 case GL_STENCIL_BACK_REF: 2039 case GL_STENCIL_BACK_FAIL: 2040 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: 2041 case GL_STENCIL_BACK_PASS_DEPTH_PASS: 2042 case GL_DEPTH_FUNC: 2043 case GL_BLEND_SRC_RGB: 2044 case GL_BLEND_SRC_ALPHA: 2045 case GL_BLEND_DST_RGB: 2046 case GL_BLEND_DST_ALPHA: 2047 case GL_BLEND_EQUATION_RGB: 2048 case GL_BLEND_EQUATION_ALPHA: 2049 case GL_STENCIL_WRITEMASK: 2050 case GL_STENCIL_BACK_WRITEMASK: 2051 case GL_STENCIL_CLEAR_VALUE: 2052 case GL_SUBPIXEL_BITS: 2053 case GL_MAX_TEXTURE_SIZE: 2054 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: 2055 case GL_SAMPLE_BUFFERS: 2056 case GL_SAMPLES: 2057 case GL_IMPLEMENTATION_COLOR_READ_TYPE: 2058 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: 2059 case GL_TEXTURE_BINDING_2D: 2060 case GL_TEXTURE_BINDING_CUBE_MAP: 2061 case GL_TEXTURE_BINDING_EXTERNAL_OES: 2062 case GL_TEXTURE_BINDING_3D_OES: 2063 case GL_COPY_READ_BUFFER_BINDING: 2064 case GL_COPY_WRITE_BUFFER_BINDING: 2065 case GL_DRAW_BUFFER0: 2066 case GL_DRAW_BUFFER1: 2067 case GL_DRAW_BUFFER2: 2068 case GL_DRAW_BUFFER3: 2069 case GL_DRAW_BUFFER4: 2070 case GL_DRAW_BUFFER5: 2071 case GL_DRAW_BUFFER6: 2072 case GL_DRAW_BUFFER7: 2073 case GL_DRAW_BUFFER8: 2074 case GL_DRAW_BUFFER9: 2075 case GL_DRAW_BUFFER10: 2076 case GL_DRAW_BUFFER11: 2077 case GL_DRAW_BUFFER12: 2078 case GL_DRAW_BUFFER13: 2079 case GL_DRAW_BUFFER14: 2080 case GL_DRAW_BUFFER15: 2081 case GL_MAJOR_VERSION: 2082 case GL_MAX_3D_TEXTURE_SIZE: 2083 case GL_MAX_ARRAY_TEXTURE_LAYERS: 2084 case GL_MAX_COLOR_ATTACHMENTS: 2085 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: 2086 case GL_MAX_COMBINED_UNIFORM_BLOCKS: 2087 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: 2088 case GL_MAX_DRAW_BUFFERS: 2089 case GL_MAX_ELEMENT_INDEX: 2090 case GL_MAX_ELEMENTS_INDICES: 2091 case GL_MAX_ELEMENTS_VERTICES: 2092 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: 2093 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: 2094 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: 2095 case GL_MAX_PROGRAM_TEXEL_OFFSET: 2096 case GL_MAX_SERVER_WAIT_TIMEOUT: 2097 case GL_MAX_TEXTURE_LOD_BIAS: 2098 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: 2099 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: 2100 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: 2101 case GL_MAX_UNIFORM_BLOCK_SIZE: 2102 case GL_MAX_UNIFORM_BUFFER_BINDINGS: 2103 case GL_MAX_VARYING_COMPONENTS: 2104 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: 2105 case GL_MAX_VERTEX_UNIFORM_BLOCKS: 2106 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: 2107 case GL_MIN_PROGRAM_TEXEL_OFFSET: 2108 case GL_MINOR_VERSION: 2109 case GL_NUM_EXTENSIONS: 2110 case GL_NUM_PROGRAM_BINARY_FORMATS: 2111 case GL_PACK_ROW_LENGTH: 2112 case GL_PACK_SKIP_PIXELS: 2113 case GL_PACK_SKIP_ROWS: 2114 case GL_PIXEL_PACK_BUFFER_BINDING: 2115 case GL_PIXEL_UNPACK_BUFFER_BINDING: 2116 case GL_PROGRAM_BINARY_FORMATS: 2117 case GL_READ_BUFFER: 2118 case GL_SAMPLER_BINDING: 2119 case GL_TEXTURE_BINDING_2D_ARRAY: 2120 case GL_UNIFORM_BUFFER_BINDING: 2121 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: 2122 case GL_UNIFORM_BUFFER_SIZE: 2123 case GL_UNIFORM_BUFFER_START: 2124 case GL_UNPACK_IMAGE_HEIGHT: 2125 case GL_UNPACK_ROW_LENGTH: 2126 case GL_UNPACK_SKIP_IMAGES: 2127 case GL_UNPACK_SKIP_PIXELS: 2128 case GL_UNPACK_SKIP_ROWS: 2129 case GL_VERTEX_ARRAY_BINDING: 2130 { 2131 *type = GL_INT; 2132 *numParams = 1; 2133 } 2134 break; 2135 case GL_MAX_SAMPLES_ANGLE: 2136 { 2137 *type = GL_INT; 2138 *numParams = 1; 2139 } 2140 break; 2141 case GL_MAX_VIEWPORT_DIMS: 2142 { 2143 *type = GL_INT; 2144 *numParams = 2; 2145 } 2146 break; 2147 case GL_VIEWPORT: 2148 case GL_SCISSOR_BOX: 2149 { 2150 *type = GL_INT; 2151 *numParams = 4; 2152 } 2153 break; 2154 case GL_SHADER_COMPILER: 2155 case GL_SAMPLE_COVERAGE_INVERT: 2156 case GL_DEPTH_WRITEMASK: 2157 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled, 2158 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries. 2159 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural 2160 case GL_SAMPLE_COVERAGE: 2161 case GL_SCISSOR_TEST: 2162 case GL_STENCIL_TEST: 2163 case GL_DEPTH_TEST: 2164 case GL_BLEND: 2165 case GL_DITHER: 2166 case GL_PRIMITIVE_RESTART_FIXED_INDEX: 2167 case GL_RASTERIZER_DISCARD: 2168 { 2169 *type = GL_BOOL; 2170 *numParams = 1; 2171 } 2172 break; 2173 case GL_COLOR_WRITEMASK: 2174 { 2175 *type = GL_BOOL; 2176 *numParams = 4; 2177 } 2178 break; 2179 case GL_POLYGON_OFFSET_FACTOR: 2180 case GL_POLYGON_OFFSET_UNITS: 2181 case GL_SAMPLE_COVERAGE_VALUE: 2182 case GL_DEPTH_CLEAR_VALUE: 2183 case GL_LINE_WIDTH: 2184 { 2185 *type = GL_FLOAT; 2186 *numParams = 1; 2187 } 2188 break; 2189 case GL_ALIASED_LINE_WIDTH_RANGE: 2190 case GL_ALIASED_POINT_SIZE_RANGE: 2191 case GL_DEPTH_RANGE: 2192 { 2193 *type = GL_FLOAT; 2194 *numParams = 2; 2195 } 2196 break; 2197 case GL_COLOR_CLEAR_VALUE: 2198 case GL_BLEND_COLOR: 2199 { 2200 *type = GL_FLOAT; 2201 *numParams = 4; 2202 } 2203 break; 2204 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: 2205 *type = GL_FLOAT; 2206 *numParams = 1; 2207 break; 2208 default: 2209 return false; 2210 } 2211 2212 return true; 2213} 2214 2215// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle 2216bool Context::applyRenderTarget() 2217{ 2218 Framebuffer *framebuffer = getDrawFramebuffer(); 2219 int width, height, samples; 2220 2221 if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE) 2222 { 2223 return error(GL_INVALID_FRAMEBUFFER_OPERATION, false); 2224 } 2225 2226 egl::Image *renderTarget = framebuffer->getRenderTarget(); 2227 device->setRenderTarget(renderTarget); 2228 if(renderTarget) renderTarget->release(); 2229 2230 egl::Image *depthStencil = framebuffer->getDepthStencil(); 2231 device->setDepthStencilSurface(depthStencil); 2232 if(depthStencil) depthStencil->release(); 2233 2234 Viewport viewport; 2235 float zNear = clamp01(mState.zNear); 2236 float zFar = clamp01(mState.zFar); 2237 2238 viewport.x0 = mState.viewportX; 2239 viewport.y0 = mState.viewportY; 2240 viewport.width = mState.viewportWidth; 2241 viewport.height = mState.viewportHeight; 2242 viewport.minZ = zNear; 2243 viewport.maxZ = zFar; 2244 2245 device->setViewport(viewport); 2246 2247 if(mState.scissorTest) 2248 { 2249 sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight}; 2250 scissor.clip(0, 0, width, height); 2251 2252 device->setScissorRect(scissor); 2253 device->setScissorEnable(true); 2254 } 2255 else 2256 { 2257 device->setScissorEnable(false); 2258 } 2259 2260 Program *program = getCurrentProgram(); 2261 2262 if(program) 2263 { 2264 GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear}; 2265 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]); 2266 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]); 2267 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]); 2268 } 2269 2270 return true; 2271} 2272 2273// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) 2274void Context::applyState(GLenum drawMode) 2275{ 2276 Framebuffer *framebuffer = getDrawFramebuffer(); 2277 2278 if(mState.cullFace) 2279 { 2280 device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace)); 2281 } 2282 else 2283 { 2284 device->setCullMode(sw::CULL_NONE); 2285 } 2286 2287 if(mDepthStateDirty) 2288 { 2289 if(mState.depthTest) 2290 { 2291 device->setDepthBufferEnable(true); 2292 device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc)); 2293 } 2294 else 2295 { 2296 device->setDepthBufferEnable(false); 2297 } 2298 2299 mDepthStateDirty = false; 2300 } 2301 2302 if(mBlendStateDirty) 2303 { 2304 if(mState.blend) 2305 { 2306 device->setAlphaBlendEnable(true); 2307 device->setSeparateAlphaBlendEnable(true); 2308 2309 device->setBlendConstant(es2sw::ConvertColor(mState.blendColor)); 2310 2311 device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB)); 2312 device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB)); 2313 device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB)); 2314 2315 device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha)); 2316 device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha)); 2317 device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha)); 2318 } 2319 else 2320 { 2321 device->setAlphaBlendEnable(false); 2322 } 2323 2324 mBlendStateDirty = false; 2325 } 2326 2327 if(mStencilStateDirty || mFrontFaceDirty) 2328 { 2329 if(mState.stencilTest && framebuffer->hasStencil()) 2330 { 2331 device->setStencilEnable(true); 2332 device->setTwoSidedStencil(true); 2333 2334 if(mState.stencilWritemask != mState.stencilBackWritemask || 2335 mState.stencilRef != mState.stencilBackRef || 2336 mState.stencilMask != mState.stencilBackMask) 2337 { 2338 ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL."); 2339 return error(GL_INVALID_OPERATION); 2340 } 2341 2342 // get the maximum size of the stencil ref 2343 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer(); 2344 GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1; 2345 2346 if(mState.frontFace == GL_CCW) 2347 { 2348 device->setStencilWriteMask(mState.stencilWritemask); 2349 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc)); 2350 2351 device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil); 2352 device->setStencilMask(mState.stencilMask); 2353 2354 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail)); 2355 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail)); 2356 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass)); 2357 2358 device->setStencilWriteMaskCCW(mState.stencilBackWritemask); 2359 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc)); 2360 2361 device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil); 2362 device->setStencilMaskCCW(mState.stencilBackMask); 2363 2364 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail)); 2365 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail)); 2366 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass)); 2367 } 2368 else 2369 { 2370 device->setStencilWriteMaskCCW(mState.stencilWritemask); 2371 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc)); 2372 2373 device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil); 2374 device->setStencilMaskCCW(mState.stencilMask); 2375 2376 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail)); 2377 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail)); 2378 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass)); 2379 2380 device->setStencilWriteMask(mState.stencilBackWritemask); 2381 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc)); 2382 2383 device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil); 2384 device->setStencilMask(mState.stencilBackMask); 2385 2386 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail)); 2387 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail)); 2388 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass)); 2389 } 2390 } 2391 else 2392 { 2393 device->setStencilEnable(false); 2394 } 2395 2396 mStencilStateDirty = false; 2397 mFrontFaceDirty = false; 2398 } 2399 2400 if(mMaskStateDirty) 2401 { 2402 device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha)); 2403 device->setDepthWriteEnable(mState.depthMask); 2404 2405 mMaskStateDirty = false; 2406 } 2407 2408 if(mPolygonOffsetStateDirty) 2409 { 2410 if(mState.polygonOffsetFill) 2411 { 2412 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer(); 2413 if(depthbuffer) 2414 { 2415 device->setSlopeDepthBias(mState.polygonOffsetFactor); 2416 float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize())); 2417 device->setDepthBias(depthBias); 2418 } 2419 } 2420 else 2421 { 2422 device->setSlopeDepthBias(0); 2423 device->setDepthBias(0); 2424 } 2425 2426 mPolygonOffsetStateDirty = false; 2427 } 2428 2429 if(mSampleStateDirty) 2430 { 2431 if(mState.sampleAlphaToCoverage) 2432 { 2433 device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE); 2434 } 2435 else 2436 { 2437 device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE); 2438 } 2439 2440 if(mState.sampleCoverage) 2441 { 2442 unsigned int mask = 0; 2443 if(mState.sampleCoverageValue != 0) 2444 { 2445 int width, height, samples; 2446 framebuffer->completeness(width, height, samples); 2447 2448 float threshold = 0.5f; 2449 2450 for(int i = 0; i < samples; i++) 2451 { 2452 mask <<= 1; 2453 2454 if((i + 1) * mState.sampleCoverageValue >= threshold) 2455 { 2456 threshold += 1.0f; 2457 mask |= 1; 2458 } 2459 } 2460 } 2461 2462 if(mState.sampleCoverageInvert) 2463 { 2464 mask = ~mask; 2465 } 2466 2467 device->setMultiSampleMask(mask); 2468 } 2469 else 2470 { 2471 device->setMultiSampleMask(0xFFFFFFFF); 2472 } 2473 2474 mSampleStateDirty = false; 2475 } 2476 2477 if(mDitherStateDirty) 2478 { 2479 // UNIMPLEMENTED(); // FIXME 2480 2481 mDitherStateDirty = false; 2482 } 2483} 2484 2485GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count) 2486{ 2487 TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS]; 2488 2489 GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes); 2490 if(err != GL_NO_ERROR) 2491 { 2492 return err; 2493 } 2494 2495 Program *program = getCurrentProgram(); 2496 2497 device->resetInputStreams(false); 2498 2499 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 2500 { 2501 if(program->getAttributeStream(i) == -1) 2502 { 2503 continue; 2504 } 2505 2506 sw::Resource *resource = attributes[i].vertexBuffer; 2507 const void *buffer = (char*)resource->data() + attributes[i].offset; 2508 2509 int stride = attributes[i].stride; 2510 2511 buffer = (char*)buffer + stride * base; 2512 2513 sw::Stream attribute(resource, buffer, stride); 2514 2515 attribute.type = attributes[i].type; 2516 attribute.count = attributes[i].count; 2517 attribute.normalized = attributes[i].normalized; 2518 2519 int stream = program->getAttributeStream(i); 2520 device->setInputStream(stream, attribute); 2521 } 2522 2523 return GL_NO_ERROR; 2524} 2525 2526// Applies the indices and element array bindings 2527GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) 2528{ 2529 GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer, indices, indexInfo); 2530 2531 if(err == GL_NO_ERROR) 2532 { 2533 device->setIndexBuffer(indexInfo->indexBuffer); 2534 } 2535 2536 return err; 2537} 2538 2539// Applies the shaders and shader constants 2540void Context::applyShaders() 2541{ 2542 Program *programObject = getCurrentProgram(); 2543 sw::VertexShader *vertexShader = programObject->getVertexShader(); 2544 sw::PixelShader *pixelShader = programObject->getPixelShader(); 2545 2546 device->setVertexShader(vertexShader); 2547 device->setPixelShader(pixelShader); 2548 2549 if(programObject->getSerial() != mAppliedProgramSerial) 2550 { 2551 programObject->dirtyAllUniforms(); 2552 mAppliedProgramSerial = programObject->getSerial(); 2553 } 2554 2555 programObject->applyUniforms(); 2556} 2557 2558void Context::applyTextures() 2559{ 2560 applyTextures(sw::SAMPLER_PIXEL); 2561 applyTextures(sw::SAMPLER_VERTEX); 2562} 2563 2564void Context::applyTextures(sw::SamplerType samplerType) 2565{ 2566 Program *programObject = getCurrentProgram(); 2567 2568 int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS; // Range of samplers of given sampler type 2569 2570 for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++) 2571 { 2572 int textureUnit = programObject->getSamplerMapping(samplerType, samplerIndex); // OpenGL texture image unit index 2573 2574 if(textureUnit != -1) 2575 { 2576 TextureType textureType = programObject->getSamplerTextureType(samplerType, samplerIndex); 2577 2578 Texture *texture = getSamplerTexture(textureUnit, textureType); 2579 2580 if(texture->isSamplerComplete()) 2581 { 2582 GLenum wrapS = texture->getWrapS(); 2583 GLenum wrapT = texture->getWrapT(); 2584 GLenum wrapR = texture->getWrapR(); 2585 GLenum texFilter = texture->getMinFilter(); 2586 GLenum magFilter = texture->getMagFilter(); 2587 GLfloat maxAnisotropy = texture->getMaxAnisotropy(); 2588 2589 device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS)); 2590 device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT)); 2591 device->setAddressingModeW(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapR)); 2592 2593 sw::FilterType minFilter; 2594 sw::MipmapType mipFilter; 2595 es2sw::ConvertMinFilter(texFilter, &minFilter, &mipFilter, maxAnisotropy); 2596 // ASSERT(minFilter == es2sw::ConvertMagFilter(magFilter)); 2597 2598 device->setTextureFilter(samplerType, samplerIndex, minFilter); 2599 // device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertMagFilter(magFilter)); 2600 device->setMipmapFilter(samplerType, samplerIndex, mipFilter); 2601 device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy); 2602 2603 applyTexture(samplerType, samplerIndex, texture); 2604 } 2605 else 2606 { 2607 applyTexture(samplerType, samplerIndex, 0); 2608 } 2609 } 2610 else 2611 { 2612 applyTexture(samplerType, samplerIndex, NULL); 2613 } 2614 } 2615} 2616 2617void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture) 2618{ 2619 Program *program = getCurrentProgram(); 2620 int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index; 2621 bool textureUsed = false; 2622 2623 if(type == sw::SAMPLER_PIXEL) 2624 { 2625 textureUsed = program->getPixelShader()->usesSampler(index); 2626 } 2627 else if(type == sw::SAMPLER_VERTEX) 2628 { 2629 textureUsed = program->getVertexShader()->usesSampler(index); 2630 } 2631 else UNREACHABLE(); 2632 2633 sw::Resource *resource = 0; 2634 2635 if(baseTexture && textureUsed) 2636 { 2637 resource = baseTexture->getResource(); 2638 } 2639 2640 device->setTextureResource(sampler, resource); 2641 2642 if(baseTexture && textureUsed) 2643 { 2644 int levelCount = baseTexture->getLevelCount(); 2645 2646 if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES) 2647 { 2648 Texture2D *texture = static_cast<Texture2D*>(baseTexture); 2649 2650 for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++) 2651 { 2652 int surfaceLevel = mipmapLevel; 2653 2654 if(surfaceLevel < 0) 2655 { 2656 surfaceLevel = 0; 2657 } 2658 else if(surfaceLevel >= levelCount) 2659 { 2660 surfaceLevel = levelCount - 1; 2661 } 2662 2663 egl::Image *surface = texture->getImage(surfaceLevel); 2664 device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D); 2665 } 2666 } 2667 else if(baseTexture->getTarget() == GL_TEXTURE_3D_OES) 2668 { 2669 Texture3D *texture = static_cast<Texture3D*>(baseTexture); 2670 2671 for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++) 2672 { 2673 int surfaceLevel = mipmapLevel; 2674 2675 if(surfaceLevel < 0) 2676 { 2677 surfaceLevel = 0; 2678 } 2679 else if(surfaceLevel >= levelCount) 2680 { 2681 surfaceLevel = levelCount - 1; 2682 } 2683 2684 egl::Image *surface = texture->getImage(surfaceLevel); 2685 device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_3D); 2686 } 2687 } 2688 else if(baseTexture->getTarget() == GL_TEXTURE_CUBE_MAP) 2689 { 2690 for(int face = 0; face < 6; face++) 2691 { 2692 TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture); 2693 2694 for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++) 2695 { 2696 int surfaceLevel = mipmapLevel; 2697 2698 if(surfaceLevel < 0) 2699 { 2700 surfaceLevel = 0; 2701 } 2702 else if(surfaceLevel >= levelCount) 2703 { 2704 surfaceLevel = levelCount - 1; 2705 } 2706 2707 egl::Image *surface = cubeTexture->getImage(face, surfaceLevel); 2708 device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE); 2709 } 2710 } 2711 } 2712 else UNIMPLEMENTED(); 2713 } 2714 else 2715 { 2716 device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL); 2717 } 2718} 2719 2720void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, 2721 GLenum format, GLenum type, GLsizei *bufSize, void* pixels) 2722{ 2723 Framebuffer *framebuffer = getReadFramebuffer(); 2724 int framebufferWidth, framebufferHeight, framebufferSamples; 2725 2726 if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE) 2727 { 2728 return error(GL_INVALID_FRAMEBUFFER_OPERATION); 2729 } 2730 2731 if(getReadFramebufferName() != 0 && framebufferSamples != 0) 2732 { 2733 return error(GL_INVALID_OPERATION); 2734 } 2735 2736 if(format != GL_RGBA || type != GL_UNSIGNED_BYTE) 2737 { 2738 if(format != framebuffer->getImplementationColorReadFormat() || type != framebuffer->getImplementationColorReadType()) 2739 { 2740 return error(GL_INVALID_OPERATION); 2741 } 2742 } 2743 2744 GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment); 2745 2746 // Sized query sanity check 2747 if(bufSize) 2748 { 2749 int requiredSize = outputPitch * height; 2750 if(requiredSize > *bufSize) 2751 { 2752 return error(GL_INVALID_OPERATION); 2753 } 2754 } 2755 2756 egl::Image *renderTarget = framebuffer->getRenderTarget(); 2757 2758 if(!renderTarget) 2759 { 2760 return error(GL_OUT_OF_MEMORY); 2761 } 2762 2763 sw::Rect rect = {x, y, x + width, y + height}; 2764 rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight()); 2765 2766 unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY); 2767 unsigned char *dest = (unsigned char*)pixels; 2768 int inputPitch = (int)renderTarget->getPitch(); 2769 2770 for(int j = 0; j < rect.y1 - rect.y0; j++) 2771 { 2772 unsigned short *dest16 = (unsigned short*)dest; 2773 unsigned int *dest32 = (unsigned int*)dest; 2774 2775 if(renderTarget->getInternalFormat() == sw::FORMAT_A8B8G8R8 && 2776 format == GL_RGBA && type == GL_UNSIGNED_BYTE) 2777 { 2778 memcpy(dest, source, (rect.x1 - rect.x0) * 4); 2779 } 2780 else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 && 2781 format == GL_RGBA && type == GL_UNSIGNED_BYTE) 2782 { 2783 for(int i = 0; i < rect.x1 - rect.x0; i++) 2784 { 2785 unsigned int argb = *(unsigned int*)(source + 4 * i); 2786 2787 dest32[i] = (argb & 0xFF00FF00) | ((argb & 0x000000FF) << 16) | ((argb & 0x00FF0000) >> 16); 2788 } 2789 } 2790 else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 && 2791 format == GL_RGBA && type == GL_UNSIGNED_BYTE) 2792 { 2793 for(int i = 0; i < rect.x1 - rect.x0; i++) 2794 { 2795 unsigned int xrgb = *(unsigned int*)(source + 4 * i); 2796 2797 dest32[i] = (xrgb & 0xFF00FF00) | ((xrgb & 0x000000FF) << 16) | ((xrgb & 0x00FF0000) >> 16) | 0xFF000000; 2798 } 2799 } 2800 else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 && 2801 format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) 2802 { 2803 for(int i = 0; i < rect.x1 - rect.x0; i++) 2804 { 2805 unsigned int xrgb = *(unsigned int*)(source + 4 * i); 2806 2807 dest32[i] = xrgb | 0xFF000000; 2808 } 2809 } 2810 else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 && 2811 format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) 2812 { 2813 memcpy(dest, source, (rect.x1 - rect.x0) * 4); 2814 } 2815 else if(renderTarget->getInternalFormat() == sw::FORMAT_A16B16G16R16F && 2816 format == GL_RGBA && type == GL_HALF_FLOAT_OES) 2817 { 2818 memcpy(dest, source, (rect.x1 - rect.x0) * 8); 2819 } 2820 else if(renderTarget->getInternalFormat() == sw::FORMAT_A32B32G32R32F && 2821 format == GL_RGBA && type == GL_FLOAT) 2822 { 2823 memcpy(dest, source, (rect.x1 - rect.x0) * 16); 2824 } 2825 else if(renderTarget->getInternalFormat() == sw::FORMAT_A1R5G5B5 && 2826 format == GL_BGRA_EXT && type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT) 2827 { 2828 memcpy(dest, source, (rect.x1 - rect.x0) * 2); 2829 } 2830 else if(renderTarget->getInternalFormat() == sw::FORMAT_R5G6B5 && 2831 format == 0x80E0 && type == GL_UNSIGNED_SHORT_5_6_5) // GL_BGR_EXT 2832 { 2833 memcpy(dest, source, (rect.x1 - rect.x0) * 2); 2834 } 2835 else 2836 { 2837 for(int i = 0; i < rect.x1 - rect.x0; i++) 2838 { 2839 float r; 2840 float g; 2841 float b; 2842 float a; 2843 2844 switch(renderTarget->getInternalFormat()) 2845 { 2846 case sw::FORMAT_R5G6B5: 2847 { 2848 unsigned short rgb = *(unsigned short*)(source + 2 * i); 2849 2850 a = 1.0f; 2851 b = (rgb & 0x001F) * (1.0f / 0x001F); 2852 g = (rgb & 0x07E0) * (1.0f / 0x07E0); 2853 r = (rgb & 0xF800) * (1.0f / 0xF800); 2854 } 2855 break; 2856 case sw::FORMAT_A1R5G5B5: 2857 { 2858 unsigned short argb = *(unsigned short*)(source + 2 * i); 2859 2860 a = (argb & 0x8000) ? 1.0f : 0.0f; 2861 b = (argb & 0x001F) * (1.0f / 0x001F); 2862 g = (argb & 0x03E0) * (1.0f / 0x03E0); 2863 r = (argb & 0x7C00) * (1.0f / 0x7C00); 2864 } 2865 break; 2866 case sw::FORMAT_A8R8G8B8: 2867 { 2868 unsigned int argb = *(unsigned int*)(source + 4 * i); 2869 2870 a = (argb & 0xFF000000) * (1.0f / 0xFF000000); 2871 b = (argb & 0x000000FF) * (1.0f / 0x000000FF); 2872 g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00); 2873 r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000); 2874 } 2875 break; 2876 case sw::FORMAT_A8B8G8R8: 2877 { 2878 unsigned int abgr = *(unsigned int*)(source + 4 * i); 2879 2880 a = (abgr & 0xFF000000) * (1.0f / 0xFF000000); 2881 b = (abgr & 0x00FF0000) * (1.0f / 0x00FF0000); 2882 g = (abgr & 0x0000FF00) * (1.0f / 0x0000FF00); 2883 r = (abgr & 0x000000FF) * (1.0f / 0x000000FF); 2884 } 2885 break; 2886 case sw::FORMAT_X8R8G8B8: 2887 { 2888 unsigned int xrgb = *(unsigned int*)(source + 4 * i); 2889 2890 a = 1.0f; 2891 b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF); 2892 g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00); 2893 r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000); 2894 } 2895 break; 2896 case sw::FORMAT_X8B8G8R8: 2897 { 2898 unsigned int xbgr = *(unsigned int*)(source + 4 * i); 2899 2900 a = 1.0f; 2901 b = (xbgr & 0x00FF0000) * (1.0f / 0x00FF0000); 2902 g = (xbgr & 0x0000FF00) * (1.0f / 0x0000FF00); 2903 r = (xbgr & 0x000000FF) * (1.0f / 0x000000FF); 2904 } 2905 break; 2906 case sw::FORMAT_A2R10G10B10: 2907 { 2908 unsigned int argb = *(unsigned int*)(source + 4 * i); 2909 2910 a = (argb & 0xC0000000) * (1.0f / 0xC0000000); 2911 b = (argb & 0x000003FF) * (1.0f / 0x000003FF); 2912 g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00); 2913 r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000); 2914 } 2915 break; 2916 case sw::FORMAT_A32B32G32R32F: 2917 { 2918 r = *((float*)(source + 16 * i) + 0); 2919 g = *((float*)(source + 16 * i) + 1); 2920 b = *((float*)(source + 16 * i) + 2); 2921 a = *((float*)(source + 16 * i) + 3); 2922 } 2923 break; 2924 case sw::FORMAT_A16B16G16R16F: 2925 { 2926 r = (float)*((sw::half*)(source + 8 * i) + 0); 2927 g = (float)*((sw::half*)(source + 8 * i) + 1); 2928 b = (float)*((sw::half*)(source + 8 * i) + 2); 2929 a = (float)*((sw::half*)(source + 8 * i) + 3); 2930 } 2931 break; 2932 default: 2933 UNIMPLEMENTED(); // FIXME 2934 UNREACHABLE(); 2935 } 2936 2937 switch(format) 2938 { 2939 case GL_RGBA: 2940 switch(type) 2941 { 2942 case GL_UNSIGNED_BYTE: 2943 dest[4 * i + 0] = (unsigned char)(255 * r + 0.5f); 2944 dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f); 2945 dest[4 * i + 2] = (unsigned char)(255 * b + 0.5f); 2946 dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f); 2947 break; 2948 default: UNREACHABLE(); 2949 } 2950 break; 2951 case GL_BGRA_EXT: 2952 switch(type) 2953 { 2954 case GL_UNSIGNED_BYTE: 2955 dest[4 * i + 0] = (unsigned char)(255 * b + 0.5f); 2956 dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f); 2957 dest[4 * i + 2] = (unsigned char)(255 * r + 0.5f); 2958 dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f); 2959 break; 2960 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: 2961 // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section 2962 // this type is packed as follows: 2963 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 2964 // -------------------------------------------------------------------------------- 2965 // | 4th | 3rd | 2nd | 1st component | 2966 // -------------------------------------------------------------------------------- 2967 // in the case of BGRA_EXT, B is the first component, G the second, and so forth. 2968 dest16[i] = 2969 ((unsigned short)(15 * a + 0.5f) << 12)| 2970 ((unsigned short)(15 * r + 0.5f) << 8) | 2971 ((unsigned short)(15 * g + 0.5f) << 4) | 2972 ((unsigned short)(15 * b + 0.5f) << 0); 2973 break; 2974 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: 2975 // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section 2976 // this type is packed as follows: 2977 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 2978 // -------------------------------------------------------------------------------- 2979 // | 4th | 3rd | 2nd | 1st component | 2980 // -------------------------------------------------------------------------------- 2981 // in the case of BGRA_EXT, B is the first component, G the second, and so forth. 2982 dest16[i] = 2983 ((unsigned short)( a + 0.5f) << 15) | 2984 ((unsigned short)(31 * r + 0.5f) << 10) | 2985 ((unsigned short)(31 * g + 0.5f) << 5) | 2986 ((unsigned short)(31 * b + 0.5f) << 0); 2987 break; 2988 default: UNREACHABLE(); 2989 } 2990 break; 2991 case GL_RGB: 2992 switch(type) 2993 { 2994 case GL_UNSIGNED_SHORT_5_6_5: 2995 dest16[i] = 2996 ((unsigned short)(31 * b + 0.5f) << 0) | 2997 ((unsigned short)(63 * g + 0.5f) << 5) | 2998 ((unsigned short)(31 * r + 0.5f) << 11); 2999 break; 3000 default: UNREACHABLE(); 3001 } 3002 break; 3003 default: UNREACHABLE(); 3004 } 3005 } 3006 } 3007 3008 source += inputPitch; 3009 dest += outputPitch; 3010 } 3011 3012 renderTarget->unlock(); 3013 renderTarget->release(); 3014} 3015 3016void Context::clear(GLbitfield mask) 3017{ 3018 Framebuffer *framebuffer = getDrawFramebuffer(); 3019 3020 if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) 3021 { 3022 return error(GL_INVALID_FRAMEBUFFER_OPERATION); 3023 } 3024 3025 if(!applyRenderTarget()) 3026 { 3027 return; 3028 } 3029 3030 unsigned int color = (unorm<8>(mState.colorClearValue.alpha) << 24) | 3031 (unorm<8>(mState.colorClearValue.red) << 16) | 3032 (unorm<8>(mState.colorClearValue.green) << 8) | 3033 (unorm<8>(mState.colorClearValue.blue) << 0); 3034 float depth = clamp01(mState.depthClearValue); 3035 int stencil = mState.stencilClearValue & 0x000000FF; 3036 3037 if(mask & GL_COLOR_BUFFER_BIT) 3038 { 3039 unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) | 3040 (mState.colorMaskGreen ? 0x2 : 0) | 3041 (mState.colorMaskBlue ? 0x4 : 0) | 3042 (mState.colorMaskAlpha ? 0x8 : 0); 3043 3044 if(rgbaMask != 0) 3045 { 3046 device->clearColor(color, rgbaMask); 3047 } 3048 } 3049 3050 if(mask & GL_DEPTH_BUFFER_BIT) 3051 { 3052 if(mState.depthMask != 0) 3053 { 3054 device->clearDepth(depth); 3055 } 3056 } 3057 3058 if(mask & GL_STENCIL_BUFFER_BIT) 3059 { 3060 if(mState.stencilWritemask != 0) 3061 { 3062 device->clearStencil(stencil, mState.stencilWritemask); 3063 } 3064 } 3065} 3066 3067void Context::drawArrays(GLenum mode, GLint first, GLsizei count) 3068{ 3069 if(!mState.currentProgram) 3070 { 3071 return error(GL_INVALID_OPERATION); 3072 } 3073 3074 PrimitiveType primitiveType; 3075 int primitiveCount; 3076 3077 if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount)) 3078 return error(GL_INVALID_ENUM); 3079 3080 if(primitiveCount <= 0) 3081 { 3082 return; 3083 } 3084 3085 if(!applyRenderTarget()) 3086 { 3087 return; 3088 } 3089 3090 applyState(mode); 3091 3092 GLenum err = applyVertexBuffer(0, first, count); 3093 if(err != GL_NO_ERROR) 3094 { 3095 return error(err); 3096 } 3097 3098 applyShaders(); 3099 applyTextures(); 3100 3101 if(!getCurrentProgram()->validateSamplers(false)) 3102 { 3103 return error(GL_INVALID_OPERATION); 3104 } 3105 3106 if(!cullSkipsDraw(mode)) 3107 { 3108 device->drawPrimitive(primitiveType, primitiveCount); 3109 } 3110} 3111 3112void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) 3113{ 3114 if(!mState.currentProgram) 3115 { 3116 return error(GL_INVALID_OPERATION); 3117 } 3118 3119 if(!indices && !mState.elementArrayBuffer) 3120 { 3121 return error(GL_INVALID_OPERATION); 3122 } 3123 3124 PrimitiveType primitiveType; 3125 int primitiveCount; 3126 3127 if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount)) 3128 return error(GL_INVALID_ENUM); 3129 3130 if(primitiveCount <= 0) 3131 { 3132 return; 3133 } 3134 3135 if(!applyRenderTarget()) 3136 { 3137 return; 3138 } 3139 3140 applyState(mode); 3141 3142 TranslatedIndexData indexInfo; 3143 GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo); 3144 if(err != GL_NO_ERROR) 3145 { 3146 return error(err); 3147 } 3148 3149 GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1; 3150 err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount); 3151 if(err != GL_NO_ERROR) 3152 { 3153 return error(err); 3154 } 3155 3156 applyShaders(); 3157 applyTextures(); 3158 3159 if(!getCurrentProgram()->validateSamplers(false)) 3160 { 3161 return error(GL_INVALID_OPERATION); 3162 } 3163 3164 if(!cullSkipsDraw(mode)) 3165 { 3166 device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount, IndexDataManager::typeSize(type)); 3167 } 3168} 3169 3170void Context::finish() 3171{ 3172 device->finish(); 3173} 3174 3175void Context::flush() 3176{ 3177 // We don't queue anything without processing it as fast as possible 3178} 3179 3180void Context::recordInvalidEnum() 3181{ 3182 mInvalidEnum = true; 3183} 3184 3185void Context::recordInvalidValue() 3186{ 3187 mInvalidValue = true; 3188} 3189 3190void Context::recordInvalidOperation() 3191{ 3192 mInvalidOperation = true; 3193} 3194 3195void Context::recordOutOfMemory() 3196{ 3197 mOutOfMemory = true; 3198} 3199 3200void Context::recordInvalidFramebufferOperation() 3201{ 3202 mInvalidFramebufferOperation = true; 3203} 3204 3205// Get one of the recorded errors and clear its flag, if any. 3206// [OpenGL ES 2.0.24] section 2.5 page 13. 3207GLenum Context::getError() 3208{ 3209 if(mInvalidEnum) 3210 { 3211 mInvalidEnum = false; 3212 3213 return GL_INVALID_ENUM; 3214 } 3215 3216 if(mInvalidValue) 3217 { 3218 mInvalidValue = false; 3219 3220 return GL_INVALID_VALUE; 3221 } 3222 3223 if(mInvalidOperation) 3224 { 3225 mInvalidOperation = false; 3226 3227 return GL_INVALID_OPERATION; 3228 } 3229 3230 if(mOutOfMemory) 3231 { 3232 mOutOfMemory = false; 3233 3234 return GL_OUT_OF_MEMORY; 3235 } 3236 3237 if(mInvalidFramebufferOperation) 3238 { 3239 mInvalidFramebufferOperation = false; 3240 3241 return GL_INVALID_FRAMEBUFFER_OPERATION; 3242 } 3243 3244 return GL_NO_ERROR; 3245} 3246 3247int Context::getSupportedMultiSampleDepth(sw::Format format, int requested) 3248{ 3249 if(requested <= 1) 3250 { 3251 return 1; 3252 } 3253 3254 if(requested == 2) 3255 { 3256 return 2; 3257 } 3258 3259 return 4; 3260} 3261 3262void Context::detachBuffer(GLuint buffer) 3263{ 3264 // [OpenGL ES 2.0.24] section 2.9 page 22: 3265 // If a buffer object is deleted while it is bound, all bindings to that object in the current context 3266 // (i.e. in the thread that called Delete-Buffers) are reset to zero. 3267 3268 if(mState.arrayBuffer.name() == buffer) 3269 { 3270 mState.arrayBuffer = NULL; 3271 } 3272 3273 if(mState.elementArrayBuffer.name() == buffer) 3274 { 3275 mState.elementArrayBuffer = NULL; 3276 } 3277 3278 for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++) 3279 { 3280 if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer) 3281 { 3282 mState.vertexAttribute[attribute].mBoundBuffer = NULL; 3283 } 3284 } 3285} 3286 3287void Context::detachTexture(GLuint texture) 3288{ 3289 // [OpenGL ES 2.0.24] section 3.8 page 84: 3290 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are 3291 // rebound to texture object zero 3292 3293 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++) 3294 { 3295 for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++) 3296 { 3297 if(mState.samplerTexture[type][sampler].name() == texture) 3298 { 3299 mState.samplerTexture[type][sampler] = NULL; 3300 } 3301 } 3302 } 3303 3304 // [OpenGL ES 2.0.24] section 4.4 page 112: 3305 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is 3306 // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this 3307 // image was attached in the currently bound framebuffer. 3308 3309 Framebuffer *readFramebuffer = getReadFramebuffer(); 3310 Framebuffer *drawFramebuffer = getDrawFramebuffer(); 3311 3312 if(readFramebuffer) 3313 { 3314 readFramebuffer->detachTexture(texture); 3315 } 3316 3317 if(drawFramebuffer && drawFramebuffer != readFramebuffer) 3318 { 3319 drawFramebuffer->detachTexture(texture); 3320 } 3321} 3322 3323void Context::detachFramebuffer(GLuint framebuffer) 3324{ 3325 // [OpenGL ES 2.0.24] section 4.4 page 107: 3326 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though 3327 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero. 3328 3329 if(mState.readFramebuffer == framebuffer) 3330 { 3331 bindReadFramebuffer(0); 3332 } 3333 3334 if(mState.drawFramebuffer == framebuffer) 3335 { 3336 bindDrawFramebuffer(0); 3337 } 3338} 3339 3340void Context::detachRenderbuffer(GLuint renderbuffer) 3341{ 3342 // [OpenGL ES 2.0.24] section 4.4 page 109: 3343 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer 3344 // had been executed with the target RENDERBUFFER and name of zero. 3345 3346 if(mState.renderbuffer.name() == renderbuffer) 3347 { 3348 bindRenderbuffer(0); 3349 } 3350 3351 // [OpenGL ES 2.0.24] section 4.4 page 111: 3352 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer, 3353 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment 3354 // point to which this image was attached in the currently bound framebuffer. 3355 3356 Framebuffer *readFramebuffer = getReadFramebuffer(); 3357 Framebuffer *drawFramebuffer = getDrawFramebuffer(); 3358 3359 if(readFramebuffer) 3360 { 3361 readFramebuffer->detachRenderbuffer(renderbuffer); 3362 } 3363 3364 if(drawFramebuffer && drawFramebuffer != readFramebuffer) 3365 { 3366 drawFramebuffer->detachRenderbuffer(renderbuffer); 3367 } 3368} 3369 3370bool Context::cullSkipsDraw(GLenum drawMode) 3371{ 3372 return mState.cullFace && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode); 3373} 3374 3375bool Context::isTriangleMode(GLenum drawMode) 3376{ 3377 switch (drawMode) 3378 { 3379 case GL_TRIANGLES: 3380 case GL_TRIANGLE_FAN: 3381 case GL_TRIANGLE_STRIP: 3382 return true; 3383 case GL_POINTS: 3384 case GL_LINES: 3385 case GL_LINE_LOOP: 3386 case GL_LINE_STRIP: 3387 return false; 3388 default: UNREACHABLE(); 3389 } 3390 3391 return false; 3392} 3393 3394void Context::setVertexAttrib(GLuint index, const GLfloat *values) 3395{ 3396 ASSERT(index < MAX_VERTEX_ATTRIBS); 3397 3398 mState.vertexAttribute[index].mCurrentValue[0] = values[0]; 3399 mState.vertexAttribute[index].mCurrentValue[1] = values[1]; 3400 mState.vertexAttribute[index].mCurrentValue[2] = values[2]; 3401 mState.vertexAttribute[index].mCurrentValue[3] = values[3]; 3402 3403 mVertexDataManager->dirtyCurrentValue(index); 3404} 3405 3406void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 3407 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 3408 GLbitfield mask) 3409{ 3410 Framebuffer *readFramebuffer = getReadFramebuffer(); 3411 Framebuffer *drawFramebuffer = getDrawFramebuffer(); 3412 3413 int readBufferWidth, readBufferHeight, readBufferSamples; 3414 int drawBufferWidth, drawBufferHeight, drawBufferSamples; 3415 3416 if(!readFramebuffer || readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE || 3417 !drawFramebuffer || drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE) 3418 { 3419 return error(GL_INVALID_FRAMEBUFFER_OPERATION); 3420 } 3421 3422 if(drawBufferSamples > 1) 3423 { 3424 return error(GL_INVALID_OPERATION); 3425 } 3426 3427 sw::SliceRect sourceRect; 3428 sw::SliceRect destRect; 3429 bool flipX = (srcX0 < srcX1) ^ (dstX0 < dstX1); 3430 bool flipy = (srcY0 < srcY1) ^ (dstY0 < dstY1); 3431 3432 if(srcX0 < srcX1) 3433 { 3434 sourceRect.x0 = srcX0; 3435 sourceRect.x1 = srcX1; 3436 } 3437 else 3438 { 3439 sourceRect.x0 = srcX1; 3440 sourceRect.x1 = srcX0; 3441 } 3442 3443 if(dstX0 < dstX1) 3444 { 3445 destRect.x0 = dstX0; 3446 destRect.x1 = dstX1; 3447 } 3448 else 3449 { 3450 destRect.x0 = dstX1; 3451 destRect.x1 = dstX0; 3452 } 3453 3454 if(srcY0 < srcY1) 3455 { 3456 sourceRect.y0 = srcY0; 3457 sourceRect.y1 = srcY1; 3458 } 3459 else 3460 { 3461 sourceRect.y0 = srcY1; 3462 sourceRect.y1 = srcY0; 3463 } 3464 3465 if(dstY0 < dstY1) 3466 { 3467 destRect.y0 = dstY0; 3468 destRect.y1 = dstY1; 3469 } 3470 else 3471 { 3472 destRect.y0 = dstY1; 3473 destRect.y1 = dstY0; 3474 } 3475 3476 sw::Rect sourceScissoredRect = sourceRect; 3477 sw::Rect destScissoredRect = destRect; 3478 3479 if(mState.scissorTest) // Only write to parts of the destination framebuffer which pass the scissor test 3480 { 3481 if(destRect.x0 < mState.scissorX) 3482 { 3483 int xDiff = mState.scissorX - destRect.x0; 3484 destScissoredRect.x0 = mState.scissorX; 3485 sourceScissoredRect.x0 += xDiff; 3486 } 3487 3488 if(destRect.x1 > mState.scissorX + mState.scissorWidth) 3489 { 3490 int xDiff = destRect.x1 - (mState.scissorX + mState.scissorWidth); 3491 destScissoredRect.x1 = mState.scissorX + mState.scissorWidth; 3492 sourceScissoredRect.x1 -= xDiff; 3493 } 3494 3495 if(destRect.y0 < mState.scissorY) 3496 { 3497 int yDiff = mState.scissorY - destRect.y0; 3498 destScissoredRect.y0 = mState.scissorY; 3499 sourceScissoredRect.y0 += yDiff; 3500 } 3501 3502 if(destRect.y1 > mState.scissorY + mState.scissorHeight) 3503 { 3504 int yDiff = destRect.y1 - (mState.scissorY + mState.scissorHeight); 3505 destScissoredRect.y1 = mState.scissorY + mState.scissorHeight; 3506 sourceScissoredRect.y1 -= yDiff; 3507 } 3508 } 3509 3510 sw::Rect sourceTrimmedRect = sourceScissoredRect; 3511 sw::Rect destTrimmedRect = destScissoredRect; 3512 3513 // The source & destination rectangles also may need to be trimmed if they fall out of the bounds of 3514 // the actual draw and read surfaces. 3515 if(sourceTrimmedRect.x0 < 0) 3516 { 3517 int xDiff = 0 - sourceTrimmedRect.x0; 3518 sourceTrimmedRect.x0 = 0; 3519 destTrimmedRect.x0 += xDiff; 3520 } 3521 3522 if(sourceTrimmedRect.x1 > readBufferWidth) 3523 { 3524 int xDiff = sourceTrimmedRect.x1 - readBufferWidth; 3525 sourceTrimmedRect.x1 = readBufferWidth; 3526 destTrimmedRect.x1 -= xDiff; 3527 } 3528 3529 if(sourceTrimmedRect.y0 < 0) 3530 { 3531 int yDiff = 0 - sourceTrimmedRect.y0; 3532 sourceTrimmedRect.y0 = 0; 3533 destTrimmedRect.y0 += yDiff; 3534 } 3535 3536 if(sourceTrimmedRect.y1 > readBufferHeight) 3537 { 3538 int yDiff = sourceTrimmedRect.y1 - readBufferHeight; 3539 sourceTrimmedRect.y1 = readBufferHeight; 3540 destTrimmedRect.y1 -= yDiff; 3541 } 3542 3543 if(destTrimmedRect.x0 < 0) 3544 { 3545 int xDiff = 0 - destTrimmedRect.x0; 3546 destTrimmedRect.x0 = 0; 3547 sourceTrimmedRect.x0 += xDiff; 3548 } 3549 3550 if(destTrimmedRect.x1 > drawBufferWidth) 3551 { 3552 int xDiff = destTrimmedRect.x1 - drawBufferWidth; 3553 destTrimmedRect.x1 = drawBufferWidth; 3554 sourceTrimmedRect.x1 -= xDiff; 3555 } 3556 3557 if(destTrimmedRect.y0 < 0) 3558 { 3559 int yDiff = 0 - destTrimmedRect.y0; 3560 destTrimmedRect.y0 = 0; 3561 sourceTrimmedRect.y0 += yDiff; 3562 } 3563 3564 if(destTrimmedRect.y1 > drawBufferHeight) 3565 { 3566 int yDiff = destTrimmedRect.y1 - drawBufferHeight; 3567 destTrimmedRect.y1 = drawBufferHeight; 3568 sourceTrimmedRect.y1 -= yDiff; 3569 } 3570 3571 bool partialBufferCopy = false; 3572 3573 if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight || 3574 sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth || 3575 destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight || 3576 destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth || 3577 sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0) 3578 { 3579 partialBufferCopy = true; 3580 } 3581 3582 bool blitRenderTarget = false; 3583 bool blitDepthStencil = false; 3584 3585 if(mask & GL_COLOR_BUFFER_BIT) 3586 { 3587 const bool validReadType = readFramebuffer->getColorbufferType() == GL_TEXTURE_2D || 3588 readFramebuffer->getColorbufferType() == GL_RENDERBUFFER; 3589 const bool validDrawType = drawFramebuffer->getColorbufferType() == GL_TEXTURE_2D || 3590 drawFramebuffer->getColorbufferType() == GL_RENDERBUFFER; 3591 if(!validReadType || !validDrawType) 3592 { 3593 return error(GL_INVALID_OPERATION); 3594 } 3595 3596 if(partialBufferCopy && readBufferSamples > 1) 3597 { 3598 return error(GL_INVALID_OPERATION); 3599 } 3600 3601 blitRenderTarget = true; 3602 } 3603 3604 if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) 3605 { 3606 Renderbuffer *readDSBuffer = NULL; 3607 Renderbuffer *drawDSBuffer = NULL; 3608 3609 // We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have 3610 // both a depth and stencil buffer, it will be the same buffer. 3611 3612 if(mask & GL_DEPTH_BUFFER_BIT) 3613 { 3614 if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer()) 3615 { 3616 if(readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType()) 3617 { 3618 return error(GL_INVALID_OPERATION); 3619 } 3620 3621 blitDepthStencil = true; 3622 readDSBuffer = readFramebuffer->getDepthbuffer(); 3623 drawDSBuffer = drawFramebuffer->getDepthbuffer(); 3624 } 3625 } 3626 3627 if(mask & GL_STENCIL_BUFFER_BIT) 3628 { 3629 if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer()) 3630 { 3631 if(readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType()) 3632 { 3633 return error(GL_INVALID_OPERATION); 3634 } 3635 3636 blitDepthStencil = true; 3637 readDSBuffer = readFramebuffer->getStencilbuffer(); 3638 drawDSBuffer = drawFramebuffer->getStencilbuffer(); 3639 } 3640 } 3641 3642 if(partialBufferCopy) 3643 { 3644 ERR("Only whole-buffer depth and stencil blits are supported by this implementation."); 3645 return error(GL_INVALID_OPERATION); // Only whole-buffer copies are permitted 3646 } 3647 3648 if((drawDSBuffer && drawDSBuffer->getSamples() > 1) || 3649 (readDSBuffer && readDSBuffer->getSamples() > 1)) 3650 { 3651 return error(GL_INVALID_OPERATION); 3652 } 3653 } 3654 3655 if(blitRenderTarget || blitDepthStencil) 3656 { 3657 if(blitRenderTarget) 3658 { 3659 egl::Image *readRenderTarget = readFramebuffer->getRenderTarget(); 3660 egl::Image *drawRenderTarget = drawFramebuffer->getRenderTarget(); 3661 3662 if(flipX) 3663 { 3664 swap(destRect.x0, destRect.x1); 3665 } 3666 if(flipy) 3667 { 3668 swap(destRect.y0, destRect.y1); 3669 } 3670 3671 bool success = device->stretchRect(readRenderTarget, &sourceRect, drawRenderTarget, &destRect, false); 3672 3673 readRenderTarget->release(); 3674 drawRenderTarget->release(); 3675 3676 if(!success) 3677 { 3678 ERR("BlitFramebuffer failed."); 3679 return; 3680 } 3681 } 3682 3683 if(blitDepthStencil) 3684 { 3685 bool success = device->stretchRect(readFramebuffer->getDepthStencil(), NULL, drawFramebuffer->getDepthStencil(), NULL, false); 3686 3687 if(!success) 3688 { 3689 ERR("BlitFramebuffer failed."); 3690 return; 3691 } 3692 } 3693 } 3694} 3695 3696void Context::bindTexImage(egl::Surface *surface) 3697{ 3698 es2::Texture2D *textureObject = getTexture2D(); 3699 3700 if(textureObject) 3701 { 3702 textureObject->bindTexImage(surface); 3703 } 3704} 3705 3706EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel) 3707{ 3708 GLenum textureTarget = GL_NONE; 3709 3710 switch(target) 3711 { 3712 case EGL_GL_TEXTURE_2D_KHR: 3713 textureTarget = GL_TEXTURE_2D; 3714 break; 3715 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: 3716 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: 3717 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: 3718 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: 3719 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: 3720 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: 3721 textureTarget = GL_TEXTURE_CUBE_MAP; 3722 break; 3723 case EGL_GL_RENDERBUFFER_KHR: 3724 break; 3725 #if defined(__ANDROID__) 3726 case EGL_NATIVE_BUFFER_ANDROID: 3727 break; 3728 #endif 3729 default: 3730 return EGL_BAD_PARAMETER; 3731 } 3732 3733 if(textureLevel >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 3734 { 3735 return EGL_BAD_MATCH; 3736 } 3737 3738 if(textureTarget != GL_NONE) 3739 { 3740 es2::Texture *texture = getTexture(name); 3741 3742 if(!texture || texture->getTarget() != textureTarget) 3743 { 3744 return EGL_BAD_PARAMETER; 3745 } 3746 3747 if(texture->isShared(textureTarget, textureLevel)) // Bound to an EGLSurface or already an EGLImage sibling 3748 { 3749 return EGL_BAD_ACCESS; 3750 } 3751 3752 if(textureLevel != 0 && !texture->isSamplerComplete()) 3753 { 3754 return EGL_BAD_PARAMETER; 3755 } 3756 3757 if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1)) 3758 { 3759 return EGL_BAD_PARAMETER; 3760 } 3761 } 3762 else if(target == EGL_GL_RENDERBUFFER_KHR) 3763 { 3764 es2::Renderbuffer *renderbuffer = getRenderbuffer(name); 3765 3766 if(!renderbuffer) 3767 { 3768 return EGL_BAD_PARAMETER; 3769 } 3770 3771 if(renderbuffer->isShared()) // Already an EGLImage sibling 3772 { 3773 return EGL_BAD_ACCESS; 3774 } 3775 } 3776 #if defined(__ANDROID__) 3777 else if(target == EGL_NATIVE_BUFFER_ANDROID) 3778 { 3779 ANativeWindowBuffer *nativeBuffer = reinterpret_cast<ANativeWindowBuffer*>(name); 3780 3781 if(nativeBuffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) 3782 { 3783 return EGL_BAD_PARAMETER; 3784 } 3785 3786 if(nativeBuffer->common.version != sizeof(ANativeWindowBuffer)) 3787 { 3788 return EGL_BAD_PARAMETER; 3789 } 3790 3791 switch(nativeBuffer->format) 3792 { 3793 case HAL_PIXEL_FORMAT_RGBA_8888: 3794 case HAL_PIXEL_FORMAT_RGBX_8888: 3795 case HAL_PIXEL_FORMAT_RGB_565: 3796 break; 3797 default: 3798 return EGL_BAD_PARAMETER; 3799 } 3800 } 3801 #endif 3802 else UNREACHABLE(); 3803 3804 return EGL_SUCCESS; 3805} 3806 3807egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel) 3808{ 3809 GLenum textureTarget = GL_NONE; 3810 3811 switch(target) 3812 { 3813 case EGL_GL_TEXTURE_2D_KHR: textureTarget = GL_TEXTURE_2D; break; 3814 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break; 3815 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break; 3816 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break; 3817 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break; 3818 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break; 3819 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break; 3820 } 3821 3822 if(textureTarget != GL_NONE) 3823 { 3824 es2::Texture *texture = getTexture(name); 3825 3826 return texture->createSharedImage(textureTarget, textureLevel); 3827 } 3828 else if(target == EGL_GL_RENDERBUFFER_KHR) 3829 { 3830 es2::Renderbuffer *renderbuffer = getRenderbuffer(name); 3831 3832 return renderbuffer->createSharedImage(); 3833 } 3834 #if defined(__ANDROID__) 3835 else if(target == EGL_NATIVE_BUFFER_ANDROID) 3836 { 3837 ANativeWindowBuffer *nativeBuffer = reinterpret_cast<ANativeWindowBuffer*>(name); 3838 nativeBuffer->common.incRef(&nativeBuffer->common); 3839 3840 GLenum format = Image::getColorFormatFromAndroid(nativeBuffer->format); 3841 GLenum type = Image::getPixelFormatFromAndroid(nativeBuffer->format); 3842 3843 es2::Image *image = new Image(0, nativeBuffer->width, nativeBuffer->height, format, type); 3844 image->setNativeBuffer(nativeBuffer); 3845 image->markShared(); 3846 3847 return image; 3848 } 3849 #endif 3850 else UNREACHABLE(); 3851 3852 return 0; 3853} 3854 3855Device *Context::getDevice() 3856{ 3857 return device; 3858} 3859 3860} 3861 3862// Exported functions for use by EGL 3863extern "C" 3864{ 3865 es2::Context *glCreateContext(const egl::Config *config, const es2::Context *shareContext, int clientVersion) 3866 { 3867 return new es2::Context(config, shareContext, clientVersion); 3868 } 3869} 3870