• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // Renderbuffer.cpp: the Renderbuffer class and its derived classes
16 // Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
17 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
18 
19 #include "Renderbuffer.h"
20 
21 #include "main.h"
22 #include "Texture.h"
23 #include "utilities.h"
24 
25 namespace es2
26 {
RenderbufferInterface()27 RenderbufferInterface::RenderbufferInterface()
28 {
29 }
30 
31 // The default case for classes inherited from RenderbufferInterface is not to
32 // need to do anything upon the reference count to the parent Renderbuffer incrementing
33 // or decrementing.
addProxyRef(const Renderbuffer * proxy)34 void RenderbufferInterface::addProxyRef(const Renderbuffer *proxy)
35 {
36 }
37 
releaseProxy(const Renderbuffer * proxy)38 void RenderbufferInterface::releaseProxy(const Renderbuffer *proxy)
39 {
40 }
41 
getRedSize() const42 GLuint RenderbufferInterface::getRedSize() const
43 {
44 	return sw2es::GetRedSize(getInternalFormat());
45 }
46 
getGreenSize() const47 GLuint RenderbufferInterface::getGreenSize() const
48 {
49 	return sw2es::GetGreenSize(getInternalFormat());
50 }
51 
getBlueSize() const52 GLuint RenderbufferInterface::getBlueSize() const
53 {
54 	return sw2es::GetBlueSize(getInternalFormat());
55 }
56 
getAlphaSize() const57 GLuint RenderbufferInterface::getAlphaSize() const
58 {
59 	return sw2es::GetAlphaSize(getInternalFormat());
60 }
61 
getDepthSize() const62 GLuint RenderbufferInterface::getDepthSize() const
63 {
64 	return sw2es::GetDepthSize(getInternalFormat());
65 }
66 
getStencilSize() const67 GLuint RenderbufferInterface::getStencilSize() const
68 {
69 	return sw2es::GetStencilSize(getInternalFormat());
70 }
71 
72 ///// RenderbufferTexture2D Implementation ////////
73 
RenderbufferTexture2D(Texture2D * texture,GLint level)74 RenderbufferTexture2D::RenderbufferTexture2D(Texture2D *texture, GLint level) : mLevel(level)
75 {
76 	mTexture2D = texture;
77 }
78 
~RenderbufferTexture2D()79 RenderbufferTexture2D::~RenderbufferTexture2D()
80 {
81 	mTexture2D = NULL;
82 }
83 
84 // Textures need to maintain their own reference count for references via
85 // Renderbuffers acting as proxies. Here, we notify the texture of a reference.
addProxyRef(const Renderbuffer * proxy)86 void RenderbufferTexture2D::addProxyRef(const Renderbuffer *proxy)
87 {
88 	mTexture2D->addProxyRef(proxy);
89 }
90 
releaseProxy(const Renderbuffer * proxy)91 void RenderbufferTexture2D::releaseProxy(const Renderbuffer *proxy)
92 {
93 	mTexture2D->releaseProxy(proxy);
94 }
95 
96 // Increments refcount on image.
97 // caller must release() the returned image
getRenderTarget()98 egl::Image *RenderbufferTexture2D::getRenderTarget()
99 {
100 	return mTexture2D->getRenderTarget(GL_TEXTURE_2D, mLevel);
101 }
102 
103 // Increments refcount on image.
104 // caller must release() the returned image
createSharedImage()105 egl::Image *RenderbufferTexture2D::createSharedImage()
106 {
107 	return mTexture2D->createSharedImage(GL_TEXTURE_2D, mLevel);
108 }
109 
isShared() const110 bool RenderbufferTexture2D::isShared() const
111 {
112 	return mTexture2D->isShared(GL_TEXTURE_2D, mLevel);
113 }
114 
getWidth() const115 GLsizei RenderbufferTexture2D::getWidth() const
116 {
117 	return mTexture2D->getWidth(GL_TEXTURE_2D, mLevel);
118 }
119 
getHeight() const120 GLsizei RenderbufferTexture2D::getHeight() const
121 {
122 	return mTexture2D->getHeight(GL_TEXTURE_2D, mLevel);
123 }
124 
getFormat() const125 GLenum RenderbufferTexture2D::getFormat() const
126 {
127 	return mTexture2D->getFormat(GL_TEXTURE_2D, mLevel);
128 }
129 
getInternalFormat() const130 sw::Format RenderbufferTexture2D::getInternalFormat() const
131 {
132 	return mTexture2D->getInternalFormat(GL_TEXTURE_2D, mLevel);
133 }
134 
getSamples() const135 GLsizei RenderbufferTexture2D::getSamples() const
136 {
137 	return 0;
138 }
139 
140 ///// RenderbufferTexture3D Implementation ////////
141 
RenderbufferTexture3D(Texture3D * texture,GLint level,GLint layer)142 RenderbufferTexture3D::RenderbufferTexture3D(Texture3D *texture, GLint level, GLint layer) : mLevel(level), mLayer(layer)
143 {
144 	mTexture3D = texture;
145 	if(mLayer != 0)
146 	{
147 		UNIMPLEMENTED();
148 	}
149 }
150 
~RenderbufferTexture3D()151 RenderbufferTexture3D::~RenderbufferTexture3D()
152 {
153 	mTexture3D = NULL;
154 }
155 
156 // Textures need to maintain their own reference count for references via
157 // Renderbuffers acting as proxies. Here, we notify the texture of a reference.
addProxyRef(const Renderbuffer * proxy)158 void RenderbufferTexture3D::addProxyRef(const Renderbuffer *proxy)
159 {
160 	mTexture3D->addProxyRef(proxy);
161 }
162 
releaseProxy(const Renderbuffer * proxy)163 void RenderbufferTexture3D::releaseProxy(const Renderbuffer *proxy)
164 {
165 	mTexture3D->releaseProxy(proxy);
166 }
167 
168 // Increments refcount on image.
169 // caller must release() the returned image
getRenderTarget()170 egl::Image *RenderbufferTexture3D::getRenderTarget()
171 {
172 	return mTexture3D->getRenderTarget(mTexture3D->getTarget(), mLevel);
173 }
174 
175 // Increments refcount on image.
176 // caller must release() the returned image
createSharedImage()177 egl::Image *RenderbufferTexture3D::createSharedImage()
178 {
179 	return mTexture3D->createSharedImage(mTexture3D->getTarget(), mLevel);
180 }
181 
isShared() const182 bool RenderbufferTexture3D::isShared() const
183 {
184 	return mTexture3D->isShared(mTexture3D->getTarget(), mLevel);
185 }
186 
getWidth() const187 GLsizei RenderbufferTexture3D::getWidth() const
188 {
189 	return mTexture3D->getWidth(mTexture3D->getTarget(), mLevel);
190 }
191 
getHeight() const192 GLsizei RenderbufferTexture3D::getHeight() const
193 {
194 	return mTexture3D->getHeight(mTexture3D->getTarget(), mLevel);
195 }
196 
getDepth() const197 GLsizei RenderbufferTexture3D::getDepth() const
198 {
199 	return mTexture3D->getDepth(mTexture3D->getTarget(), mLevel);
200 }
201 
getFormat() const202 GLenum RenderbufferTexture3D::getFormat() const
203 {
204 	return mTexture3D->getFormat(mTexture3D->getTarget(), mLevel);
205 }
206 
getInternalFormat() const207 sw::Format RenderbufferTexture3D::getInternalFormat() const
208 {
209 	return mTexture3D->getInternalFormat(mTexture3D->getTarget(), mLevel);
210 }
211 
getSamples() const212 GLsizei RenderbufferTexture3D::getSamples() const
213 {
214 	return 0;
215 }
216 
217 ///// RenderbufferTextureCubeMap Implementation ////////
218 
RenderbufferTextureCubeMap(TextureCubeMap * texture,GLenum target,GLint level)219 RenderbufferTextureCubeMap::RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target, GLint level) : mTarget(target), mLevel(level)
220 {
221 	mTextureCubeMap = texture;
222 }
223 
~RenderbufferTextureCubeMap()224 RenderbufferTextureCubeMap::~RenderbufferTextureCubeMap()
225 {
226 	mTextureCubeMap = NULL;
227 }
228 
229 // Textures need to maintain their own reference count for references via
230 // Renderbuffers acting as proxies. Here, we notify the texture of a reference.
addProxyRef(const Renderbuffer * proxy)231 void RenderbufferTextureCubeMap::addProxyRef(const Renderbuffer *proxy)
232 {
233 	mTextureCubeMap->addProxyRef(proxy);
234 }
235 
releaseProxy(const Renderbuffer * proxy)236 void RenderbufferTextureCubeMap::releaseProxy(const Renderbuffer *proxy)
237 {
238 	mTextureCubeMap->releaseProxy(proxy);
239 }
240 
241 // Increments refcount on image.
242 // caller must release() the returned image
getRenderTarget()243 egl::Image *RenderbufferTextureCubeMap::getRenderTarget()
244 {
245 	return mTextureCubeMap->getRenderTarget(mTarget, mLevel);
246 }
247 
248 // Increments refcount on image.
249 // caller must release() the returned image
createSharedImage()250 egl::Image *RenderbufferTextureCubeMap::createSharedImage()
251 {
252 	return mTextureCubeMap->createSharedImage(mTarget, mLevel);
253 }
254 
isShared() const255 bool RenderbufferTextureCubeMap::isShared() const
256 {
257 	return mTextureCubeMap->isShared(mTarget, mLevel);
258 }
259 
getWidth() const260 GLsizei RenderbufferTextureCubeMap::getWidth() const
261 {
262 	return mTextureCubeMap->getWidth(mTarget, mLevel);
263 }
264 
getHeight() const265 GLsizei RenderbufferTextureCubeMap::getHeight() const
266 {
267 	return mTextureCubeMap->getHeight(mTarget, mLevel);
268 }
269 
getFormat() const270 GLenum RenderbufferTextureCubeMap::getFormat() const
271 {
272 	return mTextureCubeMap->getFormat(mTarget, mLevel);
273 }
274 
getInternalFormat() const275 sw::Format RenderbufferTextureCubeMap::getInternalFormat() const
276 {
277 	return mTextureCubeMap->getInternalFormat(mTarget, mLevel);
278 }
279 
getSamples() const280 GLsizei RenderbufferTextureCubeMap::getSamples() const
281 {
282 	return 0;
283 }
284 
285 ////// Renderbuffer Implementation //////
286 
Renderbuffer(GLuint name,RenderbufferInterface * instance)287 Renderbuffer::Renderbuffer(GLuint name, RenderbufferInterface *instance) : NamedObject(name)
288 {
289 	ASSERT(instance);
290 	mInstance = instance;
291 }
292 
~Renderbuffer()293 Renderbuffer::~Renderbuffer()
294 {
295 	delete mInstance;
296 }
297 
298 // The RenderbufferInterface contained in this Renderbuffer may need to maintain
299 // its own reference count, so we pass it on here.
addRef()300 void Renderbuffer::addRef()
301 {
302 	mInstance->addProxyRef(this);
303 
304 	Object::addRef();
305 }
306 
release()307 void Renderbuffer::release()
308 {
309 	mInstance->releaseProxy(this);
310 
311 	Object::release();
312 }
313 
314 // Increments refcount on image.
315 // caller must Release() the returned image
getRenderTarget()316 egl::Image *Renderbuffer::getRenderTarget()
317 {
318 	return mInstance->getRenderTarget();
319 }
320 
321 // Increments refcount on image.
322 // caller must Release() the returned image
createSharedImage()323 egl::Image *Renderbuffer::createSharedImage()
324 {
325 	return mInstance->createSharedImage();
326 }
327 
isShared() const328 bool Renderbuffer::isShared() const
329 {
330 	return mInstance->isShared();
331 }
332 
getWidth() const333 GLsizei Renderbuffer::getWidth() const
334 {
335 	return mInstance->getWidth();
336 }
337 
getHeight() const338 GLsizei Renderbuffer::getHeight() const
339 {
340 	return mInstance->getHeight();
341 }
342 
getDepth() const343 GLsizei Renderbuffer::getDepth() const
344 {
345 	return mInstance->getDepth();
346 }
347 
getLayer() const348 GLint Renderbuffer::getLayer() const
349 {
350 	return mInstance->getLayer();
351 }
352 
getLevel() const353 GLint Renderbuffer::getLevel() const
354 {
355 	return mInstance->getLevel();
356 }
357 
getFormat() const358 GLenum Renderbuffer::getFormat() const
359 {
360 	return mInstance->getFormat();
361 }
362 
getInternalFormat() const363 sw::Format Renderbuffer::getInternalFormat() const
364 {
365 	return mInstance->getInternalFormat();
366 }
367 
getRedSize() const368 GLuint Renderbuffer::getRedSize() const
369 {
370 	return mInstance->getRedSize();
371 }
372 
getGreenSize() const373 GLuint Renderbuffer::getGreenSize() const
374 {
375 	return mInstance->getGreenSize();
376 }
377 
getBlueSize() const378 GLuint Renderbuffer::getBlueSize() const
379 {
380 	return mInstance->getBlueSize();
381 }
382 
getAlphaSize() const383 GLuint Renderbuffer::getAlphaSize() const
384 {
385 	return mInstance->getAlphaSize();
386 }
387 
getDepthSize() const388 GLuint Renderbuffer::getDepthSize() const
389 {
390 	return mInstance->getDepthSize();
391 }
392 
getStencilSize() const393 GLuint Renderbuffer::getStencilSize() const
394 {
395 	return mInstance->getStencilSize();
396 }
397 
getSamples() const398 GLsizei Renderbuffer::getSamples() const
399 {
400 	return mInstance->getSamples();
401 }
402 
setLayer(GLint layer)403 void Renderbuffer::setLayer(GLint layer)
404 {
405 	return mInstance->setLayer(layer);
406 }
407 
setLevel(GLint level)408 void Renderbuffer::setLevel(GLint level)
409 {
410 	return mInstance->setLevel(level);
411 }
412 
setStorage(RenderbufferStorage * newStorage)413 void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
414 {
415 	ASSERT(newStorage != NULL);
416 
417 	delete mInstance;
418 	mInstance = newStorage;
419 }
420 
RenderbufferStorage()421 RenderbufferStorage::RenderbufferStorage()
422 {
423 	mWidth = 0;
424 	mHeight = 0;
425 	format = GL_RGBA4;
426 	internalFormat = sw::FORMAT_A8B8G8R8;
427 	mSamples = 0;
428 }
429 
~RenderbufferStorage()430 RenderbufferStorage::~RenderbufferStorage()
431 {
432 }
433 
getWidth() const434 GLsizei RenderbufferStorage::getWidth() const
435 {
436 	return mWidth;
437 }
438 
getHeight() const439 GLsizei RenderbufferStorage::getHeight() const
440 {
441 	return mHeight;
442 }
443 
getFormat() const444 GLenum RenderbufferStorage::getFormat() const
445 {
446 	return format;
447 }
448 
getInternalFormat() const449 sw::Format RenderbufferStorage::getInternalFormat() const
450 {
451 	return internalFormat;
452 }
453 
getSamples() const454 GLsizei RenderbufferStorage::getSamples() const
455 {
456 	return mSamples;
457 }
458 
Colorbuffer(egl::Image * renderTarget)459 Colorbuffer::Colorbuffer(egl::Image *renderTarget) : mRenderTarget(renderTarget)
460 {
461 	if(renderTarget)
462 	{
463 		renderTarget->addRef();
464 
465 		mWidth = renderTarget->getWidth();
466 		mHeight = renderTarget->getHeight();
467 		internalFormat = renderTarget->getInternalFormat();
468 		format = sw2es::ConvertBackBufferFormat(internalFormat);
469 		mSamples = renderTarget->getDepth() & ~1;
470 	}
471 }
472 
Colorbuffer(int width,int height,GLenum format,GLsizei samples)473 Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) : mRenderTarget(nullptr)
474 {
475 	Device *device = getDevice();
476 
477 	sw::Format requestedFormat = es2sw::ConvertRenderbufferFormat(format);
478 	int supportedSamples = Context::getSupportedMultisampleCount(samples);
479 
480 	if(width > 0 && height > 0)
481 	{
482 		mRenderTarget = device->createRenderTarget(width, height, requestedFormat, supportedSamples, false);
483 
484 		if(!mRenderTarget)
485 		{
486 			error(GL_OUT_OF_MEMORY);
487 			return;
488 		}
489 	}
490 
491 	mWidth = width;
492 	mHeight = height;
493 	this->format = format;
494 	internalFormat = requestedFormat;
495 	mSamples = supportedSamples;
496 }
497 
~Colorbuffer()498 Colorbuffer::~Colorbuffer()
499 {
500 	if(mRenderTarget)
501 	{
502 		mRenderTarget->release();
503 	}
504 }
505 
506 // Increments refcount on image.
507 // caller must release() the returned image
getRenderTarget()508 egl::Image *Colorbuffer::getRenderTarget()
509 {
510 	if(mRenderTarget)
511 	{
512 		mRenderTarget->addRef();
513 	}
514 
515 	return mRenderTarget;
516 }
517 
518 // Increments refcount on image.
519 // caller must release() the returned image
createSharedImage()520 egl::Image *Colorbuffer::createSharedImage()
521 {
522 	if(mRenderTarget)
523 	{
524 		mRenderTarget->addRef();
525 		mRenderTarget->markShared();
526 	}
527 
528 	return mRenderTarget;
529 }
530 
isShared() const531 bool Colorbuffer::isShared() const
532 {
533 	return mRenderTarget->isShared();
534 }
535 
DepthStencilbuffer(egl::Image * depthStencil)536 DepthStencilbuffer::DepthStencilbuffer(egl::Image *depthStencil) : mDepthStencil(depthStencil)
537 {
538 	if(depthStencil)
539 	{
540 		depthStencil->addRef();
541 
542 		mWidth = depthStencil->getWidth();
543 		mHeight = depthStencil->getHeight();
544 		internalFormat = depthStencil->getInternalFormat();
545 		format = sw2es::ConvertDepthStencilFormat(internalFormat);
546 		mSamples = depthStencil->getDepth() & ~1;
547 	}
548 }
549 
DepthStencilbuffer(int width,int height,GLenum requestedFormat,GLsizei samples)550 DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLenum requestedFormat, GLsizei samples) : mDepthStencil(nullptr)
551 {
552 	format = requestedFormat;
553 	switch(requestedFormat)
554 	{
555 	case GL_STENCIL_INDEX8:
556 	case GL_DEPTH_COMPONENT24:
557 	case GL_DEPTH24_STENCIL8_OES:
558 		internalFormat = sw::FORMAT_D24S8;
559 		break;
560 	case GL_DEPTH32F_STENCIL8:
561 		internalFormat = sw::FORMAT_D32FS8_TEXTURE;
562 		break;
563 	case GL_DEPTH_COMPONENT16:
564 		internalFormat = sw::FORMAT_D16;
565 		break;
566 	case GL_DEPTH_COMPONENT32_OES:
567 		internalFormat = sw::FORMAT_D32;
568 		break;
569 	case GL_DEPTH_COMPONENT32F:
570 		internalFormat = sw::FORMAT_D32F;
571 		break;
572 	default:
573 		UNREACHABLE(requestedFormat);
574 		format = GL_DEPTH24_STENCIL8_OES;
575 		internalFormat = sw::FORMAT_D24S8;
576 	}
577 
578 	Device *device = getDevice();
579 
580 	int supportedSamples = Context::getSupportedMultisampleCount(samples);
581 
582 	if(width > 0 && height > 0)
583 	{
584 		mDepthStencil = device->createDepthStencilSurface(width, height, internalFormat, supportedSamples, false);
585 
586 		if(!mDepthStencil)
587 		{
588 			error(GL_OUT_OF_MEMORY);
589 			return;
590 		}
591 	}
592 
593 	mWidth = width;
594 	mHeight = height;
595 	mSamples = supportedSamples;
596 }
597 
~DepthStencilbuffer()598 DepthStencilbuffer::~DepthStencilbuffer()
599 {
600 	if(mDepthStencil)
601 	{
602 		mDepthStencil->release();
603 	}
604 }
605 
606 // Increments refcount on image.
607 // caller must release() the returned image
getRenderTarget()608 egl::Image *DepthStencilbuffer::getRenderTarget()
609 {
610 	if(mDepthStencil)
611 	{
612 		mDepthStencil->addRef();
613 	}
614 
615 	return mDepthStencil;
616 }
617 
618 // Increments refcount on image.
619 // caller must release() the returned image
createSharedImage()620 egl::Image *DepthStencilbuffer::createSharedImage()
621 {
622 	if(mDepthStencil)
623 	{
624 		mDepthStencil->addRef();
625 		mDepthStencil->markShared();
626 	}
627 
628 	return mDepthStencil;
629 }
630 
isShared() const631 bool DepthStencilbuffer::isShared() const
632 {
633 	return mDepthStencil->isShared();
634 }
635 
Depthbuffer(egl::Image * depthStencil)636 Depthbuffer::Depthbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
637 {
638 }
639 
Depthbuffer(int width,int height,GLenum format,GLsizei samples)640 Depthbuffer::Depthbuffer(int width, int height, GLenum format, GLsizei samples) : DepthStencilbuffer(width, height, format, samples)
641 {
642 }
643 
~Depthbuffer()644 Depthbuffer::~Depthbuffer()
645 {
646 }
647 
Stencilbuffer(egl::Image * depthStencil)648 Stencilbuffer::Stencilbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
649 {
650 }
651 
Stencilbuffer(int width,int height,GLsizei samples)652 Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, GL_STENCIL_INDEX8, samples)
653 {
654 }
655 
~Stencilbuffer()656 Stencilbuffer::~Stencilbuffer()
657 {
658 }
659 
660 }
661