1 // SwiftShader Software Renderer
3 // Copyright(c) 2005-2013 TransGaming Inc.
5 // All rights reserved. No part of this software may be copied, distributed, transmitted,
6 // transcribed, stored in a retrieval system, translated into any human or computer
7 // language by any means, or disclosed to third parties without the explicit written
8 // agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
9 // or implied, including but not limited to any patent rights, are granted to you.
12 // Renderbuffer.cpp: the Renderbuffer class and its derived classes
13 // Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
14 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
16 #include "Renderbuffer.h"
20 #include "utilities.h"
24 RenderbufferInterface::RenderbufferInterface()
28 // The default case for classes inherited from RenderbufferInterface is not to
29 // need to do anything upon the reference count to the parent Renderbuffer incrementing
31 void RenderbufferInterface::addProxyRef(const Renderbuffer *proxy)
35 void RenderbufferInterface::releaseProxy(const Renderbuffer *proxy)
39 GLuint RenderbufferInterface::getRedSize() const
41 return sw2es::GetRedSize(getInternalFormat());
44 GLuint RenderbufferInterface::getGreenSize() const
46 return sw2es::GetGreenSize(getInternalFormat());
49 GLuint RenderbufferInterface::getBlueSize() const
51 return sw2es::GetBlueSize(getInternalFormat());
54 GLuint RenderbufferInterface::getAlphaSize() const
56 return sw2es::GetAlphaSize(getInternalFormat());
59 GLuint RenderbufferInterface::getDepthSize() const
61 return sw2es::GetDepthSize(getInternalFormat());
64 GLuint RenderbufferInterface::getStencilSize() const
66 return sw2es::GetStencilSize(getInternalFormat());
69 ///// RenderbufferTexture2D Implementation ////////
71 RenderbufferTexture2D::RenderbufferTexture2D(Texture2D *texture)
73 mTexture2D.set(texture);
76 RenderbufferTexture2D::~RenderbufferTexture2D()
81 // Textures need to maintain their own reference count for references via
82 // Renderbuffers acting as proxies. Here, we notify the texture of a reference.
83 void RenderbufferTexture2D::addProxyRef(const Renderbuffer *proxy)
85 mTexture2D->addProxyRef(proxy);
88 void RenderbufferTexture2D::releaseProxy(const Renderbuffer *proxy)
90 mTexture2D->releaseProxy(proxy);
93 // Increments refcount on image.
94 // caller must release() the returned image
95 egl::Image *RenderbufferTexture2D::getRenderTarget()
97 return mTexture2D->getRenderTarget(GL_TEXTURE_2D, 0);
100 // Increments refcount on image.
101 // caller must release() the returned image
102 egl::Image *RenderbufferTexture2D::createSharedImage()
104 return mTexture2D->createSharedImage(GL_TEXTURE_2D, 0);
107 bool RenderbufferTexture2D::isShared() const
109 return mTexture2D->isShared(GL_TEXTURE_2D, 0);
112 GLsizei RenderbufferTexture2D::getWidth() const
114 return mTexture2D->getWidth(GL_TEXTURE_2D, 0);
117 GLsizei RenderbufferTexture2D::getHeight() const
119 return mTexture2D->getHeight(GL_TEXTURE_2D, 0);
122 GLenum RenderbufferTexture2D::getFormat() const
124 return mTexture2D->getFormat(GL_TEXTURE_2D, 0);
127 sw::Format RenderbufferTexture2D::getInternalFormat() const
129 return mTexture2D->getInternalFormat(GL_TEXTURE_2D, 0);
132 GLsizei RenderbufferTexture2D::getSamples() const
137 ////// Renderbuffer Implementation //////
139 Renderbuffer::Renderbuffer(GLuint id, RenderbufferInterface *instance) : RefCountObject(id)
141 ASSERT(instance != NULL);
142 mInstance = instance;
145 Renderbuffer::~Renderbuffer()
150 // The RenderbufferInterface contained in this Renderbuffer may need to maintain
151 // its own reference count, so we pass it on here.
152 void Renderbuffer::addRef()
154 mInstance->addProxyRef(this);
156 RefCountObject::addRef();
159 void Renderbuffer::release()
161 mInstance->releaseProxy(this);
163 RefCountObject::release();
166 // Increments refcount on image.
167 // caller must Release() the returned image
168 egl::Image *Renderbuffer::getRenderTarget()
170 return mInstance->getRenderTarget();
173 // Increments refcount on image.
174 // caller must Release() the returned image
175 egl::Image *Renderbuffer::createSharedImage()
177 return mInstance->createSharedImage();
180 bool Renderbuffer::isShared() const
182 return mInstance->isShared();
185 GLsizei Renderbuffer::getWidth() const
187 return mInstance->getWidth();
190 GLsizei Renderbuffer::getHeight() const
192 return mInstance->getHeight();
195 GLenum Renderbuffer::getFormat() const
197 return mInstance->getFormat();
200 sw::Format Renderbuffer::getInternalFormat() const
202 return mInstance->getInternalFormat();
205 GLuint Renderbuffer::getRedSize() const
207 return mInstance->getRedSize();
210 GLuint Renderbuffer::getGreenSize() const
212 return mInstance->getGreenSize();
215 GLuint Renderbuffer::getBlueSize() const
217 return mInstance->getBlueSize();
220 GLuint Renderbuffer::getAlphaSize() const
222 return mInstance->getAlphaSize();
225 GLuint Renderbuffer::getDepthSize() const
227 return mInstance->getDepthSize();
230 GLuint Renderbuffer::getStencilSize() const
232 return mInstance->getStencilSize();
235 GLsizei Renderbuffer::getSamples() const
237 return mInstance->getSamples();
240 void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
242 ASSERT(newStorage != NULL);
245 mInstance = newStorage;
248 RenderbufferStorage::RenderbufferStorage()
252 format = GL_RGBA4_OES;
253 internalFormat = sw::FORMAT_A8R8G8B8;
257 RenderbufferStorage::~RenderbufferStorage()
261 GLsizei RenderbufferStorage::getWidth() const
266 GLsizei RenderbufferStorage::getHeight() const
271 GLenum RenderbufferStorage::getFormat() const
276 sw::Format RenderbufferStorage::getInternalFormat() const
278 return internalFormat;
281 GLsizei RenderbufferStorage::getSamples() const
286 Colorbuffer::Colorbuffer(egl::Image *renderTarget) : mRenderTarget(renderTarget)
290 renderTarget->addRef();
292 mWidth = renderTarget->getWidth();
293 mHeight = renderTarget->getHeight();
294 internalFormat = renderTarget->getInternalFormat();
295 format = sw2es::ConvertBackBufferFormat(internalFormat);
296 mSamples = renderTarget->getDepth() & ~1;
300 Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) : mRenderTarget(NULL)
302 Device *device = getDevice();
304 sw::Format requestedFormat = es2sw::ConvertRenderbufferFormat(format);
305 int supportedSamples = Context::getSupportedMultiSampleDepth(requestedFormat, samples);
307 if(width > 0 && height > 0)
309 mRenderTarget = device->createRenderTarget(width, height, requestedFormat, supportedSamples, false);
313 error(GL_OUT_OF_MEMORY);
320 this->format = format;
321 internalFormat = requestedFormat;
322 mSamples = supportedSamples & ~1;
325 Colorbuffer::~Colorbuffer()
329 mRenderTarget->release();
333 // Increments refcount on image.
334 // caller must release() the returned image
335 egl::Image *Colorbuffer::getRenderTarget()
339 mRenderTarget->addRef();
342 return mRenderTarget;
345 // Increments refcount on image.
346 // caller must release() the returned image
347 egl::Image *Colorbuffer::createSharedImage()
351 mRenderTarget->addRef();
352 mRenderTarget->markShared();
355 return mRenderTarget;
358 bool Colorbuffer::isShared() const
360 return mRenderTarget->isShared();
363 DepthStencilbuffer::DepthStencilbuffer(egl::Image *depthStencil) : mDepthStencil(depthStencil)
367 depthStencil->addRef();
369 mWidth = depthStencil->getWidth();
370 mHeight = depthStencil->getHeight();
371 internalFormat = depthStencil->getInternalFormat();
372 format = sw2es::ConvertDepthStencilFormat(internalFormat);
373 mSamples = depthStencil->getDepth() & ~1;
377 DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples)
379 Device *device = getDevice();
381 mDepthStencil = NULL;
383 int supportedSamples = Context::getSupportedMultiSampleDepth(sw::FORMAT_D24S8, samples);
385 if(width > 0 && height > 0)
387 mDepthStencil = device->createDepthStencilSurface(width, height, sw::FORMAT_D24S8, supportedSamples, false);
391 error(GL_OUT_OF_MEMORY);
398 format = GL_DEPTH24_STENCIL8_OES;
399 internalFormat = sw::FORMAT_D24S8;
400 mSamples = supportedSamples & ~1;
403 DepthStencilbuffer::~DepthStencilbuffer()
407 mDepthStencil->release();
411 // Increments refcount on image.
412 // caller must release() the returned image
413 egl::Image *DepthStencilbuffer::getRenderTarget()
417 mDepthStencil->addRef();
420 return mDepthStencil;
423 // Increments refcount on image.
424 // caller must release() the returned image
425 egl::Image *DepthStencilbuffer::createSharedImage()
429 mDepthStencil->addRef();
430 mDepthStencil->markShared();
433 return mDepthStencil;
436 bool DepthStencilbuffer::isShared() const
438 return mDepthStencil->isShared();
441 Depthbuffer::Depthbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
445 format = GL_DEPTH_COMPONENT16_OES; // If the renderbuffer parameters are queried, the calling function
446 // will expect one of the valid renderbuffer formats for use in
447 // glRenderbufferStorage
451 Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
455 format = GL_DEPTH_COMPONENT16_OES; // If the renderbuffer parameters are queried, the calling function
456 // will expect one of the valid renderbuffer formats for use in
457 // glRenderbufferStorage
461 Depthbuffer::~Depthbuffer()
465 Stencilbuffer::Stencilbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
469 format = GL_STENCIL_INDEX8_OES; // If the renderbuffer parameters are queried, the calling function
470 // will expect one of the valid renderbuffer formats for use in
471 // glRenderbufferStorage
475 Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
479 format = GL_STENCIL_INDEX8_OES; // If the renderbuffer parameters are queried, the calling function
480 // will expect one of the valid renderbuffer formats for use in
481 // glRenderbufferStorage
485 Stencilbuffer::~Stencilbuffer()