Context.cpp revision 2265824443967db3003a2a875f75d3ec6d8fad96
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 mTextureCubeMapZero.set(new TextureCubeMap(0)); 135 mTextureExternalZero.set(new TextureExternal(0)); 136 137 mState.activeSampler = 0; 138 bindArrayBuffer(0); 139 bindElementArrayBuffer(0); 140 bindTextureCubeMap(0); 141 bindTexture2D(0); 142 bindReadFramebuffer(0); 143 bindDrawFramebuffer(0); 144 bindRenderbuffer(0); 145 146 mState.currentProgram = 0; 147 148 mState.packAlignment = 4; 149 mState.unpackAlignment = 4; 150 151 mVertexDataManager = NULL; 152 mIndexDataManager = NULL; 153 154 mInvalidEnum = false; 155 mInvalidValue = false; 156 mInvalidOperation = false; 157 mOutOfMemory = false; 158 mInvalidFramebufferOperation = false; 159 160 mHasBeenCurrent = false; 161 162 markAllStateDirty(); 163} 164 165Context::~Context() 166{ 167 if(mState.currentProgram != 0) 168 { 169 Program *programObject = mResourceManager->getProgram(mState.currentProgram); 170 if(programObject) 171 { 172 programObject->release(); 173 } 174 mState.currentProgram = 0; 175 } 176 177 while(!mFramebufferMap.empty()) 178 { 179 deleteFramebuffer(mFramebufferMap.begin()->first); 180 } 181 182 while(!mFenceMap.empty()) 183 { 184 deleteFence(mFenceMap.begin()->first); 185 } 186 187 while(!mQueryMap.empty()) 188 { 189 deleteQuery(mQueryMap.begin()->first); 190 } 191 192 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++) 193 { 194 for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++) 195 { 196 mState.samplerTexture[type][sampler].set(NULL); 197 } 198 } 199 200 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 201 { 202 mState.vertexAttribute[i].mBoundBuffer.set(NULL); 203 } 204 205 for(int i = 0; i < QUERY_TYPE_COUNT; i++) 206 { 207 mState.activeQuery[i].set(NULL); 208 } 209 210 mState.arrayBuffer.set(NULL); 211 mState.elementArrayBuffer.set(NULL); 212 mState.renderbuffer.set(NULL); 213 214 mTexture2DZero.set(NULL); 215 mTextureCubeMapZero.set(NULL); 216 mTextureExternalZero.set(NULL); 217 218 delete mVertexDataManager; 219 delete mIndexDataManager; 220 221 mResourceManager->release(); 222 delete device; 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: *params = NUM_COMPRESSED_TEXTURE_FORMATS; break; 1329 case GL_MAX_SAMPLES_ANGLE: *params = IMPLEMENTATION_MAX_SAMPLES; break; 1330 case GL_SAMPLE_BUFFERS: 1331 case GL_SAMPLES: 1332 { 1333 Framebuffer *framebuffer = getDrawFramebuffer(); 1334 int width, height, samples; 1335 1336 if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE) 1337 { 1338 switch(pname) 1339 { 1340 case GL_SAMPLE_BUFFERS: 1341 if(samples > 1) 1342 { 1343 *params = 1; 1344 } 1345 else 1346 { 1347 *params = 0; 1348 } 1349 break; 1350 case GL_SAMPLES: 1351 *params = samples & ~1; 1352 break; 1353 } 1354 } 1355 else 1356 { 1357 *params = 0; 1358 } 1359 } 1360 break; 1361 case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = IMPLEMENTATION_COLOR_READ_TYPE; break; 1362 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = IMPLEMENTATION_COLOR_READ_FORMAT; break; 1363 case GL_MAX_VIEWPORT_DIMS: 1364 { 1365 int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; 1366 params[0] = maxDimension; 1367 params[1] = maxDimension; 1368 } 1369 break; 1370 case GL_COMPRESSED_TEXTURE_FORMATS: 1371 { 1372 for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++) 1373 { 1374 params[i] = compressedTextureFormats[i]; 1375 } 1376 } 1377 break; 1378 case GL_VIEWPORT: 1379 params[0] = mState.viewportX; 1380 params[1] = mState.viewportY; 1381 params[2] = mState.viewportWidth; 1382 params[3] = mState.viewportHeight; 1383 break; 1384 case GL_SCISSOR_BOX: 1385 params[0] = mState.scissorX; 1386 params[1] = mState.scissorY; 1387 params[2] = mState.scissorWidth; 1388 params[3] = mState.scissorHeight; 1389 break; 1390 case GL_CULL_FACE_MODE: *params = mState.cullMode; break; 1391 case GL_FRONT_FACE: *params = mState.frontFace; break; 1392 case GL_RED_BITS: 1393 case GL_GREEN_BITS: 1394 case GL_BLUE_BITS: 1395 case GL_ALPHA_BITS: 1396 { 1397 Framebuffer *framebuffer = getDrawFramebuffer(); 1398 Renderbuffer *colorbuffer = framebuffer->getColorbuffer(); 1399 1400 if(colorbuffer) 1401 { 1402 switch (pname) 1403 { 1404 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break; 1405 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break; 1406 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break; 1407 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break; 1408 } 1409 } 1410 else 1411 { 1412 *params = 0; 1413 } 1414 } 1415 break; 1416 case GL_DEPTH_BITS: 1417 { 1418 Framebuffer *framebuffer = getDrawFramebuffer(); 1419 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer(); 1420 1421 if(depthbuffer) 1422 { 1423 *params = depthbuffer->getDepthSize(); 1424 } 1425 else 1426 { 1427 *params = 0; 1428 } 1429 } 1430 break; 1431 case GL_STENCIL_BITS: 1432 { 1433 Framebuffer *framebuffer = getDrawFramebuffer(); 1434 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer(); 1435 1436 if(stencilbuffer) 1437 { 1438 *params = stencilbuffer->getStencilSize(); 1439 } 1440 else 1441 { 1442 *params = 0; 1443 } 1444 } 1445 break; 1446 case GL_TEXTURE_BINDING_2D: 1447 { 1448 if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) 1449 { 1450 error(GL_INVALID_OPERATION); 1451 return false; 1452 } 1453 1454 *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].id(); 1455 } 1456 break; 1457 case GL_TEXTURE_BINDING_CUBE_MAP: 1458 { 1459 if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) 1460 { 1461 error(GL_INVALID_OPERATION); 1462 return false; 1463 } 1464 1465 *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].id(); 1466 } 1467 break; 1468 case GL_TEXTURE_BINDING_EXTERNAL_OES: 1469 { 1470 if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) 1471 { 1472 error(GL_INVALID_OPERATION); 1473 return false; 1474 } 1475 1476 *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].id(); 1477 } 1478 break; 1479 default: 1480 return false; 1481 } 1482 1483 return true; 1484} 1485 1486bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) 1487{ 1488 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation 1489 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due 1490 // to the fact that it is stored internally as a float, and so would require conversion 1491 // if returned from Context::getIntegerv. Since this conversion is already implemented 1492 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we 1493 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling 1494 // application. 1495 switch (pname) 1496 { 1497 case GL_COMPRESSED_TEXTURE_FORMATS: 1498 { 1499 *type = GL_INT; 1500 *numParams = NUM_COMPRESSED_TEXTURE_FORMATS; 1501 } 1502 break; 1503 case GL_SHADER_BINARY_FORMATS: 1504 { 1505 *type = GL_INT; 1506 *numParams = 0; 1507 } 1508 break; 1509 case GL_MAX_VERTEX_ATTRIBS: 1510 case GL_MAX_VERTEX_UNIFORM_VECTORS: 1511 case GL_MAX_VARYING_VECTORS: 1512 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: 1513 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: 1514 case GL_MAX_TEXTURE_IMAGE_UNITS: 1515 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: 1516 case GL_MAX_RENDERBUFFER_SIZE: 1517 case GL_NUM_SHADER_BINARY_FORMATS: 1518 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: 1519 case GL_ARRAY_BUFFER_BINDING: 1520 case GL_FRAMEBUFFER_BINDING: 1521 case GL_RENDERBUFFER_BINDING: 1522 case GL_CURRENT_PROGRAM: 1523 case GL_PACK_ALIGNMENT: 1524 case GL_UNPACK_ALIGNMENT: 1525 case GL_GENERATE_MIPMAP_HINT: 1526 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: 1527 case GL_RED_BITS: 1528 case GL_GREEN_BITS: 1529 case GL_BLUE_BITS: 1530 case GL_ALPHA_BITS: 1531 case GL_DEPTH_BITS: 1532 case GL_STENCIL_BITS: 1533 case GL_ELEMENT_ARRAY_BUFFER_BINDING: 1534 case GL_CULL_FACE_MODE: 1535 case GL_FRONT_FACE: 1536 case GL_ACTIVE_TEXTURE: 1537 case GL_STENCIL_FUNC: 1538 case GL_STENCIL_VALUE_MASK: 1539 case GL_STENCIL_REF: 1540 case GL_STENCIL_FAIL: 1541 case GL_STENCIL_PASS_DEPTH_FAIL: 1542 case GL_STENCIL_PASS_DEPTH_PASS: 1543 case GL_STENCIL_BACK_FUNC: 1544 case GL_STENCIL_BACK_VALUE_MASK: 1545 case GL_STENCIL_BACK_REF: 1546 case GL_STENCIL_BACK_FAIL: 1547 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: 1548 case GL_STENCIL_BACK_PASS_DEPTH_PASS: 1549 case GL_DEPTH_FUNC: 1550 case GL_BLEND_SRC_RGB: 1551 case GL_BLEND_SRC_ALPHA: 1552 case GL_BLEND_DST_RGB: 1553 case GL_BLEND_DST_ALPHA: 1554 case GL_BLEND_EQUATION_RGB: 1555 case GL_BLEND_EQUATION_ALPHA: 1556 case GL_STENCIL_WRITEMASK: 1557 case GL_STENCIL_BACK_WRITEMASK: 1558 case GL_STENCIL_CLEAR_VALUE: 1559 case GL_SUBPIXEL_BITS: 1560 case GL_MAX_TEXTURE_SIZE: 1561 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: 1562 case GL_SAMPLE_BUFFERS: 1563 case GL_SAMPLES: 1564 case GL_IMPLEMENTATION_COLOR_READ_TYPE: 1565 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: 1566 case GL_TEXTURE_BINDING_2D: 1567 case GL_TEXTURE_BINDING_CUBE_MAP: 1568 case GL_TEXTURE_BINDING_EXTERNAL_OES: 1569 { 1570 *type = GL_INT; 1571 *numParams = 1; 1572 } 1573 break; 1574 case GL_MAX_SAMPLES_ANGLE: 1575 { 1576 *type = GL_INT; 1577 *numParams = 1; 1578 } 1579 break; 1580 case GL_MAX_VIEWPORT_DIMS: 1581 { 1582 *type = GL_INT; 1583 *numParams = 2; 1584 } 1585 break; 1586 case GL_VIEWPORT: 1587 case GL_SCISSOR_BOX: 1588 { 1589 *type = GL_INT; 1590 *numParams = 4; 1591 } 1592 break; 1593 case GL_SHADER_COMPILER: 1594 case GL_SAMPLE_COVERAGE_INVERT: 1595 case GL_DEPTH_WRITEMASK: 1596 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled, 1597 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries. 1598 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural 1599 case GL_SAMPLE_COVERAGE: 1600 case GL_SCISSOR_TEST: 1601 case GL_STENCIL_TEST: 1602 case GL_DEPTH_TEST: 1603 case GL_BLEND: 1604 case GL_DITHER: 1605 { 1606 *type = GL_BOOL; 1607 *numParams = 1; 1608 } 1609 break; 1610 case GL_COLOR_WRITEMASK: 1611 { 1612 *type = GL_BOOL; 1613 *numParams = 4; 1614 } 1615 break; 1616 case GL_POLYGON_OFFSET_FACTOR: 1617 case GL_POLYGON_OFFSET_UNITS: 1618 case GL_SAMPLE_COVERAGE_VALUE: 1619 case GL_DEPTH_CLEAR_VALUE: 1620 case GL_LINE_WIDTH: 1621 { 1622 *type = GL_FLOAT; 1623 *numParams = 1; 1624 } 1625 break; 1626 case GL_ALIASED_LINE_WIDTH_RANGE: 1627 case GL_ALIASED_POINT_SIZE_RANGE: 1628 case GL_DEPTH_RANGE: 1629 { 1630 *type = GL_FLOAT; 1631 *numParams = 2; 1632 } 1633 break; 1634 case GL_COLOR_CLEAR_VALUE: 1635 case GL_BLEND_COLOR: 1636 { 1637 *type = GL_FLOAT; 1638 *numParams = 4; 1639 } 1640 break; 1641 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: 1642 *type = GL_FLOAT; 1643 *numParams = 1; 1644 break; 1645 default: 1646 return false; 1647 } 1648 1649 return true; 1650} 1651 1652// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle 1653bool Context::applyRenderTarget() 1654{ 1655 Framebuffer *framebuffer = getDrawFramebuffer(); 1656 int width, height, samples; 1657 1658 if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE) 1659 { 1660 return error(GL_INVALID_FRAMEBUFFER_OPERATION, false); 1661 } 1662 1663 egl::Image *renderTarget = framebuffer->getRenderTarget(); 1664 device->setRenderTarget(renderTarget); 1665 if(renderTarget) renderTarget->release(); 1666 1667 egl::Image *depthStencil = framebuffer->getDepthStencil(); 1668 device->setDepthStencilSurface(depthStencil); 1669 if(depthStencil) depthStencil->release(); 1670 1671 Viewport viewport; 1672 float zNear = clamp01(mState.zNear); 1673 float zFar = clamp01(mState.zFar); 1674 1675 viewport.x0 = mState.viewportX; 1676 viewport.y0 = mState.viewportY; 1677 viewport.width = mState.viewportWidth; 1678 viewport.height = mState.viewportHeight; 1679 viewport.minZ = zNear; 1680 viewport.maxZ = zFar; 1681 1682 device->setViewport(viewport); 1683 1684 if(mState.scissorTest) 1685 { 1686 sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight}; 1687 scissor.clip(0, 0, width, height); 1688 1689 device->setScissorRect(scissor); 1690 device->setScissorEnable(true); 1691 } 1692 else 1693 { 1694 device->setScissorEnable(false); 1695 } 1696 1697 Program *program = getCurrentProgram(); 1698 1699 if(program) 1700 { 1701 GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear}; 1702 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]); 1703 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]); 1704 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]); 1705 } 1706 1707 return true; 1708} 1709 1710// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) 1711void Context::applyState(GLenum drawMode) 1712{ 1713 Framebuffer *framebuffer = getDrawFramebuffer(); 1714 1715 if(mState.cullFace) 1716 { 1717 device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace)); 1718 } 1719 else 1720 { 1721 device->setCullMode(sw::CULL_NONE); 1722 } 1723 1724 if(mDepthStateDirty) 1725 { 1726 if(mState.depthTest) 1727 { 1728 device->setDepthBufferEnable(true); 1729 device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc)); 1730 } 1731 else 1732 { 1733 device->setDepthBufferEnable(false); 1734 } 1735 1736 mDepthStateDirty = false; 1737 } 1738 1739 if(mBlendStateDirty) 1740 { 1741 if(mState.blend) 1742 { 1743 device->setAlphaBlendEnable(true); 1744 device->setSeparateAlphaBlendEnable(true); 1745 1746 device->setBlendConstant(es2sw::ConvertColor(mState.blendColor)); 1747 1748 device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB)); 1749 device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB)); 1750 device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB)); 1751 1752 device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha)); 1753 device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha)); 1754 device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha)); 1755 } 1756 else 1757 { 1758 device->setAlphaBlendEnable(false); 1759 } 1760 1761 mBlendStateDirty = false; 1762 } 1763 1764 if(mStencilStateDirty || mFrontFaceDirty) 1765 { 1766 if(mState.stencilTest && framebuffer->hasStencil()) 1767 { 1768 device->setStencilEnable(true); 1769 device->setTwoSidedStencil(true); 1770 1771 if(mState.stencilWritemask != mState.stencilBackWritemask || 1772 mState.stencilRef != mState.stencilBackRef || 1773 mState.stencilMask != mState.stencilBackMask) 1774 { 1775 ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL."); 1776 return error(GL_INVALID_OPERATION); 1777 } 1778 1779 // get the maximum size of the stencil ref 1780 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer(); 1781 GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1; 1782 1783 if(mState.frontFace == GL_CCW) 1784 { 1785 device->setStencilWriteMask(mState.stencilWritemask); 1786 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc)); 1787 1788 device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil); 1789 device->setStencilMask(mState.stencilMask); 1790 1791 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail)); 1792 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail)); 1793 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass)); 1794 1795 device->setStencilWriteMaskCCW(mState.stencilBackWritemask); 1796 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc)); 1797 1798 device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil); 1799 device->setStencilMaskCCW(mState.stencilBackMask); 1800 1801 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail)); 1802 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail)); 1803 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass)); 1804 } 1805 else 1806 { 1807 device->setStencilWriteMaskCCW(mState.stencilWritemask); 1808 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc)); 1809 1810 device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil); 1811 device->setStencilMaskCCW(mState.stencilMask); 1812 1813 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail)); 1814 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail)); 1815 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass)); 1816 1817 device->setStencilWriteMask(mState.stencilBackWritemask); 1818 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc)); 1819 1820 device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil); 1821 device->setStencilMask(mState.stencilBackMask); 1822 1823 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail)); 1824 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail)); 1825 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass)); 1826 } 1827 } 1828 else 1829 { 1830 device->setStencilEnable(false); 1831 } 1832 1833 mStencilStateDirty = false; 1834 mFrontFaceDirty = false; 1835 } 1836 1837 if(mMaskStateDirty) 1838 { 1839 device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha)); 1840 device->setDepthWriteEnable(mState.depthMask); 1841 1842 mMaskStateDirty = false; 1843 } 1844 1845 if(mPolygonOffsetStateDirty) 1846 { 1847 if(mState.polygonOffsetFill) 1848 { 1849 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer(); 1850 if(depthbuffer) 1851 { 1852 device->setSlopeDepthBias(mState.polygonOffsetFactor); 1853 float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize())); 1854 device->setDepthBias(depthBias); 1855 } 1856 } 1857 else 1858 { 1859 device->setSlopeDepthBias(0); 1860 device->setDepthBias(0); 1861 } 1862 1863 mPolygonOffsetStateDirty = false; 1864 } 1865 1866 if(mSampleStateDirty) 1867 { 1868 if(mState.sampleAlphaToCoverage) 1869 { 1870 device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE); 1871 } 1872 else 1873 { 1874 device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE); 1875 } 1876 1877 if(mState.sampleCoverage) 1878 { 1879 unsigned int mask = 0; 1880 if(mState.sampleCoverageValue != 0) 1881 { 1882 int width, height, samples; 1883 framebuffer->completeness(width, height, samples); 1884 1885 float threshold = 0.5f; 1886 1887 for(int i = 0; i < samples; i++) 1888 { 1889 mask <<= 1; 1890 1891 if((i + 1) * mState.sampleCoverageValue >= threshold) 1892 { 1893 threshold += 1.0f; 1894 mask |= 1; 1895 } 1896 } 1897 } 1898 1899 if(mState.sampleCoverageInvert) 1900 { 1901 mask = ~mask; 1902 } 1903 1904 device->setMultiSampleMask(mask); 1905 } 1906 else 1907 { 1908 device->setMultiSampleMask(0xFFFFFFFF); 1909 } 1910 1911 mSampleStateDirty = false; 1912 } 1913 1914 if(mDitherStateDirty) 1915 { 1916 // UNIMPLEMENTED(); // FIXME 1917 1918 mDitherStateDirty = false; 1919 } 1920} 1921 1922GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count) 1923{ 1924 TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS]; 1925 1926 GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes); 1927 if(err != GL_NO_ERROR) 1928 { 1929 return err; 1930 } 1931 1932 Program *program = getCurrentProgram(); 1933 1934 device->resetInputStreams(false); 1935 1936 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 1937 { 1938 if(program->getAttributeStream(i) == -1) 1939 { 1940 continue; 1941 } 1942 1943 sw::Resource *resource = attributes[i].vertexBuffer; 1944 const void *buffer = (char*)resource->getBuffer() + attributes[i].offset; 1945 1946 int stride = attributes[i].stride; 1947 1948 buffer = (char*)buffer + stride * base; 1949 1950 sw::Stream attribute(resource, buffer, stride); 1951 1952 attribute.type = attributes[i].type; 1953 attribute.count = attributes[i].count; 1954 attribute.normalized = attributes[i].normalized; 1955 1956 int stream = program->getAttributeStream(i); 1957 device->setInputStream(stream, attribute); 1958 } 1959 1960 return GL_NO_ERROR; 1961} 1962 1963// Applies the indices and element array bindings 1964GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) 1965{ 1966 GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer.get(), indices, indexInfo); 1967 1968 if(err == GL_NO_ERROR) 1969 { 1970 device->setIndexBuffer(indexInfo->indexBuffer); 1971 } 1972 1973 return err; 1974} 1975 1976// Applies the shaders and shader constants 1977void Context::applyShaders() 1978{ 1979 Program *programObject = getCurrentProgram(); 1980 sw::VertexShader *vertexShader = programObject->getVertexShader(); 1981 sw::PixelShader *pixelShader = programObject->getPixelShader(); 1982 1983 device->setVertexShader(vertexShader); 1984 device->setPixelShader(pixelShader); 1985 1986 if(programObject->getSerial() != mAppliedProgramSerial) 1987 { 1988 programObject->dirtyAllUniforms(); 1989 mAppliedProgramSerial = programObject->getSerial(); 1990 } 1991 1992 programObject->applyUniforms(); 1993} 1994 1995void Context::applyTextures() 1996{ 1997 applyTextures(sw::SAMPLER_PIXEL); 1998 applyTextures(sw::SAMPLER_VERTEX); 1999} 2000 2001void Context::applyTextures(sw::SamplerType samplerType) 2002{ 2003 Program *programObject = getCurrentProgram(); 2004 2005 int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS; // Range of samplers of given sampler type 2006 2007 for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++) 2008 { 2009 int textureUnit = programObject->getSamplerMapping(samplerType, samplerIndex); // OpenGL texture image unit index 2010 2011 if(textureUnit != -1) 2012 { 2013 TextureType textureType = programObject->getSamplerTextureType(samplerType, samplerIndex); 2014 2015 Texture *texture = getSamplerTexture(textureUnit, textureType); 2016 2017 if(texture->isSamplerComplete()) 2018 { 2019 GLenum wrapS = texture->getWrapS(); 2020 GLenum wrapT = texture->getWrapT(); 2021 GLenum texFilter = texture->getMinFilter(); 2022 GLenum magFilter = texture->getMagFilter(); 2023 GLfloat maxAnisotropy = texture->getMaxAnisotropy(); 2024 2025 device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS)); 2026 device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT)); 2027 2028 sw::FilterType minFilter; 2029 sw::MipmapType mipFilter; 2030 es2sw::ConvertMinFilter(texFilter, &minFilter, &mipFilter, maxAnisotropy); 2031 // ASSERT(minFilter == es2sw::ConvertMagFilter(magFilter)); 2032 2033 device->setTextureFilter(samplerType, samplerIndex, minFilter); 2034 // device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertMagFilter(magFilter)); 2035 device->setMipmapFilter(samplerType, samplerIndex, mipFilter); 2036 device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy); 2037 2038 applyTexture(samplerType, samplerIndex, texture); 2039 } 2040 else 2041 { 2042 applyTexture(samplerType, samplerIndex, 0); 2043 } 2044 } 2045 else 2046 { 2047 applyTexture(samplerType, samplerIndex, NULL); 2048 } 2049 } 2050} 2051 2052void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture) 2053{ 2054 Program *program = getCurrentProgram(); 2055 int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index; 2056 bool textureUsed = false; 2057 2058 if(type == sw::SAMPLER_PIXEL) 2059 { 2060 textureUsed = program->getPixelShader()->usesSampler(index); 2061 } 2062 else if(type == sw::SAMPLER_VERTEX) 2063 { 2064 textureUsed = program->getVertexShader()->usesSampler(index); 2065 } 2066 else UNREACHABLE(); 2067 2068 sw::Resource *resource = 0; 2069 2070 if(baseTexture && textureUsed) 2071 { 2072 resource = baseTexture->getResource(); 2073 } 2074 2075 device->setTextureResource(sampler, resource); 2076 2077 if(baseTexture && textureUsed) 2078 { 2079 int levelCount = baseTexture->getLevelCount(); 2080 2081 if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES) 2082 { 2083 Texture2D *texture = static_cast<Texture2D*>(baseTexture); 2084 2085 for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++) 2086 { 2087 int surfaceLevel = mipmapLevel; 2088 2089 if(surfaceLevel < 0) 2090 { 2091 surfaceLevel = 0; 2092 } 2093 else if(surfaceLevel >= levelCount) 2094 { 2095 surfaceLevel = levelCount - 1; 2096 } 2097 2098 egl::Image *surface = texture->getImage(surfaceLevel); 2099 device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D); 2100 } 2101 } 2102 else if(baseTexture->getTarget() == GL_TEXTURE_CUBE_MAP) 2103 { 2104 for(int face = 0; face < 6; face++) 2105 { 2106 TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture); 2107 2108 for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++) 2109 { 2110 int surfaceLevel = mipmapLevel; 2111 2112 if(surfaceLevel < 0) 2113 { 2114 surfaceLevel = 0; 2115 } 2116 else if(surfaceLevel >= levelCount) 2117 { 2118 surfaceLevel = levelCount - 1; 2119 } 2120 2121 egl::Image *surface = cubeTexture->getImage(face, surfaceLevel); 2122 device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE); 2123 } 2124 } 2125 } 2126 else UNIMPLEMENTED(); 2127 } 2128 else 2129 { 2130 device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL); 2131 } 2132} 2133 2134void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, 2135 GLenum format, GLenum type, GLsizei *bufSize, void* pixels) 2136{ 2137 Framebuffer *framebuffer = getReadFramebuffer(); 2138 int framebufferWidth, framebufferHeight, framebufferSamples; 2139 2140 if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE) 2141 { 2142 return error(GL_INVALID_FRAMEBUFFER_OPERATION); 2143 } 2144 2145 if(getReadFramebufferHandle() != 0 && framebufferSamples != 0) 2146 { 2147 return error(GL_INVALID_OPERATION); 2148 } 2149 2150 GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment); 2151 2152 // Sized query sanity check 2153 if(bufSize) 2154 { 2155 int requiredSize = outputPitch * height; 2156 if(requiredSize > *bufSize) 2157 { 2158 return error(GL_INVALID_OPERATION); 2159 } 2160 } 2161 2162 egl::Image *renderTarget = framebuffer->getRenderTarget(); 2163 2164 if(!renderTarget) 2165 { 2166 return error(GL_OUT_OF_MEMORY); 2167 } 2168 2169 sw::Rect rect = {x, y, x + width, y + height}; 2170 rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight()); 2171 2172 unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY); 2173 unsigned char *dest = (unsigned char*)pixels; 2174 unsigned short *dest16 = (unsigned short*)pixels; 2175 int inputPitch = (int)renderTarget->getPitch(); 2176 2177 for(int j = 0; j < rect.y1 - rect.y0; j++) 2178 { 2179 if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 && 2180 format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) 2181 { 2182 // Fast path for EXT_read_format_bgra, given an RGBA source buffer 2183 // Note that buffers with no alpha go through the slow path below 2184 memcpy(dest + j * outputPitch, source + j * inputPitch, (rect.x1 - rect.x0) * 4); 2185 } 2186 else 2187 { 2188 for(int i = 0; i < rect.x1 - rect.x0; i++) 2189 { 2190 float r; 2191 float g; 2192 float b; 2193 float a; 2194 2195 switch(renderTarget->getInternalFormat()) 2196 { 2197 case sw::FORMAT_R5G6B5: 2198 { 2199 unsigned short rgb = *(unsigned short*)(source + 2 * i + j * inputPitch); 2200 2201 a = 1.0f; 2202 b = (rgb & 0x001F) * (1.0f / 0x001F); 2203 g = (rgb & 0x07E0) * (1.0f / 0x07E0); 2204 r = (rgb & 0xF800) * (1.0f / 0xF800); 2205 } 2206 break; 2207 case sw::FORMAT_A1R5G5B5: 2208 { 2209 unsigned short argb = *(unsigned short*)(source + 2 * i + j * inputPitch); 2210 2211 a = (argb & 0x8000) ? 1.0f : 0.0f; 2212 b = (argb & 0x001F) * (1.0f / 0x001F); 2213 g = (argb & 0x03E0) * (1.0f / 0x03E0); 2214 r = (argb & 0x7C00) * (1.0f / 0x7C00); 2215 } 2216 break; 2217 case sw::FORMAT_A8R8G8B8: 2218 { 2219 unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); 2220 2221 a = (argb & 0xFF000000) * (1.0f / 0xFF000000); 2222 b = (argb & 0x000000FF) * (1.0f / 0x000000FF); 2223 g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00); 2224 r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000); 2225 } 2226 break; 2227 case sw::FORMAT_X8R8G8B8: 2228 { 2229 unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * inputPitch); 2230 2231 a = 1.0f; 2232 b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF); 2233 g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00); 2234 r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000); 2235 } 2236 break; 2237 case sw::FORMAT_A2R10G10B10: 2238 { 2239 unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); 2240 2241 a = (argb & 0xC0000000) * (1.0f / 0xC0000000); 2242 b = (argb & 0x000003FF) * (1.0f / 0x000003FF); 2243 g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00); 2244 r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000); 2245 } 2246 break; 2247 case sw::FORMAT_A32B32G32R32F: 2248 { 2249 r = *((float*)(source + 16 * i + j * inputPitch) + 0); 2250 g = *((float*)(source + 16 * i + j * inputPitch) + 1); 2251 b = *((float*)(source + 16 * i + j * inputPitch) + 2); 2252 a = *((float*)(source + 16 * i + j * inputPitch) + 3); 2253 } 2254 break; 2255 case sw::FORMAT_A16B16G16R16F: 2256 { 2257 r = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 0); 2258 g = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 1); 2259 b = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 2); 2260 a = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 3); 2261 } 2262 break; 2263 default: 2264 UNIMPLEMENTED(); // FIXME 2265 UNREACHABLE(); 2266 } 2267 2268 switch(format) 2269 { 2270 case GL_RGBA: 2271 switch(type) 2272 { 2273 case GL_UNSIGNED_BYTE: 2274 dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f); 2275 dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f); 2276 dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f); 2277 dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f); 2278 break; 2279 default: UNREACHABLE(); 2280 } 2281 break; 2282 case GL_BGRA_EXT: 2283 switch(type) 2284 { 2285 case GL_UNSIGNED_BYTE: 2286 dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * b + 0.5f); 2287 dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f); 2288 dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * r + 0.5f); 2289 dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f); 2290 break; 2291 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: 2292 // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section 2293 // this type is packed as follows: 2294 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 2295 // -------------------------------------------------------------------------------- 2296 // | 4th | 3rd | 2nd | 1st component | 2297 // -------------------------------------------------------------------------------- 2298 // in the case of BGRA_EXT, B is the first component, G the second, and so forth. 2299 dest16[i + j * outputPitch / sizeof(unsigned short)] = 2300 ((unsigned short)(15 * a + 0.5f) << 12)| 2301 ((unsigned short)(15 * r + 0.5f) << 8) | 2302 ((unsigned short)(15 * g + 0.5f) << 4) | 2303 ((unsigned short)(15 * b + 0.5f) << 0); 2304 break; 2305 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: 2306 // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section 2307 // this type is packed as follows: 2308 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 2309 // -------------------------------------------------------------------------------- 2310 // | 4th | 3rd | 2nd | 1st component | 2311 // -------------------------------------------------------------------------------- 2312 // in the case of BGRA_EXT, B is the first component, G the second, and so forth. 2313 dest16[i + j * outputPitch / sizeof(unsigned short)] = 2314 ((unsigned short)( a + 0.5f) << 15) | 2315 ((unsigned short)(31 * r + 0.5f) << 10) | 2316 ((unsigned short)(31 * g + 0.5f) << 5) | 2317 ((unsigned short)(31 * b + 0.5f) << 0); 2318 break; 2319 default: UNREACHABLE(); 2320 } 2321 break; 2322 case GL_RGB: // IMPLEMENTATION_COLOR_READ_FORMAT 2323 switch(type) 2324 { 2325 case GL_UNSIGNED_SHORT_5_6_5: // IMPLEMENTATION_COLOR_READ_TYPE 2326 dest16[i + j * outputPitch / sizeof(unsigned short)] = 2327 ((unsigned short)(31 * b + 0.5f) << 0) | 2328 ((unsigned short)(63 * g + 0.5f) << 5) | 2329 ((unsigned short)(31 * r + 0.5f) << 11); 2330 break; 2331 default: UNREACHABLE(); 2332 } 2333 break; 2334 default: UNREACHABLE(); 2335 } 2336 } 2337 } 2338 } 2339 2340 renderTarget->unlock(); 2341 renderTarget->release(); 2342} 2343 2344void Context::clear(GLbitfield mask) 2345{ 2346 Framebuffer *framebuffer = getDrawFramebuffer(); 2347 2348 if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) 2349 { 2350 return error(GL_INVALID_FRAMEBUFFER_OPERATION); 2351 } 2352 2353 if(!applyRenderTarget()) 2354 { 2355 return; 2356 } 2357 2358 unsigned int color = (unorm<8>(mState.colorClearValue.alpha) << 24) | 2359 (unorm<8>(mState.colorClearValue.red) << 16) | 2360 (unorm<8>(mState.colorClearValue.green) << 8) | 2361 (unorm<8>(mState.colorClearValue.blue) << 0); 2362 float depth = clamp01(mState.depthClearValue); 2363 int stencil = mState.stencilClearValue & 0x000000FF; 2364 2365 if(mask & GL_COLOR_BUFFER_BIT) 2366 { 2367 unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) | 2368 (mState.colorMaskGreen ? 0x2 : 0) | 2369 (mState.colorMaskBlue ? 0x4 : 0) | 2370 (mState.colorMaskAlpha ? 0x8 : 0); 2371 2372 if(rgbaMask != 0) 2373 { 2374 device->clearColor(color, rgbaMask); 2375 } 2376 } 2377 2378 if(mask & GL_DEPTH_BUFFER_BIT) 2379 { 2380 if(mState.depthMask != 0) 2381 { 2382 device->clearDepth(depth); 2383 } 2384 } 2385 2386 if(mask & GL_STENCIL_BUFFER_BIT) 2387 { 2388 if(mState.stencilWritemask != 0) 2389 { 2390 device->clearStencil(stencil, mState.stencilWritemask); 2391 } 2392 } 2393} 2394 2395void Context::drawArrays(GLenum mode, GLint first, GLsizei count) 2396{ 2397 if(!mState.currentProgram) 2398 { 2399 return error(GL_INVALID_OPERATION); 2400 } 2401 2402 PrimitiveType primitiveType; 2403 int primitiveCount; 2404 2405 if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount)) 2406 return error(GL_INVALID_ENUM); 2407 2408 if(primitiveCount <= 0) 2409 { 2410 return; 2411 } 2412 2413 if(!applyRenderTarget()) 2414 { 2415 return; 2416 } 2417 2418 applyState(mode); 2419 2420 GLenum err = applyVertexBuffer(0, first, count); 2421 if(err != GL_NO_ERROR) 2422 { 2423 return error(err); 2424 } 2425 2426 applyShaders(); 2427 applyTextures(); 2428 2429 if(!getCurrentProgram()->validateSamplers(false)) 2430 { 2431 return error(GL_INVALID_OPERATION); 2432 } 2433 2434 if(!cullSkipsDraw(mode)) 2435 { 2436 device->drawPrimitive(primitiveType, primitiveCount); 2437 } 2438} 2439 2440void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) 2441{ 2442 if(!mState.currentProgram) 2443 { 2444 return error(GL_INVALID_OPERATION); 2445 } 2446 2447 if(!indices && !mState.elementArrayBuffer) 2448 { 2449 return error(GL_INVALID_OPERATION); 2450 } 2451 2452 PrimitiveType primitiveType; 2453 int primitiveCount; 2454 2455 if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount)) 2456 return error(GL_INVALID_ENUM); 2457 2458 if(primitiveCount <= 0) 2459 { 2460 return; 2461 } 2462 2463 if(!applyRenderTarget()) 2464 { 2465 return; 2466 } 2467 2468 applyState(mode); 2469 2470 TranslatedIndexData indexInfo; 2471 GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo); 2472 if(err != GL_NO_ERROR) 2473 { 2474 return error(err); 2475 } 2476 2477 GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1; 2478 err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount); 2479 if(err != GL_NO_ERROR) 2480 { 2481 return error(err); 2482 } 2483 2484 applyShaders(); 2485 applyTextures(); 2486 2487 if(!getCurrentProgram()->validateSamplers(false)) 2488 { 2489 return error(GL_INVALID_OPERATION); 2490 } 2491 2492 if(!cullSkipsDraw(mode)) 2493 { 2494 device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount, IndexDataManager::typeSize(type)); 2495 } 2496} 2497 2498void Context::finish() 2499{ 2500 device->finish(); 2501} 2502 2503void Context::flush() 2504{ 2505 // We don't queue anything without processing it as fast as possible 2506} 2507 2508void Context::recordInvalidEnum() 2509{ 2510 mInvalidEnum = true; 2511} 2512 2513void Context::recordInvalidValue() 2514{ 2515 mInvalidValue = true; 2516} 2517 2518void Context::recordInvalidOperation() 2519{ 2520 mInvalidOperation = true; 2521} 2522 2523void Context::recordOutOfMemory() 2524{ 2525 mOutOfMemory = true; 2526} 2527 2528void Context::recordInvalidFramebufferOperation() 2529{ 2530 mInvalidFramebufferOperation = true; 2531} 2532 2533// Get one of the recorded errors and clear its flag, if any. 2534// [OpenGL ES 2.0.24] section 2.5 page 13. 2535GLenum Context::getError() 2536{ 2537 if(mInvalidEnum) 2538 { 2539 mInvalidEnum = false; 2540 2541 return GL_INVALID_ENUM; 2542 } 2543 2544 if(mInvalidValue) 2545 { 2546 mInvalidValue = false; 2547 2548 return GL_INVALID_VALUE; 2549 } 2550 2551 if(mInvalidOperation) 2552 { 2553 mInvalidOperation = false; 2554 2555 return GL_INVALID_OPERATION; 2556 } 2557 2558 if(mOutOfMemory) 2559 { 2560 mOutOfMemory = false; 2561 2562 return GL_OUT_OF_MEMORY; 2563 } 2564 2565 if(mInvalidFramebufferOperation) 2566 { 2567 mInvalidFramebufferOperation = false; 2568 2569 return GL_INVALID_FRAMEBUFFER_OPERATION; 2570 } 2571 2572 return GL_NO_ERROR; 2573} 2574 2575int Context::getSupportedMultiSampleDepth(sw::Format format, int requested) 2576{ 2577 if(requested <= 1) 2578 { 2579 return 1; 2580 } 2581 2582 if(requested == 2) 2583 { 2584 return 2; 2585 } 2586 2587 return 4; 2588} 2589 2590void Context::detachBuffer(GLuint buffer) 2591{ 2592 // [OpenGL ES 2.0.24] section 2.9 page 22: 2593 // If a buffer object is deleted while it is bound, all bindings to that object in the current context 2594 // (i.e. in the thread that called Delete-Buffers) are reset to zero. 2595 2596 if(mState.arrayBuffer.id() == buffer) 2597 { 2598 mState.arrayBuffer.set(NULL); 2599 } 2600 2601 if(mState.elementArrayBuffer.id() == buffer) 2602 { 2603 mState.elementArrayBuffer.set(NULL); 2604 } 2605 2606 for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++) 2607 { 2608 if(mState.vertexAttribute[attribute].mBoundBuffer.id() == buffer) 2609 { 2610 mState.vertexAttribute[attribute].mBoundBuffer.set(NULL); 2611 } 2612 } 2613} 2614 2615void Context::detachTexture(GLuint texture) 2616{ 2617 // [OpenGL ES 2.0.24] section 3.8 page 84: 2618 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are 2619 // rebound to texture object zero 2620 2621 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++) 2622 { 2623 for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++) 2624 { 2625 if(mState.samplerTexture[type][sampler].id() == texture) 2626 { 2627 mState.samplerTexture[type][sampler].set(NULL); 2628 } 2629 } 2630 } 2631 2632 // [OpenGL ES 2.0.24] section 4.4 page 112: 2633 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is 2634 // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this 2635 // image was attached in the currently bound framebuffer. 2636 2637 Framebuffer *readFramebuffer = getReadFramebuffer(); 2638 Framebuffer *drawFramebuffer = getDrawFramebuffer(); 2639 2640 if(readFramebuffer) 2641 { 2642 readFramebuffer->detachTexture(texture); 2643 } 2644 2645 if(drawFramebuffer && drawFramebuffer != readFramebuffer) 2646 { 2647 drawFramebuffer->detachTexture(texture); 2648 } 2649} 2650 2651void Context::detachFramebuffer(GLuint framebuffer) 2652{ 2653 // [OpenGL ES 2.0.24] section 4.4 page 107: 2654 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though 2655 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero. 2656 2657 if(mState.readFramebuffer == framebuffer) 2658 { 2659 bindReadFramebuffer(0); 2660 } 2661 2662 if(mState.drawFramebuffer == framebuffer) 2663 { 2664 bindDrawFramebuffer(0); 2665 } 2666} 2667 2668void Context::detachRenderbuffer(GLuint renderbuffer) 2669{ 2670 // [OpenGL ES 2.0.24] section 4.4 page 109: 2671 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer 2672 // had been executed with the target RENDERBUFFER and name of zero. 2673 2674 if(mState.renderbuffer.id() == renderbuffer) 2675 { 2676 bindRenderbuffer(0); 2677 } 2678 2679 // [OpenGL ES 2.0.24] section 4.4 page 111: 2680 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer, 2681 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment 2682 // point to which this image was attached in the currently bound framebuffer. 2683 2684 Framebuffer *readFramebuffer = getReadFramebuffer(); 2685 Framebuffer *drawFramebuffer = getDrawFramebuffer(); 2686 2687 if(readFramebuffer) 2688 { 2689 readFramebuffer->detachRenderbuffer(renderbuffer); 2690 } 2691 2692 if(drawFramebuffer && drawFramebuffer != readFramebuffer) 2693 { 2694 drawFramebuffer->detachRenderbuffer(renderbuffer); 2695 } 2696} 2697 2698bool Context::cullSkipsDraw(GLenum drawMode) 2699{ 2700 return mState.cullFace && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode); 2701} 2702 2703bool Context::isTriangleMode(GLenum drawMode) 2704{ 2705 switch (drawMode) 2706 { 2707 case GL_TRIANGLES: 2708 case GL_TRIANGLE_FAN: 2709 case GL_TRIANGLE_STRIP: 2710 return true; 2711 case GL_POINTS: 2712 case GL_LINES: 2713 case GL_LINE_LOOP: 2714 case GL_LINE_STRIP: 2715 return false; 2716 default: UNREACHABLE(); 2717 } 2718 2719 return false; 2720} 2721 2722void Context::setVertexAttrib(GLuint index, const GLfloat *values) 2723{ 2724 ASSERT(index < MAX_VERTEX_ATTRIBS); 2725 2726 mState.vertexAttribute[index].mCurrentValue[0] = values[0]; 2727 mState.vertexAttribute[index].mCurrentValue[1] = values[1]; 2728 mState.vertexAttribute[index].mCurrentValue[2] = values[2]; 2729 mState.vertexAttribute[index].mCurrentValue[3] = values[3]; 2730 2731 mVertexDataManager->dirtyCurrentValue(index); 2732} 2733 2734void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 2735 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 2736 GLbitfield mask) 2737{ 2738 Framebuffer *readFramebuffer = getReadFramebuffer(); 2739 Framebuffer *drawFramebuffer = getDrawFramebuffer(); 2740 2741 int readBufferWidth, readBufferHeight, readBufferSamples; 2742 int drawBufferWidth, drawBufferHeight, drawBufferSamples; 2743 2744 if(!readFramebuffer || readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE || 2745 !drawFramebuffer || drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE) 2746 { 2747 return error(GL_INVALID_FRAMEBUFFER_OPERATION); 2748 } 2749 2750 if(drawBufferSamples > 1) 2751 { 2752 return error(GL_INVALID_OPERATION); 2753 } 2754 2755 sw::Rect sourceRect; 2756 sw::Rect destRect; 2757 2758 if(srcX0 < srcX1) 2759 { 2760 sourceRect.x0 = srcX0; 2761 sourceRect.x1 = srcX1; 2762 destRect.x0 = dstX0; 2763 destRect.x1 = dstX1; 2764 } 2765 else 2766 { 2767 sourceRect.x0 = srcX1; 2768 destRect.x0 = dstX1; 2769 sourceRect.x1 = srcX0; 2770 destRect.x1 = dstX0; 2771 } 2772 2773 if(srcY0 < srcY1) 2774 { 2775 sourceRect.y0 = srcY0; 2776 destRect.y0 = dstY0; 2777 sourceRect.y1 = srcY1; 2778 destRect.y1 = dstY1; 2779 } 2780 else 2781 { 2782 sourceRect.y0 = srcY1; 2783 destRect.y0 = dstY1; 2784 sourceRect.y1 = srcY0; 2785 destRect.y1 = dstY0; 2786 } 2787 2788 sw::Rect sourceScissoredRect = sourceRect; 2789 sw::Rect destScissoredRect = destRect; 2790 2791 if(mState.scissorTest) // Only write to parts of the destination framebuffer which pass the scissor test 2792 { 2793 if(destRect.x0 < mState.scissorX) 2794 { 2795 int xDiff = mState.scissorX - destRect.x0; 2796 destScissoredRect.x0 = mState.scissorX; 2797 sourceScissoredRect.x0 += xDiff; 2798 } 2799 2800 if(destRect.x1 > mState.scissorX + mState.scissorWidth) 2801 { 2802 int xDiff = destRect.x1 - (mState.scissorX + mState.scissorWidth); 2803 destScissoredRect.x1 = mState.scissorX + mState.scissorWidth; 2804 sourceScissoredRect.x1 -= xDiff; 2805 } 2806 2807 if(destRect.y0 < mState.scissorY) 2808 { 2809 int yDiff = mState.scissorY - destRect.y0; 2810 destScissoredRect.y0 = mState.scissorY; 2811 sourceScissoredRect.y0 += yDiff; 2812 } 2813 2814 if(destRect.y1 > mState.scissorY + mState.scissorHeight) 2815 { 2816 int yDiff = destRect.y1 - (mState.scissorY + mState.scissorHeight); 2817 destScissoredRect.y1 = mState.scissorY + mState.scissorHeight; 2818 sourceScissoredRect.y1 -= yDiff; 2819 } 2820 } 2821 2822 sw::Rect sourceTrimmedRect = sourceScissoredRect; 2823 sw::Rect destTrimmedRect = destScissoredRect; 2824 2825 // The source & destination rectangles also may need to be trimmed if they fall out of the bounds of 2826 // the actual draw and read surfaces. 2827 if(sourceTrimmedRect.x0 < 0) 2828 { 2829 int xDiff = 0 - sourceTrimmedRect.x0; 2830 sourceTrimmedRect.x0 = 0; 2831 destTrimmedRect.x0 += xDiff; 2832 } 2833 2834 if(sourceTrimmedRect.x1 > readBufferWidth) 2835 { 2836 int xDiff = sourceTrimmedRect.x1 - readBufferWidth; 2837 sourceTrimmedRect.x1 = readBufferWidth; 2838 destTrimmedRect.x1 -= xDiff; 2839 } 2840 2841 if(sourceTrimmedRect.y0 < 0) 2842 { 2843 int yDiff = 0 - sourceTrimmedRect.y0; 2844 sourceTrimmedRect.y0 = 0; 2845 destTrimmedRect.y0 += yDiff; 2846 } 2847 2848 if(sourceTrimmedRect.y1 > readBufferHeight) 2849 { 2850 int yDiff = sourceTrimmedRect.y1 - readBufferHeight; 2851 sourceTrimmedRect.y1 = readBufferHeight; 2852 destTrimmedRect.y1 -= yDiff; 2853 } 2854 2855 if(destTrimmedRect.x0 < 0) 2856 { 2857 int xDiff = 0 - destTrimmedRect.x0; 2858 destTrimmedRect.x0 = 0; 2859 sourceTrimmedRect.x0 += xDiff; 2860 } 2861 2862 if(destTrimmedRect.x1 > drawBufferWidth) 2863 { 2864 int xDiff = destTrimmedRect.x1 - drawBufferWidth; 2865 destTrimmedRect.x1 = drawBufferWidth; 2866 sourceTrimmedRect.x1 -= xDiff; 2867 } 2868 2869 if(destTrimmedRect.y0 < 0) 2870 { 2871 int yDiff = 0 - destTrimmedRect.y0; 2872 destTrimmedRect.y0 = 0; 2873 sourceTrimmedRect.y0 += yDiff; 2874 } 2875 2876 if(destTrimmedRect.y1 > drawBufferHeight) 2877 { 2878 int yDiff = destTrimmedRect.y1 - drawBufferHeight; 2879 destTrimmedRect.y1 = drawBufferHeight; 2880 sourceTrimmedRect.y1 -= yDiff; 2881 } 2882 2883 bool partialBufferCopy = false; 2884 2885 if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight || 2886 sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth || 2887 destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight || 2888 destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth || 2889 sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0) 2890 { 2891 partialBufferCopy = true; 2892 } 2893 2894 bool blitRenderTarget = false; 2895 bool blitDepthStencil = false; 2896 2897 if(mask & GL_COLOR_BUFFER_BIT) 2898 { 2899 const bool validReadType = readFramebuffer->getColorbufferType() == GL_TEXTURE_2D || 2900 readFramebuffer->getColorbufferType() == GL_RENDERBUFFER; 2901 const bool validDrawType = drawFramebuffer->getColorbufferType() == GL_TEXTURE_2D || 2902 drawFramebuffer->getColorbufferType() == GL_RENDERBUFFER; 2903 if(!validReadType || !validDrawType || 2904 readFramebuffer->getColorbuffer()->getInternalFormat() != drawFramebuffer->getColorbuffer()->getInternalFormat()) 2905 { 2906 ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation"); 2907 return error(GL_INVALID_OPERATION); 2908 } 2909 2910 if(partialBufferCopy && readBufferSamples > 1) 2911 { 2912 return error(GL_INVALID_OPERATION); 2913 } 2914 2915 blitRenderTarget = true; 2916 } 2917 2918 if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) 2919 { 2920 Renderbuffer *readDSBuffer = NULL; 2921 Renderbuffer *drawDSBuffer = NULL; 2922 2923 // We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have 2924 // both a depth and stencil buffer, it will be the same buffer. 2925 2926 if(mask & GL_DEPTH_BUFFER_BIT) 2927 { 2928 if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer()) 2929 { 2930 if(readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() || 2931 readFramebuffer->getDepthbuffer()->getInternalFormat() != drawFramebuffer->getDepthbuffer()->getInternalFormat()) 2932 { 2933 return error(GL_INVALID_OPERATION); 2934 } 2935 2936 blitDepthStencil = true; 2937 readDSBuffer = readFramebuffer->getDepthbuffer(); 2938 drawDSBuffer = drawFramebuffer->getDepthbuffer(); 2939 } 2940 } 2941 2942 if(mask & GL_STENCIL_BUFFER_BIT) 2943 { 2944 if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer()) 2945 { 2946 if(readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() || 2947 readFramebuffer->getStencilbuffer()->getInternalFormat() != drawFramebuffer->getStencilbuffer()->getInternalFormat()) 2948 { 2949 return error(GL_INVALID_OPERATION); 2950 } 2951 2952 blitDepthStencil = true; 2953 readDSBuffer = readFramebuffer->getStencilbuffer(); 2954 drawDSBuffer = drawFramebuffer->getStencilbuffer(); 2955 } 2956 } 2957 2958 if(partialBufferCopy) 2959 { 2960 ERR("Only whole-buffer depth and stencil blits are supported by this implementation."); 2961 return error(GL_INVALID_OPERATION); // Only whole-buffer copies are permitted 2962 } 2963 2964 if((drawDSBuffer && drawDSBuffer->getSamples() > 1) || 2965 (readDSBuffer && readDSBuffer->getSamples() > 1)) 2966 { 2967 return error(GL_INVALID_OPERATION); 2968 } 2969 } 2970 2971 if(blitRenderTarget || blitDepthStencil) 2972 { 2973 if(blitRenderTarget) 2974 { 2975 egl::Image *readRenderTarget = readFramebuffer->getRenderTarget(); 2976 egl::Image *drawRenderTarget = drawFramebuffer->getRenderTarget(); 2977 2978 bool success = device->stretchRect(readRenderTarget, &sourceRect, drawRenderTarget, &destRect, false); 2979 2980 readRenderTarget->release(); 2981 drawRenderTarget->release(); 2982 2983 if(!success) 2984 { 2985 ERR("BlitFramebufferANGLE failed."); 2986 return; 2987 } 2988 } 2989 2990 if(blitDepthStencil) 2991 { 2992 bool success = device->stretchRect(readFramebuffer->getDepthStencil(), NULL, drawFramebuffer->getDepthStencil(), NULL, false); 2993 2994 if(!success) 2995 { 2996 ERR("BlitFramebufferANGLE failed."); 2997 return; 2998 } 2999 } 3000 } 3001} 3002 3003void Context::bindTexImage(egl::Surface *surface) 3004{ 3005 es2::Texture2D *textureObject = getTexture2D(); 3006 3007 if(textureObject) 3008 { 3009 textureObject->bindTexImage(surface); 3010 } 3011} 3012 3013EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel) 3014{ 3015 GLenum textureTarget = GL_NONE; 3016 3017 switch(target) 3018 { 3019 case EGL_GL_TEXTURE_2D_KHR: 3020 textureTarget = GL_TEXTURE_2D; 3021 break; 3022 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: 3023 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: 3024 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: 3025 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: 3026 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: 3027 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: 3028 textureTarget = GL_TEXTURE_CUBE_MAP; 3029 break; 3030 case EGL_GL_RENDERBUFFER_KHR: 3031 break; 3032 default: 3033 return EGL_BAD_PARAMETER; 3034 } 3035 3036 if(textureLevel >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 3037 { 3038 return EGL_BAD_MATCH; 3039 } 3040 3041 if(textureTarget != GL_NONE) 3042 { 3043 es2::Texture *texture = getTexture(name); 3044 3045 if(!texture || texture->getTarget() != textureTarget) 3046 { 3047 return EGL_BAD_PARAMETER; 3048 } 3049 3050 if(texture->isShared(textureTarget, textureLevel)) // Bound to an EGLSurface or already an EGLImage sibling 3051 { 3052 return EGL_BAD_ACCESS; 3053 } 3054 3055 if(textureLevel != 0 && !texture->isSamplerComplete()) 3056 { 3057 return EGL_BAD_PARAMETER; 3058 } 3059 3060 if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1)) 3061 { 3062 return EGL_BAD_PARAMETER; 3063 } 3064 } 3065 else if(target == EGL_GL_RENDERBUFFER_KHR) 3066 { 3067 es2::Renderbuffer *renderbuffer = getRenderbuffer(name); 3068 3069 if(!renderbuffer) 3070 { 3071 return EGL_BAD_PARAMETER; 3072 } 3073 3074 if(renderbuffer->isShared()) // Already an EGLImage sibling 3075 { 3076 return EGL_BAD_ACCESS; 3077 } 3078 } 3079 else UNREACHABLE(); 3080 3081 return EGL_SUCCESS; 3082} 3083 3084egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel) 3085{ 3086 GLenum textureTarget = GL_NONE; 3087 3088 switch(target) 3089 { 3090 case EGL_GL_TEXTURE_2D_KHR: textureTarget = GL_TEXTURE_2D; break; 3091 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break; 3092 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break; 3093 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break; 3094 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break; 3095 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break; 3096 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break; 3097 } 3098 3099 if(textureTarget != GL_NONE) 3100 { 3101 es2::Texture *texture = getTexture(name); 3102 3103 return texture->createSharedImage(textureTarget, textureLevel); 3104 } 3105 else if(target == EGL_GL_RENDERBUFFER_KHR) 3106 { 3107 es2::Renderbuffer *renderbuffer = getRenderbuffer(name); 3108 3109 return renderbuffer->createSharedImage(); 3110 } 3111 else UNREACHABLE(); 3112 3113 return 0; 3114} 3115 3116Device *Context::getDevice() 3117{ 3118 return device; 3119} 3120 3121} 3122 3123// Exported functions for use by EGL 3124extern "C" 3125{ 3126 es2::Context *glCreateContext(const egl::Config *config, const es2::Context *shareContext) 3127 { 3128 return new es2::Context(config, shareContext); 3129 } 3130} 3131