Home | History | Annotate | Download | only in libGLESv2
      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 es2
     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 GetRedSize(getFormat());
     45 }
     46 
     47 GLuint RenderbufferInterface::getGreenSize() const
     48 {
     49 	return GetGreenSize(getFormat());
     50 }
     51 
     52 GLuint RenderbufferInterface::getBlueSize() const
     53 {
     54 	return GetBlueSize(getFormat());
     55 }
     56 
     57 GLuint RenderbufferInterface::getAlphaSize() const
     58 {
     59 	return GetAlphaSize(getFormat());
     60 }
     61 
     62 GLuint RenderbufferInterface::getDepthSize() const
     63 {
     64 	return GetDepthSize(getFormat());
     65 }
     66 
     67 GLuint RenderbufferInterface::getStencilSize() const
     68 {
     69 	return GetStencilSize(getFormat());
     70 }
     71 
     72 ///// RenderbufferTexture2D Implementation ////////
     73 
     74 RenderbufferTexture2D::RenderbufferTexture2D(Texture2D *texture, GLint level) : mLevel(level)
     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, mLevel);
    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, mLevel);
    108 }
    109 
    110 bool RenderbufferTexture2D::isShared() const
    111 {
    112 	return mTexture2D->isShared(GL_TEXTURE_2D, mLevel);
    113 }
    114 
    115 GLsizei RenderbufferTexture2D::getWidth() const
    116 {
    117 	return mTexture2D->getWidth(GL_TEXTURE_2D, mLevel);
    118 }
    119 
    120 GLsizei RenderbufferTexture2D::getHeight() const
    121 {
    122 	return mTexture2D->getHeight(GL_TEXTURE_2D, mLevel);
    123 }
    124 
    125 GLint RenderbufferTexture2D::getFormat() const
    126 {
    127 	return mTexture2D->getFormat(GL_TEXTURE_2D, mLevel);
    128 }
    129 
    130 GLsizei RenderbufferTexture2D::getSamples() const
    131 {
    132 	return 0;   // Core OpenGL ES 3.0 does not support multisample textures.
    133 }
    134 
    135 ///// RenderbufferTexture2DRect Implementation ////////
    136 
    137 RenderbufferTexture2DRect::RenderbufferTexture2DRect(Texture2DRect *texture)
    138 {
    139 	mTexture2DRect = texture;
    140 }
    141 
    142 RenderbufferTexture2DRect::~RenderbufferTexture2DRect()
    143 {
    144 	mTexture2DRect = NULL;
    145 }
    146 
    147 // Textures need to maintain their own reference count for references via
    148 // Renderbuffers acting as proxies. Here, we notify the texture of a reference.
    149 void RenderbufferTexture2DRect::addProxyRef(const Renderbuffer *proxy)
    150 {
    151 	mTexture2DRect->addProxyRef(proxy);
    152 }
    153 
    154 void RenderbufferTexture2DRect::releaseProxy(const Renderbuffer *proxy)
    155 {
    156 	mTexture2DRect->releaseProxy(proxy);
    157 }
    158 
    159 // Increments refcount on image.
    160 // caller must release() the returned image
    161 egl::Image *RenderbufferTexture2DRect::getRenderTarget()
    162 {
    163 	return mTexture2DRect->getRenderTarget(GL_TEXTURE_RECTANGLE_ARB, 0);
    164 }
    165 
    166 // Increments refcount on image.
    167 // caller must release() the returned image
    168 egl::Image *RenderbufferTexture2DRect::createSharedImage()
    169 {
    170 	return mTexture2DRect->createSharedImage(GL_TEXTURE_RECTANGLE_ARB, 0);
    171 }
    172 
    173 bool RenderbufferTexture2DRect::isShared() const
    174 {
    175 	return mTexture2DRect->isShared(GL_TEXTURE_RECTANGLE_ARB, 0);
    176 }
    177 
    178 GLsizei RenderbufferTexture2DRect::getWidth() const
    179 {
    180 	return mTexture2DRect->getWidth(GL_TEXTURE_RECTANGLE_ARB, 0);
    181 }
    182 
    183 GLsizei RenderbufferTexture2DRect::getHeight() const
    184 {
    185 	return mTexture2DRect->getHeight(GL_TEXTURE_RECTANGLE_ARB, 0);
    186 }
    187 
    188 GLint RenderbufferTexture2DRect::getFormat() const
    189 {
    190 	return mTexture2DRect->getFormat(GL_TEXTURE_RECTANGLE_ARB, 0);
    191 }
    192 
    193 GLsizei RenderbufferTexture2DRect::getSamples() const
    194 {
    195 	return 0;   // Core OpenGL ES 3.0 does not support multisample textures.
    196 }
    197 
    198 ///// RenderbufferTexture3D Implementation ////////
    199 
    200 RenderbufferTexture3D::RenderbufferTexture3D(Texture3D *texture, GLint level) : mLevel(level)
    201 {
    202 	mTexture3D = texture;
    203 }
    204 
    205 RenderbufferTexture3D::~RenderbufferTexture3D()
    206 {
    207 	mTexture3D = NULL;
    208 }
    209 
    210 // Textures need to maintain their own reference count for references via
    211 // Renderbuffers acting as proxies. Here, we notify the texture of a reference.
    212 void RenderbufferTexture3D::addProxyRef(const Renderbuffer *proxy)
    213 {
    214 	mTexture3D->addProxyRef(proxy);
    215 }
    216 
    217 void RenderbufferTexture3D::releaseProxy(const Renderbuffer *proxy)
    218 {
    219 	mTexture3D->releaseProxy(proxy);
    220 }
    221 
    222 // Increments refcount on image.
    223 // caller must release() the returned image
    224 egl::Image *RenderbufferTexture3D::getRenderTarget()
    225 {
    226 	return mTexture3D->getRenderTarget(mTexture3D->getTarget(), mLevel);
    227 }
    228 
    229 // Increments refcount on image.
    230 // caller must release() the returned image
    231 egl::Image *RenderbufferTexture3D::createSharedImage()
    232 {
    233 	return mTexture3D->createSharedImage(mTexture3D->getTarget(), mLevel);
    234 }
    235 
    236 bool RenderbufferTexture3D::isShared() const
    237 {
    238 	return mTexture3D->isShared(mTexture3D->getTarget(), mLevel);
    239 }
    240 
    241 GLsizei RenderbufferTexture3D::getWidth() const
    242 {
    243 	return mTexture3D->getWidth(mTexture3D->getTarget(), mLevel);
    244 }
    245 
    246 GLsizei RenderbufferTexture3D::getHeight() const
    247 {
    248 	return mTexture3D->getHeight(mTexture3D->getTarget(), mLevel);
    249 }
    250 
    251 GLsizei RenderbufferTexture3D::getDepth() const
    252 {
    253 	return mTexture3D->getDepth(mTexture3D->getTarget(), mLevel);
    254 }
    255 
    256 GLint RenderbufferTexture3D::getFormat() const
    257 {
    258 	return mTexture3D->getFormat(mTexture3D->getTarget(), mLevel);
    259 }
    260 
    261 GLsizei RenderbufferTexture3D::getSamples() const
    262 {
    263 	return 0;   // Core OpenGL ES 3.0 does not support multisample textures.
    264 }
    265 
    266 ///// RenderbufferTextureCubeMap Implementation ////////
    267 
    268 RenderbufferTextureCubeMap::RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target, GLint level) : mTarget(target), mLevel(level)
    269 {
    270 	mTextureCubeMap = texture;
    271 }
    272 
    273 RenderbufferTextureCubeMap::~RenderbufferTextureCubeMap()
    274 {
    275 	mTextureCubeMap = NULL;
    276 }
    277 
    278 // Textures need to maintain their own reference count for references via
    279 // Renderbuffers acting as proxies. Here, we notify the texture of a reference.
    280 void RenderbufferTextureCubeMap::addProxyRef(const Renderbuffer *proxy)
    281 {
    282 	mTextureCubeMap->addProxyRef(proxy);
    283 }
    284 
    285 void RenderbufferTextureCubeMap::releaseProxy(const Renderbuffer *proxy)
    286 {
    287 	mTextureCubeMap->releaseProxy(proxy);
    288 }
    289 
    290 // Increments refcount on image.
    291 // caller must release() the returned image
    292 egl::Image *RenderbufferTextureCubeMap::getRenderTarget()
    293 {
    294 	return mTextureCubeMap->getRenderTarget(mTarget, mLevel);
    295 }
    296 
    297 // Increments refcount on image.
    298 // caller must release() the returned image
    299 egl::Image *RenderbufferTextureCubeMap::createSharedImage()
    300 {
    301 	return mTextureCubeMap->createSharedImage(mTarget, mLevel);
    302 }
    303 
    304 bool RenderbufferTextureCubeMap::isShared() const
    305 {
    306 	return mTextureCubeMap->isShared(mTarget, mLevel);
    307 }
    308 
    309 GLsizei RenderbufferTextureCubeMap::getWidth() const
    310 {
    311 	return mTextureCubeMap->getWidth(mTarget, mLevel);
    312 }
    313 
    314 GLsizei RenderbufferTextureCubeMap::getHeight() const
    315 {
    316 	return mTextureCubeMap->getHeight(mTarget, mLevel);
    317 }
    318 
    319 GLint RenderbufferTextureCubeMap::getFormat() const
    320 {
    321 	return mTextureCubeMap->getFormat(mTarget, mLevel);
    322 }
    323 
    324 GLsizei RenderbufferTextureCubeMap::getSamples() const
    325 {
    326 	return 0;   // Core OpenGL ES 3.0 does not support multisample textures.
    327 }
    328 
    329 ////// Renderbuffer Implementation //////
    330 
    331 Renderbuffer::Renderbuffer(GLuint name, RenderbufferInterface *instance) : NamedObject(name)
    332 {
    333 	ASSERT(instance);
    334 	mInstance = instance;
    335 }
    336 
    337 Renderbuffer::~Renderbuffer()
    338 {
    339 	delete mInstance;
    340 }
    341 
    342 // The RenderbufferInterface contained in this Renderbuffer may need to maintain
    343 // its own reference count, so we pass it on here.
    344 void Renderbuffer::addRef()
    345 {
    346 	mInstance->addProxyRef(this);
    347 
    348 	Object::addRef();
    349 }
    350 
    351 void Renderbuffer::release()
    352 {
    353 	mInstance->releaseProxy(this);
    354 
    355 	Object::release();
    356 }
    357 
    358 // Increments refcount on image.
    359 // caller must Release() the returned image
    360 egl::Image *Renderbuffer::getRenderTarget()
    361 {
    362 	return mInstance->getRenderTarget();
    363 }
    364 
    365 // Increments refcount on image.
    366 // caller must Release() the returned image
    367 egl::Image *Renderbuffer::createSharedImage()
    368 {
    369 	return mInstance->createSharedImage();
    370 }
    371 
    372 bool Renderbuffer::isShared() const
    373 {
    374 	return mInstance->isShared();
    375 }
    376 
    377 GLsizei Renderbuffer::getWidth() const
    378 {
    379 	return mInstance->getWidth();
    380 }
    381 
    382 GLsizei Renderbuffer::getHeight() const
    383 {
    384 	return mInstance->getHeight();
    385 }
    386 
    387 GLsizei Renderbuffer::getDepth() const
    388 {
    389 	return mInstance->getDepth();
    390 }
    391 
    392 GLint Renderbuffer::getLevel() const
    393 {
    394 	return mInstance->getLevel();
    395 }
    396 
    397 GLint Renderbuffer::getFormat() const
    398 {
    399 	return mInstance->getFormat();
    400 }
    401 
    402 GLuint Renderbuffer::getRedSize() const
    403 {
    404 	return mInstance->getRedSize();
    405 }
    406 
    407 GLuint Renderbuffer::getGreenSize() const
    408 {
    409 	return mInstance->getGreenSize();
    410 }
    411 
    412 GLuint Renderbuffer::getBlueSize() const
    413 {
    414 	return mInstance->getBlueSize();
    415 }
    416 
    417 GLuint Renderbuffer::getAlphaSize() const
    418 {
    419 	return mInstance->getAlphaSize();
    420 }
    421 
    422 GLuint Renderbuffer::getDepthSize() const
    423 {
    424 	return mInstance->getDepthSize();
    425 }
    426 
    427 GLuint Renderbuffer::getStencilSize() const
    428 {
    429 	return mInstance->getStencilSize();
    430 }
    431 
    432 GLsizei Renderbuffer::getSamples() const
    433 {
    434 	return mInstance->getSamples();
    435 }
    436 
    437 void Renderbuffer::setLevel(GLint level)
    438 {
    439 	return mInstance->setLevel(level);
    440 }
    441 
    442 void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
    443 {
    444 	ASSERT(newStorage);
    445 
    446 	delete mInstance;
    447 	mInstance = newStorage;
    448 }
    449 
    450 RenderbufferStorage::RenderbufferStorage()
    451 {
    452 	mWidth = 0;
    453 	mHeight = 0;
    454 	format = GL_NONE;
    455 	mSamples = 0;
    456 }
    457 
    458 RenderbufferStorage::~RenderbufferStorage()
    459 {
    460 }
    461 
    462 GLsizei RenderbufferStorage::getWidth() const
    463 {
    464 	return mWidth;
    465 }
    466 
    467 GLsizei RenderbufferStorage::getHeight() const
    468 {
    469 	return mHeight;
    470 }
    471 
    472 GLint RenderbufferStorage::getFormat() const
    473 {
    474 	return format;
    475 }
    476 
    477 GLsizei RenderbufferStorage::getSamples() const
    478 {
    479 	return mSamples;
    480 }
    481 
    482 Colorbuffer::Colorbuffer(egl::Image *renderTarget) : mRenderTarget(renderTarget)
    483 {
    484 	if(renderTarget)
    485 	{
    486 		renderTarget->addRef();
    487 
    488 		mWidth = renderTarget->getWidth();
    489 		mHeight = renderTarget->getHeight();
    490 		format = renderTarget->getFormat();
    491 		mSamples = renderTarget->getDepth() & ~1;
    492 	}
    493 }
    494 
    495 Colorbuffer::Colorbuffer(int width, int height, GLenum internalformat, GLsizei samples) : mRenderTarget(nullptr)
    496 {
    497 	int supportedSamples = Context::getSupportedMultisampleCount(samples);
    498 
    499 	if(width > 0 && height > 0)
    500 	{
    501 		if(height > sw::OUTLINE_RESOLUTION)
    502 		{
    503 			error(GL_OUT_OF_MEMORY);
    504 			return;
    505 		}
    506 
    507 		mRenderTarget = egl::Image::create(width, height, internalformat, supportedSamples, false);
    508 
    509 		if(!mRenderTarget)
    510 		{
    511 			error(GL_OUT_OF_MEMORY);
    512 			return;
    513 		}
    514 	}
    515 
    516 	mWidth = width;
    517 	mHeight = height;
    518 	format = internalformat;
    519 	mSamples = supportedSamples;
    520 }
    521 
    522 Colorbuffer::~Colorbuffer()
    523 {
    524 	if(mRenderTarget)
    525 	{
    526 		mRenderTarget->release();
    527 	}
    528 }
    529 
    530 // Increments refcount on image.
    531 // caller must release() the returned image
    532 egl::Image *Colorbuffer::getRenderTarget()
    533 {
    534 	if(mRenderTarget)
    535 	{
    536 		mRenderTarget->addRef();
    537 	}
    538 
    539 	return mRenderTarget;
    540 }
    541 
    542 // Increments refcount on image.
    543 // caller must release() the returned image
    544 egl::Image *Colorbuffer::createSharedImage()
    545 {
    546 	if(mRenderTarget)
    547 	{
    548 		mRenderTarget->addRef();
    549 		mRenderTarget->markShared();
    550 	}
    551 
    552 	return mRenderTarget;
    553 }
    554 
    555 bool Colorbuffer::isShared() const
    556 {
    557 	return mRenderTarget->isShared();
    558 }
    559 
    560 DepthStencilbuffer::DepthStencilbuffer(egl::Image *depthStencil) : mDepthStencil(depthStencil)
    561 {
    562 	if(depthStencil)
    563 	{
    564 		depthStencil->addRef();
    565 
    566 		mWidth = depthStencil->getWidth();
    567 		mHeight = depthStencil->getHeight();
    568 		format = depthStencil->getFormat();
    569 		mSamples = depthStencil->getDepth() & ~1;
    570 	}
    571 }
    572 
    573 DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLenum internalformat, GLsizei samples) : mDepthStencil(nullptr)
    574 {
    575 	int supportedSamples = Context::getSupportedMultisampleCount(samples);
    576 
    577 	if(width > 0 && height > 0)
    578 	{
    579 		if(height > sw::OUTLINE_RESOLUTION)
    580 		{
    581 			error(GL_OUT_OF_MEMORY);
    582 			return;
    583 		}
    584 
    585 		mDepthStencil = egl::Image::create(width, height, internalformat, supportedSamples, false);
    586 
    587 		if(!mDepthStencil)
    588 		{
    589 			error(GL_OUT_OF_MEMORY);
    590 			return;
    591 		}
    592 	}
    593 
    594 	mWidth = width;
    595 	mHeight = height;
    596 	format = internalformat;
    597 	mSamples = supportedSamples;
    598 }
    599 
    600 DepthStencilbuffer::~DepthStencilbuffer()
    601 {
    602 	if(mDepthStencil)
    603 	{
    604 		mDepthStencil->release();
    605 	}
    606 }
    607 
    608 // Increments refcount on image.
    609 // caller must release() the returned image
    610 egl::Image *DepthStencilbuffer::getRenderTarget()
    611 {
    612 	if(mDepthStencil)
    613 	{
    614 		mDepthStencil->addRef();
    615 	}
    616 
    617 	return mDepthStencil;
    618 }
    619 
    620 // Increments refcount on image.
    621 // caller must release() the returned image
    622 egl::Image *DepthStencilbuffer::createSharedImage()
    623 {
    624 	if(mDepthStencil)
    625 	{
    626 		mDepthStencil->addRef();
    627 		mDepthStencil->markShared();
    628 	}
    629 
    630 	return mDepthStencil;
    631 }
    632 
    633 bool DepthStencilbuffer::isShared() const
    634 {
    635 	return mDepthStencil->isShared();
    636 }
    637 
    638 Depthbuffer::Depthbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
    639 {
    640 }
    641 
    642 Depthbuffer::Depthbuffer(int width, int height, GLenum internalformat, GLsizei samples) : DepthStencilbuffer(width, height, internalformat, samples)
    643 {
    644 }
    645 
    646 Depthbuffer::~Depthbuffer()
    647 {
    648 }
    649 
    650 Stencilbuffer::Stencilbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
    651 {
    652 }
    653 
    654 Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, GL_STENCIL_INDEX8, samples)
    655 {
    656 }
    657 
    658 Stencilbuffer::~Stencilbuffer()
    659 {
    660 }
    661 
    662 }
    663