blob: 6e4494be81e7d2e01fb52407108b84ad88c05109 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
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
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000011#include "libGLESv2/Renderbuffer.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000012
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000013#include "libGLESv2/main.h"
enne@chromium.org0fa74632010-09-21 16:18:52 +000014#include "libGLESv2/Texture.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000015#include "libGLESv2/utilities.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000016
17namespace gl
18{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000019unsigned int RenderbufferStorage::mCurrentSerial = 1;
daniel@transgaming.com092bd482010-05-12 03:39:36 +000020
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000021Renderbuffer::Renderbuffer(GLuint id, RenderbufferStorage *storage) : RefCountObject(id)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000022{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000023 ASSERT(storage != NULL);
24 mStorage = storage;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000025}
26
27Renderbuffer::~Renderbuffer()
28{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000029 delete mStorage;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000030}
31
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000032bool Renderbuffer::isColorbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000033{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000034 return mStorage->isColorbuffer();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000035}
36
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000037bool Renderbuffer::isDepthbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000038{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000039 return mStorage->isDepthbuffer();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000040}
41
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000042bool Renderbuffer::isStencilbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000043{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000044 return mStorage->isStencilbuffer();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000045}
46
47IDirect3DSurface9 *Renderbuffer::getRenderTarget()
48{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000049 return mStorage->getRenderTarget();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000050}
51
52IDirect3DSurface9 *Renderbuffer::getDepthStencil()
53{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000054 return mStorage->getDepthStencil();
55}
56
57int Renderbuffer::getWidth() const
58{
59 return mStorage->getWidth();
60}
61
62int Renderbuffer::getHeight() const
63{
64 return mStorage->getHeight();
65}
66
67GLenum Renderbuffer::getFormat() const
68{
69 return mStorage->getFormat();
70}
71
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +000072D3DFORMAT Renderbuffer::getD3DFormat() const
73{
74 return mStorage->getD3DFormat();
75}
76
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000077unsigned int Renderbuffer::getSerial() const
78{
79 return mStorage->getSerial();
80}
81
82void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
83{
84 ASSERT(newStorage != NULL);
85
86 delete mStorage;
87 mStorage = newStorage;
88}
89
daniel@transgaming.com73a5db62010-10-15 17:58:13 +000090RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerial())
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000091{
daniel@transgaming.com73a5db62010-10-15 17:58:13 +000092 mWidth = 0;
93 mHeight = 0;
94 mFormat = GL_RGBA4;
95 mD3DFormat = D3DFMT_A8R8G8B8;
96 mSamples = 0;
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000097}
98
99RenderbufferStorage::~RenderbufferStorage()
100{
101}
102
103bool RenderbufferStorage::isColorbuffer() const
104{
105 return false;
106}
107
108bool RenderbufferStorage::isDepthbuffer() const
109{
110 return false;
111}
112
113bool RenderbufferStorage::isStencilbuffer() const
114{
115 return false;
116}
117
118IDirect3DSurface9 *RenderbufferStorage::getRenderTarget()
119{
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000120 return NULL;
121}
122
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000123IDirect3DSurface9 *RenderbufferStorage::getDepthStencil()
124{
125 return NULL;
126}
127
128int RenderbufferStorage::getWidth() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000129{
130 return mWidth;
131}
132
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000133int RenderbufferStorage::getHeight() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000134{
135 return mHeight;
136}
137
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000138void RenderbufferStorage::setSize(int width, int height)
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000139{
140 mWidth = width;
141 mHeight = height;
142}
143
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000144GLenum RenderbufferStorage::getFormat() const
daniel@transgaming.com4901fca2010-04-20 18:52:41 +0000145{
146 return mFormat;
147}
148
daniel@transgaming.com1297d922010-09-01 15:47:47 +0000149bool RenderbufferStorage::isFloatingPoint() const
150{
151 return false; // no floating point renderbuffers
152}
153
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +0000154D3DFORMAT RenderbufferStorage::getD3DFormat() const
155{
156 return mD3DFormat;
157}
158
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000159GLsizei RenderbufferStorage::getSamples() const
160{
161 return mSamples;
162}
163
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000164unsigned int RenderbufferStorage::getSerial() const
daniel@transgaming.com092bd482010-05-12 03:39:36 +0000165{
166 return mSerial;
167}
168
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000169unsigned int RenderbufferStorage::issueSerial()
daniel@transgaming.com092bd482010-05-12 03:39:36 +0000170{
171 return mCurrentSerial++;
172}
173
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000174Colorbuffer::Colorbuffer(IDirect3DSurface9 *renderTarget) : mRenderTarget(renderTarget)
175{
176 if (renderTarget)
177 {
178 renderTarget->AddRef();
179
180 D3DSURFACE_DESC description;
181 renderTarget->GetDesc(&description);
182
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000183 setSize(description.Width, description.Height);
daniel@transgaming.com73a5db62010-10-15 17:58:13 +0000184 mFormat = dx2es::ConvertBackBufferFormat(description.Format);
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000185 mD3DFormat = description.Format;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000186 mSamples = es2dx::GetSamplesFromMultisampleType(description.MultiSampleType);
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000187 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000188}
189
enne@chromium.org0fa74632010-09-21 16:18:52 +0000190Colorbuffer::Colorbuffer(const Texture* texture) : mRenderTarget(NULL)
191{
192 setSize(texture->getWidth(), texture->getHeight());
193 mD3DFormat = texture->getD3DFormat();
194 mSamples = 0;
195}
196
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000197Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples)
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000198{
199 IDirect3DDevice9 *device = getDevice();
200
201 mRenderTarget = NULL;
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000202 D3DFORMAT requestedFormat = es2dx::ConvertRenderbufferFormat(format);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000203 int supportedSamples = getContext()->getNearestSupportedSamples(requestedFormat, samples);
204
205 if (supportedSamples == -1)
206 {
207 error(GL_OUT_OF_MEMORY);
208
209 return;
210 }
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000211
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000212 if (width > 0 && height > 0)
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000213 {
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000214 HRESULT result = device->CreateRenderTarget(width, height, requestedFormat,
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000215 es2dx::GetMultisampleTypeFromSamples(supportedSamples), 0, FALSE, &mRenderTarget, NULL);
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000216
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000217 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
218 {
219 error(GL_OUT_OF_MEMORY);
220
221 return;
222 }
223
224 ASSERT(SUCCEEDED(result));
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000225 }
226
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000227 if (mRenderTarget)
228 {
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000229 setSize(width, height);
daniel@transgaming.com4901fca2010-04-20 18:52:41 +0000230 mFormat = format;
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000231 mD3DFormat = requestedFormat;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000232 mSamples = supportedSamples;
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000233 }
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000234}
235
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000236Colorbuffer::~Colorbuffer()
237{
238 if (mRenderTarget)
239 {
240 mRenderTarget->Release();
241 }
242}
243
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000244bool Colorbuffer::isColorbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000245{
246 return true;
247}
248
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000249GLuint Colorbuffer::getRedSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000250{
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
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000262GLuint Colorbuffer::getGreenSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000263{
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
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000275GLuint Colorbuffer::getBlueSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000276{
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
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000288GLuint Colorbuffer::getAlphaSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000289{
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
301IDirect3DSurface9 *Colorbuffer::getRenderTarget()
302{
303 return mRenderTarget;
304}
305
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000306DepthStencilbuffer::DepthStencilbuffer(IDirect3DSurface9 *depthStencil) : mDepthStencil(depthStencil)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000307{
308 if (depthStencil)
309 {
310 depthStencil->AddRef();
311
312 D3DSURFACE_DESC description;
313 depthStencil->GetDesc(&description);
314
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000315 setSize(description.Width, description.Height);
daniel@transgaming.com73a5db62010-10-15 17:58:13 +0000316 mFormat = dx2es::ConvertDepthStencilFormat(description.Format);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000317 mSamples = es2dx::GetSamplesFromMultisampleType(description.MultiSampleType);
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000318 mD3DFormat = description.Format;
319 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000320}
321
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000322DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000323{
324 IDirect3DDevice9 *device = getDevice();
325
326 mDepthStencil = NULL;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000327
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);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000339
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 {
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000351 setSize(width, height);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000352 mFormat = GL_DEPTH24_STENCIL8_OES;
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000353 mD3DFormat = D3DFMT_D24S8;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000354 mSamples = supportedSamples;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000355 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000356}
357
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000358DepthStencilbuffer::~DepthStencilbuffer()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000359{
360 if (mDepthStencil)
361 {
362 mDepthStencil->Release();
363 }
364}
365
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000366bool DepthStencilbuffer::isDepthbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000367{
368 return true;
369}
370
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000371bool DepthStencilbuffer::isStencilbuffer() const
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000372{
373 return true;
374}
375
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000376GLuint DepthStencilbuffer::getDepthSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000377{
378 if (mDepthStencil)
379 {
380 D3DSURFACE_DESC description;
381 mDepthStencil->GetDesc(&description);
382
daniel@transgaming.com7a2c2802010-03-16 06:23:33 +0000383 return es2dx::GetDepthSize(description.Format);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000384 }
385
386 return 0;
387}
388
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000389GLuint DepthStencilbuffer::getStencilSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000390{
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
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000402IDirect3DSurface9 *DepthStencilbuffer::getDepthStencil()
403{
404 return mDepthStencil;
405}
406
407Depthbuffer::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
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000417Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000418{
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
427Depthbuffer::~Depthbuffer()
428{
429}
430
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000431bool Depthbuffer::isDepthbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000432{
433 return true;
434}
435
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000436bool Depthbuffer::isStencilbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000437{
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000438 return false;
439}
440
441Stencilbuffer::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
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000455Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000456{
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
465Stencilbuffer::~Stencilbuffer()
466{
467}
468
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000469bool Stencilbuffer::isDepthbuffer() const
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000470{
471 return false;
472}
473
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000474bool Stencilbuffer::isStencilbuffer() const
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000475{
476 return true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000477}
478}