Home | History | Annotate | Download | only in libGLES_CM
      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. [OpenGL ES 2.0.24] section 4.4.3 page 108.
     18 
     19 #include "Renderbuffer.h"
     20 
     21 #include "main.h"
     22 #include "Texture.h"
     23 #include "utilities.h"
     24 
     25 namespace es1
     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 image.
     97 // caller must release() the returned image
     98 egl::Image *RenderbufferTexture2D::getRenderTarget()
     99 {
    100 	return mTexture2D->getRenderTarget(GL_TEXTURE_2D, 0);
    101 }
    102 
    103 // Increments refcount on image.
    104 // caller must release() the returned image
    105 egl::Image *RenderbufferTexture2D::createSharedImage()
    106 {
    107 	return mTexture2D->createSharedImage(GL_TEXTURE_2D, 0);
    108 }
    109 
    110 bool RenderbufferTexture2D::isShared() const
    111 {
    112 	return mTexture2D->isShared(GL_TEXTURE_2D, 0);
    113 }
    114 
    115 GLsizei RenderbufferTexture2D::getWidth() const
    116 {
    117 	return mTexture2D->getWidth(GL_TEXTURE_2D, 0);
    118 }
    119 
    120 GLsizei RenderbufferTexture2D::getHeight() const
    121 {
    122 	return mTexture2D->getHeight(GL_TEXTURE_2D, 0);
    123 }
    124 
    125 GLenum RenderbufferTexture2D::getFormat() const
    126 {
    127 	return mTexture2D->getFormat(GL_TEXTURE_2D, 0);
    128 }
    129 
    130 sw::Format RenderbufferTexture2D::getInternalFormat() const
    131 {
    132 	return mTexture2D->getInternalFormat(GL_TEXTURE_2D, 0);
    133 }
    134 
    135 GLsizei RenderbufferTexture2D::getSamples() const
    136 {
    137 	return 0;
    138 }
    139 
    140 ////// Renderbuffer Implementation //////
    141 
    142 Renderbuffer::Renderbuffer(GLuint name, RenderbufferInterface *instance) : NamedObject(name)
    143 {
    144 	ASSERT(instance);
    145 	mInstance = instance;
    146 }
    147 
    148 Renderbuffer::~Renderbuffer()
    149 {
    150 	delete mInstance;
    151 }
    152 
    153 // The RenderbufferInterface contained in this Renderbuffer may need to maintain
    154 // its own reference count, so we pass it on here.
    155 void Renderbuffer::addRef()
    156 {
    157 	mInstance->addProxyRef(this);
    158 
    159 	Object::addRef();
    160 }
    161 
    162 void Renderbuffer::release()
    163 {
    164 	mInstance->releaseProxy(this);
    165 
    166 	Object::release();
    167 }
    168 
    169 // Increments refcount on image.
    170 // caller must Release() the returned image
    171 egl::Image *Renderbuffer::getRenderTarget()
    172 {
    173 	return mInstance->getRenderTarget();
    174 }
    175 
    176 // Increments refcount on image.
    177 // caller must Release() the returned image
    178 egl::Image *Renderbuffer::createSharedImage()
    179 {
    180 	return mInstance->createSharedImage();
    181 }
    182 
    183 bool Renderbuffer::isShared() const
    184 {
    185 	return mInstance->isShared();
    186 }
    187 
    188 GLsizei Renderbuffer::getWidth() const
    189 {
    190 	return mInstance->getWidth();
    191 }
    192 
    193 GLsizei Renderbuffer::getHeight() const
    194 {
    195 	return mInstance->getHeight();
    196 }
    197 
    198 GLenum Renderbuffer::getFormat() const
    199 {
    200 	return mInstance->getFormat();
    201 }
    202 
    203 sw::Format Renderbuffer::getInternalFormat() const
    204 {
    205 	return mInstance->getInternalFormat();
    206 }
    207 
    208 GLuint Renderbuffer::getRedSize() const
    209 {
    210 	return mInstance->getRedSize();
    211 }
    212 
    213 GLuint Renderbuffer::getGreenSize() const
    214 {
    215 	return mInstance->getGreenSize();
    216 }
    217 
    218 GLuint Renderbuffer::getBlueSize() const
    219 {
    220 	return mInstance->getBlueSize();
    221 }
    222 
    223 GLuint Renderbuffer::getAlphaSize() const
    224 {
    225 	return mInstance->getAlphaSize();
    226 }
    227 
    228 GLuint Renderbuffer::getDepthSize() const
    229 {
    230 	return mInstance->getDepthSize();
    231 }
    232 
    233 GLuint Renderbuffer::getStencilSize() const
    234 {
    235 	return mInstance->getStencilSize();
    236 }
    237 
    238 GLsizei Renderbuffer::getSamples() const
    239 {
    240 	return mInstance->getSamples();
    241 }
    242 
    243 void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
    244 {
    245 	ASSERT(newStorage);
    246 
    247 	delete mInstance;
    248 	mInstance = newStorage;
    249 }
    250 
    251 RenderbufferStorage::RenderbufferStorage()
    252 {
    253 	mWidth = 0;
    254 	mHeight = 0;
    255 	format = GL_RGBA4_OES;
    256 	internalFormat = sw::FORMAT_A8B8G8R8;
    257 	mSamples = 0;
    258 }
    259 
    260 RenderbufferStorage::~RenderbufferStorage()
    261 {
    262 }
    263 
    264 GLsizei RenderbufferStorage::getWidth() const
    265 {
    266 	return mWidth;
    267 }
    268 
    269 GLsizei RenderbufferStorage::getHeight() const
    270 {
    271 	return mHeight;
    272 }
    273 
    274 GLenum RenderbufferStorage::getFormat() const
    275 {
    276 	return format;
    277 }
    278 
    279 sw::Format RenderbufferStorage::getInternalFormat() const
    280 {
    281 	return internalFormat;
    282 }
    283 
    284 GLsizei RenderbufferStorage::getSamples() const
    285 {
    286 	return mSamples;
    287 }
    288 
    289 Colorbuffer::Colorbuffer(egl::Image *renderTarget) : mRenderTarget(renderTarget)
    290 {
    291 	if(renderTarget)
    292 	{
    293 		renderTarget->addRef();
    294 
    295 		mWidth = renderTarget->getWidth();
    296 		mHeight = renderTarget->getHeight();
    297 		internalFormat = renderTarget->getInternalFormat();
    298 		format = sw2es::ConvertBackBufferFormat(internalFormat);
    299 		mSamples = renderTarget->getDepth() & ~1;
    300 	}
    301 }
    302 
    303 Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) : mRenderTarget(nullptr)
    304 {
    305 	Device *device = getDevice();
    306 
    307 	sw::Format requestedFormat = es2sw::ConvertRenderbufferFormat(format);
    308 	int supportedSamples = Context::getSupportedMultisampleCount(samples);
    309 
    310 	if(width > 0 && height > 0)
    311 	{
    312 		mRenderTarget = device->createRenderTarget(width, height, requestedFormat, supportedSamples, false);
    313 
    314 		if(!mRenderTarget)
    315 		{
    316 			error(GL_OUT_OF_MEMORY);
    317 			return;
    318 		}
    319 	}
    320 
    321 	mWidth = width;
    322 	mHeight = height;
    323 	this->format = format;
    324 	internalFormat = requestedFormat;
    325 	mSamples = supportedSamples;
    326 }
    327 
    328 Colorbuffer::~Colorbuffer()
    329 {
    330 	if(mRenderTarget)
    331 	{
    332 		mRenderTarget->release();
    333 	}
    334 }
    335 
    336 // Increments refcount on image.
    337 // caller must release() the returned image
    338 egl::Image *Colorbuffer::getRenderTarget()
    339 {
    340 	if(mRenderTarget)
    341 	{
    342 		mRenderTarget->addRef();
    343 	}
    344 
    345 	return mRenderTarget;
    346 }
    347 
    348 // Increments refcount on image.
    349 // caller must release() the returned image
    350 egl::Image *Colorbuffer::createSharedImage()
    351 {
    352 	if(mRenderTarget)
    353 	{
    354 		mRenderTarget->addRef();
    355 		mRenderTarget->markShared();
    356 	}
    357 
    358 	return mRenderTarget;
    359 }
    360 
    361 bool Colorbuffer::isShared() const
    362 {
    363 	return mRenderTarget->isShared();
    364 }
    365 
    366 DepthStencilbuffer::DepthStencilbuffer(egl::Image *depthStencil) : mDepthStencil(depthStencil)
    367 {
    368 	if(depthStencil)
    369 	{
    370 		depthStencil->addRef();
    371 
    372 		mWidth = depthStencil->getWidth();
    373 		mHeight = depthStencil->getHeight();
    374 		internalFormat = depthStencil->getInternalFormat();
    375 		format = sw2es::ConvertDepthStencilFormat(internalFormat);
    376 		mSamples = depthStencil->getDepth() & ~1;
    377 	}
    378 }
    379 
    380 DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples) : mDepthStencil(nullptr)
    381 {
    382 	Device *device = getDevice();
    383 
    384 	int supportedSamples = Context::getSupportedMultisampleCount(samples);
    385 
    386 	if(width > 0 && height > 0)
    387 	{
    388 		mDepthStencil = device->createDepthStencilSurface(width, height, sw::FORMAT_D24S8, supportedSamples, false);
    389 
    390 		if(!mDepthStencil)
    391 		{
    392 			error(GL_OUT_OF_MEMORY);
    393 			return;
    394 		}
    395 	}
    396 
    397 	mWidth = width;
    398 	mHeight = height;
    399 	format = GL_DEPTH24_STENCIL8_OES;
    400 	internalFormat = sw::FORMAT_D24S8;
    401 	mSamples = supportedSamples;
    402 }
    403 
    404 DepthStencilbuffer::~DepthStencilbuffer()
    405 {
    406 	if(mDepthStencil)
    407 	{
    408 		mDepthStencil->release();
    409 	}
    410 }
    411 
    412 // Increments refcount on image.
    413 // caller must release() the returned image
    414 egl::Image *DepthStencilbuffer::getRenderTarget()
    415 {
    416 	if(mDepthStencil)
    417 	{
    418 		mDepthStencil->addRef();
    419 	}
    420 
    421 	return mDepthStencil;
    422 }
    423 
    424 // Increments refcount on image.
    425 // caller must release() the returned image
    426 egl::Image *DepthStencilbuffer::createSharedImage()
    427 {
    428 	if(mDepthStencil)
    429 	{
    430 		mDepthStencil->addRef();
    431 		mDepthStencil->markShared();
    432 	}
    433 
    434 	return mDepthStencil;
    435 }
    436 
    437 bool DepthStencilbuffer::isShared() const
    438 {
    439 	return mDepthStencil->isShared();
    440 }
    441 
    442 Depthbuffer::Depthbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
    443 {
    444 	if(depthStencil)
    445 	{
    446 		format = GL_DEPTH_COMPONENT16_OES;   // If the renderbuffer parameters are queried, the calling function
    447 		                                     // will expect one of the valid renderbuffer formats for use in
    448 		                                     // glRenderbufferStorage
    449 	}
    450 }
    451 
    452 Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
    453 {
    454 	if(mDepthStencil)
    455 	{
    456 		format = GL_DEPTH_COMPONENT16_OES;   // If the renderbuffer parameters are queried, the calling function
    457 		                                     // will expect one of the valid renderbuffer formats for use in
    458 		                                     // glRenderbufferStorage
    459 	}
    460 }
    461 
    462 Depthbuffer::~Depthbuffer()
    463 {
    464 }
    465 
    466 Stencilbuffer::Stencilbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
    467 {
    468 	if(depthStencil)
    469 	{
    470 		format = GL_STENCIL_INDEX8_OES;   // If the renderbuffer parameters are queried, the calling function
    471 		                                  // will expect one of the valid renderbuffer formats for use in
    472 		                                  // glRenderbufferStorage
    473 	}
    474 }
    475 
    476 Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
    477 {
    478 	if(mDepthStencil)
    479 	{
    480 		format = GL_STENCIL_INDEX8_OES;   // If the renderbuffer parameters are queried, the calling function
    481 		                                  // will expect one of the valid renderbuffer formats for use in
    482 		                                  // glRenderbufferStorage
    483 	}
    484 }
    485 
    486 Stencilbuffer::~Stencilbuffer()
    487 {
    488 }
    489 
    490 }
    491