diff --git a/src/main/cpp/gl/getter.cpp b/src/main/cpp/gl/getter.cpp index 41ea040..b851d09 100644 --- a/src/main/cpp/gl/getter.cpp +++ b/src/main/cpp/gl/getter.cpp @@ -24,7 +24,7 @@ void glGetIntegerv(GLenum pname, GLint *params) { num_extensions = 0; while (token) { num_extensions++; - token = strtok(NULL, " "); + token = strtok(nullptr, " "); } free(copy); } else { @@ -34,7 +34,7 @@ void glGetIntegerv(GLenum pname, GLint *params) { (*params) = num_extensions; return; } - LOAD_GLES(glGetIntegerv, void, GLenum pname, GLint *params); + LOAD_GLES_FUNC(glGetIntegerv); gles_glGetIntegerv(pname, params); LOG_D(" -> %d",*params); CHECK_GL_ERROR @@ -42,8 +42,12 @@ void glGetIntegerv(GLenum pname, GLint *params) { GLenum glGetError() { LOG(); - LOAD_GLES(glGetError, GLenum); - return gles_glGetError(); + LOAD_GLES_FUNC(glGetError); + GLuint err = gles_glGetError(); + if (err != GL_NO_ERROR) { + LOG_E(" -> %d", err); + } + return err; } static std::string es_ext; @@ -80,9 +84,58 @@ void AppendExtension(const char* ext) { es_ext += ' '; } +const char* getBeforeThirdSpace(const char* str) { + static char buffer[256]; + int spaceCount = 0; + const char* start = str; + while (*str) { + if (*str == ' ') { + spaceCount++; + if (spaceCount == 3) break; + } + str++; + } + int len = str - start; + if (len >= sizeof(buffer)) len = sizeof(buffer) - 1; + strncpy(buffer, start, len); + buffer[len] = '\0'; + return buffer; +} + + +const char* getGpuName() { + LOAD_GLES_FUNC(glGetString); + const char *gpuName = (const char *) gles_glGetString(GL_RENDERER); + return gpuName ? gpuName : ""; +} + +void set_es_version() { + LOAD_GLES_FUNC(glGetString); + const char* ESVersion = getBeforeThirdSpace((const char*)gles_glGetString(GL_VERSION)); + int major, minor; + + if (sscanf(ESVersion, "OpenGL ES %d.%d", &major, &minor) == 2) { + hardware->es_version = major * 100 + minor * 10; + } else { + hardware->es_version = 300; + } + LOG_I("OpenGL ES Version: %s (%d)", ESVersion, hardware->es_version); + if (hardware->es_version < 300) { + LOG_I("OpenGL ES version is lower than 3.0! This version is not supported!"); + LOG_I("Disable glslang and SPIRV-Cross. Using vgpu to process all shaders!"); + } +} + +const char* getGLESName() { + LOAD_GLES_FUNC(glGetString); + char* ESVersion = (char*)gles_glGetString(GL_VERSION); + return getBeforeThirdSpace(ESVersion); +} + +static std::string rendererString; const GLubyte * glGetString( GLenum name ) { LOG(); - LOAD_GLES(glGetString, const GLubyte *, GLenum); + LOAD_GLES_FUNC(glGetString); /* Feature in the Future * Advanced OpenGL driver: NV renderer. switch (name) { @@ -103,36 +156,43 @@ const GLubyte * glGetString( GLenum name ) { return (const GLubyte *) "Swung0x48, BZLZHH, Tungsten"; case GL_VERSION: return (const GLubyte *) "4.0.0 MobileGlues"; - case GL_RENDERER: - return gles_glGetString(GL_RENDERER); + case GL_RENDERER: + { + if (rendererString == std::string("")) { + const char* gpuName = getGpuName(); + const char* glesName = getGLESName(); + rendererString = std::string(gpuName) + " | " + std::string(glesName); + } + return (const GLubyte *)rendererString.c_str(); + } case GL_SHADING_LANGUAGE_VERSION: return (const GLubyte *) "4.50 MobileGlues with glslang and SPIRV-Cross"; case GL_EXTENSIONS: return (const GLubyte *) GetExtensionsList(); + default: + return gles_glGetString(name); } - - return gles_glGetString(name); } const GLubyte * glGetStringi(GLenum name, GLuint index) { LOG(); - LOAD_GLES(glGetStringi, const GLubyte *, GLenum, GLuint); + LOAD_GLES_FUNC(glGetStringi); typedef struct { GLenum name; const char** parts; GLuint count; } StringCache; static StringCache caches[] = { - {GL_EXTENSIONS, NULL, 0}, - {GL_VENDOR, NULL, 0}, - {GL_VERSION, NULL, 0}, - {GL_SHADING_LANGUAGE_VERSION, NULL, 0} + {GL_EXTENSIONS, nullptr, 0}, + {GL_VENDOR, nullptr, 0}, + {GL_VERSION, nullptr, 0}, + {GL_SHADING_LANGUAGE_VERSION, nullptr, 0} }; static int initialized = 0; if (!initialized) { - for (int i = 0; i < sizeof(caches)/sizeof(StringCache); i++) { - GLenum target = caches[i].name; - const GLubyte* str = NULL; + for (auto & cache : caches) { + GLenum target = cache.name; + const GLubyte* str = nullptr; const char* delimiter = " "; switch (target) { @@ -150,6 +210,8 @@ const GLubyte * glGetStringi(GLenum name, GLuint index) { case GL_EXTENSIONS: str = glGetString(GL_EXTENSIONS); break; + default: + return gles_glGetStringi(name, index); } if (!str) continue; @@ -157,23 +219,23 @@ const GLubyte * glGetStringi(GLenum name, GLuint index) { char* copy = strdup((const char*)str); char* token = strtok(copy, delimiter); while (token) { - caches[i].parts = (const char**)realloc(caches[i].parts, (caches[i].count + 1) * sizeof(char*)); - caches[i].parts[caches[i].count++] = strdup(token); - token = strtok(NULL, delimiter); + cache.parts = (const char**)realloc(cache.parts, (cache.count + 1) * sizeof(char*)); + cache.parts[cache.count++] = strdup(token); + token = strtok(nullptr, delimiter); } free(copy); } initialized = 1; } - for (int i = 0; i < sizeof(caches)/sizeof(StringCache); i++) { - if (caches[i].name == name) { - if (index >= caches[i].count) { - return NULL; + for (auto & cache : caches) { + if (cache.name == name) { + if (index >= cache.count) { + return nullptr; } - return (const GLubyte*)caches[i].parts[index]; + return (const GLubyte*)cache.parts[index]; } } - return NULL; + return nullptr; } \ No newline at end of file diff --git a/src/main/cpp/gl/getter.h b/src/main/cpp/gl/getter.h index 4fc042f..721bbd3 100644 --- a/src/main/cpp/gl/getter.h +++ b/src/main/cpp/gl/getter.h @@ -18,16 +18,13 @@ extern "C" { #endif GLAPI GLAPIENTRY const GLubyte *glGetString(GLenum name); - GLAPI GLAPIENTRY const GLubyte *glGetStringi(GLenum name, GLuint index); - GLAPI GLAPIENTRY GLenum glGetError(); - GLAPI GLAPIENTRY void glGetIntegerv(GLenum pname, GLint *params); void AppendExtension(const char* ext); - void InitGLESBaseExtensions(); +void set_es_version(); #ifdef __cplusplus } diff --git a/src/main/cpp/gl/glsl/glsl_for_es.cpp b/src/main/cpp/gl/glsl/glsl_for_es.cpp index d7e6093..38a9134 100644 --- a/src/main/cpp/gl/glsl/glsl_for_es.cpp +++ b/src/main/cpp/gl/glsl/glsl_for_es.cpp @@ -550,9 +550,10 @@ char* GLSLtoGLSLES_2(char* glsl_code, GLenum glsl_type, uint essl_version) { return result_essl; } -char * GLSLtoGLSLES_1(char* glsl_code, GLenum glsl_type) { +char * GLSLtoGLSLES_1(char* glsl_code, GLenum glsl_type, unsigned int esversion) { LOG_W("Warning: use glsl optimizer to convert shader.") - char * result = MesaConvertShader(glsl_code, glsl_type == GL_VERTEX_SHADER ? 35633 : 35632, 460LL, 320); + if (esversion < 300) esversion = 300; + char * result = MesaConvertShader(glsl_code, glsl_type == GL_VERTEX_SHADER ? 35633 : 35632, 460LL, esversion); char * ret = (char*)malloc(sizeof(char) * strlen(result) + 1); strcpy(ret, result); return ret; diff --git a/src/main/cpp/gl/glsl/glsl_for_es.h b/src/main/cpp/gl/glsl/glsl_for_es.h index 1e903f1..952a5f0 100644 --- a/src/main/cpp/gl/glsl/glsl_for_es.h +++ b/src/main/cpp/gl/glsl/glsl_for_es.h @@ -14,7 +14,7 @@ extern "C" { #endif #include "../mg.h" -__attribute__((visibility("default"))) extern char *GLSLtoGLSLES_1(char *glsl_code, GLenum glsl_type); +__attribute__((visibility("default"))) extern char *GLSLtoGLSLES_1(char *glsl_code, GLenum glsl_type, unsigned int esversion); __attribute__((visibility("default"))) extern char *GLSLtoGLSLES_2(char *glsl_code, GLenum glsl_type, uint essl_version); __attribute__((visibility("default"))) extern int getGLSLVersion(const char* glsl_code); #ifdef __cplusplus diff --git a/src/main/cpp/gl/mg.c b/src/main/cpp/gl/mg.c index 6c1637a..681bd62 100644 --- a/src/main/cpp/gl/mg.c +++ b/src/main/cpp/gl/mg.c @@ -6,7 +6,7 @@ #define DEBUG 0 -hard_ext_t hard_ext; +hardware_t hardware; gl_state_t gl_state; FUNC_GL_STATE_SIZEI(proxy_width) diff --git a/src/main/cpp/gl/mg.h b/src/main/cpp/gl/mg.h index 5262043..1f6edee 100644 --- a/src/main/cpp/gl/mg.h +++ b/src/main/cpp/gl/mg.h @@ -40,11 +40,11 @@ FUNC_GL_STATE_SIZEI_DECLARATION(proxy_height) FUNC_GL_STATE_ENUM_DECLARATION(proxy_intformat) -struct hard_ext_s { - GLint maxsize; +struct hardware_s { + unsigned int es_version; }; -typedef struct hard_ext_s *hard_ext_t; -extern hard_ext_t hard_ext; +typedef struct hardware_s *hardware_t; +extern hardware_t hardware; struct gl_state_s { GLsizei proxy_width; diff --git a/src/main/cpp/gl/shader.c b/src/main/cpp/gl/shader.c index fba2155..6d72423 100644 --- a/src/main/cpp/gl/shader.c +++ b/src/main/cpp/gl/shader.c @@ -147,10 +147,14 @@ char* process_uniform_declarations(char* glslCode) { modifiedGlslCode[modifiedCodeIndex++] = *cursor++; } - if (modifiedCodeIndex >= maxLength - 1) { + while (modifiedCodeIndex >= maxLength - 1) { maxLength *= 2; - modifiedGlslCode = (char*)realloc(modifiedGlslCode, maxLength); - if (!modifiedGlslCode) return NULL; + char* temp = (char*)realloc(modifiedGlslCode, maxLength); + if (!temp) { + free(modifiedGlslCode); + return NULL; + } + modifiedGlslCode = temp; } } @@ -158,13 +162,14 @@ char* process_uniform_declarations(char* glslCode) { return modifiedGlslCode; } -bool can_run_essl3(int esversion, const char *glsl) { - int glsl_version; - +bool can_run_essl3(unsigned int esversion, const char *glsl) { if (strncmp(glsl, "#version 100", 12) == 0) { - return true; - } else if (strncmp(glsl, "#version 300 es", 15) == 0) { - return true; + return true; + } + + unsigned int glsl_version = 0; + if (strncmp(glsl, "#version 300 es", 15) == 0) { + glsl_version = 300; } else if (strncmp(glsl, "#version 310 es", 15) == 0) { glsl_version = 310; } else if (strncmp(glsl, "#version 320 es", 15) == 0) { @@ -172,17 +177,13 @@ bool can_run_essl3(int esversion, const char *glsl) { } else { return false; } - - if (esversion >= glsl_version) { - return true; - } else { - return false; - } + return esversion >= glsl_version; } + bool is_direct_shader(char *glsl) { - bool es3_ability = can_run_essl3(320, glsl); //Assuming it is 320 + bool es3_ability = can_run_essl3(hardware->es_version, glsl); return es3_ability; } @@ -220,7 +221,11 @@ void glShaderSource(GLuint shader, GLsizei count, const GLchar *const* string, c LOG_D("%s", source); GLint shaderType; glGetShaderiv(shader, GL_SHADER_TYPE, &shaderType); - converted = glsl_version<140?GLSLtoGLSLES_1(source, shaderType):GLSLtoGLSLES_2(source,shaderType,320); + converted = glsl_version<140?GLSLtoGLSLES_1(source, shaderType, hardware->es_version):GLSLtoGLSLES_2(source,shaderType,hardware->es_version); + if (!converted) { + LOG_E("Failed to convert shader %d.", shader); + return; + } converted = process_uniform_declarations(converted); LOG_D("\n[INFO] [Shader] Converted Shader source: \n%s", converted); } diff --git a/src/main/cpp/gles/loader.c b/src/main/cpp/gles/loader.c index be86f2e..124a2e1 100644 --- a/src/main/cpp/gles/loader.c +++ b/src/main/cpp/gles/loader.c @@ -100,9 +100,9 @@ void *proc_address(void *lib, const char *name) { return dlsym(lib, name); } -void set_hard_ext() { - hard_ext = (hard_ext_t)calloc(1, sizeof(struct hard_ext_s)); - +void set_hardware() { + hardware = (hardware_t)calloc(1, sizeof(struct hardware_s)); + set_es_version(); } void init_gl_state() { @@ -158,8 +158,6 @@ void InitGLESCapabilities() { void init_target_gles() { LOG_D("Initializing %s @ %s", RENDERERNAME, __FUNCTION__); - LOG_D("Initializing %s @ hard_ext", RENDERERNAME); - set_hard_ext(); LOG_D("Initializing %s @ gl_state", RENDERERNAME); init_gl_state(); @@ -527,6 +525,9 @@ void init_target_gles() { INIT_GLES_FUNC(glTexStorage3DMultisample) INIT_GLES_FUNC(glMapBufferRange) INIT_GLES_FUNC(glBufferStorageEXT) + + LOG_D("Initializing %s @ hardware", RENDERERNAME); + set_hardware(); InitGLESCapabilities(); LogOpenGLExtensions();