gltrace_fixup.cpp revision 0469dd6d55fa331bfd7de9431da98b6340d82271
1/* 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 98/* Add the contents of the framebuffer as an argument */ 99void fixup_addFBContents(GLMessage *glmsg) { 100 GLMessage_DataType *arg_fb = glmsg->add_args(); /* Add the FB as the last argument */ 101 GLTraceContext *glContext = getGLTraceContext(); 102 103 void *fb; 104 unsigned fbsize, fbwidth, fbheight; 105 glContext->getCompressedFB(&fb, &fbsize, &fbwidth, &fbheight); 106 107 arg_fb->set_isarray(true); 108 arg_fb->set_type(GLMessage::DataType::BYTE); 109 arg_fb->add_rawbytes(fb, fbsize); 110 arg_fb->add_intvalue(fbwidth); 111 arg_fb->add_intvalue(fbheight); 112} 113 114void fixup_glTexImage2D(GLMessage *glmsg) { 115 /* void glTexImage2D(GLenum target, 116 GLint level, 117 GLint internalformat, 118 GLsizei width, 119 GLsizei height, 120 GLint border, 121 GLenum format, 122 GLenum type, 123 const GLvoid *data); 124 */ 125 GLMessage_DataType arg_width = glmsg->args(3); 126 GLMessage_DataType arg_height = glmsg->args(4); 127 GLMessage_DataType arg_format = glmsg->args(6); 128 GLMessage_DataType arg_type = glmsg->args(7); 129 GLMessage_DataType *arg_data = glmsg->mutable_args(8); 130 131 GLsizei width = arg_width.intvalue(0); 132 GLsizei height = arg_height.intvalue(0); 133 GLenum format = arg_format.intvalue(0); 134 GLenum type = arg_type.intvalue(0); 135 void *data = (void *)arg_data->intvalue(0); 136 137 int bytesPerTexel = getBytesPerTexel(format, type); 138 139 arg_data->set_type(GLMessage::DataType::BYTE); 140 arg_data->set_isarray(true); 141 arg_data->clear_rawbytes(); 142 143 if (data != NULL) { 144 arg_data->add_rawbytes(data, bytesPerTexel * width * height); 145 } else { 146 LOGE("fixup_glTexImage2D: image data is NULL.\n"); 147 arg_data->set_type(GLMessage::DataType::VOID); 148 // FIXME: 149 // This will create the texture, but it will be uninitialized. 150 // It can later be initialized with glTexSubImage2D or by 151 // attaching an FBO to it and rendering into the FBO. 152 } 153} 154 155void fixup_glShaderSource(GLMessage *glmsg) { 156 /* void glShaderSource(GLuint shader, GLsizei count, const GLchar** string, 157 const GLint* length) */ 158 GLMessage_DataType arg_count = glmsg->args(1); 159 GLMessage_DataType arg_lenp = glmsg->args(3); 160 GLMessage_DataType *arg_strpp = glmsg->mutable_args(2); 161 162 GLsizei count = arg_count.intvalue(0); 163 GLchar **stringpp = (GLchar **)arg_strpp->intvalue(0); 164 GLint *lengthp = (GLint *)arg_lenp.intvalue(0); 165 166 arg_strpp->set_type(GLMessage::DataType::CHAR); 167 arg_strpp->set_isarray(true); 168 arg_strpp->clear_charvalue(); 169 170 ::std::string src = ""; 171 for (int i = 0; i < count; i++) { 172 if (lengthp != NULL) 173 src.append(*stringpp, *lengthp); 174 else 175 src.append(*stringpp); // assume null terminated 176 stringpp++; 177 lengthp++; 178 } 179 180 arg_strpp->add_charvalue(src); 181} 182 183void fixup_glUniformGeneric(int argIndex, int nFloats, GLMessage *glmsg) { 184 GLMessage_DataType *arg_values = glmsg->mutable_args(argIndex); 185 GLfloat *src = (GLfloat*)arg_values->intvalue(0); 186 187 arg_values->set_type(GLMessage::DataType::FLOAT); 188 arg_values->set_isarray(true); 189 arg_values->clear_floatvalue(); 190 191 for (int i = 0; i < nFloats; i++) { 192 arg_values->add_floatvalue(*src++); 193 } 194} 195 196void fixup_glUniformMatrixGeneric(int matrixSize, GLMessage *glmsg) { 197 /* void glUniformMatrix?fv(GLint location, GLsizei count, GLboolean transpose, 198 const GLfloat* value) */ 199 GLMessage_DataType arg_count = glmsg->args(1); 200 int n_matrices = arg_count.intvalue(0); 201 fixup_glUniformGeneric(3, matrixSize * matrixSize * n_matrices, glmsg); 202} 203 204void fixup_GenericIntArray(int argIndex, int nInts, GLMessage *glmsg) { 205 GLMessage_DataType *arg_intarray = glmsg->mutable_args(argIndex); 206 GLint *intp = (GLint *)arg_intarray->intvalue(0); 207 208 arg_intarray->set_type(GLMessage::DataType::INT); 209 arg_intarray->set_isarray(true); 210 arg_intarray->clear_intvalue(); 211 212 for (int i = 0; i < nInts; i++, intp++) { 213 arg_intarray->add_intvalue(*intp); 214 } 215} 216 217void fixup_glGenGeneric(GLMessage *glmsg) { 218 /* void glGen*(GLsizei n, GLuint * buffers); */ 219 GLMessage_DataType arg_n = glmsg->args(0); 220 GLsizei n = arg_n.intvalue(0); 221 222 fixup_GenericIntArray(1, n, glmsg); 223} 224 225void fixup_glGetBooleanv(GLMessage *glmsg) { 226 /* void glGetBooleanv(GLenum pname, GLboolean *params); */ 227 GLMessage_DataType *arg_params = glmsg->mutable_args(1); 228 GLboolean *src = (GLboolean*)arg_params->intvalue(0); 229 230 arg_params->set_type(GLMessage::DataType::BOOL); 231 arg_params->set_isarray(true); 232 arg_params->clear_boolvalue(); 233 arg_params->add_boolvalue(*src); 234} 235 236void fixup_glGetFloatv(GLMessage *glmsg) { 237 /* void glGetFloatv(GLenum pname, GLfloat *params); */ 238 GLMessage_DataType *arg_params = glmsg->mutable_args(1); 239 GLfloat *src = (GLfloat*)arg_params->intvalue(0); 240 241 arg_params->set_type(GLMessage::DataType::FLOAT); 242 arg_params->set_isarray(true); 243 arg_params->clear_floatvalue(); 244 arg_params->add_floatvalue(*src); 245} 246 247void fixupGLMessage(GLMessage *glmsg) { 248 switch (glmsg->function()) { 249 case GLMessage::glGenBuffers: /* void glGenBuffers(GLsizei n, GLuint * buffers); */ 250 case GLMessage::glGenFramebuffers: /* void glGenFramebuffers(GLsizei n, GLuint * buffers); */ 251 case GLMessage::glGenRenderbuffers: /* void glGenFramebuffers(GLsizei n, GLuint * buffers); */ 252 case GLMessage::glGenTextures: /* void glGenTextures(GLsizei n, GLuint * buffers); */ 253 fixup_glGenGeneric(glmsg); 254 break; 255 case GLMessage::glGetAttribLocation: 256 case GLMessage::glGetUniformLocation: 257 /* int glGetAttribLocation(GLuint program, const GLchar* name) */ 258 /* int glGetUniformLocation(GLuint program, const GLchar* name) */ 259 fixup_CStringPtr(1, glmsg); 260 break; 261 case GLMessage::glGetBooleanv: 262 fixup_glGetBooleanv(glmsg); 263 break; 264 case GLMessage::glGetFloatv: 265 fixup_glGetFloatv(glmsg); 266 break; 267 case GLMessage::glGetIntegerv: /* void glGetIntegerv(GLenum pname, GLint *params); */ 268 fixup_GenericIntArray(1, 1, glmsg); 269 break; 270 case GLMessage::glGetProgramiv: 271 case GLMessage::glGetRenderbufferParameteriv: 272 case GLMessage::glGetShaderiv: 273 /* void glGetProgramiv(GLuint program, GLenum pname, GLint* params) */ 274 /* void glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) */ 275 /* void glGetShaderiv(GLuint shader, GLenum pname, GLint* params) */ 276 fixup_GenericIntArray(2, 1, glmsg); 277 break; 278 case GLMessage::glGetString: 279 fixup_glGetString(glmsg); 280 break; 281 case GLMessage::glTexImage2D: 282 fixup_glTexImage2D(glmsg); 283 break; 284 case GLMessage::glShaderSource: 285 fixup_glShaderSource(glmsg); 286 break; 287 case GLMessage::glUniformMatrix2fv: 288 /* void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, 289 const GLfloat* value) */ 290 fixup_glUniformMatrixGeneric(2, glmsg); 291 break; 292 case GLMessage::glUniformMatrix3fv: 293 /* void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, 294 const GLfloat* value) */ 295 fixup_glUniformMatrixGeneric(3, glmsg); 296 break; 297 case GLMessage::glUniformMatrix4fv: 298 /* void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, 299 const GLfloat* value) */ 300 fixup_glUniformMatrixGeneric(4, glmsg); 301 break; 302 case GLMessage::glDrawArrays: 303 case GLMessage::glDrawElements: 304 /* void glDrawArrays(GLenum mode, GLint first, GLsizei count) */ 305 /* void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) */ 306 fixup_addFBContents(glmsg); 307 break; 308 default: 309 break; 310 } 311} 312 313}; 314}; 315