• 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.
18 
19 #include "Renderbuffer.h"
20 
21 #include "main.h"
22 #include "Texture.h"
23 #include "utilities.h"
24 
25 namespace gl
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 surface.
97 // caller must release() the returned surface
getRenderTarget()98 Image *RenderbufferTexture2D::getRenderTarget()
99 {
100 	return mTexture2D->getRenderTarget(GL_TEXTURE_2D, 0);
101 }
102 
getWidth() const103 GLsizei RenderbufferTexture2D::getWidth() const
104 {
105 	return mTexture2D->getWidth(GL_TEXTURE_2D, 0);
106 }
107 
getHeight() const108 GLsizei RenderbufferTexture2D::getHeight() const
109 {
110 	return mTexture2D->getHeight(GL_TEXTURE_2D, 0);
111 }
112 
getFormat() const113 GLenum RenderbufferTexture2D::getFormat() const
114 {
115 	return mTexture2D->getFormat(GL_TEXTURE_2D, 0);
116 }
117 
getInternalFormat() const118 sw::Format RenderbufferTexture2D::getInternalFormat() const
119 {
120 	return mTexture2D->getInternalFormat(GL_TEXTURE_2D, 0);
121 }
122 
getSamples() const123 GLsizei RenderbufferTexture2D::getSamples() const
124 {
125 	return 0;
126 }
127 
128 ///// RenderbufferTextureCubeMap Implementation ////////
129 
RenderbufferTextureCubeMap(TextureCubeMap * texture,GLenum target)130 RenderbufferTextureCubeMap::RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target) : mTarget(target)
131 {
132 	mTextureCubeMap = texture;
133 }
134 
~RenderbufferTextureCubeMap()135 RenderbufferTextureCubeMap::~RenderbufferTextureCubeMap()
136 {
137 	mTextureCubeMap = nullptr;
138 }
139 
140 // Textures need to maintain their own reference count for references via
141 // Renderbuffers acting as proxies. Here, we notify the texture of a reference.
addProxyRef(const Renderbuffer * proxy)142 void RenderbufferTextureCubeMap::addProxyRef(const Renderbuffer *proxy)
143 {
144 	mTextureCubeMap->addProxyRef(proxy);
145 }
146 
releaseProxy(const Renderbuffer * proxy)147 void RenderbufferTextureCubeMap::releaseProxy(const Renderbuffer *proxy)
148 {
149 	mTextureCubeMap->releaseProxy(proxy);
150 }
151 
152 // Increments refcount on surface.
153 // caller must release() the returned surface
getRenderTarget()154 Image *RenderbufferTextureCubeMap::getRenderTarget()
155 {
156 	return mTextureCubeMap->getRenderTarget(mTarget, 0);
157 }
158 
getWidth() const159 GLsizei RenderbufferTextureCubeMap::getWidth() const
160 {
161 	return mTextureCubeMap->getWidth(mTarget, 0);
162 }
163 
getHeight() const164 GLsizei RenderbufferTextureCubeMap::getHeight() const
165 {
166 	return mTextureCubeMap->getHeight(mTarget, 0);
167 }
168 
getFormat() const169 GLenum RenderbufferTextureCubeMap::getFormat() const
170 {
171 	return mTextureCubeMap->getFormat(mTarget, 0);
172 }
173 
getInternalFormat() const174 sw::Format RenderbufferTextureCubeMap::getInternalFormat() const
175 {
176 	return mTextureCubeMap->getInternalFormat(mTarget, 0);
177 }
178 
getSamples() const179 GLsizei RenderbufferTextureCubeMap::getSamples() const
180 {
181 	return 0;
182 }
183 
184 ////// Renderbuffer Implementation //////
185 
Renderbuffer(GLuint name,RenderbufferInterface * instance)186 Renderbuffer::Renderbuffer(GLuint name, RenderbufferInterface *instance) : NamedObject(name)
187 {
188 	ASSERT(instance);
189 	mInstance = instance;
190 }
191 
~Renderbuffer()192 Renderbuffer::~Renderbuffer()
193 {
194 	delete mInstance;
195 }
196 
197 // The RenderbufferInterface contained in this Renderbuffer may need to maintain
198 // its own reference count, so we pass it on here.
addRef()199 void Renderbuffer::addRef()
200 {
201 	mInstance->addProxyRef(this);
202 
203 	Object::addRef();
204 }
205 
release()206 void Renderbuffer::release()
207 {
208 	mInstance->releaseProxy(this);
209 
210 	Object::release();
211 }
212 
213 // Increments refcount on surface.
214 // caller must Release() the returned surface
getRenderTarget()215 Image *Renderbuffer::getRenderTarget()
216 {
217 	return mInstance->getRenderTarget();
218 }
219 
getWidth() const220 GLsizei Renderbuffer::getWidth() const
221 {
222 	return mInstance->getWidth();
223 }
224 
getHeight() const225 GLsizei Renderbuffer::getHeight() const
226 {
227 	return mInstance->getHeight();
228 }
229 
getFormat() const230 GLenum Renderbuffer::getFormat() const
231 {
232 	return mInstance->getFormat();
233 }
234 
getInternalFormat() const235 sw::Format Renderbuffer::getInternalFormat() const
236 {
237 	return mInstance->getInternalFormat();
238 }
239 
getRedSize() const240 GLuint Renderbuffer::getRedSize() const
241 {
242 	return mInstance->getRedSize();
243 }
244 
getGreenSize() const245 GLuint Renderbuffer::getGreenSize() const
246 {
247 	return mInstance->getGreenSize();
248 }
249 
getBlueSize() const250 GLuint Renderbuffer::getBlueSize() const
251 {
252 	return mInstance->getBlueSize();
253 }
254 
getAlphaSize() const255 GLuint Renderbuffer::getAlphaSize() const
256 {
257 	return mInstance->getAlphaSize();
258 }
259 
getDepthSize() const260 GLuint Renderbuffer::getDepthSize() const
261 {
262 	return mInstance->getDepthSize();
263 }
264 
getStencilSize() const265 GLuint Renderbuffer::getStencilSize() const
266 {
267 	return mInstance->getStencilSize();
268 }
269 
getSamples() const270 GLsizei Renderbuffer::getSamples() const
271 {
272 	return mInstance->getSamples();
273 }
274 
setStorage(RenderbufferStorage * newStorage)275 void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
276 {
277 	ASSERT(newStorage);
278 
279 	delete mInstance;
280 	mInstance = newStorage;
281 }
282 
RenderbufferStorage()283 RenderbufferStorage::RenderbufferStorage()
284 {
285 	mWidth = 0;
286 	mHeight = 0;
287 	format = GL_RGBA4;
288 	internalFormat = sw::FORMAT_A8R8G8B8;
289 	mSamples = 0;
290 }
291 
~RenderbufferStorage()292 RenderbufferStorage::~RenderbufferStorage()
293 {
294 }
295 
296 // Increments refcount on surface.
297 // caller must Release() the returned surface
getRenderTarget()298 Image *RenderbufferStorage::getRenderTarget()
299 {
300 	return nullptr;
301 }
302 
getWidth() const303 GLsizei RenderbufferStorage::getWidth() const
304 {
305 	return mWidth;
306 }
307 
getHeight() const308 GLsizei RenderbufferStorage::getHeight() const
309 {
310 	return mHeight;
311 }
312 
getFormat() const313 GLenum RenderbufferStorage::getFormat() const
314 {
315 	return format;
316 }
317 
getInternalFormat() const318 sw::Format RenderbufferStorage::getInternalFormat() const
319 {
320 	return internalFormat;
321 }
322 
getSamples() const323 GLsizei RenderbufferStorage::getSamples() const
324 {
325 	return mSamples;
326 }
327 
Colorbuffer(Image * renderTarget)328 Colorbuffer::Colorbuffer(Image *renderTarget) : mRenderTarget(renderTarget)
329 {
330 	if(renderTarget)
331 	{
332 		renderTarget->addRef();
333 
334 		mWidth = renderTarget->getWidth();
335 		mHeight = renderTarget->getHeight();
336 		internalFormat = renderTarget->getInternalFormat();
337 		format = sw2es::ConvertBackBufferFormat(internalFormat);
338 		mSamples = renderTarget->getMultiSampleDepth() & ~1;
339 	}
340 }
341 
Colorbuffer(int width,int height,GLenum format,GLsizei samples)342 Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) : mRenderTarget(nullptr)
343 {
344 	Device *device = getDevice();
345 
346 	sw::Format requestedFormat = es2sw::ConvertRenderbufferFormat(format);
347 	int supportedSamples = Context::getSupportedMultisampleCount(samples);
348 
349 	if(width > 0 && height > 0)
350 	{
351 		mRenderTarget = device->createRenderTarget(width, height, requestedFormat, supportedSamples, false);
352 
353 		if(!mRenderTarget)
354 		{
355 			error(GL_OUT_OF_MEMORY);
356 			return;
357 		}
358 	}
359 
360 	mWidth = width;
361 	mHeight = height;
362 	this->format = format;
363 	internalFormat = requestedFormat;
364 	mSamples = supportedSamples;
365 }
366 
~Colorbuffer()367 Colorbuffer::~Colorbuffer()
368 {
369 	if(mRenderTarget)
370 	{
371 		mRenderTarget->release();
372 	}
373 }
374 
375 // Increments refcount on surface.
376 // caller must release() the returned surface
getRenderTarget()377 Image *Colorbuffer::getRenderTarget()
378 {
379 	if(mRenderTarget)
380 	{
381 		mRenderTarget->addRef();
382 	}
383 
384 	return mRenderTarget;
385 }
386 
DepthStencilbuffer(Image * depthStencil)387 DepthStencilbuffer::DepthStencilbuffer(Image *depthStencil) : mDepthStencil(depthStencil)
388 {
389 	if(depthStencil)
390 	{
391 		depthStencil->addRef();
392 
393 		mWidth = depthStencil->getWidth();
394 		mHeight = depthStencil->getHeight();
395 		internalFormat = depthStencil->getInternalFormat();
396 		format = sw2es::ConvertDepthStencilFormat(internalFormat);
397 		mSamples = depthStencil->getMultiSampleDepth() & ~1;
398 	}
399 }
400 
DepthStencilbuffer(int width,int height,GLsizei samples)401 DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples) : mDepthStencil(nullptr)
402 {
403 	Device *device = getDevice();
404 
405 	int supportedSamples = Context::getSupportedMultisampleCount(samples);
406 
407 	if(width > 0 && height > 0)
408 	{
409 		mDepthStencil = device->createDepthStencilSurface(width, height, sw::FORMAT_D24S8, supportedSamples, false);
410 
411 		if(!mDepthStencil)
412 		{
413 			error(GL_OUT_OF_MEMORY);
414 			return;
415 		}
416 	}
417 
418 	mWidth = width;
419 	mHeight = height;
420 	format = GL_DEPTH24_STENCIL8_EXT;
421 	internalFormat = sw::FORMAT_D24S8;
422 	mSamples = supportedSamples;
423 }
424 
~DepthStencilbuffer()425 DepthStencilbuffer::~DepthStencilbuffer()
426 {
427 	if(mDepthStencil)
428 	{
429 		mDepthStencil->release();
430 	}
431 }
432 
433 // Increments refcount on surface.
434 // caller must release() the returned surface
getRenderTarget()435 Image *DepthStencilbuffer::getRenderTarget()
436 {
437 	if(mDepthStencil)
438 	{
439 		mDepthStencil->addRef();
440 	}
441 
442 	return mDepthStencil;
443 }
444 
Depthbuffer(Image * depthStencil)445 Depthbuffer::Depthbuffer(Image *depthStencil) : DepthStencilbuffer(depthStencil)
446 {
447 	if(depthStencil)
448 	{
449 		format = GL_DEPTH_COMPONENT16;   // If the renderbuffer parameters are queried, the calling function
450 		                                 // will expect one of the valid renderbuffer formats for use in
451 		                                 // glRenderbufferStorage
452 	}
453 }
454 
Depthbuffer(int width,int height,GLsizei samples)455 Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
456 {
457 	if(mDepthStencil)
458 	{
459 		format = GL_DEPTH_COMPONENT16;   // If the renderbuffer parameters are queried, the calling function
460 		                                 // will expect one of the valid renderbuffer formats for use in
461 		                                 // glRenderbufferStorage
462 	}
463 }
464 
~Depthbuffer()465 Depthbuffer::~Depthbuffer()
466 {
467 }
468 
Stencilbuffer(Image * depthStencil)469 Stencilbuffer::Stencilbuffer(Image *depthStencil) : DepthStencilbuffer(depthStencil)
470 {
471 	if(depthStencil)
472 	{
473 		format = GL_STENCIL_INDEX8;   // If the renderbuffer parameters are queried, the calling function
474 		                              // will expect one of the valid renderbuffer formats for use in
475 		                              // glRenderbufferStorage
476 	}
477 }
478 
Stencilbuffer(int width,int height,GLsizei samples)479 Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
480 {
481 	if(mDepthStencil)
482 	{
483 		format = GL_STENCIL_INDEX8;   // If the renderbuffer parameters are queried, the calling function
484 		                              // will expect one of the valid renderbuffer formats for use in
485 		                              // glRenderbufferStorage
486 	}
487 }
488 
~Stencilbuffer()489 Stencilbuffer::~Stencilbuffer()
490 {
491 }
492 
493 }
494