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