diff options
author | Kim Kibum <kb0929.kim@samsung.com> | 2012-04-29 17:05:54 +0900 |
---|---|---|
committer | Kim Kibum <kb0929.kim@samsung.com> | 2012-04-29 17:05:54 +0900 |
commit | af0ee32ff16f50fd25229151af7b4a9a6753ebe5 (patch) | |
tree | 23879e4123b40df9f773d4775dd64eefd914f4fe /es_2_0/Shader.c | |
parent | 90dff65a3ccb36853763486671163ca81274b677 (diff) | |
download | simulator-opengl-af0ee32ff16f50fd25229151af7b4a9a6753ebe5.tar.gz simulator-opengl-af0ee32ff16f50fd25229151af7b4a9a6753ebe5.tar.bz2 simulator-opengl-af0ee32ff16f50fd25229151af7b4a9a6753ebe5.zip |
upload tizen1.0 source
Diffstat (limited to 'es_2_0/Shader.c')
-rwxr-xr-x | es_2_0/Shader.c | 549 |
1 files changed, 549 insertions, 0 deletions
diff --git a/es_2_0/Shader.c b/es_2_0/Shader.c new file mode 100755 index 0000000..1e661d4 --- /dev/null +++ b/es_2_0/Shader.c @@ -0,0 +1,549 @@ +/* + * 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(ShaderObjectInit)(struct ShaderObjectUnit* pUnit) { + pUnit->eShaderType = 0; + pUnit->bDeleteStatus = GL_FALSE; + pUnit->bCompileStatus = GL_FALSE; + pUnit->nAttached = 0; + pUnit->aStrSource = NULL; + pUnit->nSourceAlloc = 0; + pUnit->nSourceUsed = 0; + pUnit->nSourceLength = 0; + pUnit->strInfoLog = NULL; + pUnit->nInfoLogAlloc = 0; + pUnit->strPreped = NULL; + pUnit->nPrepedAlloc = 0; + pUnit->symbolLevel = -1; +} + +void GL_APIENTRY ES2INTER(ShaderObjectRelease)(struct ShaderObjectUnit* pUnit) { + register int i; + assert(pUnit->bDeleteStatus == GL_TRUE && pUnit->nAttached == 0); + for (i = 0; pUnit->aStrSource != NULL && i < pUnit->nSourceAlloc; i++) { + if (pUnit->aStrSource[i] != NULL) { + free(pUnit->aStrSource[i]); + } + } + if (pUnit->aStrSource != NULL) { + free(pUnit->aStrSource); + } + if (pUnit->strInfoLog != NULL) { + free(pUnit->strInfoLog); + } + if (pUnit->strPreped != NULL) { + free(pUnit->strPreped); + } + pUnit->eShaderType = 0; + pUnit->bDeleteStatus = GL_FALSE; + pUnit->bCompileStatus = GL_FALSE; + pUnit->nAttached = 0; + pUnit->aStrSource = NULL; + pUnit->nSourceAlloc = 0; + pUnit->nSourceUsed = 0; + pUnit->nSourceLength = 0; + pUnit->strInfoLog = NULL; + pUnit->nInfoLogAlloc = 0; + pUnit->strPreped = NULL; + pUnit->nPrepedAlloc = 0; + ES2INTER(SymbolRelease)(pUnit); +} + +void GL_APIENTRY ES2INTER(ShaderObjectInfoLogReset)(struct ShaderObjectUnit* pUnit) { + if (pUnit->strInfoLog == NULL) { + assert(pUnit->nInfoLogAlloc == 0); + pUnit->nInfoLogAlloc = 1024; + pUnit->strInfoLog = realloc(pUnit->strInfoLog, pUnit->nInfoLogAlloc * sizeof(GLchar)); + assert(pUnit->strInfoLog != NULL); + } + pUnit->strInfoLog[0] = '\0'; +} + +void GL_APIENTRY ES2INTER(ShaderObjectInfoLogAppend)(struct ShaderObjectUnit* pUnit, + const char* format, ...) { + static char cBuf[1024]; + int nLenBuf; + int nLenLog; + va_list ap; + va_start(ap, format); + vsnprintf(cBuf, 1024, format, ap); + if (pUnit->bDeleteStatus != GL_TRUE) { + if (pUnit->strInfoLog == NULL) { + assert(pUnit->nInfoLogAlloc == 0); + pUnit->nInfoLogAlloc = 1024; + pUnit->strInfoLog = realloc(pUnit->strInfoLog, pUnit->nInfoLogAlloc * sizeof(GLchar)); + assert(pUnit->strInfoLog != NULL); + pUnit->strInfoLog[0] = '\0'; + } + nLenBuf = strlen(cBuf) + 1; + nLenLog = strlen(pUnit->strInfoLog); + if (nLenBuf + nLenLog >= pUnit->nInfoLogAlloc) { + while (nLenBuf + nLenLog >= pUnit->nInfoLogAlloc) { + pUnit->nInfoLogAlloc *= 2; + } + pUnit->strInfoLog = realloc(pUnit->strInfoLog, pUnit->nInfoLogAlloc * sizeof(GLchar)); + assert(pUnit->strInfoLog != NULL); + } + strcat(pUnit->strInfoLog, cBuf); + } else { + ES2INTER(SetError)(GL_NO_ERROR); + } + va_end(ap); +} + +void GL_APIENTRY ES2INTER(ShaderObjectPrepedReset)(struct ShaderObjectUnit* pUnit) { + if (pUnit->strPreped == NULL) { + assert(pUnit->nPrepedAlloc == 0); + pUnit->nPrepedAlloc = 1024; + pUnit->strPreped = realloc(pUnit->strPreped, pUnit->nPrepedAlloc * sizeof(GLchar)); + assert(pUnit->strPreped != NULL); + } + pUnit->strPreped[0] = '\0'; +} + +void GL_APIENTRY ES2INTER(ShaderObjectPrepedAppend)(struct ShaderObjectUnit* pUnit, + const char* strBuf, int nLenBuf) { + int nLenPreped; + if (pUnit->strPreped == NULL) { + assert(pUnit->nPrepedAlloc == 0); + pUnit->nPrepedAlloc = 1024; + pUnit->strPreped = realloc(pUnit->strPreped, pUnit->nPrepedAlloc * sizeof(GLchar)); + assert(pUnit->strPreped != NULL); + pUnit->strPreped[0] = '\0'; + } + nLenPreped = strlen(pUnit->strPreped); + if (nLenBuf + nLenPreped >= pUnit->nPrepedAlloc) { + while (nLenBuf + nLenPreped >= pUnit->nPrepedAlloc) { + pUnit->nPrepedAlloc *= 2; + } + pUnit->strPreped = realloc(pUnit->strPreped, pUnit->nPrepedAlloc * sizeof(GLchar)); + assert(pUnit->strPreped != NULL); + } + strncat(pUnit->strPreped, strBuf, nLenBuf); +} + +GLuint GL_APIENTRY ES2ENTRY(CreateShader)(GLenum type) { + register GLuint uResult; + register GLint nAllocated; + register int i; + switch (type) { + default: + ES2INTER(SetError)(GL_INVALID_ENUM); + return 0; + case GL_VERTEX_SHADER: + case GL_FRAGMENT_SHADER: + uResult = FNPTR(CreateShader)(type); + nAllocated = CCV(nShaderObjectAllocated); + while (nAllocated <= uResult) { + nAllocated *= 2; + } + if (CCV(nShaderObjectAllocated) < nAllocated) { + register struct ShaderObjectUnit* pUnit = realloc(CCV(pShaderObject), + nAllocated * sizeof(struct ShaderObjectUnit)); + assert(pUnit != NULL); + for (i = CCV(nShaderObjectAllocated); i < nAllocated; i++) { + ES2INTER(ShaderObjectInit)(&(pUnit[i])); + } + CCV(pShaderObject) = pUnit; + CCV(nShaderObjectAllocated) = nAllocated; + } + CCV(pShaderObject)[uResult].eShaderType = type; + return uResult; + } +} + +void GL_APIENTRY ES2ENTRY(DeleteShader)(GLuint shader) { + if (shader == 0) { + return; + } else if (FNPTR(IsShader)(shader) == GL_FALSE) { + ES2INTER(SetError)(GL_INVALID_VALUE); + return; + } + FNPTR(DeleteShader)(shader); + if (shader < CCV(nShaderObjectAllocated)) { + struct ShaderObjectUnit* pUnit = &CCV(pShaderObject[shader]); + pUnit->bDeleteStatus = GL_TRUE; + if (pUnit->nAttached == 0) { + ES2INTER(ShaderObjectRelease)(pUnit); + } + } +} + +GLboolean GL_APIENTRY ES2ENTRY(IsShader)(GLuint shader) { + register GLboolean bResult; + bResult = FNPTR(IsShader)(shader); + return bResult; +} + +void GL_APIENTRY ES2ENTRY(ShaderSource)(GLuint shader, + GLsizei count, const char** string, const GLint* length) { + register struct ShaderObjectUnit* pUnit; + register int i; + if (CCV(bShaderCompiler) == GL_FALSE) { + 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; + } + if (count < 0) { + ES2INTER(SetError)(GL_INVALID_VALUE); + return; + } + assert(shader < CCV(nShaderObjectAllocated)); + pUnit = &CCV(pShaderObject[shader]); + pUnit->bCompileStatus = GL_FALSE; + pUnit->nSourceUsed = count; + if (pUnit->nSourceAlloc < count) { + pUnit->aStrSource = (GLchar**)realloc(pUnit->aStrSource, count * sizeof(GLchar*)); + assert(pUnit->aStrSource != NULL); + for (i = pUnit->nSourceAlloc; i < count; i++) { + pUnit->aStrSource[i] = NULL; + } + pUnit->nSourceAlloc = count; + } + pUnit->nSourceLength = 0; + for (i = 0; i < count; i++) { + register int len = (length == NULL) ? strlen(string[i]) : length[i]; + pUnit->aStrSource[i] = (GLchar*)realloc(pUnit->aStrSource[i], (len + 2) * sizeof(GLchar)); + if (pUnit->aStrSource[i] == NULL) { + ES2INTER(SetError)(GL_OUT_OF_MEMORY); + } + strncpy(pUnit->aStrSource[i], string[i], len); + pUnit->aStrSource[i][len] = (pUnit->aStrSource[i][len - 1] != '\n') ? '\n' : '\0'; + pUnit->aStrSource[i][len + 1] = '\0'; + pUnit->nSourceLength += (pUnit->aStrSource[i][len - 1] != '\n') ? (len + 1) : len; + } + if (pUnit->nSourceLength > 0) pUnit->nSourceLength++; + ES2INTER(ShaderObjectInfoLogReset)(pUnit); + ES2INTER(ShaderObjectPrepedReset)(pUnit); + FNPTR(ShaderSource)(shader, pUnit->nSourceUsed, (const GLchar**)pUnit->aStrSource, NULL); +} + +void GL_APIENTRY ES2ENTRY(GetShaderSource)(GLuint shader, + GLsizei bufsize, GLsizei* length, char* source) { + register struct ShaderObjectUnit* pUnit; + register char* pDst; + register char* pSrc; + register int i; + register int len; + if ((GLint)(shader) <= 0) { + ES2INTER(SetError)(GL_INVALID_VALUE); + return; + } else if (FNPTR(IsShader)(shader) == GL_FALSE) { + ES2INTER(SetError)(GL_INVALID_OPERATION); + return; + } + if (bufsize < 0) { + ES2INTER(SetError)(GL_INVALID_VALUE); + return; + } else if (bufsize == 0) { + return; + } else if (bufsize == 1) { + *source = '\0'; + if (length != NULL) *length = 0; + return; + } + pUnit = &CCV(pShaderObject[shader]); + pDst = source; + for (i = 0; bufsize > 1 && i < pUnit->nSourceUsed; i++) { + pSrc = pUnit->aStrSource[i]; + while (bufsize-- > 1) { + *pDst++ = *pSrc++; + } + } + *pDst = '\0'; + len = (int)(pDst - source); + if (length != NULL) { + *length = len; + } +} + +void GL_APIENTRY ES2ENTRY(ShaderBinary)(GLsizei n, const GLuint* shaders, + GLenum binaryformat, const void* binary, GLsizei length) { + register int i; + if (n < 0 || length < 0) { + ES2INTER(SetError)(GL_INVALID_VALUE); + return; + } + for (i = 0; i < n; i++) { + if (shaders[i] == 0) { + ES2INTER(SetError)(GL_INVALID_VALUE); + return; + } else if (FNPTR(IsShader)(shaders[i]) == GL_FALSE) { + ES2INTER(SetError)(GL_INVALID_OPERATION); + return; + } + } + + ES2INTER(SetError)(GL_INVALID_OPERATION); +} + +/* hooking for PrepLex analyzer */ +extern void hazelPrepPrepare(struct ShaderObjectUnit* pShaderObject); +extern int hazelPrepGetError(void); +extern int hazelPreplex(void); +extern void hazelPrepTerminate(void); + +extern void hazelParsePrepare(struct ShaderObjectUnit* ptr, const char* src, char* dst); +extern int hazelParseparse(void); +extern int hazelParseGetError(void); +extern void hazelParseTerminate(void); + +int hazelEnableTexture3D = GL_FALSE; + +void GL_APIENTRY ES2ENTRY(CompileShader)(GLuint shader) { + register struct ShaderObjectUnit* pUnit; + char* pExpanded; + static char* pParsed = NULL; + GLint nResult; + GLint nSemError; + if (CCV(bShaderCompiler) == GL_FALSE) { + 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; + } + assert(shader < CCV(nShaderObjectAllocated)); + pUnit = &CCV(pShaderObject[shader]); + ES2INTER(ShaderObjectInfoLogReset)(pUnit); + ES2INTER(ShaderObjectPrepedReset)(pUnit); + if (pUnit->nSourceUsed <= 0) { + ES2INTER(ShaderObjectInfoLogAppend)(pUnit, "ERROR: no source code available\n"); + pUnit->bCompileStatus = GL_FALSE; + return; + } + ES2INTER(MacroInit)(); + hazelPrepPrepare(pUnit); + hazelPreplex(); + nResult = hazelPrepGetError(); + hazelPrepTerminate(); + if (nResult != 0) { + ES2INTER(ShaderObjectInfoLogAppend)(pUnit, "ERROR: stopped during preprocessing\n"); + pUnit->bCompileStatus = GL_FALSE; + ES2INTER(MacroRelease)(); + return; + } + ES2INTER(MacroUndef)("__LINE__"); + ES2INTER(MacroUndef)("__FILE__"); + pExpanded = ES2INTER(MacroExpand)(pUnit->strPreped, 0); + if (pExpanded == NULL) { + ES2INTER(ShaderObjectInfoLogAppend)(pUnit, "ERROR: stopped during source expansion\n"); + pUnit->bCompileStatus = GL_FALSE; + ES2INTER(MacroRelease)(); + return; + } + ES2INTER(MacroRelease)(); + if (strncmp (pExpanded, "#version", 8) != 0) { + /* here pParsed has removed all the useless characters like comments. + * If the first strig is not version, set the version number to be 120. + */ + const char *versionStr = "#version 120\n"; + pParsed = realloc(pParsed, 2 * strlen(pExpanded) + strlen(versionStr)); + memset(pParsed, 0, 2 * strlen(pExpanded) + strlen(versionStr)); + + strncpy(pParsed, versionStr, strlen(versionStr)); + hazelParsePrepare(pUnit, pExpanded, &pParsed[strlen(versionStr)]); + } else { + pParsed = realloc(pParsed, 2 * strlen(pExpanded)); + memset(pParsed, 0, 2 * strlen(pExpanded)); + hazelParsePrepare(pUnit, pExpanded, pParsed); + } + + nResult = hazelParseparse(); + nSemError = hazelParseGetError(); + hazelParseTerminate(); + if (nResult != 0 || nSemError != 0) { + ES2INTER(ShaderObjectInfoLogAppend)(pUnit, "ERROR: stopped during parsing\n"); + pUnit->bCompileStatus = GL_FALSE; + return; + } + FNPTR(ShaderSource)(shader, 1, (const GLchar**)&(pParsed), NULL); + FNPTR(CompileShader)(shader); + FNPTR(GetShaderiv)(shader, GL_COMPILE_STATUS, &nResult); + pUnit->bCompileStatus = (nResult == 0) ? GL_FALSE : GL_TRUE; + FNPTR(GetShaderiv)(shader, GL_INFO_LOG_LENGTH, &nResult); + if (nResult > 1) { + GLchar* str = malloc((nResult + 1) * sizeof(GLchar)); + FNPTR(GetShaderInfoLog)(shader, nResult + 1, NULL, str); + ES2INTER(ShaderObjectInfoLogAppend)(pUnit, "%s", str); + free(str); + } +} + +void GL_APIENTRY ES2ENTRY(ReleaseShaderCompiler)(void) { + if (CCV(bShaderCompiler) == GL_FALSE) { + ES2INTER(SetError)(GL_INVALID_OPERATION); + return; + } + +} + +void GL_APIENTRY ES2ENTRY(GetShaderiv)(GLuint shader, GLenum pname, GLint* params) { + register struct ShaderObjectUnit* pUnit; + int nLenInfoLog; + if (pname == GL_COMPILE_STATUS + || pname == GL_INFO_LOG_LENGTH + || pname == GL_SHADER_SOURCE_LENGTH) { + if (CCV(bShaderCompiler) == GL_FALSE) { + 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; + } + pUnit = &CCV(pShaderObject[shader]); + switch (pname) { + default: + ES2INTER(SetError)(GL_INVALID_ENUM); + return; + case GL_SHADER_TYPE: + if (params != NULL) { + *params = pUnit->eShaderType; + } + break; + case GL_DELETE_STATUS: + if (params != NULL) { + *params = pUnit->bDeleteStatus; + } + break; + case GL_COMPILE_STATUS: + if (params != NULL) { + *params = pUnit->bCompileStatus; + } + break; + case GL_INFO_LOG_LENGTH: + if (pUnit->strInfoLog != NULL + && (nLenInfoLog = strlen(pUnit->strInfoLog)) > 0) { + if (params != NULL) { + *params = nLenInfoLog + 1; + } + } else { + FNPTR(GetShaderiv)(shader, pname, params); + } + break; + case GL_SHADER_SOURCE_LENGTH: + if (params != NULL) { + params[0] = pUnit->nSourceLength; + } + } +} + +void GL_APIENTRY ES2ENTRY(GetShaderInfoLog)(GLuint shader, + GLsizei bufsize, GLsizei* length, char* infolog) { + register struct ShaderObjectUnit* pUnit; + int len; + GLboolean done; + if ((GLint)(shader) <= 0) { + ES2INTER(SetError)(GL_INVALID_VALUE); + return; + } else if (FNPTR(IsShader)(shader) == GL_FALSE) { + ES2INTER(SetError)(GL_INVALID_OPERATION); + return; + } + if (bufsize < 0) { + ES2INTER(SetError)(GL_INVALID_VALUE); + return; + } + done = GL_FALSE; + if (shader < CCV(nShaderObjectAllocated)) { + pUnit = &CCV(pShaderObject[shader]); + if (pUnit->strInfoLog != NULL) { + len = strlen(pUnit->strInfoLog); + if (len + 1 <= bufsize) { + strcpy(infolog, pUnit->strInfoLog); + if (length != NULL) *length = len; + done = GL_TRUE; + } else if (bufsize > 0) { + strncpy(infolog, pUnit->strInfoLog, bufsize - 1); + infolog[bufsize - 1] = '\0'; + if (length != NULL) *length = bufsize - 1; + done = GL_TRUE; + } + } + } + if (done == GL_FALSE) { + FNPTR(GetShaderInfoLog)(shader, bufsize, length, infolog); + } +} + +void GL_APIENTRY ES2ENTRY(GetShaderPrecisionFormat)(GLenum shadertype, + GLenum precisiontype, GLint* range, GLint* precision) { + if (CCV(bShaderCompiler) == GL_FALSE) { + ES2INTER(SetError)(GL_INVALID_OPERATION); + return; + } + switch (shadertype) { + default: + ES2INTER(SetError)(GL_INVALID_ENUM); + return; + case GL_VERTEX_SHADER: + case GL_FRAGMENT_SHADER: + switch (precisiontype) { + default: + ES2INTER(SetError)(GL_INVALID_ENUM); + return; + case GL_LOW_FLOAT: + case GL_MEDIUM_FLOAT: + case GL_HIGH_FLOAT: + range[0] = -10; + range[1] = 10; + precision[0] = 1; + break; + case GL_LOW_INT: + case GL_MEDIUM_INT: + case GL_HIGH_INT: + range[0] = -10; + range[1] = 10; + precision[0] = 0; + break; + } + break; + } +} |