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