blob: d0ded4a5683b3702bc1d91a02b24836b8d75a8e9 [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
71unsigned int Renderbuffer::getSerial() const
72{
73 return mStorage->getSerial();
74}
75
76void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
77{
78 ASSERT(newStorage != NULL);
79
80 delete mStorage;
81 mStorage = newStorage;
82}
83
84RenderbufferStorage::RenderbufferStorage()
85{
86 mSerial = issueSerial();
87}
88
89RenderbufferStorage::~RenderbufferStorage()
90{
91}
92
93bool RenderbufferStorage::isColorbuffer() const
94{
95 return false;
96}
97
98bool RenderbufferStorage::isDepthbuffer() const
99{
100 return false;
101}
102
103bool RenderbufferStorage::isStencilbuffer() const
104{
105 return false;
106}
107
108IDirect3DSurface9 *RenderbufferStorage::getRenderTarget()
109{
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000110 return NULL;
111}
112
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000113IDirect3DSurface9 *RenderbufferStorage::getDepthStencil()
114{
115 return NULL;
116}
117
118int RenderbufferStorage::getWidth() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000119{
120 return mWidth;
121}
122
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000123int RenderbufferStorage::getHeight() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000124{
125 return mHeight;
126}
127
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000128void RenderbufferStorage::setSize(int width, int height)
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000129{
130 mWidth = width;
131 mHeight = height;
132}
133
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000134GLenum RenderbufferStorage::getFormat() const
daniel@transgaming.com4901fca2010-04-20 18:52:41 +0000135{
136 return mFormat;
137}
138
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000139unsigned int RenderbufferStorage::getSerial() const
daniel@transgaming.com092bd482010-05-12 03:39:36 +0000140{
141 return mSerial;
142}
143
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000144unsigned int RenderbufferStorage::issueSerial()
daniel@transgaming.com092bd482010-05-12 03:39:36 +0000145{
146 return mCurrentSerial++;
147}
148
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000149Colorbuffer::Colorbuffer(IDirect3DSurface9 *renderTarget) : mRenderTarget(renderTarget)
150{
151 if (renderTarget)
152 {
153 renderTarget->AddRef();
154
155 D3DSURFACE_DESC description;
156 renderTarget->GetDesc(&description);
157
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000158 setSize(description.Width, description.Height);
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000159 mD3DFormat = description.Format;
160 }
161 else
162 {
163 mD3DFormat = D3DFMT_UNKNOWN;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000164 }
daniel@transgaming.com092bd482010-05-12 03:39:36 +0000165
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000166}
167
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000168Colorbuffer::Colorbuffer(int width, int height, GLenum format)
169{
170 IDirect3DDevice9 *device = getDevice();
171
172 mRenderTarget = NULL;
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000173 D3DFORMAT requestedFormat = es2dx::ConvertRenderbufferFormat(format);
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000174
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000175 if (width > 0 && height > 0)
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000176 {
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000177 HRESULT result = device->CreateRenderTarget(width, height, requestedFormat,
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000178 D3DMULTISAMPLE_NONE, 0, FALSE, &mRenderTarget, NULL);
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000179
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000180 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
181 {
182 error(GL_OUT_OF_MEMORY);
183
184 return;
185 }
186
187 ASSERT(SUCCEEDED(result));
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000188 }
189
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000190 if (mRenderTarget)
191 {
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000192 setSize(width, height);
daniel@transgaming.com4901fca2010-04-20 18:52:41 +0000193 mFormat = format;
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000194 mD3DFormat = requestedFormat;
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000195 }
196 else
197 {
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000198 setSize(0, 0);
daniel@transgaming.com4901fca2010-04-20 18:52:41 +0000199 mFormat = GL_RGBA4;
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000200 mD3DFormat = D3DFMT_UNKNOWN;
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000201 }
202}
203
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000204Colorbuffer::~Colorbuffer()
205{
206 if (mRenderTarget)
207 {
208 mRenderTarget->Release();
209 }
210}
211
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000212bool Colorbuffer::isColorbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000213{
214 return true;
215}
216
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000217GLuint Colorbuffer::getRedSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000218{
219 if (mRenderTarget)
220 {
221 D3DSURFACE_DESC description;
222 mRenderTarget->GetDesc(&description);
223
224 return es2dx::GetRedSize(description.Format);
225 }
226
227 return 0;
228}
229
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000230GLuint Colorbuffer::getGreenSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000231{
232 if (mRenderTarget)
233 {
234 D3DSURFACE_DESC description;
235 mRenderTarget->GetDesc(&description);
236
237 return es2dx::GetGreenSize(description.Format);
238 }
239
240 return 0;
241}
242
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000243GLuint Colorbuffer::getBlueSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000244{
245 if (mRenderTarget)
246 {
247 D3DSURFACE_DESC description;
248 mRenderTarget->GetDesc(&description);
249
250 return es2dx::GetBlueSize(description.Format);
251 }
252
253 return 0;
254}
255
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000256GLuint Colorbuffer::getAlphaSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000257{
258 if (mRenderTarget)
259 {
260 D3DSURFACE_DESC description;
261 mRenderTarget->GetDesc(&description);
262
263 return es2dx::GetAlphaSize(description.Format);
264 }
265
266 return 0;
267}
268
269IDirect3DSurface9 *Colorbuffer::getRenderTarget()
270{
271 return mRenderTarget;
272}
273
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000274DepthStencilbuffer::DepthStencilbuffer(IDirect3DSurface9 *depthStencil) : mDepthStencil(depthStencil)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000275{
276 if (depthStencil)
277 {
278 depthStencil->AddRef();
279
280 D3DSURFACE_DESC description;
281 depthStencil->GetDesc(&description);
282
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000283 setSize(description.Width, description.Height);
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000284 mFormat = (description.Format == D3DFMT_D16 ? GL_DEPTH_COMPONENT16 : GL_DEPTH24_STENCIL8_OES);
285 mD3DFormat = description.Format;
286 }
287 else
288 {
289 mD3DFormat = D3DFMT_UNKNOWN;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000290 }
291}
292
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000293DepthStencilbuffer::DepthStencilbuffer(int width, int height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000294{
295 IDirect3DDevice9 *device = getDevice();
296
297 mDepthStencil = NULL;
298 HRESULT result = device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, 0);
299
300 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
301 {
302 error(GL_OUT_OF_MEMORY);
303
304 return;
305 }
306
307 ASSERT(SUCCEEDED(result));
308
309 if (mDepthStencil)
310 {
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000311 setSize(width, height);
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000312 mFormat = GL_DEPTH24_STENCIL8_OES;
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000313 mD3DFormat = D3DFMT_D24S8;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000314 }
315 else
316 {
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000317 setSize(0, 0);
daniel@transgaming.com4901fca2010-04-20 18:52:41 +0000318 mFormat = GL_RGBA4; //default format
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000319 mD3DFormat = D3DFMT_UNKNOWN;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000320 }
321}
322
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000323DepthStencilbuffer::~DepthStencilbuffer()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000324{
325 if (mDepthStencil)
326 {
327 mDepthStencil->Release();
328 }
329}
330
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000331bool DepthStencilbuffer::isDepthbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000332{
333 return true;
334}
335
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000336bool DepthStencilbuffer::isStencilbuffer() const
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000337{
338 return true;
339}
340
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000341GLuint DepthStencilbuffer::getDepthSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000342{
343 if (mDepthStencil)
344 {
345 D3DSURFACE_DESC description;
346 mDepthStencil->GetDesc(&description);
347
daniel@transgaming.com7a2c2802010-03-16 06:23:33 +0000348 return es2dx::GetDepthSize(description.Format);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000349 }
350
351 return 0;
352}
353
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000354GLuint DepthStencilbuffer::getStencilSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000355{
356 if (mDepthStencil)
357 {
358 D3DSURFACE_DESC description;
359 mDepthStencil->GetDesc(&description);
360
361 return es2dx::GetStencilSize(description.Format);
362 }
363
364 return 0;
365}
366
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000367IDirect3DSurface9 *DepthStencilbuffer::getDepthStencil()
368{
369 return mDepthStencil;
370}
371
372Depthbuffer::Depthbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil)
373{
374 if (depthStencil)
375 {
376 mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
377 // will expect one of the valid renderbuffer formats for use in
378 // glRenderbufferStorage
379 }
380}
381
382Depthbuffer::Depthbuffer(int width, int height) : DepthStencilbuffer(width, height)
383{
384 if (getDepthStencil())
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()
393{
394}
395
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000396bool Depthbuffer::isDepthbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000397{
398 return true;
399}
400
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000401bool Depthbuffer::isStencilbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000402{
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000403 return false;
404}
405
406Stencilbuffer::Stencilbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil)
407{
408 if (depthStencil)
409 {
410 mFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
411 // will expect one of the valid renderbuffer formats for use in
412 // glRenderbufferStorage
413 }
414 else
415 {
416 mFormat = GL_RGBA4; //default format
417 }
418}
419
420Stencilbuffer::Stencilbuffer(int width, int height) : DepthStencilbuffer(width, height)
421{
422 if (getDepthStencil())
423 {
424 mFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
425 // will expect one of the valid renderbuffer formats for use in
426 // glRenderbufferStorage
427 }
428}
429
430Stencilbuffer::~Stencilbuffer()
431{
432}
433
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000434bool Stencilbuffer::isDepthbuffer() const
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000435{
436 return false;
437}
438
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000439bool Stencilbuffer::isStencilbuffer() const
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000440{
441 return true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000442}
443}