trace.cpp revision a2dd6cf59962e3a21a47df29b2f243e904839ba7
1/* 2 ** Copyright 2010, The Android Open Source Project 3 ** 4 ** Licensed under the Apache License, Version 2.0 (the "License"); 5 ** you may not use this file except in compliance with the License. 6 ** You may obtain a copy of the License at 7 ** 8 ** http://www.apache.org/licenses/LICENSE-2.0 9 ** 10 ** Unless required by applicable law or agreed to in writing, software 11 ** distributed under the License is distributed on an "AS IS" BASIS, 12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 ** See the License for the specific language governing permissions and 14 ** limitations under the License. 15 */ 16 17#if EGL_TRACE 18 19#include <stdarg.h> 20#include <stdlib.h> 21 22#include <EGL/egl.h> 23#include <EGL/eglext.h> 24#include <GLES/gl.h> 25#include <GLES/glext.h> 26 27#include <cutils/log.h> 28 29#include "hooks.h" 30 31// ---------------------------------------------------------------------------- 32namespace android { 33// ---------------------------------------------------------------------------- 34 35struct GLenumString { 36 GLenum e; 37 const char* s; 38}; 39 40#undef GL_ENUM 41#define GL_ENUM(VAL,NAME) {VAL, #NAME}, 42 43static GLenumString g_enumnames[] = { 44#include "enums.in" 45}; 46#undef GL_ENUM 47 48static int compareGLEnum(const void* a, const void* b) { 49 return ((const GLenumString*) a)->e - ((const GLenumString*) b)->e; 50} 51 52static const char* GLEnumToString(GLenum e) { 53 GLenumString key = {e, ""}; 54 const GLenumString* result = (const GLenumString*) bsearch( 55 &key, g_enumnames, 56 sizeof(g_enumnames) / sizeof(g_enumnames[0]), 57 sizeof(g_enumnames[0]), compareGLEnum); 58 if (result) { 59 return result->s; 60 } 61 return NULL; 62} 63 64static GLenumString g_bitfieldNames[] = { 65 {0x00004000, "GL_COLOR_BUFFER_BIT"}, 66 {0x00000400, "GL_STENCIL_BUFFER_BIT"}, 67 {0x00000100, "GL_DEPTH_BUFFER_BIT"} 68}; 69 70 71static void TraceGLShaderSource(GLuint shader, GLsizei count, 72 const GLchar** string, const GLint* length) { 73 LOGD("const char* shaderSrc[] = {"); 74 for (GLsizei i = 0; i < count; i++) { 75 const char* comma = i < count-1 ? "," : ""; 76 const GLchar* s = string[i]; 77 if (length) { 78 GLint len = length[i]; 79 LOGD(" \"%*s\"%s", len, s, comma); 80 } else { 81 LOGD(" \"%s\"%s", s, comma); 82 } 83 } 84 LOGD("};"); 85 if (length) { 86 LOGD("const GLint* shaderLength[] = {"); 87 for (GLsizei i = 0; i < count; i++) { 88 const char* comma = i < count-1 ? "," : ""; 89 GLint len = length[i]; 90 LOGD(" \"%d\"%s", len, comma); 91 } 92 LOGD("};"); 93 LOGD("glShaderSource(%u, %u, shaderSrc, shaderLength);", 94 shader, count); 95 } else { 96 LOGD("glShaderSource(%u, %u, shaderSrc, (const GLint*) 0);", 97 shader, count); 98 } 99} 100 101static void TraceGL(const char* name, int numArgs, ...) { 102 va_list argp; 103 va_start(argp, numArgs); 104 if (strcmp(name, "glShaderSource") == 0) { 105 va_arg(argp, const char*); 106 GLuint shader = va_arg(argp, GLuint); 107 va_arg(argp, const char*); 108 GLsizei count = va_arg(argp, GLsizei); 109 va_arg(argp, const char*); 110 const GLchar** string = (const GLchar**) va_arg(argp, void*); 111 va_arg(argp, const char*); 112 const GLint* length = (const GLint*) va_arg(argp, void*); 113 TraceGLShaderSource(shader, count, string, length); 114 va_end(argp); 115 return; 116 } 117 const int lineSize = 500; 118 char line[lineSize]; 119 int line_index = 0; 120 #define APPEND(...) \ 121 line_index += snprintf(line + line_index, lineSize-line_index, __VA_ARGS__); 122 APPEND("%s(", name); 123 for (int i = 0; i < numArgs; i++) { 124 if (i > 0) { 125 APPEND(", "); 126 } 127 const char* type = va_arg(argp, const char*); 128 bool isPtr = type[strlen(type)-1] == '*' 129 || strcmp(type, "GLeglImageOES") == 0; 130 if (isPtr) { 131 const void* arg = va_arg(argp, const void*); 132 APPEND("(%s) 0x%08x", type, (size_t) arg); 133 } else if (strcmp(type, "GLbitfield") == 0) { 134 size_t arg = va_arg(argp, size_t); 135 bool first = true; 136 for (size_t i = 0; i < sizeof(g_bitfieldNames) / sizeof(g_bitfieldNames[0]); i++) { 137 const GLenumString* b = &g_bitfieldNames[i]; 138 if (b->e & arg) { 139 if (first) { 140 first = false; 141 } else { 142 APPEND(" | "); 143 } 144 APPEND("%s", b->s); 145 arg &= ~b->e; 146 } 147 } 148 if (first || arg != 0) { 149 if (!first) { 150 APPEND(" | "); 151 } 152 APPEND("0x%08x", arg); 153 } 154 } else if (strcmp(type, "GLboolean") == 0) { 155 int arg = va_arg(argp, int); 156 APPEND("%s", arg ? "GL_TRUE" : "GL_FALSE"); 157 } else if (strcmp(type, "GLclampf") == 0) { 158 double arg = va_arg(argp, double); 159 APPEND("%g", arg); 160 } else if (strcmp(type, "GLenum") == 0) { 161 GLenum arg = va_arg(argp, int); 162 const char* s = GLEnumToString(arg); 163 if (s) { 164 APPEND("%s", s); 165 } else { 166 APPEND("0x%x", arg); 167 } 168 } else if (strcmp(type, "GLfixed") == 0) { 169 int arg = va_arg(argp, int); 170 APPEND("0x%08x", arg); 171 } else if (strcmp(type, "GLfloat") == 0) { 172 double arg = va_arg(argp, double); 173 APPEND("%g", arg); 174 } else if (strcmp(type, "GLint") == 0) { 175 int arg = va_arg(argp, int); 176 const char* s = NULL; 177 if (strcmp(name, "glTexParameteri") == 0) { 178 s = GLEnumToString(arg); 179 } 180 if (s) { 181 APPEND("%s", s); 182 } else { 183 APPEND("%d", arg); 184 } 185 } else if (strcmp(type, "GLintptr") == 0) { 186 int arg = va_arg(argp, unsigned int); 187 APPEND("%u", arg); 188 } else if (strcmp(type, "GLsizei") == 0) { 189 int arg = va_arg(argp, size_t); 190 APPEND("%u", arg); 191 } else if (strcmp(type, "GLsizeiptr") == 0) { 192 int arg = va_arg(argp, size_t); 193 APPEND("%u", arg); 194 } else if (strcmp(type, "GLuint") == 0) { 195 int arg = va_arg(argp, unsigned int); 196 APPEND("%u", arg); 197 } else { 198 APPEND("/* ??? %s */", type); 199 break; 200 } 201 } 202 APPEND(");"); 203 line[lineSize-1] = '\0'; 204 LOGD("%s", line); 205 va_end(argp); 206} 207 208#undef TRACE_GL_VOID 209#undef TRACE_GL 210 211#define TRACE_GL_VOID(_api, _args, _argList, ...) \ 212static void Tracing_ ## _api _args { \ 213 TraceGL(#_api, __VA_ARGS__); \ 214 gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl; \ 215 _c->_api _argList; \ 216} 217 218#define TRACE_GL(_type, _api, _args, _argList, ...) \ 219static _type Tracing_ ## _api _args { \ 220 TraceGL(#_api, __VA_ARGS__); \ 221 gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl; \ 222 return _c->_api _argList; \ 223} 224 225extern "C" { 226#include "../trace.in" 227} 228#undef TRACE_GL_VOID 229#undef TRACE_GL 230 231#define GL_ENTRY(_r, _api, ...) Tracing_ ## _api, 232 233EGLAPI gl_hooks_t gHooksTrace = { 234 { 235 #include "entries.in" 236 }, 237 { 238 {0} 239 } 240}; 241#undef GL_ENTRY 242 243// ---------------------------------------------------------------------------- 244}; // namespace android 245// ---------------------------------------------------------------------------- 246 247#endif // EGL_TRACE 248