blob: 81cff87e8e088054a1f43bd41091bb0edf9ecb89 [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.com4f39fd92010-03-08 20:26:45 +0000159 }
daniel@transgaming.com092bd482010-05-12 03:39:36 +0000160
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000161}
162
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000163Colorbuffer::Colorbuffer(int width, int height, GLenum format)
164{
165 IDirect3DDevice9 *device = getDevice();
166
167 mRenderTarget = NULL;
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000168
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000169 if (width > 0 && height > 0)
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000170 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000171 HRESULT result = device->CreateRenderTarget(width, height, es2dx::ConvertRenderbufferFormat(format),
172 D3DMULTISAMPLE_NONE, 0, FALSE, &mRenderTarget, NULL);
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000173
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000174 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
175 {
176 error(GL_OUT_OF_MEMORY);
177
178 return;
179 }
180
181 ASSERT(SUCCEEDED(result));
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000182 }
183
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000184 if (mRenderTarget)
185 {
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000186 setSize(width, height);
daniel@transgaming.com4901fca2010-04-20 18:52:41 +0000187 mFormat = format;
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000188 }
189 else
190 {
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000191 setSize(0, 0);
daniel@transgaming.com4901fca2010-04-20 18:52:41 +0000192 mFormat = GL_RGBA4;
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000193 }
194}
195
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000196Colorbuffer::~Colorbuffer()
197{
198 if (mRenderTarget)
199 {
200 mRenderTarget->Release();
201 }
202}
203
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000204bool Colorbuffer::isColorbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000205{
206 return true;
207}
208
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000209GLuint Colorbuffer::getRedSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000210{
211 if (mRenderTarget)
212 {
213 D3DSURFACE_DESC description;
214 mRenderTarget->GetDesc(&description);
215
216 return es2dx::GetRedSize(description.Format);
217 }
218
219 return 0;
220}
221
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000222GLuint Colorbuffer::getGreenSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000223{
224 if (mRenderTarget)
225 {
226 D3DSURFACE_DESC description;
227 mRenderTarget->GetDesc(&description);
228
229 return es2dx::GetGreenSize(description.Format);
230 }
231
232 return 0;
233}
234
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000235GLuint Colorbuffer::getBlueSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000236{
237 if (mRenderTarget)
238 {
239 D3DSURFACE_DESC description;
240 mRenderTarget->GetDesc(&description);
241
242 return es2dx::GetBlueSize(description.Format);
243 }
244
245 return 0;
246}
247
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000248GLuint Colorbuffer::getAlphaSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000249{
250 if (mRenderTarget)
251 {
252 D3DSURFACE_DESC description;
253 mRenderTarget->GetDesc(&description);
254
255 return es2dx::GetAlphaSize(description.Format);
256 }
257
258 return 0;
259}
260
261IDirect3DSurface9 *Colorbuffer::getRenderTarget()
262{
263 return mRenderTarget;
264}
265
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000266DepthStencilbuffer::DepthStencilbuffer(IDirect3DSurface9 *depthStencil) : mDepthStencil(depthStencil)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000267{
268 if (depthStencil)
269 {
270 depthStencil->AddRef();
271
272 D3DSURFACE_DESC description;
273 depthStencil->GetDesc(&description);
274
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000275 setSize(description.Width, description.Height);
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000276 mFormat = GL_DEPTH24_STENCIL8_OES;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000277 }
278}
279
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000280DepthStencilbuffer::DepthStencilbuffer(int width, int height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000281{
282 IDirect3DDevice9 *device = getDevice();
283
284 mDepthStencil = NULL;
285 HRESULT result = device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, 0);
286
287 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
288 {
289 error(GL_OUT_OF_MEMORY);
290
291 return;
292 }
293
294 ASSERT(SUCCEEDED(result));
295
296 if (mDepthStencil)
297 {
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000298 setSize(width, height);
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000299 mFormat = GL_DEPTH24_STENCIL8_OES;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000300 }
301 else
302 {
daniel@transgaming.com866f3182010-05-20 19:28:22 +0000303 setSize(0, 0);
daniel@transgaming.com4901fca2010-04-20 18:52:41 +0000304 mFormat = GL_RGBA4; //default format
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000305 }
306}
307
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000308DepthStencilbuffer::~DepthStencilbuffer()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000309{
310 if (mDepthStencil)
311 {
312 mDepthStencil->Release();
313 }
314}
315
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000316bool DepthStencilbuffer::isDepthbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000317{
318 return true;
319}
320
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000321bool DepthStencilbuffer::isStencilbuffer() const
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000322{
323 return true;
324}
325
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000326GLuint DepthStencilbuffer::getDepthSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000327{
328 if (mDepthStencil)
329 {
330 D3DSURFACE_DESC description;
331 mDepthStencil->GetDesc(&description);
332
daniel@transgaming.com7a2c2802010-03-16 06:23:33 +0000333 return es2dx::GetDepthSize(description.Format);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000334 }
335
336 return 0;
337}
338
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000339GLuint DepthStencilbuffer::getStencilSize() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000340{
341 if (mDepthStencil)
342 {
343 D3DSURFACE_DESC description;
344 mDepthStencil->GetDesc(&description);
345
346 return es2dx::GetStencilSize(description.Format);
347 }
348
349 return 0;
350}
351
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000352IDirect3DSurface9 *DepthStencilbuffer::getDepthStencil()
353{
354 return mDepthStencil;
355}
356
357Depthbuffer::Depthbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil)
358{
359 if (depthStencil)
360 {
361 mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
362 // will expect one of the valid renderbuffer formats for use in
363 // glRenderbufferStorage
364 }
365}
366
367Depthbuffer::Depthbuffer(int width, int height) : DepthStencilbuffer(width, height)
368{
369 if (getDepthStencil())
370 {
371 mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
372 // will expect one of the valid renderbuffer formats for use in
373 // glRenderbufferStorage
374 }
375}
376
377Depthbuffer::~Depthbuffer()
378{
379}
380
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000381bool Depthbuffer::isDepthbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000382{
383 return true;
384}
385
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000386bool Depthbuffer::isStencilbuffer() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000387{
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000388 return false;
389}
390
391Stencilbuffer::Stencilbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil)
392{
393 if (depthStencil)
394 {
395 mFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
396 // will expect one of the valid renderbuffer formats for use in
397 // glRenderbufferStorage
398 }
399 else
400 {
401 mFormat = GL_RGBA4; //default format
402 }
403}
404
405Stencilbuffer::Stencilbuffer(int width, int height) : DepthStencilbuffer(width, height)
406{
407 if (getDepthStencil())
408 {
409 mFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
410 // will expect one of the valid renderbuffer formats for use in
411 // glRenderbufferStorage
412 }
413}
414
415Stencilbuffer::~Stencilbuffer()
416{
417}
418
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000419bool Stencilbuffer::isDepthbuffer() const
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000420{
421 return false;
422}
423
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000424bool Stencilbuffer::isStencilbuffer() const
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000425{
426 return true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000427}
428}