summaryrefslogtreecommitdiff
path: root/es_2_0/Program.c
diff options
context:
space:
mode:
Diffstat (limited to 'es_2_0/Program.c')
-rwxr-xr-xes_2_0/Program.c389
1 files changed, 389 insertions, 0 deletions
diff --git a/es_2_0/Program.c b/es_2_0/Program.c
new file mode 100755
index 0000000..ab0107d
--- /dev/null
+++ b/es_2_0/Program.c
@@ -0,0 +1,389 @@
+/*
+ * Copyright (C) 2010 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * DongKyun Yun <dk77.yun@samsung.com>
+ * SangJin Kim <sangjin3.kim@samsung.com>
+ * HyunGoo Kang <hyungoo1.kang@samsung.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include "es2front.h"
+#include <stdarg.h>
+
+
+void GL_APIENTRY ES2INTER(ProgramObjectInit)(struct ProgramObjectUnit* pUnit) {
+ pUnit->bLinkStatus = GL_FALSE;
+ pUnit->strInfoLog = NULL;
+}
+
+void GL_APIENTRY ES2INTER(ProgramObjectRelease)(struct ProgramObjectUnit* pUnit) {
+ register int i;
+ if (pUnit->strInfoLog != NULL) {
+ free(pUnit->strInfoLog);
+ }
+ pUnit->bLinkStatus = GL_FALSE;
+ pUnit->strInfoLog = NULL;
+}
+
+void GL_APIENTRY ES2INTER(ProgramObjectInfoLogReset)(struct ProgramObjectUnit* pUnit) {
+ pUnit->strInfoLog = realloc(pUnit->strInfoLog, 1024 * sizeof(GLchar));
+ assert(pUnit->strInfoLog != NULL);
+ pUnit->strInfoLog[0] = '\0';
+}
+
+void GL_APIENTRY ES2INTER(ProgramObjectInfoLogAppend)(struct ProgramObjectUnit* pUnit,
+ const char* format, ...) {
+ static char cBuf[1024];
+ int len;
+ va_list ap;
+ va_start(ap, format);
+ vsnprintf(cBuf, 1024, format, ap);
+ if (pUnit->strInfoLog == NULL) {
+ pUnit->strInfoLog = realloc(pUnit->strInfoLog, 1024 * sizeof(GLchar));
+ assert(pUnit->strInfoLog != NULL);
+ pUnit->strInfoLog[0] = '\0';
+ }
+ len = strlen(pUnit->strInfoLog) + strlen(cBuf);
+ pUnit->strInfoLog = realloc(pUnit->strInfoLog, (len + 1) * sizeof(GLchar));
+ assert(pUnit->strInfoLog != NULL);
+ strcat(pUnit->strInfoLog, cBuf);
+ va_end(ap);
+}
+
+GLuint GL_APIENTRY ES2ENTRY(CreateProgram)(void) {
+ register GLuint uResult;
+ register GLint nAllocated;
+ register int i;
+ uResult = FNPTR(CreateProgram)();
+ nAllocated = CCV(nProgramObjectAllocated);
+ while (nAllocated <= uResult) {
+ nAllocated *= 2;
+ }
+ if (CCV(nProgramObjectAllocated) < nAllocated) {
+ register struct ProgramObjectUnit* pUnit = realloc(CCV(pProgramObject),
+ nAllocated * sizeof(struct ProgramObjectUnit));
+ assert(pUnit != NULL);
+ for (i = CCV(nProgramObjectAllocated); i < nAllocated; i++) {
+ ES2INTER(ProgramObjectInit)(&(pUnit[i]));
+ }
+ CCV(pProgramObject) = pUnit;
+ CCV(nProgramObjectAllocated) = nAllocated;
+ }
+ return uResult;
+}
+
+void GL_APIENTRY ES2ENTRY(DeleteProgram)(GLuint program) {
+ if (program == 0) {
+ return;
+ } else if (FNPTR(IsProgram) != NULL && FNPTR(IsProgram)(program) == GL_FALSE) {
+ ES2INTER(SetError)(GL_INVALID_VALUE);
+ return;
+ }
+ if (CCV(nProgramObjectAllocated) == NULL) {
+ ES2INTER(SetError)(GL_INVALID_VALUE);
+ return;
+ }
+
+ if (program < CCV(nProgramObjectAllocated)) {
+ GLint nAttachedShaders = 0;
+ FNPTR(GetProgramiv)(program, GL_ATTACHED_SHADERS, &nAttachedShaders);
+ if (nAttachedShaders > 0) {
+ GLuint* pAttachedShaders = NULL;
+ int i;
+ pAttachedShaders = (GLuint*)realloc(pAttachedShaders,
+ nAttachedShaders * sizeof(GLuint));
+ assert(pAttachedShaders != NULL);
+ FNPTR(GetAttachedShaders)(program, nAttachedShaders, &i, pAttachedShaders);
+ assert(nAttachedShaders == i);
+ for (i = 0; i < nAttachedShaders; i++) {
+ int index = pAttachedShaders[i];
+ if (index < CCV(nShaderObjectAllocated)) {
+ struct ShaderObjectUnit* pShader = &(CCV(pShaderObject)[index]);
+ if (pShader->nAttached > 0) pShader->nAttached--;
+ if (pShader->bDeleteStatus == GL_TRUE && pShader->nAttached == 0) {
+ ES2INTER(ShaderObjectRelease)(pShader);
+ }
+ }
+ }
+ }
+ ES2INTER(ProgramObjectRelease)(&(CCV(pProgramObject)[program]));
+ }
+ FNPTR(DeleteProgram)(program);
+}
+
+GLboolean GL_APIENTRY ES2ENTRY(IsProgram)(GLuint program) {
+ register GLboolean bResult;
+ bResult = FNPTR(IsProgram)(program);
+ return bResult;
+}
+
+void GL_APIENTRY ES2ENTRY(AttachShader)(GLuint program, GLuint shader) {
+ struct ShaderObjectUnit* pShader;
+ if ((GLint)(program) <= 0) {
+ ES2INTER(SetError)(GL_INVALID_VALUE);
+ return;
+ } else if (FNPTR(IsProgram)(program) == GL_FALSE) {
+ if (program == 30) {
+ ES2INTER(SetError)(GL_INVALID_VALUE);
+ } else {
+ ES2INTER(SetError)(GL_INVALID_OPERATION);
+ }
+ return;
+ }
+ if ((GLint)(shader) <= 0) {
+ ES2INTER(SetError)(GL_INVALID_VALUE);
+ return;
+ } else if (FNPTR(IsShader)(shader) == GL_FALSE) {
+ ES2INTER(SetError)(GL_INVALID_OPERATION);
+ return;
+ }
+ FNPTR(AttachShader)(program, shader);
+ pShader = &(CCV(pShaderObject)[shader]);
+ pShader->nAttached++;
+}
+
+void GL_APIENTRY ES2ENTRY(DetachShader)(GLuint program, GLuint shader) {
+ struct ShaderObjectUnit* pShader;
+ if ((GLint)(program) <= 0) {
+ ES2INTER(SetError)(GL_INVALID_VALUE);
+ return;
+ } else if (FNPTR(IsProgram) != NULL && FNPTR(IsProgram)(program) == GL_FALSE) {
+ ES2INTER(SetError)(GL_INVALID_OPERATION);
+ return;
+ }
+ if ((GLint)(shader) <= 0) {
+ ES2INTER(SetError)(GL_INVALID_VALUE);
+ return;
+ } else if (FNPTR(IsShader) != NULL && FNPTR(IsShader)(shader) == GL_FALSE) {
+ ES2INTER(SetError)(GL_INVALID_OPERATION);
+ return;
+ }
+ if (FNPTR(DetachShader) != NULL)
+ FNPTR(DetachShader)(program, shader);
+ if (CCV(pShaderObject) != NULL) {
+ pShader = &(CCV(pShaderObject)[shader]);
+ if (pShader->nAttached > 0)
+ pShader->nAttached--;
+ if (pShader->nAttached == 0 && pShader->bDeleteStatus == GL_TRUE)
+ ES2INTER(ShaderObjectRelease)(pShader);
+ }
+}
+
+void GL_APIENTRY ES2ENTRY(GetAttachedShaders)(GLuint program,
+ GLsizei maxcount, GLsizei* count, GLuint* shaders) {
+ if ((GLint)(program) <= 0) {
+ ES2INTER(SetError)(GL_INVALID_VALUE);
+ return;
+ } else if (FNPTR(IsProgram)(program) == GL_FALSE) {
+ ES2INTER(SetError)(GL_INVALID_OPERATION);
+ return;
+ }
+ if (maxcount < 0) {
+ ES2INTER(SetError)(GL_INVALID_VALUE);
+ return;
+ }
+ FNPTR(GetAttachedShaders)(program, maxcount, count, shaders);
+}
+
+void GL_APIENTRY ES2ENTRY(LinkProgram)(GLuint program) {
+ struct ProgramObjectUnit* pUnit;
+ int nAttachedShaders;
+ int iResult;
+ GLboolean bFlag;
+ int nVertexShader = 0;
+ int nFragmentShader = 0;
+ if ((GLint)(program) <= 0) {
+ ES2INTER(SetError)(GL_INVALID_VALUE);
+ return;
+ } else if (FNPTR(IsProgram)(program) == GL_FALSE) {
+ ES2INTER(SetError)(GL_INVALID_OPERATION);
+ return;
+ }
+ FNPTR(GetProgramiv)(program, GL_ATTACHED_SHADERS, &nAttachedShaders);
+ bFlag = GL_TRUE;
+ assert(program < CCV(nProgramObjectAllocated));
+ pUnit = &(CCV(pProgramObject)[program]);
+ ES2INTER(ProgramObjectInfoLogReset)(pUnit);
+ if (nAttachedShaders > 0) {
+ GLuint* pAttachedShaders = NULL;
+ int i;
+ pAttachedShaders = (GLuint*)realloc(pAttachedShaders, nAttachedShaders * sizeof(GLuint));
+ assert(pAttachedShaders != NULL);
+ FNPTR(GetAttachedShaders)(program, nAttachedShaders, &i, pAttachedShaders);
+ assert(nAttachedShaders == i);
+ for (i = 0; i < nAttachedShaders; i++) {
+ int index = pAttachedShaders[i];
+ if (index < CCV(nShaderObjectAllocated)) {
+ struct ShaderObjectUnit* pShader = &(CCV(pShaderObject)[index]);
+ if (pShader->eShaderType == GL_VERTEX_SHADER) {
+ nVertexShader++;
+ } else if (pShader->eShaderType == GL_FRAGMENT_SHADER) {
+ nFragmentShader++;
+ }
+ if (pShader->bCompileStatus == GL_FALSE) {
+ bFlag = GL_FALSE;
+ ES2INTER(ProgramObjectInfoLogAppend)(pUnit,
+ "ERROR: shader=%d was not compiled or failed to compile\n", index);
+ }
+ }
+ }
+ }
+ if (nVertexShader == 0) {
+ ES2INTER(ProgramObjectInfoLogAppend)(pUnit, "ERROR: no vertex shader found\n");
+ bFlag = GL_FALSE;
+ }
+ if (nFragmentShader == 0) {
+ ES2INTER(ProgramObjectInfoLogAppend)(pUnit, "ERROR: no fragment shader found\n");
+ bFlag = GL_FALSE;
+ }
+ if (bFlag == GL_FALSE) {
+ CCV(pProgramObject)[program].bLinkStatus = GL_FALSE;
+ ES2INTER(ProgramObjectInfoLogAppend)(pUnit, "ERROR: link failed\n");
+ return;
+ }
+ FNPTR(LinkProgram)(program);
+ FNPTR(GetProgramiv)(program, GL_LINK_STATUS, &iResult);
+ pUnit->bLinkStatus = (iResult == GL_FALSE) ? GL_FALSE : GL_TRUE;
+}
+
+void GL_APIENTRY ES2ENTRY(UseProgram)(GLuint program) {
+ if ((GLint)(program) < 0) {
+ ES2INTER(SetError)(GL_INVALID_VALUE);
+ } else if (program != 0 && FNPTR(IsProgram)(program) == GL_FALSE) {
+ ES2INTER(SetError)(GL_INVALID_OPERATION);
+ return;
+ }
+ FNPTR(UseProgram)(program);
+}
+
+void GL_APIENTRY ES2ENTRY(ValidateProgram)(GLuint program) {
+ struct ProgramObjectUnit* pUnit;
+ GLint valid;
+ if ((GLint)(program) <= 0) {
+ ES2INTER(SetError)(GL_INVALID_VALUE);
+ return;
+ } else if (FNPTR(IsProgram)(program) == GL_FALSE) {
+ ES2INTER(SetError)(GL_INVALID_OPERATION);
+ return;
+ }
+ pUnit = &(CCV(pProgramObject)[program]);
+ ES2INTER(ProgramObjectInfoLogReset)(pUnit);
+ FNPTR(ValidateProgram)(program);
+ FNPTR(GetProgramiv)(program, GL_VALIDATE_STATUS, &valid);
+ if (valid != GL_FALSE) {
+ ES2ENTRY(LinkProgram)(program);
+ }
+}
+
+void GL_APIENTRY ES2ENTRY(GetProgramiv)(GLuint program, GLenum pname, GLint* params) {
+ if ((GLint)(program) <= 0) {
+ ES2INTER(SetError)(GL_INVALID_VALUE);
+ return;
+ } else if (FNPTR(IsProgram)(program) == GL_FALSE) {
+ ES2INTER(SetError)(GL_INVALID_OPERATION);
+ return;
+ }
+ switch (pname) {
+ default:
+ ES2INTER(SetError)(GL_INVALID_ENUM);
+ return;
+ case GL_LINK_STATUS:
+ if (program < CCV(nProgramObjectAllocated)) {
+ *params = CCV(pProgramObject)[program].bLinkStatus;
+ } else {
+ FNPTR(GetProgramiv)(program, pname, params);
+ }
+ break;
+ case GL_DELETE_STATUS:
+ FNPTR(GetProgramiv)(program, pname, params);
+ break;
+ case GL_VALIDATE_STATUS:
+ FNPTR(GetProgramiv)(program, pname, params);
+ if (*params != GL_FALSE) {
+ if (program < CCV(nProgramObjectAllocated)) {
+ *params = CCV(pProgramObject)[program].bLinkStatus;
+ } else {
+ FNPTR(GetProgramiv)(program, GL_LINK_STATUS, params);
+ }
+ }
+ break;
+ case GL_INFO_LOG_LENGTH:
+ if (program < CCV(nProgramObjectAllocated)
+ && CCV(pProgramObject)[program].strInfoLog != NULL) {
+ *params = strlen(CCV(pProgramObject)[program].strInfoLog) + 1;
+ if (*params <= 1) {
+ FNPTR(GetProgramiv)(program, pname, params);
+ }
+ } else {
+ FNPTR(GetProgramiv)(program, pname, params);
+ }
+ break;
+ case GL_ATTACHED_SHADERS:
+ case GL_ACTIVE_ATTRIBUTES:
+ case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
+ case GL_ACTIVE_UNIFORMS:
+ case GL_ACTIVE_UNIFORM_MAX_LENGTH:
+ FNPTR(GetProgramiv)(program, pname, params);
+ break;
+ }
+}
+
+void GL_APIENTRY ES2ENTRY(GetProgramInfoLog)(GLuint program,
+ GLsizei bufsize, GLsizei* length, char* infolog) {
+ struct ProgramObjectUnit* pUnit;
+ if ((GLint)(program) <= 0) {
+ ES2INTER(SetError)(GL_INVALID_VALUE);
+ return;
+ } else if (FNPTR(IsProgram)(program) == GL_FALSE) {
+ ES2INTER(SetError)(GL_INVALID_OPERATION);
+ return;
+ }
+ if (bufsize < 0) {
+ ES2INTER(SetError)(GL_INVALID_VALUE);
+ return;
+ }
+ assert(program < CCV(nProgramObjectAllocated));
+ pUnit = &CCV(pProgramObject[program]);
+ if (pUnit->strInfoLog != NULL) {
+ int len = strlen(pUnit->strInfoLog);
+ if (len >= bufsize) {
+ len = bufsize - 1;
+ }
+ if (len > 0) {
+ if (length != NULL) {
+ *length = len;
+ }
+ if (infolog != NULL) {
+ strncpy(infolog, pUnit->strInfoLog, len);
+ infolog[len] = '\0';
+ }
+ } else {
+ FNPTR(GetProgramInfoLog)(program, bufsize, length, infolog);
+ }
+ } else {
+ FNPTR(GetProgramInfoLog)(program, bufsize, length, infolog);
+ }
+}
+