blob: 48eeaff5882b57b43ab983abf73d23a33dc446bc [file] [log] [blame]
Jack Palevichd4d0fb92010-10-26 15:21:24 -07001/*
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