summaryrefslogtreecommitdiffstats
path: root/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'opengl')
-rw-r--r--opengl/libs/EGL/Loader.cpp187
-rw-r--r--opengl/libs/EGL/Loader.h3
-rw-r--r--opengl/libs/EGL/eglApi.cpp10
-rw-r--r--opengl/libs/EGL/egl_tls.cpp30
-rw-r--r--opengl/libs/EGL/egl_tls.h3
-rw-r--r--opengl/libs/GLES_trace/src/gltrace_context.cpp2
-rwxr-xr-xopengl/tools/glgen/gen14
-rw-r--r--opengl/tools/glgen/static/egl/EGLConfig.java2
-rw-r--r--opengl/tools/glgen/static/egl/EGLContext.java2
-rw-r--r--opengl/tools/glgen/static/egl/EGLDisplay.java2
-rw-r--r--opengl/tools/glgen/static/egl/EGLSurface.java2
-rw-r--r--opengl/tools/glgen/stubs/gles11/common.cpp1
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