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, 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, 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 GLint Renderbuffer::getLevel() const 194 { 195 return mInstance->getLevel(); 196 } 197 198 GLenum Renderbuffer::getFormat() const 199 { 200 return mInstance->getFormat(); 201 } 202 203 GLuint Renderbuffer::getRedSize() const 204 { 205 return mInstance->getRedSize(); 206 } 207 208 GLuint Renderbuffer::getGreenSize() const 209 { 210 return mInstance->getGreenSize(); 211 } 212 213 GLuint Renderbuffer::getBlueSize() const 214 { 215 return mInstance->getBlueSize(); 216 } 217 218 GLuint Renderbuffer::getAlphaSize() const 219 { 220 return mInstance->getAlphaSize(); 221 } 222 223 GLuint Renderbuffer::getDepthSize() const 224 { 225 return mInstance->getDepthSize(); 226 } 227 228 GLuint Renderbuffer::getStencilSize() const 229 { 230 return mInstance->getStencilSize(); 231 } 232 233 GLsizei Renderbuffer::getSamples() const 234 { 235 return mInstance->getSamples(); 236 } 237 238 void Renderbuffer::setLevel(GLint level) 239 { 240 return mInstance->setLevel(level); 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_NONE_OES; 256 mSamples = 0; 257 } 258 259 RenderbufferStorage::~RenderbufferStorage() 260 { 261 } 262 263 GLsizei RenderbufferStorage::getWidth() const 264 { 265 return mWidth; 266 } 267 268 GLsizei RenderbufferStorage::getHeight() const 269 { 270 return mHeight; 271 } 272 273 GLint RenderbufferStorage::getFormat() const 274 { 275 return format; 276 } 277 278 GLsizei RenderbufferStorage::getSamples() const 279 { 280 return mSamples; 281 } 282 283 Colorbuffer::Colorbuffer(egl::Image *renderTarget) : mRenderTarget(renderTarget) 284 { 285 if(renderTarget) 286 { 287 renderTarget->addRef(); 288 289 mWidth = renderTarget->getWidth(); 290 mHeight = renderTarget->getHeight(); 291 format = renderTarget->getFormat(); 292 mSamples = renderTarget->getDepth() & ~1; 293 } 294 } 295 296 Colorbuffer::Colorbuffer(int width, int height, GLenum internalformat, GLsizei samples) : mRenderTarget(nullptr) 297 { 298 int supportedSamples = Context::getSupportedMultisampleCount(samples); 299 300 if(width > 0 && height > 0) 301 { 302 if(height > sw::OUTLINE_RESOLUTION) 303 { 304 error(GL_OUT_OF_MEMORY); 305 return; 306 } 307 308 mRenderTarget = egl::Image::create(width, height, internalformat, supportedSamples, false); 309 310 if(!mRenderTarget) 311 { 312 error(GL_OUT_OF_MEMORY); 313 return; 314 } 315 } 316 317 mWidth = width; 318 mHeight = height; 319 format = internalformat; 320 mSamples = supportedSamples; 321 } 322 323 Colorbuffer::~Colorbuffer() 324 { 325 if(mRenderTarget) 326 { 327 mRenderTarget->release(); 328 } 329 } 330 331 // Increments refcount on image. 332 // caller must release() the returned image 333 egl::Image *Colorbuffer::getRenderTarget() 334 { 335 if(mRenderTarget) 336 { 337 mRenderTarget->addRef(); 338 } 339 340 return mRenderTarget; 341 } 342 343 // Increments refcount on image. 344 // caller must release() the returned image 345 egl::Image *Colorbuffer::createSharedImage() 346 { 347 if(mRenderTarget) 348 { 349 mRenderTarget->addRef(); 350 mRenderTarget->markShared(); 351 } 352 353 return mRenderTarget; 354 } 355 356 bool Colorbuffer::isShared() const 357 { 358 return mRenderTarget->isShared(); 359 } 360 361 DepthStencilbuffer::DepthStencilbuffer(egl::Image *depthStencil) : mDepthStencil(depthStencil) 362 { 363 if(depthStencil) 364 { 365 depthStencil->addRef(); 366 367 mWidth = depthStencil->getWidth(); 368 mHeight = depthStencil->getHeight(); 369 format = depthStencil->getFormat(); 370 mSamples = depthStencil->getDepth() & ~1; 371 } 372 } 373 374 DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLenum internalformat, GLsizei samples) : mDepthStencil(nullptr) 375 { 376 int supportedSamples = Context::getSupportedMultisampleCount(samples); 377 378 if(width > 0 && height > 0) 379 { 380 if(height > sw::OUTLINE_RESOLUTION) 381 { 382 error(GL_OUT_OF_MEMORY); 383 return; 384 } 385 386 mDepthStencil = egl::Image::create(width, height, internalformat, supportedSamples, false); 387 388 if(!mDepthStencil) 389 { 390 error(GL_OUT_OF_MEMORY); 391 return; 392 } 393 } 394 395 mWidth = width; 396 mHeight = height; 397 format = internalformat; 398 mSamples = supportedSamples; 399 } 400 401 DepthStencilbuffer::~DepthStencilbuffer() 402 { 403 if(mDepthStencil) 404 { 405 mDepthStencil->release(); 406 } 407 } 408 409 // Increments refcount on image. 410 // caller must release() the returned image 411 egl::Image *DepthStencilbuffer::getRenderTarget() 412 { 413 if(mDepthStencil) 414 { 415 mDepthStencil->addRef(); 416 } 417 418 return mDepthStencil; 419 } 420 421 // Increments refcount on image. 422 // caller must release() the returned image 423 egl::Image *DepthStencilbuffer::createSharedImage() 424 { 425 if(mDepthStencil) 426 { 427 mDepthStencil->addRef(); 428 mDepthStencil->markShared(); 429 } 430 431 return mDepthStencil; 432 } 433 434 bool DepthStencilbuffer::isShared() const 435 { 436 return mDepthStencil->isShared(); 437 } 438 439 Depthbuffer::Depthbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil) 440 { 441 } 442 443 Depthbuffer::Depthbuffer(int width, int height, GLenum internalformat, GLsizei samples) : DepthStencilbuffer(width, height, internalformat, samples) 444 { 445 } 446 447 Depthbuffer::~Depthbuffer() 448 { 449 } 450 451 Stencilbuffer::Stencilbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil) 452 { 453 } 454 455 Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, GL_STENCIL_INDEX8_OES, samples) 456 { 457 } 458 459 Stencilbuffer::~Stencilbuffer() 460 { 461 } 462 463 } 464