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 // Framebuffer.cpp: Implements the Framebuffer class. Implements GL framebuffer 16 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105. 17 18 #include "Framebuffer.h" 19 20 #include "main.h" 21 #include "Renderbuffer.h" 22 #include "Texture.h" 23 #include "utilities.h" 24 25 #include <algorithm> 26 27 namespace es2 28 { 29 30 bool Framebuffer::IsRenderbuffer(GLenum type) 31 { 32 return type == GL_RENDERBUFFER || type == GL_FRAMEBUFFER_DEFAULT; 33 } 34 35 Framebuffer::Framebuffer() 36 { 37 readBuffer = GL_COLOR_ATTACHMENT0; 38 drawBuffer[0] = GL_COLOR_ATTACHMENT0; 39 for(int i = 1; i < MAX_COLOR_ATTACHMENTS; i++) 40 { 41 drawBuffer[i] = GL_NONE; 42 } 43 44 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++) 45 { 46 mColorbufferType[i] = GL_NONE; 47 mColorbufferLayer[i] = 0; 48 } 49 50 mDepthbufferType = GL_NONE; 51 mDepthbufferLayer = 0; 52 mStencilbufferType = GL_NONE; 53 mStencilbufferLayer = 0; 54 } 55 56 Framebuffer::~Framebuffer() 57 { 58 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++) 59 { 60 mColorbufferPointer[i] = nullptr; 61 } 62 mDepthbufferPointer = nullptr; 63 mStencilbufferPointer = nullptr; 64 } 65 66 Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle, GLint level) const 67 { 68 Context *context = getContext(); 69 Renderbuffer *buffer = nullptr; 70 71 if(type == GL_NONE) 72 { 73 buffer = nullptr; 74 } 75 else if(IsRenderbuffer(type)) 76 { 77 buffer = context->getRenderbuffer(handle); 78 } 79 else if(IsTextureTarget(type)) 80 { 81 buffer = context->getTexture(handle)->getRenderbuffer(type, level); 82 } 83 else UNREACHABLE(type); 84 85 return buffer; 86 } 87 88 void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer, GLuint index, GLint level, GLint layer) 89 { 90 mColorbufferType[index] = (colorbuffer != 0) ? type : GL_NONE; 91 mColorbufferPointer[index] = lookupRenderbuffer(type, colorbuffer, level); 92 mColorbufferLayer[index] = layer; 93 } 94 95 void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer) 96 { 97 mDepthbufferType = (depthbuffer != 0) ? type : GL_NONE; 98 mDepthbufferPointer = lookupRenderbuffer(type, depthbuffer, level); 99 mDepthbufferLayer = layer; 100 } 101 102 void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer) 103 { 104 mStencilbufferType = (stencilbuffer != 0) ? type : GL_NONE; 105 mStencilbufferPointer = lookupRenderbuffer(type, stencilbuffer, level); 106 mStencilbufferLayer = layer; 107 } 108 109 void Framebuffer::setReadBuffer(GLenum buf) 110 { 111 readBuffer = buf; 112 } 113 114 void Framebuffer::setDrawBuffer(GLuint index, GLenum buf) 115 { 116 drawBuffer[index] = buf; 117 } 118 119 GLenum Framebuffer::getReadBuffer() const 120 { 121 return readBuffer; 122 } 123 124 GLenum Framebuffer::getDrawBuffer(GLuint index) const 125 { 126 return drawBuffer[index]; 127 } 128 129 void Framebuffer::detachTexture(GLuint texture) 130 { 131 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++) 132 { 133 if(mColorbufferPointer[i].name() == texture && IsTextureTarget(mColorbufferType[i])) 134 { 135 mColorbufferType[i] = GL_NONE; 136 mColorbufferPointer[i] = nullptr; 137 } 138 } 139 140 if(mDepthbufferPointer.name() == texture && IsTextureTarget(mDepthbufferType)) 141 { 142 mDepthbufferType = GL_NONE; 143 mDepthbufferPointer = nullptr; 144 } 145 146 if(mStencilbufferPointer.name() == texture && IsTextureTarget(mStencilbufferType)) 147 { 148 mStencilbufferType = GL_NONE; 149 mStencilbufferPointer = nullptr; 150 } 151 } 152 153 void Framebuffer::detachRenderbuffer(GLuint renderbuffer) 154 { 155 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++) 156 { 157 if(mColorbufferPointer[i].name() == renderbuffer && IsRenderbuffer(mColorbufferType[i])) 158 { 159 mColorbufferType[i] = GL_NONE; 160 mColorbufferPointer[i] = nullptr; 161 } 162 } 163 164 if(mDepthbufferPointer.name() == renderbuffer && IsRenderbuffer(mDepthbufferType)) 165 { 166 mDepthbufferType = GL_NONE; 167 mDepthbufferPointer = nullptr; 168 } 169 170 if(mStencilbufferPointer.name() == renderbuffer && IsRenderbuffer(mStencilbufferType)) 171 { 172 mStencilbufferType = GL_NONE; 173 mStencilbufferPointer = nullptr; 174 } 175 } 176 177 // Increments refcount on surface. 178 // caller must Release() the returned surface 179 egl::Image *Framebuffer::getRenderTarget(GLuint index) 180 { 181 if(index < MAX_COLOR_ATTACHMENTS) 182 { 183 Renderbuffer *colorbuffer = mColorbufferPointer[index]; 184 185 if(colorbuffer) 186 { 187 return colorbuffer->getRenderTarget(); 188 } 189 } 190 191 return nullptr; 192 } 193 194 egl::Image *Framebuffer::getReadRenderTarget() 195 { 196 return getRenderTarget(getReadBufferIndex()); 197 } 198 199 // Increments refcount on surface. 200 // caller must Release() the returned surface 201 egl::Image *Framebuffer::getDepthBuffer() 202 { 203 Renderbuffer *depthbuffer = mDepthbufferPointer; 204 205 if(depthbuffer) 206 { 207 return depthbuffer->getRenderTarget(); 208 } 209 210 return nullptr; 211 } 212 213 // Increments refcount on surface. 214 // caller must Release() the returned surface 215 egl::Image *Framebuffer::getStencilBuffer() 216 { 217 Renderbuffer *stencilbuffer = mStencilbufferPointer; 218 219 if(stencilbuffer) 220 { 221 return stencilbuffer->getRenderTarget(); 222 } 223 224 return nullptr; 225 } 226 227 Renderbuffer *Framebuffer::getColorbuffer(GLuint index) const 228 { 229 return (index < MAX_COLOR_ATTACHMENTS) ? mColorbufferPointer[index] : (Renderbuffer*)nullptr; 230 } 231 232 Renderbuffer *Framebuffer::getReadColorbuffer() const 233 { 234 return getColorbuffer(getReadBufferIndex()); 235 } 236 237 Renderbuffer *Framebuffer::getDepthbuffer() const 238 { 239 return mDepthbufferPointer; 240 } 241 242 Renderbuffer *Framebuffer::getStencilbuffer() const 243 { 244 return mStencilbufferPointer; 245 } 246 247 GLenum Framebuffer::getReadBufferType() 248 { 249 if(readBuffer == GL_NONE) 250 { 251 return GL_NONE; 252 } 253 254 return mColorbufferType[getReadBufferIndex()]; 255 } 256 257 GLenum Framebuffer::getColorbufferType(GLuint index) 258 { 259 return mColorbufferType[index]; 260 } 261 262 GLenum Framebuffer::getDepthbufferType() 263 { 264 return mDepthbufferType; 265 } 266 267 GLenum Framebuffer::getStencilbufferType() 268 { 269 return mStencilbufferType; 270 } 271 272 GLuint Framebuffer::getColorbufferName(GLuint index) 273 { 274 return mColorbufferPointer[index].name(); 275 } 276 277 GLuint Framebuffer::getDepthbufferName() 278 { 279 return mDepthbufferPointer.name(); 280 } 281 282 GLuint Framebuffer::getStencilbufferName() 283 { 284 return mStencilbufferPointer.name(); 285 } 286 287 GLint Framebuffer::getColorbufferLayer(GLuint index) 288 { 289 return mColorbufferLayer[index]; 290 } 291 292 GLint Framebuffer::getDepthbufferLayer() 293 { 294 return mDepthbufferLayer; 295 } 296 297 GLint Framebuffer::getStencilbufferLayer() 298 { 299 return mStencilbufferLayer; 300 } 301 302 bool Framebuffer::hasStencil() 303 { 304 if(mStencilbufferType != GL_NONE) 305 { 306 Renderbuffer *stencilbufferObject = getStencilbuffer(); 307 308 if(stencilbufferObject) 309 { 310 return stencilbufferObject->getStencilSize() > 0; 311 } 312 } 313 314 return false; 315 } 316 317 GLenum Framebuffer::completeness() 318 { 319 int width; 320 int height; 321 int samples; 322 323 return completeness(width, height, samples); 324 } 325 326 GLenum Framebuffer::completeness(int &width, int &height, int &samples) 327 { 328 width = -1; 329 height = -1; 330 samples = -1; 331 332 GLint version = egl::getClientVersion(); 333 334 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++) 335 { 336 if(mColorbufferType[i] != GL_NONE) 337 { 338 Renderbuffer *colorbuffer = getColorbuffer(i); 339 340 if(!colorbuffer) 341 { 342 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 343 } 344 345 if(colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0 || (colorbuffer->getDepth() <= mColorbufferLayer[i])) 346 { 347 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 348 } 349 350 if(IsRenderbuffer(mColorbufferType[i])) 351 { 352 if(!IsColorRenderable(colorbuffer->getFormat(), version)) 353 { 354 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 355 } 356 } 357 else if(IsTextureTarget(mColorbufferType[i])) 358 { 359 GLenum format = colorbuffer->getFormat(); 360 361 if(!IsColorRenderable(format, version)) 362 { 363 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 364 } 365 366 if(IsDepthTexture(format) || IsStencilTexture(format)) 367 { 368 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 369 } 370 } 371 else 372 { 373 UNREACHABLE(mColorbufferType[i]); 374 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 375 } 376 377 if(width == -1 || height == -1) 378 { 379 width = colorbuffer->getWidth(); 380 height = colorbuffer->getHeight(); 381 samples = colorbuffer->getSamples(); 382 } 383 else 384 { 385 if(version < 3 && (width != colorbuffer->getWidth() || height != colorbuffer->getHeight())) 386 { 387 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; 388 } 389 390 if(samples != colorbuffer->getSamples()) 391 { 392 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; 393 } 394 395 width = std::min(width, colorbuffer->getWidth()); 396 height = std::min(height, colorbuffer->getHeight()); 397 } 398 } 399 } 400 401 Renderbuffer *depthbuffer = nullptr; 402 Renderbuffer *stencilbuffer = nullptr; 403 404 if(mDepthbufferType != GL_NONE) 405 { 406 depthbuffer = getDepthbuffer(); 407 408 if(!depthbuffer) 409 { 410 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 411 } 412 413 if(depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0 || (depthbuffer->getDepth() <= mDepthbufferLayer)) 414 { 415 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 416 } 417 418 if(IsRenderbuffer(mDepthbufferType)) 419 { 420 if(!es2::IsDepthRenderable(depthbuffer->getFormat(), version)) 421 { 422 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 423 } 424 } 425 else if(IsTextureTarget(mDepthbufferType)) 426 { 427 if(!es2::IsDepthTexture(depthbuffer->getFormat())) 428 { 429 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 430 } 431 } 432 else 433 { 434 UNREACHABLE(mDepthbufferType); 435 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 436 } 437 438 if(width == -1 || height == -1) 439 { 440 width = depthbuffer->getWidth(); 441 height = depthbuffer->getHeight(); 442 samples = depthbuffer->getSamples(); 443 } 444 else 445 { 446 if(version < 3 && (width != depthbuffer->getWidth() || height != depthbuffer->getHeight())) 447 { 448 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; 449 } 450 451 if(samples != depthbuffer->getSamples()) 452 { 453 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; 454 } 455 456 width = std::min(width, depthbuffer->getWidth()); 457 height = std::min(height, depthbuffer->getHeight()); 458 } 459 } 460 461 if(mStencilbufferType != GL_NONE) 462 { 463 stencilbuffer = getStencilbuffer(); 464 465 if(!stencilbuffer) 466 { 467 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 468 } 469 470 if(stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0 || (stencilbuffer->getDepth() <= mStencilbufferLayer)) 471 { 472 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 473 } 474 475 if(IsRenderbuffer(mStencilbufferType)) 476 { 477 if(!es2::IsStencilRenderable(stencilbuffer->getFormat(), version)) 478 { 479 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 480 } 481 } 482 else if(IsTextureTarget(mStencilbufferType)) 483 { 484 GLenum internalformat = stencilbuffer->getFormat(); 485 486 if(!es2::IsStencilTexture(internalformat)) 487 { 488 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 489 } 490 } 491 else 492 { 493 UNREACHABLE(mStencilbufferType); 494 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 495 } 496 497 if(width == -1 || height == -1) 498 { 499 width = stencilbuffer->getWidth(); 500 height = stencilbuffer->getHeight(); 501 samples = stencilbuffer->getSamples(); 502 } 503 else 504 { 505 if(version < 3 && (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())) 506 { 507 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; 508 } 509 510 if(samples != stencilbuffer->getSamples()) 511 { 512 return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; 513 } 514 515 width = std::min(width, stencilbuffer->getWidth()); 516 height = std::min(height, stencilbuffer->getHeight()); 517 } 518 } 519 520 if((version >= 3) && depthbuffer && stencilbuffer && (depthbuffer != stencilbuffer)) 521 { 522 // In the GLES 3.0 spec, section 4.4.4, Framebuffer Completeness: 523 // "The framebuffer object target is said to be framebuffer complete if all the following conditions are true: 524 // [...] 525 // Depth and stencil attachments, if present, are the same image. 526 // { FRAMEBUFFER_UNSUPPORTED }" 527 return GL_FRAMEBUFFER_UNSUPPORTED; 528 } 529 530 // We need to have at least one attachment to be complete 531 if(width == -1 || height == -1) 532 { 533 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; 534 } 535 536 return GL_FRAMEBUFFER_COMPLETE; 537 } 538 539 GLenum Framebuffer::getImplementationColorReadFormat() const 540 { 541 Renderbuffer *colorbuffer = getReadColorbuffer(); 542 543 if(colorbuffer) 544 { 545 switch(colorbuffer->getFormat()) 546 { 547 case GL_BGRA8_EXT: return GL_BGRA_EXT; 548 case GL_RGBA4: return GL_RGBA; 549 case GL_RGB5_A1: return GL_RGBA; 550 case GL_RGBA8: return GL_RGBA; 551 case GL_RGB565: return GL_RGBA; 552 case GL_RGB8: return GL_RGB; 553 case GL_R8: return GL_RED; 554 case GL_RG8: return GL_RG; 555 case GL_R8I: return GL_RED_INTEGER; 556 case GL_RG8I: return GL_RG_INTEGER; 557 case GL_RGB8I: return GL_RGB_INTEGER; 558 case GL_RGBA8I: return GL_RGBA_INTEGER; 559 case GL_R8UI: return GL_RED_INTEGER; 560 case GL_RG8UI: return GL_RG_INTEGER; 561 case GL_RGB8UI: return GL_RGB_INTEGER; 562 case GL_RGBA8UI: return GL_RGBA_INTEGER; 563 case GL_R16I: return GL_RED_INTEGER; 564 case GL_RG16I: return GL_RG_INTEGER; 565 case GL_RGB16I: return GL_RGB_INTEGER; 566 case GL_RGBA16I: return GL_RGBA_INTEGER; 567 case GL_R16UI: return GL_RED_INTEGER; 568 case GL_RG16UI: return GL_RG_INTEGER; 569 case GL_RGB16UI: return GL_RGB_INTEGER; 570 case GL_RGB10_A2UI: return GL_RGBA_INTEGER; 571 case GL_RGBA16UI: return GL_RGBA_INTEGER; 572 case GL_R32I: return GL_RED_INTEGER; 573 case GL_RG32I: return GL_RG_INTEGER; 574 case GL_RGB32I: return GL_RGB_INTEGER; 575 case GL_RGBA32I: return GL_RGBA_INTEGER; 576 case GL_R32UI: return GL_RED_INTEGER; 577 case GL_RG32UI: return GL_RG_INTEGER; 578 case GL_RGB32UI: return GL_RGB_INTEGER; 579 case GL_RGBA32UI: return GL_RGBA_INTEGER; 580 case GL_R16F: return GL_RED; 581 case GL_RG16F: return GL_RG; 582 case GL_R11F_G11F_B10F: return GL_RGB; 583 case GL_RGB16F: return GL_RGB; 584 case GL_RGBA16F: return GL_RGBA; 585 case GL_R32F: return GL_RED; 586 case GL_RG32F: return GL_RG; 587 case GL_RGB32F: return GL_RGB; 588 case GL_RGBA32F: return GL_RGBA; 589 case GL_RGB10_A2: return GL_RGBA; 590 case GL_SRGB8: return GL_RGB; 591 case GL_SRGB8_ALPHA8: return GL_RGBA; 592 default: 593 UNREACHABLE(colorbuffer->getFormat()); 594 } 595 } 596 597 return GL_RGBA; 598 } 599 600 GLenum Framebuffer::getImplementationColorReadType() const 601 { 602 Renderbuffer *colorbuffer = getReadColorbuffer(); 603 604 if(colorbuffer) 605 { 606 switch(colorbuffer->getFormat()) 607 { 608 case GL_BGRA8_EXT: return GL_UNSIGNED_BYTE; 609 case GL_RGBA4: return GL_UNSIGNED_SHORT_4_4_4_4; 610 case GL_RGB5_A1: return GL_UNSIGNED_SHORT_5_5_5_1; 611 case GL_RGBA8: return GL_UNSIGNED_BYTE; 612 case GL_RGB565: return GL_UNSIGNED_SHORT_5_6_5; 613 case GL_RGB8: return GL_UNSIGNED_BYTE; 614 case GL_R8: return GL_UNSIGNED_BYTE; 615 case GL_RG8: return GL_UNSIGNED_BYTE; 616 case GL_R8I: return GL_INT; 617 case GL_RG8I: return GL_INT; 618 case GL_RGB8I: return GL_INT; 619 case GL_RGBA8I: return GL_INT; 620 case GL_R8UI: return GL_UNSIGNED_BYTE; 621 case GL_RG8UI: return GL_UNSIGNED_BYTE; 622 case GL_RGB8UI: return GL_UNSIGNED_BYTE; 623 case GL_RGBA8UI: return GL_UNSIGNED_BYTE; 624 case GL_R16I: return GL_INT; 625 case GL_RG16I: return GL_INT; 626 case GL_RGB16I: return GL_INT; 627 case GL_RGBA16I: return GL_INT; 628 case GL_R16UI: return GL_UNSIGNED_INT; 629 case GL_RG16UI: return GL_UNSIGNED_INT; 630 case GL_RGB16UI: return GL_UNSIGNED_INT; 631 case GL_RGB10_A2UI: return GL_UNSIGNED_INT_2_10_10_10_REV; 632 case GL_RGBA16UI: return GL_UNSIGNED_INT; 633 case GL_R32I: return GL_INT; 634 case GL_RG32I: return GL_INT; 635 case GL_RGB32I: return GL_INT; 636 case GL_RGBA32I: return GL_INT; 637 case GL_R32UI: return GL_UNSIGNED_INT; 638 case GL_RG32UI: return GL_UNSIGNED_INT; 639 case GL_RGB32UI: return GL_UNSIGNED_INT; 640 case GL_RGBA32UI: return GL_UNSIGNED_INT; 641 case GL_R16F: return GL_FLOAT; 642 case GL_RG16F: return GL_FLOAT; 643 case GL_R11F_G11F_B10F: return GL_FLOAT; 644 case GL_RGB16F: return GL_FLOAT; 645 case GL_RGBA16F: return GL_FLOAT; 646 case GL_R32F: return GL_FLOAT; 647 case GL_RG32F: return GL_FLOAT; 648 case GL_RGB32F: return GL_FLOAT; 649 case GL_RGBA32F: return GL_FLOAT; 650 case GL_RGB10_A2: return GL_UNSIGNED_INT_2_10_10_10_REV; 651 case GL_SRGB8: return GL_UNSIGNED_BYTE; 652 case GL_SRGB8_ALPHA8: return GL_UNSIGNED_BYTE; 653 default: 654 UNREACHABLE(colorbuffer->getFormat()); 655 } 656 } 657 658 return GL_UNSIGNED_BYTE; 659 } 660 661 GLenum Framebuffer::getDepthReadFormat() const 662 { 663 Renderbuffer *depthbuffer = getDepthbuffer(); 664 665 if(depthbuffer) 666 { 667 // There is only one depth read format. 668 return GL_DEPTH_COMPONENT; 669 } 670 671 // If there is no depth buffer, GL_INVALID_OPERATION occurs. 672 return GL_NONE; 673 } 674 675 GLenum Framebuffer::getDepthReadType() const 676 { 677 Renderbuffer *depthbuffer = getDepthbuffer(); 678 679 if(depthbuffer) 680 { 681 switch(depthbuffer->getFormat()) 682 { 683 case GL_DEPTH_COMPONENT16: return GL_UNSIGNED_SHORT; 684 case GL_DEPTH_COMPONENT24: return GL_UNSIGNED_INT; 685 case GL_DEPTH_COMPONENT32_OES: return GL_UNSIGNED_INT; 686 case GL_DEPTH_COMPONENT32F: return GL_FLOAT; 687 case GL_DEPTH24_STENCIL8: return GL_UNSIGNED_INT_24_8_OES; 688 case GL_DEPTH32F_STENCIL8: return GL_FLOAT; 689 default: 690 UNREACHABLE(depthbuffer->getFormat()); 691 } 692 } 693 694 // If there is no depth buffer, GL_INVALID_OPERATION occurs. 695 return GL_NONE; 696 } 697 698 GLuint Framebuffer::getReadBufferIndex() const 699 { 700 switch(readBuffer) 701 { 702 case GL_BACK: 703 return 0; 704 case GL_NONE: 705 return GL_INVALID_INDEX; 706 default: 707 return readBuffer - GL_COLOR_ATTACHMENT0; 708 } 709 } 710 711 DefaultFramebuffer::DefaultFramebuffer() 712 { 713 readBuffer = GL_BACK; 714 drawBuffer[0] = GL_BACK; 715 } 716 717 DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil) 718 { 719 GLenum defaultRenderbufferType = egl::getClientVersion() < 3 ? GL_RENDERBUFFER : GL_FRAMEBUFFER_DEFAULT; 720 mColorbufferPointer[0] = new Renderbuffer(0, colorbuffer); 721 mColorbufferType[0] = defaultRenderbufferType; 722 723 readBuffer = GL_BACK; 724 drawBuffer[0] = GL_BACK; 725 for(int i = 1; i < MAX_COLOR_ATTACHMENTS; i++) 726 { 727 mColorbufferPointer[i] = nullptr; 728 mColorbufferType[i] = GL_NONE; 729 } 730 731 Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(0, depthStencil); 732 mDepthbufferPointer = depthStencilRenderbuffer; 733 mStencilbufferPointer = depthStencilRenderbuffer; 734 735 mDepthbufferType = (depthStencilRenderbuffer->getDepthSize() != 0) ? defaultRenderbufferType : GL_NONE; 736 mStencilbufferType = (depthStencilRenderbuffer->getStencilSize() != 0) ? defaultRenderbufferType : GL_NONE; 737 } 738 739 } 740