// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Framebuffer.cpp: Implements the Framebuffer class. Implements GL framebuffer
// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.

#include "Framebuffer.h"

#include "main.h"
#include "Renderbuffer.h"
#include "Texture.h"
#include "utilities.h"

namespace es2
{

bool Framebuffer::IsRenderbuffer(GLenum type)
{
	return type == GL_RENDERBUFFER || type == GL_FRAMEBUFFER_DEFAULT;
}

Framebuffer::Framebuffer()
{
	for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
	{
		mColorbufferType[i] = GL_NONE;
	}
	mDepthbufferType = GL_NONE;
	mStencilbufferType = GL_NONE;

	readBuffer = GL_BACK;
	drawBuffer[0] = GL_BACK;
	for(int i = 1; i < MAX_COLOR_ATTACHMENTS; ++i)
	{
		drawBuffer[i] = GL_NONE;
	}
}

Framebuffer::~Framebuffer()
{
	for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
	{
		mColorbufferPointer[i] = nullptr;
	}
	mDepthbufferPointer = nullptr;
	mStencilbufferPointer = nullptr;
}

Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle, GLint level, GLint layer) const
{
	Context *context = getContext();
	Renderbuffer *buffer = nullptr;

	if(type == GL_NONE)
	{
		buffer = nullptr;
	}
	else if(IsRenderbuffer(type))
	{
		buffer = context->getRenderbuffer(handle);
	}
	else if(IsTextureTarget(type))
	{
		buffer = context->getTexture(handle)->getRenderbuffer(type, level, layer);
	}
	else UNREACHABLE(type);

	return buffer;
}

void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer, GLuint index, GLint level, GLint layer)
{
	mColorbufferType[index] = (colorbuffer != 0) ? type : GL_NONE;
	mColorbufferPointer[index] = lookupRenderbuffer(type, colorbuffer, level, layer);
}

void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer)
{
	mDepthbufferType = (depthbuffer != 0) ? type : GL_NONE;
	mDepthbufferPointer = lookupRenderbuffer(type, depthbuffer, level, layer);
}

void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer)
{
	mStencilbufferType = (stencilbuffer != 0) ? type : GL_NONE;
	mStencilbufferPointer = lookupRenderbuffer(type, stencilbuffer, level, layer);
}

void Framebuffer::setReadBuffer(GLenum buf)
{
	readBuffer = buf;
}

void Framebuffer::setDrawBuffer(GLuint index, GLenum buf)
{
	drawBuffer[index] = buf;
}

GLenum Framebuffer::getReadBuffer() const
{
	return readBuffer;
}

GLenum Framebuffer::getDrawBuffer(GLuint index) const
{
	return drawBuffer[index];
}

void Framebuffer::detachTexture(GLuint texture)
{
	for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
	{
		if(mColorbufferPointer[i].name() == texture && IsTextureTarget(mColorbufferType[i]))
		{
			mColorbufferType[i] = GL_NONE;
			mColorbufferPointer[i] = nullptr;
		}
	}

	if(mDepthbufferPointer.name() == texture && IsTextureTarget(mDepthbufferType))
	{
		mDepthbufferType = GL_NONE;
		mDepthbufferPointer = nullptr;
	}

	if(mStencilbufferPointer.name() == texture && IsTextureTarget(mStencilbufferType))
	{
		mStencilbufferType = GL_NONE;
		mStencilbufferPointer = nullptr;
	}
}

void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
{
	for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
	{
		if(mColorbufferPointer[i].name() == renderbuffer && IsRenderbuffer(mColorbufferType[i]))
		{
			mColorbufferType[i] = GL_NONE;
			mColorbufferPointer[i] = nullptr;
		}
	}

	if(mDepthbufferPointer.name() == renderbuffer && IsRenderbuffer(mDepthbufferType))
	{
		mDepthbufferType = GL_NONE;
		mDepthbufferPointer = nullptr;
	}

	if(mStencilbufferPointer.name() == renderbuffer && IsRenderbuffer(mStencilbufferType))
	{
		mStencilbufferType = GL_NONE;
		mStencilbufferPointer = nullptr;
	}
}

// Increments refcount on surface.
// caller must Release() the returned surface
egl::Image *Framebuffer::getRenderTarget(GLuint index)
{
	Renderbuffer *colorbuffer = mColorbufferPointer[index];

	if(colorbuffer)
	{
		return colorbuffer->getRenderTarget();
	}

	return nullptr;
}

