blob: 1a3b01e26bbe8a92577eb3fd24bb915b409bc146 [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();
122 Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
123
124 if (depthbuffer)
125 {
126 return depthbuffer->getSerial();
127 }
128
129 return 0;
130}
131
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000132IDirect3DSurface9 *Framebuffer::getDepthStencil()
133{
134 gl::Context *context = gl::getContext();
135 Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000136
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000137 if (depthbuffer)
138 {
139 return depthbuffer->getDepthStencil();
140 }
141
142 return NULL;
143}
144
145Colorbuffer *Framebuffer::getColorbuffer()
146{
147 gl::Context *context = gl::getContext();
148 Colorbuffer *colorbuffer = NULL;
149
daniel@transgaming.com93a81472010-04-20 18:52:58 +0000150 if (mColorbufferType == GL_NONE)
151 {
152 UNREACHABLE();
153 colorbuffer = NULL;
154 }
155 else if (mColorbufferType == GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000156 {
157 colorbuffer = context->getColorbuffer(mColorbufferHandle);
158 }
daniel@transgaming.com93a81472010-04-20 18:52:58 +0000159 else
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000160 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +0000161 colorbuffer = context->getTexture(mColorbufferHandle)->getColorbuffer(mColorbufferType);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000162 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000163
164 if (colorbuffer && colorbuffer->isColorbuffer())
165 {
166 return colorbuffer;
167 }
168
169 return NULL;
170}
171
172Depthbuffer *Framebuffer::getDepthbuffer()
173{
174 gl::Context *context = gl::getContext();
175 Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000176
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000177 if (depthbuffer && depthbuffer->isDepthbuffer())
178 {
179 return depthbuffer;
180 }
181
182 return NULL;
183}
184
185Stencilbuffer *Framebuffer::getStencilbuffer()
186{
187 gl::Context *context = gl::getContext();
188 Stencilbuffer *stencilbuffer = context->getStencilbuffer(mStencilbufferHandle);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000189
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000190 if (stencilbuffer && stencilbuffer->isStencilbuffer())
191 {
192 return stencilbuffer;
193 }
194
195 return NULL;
196}
197
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000198GLenum Framebuffer::getColorbufferType()
199{
200 return mColorbufferType;
201}
202
203GLenum Framebuffer::getDepthbufferType()
204{
205 return mDepthbufferType;
206}
207
208GLenum Framebuffer::getStencilbufferType()
209{
210 return mStencilbufferType;
211}
212
213GLuint Framebuffer::getColorbufferHandle()
214{
215 return mColorbufferHandle;
216}
217
218GLuint Framebuffer::getDepthbufferHandle()
219{
220 return mDepthbufferHandle;
221}
222
223GLuint Framebuffer::getStencilbufferHandle()
224{
225 return mStencilbufferHandle;
226}
227
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000228GLenum Framebuffer::completeness()
229{
230 gl::Context *context = gl::getContext();
231
232 int width = 0;
233 int height = 0;
234
235 if (mColorbufferType != GL_NONE)
236 {
237 Colorbuffer *colorbuffer = getColorbuffer();
238
239 if (!colorbuffer)
240 {
241 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
242 }
243
244 if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
245 {
246 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
247 }
248
249 width = colorbuffer->getWidth();
250 height = colorbuffer->getHeight();
251 }
252
253 if (mDepthbufferType != GL_NONE)
254 {
255 Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
256
257 if (!depthbuffer)
258 {
259 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
260 }
261
262 if (depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
263 {
264 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
265 }
266
267 if (width == 0)
268 {
269 width = depthbuffer->getWidth();
270 height = depthbuffer->getHeight();
271 }
272 else if (width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
273 {
274 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
275 }
276 }
277
278 if (mStencilbufferType != GL_NONE)
279 {
280 Stencilbuffer *stencilbuffer = context->getStencilbuffer(mStencilbufferHandle);
281
282 if (!stencilbuffer)
283 {
284 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
285 }
286
287 if (stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
288 {
289 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
290 }
291
292 if (width == 0)
293 {
294 width = stencilbuffer->getWidth();
295 height = stencilbuffer->getHeight();
296 }
297 else if (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
298 {
299 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
300 }
301 }
302
303 return GL_FRAMEBUFFER_COMPLETE;
304}
305}