Merge "Add runtime debugging capabilities to OpenGL" into jb-mr1-dev
This commit is contained in:
commit
60393d4520
@ -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)
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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__)
|
||||||
|
Loading…
Reference in New Issue
Block a user