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 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)
     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 GLint RenderbufferTexture2D::getFormat() const
    126 {
    127 	return mTexture2D->getFormat(GL_TEXTURE_2D, 0);
    128 }
    129 
    130 GLsizei RenderbufferTexture2D::getSamples() const
    131 {
    132 	return 0;
    133 }
    134 
    135 ////// Renderbuffer Implementation //////
    136 
    137 Renderbuffer::Renderbuffer(GLuint name, RenderbufferInterface *instance) : NamedObject(name)
    138 {
    139 	ASSERT(instance);
    140 	mInstance = instance;
    141 }
    142 
    143 Renderbuffer::~Renderbuffer()
    144 {
    145 	delete mInstance;
    146 }
    147 
    148 // The RenderbufferInterface contained in this Renderbuffer may need to maintain
    149 // its own reference count, so we pass it on here.
    150 void Renderbuffer::addRef()
    151 {
    152 	mInstance->addProxyRef(this);
    153 
    154 	Object::addRef();
    155 }
    156 
    157 void Renderbuffer::release()
    158 {
    159 	mInstance->releaseProxy(this);
    160 
    161 	Object::release();
    162 }
    163 
    164 // Increments refcount on image.
    165 // caller must Release() the returned image
    166 egl::Image *Renderbuffer::getRenderTarget()
    167 {
    168 	return mInstance->getRenderTarget();
    169 }
    170 
    171 // Increments refcount on image.
    172 // caller must Release() the returned image
    173 egl::Image *Renderbuffer::createSharedImage()
    174 {
    175 	return mInstance->createSharedImage();
    176 }
    177 
    178 bool Renderbuffer::isShared() const
    179 {
    180 	return mInstance->isShared();
    181 }
    182 
    183 GLsizei Renderbuffer::getWidth() const
    184 {
    185 	return mInstance->getWidth();
    186 }
    187 
    188 GLsizei Renderbuffer::getHeight() const
    189 {
    190 	return mInstance->getHeight();
    191 }
    192 
    193 GLenum Renderbuffer::getFormat() const
    194 {
    195 	return mInstance->getFormat();
    196 }
    197 
    198 GLuint Renderbuffer::getRedSize() const
    199 {
    200 	return mInstance->getRedSize();
    201 }
    202 
    203 GLuint Renderbuffer::getGreenSize() const
    204 {
    205 	return mInstance->getGreenSize();
    206 }
    207 
    208 GLuint Renderbuffer::getBlueSize() const
    209 {
    210 	return mInstance->getBlueSize();
    211 }
    212 
    213 GLuint Renderbuffer::getAlphaSize() const
    214 {
    215 	return mInstance->getAlphaSize();
    216 }
    217 
    218 GLuint Renderbuffer::getDepthSize() const
    219 {
    220 	return mInstance->getDepthSize();
    221 }
    222 
    223 GLuint Renderbuffer::getStencilSize() const
    224 {
    225 	return mInstance->getStencilSize();
    226 }
    227 
    228 GLsizei Renderbuffer::getSamples() const
    229 {
    230 	return mInstance->getSamples();
    231 }
    232 
    233 void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
    234 {
    235 	ASSERT(newStorage);
    236 
    237 	delete mInstance;
    238 	mInstance = newStorage;
    239 }
    240 
    241 RenderbufferStorage::RenderbufferStorage()
    242 {
    243 	mWidth = 0;
    244 	mHeight = 0;
    245 	format = GL_NONE_OES;
    246 	mSamples = 0;
    247 }
    248 
    249 RenderbufferStorage::~RenderbufferStorage()
    250 {
    251 }
    252 
    253 GLsizei RenderbufferStorage::getWidth() const
    254 {
    255 	return mWidth;
    256 }
    257 
    258 GLsizei RenderbufferStorage::getHeight() const
    259 {
    260 	return mHeight;
    261 }
    262 
    263 GLint RenderbufferStorage::getFormat() const
    264 {
    265 	return format;
    266 }
    267 
    268 GLsizei RenderbufferStorage::getSamples() const
    269 {
    270 	return mSamples;
    271 }
    272 
    273 Colorbuffer::Colorbuffer(egl::Image *renderTarget) : mRenderTarget(renderTarget)
    274 {
    275 	if(renderTarget)
    276 	{
    277 		renderTarget->addRef();
    278 
    279 		mWidth = renderTarget->getWidth();
    280 		mHeight = renderTarget->getHeight();
    281 		format = renderTarget->getFormat();
    282 		mSamples = renderTarget->getDepth() & ~1;
    283 	}
    284 }
    285 
    286 Colorbuffer::Colorbuffer(int width, int height, GLenum internalformat, GLsizei samples) : mRenderTarget(nullptr)
    287 {
    288 	int supportedSamples = Context::getSupportedMultisampleCount(samples);
    289 
    290 	if(width > 0 && height > 0)
    291 	{
    292 		if(height > sw::OUTLINE_RESOLUTION)
    293 		{
    294 			error(GL_OUT_OF_MEMORY);
    295 			return;
    296 		}
    297 
    298 		mRenderTarget = egl::Image::create(width, height, internalformat, supportedSamples, false);
    299 
    300 		if(!mRenderTarget)
    301 		{
    302 			error(GL_OUT_OF_MEMORY);
    303 			return;
    304 		}
    305 	}
    306 
    307 	mWidth = width;
    308 	mHeight = height;
    309 	format = internalformat;
    310 	mSamples = supportedSamples;
    311 }
    312 
    313 Colorbuffer::~Colorbuffer()
    314 {
    315 	if(mRenderTarget)
    316 	{
    317 		mRenderTarget->release();
    318 	}
    319 }
    320 
    321 // Increments refcount on image.
    322 // caller must release() the returned image
    323 egl::Image *Colorbuffer::getRenderTarget()
    324 {
    325 	if(mRenderTarget)
    326 	{
    327 		mRenderTarget->addRef();
    328 	}
    329 
    330 	return mRenderTarget;
    331 }
    332 
    333 // Increments refcount on image.
    334 // caller must release() the returned image
    335 egl::Image *Colorbuffer::createSharedImage()
    336 {
    337 	if(mRenderTarget)
    338 	{
    339 		mRenderTarget->addRef();
    340 		mRenderTarget->markShared();
    341 	}
    342 
    343 	return mRenderTarget;
    344 }
    345 
    346 bool Colorbuffer::isShared() const
    347 {
    348 	return mRenderTarget->isShared();
    349 }
    350 
    351 DepthStencilbuffer::DepthStencilbuffer(egl::Image *depthStencil) : mDepthStencil(depthStencil)
    352 {
    353 	if(depthStencil)
    354 	{
    355 		depthStencil->addRef();
    356 
    357 		mWidth = depthStencil->getWidth();
    358 		mHeight = depthStencil->getHeight();
    359 		format = depthStencil->getFormat();
    360 		mSamples = depthStencil->getDepth() & ~1;
    361 	}
    362 }
    363 
    364 DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLenum internalformat, GLsizei samples) : mDepthStencil(nullptr)
    365 {
    366 	int supportedSamples = Context::getSupportedMultisampleCount(samples);
    367 
    368 	if(width > 0 && height > 0)
    369 	{
    370 		if(height > sw::OUTLINE_RESOLUTION)
    371 		{
    372 			error(GL_OUT_OF_MEMORY);
    373 			return;
    374 		}
    375 
    376 		mDepthStencil = egl::Image::create(width, height, internalformat, supportedSamples, false);
    377 
    378 		if(!mDepthStencil)
    379 		{
    380 			error(GL_OUT_OF_MEMORY);
    381 			return;
    382 		}
    383 	}
    384 
    385 	mWidth = width;
    386 	mHeight = height;
    387 	format = internalformat;
    388 	mSamples = supportedSamples;
    389 }
    390 
    391 DepthStencilbuffer::~DepthStencilbuffer()
    392 {
    393 	if(mDepthStencil)
    394 	{
    395 		mDepthStencil->release();
    396 	}
    397 }
    398 
    399 // Increments refcount on image.
    400 // caller must release() the returned image
    401 egl::Image *DepthStencilbuffer::getRenderTarget()
    402 {
    403 	if(mDepthStencil)
    404 	{
    405 		mDepthStencil->addRef();
    406 	}
    407 
    408 	return mDepthStencil;
    409 }
    410 
    411 // Increments refcount on image.
    412 // caller must release() the returned image
    413 egl::Image *DepthStencilbuffer::createSharedImage()
    414 {
    415 	if(mDepthStencil)
    416 	{
    417 		mDepthStencil->addRef();
    418 		mDepthStencil->markShared();
    419 	}
    420 
    421 	return mDepthStencil;
    422 }
    423 
    424 bool DepthStencilbuffer::isShared() const
    425 {
    426 	return mDepthStencil->isShared();
    427 }
    428 
    429 Depthbuffer::Depthbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
    430 {
    431 }
    432 
    433 Depthbuffer::Depthbuffer(int width, int height, GLenum internalformat, GLsizei samples) : DepthStencilbuffer(width, height, internalformat, samples)
    434 {
    435 }
    436 
    437 Depthbuffer::~Depthbuffer()
    438 {
    439 }
    440 
    441 Stencilbuffer::Stencilbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
    442 {
    443 }
    444 
    445 Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, GL_STENCIL_INDEX8_OES, samples)
    446 {
    447 }
    448 
    449 Stencilbuffer::~Stencilbuffer()
    450 {
    451 }
    452 
    453 }
    454