Context.cpp revision 9f6e888f3d86e9bc8cd07d7315211db3be15fb16
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: 1043 { 1044 Framebuffer *framebuffer = getFramebuffer(); 1045 *params = framebuffer->getImplementationColorReadType(); 1046 } 1047 break; 1048 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: 1049 { 1050 Framebuffer *framebuffer = getFramebuffer(); 1051 *params = framebuffer->getImplementationColorReadFormat(); 1052 } 1053 break; 1054 case GL_MAX_VIEWPORT_DIMS: 1055 { 1056 int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; 1057 params[0] = maxDimension; 1058 params[1] = maxDimension; 1059 } 1060 break; 1061 case GL_COMPRESSED_TEXTURE_FORMATS: 1062 { 1063 for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++) 1064 { 1065 params[i] = compressedTextureFormats[i]; 1066 } 1067 } 1068 break; 1069 case GL_VIEWPORT: 1070 params[0] = mState.viewportX; 1071 params[1] = mState.viewportY; 1072 params[2] = mState.viewportWidth; 1073 params[3] = mState.viewportHeight; 1074 break; 1075 case GL_SCISSOR_BOX: 1076 params[0] = mState.scissorX; 1077 params[1] = mState.scissorY; 1078 params[2] = mState.scissorWidth; 1079 params[3] = mState.scissorHeight; 1080 break; 1081 case GL_CULL_FACE_MODE: *params = mState.cullMode; break; 1082 case GL_FRONT_FACE: *params = mState.frontFace; break; 1083 case GL_RED_BITS: 1084 case GL_GREEN_BITS: 1085 case GL_BLUE_BITS: 1086 case GL_ALPHA_BITS: 1087 { 1088 Framebuffer *framebuffer = getFramebuffer(); 1089 Renderbuffer *colorbuffer = framebuffer->getColorbuffer(); 1090 1091 if(colorbuffer) 1092 { 1093 switch (pname) 1094 { 1095 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break; 1096 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break; 1097 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break; 1098 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break; 1099 } 1100 } 1101 else 1102 { 1103 *params = 0; 1104 } 1105 } 1106 break; 1107 case GL_DEPTH_BITS: 1108 { 1109 Framebuffer *framebuffer = getFramebuffer(); 1110 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer(); 1111 1112 if(depthbuffer) 1113 { 1114 *params = depthbuffer->getDepthSize(); 1115 } 1116 else 1117 { 1118 *params = 0; 1119 } 1120 } 1121 break; 1122 case GL_STENCIL_BITS: 1123 { 1124 Framebuffer *framebuffer = getFramebuffer(); 1125 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer(); 1126 1127 if(stencilbuffer) 1128 { 1129 *params = stencilbuffer->getStencilSize(); 1130 } 1131 else 1132 { 1133 *params = 0; 1134 } 1135 } 1136 break; 1137 case GL_TEXTURE_BINDING_2D: 1138 { 1139 if(mState.activeSampler < 0 || mState.activeSampler > MAX_TEXTURE_UNITS - 1) 1140 { 1141 error(GL_INVALID_OPERATION); 1142 return false; 1143 } 1144 1145 *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].id(); 1146 } 1147 break; 1148 case GL_TEXTURE_BINDING_CUBE_MAP_OES: 1149 { 1150 if(mState.activeSampler < 0 || mState.activeSampler > MAX_TEXTURE_UNITS - 1) 1151 { 1152 error(GL_INVALID_OPERATION); 1153 return false; 1154 } 1155 1156 *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].id(); 1157 } 1158 break; 1159 case GL_TEXTURE_BINDING_EXTERNAL_OES: 1160 { 1161 if(mState.activeSampler < 0 || mState.activeSampler > MAX_TEXTURE_UNITS - 1) 1162 { 1163 error(GL_INVALID_OPERATION); 1164 return false; 1165 } 1166 1167 *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].id(); 1168 } 1169 break; 1170 case GL_MAX_LIGHTS: *params = MAX_LIGHTS; break; 1171 case GL_MAX_MODELVIEW_STACK_DEPTH: *params = MAX_MODELVIEW_STACK_DEPTH; break; 1172 case GL_MAX_PROJECTION_STACK_DEPTH: *params = MAX_PROJECTION_STACK_DEPTH; break; 1173 case GL_MAX_TEXTURE_STACK_DEPTH: *params = MAX_TEXTURE_STACK_DEPTH; break; 1174 case GL_MAX_TEXTURE_UNITS: *params = MAX_TEXTURE_UNITS; break; 1175 default: 1176 return false; 1177 } 1178 1179 return true; 1180} 1181 1182int Context::getQueryParameterNum(GLenum pname) 1183{ 1184 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation 1185 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due 1186 // to the fact that it is stored internally as a float, and so would require conversion 1187 // if returned from Context::getIntegerv. Since this conversion is already implemented 1188 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we 1189 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling 1190 // application. 1191 switch (pname) 1192 { 1193 case GL_COMPRESSED_TEXTURE_FORMATS: 1194 return NUM_COMPRESSED_TEXTURE_FORMATS; 1195 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: 1196 case GL_ARRAY_BUFFER_BINDING: 1197 case GL_FRAMEBUFFER_BINDING_OES: 1198 case GL_RENDERBUFFER_BINDING_OES: 1199 case GL_PACK_ALIGNMENT: 1200 case GL_UNPACK_ALIGNMENT: 1201 case GL_GENERATE_MIPMAP_HINT: 1202 case GL_RED_BITS: 1203 case GL_GREEN_BITS: 1204 case GL_BLUE_BITS: 1205 case GL_ALPHA_BITS: 1206 case GL_DEPTH_BITS: 1207 case GL_STENCIL_BITS: 1208 case GL_ELEMENT_ARRAY_BUFFER_BINDING: 1209 case GL_CULL_FACE_MODE: 1210 case GL_FRONT_FACE: 1211 case GL_ACTIVE_TEXTURE: 1212 case GL_STENCIL_FUNC: 1213 case GL_STENCIL_VALUE_MASK: 1214 case GL_STENCIL_REF: 1215 case GL_STENCIL_FAIL: 1216 case GL_STENCIL_PASS_DEPTH_FAIL: 1217 case GL_STENCIL_PASS_DEPTH_PASS: 1218 case GL_DEPTH_FUNC: 1219 case GL_BLEND_SRC_RGB_OES: 1220 case GL_BLEND_SRC_ALPHA_OES: 1221 case GL_BLEND_DST_RGB_OES: 1222 case GL_BLEND_DST_ALPHA_OES: 1223 case GL_BLEND_EQUATION_RGB_OES: 1224 case GL_BLEND_EQUATION_ALPHA_OES: 1225 case GL_STENCIL_WRITEMASK: 1226 case GL_STENCIL_CLEAR_VALUE: 1227 case GL_SUBPIXEL_BITS: 1228 case GL_MAX_TEXTURE_SIZE: 1229 case GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES: 1230 case GL_SAMPLE_BUFFERS: 1231 case GL_SAMPLES: 1232 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES: 1233 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES: 1234 case GL_TEXTURE_BINDING_2D: 1235 case GL_TEXTURE_BINDING_CUBE_MAP_OES: 1236 case GL_TEXTURE_BINDING_EXTERNAL_OES: 1237 return 1; 1238 case GL_MAX_VIEWPORT_DIMS: 1239 return 2; 1240 case GL_VIEWPORT: 1241 case GL_SCISSOR_BOX: 1242 return 4; 1243 case GL_SAMPLE_COVERAGE_INVERT: 1244 case GL_DEPTH_WRITEMASK: 1245 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled, 1246 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries. 1247 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural 1248 case GL_SAMPLE_COVERAGE: 1249 case GL_SCISSOR_TEST: 1250 case GL_STENCIL_TEST: 1251 case GL_DEPTH_TEST: 1252 case GL_BLEND: 1253 case GL_DITHER: 1254 return 1; 1255 case GL_COLOR_WRITEMASK: 1256 return 4; 1257 case GL_POLYGON_OFFSET_FACTOR: 1258 case GL_POLYGON_OFFSET_UNITS: 1259 case GL_SAMPLE_COVERAGE_VALUE: 1260 case GL_DEPTH_CLEAR_VALUE: 1261 case GL_LINE_WIDTH: 1262 return 1; 1263 case GL_ALIASED_LINE_WIDTH_RANGE: 1264 case GL_ALIASED_POINT_SIZE_RANGE: 1265 case GL_DEPTH_RANGE: 1266 return 2; 1267 case GL_COLOR_CLEAR_VALUE: 1268 return 4; 1269 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: 1270 case GL_MAX_LIGHTS: 1271 case GL_MAX_MODELVIEW_STACK_DEPTH: 1272 case GL_MAX_PROJECTION_STACK_DEPTH: 1273 case GL_MAX_TEXTURE_STACK_DEPTH: 1274 case GL_MAX_TEXTURE_UNITS: 1275 return 1; 1276 default: 1277 UNREACHABLE(); 1278 } 1279 1280 return -1; 1281} 1282 1283bool Context::isQueryParameterInt(GLenum pname) 1284{ 1285 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation 1286 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due 1287 // to the fact that it is stored internally as a float, and so would require conversion 1288 // if returned from Context::getIntegerv. Since this conversion is already implemented 1289 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we 1290 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling 1291 // application. 1292 switch(pname) 1293 { 1294 case GL_COMPRESSED_TEXTURE_FORMATS: 1295 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: 1296 case GL_ARRAY_BUFFER_BINDING: 1297 case GL_FRAMEBUFFER_BINDING_OES: 1298 case GL_RENDERBUFFER_BINDING_OES: 1299 case GL_PACK_ALIGNMENT: 1300 case GL_UNPACK_ALIGNMENT: 1301 case GL_GENERATE_MIPMAP_HINT: 1302 case GL_RED_BITS: 1303 case GL_GREEN_BITS: 1304 case GL_BLUE_BITS: 1305 case GL_ALPHA_BITS: 1306 case GL_DEPTH_BITS: 1307 case GL_STENCIL_BITS: 1308 case GL_ELEMENT_ARRAY_BUFFER_BINDING: 1309 case GL_CULL_FACE_MODE: 1310 case GL_FRONT_FACE: 1311 case GL_ACTIVE_TEXTURE: 1312 case GL_STENCIL_FUNC: 1313 case GL_STENCIL_VALUE_MASK: 1314 case GL_STENCIL_REF: 1315 case GL_STENCIL_FAIL: 1316 case GL_STENCIL_PASS_DEPTH_FAIL: 1317 case GL_STENCIL_PASS_DEPTH_PASS: 1318 case GL_DEPTH_FUNC: 1319 case GL_BLEND_SRC_RGB_OES: 1320 case GL_BLEND_SRC_ALPHA_OES: 1321 case GL_BLEND_DST_RGB_OES: 1322 case GL_BLEND_DST_ALPHA_OES: 1323 case GL_BLEND_EQUATION_RGB_OES: 1324 case GL_BLEND_EQUATION_ALPHA_OES: 1325 case GL_STENCIL_WRITEMASK: 1326 case GL_STENCIL_CLEAR_VALUE: 1327 case GL_SUBPIXEL_BITS: 1328 case GL_MAX_TEXTURE_SIZE: 1329 case GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES: 1330 case GL_SAMPLE_BUFFERS: 1331 case GL_SAMPLES: 1332 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES: 1333 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES: 1334 case GL_TEXTURE_BINDING_2D: 1335 case GL_TEXTURE_BINDING_CUBE_MAP_OES: 1336 case GL_TEXTURE_BINDING_EXTERNAL_OES: 1337 case GL_MAX_VIEWPORT_DIMS: 1338 case GL_VIEWPORT: 1339 case GL_SCISSOR_BOX: 1340 case GL_MAX_LIGHTS: 1341 case GL_MAX_MODELVIEW_STACK_DEPTH: 1342 case GL_MAX_PROJECTION_STACK_DEPTH: 1343 case GL_MAX_TEXTURE_STACK_DEPTH: 1344 case GL_MAX_TEXTURE_UNITS: 1345 return true; 1346 default: 1347 ASSERT(isQueryParameterFloat(pname) || isQueryParameterBool(pname)); 1348 } 1349 1350 return false; 1351} 1352 1353bool Context::isQueryParameterFloat(GLenum pname) 1354{ 1355 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation 1356 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due 1357 // to the fact that it is stored internally as a float, and so would require conversion 1358 // if returned from Context::getIntegerv. Since this conversion is already implemented 1359 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we 1360 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling 1361 // application. 1362 switch(pname) 1363 { 1364 case GL_POLYGON_OFFSET_FACTOR: 1365 case GL_POLYGON_OFFSET_UNITS: 1366 case GL_SAMPLE_COVERAGE_VALUE: 1367 case GL_DEPTH_CLEAR_VALUE: 1368 case GL_LINE_WIDTH: 1369 case GL_ALIASED_LINE_WIDTH_RANGE: 1370 case GL_ALIASED_POINT_SIZE_RANGE: 1371 case GL_DEPTH_RANGE: 1372 case GL_COLOR_CLEAR_VALUE: 1373 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: 1374 return true; 1375 default: 1376 ASSERT(isQueryParameterInt(pname) || isQueryParameterBool(pname)); 1377 } 1378 1379 return false; 1380} 1381 1382bool Context::isQueryParameterBool(GLenum pname) 1383{ 1384 switch(pname) 1385 { 1386 case GL_SAMPLE_COVERAGE_INVERT: 1387 case GL_DEPTH_WRITEMASK: 1388 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled, 1389 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries. 1390 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural 1391 case GL_SAMPLE_COVERAGE: 1392 case GL_SCISSOR_TEST: 1393 case GL_STENCIL_TEST: 1394 case GL_DEPTH_TEST: 1395 case GL_BLEND: 1396 case GL_DITHER: 1397 case GL_COLOR_WRITEMASK: 1398 return true; 1399 default: 1400 ASSERT(isQueryParameterInt(pname) || isQueryParameterFloat(pname)); 1401 } 1402 1403 return false; 1404} 1405 1406// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle 1407bool Context::applyRenderTarget() 1408{ 1409 Framebuffer *framebuffer = getFramebuffer(); 1410 int width, height, samples; 1411 1412 if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE_OES) 1413 { 1414 return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES, false); 1415 } 1416 1417 egl::Image *renderTarget = framebuffer->getRenderTarget(); 1418 device->setRenderTarget(renderTarget); 1419 if(renderTarget) renderTarget->release(); 1420 1421 egl::Image *depthStencil = framebuffer->getDepthStencil(); 1422 device->setDepthStencilSurface(depthStencil); 1423 if(depthStencil) depthStencil->release(); 1424 1425 Viewport viewport; 1426 float zNear = clamp01(mState.zNear); 1427 float zFar = clamp01(mState.zFar); 1428 1429 viewport.x0 = mState.viewportX; 1430 viewport.y0 = mState.viewportY; 1431 viewport.width = mState.viewportWidth; 1432 viewport.height = mState.viewportHeight; 1433 viewport.minZ = zNear; 1434 viewport.maxZ = zFar; 1435 1436 device->setViewport(viewport); 1437 1438 if(mState.scissorTest) 1439 { 1440 sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight}; 1441 scissor.clip(0, 0, width, height); 1442 1443 device->setScissorRect(scissor); 1444 device->setScissorEnable(true); 1445 } 1446 else 1447 { 1448 device->setScissorEnable(false); 1449 } 1450 1451 return true; 1452} 1453 1454// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) 1455void Context::applyState(GLenum drawMode) 1456{ 1457 Framebuffer *framebuffer = getFramebuffer(); 1458 1459 if(mState.cullFace) 1460 { 1461 device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace)); 1462 } 1463 else 1464 { 1465 device->setCullMode(sw::CULL_NONE); 1466 } 1467 1468 if(mDepthStateDirty) 1469 { 1470 if(mState.depthTest) 1471 { 1472 device->setDepthBufferEnable(true); 1473 device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc)); 1474 } 1475 else 1476 { 1477 device->setDepthBufferEnable(false); 1478 } 1479 1480 mDepthStateDirty = false; 1481 } 1482 1483 if(mBlendStateDirty) 1484 { 1485 if(mState.blend) 1486 { 1487 device->setAlphaBlendEnable(true); 1488 device->setSeparateAlphaBlendEnable(true); 1489 1490 device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB)); 1491 device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB)); 1492 device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB)); 1493 1494 device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha)); 1495 device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha)); 1496 device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha)); 1497 } 1498 else 1499 { 1500 device->setAlphaBlendEnable(false); 1501 } 1502 1503 mBlendStateDirty = false; 1504 } 1505 1506 if(mStencilStateDirty || mFrontFaceDirty) 1507 { 1508 if(mState.stencilTest && framebuffer->hasStencil()) 1509 { 1510 device->setStencilEnable(true); 1511 device->setTwoSidedStencil(true); 1512 1513 // get the maximum size of the stencil ref 1514 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer(); 1515 GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1; 1516 1517 device->setStencilWriteMask(mState.stencilWritemask); 1518 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc)); 1519 1520 device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil); 1521 device->setStencilMask(mState.stencilMask); 1522 1523 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail)); 1524 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail)); 1525 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass)); 1526 1527 device->setStencilWriteMaskCCW(mState.stencilWritemask); 1528 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc)); 1529 1530 device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil); 1531 device->setStencilMaskCCW(mState.stencilMask); 1532 1533 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail)); 1534 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail)); 1535 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass)); 1536 } 1537 else 1538 { 1539 device->setStencilEnable(false); 1540 } 1541 1542 mStencilStateDirty = false; 1543 mFrontFaceDirty = false; 1544 } 1545 1546 if(mMaskStateDirty) 1547 { 1548 device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha)); 1549 device->setDepthWriteEnable(mState.depthMask); 1550 1551 mMaskStateDirty = false; 1552 } 1553 1554 if(mPolygonOffsetStateDirty) 1555 { 1556 if(mState.polygonOffsetFill) 1557 { 1558 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer(); 1559 if(depthbuffer) 1560 { 1561 device->setSlopeDepthBias(mState.polygonOffsetFactor); 1562 float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize())); 1563 device->setDepthBias(depthBias); 1564 } 1565 } 1566 else 1567 { 1568 device->setSlopeDepthBias(0); 1569 device->setDepthBias(0); 1570 } 1571 1572 mPolygonOffsetStateDirty = false; 1573 } 1574 1575 if(mSampleStateDirty) 1576 { 1577 if(mState.sampleAlphaToCoverage) 1578 { 1579 device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE); 1580 } 1581 else 1582 { 1583 device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE); 1584 } 1585 1586 if(mState.sampleCoverage) 1587 { 1588 unsigned int mask = 0; 1589 if(mState.sampleCoverageValue != 0) 1590 { 1591 int width, height, samples; 1592 framebuffer->completeness(width, height, samples); 1593 1594 float threshold = 0.5f; 1595 1596 for(int i = 0; i < samples; i++) 1597 { 1598 mask <<= 1; 1599 1600 if((i + 1) * mState.sampleCoverageValue >= threshold) 1601 { 1602 threshold += 1.0f; 1603 mask |= 1; 1604 } 1605 } 1606 } 1607 1608 if(mState.sampleCoverageInvert) 1609 { 1610 mask = ~mask; 1611 } 1612 1613 device->setMultiSampleMask(mask); 1614 } 1615 else 1616 { 1617 device->setMultiSampleMask(0xFFFFFFFF); 1618 } 1619 1620 mSampleStateDirty = false; 1621 } 1622 1623 if(mDitherStateDirty) 1624 { 1625 // UNIMPLEMENTED(); // FIXME 1626 1627 mDitherStateDirty = false; 1628 } 1629 1630 device->setLightingEnable(lighting); 1631 device->setGlobalAmbient(sw::Color<float>(globalAmbient.red, globalAmbient.green, globalAmbient.blue, globalAmbient.alpha)); 1632 1633 for(int i = 0; i < MAX_LIGHTS; i++) 1634 { 1635 device->setLightEnable(i, light[i].enable); 1636 device->setLightAmbient(i, sw::Color<float>(light[i].ambient.red, light[i].ambient.green, light[i].ambient.blue, light[i].ambient.alpha)); 1637 device->setLightDiffuse(i, sw::Color<float>(light[i].diffuse.red, light[i].diffuse.green, light[i].diffuse.blue, light[i].diffuse.alpha)); 1638 device->setLightSpecular(i, sw::Color<float>(light[i].specular.red, light[i].specular.green, light[i].specular.blue, light[i].specular.alpha)); 1639 device->setLightAttenuation(i, light[i].attenuation.constant, light[i].attenuation.linear, light[i].attenuation.quadratic); 1640 1641 if(light[i].position.w != 0.0f) 1642 { 1643 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)); 1644 } 1645 else // Hack: set the position far way 1646 { 1647 device->setLightPosition(i, sw::Point(1e10f * light[i].position.x, 1e10f * light[i].position.y, 1e10f * light[i].position.z)); 1648 } 1649 } 1650 1651 device->setMaterialAmbient(sw::Color<float>(materialAmbient.red, materialAmbient.green, materialAmbient.blue, materialAmbient.alpha)); 1652 device->setMaterialDiffuse(sw::Color<float>(materialDiffuse.red, materialDiffuse.green, materialDiffuse.blue, materialDiffuse.alpha)); 1653 device->setMaterialSpecular(sw::Color<float>(materialSpecular.red, materialSpecular.green, materialSpecular.blue, materialSpecular.alpha)); 1654 device->setMaterialEmission(sw::Color<float>(materialEmission.red, materialEmission.green, materialEmission.blue, materialEmission.alpha)); 1655 1656 device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL); 1657 device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL); 1658 device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL); 1659 device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL); 1660 1661 device->setProjectionMatrix(projectionStack.current()); 1662 device->setModelMatrix(modelViewStack.current()); 1663 device->setTextureMatrix(0, textureStack0.current()); 1664 device->setTextureMatrix(1, textureStack1.current()); 1665 device->setTextureTransform(0, textureStack0.isIdentity() ? 0 : 4, false); 1666 device->setTextureTransform(1, textureStack1.isIdentity() ? 0 : 4, false); 1667} 1668 1669GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count) 1670{ 1671 TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS]; 1672 1673 GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes); 1674 if(err != GL_NO_ERROR) 1675 { 1676 return err; 1677 } 1678 1679 device->resetInputStreams(false); 1680 1681 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 1682 { 1683 sw::Resource *resource = attributes[i].vertexBuffer; 1684 const void *buffer = (char*)resource->data() + attributes[i].offset; 1685 1686 int stride = attributes[i].stride; 1687 1688 buffer = (char*)buffer + stride * base; 1689 1690 sw::Stream attribute(resource, buffer, stride); 1691 1692 attribute.type = attributes[i].type; 1693 attribute.count = attributes[i].count; 1694 attribute.normalized = attributes[i].normalized; 1695 1696 device->setInputStream(i, attribute); 1697 } 1698 1699 return GL_NO_ERROR; 1700} 1701 1702// Applies the indices and element array bindings 1703GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) 1704{ 1705 GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer.get(), indices, indexInfo); 1706 1707 if(err == GL_NO_ERROR) 1708 { 1709 device->setIndexBuffer(indexInfo->indexBuffer); 1710 } 1711 1712 return err; 1713} 1714 1715void Context::applyTextures() 1716{ 1717 for(int samplerIndex = 0; samplerIndex < MAX_TEXTURE_UNITS; samplerIndex++) 1718 { 1719 Texture *texture = getSamplerTexture(samplerIndex, TEXTURE_2D); 1720 1721 if(texture2D && texture->isSamplerComplete()) 1722 { 1723 GLenum wrapS = texture->getWrapS(); 1724 GLenum wrapT = texture->getWrapT(); 1725 GLenum texFilter = texture->getMinFilter(); 1726 GLenum magFilter = texture->getMagFilter(); 1727 GLfloat maxAnisotropy = texture->getMaxAnisotropy(); 1728 1729 device->setAddressingModeU(sw::SAMPLER_PIXEL, samplerIndex, es2sw::ConvertTextureWrap(wrapS)); 1730 device->setAddressingModeV(sw::SAMPLER_PIXEL, samplerIndex, es2sw::ConvertTextureWrap(wrapT)); 1731 1732 sw::FilterType minFilter; 1733 sw::MipmapType mipFilter; 1734 es2sw::ConvertMinFilter(texFilter, &minFilter, &mipFilter, maxAnisotropy); 1735 // ASSERT(minFilter == es2sw::ConvertMagFilter(magFilter)); 1736 1737 device->setTextureFilter(sw::SAMPLER_PIXEL, samplerIndex, minFilter); 1738 // device->setTextureFilter(sw::SAMPLER_PIXEL, samplerIndex, es2sw::ConvertMagFilter(magFilter)); 1739 device->setMipmapFilter(sw::SAMPLER_PIXEL, samplerIndex, mipFilter); 1740 device->setMaxAnisotropy(sw::SAMPLER_PIXEL, samplerIndex, maxAnisotropy); 1741 1742 applyTexture(samplerIndex, texture); 1743 1744 device->setStageOperation(samplerIndex, sw::TextureStage::STAGE_MODULATE); 1745 device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_TEXTURE); 1746 device->setSecondArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT); 1747 1748 device->setStageOperationAlpha(samplerIndex, sw::TextureStage::STAGE_MODULATE); 1749 device->setFirstArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_TEXTURE); 1750 device->setSecondArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT); 1751 } 1752 else 1753 { 1754 applyTexture(samplerIndex, 0); 1755 1756 device->setStageOperation(samplerIndex, sw::TextureStage::STAGE_SELECTARG1); 1757 device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT); 1758 device->setSecondArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT); 1759 1760 device->setStageOperationAlpha(samplerIndex, sw::TextureStage::STAGE_SELECTARG1); 1761 device->setFirstArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT); 1762 device->setSecondArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT); 1763 } 1764 } 1765} 1766 1767void Context::applyTexture(int index, Texture *baseTexture) 1768{ 1769 sw::Resource *resource = 0; 1770 1771 if(baseTexture) 1772 { 1773 resource = baseTexture->getResource(); 1774 } 1775 1776 device->setTextureResource(index, resource); 1777 1778 if(baseTexture) 1779 { 1780 int levelCount = baseTexture->getLevelCount(); 1781 1782 if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES) 1783 { 1784 Texture2D *texture = static_cast<Texture2D*>(baseTexture); 1785 1786 for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++) 1787 { 1788 int surfaceLevel = mipmapLevel; 1789 1790 if(surfaceLevel < 0) 1791 { 1792 surfaceLevel = 0; 1793 } 1794 else if(surfaceLevel >= levelCount) 1795 { 1796 surfaceLevel = levelCount - 1; 1797 } 1798 1799 egl::Image *surface = texture->getImage(surfaceLevel); 1800 device->setTextureLevel(index, 0, mipmapLevel, surface, sw::TEXTURE_2D); 1801 } 1802 } 1803 else UNIMPLEMENTED(); 1804 } 1805 else 1806 { 1807 device->setTextureLevel(index, 0, 0, 0, sw::TEXTURE_NULL); 1808 } 1809} 1810 1811void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, 1812 GLenum format, GLenum type, GLsizei *bufSize, void* pixels) 1813{ 1814 Framebuffer *framebuffer = getFramebuffer(); 1815 int framebufferWidth, framebufferHeight, framebufferSamples; 1816 1817 if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE_OES) 1818 { 1819 return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES); 1820 } 1821 1822 if(getFramebufferHandle() != 0 && framebufferSamples != 0) 1823 { 1824 return error(GL_INVALID_OPERATION); 1825 } 1826 1827 if(format != GL_RGBA || type != GL_UNSIGNED_BYTE) 1828 { 1829 if(format != framebuffer->getImplementationColorReadFormat() || type != framebuffer->getImplementationColorReadType()) 1830 { 1831 return error(GL_INVALID_OPERATION); 1832 } 1833 } 1834 1835 GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment); 1836 1837 // Sized query sanity check 1838 if(bufSize) 1839 { 1840 int requiredSize = outputPitch * height; 1841 if(requiredSize > *bufSize) 1842 { 1843 return error(GL_INVALID_OPERATION); 1844 } 1845 } 1846 1847 egl::Image *renderTarget = framebuffer->getRenderTarget(); 1848 1849 if(!renderTarget) 1850 { 1851 return error(GL_OUT_OF_MEMORY); 1852 } 1853 1854 sw::Rect rect = {x, y, x + width, y + height}; 1855 rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight()); 1856 1857 unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY); 1858 unsigned char *dest = (unsigned char*)pixels; 1859 int inputPitch = (int)renderTarget->getPitch(); 1860 1861 for(int j = 0; j < rect.y1 - rect.y0; j++) 1862 { 1863 unsigned short *dest16 = (unsigned short*)dest; 1864 unsigned int *dest32 = (unsigned int*)dest; 1865 1866 if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 && 1867 format == GL_RGBA && type == GL_UNSIGNED_BYTE) 1868 { 1869 for(int i = 0; i < rect.x1 - rect.x0; i++) 1870 { 1871 unsigned int argb = *(unsigned int*)(source + 4 * i); 1872 1873 dest32[i] = (argb & 0xFF00FF00) | ((argb & 0x000000FF) << 16) | ((argb & 0x00FF0000) >> 16); 1874 } 1875 } 1876 else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 && 1877 format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) 1878 { 1879 memcpy(dest, source, (rect.x1 - rect.x0) * 4); 1880 } 1881 else 1882 { 1883 for(int i = 0; i < rect.x1 - rect.x0; i++) 1884 { 1885 float r; 1886 float g; 1887 float b; 1888 float a; 1889 1890 switch(renderTarget->getInternalFormat()) 1891 { 1892 case sw::FORMAT_R5G6B5: 1893 { 1894 unsigned short rgb = *(unsigned short*)(source + 2 * i); 1895 1896 a = 1.0f; 1897 b = (rgb & 0x001F) * (1.0f / 0x001F); 1898 g = (rgb & 0x07E0) * (1.0f / 0x07E0); 1899 r = (rgb & 0xF800) * (1.0f / 0xF800); 1900 } 1901 break; 1902 case sw::FORMAT_A1R5G5B5: 1903 { 1904 unsigned short argb = *(unsigned short*)(source + 2 * i); 1905 1906 a = (argb & 0x8000) ? 1.0f : 0.0f; 1907 b = (argb & 0x001F) * (1.0f / 0x001F); 1908 g = (argb & 0x03E0) * (1.0f / 0x03E0); 1909 r = (argb & 0x7C00) * (1.0f / 0x7C00); 1910 } 1911 break; 1912 case sw::FORMAT_A8R8G8B8: 1913 { 1914 unsigned int argb = *(unsigned int*)(source + 4 * i); 1915 1916 a = (argb & 0xFF000000) * (1.0f / 0xFF000000); 1917 b = (argb & 0x000000FF) * (1.0f / 0x000000FF); 1918 g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00); 1919 r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000); 1920 } 1921 break; 1922 case sw::FORMAT_X8R8G8B8: 1923 { 1924 unsigned int xrgb = *(unsigned int*)(source + 4 * i); 1925 1926 a = 1.0f; 1927 b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF); 1928 g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00); 1929 r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000); 1930 } 1931 break; 1932 case sw::FORMAT_A2R10G10B10: 1933 { 1934 unsigned int argb = *(unsigned int*)(source + 4 * i); 1935 1936 a = (argb & 0xC0000000) * (1.0f / 0xC0000000); 1937 b = (argb & 0x000003FF) * (1.0f / 0x000003FF); 1938 g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00); 1939 r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000); 1940 } 1941 break; 1942 case sw::FORMAT_A32B32G32R32F: 1943 { 1944 r = *((float*)(source + 16 * i) + 0); 1945 g = *((float*)(source + 16 * i) + 1); 1946 b = *((float*)(source + 16 * i) + 2); 1947 a = *((float*)(source + 16 * i) + 3); 1948 } 1949 break; 1950 case sw::FORMAT_A16B16G16R16F: 1951 { 1952 r = (float)*((sw::half*)(source + 8 * i) + 0); 1953 g = (float)*((sw::half*)(source + 8 * i) + 1); 1954 b = (float)*((sw::half*)(source + 8 * i) + 2); 1955 a = (float)*((sw::half*)(source + 8 * i) + 3); 1956 } 1957 break; 1958 default: 1959 UNIMPLEMENTED(); // FIXME 1960 UNREACHABLE(); 1961 } 1962 1963 switch(format) 1964 { 1965 case GL_RGBA: 1966 switch(type) 1967 { 1968 case GL_UNSIGNED_BYTE: 1969 dest[4 * i + 0] = (unsigned char)(255 * r + 0.5f); 1970 dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f); 1971 dest[4 * i + 2] = (unsigned char)(255 * b + 0.5f); 1972 dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f); 1973 break; 1974 default: UNREACHABLE(); 1975 } 1976 break; 1977 case GL_BGRA_EXT: 1978 switch(type) 1979 { 1980 case GL_UNSIGNED_BYTE: 1981 dest[4 * i + 0] = (unsigned char)(255 * b + 0.5f); 1982 dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f); 1983 dest[4 * i + 2] = (unsigned char)(255 * r + 0.5f); 1984 dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f); 1985 break; 1986 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: 1987 // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section 1988 // this type is packed as follows: 1989 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 1990 // -------------------------------------------------------------------------------- 1991 // | 4th | 3rd | 2nd | 1st component | 1992 // -------------------------------------------------------------------------------- 1993 // in the case of BGRA_EXT, B is the first component, G the second, and so forth. 1994 dest16[i] = 1995 ((unsigned short)(15 * a + 0.5f) << 12)| 1996 ((unsigned short)(15 * r + 0.5f) << 8) | 1997 ((unsigned short)(15 * g + 0.5f) << 4) | 1998 ((unsigned short)(15 * b + 0.5f) << 0); 1999 break; 2000 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: 2001 // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section 2002 // this type is packed as follows: 2003 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 2004 // -------------------------------------------------------------------------------- 2005 // | 4th | 3rd | 2nd | 1st component | 2006 // -------------------------------------------------------------------------------- 2007 // in the case of BGRA_EXT, B is the first component, G the second, and so forth. 2008 dest16[i] = 2009 ((unsigned short)( a + 0.5f) << 15) | 2010 ((unsigned short)(31 * r + 0.5f) << 10) | 2011 ((unsigned short)(31 * g + 0.5f) << 5) | 2012 ((unsigned short)(31 * b + 0.5f) << 0); 2013 break; 2014 default: UNREACHABLE(); 2015 } 2016 break; 2017 case GL_RGB: 2018 switch(type) 2019 { 2020 case GL_UNSIGNED_SHORT_5_6_5: 2021 dest16[i] = 2022 ((unsigned short)(31 * b + 0.5f) << 0) | 2023 ((unsigned short)(63 * g + 0.5f) << 5) | 2024 ((unsigned short)(31 * r + 0.5f) << 11); 2025 break; 2026 default: UNREACHABLE(); 2027 } 2028 break; 2029 default: UNREACHABLE(); 2030 } 2031 } 2032 } 2033 2034 source += inputPitch; 2035 dest += outputPitch; 2036 } 2037 2038 renderTarget->unlock(); 2039 renderTarget->release(); 2040} 2041 2042void Context::clear(GLbitfield mask) 2043{ 2044 Framebuffer *framebuffer = getFramebuffer(); 2045 2046 if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES) 2047 { 2048 return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES); 2049 } 2050 2051 if(!applyRenderTarget()) 2052 { 2053 return; 2054 } 2055 2056 unsigned int color = (unorm<8>(mState.colorClearValue.alpha) << 24) | 2057 (unorm<8>(mState.colorClearValue.red) << 16) | 2058 (unorm<8>(mState.colorClearValue.green) << 8) | 2059 (unorm<8>(mState.colorClearValue.blue) << 0); 2060 float depth = clamp01(mState.depthClearValue); 2061 int stencil = mState.stencilClearValue & 0x000000FF; 2062 2063 if(mask & GL_COLOR_BUFFER_BIT) 2064 { 2065 unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) | 2066 (mState.colorMaskGreen ? 0x2 : 0) | 2067 (mState.colorMaskBlue ? 0x4 : 0) | 2068 (mState.colorMaskAlpha ? 0x8 : 0); 2069 2070 if(rgbaMask != 0) 2071 { 2072 device->clearColor(color, rgbaMask); 2073 } 2074 } 2075 2076 if(mask & GL_DEPTH_BUFFER_BIT) 2077 { 2078 if(mState.depthMask != 0) 2079 { 2080 device->clearDepth(depth); 2081 } 2082 } 2083 2084 if(mask & GL_STENCIL_BUFFER_BIT) 2085 { 2086 if(mState.stencilWritemask != 0) 2087 { 2088 device->clearStencil(stencil, mState.stencilWritemask); 2089 } 2090 } 2091} 2092 2093void Context::drawArrays(GLenum mode, GLint first, GLsizei count) 2094{ 2095 PrimitiveType primitiveType; 2096 int primitiveCount; 2097 2098 if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount)) 2099 return error(GL_INVALID_ENUM); 2100 2101 if(primitiveCount <= 0) 2102 { 2103 return; 2104 } 2105 2106 if(!applyRenderTarget()) 2107 { 2108 return; 2109 } 2110 2111 applyState(mode); 2112 2113 GLenum err = applyVertexBuffer(0, first, count); 2114 if(err != GL_NO_ERROR) 2115 { 2116 return error(err); 2117 } 2118 2119 applyTextures(); 2120 2121 if(!cullSkipsDraw(mode)) 2122 { 2123 device->drawPrimitive(primitiveType, primitiveCount); 2124 } 2125} 2126 2127void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) 2128{ 2129 if(!indices && !mState.elementArrayBuffer) 2130 { 2131 return error(GL_INVALID_OPERATION); 2132 } 2133 2134 PrimitiveType primitiveType; 2135 int primitiveCount; 2136 2137 if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount)) 2138 return error(GL_INVALID_ENUM); 2139 2140 if(primitiveCount <= 0) 2141 { 2142 return; 2143 } 2144 2145 if(!applyRenderTarget()) 2146 { 2147 return; 2148 } 2149 2150 applyState(mode); 2151 2152 TranslatedIndexData indexInfo; 2153 GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo); 2154 if(err != GL_NO_ERROR) 2155 { 2156 return error(err); 2157 } 2158 2159 GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1; 2160 err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount); 2161 if(err != GL_NO_ERROR) 2162 { 2163 return error(err); 2164 } 2165 2166 applyTextures(); 2167 2168 if(!cullSkipsDraw(mode)) 2169 { 2170 device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount, IndexDataManager::typeSize(type)); 2171 } 2172} 2173 2174void Context::finish() 2175{ 2176 device->finish(); 2177} 2178 2179void Context::flush() 2180{ 2181 // We don't queue anything without processing it as fast as possible 2182} 2183 2184void Context::recordInvalidEnum() 2185{ 2186 mInvalidEnum = true; 2187} 2188 2189void Context::recordInvalidValue() 2190{ 2191 mInvalidValue = true; 2192} 2193 2194void Context::recordInvalidOperation() 2195{ 2196 mInvalidOperation = true; 2197} 2198 2199void Context::recordOutOfMemory() 2200{ 2201 mOutOfMemory = true; 2202} 2203 2204void Context::recordInvalidFramebufferOperation() 2205{ 2206 mInvalidFramebufferOperation = true; 2207} 2208 2209// Get one of the recorded errors and clear its flag, if any. 2210// [OpenGL ES 2.0.24] section 2.5 page 13. 2211GLenum Context::getError() 2212{ 2213 if(mInvalidEnum) 2214 { 2215 mInvalidEnum = false; 2216 2217 return GL_INVALID_ENUM; 2218 } 2219 2220 if(mInvalidValue) 2221 { 2222 mInvalidValue = false; 2223 2224 return GL_INVALID_VALUE; 2225 } 2226 2227 if(mInvalidOperation) 2228 { 2229 mInvalidOperation = false; 2230 2231 return GL_INVALID_OPERATION; 2232 } 2233 2234 if(mOutOfMemory) 2235 { 2236 mOutOfMemory = false; 2237 2238 return GL_OUT_OF_MEMORY; 2239 } 2240 2241 if(mInvalidFramebufferOperation) 2242 { 2243 mInvalidFramebufferOperation = false; 2244 2245 return GL_INVALID_FRAMEBUFFER_OPERATION_OES; 2246 } 2247 2248 return GL_NO_ERROR; 2249} 2250 2251int Context::getSupportedMultiSampleDepth(sw::Format format, int requested) 2252{ 2253 if(requested <= 1) 2254 { 2255 return 1; 2256 } 2257 2258 if(requested == 2) 2259 { 2260 return 2; 2261 } 2262 2263 return 4; 2264} 2265 2266void Context::detachBuffer(GLuint buffer) 2267{ 2268 // [OpenGL ES 2.0.24] section 2.9 page 22: 2269 // If a buffer object is deleted while it is bound, all bindings to that object in the current context 2270 // (i.e. in the thread that called Delete-Buffers) are reset to zero. 2271 2272 if(mState.arrayBuffer.id() == buffer) 2273 { 2274 mState.arrayBuffer.set(NULL); 2275 } 2276 2277 if(mState.elementArrayBuffer.id() == buffer) 2278 { 2279 mState.elementArrayBuffer.set(NULL); 2280 } 2281 2282 for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++) 2283 { 2284 if(mState.vertexAttribute[attribute].mBoundBuffer.id() == buffer) 2285 { 2286 mState.vertexAttribute[attribute].mBoundBuffer.set(NULL); 2287 } 2288 } 2289} 2290 2291void Context::detachTexture(GLuint texture) 2292{ 2293 // [OpenGL ES 2.0.24] section 3.8 page 84: 2294 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are 2295 // rebound to texture object zero 2296 2297 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++) 2298 { 2299 for(int sampler = 0; sampler < MAX_TEXTURE_UNITS; sampler++) 2300 { 2301 if(mState.samplerTexture[type][sampler].id() == texture) 2302 { 2303 mState.samplerTexture[type][sampler].set(NULL); 2304 } 2305 } 2306 } 2307 2308 // [OpenGL ES 2.0.24] section 4.4 page 112: 2309 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is 2310 // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this 2311 // image was attached in the currently bound framebuffer. 2312 2313 Framebuffer *framebuffer = getFramebuffer(); 2314 2315 if(framebuffer) 2316 { 2317 framebuffer->detachTexture(texture); 2318 } 2319} 2320 2321void Context::detachFramebuffer(GLuint framebuffer) 2322{ 2323 // [OpenGL ES 2.0.24] section 4.4 page 107: 2324 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though 2325 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero. 2326 2327 if(mState.framebuffer == framebuffer) 2328 { 2329 bindFramebuffer(0); 2330 } 2331} 2332 2333void Context::detachRenderbuffer(GLuint renderbuffer) 2334{ 2335 // [OpenGL ES 2.0.24] section 4.4 page 109: 2336 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer 2337 // had been executed with the target RENDERBUFFER and name of zero. 2338 2339 if(mState.renderbuffer.id() == renderbuffer) 2340 { 2341 bindRenderbuffer(0); 2342 } 2343 2344 // [OpenGL ES 2.0.24] section 4.4 page 111: 2345 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer, 2346 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment 2347 // point to which this image was attached in the currently bound framebuffer. 2348 2349 Framebuffer *framebuffer = getFramebuffer(); 2350 2351 if(framebuffer) 2352 { 2353 framebuffer->detachRenderbuffer(renderbuffer); 2354 } 2355} 2356 2357bool Context::cullSkipsDraw(GLenum drawMode) 2358{ 2359 return mState.cullFace && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode); 2360} 2361 2362bool Context::isTriangleMode(GLenum drawMode) 2363{ 2364 switch (drawMode) 2365 { 2366 case GL_TRIANGLES: 2367 case GL_TRIANGLE_FAN: 2368 case GL_TRIANGLE_STRIP: 2369 return true; 2370 case GL_POINTS: 2371 case GL_LINES: 2372 case GL_LINE_LOOP: 2373 case GL_LINE_STRIP: 2374 return false; 2375 default: UNREACHABLE(); 2376 } 2377 2378 return false; 2379} 2380 2381void Context::setVertexAttrib(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) 2382{ 2383 ASSERT(index < MAX_VERTEX_ATTRIBS); 2384 2385 mState.vertexAttribute[index].mCurrentValue[0] = x; 2386 mState.vertexAttribute[index].mCurrentValue[1] = y; 2387 mState.vertexAttribute[index].mCurrentValue[2] = z; 2388 mState.vertexAttribute[index].mCurrentValue[3] = w; 2389 2390 mVertexDataManager->dirtyCurrentValue(index); 2391} 2392 2393void Context::bindTexImage(egl::Surface *surface) 2394{ 2395 es1::Texture2D *textureObject = getTexture2D(); 2396 2397 if(textureObject) 2398 { 2399 textureObject->bindTexImage(surface); 2400 } 2401} 2402 2403EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel) 2404{ 2405 switch(target) 2406 { 2407 case EGL_GL_TEXTURE_2D_KHR: 2408 break; 2409 case EGL_GL_RENDERBUFFER_KHR: 2410 break; 2411 default: 2412 return EGL_BAD_PARAMETER; 2413 } 2414 2415 if(textureLevel >= IMPLEMENTATION_MAX_TEXTURE_LEVELS) 2416 { 2417 return EGL_BAD_MATCH; 2418 } 2419 2420 if(target == EGL_GL_TEXTURE_2D_KHR) 2421 { 2422 Texture *texture = getTexture(name); 2423 2424 if(!texture || texture->getTarget() != GL_TEXTURE_2D) 2425 { 2426 return EGL_BAD_PARAMETER; 2427 } 2428 2429 if(texture->isShared(GL_TEXTURE_2D, textureLevel)) // Bound to an EGLSurface or already an EGLImage sibling 2430 { 2431 return EGL_BAD_ACCESS; 2432 } 2433 2434 if(textureLevel != 0 && !texture->isSamplerComplete()) 2435 { 2436 return EGL_BAD_PARAMETER; 2437 } 2438 2439 if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1)) 2440 { 2441 return EGL_BAD_PARAMETER; 2442 } 2443 } 2444 else if(target == EGL_GL_RENDERBUFFER_KHR) 2445 { 2446 Renderbuffer *renderbuffer = getRenderbuffer(name); 2447 2448 if(!renderbuffer) 2449 { 2450 return EGL_BAD_PARAMETER; 2451 } 2452 2453 if(renderbuffer->isShared()) // Already an EGLImage sibling 2454 { 2455 return EGL_BAD_ACCESS; 2456 } 2457 } 2458 else UNREACHABLE(); 2459 2460 return EGL_SUCCESS; 2461} 2462 2463egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel) 2464{ 2465 if(target == EGL_GL_TEXTURE_2D_KHR) 2466 { 2467 es1::Texture *texture = getTexture(name); 2468 2469 return texture->createSharedImage(GL_TEXTURE_2D, textureLevel); 2470 } 2471 else if(target == EGL_GL_RENDERBUFFER_KHR) 2472 { 2473 es1::Renderbuffer *renderbuffer = getRenderbuffer(name); 2474 2475 return renderbuffer->createSharedImage(); 2476 } 2477 else UNREACHABLE(); 2478 2479 return 0; 2480} 2481 2482Device *Context::getDevice() 2483{ 2484 return device; 2485} 2486 2487void Context::setMatrixMode(GLenum mode) 2488{ 2489 matrixMode = mode; 2490} 2491 2492sw::MatrixStack &Context::currentMatrixStack() 2493{ 2494 switch(matrixMode) 2495 { 2496 case GL_MODELVIEW: 2497 return modelViewStack; 2498 case GL_PROJECTION: 2499 return projectionStack; 2500 case GL_TEXTURE: 2501 switch(mState.activeSampler) 2502 { 2503 case 0: return textureStack0; 2504 case 1: return textureStack1; 2505 } 2506 break; 2507 } 2508 2509 UNREACHABLE(); 2510 return textureStack0; 2511} 2512 2513void Context::loadIdentity() 2514{ 2515 currentMatrixStack().identity(); 2516} 2517 2518void Context::load(const GLfloat *m) 2519{ 2520 currentMatrixStack().load(m); 2521} 2522 2523void Context::pushMatrix() 2524{ 2525 if(!currentMatrixStack().push()) 2526 { 2527 return error(GL_STACK_OVERFLOW); 2528 } 2529} 2530 2531void Context::popMatrix() 2532{ 2533 if(!currentMatrixStack().pop()) 2534 { 2535 return error(GL_STACK_OVERFLOW); 2536 } 2537} 2538 2539void Context::rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) 2540{ 2541 currentMatrixStack().rotate(angle, x, y, z); 2542} 2543 2544void Context::translate(GLfloat x, GLfloat y, GLfloat z) 2545{ 2546 currentMatrixStack().translate(x, y, z); 2547} 2548 2549void Context::scale(GLfloat x, GLfloat y, GLfloat z) 2550{ 2551 currentMatrixStack().scale(x, y, z); 2552} 2553 2554void Context::multiply(const GLfloat *m) 2555{ 2556 currentMatrixStack().multiply(m); 2557} 2558 2559void Context::ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) 2560{ 2561 currentMatrixStack().ortho(left, right, bottom, top, zNear, zFar); 2562} 2563 2564void Context::clientActiveTexture(GLenum texture) 2565{ 2566 clientTexture = texture; 2567} 2568 2569GLenum Context::getClientActiveTexture() const 2570{ 2571 return clientTexture; 2572} 2573 2574unsigned int Context::getActiveTexture() const 2575{ 2576 return mState.activeSampler; 2577} 2578 2579} 2580 2581// Exported functions for use by EGL 2582extern "C" 2583{ 2584 es1::Context *glCreateContext(const egl::Config *config, const es1::Context *shareContext) 2585 { 2586 return new es1::Context(config, shareContext); 2587 } 2588} 2589