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 25namespace es1 26{ 27RenderbufferInterface::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. 34void RenderbufferInterface::addProxyRef(const Renderbuffer *proxy) 35{ 36} 37 38void RenderbufferInterface::releaseProxy(const Renderbuffer *proxy) 39{ 40} 41 42GLuint RenderbufferInterface::getRedSize() const 43{ 44 return sw2es::GetRedSize(getInternalFormat()); 45} 46 47GLuint RenderbufferInterface::getGreenSize() const 48{ 49 return sw2es::GetGreenSize(getInternalFormat()); 50} 51 52GLuint RenderbufferInterface::getBlueSize() const 53{ 54 return sw2es::GetBlueSize(getInternalFormat()); 55} 56 57GLuint RenderbufferInterface::getAlphaSize() const 58{ 59 return sw2es::GetAlphaSize(getInternalFormat()); 60} 61 62GLuint RenderbufferInterface::getDepthSize() const 63{ 64 return sw2es::GetDepthSize(getInternalFormat()); 65} 66 67GLuint RenderbufferInterface::getStencilSize() const 68{ 69 return sw2es::GetStencilSize(getInternalFormat()); 70} 71 72///// RenderbufferTexture2D Implementation //////// 73 74RenderbufferTexture2D::RenderbufferTexture2D(Texture2D *texture) 75{ 76 mTexture2D = texture; 77} 78 79RenderbufferTexture2D::~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. 86void RenderbufferTexture2D::addProxyRef(const Renderbuffer *proxy) 87{ 88 mTexture2D->addProxyRef(proxy); 89} 90 91void RenderbufferTexture2D::releaseProxy(const Renderbuffer *proxy) 92{ 93 mTexture2D->releaseProxy(proxy); 94} 95 96// Increments refcount on image. 97// caller must release() the returned image 98egl::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 105egl::Image *RenderbufferTexture2D::createSharedImage() 106{ 107 return mTexture2D->createSharedImage(GL_TEXTURE_2D, 0); 108} 109 110bool RenderbufferTexture2D::isShared() const 111{ 112 return mTexture2D->isShared(GL_TEXTURE_2D, 0); 113} 114 115GLsizei RenderbufferTexture2D::getWidth() const 116{ 117 return mTexture2D->getWidth(GL_TEXTURE_2D, 0); 118} 119 120GLsizei RenderbufferTexture2D::getHeight() const 121{ 122 return mTexture2D->getHeight(GL_TEXTURE_2D, 0); 123} 124 125GLenum RenderbufferTexture2D::getFormat() const 126{ 127 return mTexture2D->getFormat(GL_TEXTURE_2D, 0); 128} 129 130sw::Format RenderbufferTexture2D::getInternalFormat() const 131{ 132 return mTexture2D->getInternalFormat(GL_TEXTURE_2D, 0); 133} 134 135GLsizei RenderbufferTexture2D::getSamples() const 136{ 137 return 0; 138} 139 140////// Renderbuffer Implementation ////// 141 142Renderbuffer::Renderbuffer(GLuint name, RenderbufferInterface *instance) : NamedObject(name) 143{ 144 ASSERT(instance); 145 mInstance = instance; 146} 147 148Renderbuffer::~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. 155void Renderbuffer::addRef() 156{ 157 mInstance->addProxyRef(this); 158 159 Object::addRef(); 160} 161 162void 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 171egl::Image *Renderbuffer::getRenderTarget() 172{ 173 return mInstance->getRenderTarget(); 174} 175 176// Increments refcount on image. 177// caller must Release() the returned image 178egl::Image *Renderbuffer::createSharedImage() 179{ 180 return mInstance->createSharedImage(); 181} 182 183bool Renderbuffer::isShared() const 184{ 185 return mInstance->isShared(); 186} 187 188GLsizei Renderbuffer::getWidth() const 189{ 190 return mInstance->getWidth(); 191} 192 193GLsizei Renderbuffer::getHeight() const 194{ 195 return mInstance->getHeight(); 196} 197 198GLenum Renderbuffer::getFormat() const 199{ 200 return mInstance->getFormat(); 201} 202 203sw::Format Renderbuffer::getInternalFormat() const 204{ 205 return mInstance->getInternalFormat(); 206} 207 208GLuint Renderbuffer::getRedSize() const 209{ 210 return mInstance->getRedSize(); 211} 212 213GLuint Renderbuffer::getGreenSize() const 214{ 215 return mInstance->getGreenSize(); 216} 217 218GLuint Renderbuffer::getBlueSize() const 219{ 220 return mInstance->getBlueSize(); 221} 222 223GLuint Renderbuffer::getAlphaSize() const 224{ 225 return mInstance->getAlphaSize(); 226} 227 228GLuint Renderbuffer::getDepthSize() const 229{ 230 return mInstance->getDepthSize(); 231} 232 233GLuint Renderbuffer::getStencilSize() const 234{ 235 return mInstance->getStencilSize(); 236} 237 238GLsizei Renderbuffer::getSamples() const 239{ 240 return mInstance->getSamples(); 241} 242 243void Renderbuffer::setStorage(RenderbufferStorage *newStorage) 244{ 245 ASSERT(newStorage); 246 247 delete mInstance; 248 mInstance = newStorage; 249} 250 251RenderbufferStorage::RenderbufferStorage() 252{ 253 mWidth = 0; 254 mHeight = 0; 255 format = GL_RGBA4_OES; 256 internalFormat = sw::FORMAT_A8B8G8R8; 257 mSamples = 0; 258} 259 260RenderbufferStorage::~RenderbufferStorage() 261{ 262} 263 264GLsizei RenderbufferStorage::getWidth() const 265{ 266 return mWidth; 267} 268 269GLsizei RenderbufferStorage::getHeight() const 270{ 271 return mHeight; 272} 273 274GLenum RenderbufferStorage::getFormat() const 275{ 276 return format; 277} 278 279sw::Format RenderbufferStorage::getInternalFormat() const 280{ 281 return internalFormat; 282} 283 284GLsizei RenderbufferStorage::getSamples() const 285{ 286 return mSamples; 287} 288 289Colorbuffer::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 303Colorbuffer::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 328Colorbuffer::~Colorbuffer() 329{ 330 if(mRenderTarget) 331 { 332 mRenderTarget->release(); 333 } 334} 335 336// Increments refcount on image. 337// caller must release() the returned image 338egl::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 350egl::Image *Colorbuffer::createSharedImage() 351{ 352 if(mRenderTarget) 353 { 354 mRenderTarget->addRef(); 355 mRenderTarget->markShared(); 356 } 357 358 return mRenderTarget; 359} 360 361bool Colorbuffer::isShared() const 362{ 363 return mRenderTarget->isShared(); 364} 365 366DepthStencilbuffer::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 380DepthStencilbuffer::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 404DepthStencilbuffer::~DepthStencilbuffer() 405{ 406 if(mDepthStencil) 407 { 408 mDepthStencil->release(); 409 } 410} 411 412// Increments refcount on image. 413// caller must release() the returned image 414egl::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 426egl::Image *DepthStencilbuffer::createSharedImage() 427{ 428 if(mDepthStencil) 429 { 430 mDepthStencil->addRef(); 431 mDepthStencil->markShared(); 432 } 433 434 return mDepthStencil; 435} 436 437bool DepthStencilbuffer::isShared() const 438{ 439 return mDepthStencil->isShared(); 440} 441 442Depthbuffer::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 452Depthbuffer::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 462Depthbuffer::~Depthbuffer() 463{ 464} 465 466Stencilbuffer::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 476Stencilbuffer::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 486Stencilbuffer::~Stencilbuffer() 487{ 488} 489 490} 491