• 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 GetRedSize(getFormat());
45 }
46 
getGreenSize() const47 GLuint RenderbufferInterface::getGreenSize() const
48 {
49 	return GetGreenSize(getFormat());
50 }
51 
getBlueSize() const52 GLuint RenderbufferInterface::getBlueSize() const
53 {
54 	return GetBlueSize(getFormat());
55 }
56 
getAlphaSize() const57 GLuint RenderbufferInterface::getAlphaSize() const
58 {
59 	return GetAlphaSize(getFormat());
60 }
61 
getDepthSize() const62 GLuint RenderbufferInterface::getDepthSize() const
63 {
64 	return GetDepthSize(getFormat());
65 }
66 
getStencilSize() const67 GLuint RenderbufferInterface::getStencilSize() const
68 {
69 	return GetStencilSize(getFormat());
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 = nullptr;
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 GLint RenderbufferTexture2D::getFormat() const
126 {
127 	return mTexture2D->getFormat(GL_TEXTURE_2D, mLevel);
128 }
129 
getSamples() const130 GLsizei RenderbufferTexture2D::getSamples() const
131 {
132 	return 0;   // Core OpenGL ES 3.0 does not support multisample textures.
133 }
134 
135 ///// RenderbufferTexture2DRect Implementation ////////
136 
RenderbufferTexture2DRect(Texture2DRect * texture)137 RenderbufferTexture2DRect::RenderbufferTexture2DRect(Texture2DRect *texture)
138 {
139 	mTexture2DRect = texture;
140 }
141 
~RenderbufferTexture2DRect()142 RenderbufferTexture2DRect::~RenderbufferTexture2DRect()
143 {
144 	mTexture2DRect = NULL;
145 }
146 
147 // Textures need to maintain their own reference count for references via
148 // Renderbuffers acting as proxies. Here, we notify the texture of a reference.
addProxyRef(const Renderbuffer * proxy)149 void RenderbufferTexture2DRect::addProxyRef(const Renderbuffer *proxy)
150 {
151 	mTexture2DRect->addProxyRef(proxy);
152 }
153 
releaseProxy(const Renderbuffer * proxy)154 void RenderbufferTexture2DRect::releaseProxy(const Renderbuffer *proxy)
155 {
156 	mTexture2DRect->releaseProxy(proxy);
157 }
158 
159 // Increments refcount on image.
160 // caller must release() the returned image
getRenderTarget()161 egl::Image *RenderbufferTexture2DRect::getRenderTarget()
162 {
163 	return mTexture2DRect->getRenderTarget(GL_TEXTURE_RECTANGLE_ARB, 0);
164 }
165 
166 // Increments refcount on image.
167 // caller must release() the returned image
createSharedImage()168 egl::Image *RenderbufferTexture2DRect::createSharedImage()
169 {
170 	return mTexture2DRect->createSharedImage(GL_TEXTURE_RECTANGLE_ARB, 0);
171 }
172 
isShared() const173 bool RenderbufferTexture2DRect::isShared() const
174 {
175 	return mTexture2DRect->isShared(GL_TEXTURE_RECTANGLE_ARB, 0);
176 }
177 
getWidth() const178 GLsizei RenderbufferTexture2DRect::getWidth() const
179 {
180 	return mTexture2DRect->getWidth(GL_TEXTURE_RECTANGLE_ARB, 0);
181 }
182 
getHeight() const183 GLsizei RenderbufferTexture2DRect::getHeight() const
184 {
185 	return mTexture2DRect->getHeight(GL_TEXTURE_RECTANGLE_ARB, 0);
186 }
187 
getFormat() const188 GLint RenderbufferTexture2DRect::getFormat() const
189 {
190 	return mTexture2DRect->getFormat(GL_TEXTURE_RECTANGLE_ARB, 0);
191 }
192 
getSamples() const193 GLsizei RenderbufferTexture2DRect::getSamples() const
194 {
195 	return 0;   // Core OpenGL ES 3.0 does not support multisample textures.
196 }
197 
198 ///// RenderbufferTexture3D Implementation ////////
199 
RenderbufferTexture3D(Texture3D * texture,GLint level)200 RenderbufferTexture3D::RenderbufferTexture3D(Texture3D *texture, GLint level) : mLevel(level)
201 {
202 	mTexture3D = texture;
203 }
204 
~RenderbufferTexture3D()205 RenderbufferTexture3D::~RenderbufferTexture3D()
206 {
207 	mTexture3D = NULL;
208 }
209 
210 // Textures need to maintain their own reference count for references via
211 // Renderbuffers acting as proxies. Here, we notify the texture of a reference.
addProxyRef(const Renderbuffer * proxy)212 void RenderbufferTexture3D::addProxyRef(const Renderbuffer *proxy)
213 {
214 	mTexture3D->addProxyRef(proxy);
215 }
216 
releaseProxy(const Renderbuffer * proxy)217 void RenderbufferTexture3D::releaseProxy(const Renderbuffer *proxy)
218 {
219 	mTexture3D->releaseProxy(proxy);
220 }
221 
222 // Increments refcount on image.
223 // caller must release() the returned image
getRenderTarget()224 egl::Image *RenderbufferTexture3D::getRenderTarget()
225 {
226 	return mTexture3D->getRenderTarget(mTexture3D->getTarget(), mLevel);
227 }
228 
229 // Increments refcount on image.
230 // caller must release() the returned image
createSharedImage()231 egl::Image *RenderbufferTexture3D::createSharedImage()
232 {
233 	return mTexture3D->createSharedImage(mTexture3D->getTarget(), mLevel);
234 }
235 
isShared() const236 bool RenderbufferTexture3D::isShared() const
237 {
238 	return mTexture3D->isShared(mTexture3D->getTarget(), mLevel);
239 }
240 
getWidth() const241 GLsizei RenderbufferTexture3D::getWidth() const
242 {
243 	return mTexture3D->getWidth(mTexture3D->getTarget(), mLevel);
244 }
245 
getHeight() const246 GLsizei RenderbufferTexture3D::getHeight() const
247 {
248 	return mTexture3D->getHeight(mTexture3D->getTarget(), mLevel);
249 }
250 
getDepth() const251 GLsizei RenderbufferTexture3D::getDepth() const
252 {
253 	return mTexture3D->getDepth(mTexture3D->getTarget(), mLevel);
254 }
255 
getFormat() const256 GLint RenderbufferTexture3D::getFormat() const
257 {
258 	return mTexture3D->getFormat(mTexture3D->getTarget(), mLevel);
259 }
260 
getSamples() const261 GLsizei RenderbufferTexture3D::getSamples() const
262 {
263 	return 0;   // Core OpenGL ES 3.0 does not support multisample textures.
264 }
265 
266 ///// RenderbufferTextureCubeMap Implementation ////////
267 
RenderbufferTextureCubeMap(TextureCubeMap * texture,GLenum target,GLint level)268 RenderbufferTextureCubeMap::RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target, GLint level) : mTarget(target), mLevel(level)
269 {
270 	mTextureCubeMap = texture;
271 }
272 
~RenderbufferTextureCubeMap()273 RenderbufferTextureCubeMap::~RenderbufferTextureCubeMap()
274 {
275 	mTextureCubeMap = NULL;
276 }
277 
278 // Textures need to maintain their own reference count for references via
279 // Renderbuffers acting as proxies. Here, we notify the texture of a reference.
addProxyRef(const Renderbuffer * proxy)280 void RenderbufferTextureCubeMap::addProxyRef(const Renderbuffer *proxy)
281 {
282 	mTextureCubeMap->addProxyRef(proxy);
283 }
284 
releaseProxy(const Renderbuffer * proxy)285 void RenderbufferTextureCubeMap::releaseProxy(const Renderbuffer *proxy)
286 {
287 	mTextureCubeMap->releaseProxy(proxy);
288 }
289 
290 // Increments refcount on image.
291 // caller must release() the returned image
getRenderTarget()292 egl::Image *RenderbufferTextureCubeMap::getRenderTarget()
293 {
294 	return mTextureCubeMap->getRenderTarget(mTarget, mLevel);
295 }
296 
297 // Increments refcount on image.
298 // caller must release() the returned image
createSharedImage()299 egl::Image *RenderbufferTextureCubeMap::createSharedImage()
300 {
301 	return mTextureCubeMap->createSharedImage(mTarget, mLevel);
302 }
303 
isShared() const304 bool RenderbufferTextureCubeMap::isShared() const
305 {
306 	return mTextureCubeMap->isShared(mTarget, mLevel);
307 }
308 
getWidth() const309 GLsizei RenderbufferTextureCubeMap::getWidth() const
310 {
311 	return mTextureCubeMap->getWidth(mTarget, mLevel);
312 }
313 
getHeight() const314 GLsizei RenderbufferTextureCubeMap::getHeight() const
315 {
316 	return mTextureCubeMap->getHeight(mTarget, mLevel);
317 }
318 
getFormat() const319 GLint RenderbufferTextureCubeMap::getFormat() const
320 {
321 	return mTextureCubeMap->getFormat(mTarget, mLevel);
322 }
323 
getSamples() const324 GLsizei RenderbufferTextureCubeMap::getSamples() const
325 {
326 	return 0;   // Core OpenGL ES 3.0 does not support multisample textures.
327 }
328 
329 ////// Renderbuffer Implementation //////
330 
Renderbuffer(GLuint name,RenderbufferInterface * instance)331 Renderbuffer::Renderbuffer(GLuint name, RenderbufferInterface *instance) : NamedObject(name)
332 {
333 	ASSERT(instance);
334 	mInstance = instance;
335 }
336 
~Renderbuffer()337 Renderbuffer::~Renderbuffer()
338 {
339 	delete mInstance;
340 }
341 
342 // The RenderbufferInterface contained in this Renderbuffer may need to maintain
343 // its own reference count, so we pass it on here.
addRef()344 void Renderbuffer::addRef()
345 {
346 	mInstance->addProxyRef(this);
347 
348 	Object::addRef();
349 }
350 
release()351 void Renderbuffer::release()
352 {
353 	mInstance->releaseProxy(this);
354 
355 	Object::release();
356 }
357 
358 // Increments refcount on image.
359 // caller must Release() the returned image
getRenderTarget()360 egl::Image *Renderbuffer::getRenderTarget()
361 {
362 	return mInstance->getRenderTarget();
363 }
364 
365 // Increments refcount on image.
366 // caller must Release() the returned image
createSharedImage()367 egl::Image *Renderbuffer::createSharedImage()
368 {
369 	return mInstance->createSharedImage();
370 }
371 
isShared() const372 bool Renderbuffer::isShared() const
373 {
374 	return mInstance->isShared();
375 }
376 
getWidth() const377 GLsizei Renderbuffer::getWidth() const
378 {
379 	return mInstance->getWidth();
380 }
381 
getHeight() const382 GLsizei Renderbuffer::getHeight() const
383 {
384 	return mInstance->getHeight();
385 }
386 
getDepth() const387 GLsizei Renderbuffer::getDepth() const
388 {
389 	return mInstance->getDepth();
390 }
391 
getLevel() const392 GLint Renderbuffer::getLevel() const
393 {
394 	return mInstance->getLevel();
395 }
396 
getFormat() const397 GLint Renderbuffer::getFormat() const
398 {
399 	return mInstance->getFormat();
400 }
401 
getRedSize() const402 GLuint Renderbuffer::getRedSize() const
403 {
404 	return mInstance->getRedSize();
405 }
406 
getGreenSize() const407 GLuint Renderbuffer::getGreenSize() const
408 {
409 	return mInstance->getGreenSize();
410 }
411 
getBlueSize() const412 GLuint Renderbuffer::getBlueSize() const
413 {
414 	return mInstance->getBlueSize();
415 }
416 
getAlphaSize() const417 GLuint Renderbuffer::getAlphaSize() const
418 {
419 	return mInstance->getAlphaSize();
420 }
421 
getDepthSize() const422 GLuint Renderbuffer::getDepthSize() const
423 {
424 	return mInstance->getDepthSize();
425 }
426 
getStencilSize() const427 GLuint Renderbuffer::getStencilSize() const
428 {
429 	return mInstance->getStencilSize();
430 }
431 
getSamples() const432 GLsizei Renderbuffer::getSamples() const
433 {
434 	return mInstance->getSamples();
435 }
436 
setLevel(GLint level)437 void Renderbuffer::setLevel(GLint level)
438 {
439 	return mInstance->setLevel(level);
440 }
441 
setStorage(RenderbufferStorage * newStorage)442 void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
443 {
444 	ASSERT(newStorage);
445 
446 	delete mInstance;
447 	mInstance = newStorage;
448 }
449 
RenderbufferStorage()450 RenderbufferStorage::RenderbufferStorage()
451 {
452 	mWidth = 0;
453 	mHeight = 0;
454 	format = GL_NONE;
455 	mSamples = 0;
456 }
457 
~RenderbufferStorage()458 RenderbufferStorage::~RenderbufferStorage()
459 {
460 }
461 
getWidth() const462 GLsizei RenderbufferStorage::getWidth() const
463 {
464 	return mWidth;
465 }
466 
getHeight() const467 GLsizei RenderbufferStorage::getHeight() const
468 {
469 	return mHeight;
470 }
471 
getFormat() const472 GLint RenderbufferStorage::getFormat() const
473 {
474 	return format;
475 }
476 
getSamples() const477 GLsizei RenderbufferStorage::getSamples() const
478 {
479 	return mSamples;
480 }
481 
Colorbuffer(egl::Image * renderTarget)482 Colorbuffer::Colorbuffer(egl::Image *renderTarget) : mRenderTarget(renderTarget)
483 {
484 	if(renderTarget)
485 	{
486 		renderTarget->addRef();
487 
488 		mWidth = renderTarget->getWidth();
489 		mHeight = renderTarget->getHeight();
490 		format = renderTarget->getFormat();
491 		mSamples = renderTarget->getDepth() & ~1;
492 	}
493 }
494 
Colorbuffer(int width,int height,GLenum internalformat,GLsizei samples)495 Colorbuffer::Colorbuffer(int width, int height, GLenum internalformat, GLsizei samples) : mRenderTarget(nullptr)
496 {
497 	int supportedSamples = Context::getSupportedMultisampleCount(samples);
498 
499 	if(width > 0 && height > 0)
500 	{
501 		if(height > sw::OUTLINE_RESOLUTION)
502 		{
503 			error(GL_OUT_OF_MEMORY);
504 			return;
505 		}
506 
507 		mRenderTarget = egl::Image::create(width, height, internalformat, supportedSamples, false);
508 
509 		if(!mRenderTarget)
510 		{
511 			error(GL_OUT_OF_MEMORY);
512 			return;
513 		}
514 	}
515 
516 	mWidth = width;
517 	mHeight = height;
518 	format = internalformat;
519 	mSamples = supportedSamples;
520 }
521 
~Colorbuffer()522 Colorbuffer::~Colorbuffer()
523 {
524 	if(mRenderTarget)
525 	{
526 		mRenderTarget->release();
527 	}
528 }
529 
530 // Increments refcount on image.
531 // caller must release() the returned image
getRenderTarget()532 egl::Image *Colorbuffer::getRenderTarget()
533 {
534 	if(mRenderTarget)
535 	{
536 		mRenderTarget->addRef();
537 	}
538 
539 	return mRenderTarget;
540 }
541 
542 // Increments refcount on image.
543 // caller must release() the returned image
createSharedImage()544 egl::Image *Colorbuffer::createSharedImage()
545 {
546 	if(mRenderTarget)
547 	{
548 		mRenderTarget->addRef();
549 		mRenderTarget->markShared();
550 	}
551 
552 	return mRenderTarget;
553 }
554 
isShared() const555 bool Colorbuffer::isShared() const
556 {
557 	return mRenderTarget->isShared();
558 }
559 
DepthStencilbuffer(egl::Image * depthStencil)560 DepthStencilbuffer::DepthStencilbuffer(egl::Image *depthStencil) : mDepthStencil(depthStencil)
561 {
562 	if(depthStencil)
563 	{
564 		depthStencil->addRef();
565 
566 		mWidth = depthStencil->getWidth();
567 		mHeight = depthStencil->getHeight();
568 		format = depthStencil->getFormat();
569 		mSamples = depthStencil->getDepth() & ~1;
570 	}
571 }
572 
DepthStencilbuffer(int width,int height,GLenum internalformat,GLsizei samples)573 DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLenum internalformat, GLsizei samples) : mDepthStencil(nullptr)
574 {
575 	int supportedSamples = Context::getSupportedMultisampleCount(samples);
576 
577 	if(width > 0 && height > 0)
578 	{
579 		if(height > sw::OUTLINE_RESOLUTION)
580 		{
581 			error(GL_OUT_OF_MEMORY);
582 			return;
583 		}
584 
585 		mDepthStencil = egl::Image::create(width, height, internalformat, supportedSamples, false);
586 
587 		if(!mDepthStencil)
588 		{
589 			error(GL_OUT_OF_MEMORY);
590 			return;
591 		}
592 	}
593 
594 	mWidth = width;
595 	mHeight = height;
596 	format = internalformat;
597 	mSamples = supportedSamples;
598 }
599 
~DepthStencilbuffer()600 DepthStencilbuffer::~DepthStencilbuffer()
601 {
602 	if(mDepthStencil)
603 	{
604 		mDepthStencil->release();
605 	}
606 }
607 
608 // Increments refcount on image.
609 // caller must release() the returned image
getRenderTarget()610 egl::Image *DepthStencilbuffer::getRenderTarget()
611 {
612 	if(mDepthStencil)
613 	{
614 		mDepthStencil->addRef();
615 	}
616 
617 	return mDepthStencil;
618 }
619 
620 // Increments refcount on image.
621 // caller must release() the returned image
createSharedImage()622 egl::Image *DepthStencilbuffer::createSharedImage()
623 {
624 	if(mDepthStencil)
625 	{
626 		mDepthStencil->addRef();
627 		mDepthStencil->markShared();
628 	}
629 
630 	return mDepthStencil;
631 }
632 
isShared() const633 bool DepthStencilbuffer::isShared() const
634 {
635 	return mDepthStencil->isShared();
636 }
637 
Depthbuffer(egl::Image * depthStencil)638 Depthbuffer::Depthbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
639 {
640 }
641 
Depthbuffer(int width,int height,GLenum internalformat,GLsizei samples)642 Depthbuffer::Depthbuffer(int width, int height, GLenum internalformat, GLsizei samples) : DepthStencilbuffer(width, height, internalformat, samples)
643 {
644 }
645 
~Depthbuffer()646 Depthbuffer::~Depthbuffer()
647 {
648 }
649 
Stencilbuffer(egl::Image * depthStencil)650 Stencilbuffer::Stencilbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
651 {
652 }
653 
Stencilbuffer(int width,int height,GLsizei samples)654 Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, GL_STENCIL_INDEX8, samples)
655 {
656 }
657 
~Stencilbuffer()658 Stencilbuffer::~Stencilbuffer()
659 {
660 }
661 
662 }
663