Merge "Add runtime debugging capabilities to OpenGL" into jb-mr1-dev

This commit is contained in:
Romain Guy 2012-10-18 17:33:36 -07:00 committed by Android (Google) Code Review
commit 60393d4520
4 changed files with 142 additions and 42 deletions

View File

@ -67,6 +67,11 @@
// function body. // function body.
#define ATRACE_CALL() android::ScopedTrace ___tracer(ATRACE_TAG, __FUNCTION__) #define ATRACE_CALL() android::ScopedTrace ___tracer(ATRACE_TAG, __FUNCTION__)
// ATRACE_NAME traces the beginning and end of the current function. To trace
// the correct start and end times this macro should be the first line of the
// function body.
#define ATRACE_NAME(name) android::ScopedTrace ___tracer(ATRACE_TAG, name)
// ATRACE_INT traces a named integer value. This can be used to track how the // ATRACE_INT traces a named integer value. This can be used to track how the
// value changes over time in a trace. // value changes over time in a trace.
#define ATRACE_INT(name, value) android::Tracer::traceCounter(ATRACE_TAG, name, value) #define ATRACE_INT(name, value) android::Tracer::traceCounter(ATRACE_TAG, name, value)

View File

@ -62,12 +62,18 @@ EGLAPI pthread_key_t gGLTraceKey = -1;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** /**
* There are two different tracing methods: * There are three different tracing methods:
* 1. libs/EGL/trace.cpp: Traces all functions to logcat. * 1. libs/EGL/trace.cpp: Traces all functions to systrace.
* To enable:
* - set system property "debug.egl.trace" to "systrace" to trace all apps.
* 2. libs/EGL/trace.cpp: Logs a stack trace for GL errors after each function call.
* To enable:
* - set system property "debug.egl.trace" to "error" to trace all apps.
* 3. libs/EGL/trace.cpp: Traces all functions to logcat.
* To enable: * To enable:
* - set system property "debug.egl.trace" to 1 to trace all apps. * - set system property "debug.egl.trace" to 1 to trace all apps.
* - or call setGLTraceLevel(1) from an app to enable tracing for that app. * - or call setGLTraceLevel(1) from an app to enable tracing for that app.
* 2. libs/GLES_trace: Traces all functions via protobuf to host. * 4. libs/GLES_trace: Traces all functions via protobuf to host.
* To enable: * To enable:
* - set system property "debug.egl.debug_proc" to the application name. * - set system property "debug.egl.debug_proc" to the application name.
* - or call setGLDebugLevel(1) from the app. * - or call setGLDebugLevel(1) from the app.
@ -75,10 +81,15 @@ EGLAPI pthread_key_t gGLTraceKey = -1;
static int sEGLTraceLevel; static int sEGLTraceLevel;
static int sEGLApplicationTraceLevel; static int sEGLApplicationTraceLevel;
static bool sEGLSystraceEnabled;
static bool sEGLGetErrorEnabled;
int gEGLDebugLevel; int gEGLDebugLevel;
static int sEGLApplicationDebugLevel; static int sEGLApplicationDebugLevel;
extern gl_hooks_t gHooksTrace; extern gl_hooks_t gHooksTrace;
extern gl_hooks_t gHooksSystrace;
extern gl_hooks_t gHooksErrorTrace;
static inline void setGlTraceThreadSpecific(gl_hooks_t const *value) { static inline void setGlTraceThreadSpecific(gl_hooks_t const *value) {
pthread_setspecific(gGLTraceKey, value); pthread_setspecific(gGLTraceKey, value);
@ -91,6 +102,20 @@ gl_hooks_t const* getGLTraceThreadSpecific() {
void initEglTraceLevel() { void initEglTraceLevel() {
char value[PROPERTY_VALUE_MAX]; char value[PROPERTY_VALUE_MAX];
property_get("debug.egl.trace", value, "0"); property_get("debug.egl.trace", value, "0");
sEGLGetErrorEnabled = !strcasecmp(value, "error");
if (sEGLGetErrorEnabled) {
sEGLSystraceEnabled = false;
sEGLTraceLevel = 0;
return;
}
sEGLSystraceEnabled = !strcasecmp(value, "systrace");
if (sEGLSystraceEnabled) {
sEGLTraceLevel = 0;
return;
}
int propertyLevel = atoi(value); int propertyLevel = atoi(value);
int applicationLevel = sEGLApplicationTraceLevel; int applicationLevel = sEGLApplicationTraceLevel;
sEGLTraceLevel = propertyLevel > applicationLevel ? propertyLevel : applicationLevel; sEGLTraceLevel = propertyLevel > applicationLevel ? propertyLevel : applicationLevel;
@ -125,7 +150,13 @@ void initEglDebugLevel() {
} }
void setGLHooksThreadSpecific(gl_hooks_t const *value) { void setGLHooksThreadSpecific(gl_hooks_t const *value) {
if (sEGLTraceLevel > 0) { if (sEGLGetErrorEnabled) {
setGlTraceThreadSpecific(value);
setGlThreadSpecific(&gHooksErrorTrace);
} else if (sEGLSystraceEnabled) {
setGlTraceThreadSpecific(value);
setGlThreadSpecific(&gHooksSystrace);
} else if (sEGLTraceLevel > 0) {
setGlTraceThreadSpecific(value); setGlTraceThreadSpecific(value);
setGlThreadSpecific(&gHooksTrace); setGlThreadSpecific(&gHooksTrace);
} else if (gEGLDebugLevel > 0 && value != &gHooksNoContext) { } else if (gEGLDebugLevel > 0 && value != &gHooksNoContext) {

View File

@ -26,6 +26,11 @@
#include <cutils/log.h> #include <cutils/log.h>
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#include <utils/Trace.h>
#include <utils/CallStack.h>
#include "egl_tls.h" #include "egl_tls.h"
#include "hooks.h" #include "hooks.h"
@ -314,6 +319,10 @@ static void TraceGL(const char* name, int numArgs, ...) {
va_end(argp); va_end(argp);
} }
///////////////////////////////////////////////////////////////////////////
// Log trace
///////////////////////////////////////////////////////////////////////////
#undef TRACE_GL_VOID #undef TRACE_GL_VOID
#undef TRACE_GL #undef TRACE_GL
@ -349,7 +358,6 @@ EGLAPI gl_hooks_t gHooksTrace = {
}; };
#undef GL_ENTRY #undef GL_ENTRY
#undef TRACE_GL_VOID #undef TRACE_GL_VOID
#undef TRACE_GL #undef TRACE_GL
@ -372,6 +380,99 @@ extern "C" {
#include "../debug.in" #include "../debug.in"
} }
///////////////////////////////////////////////////////////////////////////
// Systrace
///////////////////////////////////////////////////////////////////////////
#undef TRACE_GL_VOID
#undef TRACE_GL
#define TRACE_GL_VOID(_api, _args, _argList, ...) \
static void Systrace_ ## _api _args { \
ATRACE_NAME(#_api); \
gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl; \
_c->_api _argList; \
}
#define TRACE_GL(_type, _api, _args, _argList, ...) \
static _type Systrace_ ## _api _args { \
ATRACE_NAME(#_api); \
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, ...) Systrace_ ## _api,
EGLAPI gl_hooks_t gHooksSystrace = {
{
#include "entries.in"
},
{
{0}
}
};
#undef GL_ENTRY
///////////////////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////////////////
#undef TRACE_GL_VOID
#undef TRACE_GL
#define CHECK_ERROR(_c, _api) \
GLenum status = GL_NO_ERROR; \
bool error = false; \
while ((status = _c->glGetError()) != GL_NO_ERROR) { \
ALOGD("[" #_api "] 0x%x", status); \
error = true; \
} \
if (error) { \
CallStack s; \
s.update(); \
s.dump("glGetError:" #_api); \
} \
#define TRACE_GL_VOID(_api, _args, _argList, ...) \
static void ErrorTrace_ ## _api _args { \
gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl; \
_c->_api _argList; \
CHECK_ERROR(_c, _api); \
}
#define TRACE_GL(_type, _api, _args, _argList, ...) \
static _type ErrorTrace_ ## _api _args { \
gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl; \
_type _r = _c->_api _argList; \
CHECK_ERROR(_c, _api); \
return _r; \
}
extern "C" {
#include "../trace.in"
}
#undef TRACE_GL_VOID
#undef TRACE_GL
#define GL_ENTRY(_r, _api, ...) ErrorTrace_ ## _api,
EGLAPI gl_hooks_t gHooksErrorTrace = {
{
#include "entries.in"
},
{
{0}
}
};
#undef GL_ENTRY
#undef CHECK_ERROR
#undef TRACE_GL_VOID #undef TRACE_GL_VOID
#undef TRACE_GL #undef TRACE_GL

View File

@ -26,11 +26,6 @@
#include <cutils/log.h> #include <cutils/log.h>
#include <cutils/properties.h> #include <cutils/properties.h>
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#include <utils/Trace.h>
#include <utils/CallStack.h>
#include "hooks.h" #include "hooks.h"
#include "egl_impl.h" #include "egl_impl.h"
@ -44,10 +39,6 @@ using namespace android;
#undef CALL_GL_API #undef CALL_GL_API
#undef CALL_GL_API_RETURN #undef CALL_GL_API_RETURN
#define DEBUG_CALL_GL_API 0
#define DEBUG_PRINT_CALL_STACK_ON_ERROR 0
#define SYSTRACE_CALL_GL_API 0
#if USE_FAST_TLS_KEY #if USE_FAST_TLS_KEY
#ifdef HAVE_ARM_TLS_REGISTER #ifdef HAVE_ARM_TLS_REGISTER
@ -83,38 +74,10 @@ using namespace android;
#define API_ENTRY(_api) _api #define API_ENTRY(_api) _api
#if DEBUG_CALL_GL_API
#define CALL_GL_API(_api, ...) \
gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
_c->_api(__VA_ARGS__); \
GLenum status = GL_NO_ERROR; \
bool error = false; \
while ((status = glGetError()) != GL_NO_ERROR) { \
ALOGD("[" #_api "] 0x%x", status); \
error = true; \
} \
if (DEBUG_PRINT_CALL_STACK_ON_ERROR && error) { \
CallStack s; \
s.update(); \
s.dump("glGetError:" #_api); \
}
#elif SYSTRACE_CALL_GL_API
#define CALL_GL_API(_api, ...) \
ATRACE_CALL(); \
gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
_c->_api(__VA_ARGS__);
#else
#define CALL_GL_API(_api, ...) \ #define CALL_GL_API(_api, ...) \
gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
_c->_api(__VA_ARGS__); _c->_api(__VA_ARGS__);
#endif
#define CALL_GL_API_RETURN(_api, ...) \ #define CALL_GL_API_RETURN(_api, ...) \
gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
return _c->_api(__VA_ARGS__) return _c->_api(__VA_ARGS__)