blob: 5a439e356cb0ae0b03b7202255861769ba790622 [file] [log] [blame]
Siva Velusamydb974682011-11-30 15:05:37 -08001/*
2 * Copyright 2011, 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#include <cutils/log.h>
18#include <GLES2/gl2.h>
19
20#include "gltrace.pb.h"
21#include "gltrace_context.h"
22#include "gltrace_fixup.h"
23
24namespace android {
25namespace gltrace {
26
27unsigned getBytesPerTexel(const GLenum format, const GLenum type) {
28 /*
29 Description from glTexImage2D spec:
30
31 Data is read from data as a sequence of unsigned bytes or shorts, depending on type.
32 When type is GL_UNSIGNED_BYTE, each of the bytes is interpreted as one color component.
33 When type is one of GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_4_4_4_4, or
34 GL_UNSIGNED_SHORT_5_5_5_1, each unsigned short value is interpreted as containing all
35 the components for a single texel, with the color components arranged according to
36 format. Color components are treated as groups of one, two, three, or four values,
37 again based on format. Groups of components are referred to as texels.
38
39 width × height texels are read from memory, starting at location data. By default,
40 these texels are taken from adjacent memory locations, except that after all width
41 texels are read, the read pointer is advanced to the next four-byte boundary.
42 The four-byte row alignment is specified by glPixelStorei with argument
43 GL_UNPACK_ALIGNMENT, and it can be set to one, two, four, or eight bytes.
44 */
45
46 switch (type) {
47 case GL_UNSIGNED_SHORT_5_6_5:
48 case GL_UNSIGNED_SHORT_4_4_4_4:
49 case GL_UNSIGNED_SHORT_5_5_5_1:
50 return 2;
51 case GL_UNSIGNED_BYTE:
52 break;
53 default:
54 LOGE("GetBytesPerPixel: unknown type %x", type);
55 }
56
57 switch (format) {
58 case GL_ALPHA:
59 case GL_LUMINANCE:
60 return 1;
61 case GL_LUMINANCE_ALPHA:
62 return 2;
63 case GL_RGB:
64 return 3;
65 case GL_RGBA:
66 case 0x80E1: // GL_BGRA_EXT
67 return 4;
68 default:
69 LOGE("GetBytesPerPixel: unknown format %x", format);
70 }
71
72 return 1; // in doubt...
73}
74
75/** Generic helper function: extract pointer at argIndex and
76 replace it with the C style string at *pointer */
77void fixup_CStringPtr(int argIndex, GLMessage *glmsg) {
78 GLMessage_DataType *arg = glmsg->mutable_args(argIndex);
79 GLchar *ptr = (GLchar *)arg->intvalue(0);
80
81 arg->set_type(GLMessage::DataType::CHAR);
82 arg->set_isarray(true);
83 arg->add_charvalue(ptr);
84}
85
86void fixup_glGetString(GLMessage *glmsg) {
87 /* const GLubyte* GLTrace_glGetString(GLenum name) */
88 GLMessage_DataType *ret = glmsg->mutable_returnvalue();
89 GLchar *ptr = (GLchar *)ret->intvalue(0);
90
91 if (ptr != NULL) {
92 ret->set_type(GLMessage::DataType::CHAR);
93 ret->set_isarray(true);
94 ret->add_charvalue(ptr);
95 }
96}
97
Siva Velusamyc0f838f2011-12-05 11:12:31 -080098/* Add the contents of the framebuffer to the protobuf message */
Siva Velusamy1e81e712011-12-14 12:19:56 -080099void fixup_addFBContents(GLTraceContext *context, GLMessage *glmsg, FBBinding fbToRead) {
Siva Velusamyc0f838f2011-12-05 11:12:31 -0800100 void *fbcontents;
Siva Velusamydb974682011-11-30 15:05:37 -0800101 unsigned fbsize, fbwidth, fbheight;
Siva Velusamy1e81e712011-12-14 12:19:56 -0800102 context->getCompressedFB(&fbcontents, &fbsize, &fbwidth, &fbheight, fbToRead);
Siva Velusamydb974682011-11-30 15:05:37 -0800103
Siva Velusamyc0f838f2011-12-05 11:12:31 -0800104 GLMessage_FrameBuffer *fb = glmsg->mutable_fb();
105 fb->set_width(fbwidth);
106 fb->set_height(fbheight);
107 fb->add_contents(fbcontents, fbsize);
Siva Velusamydb974682011-11-30 15:05:37 -0800108}
109
110void fixup_glTexImage2D(GLMessage *glmsg) {
111 /* void glTexImage2D(GLenum target,
112 GLint level,
113 GLint internalformat,
114 GLsizei width,
115 GLsizei height,
116 GLint border,
117 GLenum format,
118 GLenum type,
119 const GLvoid *data);
120 */
121 GLMessage_DataType arg_width = glmsg->args(3);
122 GLMessage_DataType arg_height = glmsg->args(4);
123 GLMessage_DataType arg_format = glmsg->args(6);
124 GLMessage_DataType arg_type = glmsg->args(7);
125 GLMessage_DataType *arg_data = glmsg->mutable_args(8);
126
127 GLsizei width = arg_width.intvalue(0);
128 GLsizei height = arg_height.intvalue(0);
129 GLenum format = arg_format.intvalue(0);
130 GLenum type = arg_type.intvalue(0);
131 void *data = (void *)arg_data->intvalue(0);
132
133 int bytesPerTexel = getBytesPerTexel(format, type);
134
135 arg_data->set_type(GLMessage::DataType::BYTE);
136 arg_data->set_isarray(true);
137 arg_data->clear_rawbytes();
138
139 if (data != NULL) {
140 arg_data->add_rawbytes(data, bytesPerTexel * width * height);
141 } else {
142 LOGE("fixup_glTexImage2D: image data is NULL.\n");
143 arg_data->set_type(GLMessage::DataType::VOID);
144 // FIXME:
145 // This will create the texture, but it will be uninitialized.
146 // It can later be initialized with glTexSubImage2D or by
147 // attaching an FBO to it and rendering into the FBO.
148 }
149}
150
151void fixup_glShaderSource(GLMessage *glmsg) {
152 /* void glShaderSource(GLuint shader, GLsizei count, const GLchar** string,
153 const GLint* length) */
154 GLMessage_DataType arg_count = glmsg->args(1);
155 GLMessage_DataType arg_lenp = glmsg->args(3);
156 GLMessage_DataType *arg_strpp = glmsg->mutable_args(2);
157
158 GLsizei count = arg_count.intvalue(0);
159 GLchar **stringpp = (GLchar **)arg_strpp->intvalue(0);
160 GLint *lengthp = (GLint *)arg_lenp.intvalue(0);
161
162 arg_strpp->set_type(GLMessage::DataType::CHAR);
163 arg_strpp->set_isarray(true);
164 arg_strpp->clear_charvalue();
165
166 ::std::string src = "";
167 for (int i = 0; i < count; i++) {
168 if (lengthp != NULL)
169 src.append(*stringpp, *lengthp);
170 else
171 src.append(*stringpp); // assume null terminated
172 stringpp++;
173 lengthp++;
174 }
175
176 arg_strpp->add_charvalue(src);
177}
178
179void fixup_glUniformGeneric(int argIndex, int nFloats, GLMessage *glmsg) {
180 GLMessage_DataType *arg_values = glmsg->mutable_args(argIndex);
181 GLfloat *src = (GLfloat*)arg_values->intvalue(0);
182
183 arg_values->set_type(GLMessage::DataType::FLOAT);
184 arg_values->set_isarray(true);
185 arg_values->clear_floatvalue();
186
187 for (int i = 0; i < nFloats; i++) {
188 arg_values->add_floatvalue(*src++);
189 }
190}
191
192void fixup_glUniformMatrixGeneric(int matrixSize, GLMessage *glmsg) {
193 /* void glUniformMatrix?fv(GLint location, GLsizei count, GLboolean transpose,
194 const GLfloat* value) */
195 GLMessage_DataType arg_count = glmsg->args(1);
196 int n_matrices = arg_count.intvalue(0);
197 fixup_glUniformGeneric(3, matrixSize * matrixSize * n_matrices, glmsg);
198}
199
200void fixup_GenericIntArray(int argIndex, int nInts, GLMessage *glmsg) {
201 GLMessage_DataType *arg_intarray = glmsg->mutable_args(argIndex);
202 GLint *intp = (GLint *)arg_intarray->intvalue(0);
203
204 arg_intarray->set_type(GLMessage::DataType::INT);
205 arg_intarray->set_isarray(true);
206 arg_intarray->clear_intvalue();
207
208 for (int i = 0; i < nInts; i++, intp++) {
209 arg_intarray->add_intvalue(*intp);
210 }
211}
212
213void fixup_glGenGeneric(GLMessage *glmsg) {
214 /* void glGen*(GLsizei n, GLuint * buffers); */
215 GLMessage_DataType arg_n = glmsg->args(0);
216 GLsizei n = arg_n.intvalue(0);
217
218 fixup_GenericIntArray(1, n, glmsg);
219}
220
221void fixup_glGetBooleanv(GLMessage *glmsg) {
222 /* void glGetBooleanv(GLenum pname, GLboolean *params); */
223 GLMessage_DataType *arg_params = glmsg->mutable_args(1);
224 GLboolean *src = (GLboolean*)arg_params->intvalue(0);
225
226 arg_params->set_type(GLMessage::DataType::BOOL);
227 arg_params->set_isarray(true);
228 arg_params->clear_boolvalue();
229 arg_params->add_boolvalue(*src);
230}
231
232void fixup_glGetFloatv(GLMessage *glmsg) {
233 /* void glGetFloatv(GLenum pname, GLfloat *params); */
234 GLMessage_DataType *arg_params = glmsg->mutable_args(1);
235 GLfloat *src = (GLfloat*)arg_params->intvalue(0);
236
237 arg_params->set_type(GLMessage::DataType::FLOAT);
238 arg_params->set_isarray(true);
239 arg_params->clear_floatvalue();
240 arg_params->add_floatvalue(*src);
241}
242
Siva Velusamy5ed919e2011-12-15 17:32:05 -0800243void fixupGLMessage(GLTraceContext *context, nsecs_t start, nsecs_t end, GLMessage *glmsg) {
Siva Velusamy1e81e712011-12-14 12:19:56 -0800244 // for all messages, set the current context id
245 glmsg->set_context_id(context->getId());
246
Siva Velusamy5ed919e2011-12-15 17:32:05 -0800247 // set start time and duration
248 glmsg->set_start_time(start);
249 glmsg->set_duration((unsigned)(end - start));
250
Siva Velusamy1e81e712011-12-14 12:19:56 -0800251 // do any custom message dependent processing
Siva Velusamydb974682011-11-30 15:05:37 -0800252 switch (glmsg->function()) {
253 case GLMessage::glGenBuffers: /* void glGenBuffers(GLsizei n, GLuint * buffers); */
254 case GLMessage::glGenFramebuffers: /* void glGenFramebuffers(GLsizei n, GLuint * buffers); */
255 case GLMessage::glGenRenderbuffers: /* void glGenFramebuffers(GLsizei n, GLuint * buffers); */
256 case GLMessage::glGenTextures: /* void glGenTextures(GLsizei n, GLuint * buffers); */
257 fixup_glGenGeneric(glmsg);
258 break;
259 case GLMessage::glGetAttribLocation:
260 case GLMessage::glGetUniformLocation:
261 /* int glGetAttribLocation(GLuint program, const GLchar* name) */
262 /* int glGetUniformLocation(GLuint program, const GLchar* name) */
263 fixup_CStringPtr(1, glmsg);
264 break;
265 case GLMessage::glGetBooleanv:
266 fixup_glGetBooleanv(glmsg);
267 break;
268 case GLMessage::glGetFloatv:
269 fixup_glGetFloatv(glmsg);
270 break;
271 case GLMessage::glGetIntegerv: /* void glGetIntegerv(GLenum pname, GLint *params); */
272 fixup_GenericIntArray(1, 1, glmsg);
273 break;
274 case GLMessage::glGetProgramiv:
275 case GLMessage::glGetRenderbufferParameteriv:
276 case GLMessage::glGetShaderiv:
277 /* void glGetProgramiv(GLuint program, GLenum pname, GLint* params) */
278 /* void glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) */
279 /* void glGetShaderiv(GLuint shader, GLenum pname, GLint* params) */
280 fixup_GenericIntArray(2, 1, glmsg);
281 break;
282 case GLMessage::glGetString:
283 fixup_glGetString(glmsg);
284 break;
285 case GLMessage::glTexImage2D:
Siva Velusamy157fea642012-01-03 14:39:31 -0800286 if (context->getGlobalTraceState()->shouldCollectTextureDataOnGlTexImage()) {
287 fixup_glTexImage2D(glmsg);
288 }
Siva Velusamydb974682011-11-30 15:05:37 -0800289 break;
290 case GLMessage::glShaderSource:
291 fixup_glShaderSource(glmsg);
292 break;
293 case GLMessage::glUniformMatrix2fv:
294 /* void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose,
295 const GLfloat* value) */
296 fixup_glUniformMatrixGeneric(2, glmsg);
297 break;
298 case GLMessage::glUniformMatrix3fv:
299 /* void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose,
300 const GLfloat* value) */
301 fixup_glUniformMatrixGeneric(3, glmsg);
302 break;
303 case GLMessage::glUniformMatrix4fv:
304 /* void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose,
305 const GLfloat* value) */
306 fixup_glUniformMatrixGeneric(4, glmsg);
307 break;
308 case GLMessage::glDrawArrays:
Siva Velusamydb974682011-11-30 15:05:37 -0800309 /* void glDrawArrays(GLenum mode, GLint first, GLsizei count) */
Siva Velusamy157fea642012-01-03 14:39:31 -0800310 if (context->getGlobalTraceState()->shouldCollectFbOnGlDraw()) {
311 fixup_addFBContents(context, glmsg, CURRENTLY_BOUND_FB);
312 }
313 break;
314 case GLMessage::glDrawElements:
Siva Velusamydb974682011-11-30 15:05:37 -0800315 /* void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) */
Siva Velusamy157fea642012-01-03 14:39:31 -0800316 if (context->getGlobalTraceState()->shouldCollectFbOnGlDraw()) {
317 fixup_addFBContents(context, glmsg, CURRENTLY_BOUND_FB);
318 }
Siva Velusamydb974682011-11-30 15:05:37 -0800319 break;
320 default:
321 break;
322 }
323}
324
325};
326};