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 sw2rad::GetRedSize(getInternalFormat());
44 GLuint RenderbufferInterface::getGreenSize() const
46 return sw2rad::GetGreenSize(getInternalFormat());
49 GLuint RenderbufferInterface::getBlueSize() const
51 return sw2rad::GetBlueSize(getInternalFormat());
54 GLuint RenderbufferInterface::getAlphaSize() const
56 return sw2rad::GetAlphaSize(getInternalFormat());
59 GLuint RenderbufferInterface::getDepthSize() const
61 return sw2rad::GetDepthSize(getInternalFormat());
64 GLuint RenderbufferInterface::getStencilSize() const
66 return sw2rad::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 ///// RenderbufferTextureCubeMap Implementation ////////
139 RenderbufferTextureCubeMap::RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target) : mTarget(target)
141 mTextureCubeMap.set(texture);
144 RenderbufferTextureCubeMap::~RenderbufferTextureCubeMap()
146 mTextureCubeMap.set(NULL);
149 // Textures need to maintain their own reference count for references via
150 // Renderbuffers acting as proxies. Here, we notify the texture of a reference.
151 void RenderbufferTextureCubeMap::addProxyRef(const Renderbuffer *proxy)
153 mTextureCubeMap->addProxyRef(proxy);
156 void RenderbufferTextureCubeMap::releaseProxy(const Renderbuffer *proxy)
158 mTextureCubeMap->releaseProxy(proxy);
161 // Increments refcount on image.
162 // caller must release() the returned image
163 Image *RenderbufferTextureCubeMap::getRenderTarget()
165 return mTextureCubeMap->getRenderTarget(mTarget, 0);
168 // Increments refcount on image.
169 // caller must release() the returned image
170 egl::Image *RenderbufferTextureCubeMap::createSharedImage()
172 return mTextureCubeMap->createSharedImage(mTarget, 0);
175 bool RenderbufferTextureCubeMap::isShared() const
177 return mTextureCubeMap->isShared(mTarget, 0);
180 GLsizei RenderbufferTextureCubeMap::getWidth() const
182 return mTextureCubeMap->getWidth(mTarget, 0);
185 GLsizei RenderbufferTextureCubeMap::getHeight() const
187 return mTextureCubeMap->getHeight(mTarget, 0);
190 GLenum RenderbufferTextureCubeMap::getFormat() const
192 return mTextureCubeMap->getFormat(mTarget, 0);
195 sw::Format RenderbufferTextureCubeMap::getInternalFormat() const
197 return mTextureCubeMap->getInternalFormat(mTarget, 0);
200 GLsizei RenderbufferTextureCubeMap::getSamples() const
205 ////// Renderbuffer Implementation //////
207 Renderbuffer::Renderbuffer(GLuint id, RenderbufferInterface *instance) : RefCountObject(id)
209 ASSERT(instance != NULL);
210 mInstance = instance;
213 Renderbuffer::~Renderbuffer()
218 // The RenderbufferInterface contained in this Renderbuffer may need to maintain
219 // its own reference count, so we pass it on here.
220 void Renderbuffer::addRef()
222 mInstance->addProxyRef(this);
224 RefCountObject::addRef();
227 void Renderbuffer::release()
229 mInstance->releaseProxy(this);
231 RefCountObject::release();
234 // Increments refcount on image.
235 // caller must Release() the returned image
236 egl::Image *Renderbuffer::getRenderTarget()
238 return mInstance->getRenderTarget();
241 // Increments refcount on image.
242 // caller must Release() the returned image
243 egl::Image *Renderbuffer::createSharedImage()
245 return mInstance->createSharedImage();
248 bool Renderbuffer::isShared() const
250 return mInstance->isShared();
253 GLsizei Renderbuffer::getWidth() const
255 return mInstance->getWidth();
258 GLsizei Renderbuffer::getHeight() const
260 return mInstance->getHeight();
263 GLenum Renderbuffer::getFormat() const
265 return mInstance->getFormat();
268 sw::Format Renderbuffer::getInternalFormat() const
270 return mInstance->getInternalFormat();
273 GLuint Renderbuffer::getRedSize() const
275 return mInstance->getRedSize();
278 GLuint Renderbuffer::getGreenSize() const
280 return mInstance->getGreenSize();
283 GLuint Renderbuffer::getBlueSize() const
285 return mInstance->getBlueSize();
288 GLuint Renderbuffer::getAlphaSize() const
290 return mInstance->getAlphaSize();
293 GLuint Renderbuffer::getDepthSize() const
295 return mInstance->getDepthSize();
298 GLuint Renderbuffer::getStencilSize() const
300 return mInstance->getStencilSize();
303 GLsizei Renderbuffer::getSamples() const
305 return mInstance->getSamples();
308 void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
310 ASSERT(newStorage != NULL);
313 mInstance = newStorage;
316 RenderbufferStorage::RenderbufferStorage()
321 internalFormat = sw::FORMAT_A8R8G8B8;
325 RenderbufferStorage::~RenderbufferStorage()
329 GLsizei RenderbufferStorage::getWidth() const
334 GLsizei RenderbufferStorage::getHeight() const
339 GLenum RenderbufferStorage::getFormat() const
344 sw::Format RenderbufferStorage::getInternalFormat() const
346 return internalFormat;
349 GLsizei RenderbufferStorage::getSamples() const
354 Colorbuffer::Colorbuffer(egl::Image *renderTarget) : mRenderTarget(renderTarget)
358 renderTarget->addRef();
360 mWidth = renderTarget->getWidth();
361 mHeight = renderTarget->getHeight();
362 internalFormat = renderTarget->getInternalFormat();
363 format = sw2rad::ConvertBackBufferFormat(internalFormat);
364 mSamples = renderTarget->getMultiSampleDepth() & ~1;
368 Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) : mRenderTarget(NULL)
370 Device *device = getDevice();
372 sw::Format requestedFormat = rad2sw::ConvertRenderbufferFormat(format);
373 int supportedSamples = Context::getSupportedMultiSampleDepth(requestedFormat, samples);
375 if(width > 0 && height > 0)
377 mRenderTarget = device->createRenderTarget(width, height, requestedFormat, supportedSamples, false);
381 error(GL_OUT_OF_MEMORY);
388 this->format = format;
389 internalFormat = requestedFormat;
390 mSamples = supportedSamples & ~1;
393 Colorbuffer::~Colorbuffer()
397 mRenderTarget->release();
401 // Increments refcount on image.
402 // caller must release() the returned image
403 egl::Image *Colorbuffer::getRenderTarget()
407 mRenderTarget->addRef();
410 return mRenderTarget;
413 // Increments refcount on image.
414 // caller must release() the returned image
415 egl::Image *Colorbuffer::createSharedImage()
419 mRenderTarget->addRef();
420 mRenderTarget->markShared();
423 return mRenderTarget;
426 bool Colorbuffer::isShared() const
428 return mRenderTarget->isShared();
431 DepthStencilbuffer::DepthStencilbuffer(egl::Image *depthStencil) : mDepthStencil(depthStencil)
435 depthStencil->addRef();
437 mWidth = depthStencil->getWidth();
438 mHeight = depthStencil->getHeight();
439 internalFormat = depthStencil->getInternalFormat();
440 format = sw2rad::ConvertDepthStencilFormat(internalFormat);
441 mSamples = depthStencil->getMultiSampleDepth() & ~1;
445 DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples)
447 Device *device = getDevice();
449 mDepthStencil = NULL;
451 int supportedSamples = Context::getSupportedMultiSampleDepth(sw::FORMAT_D24S8, samples);
453 if(width > 0 && height > 0)
455 mDepthStencil = device->createDepthStencilSurface(width, height, sw::FORMAT_D24S8, supportedSamples, false);
459 error(GL_OUT_OF_MEMORY);
466 format = GL_DEPTH24_STENCIL8_OES;
467 internalFormat = sw::FORMAT_D24S8;
468 mSamples = supportedSamples & ~1;
471 DepthStencilbuffer::~DepthStencilbuffer()
475 mDepthStencil->release();
479 // Increments refcount on image.
480 // caller must release() the returned image
481 egl::Image *DepthStencilbuffer::getRenderTarget()
485 mDepthStencil->addRef();
488 return mDepthStencil;
491 // Increments refcount on image.
492 // caller must release() the returned image
493 egl::Image *DepthStencilbuffer::createSharedImage()
497 mDepthStencil->addRef();
498 mDepthStencil->markShared();
501 return mDepthStencil;
504 bool DepthStencilbuffer::isShared() const
506 return mDepthStencil->isShared();
509 Depthbuffer::Depthbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
513 format = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
514 // will expect one of the valid renderbuffer formats for use in
515 // glRenderbufferStorage
519 Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
523 format = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
524 // will expect one of the valid renderbuffer formats for use in
525 // glRenderbufferStorage
529 Depthbuffer::~Depthbuffer()
533 Stencilbuffer::Stencilbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
537 format = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
538 // will expect one of the valid renderbuffer formats for use in
539 // glRenderbufferStorage
543 Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
547 format = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
548 // will expect one of the valid renderbuffer formats for use in
549 // glRenderbufferStorage
553 Stencilbuffer::~Stencilbuffer()