hostsupport/hostopengles20/src/GLES2/shader.c
branchbug235_bringup_0
changeset 55 09263774e342
parent 54 067180f57b12
child 56 40cc73c24bf8
--- a/hostsupport/hostopengles20/src/GLES2/shader.c	Wed Oct 06 18:00:57 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,554 +0,0 @@
-/* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
- *
- * 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
- * BRIAN PAUL 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.
- *
- * Initial Contributors:
- * Nokia Corporation - initial contribution.
- *
- * Contributors:
- *
- * Description:
- *
- */
-
-#include "common.h"
-#include "hgl.h"
-#include "context.h"
-#include <string.h>
-
-DGLShader* DGLShader_create(GLuint name)
-{
-	DGLShader* shader = malloc(sizeof(DGLShader));
-	if(shader == NULL)
-	{
-		return NULL;
-	}
-
-	shader->obj.name = name;
-	shader->obj.next = NULL;
-
-	shader->source = NULL;
-	shader->length = 0;
-
-	return shader;
-}
-
-void DGLShader_destroy(DGLShader *shader)
-{
-	DGLES2_ASSERT(shader != NULL);
-	if(shader->source != NULL)
-	{
-		free(shader->source);
-		shader->source = NULL;
-	}
-	free(shader);
-}
-
-GL_APICALL_BUILD void GL_APIENTRY glCompileShader(GLuint shader)
-{
-	DGLES2_ENTER();
-	ctx->hgl.CompileShader(shader);
-	DGLES2_LEAVE();
-}
-
-GL_APICALL_BUILD GLuint GL_APIENTRY glCreateShader(GLenum type)
-{
-	DGLES2_ENTER_RET(0);
-	DGLES2_ERROR_IF_RET(type != GL_VERTEX_SHADER && type != GL_FRAGMENT_SHADER, GL_INVALID_ENUM, 0);
-	{
-		GLuint name = ctx->hgl.CreateShader(type);
-		if(DGLContext_getHostError(ctx) == GL_NO_ERROR && name != 0)
-		{
-			DGLContext_createShader(ctx, name);
-		}
-
-		DGLES2_LEAVE_RET(name);
-	}
-}
-
-GL_APICALL_BUILD void GL_APIENTRY glDeleteShader(GLuint shader)
-{
-	DGLES2_ENTER();
-	if(shader != 0)
-	{
-		DGLES2_ERROR_IF(ctx->hgl.IsProgram(shader), GL_INVALID_OPERATION);
-		DGLES2_ERROR_IF(!ctx->hgl.IsShader(shader), GL_INVALID_VALUE);
-		ctx->hgl.DeleteShader(shader);
-		if(DGLContext_getHostError(ctx) == GL_NO_ERROR)
-		{
-			DGLContext_destroyShader(ctx, shader);
-		}
-	}
-	DGLES2_LEAVE();
-}
-
-GL_APICALL_BUILD void GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
-{
-	DGLES2_ENTER();
-	DGLES2_ERROR_IF(ctx->hgl.IsProgram(shader), GL_INVALID_OPERATION);
-	DGLES2_ERROR_IF(!ctx->hgl.IsShader(shader), GL_INVALID_VALUE);
-	if(pname == GL_SHADER_SOURCE_LENGTH)
-	{
-		DGLShader* shader_obj = DGLContext_findShader(ctx, shader);
-		DGLES2_ASSERT(shader_obj != NULL);
-		*params = shader_obj->length + 1;
-	}
-	else
-	{
-		ctx->hgl.GetShaderiv(shader, pname, params);
-	}
-	DGLES2_LEAVE();
-}
-
-GL_APICALL_BUILD void GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog)
-{
-	DGLES2_ENTER();
-	DGLES2_ERROR_IF(ctx->hgl.IsProgram(shader), GL_INVALID_OPERATION);
-	DGLES2_ERROR_IF(!ctx->hgl.IsShader(shader), GL_INVALID_VALUE);
-	ctx->hgl.GetShaderInfoLog(shader, bufsize, length, infolog);
-	DGLES2_LEAVE();
-}
-
-GL_APICALL_BUILD void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
-{
-	DGLES2_ENTER();
-	DGLES2_ERROR_IF(shadertype != GL_VERTEX_SHADER && shadertype != GL_FRAGMENT_SHADER, GL_INVALID_ENUM);
-	// Values from the GL ES and GLSL specifications.
-	switch(precisiontype)
-	{
-		case GL_LOW_FLOAT:
-		case GL_MEDIUM_FLOAT:
-		case GL_HIGH_FLOAT:
-			range[0] = 127;
-			range[1] = 127;
-			*precision = 23;
-			break;
-
-		case GL_LOW_INT:
-		case GL_MEDIUM_INT:
-		case GL_HIGH_INT:
-			range[0] = 15;
-			range[1] = 14;
-			*precision = 0;
-			break;
-	}
-	DGLES2_LEAVE();
-}
-
-GL_APICALL_BUILD void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, char* source)
-{
-	DGLES2_ENTER();
-	DGLES2_ERROR_IF(ctx->hgl.IsProgram(shader), GL_INVALID_OPERATION);
-	DGLES2_ERROR_IF(!ctx->hgl.IsShader(shader), GL_INVALID_VALUE);
-	DGLES2_ERROR_IF(bufsize < 0, GL_INVALID_VALUE);
-	{
-		DGLShader* shader_obj = DGLContext_findShader(ctx, shader);
-		DGLES2_ASSERT(shader_obj != NULL);
-		
-		if(length != NULL)
-		{
-			*length = 0;
-		}
-
-		if(source != NULL)
-		{
-			GLsizei num_chars = shader_obj->length < bufsize - 1 ? shader_obj->length : bufsize - 1;
-			if(num_chars > 0)
-			{
-				strncpy(source, shader_obj->source, num_chars);
-				source[num_chars] = 0;
-				if(length != NULL)
-				{
-					*length = num_chars;
-				}
-			}
-		}
-	}
-	DGLES2_LEAVE();
-}
-
-GL_APICALL_BUILD GLboolean GL_APIENTRY glIsShader(GLuint shader)
-{
-	DGLES2_ENTER_RET(GL_FALSE);
-	DGLES2_LEAVE_RET(ctx->hgl.IsShader(shader));
-}
-
-GL_APICALL_BUILD void GL_APIENTRY glReleaseShaderCompiler(void)
-{
-	DGLES2_ENTER();
-	// No-op.
-	DGLES2_LEAVE();
-}
-
-GL_APICALL_BUILD void GL_APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length)
-{
-	DGLES2_ENTER();
-	// No supported formats.
-	DGLES2_ERROR(GL_INVALID_ENUM);
-	DGLES2_LEAVE();
-}
-
-static const char *opengl_strtok(const char *s, int *n)
-{
-    static char *buffer = 0;
-    static int buffersize = -1;
-    static const char *delim = " \t\n\r()[]{},;:";
-    static const char *prev = 0;
-    int cComment = 0;
-    int cppComment = 0;
-
-    if (!s) {
-        if (!*prev || !*n) {
-            if (buffer) {
-                free(buffer);
-                buffer = 0;
-                buffersize = -1;
-            }
-            prev = 0;
-            return 0;
-        }
-        s = prev;
-    } else {
-        if (buffer) {
-            free(buffer);
-            buffer = 0;
-            buffersize = -1;
-        }
-		prev = s;
-    }
-
-    if( *n && *s == '/') {
-        if(*(s+1) == '*') cComment = 1;
-        if(*(s+1) == '/') cppComment = 1;        
-    }
-    if( cComment == 1 || cppComment == 1) {
-        for(; *n && (cComment == 1 || cppComment == 1); s++, (*n)--) {
-            if(cComment == 1 && *s == '*' && *(s+1) == '/' ) {
-                cComment = 0;
-            }
-            if(cppComment == 1 && *s == '\n') {
-                cppComment = 0;
-            }
-        }
-    } else {
-        for (; *n && strchr(delim, *s); s++, (*n)--);
-    }
-
-	if(s - prev > 0) {
-		if (buffersize < s - prev) {
-			buffersize = s - prev;
-			if (buffer) {
-				free(buffer);
-			}
-			buffer = malloc(buffersize + 1);
-		}
-		memcpy(buffer, prev, s - prev);
-		buffer[s - prev] = 0;
-		prev = s;
-	} else {
-		const char *e = s;
-		for (; *n && *e && !strchr(delim, *e); e++, (*n)--);
-		prev = e;
-		if (buffersize < e - s) {
-			buffersize = e - s;
-			if (buffer) {
-				free(buffer);
-			}
-			buffer = malloc(buffersize + 1);
-		}
-		memcpy(buffer, s, e - s);
-		buffer[e - s] = 0;
-	}
-    return buffer;
-}
-
-static char* do_eglShaderPatch(char *source, int len, int *patched_len)
-{
-    /* DISCLAIMER: this is not a full-blown shader parser but a simple
-     * implementation which tries to remove the OpenGL ES shader
-     * "precision" statements and precision qualifiers "lowp", "mediump"
-     * and "highp" from the specified shader source, replace built-in
-	 * constants that were renamed in GLSL ES ("gl_MaxVertexUniformVectors",
-	 * "gl_MaxFragmentUniformVectors" and "gl_MaxVaryingVectors")
-	 * and insert a "#version 120" directive in the beginning of the source
-	 * or replace an existing "#version 100" directive. */
-	DGLES2_ASSERT(source != NULL);
-	DGLES2_ASSERT(len >= 0);
-	{
-#ifndef DGLES2_ALLOW_GLSL_110
-		GLboolean version_found = GL_FALSE;
-#endif
-		int buffer_size;
-		char *patched;
-		const char *p;
-		
-		*patched_len = 0;
-		buffer_size = len;
-		patched = malloc(buffer_size + 1);
-		if(patched == NULL)	{
-			return NULL;
-		}
-
-		p = opengl_strtok(source, &len);
-		for (; p; p = opengl_strtok(0, &len)) {
-			if (!strcmp(p, "lowp") || !strcmp(p, "mediump") || !strcmp(p, "highp")) {
-				continue;
-			} else if (!strcmp(p, "precision")) {
-				do {
-					p = opengl_strtok(0, &len);
-				} while(p && !strchr(p, ';'));
-			} else {
-				int tok_len;
-				if (!strcmp(p, "gl_MaxVertexUniformVectors")) {
-					p = "(gl_MaxVertexUniformComponents / 4)";
-				} else if (!strcmp(p, "gl_MaxFragmentUniformVectors")) {
-					p = "(gl_MaxFragmentUniformComponents / 4)";
-				} else if (!strcmp(p, "gl_MaxVaryingVectors")) {
-					p = "(gl_MaxVaryingFloats / 4)";
-				}
-#ifndef DGLES2_ALLOW_GLSL_110
-				else if (!strcmp(p, "#version")) {
-					p = opengl_strtok(0, &len);
-					if (!strcmp(p, "100")) {
-						p = "#version 120";
-						version_found = GL_TRUE;
-					}
-				} else if (!strcmp(p, "#")) {
-					p = opengl_strtok(0, &len);
-					if (!strcmp(p, "version")) {
-						p = opengl_strtok(0, &len);
-						if (!strcmp(p, "100")) {
-							p = "#version 120";
-							version_found = GL_TRUE;
-						}
-					}
-				} 
-#endif // !DGLES2_ALLOW_GLSL_110
-				tok_len = strlen(p);
-				if(*patched_len + tok_len > buffer_size) {
-					buffer_size *= 2;
-					patched = realloc(patched, buffer_size + 1);
-					if(patched == NULL) {
-						return NULL;
-					}
-				}
-				memcpy(patched + *patched_len, p, tok_len);
-				*patched_len += tok_len;
-			}
-		}
-		patched[*patched_len] = 0;
-#ifndef DGLES2_ALLOW_GLSL_110
-		/* add version directive is one was not found */
-		if (!version_found) {
-			char* new_patched;
-			*patched_len += strlen("#version 120\n");
-			new_patched = malloc(*patched_len + 1);
-			if (new_patched == NULL) {
-				return NULL;
-			}
-			strcpy(new_patched, "#version 120\n");
-			strcat(new_patched, patched);
-			free(patched);
-			patched = new_patched;
-		}
-#endif // !DGLES2_ALLOW_GLSL_110
-		{
-			/* check that we don't leave dummy preprocessor lines */
-			char *sp;
-			for (sp = patched; *sp;) {
-				for (; *sp == ' ' || *sp == '\t'; sp++);
-				if (!strncmp(sp, "#define", 7)) {
-					for (p = sp + 7; *p == ' ' || *p == '\t'; p++);
-					if (*p == '\n' || *p == '\r' || *p == '/') {
-						memset(sp, 0x20, 7);
-					}
-				}
-				for (; *sp && *sp != '\n' && *sp != '\r'; sp++);
-				for (; *sp == '\n' || *sp == '\r'; sp++);
-			}
-		}
-
-		return patched;
-	}
-}
-
-GL_APICALL_BUILD void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length)
-{
-	DGLES2_ENTER();
-	DGLES2_ERROR_IF(ctx->hgl.IsProgram(shader), GL_INVALID_OPERATION);
-	DGLES2_ERROR_IF(!ctx->hgl.IsShader(shader), GL_INVALID_VALUE);
-	DGLES2_ERROR_IF(count < 0, GL_INVALID_VALUE);
-/*
-#if(CONFIG_DEBUG == 1)
-	Dprintf("Editing shader:\n--ORIGINAL-SHADER--\n");
-	for(unsigned i = 0; i < count; ++i)
-	{
-		if(length)
-			Dprintf("%*s", length[i], string[i]);
-		else
-			Dprintf("%s", string[i]);
-	}
-	Dprintf("---END-ORIGINAL-SHADER---\n");
-#endif // !NDEBUG
-	char** string_dgl = malloc(sizeof(char*)*count);
-	GLint* length_dgl = malloc(sizeof(GLint)*count);
-
-	// Remove the non OpenGL 2.x compilant keywords.
-	for(unsigned i = 0; i < count; ++i)
-	{
-		static const char* removables[] =
-		{
-			"precision highp float;",
-			"precision mediump float;",
-			"precision lowp float;",
-			"highp",
-			"lowp",
-			"mediump",
-			"precision"
-		};
-
-		length_dgl[i] = length ? length[i] : strlen(string[i]);
-		string_dgl[i] = malloc(length_dgl[i] + 1);
-		memcpy(string_dgl[i], string[i], length_dgl[i]);
-		string_dgl[i][length_dgl[i]] = 0;
-
-		for(unsigned j = 0; j < sizeof(removables)/sizeof(removables[0]); ++j)
-		{
-			char const* p;
-			while((p = strstr(string_dgl[i], removables[j])))
-			{
-				memmove(p, p + strlen(removables[j]), strlen(p + strlen(removables[j])) + 1);
-			}
-		}
-	}
-#if(CONFIG_DEBUG == 1)
-	Dprintf("Loading shader:\n--DESKTOP-GL-SHADER--\n");
-	for(unsigned i = 0; i < count; ++i)
-	{
-		Dprintf("%*s", length_dgl[i], string_dgl[i]);
-	}
-	Dprintf("---END-DESKTOP-GL-SHADER---\n");
-#endif // !NDEBUG
-    
-	ctx->hgl.ShaderSource(shader, count, string_dgl, length_dgl);
-
-	for(unsigned i = 0; i < count; ++i)
-		free(string_dgl[i]);
-	free(string_dgl);
-	free(length_dgl);
- */
-
-	if(count > 0 && string != NULL)
-	{
-		char* source = NULL;
-		int total_len = 0;
-
-		if(count > 1)
-		{
-			int i;
-
-			// Concatenate the passed strings into one source string.
-			for(i = 0; i < count; i++)
-			{
-				int len;
-
-				if(string[i] == NULL)
-				{
-					continue;
-				}
-
-				if(length == NULL || length[i] < 0)
-				{
-					len = strlen(string[i]);
-				}
-				else
-				{
-					len = length[i];
-				}
-
-				if(len > 0)
-				{
-					total_len += len;
-
-					if(source == NULL)
-					{
-						source = malloc(total_len + 1);
-						if(source == NULL)
-						{
-							DGLES2_ERROR(GL_OUT_OF_MEMORY);
-						}
-						source[0] = 0;
-					}
-					else
-					{
-						source = realloc(source, total_len + 1);
-						if(source == NULL)
-						{
-							DGLES2_ERROR(GL_OUT_OF_MEMORY);
-						}
-					}
-
-					strncat(source, string[i], len);
-				}
-			}
-		}
-		else
-		{
-			source = (char*)string[0];
-			if(length == NULL || length[0] < 0)
-			{
-				total_len = strlen(source);
-			}
-			else
-			{
-				total_len = length[0];
-			}
-		}
-
-		{
-			// FIXME: This will fail with real constant data!
-			int patched_len;
-			const GLchar* patched = do_eglShaderPatch(source, total_len, &patched_len);
-			if(patched == NULL)
-			{
-				DGLES2_ERROR(GL_OUT_OF_MEMORY);
-			}
-			ctx->hgl.ShaderSource(shader, 1, &patched, &patched_len);
-			free((void*)patched);
-		}
-
-		if(DGLContext_getHostError(ctx) == GL_NO_ERROR)
-		{
-			if(!DGLContext_setShaderSource(ctx, shader, source, total_len))
-			{
-				DGLES2_ERROR(GL_OUT_OF_MEMORY);
-			}
-		}
-
-		if(count > 1)
-		{
-			free(source);
-		}
-	}
-	else
-	{
-		ctx->hgl.ShaderSource(shader, count, string, length);
-	}
-
-	DGLES2_LEAVE();
-}