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