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