blob: 6fcb9df712c34e7bec79f056067eb1178d8aa76d [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// Framebuffer.cpp: Implements the Framebuffer class. Implements GL framebuffer
16// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
17
18#include "Framebuffer.h"
19
20#include "main.h"
21#include "Renderbuffer.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{
27
28Framebuffer::Framebuffer()
29{
Nicolas Capens11157822014-10-23 23:00:29 -040030 mColorbufferType = GL_NONE_OES;
31 mDepthbufferType = GL_NONE_OES;
32 mStencilbufferType = GL_NONE_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040033}
34
35Framebuffer::~Framebuffer()
36{
Nicolas Capens9240dac2016-03-22 10:44:57 -040037 mColorbufferPointer = nullptr;
38 mDepthbufferPointer = nullptr;
39 mStencilbufferPointer = nullptr;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040040}
41
Nicolas Capens0ccc71d2018-03-23 10:13:06 -040042Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle, GLint level) const
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040043{
44 Context *context = getContext();
Nicolas Capens9240dac2016-03-22 10:44:57 -040045 Renderbuffer *buffer = nullptr;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040046
Nicolas Capens11157822014-10-23 23:00:29 -040047 if(type == GL_NONE_OES)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040048 {
Nicolas Capens9240dac2016-03-22 10:44:57 -040049 buffer = nullptr;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040050 }
Nicolas Capens11157822014-10-23 23:00:29 -040051 else if(type == GL_RENDERBUFFER_OES)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040052 {
53 buffer = context->getRenderbuffer(handle);
54 }
55 else if(IsTextureTarget(type))
56 {
Nicolas Capens0ccc71d2018-03-23 10:13:06 -040057 buffer = context->getTexture(handle)->getRenderbuffer(type, level);
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040058 }
Nicolas Capens3713cd42015-06-22 10:41:54 -040059 else UNREACHABLE(type);
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040060
61 return buffer;
62}
63
Nicolas Capens0ccc71d2018-03-23 10:13:06 -040064void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer, GLint level)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040065{
Nicolas Capens11157822014-10-23 23:00:29 -040066 mColorbufferType = (colorbuffer != 0) ? type : GL_NONE_OES;
Nicolas Capens0ccc71d2018-03-23 10:13:06 -040067 mColorbufferPointer = lookupRenderbuffer(type, colorbuffer, level);
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040068}
69
Nicolas Capens0ccc71d2018-03-23 10:13:06 -040070void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040071{
Nicolas Capens11157822014-10-23 23:00:29 -040072 mDepthbufferType = (depthbuffer != 0) ? type : GL_NONE_OES;
Nicolas Capens0ccc71d2018-03-23 10:13:06 -040073 mDepthbufferPointer = lookupRenderbuffer(type, depthbuffer, level);
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040074}
75
Nicolas Capens0ccc71d2018-03-23 10:13:06 -040076void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040077{
Nicolas Capens11157822014-10-23 23:00:29 -040078 mStencilbufferType = (stencilbuffer != 0) ? type : GL_NONE_OES;
Nicolas Capens0ccc71d2018-03-23 10:13:06 -040079 mStencilbufferPointer = lookupRenderbuffer(type, stencilbuffer, level);
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040080}
81
82void Framebuffer::detachTexture(GLuint texture)
83{
Nicolas Capens7cc75e12015-01-29 14:44:24 -050084 if(mColorbufferPointer.name() == texture && IsTextureTarget(mColorbufferType))
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040085 {
Nicolas Capens11157822014-10-23 23:00:29 -040086 mColorbufferType = GL_NONE_OES;
Nicolas Capens9240dac2016-03-22 10:44:57 -040087 mColorbufferPointer = nullptr;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040088 }
89
Nicolas Capens7cc75e12015-01-29 14:44:24 -050090 if(mDepthbufferPointer.name() == texture && IsTextureTarget(mDepthbufferType))
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040091 {
Nicolas Capens11157822014-10-23 23:00:29 -040092 mDepthbufferType = GL_NONE_OES;
Nicolas Capens9240dac2016-03-22 10:44:57 -040093 mDepthbufferPointer = nullptr;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040094 }
95
Nicolas Capens7cc75e12015-01-29 14:44:24 -050096 if(mStencilbufferPointer.name() == texture && IsTextureTarget(mStencilbufferType))
Nicolas Capensdbf6fc82014-10-23 13:33:20 -040097 {
Nicolas Capens11157822014-10-23 23:00:29 -040098 mStencilbufferType = GL_NONE_OES;
Nicolas Capens9240dac2016-03-22 10:44:57 -040099 mStencilbufferPointer = nullptr;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400100 }
101}
102
103void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
104{
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500105 if(mColorbufferPointer.name() == renderbuffer && mColorbufferType == GL_RENDERBUFFER_OES)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400106 {
Nicolas Capens11157822014-10-23 23:00:29 -0400107 mColorbufferType = GL_NONE_OES;
Nicolas Capens9240dac2016-03-22 10:44:57 -0400108 mColorbufferPointer = nullptr;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400109 }
110
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500111 if(mDepthbufferPointer.name() == renderbuffer && mDepthbufferType == GL_RENDERBUFFER_OES)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400112 {
Nicolas Capens11157822014-10-23 23:00:29 -0400113 mDepthbufferType = GL_NONE_OES;
Nicolas Capens9240dac2016-03-22 10:44:57 -0400114 mDepthbufferPointer = nullptr;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400115 }
116
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500117 if(mStencilbufferPointer.name() == renderbuffer && mStencilbufferType == GL_RENDERBUFFER_OES)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400118 {
Nicolas Capens11157822014-10-23 23:00:29 -0400119 mStencilbufferType = GL_NONE_OES;
Nicolas Capens9240dac2016-03-22 10:44:57 -0400120 mStencilbufferPointer = nullptr;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400121 }
122}
123
124// Increments refcount on surface.
125// caller must Release() the returned surface
Nicolas Capensead7ac52014-10-27 23:56:02 -0400126egl::Image *Framebuffer::getRenderTarget()
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400127{
Nicolas Capensd7d9b4b2015-01-29 23:46:44 -0500128 Renderbuffer *colorbuffer = mColorbufferPointer;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400129
130 if(colorbuffer)
131 {
132 return colorbuffer->getRenderTarget();
133 }
134
Nicolas Capens9240dac2016-03-22 10:44:57 -0400135 return nullptr;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400136}
137
138// Increments refcount on surface.
139// caller must Release() the returned surface
Nicolas Capens9240dac2016-03-22 10:44:57 -0400140egl::Image *Framebuffer::getDepthBuffer()
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400141{
Nicolas Capens9240dac2016-03-22 10:44:57 -0400142 Renderbuffer *depthbuffer = mDepthbufferPointer;
143
144 if(depthbuffer)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400145 {
Nicolas Capens9240dac2016-03-22 10:44:57 -0400146 return depthbuffer->getRenderTarget();
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400147 }
148
Nicolas Capens9240dac2016-03-22 10:44:57 -0400149 return nullptr;
150}
151
152// Increments refcount on surface.
153// caller must Release() the returned surface
154egl::Image *Framebuffer::getStencilBuffer()
155{
156 Renderbuffer *stencilbuffer = mStencilbufferPointer;
157
158 if(stencilbuffer)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400159 {
Nicolas Capens9240dac2016-03-22 10:44:57 -0400160 return stencilbuffer->getRenderTarget();
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400161 }
162
Nicolas Capens9240dac2016-03-22 10:44:57 -0400163 return nullptr;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400164}
165
166Renderbuffer *Framebuffer::getColorbuffer()
167{
Nicolas Capensd7d9b4b2015-01-29 23:46:44 -0500168 return mColorbufferPointer;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400169}
170
171Renderbuffer *Framebuffer::getDepthbuffer()
172{
Nicolas Capensd7d9b4b2015-01-29 23:46:44 -0500173 return mDepthbufferPointer;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400174}
175
176Renderbuffer *Framebuffer::getStencilbuffer()
177{
Nicolas Capensd7d9b4b2015-01-29 23:46:44 -0500178 return mStencilbufferPointer;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400179}
180
181GLenum Framebuffer::getColorbufferType()
182{
183 return mColorbufferType;
184}
185
186GLenum Framebuffer::getDepthbufferType()
187{
188 return mDepthbufferType;
189}
190
191GLenum Framebuffer::getStencilbufferType()
192{
193 return mStencilbufferType;
194}
195
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500196GLuint Framebuffer::getColorbufferName()
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400197{
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500198 return mColorbufferPointer.name();
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400199}
200
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500201GLuint Framebuffer::getDepthbufferName()
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400202{
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500203 return mDepthbufferPointer.name();
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400204}
205
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500206GLuint Framebuffer::getStencilbufferName()
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400207{
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500208 return mStencilbufferPointer.name();
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400209}
210
211bool Framebuffer::hasStencil()
212{
Nicolas Capens11157822014-10-23 23:00:29 -0400213 if(mStencilbufferType != GL_NONE_OES)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400214 {
215 Renderbuffer *stencilbufferObject = getStencilbuffer();
216
217 if(stencilbufferObject)
218 {
219 return stencilbufferObject->getStencilSize() > 0;
220 }
221 }
222
223 return false;
224}
225
226GLenum Framebuffer::completeness()
227{
228 int width;
229 int height;
230 int samples;
231
232 return completeness(width, height, samples);
233}
234
235GLenum Framebuffer::completeness(int &width, int &height, int &samples)
236{
237 width = -1;
238 height = -1;
239 samples = -1;
240
Nicolas Capens11157822014-10-23 23:00:29 -0400241 if(mColorbufferType != GL_NONE_OES)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400242 {
243 Renderbuffer *colorbuffer = getColorbuffer();
244
245 if(!colorbuffer)
246 {
Nicolas Capens11157822014-10-23 23:00:29 -0400247 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400248 }
249
250 if(colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
251 {
Nicolas Capens11157822014-10-23 23:00:29 -0400252 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400253 }
254
Nicolas Capens11157822014-10-23 23:00:29 -0400255 if(mColorbufferType == GL_RENDERBUFFER_OES)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400256 {
Nicolas Capens69920ad2016-04-14 14:53:24 -0400257 if(!IsColorRenderable(colorbuffer->getFormat()))
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400258 {
Nicolas Capens11157822014-10-23 23:00:29 -0400259 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400260 }
261 }
262 else if(IsTextureTarget(mColorbufferType))
263 {
264 GLenum format = colorbuffer->getFormat();
265
Nicolas Capens69920ad2016-04-14 14:53:24 -0400266 if(!IsColorRenderable(format))
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400267 {
Nicolas Capens69920ad2016-04-14 14:53:24 -0400268 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400269 }
270
Nicolas Capens69920ad2016-04-14 14:53:24 -0400271 if(IsDepthTexture(format) || IsStencilTexture(format))
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400272 {
Nicolas Capens11157822014-10-23 23:00:29 -0400273 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400274 }
275 }
276 else
277 {
Nicolas Capens3713cd42015-06-22 10:41:54 -0400278 UNREACHABLE(mColorbufferType);
Nicolas Capens11157822014-10-23 23:00:29 -0400279 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400280 }
281
282 width = colorbuffer->getWidth();
283 height = colorbuffer->getHeight();
284 samples = colorbuffer->getSamples();
285 }
286
Nicolas Capens9240dac2016-03-22 10:44:57 -0400287 Renderbuffer *depthbuffer = nullptr;
288 Renderbuffer *stencilbuffer = nullptr;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400289
Nicolas Capens11157822014-10-23 23:00:29 -0400290 if(mDepthbufferType != GL_NONE_OES)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400291 {
292 depthbuffer = getDepthbuffer();
293
294 if(!depthbuffer)
295 {
Nicolas Capens11157822014-10-23 23:00:29 -0400296 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400297 }
298
299 if(depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
300 {
Nicolas Capens11157822014-10-23 23:00:29 -0400301 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400302 }
303
Nicolas Capens11157822014-10-23 23:00:29 -0400304 if(mDepthbufferType == GL_RENDERBUFFER_OES)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400305 {
Nicolas Capens14ee7622014-10-28 23:48:41 -0400306 if(!es1::IsDepthRenderable(depthbuffer->getFormat()))
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400307 {
Nicolas Capens11157822014-10-23 23:00:29 -0400308 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400309 }
310 }
311 else if(IsTextureTarget(mDepthbufferType))
312 {
Nicolas Capens14ee7622014-10-28 23:48:41 -0400313 if(!es1::IsDepthTexture(depthbuffer->getFormat()))
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400314 {
Nicolas Capens11157822014-10-23 23:00:29 -0400315 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400316 }
317 }
318 else
319 {
Nicolas Capens3713cd42015-06-22 10:41:54 -0400320 UNREACHABLE(mDepthbufferType);
Nicolas Capens11157822014-10-23 23:00:29 -0400321 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400322 }
323
324 if(width == -1 || height == -1)
325 {
326 width = depthbuffer->getWidth();
327 height = depthbuffer->getHeight();
328 samples = depthbuffer->getSamples();
329 }
330 else if(width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
331 {
Nicolas Capens11157822014-10-23 23:00:29 -0400332 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400333 }
334 else if(samples != depthbuffer->getSamples())
335 {
Nicolas Capens3713cd42015-06-22 10:41:54 -0400336 UNREACHABLE(0);
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400337 }
338 }
339
Nicolas Capens11157822014-10-23 23:00:29 -0400340 if(mStencilbufferType != GL_NONE_OES)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400341 {
342 stencilbuffer = getStencilbuffer();
343
344 if(!stencilbuffer)
345 {
Nicolas Capens11157822014-10-23 23:00:29 -0400346 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400347 }
348
349 if(stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
350 {
Nicolas Capens11157822014-10-23 23:00:29 -0400351 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400352 }
353
Nicolas Capens11157822014-10-23 23:00:29 -0400354 if(mStencilbufferType == GL_RENDERBUFFER_OES)
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400355 {
Nicolas Capens14ee7622014-10-28 23:48:41 -0400356 if(!es1::IsStencilRenderable(stencilbuffer->getFormat()))
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400357 {
Nicolas Capens11157822014-10-23 23:00:29 -0400358 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400359 }
360 }
361 else if(IsTextureTarget(mStencilbufferType))
362 {
363 GLenum internalformat = stencilbuffer->getFormat();
364
Nicolas Capens14ee7622014-10-28 23:48:41 -0400365 if(!es1::IsStencilTexture(internalformat))
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400366 {
Nicolas Capens11157822014-10-23 23:00:29 -0400367 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400368 }
369 }
370 else
371 {
Nicolas Capens3713cd42015-06-22 10:41:54 -0400372 UNREACHABLE(mStencilbufferType);
Nicolas Capens11157822014-10-23 23:00:29 -0400373 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400374 }
375
376 if(width == -1 || height == -1)
377 {
378 width = stencilbuffer->getWidth();
379 height = stencilbuffer->getHeight();
380 samples = stencilbuffer->getSamples();
381 }
382 else if(width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
383 {
Nicolas Capens11157822014-10-23 23:00:29 -0400384 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400385 }
386 else if(samples != stencilbuffer->getSamples())
387 {
Nicolas Capens3713cd42015-06-22 10:41:54 -0400388 UNREACHABLE(0);
Nicolas Capens11157822014-10-23 23:00:29 -0400389 return GL_FRAMEBUFFER_UNSUPPORTED_OES; // GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400390 }
391 }
392
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400393 // We need to have at least one attachment to be complete
394 if(width == -1 || height == -1)
395 {
Nicolas Capens11157822014-10-23 23:00:29 -0400396 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400397 }
398
Nicolas Capens11157822014-10-23 23:00:29 -0400399 return GL_FRAMEBUFFER_COMPLETE_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400400}
401
Nicolas Capenscc863da2015-01-21 15:50:55 -0500402GLenum Framebuffer::getImplementationColorReadFormat()
403{
Nicolas Capensd7d9b4b2015-01-29 23:46:44 -0500404 Renderbuffer *colorbuffer = mColorbufferPointer;
Nicolas Capens9240dac2016-03-22 10:44:57 -0400405
Nicolas Capenscc863da2015-01-21 15:50:55 -0500406 if(colorbuffer)
407 {
Nicolas Capens3b4a25c2018-02-22 20:14:07 -0500408 switch(colorbuffer->getFormat())
Nicolas Capenscc863da2015-01-21 15:50:55 -0500409 {
Nicolas Capens3b4a25c2018-02-22 20:14:07 -0500410 case GL_BGRA8_EXT: return GL_BGRA_EXT;
411 case GL_RGBA4_OES: return GL_RGBA;
412 case GL_RGB5_A1_OES: return GL_RGBA;
413 case GL_RGBA8_OES: return GL_RGBA;
414 case GL_RGB565_OES: return GL_RGBA;
415 case GL_RGB8_OES: return GL_RGB;
Nicolas Capenscc863da2015-01-21 15:50:55 -0500416 default:
Nicolas Capens3b4a25c2018-02-22 20:14:07 -0500417 UNREACHABLE(colorbuffer->getFormat());
Nicolas Capenscc863da2015-01-21 15:50:55 -0500418 }
419 }
420
421 return GL_RGBA;
422}
423
Nicolas Capensdddc4ab2015-01-13 15:49:15 -0500424GLenum Framebuffer::getImplementationColorReadType()
425{
Nicolas Capensd7d9b4b2015-01-29 23:46:44 -0500426 Renderbuffer *colorbuffer = mColorbufferPointer;
Nicolas Capens9240dac2016-03-22 10:44:57 -0400427
Nicolas Capenscc863da2015-01-21 15:50:55 -0500428 if(colorbuffer)
429 {
Nicolas Capens3b4a25c2018-02-22 20:14:07 -0500430 switch(colorbuffer->getFormat())
Nicolas Capenscc863da2015-01-21 15:50:55 -0500431 {
Nicolas Capens3b4a25c2018-02-22 20:14:07 -0500432 case GL_BGRA8_EXT: return GL_UNSIGNED_BYTE;
433 case GL_RGBA4_OES: return GL_UNSIGNED_SHORT_4_4_4_4;
434 case GL_RGB5_A1_OES: return GL_UNSIGNED_SHORT_5_5_5_1;
435 case GL_RGBA8_OES: return GL_UNSIGNED_BYTE;
436 case GL_RGB565_OES: return GL_UNSIGNED_SHORT_5_6_5;
437 case GL_RGB8_OES: return GL_UNSIGNED_BYTE;
Nicolas Capenscc863da2015-01-21 15:50:55 -0500438 default:
Nicolas Capens3b4a25c2018-02-22 20:14:07 -0500439 UNREACHABLE(colorbuffer->getFormat());
Nicolas Capenscc863da2015-01-21 15:50:55 -0500440 }
Nicolas Capens9703d1a2015-01-14 15:55:33 -0500441 }
442
443 return GL_UNSIGNED_BYTE;
Nicolas Capensdddc4ab2015-01-13 15:49:15 -0500444}
445
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400446DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
447{
Nicolas Capensd7d9b4b2015-01-29 23:46:44 -0500448 mColorbufferPointer = new Renderbuffer(0, colorbuffer);
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400449
450 Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(0, depthStencil);
Nicolas Capensd7d9b4b2015-01-29 23:46:44 -0500451 mDepthbufferPointer = depthStencilRenderbuffer;
452 mStencilbufferPointer = depthStencilRenderbuffer;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400453
Nicolas Capens11157822014-10-23 23:00:29 -0400454 mColorbufferType = GL_RENDERBUFFER_OES;
455 mDepthbufferType = (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_RENDERBUFFER_OES : GL_NONE_OES;
456 mStencilbufferType = (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_RENDERBUFFER_OES : GL_NONE_OES;
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400457}
458
Nicolas Capensdbf6fc82014-10-23 13:33:20 -0400459}