egl::Image *Framebuffer::getReadRenderTarget()
{
	Context *context = getContext();
	return getRenderTarget(context->getReadFramebufferColorIndex());
}

// Increments refcount on surface.
// caller must Release() the returned surface
egl::Image *Framebuffer::getDepthBuffer()
{
	Renderbuffer *depthbuffer = mDepthbufferPointer;

	if(depthbuffer)
	{
		return depthbuffer->getRenderTarget();
	}

	return nullptr;
}

// Increments refcount on surface.
// caller must Release() the returned surface
egl::Image *Framebuffer::getStencilBuffer()
{
	Renderbuffer *stencilbuffer = mStencilbufferPointer;

	if(stencilbuffer)
	{
		return stencilbuffer->getRenderTarget();
	}

	return nullptr;
}

Renderbuffer *Framebuffer::getColorbuffer(GLuint index) const
{
	return (index < MAX_COLOR_ATTACHMENTS) ? mColorbufferPointer[index] : (Renderbuffer*)nullptr;
}

Renderbuffer *Framebuffer::getReadColorbuffer() const
{
	Context *context = getContext();
	return getColorbuffer(context->getReadFramebufferColorIndex());
}

Renderbuffer *Framebuffer::getDepthbuffer() const
{
	return mDepthbufferPointer;
}

Renderbuffer *Framebuffer::getStencilbuffer() const
{
	return mStencilbufferPointer;
}

GLenum Framebuffer::getColorbufferType(GLuint index)
{
	return mColorbufferType[index];
}

GLenum Framebuffer::getDepthbufferType()
{
	return mDepthbufferType;
}

GLenum Framebuffer::getStencilbufferType()
{
	return mStencilbufferType;
}

GLuint Framebuffer::getColorbufferName(GLuint index)
{
	return mColorbufferPointer[index].name();
}

GLuint Framebuffer::getDepthbufferName()
{
	return mDepthbufferPointer.name();
}

GLuint Framebuffer::getStencilbufferName()
{
	return mStencilbufferPointer.name();
}

GLint Framebuffer::getColorbufferLayer(GLuint index)
{
	Renderbuffer *colorbuffer = mColorbufferPointer[index];
	return colorbuffer ? colorbuffer->getLayer() : 0;
}

GLint Framebuffer::getDepthbufferLayer()
{
	return mDepthbufferPointer ? mDepthbufferPointer->getLayer() : 0;
}

GLint Framebuffer::getStencilbufferLayer()
{
	return mStencilbufferPointer ? mStencilbufferPointer->getLayer() : 0;
}

bool Framebuffer::hasStencil()
{
	if(mStencilbufferType != GL_NONE)
	{
		Renderbuffer *stencilbufferObject = getStencilbuffer();

		if(stencilbufferObject)
		{
			return stencilbufferObject->getStencilSize() > 0;
		}
	}

	return false;
}

GLenum Framebuffer::completeness()
{
	int width;
	int height;
	int samples;

	return completeness(width, height, samples);
}

