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