diff options
author | Mathias Agopian <mathias@google.com> | 2013-04-23 20:52:29 +0200 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2013-04-26 23:49:01 +0200 |
commit | 993814255fc248454368ed9fe34b4703a05eaf99 (patch) | |
tree | 1f1b7d89ef7d76aaf2984663f7a7a315cb693cf0 /opengl/libs/EGL | |
parent | 748b696c052d0f5e095e1dce34ae6650cd8cb5e4 (diff) | |
download | frameworks_native-993814255fc248454368ed9fe34b4703a05eaf99.tar.gz frameworks_native-993814255fc248454368ed9fe34b4703a05eaf99.tar.bz2 frameworks_native-993814255fc248454368ed9fe34b4703a05eaf99.zip |
change how the userspace GLES drivers are named
for single library:
/vendor/lib/egl/GLES.so
for multiple libraries:
/vendor/lib/egl/EGL.so
/vendor/lib/egl/GLESv1_CM.so
/vendor/lib/egl/GLESv2.so
EGL_BOARD_CONFIG as well as egl.cfg are not needed anymore.
To facilitate the transition, the loader will also look
for the older naming scheme.
Bug: 8631636
Change-Id: Id4b113468df29bae72b323f76598229914e1c7a1
Diffstat (limited to 'opengl/libs/EGL')
-rw-r--r-- | opengl/libs/EGL/Loader.cpp | 187 | ||||
-rw-r--r-- | opengl/libs/EGL/Loader.h | 3 |
2 files changed, 127 insertions, 63 deletions
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp index 73fea3437..c02a85ffe 100644 --- a/opengl/libs/EGL/Loader.cpp +++ b/opengl/libs/EGL/Loader.cpp @@ -21,6 +21,7 @@ #include <errno.h> #include <dlfcn.h> #include <limits.h> +#include <dirent.h> #include <cutils/log.h> #include <cutils/properties.h> @@ -38,9 +39,25 @@ namespace android { /* - * EGL drivers are called + * EGL userspace drivers must be provided either: + * - as a single library: + * /vendor/lib/egl/libGLES.so + * + * - as separate libraries: + * /vendor/lib/egl/libEGL.so + * /vendor/lib/egl/libGLESv1_CM.so + * /vendor/lib/egl/libGLESv2.so + * + * The software renderer for the emulator must be provided as a single + * library at: + * + * /system/lib/egl/libGLES_android.so + * + * + * For backward compatibility and to facilitate the transition to + * this new naming scheme, the loader will additionally look for: * - * /system/lib/egl/lib{[EGL|GLESv1_CM|GLESv2] | GLES}_$TAG.so + * /{vendor|system}/lib/egl/lib{GLES | [EGL|GLESv1_CM|GLESv2]}_*.so * */ @@ -137,41 +154,10 @@ status_t Loader::driver_t::set(void* hnd, int32_t api) // ---------------------------------------------------------------------------- Loader::Loader() -{ - char line[256]; - char tag[256]; - - /* Special case for GLES emulation */ - if (checkGlesEmulationStatus() == 0) { - ALOGD("Emulator without GPU support detected. " - "Fallback to software renderer."); - mDriverTag.setTo("android"); - return; - } - - /* Otherwise, use egl.cfg */ - FILE* cfg = fopen("/system/lib/egl/egl.cfg", "r"); - if (cfg == NULL) { - // default config - ALOGD("egl.cfg not found, using default config"); - mDriverTag.setTo("android"); - } else { - while (fgets(line, 256, cfg)) { - int dpy, impl; - if (sscanf(line, "%u %u %s", &dpy, &impl, tag) == 3) { - //ALOGD(">>> %u %u %s", dpy, impl, tag); - // We only load the h/w accelerated implementation - if (String8("android") != tag) { - mDriverTag = tag; - } - } - } - fclose(cfg); - } + : getProcAddress(NULL) { } -Loader::~Loader() -{ +Loader::~Loader() { GLTrace_stop(); } @@ -180,26 +166,20 @@ void* Loader::open(egl_connection_t* cnx) void* dso; driver_t* hnd = 0; - char const* tag = mDriverTag.string(); - if (tag) { - dso = load_driver("GLES", tag, cnx, EGL | GLESv1_CM | GLESv2); + dso = load_driver("GLES", cnx, EGL | GLESv1_CM | GLESv2); + if (dso) { + hnd = new driver_t(dso); + } else { + // Always load EGL first + dso = load_driver("EGL", cnx, EGL); if (dso) { hnd = new driver_t(dso); - } else { - // Always load EGL first - dso = load_driver("EGL", tag, cnx, EGL); - if (dso) { - hnd = new driver_t(dso); - // TODO: make this more automated - hnd->set( load_driver("GLESv1_CM", tag, cnx, GLESv1_CM), GLESv1_CM ); - hnd->set( load_driver("GLESv2", tag, cnx, GLESv2), GLESv2 ); - } + hnd->set( load_driver("GLESv1_CM", cnx, GLESv1_CM), GLESv1_CM ); + hnd->set( load_driver("GLESv2", cnx, GLESv2), GLESv2 ); } } - LOG_FATAL_IF(!index && !hnd, - "couldn't find the default OpenGL ES implementation " - "for default display"); + LOG_ALWAYS_FATAL_IF(!hnd, "couldn't find an OpenGL ES implementation"); return (void*)hnd; } @@ -267,21 +247,106 @@ void Loader::init_api(void* dso, } } -void *Loader::load_driver(const char* kind, const char *tag, +void *Loader::load_driver(const char* kind, egl_connection_t* cnx, uint32_t mask) { - char driver_absolute_path[PATH_MAX]; - const char* const search1 = "/vendor/lib/egl/lib%s_%s.so"; - const char* const search2 = "/system/lib/egl/lib%s_%s.so"; - - snprintf(driver_absolute_path, PATH_MAX, search1, kind, tag); - if (access(driver_absolute_path, R_OK)) { - snprintf(driver_absolute_path, PATH_MAX, search2, kind, tag); - if (access(driver_absolute_path, R_OK)) { - // this happens often, we don't want to log an error - return 0; + class MatchFile { + public: + static String8 find(const char* kind) { + String8 result; + String8 pattern; + pattern.appendFormat("lib%s", kind); + const char* const searchPaths[] = { + "/vendor/lib/egl", + "/system/lib/egl" + }; + + // first, we search for the exact name of the GLES userspace + // driver in both locations. + // i.e.: + // libGLES.so, or: + // libEGL.so, libGLESv1_CM.so, libGLESv2.so + + for (size_t i=0 ; i<NELEM(searchPaths) ; i++) { + if (find(result, pattern, searchPaths[i], true)) { + return result; + } + } + + // for compatibility with the old "egl.cfg" naming convention + // we look for files that match: + // libGLES_*.so, or: + // libEGL_*.so, libGLESv1_CM_*.so, libGLESv2_*.so + + pattern.append("_"); + for (size_t i=0 ; i<NELEM(searchPaths) ; i++) { + if (find(result, pattern, searchPaths[i], false)) { + return result; + } + } + + // we didn't find the driver. gah. + result.clear(); + return result; } + + private: + static bool find(String8& result, + const String8& pattern, const char* const search, bool exact) { + + // in the emulator case, we just return the hardcoded name + // of the software renderer. + if (checkGlesEmulationStatus() == 0) { + ALOGD("Emulator without GPU support detected. " + "Fallback to software renderer."); + result.setTo("/system/lib/egl/libGLES_android.so"); + return true; + } + + if (exact) { + String8 absolutePath; + absolutePath.appendFormat("%s/%s.so", search, pattern.string()); + if (!access(absolutePath.string(), R_OK)) { + result = absolutePath; + return true; + } + return false; + } + + DIR* d = opendir(search); + if (d != NULL) { + struct dirent cur; + struct dirent* e; + while (readdir_r(d, &cur, &e) == 0 && e) { + if (e->d_type == DT_DIR) { + continue; + } + if (!strcmp(e->d_name, "libGLES_android.so")) { + // always skip the software renderer + continue; + } + if (strstr(e->d_name, pattern.string()) == e->d_name) { + if (!strcmp(e->d_name + strlen(e->d_name) - 3, ".so")) { + result.clear(); + result.appendFormat("%s/%s", search, e->d_name); + closedir(d); + return true; + } + } + } + closedir(d); + } + return false; + } + }; + + + String8 absolutePath = MatchFile::find(kind); + if (absolutePath.isEmpty()) { + // this happens often, we don't want to log an error + return 0; } + const char* const driver_absolute_path = absolutePath.string(); void* dso = dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL); if (dso == 0) { diff --git a/opengl/libs/EGL/Loader.h b/opengl/libs/EGL/Loader.h index 30773cb6d..8cefe3276 100644 --- a/opengl/libs/EGL/Loader.h +++ b/opengl/libs/EGL/Loader.h @@ -52,7 +52,6 @@ class Loader : public Singleton<Loader> void* dso[3]; }; - String8 mDriverTag; getProcAddressType getProcAddress; public: @@ -63,7 +62,7 @@ public: private: Loader(); - void *load_driver(const char* kind, const char *tag, egl_connection_t* cnx, uint32_t mask); + void *load_driver(const char* kind, egl_connection_t* cnx, uint32_t mask); static __attribute__((noinline)) void init_api(void* dso, |