diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_V2/Android.mk b/tools/emulator/opengl/host/libs/Translator/GLES_V2/Android.mk index 75c33b4af..74c8f6fe0 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLES_V2/Android.mk +++ b/tools/emulator/opengl/host/libs/Translator/GLES_V2/Android.mk @@ -7,10 +7,11 @@ translator_path := $(LOCAL_PATH)/.. #exclude darwin builds ifeq (, $(findstring $(HOST_OS), darwin)) -LOCAL_SRC_FILES := \ - GLESv2Context.cpp \ - GLESv2Validate.cpp \ - GLESv2Imp.cpp +LOCAL_SRC_FILES := \ + GLESv2Imp.cpp \ + GLESv2Context.cpp \ + GLESv2Validate.cpp \ + ShaderParser.cpp \ LOCAL_C_INCLUDES += \ $(translator_path)/include \ diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Context.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Context.cpp index 5ec9f5cfa..ffd791a90 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Context.cpp +++ b/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Context.cpp @@ -16,6 +16,8 @@ #include "GLESv2Context.h" + + void GLESv2Context::init() { android::Mutex::Autolock mutex(s_lock); if(!m_initialized) { diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Context.h b/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Context.h index e0f9ba6c4..5bee0797b 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Context.h +++ b/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Context.h @@ -23,6 +23,7 @@ #include + class GLESv2Context : public GLEScontext{ public: void init(); @@ -31,7 +32,6 @@ public: private: void sendArr(GLvoid* arr,GLenum arrayType,GLint size,GLsizei stride,int pointsIndex = -1); void initExtensionString(); - }; #endif diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp index f95cd8b63..d708a258e 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp +++ b/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp @@ -27,6 +27,7 @@ #include #include "GLESv2Context.h" #include "GLESv2Validate.h" +#include "ShaderParser.h" extern "C" { @@ -313,11 +314,13 @@ GL_APICALL GLuint GL_APIENTRY glCreateProgram(void){ } GL_APICALL GLuint GL_APIENTRY glCreateShader(GLenum type){ - GET_CTX_RET(0); + GET_CTX_V2_RET(0); const GLuint globalShaderName = ctx->dispatcher().glCreateShader(type); if(thrd->shareGroup.Ptr() && globalShaderName) { const GLuint localShaderName = thrd->shareGroup->genName(SHADER); + ShaderParser* sp = new ShaderParser(type); thrd->shareGroup->replaceGlobalName(SHADER,localShaderName,globalShaderName); + thrd->shareGroup->setObjectData(SHADER,localShaderName,ObjectDataPtr(sp)); return localShaderName; } if(globalShaderName){ @@ -381,7 +384,8 @@ GL_APICALL void GL_APIENTRY glDeleteProgram(GLuint program){ GET_CTX(); if(thrd->shareGroup.Ptr()) { const GLuint globalProgramName = thrd->shareGroup->getGlobalName(SHADER,program); - ctx->dispatcher().glDeleteProgram(globalProgramName); + thrd->shareGroup->deleteName(SHADER,program); + ctx->dispatcher().glDeleteProgram(program); } } @@ -389,7 +393,8 @@ GL_APICALL void GL_APIENTRY glDeleteShader(GLuint shader){ GET_CTX(); if(thrd->shareGroup.Ptr()) { const GLuint globalShaderName = thrd->shareGroup->getGlobalName(SHADER,shader); - ctx->dispatcher().glDeleteShader(globalShaderName); + thrd->shareGroup->deleteName(SHADER,shader); + ctx->dispatcher().glDeleteShader(shader); } } @@ -685,17 +690,28 @@ GL_APICALL void GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, } GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision){ - GET_CTX(); - ctx->dispatcher().glGetShaderPrecisionFormat(shadertype,precisiontype,range,precision); + GET_CTX_V2(); + SET_ERROR_IF(!(GLESv2Validate::shaderType(shadertype) && GLESv2Validate::precisionType(precisiontype)),GL_INVALID_ENUM); + if(ctx->glslVersion() < Version(1,30,10)){ //version 1.30.10 is the first version of GLSL Language containing precision qualifiers + range[0] = range[1] = 0; + precision = 0; + } else { + ctx->dispatcher().glGetShaderPrecisionFormat(shadertype,precisiontype,range,precision); + } } -//TODO: may need to convert the source to fit to gles 2.0 shadders GL_APICALL void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source){ GET_CTX(); if(thrd->shareGroup.Ptr()) { - const GLuint globalShaderName = thrd->shareGroup->getGlobalName(SHADER,shader); - ctx->dispatcher().glGetShaderSource(globalShaderName,bufsize,length,source); - //now need to convert it to match gles syntax + const GLuint globalShaderName = thrd->shareGroup->getGlobalName(SHADER,shader); + SET_ERROR_IF(globalShaderName == 0,GL_INVALID_VALUE); + ObjectDataPtr objData = thrd->shareGroup->getObjectData(SHADER,shader); + SET_ERROR_IF(!objData.Ptr(),GL_INVALID_OPERATION); + const char* src = ((ShaderParser*)objData.Ptr())->getOriginalSrc(); + int srcLength = strlen(src); + SET_ERROR_IF(bufsize < 0 || srcLength > bufsize,GL_INVALID_VALUE); + *length = srcLength; + strncpy(source,src,srcLength); } } @@ -969,12 +985,17 @@ GL_APICALL void GL_APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GL } } -//TODO: may need to change the source to match to GL shaders format GL_APICALL void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length){ - GET_CTX(); + GET_CTX_V2(); + SET_ERROR_IF(count < 0,GL_INVALID_VALUE); if(thrd->shareGroup.Ptr()){ const GLuint globalShaderName = thrd->shareGroup->getGlobalName(SHADER,shader); - ctx->dispatcher().glShaderSource(globalShaderName,count,string,length); + SET_ERROR_IF(globalShaderName == 0,GL_INVALID_VALUE); + ObjectDataPtr objData = thrd->shareGroup->getObjectData(SHADER,shader); + SET_ERROR_IF(!objData.Ptr(),GL_INVALID_OPERATION); + ShaderParser* sp = (ShaderParser*)objData.Ptr(); + sp->setSrc(ctx->glslVersion(),count,string,length); + ctx->dispatcher().glShaderSource(globalShaderName,1,sp->parsedLines(),NULL); } } diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Validate.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Validate.cpp index 99ac33158..ea8cbfdd2 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Validate.cpp +++ b/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Validate.cpp @@ -119,3 +119,20 @@ bool GLESv2Validate::readPixelFrmt(GLenum format){ return false; } + +bool GLESv2Validate::shaderType(GLenum type){ + return type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER; +} + +bool GLESv2Validate::precisionType(GLenum type){ + switch(type){ + case GL_LOW_FLOAT: + case GL_MEDIUM_FLOAT: + case GL_HIGH_FLOAT: + case GL_LOW_INT: + case GL_MEDIUM_INT: + case GL_HIGH_INT: + return true; + } + return false; +} diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Validate.h b/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Validate.h index 353fc678d..63389142b 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Validate.h +++ b/tools/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Validate.h @@ -30,7 +30,8 @@ static bool hintTargetMode(GLenum target,GLenum mode); static bool capability(GLenum cap); static bool pixelStoreParam(GLenum param); static bool readPixelFrmt(GLenum format); - +static bool shaderType(GLenum type); +static bool precisionType(GLenum type); }; #endif diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.cpp new file mode 100644 index 000000000..00d6ab0aa --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.cpp @@ -0,0 +1,83 @@ +#include "ShaderParser.h" +#include + +ShaderParser::ShaderParser():m_type(0), + m_src(NULL), + m_parsedLines(NULL){}; + +ShaderParser::ShaderParser(GLenum type):m_type(type), + m_parsedLines(NULL){}; + +void ShaderParser::setSrc(const Version& ver,GLsizei count,const GLchar** strings,const GLint* length){ + for(int i = 0;i +#include +#include + +class ShaderParser:public ObjectData{ +public: + ShaderParser(); + ShaderParser(GLenum type); + void setSrc(const Version& ver,GLsizei count,const GLchar** strings,const GLint* length); + const char* getOriginalSrc(); + const GLchar** parsedLines(){return const_cast(&m_parsedLines);}; + ~ShaderParser(); + +private: + void parseOmitPrecision(); + void parseExtendDefaultPrecision(); + void clearParsedSrc(); + + GLenum m_type; + std::string m_src; + GLchar* m_parsedLines; +}; +#endif diff --git a/tools/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp b/tools/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp index 0f1e7b849..93818feae 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp +++ b/tools/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp @@ -22,6 +22,45 @@ android::Mutex GLEScontext::s_lock; std::string* GLEScontext::s_glExtensions= NULL; GLSupport GLEScontext::s_glSupport; +Version::Version():m_major(0), + m_minor(0), + m_release(0){}; + +Version::Version(int major,int minor,int release):m_major(major), + m_minor(minor), + m_release(release){}; + +Version::Version(const Version& ver):m_major(ver.m_major), + m_minor(ver.m_minor), + m_release(ver.m_release){} + +Version::Version(const char* versionString){ + m_release = 0; + if((!versionString) || + ((!(sscanf(versionString,"%d.%d" ,&m_major,&m_minor) == 2)) && + (!(sscanf(versionString,"%d.%d.%d",&m_major,&m_minor,&m_release) == 3)))){ + m_major = m_minor = 0; // the version is not in the right format + } +} + +Version& Version::operator=(const Version& ver){ + m_major = ver.m_major; + m_minor = ver.m_minor; + m_release = ver.m_release; + return *this; +} + +bool Version::operator<(const Version& ver) const{ + if(m_major < ver.m_major) return true; + if(m_major == ver.m_major){ + if(m_minor < ver.m_minor) return true; + if(m_minor == ver.m_minor){ + return m_release < ver.m_release; + } + } + return false; +} + GLEScontext::GLEScontext(): m_initialized(false) , m_activeTexture(0) , @@ -378,6 +417,8 @@ void GLEScontext::initCapsLocked(const GLubyte * extensionString) s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_SIZE,&s_glSupport.maxTexSize); s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_UNITS,&maxTexUnits); s_glSupport.maxTexUnits = maxTexUnits < MAX_TEX_UNITS ? maxTexUnits:MAX_TEX_UNITS; + const GLubyte* glslVersion = s_glDispatch.glGetString(GL_SHADING_LANGUAGE_VERSION); + s_glSupport.glslVersion = Version((const char*)(glslVersion)); if (strstr(cstring,"GL_EXT_bgra ")!=NULL) s_glSupport.GL_EXT_TEXTURE_FORMAT_BGRA8888 = true; diff --git a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h index 10dd8c03b..af2d39a82 100644 --- a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h +++ b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h @@ -22,6 +22,20 @@ typedef struct _textureUnitState { GLboolean enabled[NUM_TEXTURE_TARGETS]; } textureUnitState; +class Version{ +public: + Version(); + Version(int major,int minor,int release); + Version(const char* versionString); + Version(const Version& ver); + bool operator<(const Version& ver) const; + Version& operator=(const Version& ver); +private: + int m_major; + int m_minor; + int m_release; +}; + struct GLSupport { GLSupport():maxLights(0),maxVertexAttribs(0),maxClipPlane(0),maxTexUnits(0),maxTexSize(0) , \ GL_EXT_TEXTURE_FORMAT_BGRA8888(false), GL_EXT_FRAMEBUFFER_OBJECT(false), \ @@ -34,6 +48,7 @@ struct GLSupport { int maxClipPlane; int maxTexUnits; int maxTexSize; + Version glslVersion; bool GL_EXT_TEXTURE_FORMAT_BGRA8888; bool GL_EXT_FRAMEBUFFER_OBJECT; bool GL_ARB_VERTEX_BLEND; @@ -93,6 +108,7 @@ public: static int getMaxClipPlanes(){return s_glSupport.maxClipPlane;} static int getMaxTexUnits(){return s_glSupport.maxTexUnits;} static int getMaxTexSize(){return s_glSupport.maxTexSize;} + static Version glslVersion(){return s_glSupport.glslVersion;} protected: