* commit 'f58475b5ae4ccb3a31c05c79da8b2914c62a3510': Add runtime debugging capabilities to OpenGL
This commit is contained in:
commit
d991b40739
@ -67,6 +67,11 @@
|
||||
// function body.
|
||||
#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
|
||||
// value changes over time in a trace.
|
||||
#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:
|
||||
* 1. libs/EGL/trace.cpp: Traces all functions to logcat.
|
||||
* There are three different tracing methods:
|
||||
* 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:
|
||||
* - 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.
|
||||
* 2. libs/GLES_trace: Traces all functions via protobuf to host.
|
||||
* 4. libs/GLES_trace: Traces all functions via protobuf to host.
|
||||
* To enable:
|
||||
* - set system property "debug.egl.debug_proc" to the application name.
|
||||
* - or call setGLDebugLevel(1) from the app.
|
||||
@ -75,10 +81,15 @@ EGLAPI pthread_key_t gGLTraceKey = -1;
|
||||
static int sEGLTraceLevel;
|
||||
static int sEGLApplicationTraceLevel;
|
||||
|
||||
static bool sEGLSystraceEnabled;
|
||||
static bool sEGLGetErrorEnabled;
|
||||
|
||||
int gEGLDebugLevel;
|
||||
static int sEGLApplicationDebugLevel;
|
||||
|
||||
extern gl_hooks_t gHooksTrace;
|
||||
extern gl_hooks_t gHooksSystrace;
|
||||
extern gl_hooks_t gHooksErrorTrace;
|
||||
|
||||
static inline void setGlTraceThreadSpecific(gl_hooks_t const *value) {
|
||||
pthread_setspecific(gGLTraceKey, value);
|
||||
@ -91,6 +102,20 @@ gl_hooks_t const* getGLTraceThreadSpecific() {
|
||||
void initEglTraceLevel() {
|
||||
char value[PROPERTY_VALUE_MAX];
|
||||
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 applicationLevel = sEGLApplicationTraceLevel;
|
||||
sEGLTraceLevel = propertyLevel > applicationLevel ? propertyLevel : applicationLevel;
|
||||
@ -125,7 +150,13 @@ void initEglDebugLevel() {
|
||||
}
|
||||
|
||||
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);
|
||||
setGlThreadSpecific(&gHooksTrace);
|
||||
} else if (gEGLDebugLevel > 0 && value != &gHooksNoContext) {
|
||||
|
@ -26,6 +26,11 @@
|
||||
|
||||
#include <cutils/log.h>
|
||||
|
||||
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
|
||||
#include <utils/Trace.h>
|
||||
|
||||
#include <utils/CallStack.h>
|
||||
|
||||
#include "egl_tls.h"
|
||||
#include "hooks.h"
|
||||
|
||||
@ -314,6 +319,10 @@ static void TraceGL(const char* name, int numArgs, ...) {
|
||||
va_end(argp);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Log trace
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#undef TRACE_GL_VOID
|
||||
#undef TRACE_GL
|
||||
|
||||
@ -349,7 +358,6 @@ EGLAPI gl_hooks_t gHooksTrace = {
|
||||
};
|
||||
#undef GL_ENTRY
|
||||
|
||||
|
||||
#undef TRACE_GL_VOID
|
||||
#undef TRACE_GL
|
||||
|
||||
@ -372,6 +380,99 @@ extern "C" {
|
||||
#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
|
||||
|
||||
|
@ -26,11 +26,6 @@
|
||||
#include <cutils/log.h>
|
||||
#include <cutils/properties.h>
|
||||
|
||||
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
|
||||
#include <utils/Trace.h>
|
||||
|
||||
#include <utils/CallStack.h>
|
||||
|
||||
#include "hooks.h"
|
||||
#include "egl_impl.h"
|
||||
|
||||
@ -44,10 +39,6 @@ using namespace android;
|
||||
#undef CALL_GL_API
|
||||
#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
|
||||
|
||||
#ifdef HAVE_ARM_TLS_REGISTER
|
||||
@ -83,38 +74,10 @@ using namespace android;
|
||||
|
||||
#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, ...) \
|
||||
gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
|
||||
_c->_api(__VA_ARGS__);
|
||||
|
||||
#endif
|
||||
|
||||
#define CALL_GL_API_RETURN(_api, ...) \
|
||||
gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
|
||||
return _c->_api(__VA_ARGS__)
|
||||
|
Loading…
Reference in New Issue
Block a user