|
1 /* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
2 * |
|
3 * Permission is hereby granted, free of charge, to any person obtaining a |
|
4 * copy of this software and associated documentation files (the "Software"), |
|
5 * to deal in the Software without restriction, including without limitation |
|
6 * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
|
7 * and/or sell copies of the Software, and to permit persons to whom the |
|
8 * Software is furnished to do so, subject to the following conditions: |
|
9 * |
|
10 * The above copyright notice and this permission notice shall be included |
|
11 * in all copies or substantial portions of the Software. |
|
12 * |
|
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
|
14 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|
16 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
|
17 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
|
18 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
19 * |
|
20 * Initial Contributors: |
|
21 * Nokia Corporation - initial contribution. |
|
22 * |
|
23 * Contributors: |
|
24 * |
|
25 * Description: |
|
26 * |
|
27 */ |
|
28 |
|
29 #include "common.h" |
|
30 #include "hgl.h" |
|
31 #include "context.h" |
|
32 |
|
33 DGLRenderbuffer* DGLRenderbuffer_create(GLuint name) |
|
34 { |
|
35 DGLRenderbuffer* buffer = malloc(sizeof(DGLRenderbuffer)); |
|
36 if(buffer == NULL) |
|
37 { |
|
38 return NULL; |
|
39 } |
|
40 |
|
41 buffer->obj.name = name; |
|
42 buffer->obj.next = NULL; |
|
43 |
|
44 buffer->egl_image = NULL; |
|
45 |
|
46 return buffer; |
|
47 } |
|
48 |
|
49 void DGLRenderbuffer_destroy(DGLRenderbuffer *buffer) |
|
50 { |
|
51 DGLES2_ASSERT(buffer != NULL); |
|
52 if(buffer->egl_image != NULL) |
|
53 { |
|
54 deglUnregisterImageTarget(buffer->egl_image, GL_RENDERBUFFER, buffer->obj.name); |
|
55 buffer->egl_image = NULL; |
|
56 } |
|
57 free(buffer); |
|
58 } |
|
59 |
|
60 GL_APICALL_BUILD void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer) |
|
61 { |
|
62 DGLES2_ENTER(); |
|
63 DGLContext_getHostError(ctx); |
|
64 ctx->hgl.BindFramebufferEXT(target, framebuffer); |
|
65 if(DGLContext_getHostError(ctx) == GL_NO_ERROR) |
|
66 { |
|
67 ctx->framebuffer_binding = framebuffer; |
|
68 } |
|
69 DGLES2_LEAVE(); |
|
70 } |
|
71 |
|
72 GL_APICALL_BUILD void GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer) |
|
73 { |
|
74 DGLES2_ENTER(); |
|
75 DGLContext_getHostError(ctx); |
|
76 ctx->hgl.BindRenderbufferEXT(target, renderbuffer); |
|
77 if(DGLContext_getHostError(ctx) == GL_NO_ERROR) |
|
78 { |
|
79 if(!DGLContext_bindRenderbuffer(ctx, renderbuffer)) |
|
80 { |
|
81 DGLES2_ERROR(GL_OUT_OF_MEMORY); |
|
82 } |
|
83 } |
|
84 DGLES2_LEAVE_NO_ERROR_CHECK(); |
|
85 } |
|
86 |
|
87 GL_APICALL_BUILD GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target) |
|
88 { |
|
89 DGLES2_ENTER_RET(GL_FALSE); |
|
90 DGLES2_LEAVE_RET(ctx->hgl.CheckFramebufferStatusEXT(target)); |
|
91 } |
|
92 |
|
93 GL_APICALL_BUILD void GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) |
|
94 { |
|
95 DGLES2_ENTER(); |
|
96 DGLContext_getHostError(ctx); |
|
97 ctx->hgl.DeleteFramebuffersEXT(n, framebuffers); |
|
98 if(DGLContext_getHostError(ctx) == GL_NO_ERROR) |
|
99 { |
|
100 // Unbind framebuffer when deleted. |
|
101 int i; |
|
102 for(i = 0; i < n; i++) |
|
103 { |
|
104 if(ctx->framebuffer_binding == framebuffers[i]) |
|
105 { |
|
106 ctx->framebuffer_binding = 0; |
|
107 break; |
|
108 } |
|
109 } |
|
110 } |
|
111 DGLES2_LEAVE_NO_ERROR_CHECK(); |
|
112 } |
|
113 |
|
114 GL_APICALL_BUILD void GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) |
|
115 { |
|
116 DGLES2_ENTER(); |
|
117 DGLContext_getHostError(ctx); |
|
118 ctx->hgl.DeleteRenderbuffersEXT(n, renderbuffers); |
|
119 if(DGLContext_getHostError(ctx) == GL_NO_ERROR) |
|
120 { |
|
121 int i; |
|
122 for(i = 0; i < n; i++) |
|
123 { |
|
124 DGLContext_destroyRenderbuffer(ctx, renderbuffers[n]); |
|
125 } |
|
126 } |
|
127 DGLES2_LEAVE(); |
|
128 } |
|
129 |
|
130 GL_APICALL_BUILD void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) |
|
131 { |
|
132 DGLES2_ENTER(); |
|
133 DGLES2_ERROR_IF(attachment != GL_COLOR_ATTACHMENT0 && |
|
134 attachment != GL_DEPTH_ATTACHMENT && |
|
135 attachment != GL_STENCIL_ATTACHMENT, |
|
136 GL_INVALID_ENUM); |
|
137 ctx->hgl.FramebufferRenderbufferEXT(target, attachment, renderbuffertarget, renderbuffer); |
|
138 DGLES2_LEAVE(); |
|
139 } |
|
140 |
|
141 GL_APICALL_BUILD void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) |
|
142 { |
|
143 DGLES2_ENTER(); |
|
144 DGLES2_ERROR_IF(attachment != GL_COLOR_ATTACHMENT0 && |
|
145 attachment != GL_DEPTH_ATTACHMENT && |
|
146 attachment != GL_STENCIL_ATTACHMENT, |
|
147 GL_INVALID_ENUM); |
|
148 ctx->hgl.FramebufferTexture2DEXT(target, attachment, textarget, texture, level); |
|
149 DGLES2_LEAVE(); |
|
150 } |
|
151 |
|
152 GL_APICALL_BUILD void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers) |
|
153 { |
|
154 DGLES2_ENTER(); |
|
155 ctx->hgl.GenFramebuffersEXT(n, framebuffers); |
|
156 DGLES2_LEAVE(); |
|
157 } |
|
158 |
|
159 GL_APICALL_BUILD void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) |
|
160 { |
|
161 DGLES2_ENTER(); |
|
162 ctx->hgl.GenRenderbuffersEXT(n, renderbuffers); |
|
163 DGLES2_LEAVE(); |
|
164 } |
|
165 |
|
166 GL_APICALL_BUILD void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) |
|
167 { |
|
168 DGLES2_ENTER(); |
|
169 DGLES2_ERROR_IF(attachment != GL_COLOR_ATTACHMENT0 && |
|
170 attachment != GL_DEPTH_ATTACHMENT && |
|
171 attachment != GL_STENCIL_ATTACHMENT, |
|
172 GL_INVALID_ENUM); |
|
173 DGLES2_ERROR_IF(pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE && |
|
174 pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME && |
|
175 pname != GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL && |
|
176 pname != GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, |
|
177 GL_INVALID_ENUM); |
|
178 ctx->hgl.GetFramebufferAttachmentParameterivEXT(target, attachment, pname, params); |
|
179 DGLES2_LEAVE(); |
|
180 } |
|
181 |
|
182 GL_APICALL_BUILD void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) |
|
183 { |
|
184 DGLES2_ENTER(); |
|
185 ctx->hgl.GetRenderbufferParameterivEXT(target, pname, params); |
|
186 DGLES2_LEAVE(); |
|
187 } |
|
188 |
|
189 GL_APICALL_BUILD GLboolean GL_APIENTRY glIsFramebuffer(GLuint framebuffer) |
|
190 { |
|
191 DGLES2_ENTER_RET(GL_FALSE); |
|
192 ctx->hgl.IsFramebufferEXT(framebuffer); |
|
193 DGLES2_LEAVE_RET(GL_FALSE); |
|
194 } |
|
195 |
|
196 GL_APICALL_BUILD GLboolean GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer) |
|
197 { |
|
198 DGLES2_ENTER_RET(GL_FALSE); |
|
199 ctx->hgl.IsRenderbufferEXT(renderbuffer); |
|
200 DGLES2_LEAVE_RET(GL_FALSE); |
|
201 } |
|
202 |
|
203 GL_APICALL_BUILD void GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) |
|
204 { |
|
205 DGLES2_ENTER(); |
|
206 |
|
207 switch(internalformat) |
|
208 { |
|
209 case GL_DEPTH_COMPONENT16: |
|
210 case GL_RGBA4: |
|
211 case GL_RGB5_A1: |
|
212 case GL_STENCIL_INDEX8: |
|
213 break; |
|
214 |
|
215 case GL_RGB565: // RGB565 is not supported in desktop GL. |
|
216 internalformat = GL_RGB8; |
|
217 break; |
|
218 |
|
219 case GL_DEPTH_COMPONENT24_OES: // extension GL_OES_depth24 |
|
220 internalformat = GL_DEPTH_COMPONENT24; |
|
221 break; |
|
222 |
|
223 case GL_DEPTH_COMPONENT32_OES: // extension GL_OES_depth32 |
|
224 internalformat = GL_DEPTH_COMPONENT32; |
|
225 break; |
|
226 |
|
227 case GL_RGB8_OES: // extension GL_OES_rgb8_rgba8 |
|
228 internalformat = GL_RGB8; |
|
229 break; |
|
230 |
|
231 case GL_RGBA8_OES: // extension GL_OES_rgb8_rgba8 |
|
232 internalformat = GL_RGBA8; |
|
233 break; |
|
234 } |
|
235 |
|
236 DGLContext_getHostError(ctx); |
|
237 ctx->hgl.RenderbufferStorageEXT(target, internalformat, width, height); |
|
238 if(DGLContext_getHostError(ctx) == GL_NO_ERROR) |
|
239 { |
|
240 DGLRenderbuffer* buffer = DGLContext_findRenderbuffer(ctx, ctx->renderbuffer_binding); |
|
241 DGLES2_ASSERT(buffer != NULL); |
|
242 if(buffer->egl_image != NULL) |
|
243 { |
|
244 // Renderbuffer is respecified. It is no longer an EGLImage sibling. |
|
245 deglUnregisterImageTarget(buffer->egl_image, GL_RENDERBUFFER, buffer->obj.name); |
|
246 buffer->egl_image = NULL; |
|
247 } |
|
248 } |
|
249 |
|
250 DGLES2_LEAVE_NO_ERROR_CHECK(); |
|
251 } |
|
252 |
|
253 GL_APICALL_BUILD void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image) |
|
254 { |
|
255 DGLES2_ENTER(); |
|
256 DGLES2_ERROR_IF(target != GL_RENDERBUFFER, GL_INVALID_ENUM); |
|
257 DGLES2_ERROR_IF(image == NULL, GL_INVALID_OPERATION); |
|
258 DGLContext_getHostError(ctx); |
|
259 if(!DGLContext_specifyRenderbufferFromEGLImage(ctx, image)) |
|
260 { |
|
261 DGLES2_ERROR(GL_INVALID_OPERATION); |
|
262 } |
|
263 DGLES2_LEAVE_NO_ERROR_CHECK(); |
|
264 } |