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