blob: 68094d887a369e17d95003a4046e73fc049d0240 [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
Nicolas Capensdbf6fc82014-10-23 13:33:20 -04002//
Nicolas Capens0bac2852016-05-07 06:09:58 -04003// 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
Nicolas Capensdbf6fc82014-10-23 13:33:20 -04006//
Nicolas Capens0bac2852016-05-07 06:09:58 -04007// http://www.apache.org/licenses/LICENSE-2.0
Nicolas Capensdbf6fc82014-10-23 13:33:20 -04008//
Nicolas Capens0bac2852016-05-07 06:09:58 -04009// 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.
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040014
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
Nicolas Capens14ee7622014-10-28 23:48:41 -040025namespace es1
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040026{
27RenderbufferInterface::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
Nicolas Capens0bac2852016-05-07 06:09:58 -040033// or decrementing.
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040034void RenderbufferInterface::addProxyRef(const Renderbuffer *proxy)
35{
36}
37
38void RenderbufferInterface::releaseProxy(const Renderbuffer *proxy)
39{
40}
41
42GLuint RenderbufferInterface::getRedSize() const
43{
Nicolas Capens3b4a25c2018-02-22 20:14:07 -050044 return GetRedSize(getFormat());
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040045}
46
47GLuint RenderbufferInterface::getGreenSize() const
48{
Nicolas Capens3b4a25c2018-02-22 20:14:07 -050049 return GetGreenSize(getFormat());
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040050}
51
52GLuint RenderbufferInterface::getBlueSize() const
53{
Nicolas Capens3b4a25c2018-02-22 20:14:07 -050054 return GetBlueSize(getFormat());
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040055}
56
57GLuint RenderbufferInterface::getAlphaSize() const
58{
Nicolas Capens3b4a25c2018-02-22 20:14:07 -050059 return GetAlphaSize(getFormat());
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040060}
61
62GLuint RenderbufferInterface::getDepthSize() const
63{
Nicolas Capens3b4a25c2018-02-22 20:14:07 -050064 return GetDepthSize(getFormat());
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040065}
66
67GLuint RenderbufferInterface::getStencilSize() const
68{
Nicolas Capens3b4a25c2018-02-22 20:14:07 -050069 return GetStencilSize(getFormat());
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040070}
71
72///// RenderbufferTexture2D Implementation ////////
73
Nicolas Capens0ccc71d2018-03-23 10:13:06 -040074RenderbufferTexture2D::RenderbufferTexture2D(Texture2D *texture, GLint level) : mLevel(level)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040075{
Nicolas Capensd7d9b4b2015-01-29 23:46:44 -050076 mTexture2D = texture;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040077}
78
79RenderbufferTexture2D::~RenderbufferTexture2D()
80{
Nicolas Capens0bac2852016-05-07 06:09:58 -040081 mTexture2D = nullptr;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040082}
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.
86void RenderbufferTexture2D::addProxyRef(const Renderbuffer *proxy)
87{
Nicolas Capens0bac2852016-05-07 06:09:58 -040088 mTexture2D->addProxyRef(proxy);
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040089}
90
91void RenderbufferTexture2D::releaseProxy(const Renderbuffer *proxy)
92{
Nicolas Capens0bac2852016-05-07 06:09:58 -040093 mTexture2D->releaseProxy(proxy);
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040094}
95
96// Increments refcount on image.
97// caller must release() the returned image
Nicolas Capensead7ac52014-10-27 23:56:02 -040098egl::Image *RenderbufferTexture2D::getRenderTarget()
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040099{
100 return mTexture2D->getRenderTarget(GL_TEXTURE_2D, 0);
101}
102
103// Increments refcount on image.
104// caller must release() the returned image
Nicolas Capensead7ac52014-10-27 23:56:02 -0400105egl::Image *RenderbufferTexture2D::createSharedImage()
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400106{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400107 return mTexture2D->createSharedImage(GL_TEXTURE_2D, 0);
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400108}
109
110bool RenderbufferTexture2D::isShared() const
111{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400112 return mTexture2D->isShared(GL_TEXTURE_2D, 0);
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400113}
114
115GLsizei RenderbufferTexture2D::getWidth() const
116{
117 return mTexture2D->getWidth(GL_TEXTURE_2D, 0);
118}
119
120GLsizei RenderbufferTexture2D::getHeight() const
121{
122 return mTexture2D->getHeight(GL_TEXTURE_2D, 0);
123}
124
Nicolas Capens3e5f6fd2018-02-26 17:47:06 -0500125GLint RenderbufferTexture2D::getFormat() const
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400126{
127 return mTexture2D->getFormat(GL_TEXTURE_2D, 0);
128}
129
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400130GLsizei RenderbufferTexture2D::getSamples() const
131{
132 return 0;
133}
134
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400135////// Renderbuffer Implementation //////
136
Nicolas Capense826ef02015-04-02 14:43:13 -0400137Renderbuffer::Renderbuffer(GLuint name, RenderbufferInterface *instance) : NamedObject(name)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400138{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400139 ASSERT(instance);
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400140 mInstance = instance;
141}
142
143Renderbuffer::~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.
150void Renderbuffer::addRef()
151{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400152 mInstance->addProxyRef(this);
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400153
Nicolas Capens0bac2852016-05-07 06:09:58 -0400154 Object::addRef();
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400155}
156
157void Renderbuffer::release()
158{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400159 mInstance->releaseProxy(this);
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400160
Nicolas Capens0bac2852016-05-07 06:09:58 -0400161 Object::release();
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400162}
163
164// Increments refcount on image.
165// caller must Release() the returned image
Nicolas Capensead7ac52014-10-27 23:56:02 -0400166egl::Image *Renderbuffer::getRenderTarget()
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400167{
168 return mInstance->getRenderTarget();
169}
170
171// Increments refcount on image.
172// caller must Release() the returned image
Nicolas Capensead7ac52014-10-27 23:56:02 -0400173egl::Image *Renderbuffer::createSharedImage()
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400174{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400175 return mInstance->createSharedImage();
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400176}
177
178bool Renderbuffer::isShared() const
179{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400180 return mInstance->isShared();
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400181}
182
183GLsizei Renderbuffer::getWidth() const
184{
185 return mInstance->getWidth();
186}
187
188GLsizei Renderbuffer::getHeight() const
189{
190 return mInstance->getHeight();
191}
192
Nicolas Capens0ccc71d2018-03-23 10:13:06 -0400193GLint Renderbuffer::getLevel() const
194{
195 return mInstance->getLevel();
196}
197
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400198GLenum Renderbuffer::getFormat() const
199{
200 return mInstance->getFormat();
201}
202
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400203GLuint Renderbuffer::getRedSize() const
204{
205 return mInstance->getRedSize();
206}
207
208GLuint Renderbuffer::getGreenSize() const
209{
210 return mInstance->getGreenSize();
211}
212
213GLuint Renderbuffer::getBlueSize() const
214{
215 return mInstance->getBlueSize();
216}
217
218GLuint Renderbuffer::getAlphaSize() const
219{
220 return mInstance->getAlphaSize();
221}
222
223GLuint Renderbuffer::getDepthSize() const
224{
225 return mInstance->getDepthSize();
226}
227
228GLuint Renderbuffer::getStencilSize() const
229{
230 return mInstance->getStencilSize();
231}
232
233GLsizei Renderbuffer::getSamples() const
234{
235 return mInstance->getSamples();
236}
237
Nicolas Capens0ccc71d2018-03-23 10:13:06 -0400238void Renderbuffer::setLevel(GLint level)
239{
240 return mInstance->setLevel(level);
241}
242
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400243void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
244{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400245 ASSERT(newStorage);
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400246
247 delete mInstance;
248 mInstance = newStorage;
249}
250
251RenderbufferStorage::RenderbufferStorage()
252{
253 mWidth = 0;
254 mHeight = 0;
Nicolas Capense65f5642018-02-26 17:47:06 -0500255 format = GL_NONE_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400256 mSamples = 0;
257}
258
259RenderbufferStorage::~RenderbufferStorage()
260{
261}
262
263GLsizei RenderbufferStorage::getWidth() const
264{
265 return mWidth;
266}
267
268GLsizei RenderbufferStorage::getHeight() const
269{
270 return mHeight;
271}
272
Nicolas Capens3e5f6fd2018-02-26 17:47:06 -0500273GLint RenderbufferStorage::getFormat() const
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400274{
275 return format;
276}
277
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400278GLsizei RenderbufferStorage::getSamples() const
279{
280 return mSamples;
281}
282
Nicolas Capensead7ac52014-10-27 23:56:02 -0400283Colorbuffer::Colorbuffer(egl::Image *renderTarget) : mRenderTarget(renderTarget)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400284{
285 if(renderTarget)
286 {
287 renderTarget->addRef();
Nicolas Capens0bac2852016-05-07 06:09:58 -0400288
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400289 mWidth = renderTarget->getWidth();
290 mHeight = renderTarget->getHeight();
Nicolas Capens3b4a25c2018-02-22 20:14:07 -0500291 format = renderTarget->getFormat();
Alexis Hetub027aa92015-01-19 15:56:12 -0500292 mSamples = renderTarget->getDepth() & ~1;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400293 }
294}
295
Nicolas Capens3b4a25c2018-02-22 20:14:07 -0500296Colorbuffer::Colorbuffer(int width, int height, GLenum internalformat, GLsizei samples) : mRenderTarget(nullptr)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400297{
Nicolas Capens3ff330f2015-09-03 16:41:09 -0400298 int supportedSamples = Context::getSupportedMultisampleCount(samples);
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400299
300 if(width > 0 && height > 0)
301 {
Nicolas Capens3b4a25c2018-02-22 20:14:07 -0500302 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);
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400309
310 if(!mRenderTarget)
311 {
312 error(GL_OUT_OF_MEMORY);
313 return;
314 }
315 }
316
317 mWidth = width;
318 mHeight = height;
Nicolas Capens3b4a25c2018-02-22 20:14:07 -0500319 format = internalformat;
Alexis Hetu7a570402015-07-02 13:46:59 -0400320 mSamples = supportedSamples;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400321}
322
323Colorbuffer::~Colorbuffer()
324{
325 if(mRenderTarget)
326 {
327 mRenderTarget->release();
328 }
329}
330
331// Increments refcount on image.
332// caller must release() the returned image
Nicolas Capensead7ac52014-10-27 23:56:02 -0400333egl::Image *Colorbuffer::getRenderTarget()
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400334{
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
Nicolas Capensead7ac52014-10-27 23:56:02 -0400345egl::Image *Colorbuffer::createSharedImage()
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400346{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400347 if(mRenderTarget)
348 {
349 mRenderTarget->addRef();
350 mRenderTarget->markShared();
351 }
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400352
Nicolas Capens0bac2852016-05-07 06:09:58 -0400353 return mRenderTarget;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400354}
355
356bool Colorbuffer::isShared() const
357{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400358 return mRenderTarget->isShared();
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400359}
360
Nicolas Capensead7ac52014-10-27 23:56:02 -0400361DepthStencilbuffer::DepthStencilbuffer(egl::Image *depthStencil) : mDepthStencil(depthStencil)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400362{
363 if(depthStencil)
364 {
365 depthStencil->addRef();
366
367 mWidth = depthStencil->getWidth();
368 mHeight = depthStencil->getHeight();
Nicolas Capens3b4a25c2018-02-22 20:14:07 -0500369 format = depthStencil->getFormat();
Alexis Hetub027aa92015-01-19 15:56:12 -0500370 mSamples = depthStencil->getDepth() & ~1;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400371 }
372}
373
Nicolas Capens3b4a25c2018-02-22 20:14:07 -0500374DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLenum internalformat, GLsizei samples) : mDepthStencil(nullptr)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400375{
Nicolas Capens3ff330f2015-09-03 16:41:09 -0400376 int supportedSamples = Context::getSupportedMultisampleCount(samples);
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400377
378 if(width > 0 && height > 0)
379 {
Nicolas Capens3b4a25c2018-02-22 20:14:07 -0500380 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);
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400387
388 if(!mDepthStencil)
389 {
390 error(GL_OUT_OF_MEMORY);
391 return;
392 }
393 }
394
395 mWidth = width;
396 mHeight = height;
Nicolas Capens3b4a25c2018-02-22 20:14:07 -0500397 format = internalformat;
Alexis Hetu7a570402015-07-02 13:46:59 -0400398 mSamples = supportedSamples;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400399}
400
401DepthStencilbuffer::~DepthStencilbuffer()
402{
403 if(mDepthStencil)
404 {
405 mDepthStencil->release();
406 }
407}
408
409// Increments refcount on image.
410// caller must release() the returned image
Nicolas Capensead7ac52014-10-27 23:56:02 -0400411egl::Image *DepthStencilbuffer::getRenderTarget()
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400412{
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
Nicolas Capensead7ac52014-10-27 23:56:02 -0400423egl::Image *DepthStencilbuffer::createSharedImage()
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400424{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400425 if(mDepthStencil)
426 {
427 mDepthStencil->addRef();
428 mDepthStencil->markShared();
429 }
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400430
Nicolas Capens0bac2852016-05-07 06:09:58 -0400431 return mDepthStencil;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400432}
433
434bool DepthStencilbuffer::isShared() const
435{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400436 return mDepthStencil->isShared();
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400437}
438
Nicolas Capensead7ac52014-10-27 23:56:02 -0400439Depthbuffer::Depthbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400440{
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400441}
442
Nicolas Capens3b4a25c2018-02-22 20:14:07 -0500443Depthbuffer::Depthbuffer(int width, int height, GLenum internalformat, GLsizei samples) : DepthStencilbuffer(width, height, internalformat, samples)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400444{
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400445}
446
447Depthbuffer::~Depthbuffer()
448{
449}
450
Nicolas Capensead7ac52014-10-27 23:56:02 -0400451Stencilbuffer::Stencilbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400452{
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400453}
454
Nicolas Capens3b4a25c2018-02-22 20:14:07 -0500455Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, GL_STENCIL_INDEX8_OES, samples)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400456{
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400457}
458
459Stencilbuffer::~Stencilbuffer()
460{
461}
462
463}