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