summaryrefslogtreecommitdiffstats
path: root/opengl/libs/EGL/trace.cpp
diff options
context:
space:
mode:
authorJack Palevich <jackpal@google.com>2010-10-26 15:21:24 -0700
committerJack Palevich <jackpal@google.com>2010-10-26 15:21:24 -0700
commitd4d0fb966060f7eaeb7b93e113482724c51c15e6 (patch)
treec0a9c5f199fe441609d2c3a800e6551bc559d732 /opengl/libs/EGL/trace.cpp
parentf0a896b353e01c7093ba2ee0539f1a7cabef6ec6 (diff)
downloadframeworks_base-d4d0fb966060f7eaeb7b93e113482724c51c15e6.zip
frameworks_base-d4d0fb966060f7eaeb7b93e113482724c51c15e6.tar.gz
frameworks_base-d4d0fb966060f7eaeb7b93e113482724c51c15e6.tar.bz2
OpenGL tracing.
Enable with: adb shell setprop debug.egl.trace 1 Change-Id: Icfbc795f5260141510975228e72234e9aab56a85
Diffstat (limited to 'opengl/libs/EGL/trace.cpp')
-rw-r--r--opengl/libs/EGL/trace.cpp247
1 files changed, 247 insertions, 0 deletions
diff --git a/opengl/libs/EGL/trace.cpp b/opengl/libs/EGL/trace.cpp
new file mode 100644
index 0000000..48eeaff
--- /dev/null
+++ b/opengl/libs/EGL/trace.cpp
@@ -0,0 +1,247 @@
+/*
+ ** 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