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
Renderbuffer(GLuint id,RenderbufferStorage * storage)21 Renderbuffer::Renderbuffer(GLuint id, RenderbufferStorage *storage) : RefCountObject(id)
22 {
23 ASSERT(storage != NULL);
24 mStorage = storage;
25 }
26
~Renderbuffer()27 Renderbuffer::~Renderbuffer()
28 {
29 delete mStorage;
30 }
31
isColorbuffer() const32 bool Renderbuffer::isColorbuffer() const
33 {
34 return mStorage->isColorbuffer();
35 }
36
isDepthbuffer() const37 bool Renderbuffer::isDepthbuffer() const
38 {
39 return mStorage->isDepthbuffer();
40 }
41
isStencilbuffer() const42 bool Renderbuffer::isStencilbuffer() const
43 {
44 return mStorage->isStencilbuffer();
45 }
46
getRenderTarget()47 IDirect3DSurface9 *Renderbuffer::getRenderTarget()
48 {
49 return mStorage->getRenderTarget();
50 }
51
getDepthStencil()52 IDirect3DSurface9 *Renderbuffer::getDepthStencil()
53 {
54 return mStorage->getDepthStencil();
55 }
56
getWidth() const57 int Renderbuffer::getWidth() const
58 {
59 return mStorage->getWidth();
60 }
61
getHeight() const62 int Renderbuffer::getHeight() const
63 {
64 return mStorage->getHeight();
65 }
66
getFormat() const67 GLenum Renderbuffer::getFormat() const
68 {
69 return mStorage->getFormat();
70 }
71
getD3DFormat() const72 D3DFORMAT Renderbuffer::getD3DFormat() const
73 {
74 return mStorage->getD3DFormat();
75 }
76
getSerial() const77 unsigned int Renderbuffer::getSerial() const
78 {
79 return mStorage->getSerial();
80 }
81
setStorage(RenderbufferStorage * newStorage)82 void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
83 {
84 ASSERT(newStorage != NULL);
85
86 delete mStorage;
87 mStorage = newStorage;
88 }
89
RenderbufferStorage()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
~RenderbufferStorage()99 RenderbufferStorage::~RenderbufferStorage()
100 {
101 }
102
isColorbuffer() const103 bool RenderbufferStorage::isColorbuffer() const
104 {
105 return false;
106 }
107
isDepthbuffer() const108 bool RenderbufferStorage::isDepthbuffer() const
109 {
110 return false;
111 }
112
isStencilbuffer() const113 bool RenderbufferStorage::isStencilbuffer() const
114 {
115 return false;
116 }
117
getRenderTarget()118 IDirect3DSurface9 *RenderbufferStorage::getRenderTarget()
119 {
120 return NULL;
121 }
122
getDepthStencil()123 IDirect3DSurface9 *RenderbufferStorage::getDepthStencil()
124 {
125 return NULL;
126 }
127
getWidth() const128 int RenderbufferStorage::getWidth() const
129 {
130 return mWidth;
131 }
132
getHeight() const133 int RenderbufferStorage::getHeight() const
134 {
135 return mHeight;
136 }
137
setSize(int width,int height)138 void RenderbufferStorage::setSize(int width, int height)
139 {
140 mWidth = width;
141 mHeight = height;
142 }
143
getFormat() const144 GLenum RenderbufferStorage::getFormat() const
145 {
146 return mFormat;
147 }
148
isFloatingPoint() const149 bool RenderbufferStorage::isFloatingPoint() const
150 {
151 return false; // no floating point renderbuffers
152 }
153
getD3DFormat() const154 D3DFORMAT RenderbufferStorage::getD3DFormat() const
155 {
156 return mD3DFormat;
157 }
158
getSamples() const159 GLsizei RenderbufferStorage::getSamples() const
160 {
161 return mSamples;
162 }
163
getSerial() const164 unsigned int RenderbufferStorage::getSerial() const
165 {
166 return mSerial;
167 }
168
issueSerial()169 unsigned int RenderbufferStorage::issueSerial()
170 {
171 return mCurrentSerial++;
172 }
173
Colorbuffer(IDirect3DSurface9 * renderTarget)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
Colorbuffer(const Texture * texture)190 Colorbuffer::Colorbuffer(const Texture* texture) : mRenderTarget(NULL)
191 {
192 setSize(texture->getWidth(), texture->getHeight());
193 mD3DFormat = texture->getD3DFormat();
194 mSamples = 0;
195 }
196
Colorbuffer(int width,int height,GLenum format,GLsizei samples)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
~Colorbuffer()236 Colorbuffer::~Colorbuffer()
237 {
238 if (mRenderTarget)
239 {
240 mRenderTarget->Release();
241 }
242 }
243
isColorbuffer() const244 bool Colorbuffer::isColorbuffer() const
245 {
246 return true;
247 }
248
getRedSize() const249 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
getGreenSize() const262 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
getBlueSize() const275 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
getAlphaSize() const288 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
getRenderTarget()301 IDirect3DSurface9 *Colorbuffer::getRenderTarget()
302 {
303 return mRenderTarget;
304 }
305
DepthStencilbuffer(IDirect3DSurface9 * depthStencil)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
DepthStencilbuffer(int width,int height,GLsizei samples)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
~DepthStencilbuffer()358 DepthStencilbuffer::~DepthStencilbuffer()
359 {
360 if (mDepthStencil)
361 {
362 mDepthStencil->Release();
363 }
364 }
365
isDepthbuffer() const366 bool DepthStencilbuffer::isDepthbuffer() const
367 {
368 return true;
369 }
370
isStencilbuffer() const371 bool DepthStencilbuffer::isStencilbuffer() const
372 {
373 return true;
374 }
375
getDepthSize() const376 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
getStencilSize() const389 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
getDepthStencil()402 IDirect3DSurface9 *DepthStencilbuffer::getDepthStencil()
403 {
404 return mDepthStencil;
405 }
406
Depthbuffer(IDirect3DSurface9 * depthStencil)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
Depthbuffer(int width,int height,GLsizei samples)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
~Depthbuffer()427 Depthbuffer::~Depthbuffer()
428 {
429 }
430
isDepthbuffer() const431 bool Depthbuffer::isDepthbuffer() const
432 {
433 return true;
434 }
435
isStencilbuffer() const436 bool Depthbuffer::isStencilbuffer() const
437 {
438 return false;
439 }
440
Stencilbuffer(IDirect3DSurface9 * depthStencil)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
Stencilbuffer(int width,int height,GLsizei samples)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
~Stencilbuffer()465 Stencilbuffer::~Stencilbuffer()
466 {
467 }
468
isDepthbuffer() const469 bool Stencilbuffer::isDepthbuffer() const
470 {
471 return false;
472 }
473
isStencilbuffer() const474 bool Stencilbuffer::isStencilbuffer() const
475 {
476 return true;
477 }
478 }
479