diff options
Diffstat (limited to 'opengl')
-rw-r--r-- | opengl/libs/EGL/Loader.cpp | 187 | ||||
-rw-r--r-- | opengl/libs/EGL/Loader.h | 3 | ||||
-rw-r--r-- | opengl/libs/EGL/eglApi.cpp | 10 | ||||
-rw-r--r-- | opengl/libs/EGL/egl_tls.cpp | 30 | ||||
-rw-r--r-- | opengl/libs/EGL/egl_tls.h | 3 | ||||
-rw-r--r-- | opengl/libs/GLES_trace/src/gltrace_context.cpp | 2 | ||||
-rwxr-xr-x | opengl/tools/glgen/gen | 14 | ||||
-rw-r--r-- | opengl/tools/glgen/static/egl/EGLConfig.java | 2 | ||||
-rw-r--r-- | opengl/tools/glgen/static/egl/EGLContext.java | 2 | ||||
-rw-r--r-- | opengl/tools/glgen/static/egl/EGLDisplay.java | 2 | ||||
-rw-r--r-- | opengl/tools/glgen/static/egl/EGLSurface.java | 2 | ||||
-rw-r--r-- | opengl/tools/glgen/stubs/gles11/common.cpp | 1 |
12 files changed, 165 insertions, 93 deletions
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp index 00bfa5a..c02a85f 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 (tag != String8("android")) { - 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 30773cb..8cefe32 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, diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp index 93eedff..2bc9851 100644 --- a/opengl/libs/EGL/eglApi.cpp +++ b/opengl/libs/EGL/eglApi.cpp @@ -1182,6 +1182,11 @@ EGLBoolean eglReleaseThread(void) { clearError(); +#if EGL_TRACE + if (getEGLDebugLevel() > 0) + GLTrace_eglReleaseThread(); +#endif + // If there is context bound to the thread, release it egl_display_t::loseCurrent(get_context(getContext())); @@ -1189,12 +1194,7 @@ EGLBoolean eglReleaseThread(void) if (cnx->dso && cnx->egl.eglReleaseThread) { cnx->egl.eglReleaseThread(); } - egl_tls_t::clearTLS(); -#if EGL_TRACE - if (getEGLDebugLevel() > 0) - GLTrace_eglReleaseThread(); -#endif return EGL_TRUE; } diff --git a/opengl/libs/EGL/egl_tls.cpp b/opengl/libs/EGL/egl_tls.cpp index 52312a2..f3739aa 100644 --- a/opengl/libs/EGL/egl_tls.cpp +++ b/opengl/libs/EGL/egl_tls.cpp @@ -29,8 +29,8 @@ namespace android { -pthread_key_t egl_tls_t::sKey = -1; -pthread_mutex_t egl_tls_t::sLockKey = PTHREAD_MUTEX_INITIALIZER; +pthread_key_t egl_tls_t::sKey = TLS_KEY_NOT_INITIALIZED; +pthread_once_t egl_tls_t::sOnceKey = PTHREAD_ONCE_INIT; egl_tls_t::egl_tls_t() : error(EGL_SUCCESS), ctx(0), logCallWithNoContext(EGL_TRUE) { @@ -59,12 +59,12 @@ const char *egl_tls_t::egl_strerror(EGLint err) { void egl_tls_t::validateTLSKey() { - if (sKey == -1) { - pthread_mutex_lock(&sLockKey); - if (sKey == -1) - pthread_key_create(&sKey, NULL); - pthread_mutex_unlock(&sLockKey); - } + struct TlsKeyInitializer { + static void create() { + pthread_key_create(&sKey, (void (*)(void*))&eglReleaseThread); + } + }; + pthread_once(&sOnceKey, TlsKeyInitializer::create); } void egl_tls_t::setErrorEtcImpl( @@ -104,11 +104,11 @@ egl_tls_t* egl_tls_t::getTLS() { } void egl_tls_t::clearTLS() { - if (sKey != -1) { + if (sKey != TLS_KEY_NOT_INITIALIZED) { egl_tls_t* tls = (egl_tls_t*)pthread_getspecific(sKey); if (tls) { - delete tls; pthread_setspecific(sKey, 0); + delete tls; } } } @@ -120,10 +120,13 @@ void egl_tls_t::clearError() { } EGLint egl_tls_t::getError() { - if (sKey == -1) + if (sKey == TLS_KEY_NOT_INITIALIZED) { return EGL_SUCCESS; + } egl_tls_t* tls = (egl_tls_t*)pthread_getspecific(sKey); - if (!tls) return EGL_SUCCESS; + if (!tls) { + return EGL_SUCCESS; + } EGLint error = tls->error; tls->error = EGL_SUCCESS; return error; @@ -135,8 +138,9 @@ void egl_tls_t::setContext(EGLContext ctx) { } EGLContext egl_tls_t::getContext() { - if (sKey == -1) + if (sKey == TLS_KEY_NOT_INITIALIZED) { return EGL_NO_CONTEXT; + } egl_tls_t* tls = (egl_tls_t *)pthread_getspecific(sKey); if (!tls) return EGL_NO_CONTEXT; return tls->ctx; diff --git a/opengl/libs/EGL/egl_tls.h b/opengl/libs/EGL/egl_tls.h index 56c5dba..5af4f5b 100644 --- a/opengl/libs/EGL/egl_tls.h +++ b/opengl/libs/EGL/egl_tls.h @@ -30,8 +30,9 @@ namespace android { class DbgContext; class egl_tls_t { + enum { TLS_KEY_NOT_INITIALIZED = -1 }; static pthread_key_t sKey; - static pthread_mutex_t sLockKey; + static pthread_once_t sOnceKey; EGLint error; EGLContext ctx; diff --git a/opengl/libs/GLES_trace/src/gltrace_context.cpp b/opengl/libs/GLES_trace/src/gltrace_context.cpp index 3a8decc..0323e8f 100644 --- a/opengl/libs/GLES_trace/src/gltrace_context.cpp +++ b/opengl/libs/GLES_trace/src/gltrace_context.cpp @@ -32,7 +32,7 @@ static pthread_key_t sTLSKey = -1; static pthread_once_t sPthreadOnceKey = PTHREAD_ONCE_INIT; void createTLSKey() { - pthread_key_create(&sTLSKey, NULL); + pthread_key_create(&sTLSKey, (void (*)(void*))&releaseContext); } GLTraceContext *getGLTraceContext() { diff --git a/opengl/tools/glgen/gen b/opengl/tools/glgen/gen index d236c1e..7146a29 100755 --- a/opengl/tools/glgen/gen +++ b/opengl/tools/glgen/gen @@ -32,10 +32,6 @@ echo "package android.os; public class RemoteException extends Exception {}" > o echo "package android.util; public class Log {public static void w(String a, String b) {} public static void e(String a, String b) {}}" > out/android/util/Log.java echo "package android.opengl; public abstract class EGLObjectHandle { public int getHandle() { return 0; } }" > out/android/opengl/EGLObjectHandle.java -echo "package android.opengl; public class EGLSurface extends EGLObjectHandle { }" > out/android/opengl/EGLSurface.java -echo "package android.opengl; public class EGLContext extends EGLObjectHandle { }" > out/android/opengl/EGLContext.java -echo "package android.opengl; public class EGLDisplay extends EGLObjectHandle { }" > out/android/opengl/EGLDisplay.java -echo "package android.opengl; public class EGLConfig extends EGLObjectHandle { }" > out/android/opengl/EGLConfig.java echo "package android.graphics;" > out/android/graphics/SurfaceTexture.java @@ -47,6 +43,7 @@ echo "public interface Surface {}" >> out/android/view/Surface.java echo "package android.view;" > out/android/view/SurfaceHolder.java echo "public interface SurfaceHolder { Surface getSurface(); }" >> out/android/view/SurfaceHolder.java +cp static/egl/*.java out/android/opengl/ GLFILE=out/javax/microedition/khronos/opengles/GL.java cp stubs/jsr239/GLHeader.java-if $GLFILE @@ -141,8 +138,8 @@ compareGenerated() { echo SAID_PLEASE=1 fi - echo " " cp $2/$3 $1 - echo " " git add $1/$3 + echo " cp $2/$3 $1" + echo " (cd $1; git add $3)" KEEP_GENERATED=1 fi } @@ -161,6 +158,11 @@ do compareGenerated ../../../../base/core/jni generated/C android_opengl_${x}.cpp done +for x in EGLConfig EGLContext EGLDisplay EGLObjectHandle EGLSurface +do + compareGenerated ../../../../base/opengl/java/android/opengl generated/android/opengl ${x}.java +done + if [ $KEEP_GENERATED == "0" ] ; then rm -rf generated fi diff --git a/opengl/tools/glgen/static/egl/EGLConfig.java b/opengl/tools/glgen/static/egl/EGLConfig.java index d457c9f..a7a6bbb 100644 --- a/opengl/tools/glgen/static/egl/EGLConfig.java +++ b/opengl/tools/glgen/static/egl/EGLConfig.java @@ -29,7 +29,7 @@ public class EGLConfig extends EGLObjectHandle { @Override public boolean equals(Object o) { if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (!(o instanceof EGLConfig)) return false; EGLConfig that = (EGLConfig) o; return getHandle() == that.getHandle(); diff --git a/opengl/tools/glgen/static/egl/EGLContext.java b/opengl/tools/glgen/static/egl/EGLContext.java index 41b8ef1..c93bd6e 100644 --- a/opengl/tools/glgen/static/egl/EGLContext.java +++ b/opengl/tools/glgen/static/egl/EGLContext.java @@ -29,7 +29,7 @@ public class EGLContext extends EGLObjectHandle { @Override public boolean equals(Object o) { if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (!(o instanceof EGLContext)) return false; EGLContext that = (EGLContext) o; return getHandle() == that.getHandle(); diff --git a/opengl/tools/glgen/static/egl/EGLDisplay.java b/opengl/tools/glgen/static/egl/EGLDisplay.java index 17d1a64..5b8043a 100644 --- a/opengl/tools/glgen/static/egl/EGLDisplay.java +++ b/opengl/tools/glgen/static/egl/EGLDisplay.java @@ -29,7 +29,7 @@ public class EGLDisplay extends EGLObjectHandle { @Override public boolean equals(Object o) { if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (!(o instanceof EGLDisplay)) return false; EGLDisplay that = (EGLDisplay) o; return getHandle() == that.getHandle(); diff --git a/opengl/tools/glgen/static/egl/EGLSurface.java b/opengl/tools/glgen/static/egl/EGLSurface.java index 65bec4f..c379dc9 100644 --- a/opengl/tools/glgen/static/egl/EGLSurface.java +++ b/opengl/tools/glgen/static/egl/EGLSurface.java @@ -29,7 +29,7 @@ public class EGLSurface extends EGLObjectHandle { @Override public boolean equals(Object o) { if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (!(o instanceof EGLSurface)) return false; EGLSurface that = (EGLSurface) o; return getHandle() == that.getHandle(); diff --git a/opengl/tools/glgen/stubs/gles11/common.cpp b/opengl/tools/glgen/stubs/gles11/common.cpp index 579d573..75b75cb 100644 --- a/opengl/tools/glgen/stubs/gles11/common.cpp +++ b/opengl/tools/glgen/stubs/gles11/common.cpp @@ -272,6 +272,7 @@ getarray int _needed = 0; params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset); + _remaining /= sizeof(CTYPE); // convert from bytes to item count _needed = getNeededCount(pname); // if we didn't find this pname, we just assume the user passed // an array of the right size -- this might happen with extensions |