2 * Copyright (C) 2010 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5 * DongKyun Yun <dk77.yun@samsung.com>
6 * SangJin Kim <sangjin3.kim@samsung.com>
7 * HyunGoo Kang <hyungoo1.kang@samsung.com>
9 * Permission is hereby granted, free of charge, to any person obtaining a copy of
10 * this software and associated documentation files (the "Software"), to deal in
11 * the Software without restriction, including without limitation the rights to
12 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
13 * of the Software, and to permit persons to whom the Software is furnished to do
14 * so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included in all
17 * copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36 void GL_APIENTRY ES2INTER(ProgramObjectInit)(struct ProgramObjectUnit* pUnit) {
37 pUnit->bLinkStatus = GL_FALSE;
38 pUnit->strInfoLog = NULL;
41 void GL_APIENTRY ES2INTER(ProgramObjectRelease)(struct ProgramObjectUnit* pUnit) {
43 if (pUnit->strInfoLog != NULL) {
44 free(pUnit->strInfoLog);
46 pUnit->bLinkStatus = GL_FALSE;
47 pUnit->strInfoLog = NULL;
50 void GL_APIENTRY ES2INTER(ProgramObjectInfoLogReset)(struct ProgramObjectUnit* pUnit) {
51 pUnit->strInfoLog = realloc(pUnit->strInfoLog, 1024 * sizeof(GLchar));
52 assert(pUnit->strInfoLog != NULL);
53 pUnit->strInfoLog[0] = '\0';
56 void GL_APIENTRY ES2INTER(ProgramObjectInfoLogAppend)(struct ProgramObjectUnit* pUnit,
57 const char* format, ...) {
58 static char cBuf[1024];
62 vsnprintf(cBuf, 1024, format, ap);
63 if (pUnit->strInfoLog == NULL) {
64 pUnit->strInfoLog = realloc(pUnit->strInfoLog, 1024 * sizeof(GLchar));
65 assert(pUnit->strInfoLog != NULL);
66 pUnit->strInfoLog[0] = '\0';
68 len = strlen(pUnit->strInfoLog) + strlen(cBuf);
69 pUnit->strInfoLog = realloc(pUnit->strInfoLog, (len + 1) * sizeof(GLchar));
70 assert(pUnit->strInfoLog != NULL);
71 strcat(pUnit->strInfoLog, cBuf);
75 GLuint GL_APIENTRY ES2ENTRY(CreateProgram)(void) {
76 register GLuint uResult;
77 register GLint nAllocated;
79 uResult = FNPTR(CreateProgram)();
80 nAllocated = CCV(nProgramObjectAllocated);
81 while (nAllocated <= uResult) {
84 if (CCV(nProgramObjectAllocated) < nAllocated) {
85 register struct ProgramObjectUnit* pUnit = realloc(CCV(pProgramObject),
86 nAllocated * sizeof(struct ProgramObjectUnit));
87 assert(pUnit != NULL);
88 for (i = CCV(nProgramObjectAllocated); i < nAllocated; i++) {
89 ES2INTER(ProgramObjectInit)(&(pUnit[i]));
91 CCV(pProgramObject) = pUnit;
92 CCV(nProgramObjectAllocated) = nAllocated;
97 void GL_APIENTRY ES2ENTRY(DeleteProgram)(GLuint program) {
100 } else if (FNPTR(IsProgram) != NULL && FNPTR(IsProgram)(program) == GL_FALSE) {
101 ES2INTER(SetError)(GL_INVALID_VALUE);
104 if (CCV(nProgramObjectAllocated) == NULL) {
105 ES2INTER(SetError)(GL_INVALID_VALUE);
109 if (program < CCV(nProgramObjectAllocated)) {
110 GLint nAttachedShaders = 0;
111 FNPTR(GetProgramiv)(program, GL_ATTACHED_SHADERS, &nAttachedShaders);
112 if (nAttachedShaders > 0) {
113 GLuint* pAttachedShaders = NULL;
115 pAttachedShaders = (GLuint*)realloc(pAttachedShaders,
116 nAttachedShaders * sizeof(GLuint));
117 assert(pAttachedShaders != NULL);
118 FNPTR(GetAttachedShaders)(program, nAttachedShaders, &i, pAttachedShaders);
119 assert(nAttachedShaders == i);
120 for (i = 0; i < nAttachedShaders; i++) {
121 int index = pAttachedShaders[i];
122 if (index < CCV(nShaderObjectAllocated)) {
123 struct ShaderObjectUnit* pShader = &(CCV(pShaderObject)[index]);
124 if (pShader->nAttached > 0) pShader->nAttached--;
125 if (pShader->bDeleteStatus == GL_TRUE && pShader->nAttached == 0) {
126 ES2INTER(ShaderObjectRelease)(pShader);
131 ES2INTER(ProgramObjectRelease)(&(CCV(pProgramObject)[program]));
133 FNPTR(DeleteProgram)(program);
136 GLboolean GL_APIENTRY ES2ENTRY(IsProgram)(GLuint program) {
137 register GLboolean bResult;
138 bResult = FNPTR(IsProgram)(program);
142 void GL_APIENTRY ES2ENTRY(AttachShader)(GLuint program, GLuint shader) {
143 struct ShaderObjectUnit* pShader;
144 if ((GLint)(program) <= 0) {
145 ES2INTER(SetError)(GL_INVALID_VALUE);
147 } else if (FNPTR(IsProgram)(program) == GL_FALSE) {
149 ES2INTER(SetError)(GL_INVALID_VALUE);
151 ES2INTER(SetError)(GL_INVALID_OPERATION);
155 if ((GLint)(shader) <= 0) {
156 ES2INTER(SetError)(GL_INVALID_VALUE);
158 } else if (FNPTR(IsShader)(shader) == GL_FALSE) {
159 ES2INTER(SetError)(GL_INVALID_OPERATION);
162 FNPTR(AttachShader)(program, shader);
163 pShader = &(CCV(pShaderObject)[shader]);
164 pShader->nAttached++;
167 void GL_APIENTRY ES2ENTRY(DetachShader)(GLuint program, GLuint shader) {
168 struct ShaderObjectUnit* pShader;
169 if ((GLint)(program) <= 0) {
170 ES2INTER(SetError)(GL_INVALID_VALUE);
172 } else if (FNPTR(IsProgram) != NULL && FNPTR(IsProgram)(program) == GL_FALSE) {
173 ES2INTER(SetError)(GL_INVALID_OPERATION);
176 if ((GLint)(shader) <= 0) {
177 ES2INTER(SetError)(GL_INVALID_VALUE);
179 } else if (FNPTR(IsShader) != NULL && FNPTR(IsShader)(shader) == GL_FALSE) {
180 ES2INTER(SetError)(GL_INVALID_OPERATION);
183 if (FNPTR(DetachShader) != NULL)
184 FNPTR(DetachShader)(program, shader);
185 if (CCV(pShaderObject) != NULL) {
186 pShader = &(CCV(pShaderObject)[shader]);
187 if (pShader->nAttached > 0)
188 pShader->nAttached--;
189 if (pShader->nAttached == 0 && pShader->bDeleteStatus == GL_TRUE)
190 ES2INTER(ShaderObjectRelease)(pShader);
194 void GL_APIENTRY ES2ENTRY(GetAttachedShaders)(GLuint program,
195 GLsizei maxcount, GLsizei* count, GLuint* shaders) {
196 if ((GLint)(program) <= 0) {
197 ES2INTER(SetError)(GL_INVALID_VALUE);
199 } else if (FNPTR(IsProgram)(program) == GL_FALSE) {
200 ES2INTER(SetError)(GL_INVALID_OPERATION);
204 ES2INTER(SetError)(GL_INVALID_VALUE);
207 FNPTR(GetAttachedShaders)(program, maxcount, count, shaders);
210 void GL_APIENTRY ES2ENTRY(LinkProgram)(GLuint program) {
211 struct ProgramObjectUnit* pUnit;
212 int nAttachedShaders;
215 int nVertexShader = 0;
216 int nFragmentShader = 0;
217 if ((GLint)(program) <= 0) {
218 ES2INTER(SetError)(GL_INVALID_VALUE);
220 } else if (FNPTR(IsProgram)(program) == GL_FALSE) {
221 ES2INTER(SetError)(GL_INVALID_OPERATION);
224 FNPTR(GetProgramiv)(program, GL_ATTACHED_SHADERS, &nAttachedShaders);
226 assert(program < CCV(nProgramObjectAllocated));
227 pUnit = &(CCV(pProgramObject)[program]);
228 ES2INTER(ProgramObjectInfoLogReset)(pUnit);
229 if (nAttachedShaders > 0) {
230 GLuint* pAttachedShaders = NULL;
232 pAttachedShaders = (GLuint*)realloc(pAttachedShaders, nAttachedShaders * sizeof(GLuint));
233 assert(pAttachedShaders != NULL);
234 FNPTR(GetAttachedShaders)(program, nAttachedShaders, &i, pAttachedShaders);
235 assert(nAttachedShaders == i);
236 for (i = 0; i < nAttachedShaders; i++) {
237 int index = pAttachedShaders[i];
238 if (index < CCV(nShaderObjectAllocated)) {
239 struct ShaderObjectUnit* pShader = &(CCV(pShaderObject)[index]);
240 if (pShader->eShaderType == GL_VERTEX_SHADER) {
242 } else if (pShader->eShaderType == GL_FRAGMENT_SHADER) {
245 if (pShader->bCompileStatus == GL_FALSE) {
247 ES2INTER(ProgramObjectInfoLogAppend)(pUnit,
248 "ERROR: shader=%d was not compiled or failed to compile\n", index);
253 if (nVertexShader == 0) {
254 ES2INTER(ProgramObjectInfoLogAppend)(pUnit, "ERROR: no vertex shader found\n");
257 if (nFragmentShader == 0) {
258 ES2INTER(ProgramObjectInfoLogAppend)(pUnit, "ERROR: no fragment shader found\n");
261 if (bFlag == GL_FALSE) {
262 CCV(pProgramObject)[program].bLinkStatus = GL_FALSE;
263 ES2INTER(ProgramObjectInfoLogAppend)(pUnit, "ERROR: link failed\n");
266 FNPTR(LinkProgram)(program);
267 FNPTR(GetProgramiv)(program, GL_LINK_STATUS, &iResult);
268 pUnit->bLinkStatus = (iResult == GL_FALSE) ? GL_FALSE : GL_TRUE;
271 void GL_APIENTRY ES2ENTRY(UseProgram)(GLuint program) {
272 if ((GLint)(program) < 0) {
273 ES2INTER(SetError)(GL_INVALID_VALUE);
274 } else if (program != 0 && FNPTR(IsProgram)(program) == GL_FALSE) {
275 ES2INTER(SetError)(GL_INVALID_OPERATION);
278 FNPTR(UseProgram)(program);
281 void GL_APIENTRY ES2ENTRY(ValidateProgram)(GLuint program) {
282 struct ProgramObjectUnit* pUnit;
284 if ((GLint)(program) <= 0) {
285 ES2INTER(SetError)(GL_INVALID_VALUE);
287 } else if (FNPTR(IsProgram)(program) == GL_FALSE) {
288 ES2INTER(SetError)(GL_INVALID_OPERATION);
291 pUnit = &(CCV(pProgramObject)[program]);
292 ES2INTER(ProgramObjectInfoLogReset)(pUnit);
293 FNPTR(ValidateProgram)(program);
294 FNPTR(GetProgramiv)(program, GL_VALIDATE_STATUS, &valid);
295 if (valid != GL_FALSE) {
296 ES2ENTRY(LinkProgram)(program);
300 void GL_APIENTRY ES2ENTRY(GetProgramiv)(GLuint program, GLenum pname, GLint* params) {
301 if ((GLint)(program) <= 0) {
302 ES2INTER(SetError)(GL_INVALID_VALUE);
304 } else if (FNPTR(IsProgram)(program) == GL_FALSE) {
305 ES2INTER(SetError)(GL_INVALID_OPERATION);
310 ES2INTER(SetError)(GL_INVALID_ENUM);
313 if (program < CCV(nProgramObjectAllocated)) {
314 *params = CCV(pProgramObject)[program].bLinkStatus;
316 FNPTR(GetProgramiv)(program, pname, params);
319 case GL_DELETE_STATUS:
320 FNPTR(GetProgramiv)(program, pname, params);
322 case GL_VALIDATE_STATUS:
323 FNPTR(GetProgramiv)(program, pname, params);
324 if (*params != GL_FALSE) {
325 if (program < CCV(nProgramObjectAllocated)) {
326 *params = CCV(pProgramObject)[program].bLinkStatus;
328 FNPTR(GetProgramiv)(program, GL_LINK_STATUS, params);
332 case GL_INFO_LOG_LENGTH:
333 if (program < CCV(nProgramObjectAllocated)
334 && CCV(pProgramObject)[program].strInfoLog != NULL) {
335 *params = strlen(CCV(pProgramObject)[program].strInfoLog) + 1;
337 FNPTR(GetProgramiv)(program, pname, params);
340 FNPTR(GetProgramiv)(program, pname, params);
343 case GL_ATTACHED_SHADERS:
344 case GL_ACTIVE_ATTRIBUTES:
345 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
346 case GL_ACTIVE_UNIFORMS:
347 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
348 FNPTR(GetProgramiv)(program, pname, params);
353 void GL_APIENTRY ES2ENTRY(GetProgramInfoLog)(GLuint program,
354 GLsizei bufsize, GLsizei* length, char* infolog) {
355 struct ProgramObjectUnit* pUnit;
356 if ((GLint)(program) <= 0) {
357 ES2INTER(SetError)(GL_INVALID_VALUE);
359 } else if (FNPTR(IsProgram)(program) == GL_FALSE) {
360 ES2INTER(SetError)(GL_INVALID_OPERATION);
364 ES2INTER(SetError)(GL_INVALID_VALUE);
367 assert(program < CCV(nProgramObjectAllocated));
368 pUnit = &CCV(pProgramObject[program]);
369 if (pUnit->strInfoLog != NULL) {
370 int len = strlen(pUnit->strInfoLog);
371 if (len >= bufsize) {
375 if (length != NULL) {
378 if (infolog != NULL) {
379 strncpy(infolog, pUnit->strInfoLog, len);
383 FNPTR(GetProgramInfoLog)(program, bufsize, length, infolog);
386 FNPTR(GetProgramInfoLog)(program, bufsize, length, infolog);