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 es1::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 "Framebuffer.h" 23#include "Query.h" 24#include "Renderbuffer.h" 25#include "Texture.h" 26#include "VertexDataManager.h" 27#include "IndexDataManager.h" 28#include "libEGL/Display.h" 29#include "libEGL/Surface.h" 30#include "Common/Half.hpp" 31 32#include <EGL/eglext.h> 33 34#undef near 35#undef far 36 37namespace es1 38{ 39Device *Context::device = 0; 40 41Context::Context(const egl::Config *config, const Context *shareContext) 42 : modelViewStack(MAX_MODELVIEW_STACK_DEPTH), 43 projectionStack(MAX_PROJECTION_STACK_DEPTH), 44 textureStack0(MAX_TEXTURE_STACK_DEPTH), 45 textureStack1(MAX_TEXTURE_STACK_DEPTH) 46{ 47 device = getDevice(); 48 49 mVertexDataManager = new VertexDataManager(this); 50 mIndexDataManager = new IndexDataManager(); 51 52 setClearColor(0.0f, 0.0f, 0.0f, 0.0f); 53 54 mState.depthClearValue = 1.0f; 55 mState.stencilClearValue = 0; 56 57 mState.cullFace = false; 58 mState.cullMode = GL_BACK; 59 mState.frontFace = GL_CCW; 60 mState.depthTest = false; 61 mState.depthFunc = GL_LESS; 62 mState.blend = false; 63 mState.sourceBlendRGB = GL_ONE; 64 mState.sourceBlendAlpha = GL_ONE; 65 mState.destBlendRGB = GL_ZERO; 66 mState.destBlendAlpha = GL_ZERO; 67 mState.blendEquationRGB = GL_FUNC_ADD_OES; 68 mState.blendEquationAlpha = GL_FUNC_ADD_OES; 69 mState.stencilTest = false; 70 mState.stencilFunc = GL_ALWAYS; 71 mState.stencilRef = 0; 72 mState.stencilMask = -1; 73 mState.stencilWritemask = -1; 74 mState.stencilFail = GL_KEEP; 75 mState.stencilPassDepthFail = GL_KEEP; 76 mState.stencilPassDepthPass = GL_KEEP; 77 mState.polygonOffsetFill = false; 78 mState.polygonOffsetFactor = 0.0f; 79 mState.polygonOffsetUnits = 0.0f; 80 mState.sampleAlphaToCoverage = false; 81 mState.sampleCoverage = false; 82 mState.sampleCoverageValue = 1.0f; 83 mState.sampleCoverageInvert = false; 84 mState.scissorTest = false; 85 mState.dither = true; 86 mState.generateMipmapHint = GL_DONT_CARE; 87 88 mState.lineWidth = 1.0f; 89 90 mState.viewportX = 0; 91 mState.viewportY = 0; 92 mState.viewportWidth = config->mDisplayMode.width; 93 mState.viewportHeight = config->mDisplayMode.height; 94 mState.zNear = 0.0f; 95 mState.zFar = 1.0f; 96 97 mState.scissorX = 0; 98 mState.scissorY = 0; 99 mState.scissorWidth = config->mDisplayMode.width; 100 mState.scissorHeight = config->mDisplayMode.height; 101 102 mState.colorMaskRed = true; 103 mState.colorMaskGreen = true; 104 mState.colorMaskBlue = true; 105 mState.colorMaskAlpha = true; 106 mState.depthMask = true; 107 108 if(shareContext != NULL) 109 { 110 mResourceManager = shareContext->mResourceManager; 111 mResourceManager->addRef(); 112 } 113 else 114 { 115 mResourceManager = new ResourceManager(); 116 } 117 118 // [OpenGL ES 2.0.24] section 3.7 page 83: 119 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional 120 // and cube map texture state vectors respectively associated with them. 121 // In order that access to these initial textures not be lost, they are treated as texture 122 // objects all of whose names are 0. 123 124 mTexture2DZero.set(new Texture2D(0)); 125 mTextureExternalZero.set(new TextureExternal(0)); 126 127 mState.activeSampler = 0; 128 bindArrayBuffer(0); 129 bindElementArrayBuffer(0); 130 bindTexture2D(0); 131 bindFramebuffer(0); 132 bindRenderbuffer(0); 133 134 mState.packAlignment = 4; 135 mState.unpackAlignment = 4; 136 137 mInvalidEnum = false; 138 mInvalidValue = false; 139 mInvalidOperation = false; 140 mOutOfMemory = false; 141 mInvalidFramebufferOperation = false; 142 143 lighting = false; 144 145 for(int i = 0; i < MAX_LIGHTS; i++) 146 { 147 light[i].enable = false; 148 light[i].ambient = {0.0f, 0.0f, 0.0f, 1.0f}; 149 light[i].diffuse = {0.0f, 0.0f, 0.0f, 1.0f}; 150 light[i].specular = {0.0f, 0.0f, 0.0f, 1.0f}; 151 light[i].position = {0.0f, 0.0f, 1.0f, 0.0f}; 152 light[i].direction = {0.0f, 0.0f, -1.0f}; 153 light[i].attenuation = {1.0f, 0.0f, 0.0f}; 154 } 155 156 light[0].diffuse = {1.0f, 1.0f, 1.0f, 1.0f}; 157 light[0].specular = {1.0f, 1.0f, 1.0f, 1.0f}; 158 159 globalAmbient = {0.2f, 0.2f, 0.2f, 1.0f}; 160 materialAmbient = {0.2f, 0.2f, 0.2f, 1.0f}; 161 materialDiffuse = {0.8f, 0.8f, 0.8f, 1.0f}; 162 materialSpecular = {0.0f, 0.0f, 0.0f, 1.0f}; 163 materialEmission = {0.0f, 0.0f, 0.0f, 1.0f}; 164 165 matrixMode = GL_MODELVIEW; 166 texture2D = false; 167 clientTexture = GL_TEXTURE0; 168 169 setVertexAttrib(sw::Color0, 1.0f, 1.0f, 1.0f, 1.0f); 170 171 for(int i = 0; i < MAX_TEXTURE_UNITS; i++) 172 { 173 setVertexAttrib(sw::TexCoord0 + i, 0.0f, 0.0f, 0.0f, 1.0f); 174 } 175 176 setVertexAttrib(sw::Normal, 0.0f, 0.0f, 1.0f, 1.0f); 177 178 mHasBeenCurrent = false; 179 180 markAllStateDirty(); 181} 182 183Context::~Context() 184{ 185 while(!mFramebufferMap.empty()) 186 { 187 deleteFramebuffer(mFramebufferMap.begin()->first); 188 } 189 190 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++) 191 { 192 for(int sampler = 0; sampler < MAX_TEXTURE_UNITS; sampler++) 193 { 194 mState.samplerTexture[type][sampler].set(NULL); 195 } 196 } 197 198 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 199 { 200 mState.vertexAttribute[i].mBoundBuffer.set(NULL); 201 } 202 203 mState.arrayBuffer.set(NULL); 204 mState.elementArrayBuffer.set(NULL); 205 mState.renderbuffer.set(NULL); 206 207 mTexture2DZero.set(NULL); 208 mTextureExternalZero.set(NULL); 209 210 delete mVertexDataManager; 211 delete mIndexDataManager; 212 213 mResourceManager->release(); 214} 215 216void Context::makeCurrent(egl::Surface *surface) 217{ 218 if(!mHasBeenCurrent) 219 { 220 mState.viewportX = 0; 221 mState.viewportY = 0; 222 mState.viewportWidth = surface->getWidth(); 223 mState.viewportHeight = surface->getHeight(); 224 225 mState.scissorX = 0; 226 mState.scissorY = 0; 227 mState.scissorWidth = surface->getWidth(); 228 mState.scissorHeight = surface->getHeight(); 229 230 mHasBeenCurrent = true; 231 } 232 233 // Wrap the existing resources into GL objects and assign them to the '0' names 234 egl::Image *defaultRenderTarget = surface->getRenderTarget(); 235 egl::Image *depthStencil = surface->getDepthStencil(); 236 237 Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget); 238 DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil); 239 Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero); 240 241 setFramebufferZero(framebufferZero); 242 243 if(defaultRenderTarget) 244 { 245 defaultRenderTarget->release(); 246 } 247 248 if(depthStencil) 249 { 250 depthStencil->release(); 251 } 252 253 markAllStateDirty(); 254} 255 256void Context::destroy() 257{ 258 delete this; 259} 260 261int Context::getClientVersion() 262{ 263 return 1; 264} 265 266// This function will set all of the state-related dirty flags, so that all state is set during next pre-draw. 267void Context::markAllStateDirty() 268{ 269 mDepthStateDirty = true; 270 mMaskStateDirty = true; 271 mBlendStateDirty = true; 272 mStencilStateDirty = true; 273 mPolygonOffsetStateDirty = true; 274 mSampleStateDirty = true; 275 mDitherStateDirty = true; 276 mFrontFaceDirty = true; 277} 278 279void Context::setClearColor(float red, float green, float blue, float alpha) 280{ 281 mState.colorClearValue.red = red; 282 mState.colorClearValue.green = green; 283 mState.colorClearValue.blue = blue; 284 mState.colorClearValue.alpha = alpha; 285} 286 287void Context::setClearDepth(float depth) 288{ 289 mState.depthClearValue = depth; 290} 291 292void Context::setClearStencil(int stencil) 293{ 294 mState.stencilClearValue = stencil; 295} 296 297void Context::setCullFace(bool enabled) 298{ 299 mState.cullFace = enabled; 300} 301 302bool Context::isCullFaceEnabled() const 303{ 304 return mState.cullFace; 305} 306 307void Context::setCullMode(GLenum mode) 308{ 309 mState.cullMode = mode; 310} 311 312void Context::setFrontFace(GLenum front) 313{ 314 if(mState.frontFace != front) 315 { 316 mState.frontFace = front; 317 mFrontFaceDirty = true; 318 } 319} 320 321void Context::setDepthTest(bool enabled) 322{ 323 if(mState.depthTest != enabled) 324 { 325 mState.depthTest = enabled; 326 mDepthStateDirty = true; 327 } 328} 329 330bool Context::isDepthTestEnabled() const 331{ 332 return mState.depthTest; 333} 334 335void Context::setDepthFunc(GLenum depthFunc) 336{ 337 if(mState.depthFunc != depthFunc) 338 { 339 mState.depthFunc = depthFunc; 340 mDepthStateDirty = true; 341 } 342} 343 344void Context::setDepthRange(float zNear, float zFar) 345{ 346 mState.zNear = zNear; 347 mState.zFar = zFar; 348} 349 350void Context::setBlend(bool enabled) 351{ 352 if(mState.blend != enabled) 353 { 354 mState.blend = enabled; 355 mBlendStateDirty = true; 356 } 357} 358 359bool Context::isBlendEnabled() const 360{ 361 return mState.blend; 362} 363 364void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha) 365{ 366 if(mState.sourceBlendRGB != sourceRGB || 367 mState.sourceBlendAlpha != sourceAlpha || 368 mState.destBlendRGB != destRGB || 369 mState.destBlendAlpha != destAlpha) 370 { 371 mState.sourceBlendRGB = sourceRGB; 372 mState.destBlendRGB = destRGB; 373 mState.sourceBlendAlpha = sourceAlpha; 374 mState.destBlendAlpha = destAlpha; 375 mBlendStateDirty = true; 376 } 377} 378 379void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation) 380{ 381 if(mState.blendEquationRGB != rgbEquation || 382 mState.blendEquationAlpha != alphaEquation) 383 { 384 mState.blendEquationRGB = rgbEquation; 385 mState.blendEquationAlpha = alphaEquation; 386 mBlendStateDirty = true; 387 } 388} 389 390void Context::setStencilTest(bool enabled) 391{ 392 if(mState.stencilTest != enabled) 393 { 394 mState.stencilTest = enabled; 395 mStencilStateDirty = true; 396 } 397} 398 399bool Context::isStencilTestEnabled() const 400{ 401 return mState.stencilTest; 402} 403 404void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask) 405{ 406 if(mState.stencilFunc != stencilFunc || 407 mState.stencilRef != stencilRef || 408 mState.stencilMask != stencilMask) 409 { 410 mState.stencilFunc = stencilFunc; 411 mState.stencilRef = (stencilRef > 0) ? stencilRef : 0; 412 mState.stencilMask = stencilMask; 413 mStencilStateDirty = true; 414 } 415} 416 417void Context::setStencilWritemask(GLuint stencilWritemask) 418{ 419 if(mState.stencilWritemask != stencilWritemask) 420 { 421 mState.stencilWritemask = stencilWritemask; 422 mStencilStateDirty = true; 423 } 424} 425 426void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass) 427{ 428 if(mState.stencilFail != stencilFail || 429 mState.stencilPassDepthFail != stencilPassDepthFail || 430 mState.stencilPassDepthPass != stencilPassDepthPass) 431 { 432 mState.stencilFail = stencilFail; 433 mState.stencilPassDepthFail = stencilPassDepthFail; 434 mState.stencilPassDepthPass = stencilPassDepthPass; 435 mStencilStateDirty = true; 436 } 437} 438 439void Context::setPolygonOffsetFill(bool enabled) 440{ 441 if(mState.polygonOffsetFill != enabled) 442 { 443 mState.polygonOffsetFill = enabled; 444 mPolygonOffsetStateDirty = true; 445 } 446} 447 448bool Context::isPolygonOffsetFillEnabled() const 449{ 450 return mState.polygonOffsetFill; 451} 452 453void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units) 454{ 455 if(mState.polygonOffsetFactor != factor || 456 mState.polygonOffsetUnits != units) 457 { 458 mState.polygonOffsetFactor = factor; 459 mState.polygonOffsetUnits = units; 460 mPolygonOffsetStateDirty = true; 461 } 462} 463 464void Context::setSampleAlphaToCoverage(bool enabled) 465{ 466 if(mState.sampleAlphaToCoverage != enabled) 467 { 468 mState.sampleAlphaToCoverage = enabled; 469 mSampleStateDirty = true; 470 } 471} 472 473bool Context::isSampleAlphaToCoverageEnabled() const 474{ 475 return mState.sampleAlphaToCoverage; 476} 477 478void Context::setSampleCoverage(bool enabled) 479{ 480 if(mState.sampleCoverage != enabled) 481 { 482 mState.sampleCoverage = enabled; 483 mSampleStateDirty = true; 484 } 485} 486 487bool Context::isSampleCoverageEnabled() const 488{ 489 return mState.sampleCoverage; 490} 491 492void Context::setSampleCoverageParams(GLclampf value, bool invert) 493{ 494 if(mState.sampleCoverageValue != value || 495 mState.sampleCoverageInvert != invert) 496 { 497 mState.sampleCoverageValue = value; 498 mState.sampleCoverageInvert = invert; 499 mSampleStateDirty = true; 500 } 501} 502 503void Context::setScissorTest(bool enabled) 504{ 505 mState.scissorTest = enabled; 506} 507 508bool Context::isScissorTestEnabled() const 509{ 510 return mState.scissorTest; 511} 512 513void Context::setDither(bool enabled) 514{ 515 if(mState.dither != enabled) 516 { 517 mState.dither = enabled; 518 mDitherStateDirty = true; 519 } 520} 521 522bool Context::isDitherEnabled() const 523{ 524 return mState.dither; 525} 526 527void Context::setLighting(bool enable) 528{ 529 lighting = enable; 530} 531 532void Context::setLight(int index, bool enable) 533{ 534 light[index].enable = enable; 535} 536 537void Context::setLightAmbient(int index, float r, float g, float b, float a) 538{ 539 light[index].ambient = {r, g, b, a}; 540} 541 542void Context::setLightDiffuse(int index, float r, float g, float b, float a) 543{ 544 light[index].diffuse = {r, g, b, a}; 545} 546 547void Context::setLightSpecular(int index, float r, float g, float b, float a) 548{ 549 light[index].specular = {r, g, b, a}; 550} 551 552void Context::setLightPosition(int index, float x, float y, float z, float w) 553{ 554 light[index].position = {x, y, z, w}; 555} 556 557void Context::setLightDirection(int index, float x, float y, float z) 558{ 559 light[index].direction = {x, y, z}; 560} 561 562void Context::setLightAttenuationConstant(int index, float constant) 563{ 564 light[index].attenuation.constant = constant; 565} 566 567void Context::setLightAttenuationLinear(int index, float linear) 568{ 569 light[index].attenuation.linear = linear; 570} 571 572void Context::setLightAttenuationQuadratic(int index, float quadratic) 573{ 574 light[index].attenuation.quadratic = quadratic; 575} 576 577void Context::setTexture2D(bool enable) 578{ 579 texture2D = enable; 580} 581 582void Context::setLineWidth(GLfloat width) 583{ 584 mState.lineWidth = width; 585} 586 587void Context::setGenerateMipmapHint(GLenum hint) 588{ 589 mState.generateMipmapHint = hint; 590} 591 592void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height) 593{ 594 mState.viewportX = x; 595 mState.viewportY = y; 596 mState.viewportWidth = width; 597 mState.viewportHeight = height; 598} 599 600void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height) 601{ 602 mState.scissorX = x; 603 mState.scissorY = y; 604 mState.scissorWidth = width; 605 mState.scissorHeight = height; 606} 607 608void Context::setColorMask(bool red, bool green, bool blue, bool alpha) 609{ 610 if(mState.colorMaskRed != red || mState.colorMaskGreen != green || 611 mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha) 612 { 613 mState.colorMaskRed = red; 614 mState.colorMaskGreen = green; 615 mState.colorMaskBlue = blue; 616 mState.colorMaskAlpha = alpha; 617 mMaskStateDirty = true; 618 } 619} 620 621void Context::setDepthMask(bool mask) 622{ 623 if(mState.depthMask != mask) 624 { 625 mState.depthMask = mask; 626 mMaskStateDirty = true; 627 } 628} 629 630void Context::setActiveSampler(unsigned int active) 631{ 632 mState.activeSampler = active; 633} 634 635GLuint Context::getFramebufferHandle() const 636{ 637 return mState.framebuffer; 638} 639 640GLuint Context::getRenderbufferHandle() const 641{ 642 return mState.renderbuffer.id(); 643} 644 645GLuint Context::getArrayBufferHandle() const 646{ 647 return mState.arrayBuffer.id(); 648} 649 650void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled) 651{ 652 mState.vertexAttribute[attribNum].mArrayEnabled = enabled; 653} 654 655const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) 656{ 657 return mState.vertexAttribute[attribNum]; 658} 659 660void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized, 661 GLsizei stride, const void *pointer) 662{ 663 mState.vertexAttribute[attribNum].mBoundBuffer.set(boundBuffer); 664 mState.vertexAttribute[attribNum].mSize = size; 665 mState.vertexAttribute[attribNum].mType = type; 666 mState.vertexAttribute[attribNum].mNormalized = normalized; 667 mState.vertexAttribute[attribNum].mStride = stride; 668 mState.vertexAttribute[attribNum].mPointer = pointer; 669} 670 671const void *Context::getVertexAttribPointer(unsigned int attribNum) const 672{ 673 return mState.vertexAttribute[attribNum].mPointer; 674} 675 676const VertexAttributeArray &Context::getVertexAttributes() 677{ 678 return mState.vertexAttribute; 679} 680 681void Context::setPackAlignment(GLint alignment) 682{ 683 mState.packAlignment = alignment; 684} 685 686GLint Context::getPackAlignment() const 687{ 688 return mState.packAlignment; 689} 690 691void Context::setUnpackAlignment(GLint alignment) 692{ 693 mState.unpackAlignment = alignment; 694} 695 696GLint Context::getUnpackAlignment() const 697{ 698 return mState.unpackAlignment; 699} 700 701GLuint Context::createBuffer() 702{ 703 return mResourceManager->createBuffer(); 704} 705 706GLuint Context::createTexture() 707{ 708 return mResourceManager->createTexture(); 709} 710 711GLuint Context::createRenderbuffer() 712{ 713 return mResourceManager->createRenderbuffer(); 714} 715 716// Returns an unused framebuffer name 717GLuint Context::createFramebuffer() 718{ 719 GLuint handle = mFramebufferHandleAllocator.allocate(); 720 721 mFramebufferMap[handle] = NULL; 722 723 return handle; 724} 725 726void Context::deleteBuffer(GLuint buffer) 727{ 728 if(mResourceManager->getBuffer(buffer)) 729 { 730 detachBuffer(buffer); 731 } 732 733 mResourceManager->deleteBuffer(buffer); 734} 735 736void Context::deleteTexture(GLuint texture) 737{ 738 if(mResourceManager->getTexture(texture)) 739 { 740 detachTexture(texture); 741 } 742 743 mResourceManager->deleteTexture(texture); 744} 745 746void Context::deleteRenderbuffer(GLuint renderbuffer) 747{ 748 if(mResourceManager->getRenderbuffer(renderbuffer)) 749 { 750 detachRenderbuffer(renderbuffer); 751 } 752 753 mResourceManager->deleteRenderbuffer(renderbuffer); 754} 755 756void Context::deleteFramebuffer(GLuint framebuffer) 757{ 758 FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer); 759 760 if(framebufferObject != mFramebufferMap.end()) 761 { 762 detachFramebuffer(framebuffer); 763 764 mFramebufferHandleAllocator.release(framebufferObject->first); 765 delete framebufferObject->second; 766 mFramebufferMap.erase(framebufferObject); 767 } 768} 769 770Buffer *Context::getBuffer(GLuint handle) 771{ 772 return mResourceManager->getBuffer(handle); 773} 774 775Texture *Context::getTexture(GLuint handle) 776{ 777 return mResourceManager->getTexture(handle); 778} 779 780Renderbuffer *Context::getRenderbuffer(GLuint handle) 781{ 782 return mResourceManager->getRenderbuffer(handle); 783} 784 785Framebuffer *Context::getFramebuffer() 786{ 787 return getFramebuffer(mState.framebuffer); 788} 789 790void Context::bindArrayBuffer(unsigned int buffer) 791{ 792 mResourceManager->checkBufferAllocation(buffer); 793 794 mState.arrayBuffer.set(getBuffer(buffer)); 795} 796 797void Context::bindElementArrayBuffer(unsigned int buffer) 798{ 799 mResourceManager->checkBufferAllocation(buffer); 800 801 mState.elementArrayBuffer.set(getBuffer(buffer)); 802} 803 804void Context::bindTexture2D(GLuint texture) 805{ 806 mResourceManager->checkTextureAllocation(texture, TEXTURE_2D); 807 808 mState.samplerTexture[TEXTURE_2D][mState.activeSampler].set(getTexture(texture)); 809} 810 811void Context::bindTextureExternal(GLuint texture) 812{ 813 mResourceManager->checkTextureAllocation(texture, TEXTURE_EXTERNAL); 814 815 mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].set(getTexture(texture)); 816} 817 818void Context::bindFramebuffer(GLuint framebuffer) 819{ 820 if(!getFramebuffer(framebuffer)) 821 { 822 mFramebufferMap[framebuffer] = new Framebuffer(); 823 } 824 825 mState.framebuffer = framebuffer; 826} 827 828void Context::bindRenderbuffer(GLuint renderbuffer) 829{ 830 mState.renderbuffer.set(getRenderbuffer(renderbuffer)); 831} 832 833void Context::setFramebufferZero(Framebuffer *buffer) 834{ 835 delete mFramebufferMap[0]; 836 mFramebufferMap[0] = buffer; 837} 838 839void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer) 840{ 841 Renderbuffer *renderbufferObject = mState.renderbuffer.get(); 842 renderbufferObject->setStorage(renderbuffer); 843} 844 845Framebuffer *Context::getFramebuffer(unsigned int handle) 846{ 847 FramebufferMap::iterator framebuffer = mFramebufferMap.find(handle); 848 849 if(framebuffer == mFramebufferMap.end()) 850 { 851 return NULL; 852 } 853 else 854 { 855 return framebuffer->second; 856 } 857} 858 859Buffer *Context::getArrayBuffer() 860{ 861 return mState.arrayBuffer.get(); 862} 863 864Buffer *Context::getElementArrayBuffer() 865{ 866 return mState.elementArrayBuffer.get(); 867} 868 869Texture2D *Context::getTexture2D() 870{ 871 return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D)); 872} 873 874TextureExternal *Context::getTextureExternal() 875{ 876 return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL)); 877} 878 879Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) 880{ 881 GLuint texid = mState.samplerTexture[type][sampler].id(); 882 883 if(texid == 0) // Special case: 0 refers to different initial textures based on the target 884 { 885 switch (type) 886 { 887 case TEXTURE_2D: return mTexture2DZero.get(); 888 case TEXTURE_EXTERNAL: return mTextureExternalZero.get(); 889 default: UNREACHABLE(); 890 } 891 } 892 893 return mState.samplerTexture[type][sampler].get(); 894} 895 896bool Context::getBooleanv(GLenum pname, GLboolean *params) 897{ 898 switch (pname) 899 { 900 case GL_SAMPLE_COVERAGE_INVERT: *params = mState.sampleCoverageInvert; break; 901 case GL_DEPTH_WRITEMASK: *params = mState.depthMask; break; 902 case GL_COLOR_WRITEMASK: 903 params[0] = mState.colorMaskRed; 904 params[1] = mState.colorMaskGreen; 905 params[2] = mState.colorMaskBlue; 906 params[3] = mState.colorMaskAlpha; 907 break; 908 case GL_CULL_FACE: *params = mState.cullFace; break; 909 case GL_POLYGON_OFFSET_FILL: *params = mState.polygonOffsetFill; break; 910 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverage; break; 911 case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverage; break; 912 case GL_SCISSOR_TEST: *params = mState.scissorTest; break; 913 case GL_STENCIL_TEST: *params = mState.stencilTest; break; 914 case GL_DEPTH_TEST: *params = mState.depthTest; break; 915 case GL_BLEND: *params = mState.blend; break; 916 case GL_DITHER: *params = mState.dither; break; 917 default: 918 return false; 919 } 920 921 return true; 922} 923 924bool Context::getFloatv(GLenum pname, GLfloat *params) 925{ 926 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation 927 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names 928 // GetIntegerv as its native query function. As it would require conversion in any 929 // case, this should make no difference to the calling application. 930 switch (pname) 931 { 932 case GL_LINE_WIDTH: *params = mState.lineWidth; break; 933 case GL_SAMPLE_COVERAGE_VALUE: *params = mState.sampleCoverageValue; break; 934 case GL_DEPTH_CLEAR_VALUE: *params = mState.depthClearValue; break; 935 case GL_POLYGON_OFFSET_FACTOR: *params = mState.polygonOffsetFactor; break; 936 case GL_POLYGON_OFFSET_UNITS: *params = mState.polygonOffsetUnits; break; 937 case GL_ALIASED_LINE_WIDTH_RANGE: 938 params[0] = ALIASED_LINE_WIDTH_RANGE_MIN; 939 params[1] = ALIASED_LINE_WIDTH_RANGE_MAX; 940 break; 941 case GL_ALIASED_POINT_SIZE_RANGE: 942 params[0] = ALIASED_POINT_SIZE_RANGE_MIN; 943 params[1] = ALIASED_POINT_SIZE_RANGE_MAX; 944 break; 945 case GL_DEPTH_RANGE: 946 params[0] = mState.zNear; 947 params[1] = mState.zFar; 948 break; 949 case GL_COLOR_CLEAR_VALUE: 950 params[0] = mState.colorClearValue.red; 951 params[1] = mState.colorClearValue.green; 952 params[2] = mState.colorClearValue.blue; 953 params[3] = mState.colorClearValue.alpha; 954 break; 955 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: 956 *params = MAX_TEXTURE_MAX_ANISOTROPY; 957 break; 958 case GL_MODELVIEW_MATRIX: 959 for(int i = 0; i < 16; i++) 960 { 961 params[i] = modelViewStack.current()[i % 4][i / 4]; 962 } 963 break; 964 case GL_PROJECTION_MATRIX: 965 for(int i = 0; i < 16; i++) 966 { 967 params[i] = projectionStack.current()[i % 4][i / 4]; 968 } 969 break; 970 default: 971 return false; 972 } 973 974 return true; 975} 976 977bool Context::getIntegerv(GLenum pname, GLint *params) 978{ 979 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation 980 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names 981 // GetIntegerv as its native query function. As it would require conversion in any 982 // case, this should make no difference to the calling application. You may find it in 983 // Context::getFloatv. 984 switch (pname) 985 { 986 case GL_ARRAY_BUFFER_BINDING: *params = mState.arrayBuffer.id(); break; 987 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = mState.elementArrayBuffer.id(); break; 988 case GL_FRAMEBUFFER_BINDING_OES: *params = mState.framebuffer; break; 989 case GL_RENDERBUFFER_BINDING_OES: *params = mState.renderbuffer.id(); break; 990 case GL_PACK_ALIGNMENT: *params = mState.packAlignment; break; 991 case GL_UNPACK_ALIGNMENT: *params = mState.unpackAlignment; break; 992 case GL_GENERATE_MIPMAP_HINT: *params = mState.generateMipmapHint; break; 993 case GL_ACTIVE_TEXTURE: *params = (mState.activeSampler + GL_TEXTURE0); break; 994 case GL_STENCIL_FUNC: *params = mState.stencilFunc; break; 995 case GL_STENCIL_REF: *params = mState.stencilRef; break; 996 case GL_STENCIL_VALUE_MASK: *params = mState.stencilMask; break; 997 case GL_STENCIL_FAIL: *params = mState.stencilFail; break; 998 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mState.stencilPassDepthFail; break; 999 case GL_STENCIL_PASS_DEPTH_PASS: *params = mState.stencilPassDepthPass; break; 1000 case GL_DEPTH_FUNC: *params = mState.depthFunc; break; 1001 case GL_BLEND_SRC_RGB_OES: *params = mState.sourceBlendRGB; break; 1002 case GL_BLEND_SRC_ALPHA_OES: *params = mState.sourceBlendAlpha; break; 1003 case GL_BLEND_DST_RGB_OES: *params = mState.destBlendRGB; break; 1004 case GL_BLEND_DST_ALPHA_OES: *params = mState.destBlendAlpha; break; 1005 case GL_BLEND_EQUATION_RGB_OES: *params = mState.blendEquationRGB; break; 1006 case GL_BLEND_EQUATION_ALPHA_OES: *params = mState.blendEquationAlpha; break; 1007 case GL_STENCIL_WRITEMASK: *params = mState.stencilWritemask; break; 1008 case GL_STENCIL_CLEAR_VALUE: *params = mState.stencilClearValue; break; 1009 case GL_SUBPIXEL_BITS: *params = 4; break; 1010 case GL_MAX_TEXTURE_SIZE: *params = IMPLEMENTATION_MAX_TEXTURE_SIZE; break; 1011 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: 1012 { 1013 if(S3TC_SUPPORT) 1014 { 1015 // GL_COMPRESSED_RGB_S3TC_DXT1_EXT 1016 // GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 1017 *params = 2; 1018 } 1019 else 1020 { 1021 *params = 0; 1022 } 1023 } 1024 break; 1025 case GL_SAMPLE_BUFFERS: 1026 case GL_SAMPLES: 1027 { 1028 Framebuffer *framebuffer = getFramebuffer(); 1029 int width, height, samples; 1030 1031 if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE_OES) 1032 { 1033 switch(pname) 1034 { 1035 case GL_SAMPLE_BUFFERS: 1036 if(samples > 1) 1037 { 1038 *params = 1; 1039 } 1040 else 1041 { 1042 *params = 0; 1043 } 1044 break; 1045 case GL_SAMPLES: 1046 *params = samples & ~1; 1047 break; 1048 } 1049 } 1050 else 1051 { 1052 *params = 0; 1053 } 1054 } 1055 break; 1056 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES: *params = IMPLEMENTATION_COLOR_READ_TYPE; break; 1057 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES: *params = IMPLEMENTATION_COLOR_READ_FORMAT; break; 1058 case GL_MAX_VIEWPORT_DIMS: 1059 { 1060 int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; 1061 params[0] = maxDimension; 1062 params[1] = maxDimension; 1063 } 1064 break; 1065 case GL_COMPRESSED_TEXTURE_FORMATS: 1066 { 1067 if(S3TC_SUPPORT) 1068 { 1069 params[0] = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; 1070 params[1] = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; 1071 } 1072 } 1073 break; 1074 case GL_VIEWPORT: 1075 params[0] = mState.viewportX; 1076 params[1] = mState.viewportY; 1077 params[2] = mState.viewportWidth; 1078 params[3] = mState.viewportHeight; 1079 break; 1080 case GL_SCISSOR_BOX: 1081 params[0] = mState.scissorX; 1082 params[1] = mState.scissorY; 1083 params[2] = mState.scissorWidth; 1084 params[3] = mState.scissorHeight; 1085 break; 1086 case GL_CULL_FACE_MODE: *params = mState.cullMode; break; 1087 case GL_FRONT_FACE: *params = mState.frontFace; break; 1088 case GL_RED_BITS: 1089 case GL_GREEN_BITS: 1090 case GL_BLUE_BITS: 1091 case GL_ALPHA_BITS: 1092 { 1093 Framebuffer *framebuffer = getFramebuffer(); 1094 Renderbuffer *colorbuffer = framebuffer->getColorbuffer(); 1095 1096 if(colorbuffer) 1097 { 1098 switch (pname) 1099 { 1100 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break; 1101 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break; 1102 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break; 1103 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break; 1104 } 1105 } 1106 else 1107 { 1108 *params = 0; 1109 } 1110 } 1111 break; 1112 case GL_DEPTH_BITS: 1113 { 1114 Framebuffer *framebuffer = getFramebuffer(); 1115 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer(); 1116 1117 if(depthbuffer) 1118 { 1119 *params = depthbuffer->getDepthSize(); 1120 } 1121 else 1122 { 1123 *params = 0; 1124 } 1125 } 1126 break; 1127 case GL_STENCIL_BITS: 1128 { 1129 Framebuffer *framebuffer = getFramebuffer(); 1130 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer(); 1131 1132 if(stencilbuffer) 1133 { 1134 *params = stencilbuffer->getStencilSize(); 1135 } 1136 else 1137 { 1138 *params = 0; 1139 } 1140 } 1141 break; 1142 case GL_TEXTURE_BINDING_2D: 1143 { 1144 if(mState.activeSampler < 0 || mState.activeSampler > MAX_TEXTURE_UNITS - 1) 1145 { 1146 error(GL_INVALID_OPERATION); 1147 return false; 1148 } 1149 1150 *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].id(); 1151 } 1152 break; 1153 case GL_TEXTURE_BINDING_CUBE_MAP_OES: 1154 { 1155 if(mState.activeSampler < 0 || mState.activeSampler > MAX_TEXTURE_UNITS - 1) 1156 { 1157 error(GL_INVALID_OPERATION); 1158 return false; 1159 } 1160 1161 *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].id(); 1162 } 1163 break; 1164 case GL_TEXTURE_BINDING_EXTERNAL_OES: 1165 { 1166 if(mState.activeSampler < 0 || mState.activeSampler > MAX_TEXTURE_UNITS - 1) 1167 { 1168 error(GL_INVALID_OPERATION); 1169 return false; 1170 } 1171 1172 *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].id(); 1173 } 1174 break; 1175 case GL_MAX_LIGHTS: *params = MAX_LIGHTS; break; 1176 case GL_MAX_MODELVIEW_STACK_DEPTH: *params = MAX_MODELVIEW_STACK_DEPTH; break; 1177 case GL_MAX_PROJECTION_STACK_DEPTH: *params = MAX_PROJECTION_STACK_DEPTH; break; 1178 case GL_MAX_TEXTURE_STACK_DEPTH: *params = MAX_TEXTURE_STACK_DEPTH; break; 1179 case GL_MAX_TEXTURE_UNITS: *params = MAX_TEXTURE_UNITS; break; 1180 default: 1181 return false; 1182 } 1183 1184 return true; 1185} 1186 1187int Context::getQueryParameterNum(GLenum pname) 1188{ 1189 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation 1190 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due 1191 // to the fact that it is stored internally as a float, and so would require conversion 1192 // if returned from Context::getIntegerv. Since this conversion is already implemented 1193 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we 1194 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling 1195 // application. 1196 switch (pname) 1197 { 1198 case GL_COMPRESSED_TEXTURE_FORMATS: 1199 return S3TC_SUPPORT ? 2 : 0; 1200 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: 1201 case GL_ARRAY_BUFFER_BINDING: 1202 case GL_FRAMEBUFFER_BINDING_OES: 1203 case GL_RENDERBUFFER_BINDING_OES: 1204 case GL_PACK_ALIGNMENT: 1205 case GL_UNPACK_ALIGNMENT: 1206 case GL_GENERATE_MIPMAP_HINT: 1207 case GL_RED_BITS: 1208 case GL_GREEN_BITS: 1209 case GL_BLUE_BITS: 1210 case GL_ALPHA_BITS: 1211 case GL_DEPTH_BITS: 1212 case GL_STENCIL_BITS: 1213 case GL_ELEMENT_ARRAY_BUFFER_BINDING: 1214 case GL_CULL_FACE_MODE: 1215 case GL_FRONT_FACE: 1216 case GL_ACTIVE_TEXTURE: 1217 case GL_STENCIL_FUNC: 1218 case GL_STENCIL_VALUE_MASK: 1219 case GL_STENCIL_REF: 1220 case GL_STENCIL_FAIL: 1221 case GL_STENCIL_PASS_DEPTH_FAIL: 1222 case GL_STENCIL_PASS_DEPTH_PASS: 1223 case GL_DEPTH_FUNC: 1224 case GL_BLEND_SRC_RGB_OES: 1225 case GL_BLEND_SRC_ALPHA_OES: 1226 case GL_BLEND_DST_RGB_OES: 1227 case GL_BLEND_DST_ALPHA_OES: 1228 case GL_BLEND_EQUATION_RGB_OES: 1229 case GL_BLEND_EQUATION_ALPHA_OES: 1230 case GL_STENCIL_WRITEMASK: 1231 case GL_STENCIL_CLEAR_VALUE: 1232 case GL_SUBPIXEL_BITS: 1233 case GL_MAX_TEXTURE_SIZE: 1234 case GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES: 1235 case GL_SAMPLE_BUFFERS: 1236 case GL_SAMPLES: 1237 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES: 1238 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES: 1239 case GL_TEXTURE_BINDING_2D: 1240 case GL_TEXTURE_BINDING_CUBE_MAP_OES: 1241 case GL_TEXTURE_BINDING_EXTERNAL_OES: 1242 return 1; 1243 case GL_MAX_VIEWPORT_DIMS: 1244 return 2; 1245 case GL_VIEWPORT: 1246 case GL_SCISSOR_BOX: 1247 return 4; 1248 case GL_SAMPLE_COVERAGE_INVERT: 1249 case GL_DEPTH_WRITEMASK: 1250 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled, 1251 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries. 1252 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural 1253 case GL_SAMPLE_COVERAGE: 1254 case GL_SCISSOR_TEST: 1255 case GL_STENCIL_TEST: 1256 case GL_DEPTH_TEST: 1257 case GL_BLEND: 1258 case GL_DITHER: 1259 return 1; 1260 case GL_COLOR_WRITEMASK: 1261 return 4; 1262 case GL_POLYGON_OFFSET_FACTOR: 1263 case GL_POLYGON_OFFSET_UNITS: 1264 case GL_SAMPLE_COVERAGE_VALUE: 1265 case GL_DEPTH_CLEAR_VALUE: 1266 case GL_LINE_WIDTH: 1267 return 1; 1268 case GL_ALIASED_LINE_WIDTH_RANGE: 1269 case GL_ALIASED_POINT_SIZE_RANGE: 1270 case GL_DEPTH_RANGE: 1271 return 2; 1272 case GL_COLOR_CLEAR_VALUE: 1273 return 4; 1274 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: 1275 case GL_MAX_LIGHTS: 1276 case GL_MAX_MODELVIEW_STACK_DEPTH: 1277 case GL_MAX_PROJECTION_STACK_DEPTH: 1278 case GL_MAX_TEXTURE_STACK_DEPTH: 1279 case GL_MAX_TEXTURE_UNITS: 1280 return 1; 1281 default: 1282 UNREACHABLE(); 1283 } 1284 1285 return -1; 1286} 1287 1288bool Context::isQueryParameterInt(GLenum pname) 1289{ 1290 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation 1291 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due 1292 // to the fact that it is stored internally as a float, and so would require conversion 1293 // if returned from Context::getIntegerv. Since this conversion is already implemented 1294 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we 1295 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling 1296 // application. 1297 switch(pname) 1298 { 1299 case GL_COMPRESSED_TEXTURE_FORMATS: 1300 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: 1301 case GL_ARRAY_BUFFER_BINDING: 1302 case GL_FRAMEBUFFER_BINDING_OES: 1303 case GL_RENDERBUFFER_BINDING_OES: 1304 case GL_PACK_ALIGNMENT: 1305 case GL_UNPACK_ALIGNMENT: 1306 case GL_GENERATE_MIPMAP_HINT: 1307 case GL_RED_BITS: 1308 case GL_GREEN_BITS: 1309 case GL_BLUE_BITS: 1310 case GL_ALPHA_BITS: 1311 case GL_DEPTH_BITS: 1312 case GL_STENCIL_BITS: 1313 case GL_ELEMENT_ARRAY_BUFFER_BINDING: 1314 case GL_CULL_FACE_MODE: 1315 case GL_FRONT_FACE: 1316 case GL_ACTIVE_TEXTURE: 1317 case GL_STENCIL_FUNC: 1318 case GL_STENCIL_VALUE_MASK: 1319 case GL_STENCIL_REF: 1320 case GL_STENCIL_FAIL: 1321 case GL_STENCIL_PASS_DEPTH_FAIL: 1322 case GL_STENCIL_PASS_DEPTH_PASS: 1323 case GL_DEPTH_FUNC: 1324 case GL_BLEND_SRC_RGB_OES: 1325 case GL_BLEND_SRC_ALPHA_OES: 1326 case GL_BLEND_DST_RGB_OES: 1327 case GL_BLEND_DST_ALPHA_OES: 1328 case GL_BLEND_EQUATION_RGB_OES: 1329 case GL_BLEND_EQUATION_ALPHA_OES: 1330 case GL_STENCIL_WRITEMASK: 1331 case GL_STENCIL_CLEAR_VALUE: 1332 case GL_SUBPIXEL_BITS: 1333 case GL_MAX_TEXTURE_SIZE: 1334 case GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES: 1335 case GL_SAMPLE_BUFFERS: 1336 case GL_SAMPLES: 1337 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES: 1338 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES: 1339 case GL_TEXTURE_BINDING_2D: 1340 case GL_TEXTURE_BINDING_CUBE_MAP_OES: 1341 case GL_TEXTURE_BINDING_EXTERNAL_OES: 1342 case GL_MAX_VIEWPORT_DIMS: 1343 case GL_VIEWPORT: 1344 case GL_SCISSOR_BOX: 1345 case GL_MAX_LIGHTS: 1346 case GL_MAX_MODELVIEW_STACK_DEPTH: 1347 case GL_MAX_PROJECTION_STACK_DEPTH: 1348 case GL_MAX_TEXTURE_STACK_DEPTH: 1349 case GL_MAX_TEXTURE_UNITS: 1350 return true; 1351 default: 1352 ASSERT(isQueryParameterFloat(pname) || isQueryParameterBool(pname)); 1353 } 1354 1355 return false; 1356} 1357 1358bool Context::isQueryParameterFloat(GLenum pname) 1359{ 1360 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation 1361 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due 1362 // to the fact that it is stored internally as a float, and so would require conversion 1363 // if returned from Context::getIntegerv. Since this conversion is already implemented 1364 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we 1365 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling 1366 // application. 1367 switch(pname) 1368 { 1369 case GL_POLYGON_OFFSET_FACTOR: 1370 case GL_POLYGON_OFFSET_UNITS: 1371 case GL_SAMPLE_COVERAGE_VALUE: 1372 case GL_DEPTH_CLEAR_VALUE: 1373 case GL_LINE_WIDTH: 1374 case GL_ALIASED_LINE_WIDTH_RANGE: 1375 case GL_ALIASED_POINT_SIZE_RANGE: 1376 case GL_DEPTH_RANGE: 1377 case GL_COLOR_CLEAR_VALUE: 1378 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: 1379 return true; 1380 default: 1381 ASSERT(isQueryParameterInt(pname) || isQueryParameterBool(pname)); 1382 } 1383 1384 return false; 1385} 1386 1387bool Context::isQueryParameterBool(GLenum pname) 1388{ 1389 switch(pname) 1390 { 1391 case GL_SAMPLE_COVERAGE_INVERT: 1392 case GL_DEPTH_WRITEMASK: 1393 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled, 1394 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries. 1395 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural 1396 case GL_SAMPLE_COVERAGE: 1397 case GL_SCISSOR_TEST: 1398 case GL_STENCIL_TEST: 1399 case GL_DEPTH_TEST: 1400 case GL_BLEND: 1401 case GL_DITHER: 1402 case GL_COLOR_WRITEMASK: 1403 return true; 1404 default: 1405 ASSERT(isQueryParameterInt(pname) || isQueryParameterFloat(pname)); 1406 } 1407 1408 return false; 1409} 1410 1411// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle 1412bool Context::applyRenderTarget() 1413{ 1414 Framebuffer *framebuffer = getFramebuffer(); 1415 int width, height, samples; 1416 1417 if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE_OES) 1418 { 1419 return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES, false); 1420 } 1421 1422 egl::Image *renderTarget = framebuffer->getRenderTarget(); 1423 device->setRenderTarget(renderTarget); 1424 if(renderTarget) renderTarget->release(); 1425 1426 egl::Image *depthStencil = framebuffer->getDepthStencil(); 1427 device->setDepthStencilSurface(depthStencil); 1428 if(depthStencil) depthStencil->release(); 1429 1430 Viewport viewport; 1431 float zNear = clamp01(mState.zNear); 1432 float zFar = clamp01(mState.zFar); 1433 1434 viewport.x0 = mState.viewportX; 1435 viewport.y0 = mState.viewportY; 1436 viewport.width = mState.viewportWidth; 1437 viewport.height = mState.viewportHeight; 1438 viewport.minZ = zNear; 1439 viewport.maxZ = zFar; 1440 1441 device->setViewport(viewport); 1442 1443 if(mState.scissorTest) 1444 { 1445 sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight}; 1446 scissor.clip(0, 0, width, height); 1447 1448 device->setScissorRect(scissor); 1449 device->setScissorEnable(true); 1450 } 1451 else 1452 { 1453 device->setScissorEnable(false); 1454 } 1455 1456 return true; 1457} 1458 1459// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) 1460void Context::applyState(GLenum drawMode) 1461{ 1462 Framebuffer *framebuffer = getFramebuffer(); 1463 1464 if(mState.cullFace) 1465 { 1466 device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace)); 1467 } 1468 else 1469 { 1470 device->setCullMode(sw::CULL_NONE); 1471 } 1472 1473 if(mDepthStateDirty) 1474 { 1475 if(mState.depthTest) 1476 { 1477 device->setDepthBufferEnable(true); 1478 device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc)); 1479 } 1480 else 1481 { 1482 device->setDepthBufferEnable(false); 1483 } 1484 1485 mDepthStateDirty = false; 1486 } 1487 1488 if(mBlendStateDirty) 1489 { 1490 if(mState.blend) 1491 { 1492 device->setAlphaBlendEnable(true); 1493 device->setSeparateAlphaBlendEnable(true); 1494 1495 device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB)); 1496 device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB)); 1497 device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB)); 1498 1499 device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha)); 1500 device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha)); 1501 device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha)); 1502 } 1503 else 1504 { 1505 device->setAlphaBlendEnable(false); 1506 } 1507 1508 mBlendStateDirty = false; 1509 } 1510 1511 if(mStencilStateDirty || mFrontFaceDirty) 1512 { 1513 if(mState.stencilTest && framebuffer->hasStencil()) 1514 { 1515 device->setStencilEnable(true); 1516 device->setTwoSidedStencil(true); 1517 1518 // get the maximum size of the stencil ref 1519 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer(); 1520 GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1; 1521 1522 device->setStencilWriteMask(mState.stencilWritemask); 1523 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc)); 1524 1525 device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil); 1526 device->setStencilMask(mState.stencilMask); 1527 1528 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail)); 1529 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail)); 1530 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass)); 1531 1532 device->setStencilWriteMaskCCW(mState.stencilWritemask); 1533 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc)); 1534 1535 device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil); 1536 device->setStencilMaskCCW(mState.stencilMask); 1537 1538 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail)); 1539 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail)); 1540 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass)); 1541 } 1542 else 1543 { 1544 device->setStencilEnable(false); 1545 } 1546 1547 mStencilStateDirty = false; 1548 mFrontFaceDirty = false; 1549 } 1550 1551 if(mMaskStateDirty) 1552 { 1553 device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha)); 1554 device->setDepthWriteEnable(mState.depthMask); 1555 1556 mMaskStateDirty = false; 1557 } 1558 1559 if(mPolygonOffsetStateDirty) 1560 { 1561 if(mState.polygonOffsetFill) 1562 { 1563 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer(); 1564 if(depthbuffer) 1565 { 1566 device->setSlopeDepthBias(mState.polygonOffsetFactor); 1567 float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize())); 1568 device->setDepthBias(depthBias); 1569 } 1570 } 1571 else 1572 { 1573 device->setSlopeDepthBias(0); 1574 device->setDepthBias(0); 1575 } 1576 1577 mPolygonOffsetStateDirty = false; 1578 } 1579 1580 if(mSampleStateDirty) 1581 { 1582 if(mState.sampleAlphaToCoverage) 1583 { 1584 device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE); 1585 } 1586 else 1587 { 1588 device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE); 1589 } 1590 1591 if(mState.sampleCoverage) 1592 { 1593 unsigned int mask = 0; 1594 if(mState.sampleCoverageValue != 0) 1595 { 1596 int width, height, samples; 1597 framebuffer->completeness(width, height, samples); 1598 1599 float threshold = 0.5f; 1600 1601 for(int i = 0; i < samples; i++) 1602 { 1603 mask <<= 1; 1604 1605 if((i + 1) * mState.sampleCoverageValue >= threshold) 1606 { 1607 threshold += 1.0f; 1608 mask |= 1; 1609 } 1610 } 1611 } 1612 1613 if(mState.sampleCoverageInvert) 1614 { 1615 mask = ~mask; 1616 } 1617 1618 device->setMultiSampleMask(mask); 1619 } 1620 else 1621 { 1622 device->setMultiSampleMask(0xFFFFFFFF); 1623 } 1624 1625 mSampleStateDirty = false; 1626 } 1627 1628 if(mDitherStateDirty) 1629 { 1630 // UNIMPLEMENTED(); // FIXME 1631 1632 mDitherStateDirty = false; 1633 } 1634 1635 device->setLightingEnable(lighting); 1636 device->setGlobalAmbient(sw::Color<float>(globalAmbient.red, globalAmbient.green, globalAmbient.blue, globalAmbient.alpha)); 1637 1638 for(int i = 0; i < MAX_LIGHTS; i++) 1639 { 1640 device->setLightEnable(i, light[i].enable); 1641 device->setLightAmbient(i, sw::Color<float>(light[i].ambient.red, light[i].ambient.green, light[i].ambient.blue, light[i].ambient.alpha)); 1642 device->setLightDiffuse(i, sw::Color<float>(light[i].diffuse.red, light[i].diffuse.green, light[i].diffuse.blue, light[i].diffuse.alpha)); 1643 device->setLightSpecular(i, sw::Color<float>(light[i].specular.red, light[i].specular.green, light[i].specular.blue, light[i].specular.alpha)); 1644 device->setLightAttenuation(i, light[i].attenuation.constant, light[i].attenuation.linear, light[i].attenuation.quadratic); 1645 1646 if(light[i].position.w != 0.0f) 1647 { 1648 device->setLightPosition(i, sw::Point(light[i].position.x / light[i].position.w, light[i].position.y / light[i].position.w, light[i].position.z / light[i].position.w)); 1649 } 1650 else // Hack: set the position far way 1651 { 1652 device->setLightPosition(i, sw::Point(1e10f * light[i].position.x, 1e10f * light[i].position.y, 1e10f * light[i].position.z)); 1653 } 1654 } 1655 1656 device->setMaterialAmbient(sw::Color<float>(materialAmbient.red, materialAmbient.green, materialAmbient.blue, materialAmbient.alpha)); 1657 device->setMaterialDiffuse(sw::Color<float>(materialDiffuse.red, materialDiffuse.green, materialDiffuse.blue, materialDiffuse.alpha)); 1658 device->setMaterialSpecular(sw::Color<float>(materialSpecular.red, materialSpecular.green, materialSpecular.blue, materialSpecular.alpha)); 1659 device->setMaterialEmission(sw::Color<float>(materialEmission.red, materialEmission.green, materialEmission.blue, materialEmission.alpha)); 1660 1661 device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL); 1662 device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL); 1663 device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL); 1664 device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL); 1665 1666 device->setProjectionMatrix(projectionStack.current()); 1667 device->setModelMatrix(modelViewStack.current()); 1668 device->setTextureMatrix(0, textureStack0.current()); 1669 device->setTextureMatrix(1, textureStack1.current()); 1670 device->setTextureTransform(0, textureStack0.isIdentity() ? 0 : 4, false); 1671 device->setTextureTransform(1, textureStack1.isIdentity() ? 0 : 4, false); 1672} 1673 1674GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count) 1675{ 1676 TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS]; 1677 1678 GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes); 1679 if(err != GL_NO_ERROR) 1680 { 1681 return err; 1682 } 1683 1684 device->resetInputStreams(false); 1685 1686 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 1687 { 1688 sw::Resource *resource = attributes[i].vertexBuffer; 1689 const void *buffer = (char*)resource->getBuffer() + attributes[i].offset; 1690 1691 int stride = attributes[i].stride; 1692 1693 buffer = (char*)buffer + stride * base; 1694 1695 sw::Stream attribute(resource, buffer, stride); 1696 1697 attribute.type = attributes[i].type; 1698 attribute.count = attributes[i].count; 1699 attribute.normalized = attributes[i].normalized; 1700 1701 device->setInputStream(i, attribute); 1702 } 1703 1704 return GL_NO_ERROR; 1705} 1706 1707// Applies the indices and element array bindings 1708GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) 1709{ 1710 GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer.get(), indices, indexInfo); 1711 1712 if(err == GL_NO_ERROR) 1713 { 1714 device->setIndexBuffer(indexInfo->indexBuffer); 1715 } 1716 1717 return err; 1718} 1719 1720void Context::applyTextures() 1721{ 1722 for(int samplerIndex = 0; samplerIndex < MAX_TEXTURE_UNITS; samplerIndex++) 1723 { 1724 Texture *texture = getSamplerTexture(samplerIndex, TEXTURE_2D); 1725 1726 if(texture2D && texture->isSamplerComplete()) 1727 { 1728 GLenum wrapS = texture->getWrapS(); 1729 GLenum wrapT = texture->getWrapT(); 1730 GLenum texFilter = texture->getMinFilter(); 1731 GLenum magFilter = texture->getMagFilter(); 1732 GLfloat maxAnisotropy = texture->getMaxAnisotropy(); 1733 1734 device->setAddressingModeU(sw::SAMPLER_PIXEL, samplerIndex, es2sw::ConvertTextureWrap(wrapS)); 1735 device->setAddressingModeV(sw::SAMPLER_PIXEL, samplerIndex, es2sw::ConvertTextureWrap(wrapT)); 1736 1737 sw::FilterType minFilter; 1738 sw::MipmapType mipFilter; 1739 es2sw::ConvertMinFilter(texFilter, &minFilter, &mipFilter, maxAnisotropy); 1740 // ASSERT(minFilter == es2sw::ConvertMagFilter(magFilter)); 1741 1742 device->setTextureFilter(sw::SAMPLER_PIXEL, samplerIndex, minFilter); 1743 // device->setTextureFilter(sw::SAMPLER_PIXEL, samplerIndex, es2sw::ConvertMagFilter(magFilter)); 1744 device->setMipmapFilter(sw::SAMPLER_PIXEL, samplerIndex, mipFilter); 1745 device->setMaxAnisotropy(sw::SAMPLER_PIXEL, samplerIndex, maxAnisotropy); 1746 1747 applyTexture(samplerIndex, texture); 1748 1749 device->setStageOperation(samplerIndex, sw::TextureStage::STAGE_MODULATE); 1750 device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_TEXTURE); 1751 device->setSecondArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT); 1752 1753 device->setStageOperationAlpha(samplerIndex, sw::TextureStage::STAGE_MODULATE); 1754 device->setFirstArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_TEXTURE); 1755 device->setSecondArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT); 1756 } 1757 else 1758 { 1759 applyTexture(samplerIndex, 0); 1760 1761 device->setStageOperation(samplerIndex, sw::TextureStage::STAGE_SELECTARG1); 1762 device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT); 1763 device->setSecondArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT); 1764 1765 device->setStageOperationAlpha(samplerIndex, sw::TextureStage::STAGE_SELECTARG1); 1766 device->setFirstArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT); 1767 device->setSecondArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT); 1768 } 1769 } 1770} 1771 1772void Context::applyTexture(int index, Texture *baseTexture) 1773{ 1774 sw::Resource *resource = 0; 1775 1776 if(baseTexture) 1777 { 1778 resource = baseTexture->getResource(); 1779 } 1780 1781 device->setTextureResource(index, resource); 1782 1783 if(baseTexture) 1784 { 1785 int levelCount = baseTexture->getLevelCount(); 1786 1787 if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES) 1788 { 1789 Texture2D *texture = static_cast<Texture2D*>(baseTexture); 1790 1791 for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++) 1792 { 1793 int surfaceLevel = mipmapLevel; 1794 1795 if(surfaceLevel < 0) 1796 { 1797 surfaceLevel = 0; 1798 } 1799 else if(surfaceLevel >= levelCount) 1800 { 1801 surfaceLevel = levelCount - 1; 1802 } 1803 1804 egl::Image *surface = texture->getImage(surfaceLevel); 1805 device->setTextureLevel(index, 0, mipmapLevel, surface, sw::TEXTURE_2D); 1806 } 1807 } 1808 else UNIMPLEMENTED(); 1809 } 1810 else 1811 { 1812 device->setTextureLevel(index, 0, 0, 0, sw::TEXTURE_NULL); 1813 } 1814} 1815 1816void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, 1817 GLenum format, GLenum type, GLsizei *bufSize, void* pixels) 1818{ 1819 Framebuffer *framebuffer = getFramebuffer(); 1820 int framebufferWidth, framebufferHeight, framebufferSamples; 1821 1822 if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE_OES) 1823 { 1824 return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES); 1825 } 1826 1827 if(getFramebufferHandle() != 0 && framebufferSamples != 0) 1828 { 1829 return error(GL_INVALID_OPERATION); 1830 } 1831 1832 GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment); 1833 1834 // Sized query sanity check 1835 if(bufSize) 1836 { 1837 int requiredSize = outputPitch * height; 1838 if(requiredSize > *bufSize) 1839 { 1840 return error(GL_INVALID_OPERATION); 1841 } 1842 } 1843 1844 egl::Image *renderTarget = framebuffer->getRenderTarget(); 1845 1846 if(!renderTarget) 1847 { 1848 return error(GL_OUT_OF_MEMORY); 1849 } 1850 1851 sw::Rect rect = {x, y, x + width, y + height}; 1852 rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight()); 1853 1854 unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY); 1855 unsigned char *dest = (unsigned char*)pixels; 1856 unsigned short *dest16 = (unsigned short*)pixels; 1857 int inputPitch = (int)renderTarget->getPitch(); 1858 1859 for(int j = 0; j < rect.y1 - rect.y0; j++) 1860 { 1861 if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 && 1862 format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) 1863 { 1864 // Fast path for EXT_read_format_bgra, given an RGBA source buffer 1865 // Note that buffers with no alpha go through the slow path below 1866 memcpy(dest + j * outputPitch, source + j * inputPitch, (rect.x1 - rect.x0) * 4); 1867 } 1868 else 1869 { 1870 for(int i = 0; i < rect.x1 - rect.x0; i++) 1871 { 1872 float r; 1873 float g; 1874 float b; 1875 float a; 1876 1877 switch(renderTarget->getInternalFormat()) 1878 { 1879 case sw::FORMAT_R5G6B5: 1880 { 1881 unsigned short rgb = *(unsigned short*)(source + 2 * i + j * inputPitch); 1882 1883 a = 1.0f; 1884 b = (rgb & 0x001F) * (1.0f / 0x001F); 1885 g = (rgb & 0x07E0) * (1.0f / 0x07E0); 1886 r = (rgb & 0xF800) * (1.0f / 0xF800); 1887 } 1888 break; 1889 case sw::FORMAT_A1R5G5B5: 1890 { 1891 unsigned short argb = *(unsigned short*)(source + 2 * i + j * inputPitch); 1892 1893 a = (argb & 0x8000) ? 1.0f : 0.0f; 1894 b = (argb & 0x001F) * (1.0f / 0x001F); 1895 g = (argb & 0x03E0) * (1.0f / 0x03E0); 1896 r = (argb & 0x7C00) * (1.0f / 0x7C00); 1897 } 1898 break; 1899 case sw::FORMAT_A8R8G8B8: 1900 { 1901 unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); 1902 1903 a = (argb & 0xFF000000) * (1.0f / 0xFF000000); 1904 b = (argb & 0x000000FF) * (1.0f / 0x000000FF); 1905 g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00); 1906 r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000); 1907 } 1908 break; 1909 case sw::FORMAT_X8R8G8B8: 1910 { 1911 unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * inputPitch); 1912 1913 a = 1.0f; 1914 b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF); 1915 g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00); 1916 r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000); 1917 } 1918 break; 1919 case sw::FORMAT_A2R10G10B10: 1920 { 1921 unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); 1922 1923 a = (argb & 0xC0000000) * (1.0f / 0xC0000000); 1924 b = (argb & 0x000003FF) * (1.0f / 0x000003FF); 1925 g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00); 1926 r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000); 1927 } 1928 break; 1929 case sw::FORMAT_A32B32G32R32F: 1930 { 1931 r = *((float*)(source + 16 * i + j * inputPitch) + 0); 1932 g = *((float*)(source + 16 * i + j * inputPitch) + 1); 1933 b = *((float*)(source + 16 * i + j * inputPitch) + 2); 1934 a = *((float*)(source + 16 * i + j * inputPitch) + 3); 1935 } 1936 break; 1937 case sw::FORMAT_A16B16G16R16F: 1938 { 1939 r = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 0); 1940 g = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 1); 1941 b = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 2); 1942 a = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 3); 1943 } 1944 break; 1945 default: 1946 UNIMPLEMENTED(); // FIXME 1947 UNREACHABLE(); 1948 } 1949 1950 switch(format) 1951 { 1952 case GL_RGBA: 1953 switch(type) 1954 { 1955 case GL_UNSIGNED_BYTE: 1956 dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f); 1957 dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f); 1958 dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f); 1959 dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f); 1960 break; 1961 default: UNREACHABLE(); 1962 } 1963 break; 1964 case GL_BGRA_EXT: 1965 switch(type) 1966 { 1967 case GL_UNSIGNED_BYTE: 1968 dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * b + 0.5f); 1969 dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f); 1970 dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * r + 0.5f); 1971 dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f); 1972 break; 1973 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: 1974 // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section 1975 // this type is packed as follows: 1976 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 1977 // -------------------------------------------------------------------------------- 1978 // | 4th | 3rd | 2nd | 1st component | 1979 // -------------------------------------------------------------------------------- 1980 // in the case of BGRA_EXT, B is the first component, G the second, and so forth. 1981 dest16[i + j * outputPitch / sizeof(unsigned short)] = 1982 ((unsigned short)(15 * a + 0.5f) << 12)| 1983 ((unsigned short)(15 * r + 0.5f) << 8) | 1984 ((unsigned short)(15 * g + 0.5f) << 4) | 1985 ((unsigned short)(15 * b + 0.5f) << 0); 1986 break; 1987 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: 1988 // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section 1989 // this type is packed as follows: 1990 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 1991 // -------------------------------------------------------------------------------- 1992 // | 4th | 3rd | 2nd | 1st component | 1993 // -------------------------------------------------------------------------------- 1994 // in the case of BGRA_EXT, B is the first component, G the second, and so forth. 1995 dest16[i + j * outputPitch / sizeof(unsigned short)] = 1996 ((unsigned short)( a + 0.5f) << 15) | 1997 ((unsigned short)(31 * r + 0.5f) << 10) | 1998 ((unsigned short)(31 * g + 0.5f) << 5) | 1999 ((unsigned short)(31 * b + 0.5f) << 0); 2000 break; 2001 default: UNREACHABLE(); 2002 } 2003 break; 2004 case GL_RGB: // IMPLEMENTATION_COLOR_READ_FORMAT 2005 switch(type) 2006 { 2007 case GL_UNSIGNED_SHORT_5_6_5: // IMPLEMENTATION_COLOR_READ_TYPE 2008 dest16[i + j * outputPitch / sizeof(unsigned short)] = 2009 ((unsigned short)(31 * b + 0.5f) << 0) | 2010 ((unsigned short)(63 * g + 0.5f) << 5) | 2011 ((unsigned short)(31 * r + 0.5f) << 11); 2012 break; 2013 default: UNREACHABLE(); 2014 } 2015 break; 2016 default: UNREACHABLE(); 2017 } 2018 } 2019 } 2020 } 2021 2022 renderTarget->unlock(); 2023 renderTarget->release(); 2024} 2025 2026void Context::clear(GLbitfield mask) 2027{ 2028 Framebuffer *framebuffer = getFramebuffer(); 2029 2030 if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES) 2031 { 2032 return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES); 2033 } 2034 2035 if(!applyRenderTarget()) 2036 { 2037 return; 2038 } 2039 2040 unsigned int color = (unorm<8>(mState.colorClearValue.alpha) << 24) | 2041 (unorm<8>(mState.colorClearValue.red) << 16) | 2042 (unorm<8>(mState.colorClearValue.green) << 8) | 2043 (unorm<8>(mState.colorClearValue.blue) << 0); 2044 float depth = clamp01(mState.depthClearValue); 2045 int stencil = mState.stencilClearValue & 0x000000FF; 2046 2047 if(mask & GL_COLOR_BUFFER_BIT) 2048 { 2049 unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) | 2050 (mState.colorMaskGreen ? 0x2 : 0) | 2051 (mState.colorMaskBlue ? 0x4 : 0) | 2052 (mState.colorMaskAlpha ? 0x8 : 0); 2053 2054 if(rgbaMask != 0) 2055 { 2056 device->clearColor(color, rgbaMask); 2057 } 2058 } 2059 2060 if(mask & GL_DEPTH_BUFFER_BIT) 2061 { 2062 if(mState.depthMask != 0) 2063 { 2064 device->clearDepth(depth); 2065 } 2066 } 2067 2068 if(mask & GL_STENCIL_BUFFER_BIT) 2069 { 2070 if(mState.stencilWritemask != 0) 2071 { 2072 device->clearStencil(stencil, mState.stencilWritemask); 2073 } 2074 } 2075} 2076 2077void Context::drawArrays(GLenum mode, GLint first, GLsizei count) 2078{ 2079 PrimitiveType primitiveType; 2080 int primitiveCount; 2081 2082 if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount)) 2083 return error(GL_INVALID_ENUM); 2084 2085 if(primitiveCount <= 0) 2086 { 2087 return; 2088 } 2089 2090 if(!applyRenderTarget()) 2091 { 2092 return; 2093 } 2094 2095 applyState(mode); 2096 2097 GLenum err = applyVertexBuffer(0, first, count); 2098 if(err != GL_NO_ERROR) 2099 { 2100 return error(err); 2101 } 2102 2103 applyTextures(); 2104 2105 if(!cullSkipsDraw(mode)) 2106 { 2107 device->drawPrimitive(primitiveType, primitiveCount); 2108 } 2109} 2110 2111void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) 2112{ 2113 if(!indices && !mState.elementArrayBuffer) 2114 { 2115 return error(GL_INVALID_OPERATION); 2116 } 2117 2118 PrimitiveType primitiveType; 2119 int primitiveCount; 2120 2121 if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount)) 2122 return error(GL_INVALID_ENUM); 2123 2124 if(primitiveCount <= 0) 2125 { 2126 return; 2127 } 2128 2129 if(!applyRenderTarget()) 2130 { 2131 return; 2132 } 2133 2134 applyState(mode); 2135 2136 TranslatedIndexData indexInfo; 2137 GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo); 2138 if(err != GL_NO_ERROR) 2139 { 2140 return error(err); 2141 } 2142 2143 GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1; 2144 err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount); 2145 if(err != GL_NO_ERROR) 2146 { 2147 return error(err); 2148 } 2149 2150 applyTextures(); 2151 2152 if(!cullSkipsDraw(mode)) 2153 { 2154 device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount, IndexDataManager::typeSize(type)); 2155 } 2156} 2157 2158void Context::finish() 2159{ 2160 device->finish(); 2161} 2162 2163void Context::flush() 2164{ 2165 // We don't queue anything without processing it as fast as possible 2166} 2167 2168void Context::recordInvalidEnum() 2169{ 2170 mInvalidEnum = true; 2171} 2172 2173void Context::recordInvalidValue() 2174{ 2175 mInvalidValue = true; 2176} 2177 2178void Context::recordInvalidOperation() 2179{ 2180 mInvalidOperation = true; 2181} 2182 2183void Context::recordOutOfMemory() 2184{ 2185 mOutOfMemory = true; 2186} 2187 2188void Context::recordInvalidFramebufferOperation() 2189{ 2190 mInvalidFramebufferOperation = true; 2191} 2192 2193// Get one of the recorded errors and clear its flag, if any. 2194// [OpenGL ES 2.0.24] section 2.5 page 13. 2195GLenum Context::getError() 2196{ 2197 if(mInvalidEnum) 2198 { 2199 mInvalidEnum = false; 2200 2201 return GL_INVALID_ENUM; 2202 } 2203 2204 if(mInvalidValue) 2205 { 2206 mInvalidValue = false; 2207 2208 return GL_INVALID_VALUE; 2209 } 2210 2211 if(mInvalidOperation) 2212 { 2213 mInvalidOperation = false; 2214 2215 return GL_INVALID_OPERATION; 2216 } 2217 2218 if(mOutOfMemory) 2219 { 2220 mOutOfMemory = false; 2221 2222 return GL_OUT_OF_MEMORY; 2223 } 2224 2225 if(mInvalidFramebufferOperation) 2226 { 2227 mInvalidFramebufferOperation = false; 2228 2229 return GL_INVALID_FRAMEBUFFER_OPERATION_OES; 2230 } 2231 2232 return GL_NO_ERROR; 2233} 2234 2235int Context::getSupportedMultiSampleDepth(sw::Format format, int requested) 2236{ 2237 if(requested <= 1) 2238 { 2239 return 1; 2240 } 2241 2242 if(requested == 2) 2243 { 2244 return 2; 2245 } 2246 2247 return 4; 2248} 2249 2250void Context::detachBuffer(GLuint buffer) 2251{ 2252 // [OpenGL ES 2.0.24] section 2.9 page 22: 2253 // If a buffer object is deleted while it is bound, all bindings to that object in the current context 2254 // (i.e. in the thread that called Delete-Buffers) are reset to zero. 2255 2256 if(mState.arrayBuffer.id() == buffer) 2257 { 2258 mState.arrayBuffer.set(NULL); 2259 } 2260 2261 if(mState.elementArrayBuffer.id() == buffer) 2262 { 2263 mState.elementArrayBuffer.set(NULL); 2264 } 2265 2266 for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++) 2267 { 2268 if(mState.vertexAttribute[attribute].mBoundBuffer.id() == buffer) 2269 { 2270 mState.vertexAttribute[attribute].mBoundBuffer.set(NULL); 2271 } 2272 } 2273} 2274 2275void Context::detachTexture(GLuint texture) 2276{ 2277 // [OpenGL ES 2.0.24] section 3.8 page 84: 2278 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are 2279 // rebound to texture object zero 2280 2281 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++) 2282 { 2283 for(int sampler = 0; sampler < MAX_TEXTURE_UNITS; sampler++) 2284 { 2285 if(mState.samplerTexture[type][sampler].id() == texture) 2286 { 2287 mState.samplerTexture[type][sampler].set(NULL); 2288 } 2289 } 2290 } 2291 2292 // [OpenGL ES 2.0.24] section 4.4 page 112: 2293 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is 2294 // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this 2295 // image was attached in the currently bound framebuffer. 2296 2297 Framebuffer *framebuffer = getFramebuffer(); 2298 2299 if(framebuffer) 2300 { 2301 framebuffer->detachTexture(texture); 2302 } 2303} 2304 2305void Context::detachFramebuffer(GLuint framebuffer) 2306{ 2307 // [OpenGL ES 2.0.24] section 4.4 page 107: 2308 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though 2309 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero. 2310 2311 if(mState.framebuffer == framebuffer) 2312 { 2313 bindFramebuffer(0); 2314 } 2315} 2316 2317void Context::detachRenderbuffer(GLuint renderbuffer) 2318{ 2319 // [OpenGL ES 2.0.24] section 4.4 page 109: 2320 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer 2321 // had been executed with the target RENDERBUFFER and name of zero. 2322 2323 if(mState.renderbuffer.id() == renderbuffer) 2324 { 2325 bindRenderbuffer(0); 2326 } 2327 2328 // [OpenGL ES 2.0.24] section 4.4 page 111: 2329 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer, 2330 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment 2331 // point to which this image was attached in the currently bound framebuffer. 2332 2333 Framebuffer *framebuffer = getFramebuffer(); 2334 2335 if(framebuffer) 2336 { 2337 framebuffer->detachRenderbuffer(renderbuffer); 2338 } 2339} 2340 2341bool Context::cullSkipsDraw(GLenum drawMode) 2342{ 2343 return mState.cullFace && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode); 2344} 2345 2346bool Context::isTriangleMode(GLenum drawMode) 2347{ 2348 switch (drawMode) 2349 { 2350 case GL_TRIANGLES: 2351 case GL_TRIANGLE_FAN: 2352 case GL_TRIANGLE_STRIP: 2353 return true; 2354 case GL_POINTS: 2355 case GL_LINES: 2356 case GL_LINE_LOOP: 2357 case GL_LINE_STRIP: 2358 return false; 2359 default: UNREACHABLE(); 2360 } 2361 2362 return false; 2363} 2364 2365void Context::setVertexAttrib(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) 2366{ 2367 ASSERT(index < MAX_VERTEX_ATTRIBS); 2368 2369 mState.vertexAttribute[index].mCurrentValue[0] = x; 2370 mState.vertexAttribute[index].mCurrentValue[1] = y; 2371 mState.vertexAttribute[index].mCurrentValue[2] = z; 2372 mState.vertexAttribute[index].mCurrentValue[3] = w; 2373 2374 mVertexDataManager->dirtyCurrentValue(index); 2375} 2376 2377void Context::bindTexImage(egl::Surface *surface) 2378{ 2379 es1::Texture2D *textureObject = getTexture2D(); 2380 2381 if(textureObject) 2382 { 2383 textureObject->bindTexImage(surface); 2384 } 2385} 2386 2387EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel) 2388{ 2389 switch(target) 2390 { 2391 case EGL_GL_TEXTURE_2D_KHR: 2392 break; 2393 case EGL_GL_RENDERBUFFER_KHR: 2394 break; 2395 default: 2396 return EGL_BAD_PARAMETER; 2397 } 2398 2399 if(textureLevel >= IMPLEMENTATION_MAX_TEXTURE_LEVELS) 2400 { 2401 return EGL_BAD_MATCH; 2402 } 2403 2404 if(target == EGL_GL_TEXTURE_2D_KHR) 2405 { 2406 Texture *texture = getTexture(name); 2407 2408 if(!texture || texture->getTarget() != GL_TEXTURE_2D) 2409 { 2410 return EGL_BAD_PARAMETER; 2411 } 2412 2413 if(texture->isShared(GL_TEXTURE_2D, textureLevel)) // Bound to an EGLSurface or already an EGLImage sibling 2414 { 2415 return EGL_BAD_ACCESS; 2416 } 2417 2418 if(textureLevel != 0 && !texture->isSamplerComplete()) 2419 { 2420 return EGL_BAD_PARAMETER; 2421 } 2422 2423 if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1)) 2424 { 2425 return EGL_BAD_PARAMETER; 2426 } 2427 } 2428 else if(target == EGL_GL_RENDERBUFFER_KHR) 2429 { 2430 Renderbuffer *renderbuffer = getRenderbuffer(name); 2431 2432 if(!renderbuffer) 2433 { 2434 return EGL_BAD_PARAMETER; 2435 } 2436 2437 if(renderbuffer->isShared()) // Already an EGLImage sibling 2438 { 2439 return EGL_BAD_ACCESS; 2440 } 2441 } 2442 else UNREACHABLE(); 2443 2444 return EGL_SUCCESS; 2445} 2446 2447egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel) 2448{ 2449 if(target == EGL_GL_TEXTURE_2D_KHR) 2450 { 2451 es1::Texture *texture = getTexture(name); 2452 2453 return texture->createSharedImage(GL_TEXTURE_2D, textureLevel); 2454 } 2455 else if(target == EGL_GL_RENDERBUFFER_KHR) 2456 { 2457 es1::Renderbuffer *renderbuffer = getRenderbuffer(name); 2458 2459 return renderbuffer->createSharedImage(); 2460 } 2461 else UNREACHABLE(); 2462 2463 return 0; 2464} 2465 2466Device *Context::getDevice() 2467{ 2468 if(!device) 2469 { 2470 sw::Context *context = new sw::Context(); 2471 device = new es1::Device(context); 2472 } 2473 2474 return device; 2475} 2476 2477void Context::setMatrixMode(GLenum mode) 2478{ 2479 matrixMode = mode; 2480} 2481 2482sw::MatrixStack &Context::currentMatrixStack() 2483{ 2484 switch(matrixMode) 2485 { 2486 case GL_MODELVIEW: 2487 return modelViewStack; 2488 case GL_PROJECTION: 2489 return projectionStack; 2490 case GL_TEXTURE: 2491 switch(mState.activeSampler) 2492 { 2493 case 0: return textureStack0; 2494 case 1: return textureStack1; 2495 } 2496 break; 2497 } 2498 2499 UNREACHABLE(); 2500 return textureStack0; 2501} 2502 2503void Context::loadIdentity() 2504{ 2505 currentMatrixStack().identity(); 2506} 2507 2508void Context::load(const GLfloat *m) 2509{ 2510 currentMatrixStack().load(m); 2511} 2512 2513void Context::pushMatrix() 2514{ 2515 if(!currentMatrixStack().push()) 2516 { 2517 return error(GL_STACK_OVERFLOW); 2518 } 2519} 2520 2521void Context::popMatrix() 2522{ 2523 if(!currentMatrixStack().pop()) 2524 { 2525 return error(GL_STACK_OVERFLOW); 2526 } 2527} 2528 2529void Context::rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) 2530{ 2531 currentMatrixStack().rotate(angle, x, y, z); 2532} 2533 2534void Context::translate(GLfloat x, GLfloat y, GLfloat z) 2535{ 2536 currentMatrixStack().translate(x, y, z); 2537} 2538 2539void Context::scale(GLfloat x, GLfloat y, GLfloat z) 2540{ 2541 currentMatrixStack().scale(x, y, z); 2542} 2543 2544void Context::multiply(const GLfloat *m) 2545{ 2546 currentMatrixStack().multiply(m); 2547} 2548 2549void Context::ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) 2550{ 2551 currentMatrixStack().ortho(left, right, bottom, top, zNear, zFar); 2552} 2553 2554void Context::clientActiveTexture(GLenum texture) 2555{ 2556 clientTexture = texture; 2557} 2558 2559GLenum Context::getClientActiveTexture() const 2560{ 2561 return clientTexture; 2562} 2563 2564unsigned int Context::getActiveTexture() const 2565{ 2566 return mState.activeSampler; 2567} 2568 2569} 2570 2571// Exported functions for use by EGL 2572extern "C" 2573{ 2574 es1::Context *glCreateContext(const egl::Config *config, const es1::Context *shareContext) 2575 { 2576 return new es1::Context(config, shareContext); 2577 } 2578} 2579