1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/angle/src/libGLESv2/Framebuffer.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,603 @@ 1.4 +#include "precompiled.h" 1.5 +// 1.6 +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. 1.7 +// Use of this source code is governed by a BSD-style license that can be 1.8 +// found in the LICENSE file. 1.9 +// 1.10 + 1.11 +// Framebuffer.cpp: Implements the gl::Framebuffer class. Implements GL framebuffer 1.12 +// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105. 1.13 + 1.14 +#include "libGLESv2/Framebuffer.h" 1.15 + 1.16 +#include "libGLESv2/main.h" 1.17 +#include "libGLESv2/utilities.h" 1.18 +#include "libGLESv2/Texture.h" 1.19 +#include "libGLESv2/Context.h" 1.20 +#include "libGLESv2/renderer/Renderer.h" 1.21 +#include "libGLESv2/Renderbuffer.h" 1.22 + 1.23 +namespace gl 1.24 +{ 1.25 + 1.26 +Framebuffer::Framebuffer(rx::Renderer *renderer) 1.27 + : mRenderer(renderer) 1.28 +{ 1.29 + for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) 1.30 + { 1.31 + mColorbufferTypes[colorAttachment] = GL_NONE; 1.32 + mDrawBufferStates[colorAttachment] = GL_NONE; 1.33 + } 1.34 + mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT; 1.35 + mReadBufferState = GL_COLOR_ATTACHMENT0_EXT; 1.36 + 1.37 + mDepthbufferType = GL_NONE; 1.38 + mStencilbufferType = GL_NONE; 1.39 +} 1.40 + 1.41 +Framebuffer::~Framebuffer() 1.42 +{ 1.43 + for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) 1.44 + { 1.45 + mColorbufferPointers[colorAttachment].set(NULL); 1.46 + } 1.47 + mDepthbufferPointer.set(NULL); 1.48 + mStencilbufferPointer.set(NULL); 1.49 +} 1.50 + 1.51 +Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const 1.52 +{ 1.53 + gl::Context *context = gl::getContext(); 1.54 + Renderbuffer *buffer = NULL; 1.55 + 1.56 + if (type == GL_NONE) 1.57 + { 1.58 + buffer = NULL; 1.59 + } 1.60 + else if (type == GL_RENDERBUFFER) 1.61 + { 1.62 + buffer = context->getRenderbuffer(handle); 1.63 + } 1.64 + else if (IsInternalTextureTarget(type)) 1.65 + { 1.66 + buffer = context->getTexture(handle)->getRenderbuffer(type); 1.67 + } 1.68 + else 1.69 + { 1.70 + UNREACHABLE(); 1.71 + } 1.72 + 1.73 + return buffer; 1.74 +} 1.75 + 1.76 +void Framebuffer::setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer) 1.77 +{ 1.78 + ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS); 1.79 + mColorbufferTypes[colorAttachment] = (colorbuffer != 0) ? type : GL_NONE; 1.80 + mColorbufferPointers[colorAttachment].set(lookupRenderbuffer(type, colorbuffer)); 1.81 +} 1.82 + 1.83 +void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer) 1.84 +{ 1.85 + mDepthbufferType = (depthbuffer != 0) ? type : GL_NONE; 1.86 + mDepthbufferPointer.set(lookupRenderbuffer(type, depthbuffer)); 1.87 +} 1.88 + 1.89 +void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer) 1.90 +{ 1.91 + mStencilbufferType = (stencilbuffer != 0) ? type : GL_NONE; 1.92 + mStencilbufferPointer.set(lookupRenderbuffer(type, stencilbuffer)); 1.93 +} 1.94 + 1.95 +void Framebuffer::detachTexture(GLuint texture) 1.96 +{ 1.97 + for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) 1.98 + { 1.99 + if (mColorbufferPointers[colorAttachment].id() == texture && IsInternalTextureTarget(mColorbufferTypes[colorAttachment])) 1.100 + { 1.101 + mColorbufferTypes[colorAttachment] = GL_NONE; 1.102 + mColorbufferPointers[colorAttachment].set(NULL); 1.103 + } 1.104 + } 1.105 + 1.106 + if (mDepthbufferPointer.id() == texture && IsInternalTextureTarget(mDepthbufferType)) 1.107 + { 1.108 + mDepthbufferType = GL_NONE; 1.109 + mDepthbufferPointer.set(NULL); 1.110 + } 1.111 + 1.112 + if (mStencilbufferPointer.id() == texture && IsInternalTextureTarget(mStencilbufferType)) 1.113 + { 1.114 + mStencilbufferType = GL_NONE; 1.115 + mStencilbufferPointer.set(NULL); 1.116 + } 1.117 +} 1.118 + 1.119 +void Framebuffer::detachRenderbuffer(GLuint renderbuffer) 1.120 +{ 1.121 + for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) 1.122 + { 1.123 + if (mColorbufferPointers[colorAttachment].id() == renderbuffer && mColorbufferTypes[colorAttachment] == GL_RENDERBUFFER) 1.124 + { 1.125 + mColorbufferTypes[colorAttachment] = GL_NONE; 1.126 + mColorbufferPointers[colorAttachment].set(NULL); 1.127 + } 1.128 + } 1.129 + 1.130 + if (mDepthbufferPointer.id() == renderbuffer && mDepthbufferType == GL_RENDERBUFFER) 1.131 + { 1.132 + mDepthbufferType = GL_NONE; 1.133 + mDepthbufferPointer.set(NULL); 1.134 + } 1.135 + 1.136 + if (mStencilbufferPointer.id() == renderbuffer && mStencilbufferType == GL_RENDERBUFFER) 1.137 + { 1.138 + mStencilbufferType = GL_NONE; 1.139 + mStencilbufferPointer.set(NULL); 1.140 + } 1.141 +} 1.142 + 1.143 +unsigned int Framebuffer::getRenderTargetSerial(unsigned int colorAttachment) const 1.144 +{ 1.145 + ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS); 1.146 + 1.147 + Renderbuffer *colorbuffer = mColorbufferPointers[colorAttachment].get(); 1.148 + 1.149 + if (colorbuffer) 1.150 + { 1.151 + return colorbuffer->getSerial(); 1.152 + } 1.153 + 1.154 + return 0; 1.155 +} 1.156 + 1.157 +unsigned int Framebuffer::getDepthbufferSerial() const 1.158 +{ 1.159 + Renderbuffer *depthbuffer = mDepthbufferPointer.get(); 1.160 + 1.161 + if (depthbuffer) 1.162 + { 1.163 + return depthbuffer->getSerial(); 1.164 + } 1.165 + 1.166 + return 0; 1.167 +} 1.168 + 1.169 +unsigned int Framebuffer::getStencilbufferSerial() const 1.170 +{ 1.171 + Renderbuffer *stencilbuffer = mStencilbufferPointer.get(); 1.172 + 1.173 + if (stencilbuffer) 1.174 + { 1.175 + return stencilbuffer->getSerial(); 1.176 + } 1.177 + 1.178 + return 0; 1.179 +} 1.180 + 1.181 +Renderbuffer *Framebuffer::getColorbuffer(unsigned int colorAttachment) const 1.182 +{ 1.183 + ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS); 1.184 + return mColorbufferPointers[colorAttachment].get(); 1.185 +} 1.186 + 1.187 +Renderbuffer *Framebuffer::getDepthbuffer() const 1.188 +{ 1.189 + return mDepthbufferPointer.get(); 1.190 +} 1.191 + 1.192 +Renderbuffer *Framebuffer::getStencilbuffer() const 1.193 +{ 1.194 + return mStencilbufferPointer.get(); 1.195 +} 1.196 + 1.197 +Renderbuffer *Framebuffer::getDepthOrStencilbuffer() const 1.198 +{ 1.199 + Renderbuffer *depthstencilbuffer = mDepthbufferPointer.get(); 1.200 + 1.201 + if (!depthstencilbuffer) 1.202 + { 1.203 + depthstencilbuffer = mStencilbufferPointer.get(); 1.204 + } 1.205 + 1.206 + return depthstencilbuffer; 1.207 +} 1.208 + 1.209 +Renderbuffer *Framebuffer::getReadColorbuffer() const 1.210 +{ 1.211 + // Will require more logic if glReadBuffers is supported 1.212 + return mColorbufferPointers[0].get(); 1.213 +} 1.214 + 1.215 +GLenum Framebuffer::getReadColorbufferType() const 1.216 +{ 1.217 + // Will require more logic if glReadBuffers is supported 1.218 + return mColorbufferTypes[0]; 1.219 +} 1.220 + 1.221 +Renderbuffer *Framebuffer::getFirstColorbuffer() const 1.222 +{ 1.223 + for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) 1.224 + { 1.225 + if (mColorbufferTypes[colorAttachment] != GL_NONE) 1.226 + { 1.227 + return mColorbufferPointers[colorAttachment].get(); 1.228 + } 1.229 + } 1.230 + 1.231 + return NULL; 1.232 +} 1.233 + 1.234 +GLenum Framebuffer::getColorbufferType(unsigned int colorAttachment) const 1.235 +{ 1.236 + ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS); 1.237 + return mColorbufferTypes[colorAttachment]; 1.238 +} 1.239 + 1.240 +GLenum Framebuffer::getDepthbufferType() const 1.241 +{ 1.242 + return mDepthbufferType; 1.243 +} 1.244 + 1.245 +GLenum Framebuffer::getStencilbufferType() const 1.246 +{ 1.247 + return mStencilbufferType; 1.248 +} 1.249 + 1.250 +GLuint Framebuffer::getColorbufferHandle(unsigned int colorAttachment) const 1.251 +{ 1.252 + ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS); 1.253 + return mColorbufferPointers[colorAttachment].id(); 1.254 +} 1.255 + 1.256 +GLuint Framebuffer::getDepthbufferHandle() const 1.257 +{ 1.258 + return mDepthbufferPointer.id(); 1.259 +} 1.260 + 1.261 +GLuint Framebuffer::getStencilbufferHandle() const 1.262 +{ 1.263 + return mStencilbufferPointer.id(); 1.264 +} 1.265 + 1.266 +GLenum Framebuffer::getDrawBufferState(unsigned int colorAttachment) const 1.267 +{ 1.268 + return mDrawBufferStates[colorAttachment]; 1.269 +} 1.270 + 1.271 +void Framebuffer::setDrawBufferState(unsigned int colorAttachment, GLenum drawBuffer) 1.272 +{ 1.273 + mDrawBufferStates[colorAttachment] = drawBuffer; 1.274 +} 1.275 + 1.276 +bool Framebuffer::isEnabledColorAttachment(unsigned int colorAttachment) const 1.277 +{ 1.278 + return (mColorbufferTypes[colorAttachment] != GL_NONE && mDrawBufferStates[colorAttachment] != GL_NONE); 1.279 +} 1.280 + 1.281 +bool Framebuffer::hasEnabledColorAttachment() const 1.282 +{ 1.283 + for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) 1.284 + { 1.285 + if (isEnabledColorAttachment(colorAttachment)) 1.286 + { 1.287 + return true; 1.288 + } 1.289 + } 1.290 + 1.291 + return false; 1.292 +} 1.293 + 1.294 +bool Framebuffer::hasStencil() const 1.295 +{ 1.296 + if (mStencilbufferType != GL_NONE) 1.297 + { 1.298 + const Renderbuffer *stencilbufferObject = getStencilbuffer(); 1.299 + 1.300 + if (stencilbufferObject) 1.301 + { 1.302 + return stencilbufferObject->getStencilSize() > 0; 1.303 + } 1.304 + } 1.305 + 1.306 + return false; 1.307 +} 1.308 + 1.309 +bool Framebuffer::usingExtendedDrawBuffers() const 1.310 +{ 1.311 + for (unsigned int colorAttachment = 1; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) 1.312 + { 1.313 + if (isEnabledColorAttachment(colorAttachment)) 1.314 + { 1.315 + return true; 1.316 + } 1.317 + } 1.318 + 1.319 + return false; 1.320 +} 1.321 + 1.322 +GLenum Framebuffer::completeness() const 1.323 +{ 1.324 + int width = 0; 1.325 + int height = 0; 1.326 + int colorbufferSize = 0; 1.327 + int samples = -1; 1.328 + bool missingAttachment = true; 1.329 + 1.330 + for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) 1.331 + { 1.332 + if (mColorbufferTypes[colorAttachment] != GL_NONE) 1.333 + { 1.334 + const Renderbuffer *colorbuffer = getColorbuffer(colorAttachment); 1.335 + 1.336 + if (!colorbuffer) 1.337 + { 1.338 + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 1.339 + } 1.340 + 1.341 + if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0) 1.342 + { 1.343 + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 1.344 + } 1.345 + 1.346 + if (mColorbufferTypes[colorAttachment] == GL_RENDERBUFFER) 1.347 + { 1.348 + if (!gl::IsColorRenderable(colorbuffer->getInternalFormat())) 1.349 + { 1.350 + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 1.351 + } 1.352 + } 1.353 + else if (IsInternalTextureTarget(mColorbufferTypes[colorAttachment])) 1.354 + { 1.355 + GLint internalformat = colorbuffer->getInternalFormat(); 1.356 + GLenum format = gl::ExtractFormat(internalformat); 1.357 + 1.358 + if (IsCompressed(format) || 1.359 + format == GL_ALPHA || 1.360 + format == GL_LUMINANCE || 1.361 + format == GL_LUMINANCE_ALPHA) 1.362 + { 1.363 + return GL_FRAMEBUFFER_UNSUPPORTED; 1.364 + } 1.365 + 1.366 + bool filtering, renderable; 1.367 + 1.368 + if ((gl::IsFloat32Format(internalformat) && !mRenderer->getFloat32TextureSupport(&filtering, &renderable)) || 1.369 + (gl::IsFloat16Format(internalformat) && !mRenderer->getFloat16TextureSupport(&filtering, &renderable))) 1.370 + { 1.371 + return GL_FRAMEBUFFER_UNSUPPORTED; 1.372 + } 1.373 + 1.374 + if (gl::IsDepthTexture(internalformat) || gl::IsStencilTexture(internalformat)) 1.375 + { 1.376 + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 1.377 + } 1.378 + } 1.379 + else 1.380 + { 1.381 + UNREACHABLE(); 1.382 + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 1.383 + } 1.384 + 1.385 + if (!missingAttachment) 1.386 + { 1.387 + // all color attachments must have the same width and height 1.388 + if (colorbuffer->getWidth() != width || colorbuffer->getHeight() != height) 1.389 + { 1.390 + return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; 1.391 + } 1.392 + 1.393 + // APPLE_framebuffer_multisample, which EXT_draw_buffers refers to, requires that 1.394 + // all color attachments have the same number of samples for the FBO to be complete. 1.395 + if (colorbuffer->getSamples() != samples) 1.396 + { 1.397 + return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT; 1.398 + } 1.399 + 1.400 + // all color attachments attachments must have the same number of bitplanes 1.401 + if (gl::ComputePixelSize(colorbuffer->getInternalFormat()) != colorbufferSize) 1.402 + { 1.403 + return GL_FRAMEBUFFER_UNSUPPORTED; 1.404 + } 1.405 + 1.406 + // D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness 1.407 + for (unsigned int previousColorAttachment = 0; previousColorAttachment < colorAttachment; previousColorAttachment++) 1.408 + { 1.409 + if (mColorbufferPointers[colorAttachment].get() == mColorbufferPointers[previousColorAttachment].get()) 1.410 + { 1.411 + return GL_FRAMEBUFFER_UNSUPPORTED; 1.412 + } 1.413 + } 1.414 + } 1.415 + else 1.416 + { 1.417 + width = colorbuffer->getWidth(); 1.418 + height = colorbuffer->getHeight(); 1.419 + samples = colorbuffer->getSamples(); 1.420 + colorbufferSize = gl::ComputePixelSize(colorbuffer->getInternalFormat()); 1.421 + missingAttachment = false; 1.422 + } 1.423 + } 1.424 + } 1.425 + 1.426 + const Renderbuffer *depthbuffer = NULL; 1.427 + const Renderbuffer *stencilbuffer = NULL; 1.428 + 1.429 + if (mDepthbufferType != GL_NONE) 1.430 + { 1.431 + depthbuffer = getDepthbuffer(); 1.432 + 1.433 + if (!depthbuffer) 1.434 + { 1.435 + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 1.436 + } 1.437 + 1.438 + if (depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0) 1.439 + { 1.440 + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 1.441 + } 1.442 + 1.443 + if (mDepthbufferType == GL_RENDERBUFFER) 1.444 + { 1.445 + if (!gl::IsDepthRenderable(depthbuffer->getInternalFormat())) 1.446 + { 1.447 + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 1.448 + } 1.449 + } 1.450 + else if (IsInternalTextureTarget(mDepthbufferType)) 1.451 + { 1.452 + GLint internalformat = depthbuffer->getInternalFormat(); 1.453 + 1.454 + // depth texture attachments require OES/ANGLE_depth_texture 1.455 + if (!mRenderer->getDepthTextureSupport()) 1.456 + { 1.457 + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 1.458 + } 1.459 + 1.460 + if (!gl::IsDepthTexture(internalformat)) 1.461 + { 1.462 + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 1.463 + } 1.464 + } 1.465 + else 1.466 + { 1.467 + UNREACHABLE(); 1.468 + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 1.469 + } 1.470 + 1.471 + if (missingAttachment) 1.472 + { 1.473 + width = depthbuffer->getWidth(); 1.474 + height = depthbuffer->getHeight(); 1.475 + samples = depthbuffer->getSamples(); 1.476 + missingAttachment = false; 1.477 + } 1.478 + else if (width != depthbuffer->getWidth() || height != depthbuffer->getHeight()) 1.479 + { 1.480 + return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; 1.481 + } 1.482 + else if (samples != depthbuffer->getSamples()) 1.483 + { 1.484 + return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE; 1.485 + } 1.486 + } 1.487 + 1.488 + if (mStencilbufferType != GL_NONE) 1.489 + { 1.490 + stencilbuffer = getStencilbuffer(); 1.491 + 1.492 + if (!stencilbuffer) 1.493 + { 1.494 + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 1.495 + } 1.496 + 1.497 + if (stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0) 1.498 + { 1.499 + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 1.500 + } 1.501 + 1.502 + if (mStencilbufferType == GL_RENDERBUFFER) 1.503 + { 1.504 + if (!gl::IsStencilRenderable(stencilbuffer->getInternalFormat())) 1.505 + { 1.506 + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 1.507 + } 1.508 + } 1.509 + else if (IsInternalTextureTarget(mStencilbufferType)) 1.510 + { 1.511 + GLint internalformat = stencilbuffer->getInternalFormat(); 1.512 + 1.513 + // texture stencil attachments come along as part 1.514 + // of OES_packed_depth_stencil + OES/ANGLE_depth_texture 1.515 + if (!mRenderer->getDepthTextureSupport()) 1.516 + { 1.517 + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 1.518 + } 1.519 + 1.520 + if (!gl::IsStencilTexture(internalformat)) 1.521 + { 1.522 + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 1.523 + } 1.524 + } 1.525 + else 1.526 + { 1.527 + UNREACHABLE(); 1.528 + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; 1.529 + } 1.530 + 1.531 + if (missingAttachment) 1.532 + { 1.533 + width = stencilbuffer->getWidth(); 1.534 + height = stencilbuffer->getHeight(); 1.535 + samples = stencilbuffer->getSamples(); 1.536 + missingAttachment = false; 1.537 + } 1.538 + else if (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight()) 1.539 + { 1.540 + return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; 1.541 + } 1.542 + else if (samples != stencilbuffer->getSamples()) 1.543 + { 1.544 + return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE; 1.545 + } 1.546 + } 1.547 + 1.548 + // if we have both a depth and stencil buffer, they must refer to the same object 1.549 + // since we only support packed_depth_stencil and not separate depth and stencil 1.550 + if (depthbuffer && stencilbuffer && (depthbuffer != stencilbuffer)) 1.551 + { 1.552 + return GL_FRAMEBUFFER_UNSUPPORTED; 1.553 + } 1.554 + 1.555 + // we need to have at least one attachment to be complete 1.556 + if (missingAttachment) 1.557 + { 1.558 + return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; 1.559 + } 1.560 + 1.561 + return GL_FRAMEBUFFER_COMPLETE; 1.562 +} 1.563 + 1.564 +DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil) 1.565 + : Framebuffer(renderer) 1.566 +{ 1.567 + mColorbufferPointers[0].set(new Renderbuffer(mRenderer, 0, colorbuffer)); 1.568 + 1.569 + Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(mRenderer, 0, depthStencil); 1.570 + mDepthbufferPointer.set(depthStencilRenderbuffer); 1.571 + mStencilbufferPointer.set(depthStencilRenderbuffer); 1.572 + 1.573 + mColorbufferTypes[0] = GL_RENDERBUFFER; 1.574 + mDepthbufferType = (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE; 1.575 + mStencilbufferType = (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE; 1.576 + 1.577 + mDrawBufferStates[0] = GL_BACK; 1.578 + mReadBufferState = GL_BACK; 1.579 +} 1.580 + 1.581 +int Framebuffer::getSamples() const 1.582 +{ 1.583 + if (completeness() == GL_FRAMEBUFFER_COMPLETE) 1.584 + { 1.585 + // for a complete framebuffer, all attachments must have the same sample count 1.586 + // in this case return the first nonzero sample size 1.587 + for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) 1.588 + { 1.589 + if (mColorbufferTypes[colorAttachment] != GL_NONE) 1.590 + { 1.591 + return getColorbuffer(colorAttachment)->getSamples(); 1.592 + } 1.593 + } 1.594 + } 1.595 + 1.596 + return 0; 1.597 +} 1.598 + 1.599 +GLenum DefaultFramebuffer::completeness() const 1.600 +{ 1.601 + // The default framebuffer *must* always be complete, though it may not be 1.602 + // subject to the same rules as application FBOs. ie, it could have 0x0 size. 1.603 + return GL_FRAMEBUFFER_COMPLETE; 1.604 +} 1.605 + 1.606 +}