1 // 2 // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // Renderbuffer.cpp: the gl::Renderbuffer class and its derived classes 8 // Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer 9 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108. 10 11 #include "libGLESv2/Renderbuffer.h" 12 13 #include "libGLESv2/main.h" 14 #include "libGLESv2/Texture.h" 15 #include "libGLESv2/utilities.h" 16 17 namespace gl 18 { 19 unsigned int RenderbufferStorage::mCurrentSerial = 1; 20 21 Renderbuffer::Renderbuffer(GLuint id, RenderbufferStorage *storage) : RefCountObject(id) 22 { 23 ASSERT(storage != NULL); 24 mStorage = storage; 25 } 26 27 Renderbuffer::~Renderbuffer() 28 { 29 delete mStorage; 30 } 31 32 bool Renderbuffer::isColorbuffer() const 33 { 34 return mStorage->isColorbuffer(); 35 } 36 37 bool Renderbuffer::isDepthbuffer() const 38 { 39 return mStorage->isDepthbuffer(); 40 } 41 42 bool Renderbuffer::isStencilbuffer() const 43 { 44 return mStorage->isStencilbuffer(); 45 } 46 47 IDirect3DSurface9 *Renderbuffer::getRenderTarget() 48 { 49 return mStorage->getRenderTarget(); 50 } 51 52 IDirect3DSurface9 *Renderbuffer::getDepthStencil() 53 { 54 return mStorage->getDepthStencil(); 55 } 56 57 int Renderbuffer::getWidth() const 58 { 59 return mStorage->getWidth(); 60 } 61 62 int Renderbuffer::getHeight() const 63 { 64 return mStorage->getHeight(); 65 } 66 67 GLenum Renderbuffer::getFormat() const 68 { 69 return mStorage->getFormat(); 70 } 71 72 D3DFORMAT Renderbuffer::getD3DFormat() const 73 { 74 return mStorage->getD3DFormat(); 75 } 76 77 unsigned int Renderbuffer::getSerial() const 78 { 79 return mStorage->getSerial(); 80 } 81 82 void Renderbuffer::setStorage(RenderbufferStorage *newStorage) 83 { 84 ASSERT(newStorage != NULL); 85 86 delete mStorage; 87 mStorage = newStorage; 88 } 89 90 RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerial()) 91 { 92 mWidth = 0; 93 mHeight = 0; 94 mFormat = GL_RGBA4; 95 mD3DFormat = D3DFMT_A8R8G8B8; 96 mSamples = 0; 97 } 98 99 RenderbufferStorage::~RenderbufferStorage() 100 { 101 } 102 103 bool RenderbufferStorage::isColorbuffer() const 104 { 105 return false; 106 } 107 108 bool RenderbufferStorage::isDepthbuffer() const 109 { 110 return false; 111 } 112 113 bool RenderbufferStorage::isStencilbuffer() const 114 { 115 return false; 116 } 117 118 IDirect3DSurface9 *RenderbufferStorage::getRenderTarget() 119 { 120 return NULL; 121 } 122 123 IDirect3DSurface9 *RenderbufferStorage::getDepthStencil() 124 { 125 return NULL; 126 } 127 128 int RenderbufferStorage::getWidth() const 129 { 130 return mWidth; 131 } 132 133 int RenderbufferStorage::getHeight() const 134 { 135 return mHeight; 136 } 137 138 void RenderbufferStorage::setSize(int width, int height) 139 { 140 mWidth = width; 141 mHeight = height; 142 } 143 144 GLenum RenderbufferStorage::getFormat() const 145 { 146 return mFormat; 147 } 148 149 bool RenderbufferStorage::isFloatingPoint() const 150 { 151 return false; // no floating point renderbuffers 152 } 153 154 D3DFORMAT RenderbufferStorage::getD3DFormat() const 155 { 156 return mD3DFormat; 157 } 158 159 GLsizei RenderbufferStorage::getSamples() const 160 { 161 return mSamples; 162 } 163 164 unsigned int RenderbufferStorage::getSerial() const 165 { 166 return mSerial; 167 } 168 169 unsigned int RenderbufferStorage::issueSerial() 170 { 171 return mCurrentSerial++; 172 } 173 174 Colorbuffer::Colorbuffer(IDirect3DSurface9 *renderTarget) : mRenderTarget(renderTarget) 175 { 176 if (renderTarget) 177 { 178 renderTarget->AddRef(); 179 180 D3DSURFACE_DESC description; 181 renderTarget->GetDesc(&description); 182 183 setSize(description.Width, description.Height); 184 mFormat = dx2es::ConvertBackBufferFormat(description.Format); 185 mD3DFormat = description.Format; 186 mSamples = es2dx::GetSamplesFromMultisampleType(description.MultiSampleType); 187 } 188 } 189 190 Colorbuffer::Colorbuffer(const Texture* texture) : mRenderTarget(NULL) 191 { 192 setSize(texture->getWidth(), texture->getHeight()); 193 mD3DFormat = texture->getD3DFormat(); 194 mSamples = 0; 195 } 196 197 Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) 198 { 199 IDirect3DDevice9 *device = getDevice(); 200 201 mRenderTarget = NULL; 202 D3DFORMAT requestedFormat = es2dx::ConvertRenderbufferFormat(format); 203 int supportedSamples = getContext()->getNearestSupportedSamples(requestedFormat, samples); 204 205 if (supportedSamples == -1) 206 { 207 error(GL_OUT_OF_MEMORY); 208 209 return; 210 } 211 212 if (width > 0 && height > 0) 213 { 214 HRESULT result = device->CreateRenderTarget(width, height, requestedFormat, 215 es2dx::GetMultisampleTypeFromSamples(supportedSamples), 0, FALSE, &mRenderTarget, NULL); 216 217 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) 218 { 219 error(GL_OUT_OF_MEMORY); 220 221 return; 222 } 223 224 ASSERT(SUCCEEDED(result)); 225 } 226 227 if (mRenderTarget) 228 { 229 setSize(width, height); 230 mFormat = format; 231 mD3DFormat = requestedFormat; 232 mSamples = supportedSamples; 233 } 234 } 235 236 Colorbuffer::~Colorbuffer() 237 { 238 if (mRenderTarget) 239 { 240 mRenderTarget->Release(); 241 } 242 } 243 244 bool Colorbuffer::isColorbuffer() const 245 { 246 return true; 247 } 248 249 GLuint Colorbuffer::getRedSize() const 250 { 251 if (mRenderTarget) 252 { 253 D3DSURFACE_DESC description; 254 mRenderTarget->GetDesc(&description); 255 256 return es2dx::GetRedSize(description.Format); 257 } 258 259 return 0; 260 } 261 262 GLuint Colorbuffer::getGreenSize() const 263 { 264 if (mRenderTarget) 265 { 266 D3DSURFACE_DESC description; 267 mRenderTarget->GetDesc(&description); 268 269 return es2dx::GetGreenSize(description.Format); 270 } 271 272 return 0; 273 } 274 275 GLuint Colorbuffer::getBlueSize() const 276 { 277 if (mRenderTarget) 278 { 279 D3DSURFACE_DESC description; 280 mRenderTarget->GetDesc(&description); 281 282 return es2dx::GetBlueSize(description.Format); 283 } 284 285 return 0; 286 } 287 288 GLuint Colorbuffer::getAlphaSize() const 289 { 290 if (mRenderTarget) 291 { 292 D3DSURFACE_DESC description; 293 mRenderTarget->GetDesc(&description); 294 295 return es2dx::GetAlphaSize(description.Format); 296 } 297 298 return 0; 299 } 300 301 IDirect3DSurface9 *Colorbuffer::getRenderTarget() 302 { 303 return mRenderTarget; 304 } 305 306 DepthStencilbuffer::DepthStencilbuffer(IDirect3DSurface9 *depthStencil) : mDepthStencil(depthStencil) 307 { 308 if (depthStencil) 309 { 310 depthStencil->AddRef(); 311 312 D3DSURFACE_DESC description; 313 depthStencil->GetDesc(&description); 314 315 setSize(description.Width, description.Height); 316 mFormat = dx2es::ConvertDepthStencilFormat(description.Format); 317 mSamples = es2dx::GetSamplesFromMultisampleType(description.MultiSampleType); 318 mD3DFormat = description.Format; 319 } 320 } 321 322 DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples) 323 { 324 IDirect3DDevice9 *device = getDevice(); 325 326 mDepthStencil = NULL; 327 328 int supportedSamples = getContext()->getNearestSupportedSamples(D3DFMT_D24S8, samples); 329 330 if (supportedSamples == -1) 331 { 332 error(GL_OUT_OF_MEMORY); 333 334 return; 335 } 336 337 HRESULT result = device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, es2dx::GetMultisampleTypeFromSamples(supportedSamples), 338 0, FALSE, &mDepthStencil, 0); 339 340 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) 341 { 342 error(GL_OUT_OF_MEMORY); 343 344 return; 345 } 346 347 ASSERT(SUCCEEDED(result)); 348 349 if (mDepthStencil) 350 { 351 setSize(width, height); 352 mFormat = GL_DEPTH24_STENCIL8_OES; 353 mD3DFormat = D3DFMT_D24S8; 354 mSamples = supportedSamples; 355 } 356 } 357 358 DepthStencilbuffer::~DepthStencilbuffer() 359 { 360 if (mDepthStencil) 361 { 362 mDepthStencil->Release(); 363 } 364 } 365 366 bool DepthStencilbuffer::isDepthbuffer() const 367 { 368 return true; 369 } 370 371 bool DepthStencilbuffer::isStencilbuffer() const 372 { 373 return true; 374 } 375 376 GLuint DepthStencilbuffer::getDepthSize() const 377 { 378 if (mDepthStencil) 379 { 380 D3DSURFACE_DESC description; 381 mDepthStencil->GetDesc(&description); 382 383 return es2dx::GetDepthSize(description.Format); 384 } 385 386 return 0; 387 } 388 389 GLuint DepthStencilbuffer::getStencilSize() const 390 { 391 if (mDepthStencil) 392 { 393 D3DSURFACE_DESC description; 394 mDepthStencil->GetDesc(&description); 395 396 return es2dx::GetStencilSize(description.Format); 397 } 398 399 return 0; 400 } 401 402 IDirect3DSurface9 *DepthStencilbuffer::getDepthStencil() 403 { 404 return mDepthStencil; 405 } 406 407 Depthbuffer::Depthbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil) 408 { 409 if (depthStencil) 410 { 411 mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function 412 // will expect one of the valid renderbuffer formats for use in 413 // glRenderbufferStorage 414 } 415 } 416 417 Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples) 418 { 419 if (getDepthStencil()) 420 { 421 mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function 422 // will expect one of the valid renderbuffer formats for use in 423 // glRenderbufferStorage 424 } 425 } 426 427 Depthbuffer::~Depthbuffer() 428 { 429 } 430 431 bool Depthbuffer::isDepthbuffer() const 432 { 433 return true; 434 } 435 436 bool Depthbuffer::isStencilbuffer() const 437 { 438 return false; 439 } 440 441 Stencilbuffer::Stencilbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil) 442 { 443 if (depthStencil) 444 { 445 mFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function 446 // will expect one of the valid renderbuffer formats for use in 447 // glRenderbufferStorage 448 } 449 else 450 { 451 mFormat = GL_RGBA4; //default format 452 } 453 } 454 455 Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples) 456 { 457 if (getDepthStencil()) 458 { 459 mFormat = GL_STENCIL_INDEX8; // 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 Stencilbuffer::~Stencilbuffer() 466 { 467 } 468 469 bool Stencilbuffer::isDepthbuffer() const 470 { 471 return false; 472 } 473 474 bool Stencilbuffer::isStencilbuffer() const 475 { 476 return true; 477 } 478 } 479