blob: e7fbe62fe7695154298df8f20235fdbb1de109c8 [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"
14#include "libGLESv2/utilities.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000015
16namespace gl
17{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000018unsigned int RenderbufferStorage::mCurrentSerial = 1;
daniel@transgaming.com092bd482010-05-12 03:39:36 +000019
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000020Renderbuffer::Renderbuffer(GLuint id, RenderbufferStorage *storage) : RefCountObject(id)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000021{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000022 ASSERT(storage != NULL);
23 mStorage = storage;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000024}
25
26Renderbuffer::~Renderbuffer()
27{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000028 delete mStorage;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000029}
30
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000031bool Renderbuffer::isColorbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000032{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000033 return mStorage->isColorbuffer();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000034}
35
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000036bool Renderbuffer::isDepthbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000037{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000038 return mStorage->isDepthbuffer();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000039}
40
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000041bool Renderbuffer::isStencilbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000042{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000043 return mStorage->isStencilbuffer();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000044}
45
46IDirect3DSurface9 *Renderbuffer::getRenderTarget()
47{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000048 return mStorage->getRenderTarget();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000049}
50
51IDirect3DSurface9 *Renderbuffer::getDepthStencil()
52{
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000053 return mStorage->getDepthStencil();
54}
55
56int Renderbuffer::getWidth() const
57{
58 return mStorage->getWidth();
59}
60
61int Renderbuffer::getHeight() const
62{
63 return mStorage->getHeight();
64}
65
66GLenum Renderbuffer::getFormat() const
67{
68 return mStorage->getFormat();
69}
70
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +000071D3DFORMAT Renderbuffer::getD3DFormat() const
72{
73 return mStorage->getD3DFormat();
74}
75
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +000076unsigned int Renderbuffer::getSerial() const
77{
78 return mStorage->getSerial();
79}
80
81void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
82{
83 ASSERT(newStorage != NULL);
84
85 delete mStorage;
86 mStorage = newStorage;
87}
88
89RenderbufferStorage::RenderbufferStorage()
90{
91 mSerial = issueSerial();
92}
93
94RenderbufferStorage::~RenderbufferStorage()
95{
96}
97
98bool RenderbufferStorage::isColorbuffer() const
99{
100 return false;
101}
102
103bool RenderbufferStorage::isDepthbuffer() const
104{
105 return false;
106}
107
108bool RenderbufferStorage::isStencilbuffer() const
109{
110 return false;
111}
112
113IDirect3DSurface9 *RenderbufferStorage::getRenderTarget()
114{
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000115 return NULL;
116}
117
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000118IDirect3DSurface9 *RenderbufferStorage::getDepthStencil()
119{
120 return NULL;
121}
122
123int RenderbufferStorage::getWidth() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000124{
125 return mWidth;
126}
127
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000128int RenderbufferStorage::getHeight() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000129{
130 return mHeight;
131}
132
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000133void RenderbufferStorage::setSize(int width, int height)
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000134{
135 mWidth = width;
136 mHeight = height;
137}
138
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000139GLenum RenderbufferStorage::getFormat() const
daniel@transgaming.com4901fca2010-04-20 18:52:41 +0000140{
141 return mFormat;
142}
143
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +0000144D3DFORMAT RenderbufferStorage::getD3DFormat() const
145{
146 return mD3DFormat;
147}
148
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000149unsigned int RenderbufferStorage::getSerial() const
daniel@transgaming.com092bd482010-05-12 03:39:36 +0000150{
151 return mSerial;
152}
153
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000154unsigned int RenderbufferStorage::issueSerial()
daniel@transgaming.com092bd482010-05-12 03:39:36 +0000155{
156 return mCurrentSerial++;
157}
158
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000159Colorbuffer::Colorbuffer(IDirect3DSurface9 *renderTarget) : mRenderTarget(renderTarget)
160{
161 if (renderTarget)
162 {
163 renderTarget->AddRef();
164
165 D3DSURFACE_DESC description;
166 renderTarget->GetDesc(&description);
167
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000168 setSize(description.Width, description.Height);
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000169 mD3DFormat = description.Format;
170 }
171 else
172 {
173 mD3DFormat = D3DFMT_UNKNOWN;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000174 }
daniel@transgaming.com092bd482010-05-12 03:39:36 +0000175
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000176}
177
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000178Colorbuffer::Colorbuffer(int width, int height, GLenum format)
179{
180 IDirect3DDevice9 *device = getDevice();
181
182 mRenderTarget = NULL;
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000183 D3DFORMAT requestedFormat = es2dx::ConvertRenderbufferFormat(format);
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000184
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000185 if (width > 0 && height > 0)
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000186 {
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000187 HRESULT result = device->CreateRenderTarget(width, height, requestedFormat,
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000188 D3DMULTISAMPLE_NONE, 0, FALSE, &mRenderTarget, NULL);
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000189
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000190 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
191 {
192 error(GL_OUT_OF_MEMORY);
193
194 return;
195 }
196
197 ASSERT(SUCCEEDED(result));
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000198 }
199
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000200 if (mRenderTarget)
201 {
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000202 setSize(width, height);
daniel@transgaming.com4901fca2010-04-20 18:52:41 +0000203 mFormat = format;
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000204 mD3DFormat = requestedFormat;
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000205 }
206 else
207 {
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000208 setSize(0, 0);
daniel@transgaming.com4901fca2010-04-20 18:52:41 +0000209 mFormat = GL_RGBA4;
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000210 mD3DFormat = D3DFMT_UNKNOWN;
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000211 }
212}
213
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000214Colorbuffer::~Colorbuffer()
215{
216 if (mRenderTarget)
217 {
218 mRenderTarget->Release();
219 }
220}
221
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000222bool Colorbuffer::isColorbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000223{
224 return true;
225}
226
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000227GLuint Colorbuffer::getRedSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000228{
229 if (mRenderTarget)
230 {
231 D3DSURFACE_DESC description;
232 mRenderTarget->GetDesc(&description);
233
234 return es2dx::GetRedSize(description.Format);
235 }
236
237 return 0;
238}
239
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000240GLuint Colorbuffer::getGreenSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000241{
242 if (mRenderTarget)
243 {
244 D3DSURFACE_DESC description;
245 mRenderTarget->GetDesc(&description);
246
247 return es2dx::GetGreenSize(description.Format);
248 }
249
250 return 0;
251}
252
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000253GLuint Colorbuffer::getBlueSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000254{
255 if (mRenderTarget)
256 {
257 D3DSURFACE_DESC description;
258 mRenderTarget->GetDesc(&description);
259
260 return es2dx::GetBlueSize(description.Format);
261 }
262
263 return 0;
264}
265
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000266GLuint Colorbuffer::getAlphaSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000267{
268 if (mRenderTarget)
269 {
270 D3DSURFACE_DESC description;
271 mRenderTarget->GetDesc(&description);
272
273 return es2dx::GetAlphaSize(description.Format);
274 }
275
276 return 0;
277}
278
279IDirect3DSurface9 *Colorbuffer::getRenderTarget()
280{
281 return mRenderTarget;
282}
283
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000284DepthStencilbuffer::DepthStencilbuffer(IDirect3DSurface9 *depthStencil) : mDepthStencil(depthStencil)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000285{
286 if (depthStencil)
287 {
288 depthStencil->AddRef();
289
290 D3DSURFACE_DESC description;
291 depthStencil->GetDesc(&description);
292
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000293 setSize(description.Width, description.Height);
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000294 mFormat = (description.Format == D3DFMT_D16 ? GL_DEPTH_COMPONENT16 : GL_DEPTH24_STENCIL8_OES);
295 mD3DFormat = description.Format;
296 }
297 else
298 {
299 mD3DFormat = D3DFMT_UNKNOWN;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000300 }
301}
302
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000303DepthStencilbuffer::DepthStencilbuffer(int width, int height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000304{
305 IDirect3DDevice9 *device = getDevice();
306
307 mDepthStencil = NULL;
308 HRESULT result = device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, 0);
309
310 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
311 {
312 error(GL_OUT_OF_MEMORY);
313
314 return;
315 }
316
317 ASSERT(SUCCEEDED(result));
318
319 if (mDepthStencil)
320 {
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000321 setSize(width, height);
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000322 mFormat = GL_DEPTH24_STENCIL8_OES;
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000323 mD3DFormat = D3DFMT_D24S8;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000324 }
325 else
326 {
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000327 setSize(0, 0);
daniel@transgaming.com4901fca2010-04-20 18:52:41 +0000328 mFormat = GL_RGBA4; //default format
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000329 mD3DFormat = D3DFMT_UNKNOWN;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000330 }
331}
332
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000333DepthStencilbuffer::~DepthStencilbuffer()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000334{
335 if (mDepthStencil)
336 {
337 mDepthStencil->Release();
338 }
339}
340
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000341bool DepthStencilbuffer::isDepthbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000342{
343 return true;
344}
345
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000346bool DepthStencilbuffer::isStencilbuffer() const
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000347{
348 return true;
349}
350
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000351GLuint DepthStencilbuffer::getDepthSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000352{
353 if (mDepthStencil)
354 {
355 D3DSURFACE_DESC description;
356 mDepthStencil->GetDesc(&description);
357
daniel@transgaming.com7a2c2802010-03-16 06:23:33 +0000358 return es2dx::GetDepthSize(description.Format);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000359 }
360
361 return 0;
362}
363
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000364GLuint DepthStencilbuffer::getStencilSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000365{
366 if (mDepthStencil)
367 {
368 D3DSURFACE_DESC description;
369 mDepthStencil->GetDesc(&description);
370
371 return es2dx::GetStencilSize(description.Format);
372 }
373
374 return 0;
375}
376
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000377IDirect3DSurface9 *DepthStencilbuffer::getDepthStencil()
378{
379 return mDepthStencil;
380}
381
382Depthbuffer::Depthbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil)
383{
384 if (depthStencil)
385 {
386 mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
387 // will expect one of the valid renderbuffer formats for use in
388 // glRenderbufferStorage
389 }
390}
391
392Depthbuffer::Depthbuffer(int width, int height) : DepthStencilbuffer(width, height)
393{
394 if (getDepthStencil())
395 {
396 mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
397 // will expect one of the valid renderbuffer formats for use in
398 // glRenderbufferStorage
399 }
400}
401
402Depthbuffer::~Depthbuffer()
403{
404}
405
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000406bool Depthbuffer::isDepthbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000407{
408 return true;
409}
410
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000411bool Depthbuffer::isStencilbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000412{
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000413 return false;
414}
415
416Stencilbuffer::Stencilbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil)
417{
418 if (depthStencil)
419 {
420 mFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
421 // will expect one of the valid renderbuffer formats for use in
422 // glRenderbufferStorage
423 }
424 else
425 {
426 mFormat = GL_RGBA4; //default format
427 }
428}
429
430Stencilbuffer::Stencilbuffer(int width, int height) : DepthStencilbuffer(width, height)
431{
432 if (getDepthStencil())
433 {
434 mFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
435 // will expect one of the valid renderbuffer formats for use in
436 // glRenderbufferStorage
437 }
438}
439
440Stencilbuffer::~Stencilbuffer()
441{
442}
443
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000444bool Stencilbuffer::isDepthbuffer() const
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000445{
446 return false;
447}
448
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000449bool Stencilbuffer::isStencilbuffer() const
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000450{
451 return true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000452}
453}