GLenum Framebuffer::completeness(int &width, int &height, int &samples)
{
	width = -1;
	height = -1;
	samples = -1;

	for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
	{
		if(mColorbufferType[i] != GL_NONE)
		{
			Renderbuffer *colorbuffer = getColorbuffer(i);

			if(!colorbuffer)
			{
				return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
			}

			if(colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0 || (colorbuffer->getDepth() <= colorbuffer->getLayer()))
			{
				return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
			}

			if(IsRenderbuffer(mColorbufferType[i]))
			{
				if(!IsColorRenderable(colorbuffer->getFormat(), egl::getClientVersion(), false))
				{
					return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
				}
			}
			else if(IsTextureTarget(mColorbufferType[i]))
			{
				GLenum format = colorbuffer->getFormat();

				if(!IsColorRenderable(format, egl::getClientVersion(), true))
				{
					return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
				}

				if(IsDepthTexture(format) || IsStencilTexture(format))
				{
					return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
				}
			}
			else
			{
				UNREACHABLE(mColorbufferType[i]);
				return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
			}

			width = colorbuffer->getWidth();
			height = colorbuffer->getHeight();

			if(samples == -1)
			{
				samples = colorbuffer->getSamples();
			}
			else if(samples != colorbuffer->getSamples())
			{
				return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
			}
		}
	}

	Renderbuffer *depthbuffer = nullptr;
	Renderbuffer *stencilbuffer = nullptr;

	if(mDepthbufferType != GL_NONE)
	{
		depthbuffer = getDepthbuffer();

		if(!depthbuffer)
		{
			return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
		}

		if(depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
		{
			return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
		}

		if(IsRenderbuffer(mDepthbufferType))
		{
			if(!es2::IsDepthRenderable(depthbuffer->getFormat(), egl::getClientVersion()))
			{
				return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
			}
		}
		else if(IsTextureTarget(mDepthbufferType))
		{
			if(!es2::IsDepthTexture(depthbuffer->getFormat()))
			{
				return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
			}
		}
		else
		{
			UNREACHABLE(mDepthbufferType);
			return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
		}

		if(width == -1 || height == -1)
		{
			width = depthbuffer->getWidth();
			height = depthbuffer->getHeight();
			samples = depthbuffer->getSamples();
		}
		else if(width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
		{
			return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
		}
		else if(samples != depthbuffer->getSamples())
		{
			return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
		}
	}

	if(mStencilbufferType != GL_NONE)
	{
		stencilbuffer = getStencilbuffer();

		if(!stencilbuffer)
		{
			return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
		}

		if(stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
		{
			return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
		}

		if(IsRenderbuffer(mStencilbufferType))
		{
			if(!es2::IsStencilRenderable(stencilbuffer->getFormat(), egl::getClientVersion()))
			{
				return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
			}
		}
		else if(IsTextureTarget(mStencilbufferType))
		{
			GLenum internalformat = stencilbuffer->getFormat();

			if(!es2::IsStencilTexture(internalformat))
			{
				return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
			}
		}
		else
		{
			UNREACHABLE(mStencilbufferType);
			return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
		}

		if(width == -1 || height == -1)
		{
			width = stencilbuffer->getWidth();
			height = stencilbuffer->getHeight();
			samples = stencilbuffer->getSamples();
		}
		else if(width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
		{
			return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
		}
		else if(samples != stencilbuffer->getSamples())
		{
			return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
		}
	}

	if((egl::getClientVersion() >= 3) && depthbuffer && stencilbuffer && (depthbuffer != stencilbuffer))
	{
		// In the GLES 3.0 spec, section 4.4.4, Framebuffer Completeness:
		// "The framebuffer object target is said to be framebuffer complete if all the following conditions are true:
		//  [...]
		//  Depth and stencil attachments, if present, are the same image.
		//  { FRAMEBUFFER_UNSUPPORTED }"
		return GL_FRAMEBUFFER_UNSUPPORTED;
	}

	// We need to have at least one attachment to be complete
	if(width == -1 || height == -1)
	{
		return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
	}

	return GL_FRAMEBUFFER_COMPLETE;
}

GLenum Framebuffer::getImplementationColorReadFormat() const
{
	Renderbuffer *colorbuffer = getReadColorbuffer();

	if(colorbuffer)
	{
		switch(colorbuffer->getInternalFormat())
		{
		case sw::FORMAT_A8B8G8R8I:       return GL_RGBA_INTEGER;
		case sw::FORMAT_A8B8G8R8UI:      return GL_RGBA_INTEGER;
		case sw::FORMAT_A16B16G16R16I:   return GL_RGBA_INTEGER;
		case sw::FORMAT_A16B16G16R16UI:  return GL_RGBA_INTEGER;
		case sw::FORMAT_A32B32G32R32I:   return GL_RGBA_INTEGER;
		case sw::FORMAT_A32B32G32R32UI:  return GL_RGBA_INTEGER;
		case sw::FORMAT_A2B10G10R10:     return GL_RGB10_A2;
		case sw::FORMAT_A8B8G8R8I_SNORM: return GL_RGBA;
		case sw::FORMAT_A8B8G8R8:        return GL_RGBA;
		case sw::FORMAT_SRGB8_A8:        return GL_RGBA;
		case sw::FORMAT_A8R8G8B8:        return GL_BGRA_EXT;
		case sw::FORMAT_A1R5G5B5:        return GL_BGRA_EXT;
		case sw::FORMAT_X8B8G8R8I:       return GL_RGBA_INTEGER;
		case sw::FORMAT_X8B8G8R8UI:      return GL_RGBA_INTEGER;
		case sw::FORMAT_X16B16G16R16I:   return GL_RGBA_INTEGER;
		case sw::FORMAT_X16B16G16R16UI:  return GL_RGBA_INTEGER;
		case sw::FORMAT_X32B32G32R32I:   return GL_RGBA_INTEGER;
		case sw::FORMAT_X32B32G32R32UI:  return GL_RGBA_INTEGER;
		case sw::FORMAT_X8B8G8R8I_SNORM: return GL_RGBA;
		case sw::FORMAT_SRGB8_X8:        return GL_RGBA;
		case sw::FORMAT_X8B8G8R8:        return GL_RGBA;
		case sw::FORMAT_X8R8G8B8:        return GL_BGRA_EXT;
		case sw::FORMAT_R5G6B5:          return GL_RGB;
		case sw::FORMAT_G8R8I:           return GL_RG_INTEGER;
		case sw::FORMAT_G8R8UI:          return GL_RG_INTEGER;
		case sw::FORMAT_G16R16I:         return GL_RG_INTEGER;
		case sw::FORMAT_G16R16UI:        return GL_RG_INTEGER;
		case sw::FORMAT_G32R32I:         return GL_RG_INTEGER;
		case sw::FORMAT_G32R32UI:        return GL_RG_INTEGER;
		case sw::FORMAT_R8I:             return GL_RED_INTEGER;
		case sw::FORMAT_R8UI:            return GL_RED_INTEGER;
		case sw::FORMAT_R16I:            return GL_RED_INTEGER;
		case sw::FORMAT_R16UI:           return GL_RED_INTEGER;
		case sw::FORMAT_R32I:            return GL_RED_INTEGER;
		case sw::FORMAT_R32UI:           return GL_RED_INTEGER;
		case sw::FORMAT_R8:              return GL_RED;
		case sw::FORMAT_R8I_SNORM:       return GL_RED;
		case sw::FORMAT_R16F:            return GL_RED;
		case sw::FORMAT_R32F:            return GL_RED;
		case sw::FORMAT_G8R8:            return GL_RG;
		case sw::FORMAT_G8R8I_SNORM:     return GL_RG;
		case sw::FORMAT_G16R16F:         return GL_RG;
		case sw::FORMAT_G32R32F:         return GL_RG;
		case sw::FORMAT_B16G16R16F:      return GL_RGB;
		case sw::FORMAT_X32B32G32R32F:   return GL_RGBA;
		case sw::FORMAT_A16B16G16R16F:   return GL_RGBA;
		case sw::FORMAT_A32B32G32R32F:   return GL_RGBA;
		default:
			UNREACHABLE(colorbuffer->getInternalFormat());
		}
	}

	return GL_RGBA;
}

GLenum Framebuffer::getImplementationColorReadType() const
{
	Renderbuffer *colorbuffer = getReadColorbuffer();

	if(colorbuffer)
	{
		switch(colorbuffer->getInternalFormat())
		{
		case sw::FORMAT_R16F:            return GL_FLOAT;
		case sw::FORMAT_G16R16F:         return GL_FLOAT;
		case sw::FORMAT_B16G16R16F:      return GL_FLOAT;
		case sw::FORMAT_A16B16G16R16F:   return GL_FLOAT;
		case sw::FORMAT_R32F:            return GL_FLOAT;
		case sw::FORMAT_G32R32F:         return GL_FLOAT;
		case sw::FORMAT_B32G32R32F:      return GL_FLOAT;
		case sw::FORMAT_X32B32G32R32F:   return GL_FLOAT;
		case sw::FORMAT_A32B32G32R32F:   return GL_FLOAT;
		case sw::FORMAT_R8I_SNORM:       return GL_BYTE;
		case sw::FORMAT_G8R8I_SNORM:     return GL_BYTE;
		case sw::FORMAT_X8B8G8R8I_SNORM: return GL_BYTE;
		case sw::FORMAT_A8B8G8R8I_SNORM: return GL_BYTE;
		case sw::FORMAT_R8:              return GL_UNSIGNED_BYTE;
		case sw::FORMAT_G8R8:            return GL_UNSIGNED_BYTE;
		case sw::FORMAT_SRGB8_X8:        return GL_UNSIGNED_BYTE;
		case sw::FORMAT_SRGB8_A8:        return GL_UNSIGNED_BYTE;
		case sw::FORMAT_A8R8G8B8:        return GL_UNSIGNED_BYTE;
		case sw::FORMAT_A8B8G8R8:        return GL_UNSIGNED_BYTE;
		case sw::FORMAT_X8R8G8B8:        return GL_UNSIGNED_BYTE;
		case sw::FORMAT_X8B8G8R8:        return GL_UNSIGNED_BYTE;
		case sw::FORMAT_R8I:             return GL_INT;
		case sw::FORMAT_G8R8I:           return GL_INT;
		case sw::FORMAT_X8B8G8R8I:       return GL_INT;
		case sw::FORMAT_A8B8G8R8I:       return GL_INT;
		case sw::FORMAT_R16I:            return GL_INT;
		case sw::FORMAT_G16R16I:         return GL_INT;
		case sw::FORMAT_X16B16G16R16I:   return GL_INT;
		case sw::FORMAT_A16B16G16R16I:   return GL_INT;
		case sw::FORMAT_R32I:            return GL_INT;
		case sw::FORMAT_G32R32I:         return GL_INT;
		case sw::FORMAT_X32B32G32R32I:   return GL_INT;
		case sw::FORMAT_A32B32G32R32I:   return GL_INT;
		case sw::FORMAT_R8UI:            return GL_UNSIGNED_INT;
		case sw::FORMAT_G8R8UI:          return GL_UNSIGNED_INT;
		case sw::FORMAT_X8B8G8R8UI:      return GL_UNSIGNED_INT;
		case sw::FORMAT_A8B8G8R8UI:      return GL_UNSIGNED_INT;
		case sw::FORMAT_R16UI:           return GL_UNSIGNED_INT;
		case sw::FORMAT_G16R16UI:        return GL_UNSIGNED_INT;
		case sw::FORMAT_X16B16G16R16UI:  return GL_UNSIGNED_INT;
		case sw::FORMAT_A16B16G16R16UI:  return GL_UNSIGNED_INT;
		case sw::FORMAT_R32UI:           return GL_UNSIGNED_INT;
		case sw::FORMAT_G32R32UI:        return GL_UNSIGNED_INT;
		case sw::FORMAT_X32B32G32R32UI:  return GL_UNSIGNED_INT;
		case sw::FORMAT_A32B32G32R32UI:  return GL_UNSIGNED_INT;
		case sw::FORMAT_A2B10G10R10:     return GL_UNSIGNED_INT_10_10_10_2_OES;
		case sw::FORMAT_A1R5G5B5:        return GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT;
		case sw::FORMAT_R5G6B5:          return GL_UNSIGNED_SHORT_5_6_5;
		default:
			UNREACHABLE(colorbuffer->getInternalFormat());
		}
	}

	return GL_UNSIGNED_BYTE;
}

GLenum Framebuffer::getDepthReadFormat() const
{
	Renderbuffer *depthbuffer = getDepthbuffer();

	if(depthbuffer)
	{
		// There is only one depth read format.
		return GL_DEPTH_COMPONENT;
	}

	// If there is no depth buffer, GL_INVALID_OPERATION occurs.
	return GL_NONE;
}

GLenum Framebuffer::getDepthReadType() const
{
	Renderbuffer *depthbuffer = getDepthbuffer();

	if(depthbuffer)
	{
		switch(depthbuffer->getInternalFormat())
		{
		case sw::FORMAT_D16:                return GL_UNSIGNED_SHORT;
		case sw::FORMAT_D24S8:              return GL_UNSIGNED_INT_24_8_OES;
		case sw::FORMAT_D32:                return GL_UNSIGNED_INT;
		case sw::FORMAT_D32F:
		case sw::FORMAT_D32F_COMPLEMENTARY:
		case sw::FORMAT_D32F_LOCKABLE:
		case sw::FORMAT_D32FS8_TEXTURE:
		case sw::FORMAT_D32FS8_SHADOW:      return GL_FLOAT;
		default:
			UNREACHABLE(depthbuffer->getInternalFormat());
		}
	}

	// If there is no depth buffer, GL_INVALID_OPERATION occurs.
	return GL_NONE;
}

DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
{
	GLenum defaultRenderbufferType = egl::getClientVersion() < 3 ? GL_RENDERBUFFER : GL_FRAMEBUFFER_DEFAULT;
	mColorbufferPointer[0] = new Renderbuffer(0, colorbuffer);
	mColorbufferType[0] = defaultRenderbufferType;

	for(int i = 1; i < MAX_COLOR_ATTACHMENTS; i++)
	{
		mColorbufferPointer[i] = nullptr;
		mColorbufferType[i] = GL_NONE;
	}

	Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(0, depthStencil);
	mDepthbufferPointer = depthStencilRenderbuffer;
	mStencilbufferPointer = depthStencilRenderbuffer;

	mDepthbufferType = (depthStencilRenderbuffer->getDepthSize() != 0) ? defaultRenderbufferType : GL_NONE;
	mStencilbufferType = (depthStencilRenderbuffer->getStencilSize() != 0) ? defaultRenderbufferType : GL_NONE;
}

}
