| // |
| // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| |
| // Renderbuffer.cpp: the gl::Renderbuffer class and its derived classes |
| // Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer |
| // objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108. |
| |
| #include "libGLESv2/Renderbuffer.h" |
| |
| #include "libGLESv2/main.h" |
| #include "libGLESv2/Texture.h" |
| #include "libGLESv2/utilities.h" |
| |
| namespace gl |
| { |
| unsigned int RenderbufferStorage::mCurrentSerial = 1; |
| |
| Renderbuffer::Renderbuffer(GLuint id, RenderbufferStorage *storage) : RefCountObject(id) |
| { |
| ASSERT(storage != NULL); |
| mStorage = storage; |
| } |
| |
| Renderbuffer::~Renderbuffer() |
| { |
| delete mStorage; |
| } |
| |
| bool Renderbuffer::isColorbuffer() const |
| { |
| return mStorage->isColorbuffer(); |
| } |
| |
| bool Renderbuffer::isDepthbuffer() const |
| { |
| return mStorage->isDepthbuffer(); |
| } |
| |
| bool Renderbuffer::isStencilbuffer() const |
| { |
| return mStorage->isStencilbuffer(); |
| } |
| |
| IDirect3DSurface9 *Renderbuffer::getRenderTarget() |
| { |
| return mStorage->getRenderTarget(); |
| } |
| |
| IDirect3DSurface9 *Renderbuffer::getDepthStencil() |
| { |
| return mStorage->getDepthStencil(); |
| } |
| |
| int Renderbuffer::getWidth() const |
| { |
| return mStorage->getWidth(); |
| } |
| |
| int Renderbuffer::getHeight() const |
| { |
| return mStorage->getHeight(); |
| } |
| |
| GLenum Renderbuffer::getFormat() const |
| { |
| return mStorage->getFormat(); |
| } |
| |
| D3DFORMAT Renderbuffer::getD3DFormat() const |
| { |
| return mStorage->getD3DFormat(); |
| } |
| |
| unsigned int Renderbuffer::getSerial() const |
| { |
| return mStorage->getSerial(); |
| } |
| |
| void Renderbuffer::setStorage(RenderbufferStorage *newStorage) |
| { |
| ASSERT(newStorage != NULL); |
| |
| delete mStorage; |
| mStorage = newStorage; |
| } |
| |
| RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerial()) |
| { |
| mWidth = 0; |
| mHeight = 0; |
| mFormat = GL_RGBA4; |
| mD3DFormat = D3DFMT_A8R8G8B8; |
| mSamples = 0; |
| } |
| |
| RenderbufferStorage::~RenderbufferStorage() |
| { |
| } |
| |
| bool RenderbufferStorage::isColorbuffer() const |
| { |
| return false; |
| } |
| |
| bool RenderbufferStorage::isDepthbuffer() const |
| { |
| return false; |
| } |
| |
| bool RenderbufferStorage::isStencilbuffer() const |
| { |
| return false; |
| } |
| |
| IDirect3DSurface9 *RenderbufferStorage::getRenderTarget() |
| { |
| return NULL; |
| } |
| |
| IDirect3DSurface9 *RenderbufferStorage::getDepthStencil() |
| { |
| return NULL; |
| } |
| |
| int RenderbufferStorage::getWidth() const |
| { |
| return mWidth; |
| } |
| |
| int RenderbufferStorage::getHeight() const |
| { |
| return mHeight; |
| } |
| |
| void RenderbufferStorage::setSize(int width, int height) |
| { |
| mWidth = width; |
| mHeight = height; |
| } |
| |
| GLenum RenderbufferStorage::getFormat() const |
| { |
| return mFormat; |
| } |
| |
| bool RenderbufferStorage::isFloatingPoint() const |
| { |
| return false; // no floating point renderbuffers |
| } |
| |
| D3DFORMAT RenderbufferStorage::getD3DFormat() const |
| { |
| return mD3DFormat; |
| } |
| |
| GLsizei RenderbufferStorage::getSamples() const |
| { |
| return mSamples; |
| } |
| |
| unsigned int RenderbufferStorage::getSerial() const |
| { |
| return mSerial; |
| } |
| |
| unsigned int RenderbufferStorage::issueSerial() |
| { |
| return mCurrentSerial++; |
| } |
| |
| Colorbuffer::Colorbuffer(IDirect3DSurface9 *renderTarget) : mRenderTarget(renderTarget) |
| { |
| if (renderTarget) |
| { |
| renderTarget->AddRef(); |
| |
| D3DSURFACE_DESC description; |
| renderTarget->GetDesc(&description); |
| |
| setSize(description.Width, description.Height); |
| mFormat = dx2es::ConvertBackBufferFormat(description.Format); |
| mD3DFormat = description.Format; |
| mSamples = es2dx::GetSamplesFromMultisampleType(description.MultiSampleType); |
| } |
| } |
| |
| Colorbuffer::Colorbuffer(const Texture* texture) : mRenderTarget(NULL) |
| { |
| setSize(texture->getWidth(), texture->getHeight()); |
| mD3DFormat = texture->getD3DFormat(); |
| mSamples = 0; |
| } |
| |
| Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) |
| { |
| IDirect3DDevice9 *device = getDevice(); |
| |
| mRenderTarget = NULL; |
| D3DFORMAT requestedFormat = es2dx::ConvertRenderbufferFormat(format); |
| int supportedSamples = getContext()->getNearestSupportedSamples(requestedFormat, samples); |
| |
| if (supportedSamples == -1) |
| { |
| error(GL_OUT_OF_MEMORY); |
| |
| return; |
| } |
| |
| if (width > 0 && height > 0) |
| { |
| HRESULT result = device->CreateRenderTarget(width, height, requestedFormat, |
| es2dx::GetMultisampleTypeFromSamples(supportedSamples), 0, FALSE, &mRenderTarget, NULL); |
| |
| if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) |
| { |
| error(GL_OUT_OF_MEMORY); |
| |
| return; |
| } |
| |
| ASSERT(SUCCEEDED(result)); |
| } |
| |
| if (mRenderTarget) |
| { |
| setSize(width, height); |
| mFormat = format; |
| mD3DFormat = requestedFormat; |
| mSamples = supportedSamples; |
| } |
| } |
| |
| Colorbuffer::~Colorbuffer() |
| { |
| if (mRenderTarget) |
| { |
| mRenderTarget->Release(); |
| } |
| } |
| |
| bool Colorbuffer::isColorbuffer() const |
| { |
| return true; |
| } |
| |
| GLuint Colorbuffer::getRedSize() const |
| { |
| if (mRenderTarget) |
| { |
| D3DSURFACE_DESC description; |
| mRenderTarget->GetDesc(&description); |
| |
| return es2dx::GetRedSize(description.Format); |
| } |
| |
| return 0; |
| } |
| |
| GLuint Colorbuffer::getGreenSize() const |
| { |
| if (mRenderTarget) |
| { |
| D3DSURFACE_DESC description; |
| mRenderTarget->GetDesc(&description); |
| |
| return es2dx::GetGreenSize(description.Format); |
| } |
| |
| return 0; |
| } |
| |
| GLuint Colorbuffer::getBlueSize() const |
| { |
| if (mRenderTarget) |
| { |
| D3DSURFACE_DESC description; |
| mRenderTarget->GetDesc(&description); |
| |
| return es2dx::GetBlueSize(description.Format); |
| } |
| |
| return 0; |
| } |
| |
| GLuint Colorbuffer::getAlphaSize() const |
| { |
| if (mRenderTarget) |
| { |
| D3DSURFACE_DESC description; |
| mRenderTarget->GetDesc(&description); |
| |
| return es2dx::GetAlphaSize(description.Format); |
| } |
| |
| return 0; |
| } |
| |
| IDirect3DSurface9 *Colorbuffer::getRenderTarget() |
| { |
| return mRenderTarget; |
| } |
| |
| DepthStencilbuffer::DepthStencilbuffer(IDirect3DSurface9 *depthStencil) : mDepthStencil(depthStencil) |
| { |
| if (depthStencil) |
| { |
| depthStencil->AddRef(); |
| |
| D3DSURFACE_DESC description; |
| depthStencil->GetDesc(&description); |
| |
| setSize(description.Width, description.Height); |
| mFormat = dx2es::ConvertDepthStencilFormat(description.Format); |
| mSamples = es2dx::GetSamplesFromMultisampleType(description.MultiSampleType); |
| mD3DFormat = description.Format; |
| } |
| } |
| |
| DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples) |
| { |
| IDirect3DDevice9 *device = getDevice(); |
| |
| mDepthStencil = NULL; |
| |
| int supportedSamples = getContext()->getNearestSupportedSamples(D3DFMT_D24S8, samples); |
| |
| if (supportedSamples == -1) |
| { |
| error(GL_OUT_OF_MEMORY); |
| |
| return; |
| } |
| |
| HRESULT result = device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, es2dx::GetMultisampleTypeFromSamples(supportedSamples), |
| 0, FALSE, &mDepthStencil, 0); |
| |
| if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) |
| { |
| error(GL_OUT_OF_MEMORY); |
| |
| return; |
| } |
| |
| ASSERT(SUCCEEDED(result)); |
| |
| if (mDepthStencil) |
| { |
| setSize(width, height); |
| mFormat = GL_DEPTH24_STENCIL8_OES; |
| mD3DFormat = D3DFMT_D24S8; |
| mSamples = supportedSamples; |
| } |
| } |
| |
| DepthStencilbuffer::~DepthStencilbuffer() |
| { |
| if (mDepthStencil) |
| { |
| mDepthStencil->Release(); |
| } |
| } |
| |
| bool DepthStencilbuffer::isDepthbuffer() const |
| { |
| return true; |
| } |
| |
| bool DepthStencilbuffer::isStencilbuffer() const |
| { |
| return true; |
| } |
| |
| GLuint DepthStencilbuffer::getDepthSize() const |
| { |
| if (mDepthStencil) |
| { |
| D3DSURFACE_DESC description; |
| mDepthStencil->GetDesc(&description); |
| |
| return es2dx::GetDepthSize(description.Format); |
| } |
| |
| return 0; |
| } |
| |
| GLuint DepthStencilbuffer::getStencilSize() const |
| { |
| if (mDepthStencil) |
| { |
| D3DSURFACE_DESC description; |
| mDepthStencil->GetDesc(&description); |
| |
| return es2dx::GetStencilSize(description.Format); |
| } |
| |
| return 0; |
| } |
| |
| IDirect3DSurface9 *DepthStencilbuffer::getDepthStencil() |
| { |
| return mDepthStencil; |
| } |
| |
| Depthbuffer::Depthbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil) |
| { |
| if (depthStencil) |
| { |
| mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function |
| // will expect one of the valid renderbuffer formats for use in |
| // glRenderbufferStorage |
| } |
| } |
| |
| Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples) |
| { |
| if (getDepthStencil()) |
| { |
| mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function |
| // will expect one of the valid renderbuffer formats for use in |
| // glRenderbufferStorage |
| } |
| } |
| |
| Depthbuffer::~Depthbuffer() |
| { |
| } |
| |
| bool Depthbuffer::isDepthbuffer() const |
| { |
| return true; |
| } |
| |
| bool Depthbuffer::isStencilbuffer() const |
| { |
| return false; |
| } |
| |
| Stencilbuffer::Stencilbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil) |
| { |
| if (depthStencil) |
| { |
| mFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function |
| // will expect one of the valid renderbuffer formats for use in |
| // glRenderbufferStorage |
| } |
| else |
| { |
| mFormat = GL_RGBA4; //default format |
| } |
| } |
| |
| Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples) |
| { |
| if (getDepthStencil()) |
| { |
| mFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function |
| // will expect one of the valid renderbuffer formats for use in |
| // glRenderbufferStorage |
| } |
| } |
| |
| Stencilbuffer::~Stencilbuffer() |
| { |
| } |
| |
| bool Stencilbuffer::isDepthbuffer() const |
| { |
| return false; |
| } |
| |
| bool Stencilbuffer::isStencilbuffer() const |
| { |
| return true; |
| } |
| } |