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