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