blob: e4d6798bc3810dcf723645930aa62a17c3a097f6 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
2// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Framebuffer.cpp: Implements the gl::Framebuffer class. Implements GL framebuffer
8// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
9
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000010#include "libGLESv2/Framebuffer.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000011
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000012#include "libGLESv2/main.h"
13#include "libGLESv2/Renderbuffer.h"
14#include "libGLESv2/Texture.h"
daniel@transgaming.com93a81472010-04-20 18:52:58 +000015#include "libGLESv2/utilities.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000016
17namespace gl
18{
19Framebuffer::Framebuffer()
20{
21 mColorbufferType = GL_NONE;
22 mColorbufferHandle = 0;
23
24 mDepthbufferType = GL_NONE;
25 mDepthbufferHandle = 0;
26
27 mStencilbufferType = GL_NONE;
28 mStencilbufferHandle = 0;
29}
30
31Framebuffer::~Framebuffer()
32{
33}
34
35void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer)
36{
37 mColorbufferType = type;
38 mColorbufferHandle = colorbuffer;
39}
40
41void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer)
42{
43 mDepthbufferType = type;
44 mDepthbufferHandle = depthbuffer;
45}
46
47void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer)
48{
49 mStencilbufferType = type;
50 mStencilbufferHandle = stencilbuffer;
51}
52
53void Framebuffer::detachTexture(GLuint texture)
54{
daniel@transgaming.com19ffc242010-05-04 03:35:21 +000055 if (mColorbufferHandle == texture && IsTextureTarget(mColorbufferType))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000056 {
57 mColorbufferType = GL_NONE;
58 mColorbufferHandle = 0;
59 }
daniel@transgaming.comfbc09532010-04-26 15:33:41 +000060
daniel@transgaming.com19ffc242010-05-04 03:35:21 +000061 if (mDepthbufferHandle == texture && IsTextureTarget(mDepthbufferType))
daniel@transgaming.comfbc09532010-04-26 15:33:41 +000062 {
63 mDepthbufferType = GL_NONE;
64 mDepthbufferHandle = 0;
65 }
66
daniel@transgaming.com19ffc242010-05-04 03:35:21 +000067 if (mStencilbufferHandle == texture && IsTextureTarget(mStencilbufferType))
daniel@transgaming.comfbc09532010-04-26 15:33:41 +000068 {
69 mStencilbufferType = GL_NONE;
70 mStencilbufferHandle = 0;
71 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000072}
73
74void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
75{
76 if (mColorbufferHandle == renderbuffer && mColorbufferType == GL_RENDERBUFFER)
77 {
78 mColorbufferType = GL_NONE;
79 mColorbufferHandle = 0;
80 }
81
82 if (mDepthbufferHandle == renderbuffer && mDepthbufferType == GL_RENDERBUFFER)
83 {
84 mDepthbufferType = GL_NONE;
85 mDepthbufferHandle = 0;
86 }
87
88 if (mStencilbufferHandle == renderbuffer && mStencilbufferType == GL_RENDERBUFFER)
89 {
90 mStencilbufferType = GL_NONE;
91 mStencilbufferHandle = 0;
92 }
93}
94
daniel@transgaming.com092bd482010-05-12 03:39:36 +000095unsigned int Framebuffer::getRenderTargetSerial()
96{
97 Renderbuffer *colorbuffer = getColorbuffer();
98
99 if (colorbuffer)
100 {
101 return colorbuffer->getSerial();
102 }
103
104 return 0;
105}
106
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000107IDirect3DSurface9 *Framebuffer::getRenderTarget()
108{
109 Renderbuffer *colorbuffer = getColorbuffer();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000110
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000111 if (colorbuffer)
112 {
113 return colorbuffer->getRenderTarget();
114 }
115
116 return NULL;
117}
118
daniel@transgaming.com339ae702010-05-12 03:40:20 +0000119unsigned int Framebuffer::getDepthbufferSerial()
120{
121 gl::Context *context = gl::getContext();
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000122 DepthStencilbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
daniel@transgaming.com339ae702010-05-12 03:40:20 +0000123
124 if (depthbuffer)
125 {
126 return depthbuffer->getSerial();
127 }
128
129 return 0;
130}
131
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000132Colorbuffer *Framebuffer::getColorbuffer()
133{
134 gl::Context *context = gl::getContext();
135 Colorbuffer *colorbuffer = NULL;
136
daniel@transgaming.com93a81472010-04-20 18:52:58 +0000137 if (mColorbufferType == GL_NONE)
138 {
139 UNREACHABLE();
140 colorbuffer = NULL;
141 }
142 else if (mColorbufferType == GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000143 {
144 colorbuffer = context->getColorbuffer(mColorbufferHandle);
145 }
daniel@transgaming.com93a81472010-04-20 18:52:58 +0000146 else
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000147 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +0000148 colorbuffer = context->getTexture(mColorbufferHandle)->getColorbuffer(mColorbufferType);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000149 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000150
151 if (colorbuffer && colorbuffer->isColorbuffer())
152 {
153 return colorbuffer;
154 }
155
156 return NULL;
157}
158
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000159DepthStencilbuffer *Framebuffer::getDepthbuffer()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000160{
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000161 if (mDepthbufferType != GL_NONE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000162 {
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000163 gl::Context *context = gl::getContext();
164 DepthStencilbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
165
166 if (depthbuffer && depthbuffer->isDepthbuffer())
167 {
168 return depthbuffer;
169 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000170 }
171
172 return NULL;
173}
174
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000175DepthStencilbuffer *Framebuffer::getStencilbuffer()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000176{
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000177 if (mStencilbufferType != GL_NONE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000178 {
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000179 gl::Context *context = gl::getContext();
180 DepthStencilbuffer *stencilbuffer = context->getStencilbuffer(mStencilbufferHandle);
181
182 if (stencilbuffer && stencilbuffer->isStencilbuffer())
183 {
184 return stencilbuffer;
185 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000186 }
187
188 return NULL;
189}
190
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000191GLenum Framebuffer::getColorbufferType()
192{
193 return mColorbufferType;
194}
195
196GLenum Framebuffer::getDepthbufferType()
197{
198 return mDepthbufferType;
199}
200
201GLenum Framebuffer::getStencilbufferType()
202{
203 return mStencilbufferType;
204}
205
206GLuint Framebuffer::getColorbufferHandle()
207{
208 return mColorbufferHandle;
209}
210
211GLuint Framebuffer::getDepthbufferHandle()
212{
213 return mDepthbufferHandle;
214}
215
216GLuint Framebuffer::getStencilbufferHandle()
217{
218 return mStencilbufferHandle;
219}
220
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000221GLenum Framebuffer::completeness()
222{
223 gl::Context *context = gl::getContext();
224
225 int width = 0;
226 int height = 0;
227
228 if (mColorbufferType != GL_NONE)
229 {
230 Colorbuffer *colorbuffer = getColorbuffer();
231
232 if (!colorbuffer)
233 {
234 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
235 }
236
237 if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
238 {
239 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
240 }
241
242 width = colorbuffer->getWidth();
243 height = colorbuffer->getHeight();
244 }
245
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000246 DepthStencilbuffer *depthbuffer = NULL;
247 DepthStencilbuffer *stencilbuffer = NULL;
248
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000249 if (mDepthbufferType != GL_NONE)
250 {
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000251 depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000252
253 if (!depthbuffer)
254 {
255 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
256 }
257
258 if (depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
259 {
260 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
261 }
262
263 if (width == 0)
264 {
265 width = depthbuffer->getWidth();
266 height = depthbuffer->getHeight();
267 }
268 else if (width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
269 {
270 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
271 }
272 }
273
274 if (mStencilbufferType != GL_NONE)
275 {
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000276 stencilbuffer = context->getStencilbuffer(mStencilbufferHandle);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000277
278 if (!stencilbuffer)
279 {
280 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
281 }
282
283 if (stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
284 {
285 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
286 }
287
288 if (width == 0)
289 {
290 width = stencilbuffer->getWidth();
291 height = stencilbuffer->getHeight();
292 }
293 else if (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
294 {
295 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
296 }
297 }
298
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +0000299 if (mDepthbufferType == GL_RENDERBUFFER && mStencilbufferType == GL_RENDERBUFFER)
300 {
301 if (depthbuffer->getFormat() != GL_DEPTH24_STENCIL8_OES ||
302 stencilbuffer->getFormat() != GL_DEPTH24_STENCIL8_OES ||
303 depthbuffer->getSerial() != stencilbuffer->getSerial())
304 {
305 return GL_FRAMEBUFFER_UNSUPPORTED;
306 }
307 }
308
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000309 return GL_FRAMEBUFFER_COMPLETE;
310}
311}