• 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 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 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)74 RenderbufferTexture2D::RenderbufferTexture2D(Texture2D *texture)
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 GLenum RenderbufferTexture2D::getFormat() const
126 {
127 	return mTexture2D->getFormat(GL_TEXTURE_2D, 0);
128 }
129 
getInternalFormat() const130 sw::Format RenderbufferTexture2D::getInternalFormat() const
131 {
132 	return mTexture2D->getInternalFormat(GL_TEXTURE_2D, 0);
133 }
134 
getSamples() const135 GLsizei RenderbufferTexture2D::getSamples() const
136 {
137 	return 0;
138 }
139 
140 ////// Renderbuffer Implementation //////
141 
Renderbuffer(GLuint name,RenderbufferInterface * instance)142 Renderbuffer::Renderbuffer(GLuint name, RenderbufferInterface *instance) : NamedObject(name)
143 {
144 	ASSERT(instance);
145 	mInstance = instance;
146 }
147 
~Renderbuffer()148 Renderbuffer::~Renderbuffer()
149 {
150 	delete mInstance;
151 }
152 
153 // The RenderbufferInterface contained in this Renderbuffer may need to maintain
154 // its own reference count, so we pass it on here.
addRef()155 void Renderbuffer::addRef()
156 {
157 	mInstance->addProxyRef(this);
158 
159 	Object::addRef();
160 }
161 
release()162 void Renderbuffer::release()
163 {
164 	mInstance->releaseProxy(this);
165 
166 	Object::release();
167 }
168 
169 // Increments refcount on image.
170 // caller must Release() the returned image
getRenderTarget()171 egl::Image *Renderbuffer::getRenderTarget()
172 {
173 	return mInstance->getRenderTarget();
174 }
175 
176 // Increments refcount on image.
177 // caller must Release() the returned image
createSharedImage()178 egl::Image *Renderbuffer::createSharedImage()
179 {
180 	return mInstance->createSharedImage();
181 }
182 
isShared() const183 bool Renderbuffer::isShared() const
184 {
185 	return mInstance->isShared();
186 }
187 
getWidth() const188 GLsizei Renderbuffer::getWidth() const
189 {
190 	return mInstance->getWidth();
191 }
192 
getHeight() const193 GLsizei Renderbuffer::getHeight() const
194 {
195 	return mInstance->getHeight();
196 }
197 
getFormat() const198 GLenum Renderbuffer::getFormat() const
199 {
200 	return mInstance->getFormat();
201 }
202 
getInternalFormat() const203 sw::Format Renderbuffer::getInternalFormat() const
204 {
205 	return mInstance->getInternalFormat();
206 }
207 
getRedSize() const208 GLuint Renderbuffer::getRedSize() const
209 {
210 	return mInstance->getRedSize();
211 }
212 
getGreenSize() const213 GLuint Renderbuffer::getGreenSize() const
214 {
215 	return mInstance->getGreenSize();
216 }
217 
getBlueSize() const218 GLuint Renderbuffer::getBlueSize() const
219 {
220 	return mInstance->getBlueSize();
221 }
222 
getAlphaSize() const223 GLuint Renderbuffer::getAlphaSize() const
224 {
225 	return mInstance->getAlphaSize();
226 }
227 
getDepthSize() const228 GLuint Renderbuffer::getDepthSize() const
229 {
230 	return mInstance->getDepthSize();
231 }
232 
getStencilSize() const233 GLuint Renderbuffer::getStencilSize() const
234 {
235 	return mInstance->getStencilSize();
236 }
237 
getSamples() const238 GLsizei Renderbuffer::getSamples() const
239 {
240 	return mInstance->getSamples();
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_RGBA4_OES;
256 	internalFormat = sw::FORMAT_A8B8G8R8;
257 	mSamples = 0;
258 }
259 
~RenderbufferStorage()260 RenderbufferStorage::~RenderbufferStorage()
261 {
262 }
263 
getWidth() const264 GLsizei RenderbufferStorage::getWidth() const
265 {
266 	return mWidth;
267 }
268 
getHeight() const269 GLsizei RenderbufferStorage::getHeight() const
270 {
271 	return mHeight;
272 }
273 
getFormat() const274 GLenum RenderbufferStorage::getFormat() const
275 {
276 	return format;
277 }
278 
getInternalFormat() const279 sw::Format RenderbufferStorage::getInternalFormat() const
280 {
281 	return internalFormat;
282 }
283 
getSamples() const284 GLsizei RenderbufferStorage::getSamples() const
285 {
286 	return mSamples;
287 }
288 
Colorbuffer(egl::Image * renderTarget)289 Colorbuffer::Colorbuffer(egl::Image *renderTarget) : mRenderTarget(renderTarget)
290 {
291 	if(renderTarget)
292 	{
293 		renderTarget->addRef();
294 
295 		mWidth = renderTarget->getWidth();
296 		mHeight = renderTarget->getHeight();
297 		internalFormat = renderTarget->getInternalFormat();
298 		format = sw2es::ConvertBackBufferFormat(internalFormat);
299 		mSamples = renderTarget->getDepth() & ~1;
300 	}
301 }
302 
Colorbuffer(int width,int height,GLenum format,GLsizei samples)303 Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) : mRenderTarget(nullptr)
304 {
305 	Device *device = getDevice();
306 
307 	sw::Format requestedFormat = es2sw::ConvertRenderbufferFormat(format);
308 	int supportedSamples = Context::getSupportedMultisampleCount(samples);
309 
310 	if(width > 0 && height > 0)
311 	{
312 		mRenderTarget = device->createRenderTarget(width, height, requestedFormat, supportedSamples, false);
313 
314 		if(!mRenderTarget)
315 		{
316 			error(GL_OUT_OF_MEMORY);
317 			return;
318 		}
319 	}
320 
321 	mWidth = width;
322 	mHeight = height;
323 	this->format = format;
324 	internalFormat = requestedFormat;
325 	mSamples = supportedSamples;
326 }
327 
~Colorbuffer()328 Colorbuffer::~Colorbuffer()
329 {
330 	if(mRenderTarget)
331 	{
332 		mRenderTarget->release();
333 	}
334 }
335 
336 // Increments refcount on image.
337 // caller must release() the returned image
getRenderTarget()338 egl::Image *Colorbuffer::getRenderTarget()
339 {
340 	if(mRenderTarget)
341 	{
342 		mRenderTarget->addRef();
343 	}
344 
345 	return mRenderTarget;
346 }
347 
348 // Increments refcount on image.
349 // caller must release() the returned image
createSharedImage()350 egl::Image *Colorbuffer::createSharedImage()
351 {
352 	if(mRenderTarget)
353 	{
354 		mRenderTarget->addRef();
355 		mRenderTarget->markShared();
356 	}
357 
358 	return mRenderTarget;
359 }
360 
isShared() const361 bool Colorbuffer::isShared() const
362 {
363 	return mRenderTarget->isShared();
364 }
365 
DepthStencilbuffer(egl::Image * depthStencil)366 DepthStencilbuffer::DepthStencilbuffer(egl::Image *depthStencil) : mDepthStencil(depthStencil)
367 {
368 	if(depthStencil)
369 	{
370 		depthStencil->addRef();
371 
372 		mWidth = depthStencil->getWidth();
373 		mHeight = depthStencil->getHeight();
374 		internalFormat = depthStencil->getInternalFormat();
375 		format = sw2es::ConvertDepthStencilFormat(internalFormat);
376 		mSamples = depthStencil->getDepth() & ~1;
377 	}
378 }
379 
DepthStencilbuffer(int width,int height,GLsizei samples)380 DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples) : mDepthStencil(nullptr)
381 {
382 	Device *device = getDevice();
383 
384 	int supportedSamples = Context::getSupportedMultisampleCount(samples);
385 
386 	if(width > 0 && height > 0)
387 	{
388 		mDepthStencil = device->createDepthStencilSurface(width, height, sw::FORMAT_D24S8, supportedSamples, false);
389 
390 		if(!mDepthStencil)
391 		{
392 			error(GL_OUT_OF_MEMORY);
393 			return;
394 		}
395 	}
396 
397 	mWidth = width;
398 	mHeight = height;
399 	format = GL_DEPTH24_STENCIL8_OES;
400 	internalFormat = sw::FORMAT_D24S8;
401 	mSamples = supportedSamples;
402 }
403 
~DepthStencilbuffer()404 DepthStencilbuffer::~DepthStencilbuffer()
405 {
406 	if(mDepthStencil)
407 	{
408 		mDepthStencil->release();
409 	}
410 }
411 
412 // Increments refcount on image.
413 // caller must release() the returned image
getRenderTarget()414 egl::Image *DepthStencilbuffer::getRenderTarget()
415 {
416 	if(mDepthStencil)
417 	{
418 		mDepthStencil->addRef();
419 	}
420 
421 	return mDepthStencil;
422 }
423 
424 // Increments refcount on image.
425 // caller must release() the returned image
createSharedImage()426 egl::Image *DepthStencilbuffer::createSharedImage()
427 {
428 	if(mDepthStencil)
429 	{
430 		mDepthStencil->addRef();
431 		mDepthStencil->markShared();
432 	}
433 
434 	return mDepthStencil;
435 }
436 
isShared() const437 bool DepthStencilbuffer::isShared() const
438 {
439 	return mDepthStencil->isShared();
440 }
441 
Depthbuffer(egl::Image * depthStencil)442 Depthbuffer::Depthbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
443 {
444 	if(depthStencil)
445 	{
446 		format = GL_DEPTH_COMPONENT16_OES;   // If the renderbuffer parameters are queried, the calling function
447 		                                     // will expect one of the valid renderbuffer formats for use in
448 		                                     // glRenderbufferStorage
449 	}
450 }
451 
Depthbuffer(int width,int height,GLsizei samples)452 Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
453 {
454 	if(mDepthStencil)
455 	{
456 		format = GL_DEPTH_COMPONENT16_OES;   // If the renderbuffer parameters are queried, the calling function
457 		                                     // will expect one of the valid renderbuffer formats for use in
458 		                                     // glRenderbufferStorage
459 	}
460 }
461 
~Depthbuffer()462 Depthbuffer::~Depthbuffer()
463 {
464 }
465 
Stencilbuffer(egl::Image * depthStencil)466 Stencilbuffer::Stencilbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
467 {
468 	if(depthStencil)
469 	{
470 		format = GL_STENCIL_INDEX8_OES;   // If the renderbuffer parameters are queried, the calling function
471 		                                  // will expect one of the valid renderbuffer formats for use in
472 		                                  // glRenderbufferStorage
473 	}
474 }
475 
Stencilbuffer(int width,int height,GLsizei samples)476 Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
477 {
478 	if(mDepthStencil)
479 	{
480 		format = GL_STENCIL_INDEX8_OES;   // If the renderbuffer parameters are queried, the calling function
481 		                                  // will expect one of the valid renderbuffer formats for use in
482 		                                  // glRenderbufferStorage
483 	}
484 }
485 
~Stencilbuffer()486 Stencilbuffer::~Stencilbuffer()
487 {
488 }
489 
490 }
491