Loading opengl/libs/Android.mk +2 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ EGL/egl.cpp \ EGL/trace.cpp \ EGL/getProcAddress.cpp.arm \ EGL/hooks.cpp \ EGL/Loader.cpp \ Loading @@ -33,6 +34,7 @@ endif LOCAL_CFLAGS += -DLOG_TAG=\"libEGL\" LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES LOCAL_CFLAGS += -fvisibility=hidden LOCAL_CFLAGS += -DEGL_TRACE=1 ifeq ($(TARGET_BOARD_PLATFORM),msm7k) LOCAL_CFLAGS += -DADRENO130=1 Loading opengl/libs/EGL/egl.cpp +73 −6 Original line number Diff line number Diff line Loading @@ -285,6 +285,58 @@ EGLAPI gl_hooks_t gHooks[2][IMPL_NUM_IMPLEMENTATIONS]; EGLAPI gl_hooks_t gHooksNoContext; EGLAPI pthread_key_t gGLWrapperKey = -1; #if EGL_TRACE EGLAPI pthread_key_t gGLTraceKey = -1; // ---------------------------------------------------------------------------- static int gEGLTraceLevel; static int gEGLApplicationTraceLevel; extern EGLAPI gl_hooks_t gHooksTrace; static inline void setGlTraceThreadSpecific(gl_hooks_t const *value) { pthread_setspecific(gGLTraceKey, value); } gl_hooks_t const* getGLTraceThreadSpecific() { return static_cast<gl_hooks_t*>(pthread_getspecific(gGLTraceKey)); } static void initEglTraceLevel() { char value[PROPERTY_VALUE_MAX]; property_get("debug.egl.trace", value, "0"); int propertyLevel = atoi(value); int applicationLevel = gEGLApplicationTraceLevel; gEGLTraceLevel = propertyLevel > applicationLevel ? propertyLevel : applicationLevel; } static void setGLHooksThreadSpecific(gl_hooks_t const *value) { if (gEGLTraceLevel > 0) { setGlTraceThreadSpecific(value); setGlThreadSpecific(&gHooksTrace); } else { setGlThreadSpecific(value); } } /* * Global entry point to allow applications to modify their own trace level. * The effective trace level is the max of this level and the value of debug.egl.trace. */ extern "C" void setGLTraceLevel(int level) { gEGLApplicationTraceLevel = level; } #else static inline void setGLHooksThreadSpecific(gl_hooks_t const *value) { setGlThreadSpecific(value); } #endif // ---------------------------------------------------------------------------- static __attribute__((noinline)) Loading Loading @@ -458,6 +510,10 @@ 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(); #endif uint32_t addr = (uint32_t)((void*)gl_no_context); android_memset32( Loading @@ -465,7 +521,7 @@ static void early_egl_init(void) addr, sizeof(gHooksNoContext)); setGlThreadSpecific(&gHooksNoContext); setGLHooksThreadSpecific(&gHooksNoContext); } static pthread_once_t once_control = PTHREAD_ONCE_INIT; Loading Loading @@ -678,7 +734,15 @@ EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) return EGL_TRUE; } setGlThreadSpecific(&gHooksNoContext); #if EGL_TRACE // Called both at early_init time and at this time. (Early_init is pre-zygote, so // the information from that call may be stale.) initEglTraceLevel(); #endif setGLHooksThreadSpecific(&gHooksNoContext); // initialize each EGL and // build our own extension string first, based on the extension we know Loading Loading @@ -1238,11 +1302,11 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw, // cur_c has to be valid here (but could be terminated) if (ctx != EGL_NO_CONTEXT) { setGlThreadSpecific(c->cnx->hooks[c->version]); setGLHooksThreadSpecific(c->cnx->hooks[c->version]); setContext(ctx); _c.acquire(); } else { setGlThreadSpecific(&gHooksNoContext); setGLHooksThreadSpecific(&gHooksNoContext); setContext(EGL_NO_CONTEXT); } _cur_c.release(); Loading Loading @@ -1434,6 +1498,9 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname) // Extensions are independent of the bound context cnx->hooks[GLESv1_INDEX]->ext.extensions[slot] = cnx->hooks[GLESv2_INDEX]->ext.extensions[slot] = #if EGL_TRACE gHooksTrace.ext.extensions[slot] = #endif cnx->egl.eglGetProcAddress(procname); } } Loading opengl/libs/EGL/trace.cpp 0 → 100644 +247 −0 Original line number Diff line number Diff line /* ** Copyright 2010, 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 ** ** 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 ** limitations under the License. */ #if EGL_TRACE #include <stdarg.h> #include <stdlib.h> #include <EGL/egl.h> #include <EGL/eglext.h> #include <GLES/gl.h> #include <GLES/glext.h> #include <cutils/log.h> #include "hooks.h" // ---------------------------------------------------------------------------- namespace android { // ---------------------------------------------------------------------------- struct GLenumString { GLenum e; const char* s; }; #undef GL_ENUM #define GL_ENUM(VAL,NAME) {VAL, #NAME}, static GLenumString g_enumnames[] = { #include "enums.in" }; #undef GL_ENUM static int compareGLEnum(const void* a, const void* b) { return ((const GLenumString*) a)->e - ((const GLenumString*) b)->e; } static const char* GLEnumToString(GLenum e) { GLenumString key = {e, ""}; const GLenumString* result = (const GLenumString*) bsearch( &key, g_enumnames, sizeof(g_enumnames) / sizeof(g_enumnames[0]), sizeof(g_enumnames[0]), compareGLEnum); if (result) { return result->s; } return NULL; } static GLenumString g_bitfieldNames[] = { {0x00004000, "GL_COLOR_BUFFER_BIT"}, {0x00000400, "GL_STENCIL_BUFFER_BIT"}, {0x00000100, "GL_DEPTH_BUFFER_BIT"} }; static void TraceGLShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length) { LOGD("const char* shaderSrc[] = {"); for (GLsizei i = 0; i < count; i++) { const char* comma = i < count-1 ? "," : ""; const GLchar* s = string[i]; if (length) { GLint len = length[i]; LOGD(" \"%*s\"%s", len, s, comma); } else { LOGD(" \"%s\"%s", s, comma); } } LOGD("};"); if (length) { LOGD("const GLint* shaderLength[] = {"); for (GLsizei i = 0; i < count; i++) { const char* comma = i < count-1 ? "," : ""; GLint len = length[i]; LOGD(" \"%d\"%s", len, comma); } LOGD("};"); LOGD("glShaderSource(%u, %u, shaderSrc, shaderLength);", shader, count); } else { LOGD("glShaderSource(%u, %u, shaderSrc, (const GLint*) 0);", shader, count); } } static void TraceGL(const char* name, int numArgs, ...) { va_list argp; va_start(argp, numArgs); if (strcmp(name, "glShaderSource") == 0) { va_arg(argp, const char*); GLuint shader = va_arg(argp, GLuint); va_arg(argp, const char*); GLsizei count = va_arg(argp, GLsizei); va_arg(argp, const char*); const GLchar** string = (const GLchar**) va_arg(argp, void*); va_arg(argp, const char*); const GLint* length = (const GLint*) va_arg(argp, void*); TraceGLShaderSource(shader, count, string, length); va_end(argp); return; } const int lineSize = 500; char line[lineSize]; int line_index = 0; #define APPEND(...) \ line_index += snprintf(line + line_index, lineSize-line_index, __VA_ARGS__); APPEND("%s(", name); for (int i = 0; i < numArgs; i++) { if (i > 0) { APPEND(", "); } const char* type = va_arg(argp, const char*); bool isPtr = type[strlen(type)-1] == '*' || strcmp(type, "GLeglImageOES") == 0; if (isPtr) { const void* arg = va_arg(argp, const void*); APPEND("(%s) 0x%08x", type, (size_t) arg); } else if (strcmp(type, "GLbitfield") == 0) { size_t arg = va_arg(argp, size_t); bool first = true; for (size_t i = 0; i < sizeof(g_bitfieldNames) / sizeof(g_bitfieldNames[0]); i++) { const GLenumString* b = &g_bitfieldNames[i]; if (b->e & arg) { if (first) { first = false; } else { APPEND(" | "); } APPEND("%s", b->s); arg &= ~b->e; } } if (first || arg != 0) { if (!first) { APPEND(" | "); } APPEND("0x%08x", arg); } } else if (strcmp(type, "GLboolean") == 0) { int arg = va_arg(argp, int); APPEND("%s", arg ? "GL_TRUE" : "GL_FALSE"); } else if (strcmp(type, "GLclampf") == 0) { double arg = va_arg(argp, double); APPEND("%g", arg); } else if (strcmp(type, "GLenum") == 0) { GLenum arg = va_arg(argp, int); const char* s = GLEnumToString(arg); if (s) { APPEND("%s", s); } else { APPEND("0x%x", arg); } } else if (strcmp(type, "GLfixed") == 0) { int arg = va_arg(argp, int); APPEND("0x%08x", arg); } else if (strcmp(type, "GLfloat") == 0) { double arg = va_arg(argp, double); APPEND("%g", arg); } else if (strcmp(type, "GLint") == 0) { int arg = va_arg(argp, int); const char* s = NULL; if (strcmp(name, "glTexParameteri") == 0) { s = GLEnumToString(arg); } if (s) { APPEND("%s", s); } else { APPEND("%d", arg); } } else if (strcmp(type, "GLintptr") == 0) { int arg = va_arg(argp, unsigned int); APPEND("%u", arg); } else if (strcmp(type, "GLsizei") == 0) { int arg = va_arg(argp, size_t); APPEND("%u", arg); } else if (strcmp(type, "GLsizeiptr") == 0) { int arg = va_arg(argp, size_t); APPEND("%u", arg); } else if (strcmp(type, "GLuint") == 0) { int arg = va_arg(argp, unsigned int); APPEND("%u", arg); } else { APPEND("/* ??? %s */", type); break; } } APPEND(");"); line[lineSize-1] = '\0'; LOGD("%s", line); va_end(argp); } #undef TRACE_GL_VOID #undef TRACE_GL #define TRACE_GL_VOID(_api, _args, _argList, ...) \ static void Tracing_ ## _api _args { \ TraceGL(#_api, __VA_ARGS__); \ gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl; \ _c->_api _argList; \ } #define TRACE_GL(_type, _api, _args, _argList, ...) \ static _type Tracing_ ## _api _args { \ TraceGL(#_api, __VA_ARGS__); \ gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl; \ return _c->_api _argList; \ } extern "C" { #include "../trace.in" } #undef TRACE_GL_VOID #undef TRACE_GL #define GL_ENTRY(_r, _api, ...) Tracing_ ## _api, EGLAPI gl_hooks_t gHooksTrace = { { #include "entries.in" }, { {0} } }; #undef GL_ENTRY // ---------------------------------------------------------------------------- }; // namespace android // ---------------------------------------------------------------------------- #endif // EGL_TRACE Loading
opengl/libs/Android.mk +2 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ EGL/egl.cpp \ EGL/trace.cpp \ EGL/getProcAddress.cpp.arm \ EGL/hooks.cpp \ EGL/Loader.cpp \ Loading @@ -33,6 +34,7 @@ endif LOCAL_CFLAGS += -DLOG_TAG=\"libEGL\" LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES LOCAL_CFLAGS += -fvisibility=hidden LOCAL_CFLAGS += -DEGL_TRACE=1 ifeq ($(TARGET_BOARD_PLATFORM),msm7k) LOCAL_CFLAGS += -DADRENO130=1 Loading
opengl/libs/EGL/egl.cpp +73 −6 Original line number Diff line number Diff line Loading @@ -285,6 +285,58 @@ EGLAPI gl_hooks_t gHooks[2][IMPL_NUM_IMPLEMENTATIONS]; EGLAPI gl_hooks_t gHooksNoContext; EGLAPI pthread_key_t gGLWrapperKey = -1; #if EGL_TRACE EGLAPI pthread_key_t gGLTraceKey = -1; // ---------------------------------------------------------------------------- static int gEGLTraceLevel; static int gEGLApplicationTraceLevel; extern EGLAPI gl_hooks_t gHooksTrace; static inline void setGlTraceThreadSpecific(gl_hooks_t const *value) { pthread_setspecific(gGLTraceKey, value); } gl_hooks_t const* getGLTraceThreadSpecific() { return static_cast<gl_hooks_t*>(pthread_getspecific(gGLTraceKey)); } static void initEglTraceLevel() { char value[PROPERTY_VALUE_MAX]; property_get("debug.egl.trace", value, "0"); int propertyLevel = atoi(value); int applicationLevel = gEGLApplicationTraceLevel; gEGLTraceLevel = propertyLevel > applicationLevel ? propertyLevel : applicationLevel; } static void setGLHooksThreadSpecific(gl_hooks_t const *value) { if (gEGLTraceLevel > 0) { setGlTraceThreadSpecific(value); setGlThreadSpecific(&gHooksTrace); } else { setGlThreadSpecific(value); } } /* * Global entry point to allow applications to modify their own trace level. * The effective trace level is the max of this level and the value of debug.egl.trace. */ extern "C" void setGLTraceLevel(int level) { gEGLApplicationTraceLevel = level; } #else static inline void setGLHooksThreadSpecific(gl_hooks_t const *value) { setGlThreadSpecific(value); } #endif // ---------------------------------------------------------------------------- static __attribute__((noinline)) Loading Loading @@ -458,6 +510,10 @@ 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(); #endif uint32_t addr = (uint32_t)((void*)gl_no_context); android_memset32( Loading @@ -465,7 +521,7 @@ static void early_egl_init(void) addr, sizeof(gHooksNoContext)); setGlThreadSpecific(&gHooksNoContext); setGLHooksThreadSpecific(&gHooksNoContext); } static pthread_once_t once_control = PTHREAD_ONCE_INIT; Loading Loading @@ -678,7 +734,15 @@ EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) return EGL_TRUE; } setGlThreadSpecific(&gHooksNoContext); #if EGL_TRACE // Called both at early_init time and at this time. (Early_init is pre-zygote, so // the information from that call may be stale.) initEglTraceLevel(); #endif setGLHooksThreadSpecific(&gHooksNoContext); // initialize each EGL and // build our own extension string first, based on the extension we know Loading Loading @@ -1238,11 +1302,11 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw, // cur_c has to be valid here (but could be terminated) if (ctx != EGL_NO_CONTEXT) { setGlThreadSpecific(c->cnx->hooks[c->version]); setGLHooksThreadSpecific(c->cnx->hooks[c->version]); setContext(ctx); _c.acquire(); } else { setGlThreadSpecific(&gHooksNoContext); setGLHooksThreadSpecific(&gHooksNoContext); setContext(EGL_NO_CONTEXT); } _cur_c.release(); Loading Loading @@ -1434,6 +1498,9 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname) // Extensions are independent of the bound context cnx->hooks[GLESv1_INDEX]->ext.extensions[slot] = cnx->hooks[GLESv2_INDEX]->ext.extensions[slot] = #if EGL_TRACE gHooksTrace.ext.extensions[slot] = #endif cnx->egl.eglGetProcAddress(procname); } } Loading
opengl/libs/EGL/trace.cpp 0 → 100644 +247 −0 Original line number Diff line number Diff line /* ** Copyright 2010, 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 ** ** 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 ** limitations under the License. */ #if EGL_TRACE #include <stdarg.h> #include <stdlib.h> #include <EGL/egl.h> #include <EGL/eglext.h> #include <GLES/gl.h> #include <GLES/glext.h> #include <cutils/log.h> #include "hooks.h" // ---------------------------------------------------------------------------- namespace android { // ---------------------------------------------------------------------------- struct GLenumString { GLenum e; const char* s; }; #undef GL_ENUM #define GL_ENUM(VAL,NAME) {VAL, #NAME}, static GLenumString g_enumnames[] = { #include "enums.in" }; #undef GL_ENUM static int compareGLEnum(const void* a, const void* b) { return ((const GLenumString*) a)->e - ((const GLenumString*) b)->e; } static const char* GLEnumToString(GLenum e) { GLenumString key = {e, ""}; const GLenumString* result = (const GLenumString*) bsearch( &key, g_enumnames, sizeof(g_enumnames) / sizeof(g_enumnames[0]), sizeof(g_enumnames[0]), compareGLEnum); if (result) { return result->s; } return NULL; } static GLenumString g_bitfieldNames[] = { {0x00004000, "GL_COLOR_BUFFER_BIT"}, {0x00000400, "GL_STENCIL_BUFFER_BIT"}, {0x00000100, "GL_DEPTH_BUFFER_BIT"} }; static void TraceGLShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length) { LOGD("const char* shaderSrc[] = {"); for (GLsizei i = 0; i < count; i++) { const char* comma = i < count-1 ? "," : ""; const GLchar* s = string[i]; if (length) { GLint len = length[i]; LOGD(" \"%*s\"%s", len, s, comma); } else { LOGD(" \"%s\"%s", s, comma); } } LOGD("};"); if (length) { LOGD("const GLint* shaderLength[] = {"); for (GLsizei i = 0; i < count; i++) { const char* comma = i < count-1 ? "," : ""; GLint len = length[i]; LOGD(" \"%d\"%s", len, comma); } LOGD("};"); LOGD("glShaderSource(%u, %u, shaderSrc, shaderLength);", shader, count); } else { LOGD("glShaderSource(%u, %u, shaderSrc, (const GLint*) 0);", shader, count); } } static void TraceGL(const char* name, int numArgs, ...) { va_list argp; va_start(argp, numArgs); if (strcmp(name, "glShaderSource") == 0) { va_arg(argp, const char*); GLuint shader = va_arg(argp, GLuint); va_arg(argp, const char*); GLsizei count = va_arg(argp, GLsizei); va_arg(argp, const char*); const GLchar** string = (const GLchar**) va_arg(argp, void*); va_arg(argp, const char*); const GLint* length = (const GLint*) va_arg(argp, void*); TraceGLShaderSource(shader, count, string, length); va_end(argp); return; } const int lineSize = 500; char line[lineSize]; int line_index = 0; #define APPEND(...) \ line_index += snprintf(line + line_index, lineSize-line_index, __VA_ARGS__); APPEND("%s(", name); for (int i = 0; i < numArgs; i++) { if (i > 0) { APPEND(", "); } const char* type = va_arg(argp, const char*); bool isPtr = type[strlen(type)-1] == '*' || strcmp(type, "GLeglImageOES") == 0; if (isPtr) { const void* arg = va_arg(argp, const void*); APPEND("(%s) 0x%08x", type, (size_t) arg); } else if (strcmp(type, "GLbitfield") == 0) { size_t arg = va_arg(argp, size_t); bool first = true; for (size_t i = 0; i < sizeof(g_bitfieldNames) / sizeof(g_bitfieldNames[0]); i++) { const GLenumString* b = &g_bitfieldNames[i]; if (b->e & arg) { if (first) { first = false; } else { APPEND(" | "); } APPEND("%s", b->s); arg &= ~b->e; } } if (first || arg != 0) { if (!first) { APPEND(" | "); } APPEND("0x%08x", arg); } } else if (strcmp(type, "GLboolean") == 0) { int arg = va_arg(argp, int); APPEND("%s", arg ? "GL_TRUE" : "GL_FALSE"); } else if (strcmp(type, "GLclampf") == 0) { double arg = va_arg(argp, double); APPEND("%g", arg); } else if (strcmp(type, "GLenum") == 0) { GLenum arg = va_arg(argp, int); const char* s = GLEnumToString(arg); if (s) { APPEND("%s", s); } else { APPEND("0x%x", arg); } } else if (strcmp(type, "GLfixed") == 0) { int arg = va_arg(argp, int); APPEND("0x%08x", arg); } else if (strcmp(type, "GLfloat") == 0) { double arg = va_arg(argp, double); APPEND("%g", arg); } else if (strcmp(type, "GLint") == 0) { int arg = va_arg(argp, int); const char* s = NULL; if (strcmp(name, "glTexParameteri") == 0) { s = GLEnumToString(arg); } if (s) { APPEND("%s", s); } else { APPEND("%d", arg); } } else if (strcmp(type, "GLintptr") == 0) { int arg = va_arg(argp, unsigned int); APPEND("%u", arg); } else if (strcmp(type, "GLsizei") == 0) { int arg = va_arg(argp, size_t); APPEND("%u", arg); } else if (strcmp(type, "GLsizeiptr") == 0) { int arg = va_arg(argp, size_t); APPEND("%u", arg); } else if (strcmp(type, "GLuint") == 0) { int arg = va_arg(argp, unsigned int); APPEND("%u", arg); } else { APPEND("/* ??? %s */", type); break; } } APPEND(");"); line[lineSize-1] = '\0'; LOGD("%s", line); va_end(argp); } #undef TRACE_GL_VOID #undef TRACE_GL #define TRACE_GL_VOID(_api, _args, _argList, ...) \ static void Tracing_ ## _api _args { \ TraceGL(#_api, __VA_ARGS__); \ gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl; \ _c->_api _argList; \ } #define TRACE_GL(_type, _api, _args, _argList, ...) \ static _type Tracing_ ## _api _args { \ TraceGL(#_api, __VA_ARGS__); \ gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl; \ return _c->_api _argList; \ } extern "C" { #include "../trace.in" } #undef TRACE_GL_VOID #undef TRACE_GL #define GL_ENTRY(_r, _api, ...) Tracing_ ## _api, EGLAPI gl_hooks_t gHooksTrace = { { #include "entries.in" }, { {0} } }; #undef GL_ENTRY // ---------------------------------------------------------------------------- }; // namespace android // ---------------------------------------------------------------------------- #endif // EGL_TRACE