Home | History | Annotate | Download | only in libGLESv2
      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