diff options
Diffstat (limited to 'opengl')
-rw-r--r-- | opengl/libs/EGL/Loader.cpp | 237 | ||||
-rw-r--r-- | opengl/libs/EGL/Loader.h | 3 | ||||
-rw-r--r-- | opengl/libs/EGL/egl.cpp | 34 | ||||
-rw-r--r-- | opengl/libs/EGL/eglApi.cpp | 12 | ||||
-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/EGL/getProcAddress.cpp | 22 | ||||
-rw-r--r-- | opengl/libs/GLES2/gl2.cpp | 34 | ||||
-rw-r--r-- | opengl/libs/GLES_CM/gl.cpp | 56 | ||||
-rw-r--r-- | opengl/libs/GLES_trace/src/gltrace_context.cpp | 2 | ||||
-rw-r--r-- | opengl/libs/hooks.h | 35 | ||||
-rw-r--r-- | opengl/specs/EGL_ANDROID_presentation_time.txt | 21 | ||||
-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 |
18 files changed, 258 insertions, 254 deletions
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp index 56550b3..beaa560 100644 --- a/opengl/libs/EGL/Loader.cpp +++ b/opengl/libs/EGL/Loader.cpp @@ -1,16 +1,16 @@ -/* +/* ** Copyright 2007, The Android Open Source Project ** - ** Licensed under the Apache License, Version 2.0 (the "License"); - ** you may not use this file except in compliance with the License. - ** You may obtain a copy of the License at + ** Licensed under the Apache License, Version 2.0 (the "License"); + ** you may not use this file except in compliance with the License. + ** You may obtain a copy of the License at ** - ** http://www.apache.org/licenses/LICENSE-2.0 + ** http://www.apache.org/licenses/LICENSE-2.0 ** - ** Unless required by applicable law or agreed to in writing, software - ** distributed under the License is distributed on an "AS IS" BASIS, - ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ** See the License for the specific language governing permissions and + ** Unless required by applicable law or agreed to in writing, software + ** distributed under the License is distributed on an "AS IS" BASIS, + ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ** See the License for the specific language governing permissions and ** limitations under the License. */ @@ -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,10 +39,26 @@ namespace android { /* - * EGL drivers are called - * - * /system/lib/egl/lib{[EGL|GLESv1_CM|GLESv2] | GLES}_$TAG.so - * + * 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: + * + * /{vendor|system}/lib/egl/lib{GLES | [EGL|GLESv1_CM|GLESv2]}_*.so + * */ ANDROID_SINGLETON_STATIC_INSTANCE( Loader ) @@ -99,14 +116,14 @@ static char const * getProcessCmdline() { // ---------------------------------------------------------------------------- -Loader::driver_t::driver_t(void* gles) +Loader::driver_t::driver_t(void* gles) { dso[0] = gles; for (size_t i=1 ; i<NELEM(dso) ; i++) dso[i] = 0; } -Loader::driver_t::~driver_t() +Loader::driver_t::~driver_t() { for (size_t i=0 ; i<NELEM(dso) ; i++) { if (dso[i]) { @@ -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(); } @@ -185,30 +171,24 @@ 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"); - cnx->libGles2 = load_wrapper("system/lib/libGLESv2.so"); - cnx->libGles1 = load_wrapper("system/lib/libGLESv1_CM.so"); + cnx->libGles2 = load_wrapper("/system/lib/libGLESv2.so"); + cnx->libGles1 = load_wrapper("/system/lib/libGLESv1_CM.so"); LOG_ALWAYS_FATAL_IF(!cnx->libGles2 || !cnx->libGles1, "couldn't load system OpenGL ES wrapper libraries"); @@ -222,16 +202,16 @@ status_t Loader::close(void* driver) return NO_ERROR; } -void Loader::init_api(void* dso, - char const * const * api, - __eglMustCastToProperFunctionPointerType* curr, - getProcAddressType getProcAddress) +void Loader::init_api(void* dso, + char const * const * api, + __eglMustCastToProperFunctionPointerType* curr, + getProcAddressType getProcAddress) { const ssize_t SIZE = 256; char scrap[SIZE]; while (*api) { char const * name = *api; - __eglMustCastToProperFunctionPointerType f = + __eglMustCastToProperFunctionPointerType f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, name); if (f == NULL) { // couldn't find the entry-point, use eglGetProcAddress() @@ -278,21 +258,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) { @@ -306,7 +371,7 @@ void *Loader::load_driver(const char* kind, const char *tag, if (mask & EGL) { getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress"); - ALOGE_IF(!getProcAddress, + ALOGE_IF(!getProcAddress, "can't find eglGetProcAddress() in %s", driver_absolute_path); #ifdef SYSTEMUI_PBSIZE_HACK @@ -344,7 +409,7 @@ void *Loader::load_driver(const char* kind, const char *tag, char const * const * api = egl_names; while (*api) { char const * name = *api; - __eglMustCastToProperFunctionPointerType f = + __eglMustCastToProperFunctionPointerType f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, name); if (f == NULL) { // couldn't find the entry-point, use eglGetProcAddress() @@ -357,7 +422,7 @@ void *Loader::load_driver(const char* kind, const char *tag, api++; } } - + if (mask & GLESv1_CM) { init_api(dso, gl_names, (__eglMustCastToProperFunctionPointerType*) @@ -371,7 +436,7 @@ void *Loader::load_driver(const char* kind, const char *tag, &cnx->hooks[egl_connection_t::GLESv2_INDEX]->gl, getProcAddress); } - + return dso; } 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/egl.cpp b/opengl/libs/EGL/egl.cpp index 6ac8724..86637dc 100644 --- a/opengl/libs/EGL/egl.cpp +++ b/opengl/libs/EGL/egl.cpp @@ -230,9 +230,6 @@ static int gl_no_context() { static void early_egl_init(void) { -#if !USE_FAST_TLS_KEY - pthread_key_create(&gGLWrapperKey, NULL); -#endif #if EGL_TRACE pthread_key_create(&gGLTraceKey, NULL); initEglTraceLevel(); @@ -341,42 +338,11 @@ void gl_noop() { // ---------------------------------------------------------------------------- -#if USE_FAST_TLS_KEY - -// We have a dedicated TLS slot in bionic -static inline gl_hooks_t const * volatile * get_tls_hooks() { - volatile void *tls_base = __get_tls(); - gl_hooks_t const * volatile * tls_hooks = - reinterpret_cast<gl_hooks_t const * volatile *>(tls_base); - return tls_hooks; -} - void setGlThreadSpecific(gl_hooks_t const *value) { gl_hooks_t const * volatile * tls_hooks = get_tls_hooks(); tls_hooks[TLS_SLOT_OPENGL_API] = value; } -gl_hooks_t const* getGlThreadSpecific() { - gl_hooks_t const * volatile * tls_hooks = get_tls_hooks(); - gl_hooks_t const* hooks = tls_hooks[TLS_SLOT_OPENGL_API]; - if (hooks) return hooks; - return &gHooksNoContext; -} - -#else - -void setGlThreadSpecific(gl_hooks_t const *value) { - pthread_setspecific(gGLWrapperKey, value); -} - -gl_hooks_t const* getGlThreadSpecific() { - gl_hooks_t const* hooks = static_cast<gl_hooks_t*>(pthread_getspecific(gGLWrapperKey)); - if (hooks) return hooks; - return &gHooksNoContext; -} - -#endif - // ---------------------------------------------------------------------------- // GL / EGL hooks // ---------------------------------------------------------------------------- diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp index f39c386..6c285d3 100644 --- a/opengl/libs/EGL/eglApi.cpp +++ b/opengl/libs/EGL/eglApi.cpp @@ -866,9 +866,7 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname) } if (found) { -#if USE_FAST_TLS_KEY addr = gExtensionForwarders[slot]; -#endif sGLExtentionMap.add(name, addr); sGLExtentionSlot++; } @@ -1199,6 +1197,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())); @@ -1206,12 +1209,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/EGL/getProcAddress.cpp b/opengl/libs/EGL/getProcAddress.cpp index c160aa0..add2a79 100644 --- a/opengl/libs/EGL/getProcAddress.cpp +++ b/opengl/libs/EGL/getProcAddress.cpp @@ -34,9 +34,7 @@ namespace android { #undef GL_EXTENSION_LIST #undef GET_TLS -#if USE_FAST_TLS_KEY - - #if defined(__arm__) +#if defined(__arm__) #define GET_TLS(reg) "mrc p15, 0, " #reg ", c13, c0, 3 \n" @@ -58,7 +56,7 @@ namespace android { : \ ); - #elif defined(__mips__) +#elif defined(__mips__) #define API_ENTRY(_api) __attribute__((noinline)) _api @@ -88,27 +86,21 @@ namespace android { ext.extensions[_api])) \ : \ ); +#endif - #else - #error Unsupported architecture - #endif - +#if defined(CALL_GL_EXTENSION_API) #define GL_EXTENSION_NAME(_n) __glExtFwd##_n #define GL_EXTENSION(_n) \ void API_ENTRY(GL_EXTENSION_NAME(_n))() { \ CALL_GL_EXTENSION_API(_n); \ } - - #else + #define GL_EXTENSION_NAME(_n) NULL - #define GL_EXTENSION_NAME(_n) NULL - - #define GL_EXTENSION(_n) - - #warning "eglGetProcAddress() partially supported" + #define GL_EXTENSION(_n) + #warning "eglGetProcAddress() partially supported" #endif diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp index fad2176..3134e56 100644 --- a/opengl/libs/GLES2/gl2.cpp +++ b/opengl/libs/GLES2/gl2.cpp @@ -40,13 +40,11 @@ using namespace android; #undef CALL_GL_API #undef CALL_GL_API_RETURN -#if USE_FAST_TLS_KEY - - #if defined(__arm__) +#if defined(__arm__) && !USE_SLOW_BINDING #define GET_TLS(reg) "mrc p15, 0, " #reg ", c13, c0, 3 \n" - #define API_ENTRY(_api) __attribute__((naked)) _api + #define API_ENTRY(_api) __attribute__((noinline)) _api #define CALL_GL_API(_api, ...) \ asm volatile( \ @@ -54,15 +52,13 @@ using namespace android; "ldr r12, [r12, %[tls]] \n" \ "cmp r12, #0 \n" \ "ldrne pc, [r12, %[api]] \n" \ - "mov r0, #0 \n" \ - "bx lr \n" \ : \ : [tls] "J"(TLS_SLOT_OPENGL_API*4), \ [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api)) \ : \ ); - #elif defined(__mips__) +#elif defined(__mips__) && !USE_SLOW_BINDING #define API_ENTRY(_api) __attribute__((noinline)) _api @@ -94,30 +90,21 @@ using namespace android; : \ ); - #else - - #error Unsupported architecture - - #endif - - #define CALL_GL_API_RETURN(_api, ...) \ - CALL_GL_API(_api, __VA_ARGS__) \ - return 0; // placate gcc's warnings. never reached. - #else #define API_ENTRY(_api) _api #define CALL_GL_API(_api, ...) \ gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ - _c->_api(__VA_ARGS__); - - #define CALL_GL_API_RETURN(_api, ...) \ - gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ - return _c->_api(__VA_ARGS__) + if (_c) return _c->_api(__VA_ARGS__); #endif +#define CALL_GL_API_RETURN(_api, ...) \ + CALL_GL_API(_api, __VA_ARGS__) \ + return 0; + + extern "C" { #include "gl3_api.in" @@ -139,7 +126,8 @@ const GLubyte * glGetString(GLenum name) { const GLubyte * ret = egl_get_string_for_current_context(name); if (ret == NULL) { - ret = __glGetString(name); + gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; + ret = _c->glGetString(name); } return ret; } diff --git a/opengl/libs/GLES_CM/gl.cpp b/opengl/libs/GLES_CM/gl.cpp index a5bbdc6..18ef6f9 100644 --- a/opengl/libs/GLES_CM/gl.cpp +++ b/opengl/libs/GLES_CM/gl.cpp @@ -31,9 +31,6 @@ using namespace android; -// set this to 1 for crude GL debugging -#define CHECK_FOR_GL_ERRORS 0 - // ---------------------------------------------------------------------------- // extensions for the framework // ---------------------------------------------------------------------------- @@ -95,13 +92,11 @@ GL_API void GL_APIENTRY glWeightPointerOESBounds(GLint size, GLenum type, #undef CALL_GL_API #undef CALL_GL_API_RETURN -#if USE_FAST_TLS_KEY && !CHECK_FOR_GL_ERRORS - - #if defined(__arm__) +#if defined(__arm__) && !USE_SLOW_BINDING #define GET_TLS(reg) "mrc p15, 0, " #reg ", c13, c0, 3 \n" - #define API_ENTRY(_api) __attribute__((naked)) _api + #define API_ENTRY(_api) __attribute__((noinline)) _api #define CALL_GL_API(_api, ...) \ asm volatile( \ @@ -109,15 +104,13 @@ GL_API void GL_APIENTRY glWeightPointerOESBounds(GLint size, GLenum type, "ldr r12, [r12, %[tls]] \n" \ "cmp r12, #0 \n" \ "ldrne pc, [r12, %[api]] \n" \ - "mov r0, #0 \n" \ - "bx lr \n" \ : \ : [tls] "J"(TLS_SLOT_OPENGL_API*4), \ [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api)) \ : \ ); - #elif defined(__mips__) +#elif defined(__mips__) && !USE_SLOW_BINDING #define API_ENTRY(_api) __attribute__((noinline)) _api @@ -149,43 +142,20 @@ GL_API void GL_APIENTRY glWeightPointerOESBounds(GLint size, GLenum type, : \ ); - #else - #error Unsupported architecture - #endif - - #define CALL_GL_API_RETURN(_api, ...) \ - CALL_GL_API(_api, __VA_ARGS__) \ - return 0; // placate gcc's warnings. never reached. - #else - #if CHECK_FOR_GL_ERRORS - - #define CHECK_GL_ERRORS(_api) \ - do { GLint err = glGetError(); \ - ALOGE_IF(err != GL_NO_ERROR, "%s failed (0x%04X)", #_api, err); \ - } while(false); - - #else - - #define CHECK_GL_ERRORS(_api) do { } while(false); - - #endif - - #define API_ENTRY(_api) _api - #define CALL_GL_API(_api, ...) \ - gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ - _c->_api(__VA_ARGS__); \ - CHECK_GL_ERRORS(_api) - - #define CALL_GL_API_RETURN(_api, ...) \ - gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ - return _c->_api(__VA_ARGS__) + #define CALL_GL_API(_api, ...) \ + gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ + if (_c) return _c->_api(__VA_ARGS__); #endif +#define CALL_GL_API_RETURN(_api, ...) \ + CALL_GL_API(_api, __VA_ARGS__) \ + return 0; + extern "C" { #include "gl_api.in" @@ -202,11 +172,11 @@ extern "C" { extern "C" const GLubyte * __glGetString(GLenum name); -const GLubyte * glGetString(GLenum name) -{ +const GLubyte * glGetString(GLenum name) { const GLubyte * ret = egl_get_string_for_current_context(name); if (ret == NULL) { - ret = __glGetString(name); + gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; + ret = _c->glGetString(name); } return ret; } 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/libs/hooks.h b/opengl/libs/hooks.h index b2a684c..4b43198 100644 --- a/opengl/libs/hooks.h +++ b/opengl/libs/hooks.h @@ -32,13 +32,11 @@ #include <GLES3/gl3.h> #include <GLES3/gl3ext.h> -#if !defined(__arm__) && !defined(__mips__) -#define USE_SLOW_BINDING 1 -#else -#define USE_SLOW_BINDING 0 -#endif +// set to 1 for debugging +#define USE_SLOW_BINDING 0 + #undef NELEM -#define NELEM(x) (sizeof(x)/sizeof(*(x))) +#define NELEM(x) (sizeof(x)/sizeof(*(x))) // maximum number of GL extensions that can be used simultaneously in // a given process. this limitation exists because we need to have @@ -47,15 +45,7 @@ #define MAX_NUMBER_OF_GL_EXTENSIONS 256 -#if defined(HAVE_ANDROID_OS) && !USE_SLOW_BINDING && __OPTIMIZE__ -#define USE_FAST_TLS_KEY 1 -#else -#define USE_FAST_TLS_KEY 0 -#endif - -#if USE_FAST_TLS_KEY -# include <bionic_tls.h> /* special private C library header */ -#endif +#include <bionic_tls.h> /* special private C library header */ // ---------------------------------------------------------------------------- namespace android { @@ -84,7 +74,20 @@ struct gl_hooks_t { #undef EGL_ENTRY EGLAPI void setGlThreadSpecific(gl_hooks_t const *value); -EGLAPI gl_hooks_t const* getGlThreadSpecific(); + +// We have a dedicated TLS slot in bionic +inline gl_hooks_t const * volatile * get_tls_hooks() { + volatile void *tls_base = __get_tls(); + gl_hooks_t const * volatile * tls_hooks = + reinterpret_cast<gl_hooks_t const * volatile *>(tls_base); + return tls_hooks; +} + +inline EGLAPI gl_hooks_t const* getGlThreadSpecific() { + gl_hooks_t const * volatile * tls_hooks = get_tls_hooks(); + gl_hooks_t const* hooks = tls_hooks[TLS_SLOT_OPENGL_API]; + return hooks; +} // ---------------------------------------------------------------------------- }; // namespace android diff --git a/opengl/specs/EGL_ANDROID_presentation_time.txt b/opengl/specs/EGL_ANDROID_presentation_time.txt index 09b3938..e1dab34 100644 --- a/opengl/specs/EGL_ANDROID_presentation_time.txt +++ b/opengl/specs/EGL_ANDROID_presentation_time.txt @@ -10,6 +10,7 @@ Contributors Jamie Gennis Andy McFadden + Jesse Hall Contact @@ -21,7 +22,7 @@ Status Version - Version 2, April 1, 2013 + Version 3, June 26, 2013 Number @@ -92,7 +93,9 @@ Changes to Chapter 3 of the EGL 1.2 Specification (EGL Functions and Errors) If the surface presentation time is successfully set, EGL_TRUE is returned. Otherwise EGL_FALSE is returned and an appropriate error is - set. + set. If <dpy> is not the name of a valid, initialized EGLDisplay, an + EGL_BAD_DISPLAY error is generated. If <surface> is not a valid EGLSurface + then an EGL_BAD_SURFACE error is generated. Issues @@ -110,9 +113,21 @@ Issues System.nanoTime() method, or from the native clock_gettime function by passing CLOCK_MONOTONIC as the clock identifier. + 3. Should the presentation time be state which is used by eglSwapBuffers, + or should it be a new parameter to an extended variant of eglSwapBuffers? + + RESOLVED: The presentation time should be new state which is used by + the existing eglSwapBuffers call. Adding new state composes better with + other (hypothetical) extensions that also modify the behavior of + eglSwapBuffers. + Revision History -#1 (Jamie Gennis, April 1, 2013) +#3 (Jesse Hall, June 26, 2013) + - Enumerated errors generated by eglPresentationTimeANDROID. + - Added Issue #3 with resolution. + +#2 (Jamie Gennis, April 1, 2013) - Clarified how uses that either do or do not need an absolute time should be handled. - Specified the eglPresentationTimeANDROID return value. 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 |