OSDN Git Service

Adding Texture3D support.
[android-x86/external-swiftshader.git] / src / OpenGL / libGLES_CM / Renderbuffer.cpp
1 // SwiftShader Software Renderer
2 //
3 // Copyright(c) 2005-2013 TransGaming Inc.
4 //
5 // All rights reserved. No part of this software may be copied, distributed, transmitted,
6 // transcribed, stored in a retrieval system, translated into any human or computer
7 // language by any means, or disclosed to third parties without the explicit written
8 // agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
9 // or implied, including but not limited to any patent rights, are granted to you.
10 //
11
12 // Renderbuffer.cpp: the Renderbuffer class and its derived classes
13 // Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
14 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
15
16 #include "Renderbuffer.h"
17
18 #include "main.h"
19 #include "Texture.h"
20 #include "utilities.h"
21
22 namespace es1
23 {
24 RenderbufferInterface::RenderbufferInterface()
25 {
26 }
27
28 // The default case for classes inherited from RenderbufferInterface is not to
29 // need to do anything upon the reference count to the parent Renderbuffer incrementing
30 // or decrementing. 
31 void RenderbufferInterface::addProxyRef(const Renderbuffer *proxy)
32 {
33 }
34
35 void RenderbufferInterface::releaseProxy(const Renderbuffer *proxy)
36 {
37 }
38
39 GLuint RenderbufferInterface::getRedSize() const
40 {
41         return sw2es::GetRedSize(getInternalFormat());
42 }
43
44 GLuint RenderbufferInterface::getGreenSize() const
45 {
46         return sw2es::GetGreenSize(getInternalFormat());
47 }
48
49 GLuint RenderbufferInterface::getBlueSize() const
50 {
51         return sw2es::GetBlueSize(getInternalFormat());
52 }
53
54 GLuint RenderbufferInterface::getAlphaSize() const
55 {
56         return sw2es::GetAlphaSize(getInternalFormat());
57 }
58
59 GLuint RenderbufferInterface::getDepthSize() const
60 {
61         return sw2es::GetDepthSize(getInternalFormat());
62 }
63
64 GLuint RenderbufferInterface::getStencilSize() const
65 {
66         return sw2es::GetStencilSize(getInternalFormat());
67 }
68
69 ///// RenderbufferTexture2D Implementation ////////
70
71 RenderbufferTexture2D::RenderbufferTexture2D(Texture2D *texture)
72 {
73         mTexture2D.set(texture);
74 }
75
76 RenderbufferTexture2D::~RenderbufferTexture2D()
77 {
78         mTexture2D.set(NULL);
79 }
80
81 // Textures need to maintain their own reference count for references via
82 // Renderbuffers acting as proxies. Here, we notify the texture of a reference.
83 void RenderbufferTexture2D::addProxyRef(const Renderbuffer *proxy)
84 {
85     mTexture2D->addProxyRef(proxy);
86 }
87
88 void RenderbufferTexture2D::releaseProxy(const Renderbuffer *proxy)
89 {
90     mTexture2D->releaseProxy(proxy);
91 }
92
93 // Increments refcount on image.
94 // caller must release() the returned image
95 egl::Image *RenderbufferTexture2D::getRenderTarget()
96 {
97         return mTexture2D->getRenderTarget(GL_TEXTURE_2D, 0);
98 }
99
100 // Increments refcount on image.
101 // caller must release() the returned image
102 egl::Image *RenderbufferTexture2D::createSharedImage()
103 {
104     return mTexture2D->createSharedImage(GL_TEXTURE_2D, 0);
105 }
106
107 bool RenderbufferTexture2D::isShared() const
108 {
109     return mTexture2D->isShared(GL_TEXTURE_2D, 0);
110 }
111
112 GLsizei RenderbufferTexture2D::getWidth() const
113 {
114         return mTexture2D->getWidth(GL_TEXTURE_2D, 0);
115 }
116
117 GLsizei RenderbufferTexture2D::getHeight() const
118 {
119         return mTexture2D->getHeight(GL_TEXTURE_2D, 0);
120 }
121
122 GLenum RenderbufferTexture2D::getFormat() const
123 {
124         return mTexture2D->getFormat(GL_TEXTURE_2D, 0);
125 }
126
127 sw::Format RenderbufferTexture2D::getInternalFormat() const
128 {
129         return mTexture2D->getInternalFormat(GL_TEXTURE_2D, 0);
130 }
131
132 GLsizei RenderbufferTexture2D::getSamples() const
133 {
134         return 0;
135 }
136
137 ////// Renderbuffer Implementation //////
138
139 Renderbuffer::Renderbuffer(GLuint id, RenderbufferInterface *instance) : RefCountObject(id)
140 {
141         ASSERT(instance != NULL);
142         mInstance = instance;
143 }
144
145 Renderbuffer::~Renderbuffer()
146 {
147         delete mInstance;
148 }
149
150 // The RenderbufferInterface contained in this Renderbuffer may need to maintain
151 // its own reference count, so we pass it on here.
152 void Renderbuffer::addRef()
153 {
154     mInstance->addProxyRef(this);
155
156     RefCountObject::addRef();
157 }
158
159 void Renderbuffer::release()
160 {
161     mInstance->releaseProxy(this);
162
163     RefCountObject::release();
164 }
165
166 // Increments refcount on image.
167 // caller must Release() the returned image
168 egl::Image *Renderbuffer::getRenderTarget()
169 {
170         return mInstance->getRenderTarget();
171 }
172
173 // Increments refcount on image.
174 // caller must Release() the returned image
175 egl::Image *Renderbuffer::createSharedImage()
176 {
177     return mInstance->createSharedImage();
178 }
179
180 bool Renderbuffer::isShared() const
181 {
182     return mInstance->isShared();
183 }
184
185 GLsizei Renderbuffer::getWidth() const
186 {
187         return mInstance->getWidth();
188 }
189
190 GLsizei Renderbuffer::getHeight() const
191 {
192         return mInstance->getHeight();
193 }
194
195 GLenum Renderbuffer::getFormat() const
196 {
197         return mInstance->getFormat();
198 }
199
200 sw::Format Renderbuffer::getInternalFormat() const
201 {
202         return mInstance->getInternalFormat();
203 }
204
205 GLuint Renderbuffer::getRedSize() const
206 {
207         return mInstance->getRedSize();
208 }
209
210 GLuint Renderbuffer::getGreenSize() const
211 {
212         return mInstance->getGreenSize();
213 }
214
215 GLuint Renderbuffer::getBlueSize() const
216 {
217         return mInstance->getBlueSize();
218 }
219
220 GLuint Renderbuffer::getAlphaSize() const
221 {
222         return mInstance->getAlphaSize();
223 }
224
225 GLuint Renderbuffer::getDepthSize() const
226 {
227         return mInstance->getDepthSize();
228 }
229
230 GLuint Renderbuffer::getStencilSize() const
231 {
232         return mInstance->getStencilSize();
233 }
234
235 GLsizei Renderbuffer::getSamples() const
236 {
237         return mInstance->getSamples();
238 }
239
240 void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
241 {
242         ASSERT(newStorage != NULL);
243
244         delete mInstance;
245         mInstance = newStorage;
246 }
247
248 RenderbufferStorage::RenderbufferStorage()
249 {
250         mWidth = 0;
251         mHeight = 0;
252         format = GL_RGBA4_OES;
253         internalFormat = sw::FORMAT_A8R8G8B8;
254         mSamples = 0;
255 }
256
257 RenderbufferStorage::~RenderbufferStorage()
258 {
259 }
260
261 GLsizei RenderbufferStorage::getWidth() const
262 {
263         return mWidth;
264 }
265
266 GLsizei RenderbufferStorage::getHeight() const
267 {
268         return mHeight;
269 }
270
271 GLenum RenderbufferStorage::getFormat() const
272 {
273         return format;
274 }
275
276 sw::Format RenderbufferStorage::getInternalFormat() const
277 {
278         return internalFormat;
279 }
280
281 GLsizei RenderbufferStorage::getSamples() const
282 {
283         return mSamples;
284 }
285
286 Colorbuffer::Colorbuffer(egl::Image *renderTarget) : mRenderTarget(renderTarget)
287 {
288         if(renderTarget)
289         {
290                 renderTarget->addRef();
291                 
292                 mWidth = renderTarget->getWidth();
293                 mHeight = renderTarget->getHeight();
294                 internalFormat = renderTarget->getInternalFormat();
295                 format = sw2es::ConvertBackBufferFormat(internalFormat);
296                 mSamples = renderTarget->getDepth() & ~1;
297         }
298 }
299
300 Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) : mRenderTarget(NULL)
301 {
302         Device *device = getDevice();
303
304         sw::Format requestedFormat = es2sw::ConvertRenderbufferFormat(format);
305         int supportedSamples = Context::getSupportedMultiSampleDepth(requestedFormat, samples);
306
307         if(width > 0 && height > 0)
308         {
309                 mRenderTarget = device->createRenderTarget(width, height, requestedFormat, supportedSamples, false);
310
311                 if(!mRenderTarget)
312                 {
313                         error(GL_OUT_OF_MEMORY);
314                         return;
315                 }
316         }
317
318         mWidth = width;
319         mHeight = height;
320         this->format = format;
321         internalFormat = requestedFormat;
322         mSamples = supportedSamples & ~1;
323 }
324
325 Colorbuffer::~Colorbuffer()
326 {
327         if(mRenderTarget)
328         {
329                 mRenderTarget->release();
330         }
331 }
332
333 // Increments refcount on image.
334 // caller must release() the returned image
335 egl::Image *Colorbuffer::getRenderTarget()
336 {
337         if(mRenderTarget)
338         {
339                 mRenderTarget->addRef();
340         }
341
342         return mRenderTarget;
343 }
344
345 // Increments refcount on image.
346 // caller must release() the returned image
347 egl::Image *Colorbuffer::createSharedImage()
348 {
349     if(mRenderTarget)
350     {
351         mRenderTarget->addRef();
352         mRenderTarget->markShared();
353     }
354
355     return mRenderTarget;
356 }
357
358 bool Colorbuffer::isShared() const
359 {
360     return mRenderTarget->isShared();
361 }
362
363 DepthStencilbuffer::DepthStencilbuffer(egl::Image *depthStencil) : mDepthStencil(depthStencil)
364 {
365         if(depthStencil)
366         {
367                 depthStencil->addRef();
368
369                 mWidth = depthStencil->getWidth();
370                 mHeight = depthStencil->getHeight();
371                 internalFormat = depthStencil->getInternalFormat();
372                 format = sw2es::ConvertDepthStencilFormat(internalFormat);
373                 mSamples = depthStencil->getDepth() & ~1;
374         }
375 }
376
377 DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples)
378 {
379         Device *device = getDevice();
380
381         mDepthStencil = NULL;
382         
383         int supportedSamples = Context::getSupportedMultiSampleDepth(sw::FORMAT_D24S8, samples);
384
385         if(width > 0 && height > 0)
386         {
387                 mDepthStencil = device->createDepthStencilSurface(width, height, sw::FORMAT_D24S8, supportedSamples, false);
388
389                 if(!mDepthStencil)
390                 {
391                         error(GL_OUT_OF_MEMORY);
392                         return;
393                 }
394         }
395
396         mWidth = width;
397         mHeight = height;
398         format = GL_DEPTH24_STENCIL8_OES;
399         internalFormat = sw::FORMAT_D24S8;
400         mSamples = supportedSamples & ~1;
401 }
402
403 DepthStencilbuffer::~DepthStencilbuffer()
404 {
405         if(mDepthStencil)
406         {
407                 mDepthStencil->release();
408         }
409 }
410
411 // Increments refcount on image.
412 // caller must release() the returned image
413 egl::Image *DepthStencilbuffer::getRenderTarget()
414 {
415         if(mDepthStencil)
416         {
417                 mDepthStencil->addRef();
418         }
419
420         return mDepthStencil;
421 }
422
423 // Increments refcount on image.
424 // caller must release() the returned image
425 egl::Image *DepthStencilbuffer::createSharedImage()
426 {
427     if(mDepthStencil)
428     {
429         mDepthStencil->addRef();
430         mDepthStencil->markShared();
431     }
432
433     return mDepthStencil;
434 }
435
436 bool DepthStencilbuffer::isShared() const
437 {
438     return mDepthStencil->isShared();
439 }
440
441 Depthbuffer::Depthbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
442 {
443         if(depthStencil)
444         {
445                 format = GL_DEPTH_COMPONENT16_OES;   // 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 }
450
451 Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
452 {
453         if(mDepthStencil)
454         {
455                 format = GL_DEPTH_COMPONENT16_OES;   // If the renderbuffer parameters are queried, the calling function
456                                                      // will expect one of the valid renderbuffer formats for use in 
457                                                      // glRenderbufferStorage
458         }
459 }
460
461 Depthbuffer::~Depthbuffer()
462 {
463 }
464
465 Stencilbuffer::Stencilbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
466 {
467         if(depthStencil)
468         {
469                 format = GL_STENCIL_INDEX8_OES;   // If the renderbuffer parameters are queried, the calling function
470                                                   // will expect one of the valid renderbuffer formats for use in 
471                                                   // glRenderbufferStorage
472         }
473 }
474
475 Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
476 {
477         if(mDepthStencil)
478         {
479                 format = GL_STENCIL_INDEX8_OES;   // If the renderbuffer parameters are queried, the calling function
480                                                   // will expect one of the valid renderbuffer formats for use in 
481                                                   // glRenderbufferStorage
482         }
483 }
484
485 Stencilbuffer::~Stencilbuffer()
486 {
487 }
488
489 }