Home | History | Annotate | Download | only in libGL
      1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //    http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 // Renderbuffer.cpp: the Renderbuffer class and its derived classes
     16 // Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
     17 // objects and related functionality.
     18 
     19 #include "Renderbuffer.h"
     20 
     21 #include "main.h"
     22 #include "Texture.h"
     23 #include "utilities.h"
     24 
     25 namespace gl
     26 {
     27 RenderbufferInterface::RenderbufferInterface()
     28 {
     29 }
     30 
     31 // The default case for classes inherited from RenderbufferInterface is not to
     32 // need to do anything upon the reference count to the parent Renderbuffer incrementing
     33 // or decrementing.
     34 void RenderbufferInterface::addProxyRef(const Renderbuffer *proxy)
     35 {
     36 }
     37 
     38 void RenderbufferInterface::releaseProxy(const Renderbuffer *proxy)
     39 {
     40 }
     41 
     42 GLuint RenderbufferInterface::getRedSize() const
     43 {
     44 	return sw2es::GetRedSize(getInternalFormat());
     45 }
     46 
     47 GLuint RenderbufferInterface::getGreenSize() const
     48 {
     49 	return sw2es::GetGreenSize(getInternalFormat());
     50 }
     51 
     52 GLuint RenderbufferInterface::getBlueSize() const
     53 {
     54 	return sw2es::GetBlueSize(getInternalFormat());
     55 }
     56 
     57 GLuint RenderbufferInterface::getAlphaSize() const
     58 {
     59 	return sw2es::GetAlphaSize(getInternalFormat());
     60 }
     61 
     62 GLuint RenderbufferInterface::getDepthSize() const
     63 {
     64 	return sw2es::GetDepthSize(getInternalFormat());
     65 }
     66 
     67 GLuint RenderbufferInterface::getStencilSize() const
     68 {
     69 	return sw2es::GetStencilSize(getInternalFormat());
     70 }
     71 
     72 ///// RenderbufferTexture2D Implementation ////////
     73 
     74 RenderbufferTexture2D::RenderbufferTexture2D(Texture2D *texture)
     75 {
     76 	mTexture2D = texture;
     77 }
     78 
     79 RenderbufferTexture2D::~RenderbufferTexture2D()
     80 {
     81 	mTexture2D = nullptr;
     82 }
     83 
     84 // Textures need to maintain their own reference count for references via
     85 // Renderbuffers acting as proxies. Here, we notify the texture of a reference.
     86 void RenderbufferTexture2D::addProxyRef(const Renderbuffer *proxy)
     87 {
     88 	mTexture2D->addProxyRef(proxy);
     89 }
     90 
     91 void RenderbufferTexture2D::releaseProxy(const Renderbuffer *proxy)
     92 {
     93 	mTexture2D->releaseProxy(proxy);
     94 }
     95 
     96 // Increments refcount on surface.
     97 // caller must release() the returned surface
     98 Image *RenderbufferTexture2D::getRenderTarget()
     99 {
    100 	return mTexture2D->getRenderTarget(GL_TEXTURE_2D, 0);
    101 }
    102 
    103 GLsizei RenderbufferTexture2D::getWidth() const
    104 {
    105 	return mTexture2D->getWidth(GL_TEXTURE_2D, 0);
    106 }
    107 
    108 GLsizei RenderbufferTexture2D::getHeight() const
    109 {
    110 	return mTexture2D->getHeight(GL_TEXTURE_2D, 0);
    111 }
    112 
    113 GLenum RenderbufferTexture2D::getFormat() const
    114 {
    115 	return mTexture2D->getFormat(GL_TEXTURE_2D, 0);
    116 }
    117 
    118 sw::Format RenderbufferTexture2D::getInternalFormat() const
    119 {
    120 	return mTexture2D->getInternalFormat(GL_TEXTURE_2D, 0);
    121 }
    122 
    123 GLsizei RenderbufferTexture2D::getSamples() const
    124 {
    125 	return 0;
    126 }
    127 
    128 ///// RenderbufferTextureCubeMap Implementation ////////
    129 
    130 RenderbufferTextureCubeMap::RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target) : mTarget(target)
    131 {
    132 	mTextureCubeMap = texture;
    133 }
    134 
    135 RenderbufferTextureCubeMap::~RenderbufferTextureCubeMap()
    136 {
    137 	mTextureCubeMap = nullptr;
    138 }
    139 
    140 // Textures need to maintain their own reference count for references via
    141 // Renderbuffers acting as proxies. Here, we notify the texture of a reference.
    142 void RenderbufferTextureCubeMap::addProxyRef(const Renderbuffer *proxy)
    143 {
    144 	mTextureCubeMap->addProxyRef(proxy);
    145 }
    146 
    147 void RenderbufferTextureCubeMap::releaseProxy(const Renderbuffer *proxy)
    148 {
    149 	mTextureCubeMap->releaseProxy(proxy);
    150 }
    151 
    152 // Increments refcount on surface.
    153 // caller must release() the returned surface
    154 Image *RenderbufferTextureCubeMap::getRenderTarget()
    155 {
    156 	return mTextureCubeMap->getRenderTarget(mTarget, 0);
    157 }
    158 
    159 GLsizei RenderbufferTextureCubeMap::getWidth() const
    160 {
    161 	return mTextureCubeMap->getWidth(mTarget, 0);
    162 }
    163 
    164 GLsizei RenderbufferTextureCubeMap::getHeight() const
    165 {
    166 	return mTextureCubeMap->getHeight(mTarget, 0);
    167 }
    168 
    169 GLenum RenderbufferTextureCubeMap::getFormat() const
    170 {
    171 	return mTextureCubeMap->getFormat(mTarget, 0);
    172 }
    173 
    174 sw::Format RenderbufferTextureCubeMap::getInternalFormat() const
    175 {
    176 	return mTextureCubeMap->getInternalFormat(mTarget, 0);
    177 }
    178 
    179 GLsizei RenderbufferTextureCubeMap::getSamples() const
    180 {
    181 	return 0;
    182 }
    183 
    184 ////// Renderbuffer Implementation //////
    185 
    186 Renderbuffer::Renderbuffer(GLuint name, RenderbufferInterface *instance) : NamedObject(name)
    187 {
    188 	ASSERT(instance);
    189 	mInstance = instance;
    190 }
    191 
    192 Renderbuffer::~Renderbuffer()
    193 {
    194 	delete mInstance;
    195 }
    196 
    197 // The RenderbufferInterface contained in this Renderbuffer may need to maintain
    198 // its own reference count, so we pass it on here.
    199 void Renderbuffer::addRef()
    200 {
    201 	mInstance->addProxyRef(this);
    202 
    203 	Object::addRef();
    204 }
    205 
    206 void Renderbuffer::release()
    207 {
    208 	mInstance->releaseProxy(this);
    209 
    210 	Object::release();
    211 }
    212 
    213 // Increments refcount on surface.
    214 // caller must Release() the returned surface
    215 Image *Renderbuffer::getRenderTarget()
    216 {
    217 	return mInstance->getRenderTarget();
    218 }
    219 
    220 GLsizei Renderbuffer::getWidth() const
    221 {
    222 	return mInstance->getWidth();
    223 }
    224 
    225 GLsizei Renderbuffer::getHeight() const
    226 {
    227 	return mInstance->getHeight();
    228 }
    229 
    230 GLenum Renderbuffer::getFormat() const
    231 {
    232 	return mInstance->getFormat();
    233 }
    234 
    235 sw::Format Renderbuffer::getInternalFormat() const
    236 {
    237 	return mInstance->getInternalFormat();
    238 }
    239 
    240 GLuint Renderbuffer::getRedSize() const
    241 {
    242 	return mInstance->getRedSize();
    243 }
    244 
    245 GLuint Renderbuffer::getGreenSize() const
    246 {
    247 	return mInstance->getGreenSize();
    248 }
    249 
    250 GLuint Renderbuffer::getBlueSize() const
    251 {
    252 	return mInstance->getBlueSize();
    253 }
    254 
    255 GLuint Renderbuffer::getAlphaSize() const
    256 {
    257 	return mInstance->getAlphaSize();
    258 }
    259 
    260 GLuint Renderbuffer::getDepthSize() const
    261 {
    262 	return mInstance->getDepthSize();
    263 }
    264 
    265 GLuint Renderbuffer::getStencilSize() const
    266 {
    267 	return mInstance->getStencilSize();
    268 }
    269 
    270 GLsizei Renderbuffer::getSamples() const
    271 {
    272 	return mInstance->getSamples();
    273 }
    274 
    275 void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
    276 {
    277 	ASSERT(newStorage);
    278 
    279 	delete mInstance;
    280 	mInstance = newStorage;
    281 }
    282 
    283 RenderbufferStorage::RenderbufferStorage()
    284 {
    285 	mWidth = 0;
    286 	mHeight = 0;
    287 	format = GL_RGBA4;
    288 	internalFormat = sw::FORMAT_A8R8G8B8;
    289 	mSamples = 0;
    290 }
    291 
    292 RenderbufferStorage::~RenderbufferStorage()
    293 {
    294 }
    295 
    296 // Increments refcount on surface.
    297 // caller must Release() the returned surface
    298 Image *RenderbufferStorage::getRenderTarget()
    299 {
    300 	return nullptr;
    301 }
    302 
    303 GLsizei RenderbufferStorage::getWidth() const
    304 {
    305 	return mWidth;
    306 }
    307 
    308 GLsizei RenderbufferStorage::getHeight() const
    309 {
    310 	return mHeight;
    311 }
    312 
    313 GLenum RenderbufferStorage::getFormat() const
    314 {
    315 	return format;
    316 }
    317 
    318 sw::Format RenderbufferStorage::getInternalFormat() const
    319 {
    320 	return internalFormat;
    321 }
    322 
    323 GLsizei RenderbufferStorage::getSamples() const
    324 {
    325 	return mSamples;
    326 }
    327 
    328 Colorbuffer::Colorbuffer(Image *renderTarget) : mRenderTarget(renderTarget)
    329 {
    330 	if(renderTarget)
    331 	{
    332 		renderTarget->addRef();
    333 
    334 		mWidth = renderTarget->getWidth();
    335 		mHeight = renderTarget->getHeight();
    336 		internalFormat = renderTarget->getInternalFormat();
    337 		format = sw2es::ConvertBackBufferFormat(internalFormat);
    338 		mSamples = renderTarget->getMultiSampleDepth() & ~1;
    339 	}
    340 }
    341 
    342 Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) : mRenderTarget(nullptr)
    343 {
    344 	Device *device = getDevice();
    345 
    346 	sw::Format requestedFormat = es2sw::ConvertRenderbufferFormat(format);
    347 	int supportedSamples = Context::getSupportedMultisampleCount(samples);
    348 
    349 	if(width > 0 && height > 0)
    350 	{
    351 		mRenderTarget = device->createRenderTarget(width, height, requestedFormat, supportedSamples, false);
    352 
    353 		if(!mRenderTarget)
    354 		{
    355 			error(GL_OUT_OF_MEMORY);
    356 			return;
    357 		}
    358 	}
    359 
    360 	mWidth = width;
    361 	mHeight = height;
    362 	this->format = format;
    363 	internalFormat = requestedFormat;
    364 	mSamples = supportedSamples;
    365 }
    366 
    367 Colorbuffer::~Colorbuffer()
    368 {
    369 	if(mRenderTarget)
    370 	{
    371 		mRenderTarget->release();
    372 	}
    373 }
    374 
    375 // Increments refcount on surface.
    376 // caller must release() the returned surface
    377 Image *Colorbuffer::getRenderTarget()
    378 {
    379 	if(mRenderTarget)
    380 	{
    381 		mRenderTarget->addRef();
    382 	}
    383 
    384 	return mRenderTarget;
    385 }
    386 
    387 DepthStencilbuffer::DepthStencilbuffer(Image *depthStencil) : mDepthStencil(depthStencil)
    388 {
    389 	if(depthStencil)
    390 	{
    391 		depthStencil->addRef();
    392 
    393 		mWidth = depthStencil->getWidth();
    394 		mHeight = depthStencil->getHeight();
    395 		internalFormat = depthStencil->getInternalFormat();
    396 		format = sw2es::ConvertDepthStencilFormat(internalFormat);
    397 		mSamples = depthStencil->getMultiSampleDepth() & ~1;
    398 	}
    399 }
    400 
    401 DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples) : mDepthStencil(nullptr)
    402 {
    403 	Device *device = getDevice();
    404 
    405 	int supportedSamples = Context::getSupportedMultisampleCount(samples);
    406 
    407 	if(width > 0 && height > 0)
    408 	{
    409 		mDepthStencil = device->createDepthStencilSurface(width, height, sw::FORMAT_D24S8, supportedSamples, false);
    410 
    411 		if(!mDepthStencil)
    412 		{
    413 			error(GL_OUT_OF_MEMORY);
    414 			return;
    415 		}
    416 	}
    417 
    418 	mWidth = width;
    419 	mHeight = height;
    420 	format = GL_DEPTH24_STENCIL8_EXT;
    421 	internalFormat = sw::FORMAT_D24S8;
    422 	mSamples = supportedSamples;
    423 }
    424 
    425 DepthStencilbuffer::~DepthStencilbuffer()
    426 {
    427 	if(mDepthStencil)
    428 	{
    429 		mDepthStencil->release();
    430 	}
    431 }
    432 
    433 // Increments refcount on surface.
    434 // caller must release() the returned surface
    435 Image *DepthStencilbuffer::getRenderTarget()
    436 {
    437 	if(mDepthStencil)
    438 	{
    439 		mDepthStencil->addRef();
    440 	}
    441 
    442 	return mDepthStencil;
    443 }
    444 
    445 Depthbuffer::Depthbuffer(Image *depthStencil) : DepthStencilbuffer(depthStencil)
    446 {
    447 	if(depthStencil)
    448 	{
    449 		format = GL_DEPTH_COMPONENT16;   // If the renderbuffer parameters are queried, the calling function
    450 		                                 // will expect one of the valid renderbuffer formats for use in
    451 		                                 // glRenderbufferStorage
    452 	}
    453 }
    454 
    455 Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
    456 {
    457 	if(mDepthStencil)
    458 	{
    459 		format = GL_DEPTH_COMPONENT16;   // If the renderbuffer parameters are queried, the calling function
    460 		                                 // will expect one of the valid renderbuffer formats for use in
    461 		                                 // glRenderbufferStorage
    462 	}
    463 }
    464 
    465 Depthbuffer::~Depthbuffer()
    466 {
    467 }
    468 
    469 Stencilbuffer::Stencilbuffer(Image *depthStencil) : DepthStencilbuffer(depthStencil)
    470 {
    471 	if(depthStencil)
    472 	{
    473 		format = GL_STENCIL_INDEX8;   // If the renderbuffer parameters are queried, the calling function
    474 		                              // will expect one of the valid renderbuffer formats for use in
    475 		                              // glRenderbufferStorage
    476 	}
    477 }
    478 
    479 Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
    480 {
    481 	if(mDepthStencil)
    482 	{
    483 		format = GL_STENCIL_INDEX8;   // If the renderbuffer parameters are queried, the calling function
    484 		                              // will expect one of the valid renderbuffer formats for use in
    485 		                              // glRenderbufferStorage
    486 	}
    487 }
    488 
    489 Stencilbuffer::~Stencilbuffer()
    490 {
    491 }
    492 
    493 }
    494