diff options
Diffstat (limited to 'es_2_0/Program.c')
-rwxr-xr-x | es_2_0/Program.c | 389 |
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); + } +} + |