blob: 9d44c6feaef973943e234a6406698661ec745ba4 [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
119IDirect3DSurface9 *Framebuffer::getDepthStencil()
120{
121 gl::Context *context = gl::getContext();
122 Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000123
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000124 if (depthbuffer)
125 {
126 return depthbuffer->getDepthStencil();
127 }
128
129 return NULL;
130}
131
132Colorbuffer *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
159Depthbuffer *Framebuffer::getDepthbuffer()
160{
161 gl::Context *context = gl::getContext();
162 Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000163
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000164 if (depthbuffer && depthbuffer->isDepthbuffer())
165 {
166 return depthbuffer;
167 }
168
169 return NULL;
170}
171
172Stencilbuffer *Framebuffer::getStencilbuffer()
173{
174 gl::Context *context = gl::getContext();
175 Stencilbuffer *stencilbuffer = context->getStencilbuffer(mStencilbufferHandle);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000176
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000177 if (stencilbuffer && stencilbuffer->isStencilbuffer())
178 {
179 return stencilbuffer;
180 }
181
182 return NULL;
183}
184
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +0000185GLenum Framebuffer::getColorbufferType()
186{
187 return mColorbufferType;
188}
189
190GLenum Framebuffer::getDepthbufferType()
191{
192 return mDepthbufferType;
193}
194
195GLenum Framebuffer::getStencilbufferType()
196{
197 return mStencilbufferType;
198}
199
200GLuint Framebuffer::getColorbufferHandle()
201{
202 return mColorbufferHandle;
203}
204
205GLuint Framebuffer::getDepthbufferHandle()
206{
207 return mDepthbufferHandle;
208}
209
210GLuint Framebuffer::getStencilbufferHandle()
211{
212 return mStencilbufferHandle;
213}
214
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000215GLenum Framebuffer::completeness()
216{
217 gl::Context *context = gl::getContext();
218
219 int width = 0;
220 int height = 0;
221
222 if (mColorbufferType != GL_NONE)
223 {
224 Colorbuffer *colorbuffer = getColorbuffer();
225
226 if (!colorbuffer)
227 {
228 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
229 }
230
231 if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
232 {
233 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
234 }
235
236 width = colorbuffer->getWidth();
237 height = colorbuffer->getHeight();
238 }
239
240 if (mDepthbufferType != GL_NONE)
241 {
242 Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
243
244 if (!depthbuffer)
245 {
246 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
247 }
248
249 if (depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
250 {
251 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
252 }
253
254 if (width == 0)
255 {
256 width = depthbuffer->getWidth();
257 height = depthbuffer->getHeight();
258 }
259 else if (width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
260 {
261 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
262 }
263 }
264
265 if (mStencilbufferType != GL_NONE)
266 {
267 Stencilbuffer *stencilbuffer = context->getStencilbuffer(mStencilbufferHandle);
268
269 if (!stencilbuffer)
270 {
271 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
272 }
273
274 if (stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
275 {
276 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
277 }
278
279 if (width == 0)
280 {
281 width = stencilbuffer->getWidth();
282 height = stencilbuffer->getHeight();
283 }
284 else if (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
285 {
286 return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
287 }
288 }
289
290 return GL_FRAMEBUFFER_COMPLETE;
291}
292}