Context.cpp revision dddc4ab703d29db721a18e81e63b23718bb2cc66
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 unsigned short *dest16 = (unsigned short*)pixels; 1860 int inputPitch = (int)renderTarget->getPitch(); 1861 1862 for(int j = 0; j < rect.y1 - rect.y0; j++) 1863 { 1864 if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 && 1865 format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) 1866 { 1867 // Fast path for EXT_read_format_bgra, given an RGBA source buffer 1868 // Note that buffers with no alpha go through the slow path below 1869 memcpy(dest + j * outputPitch, source + j * inputPitch, (rect.x1 - rect.x0) * 4); 1870 } 1871 else 1872 { 1873 for(int i = 0; i < rect.x1 - rect.x0; i++) 1874 { 1875 float r; 1876 float g; 1877 float b; 1878 float a; 1879 1880 switch(renderTarget->getInternalFormat()) 1881 { 1882 case sw::FORMAT_R5G6B5: 1883 { 1884 unsigned short rgb = *(unsigned short*)(source + 2 * i + j * inputPitch); 1885 1886 a = 1.0f; 1887 b = (rgb & 0x001F) * (1.0f / 0x001F); 1888 g = (rgb & 0x07E0) * (1.0f / 0x07E0); 1889 r = (rgb & 0xF800) * (1.0f / 0xF800); 1890 } 1891 break; 1892 case sw::FORMAT_A1R5G5B5: 1893 { 1894 unsigned short argb = *(unsigned short*)(source + 2 * i + j * inputPitch); 1895 1896 a = (argb & 0x8000) ? 1.0f : 0.0f; 1897 b = (argb & 0x001F) * (1.0f / 0x001F); 1898 g = (argb & 0x03E0) * (1.0f / 0x03E0); 1899 r = (argb & 0x7C00) * (1.0f / 0x7C00); 1900 } 1901 break; 1902 case sw::FORMAT_A8R8G8B8: 1903 { 1904 unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); 1905 1906 a = (argb & 0xFF000000) * (1.0f / 0xFF000000); 1907 b = (argb & 0x000000FF) * (1.0f / 0x000000FF); 1908 g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00); 1909 r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000); 1910 } 1911 break; 1912 case sw::FORMAT_X8R8G8B8: 1913 { 1914 unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * inputPitch); 1915 1916 a = 1.0f; 1917 b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF); 1918 g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00); 1919 r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000); 1920 } 1921 break; 1922 case sw::FORMAT_A2R10G10B10: 1923 { 1924 unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); 1925 1926 a = (argb & 0xC0000000) * (1.0f / 0xC0000000); 1927 b = (argb & 0x000003FF) * (1.0f / 0x000003FF); 1928 g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00); 1929 r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000); 1930 } 1931 break; 1932 case sw::FORMAT_A32B32G32R32F: 1933 { 1934 r = *((float*)(source + 16 * i + j * inputPitch) + 0); 1935 g = *((float*)(source + 16 * i + j * inputPitch) + 1); 1936 b = *((float*)(source + 16 * i + j * inputPitch) + 2); 1937 a = *((float*)(source + 16 * i + j * inputPitch) + 3); 1938 } 1939 break; 1940 case sw::FORMAT_A16B16G16R16F: 1941 { 1942 r = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 0); 1943 g = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 1); 1944 b = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 2); 1945 a = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 3); 1946 } 1947 break; 1948 default: 1949 UNIMPLEMENTED(); // FIXME 1950 UNREACHABLE(); 1951 } 1952 1953 switch(format) 1954 { 1955 case GL_RGBA: 1956 switch(type) 1957 { 1958 case GL_UNSIGNED_BYTE: 1959 dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f); 1960 dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f); 1961 dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f); 1962 dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f); 1963 break; 1964 default: UNREACHABLE(); 1965 } 1966 break; 1967 case GL_BGRA_EXT: 1968 switch(type) 1969 { 1970 case GL_UNSIGNED_BYTE: 1971 dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * b + 0.5f); 1972 dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f); 1973 dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * r + 0.5f); 1974 dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f); 1975 break; 1976 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: 1977 // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section 1978 // this type is packed as follows: 1979 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 1980 // -------------------------------------------------------------------------------- 1981 // | 4th | 3rd | 2nd | 1st component | 1982 // -------------------------------------------------------------------------------- 1983 // in the case of BGRA_EXT, B is the first component, G the second, and so forth. 1984 dest16[i + j * outputPitch / sizeof(unsigned short)] = 1985 ((unsigned short)(15 * a + 0.5f) << 12)| 1986 ((unsigned short)(15 * r + 0.5f) << 8) | 1987 ((unsigned short)(15 * g + 0.5f) << 4) | 1988 ((unsigned short)(15 * b + 0.5f) << 0); 1989 break; 1990 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: 1991 // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section 1992 // this type is packed as follows: 1993 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 1994 // -------------------------------------------------------------------------------- 1995 // | 4th | 3rd | 2nd | 1st component | 1996 // -------------------------------------------------------------------------------- 1997 // in the case of BGRA_EXT, B is the first component, G the second, and so forth. 1998 dest16[i + j * outputPitch / sizeof(unsigned short)] = 1999 ((unsigned short)( a + 0.5f) << 15) | 2000 ((unsigned short)(31 * r + 0.5f) << 10) | 2001 ((unsigned short)(31 * g + 0.5f) << 5) | 2002 ((unsigned short)(31 * b + 0.5f) << 0); 2003 break; 2004 default: UNREACHABLE(); 2005 } 2006 break; 2007 case GL_RGB: 2008 switch(type) 2009 { 2010 case GL_UNSIGNED_SHORT_5_6_5: 2011 dest16[i + j * outputPitch / sizeof(unsigned short)] = 2012 ((unsigned short)(31 * b + 0.5f) << 0) | 2013 ((unsigned short)(63 * g + 0.5f) << 5) | 2014 ((unsigned short)(31 * r + 0.5f) << 11); 2015 break; 2016 default: UNREACHABLE(); 2017 } 2018 break; 2019 default: UNREACHABLE(); 2020 } 2021 } 2022 } 2023 } 2024 2025 renderTarget->unlock(); 2026 renderTarget->release(); 2027} 2028 2029void Context::clear(GLbitfield mask) 2030{ 2031 Framebuffer *framebuffer = getFramebuffer(); 2032 2033 if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES) 2034 { 2035 return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES); 2036 } 2037 2038 if(!applyRenderTarget()) 2039 { 2040 return; 2041 } 2042 2043 unsigned int color = (unorm<8>(mState.colorClearValue.alpha) << 24) | 2044 (unorm<8>(mState.colorClearValue.red) << 16) | 2045 (unorm<8>(mState.colorClearValue.green) << 8) | 2046 (unorm<8>(mState.colorClearValue.blue) << 0); 2047 float depth = clamp01(mState.depthClearValue); 2048 int stencil = mState.stencilClearValue & 0x000000FF; 2049 2050 if(mask & GL_COLOR_BUFFER_BIT) 2051 { 2052 unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) | 2053 (mState.colorMaskGreen ? 0x2 : 0) | 2054 (mState.colorMaskBlue ? 0x4 : 0) | 2055 (mState.colorMaskAlpha ? 0x8 : 0); 2056 2057 if(rgbaMask != 0) 2058 { 2059 device->clearColor(color, rgbaMask); 2060 } 2061 } 2062 2063 if(mask & GL_DEPTH_BUFFER_BIT) 2064 { 2065 if(mState.depthMask != 0) 2066 { 2067 device->clearDepth(depth); 2068 } 2069 } 2070 2071 if(mask & GL_STENCIL_BUFFER_BIT) 2072 { 2073 if(mState.stencilWritemask != 0) 2074 { 2075 device->clearStencil(stencil, mState.stencilWritemask); 2076 } 2077 } 2078} 2079 2080void Context::drawArrays(GLenum mode, GLint first, GLsizei count) 2081{ 2082 PrimitiveType primitiveType; 2083 int primitiveCount; 2084 2085 if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount)) 2086 return error(GL_INVALID_ENUM); 2087 2088 if(primitiveCount <= 0) 2089 { 2090 return; 2091 } 2092 2093 if(!applyRenderTarget()) 2094 { 2095 return; 2096 } 2097 2098 applyState(mode); 2099 2100 GLenum err = applyVertexBuffer(0, first, count); 2101 if(err != GL_NO_ERROR) 2102 { 2103 return error(err); 2104 } 2105 2106 applyTextures(); 2107 2108 if(!cullSkipsDraw(mode)) 2109 { 2110 device->drawPrimitive(primitiveType, primitiveCount); 2111 } 2112} 2113 2114void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) 2115{ 2116 if(!indices && !mState.elementArrayBuffer) 2117 { 2118 return error(GL_INVALID_OPERATION); 2119 } 2120 2121 PrimitiveType primitiveType; 2122 int primitiveCount; 2123 2124 if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount)) 2125 return error(GL_INVALID_ENUM); 2126 2127 if(primitiveCount <= 0) 2128 { 2129 return; 2130 } 2131 2132 if(!applyRenderTarget()) 2133 { 2134 return; 2135 } 2136 2137 applyState(mode); 2138 2139 TranslatedIndexData indexInfo; 2140 GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo); 2141 if(err != GL_NO_ERROR) 2142 { 2143 return error(err); 2144 } 2145 2146 GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1; 2147 err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount); 2148 if(err != GL_NO_ERROR) 2149 { 2150 return error(err); 2151 } 2152 2153 applyTextures(); 2154 2155 if(!cullSkipsDraw(mode)) 2156 { 2157 device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount, IndexDataManager::typeSize(type)); 2158 } 2159} 2160 2161void Context::finish() 2162{ 2163 device->finish(); 2164} 2165 2166void Context::flush() 2167{ 2168 // We don't queue anything without processing it as fast as possible 2169} 2170 2171void Context::recordInvalidEnum() 2172{ 2173 mInvalidEnum = true; 2174} 2175 2176void Context::recordInvalidValue() 2177{ 2178 mInvalidValue = true; 2179} 2180 2181void Context::recordInvalidOperation() 2182{ 2183 mInvalidOperation = true; 2184} 2185 2186void Context::recordOutOfMemory() 2187{ 2188 mOutOfMemory = true; 2189} 2190 2191void Context::recordInvalidFramebufferOperation() 2192{ 2193 mInvalidFramebufferOperation = true; 2194} 2195 2196// Get one of the recorded errors and clear its flag, if any. 2197// [OpenGL ES 2.0.24] section 2.5 page 13. 2198GLenum Context::getError() 2199{ 2200 if(mInvalidEnum) 2201 { 2202 mInvalidEnum = false; 2203 2204 return GL_INVALID_ENUM; 2205 } 2206 2207 if(mInvalidValue) 2208 { 2209 mInvalidValue = false; 2210 2211 return GL_INVALID_VALUE; 2212 } 2213 2214 if(mInvalidOperation) 2215 { 2216 mInvalidOperation = false; 2217 2218 return GL_INVALID_OPERATION; 2219 } 2220 2221 if(mOutOfMemory) 2222 { 2223 mOutOfMemory = false; 2224 2225 return GL_OUT_OF_MEMORY; 2226 } 2227 2228 if(mInvalidFramebufferOperation) 2229 { 2230 mInvalidFramebufferOperation = false; 2231 2232 return GL_INVALID_FRAMEBUFFER_OPERATION_OES; 2233 } 2234 2235 return GL_NO_ERROR; 2236} 2237 2238int Context::getSupportedMultiSampleDepth(sw::Format format, int requested) 2239{ 2240 if(requested <= 1) 2241 { 2242 return 1; 2243 } 2244 2245 if(requested == 2) 2246 { 2247 return 2; 2248 } 2249 2250 return 4; 2251} 2252 2253void Context::detachBuffer(GLuint buffer) 2254{ 2255 // [OpenGL ES 2.0.24] section 2.9 page 22: 2256 // If a buffer object is deleted while it is bound, all bindings to that object in the current context 2257 // (i.e. in the thread that called Delete-Buffers) are reset to zero. 2258 2259 if(mState.arrayBuffer.id() == buffer) 2260 { 2261 mState.arrayBuffer.set(NULL); 2262 } 2263 2264 if(mState.elementArrayBuffer.id() == buffer) 2265 { 2266 mState.elementArrayBuffer.set(NULL); 2267 } 2268 2269 for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++) 2270 { 2271 if(mState.vertexAttribute[attribute].mBoundBuffer.id() == buffer) 2272 { 2273 mState.vertexAttribute[attribute].mBoundBuffer.set(NULL); 2274 } 2275 } 2276} 2277 2278void Context::detachTexture(GLuint texture) 2279{ 2280 // [OpenGL ES 2.0.24] section 3.8 page 84: 2281 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are 2282 // rebound to texture object zero 2283 2284 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++) 2285 { 2286 for(int sampler = 0; sampler < MAX_TEXTURE_UNITS; sampler++) 2287 { 2288 if(mState.samplerTexture[type][sampler].id() == texture) 2289 { 2290 mState.samplerTexture[type][sampler].set(NULL); 2291 } 2292 } 2293 } 2294 2295 // [OpenGL ES 2.0.24] section 4.4 page 112: 2296 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is 2297 // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this 2298 // image was attached in the currently bound framebuffer. 2299 2300 Framebuffer *framebuffer = getFramebuffer(); 2301 2302 if(framebuffer) 2303 { 2304 framebuffer->detachTexture(texture); 2305 } 2306} 2307 2308void Context::detachFramebuffer(GLuint framebuffer) 2309{ 2310 // [OpenGL ES 2.0.24] section 4.4 page 107: 2311 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though 2312 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero. 2313 2314 if(mState.framebuffer == framebuffer) 2315 { 2316 bindFramebuffer(0); 2317 } 2318} 2319 2320void Context::detachRenderbuffer(GLuint renderbuffer) 2321{ 2322 // [OpenGL ES 2.0.24] section 4.4 page 109: 2323 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer 2324 // had been executed with the target RENDERBUFFER and name of zero. 2325 2326 if(mState.renderbuffer.id() == renderbuffer) 2327 { 2328 bindRenderbuffer(0); 2329 } 2330 2331 // [OpenGL ES 2.0.24] section 4.4 page 111: 2332 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer, 2333 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment 2334 // point to which this image was attached in the currently bound framebuffer. 2335 2336 Framebuffer *framebuffer = getFramebuffer(); 2337 2338 if(framebuffer) 2339 { 2340 framebuffer->detachRenderbuffer(renderbuffer); 2341 } 2342} 2343 2344bool Context::cullSkipsDraw(GLenum drawMode) 2345{ 2346 return mState.cullFace && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode); 2347} 2348 2349bool Context::isTriangleMode(GLenum drawMode) 2350{ 2351 switch (drawMode) 2352 { 2353 case GL_TRIANGLES: 2354 case GL_TRIANGLE_FAN: 2355 case GL_TRIANGLE_STRIP: 2356 return true; 2357 case GL_POINTS: 2358 case GL_LINES: 2359 case GL_LINE_LOOP: 2360 case GL_LINE_STRIP: 2361 return false; 2362 default: UNREACHABLE(); 2363 } 2364 2365 return false; 2366} 2367 2368void Context::setVertexAttrib(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) 2369{ 2370 ASSERT(index < MAX_VERTEX_ATTRIBS); 2371 2372 mState.vertexAttribute[index].mCurrentValue[0] = x; 2373 mState.vertexAttribute[index].mCurrentValue[1] = y; 2374 mState.vertexAttribute[index].mCurrentValue[2] = z; 2375 mState.vertexAttribute[index].mCurrentValue[3] = w; 2376 2377 mVertexDataManager->dirtyCurrentValue(index); 2378} 2379 2380void Context::bindTexImage(egl::Surface *surface) 2381{ 2382 es1::Texture2D *textureObject = getTexture2D(); 2383 2384 if(textureObject) 2385 { 2386 textureObject->bindTexImage(surface); 2387 } 2388} 2389 2390EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel) 2391{ 2392 switch(target) 2393 { 2394 case EGL_GL_TEXTURE_2D_KHR: 2395 break; 2396 case EGL_GL_RENDERBUFFER_KHR: 2397 break; 2398 default: 2399 return EGL_BAD_PARAMETER; 2400 } 2401 2402 if(textureLevel >= IMPLEMENTATION_MAX_TEXTURE_LEVELS) 2403 { 2404 return EGL_BAD_MATCH; 2405 } 2406 2407 if(target == EGL_GL_TEXTURE_2D_KHR) 2408 { 2409 Texture *texture = getTexture(name); 2410 2411 if(!texture || texture->getTarget() != GL_TEXTURE_2D) 2412 { 2413 return EGL_BAD_PARAMETER; 2414 } 2415 2416 if(texture->isShared(GL_TEXTURE_2D, textureLevel)) // Bound to an EGLSurface or already an EGLImage sibling 2417 { 2418 return EGL_BAD_ACCESS; 2419 } 2420 2421 if(textureLevel != 0 && !texture->isSamplerComplete()) 2422 { 2423 return EGL_BAD_PARAMETER; 2424 } 2425 2426 if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1)) 2427 { 2428 return EGL_BAD_PARAMETER; 2429 } 2430 } 2431 else if(target == EGL_GL_RENDERBUFFER_KHR) 2432 { 2433 Renderbuffer *renderbuffer = getRenderbuffer(name); 2434 2435 if(!renderbuffer) 2436 { 2437 return EGL_BAD_PARAMETER; 2438 } 2439 2440 if(renderbuffer->isShared()) // Already an EGLImage sibling 2441 { 2442 return EGL_BAD_ACCESS; 2443 } 2444 } 2445 else UNREACHABLE(); 2446 2447 return EGL_SUCCESS; 2448} 2449 2450egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel) 2451{ 2452 if(target == EGL_GL_TEXTURE_2D_KHR) 2453 { 2454 es1::Texture *texture = getTexture(name); 2455 2456 return texture->createSharedImage(GL_TEXTURE_2D, textureLevel); 2457 } 2458 else if(target == EGL_GL_RENDERBUFFER_KHR) 2459 { 2460 es1::Renderbuffer *renderbuffer = getRenderbuffer(name); 2461 2462 return renderbuffer->createSharedImage(); 2463 } 2464 else UNREACHABLE(); 2465 2466 return 0; 2467} 2468 2469Device *Context::getDevice() 2470{ 2471 return device; 2472} 2473 2474void Context::setMatrixMode(GLenum mode) 2475{ 2476 matrixMode = mode; 2477} 2478 2479sw::MatrixStack &Context::currentMatrixStack() 2480{ 2481 switch(matrixMode) 2482 { 2483 case GL_MODELVIEW: 2484 return modelViewStack; 2485 case GL_PROJECTION: 2486 return projectionStack; 2487 case GL_TEXTURE: 2488 switch(mState.activeSampler) 2489 { 2490 case 0: return textureStack0; 2491 case 1: return textureStack1; 2492 } 2493 break; 2494 } 2495 2496 UNREACHABLE(); 2497 return textureStack0; 2498} 2499 2500void Context::loadIdentity() 2501{ 2502 currentMatrixStack().identity(); 2503} 2504 2505void Context::load(const GLfloat *m) 2506{ 2507 currentMatrixStack().load(m); 2508} 2509 2510void Context::pushMatrix() 2511{ 2512 if(!currentMatrixStack().push()) 2513 { 2514 return error(GL_STACK_OVERFLOW); 2515 } 2516} 2517 2518void Context::popMatrix() 2519{ 2520 if(!currentMatrixStack().pop()) 2521 { 2522 return error(GL_STACK_OVERFLOW); 2523 } 2524} 2525 2526void Context::rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) 2527{ 2528 currentMatrixStack().rotate(angle, x, y, z); 2529} 2530 2531void Context::translate(GLfloat x, GLfloat y, GLfloat z) 2532{ 2533 currentMatrixStack().translate(x, y, z); 2534} 2535 2536void Context::scale(GLfloat x, GLfloat y, GLfloat z) 2537{ 2538 currentMatrixStack().scale(x, y, z); 2539} 2540 2541void Context::multiply(const GLfloat *m) 2542{ 2543 currentMatrixStack().multiply(m); 2544} 2545 2546void Context::ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) 2547{ 2548 currentMatrixStack().ortho(left, right, bottom, top, zNear, zFar); 2549} 2550 2551void Context::clientActiveTexture(GLenum texture) 2552{ 2553 clientTexture = texture; 2554} 2555 2556GLenum Context::getClientActiveTexture() const 2557{ 2558 return clientTexture; 2559} 2560 2561unsigned int Context::getActiveTexture() const 2562{ 2563 return mState.activeSampler; 2564} 2565 2566} 2567 2568// Exported functions for use by EGL 2569extern "C" 2570{ 2571 es1::Context *glCreateContext(const egl::Config *config, const es1::Context *shareContext) 2572 { 2573 return new es1::Context(config, shareContext); 2574 } 2575} 2576