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