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 es1
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, 0);
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, 0);
108 }
109 
isShared() const110 bool RenderbufferTexture2D::isShared() const
111 {
112 	return mTexture2D->isShared(GL_TEXTURE_2D, 0);
113 }
114 
getWidth() const115 GLsizei RenderbufferTexture2D::getWidth() const
116 {
117 	return mTexture2D->getWidth(GL_TEXTURE_2D, 0);
118 }
119 
getHeight() const120 GLsizei RenderbufferTexture2D::getHeight() const
121 {
122 	return mTexture2D->getHeight(GL_TEXTURE_2D, 0);
123 }
124 
getFormat() const125 GLint RenderbufferTexture2D::getFormat() const
126 {
127 	return mTexture2D->getFormat(GL_TEXTURE_2D, 0);
128 }
129 
getSamples() const130 GLsizei RenderbufferTexture2D::getSamples() const
131 {
132 	return 0;
133 }
134 
135 ////// Renderbuffer Implementation //////
136 
Renderbuffer(GLuint name,RenderbufferInterface * instance)137 Renderbuffer::Renderbuffer(GLuint name, RenderbufferInterface *instance) : NamedObject(name)
138 {
139 	ASSERT(instance);
140 	mInstance = instance;
141 }
142 
~Renderbuffer()143 Renderbuffer::~Renderbuffer()
144 {
145 	delete mInstance;
146 }
147 
148 // The RenderbufferInterface contained in this Renderbuffer may need to maintain
149 // its own reference count, so we pass it on here.
addRef()150 void Renderbuffer::addRef()
151 {
152 	mInstance->addProxyRef(this);
153 
154 	Object::addRef();
155 }
156 
release()157 void Renderbuffer::release()
158 {
159 	mInstance->releaseProxy(this);
160 
161 	Object::release();
162 }
163 
164 // Increments refcount on image.
165 // caller must Release() the returned image
getRenderTarget()166 egl::Image *Renderbuffer::getRenderTarget()
167 {
168 	return mInstance->getRenderTarget();
169 }
170 
171 // Increments refcount on image.
172 // caller must Release() the returned image
createSharedImage()173 egl::Image *Renderbuffer::createSharedImage()
174 {
175 	return mInstance->createSharedImage();
176 }
177 
isShared() const178 bool Renderbuffer::isShared() const
179 {
180 	return mInstance->isShared();
181 }
182 
getWidth() const183 GLsizei Renderbuffer::getWidth() const
184 {
185 	return mInstance->getWidth();
186 }
187 
getHeight() const188 GLsizei Renderbuffer::getHeight() const
189 {
190 	return mInstance->getHeight();
191 }
192 
getLevel() const193 GLint Renderbuffer::getLevel() const
194 {
195 	return mInstance->getLevel();
196 }
197 
getFormat() const198 GLenum Renderbuffer::getFormat() const
199 {
200 	return mInstance->getFormat();
201 }
202 
getRedSize() const203 GLuint Renderbuffer::getRedSize() const
204 {
205 	return mInstance->getRedSize();
206 }
207 
getGreenSize() const208 GLuint Renderbuffer::getGreenSize() const
209 {
210 	return mInstance->getGreenSize();
211 }
212 
getBlueSize() const213 GLuint Renderbuffer::getBlueSize() const
214 {
215 	return mInstance->getBlueSize();
216 }
217 
getAlphaSize() const218 GLuint Renderbuffer::getAlphaSize() const
219 {
220 	return mInstance->getAlphaSize();
221 }
222 
getDepthSize() const223 GLuint Renderbuffer::getDepthSize() const
224 {
225 	return mInstance->getDepthSize();
226 }
227 
getStencilSize() const228 GLuint Renderbuffer::getStencilSize() const
229 {
230 	return mInstance->getStencilSize();
231 }
232 
getSamples() const233 GLsizei Renderbuffer::getSamples() const
234 {
235 	return mInstance->getSamples();
236 }
237 
setLevel(GLint level)238 void Renderbuffer::setLevel(GLint level)
239 {
240 	return mInstance->setLevel(level);
241 }
242 
setStorage(RenderbufferStorage * newStorage)243 void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
244 {
245 	ASSERT(newStorage);
246 
247 	delete mInstance;
248 	mInstance = newStorage;
249 }
250 
RenderbufferStorage()251 RenderbufferStorage::RenderbufferStorage()
252 {
253 	mWidth = 0;
254 	mHeight = 0;
255 	format = GL_NONE_OES;
256 	mSamples = 0;
257 }
258 
~RenderbufferStorage()259 RenderbufferStorage::~RenderbufferStorage()
260 {
261 }
262 
getWidth() const263 GLsizei RenderbufferStorage::getWidth() const
264 {
265 	return mWidth;
266 }
267 
getHeight() const268 GLsizei RenderbufferStorage::getHeight() const
269 {
270 	return mHeight;
271 }
272 
getFormat() const273 GLint RenderbufferStorage::getFormat() const
274 {
275 	return format;
276 }
277 
getSamples() const278 GLsizei RenderbufferStorage::getSamples() const
279 {
280 	return mSamples;
281 }
282 
Colorbuffer(egl::Image * renderTarget)283 Colorbuffer::Colorbuffer(egl::Image *renderTarget) : mRenderTarget(renderTarget)
284 {
285 	if(renderTarget)
286 	{
287 		renderTarget->addRef();
288 
289 		mWidth = renderTarget->getWidth();
290 		mHeight = renderTarget->getHeight();
291 		format = renderTarget->getFormat();
292 		mSamples = renderTarget->getDepth() & ~1;
293 	}
294 }
295 
Colorbuffer(int width,int height,GLenum internalformat,GLsizei samples)296 Colorbuffer::Colorbuffer(int width, int height, GLenum internalformat, GLsizei samples) : mRenderTarget(nullptr)
297 {
298 	int supportedSamples = Context::getSupportedMultisampleCount(samples);
299 
300 	if(width > 0 && height > 0)
301 	{
302 		if(height > sw::OUTLINE_RESOLUTION)
303 		{
304 			error(GL_OUT_OF_MEMORY);
305 			return;
306 		}
307 
308 		mRenderTarget = egl::Image::create(width, height, internalformat, supportedSamples, false);
309 
310 		if(!mRenderTarget)
311 		{
312 			error(GL_OUT_OF_MEMORY);
313 			return;
314 		}
315 	}
316 
317 	mWidth = width;
318 	mHeight = height;
319 	format = internalformat;
320 	mSamples = supportedSamples;
321 }
322 
~Colorbuffer()323 Colorbuffer::~Colorbuffer()
324 {
325 	if(mRenderTarget)
326 	{
327 		mRenderTarget->release();
328 	}
329 }
330 
331 // Increments refcount on image.
332 // caller must release() the returned image
getRenderTarget()333 egl::Image *Colorbuffer::getRenderTarget()
334 {
335 	if(mRenderTarget)
336 	{
337 		mRenderTarget->addRef();
338 	}
339 
340 	return mRenderTarget;
341 }
342 
343 // Increments refcount on image.
344 // caller must release() the returned image
createSharedImage()345 egl::Image *Colorbuffer::createSharedImage()
346 {
347 	if(mRenderTarget)
348 	{
349 		mRenderTarget->addRef();
350 		mRenderTarget->markShared();
351 	}
352 
353 	return mRenderTarget;
354 }
355 
isShared() const356 bool Colorbuffer::isShared() const
357 {
358 	return mRenderTarget->isShared();
359 }
360 
DepthStencilbuffer(egl::Image * depthStencil)361 DepthStencilbuffer::DepthStencilbuffer(egl::Image *depthStencil) : mDepthStencil(depthStencil)
362 {
363 	if(depthStencil)
364 	{
365 		depthStencil->addRef();
366 
367 		mWidth = depthStencil->getWidth();
368 		mHeight = depthStencil->getHeight();
369 		format = depthStencil->getFormat();
370 		mSamples = depthStencil->getDepth() & ~1;
371 	}
372 }
373 
DepthStencilbuffer(int width,int height,GLenum internalformat,GLsizei samples)374 DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLenum internalformat, GLsizei samples) : mDepthStencil(nullptr)
375 {
376 	int supportedSamples = Context::getSupportedMultisampleCount(samples);
377 
378 	if(width > 0 && height > 0)
379 	{
380 		if(height > sw::OUTLINE_RESOLUTION)
381 		{
382 			error(GL_OUT_OF_MEMORY);
383 			return;
384 		}
385 
386 		mDepthStencil = egl::Image::create(width, height, internalformat, supportedSamples, false);
387 
388 		if(!mDepthStencil)
389 		{
390 			error(GL_OUT_OF_MEMORY);
391 			return;
392 		}
393 	}
394 
395 	mWidth = width;
396 	mHeight = height;
397 	format = internalformat;
398 	mSamples = supportedSamples;
399 }
400 
~DepthStencilbuffer()401 DepthStencilbuffer::~DepthStencilbuffer()
402 {
403 	if(mDepthStencil)
404 	{
405 		mDepthStencil->release();
406 	}
407 }
408 
409 // Increments refcount on image.
410 // caller must release() the returned image
getRenderTarget()411 egl::Image *DepthStencilbuffer::getRenderTarget()
412 {
413 	if(mDepthStencil)
414 	{
415 		mDepthStencil->addRef();
416 	}
417 
418 	return mDepthStencil;
419 }
420 
421 // Increments refcount on image.
422 // caller must release() the returned image
createSharedImage()423 egl::Image *DepthStencilbuffer::createSharedImage()
424 {
425 	if(mDepthStencil)
426 	{
427 		mDepthStencil->addRef();
428 		mDepthStencil->markShared();
429 	}
430 
431 	return mDepthStencil;
432 }
433 
isShared() const434 bool DepthStencilbuffer::isShared() const
435 {
436 	return mDepthStencil->isShared();
437 }
438 
Depthbuffer(egl::Image * depthStencil)439 Depthbuffer::Depthbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
440 {
441 }
442 
Depthbuffer(int width,int height,GLenum internalformat,GLsizei samples)443 Depthbuffer::Depthbuffer(int width, int height, GLenum internalformat, GLsizei samples) : DepthStencilbuffer(width, height, internalformat, samples)
444 {
445 }
446 
~Depthbuffer()447 Depthbuffer::~Depthbuffer()
448 {
449 }
450 
Stencilbuffer(egl::Image * depthStencil)451 Stencilbuffer::Stencilbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
452 {
453 }
454 
Stencilbuffer(int width,int height,GLsizei samples)455 Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, GL_STENCIL_INDEX8_OES, samples)
456 {
457 }
458 
~Stencilbuffer()459 Stencilbuffer::~Stencilbuffer()
460 {
461 }
462 
463 }
464