1 // 2 // Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // Context.cpp: Implements the gl::Context class, managing all GL state and performing 8 // rendering operations. It is the GLES2 specific implementation of EGLContext. 9 10 #include "libGLESv2/Context.h" 11 12 #include "libGLESv2/main.h" 13 #include "common/utilities.h" 14 #include "common/platform.h" 15 #include "libGLESv2/formatutils.h" 16 #include "libGLESv2/Buffer.h" 17 #include "libGLESv2/Fence.h" 18 #include "libGLESv2/Framebuffer.h" 19 #include "libGLESv2/FramebufferAttachment.h" 20 #include "libGLESv2/Renderbuffer.h" 21 #include "libGLESv2/Program.h" 22 #include "libGLESv2/ProgramBinary.h" 23 #include "libGLESv2/Query.h" 24 #include "libGLESv2/Texture.h" 25 #include "libGLESv2/ResourceManager.h" 26 #include "libGLESv2/renderer/d3d/IndexDataManager.h" 27 #include "libGLESv2/renderer/Renderer.h" 28 #include "libGLESv2/VertexArray.h" 29 #include "libGLESv2/Sampler.h" 30 #include "libGLESv2/validationES.h" 31 #include "libGLESv2/TransformFeedback.h" 32 33 #include "libEGL/Surface.h" 34 35 #include <sstream> 36 37 namespace gl 38 { 39 40 Context::Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) 41 : mRenderer(renderer) 42 { 43 ASSERT(robustAccess == false); // Unimplemented 44 45 initCaps(clientVersion); 46 mState.initialize(mCaps, clientVersion); 47 48 mClientVersion = clientVersion; 49 50 mFenceNVHandleAllocator.setBaseHandle(0); 51 52 if (shareContext != NULL) 53 { 54 mResourceManager = shareContext->mResourceManager; 55 mResourceManager->addRef(); 56 } 57 else 58 { 59 mResourceManager = new ResourceManager(mRenderer); 60 } 61 62 // [OpenGL ES 2.0.24] section 3.7 page 83: 63 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional 64 // and cube map texture state vectors respectively associated with them. 65 // In order that access to these initial textures not be lost, they are treated as texture 66 // objects all of whose names are 0. 67 68 mZeroTextures[GL_TEXTURE_2D].set(new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), 0)); 69 bindTexture(GL_TEXTURE_2D, 0); 70 71 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0)); 72 bindTexture(GL_TEXTURE_CUBE_MAP, 0); 73 74 if (mClientVersion >= 3) 75 { 76 // TODO: These could also be enabled via extension 77 mZeroTextures[GL_TEXTURE_3D].set(new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), 0)); 78 bindTexture(GL_TEXTURE_3D, 0); 79 80 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0)); 81 bindTexture(GL_TEXTURE_2D_ARRAY, 0); 82 } 83 84 bindVertexArray(0); 85 bindArrayBuffer(0); 86 bindElementArrayBuffer(0); 87 88 bindReadFramebuffer(0); 89 bindDrawFramebuffer(0); 90 bindRenderbuffer(0); 91 92 bindGenericUniformBuffer(0); 93 for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++) 94 { 95 bindIndexedUniformBuffer(0, i, 0, -1); 96 } 97 98 bindGenericTransformFeedbackBuffer(0); 99 for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) 100 { 101 bindIndexedTransformFeedbackBuffer(0, i, 0, -1); 102 } 103 104 bindCopyReadBuffer(0); 105 bindCopyWriteBuffer(0); 106 bindPixelPackBuffer(0); 107 bindPixelUnpackBuffer(0); 108 109 // [OpenGL ES 3.0.2] section 2.14.1 pg 85: 110 // In the initial state, a default transform feedback object is bound and treated as 111 // a transform feedback object with a name of zero. That object is bound any time 112 // BindTransformFeedback is called with id of zero 113 mTransformFeedbackZero.set(new TransformFeedback(mRenderer->createTransformFeedback(), 0)); 114 bindTransformFeedback(0); 115 116 mHasBeenCurrent = false; 117 mContextLost = false; 118 mResetStatus = GL_NO_ERROR; 119 mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT); 120 mRobustAccess = robustAccess; 121 122 mState.setContext(this); 123 } 124 125 Context::~Context() 126 { 127 GLuint currentProgram = mState.getCurrentProgramId(); 128 if (currentProgram != 0) 129 { 130 Program *programObject = mResourceManager->getProgram(currentProgram); 131 if (programObject) 132 { 133 programObject->release(); 134 } 135 currentProgram = 0; 136 } 137 mState.setCurrentProgram(0, NULL); 138 139 while (!mFramebufferMap.empty()) 140 { 141 deleteFramebuffer(mFramebufferMap.begin()->first); 142 } 143 144 while (!mFenceNVMap.empty()) 145 { 146 deleteFenceNV(mFenceNVMap.begin()->first); 147 } 148 149 while (!mQueryMap.empty()) 150 { 151 deleteQuery(mQueryMap.begin()->first); 152 } 153 154 while (!mVertexArrayMap.empty()) 155 { 156 deleteVertexArray(mVertexArrayMap.begin()->first); 157 } 158 159 mTransformFeedbackZero.set(NULL); 160 while (!mTransformFeedbackMap.empty()) 161 { 162 deleteTransformFeedback(mTransformFeedbackMap.begin()->first); 163 } 164 165 for (TextureMap::iterator i = mIncompleteTextures.begin(); i != mIncompleteTextures.end(); i++) 166 { 167 i->second.set(NULL); 168 } 169 mIncompleteTextures.clear(); 170 171 for (TextureMap::iterator i = mZeroTextures.begin(); i != mZeroTextures.end(); i++) 172 { 173 i->second.set(NULL); 174 } 175 mZeroTextures.clear(); 176 177 mResourceManager->release(); 178 } 179 180 void Context::makeCurrent(egl::Surface *surface) 181 { 182 if (!mHasBeenCurrent) 183 { 184 initRendererString(); 185 initExtensionStrings(); 186 187 mState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight()); 188 mState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight()); 189 190 mHasBeenCurrent = true; 191 } 192 193 // Wrap the existing swapchain resources into GL objects and assign them to the '0' names 194 rx::SwapChain *swapchain = surface->getSwapChain(); 195 196 Colorbuffer *colorbufferZero = new Colorbuffer(mRenderer, swapchain); 197 DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(mRenderer, swapchain); 198 Framebuffer *framebufferZero = new DefaultFramebuffer(mRenderer, colorbufferZero, depthStencilbufferZero); 199 200 setFramebufferZero(framebufferZero); 201 202 // Store the current client version in the renderer 203 mRenderer->setCurrentClientVersion(mClientVersion); 204 } 205 206 // NOTE: this function should not assume that this context is current! 207 void Context::markContextLost() 208 { 209 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT) 210 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT; 211 mContextLost = true; 212 } 213 214 bool Context::isContextLost() 215 { 216 return mContextLost; 217 } 218 219 GLuint Context::createBuffer() 220 { 221 return mResourceManager->createBuffer(); 222 } 223 224 GLuint Context::createProgram() 225 { 226 return mResourceManager->createProgram(); 227 } 228 229 GLuint Context::createShader(GLenum type) 230 { 231 return mResourceManager->createShader(type); 232 } 233 234 GLuint Context::createTexture() 235 { 236 return mResourceManager->createTexture(); 237 } 238 239 GLuint Context::createRenderbuffer() 240 { 241 return mResourceManager->createRenderbuffer(); 242 } 243 244 GLsync Context::createFenceSync(GLenum condition) 245 { 246 GLuint handle = mResourceManager->createFenceSync(); 247 248 gl::FenceSync *fenceSync = mResourceManager->getFenceSync(handle); 249 ASSERT(fenceSync); 250 251 fenceSync->set(condition); 252 253 return reinterpret_cast<GLsync>(handle); 254 } 255 256 GLuint Context::createVertexArray() 257 { 258 GLuint handle = mVertexArrayHandleAllocator.allocate(); 259 260 // Although the spec states VAO state is not initialized until the object is bound, 261 // we create it immediately. The resulting behaviour is transparent to the application, 262 // since it's not currently possible to access the state until the object is bound. 263 VertexArray *vertexArray = new VertexArray(mRenderer->createVertexArray(), handle, MAX_VERTEX_ATTRIBS); 264 mVertexArrayMap[handle] = vertexArray; 265 return handle; 266 } 267 268 GLuint Context::createSampler() 269 { 270 return mResourceManager->createSampler(); 271 } 272 273 GLuint Context::createTransformFeedback() 274 { 275 GLuint handle = mTransformFeedbackAllocator.allocate(); 276 TransformFeedback *transformFeedback = new TransformFeedback(mRenderer->createTransformFeedback(), handle); 277 transformFeedback->addRef(); 278 mTransformFeedbackMap[handle] = transformFeedback; 279 return handle; 280 } 281 282 // Returns an unused framebuffer name 283 GLuint Context::createFramebuffer() 284 { 285 GLuint handle = mFramebufferHandleAllocator.allocate(); 286 287 mFramebufferMap[handle] = NULL; 288 289 return handle; 290 } 291 292 GLuint Context::createFenceNV() 293 { 294 GLuint handle = mFenceNVHandleAllocator.allocate(); 295 296 mFenceNVMap[handle] = new FenceNV(mRenderer); 297 298 return handle; 299 } 300 301 // Returns an unused query name 302 GLuint Context::createQuery() 303 { 304 GLuint handle = mQueryHandleAllocator.allocate(); 305 306 mQueryMap[handle] = NULL; 307 308 return handle; 309 } 310 311 void Context::deleteBuffer(GLuint buffer) 312 { 313 if (mResourceManager->getBuffer(buffer)) 314 { 315 detachBuffer(buffer); 316 } 317 318 mResourceManager->deleteBuffer(buffer); 319 } 320 321 void Context::deleteShader(GLuint shader) 322 { 323 mResourceManager->deleteShader(shader); 324 } 325 326 void Context::deleteProgram(GLuint program) 327 { 328 mResourceManager->deleteProgram(program); 329 } 330 331 void Context::deleteTexture(GLuint texture) 332 { 333 if (mResourceManager->getTexture(texture)) 334 { 335 detachTexture(texture); 336 } 337 338 mResourceManager->deleteTexture(texture); 339 } 340 341 void Context::deleteRenderbuffer(GLuint renderbuffer) 342 { 343 if (mResourceManager->getRenderbuffer(renderbuffer)) 344 { 345 detachRenderbuffer(renderbuffer); 346 } 347 348 mResourceManager->deleteRenderbuffer(renderbuffer); 349 } 350 351 void Context::deleteFenceSync(GLsync fenceSync) 352 { 353 // The spec specifies the underlying Fence object is not deleted until all current 354 // wait commands finish. However, since the name becomes invalid, we cannot query the fence, 355 // and since our API is currently designed for being called from a single thread, we can delete 356 // the fence immediately. 357 mResourceManager->deleteFenceSync(reinterpret_cast<GLuint>(fenceSync)); 358 } 359 360 void Context::deleteVertexArray(GLuint vertexArray) 361 { 362 auto vertexArrayObject = mVertexArrayMap.find(vertexArray); 363 364 if (vertexArrayObject != mVertexArrayMap.end()) 365 { 366 detachVertexArray(vertexArray); 367 368 mVertexArrayHandleAllocator.release(vertexArrayObject->first); 369 delete vertexArrayObject->second; 370 mVertexArrayMap.erase(vertexArrayObject); 371 } 372 } 373 374 void Context::deleteSampler(GLuint sampler) 375 { 376 if (mResourceManager->getSampler(sampler)) 377 { 378 detachSampler(sampler); 379 } 380 381 mResourceManager->deleteSampler(sampler); 382 } 383 384 void Context::deleteTransformFeedback(GLuint transformFeedback) 385 { 386 TransformFeedbackMap::const_iterator iter = mTransformFeedbackMap.find(transformFeedback); 387 if (iter != mTransformFeedbackMap.end()) 388 { 389 detachTransformFeedback(transformFeedback); 390 mTransformFeedbackAllocator.release(transformFeedback); 391 iter->second->release(); 392 mTransformFeedbackMap.erase(iter); 393 } 394 } 395 396 void Context::deleteFramebuffer(GLuint framebuffer) 397 { 398 FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer); 399 400 if (framebufferObject != mFramebufferMap.end()) 401 { 402 detachFramebuffer(framebuffer); 403 404 mFramebufferHandleAllocator.release(framebufferObject->first); 405 delete framebufferObject->second; 406 mFramebufferMap.erase(framebufferObject); 407 } 408 } 409 410 void Context::deleteFenceNV(GLuint fence) 411 { 412 FenceNVMap::iterator fenceObject = mFenceNVMap.find(fence); 413 414 if (fenceObject != mFenceNVMap.end()) 415 { 416 mFenceNVHandleAllocator.release(fenceObject->first); 417 delete fenceObject->second; 418 mFenceNVMap.erase(fenceObject); 419 } 420 } 421 422 void Context::deleteQuery(GLuint query) 423 { 424 QueryMap::iterator queryObject = mQueryMap.find(query); 425 if (queryObject != mQueryMap.end()) 426 { 427 mQueryHandleAllocator.release(queryObject->first); 428 if (queryObject->second) 429 { 430 queryObject->second->release(); 431 } 432 mQueryMap.erase(queryObject); 433 } 434 } 435 436 Buffer *Context::getBuffer(GLuint handle) 437 { 438 return mResourceManager->getBuffer(handle); 439 } 440 441 Shader *Context::getShader(GLuint handle) const 442 { 443 return mResourceManager->getShader(handle); 444 } 445 446 Program *Context::getProgram(GLuint handle) const 447 { 448 return mResourceManager->getProgram(handle); 449 } 450 451 Texture *Context::getTexture(GLuint handle) const 452 { 453 return mResourceManager->getTexture(handle); 454 } 455 456 Renderbuffer *Context::getRenderbuffer(GLuint handle) 457 { 458 return mResourceManager->getRenderbuffer(handle); 459 } 460 461 FenceSync *Context::getFenceSync(GLsync handle) const 462 { 463 return mResourceManager->getFenceSync(reinterpret_cast<GLuint>(handle)); 464 } 465 466 VertexArray *Context::getVertexArray(GLuint handle) const 467 { 468 auto vertexArray = mVertexArrayMap.find(handle); 469 470 if (vertexArray == mVertexArrayMap.end()) 471 { 472 return NULL; 473 } 474 else 475 { 476 return vertexArray->second; 477 } 478 } 479 480 Sampler *Context::getSampler(GLuint handle) const 481 { 482 return mResourceManager->getSampler(handle); 483 } 484 485 TransformFeedback *Context::getTransformFeedback(GLuint handle) const 486 { 487 if (handle == 0) 488 { 489 return mTransformFeedbackZero.get(); 490 } 491 else 492 { 493 TransformFeedbackMap::const_iterator iter = mTransformFeedbackMap.find(handle); 494 return (iter != mTransformFeedbackMap.end()) ? iter->second : NULL; 495 } 496 } 497 498 bool Context::isSampler(GLuint samplerName) const 499 { 500 return mResourceManager->isSampler(samplerName); 501 } 502 503 void Context::bindArrayBuffer(unsigned int buffer) 504 { 505 mResourceManager->checkBufferAllocation(buffer); 506 507 mState.setArrayBufferBinding(getBuffer(buffer)); 508 } 509 510 void Context::bindElementArrayBuffer(unsigned int buffer) 511 { 512 mResourceManager->checkBufferAllocation(buffer); 513 514 mState.getVertexArray()->setElementArrayBuffer(getBuffer(buffer)); 515 } 516 517 void Context::bindTexture(GLenum target, GLuint texture) 518 { 519 mResourceManager->checkTextureAllocation(texture, target); 520 521 mState.setSamplerTexture(target, getTexture(texture)); 522 } 523 524 void Context::bindReadFramebuffer(GLuint framebuffer) 525 { 526 if (!getFramebuffer(framebuffer)) 527 { 528 mFramebufferMap[framebuffer] = new Framebuffer(mRenderer, framebuffer); 529 } 530 531 mState.setReadFramebufferBinding(getFramebuffer(framebuffer)); 532 } 533 534 void Context::bindDrawFramebuffer(GLuint framebuffer) 535 { 536 if (!getFramebuffer(framebuffer)) 537 { 538 mFramebufferMap[framebuffer] = new Framebuffer(mRenderer, framebuffer); 539 } 540 541 mState.setDrawFramebufferBinding(getFramebuffer(framebuffer)); 542 } 543 544 void Context::bindRenderbuffer(GLuint renderbuffer) 545 { 546 mResourceManager->checkRenderbufferAllocation(renderbuffer); 547 548 mState.setRenderbufferBinding(getRenderbuffer(renderbuffer)); 549 } 550 551 void Context::bindVertexArray(GLuint vertexArray) 552 { 553 if (!getVertexArray(vertexArray)) 554 { 555 VertexArray *vertexArrayObject = new VertexArray(mRenderer->createVertexArray(), vertexArray, MAX_VERTEX_ATTRIBS); 556 mVertexArrayMap[vertexArray] = vertexArrayObject; 557 } 558 559 mState.setVertexArrayBinding(getVertexArray(vertexArray)); 560 } 561 562 void Context::bindSampler(GLuint textureUnit, GLuint sampler) 563 { 564 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits); 565 mResourceManager->checkSamplerAllocation(sampler); 566 567 mState.setSamplerBinding(textureUnit, getSampler(sampler)); 568 } 569 570 void Context::bindGenericUniformBuffer(GLuint buffer) 571 { 572 mResourceManager->checkBufferAllocation(buffer); 573 574 mState.setGenericUniformBufferBinding(getBuffer(buffer)); 575 } 576 577 void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size) 578 { 579 mResourceManager->checkBufferAllocation(buffer); 580 581 mState.setIndexedUniformBufferBinding(index, getBuffer(buffer), offset, size); 582 } 583 584 void Context::bindGenericTransformFeedbackBuffer(GLuint buffer) 585 { 586 mResourceManager->checkBufferAllocation(buffer); 587 588 mState.setGenericTransformFeedbackBufferBinding(getBuffer(buffer)); 589 } 590 591 void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size) 592 { 593 mResourceManager->checkBufferAllocation(buffer); 594 595 mState.setIndexedTransformFeedbackBufferBinding(index, getBuffer(buffer), offset, size); 596 } 597 598 void Context::bindCopyReadBuffer(GLuint buffer) 599 { 600 mResourceManager->checkBufferAllocation(buffer); 601 602 mState.setCopyReadBufferBinding(getBuffer(buffer)); 603 } 604 605 void Context::bindCopyWriteBuffer(GLuint buffer) 606 { 607 mResourceManager->checkBufferAllocation(buffer); 608 609 mState.setCopyWriteBufferBinding(getBuffer(buffer)); 610 } 611 612 void Context::bindPixelPackBuffer(GLuint buffer) 613 { 614 mResourceManager->checkBufferAllocation(buffer); 615 616 mState.setPixelPackBufferBinding(getBuffer(buffer)); 617 } 618 619 void Context::bindPixelUnpackBuffer(GLuint buffer) 620 { 621 mResourceManager->checkBufferAllocation(buffer); 622 623 mState.setPixelUnpackBufferBinding(getBuffer(buffer)); 624 } 625 626 void Context::useProgram(GLuint program) 627 { 628 GLuint priorProgramId = mState.getCurrentProgramId(); 629 Program *priorProgram = mResourceManager->getProgram(priorProgramId); 630 631 if (priorProgramId != program) 632 { 633 mState.setCurrentProgram(program, mResourceManager->getProgram(program)); 634 635 if (priorProgram) 636 { 637 priorProgram->release(); 638 } 639 } 640 } 641 642 void Context::linkProgram(GLuint program) 643 { 644 Program *programObject = mResourceManager->getProgram(program); 645 646 bool linked = programObject->link(getCaps()); 647 648 // if the current program was relinked successfully we 649 // need to install the new executables 650 if (linked && program == mState.getCurrentProgramId()) 651 { 652 mState.setCurrentProgramBinary(programObject->getProgramBinary()); 653 } 654 } 655 656 void Context::setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length) 657 { 658 Program *programObject = mResourceManager->getProgram(program); 659 660 bool loaded = programObject->setProgramBinary(binaryFormat, binary, length); 661 662 // if the current program was reloaded successfully we 663 // need to install the new executables 664 if (loaded && program == mState.getCurrentProgramId()) 665 { 666 mState.setCurrentProgramBinary(programObject->getProgramBinary()); 667 } 668 669 } 670 671 void Context::bindTransformFeedback(GLuint transformFeedback) 672 { 673 mState.setTransformFeedbackBinding(getTransformFeedback(transformFeedback)); 674 } 675 676 Error Context::beginQuery(GLenum target, GLuint query) 677 { 678 Query *queryObject = getQuery(query, true, target); 679 ASSERT(queryObject); 680 681 // begin query 682 Error error = queryObject->begin(); 683 if (error.isError()) 684 { 685 return error; 686 } 687 688 // set query as active for specified target only if begin succeeded 689 mState.setActiveQuery(target, queryObject); 690 691 return Error(GL_NO_ERROR); 692 } 693 694 Error Context::endQuery(GLenum target) 695 { 696 Query *queryObject = mState.getActiveQuery(target); 697 ASSERT(queryObject); 698 699 gl::Error error = queryObject->end(); 700 701 // Always unbind the query, even if there was an error. This may delete the query object. 702 mState.setActiveQuery(target, NULL); 703 704 return error; 705 } 706 707 void Context::setFramebufferZero(Framebuffer *buffer) 708 { 709 // First, check to see if the old default framebuffer 710 // was set for draw or read framebuffer, and change 711 // the bindings to point to the new one before deleting it. 712 if (mState.getDrawFramebuffer()->id() == 0) 713 { 714 mState.setDrawFramebufferBinding(buffer); 715 } 716 717 if (mState.getReadFramebuffer()->id() == 0) 718 { 719 mState.setReadFramebufferBinding(buffer); 720 } 721 722 delete mFramebufferMap[0]; 723 mFramebufferMap[0] = buffer; 724 } 725 726 void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples) 727 { 728 ASSERT(getTextureCaps().get(internalformat).renderable); 729 730 RenderbufferStorage *renderbuffer = NULL; 731 732 const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat); 733 if (formatInfo.depthBits > 0 && formatInfo.stencilBits > 0) 734 { 735 renderbuffer = new gl::DepthStencilbuffer(mRenderer, width, height, samples); 736 } 737 else if (formatInfo.depthBits > 0) 738 { 739 renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples); 740 } 741 else if (formatInfo.stencilBits > 0) 742 { 743 renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples); 744 } 745 else 746 { 747 renderbuffer = new gl::Colorbuffer(mRenderer, width, height, internalformat, samples); 748 } 749 750 mState.getCurrentRenderbuffer()->setStorage(renderbuffer); 751 } 752 753 Framebuffer *Context::getFramebuffer(unsigned int handle) const 754 { 755 FramebufferMap::const_iterator framebuffer = mFramebufferMap.find(handle); 756 757 if (framebuffer == mFramebufferMap.end()) 758 { 759 return NULL; 760 } 761 else 762 { 763 return framebuffer->second; 764 } 765 } 766 767 FenceNV *Context::getFenceNV(unsigned int handle) 768 { 769 FenceNVMap::iterator fence = mFenceNVMap.find(handle); 770 771 if (fence == mFenceNVMap.end()) 772 { 773 return NULL; 774 } 775 else 776 { 777 return fence->second; 778 } 779 } 780 781 Query *Context::getQuery(unsigned int handle, bool create, GLenum type) 782 { 783 QueryMap::iterator query = mQueryMap.find(handle); 784 785 if (query == mQueryMap.end()) 786 { 787 return NULL; 788 } 789 else 790 { 791 if (!query->second && create) 792 { 793 query->second = new Query(mRenderer->createQuery(type), handle); 794 query->second->addRef(); 795 } 796 return query->second; 797 } 798 } 799 800 Texture *Context::getTargetTexture(GLenum target) const 801 { 802 if (!ValidTextureTarget(this, target)) 803 { 804 return NULL; 805 } 806 807 switch (target) 808 { 809 case GL_TEXTURE_2D: return getTexture2D(); 810 case GL_TEXTURE_CUBE_MAP: return getTextureCubeMap(); 811 case GL_TEXTURE_3D: return getTexture3D(); 812 case GL_TEXTURE_2D_ARRAY: return getTexture2DArray(); 813 default: return NULL; 814 } 815 } 816 817 Texture2D *Context::getTexture2D() const 818 { 819 return static_cast<Texture2D*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_2D)); 820 } 821 822 TextureCubeMap *Context::getTextureCubeMap() const 823 { 824 return static_cast<TextureCubeMap*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_CUBE_MAP)); 825 } 826 827 Texture3D *Context::getTexture3D() const 828 { 829 return static_cast<Texture3D*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_3D)); 830 } 831 832 Texture2DArray *Context::getTexture2DArray() const 833 { 834 return static_cast<Texture2DArray*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_2D_ARRAY)); 835 } 836 837 Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const 838 { 839 if (mState.getSamplerTextureId(sampler, type) == 0) 840 { 841 return mZeroTextures.at(type).get(); 842 } 843 else 844 { 845 return mState.getSamplerTexture(sampler, type); 846 } 847 } 848 849 void Context::getBooleanv(GLenum pname, GLboolean *params) 850 { 851 switch (pname) 852 { 853 case GL_SHADER_COMPILER: *params = GL_TRUE; break; 854 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break; 855 default: 856 mState.getBooleanv(pname, params); 857 break; 858 } 859 } 860 861 void Context::getFloatv(GLenum pname, GLfloat *params) 862 { 863 // Queries about context capabilities and maximums are answered by Context. 864 // Queries about current GL state values are answered by State. 865 switch (pname) 866 { 867 case GL_ALIASED_LINE_WIDTH_RANGE: 868 params[0] = mCaps.minAliasedLineWidth; 869 params[1] = mCaps.maxAliasedLineWidth; 870 break; 871 case GL_ALIASED_POINT_SIZE_RANGE: 872 params[0] = mCaps.minAliasedPointSize; 873 params[1] = mCaps.maxAliasedPointSize; 874 break; 875 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: 876 ASSERT(mExtensions.textureFilterAnisotropic); 877 *params = mExtensions.maxTextureAnisotropy; 878 break; 879 default: 880 mState.getFloatv(pname, params); 881 break; 882 } 883 } 884 885 void Context::getIntegerv(GLenum pname, GLint *params) 886 { 887 // Queries about context capabilities and maximums are answered by Context. 888 // Queries about current GL state values are answered by State. 889 890 switch (pname) 891 { 892 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break; 893 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break; 894 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break; 895 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break; 896 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break; 897 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break; 898 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break; 899 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break; 900 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break; 901 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break; 902 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break; 903 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break; 904 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break; 905 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 906 case GL_SUBPIXEL_BITS: *params = 4; break; 907 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break; 908 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break; 909 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break; 910 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break; 911 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break; 912 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break; 913 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break; 914 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break; 915 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break; 916 case GL_MAJOR_VERSION: *params = mClientVersion; break; 917 case GL_MINOR_VERSION: *params = 0; break; 918 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break; 919 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break; 920 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break; 921 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break; 922 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break; 923 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: *params = mCaps.compressedTextureFormats.size(); break; 924 case GL_MAX_SAMPLES_ANGLE: *params = mExtensions.maxSamples; break; 925 case GL_IMPLEMENTATION_COLOR_READ_TYPE: 926 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: 927 { 928 GLenum internalFormat, format, type; 929 getCurrentReadFormatType(&internalFormat, &format, &type); 930 if (pname == GL_IMPLEMENTATION_COLOR_READ_FORMAT) 931 *params = format; 932 else 933 *params = type; 934 } 935 break; 936 case GL_MAX_VIEWPORT_DIMS: 937 { 938 params[0] = mCaps.maxViewportWidth; 939 params[1] = mCaps.maxViewportHeight; 940 } 941 break; 942 case GL_COMPRESSED_TEXTURE_FORMATS: 943 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params); 944 break; 945 case GL_RESET_NOTIFICATION_STRATEGY_EXT: 946 *params = mResetStrategy; 947 break; 948 case GL_NUM_SHADER_BINARY_FORMATS: 949 *params = mCaps.shaderBinaryFormats.size(); 950 break; 951 case GL_SHADER_BINARY_FORMATS: 952 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params); 953 break; 954 case GL_NUM_PROGRAM_BINARY_FORMATS: 955 *params = mCaps.programBinaryFormats.size(); 956 break; 957 case GL_PROGRAM_BINARY_FORMATS: 958 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params); 959 break; 960 case GL_NUM_EXTENSIONS: 961 *params = static_cast<GLint>(mExtensionStrings.size()); 962 break; 963 default: 964 mState.getIntegerv(pname, params); 965 break; 966 } 967 } 968 969 void Context::getInteger64v(GLenum pname, GLint64 *params) 970 { 971 // Queries about context capabilities and maximums are answered by Context. 972 // Queries about current GL state values are answered by State. 973 switch (pname) 974 { 975 case GL_MAX_ELEMENT_INDEX: 976 *params = mCaps.maxElementIndex; 977 break; 978 case GL_MAX_UNIFORM_BLOCK_SIZE: 979 *params = mCaps.maxUniformBlockSize; 980 break; 981 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: 982 *params = mCaps.maxCombinedVertexUniformComponents; 983 break; 984 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: 985 *params = mCaps.maxCombinedFragmentUniformComponents; 986 break; 987 case GL_MAX_SERVER_WAIT_TIMEOUT: 988 *params = mCaps.maxServerWaitTimeout; 989 break; 990 default: 991 UNREACHABLE(); 992 break; 993 } 994 } 995 996 bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data) 997 { 998 // Queries about context capabilities and maximums are answered by Context. 999 // Queries about current GL state values are answered by State. 1000 // Indexed integer queries all refer to current state, so this function is a 1001 // mere passthrough. 1002 return mState.getIndexedIntegerv(target, index, data); 1003 } 1004 1005 bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data) 1006 { 1007 // Queries about context capabilities and maximums are answered by Context. 1008 // Queries about current GL state values are answered by State. 1009 // Indexed integer queries all refer to current state, so this function is a 1010 // mere passthrough. 1011 return mState.getIndexedInteger64v(target, index, data); 1012 } 1013 1014 bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) 1015 { 1016 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT) 1017 { 1018 *type = GL_INT; 1019 *numParams = 1; 1020 return true; 1021 } 1022 1023 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation 1024 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due 1025 // to the fact that it is stored internally as a float, and so would require conversion 1026 // if returned from Context::getIntegerv. Since this conversion is already implemented 1027 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we 1028 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling 1029 // application. 1030 switch (pname) 1031 { 1032 case GL_COMPRESSED_TEXTURE_FORMATS: 1033 { 1034 *type = GL_INT; 1035 *numParams = mCaps.compressedTextureFormats.size(); 1036 } 1037 return true; 1038 case GL_PROGRAM_BINARY_FORMATS_OES: 1039 { 1040 *type = GL_INT; 1041 *numParams = mCaps.programBinaryFormats.size(); 1042 } 1043 return true; 1044 case GL_SHADER_BINARY_FORMATS: 1045 { 1046 *type = GL_INT; 1047 *numParams = mCaps.shaderBinaryFormats.size(); 1048 } 1049 return true; 1050 case GL_MAX_VERTEX_ATTRIBS: 1051 case GL_MAX_VERTEX_UNIFORM_VECTORS: 1052 case GL_MAX_VARYING_VECTORS: 1053 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: 1054 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: 1055 case GL_MAX_TEXTURE_IMAGE_UNITS: 1056 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: 1057 case GL_MAX_RENDERBUFFER_SIZE: 1058 case GL_MAX_COLOR_ATTACHMENTS_EXT: 1059 case GL_MAX_DRAW_BUFFERS_EXT: 1060 case GL_NUM_SHADER_BINARY_FORMATS: 1061 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: 1062 case GL_ARRAY_BUFFER_BINDING: 1063 //case GL_FRAMEBUFFER_BINDING: // equivalent to DRAW_FRAMEBUFFER_BINDING_ANGLE 1064 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: 1065 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: 1066 case GL_RENDERBUFFER_BINDING: 1067 case GL_CURRENT_PROGRAM: 1068 case GL_PACK_ALIGNMENT: 1069 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: 1070 case GL_UNPACK_ALIGNMENT: 1071 case GL_GENERATE_MIPMAP_HINT: 1072 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: 1073 case GL_RED_BITS: 1074 case GL_GREEN_BITS: 1075 case GL_BLUE_BITS: 1076 case GL_ALPHA_BITS: 1077 case GL_DEPTH_BITS: 1078 case GL_STENCIL_BITS: 1079 case GL_ELEMENT_ARRAY_BUFFER_BINDING: 1080 case GL_CULL_FACE_MODE: 1081 case GL_FRONT_FACE: 1082 case GL_ACTIVE_TEXTURE: 1083 case GL_STENCIL_FUNC: 1084 case GL_STENCIL_VALUE_MASK: 1085 case GL_STENCIL_REF: 1086 case GL_STENCIL_FAIL: 1087 case GL_STENCIL_PASS_DEPTH_FAIL: 1088 case GL_STENCIL_PASS_DEPTH_PASS: 1089 case GL_STENCIL_BACK_FUNC: 1090 case GL_STENCIL_BACK_VALUE_MASK: 1091 case GL_STENCIL_BACK_REF: 1092 case GL_STENCIL_BACK_FAIL: 1093 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: 1094 case GL_STENCIL_BACK_PASS_DEPTH_PASS: 1095 case GL_DEPTH_FUNC: 1096 case GL_BLEND_SRC_RGB: 1097 case GL_BLEND_SRC_ALPHA: 1098 case GL_BLEND_DST_RGB: 1099 case GL_BLEND_DST_ALPHA: 1100 case GL_BLEND_EQUATION_RGB: 1101 case GL_BLEND_EQUATION_ALPHA: 1102 case GL_STENCIL_WRITEMASK: 1103 case GL_STENCIL_BACK_WRITEMASK: 1104 case GL_STENCIL_CLEAR_VALUE: 1105 case GL_SUBPIXEL_BITS: 1106 case GL_MAX_TEXTURE_SIZE: 1107 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: 1108 case GL_SAMPLE_BUFFERS: 1109 case GL_SAMPLES: 1110 case GL_IMPLEMENTATION_COLOR_READ_TYPE: 1111 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: 1112 case GL_TEXTURE_BINDING_2D: 1113 case GL_TEXTURE_BINDING_CUBE_MAP: 1114 case GL_RESET_NOTIFICATION_STRATEGY_EXT: 1115 case GL_NUM_PROGRAM_BINARY_FORMATS_OES: 1116 { 1117 *type = GL_INT; 1118 *numParams = 1; 1119 } 1120 return true; 1121 case GL_MAX_SAMPLES_ANGLE: 1122 { 1123 if (mExtensions.framebufferMultisample) 1124 { 1125 *type = GL_INT; 1126 *numParams = 1; 1127 } 1128 else 1129 { 1130 return false; 1131 } 1132 } 1133 return true; 1134 case GL_PIXEL_PACK_BUFFER_BINDING: 1135 case GL_PIXEL_UNPACK_BUFFER_BINDING: 1136 { 1137 if (mExtensions.pixelBufferObject) 1138 { 1139 *type = GL_INT; 1140 *numParams = 1; 1141 } 1142 else 1143 { 1144 return false; 1145 } 1146 } 1147 return true; 1148 case GL_MAX_VIEWPORT_DIMS: 1149 { 1150 *type = GL_INT; 1151 *numParams = 2; 1152 } 1153 return true; 1154 case GL_VIEWPORT: 1155 case GL_SCISSOR_BOX: 1156 { 1157 *type = GL_INT; 1158 *numParams = 4; 1159 } 1160 return true; 1161 case GL_SHADER_COMPILER: 1162 case GL_SAMPLE_COVERAGE_INVERT: 1163 case GL_DEPTH_WRITEMASK: 1164 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled, 1165 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries. 1166 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural 1167 case GL_SAMPLE_COVERAGE: 1168 case GL_SCISSOR_TEST: 1169 case GL_STENCIL_TEST: 1170 case GL_DEPTH_TEST: 1171 case GL_BLEND: 1172 case GL_DITHER: 1173 case GL_CONTEXT_ROBUST_ACCESS_EXT: 1174 { 1175 *type = GL_BOOL; 1176 *numParams = 1; 1177 } 1178 return true; 1179 case GL_COLOR_WRITEMASK: 1180 { 1181 *type = GL_BOOL; 1182 *numParams = 4; 1183 } 1184 return true; 1185 case GL_POLYGON_OFFSET_FACTOR: 1186 case GL_POLYGON_OFFSET_UNITS: 1187 case GL_SAMPLE_COVERAGE_VALUE: 1188 case GL_DEPTH_CLEAR_VALUE: 1189 case GL_LINE_WIDTH: 1190 { 1191 *type = GL_FLOAT; 1192 *numParams = 1; 1193 } 1194 return true; 1195 case GL_ALIASED_LINE_WIDTH_RANGE: 1196 case GL_ALIASED_POINT_SIZE_RANGE: 1197 case GL_DEPTH_RANGE: 1198 { 1199 *type = GL_FLOAT; 1200 *numParams = 2; 1201 } 1202 return true; 1203 case GL_COLOR_CLEAR_VALUE: 1204 case GL_BLEND_COLOR: 1205 { 1206 *type = GL_FLOAT; 1207 *numParams = 4; 1208 } 1209 return true; 1210 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: 1211 if (!mExtensions.maxTextureAnisotropy) 1212 { 1213 return false; 1214 } 1215 *type = GL_FLOAT; 1216 *numParams = 1; 1217 return true; 1218 } 1219 1220 if (mClientVersion < 3) 1221 { 1222 return false; 1223 } 1224 1225 // Check for ES3.0+ parameter names 1226 switch (pname) 1227 { 1228 case GL_MAX_UNIFORM_BUFFER_BINDINGS: 1229 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: 1230 case GL_UNIFORM_BUFFER_BINDING: 1231 case GL_TRANSFORM_FEEDBACK_BINDING: 1232 case GL_COPY_READ_BUFFER_BINDING: 1233 case GL_COPY_WRITE_BUFFER_BINDING: 1234 case GL_TEXTURE_BINDING_3D: 1235 case GL_TEXTURE_BINDING_2D_ARRAY: 1236 case GL_MAX_3D_TEXTURE_SIZE: 1237 case GL_MAX_ARRAY_TEXTURE_LAYERS: 1238 case GL_MAX_VERTEX_UNIFORM_BLOCKS: 1239 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: 1240 case GL_MAX_COMBINED_UNIFORM_BLOCKS: 1241 case GL_MAX_VARYING_COMPONENTS: 1242 case GL_VERTEX_ARRAY_BINDING: 1243 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: 1244 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: 1245 case GL_NUM_EXTENSIONS: 1246 case GL_MAJOR_VERSION: 1247 case GL_MINOR_VERSION: 1248 case GL_MAX_ELEMENTS_INDICES: 1249 case GL_MAX_ELEMENTS_VERTICES: 1250 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: 1251 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: 1252 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: 1253 { 1254 *type = GL_INT; 1255 *numParams = 1; 1256 } 1257 return true; 1258 1259 case GL_MAX_ELEMENT_INDEX: 1260 case GL_MAX_UNIFORM_BLOCK_SIZE: 1261 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: 1262 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: 1263 case GL_MAX_SERVER_WAIT_TIMEOUT: 1264 { 1265 *type = GL_INT_64_ANGLEX; 1266 *numParams = 1; 1267 } 1268 return true; 1269 1270 case GL_TRANSFORM_FEEDBACK_ACTIVE: 1271 case GL_TRANSFORM_FEEDBACK_PAUSED: 1272 { 1273 *type = GL_BOOL; 1274 *numParams = 1; 1275 } 1276 return true; 1277 } 1278 1279 return false; 1280 } 1281 1282 bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams) 1283 { 1284 if (mClientVersion < 3) 1285 { 1286 return false; 1287 } 1288 1289 switch (target) 1290 { 1291 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: 1292 case GL_UNIFORM_BUFFER_BINDING: 1293 { 1294 *type = GL_INT; 1295 *numParams = 1; 1296 } 1297 return true; 1298 case GL_TRANSFORM_FEEDBACK_BUFFER_START: 1299 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: 1300 case GL_UNIFORM_BUFFER_START: 1301 case GL_UNIFORM_BUFFER_SIZE: 1302 { 1303 *type = GL_INT_64_ANGLEX; 1304 *numParams = 1; 1305 } 1306 } 1307 1308 return false; 1309 } 1310 1311 // Applies the render target surface, depth stencil surface, viewport rectangle and 1312 // scissor rectangle to the renderer 1313 void Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport) 1314 { 1315 Framebuffer *framebufferObject = mState.getDrawFramebuffer(); 1316 ASSERT(framebufferObject && framebufferObject->completeness() == GL_FRAMEBUFFER_COMPLETE); 1317 1318 mRenderer->applyRenderTarget(framebufferObject); 1319 1320 float nearZ, farZ; 1321 mState.getDepthRange(&nearZ, &farZ); 1322 mRenderer->setViewport(mState.getViewport(), nearZ, farZ, drawMode, mState.getRasterizerState().frontFace, 1323 ignoreViewport); 1324 1325 mRenderer->setScissorRectangle(mState.getScissor(), mState.isScissorTestEnabled()); 1326 } 1327 1328 // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device 1329 void Context::applyState(GLenum drawMode) 1330 { 1331 Framebuffer *framebufferObject = mState.getDrawFramebuffer(); 1332 int samples = framebufferObject->getSamples(); 1333 1334 RasterizerState rasterizer = mState.getRasterizerState(); 1335 rasterizer.pointDrawMode = (drawMode == GL_POINTS); 1336 rasterizer.multiSample = (samples != 0); 1337 1338 mRenderer->setRasterizerState(rasterizer); 1339 1340 unsigned int mask = 0; 1341 if (mState.isSampleCoverageEnabled()) 1342 { 1343 GLclampf coverageValue; 1344 bool coverageInvert = false; 1345 mState.getSampleCoverageParams(&coverageValue, &coverageInvert); 1346 if (coverageValue != 0) 1347 { 1348 1349 float threshold = 0.5f; 1350 1351 for (int i = 0; i < samples; ++i) 1352 { 1353 mask <<= 1; 1354 1355 if ((i + 1) * coverageValue >= threshold) 1356 { 1357 threshold += 1.0f; 1358 mask |= 1; 1359 } 1360 } 1361 } 1362 1363 if (coverageInvert) 1364 { 1365 mask = ~mask; 1366 } 1367 } 1368 else 1369 { 1370 mask = 0xFFFFFFFF; 1371 } 1372 mRenderer->setBlendState(framebufferObject, mState.getBlendState(), mState.getBlendColor(), mask); 1373 1374 mRenderer->setDepthStencilState(mState.getDepthStencilState(), mState.getStencilRef(), mState.getStencilBackRef(), 1375 rasterizer.frontFace == GL_CCW); 1376 } 1377 1378 // Applies the shaders and shader constants to the Direct3D 9 device 1379 void Context::applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive) 1380 { 1381 const VertexAttribute *vertexAttributes = mState.getVertexArray()->getVertexAttributes(); 1382 1383 VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]; 1384 VertexFormat::GetInputLayout(inputLayout, programBinary, vertexAttributes, mState.getVertexAttribCurrentValues()); 1385 1386 const Framebuffer *fbo = mState.getDrawFramebuffer(); 1387 1388 mRenderer->applyShaders(programBinary, inputLayout, fbo, mState.getRasterizerState().rasterizerDiscard, transformFeedbackActive); 1389 1390 programBinary->applyUniforms(); 1391 } 1392 1393 void Context::generateSwizzles(ProgramBinary *programBinary, SamplerType type) 1394 { 1395 size_t samplerRange = programBinary->getUsedSamplerRange(type); 1396 1397 for (size_t i = 0; i < samplerRange; i++) 1398 { 1399 GLenum textureType = programBinary->getSamplerTextureType(type, i); 1400 GLint textureUnit = programBinary->getSamplerMapping(type, i, getCaps()); 1401 if (textureUnit != -1) 1402 { 1403 Texture* texture = getSamplerTexture(textureUnit, textureType); 1404 if (texture->getSamplerState().swizzleRequired()) 1405 { 1406 mRenderer->generateSwizzle(texture); 1407 } 1408 } 1409 } 1410 } 1411 1412 void Context::generateSwizzles(ProgramBinary *programBinary) 1413 { 1414 generateSwizzles(programBinary, SAMPLER_VERTEX); 1415 generateSwizzles(programBinary, SAMPLER_PIXEL); 1416 } 1417 1418 // For each Direct3D sampler of either the pixel or vertex stage, 1419 // looks up the corresponding OpenGL texture image unit and texture type, 1420 // and sets the texture and its addressing/filtering state (or NULL when inactive). 1421 void Context::applyTextures(ProgramBinary *programBinary, SamplerType shaderType, 1422 const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount) 1423 { 1424 size_t samplerRange = programBinary->getUsedSamplerRange(shaderType); 1425 for (size_t samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++) 1426 { 1427 GLenum textureType = programBinary->getSamplerTextureType(shaderType, samplerIndex); 1428 GLint textureUnit = programBinary->getSamplerMapping(shaderType, samplerIndex, getCaps()); 1429 if (textureUnit != -1) 1430 { 1431 SamplerState sampler; 1432 Texture* texture = getSamplerTexture(textureUnit, textureType); 1433 texture->getSamplerStateWithNativeOffset(&sampler); 1434 1435 Sampler *samplerObject = mState.getSampler(textureUnit); 1436 if (samplerObject) 1437 { 1438 samplerObject->getState(&sampler); 1439 } 1440 1441 // TODO: std::binary_search may become unavailable using older versions of GCC 1442 if (texture->isSamplerComplete(sampler, mTextureCaps, mExtensions, mClientVersion) && 1443 !std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial())) 1444 { 1445 mRenderer->setSamplerState(shaderType, samplerIndex, sampler); 1446 mRenderer->setTexture(shaderType, samplerIndex, texture); 1447 } 1448 else 1449 { 1450 // Texture is not sampler complete or it is in use by the framebuffer. Bind the incomplete texture. 1451 Texture *incompleteTexture = getIncompleteTexture(textureType); 1452 mRenderer->setTexture(shaderType, samplerIndex, incompleteTexture); 1453 } 1454 } 1455 else 1456 { 1457 // No texture bound to this slot even though it is used by the shader, bind a NULL texture 1458 mRenderer->setTexture(shaderType, samplerIndex, NULL); 1459 } 1460 } 1461 1462 // Set all the remaining textures to NULL 1463 size_t samplerCount = (shaderType == SAMPLER_PIXEL) ? mCaps.maxTextureImageUnits 1464 : mCaps.maxVertexTextureImageUnits; 1465 for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++) 1466 { 1467 mRenderer->setTexture(shaderType, samplerIndex, NULL); 1468 } 1469 } 1470 1471 void Context::applyTextures(ProgramBinary *programBinary) 1472 { 1473 FramebufferTextureSerialArray framebufferSerials; 1474 size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&framebufferSerials); 1475 1476 applyTextures(programBinary, SAMPLER_VERTEX, framebufferSerials, framebufferSerialCount); 1477 applyTextures(programBinary, SAMPLER_PIXEL, framebufferSerials, framebufferSerialCount); 1478 } 1479 1480 bool Context::applyUniformBuffers() 1481 { 1482 Program *programObject = getProgram(mState.getCurrentProgramId()); 1483 ProgramBinary *programBinary = programObject->getProgramBinary(); 1484 1485 std::vector<Buffer*> boundBuffers; 1486 1487 for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++) 1488 { 1489 GLuint blockBinding = programObject->getUniformBlockBinding(uniformBlockIndex); 1490 1491 if (mState.getIndexedUniformBuffer(blockBinding)->id() == 0) 1492 { 1493 // undefined behaviour 1494 return false; 1495 } 1496 else 1497 { 1498 Buffer *uniformBuffer = mState.getIndexedUniformBuffer(blockBinding); 1499 ASSERT(uniformBuffer); 1500 boundBuffers.push_back(uniformBuffer); 1501 } 1502 } 1503 1504 return programBinary->applyUniformBuffers(boundBuffers, getCaps()); 1505 } 1506 1507 bool Context::applyTransformFeedbackBuffers() 1508 { 1509 TransformFeedback *curTransformFeedback = mState.getCurrentTransformFeedback(); 1510 if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused()) 1511 { 1512 Buffer *transformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; 1513 GLintptr transformFeedbackOffsets[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; 1514 for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) 1515 { 1516 transformFeedbackBuffers[i] = mState.getIndexedTransformFeedbackBuffer(i); 1517 transformFeedbackOffsets[i] = mState.getIndexedTransformFeedbackBufferOffset(i); 1518 } 1519 mRenderer->applyTransformFeedbackBuffers(transformFeedbackBuffers, transformFeedbackOffsets); 1520 return true; 1521 } 1522 else 1523 { 1524 return false; 1525 } 1526 } 1527 1528 void Context::markTransformFeedbackUsage() 1529 { 1530 for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) 1531 { 1532 Buffer *buffer = mState.getIndexedTransformFeedbackBuffer(i); 1533 if (buffer) 1534 { 1535 buffer->markTransformFeedbackUsage(); 1536 } 1537 } 1538 } 1539 1540 Error Context::clear(GLbitfield mask) 1541 { 1542 if (mState.isRasterizerDiscardEnabled()) 1543 { 1544 return Error(GL_NO_ERROR); 1545 } 1546 1547 ClearParameters clearParams = mState.getClearParameters(mask); 1548 1549 applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport 1550 1551 return mRenderer->clear(clearParams, mState.getDrawFramebuffer()); 1552 } 1553 1554 Error Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values) 1555 { 1556 if (mState.isRasterizerDiscardEnabled()) 1557 { 1558 return Error(GL_NO_ERROR); 1559 } 1560 1561 // glClearBufferfv can be called to clear the color buffer or depth buffer 1562 ClearParameters clearParams = mState.getClearParameters(0); 1563 1564 if (buffer == GL_COLOR) 1565 { 1566 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) 1567 { 1568 clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i)); 1569 } 1570 clearParams.colorFClearValue = ColorF(values[0], values[1], values[2], values[3]); 1571 clearParams.colorClearType = GL_FLOAT; 1572 } 1573 1574 if (buffer == GL_DEPTH) 1575 { 1576 clearParams.clearDepth = true; 1577 clearParams.depthClearValue = values[0]; 1578 } 1579 1580 applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport 1581 1582 return mRenderer->clear(clearParams, mState.getDrawFramebuffer()); 1583 } 1584 1585 Error Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values) 1586 { 1587 if (mState.isRasterizerDiscardEnabled()) 1588 { 1589 return Error(GL_NO_ERROR); 1590 } 1591 1592 // glClearBufferuv can only be called to clear a color buffer 1593 ClearParameters clearParams = mState.getClearParameters(0); 1594 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) 1595 { 1596 clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i)); 1597 } 1598 clearParams.colorUIClearValue = ColorUI(values[0], values[1], values[2], values[3]); 1599 clearParams.colorClearType = GL_UNSIGNED_INT; 1600 1601 applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport 1602 1603 return mRenderer->clear(clearParams, mState.getDrawFramebuffer()); 1604 } 1605 1606 Error Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values) 1607 { 1608 if (mState.isRasterizerDiscardEnabled()) 1609 { 1610 return Error(GL_NO_ERROR); 1611 } 1612 1613 // glClearBufferfv can be called to clear the color buffer or stencil buffer 1614 ClearParameters clearParams = mState.getClearParameters(0); 1615 1616 if (buffer == GL_COLOR) 1617 { 1618 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) 1619 { 1620 clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i)); 1621 } 1622 clearParams.colorIClearValue = ColorI(values[0], values[1], values[2], values[3]); 1623 clearParams.colorClearType = GL_INT; 1624 } 1625 1626 if (buffer == GL_STENCIL) 1627 { 1628 clearParams.clearStencil = true; 1629 clearParams.stencilClearValue = values[1]; 1630 } 1631 1632 applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport 1633 1634 return mRenderer->clear(clearParams, mState.getDrawFramebuffer()); 1635 } 1636 1637 Error Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil) 1638 { 1639 if (mState.isRasterizerDiscardEnabled()) 1640 { 1641 return Error(GL_NO_ERROR); 1642 } 1643 1644 // glClearBufferfi can only be called to clear a depth stencil buffer 1645 ClearParameters clearParams = mState.getClearParameters(0); 1646 clearParams.clearDepth = true; 1647 clearParams.depthClearValue = depth; 1648 clearParams.clearStencil = true; 1649 clearParams.stencilClearValue = stencil; 1650 1651 applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport 1652 1653 return mRenderer->clear(clearParams, mState.getDrawFramebuffer()); 1654 } 1655 1656 Error Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, 1657 GLenum format, GLenum type, GLsizei *bufSize, void* pixels) 1658 { 1659 Framebuffer *framebuffer = mState.getReadFramebuffer(); 1660 1661 GLenum sizedInternalFormat = GetSizedInternalFormat(format, type); 1662 const InternalFormat &sizedFormatInfo = GetInternalFormatInfo(sizedInternalFormat); 1663 GLuint outputPitch = sizedFormatInfo.computeRowPitch(type, width, mState.getPackAlignment()); 1664 1665 return mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, mState.getPackState(), 1666 reinterpret_cast<uint8_t*>(pixels)); 1667 } 1668 1669 void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances) 1670 { 1671 ASSERT(mState.getCurrentProgramId() != 0); 1672 1673 ProgramBinary *programBinary = mState.getCurrentProgramBinary(); 1674 programBinary->updateSamplerMapping(); 1675 1676 generateSwizzles(programBinary); 1677 1678 if (!mRenderer->applyPrimitiveType(mode, count)) 1679 { 1680 return; 1681 } 1682 1683 applyRenderTarget(mode, false); 1684 applyState(mode); 1685 1686 Error error = mRenderer->applyVertexBuffer(programBinary, mState.getVertexArray()->getVertexAttributes(), mState.getVertexAttribCurrentValues(), first, count, instances); 1687 if (error.isError()) 1688 { 1689 return gl::error(error.getCode()); 1690 } 1691 1692 bool transformFeedbackActive = applyTransformFeedbackBuffers(); 1693 1694 applyShaders(programBinary, transformFeedbackActive); 1695 1696 applyTextures(programBinary); 1697 1698 if (!applyUniformBuffers()) 1699 { 1700 return; 1701 } 1702 1703 if (!skipDraw(mode)) 1704 { 1705 mRenderer->drawArrays(mode, count, instances, transformFeedbackActive); 1706 1707 if (transformFeedbackActive) 1708 { 1709 markTransformFeedbackUsage(); 1710 } 1711 } 1712 } 1713 1714 void Context::drawElements(GLenum mode, GLsizei count, GLenum type, 1715 const GLvoid *indices, GLsizei instances, 1716 const rx::RangeUI &indexRange) 1717 { 1718 ASSERT(mState.getCurrentProgramId() != 0); 1719 1720 ProgramBinary *programBinary = mState.getCurrentProgramBinary(); 1721 programBinary->updateSamplerMapping(); 1722 1723 generateSwizzles(programBinary); 1724 1725 if (!mRenderer->applyPrimitiveType(mode, count)) 1726 { 1727 return; 1728 } 1729 1730 applyRenderTarget(mode, false); 1731 applyState(mode); 1732 1733 VertexArray *vao = mState.getVertexArray(); 1734 rx::TranslatedIndexData indexInfo; 1735 indexInfo.indexRange = indexRange; 1736 Error error = mRenderer->applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo); 1737 if (error.isError()) 1738 { 1739 return gl::error(error.getCode()); 1740 } 1741 1742 GLsizei vertexCount = indexInfo.indexRange.length() + 1; 1743 error = mRenderer->applyVertexBuffer(programBinary, vao->getVertexAttributes(), 1744 mState.getVertexAttribCurrentValues(), 1745 indexInfo.indexRange.start, vertexCount, instances); 1746 if (error.isError()) 1747 { 1748 return gl::error(error.getCode()); 1749 } 1750 1751 bool transformFeedbackActive = applyTransformFeedbackBuffers(); 1752 // Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation 1753 // layer. 1754 ASSERT(!transformFeedbackActive); 1755 1756 applyShaders(programBinary, transformFeedbackActive); 1757 1758 applyTextures(programBinary); 1759 1760 if (!applyUniformBuffers()) 1761 { 1762 return; 1763 } 1764 1765 if (!skipDraw(mode)) 1766 { 1767 mRenderer->drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances); 1768 } 1769 } 1770 1771 // Implements glFlush when block is false, glFinish when block is true 1772 void Context::sync(bool block) 1773 { 1774 mRenderer->sync(block); 1775 } 1776 1777 void Context::recordError(const Error &error) 1778 { 1779 if (error.isError()) 1780 { 1781 mErrors.insert(error.getCode()); 1782 } 1783 } 1784 1785 // Get one of the recorded errors and clear its flag, if any. 1786 // [OpenGL ES 2.0.24] section 2.5 page 13. 1787 GLenum Context::getError() 1788 { 1789 if (mErrors.empty()) 1790 { 1791 return GL_NO_ERROR; 1792 } 1793 else 1794 { 1795 GLenum error = *mErrors.begin(); 1796 mErrors.erase(mErrors.begin()); 1797 return error; 1798 } 1799 } 1800 1801 GLenum Context::getResetStatus() 1802 { 1803 if (mResetStatus == GL_NO_ERROR && !mContextLost) 1804 { 1805 // mResetStatus will be set by the markContextLost callback 1806 // in the case a notification is sent 1807 mRenderer->testDeviceLost(true); 1808 } 1809 1810 GLenum status = mResetStatus; 1811 1812 if (mResetStatus != GL_NO_ERROR) 1813 { 1814 ASSERT(mContextLost); 1815 1816 if (mRenderer->testDeviceResettable()) 1817 { 1818 mResetStatus = GL_NO_ERROR; 1819 } 1820 } 1821 1822 return status; 1823 } 1824 1825 bool Context::isResetNotificationEnabled() 1826 { 1827 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT); 1828 } 1829 1830 int Context::getClientVersion() const 1831 { 1832 return mClientVersion; 1833 } 1834 1835 const Caps &Context::getCaps() const 1836 { 1837 return mCaps; 1838 } 1839 1840 const TextureCapsMap &Context::getTextureCaps() const 1841 { 1842 return mTextureCaps; 1843 } 1844 1845 const Extensions &Context::getExtensions() const 1846 { 1847 return mExtensions; 1848 } 1849 1850 void Context::getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type) 1851 { 1852 Framebuffer *framebuffer = mState.getReadFramebuffer(); 1853 ASSERT(framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE); 1854 1855 FramebufferAttachment *attachment = framebuffer->getReadColorbuffer(); 1856 ASSERT(attachment); 1857 1858 GLenum actualFormat = attachment->getActualFormat(); 1859 const InternalFormat &actualFormatInfo = GetInternalFormatInfo(actualFormat); 1860 1861 *internalFormat = actualFormat; 1862 *format = actualFormatInfo.format; 1863 *type = actualFormatInfo.type; 1864 } 1865 1866 void Context::detachTexture(GLuint texture) 1867 { 1868 // Simple pass-through to State's detachTexture method, as textures do not require 1869 // allocation map management either here or in the resource manager at detach time. 1870 // Zero textures are held by the Context, and we don't attempt to request them from 1871 // the State. 1872 mState.detachTexture(texture); 1873 } 1874 1875 void Context::detachBuffer(GLuint buffer) 1876 { 1877 // Buffer detachment is handled by Context, because the buffer must also be 1878 // attached from any VAOs in existence, and Context holds the VAO map. 1879 1880 // [OpenGL ES 2.0.24] section 2.9 page 22: 1881 // If a buffer object is deleted while it is bound, all bindings to that object in the current context 1882 // (i.e. in the thread that called Delete-Buffers) are reset to zero. 1883 1884 mState.removeArrayBufferBinding(buffer); 1885 1886 // mark as freed among the vertex array objects 1887 for (auto vaoIt = mVertexArrayMap.begin(); vaoIt != mVertexArrayMap.end(); vaoIt++) 1888 { 1889 vaoIt->second->detachBuffer(buffer); 1890 } 1891 } 1892 1893 void Context::detachFramebuffer(GLuint framebuffer) 1894 { 1895 // Framebuffer detachment is handled by Context, because 0 is a valid 1896 // Framebuffer object, and a pointer to it must be passed from Context 1897 // to State at binding time. 1898 1899 // [OpenGL ES 2.0.24] section 4.4 page 107: 1900 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though 1901 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero. 1902 1903 if (mState.removeReadFramebufferBinding(framebuffer)) 1904 { 1905 bindReadFramebuffer(0); 1906 } 1907 1908 if (mState.removeDrawFramebufferBinding(framebuffer)) 1909 { 1910 bindDrawFramebuffer(0); 1911 } 1912 } 1913 1914 void Context::detachRenderbuffer(GLuint renderbuffer) 1915 { 1916 mState.detachRenderbuffer(renderbuffer); 1917 } 1918 1919 void Context::detachVertexArray(GLuint vertexArray) 1920 { 1921 // Vertex array detachment is handled by Context, because 0 is a valid 1922 // VAO, and a pointer to it must be passed from Context to State at 1923 // binding time. 1924 1925 // [OpenGL ES 3.0.2] section 2.10 page 43: 1926 // If a vertex array object that is currently bound is deleted, the binding 1927 // for that object reverts to zero and the default vertex array becomes current. 1928 if (mState.removeVertexArrayBinding(vertexArray)) 1929 { 1930 bindVertexArray(0); 1931 } 1932 } 1933 1934 void Context::detachTransformFeedback(GLuint transformFeedback) 1935 { 1936 mState.detachTransformFeedback(transformFeedback); 1937 } 1938 1939 void Context::detachSampler(GLuint sampler) 1940 { 1941 mState.detachSampler(sampler); 1942 } 1943 1944 Texture *Context::getIncompleteTexture(GLenum type) 1945 { 1946 if (mIncompleteTextures.find(type) == mIncompleteTextures.end()) 1947 { 1948 const GLubyte color[] = { 0, 0, 0, 255 }; 1949 const PixelUnpackState incompleteUnpackState(1); 1950 1951 Texture* t = NULL; 1952 switch (type) 1953 { 1954 default: 1955 UNREACHABLE(); 1956 // default falls through to TEXTURE_2D 1957 1958 case GL_TEXTURE_2D: 1959 { 1960 Texture2D *incomplete2d = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), Texture::INCOMPLETE_TEXTURE_ID); 1961 incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); 1962 t = incomplete2d; 1963 } 1964 break; 1965 1966 case GL_TEXTURE_CUBE_MAP: 1967 { 1968 TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), Texture::INCOMPLETE_TEXTURE_ID); 1969 1970 incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); 1971 incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); 1972 incompleteCube->setImagePosY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); 1973 incompleteCube->setImageNegY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); 1974 incompleteCube->setImagePosZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); 1975 incompleteCube->setImageNegZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); 1976 1977 t = incompleteCube; 1978 } 1979 break; 1980 1981 case GL_TEXTURE_3D: 1982 { 1983 Texture3D *incomplete3d = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), Texture::INCOMPLETE_TEXTURE_ID); 1984 incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); 1985 1986 t = incomplete3d; 1987 } 1988 break; 1989 1990 case GL_TEXTURE_2D_ARRAY: 1991 { 1992 Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), Texture::INCOMPLETE_TEXTURE_ID); 1993 incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); 1994 1995 t = incomplete2darray; 1996 } 1997 break; 1998 } 1999 2000 mIncompleteTextures[type].set(t); 2001 } 2002 2003 return mIncompleteTextures[type].get(); 2004 } 2005 2006 bool Context::skipDraw(GLenum drawMode) 2007 { 2008 if (drawMode == GL_POINTS) 2009 { 2010 // ProgramBinary assumes non-point rendering if gl_PointSize isn't written, 2011 // which affects varying interpolation. Since the value of gl_PointSize is 2012 // undefined when not written, just skip drawing to avoid unexpected results. 2013 if (!mState.getCurrentProgramBinary()->usesPointSize()) 2014 { 2015 // This is stictly speaking not an error, but developers should be 2016 // notified of risking undefined behavior. 2017 ERR("Point rendering without writing to gl_PointSize."); 2018 2019 return true; 2020 } 2021 } 2022 else if (IsTriangleMode(drawMode)) 2023 { 2024 if (mState.getRasterizerState().cullFace && mState.getRasterizerState().cullMode == GL_FRONT_AND_BACK) 2025 { 2026 return true; 2027 } 2028 } 2029 2030 return false; 2031 } 2032 2033 void Context::setVertexAttribDivisor(GLuint index, GLuint divisor) 2034 { 2035 mState.getVertexArray()->setVertexAttribDivisor(index, divisor); 2036 } 2037 2038 void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param) 2039 { 2040 mResourceManager->checkSamplerAllocation(sampler); 2041 2042 Sampler *samplerObject = getSampler(sampler); 2043 ASSERT(samplerObject); 2044 2045 switch (pname) 2046 { 2047 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break; 2048 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break; 2049 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break; 2050 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break; 2051 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break; 2052 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break; 2053 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break; 2054 case GL_TEXTURE_COMPARE_MODE: samplerObject->setComparisonMode(static_cast<GLenum>(param)); break; 2055 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setComparisonFunc(static_cast<GLenum>(param)); break; 2056 default: UNREACHABLE(); break; 2057 } 2058 } 2059 2060 void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param) 2061 { 2062 mResourceManager->checkSamplerAllocation(sampler); 2063 2064 Sampler *samplerObject = getSampler(sampler); 2065 ASSERT(samplerObject); 2066 2067 switch (pname) 2068 { 2069 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break; 2070 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break; 2071 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break; 2072 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break; 2073 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break; 2074 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break; 2075 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break; 2076 case GL_TEXTURE_COMPARE_MODE: samplerObject->setComparisonMode(uiround<GLenum>(param)); break; 2077 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setComparisonFunc(uiround<GLenum>(param)); break; 2078 default: UNREACHABLE(); break; 2079 } 2080 } 2081 2082 GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname) 2083 { 2084 mResourceManager->checkSamplerAllocation(sampler); 2085 2086 Sampler *samplerObject = getSampler(sampler); 2087 ASSERT(samplerObject); 2088 2089 switch (pname) 2090 { 2091 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter()); 2092 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter()); 2093 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS()); 2094 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT()); 2095 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR()); 2096 case GL_TEXTURE_MIN_LOD: return uiround<GLint>(samplerObject->getMinLod()); 2097 case GL_TEXTURE_MAX_LOD: return uiround<GLint>(samplerObject->getMaxLod()); 2098 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getComparisonMode()); 2099 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getComparisonFunc()); 2100 default: UNREACHABLE(); return 0; 2101 } 2102 } 2103 2104 GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname) 2105 { 2106 mResourceManager->checkSamplerAllocation(sampler); 2107 2108 Sampler *samplerObject = getSampler(sampler); 2109 ASSERT(samplerObject); 2110 2111 switch (pname) 2112 { 2113 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter()); 2114 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter()); 2115 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS()); 2116 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT()); 2117 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR()); 2118 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod(); 2119 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod(); 2120 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getComparisonMode()); 2121 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getComparisonFunc()); 2122 default: UNREACHABLE(); return 0; 2123 } 2124 } 2125 2126 void Context::initRendererString() 2127 { 2128 std::ostringstream rendererString; 2129 rendererString << "ANGLE ("; 2130 rendererString << mRenderer->getRendererDescription(); 2131 rendererString << ")"; 2132 2133 mRendererString = MakeStaticString(rendererString.str()); 2134 } 2135 2136 const std::string &Context::getRendererString() const 2137 { 2138 return mRendererString; 2139 } 2140 2141 void Context::initExtensionStrings() 2142 { 2143 mExtensionStrings = mExtensions.getStrings(); 2144 2145 std::ostringstream combinedStringStream; 2146 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " ")); 2147 mExtensionString = combinedStringStream.str(); 2148 } 2149 2150 const std::string &Context::getExtensionString() const 2151 { 2152 return mExtensionString; 2153 } 2154 2155 const std::string &Context::getExtensionString(size_t idx) const 2156 { 2157 return mExtensionStrings[idx]; 2158 } 2159 2160 size_t Context::getExtensionStringCount() const 2161 { 2162 return mExtensionStrings.size(); 2163 } 2164 2165 size_t Context::getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray) 2166 { 2167 size_t serialCount = 0; 2168 2169 Framebuffer *drawFramebuffer = mState.getDrawFramebuffer(); 2170 for (unsigned int i = 0; i < IMPLEMENTATION_MAX_DRAW_BUFFERS; i++) 2171 { 2172 FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i); 2173 if (attachment && attachment->isTexture()) 2174 { 2175 Texture *texture = attachment->getTexture(); 2176 (*outSerialArray)[serialCount++] = texture->getTextureSerial(); 2177 } 2178 } 2179 2180 FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer(); 2181 if (depthStencilAttachment && depthStencilAttachment->isTexture()) 2182 { 2183 Texture *depthStencilTexture = depthStencilAttachment->getTexture(); 2184 (*outSerialArray)[serialCount++] = depthStencilTexture->getTextureSerial(); 2185 } 2186 2187 std::sort(outSerialArray->begin(), outSerialArray->begin() + serialCount); 2188 2189 return serialCount; 2190 } 2191 2192 void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 2193 GLbitfield mask, GLenum filter) 2194 { 2195 Framebuffer *readFramebuffer = mState.getReadFramebuffer(); 2196 Framebuffer *drawFramebuffer = mState.getDrawFramebuffer(); 2197 2198 bool blitRenderTarget = false; 2199 bool blitDepth = false; 2200 bool blitStencil = false; 2201 if ((mask & GL_COLOR_BUFFER_BIT) && readFramebuffer->getReadColorbuffer() && drawFramebuffer->getFirstColorbuffer()) 2202 { 2203 blitRenderTarget = true; 2204 } 2205 if ((mask & GL_STENCIL_BUFFER_BIT) && readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer()) 2206 { 2207 blitStencil = true; 2208 } 2209 if ((mask & GL_DEPTH_BUFFER_BIT) && readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer()) 2210 { 2211 blitDepth = true; 2212 } 2213 2214 Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0); 2215 Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0); 2216 if (blitRenderTarget || blitDepth || blitStencil) 2217 { 2218 const Rectangle *scissor = mState.isScissorTestEnabled() ? &mState.getScissor() : NULL; 2219 mRenderer->blitRect(readFramebuffer, srcRect, drawFramebuffer, dstRect, scissor, 2220 blitRenderTarget, blitDepth, blitStencil, filter); 2221 } 2222 } 2223 2224 void Context::releaseShaderCompiler() 2225 { 2226 mRenderer->releaseShaderCompiler(); 2227 } 2228 2229 void Context::initCaps(GLuint clientVersion) 2230 { 2231 mCaps = mRenderer->getRendererCaps(); 2232 2233 mExtensions = mRenderer->getRendererExtensions(); 2234 2235 if (clientVersion < 3) 2236 { 2237 // Disable ES3+ extensions 2238 mExtensions.colorBufferFloat = false; 2239 } 2240 2241 if (clientVersion > 2) 2242 { 2243 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts 2244 //mExtensions.sRGB = false; 2245 } 2246 2247 // Apply implementation limits 2248 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS); 2249 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS); 2250 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4); 2251 2252 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4); 2253 2254 GLuint maxSamples = 0; 2255 mCaps.compressedTextureFormats.clear(); 2256 2257 const TextureCapsMap &rendererFormats = mRenderer->getRendererTextureCaps(); 2258 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++) 2259 { 2260 GLenum format = i->first; 2261 TextureCaps formatCaps = i->second; 2262 2263 const InternalFormat &formatInfo = GetInternalFormatInfo(format); 2264 if (formatCaps.texturable && formatInfo.textureSupport(clientVersion, mExtensions)) 2265 { 2266 // Update the format caps based on the client version and extensions 2267 formatCaps.renderable = formatInfo.renderSupport(clientVersion, mExtensions); 2268 formatCaps.filterable = formatInfo.filterSupport(clientVersion, mExtensions); 2269 2270 // OpenGL ES does not support multisampling with integer formats 2271 if (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT) 2272 { 2273 formatCaps.sampleCounts.clear(); 2274 } 2275 maxSamples = std::max(maxSamples, formatCaps.getMaxSamples()); 2276 2277 if (formatInfo.compressed) 2278 { 2279 mCaps.compressedTextureFormats.push_back(format); 2280 } 2281 2282 mTextureCaps.insert(format, formatCaps); 2283 } 2284 } 2285 2286 mExtensions.maxSamples = maxSamples; 2287 } 2288 2289 } 2290 2291 extern "C" 2292 { 2293 gl::Context *glCreateContext(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) 2294 { 2295 return new gl::Context(clientVersion, shareContext, renderer, notifyResets, robustAccess); 2296 } 2297 2298 void glDestroyContext(gl::Context *context) 2299 { 2300 delete context; 2301 2302 if (context == gl::getContext()) 2303 { 2304 gl::makeCurrent(NULL, NULL, NULL); 2305 } 2306 } 2307 2308 void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface) 2309 { 2310 gl::makeCurrent(context, display, surface); 2311 } 2312 2313 gl::Context *glGetCurrentContext() 2314 { 2315 return gl::getContext(); 2316 } 2317 2318 } 2319