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