michael@0: #include "precompiled.h" michael@0: // michael@0: // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: // michael@0: michael@0: // Renderbuffer.cpp: the gl::Renderbuffer class and its derived classes michael@0: // Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer michael@0: // objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108. michael@0: michael@0: #include "libGLESv2/Renderbuffer.h" michael@0: #include "libGLESv2/renderer/RenderTarget.h" michael@0: michael@0: #include "libGLESv2/Texture.h" michael@0: #include "libGLESv2/renderer/Renderer.h" michael@0: #include "libGLESv2/utilities.h" michael@0: michael@0: namespace gl michael@0: { michael@0: unsigned int RenderbufferStorage::mCurrentSerial = 1; michael@0: michael@0: RenderbufferInterface::RenderbufferInterface() michael@0: { michael@0: } michael@0: michael@0: // The default case for classes inherited from RenderbufferInterface is not to michael@0: // need to do anything upon the reference count to the parent Renderbuffer incrementing michael@0: // or decrementing. michael@0: void RenderbufferInterface::addProxyRef(const Renderbuffer *proxy) michael@0: { michael@0: } michael@0: michael@0: void RenderbufferInterface::releaseProxy(const Renderbuffer *proxy) michael@0: { michael@0: } michael@0: michael@0: GLuint RenderbufferInterface::getRedSize() const michael@0: { michael@0: return gl::GetRedSize(getActualFormat()); michael@0: } michael@0: michael@0: GLuint RenderbufferInterface::getGreenSize() const michael@0: { michael@0: return gl::GetGreenSize(getActualFormat()); michael@0: } michael@0: michael@0: GLuint RenderbufferInterface::getBlueSize() const michael@0: { michael@0: return gl::GetBlueSize(getActualFormat()); michael@0: } michael@0: michael@0: GLuint RenderbufferInterface::getAlphaSize() const michael@0: { michael@0: return gl::GetAlphaSize(getActualFormat()); michael@0: } michael@0: michael@0: GLuint RenderbufferInterface::getDepthSize() const michael@0: { michael@0: return gl::GetDepthSize(getActualFormat()); michael@0: } michael@0: michael@0: GLuint RenderbufferInterface::getStencilSize() const michael@0: { michael@0: return gl::GetStencilSize(getActualFormat()); michael@0: } michael@0: michael@0: ///// RenderbufferTexture2D Implementation //////// michael@0: michael@0: RenderbufferTexture2D::RenderbufferTexture2D(Texture2D *texture, GLenum target) : mTarget(target) michael@0: { michael@0: mTexture2D.set(texture); michael@0: } michael@0: michael@0: RenderbufferTexture2D::~RenderbufferTexture2D() michael@0: { michael@0: mTexture2D.set(NULL); michael@0: } michael@0: michael@0: // Textures need to maintain their own reference count for references via michael@0: // Renderbuffers acting as proxies. Here, we notify the texture of a reference. michael@0: void RenderbufferTexture2D::addProxyRef(const Renderbuffer *proxy) michael@0: { michael@0: mTexture2D->addProxyRef(proxy); michael@0: } michael@0: michael@0: void RenderbufferTexture2D::releaseProxy(const Renderbuffer *proxy) michael@0: { michael@0: mTexture2D->releaseProxy(proxy); michael@0: } michael@0: michael@0: rx::RenderTarget *RenderbufferTexture2D::getRenderTarget() michael@0: { michael@0: return mTexture2D->getRenderTarget(mTarget); michael@0: } michael@0: michael@0: rx::RenderTarget *RenderbufferTexture2D::getDepthStencil() michael@0: { michael@0: return mTexture2D->getDepthStencil(mTarget); michael@0: } michael@0: michael@0: GLsizei RenderbufferTexture2D::getWidth() const michael@0: { michael@0: return mTexture2D->getWidth(0); michael@0: } michael@0: michael@0: GLsizei RenderbufferTexture2D::getHeight() const michael@0: { michael@0: return mTexture2D->getHeight(0); michael@0: } michael@0: michael@0: GLenum RenderbufferTexture2D::getInternalFormat() const michael@0: { michael@0: return mTexture2D->getInternalFormat(0); michael@0: } michael@0: michael@0: GLenum RenderbufferTexture2D::getActualFormat() const michael@0: { michael@0: return mTexture2D->getActualFormat(0); michael@0: } michael@0: michael@0: GLsizei RenderbufferTexture2D::getSamples() const michael@0: { michael@0: return 0; michael@0: } michael@0: michael@0: unsigned int RenderbufferTexture2D::getSerial() const michael@0: { michael@0: return mTexture2D->getRenderTargetSerial(mTarget); michael@0: } michael@0: michael@0: ///// RenderbufferTextureCubeMap Implementation //////// michael@0: michael@0: RenderbufferTextureCubeMap::RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target) : mTarget(target) michael@0: { michael@0: mTextureCubeMap.set(texture); michael@0: } michael@0: michael@0: RenderbufferTextureCubeMap::~RenderbufferTextureCubeMap() michael@0: { michael@0: mTextureCubeMap.set(NULL); michael@0: } michael@0: michael@0: // Textures need to maintain their own reference count for references via michael@0: // Renderbuffers acting as proxies. Here, we notify the texture of a reference. michael@0: void RenderbufferTextureCubeMap::addProxyRef(const Renderbuffer *proxy) michael@0: { michael@0: mTextureCubeMap->addProxyRef(proxy); michael@0: } michael@0: michael@0: void RenderbufferTextureCubeMap::releaseProxy(const Renderbuffer *proxy) michael@0: { michael@0: mTextureCubeMap->releaseProxy(proxy); michael@0: } michael@0: michael@0: rx::RenderTarget *RenderbufferTextureCubeMap::getRenderTarget() michael@0: { michael@0: return mTextureCubeMap->getRenderTarget(mTarget); michael@0: } michael@0: michael@0: rx::RenderTarget *RenderbufferTextureCubeMap::getDepthStencil() michael@0: { michael@0: return NULL; michael@0: } michael@0: michael@0: GLsizei RenderbufferTextureCubeMap::getWidth() const michael@0: { michael@0: return mTextureCubeMap->getWidth(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0); michael@0: } michael@0: michael@0: GLsizei RenderbufferTextureCubeMap::getHeight() const michael@0: { michael@0: return mTextureCubeMap->getHeight(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0); michael@0: } michael@0: michael@0: GLenum RenderbufferTextureCubeMap::getInternalFormat() const michael@0: { michael@0: return mTextureCubeMap->getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0); michael@0: } michael@0: michael@0: GLenum RenderbufferTextureCubeMap::getActualFormat() const michael@0: { michael@0: return mTextureCubeMap->getActualFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0); michael@0: } michael@0: michael@0: GLsizei RenderbufferTextureCubeMap::getSamples() const michael@0: { michael@0: return 0; michael@0: } michael@0: michael@0: unsigned int RenderbufferTextureCubeMap::getSerial() const michael@0: { michael@0: return mTextureCubeMap->getRenderTargetSerial(mTarget); michael@0: } michael@0: michael@0: ////// Renderbuffer Implementation ////// michael@0: michael@0: Renderbuffer::Renderbuffer(rx::Renderer *renderer, GLuint id, RenderbufferInterface *instance) : RefCountObject(id) michael@0: { michael@0: ASSERT(instance != NULL); michael@0: mInstance = instance; michael@0: } michael@0: michael@0: Renderbuffer::~Renderbuffer() michael@0: { michael@0: delete mInstance; michael@0: } michael@0: michael@0: // The RenderbufferInterface contained in this Renderbuffer may need to maintain michael@0: // its own reference count, so we pass it on here. michael@0: void Renderbuffer::addRef() const michael@0: { michael@0: mInstance->addProxyRef(this); michael@0: michael@0: RefCountObject::addRef(); michael@0: } michael@0: michael@0: void Renderbuffer::release() const michael@0: { michael@0: mInstance->releaseProxy(this); michael@0: michael@0: RefCountObject::release(); michael@0: } michael@0: michael@0: rx::RenderTarget *Renderbuffer::getRenderTarget() michael@0: { michael@0: return mInstance->getRenderTarget(); michael@0: } michael@0: michael@0: rx::RenderTarget *Renderbuffer::getDepthStencil() michael@0: { michael@0: return mInstance->getDepthStencil(); michael@0: } michael@0: michael@0: GLsizei Renderbuffer::getWidth() const michael@0: { michael@0: return mInstance->getWidth(); michael@0: } michael@0: michael@0: GLsizei Renderbuffer::getHeight() const michael@0: { michael@0: return mInstance->getHeight(); michael@0: } michael@0: michael@0: GLenum Renderbuffer::getInternalFormat() const michael@0: { michael@0: return mInstance->getInternalFormat(); michael@0: } michael@0: michael@0: GLenum Renderbuffer::getActualFormat() const michael@0: { michael@0: return mInstance->getActualFormat(); michael@0: } michael@0: michael@0: GLuint Renderbuffer::getRedSize() const michael@0: { michael@0: return mInstance->getRedSize(); michael@0: } michael@0: michael@0: GLuint Renderbuffer::getGreenSize() const michael@0: { michael@0: return mInstance->getGreenSize(); michael@0: } michael@0: michael@0: GLuint Renderbuffer::getBlueSize() const michael@0: { michael@0: return mInstance->getBlueSize(); michael@0: } michael@0: michael@0: GLuint Renderbuffer::getAlphaSize() const michael@0: { michael@0: return mInstance->getAlphaSize(); michael@0: } michael@0: michael@0: GLuint Renderbuffer::getDepthSize() const michael@0: { michael@0: return mInstance->getDepthSize(); michael@0: } michael@0: michael@0: GLuint Renderbuffer::getStencilSize() const michael@0: { michael@0: return mInstance->getStencilSize(); michael@0: } michael@0: michael@0: GLsizei Renderbuffer::getSamples() const michael@0: { michael@0: return mInstance->getSamples(); michael@0: } michael@0: michael@0: unsigned int Renderbuffer::getSerial() const michael@0: { michael@0: return mInstance->getSerial(); michael@0: } michael@0: michael@0: void Renderbuffer::setStorage(RenderbufferStorage *newStorage) michael@0: { michael@0: ASSERT(newStorage != NULL); michael@0: michael@0: delete mInstance; michael@0: mInstance = newStorage; michael@0: } michael@0: michael@0: RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerial()) michael@0: { michael@0: mWidth = 0; michael@0: mHeight = 0; michael@0: mInternalFormat = GL_RGBA4; michael@0: mActualFormat = GL_RGBA8_OES; michael@0: mSamples = 0; michael@0: } michael@0: michael@0: RenderbufferStorage::~RenderbufferStorage() michael@0: { michael@0: } michael@0: michael@0: rx::RenderTarget *RenderbufferStorage::getRenderTarget() michael@0: { michael@0: return NULL; michael@0: } michael@0: michael@0: rx::RenderTarget *RenderbufferStorage::getDepthStencil() michael@0: { michael@0: return NULL; michael@0: } michael@0: michael@0: GLsizei RenderbufferStorage::getWidth() const michael@0: { michael@0: return mWidth; michael@0: } michael@0: michael@0: GLsizei RenderbufferStorage::getHeight() const michael@0: { michael@0: return mHeight; michael@0: } michael@0: michael@0: GLenum RenderbufferStorage::getInternalFormat() const michael@0: { michael@0: return mInternalFormat; michael@0: } michael@0: michael@0: GLenum RenderbufferStorage::getActualFormat() const michael@0: { michael@0: return mActualFormat; michael@0: } michael@0: michael@0: GLsizei RenderbufferStorage::getSamples() const michael@0: { michael@0: return mSamples; michael@0: } michael@0: michael@0: unsigned int RenderbufferStorage::getSerial() const michael@0: { michael@0: return mSerial; michael@0: } michael@0: michael@0: unsigned int RenderbufferStorage::issueSerial() michael@0: { michael@0: return mCurrentSerial++; michael@0: } michael@0: michael@0: unsigned int RenderbufferStorage::issueCubeSerials() michael@0: { michael@0: unsigned int firstSerial = mCurrentSerial; michael@0: mCurrentSerial += 6; michael@0: return firstSerial; michael@0: } michael@0: michael@0: Colorbuffer::Colorbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain) michael@0: { michael@0: mRenderTarget = renderer->createRenderTarget(swapChain, false); michael@0: michael@0: if (mRenderTarget) michael@0: { michael@0: mWidth = mRenderTarget->getWidth(); michael@0: mHeight = mRenderTarget->getHeight(); michael@0: mInternalFormat = mRenderTarget->getInternalFormat(); michael@0: mActualFormat = mRenderTarget->getActualFormat(); michael@0: mSamples = mRenderTarget->getSamples(); michael@0: } michael@0: } michael@0: michael@0: Colorbuffer::Colorbuffer(rx::Renderer *renderer, int width, int height, GLenum format, GLsizei samples) : mRenderTarget(NULL) michael@0: { michael@0: mRenderTarget = renderer->createRenderTarget(width, height, format, samples, false); michael@0: michael@0: if (mRenderTarget) michael@0: { michael@0: mWidth = width; michael@0: mHeight = height; michael@0: mInternalFormat = format; michael@0: mActualFormat = mRenderTarget->getActualFormat(); michael@0: mSamples = mRenderTarget->getSamples(); michael@0: } michael@0: } michael@0: michael@0: Colorbuffer::~Colorbuffer() michael@0: { michael@0: if (mRenderTarget) michael@0: { michael@0: delete mRenderTarget; michael@0: } michael@0: } michael@0: michael@0: rx::RenderTarget *Colorbuffer::getRenderTarget() michael@0: { michael@0: if (mRenderTarget) michael@0: { michael@0: return mRenderTarget; michael@0: } michael@0: michael@0: return NULL; michael@0: } michael@0: michael@0: DepthStencilbuffer::DepthStencilbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain) michael@0: { michael@0: mDepthStencil = renderer->createRenderTarget(swapChain, true); michael@0: if (mDepthStencil) michael@0: { michael@0: mWidth = mDepthStencil->getWidth(); michael@0: mHeight = mDepthStencil->getHeight(); michael@0: mInternalFormat = mDepthStencil->getInternalFormat(); michael@0: mSamples = mDepthStencil->getSamples(); michael@0: mActualFormat = mDepthStencil->getActualFormat(); michael@0: } michael@0: } michael@0: michael@0: DepthStencilbuffer::DepthStencilbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples) michael@0: { michael@0: michael@0: mDepthStencil = renderer->createRenderTarget(width, height, GL_DEPTH24_STENCIL8_OES, samples, true); michael@0: michael@0: mWidth = mDepthStencil->getWidth(); michael@0: mHeight = mDepthStencil->getHeight(); michael@0: mInternalFormat = GL_DEPTH24_STENCIL8_OES; michael@0: mActualFormat = mDepthStencil->getActualFormat(); michael@0: mSamples = mDepthStencil->getSamples(); michael@0: } michael@0: michael@0: DepthStencilbuffer::~DepthStencilbuffer() michael@0: { michael@0: if (mDepthStencil) michael@0: { michael@0: delete mDepthStencil; michael@0: } michael@0: } michael@0: michael@0: rx::RenderTarget *DepthStencilbuffer::getDepthStencil() michael@0: { michael@0: if (mDepthStencil) michael@0: { michael@0: return mDepthStencil; michael@0: } michael@0: michael@0: return NULL; michael@0: } michael@0: michael@0: Depthbuffer::Depthbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples) : DepthStencilbuffer(renderer, width, height, samples) michael@0: { michael@0: if (mDepthStencil) michael@0: { michael@0: mInternalFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function michael@0: // will expect one of the valid renderbuffer formats for use in michael@0: // glRenderbufferStorage michael@0: } michael@0: } michael@0: michael@0: Depthbuffer::~Depthbuffer() michael@0: { michael@0: } michael@0: michael@0: Stencilbuffer::Stencilbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples) : DepthStencilbuffer(renderer, width, height, samples) michael@0: { michael@0: if (mDepthStencil) michael@0: { michael@0: mInternalFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function michael@0: // will expect one of the valid renderbuffer formats for use in michael@0: // glRenderbufferStorage michael@0: } michael@0: } michael@0: michael@0: Stencilbuffer::~Stencilbuffer() michael@0: { michael@0: } michael@0: michael@0: }