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