Context.cpp revision e8af6d1a7a08e53a2369cd9e9c24ebb185779196
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 es2::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 "Fence.h" 23#include "Framebuffer.h" 24#include "Program.h" 25#include "Query.h" 26#include "Renderbuffer.h" 27#include "Sampler.h" 28#include "Shader.h" 29#include "Texture.h" 30#include "TransformFeedback.h" 31#include "VertexArray.h" 32#include "VertexDataManager.h" 33#include "IndexDataManager.h" 34#include "libEGL/Display.h" 35#include "libEGL/Surface.h" 36#include "Common/Half.hpp" 37 38#include <EGL/eglext.h> 39 40#ifdef __ANDROID__ 41 #include "../common/AndroidCommon.hpp" 42#endif // __ANDROID__ 43 44#undef near 45#undef far 46 47namespace es2 48{ 49Context::Context(const egl::Config *config, const Context *shareContext, EGLint clientVersion) 50 : mConfig(config), clientVersion(clientVersion) 51{ 52 sw::Context *context = new sw::Context(); 53 device = new es2::Device(context); 54 55 mFenceNameSpace.setBaseHandle(0); 56 57 setClearColor(0.0f, 0.0f, 0.0f, 0.0f); 58 59 mState.depthClearValue = 1.0f; 60 mState.stencilClearValue = 0; 61 62 mState.cullFace = false; 63 mState.cullMode = GL_BACK; 64 mState.frontFace = GL_CCW; 65 mState.depthTest = false; 66 mState.depthFunc = GL_LESS; 67 mState.blend = false; 68 mState.sourceBlendRGB = GL_ONE; 69 mState.sourceBlendAlpha = GL_ONE; 70 mState.destBlendRGB = GL_ZERO; 71 mState.destBlendAlpha = GL_ZERO; 72 mState.blendEquationRGB = GL_FUNC_ADD; 73 mState.blendEquationAlpha = GL_FUNC_ADD; 74 mState.blendColor.red = 0; 75 mState.blendColor.green = 0; 76 mState.blendColor.blue = 0; 77 mState.blendColor.alpha = 0; 78 mState.stencilTest = false; 79 mState.stencilFunc = GL_ALWAYS; 80 mState.stencilRef = 0; 81 mState.stencilMask = -1; 82 mState.stencilWritemask = -1; 83 mState.stencilBackFunc = GL_ALWAYS; 84 mState.stencilBackRef = 0; 85 mState.stencilBackMask = - 1; 86 mState.stencilBackWritemask = -1; 87 mState.stencilFail = GL_KEEP; 88 mState.stencilPassDepthFail = GL_KEEP; 89 mState.stencilPassDepthPass = GL_KEEP; 90 mState.stencilBackFail = GL_KEEP; 91 mState.stencilBackPassDepthFail = GL_KEEP; 92 mState.stencilBackPassDepthPass = GL_KEEP; 93 mState.polygonOffsetFill = false; 94 mState.polygonOffsetFactor = 0.0f; 95 mState.polygonOffsetUnits = 0.0f; 96 mState.sampleAlphaToCoverage = false; 97 mState.sampleCoverage = false; 98 mState.sampleCoverageValue = 1.0f; 99 mState.sampleCoverageInvert = false; 100 mState.scissorTest = false; 101 mState.dither = true; 102 mState.primitiveRestartFixedIndex = false; 103 mState.rasterizerDiscard = false; 104 mState.generateMipmapHint = GL_DONT_CARE; 105 mState.fragmentShaderDerivativeHint = GL_DONT_CARE; 106 107 mState.lineWidth = 1.0f; 108 109 mState.viewportX = 0; 110 mState.viewportY = 0; 111 mState.viewportWidth = config->mDisplayMode.width; 112 mState.viewportHeight = config->mDisplayMode.height; 113 mState.zNear = 0.0f; 114 mState.zFar = 1.0f; 115 116 mState.scissorX = 0; 117 mState.scissorY = 0; 118 mState.scissorWidth = config->mDisplayMode.width; 119 mState.scissorHeight = config->mDisplayMode.height; 120 121 mState.colorMaskRed = true; 122 mState.colorMaskGreen = true; 123 mState.colorMaskBlue = true; 124 mState.colorMaskAlpha = true; 125 mState.depthMask = true; 126 127 if(shareContext != NULL) 128 { 129 mResourceManager = shareContext->mResourceManager; 130 mResourceManager->addRef(); 131 } 132 else 133 { 134 mResourceManager = new ResourceManager(); 135 } 136 137 // [OpenGL ES 2.0.24] section 3.7 page 83: 138 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional 139 // and cube map texture state vectors respectively associated with them. 140 // In order that access to these initial textures not be lost, they are treated as texture 141 // objects all of whose names are 0. 142 143 mTexture2DZero = new Texture2D(0); 144 mTexture3DZero = new Texture3D(0); 145 mTextureCubeMapZero = new TextureCubeMap(0); 146 mTextureExternalZero = new TextureExternal(0); 147 148 mState.activeSampler = 0; 149 bindArrayBuffer(0); 150 bindElementArrayBuffer(0); 151 bindTextureCubeMap(0); 152 bindTexture2D(0); 153 bindReadFramebuffer(0); 154 bindDrawFramebuffer(0); 155 bindRenderbuffer(0); 156 bindTransformFeedback(0); 157 158 mState.currentProgram = 0; 159 160 mState.packAlignment = 4; 161 mState.unpackAlignment = 4; 162 163 mVertexDataManager = NULL; 164 mIndexDataManager = NULL; 165 166 mInvalidEnum = false; 167 mInvalidValue = false; 168 mInvalidOperation = false; 169 mOutOfMemory = false; 170 mInvalidFramebufferOperation = false; 171 172 mHasBeenCurrent = false; 173 174 markAllStateDirty(); 175} 176 177Context::~Context() 178{ 179 if(mState.currentProgram != 0) 180 { 181 Program *programObject = mResourceManager->getProgram(mState.currentProgram); 182 if(programObject) 183 { 184 programObject->release(); 185 } 186 mState.currentProgram = 0; 187 } 188 189 while(!mFramebufferMap.empty()) 190 { 191 deleteFramebuffer(mFramebufferMap.begin()->first); 192 } 193 194 while(!mFenceMap.empty()) 195 { 196 deleteFence(mFenceMap.begin()->first); 197 } 198 199 while(!mQueryMap.empty()) 200 { 201 deleteQuery(mQueryMap.begin()->first); 202 } 203 204 while(!mVertexArrayMap.empty()) 205 { 206 deleteVertexArray(mVertexArrayMap.begin()->first); 207 } 208 209 while(!mTransformFeedbackMap.empty()) 210 { 211 deleteTransformFeedback(mTransformFeedbackMap.begin()->first); 212 } 213 214 while(!mSamplerMap.empty()) 215 { 216 deleteSampler(mSamplerMap.begin()->first); 217 } 218 219 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++) 220 { 221 for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_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 for(int i = 0; i < QUERY_TYPE_COUNT; i++) 233 { 234 mState.activeQuery[i] = NULL; 235 } 236 237 mState.arrayBuffer = NULL; 238 mState.elementArrayBuffer = NULL; 239 mState.copyReadBuffer = NULL; 240 mState.copyWriteBuffer = NULL; 241 mState.pixelPackBuffer = NULL; 242 mState.pixelUnpackBuffer = NULL; 243 mState.uniformBuffer = NULL; 244 mState.renderbuffer = NULL; 245 246 mState.vertexArray = NULL; 247 for(int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++i) 248 { 249 mState.sampler[i] = NULL; 250 } 251 252 mTexture2DZero = NULL; 253 mTexture3DZero = NULL; 254 mTextureCubeMapZero = NULL; 255 mTextureExternalZero = NULL; 256 257 delete mVertexDataManager; 258 delete mIndexDataManager; 259 260 mResourceManager->release(); 261 delete device; 262} 263 264void Context::makeCurrent(egl::Surface *surface) 265{ 266 if(!mHasBeenCurrent) 267 { 268 mVertexDataManager = new VertexDataManager(this); 269 mIndexDataManager = new IndexDataManager(); 270 271 mState.viewportX = 0; 272 mState.viewportY = 0; 273 mState.viewportWidth = surface->getWidth(); 274 mState.viewportHeight = surface->getHeight(); 275 276 mState.scissorX = 0; 277 mState.scissorY = 0; 278 mState.scissorWidth = surface->getWidth(); 279 mState.scissorHeight = surface->getHeight(); 280 281 mHasBeenCurrent = true; 282 } 283 284 // Wrap the existing resources into GL objects and assign them to the '0' names 285 egl::Image *defaultRenderTarget = surface->getRenderTarget(); 286 egl::Image *depthStencil = surface->getDepthStencil(); 287 288 Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget); 289 DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil); 290 Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero); 291 292 setFramebufferZero(framebufferZero); 293 294 if(defaultRenderTarget) 295 { 296 defaultRenderTarget->release(); 297 } 298 299 if(depthStencil) 300 { 301 depthStencil->release(); 302 } 303 304 markAllStateDirty(); 305} 306 307EGLint Context::getClientVersion() const 308{ 309 return clientVersion; 310} 311 312// This function will set all of the state-related dirty flags, so that all state is set during next pre-draw. 313void Context::markAllStateDirty() 314{ 315 mAppliedProgramSerial = 0; 316 317 mDepthStateDirty = true; 318 mMaskStateDirty = true; 319 mBlendStateDirty = true; 320 mStencilStateDirty = true; 321 mPolygonOffsetStateDirty = true; 322 mSampleStateDirty = true; 323 mDitherStateDirty = true; 324 mFrontFaceDirty = true; 325} 326 327void Context::setClearColor(float red, float green, float blue, float alpha) 328{ 329 mState.colorClearValue.red = red; 330 mState.colorClearValue.green = green; 331 mState.colorClearValue.blue = blue; 332 mState.colorClearValue.alpha = alpha; 333} 334 335void Context::setClearDepth(float depth) 336{ 337 mState.depthClearValue = depth; 338} 339 340void Context::setClearStencil(int stencil) 341{ 342 mState.stencilClearValue = stencil; 343} 344 345void Context::setCullFace(bool enabled) 346{ 347 mState.cullFace = enabled; 348} 349 350bool Context::isCullFaceEnabled() const 351{ 352 return mState.cullFace; 353} 354 355void Context::setCullMode(GLenum mode) 356{ 357 mState.cullMode = mode; 358} 359 360void Context::setFrontFace(GLenum front) 361{ 362 if(mState.frontFace != front) 363 { 364 mState.frontFace = front; 365 mFrontFaceDirty = true; 366 } 367} 368 369void Context::setDepthTest(bool enabled) 370{ 371 if(mState.depthTest != enabled) 372 { 373 mState.depthTest = enabled; 374 mDepthStateDirty = true; 375 } 376} 377 378bool Context::isDepthTestEnabled() const 379{ 380 return mState.depthTest; 381} 382 383void Context::setDepthFunc(GLenum depthFunc) 384{ 385 if(mState.depthFunc != depthFunc) 386 { 387 mState.depthFunc = depthFunc; 388 mDepthStateDirty = true; 389 } 390} 391 392void Context::setDepthRange(float zNear, float zFar) 393{ 394 mState.zNear = zNear; 395 mState.zFar = zFar; 396} 397 398void Context::setBlend(bool enabled) 399{ 400 if(mState.blend != enabled) 401 { 402 mState.blend = enabled; 403 mBlendStateDirty = true; 404 } 405} 406 407bool Context::isBlendEnabled() const 408{ 409 return mState.blend; 410} 411 412void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha) 413{ 414 if(mState.sourceBlendRGB != sourceRGB || 415 mState.sourceBlendAlpha != sourceAlpha || 416 mState.destBlendRGB != destRGB || 417 mState.destBlendAlpha != destAlpha) 418 { 419 mState.sourceBlendRGB = sourceRGB; 420 mState.destBlendRGB = destRGB; 421 mState.sourceBlendAlpha = sourceAlpha; 422 mState.destBlendAlpha = destAlpha; 423 mBlendStateDirty = true; 424 } 425} 426 427void Context::setBlendColor(float red, float green, float blue, float alpha) 428{ 429 if(mState.blendColor.red != red || 430 mState.blendColor.green != green || 431 mState.blendColor.blue != blue || 432 mState.blendColor.alpha != alpha) 433 { 434 mState.blendColor.red = red; 435 mState.blendColor.green = green; 436 mState.blendColor.blue = blue; 437 mState.blendColor.alpha = alpha; 438 mBlendStateDirty = true; 439 } 440} 441 442void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation) 443{ 444 if(mState.blendEquationRGB != rgbEquation || 445 mState.blendEquationAlpha != alphaEquation) 446 { 447 mState.blendEquationRGB = rgbEquation; 448 mState.blendEquationAlpha = alphaEquation; 449 mBlendStateDirty = true; 450 } 451} 452 453void Context::setStencilTest(bool enabled) 454{ 455 if(mState.stencilTest != enabled) 456 { 457 mState.stencilTest = enabled; 458 mStencilStateDirty = true; 459 } 460} 461 462bool Context::isStencilTestEnabled() const 463{ 464 return mState.stencilTest; 465} 466 467void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask) 468{ 469 if(mState.stencilFunc != stencilFunc || 470 mState.stencilRef != stencilRef || 471 mState.stencilMask != stencilMask) 472 { 473 mState.stencilFunc = stencilFunc; 474 mState.stencilRef = (stencilRef > 0) ? stencilRef : 0; 475 mState.stencilMask = stencilMask; 476 mStencilStateDirty = true; 477 } 478} 479 480void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask) 481{ 482 if(mState.stencilBackFunc != stencilBackFunc || 483 mState.stencilBackRef != stencilBackRef || 484 mState.stencilBackMask != stencilBackMask) 485 { 486 mState.stencilBackFunc = stencilBackFunc; 487 mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0; 488 mState.stencilBackMask = stencilBackMask; 489 mStencilStateDirty = true; 490 } 491} 492 493void Context::setStencilWritemask(GLuint stencilWritemask) 494{ 495 if(mState.stencilWritemask != stencilWritemask) 496 { 497 mState.stencilWritemask = stencilWritemask; 498 mStencilStateDirty = true; 499 } 500} 501 502void Context::setStencilBackWritemask(GLuint stencilBackWritemask) 503{ 504 if(mState.stencilBackWritemask != stencilBackWritemask) 505 { 506 mState.stencilBackWritemask = stencilBackWritemask; 507 mStencilStateDirty = true; 508 } 509} 510 511void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass) 512{ 513 if(mState.stencilFail != stencilFail || 514 mState.stencilPassDepthFail != stencilPassDepthFail || 515 mState.stencilPassDepthPass != stencilPassDepthPass) 516 { 517 mState.stencilFail = stencilFail; 518 mState.stencilPassDepthFail = stencilPassDepthFail; 519 mState.stencilPassDepthPass = stencilPassDepthPass; 520 mStencilStateDirty = true; 521 } 522} 523 524void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass) 525{ 526 if(mState.stencilBackFail != stencilBackFail || 527 mState.stencilBackPassDepthFail != stencilBackPassDepthFail || 528 mState.stencilBackPassDepthPass != stencilBackPassDepthPass) 529 { 530 mState.stencilBackFail = stencilBackFail; 531 mState.stencilBackPassDepthFail = stencilBackPassDepthFail; 532 mState.stencilBackPassDepthPass = stencilBackPassDepthPass; 533 mStencilStateDirty = true; 534 } 535} 536 537void Context::setPolygonOffsetFill(bool enabled) 538{ 539 if(mState.polygonOffsetFill != enabled) 540 { 541 mState.polygonOffsetFill = enabled; 542 mPolygonOffsetStateDirty = true; 543 } 544} 545 546bool Context::isPolygonOffsetFillEnabled() const 547{ 548 return mState.polygonOffsetFill; 549} 550 551void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units) 552{ 553 if(mState.polygonOffsetFactor != factor || 554 mState.polygonOffsetUnits != units) 555 { 556 mState.polygonOffsetFactor = factor; 557 mState.polygonOffsetUnits = units; 558 mPolygonOffsetStateDirty = true; 559 } 560} 561 562void Context::setSampleAlphaToCoverage(bool enabled) 563{ 564 if(mState.sampleAlphaToCoverage != enabled) 565 { 566 mState.sampleAlphaToCoverage = enabled; 567 mSampleStateDirty = true; 568 } 569} 570 571bool Context::isSampleAlphaToCoverageEnabled() const 572{ 573 return mState.sampleAlphaToCoverage; 574} 575 576void Context::setSampleCoverage(bool enabled) 577{ 578 if(mState.sampleCoverage != enabled) 579 { 580 mState.sampleCoverage = enabled; 581 mSampleStateDirty = true; 582 } 583} 584 585bool Context::isSampleCoverageEnabled() const 586{ 587 return mState.sampleCoverage; 588} 589 590void Context::setSampleCoverageParams(GLclampf value, bool invert) 591{ 592 if(mState.sampleCoverageValue != value || 593 mState.sampleCoverageInvert != invert) 594 { 595 mState.sampleCoverageValue = value; 596 mState.sampleCoverageInvert = invert; 597 mSampleStateDirty = true; 598 } 599} 600 601void Context::setScissorTest(bool enabled) 602{ 603 mState.scissorTest = enabled; 604} 605 606bool Context::isScissorTestEnabled() const 607{ 608 return mState.scissorTest; 609} 610 611void Context::setDither(bool enabled) 612{ 613 if(mState.dither != enabled) 614 { 615 mState.dither = enabled; 616 mDitherStateDirty = true; 617 } 618} 619 620bool Context::isDitherEnabled() const 621{ 622 return mState.dither; 623} 624 625void Context::setPrimitiveRestartFixedIndex(bool enabled) 626{ 627 UNIMPLEMENTED(); 628 mState.primitiveRestartFixedIndex = enabled; 629} 630 631bool Context::isPrimitiveRestartFixedIndexEnabled() const 632{ 633 return mState.primitiveRestartFixedIndex; 634} 635 636void Context::setRasterizerDiscard(bool enabled) 637{ 638 UNIMPLEMENTED(); 639 mState.rasterizerDiscard = enabled; 640} 641 642bool Context::isRasterizerDiscardEnabled() const 643{ 644 return mState.rasterizerDiscard; 645} 646 647void Context::setLineWidth(GLfloat width) 648{ 649 mState.lineWidth = width; 650 device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX)); 651} 652 653void Context::setGenerateMipmapHint(GLenum hint) 654{ 655 mState.generateMipmapHint = hint; 656} 657 658void Context::setFragmentShaderDerivativeHint(GLenum hint) 659{ 660 mState.fragmentShaderDerivativeHint = hint; 661 // TODO: Propagate the hint to shader translator so we can write 662 // ddx, ddx_coarse, or ddx_fine depending on the hint. 663 // Ignore for now. It is valid for implementations to ignore hint. 664} 665 666void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height) 667{ 668 mState.viewportX = x; 669 mState.viewportY = y; 670 mState.viewportWidth = width; 671 mState.viewportHeight = height; 672} 673 674void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height) 675{ 676 mState.scissorX = x; 677 mState.scissorY = y; 678 mState.scissorWidth = width; 679 mState.scissorHeight = height; 680} 681 682void Context::setColorMask(bool red, bool green, bool blue, bool alpha) 683{ 684 if(mState.colorMaskRed != red || mState.colorMaskGreen != green || 685 mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha) 686 { 687 mState.colorMaskRed = red; 688 mState.colorMaskGreen = green; 689 mState.colorMaskBlue = blue; 690 mState.colorMaskAlpha = alpha; 691 mMaskStateDirty = true; 692 } 693} 694 695void Context::setDepthMask(bool mask) 696{ 697 if(mState.depthMask != mask) 698 { 699 mState.depthMask = mask; 700 mMaskStateDirty = true; 701 } 702} 703 704void Context::setActiveSampler(unsigned int active) 705{ 706 mState.activeSampler = active; 707} 708 709GLuint Context::getReadFramebufferName() const 710{ 711 return mState.readFramebuffer; 712} 713 714GLuint Context::getDrawFramebufferName() const 715{ 716 return mState.drawFramebuffer; 717} 718 719GLuint Context::getRenderbufferName() const 720{ 721 return mState.renderbuffer.name(); 722} 723 724GLuint Context::getArrayBufferName() const 725{ 726 return mState.arrayBuffer.name(); 727} 728 729GLuint Context::getActiveQuery(GLenum target) const 730{ 731 Query *queryObject = NULL; 732 733 switch(target) 734 { 735 case GL_ANY_SAMPLES_PASSED_EXT: 736 queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED]; 737 break; 738 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: 739 queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE]; 740 break; 741 default: 742 ASSERT(false); 743 } 744 745 if(queryObject) 746 { 747 return queryObject->name; 748 } 749 750 return 0; 751} 752 753void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled) 754{ 755 mState.vertexAttribute[attribNum].mArrayEnabled = enabled; 756} 757 758void Context::setVertexAttribDivisor(unsigned int attribNum, GLuint divisor) 759{ 760 mState.vertexAttribute[attribNum].mDivisor = divisor; 761} 762 763const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) 764{ 765 return mState.vertexAttribute[attribNum]; 766} 767 768void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized, 769 GLsizei stride, const void *pointer) 770{ 771 mState.vertexAttribute[attribNum].mBoundBuffer = boundBuffer; 772 mState.vertexAttribute[attribNum].mSize = size; 773 mState.vertexAttribute[attribNum].mType = type; 774 mState.vertexAttribute[attribNum].mNormalized = normalized; 775 mState.vertexAttribute[attribNum].mStride = stride; 776 mState.vertexAttribute[attribNum].mPointer = pointer; 777} 778 779const void *Context::getVertexAttribPointer(unsigned int attribNum) const 780{ 781 return mState.vertexAttribute[attribNum].mPointer; 782} 783 784const VertexAttributeArray &Context::getVertexAttributes() 785{ 786 return mState.vertexAttribute; 787} 788 789void Context::setPackAlignment(GLint alignment) 790{ 791 mState.packAlignment = alignment; 792} 793 794GLint Context::getPackAlignment() const 795{ 796 return mState.packAlignment; 797} 798 799void Context::setUnpackAlignment(GLint alignment) 800{ 801 mState.unpackAlignment = alignment; 802} 803 804GLint Context::getUnpackAlignment() const 805{ 806 return mState.unpackAlignment; 807} 808 809GLuint Context::createBuffer() 810{ 811 return mResourceManager->createBuffer(); 812} 813 814GLuint Context::createProgram() 815{ 816 return mResourceManager->createProgram(); 817} 818 819GLuint Context::createShader(GLenum type) 820{ 821 return mResourceManager->createShader(type); 822} 823 824GLuint Context::createTexture() 825{ 826 return mResourceManager->createTexture(); 827} 828 829GLuint Context::createRenderbuffer() 830{ 831 return mResourceManager->createRenderbuffer(); 832} 833 834// Returns an unused framebuffer name 835GLuint Context::createFramebuffer() 836{ 837 GLuint handle = mFramebufferNameSpace.allocate(); 838 839 mFramebufferMap[handle] = NULL; 840 841 return handle; 842} 843 844GLuint Context::createFence() 845{ 846 GLuint handle = mFenceNameSpace.allocate(); 847 848 mFenceMap[handle] = new Fence; 849 850 return handle; 851} 852 853// Returns an unused query name 854GLuint Context::createQuery() 855{ 856 GLuint handle = mQueryNameSpace.allocate(); 857 858 mQueryMap[handle] = NULL; 859 860 return handle; 861} 862 863// Returns an unused vertex array name 864GLuint Context::createVertexArray() 865{ 866 GLuint handle = mVertexArrayNameSpace.allocate(); 867 868 mVertexArrayMap[handle] = NULL; 869 870 return handle; 871} 872 873// Returns an unused transform feedback name 874GLuint Context::createTransformFeedback() 875{ 876 GLuint handle = mTransformFeedbackNameSpace.allocate(); 877 878 mTransformFeedbackMap[handle] = NULL; 879 880 return handle; 881} 882 883// Returns an unused sampler name 884GLuint Context::createSampler() 885{ 886 GLuint handle = mSamplerNameSpace.allocate(); 887 888 mSamplerMap[handle] = NULL; 889 890 return handle; 891} 892 893void Context::deleteBuffer(GLuint buffer) 894{ 895 if(mResourceManager->getBuffer(buffer)) 896 { 897 detachBuffer(buffer); 898 } 899 900 mResourceManager->deleteBuffer(buffer); 901} 902 903void Context::deleteShader(GLuint shader) 904{ 905 mResourceManager->deleteShader(shader); 906} 907 908void Context::deleteProgram(GLuint program) 909{ 910 mResourceManager->deleteProgram(program); 911} 912 913void Context::deleteTexture(GLuint texture) 914{ 915 if(mResourceManager->getTexture(texture)) 916 { 917 detachTexture(texture); 918 } 919 920 mResourceManager->deleteTexture(texture); 921} 922 923void Context::deleteRenderbuffer(GLuint renderbuffer) 924{ 925 if(mResourceManager->getRenderbuffer(renderbuffer)) 926 { 927 detachRenderbuffer(renderbuffer); 928 } 929 930 mResourceManager->deleteRenderbuffer(renderbuffer); 931} 932 933void Context::deleteFramebuffer(GLuint framebuffer) 934{ 935 FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer); 936 937 if(framebufferObject != mFramebufferMap.end()) 938 { 939 detachFramebuffer(framebuffer); 940 941 mFramebufferNameSpace.release(framebufferObject->first); 942 delete framebufferObject->second; 943 mFramebufferMap.erase(framebufferObject); 944 } 945} 946 947void Context::deleteFence(GLuint fence) 948{ 949 FenceMap::iterator fenceObject = mFenceMap.find(fence); 950 951 if(fenceObject != mFenceMap.end()) 952 { 953 mFenceNameSpace.release(fenceObject->first); 954 delete fenceObject->second; 955 mFenceMap.erase(fenceObject); 956 } 957} 958 959void Context::deleteQuery(GLuint query) 960{ 961 QueryMap::iterator queryObject = mQueryMap.find(query); 962 963 if(queryObject != mQueryMap.end()) 964 { 965 mQueryNameSpace.release(queryObject->first); 966 967 if(queryObject->second) 968 { 969 queryObject->second->release(); 970 } 971 972 mQueryMap.erase(queryObject); 973 } 974} 975 976void Context::deleteVertexArray(GLuint vertexArray) 977{ 978 VertexArrayMap::iterator vertexArrayObject = mVertexArrayMap.find(vertexArray); 979 980 if(vertexArrayObject != mVertexArrayMap.end()) 981 { 982 mVertexArrayNameSpace.release(vertexArrayObject->first); 983 984 if(vertexArrayObject->second) 985 { 986 vertexArrayObject->second->release(); 987 } 988 989 mVertexArrayMap.erase(vertexArrayObject); 990 } 991} 992 993void Context::deleteTransformFeedback(GLuint transformFeedback) 994{ 995 TransformFeedbackMap::iterator transformFeedbackObject = mTransformFeedbackMap.find(transformFeedback); 996 997 if(transformFeedbackObject != mTransformFeedbackMap.end()) 998 { 999 mTransformFeedbackNameSpace.release(transformFeedbackObject->first); 1000 delete transformFeedbackObject->second; 1001 mTransformFeedbackMap.erase(transformFeedbackObject); 1002 } 1003} 1004 1005void Context::deleteSampler(GLuint sampler) 1006{ 1007 SamplerMap::iterator samplerObject = mSamplerMap.find(sampler); 1008 1009 if(samplerObject != mSamplerMap.end()) 1010 { 1011 mSamplerNameSpace.release(samplerObject->first); 1012 1013 if(samplerObject->second) 1014 { 1015 samplerObject->second->release(); 1016 } 1017 1018 mSamplerMap.erase(samplerObject); 1019 } 1020} 1021 1022Buffer *Context::getBuffer(GLuint handle) 1023{ 1024 return mResourceManager->getBuffer(handle); 1025} 1026 1027Shader *Context::getShader(GLuint handle) 1028{ 1029 return mResourceManager->getShader(handle); 1030} 1031 1032Program *Context::getProgram(GLuint handle) 1033{ 1034 return mResourceManager->getProgram(handle); 1035} 1036 1037Texture *Context::getTexture(GLuint handle) 1038{ 1039 return mResourceManager->getTexture(handle); 1040} 1041 1042Renderbuffer *Context::getRenderbuffer(GLuint handle) 1043{ 1044 return mResourceManager->getRenderbuffer(handle); 1045} 1046 1047Framebuffer *Context::getReadFramebuffer() 1048{ 1049 return getFramebuffer(mState.readFramebuffer); 1050} 1051 1052Framebuffer *Context::getDrawFramebuffer() 1053{ 1054 return getFramebuffer(mState.drawFramebuffer); 1055} 1056 1057void Context::bindArrayBuffer(unsigned int buffer) 1058{ 1059 mResourceManager->checkBufferAllocation(buffer); 1060 1061 mState.arrayBuffer = getBuffer(buffer); 1062} 1063 1064void Context::bindElementArrayBuffer(unsigned int buffer) 1065{ 1066 mResourceManager->checkBufferAllocation(buffer); 1067 1068 mState.elementArrayBuffer = getBuffer(buffer); 1069} 1070 1071void Context::bindCopyReadBuffer(GLuint buffer) 1072{ 1073 mResourceManager->checkBufferAllocation(buffer); 1074 1075 mState.copyReadBuffer = getBuffer(buffer); 1076} 1077 1078void Context::bindCopyWriteBuffer(GLuint buffer) 1079{ 1080 mResourceManager->checkBufferAllocation(buffer); 1081 1082 mState.copyWriteBuffer = getBuffer(buffer); 1083} 1084 1085void Context::bindPixelPackBuffer(GLuint buffer) 1086{ 1087 mResourceManager->checkBufferAllocation(buffer); 1088 1089 mState.pixelPackBuffer = getBuffer(buffer); 1090} 1091 1092void Context::bindPixelUnpackBuffer(GLuint buffer) 1093{ 1094 mResourceManager->checkBufferAllocation(buffer); 1095 1096 mState.pixelUnpackBuffer = getBuffer(buffer); 1097} 1098 1099void Context::bindUniformBuffer(GLuint buffer) 1100{ 1101 mResourceManager->checkBufferAllocation(buffer); 1102 1103 mState.uniformBuffer = getBuffer(buffer); 1104} 1105 1106void Context::bindTexture2D(GLuint texture) 1107{ 1108 mResourceManager->checkTextureAllocation(texture, TEXTURE_2D); 1109 1110 mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture); 1111} 1112 1113void Context::bindTextureCubeMap(GLuint texture) 1114{ 1115 mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE); 1116 1117 mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler] = getTexture(texture); 1118} 1119 1120void Context::bindTextureExternal(GLuint texture) 1121{ 1122 mResourceManager->checkTextureAllocation(texture, TEXTURE_EXTERNAL); 1123 1124 mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler] = getTexture(texture); 1125} 1126 1127void Context::bindTexture3D(GLuint texture) 1128{ 1129 mResourceManager->checkTextureAllocation(texture, TEXTURE_3D); 1130 1131 mState.samplerTexture[TEXTURE_3D][mState.activeSampler] = getTexture(texture); 1132} 1133 1134void Context::bindReadFramebuffer(GLuint framebuffer) 1135{ 1136 if(!getFramebuffer(framebuffer)) 1137 { 1138 mFramebufferMap[framebuffer] = new Framebuffer(); 1139 } 1140 1141 mState.readFramebuffer = framebuffer; 1142} 1143 1144void Context::bindDrawFramebuffer(GLuint framebuffer) 1145{ 1146 if(!getFramebuffer(framebuffer)) 1147 { 1148 mFramebufferMap[framebuffer] = new Framebuffer(); 1149 } 1150 1151 mState.drawFramebuffer = framebuffer; 1152} 1153 1154void Context::bindRenderbuffer(GLuint renderbuffer) 1155{ 1156 mState.renderbuffer = getRenderbuffer(renderbuffer); 1157} 1158 1159bool Context::bindVertexArray(GLuint array) 1160{ 1161 VertexArray* vertexArray = getVertexArray(array); 1162 1163 if(vertexArray) 1164 { 1165 mState.vertexArray = vertexArray; 1166 } 1167 1168 return !!vertexArray; 1169} 1170 1171bool Context::bindTransformFeedback(GLuint id) 1172{ 1173 if(!getTransformFeedback(id)) 1174 { 1175 mTransformFeedbackMap[id] = new TransformFeedback(id); 1176 } 1177 1178 mState.transformFeedback = id; 1179 1180 return true; 1181} 1182 1183bool Context::bindSampler(GLuint unit, GLuint sampler) 1184{ 1185 Sampler* samplerObject = getSampler(sampler); 1186 1187 if(sampler) 1188 { 1189 mState.sampler[unit] = samplerObject; 1190 } 1191 1192 return !!samplerObject; 1193} 1194 1195void Context::useProgram(GLuint program) 1196{ 1197 GLuint priorProgram = mState.currentProgram; 1198 mState.currentProgram = program; // Must switch before trying to delete, otherwise it only gets flagged. 1199 1200 if(priorProgram != program) 1201 { 1202 Program *newProgram = mResourceManager->getProgram(program); 1203 Program *oldProgram = mResourceManager->getProgram(priorProgram); 1204 1205 if(newProgram) 1206 { 1207 newProgram->addRef(); 1208 } 1209 1210 if(oldProgram) 1211 { 1212 oldProgram->release(); 1213 } 1214 } 1215} 1216 1217void Context::beginQuery(GLenum target, GLuint query) 1218{ 1219 // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id> 1220 // of zero, if the active query object name for <target> is non-zero (for the 1221 // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if 1222 // the active query for either target is non-zero), if <id> is the name of an 1223 // existing query object whose type does not match <target>, or if <id> is the 1224 // active query object name for any query type, the error INVALID_OPERATION is 1225 // generated. 1226 1227 // Ensure no other queries are active 1228 // NOTE: If other queries than occlusion are supported, we will need to check 1229 // separately that: 1230 // a) The query ID passed is not the current active query for any target/type 1231 // b) There are no active queries for the requested target (and in the case 1232 // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, 1233 // no query may be active for either if glBeginQuery targets either. 1234 for(int i = 0; i < QUERY_TYPE_COUNT; i++) 1235 { 1236 if(mState.activeQuery[i] != NULL) 1237 { 1238 return error(GL_INVALID_OPERATION); 1239 } 1240 } 1241 1242 QueryType qType; 1243 switch(target) 1244 { 1245 case GL_ANY_SAMPLES_PASSED_EXT: 1246 qType = QUERY_ANY_SAMPLES_PASSED; 1247 break; 1248 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: 1249 qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE; 1250 break; 1251 default: 1252 ASSERT(false); 1253 } 1254 1255 Query *queryObject = getQuery(query, true, target); 1256 1257 // Check that name was obtained with glGenQueries 1258 if(!queryObject) 1259 { 1260 return error(GL_INVALID_OPERATION); 1261 } 1262 1263 // Check for type mismatch 1264 if(queryObject->getType() != target) 1265 { 1266 return error(GL_INVALID_OPERATION); 1267 } 1268 1269 // Set query as active for specified target 1270 mState.activeQuery[qType] = queryObject; 1271 1272 // Begin query 1273 queryObject->begin(); 1274} 1275 1276void Context::endQuery(GLenum target) 1277{ 1278 QueryType qType; 1279 1280 switch(target) 1281 { 1282 case GL_ANY_SAMPLES_PASSED_EXT: 1283 qType = QUERY_ANY_SAMPLES_PASSED; 1284 break; 1285 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: 1286 qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE; 1287 break; 1288 default: 1289 ASSERT(false); 1290 } 1291 1292 Query *queryObject = mState.activeQuery[qType]; 1293 1294 if(queryObject == NULL) 1295 { 1296 return error(GL_INVALID_OPERATION); 1297 } 1298 1299 queryObject->end(); 1300 1301 mState.activeQuery[qType] = NULL; 1302} 1303 1304void Context::setFramebufferZero(Framebuffer *buffer) 1305{ 1306 delete mFramebufferMap[0]; 1307 mFramebufferMap[0] = buffer; 1308} 1309 1310void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer) 1311{ 1312 Renderbuffer *renderbufferObject = mState.renderbuffer; 1313 renderbufferObject->setStorage(renderbuffer); 1314} 1315 1316Framebuffer *Context::getFramebuffer(unsigned int handle) 1317{ 1318 FramebufferMap::iterator framebuffer = mFramebufferMap.find(handle); 1319 1320 if(framebuffer == mFramebufferMap.end()) 1321 { 1322 return NULL; 1323 } 1324 else 1325 { 1326 return framebuffer->second; 1327 } 1328} 1329 1330Fence *Context::getFence(unsigned int handle) 1331{ 1332 FenceMap::iterator fence = mFenceMap.find(handle); 1333 1334 if(fence == mFenceMap.end()) 1335 { 1336 return NULL; 1337 } 1338 else 1339 { 1340 return fence->second; 1341 } 1342} 1343 1344Query *Context::getQuery(unsigned int handle, bool create, GLenum type) 1345{ 1346 QueryMap::iterator query = mQueryMap.find(handle); 1347 1348 if(query == mQueryMap.end()) 1349 { 1350 return NULL; 1351 } 1352 else 1353 { 1354 if(!query->second && create) 1355 { 1356 query->second = new Query(handle, type); 1357 query->second->addRef(); 1358 } 1359 1360 return query->second; 1361 } 1362} 1363 1364VertexArray *Context::getVertexArray(GLuint array) 1365{ 1366 VertexArrayMap::iterator vertexArray = mVertexArrayMap.find(array); 1367 1368 return (vertexArray == mVertexArrayMap.end()) ? NULL : vertexArray->second; 1369} 1370 1371TransformFeedback *Context::getTransformFeedback(GLuint transformFeedback) 1372{ 1373 TransformFeedbackMap::iterator transformFeedbackObject = mTransformFeedbackMap.find(transformFeedback); 1374 1375 return (transformFeedbackObject == mTransformFeedbackMap.end()) ? NULL : transformFeedbackObject->second; 1376} 1377 1378Sampler *Context::getSampler(GLuint sampler) 1379{ 1380 SamplerMap::iterator samplerObject = mSamplerMap.find(sampler); 1381 1382 return (samplerObject == mSamplerMap.end()) ? NULL : samplerObject->second; 1383} 1384 1385Buffer *Context::getArrayBuffer() 1386{ 1387 return mState.arrayBuffer; 1388} 1389 1390Buffer *Context::getElementArrayBuffer() 1391{ 1392 return mState.elementArrayBuffer; 1393} 1394 1395Buffer *Context::getCopyReadBuffer() 1396{ 1397 return mState.copyReadBuffer; 1398} 1399 1400Buffer *Context::getCopyWriteBuffer() 1401{ 1402 return mState.copyWriteBuffer; 1403} 1404 1405Buffer *Context::getPixelPackBuffer() 1406{ 1407 return mState.pixelPackBuffer; 1408} 1409 1410Buffer *Context::getPixelUnpackBuffer() 1411{ 1412 return mState.pixelUnpackBuffer; 1413} 1414 1415Buffer *Context::getUniformBuffer() 1416{ 1417 return mState.uniformBuffer; 1418} 1419 1420bool Context::getBuffer(GLenum target, es2::Buffer **buffer) 1421{ 1422 switch(target) 1423 { 1424 case GL_ARRAY_BUFFER: 1425 *buffer = getArrayBuffer(); 1426 break; 1427 case GL_ELEMENT_ARRAY_BUFFER: 1428 *buffer = getElementArrayBuffer(); 1429 break; 1430 case GL_COPY_READ_BUFFER: 1431 if(clientVersion >= 3) 1432 { 1433 *buffer = getCopyReadBuffer(); 1434 break; 1435 } 1436 else return false; 1437 case GL_COPY_WRITE_BUFFER: 1438 if(clientVersion >= 3) 1439 { 1440 *buffer = getCopyWriteBuffer(); 1441 break; 1442 } 1443 else return false; 1444 case GL_PIXEL_PACK_BUFFER: 1445 if(clientVersion >= 3) 1446 { 1447 *buffer = getPixelPackBuffer(); 1448 break; 1449 } 1450 else return false; 1451 case GL_PIXEL_UNPACK_BUFFER: 1452 if(clientVersion >= 3) 1453 { 1454 *buffer = getPixelUnpackBuffer(); 1455 break; 1456 } 1457 else return false; 1458 case GL_TRANSFORM_FEEDBACK_BUFFER: 1459 if(clientVersion >= 3) 1460 { 1461 UNIMPLEMENTED(); 1462 return false; 1463 } 1464 else return false; 1465 case GL_UNIFORM_BUFFER: 1466 if(clientVersion >= 3) 1467 { 1468 *buffer = getUniformBuffer(); 1469 break; 1470 } 1471 else return false; 1472 default: 1473 return false; 1474 } 1475 return true; 1476} 1477 1478TransformFeedback *Context::getTransformFeedback() 1479{ 1480 return getTransformFeedback(mState.transformFeedback); 1481} 1482 1483Program *Context::getCurrentProgram() 1484{ 1485 return mResourceManager->getProgram(mState.currentProgram); 1486} 1487 1488Texture2D *Context::getTexture2D() 1489{ 1490 return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D)); 1491} 1492 1493Texture3D *Context::getTexture3D() 1494{ 1495 return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D)); 1496} 1497 1498TextureCubeMap *Context::getTextureCubeMap() 1499{ 1500 return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE)); 1501} 1502 1503TextureExternal *Context::getTextureExternal() 1504{ 1505 return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL)); 1506} 1507 1508Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) 1509{ 1510 GLuint texid = mState.samplerTexture[type][sampler].name(); 1511 1512 if(texid == 0) // Special case: 0 refers to different initial textures based on the target 1513 { 1514 switch (type) 1515 { 1516 case TEXTURE_2D: return mTexture2DZero; 1517 case TEXTURE_3D: return mTexture3DZero; 1518 case TEXTURE_CUBE: return mTextureCubeMapZero; 1519 case TEXTURE_EXTERNAL: return mTextureExternalZero; 1520 default: UNREACHABLE(); 1521 } 1522 } 1523 1524 return mState.samplerTexture[type][sampler]; 1525} 1526 1527bool Context::getBooleanv(GLenum pname, GLboolean *params) 1528{ 1529 switch (pname) 1530 { 1531 case GL_SHADER_COMPILER: *params = GL_TRUE; break; 1532 case GL_SAMPLE_COVERAGE_INVERT: *params = mState.sampleCoverageInvert; break; 1533 case GL_DEPTH_WRITEMASK: *params = mState.depthMask; break; 1534 case GL_COLOR_WRITEMASK: 1535 params[0] = mState.colorMaskRed; 1536 params[1] = mState.colorMaskGreen; 1537 params[2] = mState.colorMaskBlue; 1538 params[3] = mState.colorMaskAlpha; 1539 break; 1540 case GL_CULL_FACE: *params = mState.cullFace; break; 1541 case GL_POLYGON_OFFSET_FILL: *params = mState.polygonOffsetFill; break; 1542 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverage; break; 1543 case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverage; break; 1544 case GL_SCISSOR_TEST: *params = mState.scissorTest; break; 1545 case GL_STENCIL_TEST: *params = mState.stencilTest; break; 1546 case GL_DEPTH_TEST: *params = mState.depthTest; break; 1547 case GL_BLEND: *params = mState.blend; break; 1548 case GL_DITHER: *params = mState.dither; break; 1549 case GL_PRIMITIVE_RESTART_FIXED_INDEX: *params = mState.primitiveRestartFixedIndex; break; 1550 case GL_RASTERIZER_DISCARD: *params = mState.rasterizerDiscard; break; 1551 case GL_TRANSFORM_FEEDBACK_ACTIVE: 1552 { 1553 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback); 1554 if(transformFeedback) 1555 { 1556 *params = transformFeedback->isActive(); 1557 break; 1558 } 1559 else return false; 1560 } 1561 case GL_TRANSFORM_FEEDBACK_PAUSED: 1562 { 1563 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback); 1564 if(transformFeedback) 1565 { 1566 *params = transformFeedback->isPaused(); 1567 break; 1568 } 1569 else return false; 1570 } 1571 default: 1572 return false; 1573 } 1574 1575 return true; 1576} 1577 1578bool Context::getFloatv(GLenum pname, GLfloat *params) 1579{ 1580 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation 1581 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names 1582 // GetIntegerv as its native query function. As it would require conversion in any 1583 // case, this should make no difference to the calling application. 1584 switch (pname) 1585 { 1586 case GL_LINE_WIDTH: *params = mState.lineWidth; break; 1587 case GL_SAMPLE_COVERAGE_VALUE: *params = mState.sampleCoverageValue; break; 1588 case GL_DEPTH_CLEAR_VALUE: *params = mState.depthClearValue; break; 1589 case GL_POLYGON_OFFSET_FACTOR: *params = mState.polygonOffsetFactor; break; 1590 case GL_POLYGON_OFFSET_UNITS: *params = mState.polygonOffsetUnits; break; 1591 case GL_ALIASED_LINE_WIDTH_RANGE: 1592 params[0] = ALIASED_LINE_WIDTH_RANGE_MIN; 1593 params[1] = ALIASED_LINE_WIDTH_RANGE_MAX; 1594 break; 1595 case GL_ALIASED_POINT_SIZE_RANGE: 1596 params[0] = ALIASED_POINT_SIZE_RANGE_MIN; 1597 params[1] = ALIASED_POINT_SIZE_RANGE_MAX; 1598 break; 1599 case GL_DEPTH_RANGE: 1600 params[0] = mState.zNear; 1601 params[1] = mState.zFar; 1602 break; 1603 case GL_COLOR_CLEAR_VALUE: 1604 params[0] = mState.colorClearValue.red; 1605 params[1] = mState.colorClearValue.green; 1606 params[2] = mState.colorClearValue.blue; 1607 params[3] = mState.colorClearValue.alpha; 1608 break; 1609 case GL_BLEND_COLOR: 1610 params[0] = mState.blendColor.red; 1611 params[1] = mState.blendColor.green; 1612 params[2] = mState.blendColor.blue; 1613 params[3] = mState.blendColor.alpha; 1614 break; 1615 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: 1616 *params = MAX_TEXTURE_MAX_ANISOTROPY; 1617 break; 1618 default: 1619 return false; 1620 } 1621 1622 return true; 1623} 1624 1625bool Context::getIntegerv(GLenum pname, GLint *params) 1626{ 1627 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation 1628 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names 1629 // GetIntegerv as its native query function. As it would require conversion in any 1630 // case, this should make no difference to the calling application. You may find it in 1631 // Context::getFloatv. 1632 switch (pname) 1633 { 1634 case GL_MAX_VERTEX_ATTRIBS: *params = MAX_VERTEX_ATTRIBS; break; 1635 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = MAX_VERTEX_UNIFORM_VECTORS; break; 1636 case GL_MAX_VARYING_VECTORS: *params = MAX_VARYING_VECTORS; break; 1637 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = MAX_COMBINED_TEXTURE_IMAGE_UNITS; break; 1638 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = MAX_VERTEX_TEXTURE_IMAGE_UNITS; break; 1639 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = MAX_TEXTURE_IMAGE_UNITS; break; 1640 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = MAX_FRAGMENT_UNIFORM_VECTORS; break; 1641 case GL_MAX_RENDERBUFFER_SIZE: *params = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; break; 1642 case GL_NUM_SHADER_BINARY_FORMATS: *params = 0; break; 1643 case GL_SHADER_BINARY_FORMATS: /* no shader binary formats are supported */ break; 1644 case GL_ARRAY_BUFFER_BINDING: *params = mState.arrayBuffer.name(); break; 1645 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = mState.elementArrayBuffer.name(); break; 1646// case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 1647 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mState.drawFramebuffer; break; 1648 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mState.readFramebuffer; break; 1649 case GL_RENDERBUFFER_BINDING: *params = mState.renderbuffer.name(); break; 1650 case GL_CURRENT_PROGRAM: *params = mState.currentProgram; break; 1651 case GL_PACK_ALIGNMENT: *params = mState.packAlignment; break; 1652 case GL_UNPACK_ALIGNMENT: *params = mState.unpackAlignment; break; 1653 case GL_GENERATE_MIPMAP_HINT: *params = mState.generateMipmapHint; break; 1654 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; break; 1655 case GL_ACTIVE_TEXTURE: *params = (mState.activeSampler + GL_TEXTURE0); break; 1656 case GL_STENCIL_FUNC: *params = mState.stencilFunc; break; 1657 case GL_STENCIL_REF: *params = mState.stencilRef; break; 1658 case GL_STENCIL_VALUE_MASK: *params = mState.stencilMask; break; 1659 case GL_STENCIL_BACK_FUNC: *params = mState.stencilBackFunc; break; 1660 case GL_STENCIL_BACK_REF: *params = mState.stencilBackRef; break; 1661 case GL_STENCIL_BACK_VALUE_MASK: *params = mState.stencilBackMask; break; 1662 case GL_STENCIL_FAIL: *params = mState.stencilFail; break; 1663 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mState.stencilPassDepthFail; break; 1664 case GL_STENCIL_PASS_DEPTH_PASS: *params = mState.stencilPassDepthPass; break; 1665 case GL_STENCIL_BACK_FAIL: *params = mState.stencilBackFail; break; 1666 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mState.stencilBackPassDepthFail; break; 1667 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mState.stencilBackPassDepthPass; break; 1668 case GL_DEPTH_FUNC: *params = mState.depthFunc; break; 1669 case GL_BLEND_SRC_RGB: *params = mState.sourceBlendRGB; break; 1670 case GL_BLEND_SRC_ALPHA: *params = mState.sourceBlendAlpha; break; 1671 case GL_BLEND_DST_RGB: *params = mState.destBlendRGB; break; 1672 case GL_BLEND_DST_ALPHA: *params = mState.destBlendAlpha; break; 1673 case GL_BLEND_EQUATION_RGB: *params = mState.blendEquationRGB; break; 1674 case GL_BLEND_EQUATION_ALPHA: *params = mState.blendEquationAlpha; break; 1675 case GL_STENCIL_WRITEMASK: *params = mState.stencilWritemask; break; 1676 case GL_STENCIL_BACK_WRITEMASK: *params = mState.stencilBackWritemask; break; 1677 case GL_STENCIL_CLEAR_VALUE: *params = mState.stencilClearValue; break; 1678 case GL_SUBPIXEL_BITS: *params = 4; break; 1679 case GL_MAX_TEXTURE_SIZE: *params = IMPLEMENTATION_MAX_TEXTURE_SIZE; break; 1680 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE; break; 1681 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: *params = NUM_COMPRESSED_TEXTURE_FORMATS; break; 1682 case GL_MAX_SAMPLES_ANGLE: *params = IMPLEMENTATION_MAX_SAMPLES; break; 1683 case GL_SAMPLE_BUFFERS: 1684 case GL_SAMPLES: 1685 { 1686 Framebuffer *framebuffer = getDrawFramebuffer(); 1687 int width, height, samples; 1688 1689 if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE) 1690 { 1691 switch(pname) 1692 { 1693 case GL_SAMPLE_BUFFERS: 1694 if(samples > 1) 1695 { 1696 *params = 1; 1697 } 1698 else 1699 { 1700 *params = 0; 1701 } 1702 break; 1703 case GL_SAMPLES: 1704 *params = samples & ~1; 1705 break; 1706 } 1707 } 1708 else 1709 { 1710 *params = 0; 1711 } 1712 } 1713 break; 1714 case GL_IMPLEMENTATION_COLOR_READ_TYPE: 1715 { 1716 Framebuffer *framebuffer = getReadFramebuffer(); 1717 *params = framebuffer->getImplementationColorReadType(); 1718 } 1719 break; 1720 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: 1721 { 1722 Framebuffer *framebuffer = getReadFramebuffer(); 1723 *params = framebuffer->getImplementationColorReadFormat(); 1724 } 1725 break; 1726 case GL_MAX_VIEWPORT_DIMS: 1727 { 1728 int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; 1729 params[0] = maxDimension; 1730 params[1] = maxDimension; 1731 } 1732 break; 1733 case GL_COMPRESSED_TEXTURE_FORMATS: 1734 { 1735 for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++) 1736 { 1737 params[i] = compressedTextureFormats[i]; 1738 } 1739 } 1740 break; 1741 case GL_VIEWPORT: 1742 params[0] = mState.viewportX; 1743 params[1] = mState.viewportY; 1744 params[2] = mState.viewportWidth; 1745 params[3] = mState.viewportHeight; 1746 break; 1747 case GL_SCISSOR_BOX: 1748 params[0] = mState.scissorX; 1749 params[1] = mState.scissorY; 1750 params[2] = mState.scissorWidth; 1751 params[3] = mState.scissorHeight; 1752 break; 1753 case GL_CULL_FACE_MODE: *params = mState.cullMode; break; 1754 case GL_FRONT_FACE: *params = mState.frontFace; break; 1755 case GL_RED_BITS: 1756 case GL_GREEN_BITS: 1757 case GL_BLUE_BITS: 1758 case GL_ALPHA_BITS: 1759 { 1760 Framebuffer *framebuffer = getDrawFramebuffer(); 1761 Renderbuffer *colorbuffer = framebuffer->getColorbuffer(); 1762 1763 if(colorbuffer) 1764 { 1765 switch (pname) 1766 { 1767 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break; 1768 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break; 1769 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break; 1770 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break; 1771 } 1772 } 1773 else 1774 { 1775 *params = 0; 1776 } 1777 } 1778 break; 1779 case GL_DEPTH_BITS: 1780 { 1781 Framebuffer *framebuffer = getDrawFramebuffer(); 1782 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer(); 1783 1784 if(depthbuffer) 1785 { 1786 *params = depthbuffer->getDepthSize(); 1787 } 1788 else 1789 { 1790 *params = 0; 1791 } 1792 } 1793 break; 1794 case GL_STENCIL_BITS: 1795 { 1796 Framebuffer *framebuffer = getDrawFramebuffer(); 1797 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer(); 1798 1799 if(stencilbuffer) 1800 { 1801 *params = stencilbuffer->getStencilSize(); 1802 } 1803 else 1804 { 1805 *params = 0; 1806 } 1807 } 1808 break; 1809 case GL_TEXTURE_BINDING_2D: 1810 { 1811 if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) 1812 { 1813 error(GL_INVALID_OPERATION); 1814 return false; 1815 } 1816 1817 *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name(); 1818 } 1819 break; 1820 case GL_TEXTURE_BINDING_CUBE_MAP: 1821 { 1822 if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) 1823 { 1824 error(GL_INVALID_OPERATION); 1825 return false; 1826 } 1827 1828 *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name(); 1829 } 1830 break; 1831 case GL_TEXTURE_BINDING_EXTERNAL_OES: 1832 { 1833 if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) 1834 { 1835 error(GL_INVALID_OPERATION); 1836 return false; 1837 } 1838 1839 *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name(); 1840 } 1841 break; 1842 case GL_TEXTURE_BINDING_3D_OES: 1843 case GL_TEXTURE_BINDING_2D_ARRAY: // GLES 3.0 1844 { 1845 if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) 1846 { 1847 error(GL_INVALID_OPERATION); 1848 return false; 1849 } 1850 1851 *params = mState.samplerTexture[TEXTURE_3D][mState.activeSampler].name(); 1852 } 1853 break; 1854 case GL_COPY_READ_BUFFER_BINDING: // name, initially 0 1855 if(clientVersion >= 3) 1856 { 1857 *params = mState.copyReadBuffer.name(); 1858 } 1859 else 1860 { 1861 return false; 1862 } 1863 break; 1864 case GL_COPY_WRITE_BUFFER_BINDING: // name, initially 0 1865 if(clientVersion >= 3) 1866 { 1867 *params = mState.copyWriteBuffer.name(); 1868 } 1869 else 1870 { 1871 return false; 1872 } 1873 break; 1874 case GL_DRAW_BUFFER0: // symbolic constant, initial value is GL_BACK 1875 UNIMPLEMENTED(); 1876 *params = GL_BACK; 1877 break; 1878 case GL_DRAW_BUFFER1: // symbolic constant, initial value is GL_NONE 1879 case GL_DRAW_BUFFER2: 1880 case GL_DRAW_BUFFER3: 1881 case GL_DRAW_BUFFER4: 1882 case GL_DRAW_BUFFER5: 1883 case GL_DRAW_BUFFER6: 1884 case GL_DRAW_BUFFER7: 1885 case GL_DRAW_BUFFER8: 1886 case GL_DRAW_BUFFER9: 1887 case GL_DRAW_BUFFER10: 1888 case GL_DRAW_BUFFER11: 1889 case GL_DRAW_BUFFER12: 1890 case GL_DRAW_BUFFER13: 1891 case GL_DRAW_BUFFER14: 1892 case GL_DRAW_BUFFER15: 1893 UNIMPLEMENTED(); 1894 *params = GL_NONE; 1895 break; 1896 case GL_MAJOR_VERSION: // integer, at least 3 1897 UNIMPLEMENTED(); 1898 *params = 3; 1899 break; 1900 case GL_MAX_3D_TEXTURE_SIZE: // GLint, at least 2048 1901 UNIMPLEMENTED(); 1902 *params = 2048; 1903 break; 1904 case GL_MAX_ARRAY_TEXTURE_LAYERS: // GLint, at least 2048 1905 UNIMPLEMENTED(); 1906 *params = 2048; 1907 break; 1908 case GL_MAX_COLOR_ATTACHMENTS: // integer, at least 8 1909 UNIMPLEMENTED(); 1910 *params = IMPLEMENTATION_MAX_COLOR_ATTACHMENTS; 1911 break; 1912 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: // integer, at least 50048 1913 UNIMPLEMENTED(); 1914 *params = MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS; 1915 break; 1916 case GL_MAX_COMBINED_UNIFORM_BLOCKS: // integer, at least 70 1917 UNIMPLEMENTED(); 1918 *params = 70; 1919 break; 1920 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: // integer, at least 50176 1921 UNIMPLEMENTED(); 1922 *params = MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS; 1923 break; 1924 case GL_MAX_DRAW_BUFFERS: // integer, at least 8 1925 UNIMPLEMENTED(); 1926 *params = IMPLEMENTATION_MAX_DRAW_BUFFERS; 1927 break; 1928 case GL_MAX_ELEMENT_INDEX: // integer, at least 16777215 1929 UNIMPLEMENTED(); 1930 *params = 16777215; 1931 break; 1932 case GL_MAX_ELEMENTS_INDICES: // integer 1933 UNIMPLEMENTED(); 1934 *params = 0; 1935 break; 1936 case GL_MAX_ELEMENTS_VERTICES: // integer 1937 UNIMPLEMENTED(); 1938 *params = 0; 1939 break; 1940 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: // integer, at least 128 1941 UNIMPLEMENTED(); 1942 *params = 128; 1943 break; 1944 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: // integer, at least 12 1945 UNIMPLEMENTED(); 1946 *params = 12; 1947 break; 1948 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: // integer, at least 1024 1949 UNIMPLEMENTED(); 1950 *params = 1024; 1951 break; 1952 case GL_MAX_PROGRAM_TEXEL_OFFSET: // integer, minimum is 7 1953 UNIMPLEMENTED(); 1954 *params = 7; 1955 break; 1956 case GL_MAX_SERVER_WAIT_TIMEOUT: // integer 1957 UNIMPLEMENTED(); 1958 *params = 0; 1959 break; 1960 case GL_MAX_TEXTURE_LOD_BIAS: // integer, at least 2.0 1961 UNIMPLEMENTED(); 1962 *params = 2; 1963 break; 1964 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: // integer, at least 64 1965 UNIMPLEMENTED(); 1966 *params = 64; 1967 break; 1968 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: // integer, at least 4 1969 UNIMPLEMENTED(); 1970 *params = IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS; 1971 break; 1972 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: // integer, at least 4 1973 UNIMPLEMENTED(); 1974 *params = 4; 1975 break; 1976 case GL_MAX_UNIFORM_BLOCK_SIZE: // integer, at least 16384 1977 UNIMPLEMENTED(); 1978 *params = 16384; 1979 break; 1980 case GL_MAX_UNIFORM_BUFFER_BINDINGS: // integer, at least 36 1981 UNIMPLEMENTED(); 1982 *params = IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS; 1983 break; 1984 case GL_MAX_VARYING_COMPONENTS: // integer, at least 60 1985 UNIMPLEMENTED(); 1986 *params = 60; 1987 break; 1988 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: // integer, at least 64 1989 UNIMPLEMENTED(); 1990 *params = 64; 1991 break; 1992 case GL_MAX_VERTEX_UNIFORM_BLOCKS: // integer, at least 12 1993 UNIMPLEMENTED(); 1994 *params = 12; 1995 break; 1996 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: // integer, at least 1024 1997 UNIMPLEMENTED(); 1998 *params = 1024; 1999 break; 2000 case GL_MIN_PROGRAM_TEXEL_OFFSET: // integer, maximum is -8 2001 UNIMPLEMENTED(); 2002 *params = -8; 2003 break; 2004 case GL_MINOR_VERSION: // integer 2005 UNIMPLEMENTED(); 2006 *params = 0; 2007 break; 2008 case GL_NUM_EXTENSIONS: // integer 2009 GLuint numExtensions; 2010 getExtensions(0, &numExtensions); 2011 *params = numExtensions; 2012 break; 2013 case GL_NUM_PROGRAM_BINARY_FORMATS: // integer, at least 0 2014 UNIMPLEMENTED(); 2015 *params = 0; 2016 break; 2017 case GL_PACK_ROW_LENGTH: // integer, initially 0 2018 UNIMPLEMENTED(); 2019 *params = 0; 2020 break; 2021 case GL_PACK_SKIP_PIXELS: // integer, initially 0 2022 UNIMPLEMENTED(); 2023 *params = 0; 2024 break; 2025 case GL_PACK_SKIP_ROWS: // integer, initially 0 2026 UNIMPLEMENTED(); 2027 *params = 0; 2028 break; 2029 case GL_PIXEL_PACK_BUFFER_BINDING: // integer, initially 0 2030 if(clientVersion >= 3) 2031 { 2032 *params = mState.pixelPackBuffer.name(); 2033 } 2034 else 2035 { 2036 return false; 2037 } 2038 break; 2039 case GL_PIXEL_UNPACK_BUFFER_BINDING: // integer, initially 0 2040 if(clientVersion >= 3) 2041 { 2042 *params = mState.pixelUnpackBuffer.name(); 2043 } 2044 else 2045 { 2046 return false; 2047 } 2048 break; 2049 case GL_PROGRAM_BINARY_FORMATS: // integer[GL_NUM_PROGRAM_BINARY_FORMATS] 2050 UNIMPLEMENTED(); 2051 *params = 0; 2052 break; 2053 case GL_READ_BUFFER: // symbolic constant, initial value is GL_BACK 2054 UNIMPLEMENTED(); 2055 *params = GL_BACK; 2056 break; 2057 case GL_SAMPLER_BINDING: // GLint, default 0 2058 UNIMPLEMENTED(); 2059 *params = 0; 2060 break; 2061 case GL_UNIFORM_BUFFER_BINDING: // name, initially 0 2062 if(clientVersion >= 3) 2063 { 2064 *params = mState.uniformBuffer.name(); 2065 } 2066 else 2067 { 2068 return false; 2069 } 2070 break; 2071 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: // integer, defaults to 1 2072 UNIMPLEMENTED(); 2073 *params = IMPLEMENTATION_UNIFORM_BUFFER_OFFSET_ALIGNMENT; 2074 break; 2075 case GL_UNIFORM_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0 2076 UNIMPLEMENTED(); 2077 *params = 0; 2078 break; 2079 case GL_UNIFORM_BUFFER_START: // indexed[n] 64-bit integer, initially 0 2080 UNIMPLEMENTED(); 2081 *params = 0; 2082 break; 2083 case GL_UNPACK_IMAGE_HEIGHT: // integer, initially 0 2084 UNIMPLEMENTED(); 2085 *params = 0; 2086 break; 2087 case GL_UNPACK_ROW_LENGTH: // integer, initially 0 2088 UNIMPLEMENTED(); 2089 *params = 0; 2090 break; 2091 case GL_UNPACK_SKIP_IMAGES: // integer, initially 0 2092 UNIMPLEMENTED(); 2093 *params = 0; 2094 break; 2095 case GL_UNPACK_SKIP_PIXELS: // integer, initially 0 2096 UNIMPLEMENTED(); 2097 *params = 0; 2098 break; 2099 case GL_UNPACK_SKIP_ROWS: // integer, initially 0 2100 UNIMPLEMENTED(); 2101 *params = 0; 2102 break; 2103 case GL_VERTEX_ARRAY_BINDING: // GLint, initially 0 2104 UNIMPLEMENTED(); 2105 *params = 0; 2106 break; 2107 default: 2108 return false; 2109 } 2110 2111 return true; 2112} 2113 2114bool Context::getTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param) 2115{ 2116 UNIMPLEMENTED(); 2117 2118 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback); 2119 if(!transformFeedback) 2120 { 2121 return false; 2122 } 2123 2124 switch(pname) 2125 { 2126 case GL_TRANSFORM_FEEDBACK_BINDING: // GLint, initially 0 2127 *param = 0; 2128 break; 2129 case GL_TRANSFORM_FEEDBACK_ACTIVE: // boolean, initially GL_FALSE 2130 *param = transformFeedback->isActive(); 2131 break; 2132 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: // name, initially 0 2133 *param = transformFeedback->name; 2134 break; 2135 case GL_TRANSFORM_FEEDBACK_PAUSED: // boolean, initially GL_FALSE 2136 *param = transformFeedback->isPaused(); 2137 break; 2138 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0 2139 if(transformFeedback->getGenericBuffer()) 2140 { 2141 *param = transformFeedback->getGenericBuffer()->size(); 2142 break; 2143 } 2144 else return false; 2145 case GL_TRANSFORM_FEEDBACK_BUFFER_START: // indexed[n] 64-bit integer, initially 0 2146 *param = 0; 2147 break; 2148 default: 2149 return false; 2150 } 2151 2152 return true; 2153} 2154 2155bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) 2156{ 2157 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation 2158 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due 2159 // to the fact that it is stored internally as a float, and so would require conversion 2160 // if returned from Context::getIntegerv. Since this conversion is already implemented 2161 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we 2162 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling 2163 // application. 2164 switch (pname) 2165 { 2166 case GL_COMPRESSED_TEXTURE_FORMATS: 2167 { 2168 *type = GL_INT; 2169 *numParams = NUM_COMPRESSED_TEXTURE_FORMATS; 2170 } 2171 break; 2172 case GL_SHADER_BINARY_FORMATS: 2173 { 2174 *type = GL_INT; 2175 *numParams = 0; 2176 } 2177 break; 2178 case GL_MAX_VERTEX_ATTRIBS: 2179 case GL_MAX_VERTEX_UNIFORM_VECTORS: 2180 case GL_MAX_VARYING_VECTORS: 2181 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: 2182 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: 2183 case GL_MAX_TEXTURE_IMAGE_UNITS: 2184 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: 2185 case GL_MAX_RENDERBUFFER_SIZE: 2186 case GL_NUM_SHADER_BINARY_FORMATS: 2187 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: 2188 case GL_ARRAY_BUFFER_BINDING: 2189 case GL_FRAMEBUFFER_BINDING: 2190 case GL_RENDERBUFFER_BINDING: 2191 case GL_CURRENT_PROGRAM: 2192 case GL_PACK_ALIGNMENT: 2193 case GL_UNPACK_ALIGNMENT: 2194 case GL_GENERATE_MIPMAP_HINT: 2195 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: 2196 case GL_RED_BITS: 2197 case GL_GREEN_BITS: 2198 case GL_BLUE_BITS: 2199 case GL_ALPHA_BITS: 2200 case GL_DEPTH_BITS: 2201 case GL_STENCIL_BITS: 2202 case GL_ELEMENT_ARRAY_BUFFER_BINDING: 2203 case GL_CULL_FACE_MODE: 2204 case GL_FRONT_FACE: 2205 case GL_ACTIVE_TEXTURE: 2206 case GL_STENCIL_FUNC: 2207 case GL_STENCIL_VALUE_MASK: 2208 case GL_STENCIL_REF: 2209 case GL_STENCIL_FAIL: 2210 case GL_STENCIL_PASS_DEPTH_FAIL: 2211 case GL_STENCIL_PASS_DEPTH_PASS: 2212 case GL_STENCIL_BACK_FUNC: 2213 case GL_STENCIL_BACK_VALUE_MASK: 2214 case GL_STENCIL_BACK_REF: 2215 case GL_STENCIL_BACK_FAIL: 2216 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: 2217 case GL_STENCIL_BACK_PASS_DEPTH_PASS: 2218 case GL_DEPTH_FUNC: 2219 case GL_BLEND_SRC_RGB: 2220 case GL_BLEND_SRC_ALPHA: 2221 case GL_BLEND_DST_RGB: 2222 case GL_BLEND_DST_ALPHA: 2223 case GL_BLEND_EQUATION_RGB: 2224 case GL_BLEND_EQUATION_ALPHA: 2225 case GL_STENCIL_WRITEMASK: 2226 case GL_STENCIL_BACK_WRITEMASK: 2227 case GL_STENCIL_CLEAR_VALUE: 2228 case GL_SUBPIXEL_BITS: 2229 case GL_MAX_TEXTURE_SIZE: 2230 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: 2231 case GL_SAMPLE_BUFFERS: 2232 case GL_SAMPLES: 2233 case GL_IMPLEMENTATION_COLOR_READ_TYPE: 2234 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: 2235 case GL_TEXTURE_BINDING_2D: 2236 case GL_TEXTURE_BINDING_CUBE_MAP: 2237 case GL_TEXTURE_BINDING_EXTERNAL_OES: 2238 case GL_TEXTURE_BINDING_3D_OES: 2239 case GL_COPY_READ_BUFFER_BINDING: 2240 case GL_COPY_WRITE_BUFFER_BINDING: 2241 case GL_DRAW_BUFFER0: 2242 case GL_DRAW_BUFFER1: 2243 case GL_DRAW_BUFFER2: 2244 case GL_DRAW_BUFFER3: 2245 case GL_DRAW_BUFFER4: 2246 case GL_DRAW_BUFFER5: 2247 case GL_DRAW_BUFFER6: 2248 case GL_DRAW_BUFFER7: 2249 case GL_DRAW_BUFFER8: 2250 case GL_DRAW_BUFFER9: 2251 case GL_DRAW_BUFFER10: 2252 case GL_DRAW_BUFFER11: 2253 case GL_DRAW_BUFFER12: 2254 case GL_DRAW_BUFFER13: 2255 case GL_DRAW_BUFFER14: 2256 case GL_DRAW_BUFFER15: 2257 case GL_MAJOR_VERSION: 2258 case GL_MAX_3D_TEXTURE_SIZE: 2259 case GL_MAX_ARRAY_TEXTURE_LAYERS: 2260 case GL_MAX_COLOR_ATTACHMENTS: 2261 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: 2262 case GL_MAX_COMBINED_UNIFORM_BLOCKS: 2263 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: 2264 case GL_MAX_DRAW_BUFFERS: 2265 case GL_MAX_ELEMENT_INDEX: 2266 case GL_MAX_ELEMENTS_INDICES: 2267 case GL_MAX_ELEMENTS_VERTICES: 2268 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: 2269 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: 2270 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: 2271 case GL_MAX_PROGRAM_TEXEL_OFFSET: 2272 case GL_MAX_SERVER_WAIT_TIMEOUT: 2273 case GL_MAX_TEXTURE_LOD_BIAS: 2274 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: 2275 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: 2276 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: 2277 case GL_MAX_UNIFORM_BLOCK_SIZE: 2278 case GL_MAX_UNIFORM_BUFFER_BINDINGS: 2279 case GL_MAX_VARYING_COMPONENTS: 2280 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: 2281 case GL_MAX_VERTEX_UNIFORM_BLOCKS: 2282 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: 2283 case GL_MIN_PROGRAM_TEXEL_OFFSET: 2284 case GL_MINOR_VERSION: 2285 case GL_NUM_EXTENSIONS: 2286 case GL_NUM_PROGRAM_BINARY_FORMATS: 2287 case GL_PACK_ROW_LENGTH: 2288 case GL_PACK_SKIP_PIXELS: 2289 case GL_PACK_SKIP_ROWS: 2290 case GL_PIXEL_PACK_BUFFER_BINDING: 2291 case GL_PIXEL_UNPACK_BUFFER_BINDING: 2292 case GL_PROGRAM_BINARY_FORMATS: 2293 case GL_READ_BUFFER: 2294 case GL_SAMPLER_BINDING: 2295 case GL_TEXTURE_BINDING_2D_ARRAY: 2296 case GL_UNIFORM_BUFFER_BINDING: 2297 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: 2298 case GL_UNIFORM_BUFFER_SIZE: 2299 case GL_UNIFORM_BUFFER_START: 2300 case GL_UNPACK_IMAGE_HEIGHT: 2301 case GL_UNPACK_ROW_LENGTH: 2302 case GL_UNPACK_SKIP_IMAGES: 2303 case GL_UNPACK_SKIP_PIXELS: 2304 case GL_UNPACK_SKIP_ROWS: 2305 case GL_VERTEX_ARRAY_BINDING: 2306 { 2307 *type = GL_INT; 2308 *numParams = 1; 2309 } 2310 break; 2311 case GL_MAX_SAMPLES_ANGLE: 2312 { 2313 *type = GL_INT; 2314 *numParams = 1; 2315 } 2316 break; 2317 case GL_MAX_VIEWPORT_DIMS: 2318 { 2319 *type = GL_INT; 2320 *numParams = 2; 2321 } 2322 break; 2323 case GL_VIEWPORT: 2324 case GL_SCISSOR_BOX: 2325 { 2326 *type = GL_INT; 2327 *numParams = 4; 2328 } 2329 break; 2330 case GL_SHADER_COMPILER: 2331 case GL_SAMPLE_COVERAGE_INVERT: 2332 case GL_DEPTH_WRITEMASK: 2333 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled, 2334 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries. 2335 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural 2336 case GL_SAMPLE_COVERAGE: 2337 case GL_SCISSOR_TEST: 2338 case GL_STENCIL_TEST: 2339 case GL_DEPTH_TEST: 2340 case GL_BLEND: 2341 case GL_DITHER: 2342 case GL_PRIMITIVE_RESTART_FIXED_INDEX: 2343 case GL_RASTERIZER_DISCARD: 2344 { 2345 *type = GL_BOOL; 2346 *numParams = 1; 2347 } 2348 break; 2349 case GL_COLOR_WRITEMASK: 2350 { 2351 *type = GL_BOOL; 2352 *numParams = 4; 2353 } 2354 break; 2355 case GL_POLYGON_OFFSET_FACTOR: 2356 case GL_POLYGON_OFFSET_UNITS: 2357 case GL_SAMPLE_COVERAGE_VALUE: 2358 case GL_DEPTH_CLEAR_VALUE: 2359 case GL_LINE_WIDTH: 2360 { 2361 *type = GL_FLOAT; 2362 *numParams = 1; 2363 } 2364 break; 2365 case GL_ALIASED_LINE_WIDTH_RANGE: 2366 case GL_ALIASED_POINT_SIZE_RANGE: 2367 case GL_DEPTH_RANGE: 2368 { 2369 *type = GL_FLOAT; 2370 *numParams = 2; 2371 } 2372 break; 2373 case GL_COLOR_CLEAR_VALUE: 2374 case GL_BLEND_COLOR: 2375 { 2376 *type = GL_FLOAT; 2377 *numParams = 4; 2378 } 2379 break; 2380 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: 2381 *type = GL_FLOAT; 2382 *numParams = 1; 2383 break; 2384 default: 2385 return false; 2386 } 2387 2388 return true; 2389} 2390 2391// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle 2392bool Context::applyRenderTarget() 2393{ 2394 Framebuffer *framebuffer = getDrawFramebuffer(); 2395 int width, height, samples; 2396 2397 if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE) 2398 { 2399 return error(GL_INVALID_FRAMEBUFFER_OPERATION, false); 2400 } 2401 2402 egl::Image *renderTarget = framebuffer->getRenderTarget(); 2403 device->setRenderTarget(renderTarget); 2404 if(renderTarget) renderTarget->release(); 2405 2406 egl::Image *depthStencil = framebuffer->getDepthStencil(); 2407 device->setDepthStencilSurface(depthStencil); 2408 if(depthStencil) depthStencil->release(); 2409 2410 Viewport viewport; 2411 float zNear = clamp01(mState.zNear); 2412 float zFar = clamp01(mState.zFar); 2413 2414 viewport.x0 = mState.viewportX; 2415 viewport.y0 = mState.viewportY; 2416 viewport.width = mState.viewportWidth; 2417 viewport.height = mState.viewportHeight; 2418 viewport.minZ = zNear; 2419 viewport.maxZ = zFar; 2420 2421 device->setViewport(viewport); 2422 2423 if(mState.scissorTest) 2424 { 2425 sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight}; 2426 scissor.clip(0, 0, width, height); 2427 2428 device->setScissorRect(scissor); 2429 device->setScissorEnable(true); 2430 } 2431 else 2432 { 2433 device->setScissorEnable(false); 2434 } 2435 2436 Program *program = getCurrentProgram(); 2437 2438 if(program) 2439 { 2440 GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear}; 2441 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]); 2442 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]); 2443 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]); 2444 } 2445 2446 return true; 2447} 2448 2449// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) 2450void Context::applyState(GLenum drawMode) 2451{ 2452 Framebuffer *framebuffer = getDrawFramebuffer(); 2453 2454 if(mState.cullFace) 2455 { 2456 device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace)); 2457 } 2458 else 2459 { 2460 device->setCullMode(sw::CULL_NONE); 2461 } 2462 2463 if(mDepthStateDirty) 2464 { 2465 if(mState.depthTest) 2466 { 2467 device->setDepthBufferEnable(true); 2468 device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc)); 2469 } 2470 else 2471 { 2472 device->setDepthBufferEnable(false); 2473 } 2474 2475 mDepthStateDirty = false; 2476 } 2477 2478 if(mBlendStateDirty) 2479 { 2480 if(mState.blend) 2481 { 2482 device->setAlphaBlendEnable(true); 2483 device->setSeparateAlphaBlendEnable(true); 2484 2485 device->setBlendConstant(es2sw::ConvertColor(mState.blendColor)); 2486 2487 device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB)); 2488 device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB)); 2489 device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB)); 2490 2491 device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha)); 2492 device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha)); 2493 device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha)); 2494 } 2495 else 2496 { 2497 device->setAlphaBlendEnable(false); 2498 } 2499 2500 mBlendStateDirty = false; 2501 } 2502 2503 if(mStencilStateDirty || mFrontFaceDirty) 2504 { 2505 if(mState.stencilTest && framebuffer->hasStencil()) 2506 { 2507 device->setStencilEnable(true); 2508 device->setTwoSidedStencil(true); 2509 2510 if(mState.stencilWritemask != mState.stencilBackWritemask || 2511 mState.stencilRef != mState.stencilBackRef || 2512 mState.stencilMask != mState.stencilBackMask) 2513 { 2514 ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL."); 2515 return error(GL_INVALID_OPERATION); 2516 } 2517 2518 // get the maximum size of the stencil ref 2519 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer(); 2520 GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1; 2521 2522 if(mState.frontFace == GL_CCW) 2523 { 2524 device->setStencilWriteMask(mState.stencilWritemask); 2525 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc)); 2526 2527 device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil); 2528 device->setStencilMask(mState.stencilMask); 2529 2530 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail)); 2531 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail)); 2532 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass)); 2533 2534 device->setStencilWriteMaskCCW(mState.stencilBackWritemask); 2535 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc)); 2536 2537 device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil); 2538 device->setStencilMaskCCW(mState.stencilBackMask); 2539 2540 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail)); 2541 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail)); 2542 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass)); 2543 } 2544 else 2545 { 2546 device->setStencilWriteMaskCCW(mState.stencilWritemask); 2547 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc)); 2548 2549 device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil); 2550 device->setStencilMaskCCW(mState.stencilMask); 2551 2552 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail)); 2553 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail)); 2554 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass)); 2555 2556 device->setStencilWriteMask(mState.stencilBackWritemask); 2557 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc)); 2558 2559 device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil); 2560 device->setStencilMask(mState.stencilBackMask); 2561 2562 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail)); 2563 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail)); 2564 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass)); 2565 } 2566 } 2567 else 2568 { 2569 device->setStencilEnable(false); 2570 } 2571 2572 mStencilStateDirty = false; 2573 mFrontFaceDirty = false; 2574 } 2575 2576 if(mMaskStateDirty) 2577 { 2578 device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha)); 2579 device->setDepthWriteEnable(mState.depthMask); 2580 2581 mMaskStateDirty = false; 2582 } 2583 2584 if(mPolygonOffsetStateDirty) 2585 { 2586 if(mState.polygonOffsetFill) 2587 { 2588 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer(); 2589 if(depthbuffer) 2590 { 2591 device->setSlopeDepthBias(mState.polygonOffsetFactor); 2592 float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize())); 2593 device->setDepthBias(depthBias); 2594 } 2595 } 2596 else 2597 { 2598 device->setSlopeDepthBias(0); 2599 device->setDepthBias(0); 2600 } 2601 2602 mPolygonOffsetStateDirty = false; 2603 } 2604 2605 if(mSampleStateDirty) 2606 { 2607 if(mState.sampleAlphaToCoverage) 2608 { 2609 device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE); 2610 } 2611 else 2612 { 2613 device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE); 2614 } 2615 2616 if(mState.sampleCoverage) 2617 { 2618 unsigned int mask = 0; 2619 if(mState.sampleCoverageValue != 0) 2620 { 2621 int width, height, samples; 2622 framebuffer->completeness(width, height, samples); 2623 2624 float threshold = 0.5f; 2625 2626 for(int i = 0; i < samples; i++) 2627 { 2628 mask <<= 1; 2629 2630 if((i + 1) * mState.sampleCoverageValue >= threshold) 2631 { 2632 threshold += 1.0f; 2633 mask |= 1; 2634 } 2635 } 2636 } 2637 2638 if(mState.sampleCoverageInvert) 2639 { 2640 mask = ~mask; 2641 } 2642 2643 device->setMultiSampleMask(mask); 2644 } 2645 else 2646 { 2647 device->setMultiSampleMask(0xFFFFFFFF); 2648 } 2649 2650 mSampleStateDirty = false; 2651 } 2652 2653 if(mDitherStateDirty) 2654 { 2655 // UNIMPLEMENTED(); // FIXME 2656 2657 mDitherStateDirty = false; 2658 } 2659} 2660 2661GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count) 2662{ 2663 TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS]; 2664 2665 GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes); 2666 if(err != GL_NO_ERROR) 2667 { 2668 return err; 2669 } 2670 2671 Program *program = getCurrentProgram(); 2672 2673 device->resetInputStreams(false); 2674 2675 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 2676 { 2677 if(program->getAttributeStream(i) == -1) 2678 { 2679 continue; 2680 } 2681 2682 sw::Resource *resource = attributes[i].vertexBuffer; 2683 const void *buffer = (char*)resource->data() + attributes[i].offset; 2684 2685 int stride = attributes[i].stride; 2686 2687 buffer = (char*)buffer + stride * base; 2688 2689 sw::Stream attribute(resource, buffer, stride); 2690 2691 attribute.type = attributes[i].type; 2692 attribute.count = attributes[i].count; 2693 attribute.normalized = attributes[i].normalized; 2694 2695 int stream = program->getAttributeStream(i); 2696 device->setInputStream(stream, attribute); 2697 } 2698 2699 return GL_NO_ERROR; 2700} 2701 2702// Applies the indices and element array bindings 2703GLenum Context::applyIndexBuffer(const void *indices, GLuint start, GLuint end, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) 2704{ 2705 GLenum err = mIndexDataManager->prepareIndexData(type, start, end, count, mState.elementArrayBuffer, indices, indexInfo); 2706 2707 if(err == GL_NO_ERROR) 2708 { 2709 device->setIndexBuffer(indexInfo->indexBuffer); 2710 } 2711 2712 return err; 2713} 2714 2715// Applies the shaders and shader constants 2716void Context::applyShaders() 2717{ 2718 Program *programObject = getCurrentProgram(); 2719 sw::VertexShader *vertexShader = programObject->getVertexShader(); 2720 sw::PixelShader *pixelShader = programObject->getPixelShader(); 2721 2722 device->setVertexShader(vertexShader); 2723 device->setPixelShader(pixelShader); 2724 2725 if(programObject->getSerial() != mAppliedProgramSerial) 2726 { 2727 programObject->dirtyAllUniforms(); 2728 mAppliedProgramSerial = programObject->getSerial(); 2729 } 2730 2731 programObject->applyUniforms(); 2732} 2733 2734void Context::applyTextures() 2735{ 2736 applyTextures(sw::SAMPLER_PIXEL); 2737 applyTextures(sw::SAMPLER_VERTEX); 2738} 2739 2740void Context::applyTextures(sw::SamplerType samplerType) 2741{ 2742 Program *programObject = getCurrentProgram(); 2743 2744 int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS; // Range of samplers of given sampler type 2745 2746 for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++) 2747 { 2748 int textureUnit = programObject->getSamplerMapping(samplerType, samplerIndex); // OpenGL texture image unit index 2749 2750 if(textureUnit != -1) 2751 { 2752 TextureType textureType = programObject->getSamplerTextureType(samplerType, samplerIndex); 2753 2754 Texture *texture = getSamplerTexture(textureUnit, textureType); 2755 2756 if(texture->isSamplerComplete()) 2757 { 2758 GLenum wrapS = texture->getWrapS(); 2759 GLenum wrapT = texture->getWrapT(); 2760 GLenum wrapR = texture->getWrapR(); 2761 GLenum texFilter = texture->getMinFilter(); 2762 GLenum magFilter = texture->getMagFilter(); 2763 GLfloat maxAnisotropy = texture->getMaxAnisotropy(); 2764 2765 device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS)); 2766 device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT)); 2767 device->setAddressingModeW(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapR)); 2768 2769 sw::FilterType minFilter; 2770 sw::MipmapType mipFilter; 2771 es2sw::ConvertMinFilter(texFilter, &minFilter, &mipFilter, maxAnisotropy); 2772 // ASSERT(minFilter == es2sw::ConvertMagFilter(magFilter)); 2773 2774 device->setTextureFilter(samplerType, samplerIndex, minFilter); 2775 // device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertMagFilter(magFilter)); 2776 device->setMipmapFilter(samplerType, samplerIndex, mipFilter); 2777 device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy); 2778 2779 applyTexture(samplerType, samplerIndex, texture); 2780 } 2781 else 2782 { 2783 applyTexture(samplerType, samplerIndex, 0); 2784 } 2785 } 2786 else 2787 { 2788 applyTexture(samplerType, samplerIndex, NULL); 2789 } 2790 } 2791} 2792 2793void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture) 2794{ 2795 Program *program = getCurrentProgram(); 2796 int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index; 2797 bool textureUsed = false; 2798 2799 if(type == sw::SAMPLER_PIXEL) 2800 { 2801 textureUsed = program->getPixelShader()->usesSampler(index); 2802 } 2803 else if(type == sw::SAMPLER_VERTEX) 2804 { 2805 textureUsed = program->getVertexShader()->usesSampler(index); 2806 } 2807 else UNREACHABLE(); 2808 2809 sw::Resource *resource = 0; 2810 2811 if(baseTexture && textureUsed) 2812 { 2813 resource = baseTexture->getResource(); 2814 } 2815 2816 device->setTextureResource(sampler, resource); 2817 2818 if(baseTexture && textureUsed) 2819 { 2820 int levelCount = baseTexture->getLevelCount(); 2821 2822 if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES) 2823 { 2824 Texture2D *texture = static_cast<Texture2D*>(baseTexture); 2825 2826 for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++) 2827 { 2828 int surfaceLevel = mipmapLevel; 2829 2830 if(surfaceLevel < 0) 2831 { 2832 surfaceLevel = 0; 2833 } 2834 else if(surfaceLevel >= levelCount) 2835 { 2836 surfaceLevel = levelCount - 1; 2837 } 2838 2839 egl::Image *surface = texture->getImage(surfaceLevel); 2840 device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D); 2841 } 2842 } 2843 else if(baseTexture->getTarget() == GL_TEXTURE_3D_OES) 2844 { 2845 Texture3D *texture = static_cast<Texture3D*>(baseTexture); 2846 2847 for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++) 2848 { 2849 int surfaceLevel = mipmapLevel; 2850 2851 if(surfaceLevel < 0) 2852 { 2853 surfaceLevel = 0; 2854 } 2855 else if(surfaceLevel >= levelCount) 2856 { 2857 surfaceLevel = levelCount - 1; 2858 } 2859 2860 egl::Image *surface = texture->getImage(surfaceLevel); 2861 device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_3D); 2862 } 2863 } 2864 else if(baseTexture->getTarget() == GL_TEXTURE_CUBE_MAP) 2865 { 2866 for(int face = 0; face < 6; face++) 2867 { 2868 TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture); 2869 2870 for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++) 2871 { 2872 int surfaceLevel = mipmapLevel; 2873 2874 if(surfaceLevel < 0) 2875 { 2876 surfaceLevel = 0; 2877 } 2878 else if(surfaceLevel >= levelCount) 2879 { 2880 surfaceLevel = levelCount - 1; 2881 } 2882 2883 egl::Image *surface = cubeTexture->getImage(face, surfaceLevel); 2884 device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE); 2885 } 2886 } 2887 } 2888 else UNIMPLEMENTED(); 2889 } 2890 else 2891 { 2892 device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL); 2893 } 2894} 2895 2896void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, 2897 GLenum format, GLenum type, GLsizei *bufSize, void* pixels) 2898{ 2899 Framebuffer *framebuffer = getReadFramebuffer(); 2900 int framebufferWidth, framebufferHeight, framebufferSamples; 2901 2902 if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE) 2903 { 2904 return error(GL_INVALID_FRAMEBUFFER_OPERATION); 2905 } 2906 2907 if(getReadFramebufferName() != 0 && framebufferSamples != 0) 2908 { 2909 return error(GL_INVALID_OPERATION); 2910 } 2911 2912 if(format != GL_RGBA || type != GL_UNSIGNED_BYTE) 2913 { 2914 if(format != framebuffer->getImplementationColorReadFormat() || type != framebuffer->getImplementationColorReadType()) 2915 { 2916 return error(GL_INVALID_OPERATION); 2917 } 2918 } 2919 2920 GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment); 2921 2922 // Sized query sanity check 2923 if(bufSize) 2924 { 2925 int requiredSize = outputPitch * height; 2926 if(requiredSize > *bufSize) 2927 { 2928 return error(GL_INVALID_OPERATION); 2929 } 2930 } 2931 2932 egl::Image *renderTarget = framebuffer->getRenderTarget(); 2933 2934 if(!renderTarget) 2935 { 2936 return error(GL_OUT_OF_MEMORY); 2937 } 2938 2939 sw::Rect rect = {x, y, x + width, y + height}; 2940 rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight()); 2941 2942 unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY); 2943 unsigned char *dest = (unsigned char*)pixels; 2944 int inputPitch = (int)renderTarget->getPitch(); 2945 2946 for(int j = 0; j < rect.y1 - rect.y0; j++) 2947 { 2948 unsigned short *dest16 = (unsigned short*)dest; 2949 unsigned int *dest32 = (unsigned int*)dest; 2950 2951 if(renderTarget->getInternalFormat() == sw::FORMAT_A8B8G8R8 && 2952 format == GL_RGBA && type == GL_UNSIGNED_BYTE) 2953 { 2954 memcpy(dest, source, (rect.x1 - rect.x0) * 4); 2955 } 2956 else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 && 2957 format == GL_RGBA && type == GL_UNSIGNED_BYTE) 2958 { 2959 for(int i = 0; i < rect.x1 - rect.x0; i++) 2960 { 2961 unsigned int argb = *(unsigned int*)(source + 4 * i); 2962 2963 dest32[i] = (argb & 0xFF00FF00) | ((argb & 0x000000FF) << 16) | ((argb & 0x00FF0000) >> 16); 2964 } 2965 } 2966 else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 && 2967 format == GL_RGBA && type == GL_UNSIGNED_BYTE) 2968 { 2969 for(int i = 0; i < rect.x1 - rect.x0; i++) 2970 { 2971 unsigned int xrgb = *(unsigned int*)(source + 4 * i); 2972 2973 dest32[i] = (xrgb & 0xFF00FF00) | ((xrgb & 0x000000FF) << 16) | ((xrgb & 0x00FF0000) >> 16) | 0xFF000000; 2974 } 2975 } 2976 else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 && 2977 format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) 2978 { 2979 for(int i = 0; i < rect.x1 - rect.x0; i++) 2980 { 2981 unsigned int xrgb = *(unsigned int*)(source + 4 * i); 2982 2983 dest32[i] = xrgb | 0xFF000000; 2984 } 2985 } 2986 else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 && 2987 format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) 2988 { 2989 memcpy(dest, source, (rect.x1 - rect.x0) * 4); 2990 } 2991 else if(renderTarget->getInternalFormat() == sw::FORMAT_A16B16G16R16F && 2992 format == GL_RGBA && type == GL_HALF_FLOAT_OES) 2993 { 2994 memcpy(dest, source, (rect.x1 - rect.x0) * 8); 2995 } 2996 else if(renderTarget->getInternalFormat() == sw::FORMAT_A32B32G32R32F && 2997 format == GL_RGBA && type == GL_FLOAT) 2998 { 2999 memcpy(dest, source, (rect.x1 - rect.x0) * 16); 3000 } 3001 else if(renderTarget->getInternalFormat() == sw::FORMAT_A1R5G5B5 && 3002 format == GL_BGRA_EXT && type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT) 3003 { 3004 memcpy(dest, source, (rect.x1 - rect.x0) * 2); 3005 } 3006 else if(renderTarget->getInternalFormat() == sw::FORMAT_R5G6B5 && 3007 format == 0x80E0 && type == GL_UNSIGNED_SHORT_5_6_5) // GL_BGR_EXT 3008 { 3009 memcpy(dest, source, (rect.x1 - rect.x0) * 2); 3010 } 3011 else 3012 { 3013 for(int i = 0; i < rect.x1 - rect.x0; i++) 3014 { 3015 float r; 3016 float g; 3017 float b; 3018 float a; 3019 3020 switch(renderTarget->getInternalFormat()) 3021 { 3022 case sw::FORMAT_R5G6B5: 3023 { 3024 unsigned short rgb = *(unsigned short*)(source + 2 * i); 3025 3026 a = 1.0f; 3027 b = (rgb & 0x001F) * (1.0f / 0x001F); 3028 g = (rgb & 0x07E0) * (1.0f / 0x07E0); 3029 r = (rgb & 0xF800) * (1.0f / 0xF800); 3030 } 3031 break; 3032 case sw::FORMAT_A1R5G5B5: 3033 { 3034 unsigned short argb = *(unsigned short*)(source + 2 * i); 3035 3036 a = (argb & 0x8000) ? 1.0f : 0.0f; 3037 b = (argb & 0x001F) * (1.0f / 0x001F); 3038 g = (argb & 0x03E0) * (1.0f / 0x03E0); 3039 r = (argb & 0x7C00) * (1.0f / 0x7C00); 3040 } 3041 break; 3042 case sw::FORMAT_A8R8G8B8: 3043 { 3044 unsigned int argb = *(unsigned int*)(source + 4 * i); 3045 3046 a = (argb & 0xFF000000) * (1.0f / 0xFF000000); 3047 b = (argb & 0x000000FF) * (1.0f / 0x000000FF); 3048 g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00); 3049 r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000); 3050 } 3051 break; 3052 case sw::FORMAT_A8B8G8R8: 3053 { 3054 unsigned int abgr = *(unsigned int*)(source + 4 * i); 3055 3056 a = (abgr & 0xFF000000) * (1.0f / 0xFF000000); 3057 b = (abgr & 0x00FF0000) * (1.0f / 0x00FF0000); 3058 g = (abgr & 0x0000FF00) * (1.0f / 0x0000FF00); 3059 r = (abgr & 0x000000FF) * (1.0f / 0x000000FF); 3060 } 3061 break; 3062 case sw::FORMAT_X8R8G8B8: 3063 { 3064 unsigned int xrgb = *(unsigned int*)(source + 4 * i); 3065 3066 a = 1.0f; 3067 b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF); 3068 g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00); 3069 r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000); 3070 } 3071 break; 3072 case sw::FORMAT_X8B8G8R8: 3073 { 3074 unsigned int xbgr = *(unsigned int*)(source + 4 * i); 3075 3076 a = 1.0f; 3077 b = (xbgr & 0x00FF0000) * (1.0f / 0x00FF0000); 3078 g = (xbgr & 0x0000FF00) * (1.0f / 0x0000FF00); 3079 r = (xbgr & 0x000000FF) * (1.0f / 0x000000FF); 3080 } 3081 break; 3082 case sw::FORMAT_A2R10G10B10: 3083 { 3084 unsigned int argb = *(unsigned int*)(source + 4 * i); 3085 3086 a = (argb & 0xC0000000) * (1.0f / 0xC0000000); 3087 b = (argb & 0x000003FF) * (1.0f / 0x000003FF); 3088 g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00); 3089 r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000); 3090 } 3091 break; 3092 case sw::FORMAT_A32B32G32R32F: 3093 { 3094 r = *((float*)(source + 16 * i) + 0); 3095 g = *((float*)(source + 16 * i) + 1); 3096 b = *((float*)(source + 16 * i) + 2); 3097 a = *((float*)(source + 16 * i) + 3); 3098 } 3099 break; 3100 case sw::FORMAT_A16B16G16R16F: 3101 { 3102 r = (float)*((sw::half*)(source + 8 * i) + 0); 3103 g = (float)*((sw::half*)(source + 8 * i) + 1); 3104 b = (float)*((sw::half*)(source + 8 * i) + 2); 3105 a = (float)*((sw::half*)(source + 8 * i) + 3); 3106 } 3107 break; 3108 default: 3109 UNIMPLEMENTED(); // FIXME 3110 UNREACHABLE(); 3111 } 3112 3113 switch(format) 3114 { 3115 case GL_RGBA: 3116 switch(type) 3117 { 3118 case GL_UNSIGNED_BYTE: 3119 dest[4 * i + 0] = (unsigned char)(255 * r + 0.5f); 3120 dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f); 3121 dest[4 * i + 2] = (unsigned char)(255 * b + 0.5f); 3122 dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f); 3123 break; 3124 default: UNREACHABLE(); 3125 } 3126 break; 3127 case GL_BGRA_EXT: 3128 switch(type) 3129 { 3130 case GL_UNSIGNED_BYTE: 3131 dest[4 * i + 0] = (unsigned char)(255 * b + 0.5f); 3132 dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f); 3133 dest[4 * i + 2] = (unsigned char)(255 * r + 0.5f); 3134 dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f); 3135 break; 3136 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: 3137 // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section 3138 // this type is packed as follows: 3139 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 3140 // -------------------------------------------------------------------------------- 3141 // | 4th | 3rd | 2nd | 1st component | 3142 // -------------------------------------------------------------------------------- 3143 // in the case of BGRA_EXT, B is the first component, G the second, and so forth. 3144 dest16[i] = 3145 ((unsigned short)(15 * a + 0.5f) << 12)| 3146 ((unsigned short)(15 * r + 0.5f) << 8) | 3147 ((unsigned short)(15 * g + 0.5f) << 4) | 3148 ((unsigned short)(15 * b + 0.5f) << 0); 3149 break; 3150 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: 3151 // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section 3152 // this type is packed as follows: 3153 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 3154 // -------------------------------------------------------------------------------- 3155 // | 4th | 3rd | 2nd | 1st component | 3156 // -------------------------------------------------------------------------------- 3157 // in the case of BGRA_EXT, B is the first component, G the second, and so forth. 3158 dest16[i] = 3159 ((unsigned short)( a + 0.5f) << 15) | 3160 ((unsigned short)(31 * r + 0.5f) << 10) | 3161 ((unsigned short)(31 * g + 0.5f) << 5) | 3162 ((unsigned short)(31 * b + 0.5f) << 0); 3163 break; 3164 default: UNREACHABLE(); 3165 } 3166 break; 3167 case GL_RGB: 3168 switch(type) 3169 { 3170 case GL_UNSIGNED_SHORT_5_6_5: 3171 dest16[i] = 3172 ((unsigned short)(31 * b + 0.5f) << 0) | 3173 ((unsigned short)(63 * g + 0.5f) << 5) | 3174 ((unsigned short)(31 * r + 0.5f) << 11); 3175 break; 3176 default: UNREACHABLE(); 3177 } 3178 break; 3179 default: UNREACHABLE(); 3180 } 3181 } 3182 } 3183 3184 source += inputPitch; 3185 dest += outputPitch; 3186 } 3187 3188 renderTarget->unlock(); 3189 renderTarget->release(); 3190} 3191 3192void Context::clear(GLbitfield mask) 3193{ 3194 Framebuffer *framebuffer = getDrawFramebuffer(); 3195 3196 if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) 3197 { 3198 return error(GL_INVALID_FRAMEBUFFER_OPERATION); 3199 } 3200 3201 if(!applyRenderTarget()) 3202 { 3203 return; 3204 } 3205 3206 unsigned int color = (unorm<8>(mState.colorClearValue.alpha) << 24) | 3207 (unorm<8>(mState.colorClearValue.red) << 16) | 3208 (unorm<8>(mState.colorClearValue.green) << 8) | 3209 (unorm<8>(mState.colorClearValue.blue) << 0); 3210 float depth = clamp01(mState.depthClearValue); 3211 int stencil = mState.stencilClearValue & 0x000000FF; 3212 3213 if(mask & GL_COLOR_BUFFER_BIT) 3214 { 3215 unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) | 3216 (mState.colorMaskGreen ? 0x2 : 0) | 3217 (mState.colorMaskBlue ? 0x4 : 0) | 3218 (mState.colorMaskAlpha ? 0x8 : 0); 3219 3220 if(rgbaMask != 0) 3221 { 3222 device->clearColor(color, rgbaMask); 3223 } 3224 } 3225 3226 if(mask & GL_DEPTH_BUFFER_BIT) 3227 { 3228 if(mState.depthMask != 0) 3229 { 3230 device->clearDepth(depth); 3231 } 3232 } 3233 3234 if(mask & GL_STENCIL_BUFFER_BIT) 3235 { 3236 if(mState.stencilWritemask != 0) 3237 { 3238 device->clearStencil(stencil, mState.stencilWritemask); 3239 } 3240 } 3241} 3242 3243void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount) 3244{ 3245 if(!mState.currentProgram) 3246 { 3247 return error(GL_INVALID_OPERATION); 3248 } 3249 3250 PrimitiveType primitiveType; 3251 int primitiveCount; 3252 3253 if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount)) 3254 return error(GL_INVALID_ENUM); 3255 3256 if(primitiveCount <= 0) 3257 { 3258 return; 3259 } 3260 3261 if(!applyRenderTarget()) 3262 { 3263 return; 3264 } 3265 3266 applyState(mode); 3267 3268 GLenum err = applyVertexBuffer(0, first, count); 3269 if(err != GL_NO_ERROR) 3270 { 3271 return error(err); 3272 } 3273 3274 applyShaders(); 3275 applyTextures(); 3276 3277 if(!getCurrentProgram()->validateSamplers(false)) 3278 { 3279 return error(GL_INVALID_OPERATION); 3280 } 3281 3282 if(!cullSkipsDraw(mode)) 3283 { 3284 device->drawPrimitive(primitiveType, primitiveCount); 3285 } 3286} 3287 3288void Context::drawElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount) 3289{ 3290 if(!mState.currentProgram) 3291 { 3292 return error(GL_INVALID_OPERATION); 3293 } 3294 3295 if(!indices && !mState.elementArrayBuffer) 3296 { 3297 return error(GL_INVALID_OPERATION); 3298 } 3299 3300 PrimitiveType primitiveType; 3301 int primitiveCount; 3302 3303 if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount)) 3304 return error(GL_INVALID_ENUM); 3305 3306 if(primitiveCount <= 0) 3307 { 3308 return; 3309 } 3310 3311 if(!applyRenderTarget()) 3312 { 3313 return; 3314 } 3315 3316 applyState(mode); 3317 3318 TranslatedIndexData indexInfo; 3319 GLenum err = applyIndexBuffer(indices, start, end, count, mode, type, &indexInfo); 3320 if(err != GL_NO_ERROR) 3321 { 3322 return error(err); 3323 } 3324 3325 GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1; 3326 err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount); 3327 if(err != GL_NO_ERROR) 3328 { 3329 return error(err); 3330 } 3331 3332 applyShaders(); 3333 applyTextures(); 3334 3335 if(!getCurrentProgram()->validateSamplers(false)) 3336 { 3337 return error(GL_INVALID_OPERATION); 3338 } 3339 3340 if(!cullSkipsDraw(mode)) 3341 { 3342 device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount, IndexDataManager::typeSize(type)); 3343 } 3344} 3345 3346void Context::finish() 3347{ 3348 device->finish(); 3349} 3350 3351void Context::flush() 3352{ 3353 // We don't queue anything without processing it as fast as possible 3354} 3355 3356void Context::recordInvalidEnum() 3357{ 3358 mInvalidEnum = true; 3359} 3360 3361void Context::recordInvalidValue() 3362{ 3363 mInvalidValue = true; 3364} 3365 3366void Context::recordInvalidOperation() 3367{ 3368 mInvalidOperation = true; 3369} 3370 3371void Context::recordOutOfMemory() 3372{ 3373 mOutOfMemory = true; 3374} 3375 3376void Context::recordInvalidFramebufferOperation() 3377{ 3378 mInvalidFramebufferOperation = true; 3379} 3380 3381// Get one of the recorded errors and clear its flag, if any. 3382// [OpenGL ES 2.0.24] section 2.5 page 13. 3383GLenum Context::getError() 3384{ 3385 if(mInvalidEnum) 3386 { 3387 mInvalidEnum = false; 3388 3389 return GL_INVALID_ENUM; 3390 } 3391 3392 if(mInvalidValue) 3393 { 3394 mInvalidValue = false; 3395 3396 return GL_INVALID_VALUE; 3397 } 3398 3399 if(mInvalidOperation) 3400 { 3401 mInvalidOperation = false; 3402 3403 return GL_INVALID_OPERATION; 3404 } 3405 3406 if(mOutOfMemory) 3407 { 3408 mOutOfMemory = false; 3409 3410 return GL_OUT_OF_MEMORY; 3411 } 3412 3413 if(mInvalidFramebufferOperation) 3414 { 3415 mInvalidFramebufferOperation = false; 3416 3417 return GL_INVALID_FRAMEBUFFER_OPERATION; 3418 } 3419 3420 return GL_NO_ERROR; 3421} 3422 3423int Context::getSupportedMultiSampleDepth(sw::Format format, int requested) 3424{ 3425 if(requested <= 1) 3426 { 3427 return 1; 3428 } 3429 3430 if(requested == 2) 3431 { 3432 return 2; 3433 } 3434 3435 return 4; 3436} 3437 3438void Context::detachBuffer(GLuint buffer) 3439{ 3440 // [OpenGL ES 2.0.24] section 2.9 page 22: 3441 // If a buffer object is deleted while it is bound, all bindings to that object in the current context 3442 // (i.e. in the thread that called Delete-Buffers) are reset to zero. 3443 3444 if(mState.arrayBuffer.name() == buffer) 3445 { 3446 mState.arrayBuffer = NULL; 3447 } 3448 3449 if(mState.elementArrayBuffer.name() == buffer) 3450 { 3451 mState.elementArrayBuffer = NULL; 3452 } 3453 3454 for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++) 3455 { 3456 if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer) 3457 { 3458 mState.vertexAttribute[attribute].mBoundBuffer = NULL; 3459 } 3460 } 3461} 3462 3463void Context::detachTexture(GLuint texture) 3464{ 3465 // [OpenGL ES 2.0.24] section 3.8 page 84: 3466 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are 3467 // rebound to texture object zero 3468 3469 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++) 3470 { 3471 for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++) 3472 { 3473 if(mState.samplerTexture[type][sampler].name() == texture) 3474 { 3475 mState.samplerTexture[type][sampler] = NULL; 3476 } 3477 } 3478 } 3479 3480 // [OpenGL ES 2.0.24] section 4.4 page 112: 3481 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is 3482 // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this 3483 // image was attached in the currently bound framebuffer. 3484 3485 Framebuffer *readFramebuffer = getReadFramebuffer(); 3486 Framebuffer *drawFramebuffer = getDrawFramebuffer(); 3487 3488 if(readFramebuffer) 3489 { 3490 readFramebuffer->detachTexture(texture); 3491 } 3492 3493 if(drawFramebuffer && drawFramebuffer != readFramebuffer) 3494 { 3495 drawFramebuffer->detachTexture(texture); 3496 } 3497} 3498 3499void Context::detachFramebuffer(GLuint framebuffer) 3500{ 3501 // [OpenGL ES 2.0.24] section 4.4 page 107: 3502 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though 3503 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero. 3504 3505 if(mState.readFramebuffer == framebuffer) 3506 { 3507 bindReadFramebuffer(0); 3508 } 3509 3510 if(mState.drawFramebuffer == framebuffer) 3511 { 3512 bindDrawFramebuffer(0); 3513 } 3514} 3515 3516void Context::detachRenderbuffer(GLuint renderbuffer) 3517{ 3518 // [OpenGL ES 2.0.24] section 4.4 page 109: 3519 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer 3520 // had been executed with the target RENDERBUFFER and name of zero. 3521 3522 if(mState.renderbuffer.name() == renderbuffer) 3523 { 3524 bindRenderbuffer(0); 3525 } 3526 3527 // [OpenGL ES 2.0.24] section 4.4 page 111: 3528 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer, 3529 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment 3530 // point to which this image was attached in the currently bound framebuffer. 3531 3532 Framebuffer *readFramebuffer = getReadFramebuffer(); 3533 Framebuffer *drawFramebuffer = getDrawFramebuffer(); 3534 3535 if(readFramebuffer) 3536 { 3537 readFramebuffer->detachRenderbuffer(renderbuffer); 3538 } 3539 3540 if(drawFramebuffer && drawFramebuffer != readFramebuffer) 3541 { 3542 drawFramebuffer->detachRenderbuffer(renderbuffer); 3543 } 3544} 3545 3546bool Context::cullSkipsDraw(GLenum drawMode) 3547{ 3548 return mState.cullFace && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode); 3549} 3550 3551bool Context::isTriangleMode(GLenum drawMode) 3552{ 3553 switch (drawMode) 3554 { 3555 case GL_TRIANGLES: 3556 case GL_TRIANGLE_FAN: 3557 case GL_TRIANGLE_STRIP: 3558 return true; 3559 case GL_POINTS: 3560 case GL_LINES: 3561 case GL_LINE_LOOP: 3562 case GL_LINE_STRIP: 3563 return false; 3564 default: UNREACHABLE(); 3565 } 3566 3567 return false; 3568} 3569 3570void Context::setVertexAttrib(GLuint index, const GLfloat *values) 3571{ 3572 ASSERT(index < MAX_VERTEX_ATTRIBS); 3573 3574 mState.vertexAttribute[index].setCurrentValue(values); 3575 3576 mVertexDataManager->dirtyCurrentValue(index); 3577} 3578 3579void Context::setVertexAttrib(GLuint index, const GLint *values) 3580{ 3581 ASSERT(index < MAX_VERTEX_ATTRIBS); 3582 3583 mState.vertexAttribute[index].setCurrentValue(values); 3584 3585 mVertexDataManager->dirtyCurrentValue(index); 3586} 3587 3588void Context::setVertexAttrib(GLuint index, const GLuint *values) 3589{ 3590 ASSERT(index < MAX_VERTEX_ATTRIBS); 3591 3592 mState.vertexAttribute[index].setCurrentValue(values); 3593 3594 mVertexDataManager->dirtyCurrentValue(index); 3595} 3596 3597void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 3598 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 3599 GLbitfield mask) 3600{ 3601 Framebuffer *readFramebuffer = getReadFramebuffer(); 3602 Framebuffer *drawFramebuffer = getDrawFramebuffer(); 3603 3604 int readBufferWidth, readBufferHeight, readBufferSamples; 3605 int drawBufferWidth, drawBufferHeight, drawBufferSamples; 3606 3607 if(!readFramebuffer || readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE || 3608 !drawFramebuffer || drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE) 3609 { 3610 return error(GL_INVALID_FRAMEBUFFER_OPERATION); 3611 } 3612 3613 if(drawBufferSamples > 1) 3614 { 3615 return error(GL_INVALID_OPERATION); 3616 } 3617 3618 sw::SliceRect sourceRect; 3619 sw::SliceRect destRect; 3620 bool flipX = (srcX0 < srcX1) ^ (dstX0 < dstX1); 3621 bool flipy = (srcY0 < srcY1) ^ (dstY0 < dstY1); 3622 3623 if(srcX0 < srcX1) 3624 { 3625 sourceRect.x0 = srcX0; 3626 sourceRect.x1 = srcX1; 3627 } 3628 else 3629 { 3630 sourceRect.x0 = srcX1; 3631 sourceRect.x1 = srcX0; 3632 } 3633 3634 if(dstX0 < dstX1) 3635 { 3636 destRect.x0 = dstX0; 3637 destRect.x1 = dstX1; 3638 } 3639 else 3640 { 3641 destRect.x0 = dstX1; 3642 destRect.x1 = dstX0; 3643 } 3644 3645 if(srcY0 < srcY1) 3646 { 3647 sourceRect.y0 = srcY0; 3648 sourceRect.y1 = srcY1; 3649 } 3650 else 3651 { 3652 sourceRect.y0 = srcY1; 3653 sourceRect.y1 = srcY0; 3654 } 3655 3656 if(dstY0 < dstY1) 3657 { 3658 destRect.y0 = dstY0; 3659 destRect.y1 = dstY1; 3660 } 3661 else 3662 { 3663 destRect.y0 = dstY1; 3664 destRect.y1 = dstY0; 3665 } 3666 3667 sw::Rect sourceScissoredRect = sourceRect; 3668 sw::Rect destScissoredRect = destRect; 3669 3670 if(mState.scissorTest) // Only write to parts of the destination framebuffer which pass the scissor test 3671 { 3672 if(destRect.x0 < mState.scissorX) 3673 { 3674 int xDiff = mState.scissorX - destRect.x0; 3675 destScissoredRect.x0 = mState.scissorX; 3676 sourceScissoredRect.x0 += xDiff; 3677 } 3678 3679 if(destRect.x1 > mState.scissorX + mState.scissorWidth) 3680 { 3681 int xDiff = destRect.x1 - (mState.scissorX + mState.scissorWidth); 3682 destScissoredRect.x1 = mState.scissorX + mState.scissorWidth; 3683 sourceScissoredRect.x1 -= xDiff; 3684 } 3685 3686 if(destRect.y0 < mState.scissorY) 3687 { 3688 int yDiff = mState.scissorY - destRect.y0; 3689 destScissoredRect.y0 = mState.scissorY; 3690 sourceScissoredRect.y0 += yDiff; 3691 } 3692 3693 if(destRect.y1 > mState.scissorY + mState.scissorHeight) 3694 { 3695 int yDiff = destRect.y1 - (mState.scissorY + mState.scissorHeight); 3696 destScissoredRect.y1 = mState.scissorY + mState.scissorHeight; 3697 sourceScissoredRect.y1 -= yDiff; 3698 } 3699 } 3700 3701 sw::Rect sourceTrimmedRect = sourceScissoredRect; 3702 sw::Rect destTrimmedRect = destScissoredRect; 3703 3704 // The source & destination rectangles also may need to be trimmed if they fall out of the bounds of 3705 // the actual draw and read surfaces. 3706 if(sourceTrimmedRect.x0 < 0) 3707 { 3708 int xDiff = 0 - sourceTrimmedRect.x0; 3709 sourceTrimmedRect.x0 = 0; 3710 destTrimmedRect.x0 += xDiff; 3711 } 3712 3713 if(sourceTrimmedRect.x1 > readBufferWidth) 3714 { 3715 int xDiff = sourceTrimmedRect.x1 - readBufferWidth; 3716 sourceTrimmedRect.x1 = readBufferWidth; 3717 destTrimmedRect.x1 -= xDiff; 3718 } 3719 3720 if(sourceTrimmedRect.y0 < 0) 3721 { 3722 int yDiff = 0 - sourceTrimmedRect.y0; 3723 sourceTrimmedRect.y0 = 0; 3724 destTrimmedRect.y0 += yDiff; 3725 } 3726 3727 if(sourceTrimmedRect.y1 > readBufferHeight) 3728 { 3729 int yDiff = sourceTrimmedRect.y1 - readBufferHeight; 3730 sourceTrimmedRect.y1 = readBufferHeight; 3731 destTrimmedRect.y1 -= yDiff; 3732 } 3733 3734 if(destTrimmedRect.x0 < 0) 3735 { 3736 int xDiff = 0 - destTrimmedRect.x0; 3737 destTrimmedRect.x0 = 0; 3738 sourceTrimmedRect.x0 += xDiff; 3739 } 3740 3741 if(destTrimmedRect.x1 > drawBufferWidth) 3742 { 3743 int xDiff = destTrimmedRect.x1 - drawBufferWidth; 3744 destTrimmedRect.x1 = drawBufferWidth; 3745 sourceTrimmedRect.x1 -= xDiff; 3746 } 3747 3748 if(destTrimmedRect.y0 < 0) 3749 { 3750 int yDiff = 0 - destTrimmedRect.y0; 3751 destTrimmedRect.y0 = 0; 3752 sourceTrimmedRect.y0 += yDiff; 3753 } 3754 3755 if(destTrimmedRect.y1 > drawBufferHeight) 3756 { 3757 int yDiff = destTrimmedRect.y1 - drawBufferHeight; 3758 destTrimmedRect.y1 = drawBufferHeight; 3759 sourceTrimmedRect.y1 -= yDiff; 3760 } 3761 3762 bool partialBufferCopy = false; 3763 3764 if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight || 3765 sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth || 3766 destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight || 3767 destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth || 3768 sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0) 3769 { 3770 partialBufferCopy = true; 3771 } 3772 3773 bool blitRenderTarget = false; 3774 bool blitDepthStencil = false; 3775 3776 if(mask & GL_COLOR_BUFFER_BIT) 3777 { 3778 const bool validReadType = readFramebuffer->getColorbufferType() == GL_TEXTURE_2D || 3779 readFramebuffer->getColorbufferType() == GL_RENDERBUFFER; 3780 const bool validDrawType = drawFramebuffer->getColorbufferType() == GL_TEXTURE_2D || 3781 drawFramebuffer->getColorbufferType() == GL_RENDERBUFFER; 3782 if(!validReadType || !validDrawType) 3783 { 3784 return error(GL_INVALID_OPERATION); 3785 } 3786 3787 if(partialBufferCopy && readBufferSamples > 1) 3788 { 3789 return error(GL_INVALID_OPERATION); 3790 } 3791 3792 blitRenderTarget = true; 3793 } 3794 3795 if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) 3796 { 3797 Renderbuffer *readDSBuffer = NULL; 3798 Renderbuffer *drawDSBuffer = NULL; 3799 3800 // We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have 3801 // both a depth and stencil buffer, it will be the same buffer. 3802 3803 if(mask & GL_DEPTH_BUFFER_BIT) 3804 { 3805 if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer()) 3806 { 3807 if(readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType()) 3808 { 3809 return error(GL_INVALID_OPERATION); 3810 } 3811 3812 blitDepthStencil = true; 3813 readDSBuffer = readFramebuffer->getDepthbuffer(); 3814 drawDSBuffer = drawFramebuffer->getDepthbuffer(); 3815 } 3816 } 3817 3818 if(mask & GL_STENCIL_BUFFER_BIT) 3819 { 3820 if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer()) 3821 { 3822 if(readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType()) 3823 { 3824 return error(GL_INVALID_OPERATION); 3825 } 3826 3827 blitDepthStencil = true; 3828 readDSBuffer = readFramebuffer->getStencilbuffer(); 3829 drawDSBuffer = drawFramebuffer->getStencilbuffer(); 3830 } 3831 } 3832 3833 if(partialBufferCopy) 3834 { 3835 ERR("Only whole-buffer depth and stencil blits are supported by this implementation."); 3836 return error(GL_INVALID_OPERATION); // Only whole-buffer copies are permitted 3837 } 3838 3839 if((drawDSBuffer && drawDSBuffer->getSamples() > 1) || 3840 (readDSBuffer && readDSBuffer->getSamples() > 1)) 3841 { 3842 return error(GL_INVALID_OPERATION); 3843 } 3844 } 3845 3846 if(blitRenderTarget || blitDepthStencil) 3847 { 3848 if(blitRenderTarget) 3849 { 3850 egl::Image *readRenderTarget = readFramebuffer->getRenderTarget(); 3851 egl::Image *drawRenderTarget = drawFramebuffer->getRenderTarget(); 3852 3853 if(flipX) 3854 { 3855 swap(destRect.x0, destRect.x1); 3856 } 3857 if(flipy) 3858 { 3859 swap(destRect.y0, destRect.y1); 3860 } 3861 3862 bool success = device->stretchRect(readRenderTarget, &sourceRect, drawRenderTarget, &destRect, false); 3863 3864 readRenderTarget->release(); 3865 drawRenderTarget->release(); 3866 3867 if(!success) 3868 { 3869 ERR("BlitFramebuffer failed."); 3870 return; 3871 } 3872 } 3873 3874 if(blitDepthStencil) 3875 { 3876 bool success = device->stretchRect(readFramebuffer->getDepthStencil(), NULL, drawFramebuffer->getDepthStencil(), NULL, false); 3877 3878 if(!success) 3879 { 3880 ERR("BlitFramebuffer failed."); 3881 return; 3882 } 3883 } 3884 } 3885} 3886 3887void Context::bindTexImage(egl::Surface *surface) 3888{ 3889 es2::Texture2D *textureObject = getTexture2D(); 3890 3891 if(textureObject) 3892 { 3893 textureObject->bindTexImage(surface); 3894 } 3895} 3896 3897EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel) 3898{ 3899 GLenum textureTarget = GL_NONE; 3900 3901 switch(target) 3902 { 3903 case EGL_GL_TEXTURE_2D_KHR: 3904 textureTarget = GL_TEXTURE_2D; 3905 break; 3906 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: 3907 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: 3908 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: 3909 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: 3910 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: 3911 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: 3912 textureTarget = GL_TEXTURE_CUBE_MAP; 3913 break; 3914 case EGL_GL_RENDERBUFFER_KHR: 3915 break; 3916 #if defined(__ANDROID__) 3917 case EGL_NATIVE_BUFFER_ANDROID: 3918 break; 3919 #endif 3920 default: 3921 return EGL_BAD_PARAMETER; 3922 } 3923 3924 if(textureLevel >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 3925 { 3926 return EGL_BAD_MATCH; 3927 } 3928 3929 if(textureTarget != GL_NONE) 3930 { 3931 es2::Texture *texture = getTexture(name); 3932 3933 if(!texture || texture->getTarget() != textureTarget) 3934 { 3935 return EGL_BAD_PARAMETER; 3936 } 3937 3938 if(texture->isShared(textureTarget, textureLevel)) // Bound to an EGLSurface or already an EGLImage sibling 3939 { 3940 return EGL_BAD_ACCESS; 3941 } 3942 3943 if(textureLevel != 0 && !texture->isSamplerComplete()) 3944 { 3945 return EGL_BAD_PARAMETER; 3946 } 3947 3948 if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1)) 3949 { 3950 return EGL_BAD_PARAMETER; 3951 } 3952 } 3953 else if(target == EGL_GL_RENDERBUFFER_KHR) 3954 { 3955 es2::Renderbuffer *renderbuffer = getRenderbuffer(name); 3956 3957 if(!renderbuffer) 3958 { 3959 return EGL_BAD_PARAMETER; 3960 } 3961 3962 if(renderbuffer->isShared()) // Already an EGLImage sibling 3963 { 3964 return EGL_BAD_ACCESS; 3965 } 3966 } 3967 #if defined(__ANDROID__) 3968 else if(target == EGL_NATIVE_BUFFER_ANDROID) 3969 { 3970 ANativeWindowBuffer *nativeBuffer = reinterpret_cast<ANativeWindowBuffer*>(name); 3971 3972 if(nativeBuffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) 3973 { 3974 return EGL_BAD_PARAMETER; 3975 } 3976 3977 if(nativeBuffer->common.version != sizeof(ANativeWindowBuffer)) 3978 { 3979 return EGL_BAD_PARAMETER; 3980 } 3981 3982 switch(nativeBuffer->format) 3983 { 3984 case HAL_PIXEL_FORMAT_RGBA_8888: 3985 case HAL_PIXEL_FORMAT_RGBX_8888: 3986 case HAL_PIXEL_FORMAT_RGB_565: 3987 break; 3988 default: 3989 return EGL_BAD_PARAMETER; 3990 } 3991 } 3992 #endif 3993 else UNREACHABLE(); 3994 3995 return EGL_SUCCESS; 3996} 3997 3998egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel) 3999{ 4000 GLenum textureTarget = GL_NONE; 4001 4002 switch(target) 4003 { 4004 case EGL_GL_TEXTURE_2D_KHR: textureTarget = GL_TEXTURE_2D; break; 4005 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break; 4006 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break; 4007 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break; 4008 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break; 4009 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break; 4010 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break; 4011 } 4012 4013 if(textureTarget != GL_NONE) 4014 { 4015 es2::Texture *texture = getTexture(name); 4016 4017 return texture->createSharedImage(textureTarget, textureLevel); 4018 } 4019 else if(target == EGL_GL_RENDERBUFFER_KHR) 4020 { 4021 es2::Renderbuffer *renderbuffer = getRenderbuffer(name); 4022 4023 return renderbuffer->createSharedImage(); 4024 } 4025 #if defined(__ANDROID__) 4026 else if(target == EGL_NATIVE_BUFFER_ANDROID) 4027 { 4028 ANativeWindowBuffer *nativeBuffer = reinterpret_cast<ANativeWindowBuffer*>(name); 4029 nativeBuffer->common.incRef(&nativeBuffer->common); 4030 4031 GLenum format = getColorFormatFromAndroid(nativeBuffer->format); 4032 GLenum type = getPixelFormatFromAndroid(nativeBuffer->format); 4033 4034 es2::Image *image = new Image(0, nativeBuffer->width, nativeBuffer->height, format, type); 4035 image->setNativeBuffer(nativeBuffer); 4036 image->markShared(); 4037 4038 return image; 4039 } 4040 #endif 4041 else UNREACHABLE(); 4042 4043 return 0; 4044} 4045 4046Device *Context::getDevice() 4047{ 4048 return device; 4049} 4050 4051const GLubyte* Context::getExtensions(GLuint index, GLuint* numExt) 4052{ 4053 // Keep list sorted in following order: 4054 // OES extensions 4055 // EXT extensions 4056 // Vendor extensions 4057 static const GLubyte* extensions[] = { 4058 (const GLubyte*)"GL_OES_compressed_ETC1_RGB8_texture", 4059 (const GLubyte*)"GL_OES_depth_texture", 4060 (const GLubyte*)"GL_OES_depth_texture_cube_map", 4061 (const GLubyte*)"GL_OES_EGL_image", 4062 (const GLubyte*)"GL_OES_EGL_image_external", 4063 (const GLubyte*)"GL_OES_element_index_uint", 4064 (const GLubyte*)"GL_OES_packed_depth_stencil", 4065 (const GLubyte*)"GL_OES_rgb8_rgba8", 4066 (const GLubyte*)"GL_OES_standard_derivatives", 4067 (const GLubyte*)"GL_OES_texture_float", 4068 (const GLubyte*)"GL_OES_texture_float_linear", 4069 (const GLubyte*)"GL_OES_texture_half_float", 4070 (const GLubyte*)"GL_OES_texture_half_float_linear", 4071 (const GLubyte*)"GL_OES_texture_npot", 4072 (const GLubyte*)"GL_OES_texture_3D", 4073 (const GLubyte*)"GL_EXT_blend_minmax", 4074 (const GLubyte*)"GL_EXT_occlusion_query_boolean", 4075 (const GLubyte*)"GL_EXT_read_format_bgra", 4076#if (S3TC_SUPPORT) 4077 (const GLubyte*)"GL_EXT_texture_compression_dxt1", 4078#endif 4079 (const GLubyte*)"GL_EXT_texture_filter_anisotropic", 4080 (const GLubyte*)"GL_EXT_texture_format_BGRA8888", 4081 (const GLubyte*)"GL_ANGLE_framebuffer_blit", 4082 (const GLubyte*)"GL_NV_framebuffer_blit", 4083 (const GLubyte*)"GL_ANGLE_framebuffer_multisample", 4084#if (S3TC_SUPPORT) 4085 (const GLubyte*)"GL_ANGLE_texture_compression_dxt3", 4086 (const GLubyte*)"GL_ANGLE_texture_compression_dxt5", 4087#endif 4088 (const GLubyte*)"GL_NV_fence", 4089 (const GLubyte*)"GL_EXT_instanced_arrays", 4090 }; 4091 static const GLuint numExtensions = sizeof(extensions) / sizeof(*extensions); 4092 4093 if(numExt) 4094 { 4095 *numExt = numExtensions; 4096 return nullptr; 4097 } 4098 4099 if(index == GL_INVALID_INDEX) 4100 { 4101 static GLubyte* extensionsCat = nullptr; 4102 if((extensionsCat == nullptr) && (numExtensions > 0)) 4103 { 4104 int totalLength = numExtensions; // 1 space between each extension name + terminating null 4105 for(int i = 0; i < numExtensions; ++i) 4106 { 4107 totalLength += strlen(reinterpret_cast<const char*>(extensions[i])); 4108 } 4109 extensionsCat = new GLubyte[totalLength]; 4110 extensionsCat[0] = '\0'; 4111 for(int i = 0; i < numExtensions; ++i) 4112 { 4113 if(i != 0) 4114 { 4115 strcat(reinterpret_cast<char*>(extensionsCat), " "); 4116 } 4117 strcat(reinterpret_cast<char*>(extensionsCat), reinterpret_cast<const char*>(extensions[i])); 4118 } 4119 } 4120 return extensionsCat; 4121 } 4122 4123 if(index >= numExtensions) 4124 { 4125 return nullptr; 4126 } 4127 4128 return extensions[index]; 4129} 4130 4131} 4132 4133egl::Context *es2CreateContext(const egl::Config *config, const egl::Context *shareContext, int clientVersion) 4134{ 4135 ASSERT(!shareContext || shareContext->getClientVersion() == clientVersion); // Should be checked by eglCreateContext 4136 return new es2::Context(config, static_cast<const es2::Context*>(shareContext), clientVersion); 4137} 4138