OSDN Git Service

06c023d51c034f5e4fa5e50c9ab01858ae77b285
[android-x86/external-swiftshader.git] / src / Radiance / libRAD / 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 rad
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 sw2rad::GetRedSize(getInternalFormat());
42 }
43
44 GLuint RenderbufferInterface::getGreenSize() const
45 {
46         return sw2rad::GetGreenSize(getInternalFormat());
47 }
48
49 GLuint RenderbufferInterface::getBlueSize() const
50 {
51         return sw2rad::GetBlueSize(getInternalFormat());
52 }
53
54 GLuint RenderbufferInterface::getAlphaSize() const
55 {
56         return sw2rad::GetAlphaSize(getInternalFormat());
57 }
58
59 GLuint RenderbufferInterface::getDepthSize() const
60 {
61         return sw2rad::GetDepthSize(getInternalFormat());
62 }
63
64 GLuint RenderbufferInterface::getStencilSize() const
65 {
66         return sw2rad::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 ///// RenderbufferTextureCubeMap Implementation ////////
138
139 RenderbufferTextureCubeMap::RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target) : mTarget(target)
140 {
141         mTextureCubeMap.set(texture);
142 }
143
144 RenderbufferTextureCubeMap::~RenderbufferTextureCubeMap()
145 {
146         mTextureCubeMap.set(NULL);
147 }
148
149 // Textures need to maintain their own reference count for references via
150 // Renderbuffers acting as proxies. Here, we notify the texture of a reference.
151 void RenderbufferTextureCubeMap::addProxyRef(const Renderbuffer *proxy)
152 {
153     mTextureCubeMap->addProxyRef(proxy);
154 }
155
156 void RenderbufferTextureCubeMap::releaseProxy(const Renderbuffer *proxy)
157 {
158     mTextureCubeMap->releaseProxy(proxy);
159 }
160
161 // Increments refcount on image.
162 // caller must release() the returned image
163 Image *RenderbufferTextureCubeMap::getRenderTarget()
164 {
165         return mTextureCubeMap->getRenderTarget(mTarget, 0);
166 }
167
168 // Increments refcount on image.
169 // caller must release() the returned image
170 egl::Image *RenderbufferTextureCubeMap::createSharedImage()
171 {
172     return mTextureCubeMap->createSharedImage(mTarget, 0);
173 }
174
175 bool RenderbufferTextureCubeMap::isShared() const
176 {
177     return mTextureCubeMap->isShared(mTarget, 0);
178 }
179
180 GLsizei RenderbufferTextureCubeMap::getWidth() const
181 {
182         return mTextureCubeMap->getWidth(mTarget, 0);
183 }
184
185 GLsizei RenderbufferTextureCubeMap::getHeight() const
186 {
187         return mTextureCubeMap->getHeight(mTarget, 0);
188 }
189
190 GLenum RenderbufferTextureCubeMap::getFormat() const
191 {
192         return mTextureCubeMap->getFormat(mTarget, 0);
193 }
194
195 sw::Format RenderbufferTextureCubeMap::getInternalFormat() const
196 {
197         return mTextureCubeMap->getInternalFormat(mTarget, 0);
198 }
199
200 GLsizei RenderbufferTextureCubeMap::getSamples() const
201 {
202         return 0;
203 }
204
205 ////// Renderbuffer Implementation //////
206
207 Renderbuffer::Renderbuffer(GLuint id, RenderbufferInterface *instance) : RefCountObject(id)
208 {
209         ASSERT(instance != NULL);
210         mInstance = instance;
211 }
212
213 Renderbuffer::~Renderbuffer()
214 {
215         delete mInstance;
216 }
217
218 // The RenderbufferInterface contained in this Renderbuffer may need to maintain
219 // its own reference count, so we pass it on here.
220 void Renderbuffer::addRef()
221 {
222     mInstance->addProxyRef(this);
223
224     RefCountObject::addRef();
225 }
226
227 void Renderbuffer::release()
228 {
229     mInstance->releaseProxy(this);
230
231     RefCountObject::release();
232 }
233
234 // Increments refcount on image.
235 // caller must Release() the returned image
236 egl::Image *Renderbuffer::getRenderTarget()
237 {
238         return mInstance->getRenderTarget();
239 }
240
241 // Increments refcount on image.
242 // caller must Release() the returned image
243 egl::Image *Renderbuffer::createSharedImage()
244 {
245     return mInstance->createSharedImage();
246 }
247
248 bool Renderbuffer::isShared() const
249 {
250     return mInstance->isShared();
251 }
252
253 GLsizei Renderbuffer::getWidth() const
254 {
255         return mInstance->getWidth();
256 }
257
258 GLsizei Renderbuffer::getHeight() const
259 {
260         return mInstance->getHeight();
261 }
262
263 GLenum Renderbuffer::getFormat() const
264 {
265         return mInstance->getFormat();
266 }
267
268 sw::Format Renderbuffer::getInternalFormat() const
269 {
270         return mInstance->getInternalFormat();
271 }
272
273 GLuint Renderbuffer::getRedSize() const
274 {
275         return mInstance->getRedSize();
276 }
277
278 GLuint Renderbuffer::getGreenSize() const
279 {
280         return mInstance->getGreenSize();
281 }
282
283 GLuint Renderbuffer::getBlueSize() const
284 {
285         return mInstance->getBlueSize();
286 }
287
288 GLuint Renderbuffer::getAlphaSize() const
289 {
290         return mInstance->getAlphaSize();
291 }
292
293 GLuint Renderbuffer::getDepthSize() const
294 {
295         return mInstance->getDepthSize();
296 }
297
298 GLuint Renderbuffer::getStencilSize() const
299 {
300         return mInstance->getStencilSize();
301 }
302
303 GLsizei Renderbuffer::getSamples() const
304 {
305         return mInstance->getSamples();
306 }
307
308 void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
309 {
310         ASSERT(newStorage != NULL);
311
312         delete mInstance;
313         mInstance = newStorage;
314 }
315
316 RenderbufferStorage::RenderbufferStorage()
317 {
318         mWidth = 0;
319         mHeight = 0;
320         format = GL_RGBA4;
321         internalFormat = sw::FORMAT_A8R8G8B8;
322         mSamples = 0;
323 }
324
325 RenderbufferStorage::~RenderbufferStorage()
326 {
327 }
328
329 GLsizei RenderbufferStorage::getWidth() const
330 {
331         return mWidth;
332 }
333
334 GLsizei RenderbufferStorage::getHeight() const
335 {
336         return mHeight;
337 }
338
339 GLenum RenderbufferStorage::getFormat() const
340 {
341         return format;
342 }
343
344 sw::Format RenderbufferStorage::getInternalFormat() const
345 {
346         return internalFormat;
347 }
348
349 GLsizei RenderbufferStorage::getSamples() const
350 {
351         return mSamples;
352 }
353
354 Colorbuffer::Colorbuffer(egl::Image *renderTarget) : mRenderTarget(renderTarget)
355 {
356         if(renderTarget)
357         {
358                 renderTarget->addRef();
359                 
360                 mWidth = renderTarget->getWidth();
361                 mHeight = renderTarget->getHeight();
362                 internalFormat = renderTarget->getInternalFormat();
363                 format = sw2rad::ConvertBackBufferFormat(internalFormat);
364                 mSamples = renderTarget->getMultiSampleDepth() & ~1;
365         }
366 }
367
368 Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) : mRenderTarget(NULL)
369 {
370         Device *device = getDevice();
371
372         sw::Format requestedFormat = rad2sw::ConvertRenderbufferFormat(format);
373         int supportedSamples = Context::getSupportedMultiSampleDepth(requestedFormat, samples);
374
375         if(width > 0 && height > 0)
376         {
377                 mRenderTarget = device->createRenderTarget(width, height, requestedFormat, supportedSamples, false);
378
379                 if(!mRenderTarget)
380                 {
381                         error(GL_OUT_OF_MEMORY);
382                         return;
383                 }
384         }
385
386         mWidth = width;
387         mHeight = height;
388         this->format = format;
389         internalFormat = requestedFormat;
390         mSamples = supportedSamples & ~1;
391 }
392
393 Colorbuffer::~Colorbuffer()
394 {
395         if(mRenderTarget)
396         {
397                 mRenderTarget->release();
398         }
399 }
400
401 // Increments refcount on image.
402 // caller must release() the returned image
403 egl::Image *Colorbuffer::getRenderTarget()
404 {
405         if(mRenderTarget)
406         {
407                 mRenderTarget->addRef();
408         }
409
410         return mRenderTarget;
411 }
412
413 // Increments refcount on image.
414 // caller must release() the returned image
415 egl::Image *Colorbuffer::createSharedImage()
416 {
417     if(mRenderTarget)
418     {
419         mRenderTarget->addRef();
420         mRenderTarget->markShared();
421     }
422
423     return mRenderTarget;
424 }
425
426 bool Colorbuffer::isShared() const
427 {
428     return mRenderTarget->isShared();
429 }
430
431 DepthStencilbuffer::DepthStencilbuffer(egl::Image *depthStencil) : mDepthStencil(depthStencil)
432 {
433         if(depthStencil)
434         {
435                 depthStencil->addRef();
436
437                 mWidth = depthStencil->getWidth();
438                 mHeight = depthStencil->getHeight();
439                 internalFormat = depthStencil->getInternalFormat();
440                 format = sw2rad::ConvertDepthStencilFormat(internalFormat);
441                 mSamples = depthStencil->getMultiSampleDepth() & ~1;
442         }
443 }
444
445 DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples)
446 {
447         Device *device = getDevice();
448
449         mDepthStencil = NULL;
450         
451         int supportedSamples = Context::getSupportedMultiSampleDepth(sw::FORMAT_D24S8, samples);
452
453         if(width > 0 && height > 0)
454         {
455                 mDepthStencil = device->createDepthStencilSurface(width, height, sw::FORMAT_D24S8, supportedSamples, false);
456
457                 if(!mDepthStencil)
458                 {
459                         error(GL_OUT_OF_MEMORY);
460                         return;
461                 }
462         }
463
464         mWidth = width;
465         mHeight = height;
466         format = GL_DEPTH24_STENCIL8_OES;
467         internalFormat = sw::FORMAT_D24S8;
468         mSamples = supportedSamples & ~1;
469 }
470
471 DepthStencilbuffer::~DepthStencilbuffer()
472 {
473         if(mDepthStencil)
474         {
475                 mDepthStencil->release();
476         }
477 }
478
479 // Increments refcount on image.
480 // caller must release() the returned image
481 egl::Image *DepthStencilbuffer::getRenderTarget()
482 {
483         if(mDepthStencil)
484         {
485                 mDepthStencil->addRef();
486         }
487
488         return mDepthStencil;
489 }
490
491 // Increments refcount on image.
492 // caller must release() the returned image
493 egl::Image *DepthStencilbuffer::createSharedImage()
494 {
495     if(mDepthStencil)
496     {
497         mDepthStencil->addRef();
498         mDepthStencil->markShared();
499     }
500
501     return mDepthStencil;
502 }
503
504 bool DepthStencilbuffer::isShared() const
505 {
506     return mDepthStencil->isShared();
507 }
508
509 Depthbuffer::Depthbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
510 {
511         if(depthStencil)
512         {
513                 format = GL_DEPTH_COMPONENT16;   // If the renderbuffer parameters are queried, the calling function
514                                                  // will expect one of the valid renderbuffer formats for use in 
515                                                  // glRenderbufferStorage
516         }
517 }
518
519 Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
520 {
521         if(mDepthStencil)
522         {
523                 format = GL_DEPTH_COMPONENT16;   // If the renderbuffer parameters are queried, the calling function
524                                                  // will expect one of the valid renderbuffer formats for use in 
525                                                  // glRenderbufferStorage
526         }
527 }
528
529 Depthbuffer::~Depthbuffer()
530 {
531 }
532
533 Stencilbuffer::Stencilbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
534 {
535         if(depthStencil)
536         {
537                 format = GL_STENCIL_INDEX8;   // If the renderbuffer parameters are queried, the calling function
538                                               // will expect one of the valid renderbuffer formats for use in 
539                                               // glRenderbufferStorage
540         }
541 }
542
543 Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
544 {
545         if(mDepthStencil)
546         {
547                 format = GL_STENCIL_INDEX8;   // If the renderbuffer parameters are queried, the calling function
548                                               // will expect one of the valid renderbuffer formats for use in 
549                                               // glRenderbufferStorage
550         }
551 }
552
553 Stencilbuffer::~Stencilbuffer()
554 {
555 }
556
557 }