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