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 package com.android.ide.eclipse.gldebugger; 18 19 import com.android.ide.eclipse.gldebugger.DebuggerMessage.Message; 20 import com.android.ide.eclipse.gldebugger.DebuggerMessage.Message.Function; 21 import com.android.sdklib.util.SparseIntArray; 22 23 import org.eclipse.core.runtime.IProgressMonitor; 24 import org.eclipse.jface.dialogs.ProgressMonitorDialog; 25 import org.eclipse.jface.operation.IRunnableWithProgress; 26 import org.eclipse.swt.widgets.Shell; 27 28 import java.io.FileOutputStream; 29 import java.io.FileWriter; 30 import java.io.IOException; 31 import java.io.PrintWriter; 32 import java.lang.reflect.InvocationTargetException; 33 import java.nio.ByteBuffer; 34 35 public class CodeGen implements IRunnableWithProgress { 36 private FileWriter codeFile, makeFile, namesHeaderFile, namesSourceFile; 37 private PrintWriter code, make, namesHeader, namesSource; 38 private FileOutputStream dataOut; 39 private SparseIntArray bufferNames, 40 framebufferNames, programNames, textureNames, shaderNames, renderbufferNames; 41 42 /** return true if msg was a texture upload */ codeGenTextureUpload(final Message msg, final boolean replaceCopy)43 private boolean codeGenTextureUpload(final Message msg, final boolean replaceCopy) { 44 String s = null; 45 switch (msg.getFunction()) { 46 case glCompressedTexImage2D: 47 s = MessageFormatter.format(msg, true).replace("arg7", "texData"); 48 break; 49 case glCompressedTexSubImage2D: 50 case glTexImage2D: 51 case glTexSubImage2D: 52 s = MessageFormatter.format(msg, true).replace("arg8", "texData"); 53 break; 54 case glCopyTexImage2D: 55 if (!replaceCopy) { 56 code.write(MessageFormatter.format(msg, true)); 57 code.write(";CHKERR;\n"); 58 return true; 59 } 60 assert msg.getArg2() == msg.getPixelFormat(); // TODO 61 s = "//" + MessageFormatter.format(msg, true) + "\n"; 62 s += String.format("glTexImage2D(%s, %d, %s, %d, %d, %d, %s, %s, texData);CHKERR;", 63 GLEnum.valueOf(msg.getArg0()), msg.getArg1(), 64 GLEnum.valueOf(msg.getArg2()), msg.getArg5(), msg.getArg6(), 65 msg.getArg7(), GLEnum.valueOf(msg.getPixelFormat()), 66 GLEnum.valueOf(msg.getPixelType())); 67 break; 68 case glCopyTexSubImage2D: 69 if (!replaceCopy) { 70 code.write(MessageFormatter.format(msg, true)); 71 code.write(";CHKERR;\n"); 72 return true; 73 } 74 // FIXME: check the texture format & type, and convert 75 s = "//" + MessageFormatter.format(msg, true) + "\n"; 76 s += String.format( 77 "glTexSubImage2D(%s, %d, %d, %d, %d, %d, %s, %s, texData);CHKERR;", 78 GLEnum.valueOf(msg.getArg0()), msg.getArg1(), msg.getArg2(), 79 msg.getArg3(), msg.getArg6(), msg.getArg7(), 80 GLEnum.valueOf(msg.getPixelFormat()), GLEnum.valueOf(msg.getPixelType())); 81 break; 82 default: 83 return false; 84 } 85 86 if (msg.hasData()) { 87 final byte[] data = MessageProcessor.lzfDecompressChunks(msg.getData()); 88 try { 89 code.write("{\n"); 90 code.format(" void * texData = malloc(%d);CHKERR;\n", data.length); 91 code.format(" FILE * texFile = fopen(\"/sdcard/frame_data.bin\", \"rb\");CHKERR;\n"); 92 code.format(" assert(texFile);CHKERR;\n"); 93 code.format(" fseek(texFile, %d, SEEK_SET);CHKERR;\n", dataOut.getChannel() 94 .position()); 95 dataOut.write(data); 96 code.format(" fread(texData, %d, 1, texFile);CHKERR;\n", data.length); 97 code.format(" fclose(texFile);CHKERR;\n"); 98 code.format(" " + s + ";\n"); 99 code.format(" free(texData);CHKERR;\n"); 100 code.format("}\n"); 101 } catch (IOException e) { 102 e.printStackTrace(); 103 assert false; 104 } 105 } else 106 code.write(s.replace("texData", "NULL") + ";\n"); 107 return true; 108 } 109 codeGenServerState(final GLServerState serverState)110 private void codeGenServerState(final GLServerState serverState) { 111 code.write("// CodeGenServerState\n"); 112 for (int i = 0; i < serverState.enableDisables.size(); i++) { 113 final GLEnum key = GLEnum.valueOf(serverState.enableDisables.keyAt(i)); 114 if (serverState.enableDisables.valueAt(i) == 0) 115 code.format("glDisable(%s);CHKERR;\n", key); 116 else 117 code.format("glEnable(%s);CHKERR;\n", key); 118 } 119 for (int i = 0; i < serverState.lastSetter.size(); i++) { 120 final Function key = Function.valueOf(serverState.lastSetter.keyAt(i)); 121 final Message msg = serverState.lastSetter.valueAt(i); 122 if (msg == null) { 123 code.format("// %s is default\n", key); 124 continue; 125 } 126 final String s = MessageFormatter.format(msg, true); 127 code.write(s); 128 code.write(";\n"); 129 } 130 // TODO: stencil and integers 131 } 132 codeGenServerShader(final GLServerShader serverShader)133 private void codeGenServerShader(final GLServerShader serverShader) { 134 code.write("// CodeGenServerShader\n"); 135 for (int i = 0; i < serverShader.shaders.size(); i++) { 136 final int name = serverShader.shaders.keyAt(i); 137 final GLShader shader = serverShader.shaders.valueAt(i); 138 final String id = "shader_" + name; 139 if (shaderNames.indexOfKey(name) < 0) { 140 namesSource.format("GLuint %s = 0;\n", id); 141 namesHeader.format("extern GLuint %s;\n", id); 142 } 143 code.format("%s = glCreateShader(%s);CHKERR;\n", id, shader.type); 144 shaderNames.put(name, name); 145 146 if (shader.source != null) { 147 final String src = shader.source.replace("\r", "").replace("\n", "\\n\\\n") 148 .replace("\"", "\\\""); 149 code.format("glShaderSource(%s, 1, (const GLchar *[]){\"%s\"}, NULL);CHKERR;\n", 150 id, src); 151 code.format("glCompileShader(%s);CHKERR;\n", id); 152 } 153 } 154 155 for (int i = 0; i < serverShader.programs.size(); i++) { 156 final int name = serverShader.programs.keyAt(i); 157 final GLProgram program = serverShader.programs.valueAt(i); 158 final String id = "program_" + name; 159 if (programNames.indexOfKey(name) < 0) { 160 namesSource.format("GLuint %s = 0;\n", id); 161 namesHeader.format("extern GLuint %s;\n", id); 162 } 163 code.format("%s = glCreateProgram();CHKERR;\n", id); 164 programNames.put(name, name); 165 code.format("glAttachShader(%s, shader_%d);CHKERR;\n", id, 166 program.vert); 167 code.format("glAttachShader(%s, shader_%d);CHKERR;\n", id, 168 program.frag); 169 code.format("glLinkProgram(%s);CHKERR;\n", id); 170 if (serverShader.current == program) 171 code.format("glUseProgram(%s);CHKERR;\n", id); 172 } 173 } 174 codeGenServerTexture(final GLServerTexture serverTexture, final boolean replaceCopy)175 private void codeGenServerTexture(final GLServerTexture serverTexture, final boolean replaceCopy) { 176 code.write("// CodeGenServerTexture\n"); 177 for (int i = 0; i < serverTexture.textures.size(); i++) { 178 final int name = serverTexture.textures.keyAt(i); 179 final GLTexture tex = serverTexture.textures.valueAt(i); 180 final String id = "texture_" + name; 181 if (textureNames.indexOfKey(name) < 0) { 182 namesHeader.format("extern GLuint %s;\n", id); 183 namesSource.format("GLuint %s = 0;\n", id); 184 } 185 code.format("%s = 0;\n", id); 186 textureNames.put(name, name); 187 188 if (name == 0) 189 continue; 190 code.format("glGenTextures(1, &%s);CHKERR;\n", id); 191 String s = String.format("glBindTexture(%s, texture_%d);CHKERR;\n", tex.target, 192 tex.name); 193 code.write(s); 194 for (final Message msg : tex.contentChanges) { 195 if (codeGenTextureUpload(msg, replaceCopy)) 196 continue; 197 switch (msg.getFunction()) { 198 case glGenerateMipmap: 199 s = MessageFormatter.format(msg, true); 200 break; 201 default: 202 assert false; 203 } 204 code.write(s + ";\n"); 205 } 206 code.format("glTexParameteriv(%s, GL_TEXTURE_WRAP_S, (GLint[]){%s});CHKERR;\n", 207 tex.target, tex.wrapS); 208 code.format("glTexParameteriv(%s, GL_TEXTURE_WRAP_T, (GLint[]){%s});CHKERR;\n", 209 tex.target, tex.wrapT); 210 code.format("glTexParameteriv(%s, GL_TEXTURE_MIN_FILTER, (GLint[]){%s});CHKERR;\n", 211 tex.target, tex.min); 212 code.format("glTexParameteriv(%s, GL_TEXTURE_MAG_FILTER, (GLint[]){%s});CHKERR;\n", 213 tex.target, tex.mag); 214 } 215 for (int i = 0; i < serverTexture.tmu2D.length; i++) { 216 code.format("glActiveTexture(%s);CHKERR;\n", 217 GLEnum.valueOf(GLEnum.GL_TEXTURE0.value + i)); 218 code.format("glBindTexture(GL_TEXTURE_2D, texture_%d);CHKERR;\n", 219 serverTexture.tmu2D[i]); 220 } 221 for (int i = 0; i < serverTexture.tmuCube.length; i++) { 222 code.format("glActiveTexture(%s);CHKERR;\n", 223 GLEnum.valueOf(GLEnum.GL_TEXTURE0.value + i)); 224 code.format("glBindTexture(GL_TEXTURE_CUBE_MAP, texture_%d);CHKERR;\n", 225 serverTexture.tmuCube[i]); 226 } 227 code.format("glActiveTexture(%s);CHKERR;\n", serverTexture.activeTexture); 228 if (serverTexture.tex2D == null) 229 code.format("glBindTexture(GL_TEXTURE_2D, 0);CHKERR;\n"); 230 else 231 code.format("glBindTexture(GL_TEXTURE_2D, texture_%d);CHKERR;\n", 232 serverTexture.tex2D.name); 233 if (serverTexture.texCube == null) 234 code.format("glBindTexture(GL_TEXTURE_CUBE_MAP, 0);CHKERR;\n"); 235 else 236 code.format("glBindTexture(GL_TEXTURE_CUBE_MAP, texture_%d);CHKERR;\n", 237 serverTexture.texCube.name); 238 } 239 codeGenBufferData(final ByteBuffer buffer, final String call)240 private void codeGenBufferData(final ByteBuffer buffer, final String call) { 241 ByteBuffer bfr = buffer; 242 if (buffer.isReadOnly()) { 243 bfr = ByteBuffer.allocate(buffer.capacity()); 244 bfr.put(buffer); 245 } 246 final byte[] data = bfr.array(); 247 try { 248 code.write("{\n"); 249 code.format(" void * bufferData = malloc(%d);\n", data.length); 250 code.format(" FILE * bufferFile = fopen(\"/sdcard/frame_data.bin\", \"rb\");\n"); 251 code.format(" assert(bufferFile);\n"); 252 code.format(" fseek(bufferFile, %d, SEEK_SET);\n", dataOut.getChannel() 253 .position()); 254 dataOut.write(data); 255 code.format(" fread(bufferData, %d, 1, bufferFile);\n", data.length); 256 code.format(" fclose(bufferFile);\n"); 257 code.format(" " + call + ";CHKERR;\n"); 258 code.format(" free(bufferData);\n"); 259 code.format("}\n"); 260 } catch (IOException e) { 261 e.printStackTrace(); 262 assert false; 263 } 264 } 265 codeGenServerVertex(final GLServerVertex v)266 private void codeGenServerVertex(final GLServerVertex v) { 267 code.write("// CodeGenServerVertex\n"); 268 for (int i = 0; i < v.buffers.size(); i++) { 269 final int name = v.buffers.keyAt(i); 270 final String id = "buffer_" + name; 271 final GLBuffer buffer = v.buffers.valueAt(i); 272 if (bufferNames.indexOfKey(name) < 0) { 273 namesHeader.format("extern GLuint %s;\n", id); 274 namesSource.format("GLuint %s = 0;\n", id); 275 } 276 code.format("%s = 0;\n", id); 277 bufferNames.put(name, name); 278 if (name == 0) 279 continue; 280 code.format("glGenBuffers(1, &%s);CHKERR;\n", id); 281 if (buffer.target != null) { 282 code.format("glBindBuffer(%s, %s);CHKERR;\n", buffer.target, id); 283 if (buffer.data != null) { 284 String s = String.format("glBufferData(%s, %d, bufferData, %s)", buffer.target, 285 buffer.data.capacity(), buffer.usage); 286 codeGenBufferData(buffer.data, s); 287 } 288 } 289 } 290 // TODO: use MAX_VERTEX_ATTRIBS 291 for (int i = 0; i < v.defaultAttribs.length; i++) 292 code.format("glVertexAttrib4f(%d, %f, %f, %f, %f);CHKERR;\n", i, 293 v.defaultAttribs[i][0], 294 v.defaultAttribs[i][1], v.defaultAttribs[i][2], v.defaultAttribs[i][3]); 295 for (int i = 0; i < v.attribPointers.length; i++) { 296 final GLAttribPointer att = v.attribPointers[i]; 297 if (att.type == null) 298 continue; 299 if (att.buffer != null) 300 code.format("glBindBuffer(GL_ARRAY_BUFFER, buffer_%d);CHKERR;\n", att.buffer.name); 301 else 302 code.format("glBindBuffer(GL_ARRAY_BUFFER, 0);CHKERR;\n"); 303 code.format("glVertexAttribPointer(%d, %d, %s, %b, %d, (const GLvoid *)%d);CHKERR;\n", 304 i, att.size, att.type, att.normalized, att.stride, att.ptr); 305 } 306 if (v.attribBuffer != null) 307 code.format("glBindBuffer(GL_ARRAY_BUFFER, buffer_%d);CHKERR;\n", v.attribBuffer.name); 308 else 309 code.write("glBindBuffer(GL_ARRAY_BUFFER, 0);CHKERR;\n"); 310 if (v.indexBuffer != null) 311 code.format("glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_%d);CHKERR;\n", 312 v.indexBuffer.name); 313 else 314 code.write("glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);CHKERR;\n"); 315 } 316 codeGenGenNames(final Message msg)317 private void codeGenGenNames(final Message msg) { 318 final ByteBuffer names = msg.getData().asReadOnlyByteBuffer(); 319 names.order(GLFramesView.TARGET_BYTE_ORDER); 320 SparseIntArray namesArray = null; 321 for (int i = 0; i < msg.getArg0(); i++) { 322 String id = ""; 323 final int name = names.getInt(); 324 switch (msg.getFunction()) { 325 case glGenBuffers: 326 id = "buffer"; 327 namesArray = bufferNames; 328 break; 329 case glGenFramebuffers: 330 id = "framebuffer"; 331 namesArray = framebufferNames; 332 break; 333 case glGenRenderbuffers: 334 id = "renderbuffer"; 335 namesArray = renderbufferNames; 336 break; 337 case glGenTextures: 338 id = "texture"; 339 namesArray = textureNames; 340 break; 341 default: 342 assert false; 343 } 344 id += "_" + name; 345 if (namesArray.indexOfKey(name) < 0) { 346 namesHeader.format("extern GLuint %s;\n", id); 347 namesSource.format("GLuint %s = 0;\n", id); 348 } 349 code.format("%s = 0;\n", id); 350 namesArray.put(name, name); 351 code.format("%s(1, &%s);CHKERR;\n", msg.getFunction(), id); 352 } 353 } 354 codeGenDeleteNames(final Message msg)355 private void codeGenDeleteNames(final Message msg) { 356 final ByteBuffer names = msg.getData().asReadOnlyByteBuffer(); 357 names.order(GLFramesView.TARGET_BYTE_ORDER); 358 SparseIntArray namesArray = null; 359 for (int i = 0; i < msg.getArg0(); i++) { 360 String id = null; 361 final int name = names.getInt(); 362 switch (msg.getFunction()) { 363 case glDeleteBuffers: 364 id = "buffer"; 365 namesArray = bufferNames; 366 break; 367 case glDeleteFramebuffers: 368 id = "framebuffer"; 369 namesArray = framebufferNames; 370 break; 371 case glDeleteRenderbuffers: 372 id = "renderbuffer"; 373 namesArray = renderbufferNames; 374 break; 375 case glDeleteTextures: 376 id = "texture"; 377 namesArray = textureNames; 378 break; 379 default: 380 assert false; 381 } 382 id += "_" + name; 383 code.format("%s = 0;\n", id); 384 namesArray.put(name, 0); 385 code.format("%s(1, &%s);CHKERR;\n", msg.getFunction(), id); 386 } 387 } 388 codeGenBindNames(final Message msg)389 private void codeGenBindNames(final Message msg) { 390 String id = null; 391 SparseIntArray namesArray = null; 392 final int name = msg.getArg1(); 393 switch (msg.getFunction()) { 394 case glBindBuffer: 395 id = "buffer"; 396 namesArray = bufferNames; 397 break; 398 case glBindFramebuffer: 399 id = "framebuffer"; 400 namesArray = framebufferNames; 401 break; 402 case glBindRenderbuffer: 403 id = "renderbuffer"; 404 namesArray = renderbufferNames; 405 break; 406 case glBindTexture: 407 id = "texture"; 408 namesArray = textureNames; 409 break; 410 default: 411 assert false; 412 } 413 id += "_" + name; 414 if (namesArray.indexOfKey(name) < 0) { 415 namesHeader.format("extern GLuint %s;\n", id); 416 namesSource.format("GLuint %s = 0;\n", id); 417 } else if (namesArray.get(name) != name) 418 code.format("%s = %d;\n", id, name); // name was deleted 419 namesArray.put(name, name); 420 code.write(MessageFormatter.format(msg, true)); 421 code.write(";CHKERR;\n"); 422 } 423 codeGenDrawArrays(final GLServerVertex v, final MessageData msgData)424 private void codeGenDrawArrays(final GLServerVertex v, final MessageData msgData) 425 throws IOException { 426 final int maxAttrib = msgData.msg.getArg7(); 427 if (maxAttrib < 1) { 428 code.write("// no vertex data\n"); 429 return; 430 } 431 final byte[] data = msgData.msg.getData().toByteArray(); 432 final GLEnum mode = GLEnum.valueOf(msgData.msg.getArg0()); 433 final int first = msgData.msg.getArg1(), count = msgData.msg.getArg2(); 434 int attribDataStride = 0; 435 for (int i = 0; i < maxAttrib; i++) { 436 final GLAttribPointer att = v.attribPointers[i]; 437 if (!att.enabled) 438 continue; 439 if (att.buffer != null) 440 continue; 441 attribDataStride += att.elemSize; 442 } 443 assert attribDataStride * count == data.length; 444 code.write("{\n"); 445 if (attribDataStride > 0) { 446 code.format(" FILE * attribFile = fopen(\"/sdcard/frame_data.bin\", \"rb\");CHKERR;\n"); 447 code.format(" assert(attribFile);CHKERR;\n"); 448 code.format(" fseek(attribFile, %d, SEEK_SET);CHKERR;\n", dataOut.getChannel() 449 .position()); 450 dataOut.write(data); 451 code.format(" char * const attribData = (char *)malloc(%d);\n", first 452 * attribDataStride + data.length); 453 code.format(" assert(attribData);\n"); 454 code.format(" fread(attribData + %d, %d, 1, attribFile);\n", 455 first * attribDataStride, data.length); 456 code.format(" fclose(attribFile);\n"); 457 code.format(" glBindBuffer(GL_ARRAY_BUFFER, 0);CHKERR;\n"); 458 int attribDataOffset = 0; 459 for (int i = 0; i < maxAttrib; i++) { 460 final GLAttribPointer att = v.attribPointers[i]; 461 if (!att.enabled) 462 continue; 463 if (att.buffer != null) 464 continue; 465 code.format( 466 " glVertexAttribPointer(%d, %d, %s, %b, %d, attribData + %d);CHKERR;\n", 467 i, att.size, att.type, att.normalized, 468 attribDataStride, attribDataOffset); 469 attribDataOffset += att.elemSize; 470 } 471 if (v.attribBuffer != null) 472 code.format(" glBindBuffer(GL_ARRAY_BUFFER, %d);CHKERR;\n", 473 v.attribBuffer.name); 474 } 475 code.format(" glDrawArrays(%s, %d, %d);CHKERR;\n", mode, first, count); 476 if (attribDataStride > 0) 477 code.format(" free(attribData);CHKERR;\n"); 478 code.write("};\n"); 479 } 480 codeGenDrawElements(final GLServerVertex v, final MessageData msgData)481 private void codeGenDrawElements(final GLServerVertex v, final MessageData msgData) 482 throws IOException { 483 final int maxAttrib = msgData.msg.getArg7(); 484 if (maxAttrib < 1) { 485 code.write("// no vertex data\n"); 486 return; 487 } 488 final GLEnum mode = GLEnum.valueOf(msgData.msg.getArg0()); 489 final int count = msgData.msg.getArg1(); 490 final GLEnum type = GLEnum.valueOf(msgData.msg.getArg2()); 491 String typeName = "GLubyte"; 492 if (type == GLEnum.GL_UNSIGNED_SHORT) 493 typeName = "GLushort"; 494 int attribDataStride = 0; 495 for (int i = 0; i < maxAttrib; i++) { 496 final GLAttribPointer att = v.attribPointers[i]; 497 if (!att.enabled) 498 continue; 499 if (att.buffer != null) 500 continue; 501 attribDataStride += att.elemSize; 502 } 503 code.write("{\n"); 504 if (v.indexBuffer == null || attribDataStride > 0) { 505 // need to load user pointer indices and/or attributes 506 final byte[] element = new byte[attribDataStride]; 507 final ByteBuffer data = msgData.msg.getData().asReadOnlyByteBuffer(); 508 data.order(GLFramesView.TARGET_BYTE_ORDER); 509 final ByteBuffer indexData = ByteBuffer.allocate(count * GLServerVertex.typeSize(type)); 510 indexData.order(GLFramesView.TARGET_BYTE_ORDER); 511 final ByteBuffer attribData = ByteBuffer.allocate(count * attribDataStride); 512 attribData.order(GLFramesView.TARGET_BYTE_ORDER); 513 int maxIndex = -1; 514 ByteBuffer indexSrc = data; 515 if (v.indexBuffer != null) { 516 indexSrc = v.indexBuffer.data; 517 indexSrc.position(msgData.msg.getArg3()); 518 } 519 indexSrc.order(GLFramesView.TARGET_BYTE_ORDER); 520 for (int i = 0; i < count; i++) { 521 int index = -1; 522 if (type == GLEnum.GL_UNSIGNED_BYTE) { 523 byte idx = indexSrc.get(); 524 index = idx & 0xff; 525 indexData.put(idx); 526 } else if (type == GLEnum.GL_UNSIGNED_SHORT) { 527 short idx = indexSrc.getShort(); 528 index = idx & 0xffff; 529 indexData.putShort(idx); 530 } else 531 assert false; 532 data.get(element); 533 attribData.put(element); 534 if (index > maxIndex) 535 maxIndex = index; 536 } 537 code.format(" FILE * attribFile = fopen(\"/sdcard/frame_data.bin\", \"rb\");CHKERR;\n"); 538 code.format(" assert(attribFile);CHKERR;\n"); 539 code.format(" fseek(attribFile, 0x%X, SEEK_SET);CHKERR;\n", 540 dataOut.getChannel().position()); 541 dataOut.write(indexData.array()); 542 code.format(" %s * const indexData = (%s *)malloc(%d);\n", typeName, typeName, 543 indexData.capacity()); 544 code.format(" assert(indexData);\n"); 545 code.format(" fread(indexData, %d, 1, attribFile);\n", indexData.capacity()); 546 if (attribDataStride > 0) { 547 code.format(" glBindBuffer(GL_ARRAY_BUFFER, 0);CHKERR;\n"); 548 for (int i = 0; i < maxAttrib; i++) { 549 final GLAttribPointer att = v.attribPointers[i]; 550 if (!att.enabled) 551 continue; 552 if (att.buffer != null) 553 continue; 554 code.format(" char * const attrib%d = (char *)malloc(%d);\n", 555 i, att.elemSize * (maxIndex + 1)); 556 code.format(" assert(attrib%d);\n", i); 557 code.format( 558 " glVertexAttribPointer(%d, %d, %s, %b, %d, attrib%d);CHKERR;\n", 559 i, att.size, att.type, att.normalized, att.elemSize, i); 560 } 561 dataOut.write(attribData.array()); 562 code.format(" for (%s i = 0; i < %d; i++) {\n", typeName, count); 563 for (int i = 0; i < maxAttrib; i++) { 564 final GLAttribPointer att = v.attribPointers[i]; 565 if (!att.enabled) 566 continue; 567 if (att.buffer != null) 568 continue; 569 code.format( 570 " fread(attrib%d + indexData[i] * %d, %d, 1, attribFile);\n", 571 i, att.elemSize, att.elemSize); 572 } 573 code.format(" }\n"); 574 if (v.attribBuffer != null) 575 code.format(" glBindBuffer(GL_ARRAY_BUFFER, %d);CHKERR;\n", 576 v.attribBuffer.name); 577 } 578 code.format(" fclose(attribFile);\n"); 579 } 580 if (v.indexBuffer != null) 581 code.format(" glDrawElements(%s, %d, %s, (const void *)%d);CHKERR;\n", 582 mode, count, type, msgData.msg.getArg3()); 583 else { 584 code.format(" glDrawElements(%s, %d, %s, indexData);CHKERR;\n", 585 mode, count, type); 586 code.format(" free(indexData);\n"); 587 } 588 for (int i = 0; i < maxAttrib; i++) { 589 final GLAttribPointer att = v.attribPointers[i]; 590 if (!att.enabled) 591 continue; 592 if (att.buffer != null) 593 continue; 594 code.format(" free(attrib%d);\n", i); 595 } 596 code.write("};\n"); 597 } 598 codeGenDraw(final GLServerVertex v, final MessageData msgData)599 private void codeGenDraw(final GLServerVertex v, final MessageData msgData) 600 throws IOException { 601 final int maxAttrib = msgData.msg.getArg7(); 602 if (maxAttrib < 1) { 603 code.write("// no vertex data\n"); 604 return; 605 } 606 final int count = msgData.attribs[0].length / 4; 607 final GLEnum mode = GLEnum.valueOf(msgData.msg.getArg0()); 608 final ByteBuffer attribData = ByteBuffer.allocate(maxAttrib * count * 16); 609 attribData.order(GLFramesView.TARGET_BYTE_ORDER); 610 for (int i = 0; i < count; i++) 611 for (int j = 0; j < maxAttrib; j++) 612 for (int k = 0; k < 4; k++) 613 attribData.putFloat(msgData.attribs[j][i * 4 + k]); 614 assert attribData.remaining() == 0; 615 code.write("{\n"); 616 code.format(" FILE * attribFile = fopen(\"/sdcard/frame_data.bin\", \"rb\");CHKERR;\n"); 617 code.format(" assert(attribFile);CHKERR;\n"); 618 code.format(" fseek(attribFile, 0x%X, SEEK_SET);CHKERR;\n", 619 dataOut.getChannel().position()); 620 dataOut.write(attribData.array()); 621 code.format(" char * const attribData = (char *)malloc(%d);\n", attribData.capacity()); 622 code.format(" assert(attribData);\n"); 623 code.format(" fread(attribData, %d, 1, attribFile);\n", attribData.capacity()); 624 code.format(" fclose(attribFile);\n"); 625 code.format(" glBindBuffer(GL_ARRAY_BUFFER, 0);CHKERR;\n"); 626 for (int i = 0; i < maxAttrib; i++) { 627 final GLAttribPointer att = v.attribPointers[i]; 628 assert msgData.attribs[i].length == count * 4; 629 code.format( 630 " glVertexAttribPointer(%d, %d, GL_FLOAT, GL_FALSE, %d, attribData + %d);CHKERR;\n", 631 i, att.size, maxAttrib * 16, i * 16); 632 } 633 code.format(" glDrawArrays(%s, 0, %d);CHKERR;\n", mode, count); 634 code.format(" free(attribData);\n"); 635 if (v.attribBuffer != null) 636 code.format(" glBindBuffer(GL_ARRAY_BUFFER, %d);CHKERR;\n", 637 v.attribBuffer.name); 638 code.write("};\n"); 639 } 640 codeGenFunction(final Context ctx, final MessageData msgData)641 private void codeGenFunction(final Context ctx, final MessageData msgData) 642 throws IOException { 643 final Message msg = msgData.msg; 644 String call = MessageFormatter.format(msg, true); 645 switch (msg.getFunction()) { 646 case glActiveTexture: 647 case glAttachShader: 648 case glBindAttribLocation: 649 break; 650 case glBindBuffer: 651 case glBindFramebuffer: 652 case glBindRenderbuffer: 653 case glBindTexture: 654 codeGenBindNames(msg); 655 return; 656 case glBlendColor: 657 case glBlendEquation: 658 case glBlendEquationSeparate: 659 case glBlendFunc: 660 case glBlendFuncSeparate: 661 break; 662 case glBufferData: 663 call = MessageFormatter.format(msg, true).replace("arg2", "bufferData"); 664 codeGenBufferData(msg.getData().asReadOnlyByteBuffer(), call); 665 return; 666 case glBufferSubData: 667 call = MessageFormatter.format(msg, true).replace("arg3", "bufferData"); 668 codeGenBufferData(msg.getData().asReadOnlyByteBuffer(), call); 669 return; 670 case glCheckFramebufferStatus: 671 case glClear: 672 case glClearColor: 673 case glClearDepthf: 674 case glClearStencil: 675 case glColorMask: 676 case glCompileShader: 677 break; 678 case glCompressedTexImage2D: 679 case glCompressedTexSubImage2D: 680 case glCopyTexImage2D: 681 case glCopyTexSubImage2D: 682 codeGenTextureUpload(msg, false); 683 return; 684 case glCreateProgram: 685 namesHeader.format("extern GLuint program_%d;\n", msg.getRet()); 686 namesSource.format("GLuint program_%d = 0;\n", msg.getRet()); 687 code.format("program_%d = glCreateProgram();CHKERR;\n", msg.getRet()); 688 return; 689 case glCreateShader: 690 namesHeader.format("extern GLuint shader_%d;\n", msg.getRet()); 691 namesSource.format("GLuint shader_%d = 0;\n", msg.getRet()); 692 code.format("shader_%d = %s;\n", msg.getRet(), call); 693 return; 694 case glCullFace: 695 break; 696 case glDeleteBuffers: 697 case glDeleteFramebuffers: 698 case glDeleteProgram: 699 programNames.put(msg.getArg0(), 0); 700 break; 701 case glDeleteRenderbuffers: 702 codeGenDeleteNames(msg); 703 return; 704 case glDeleteShader: 705 shaderNames.put(msg.getArg0(), 0); 706 return; 707 case glDeleteTextures: 708 codeGenDeleteNames(msg); 709 return; 710 case glDepthFunc: 711 case glDepthMask: 712 case glDepthRangef: 713 case glDetachShader: 714 case glDisable: 715 case glDisableVertexAttribArray: 716 break; 717 case glDrawArrays: 718 // CodeGenDraw(ctx.serverVertex, msgData); 719 codeGenDrawArrays(ctx.serverVertex, msgData); 720 return; 721 case glDrawElements: 722 // CodeGenDraw(ctx.serverVertex, msgData); 723 codeGenDrawElements(ctx.serverVertex, msgData); 724 return; 725 case glEnable: 726 case glEnableVertexAttribArray: 727 case glFinish: 728 case glFlush: 729 case glFramebufferRenderbuffer: 730 case glFramebufferTexture2D: 731 case glFrontFace: 732 break; 733 case glGenBuffers: 734 codeGenGenNames(msg); 735 return; 736 case glGenerateMipmap: 737 break; 738 case glGenFramebuffers: 739 case glGenRenderbuffers: 740 case glGenTextures: 741 codeGenGenNames(msg); 742 return; 743 case glGetActiveAttrib: 744 case glGetActiveUniform: 745 case glGetAttachedShaders: 746 break; 747 case glGetAttribLocation: 748 call = String.format("assert(%d == %s)", msg.getRet(), call); 749 break; 750 case glGetBooleanv: 751 case glGetBufferParameteriv: 752 return; // TODO 753 case glGetError: 754 code.write("CHKERR;\n"); 755 return; 756 case glGetFloatv: 757 case glGetFramebufferAttachmentParameteriv: 758 case glGetIntegerv: 759 case glGetProgramiv: 760 case glGetProgramInfoLog: 761 case glGetRenderbufferParameteriv: 762 case glGetShaderiv: 763 case glGetShaderInfoLog: 764 case glGetShaderPrecisionFormat: 765 case glGetShaderSource: 766 case glGetString: 767 case glGetTexParameterfv: 768 case glGetTexParameteriv: 769 case glGetUniformfv: 770 case glGetUniformiv: 771 return; 772 case glGetUniformLocation: 773 call = String.format("assert(%d == %s)", msg.getRet(), call); 774 break; 775 case glGetVertexAttribfv: 776 case glGetVertexAttribiv: 777 case glGetVertexAttribPointerv: 778 return; // TODO 779 case glHint: 780 case glIsBuffer: 781 case glIsEnabled: 782 case glIsFramebuffer: 783 case glIsProgram: 784 case glIsRenderbuffer: 785 case glIsShader: 786 case glIsTexture: 787 case glLineWidth: 788 case glLinkProgram: 789 case glPixelStorei: 790 case glPolygonOffset: 791 break; 792 case glReadPixels: 793 return; // TODO 794 case glReleaseShaderCompiler: 795 case glRenderbufferStorage: 796 case glSampleCoverage: 797 case glScissor: 798 break; 799 case glShaderBinary: 800 return; // TODO 801 case glShaderSource: 802 call = String.format( 803 "glShaderSource(shader_%d, 1, (const char * []){\"%s\"}, NULL)", 804 msg.getArg0(), 805 msg.getData().toStringUtf8().replace("\r", "").replace("\n", "\\n\\\n") 806 .replace("\"", "\\\"") 807 ); 808 break; 809 case glStencilFunc: 810 case glStencilFuncSeparate: 811 case glStencilMask: 812 case glStencilMaskSeparate: 813 case glStencilOp: 814 case glStencilOpSeparate: 815 break; 816 case glTexImage2D: 817 codeGenTextureUpload(msg, false); 818 return; 819 case glTexParameterf: 820 break; 821 case glTexParameterfv: 822 return; // TODO 823 case glTexParameteri: 824 break; 825 case glTexParameteriv: 826 return; // TODO 827 case glTexSubImage2D: 828 codeGenTextureUpload(msg, false); 829 return; 830 case glUniform1f: 831 case glUniform1fv: 832 case glUniform1i: 833 case glUniform1iv: 834 case glUniform2f: 835 case glUniform2fv: 836 case glUniform2i: 837 case glUniform2iv: 838 case glUniform3f: 839 case glUniform3fv: 840 case glUniform3i: 841 case glUniform3iv: 842 case glUniform4f: 843 case glUniform4fv: 844 case glUniform4i: 845 case glUniform4iv: 846 case glUniformMatrix2fv: 847 case glUniformMatrix3fv: 848 case glUniformMatrix4fv: 849 case glUseProgram: 850 case glValidateProgram: 851 case glVertexAttrib1f: 852 case glVertexAttrib1fv: 853 case glVertexAttrib2f: 854 case glVertexAttrib2fv: 855 case glVertexAttrib3f: 856 case glVertexAttrib3fv: 857 case glVertexAttrib4f: 858 case glVertexAttrib4fv: 859 break; 860 case glVertexAttribPointer: 861 // if it's user pointer, then CodeGenDrawArrays/Elements will 862 // replace it with loaded data just before the draw 863 call = call.replace("arg5", "(const void *)0x" + 864 Integer.toHexString(msg.getArg5())); 865 break; 866 case glViewport: 867 break; 868 case eglSwapBuffers: 869 return; 870 default: 871 assert false; 872 return; 873 } 874 if (call.indexOf("glEnable(/*cap*/ GL_TEXTURE_2D)") >= 0) 875 return; 876 else if (call.indexOf("glDisable(/*cap*/ GL_TEXTURE_2D)") >= 0) 877 return; 878 else if (call.indexOf("glActiveTexture(/*texture*/ GL_TEXTURE_2D)") >= 0) 879 return; 880 code.write(call + ";CHKERR;\n"); 881 } 882 codeGenSetup(final Context ctx)883 private void codeGenSetup(final Context ctx) { 884 try { 885 codeFile = new FileWriter("frame_setup.cpp", false); 886 code = new PrintWriter(codeFile); 887 dataOut = new FileOutputStream("frame_data.bin", false); 888 namesHeaderFile = new FileWriter("frame_names.h", false); 889 namesHeader = new PrintWriter(namesHeaderFile); 890 namesSourceFile = new FileWriter("frame_names.cpp", false); 891 namesSource = new PrintWriter(namesSourceFile); 892 } catch (IOException e) { 893 e.printStackTrace(); 894 assert false; 895 } 896 bufferNames = new SparseIntArray(); 897 framebufferNames = new SparseIntArray(); 898 programNames = new SparseIntArray(); 899 textureNames = new SparseIntArray(); 900 shaderNames = new SparseIntArray(); 901 renderbufferNames = new SparseIntArray(); 902 903 namesHeader.write("#include <stdlib.h>\n"); 904 namesHeader.write("#include <stdio.h>\n"); 905 namesHeader.write("#include <assert.h>\n"); 906 namesHeader.write("#include <GLES2/gl2.h>\n"); 907 namesHeader.write("#include <GLES2/gl2ext.h>\n"); 908 namesHeader.write("#define CHKERR assert(GL_NO_ERROR == glGetError());/**/\n"); 909 namesHeader.write("void FrameSetup();\n"); 910 namesHeader.write("extern const unsigned int FrameCount;\n"); 911 namesHeader.write("extern const GLuint program_0;\n"); 912 913 namesSource.write("/*\n" + 914 " * Copyright (C) 2011 The Android Open Source Project\n" + 915 " *\n" + 916 " * Licensed under the Apache License, Version 2.0 (the \"License\");\n" + 917 " * you may not use this file except in compliance with the License.\n" + 918 " * You may obtain a copy of the License at\n" + 919 " *\n" + 920 " * http://www.apache.org/licenses/LICENSE-2.0\n" + 921 " *\n" + 922 " * Unless required by applicable law or agreed to in writing, software\n" + 923 " * distributed under the License is distributed on an \"AS IS\" BASIS,\n" + 924 " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" + 925 " * See the License for the specific language governing permissions and\n" + 926 " * limitations under the License.\n" + 927 " */\n" + 928 "\n" + 929 "#include <stdlib.h>\n" + 930 "#include <stdio.h>\n" + 931 "\n" + 932 "#include <EGL/egl.h>\n" + 933 "#include <GLES2/gl2.h>\n" + 934 "#include <GLES2/gl2ext.h>\n" + 935 "\n" + 936 "#include <ui/FramebufferNativeWindow.h>\n" + 937 "#include <ui/EGLUtils.h>\n" + 938 "\n" + 939 "#include <private/ui/android_natives_priv.h>\n" + 940 "\n" + 941 "#include <surfaceflinger/Surface.h>\n" + 942 "#include <surfaceflinger/ISurface.h>\n" + 943 "#include <surfaceflinger/SurfaceComposerClient.h>\n" + 944 "\n" + 945 "using namespace android;\n" + 946 "\n" + 947 "static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE)\n" + 948 "{\n" + 949 " if (returnVal != EGL_TRUE) {\n" + 950 " fprintf(stderr, \"%s() returned %d\\n\", op, returnVal);\n" + 951 " }\n" + 952 "\n" + 953 " for (EGLint error = eglGetError(); error != EGL_SUCCESS; error\n" + 954 " = eglGetError()) {\n" + 955 " fprintf(stderr, \"after %s() eglError %s (0x%x)\\n\", op, EGLUtils::strerror(error),\n" + 956 " error);\n" + 957 " }\n" + 958 "}\n" + 959 "\n" + 960 "static EGLDisplay dpy;\n" + 961 "static EGLSurface surface;\n" + 962 "\n" + 963 "#include \"frame_names.h\"\n" + 964 "const GLuint program_0 = 0;\n" + 965 "int main(int argc, char** argv)\n" + 966 "{\n" + 967 " EGLBoolean returnValue;\n" + 968 " EGLConfig myConfig = {0};\n" + 969 "\n" + 970 " EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };\n" + 971 " EGLint majorVersion;\n" + 972 " EGLint minorVersion;\n" + 973 " EGLContext context;\n" + 974 " EGLint w, h;\n" + 975 "\n" + 976 "\n" + 977 " checkEglError(\"<init>\");\n" + 978 " dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);\n" + 979 " checkEglError(\"eglGetDisplay\");\n" + 980 " if (dpy == EGL_NO_DISPLAY) {\n" + 981 " printf(\"eglGetDisplay returned EGL_NO_DISPLAY.\\n\");\n" + 982 " return 0;\n" + 983 " }\n" + 984 "\n" + 985 " returnValue = eglInitialize(dpy, &majorVersion, &minorVersion);\n" + 986 " checkEglError(\"eglInitialize\", returnValue);\n" + 987 " if (returnValue != EGL_TRUE) {\n" + 988 " printf(\"eglInitialize failed\\n\");\n" + 989 " return 0;\n" + 990 " }\n" + 991 "\n" + 992 " sp<SurfaceComposerClient> spClient;\n" + 993 " sp<SurfaceControl> spControl;\n" + 994 " sp<Surface> spSurface;\n" + 995 "\n" + 996 " // create a client to surfaceflinger\n" + 997 " spClient = new SurfaceComposerClient();\n" + 998 "\n" + 999 " spControl = spClient->createSurface(getpid(), 0, 1280, 752, PIXEL_FORMAT_RGBX_8888);\n" + 1000 " spClient->openTransaction();\n" + 1001 " spControl->setLayer(350000);\n" + 1002 " spControl->show();\n" + 1003 " spClient->closeTransaction();\n" + 1004 "\n" + 1005 " spSurface = spControl->getSurface();\n" + 1006 " EGLNativeWindowType window = spSurface.get();\n" + 1007 "\n" + 1008 " printf(\"window=%p\\n\", window);\n" + 1009 " EGLint attrib_list[] = {\n" + 1010 " EGL_SURFACE_TYPE, EGL_WINDOW_BIT,\n" + 1011 " EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,\n" + 1012 " EGL_BUFFER_SIZE, 32,\n" + 1013 " EGL_RED_SIZE, 8,\n" + 1014 " EGL_GREEN_SIZE, 8,\n" + 1015 " EGL_BLUE_SIZE, 8,\n" + 1016 " EGL_NONE\n" + 1017 " };\n" + 1018 "\n" + 1019 " EGLConfig configs[12] = {0};\n" + 1020 " int num_config = -1;\n" + 1021 " eglChooseConfig(dpy, attrib_list, configs, sizeof(configs) / sizeof(*configs), &num_config);\n" + 1022 " printf(\"eglChooseConfig %d \\n\", num_config);\n" + 1023 "\n" + 1024 " surface = eglCreateWindowSurface(dpy, configs[0], window, NULL);\n" + 1025 " checkEglError(\"eglCreateWindowSurface\");\n" + 1026 " if (surface == EGL_NO_SURFACE) {\n" + 1027 " printf(\"gelCreateWindowSurface failed.\\n\");\n" + 1028 " return 0;\n" + 1029 " }\n" + 1030 "\n" + 1031 " context = eglCreateContext(dpy, configs[0], EGL_NO_CONTEXT, context_attribs);\n" + 1032 " checkEglError(\"eglCreateContext\");\n" + 1033 " if (context == EGL_NO_CONTEXT) {\n" + 1034 " printf(\"eglCreateContext failed\\n\");\n" + 1035 " return 0;\n" + 1036 " }\n" + 1037 " printf(\"context=%p \\n\", context);\n" + 1038 "\n" + 1039 " returnValue = eglMakeCurrent(dpy, surface, surface, context);\n" + 1040 " checkEglError(\"eglMakeCurrent\", returnValue);\n" + 1041 " if (returnValue != EGL_TRUE) {\n" + 1042 " return 0;\n" + 1043 " }\n" + 1044 "\n" + 1045 " glClearColor(1,1,1,1);\n" + 1046 " glClear(GL_COLOR_BUFFER_BIT);\n" + 1047 "\n" + 1048 " FrameSetup();\n" + 1049 " while (true)\n" + 1050 " for (unsigned int i = 0; i < FrameCount; i++) {\n" + 1051 " Frames[i]();\n" + 1052 " eglSwapBuffers(dpy, surface);\n" + 1053 " printf(\"press ENTER after Frame%d \\n\", i);\n" + 1054 " getchar();\n" + 1055 " }\n" + 1056 "\n" + 1057 " return 0;\n" + 1058 "}"); 1059 1060 code.write("#include \"frame_names.h\"\n"); 1061 code.write("void FrameSetup(){\n"); 1062 1063 codeGenServerState(ctx.serverState); 1064 codeGenServerShader(ctx.serverShader); 1065 codeGenServerTexture(ctx.serverTexture, true); 1066 codeGenServerVertex(ctx.serverVertex); 1067 1068 code.write("}\n"); 1069 1070 try { 1071 codeFile.close(); 1072 makeFile = new FileWriter("Android.mk", false); 1073 make = new PrintWriter(makeFile); 1074 make.write("LOCAL_PATH:= $(call my-dir)\n" + 1075 "include $(CLEAR_VARS)\n" + 1076 "LOCAL_SRC_FILES := \\\n"); 1077 } catch (IOException e) { 1078 e.printStackTrace(); 1079 assert false; 1080 } 1081 } 1082 codeGenCleanup()1083 private void codeGenCleanup() { 1084 make.write(" frame_setup.cpp \\\n"); 1085 make.write(" frame_names.cpp \\\n"); 1086 make.write("#\n"); 1087 make.write( 1088 "LOCAL_SHARED_LIBRARIES := \\\n" + 1089 " libcutils \\\n" + 1090 " libutils \\\n" + 1091 " libEGL \\\n" + 1092 " libGLESv2 \\\n" + 1093 " libui \\\n" + 1094 " libhardware \\\n" + 1095 " libgui\n" + 1096 "\n" + 1097 "LOCAL_MODULE:= gles2dbg\n" + 1098 "\n" + 1099 "LOCAL_MODULE_TAGS := optional\n" + 1100 "\n" + 1101 "LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -O0 -g -DDEBUG -UNDEBUG\n" + 1102 "\n" + 1103 "include $(BUILD_EXECUTABLE)"); 1104 try { 1105 dataOut.flush(); 1106 dataOut.close(); 1107 codeFile.close(); 1108 makeFile.close(); 1109 namesHeaderFile.close(); 1110 namesSourceFile.close(); 1111 } catch (IOException e) { 1112 e.printStackTrace(); 1113 assert false; 1114 } 1115 dataOut = null; 1116 code = null; 1117 codeFile = null; 1118 make = null; 1119 makeFile = null; 1120 1121 bufferNames = null; 1122 framebufferNames = null; 1123 programNames = null; 1124 textureNames = null; 1125 shaderNames = null; 1126 renderbufferNames = null; 1127 } 1128 1129 private DebugContext dbgCtx; 1130 private int count; 1131 private IProgressMonitor progress; 1132 1133 @Override run(IProgressMonitor monitor)1134 public void run(IProgressMonitor monitor) { 1135 progress.beginTask("CodeGenFrames", count + 2); 1136 Context ctx = dbgCtx.getFrame(0).startContext.clone(); 1137 codeGenSetup(ctx); 1138 progress.worked(1); 1139 for (int i = 0; i < count; i++) { 1140 try { 1141 codeFile = new FileWriter("frame" + i + ".cpp", false); 1142 code = new PrintWriter(codeFile); 1143 } catch (IOException e1) { 1144 e1.printStackTrace(); 1145 assert false; 1146 } 1147 make.format(" frame%d.cpp \\\n", i); 1148 1149 code.write("#include \"frame_names.h\"\n"); 1150 code.format("void Frame%d(){\n", i); 1151 final Frame frame = dbgCtx.getFrame(i); 1152 for (int j = 0; j < frame.size(); j++) { 1153 final MessageData msgData = frame.get(j); 1154 code.format("/* frame function %d: %s %s*/\n", j, msgData.msg.getFunction(), 1155 MessageFormatter.format(msgData.msg, false)); 1156 ctx.processMessage(msgData.msg); 1157 try { 1158 codeGenFunction(ctx, msgData); 1159 } catch (IOException e) { 1160 e.printStackTrace(); 1161 assert false; 1162 } 1163 } 1164 code.write("}\n"); 1165 try { 1166 codeFile.close(); 1167 } catch (IOException e) { 1168 e.printStackTrace(); 1169 assert false; 1170 } 1171 progress.worked(1); 1172 } 1173 for (int i = 0; i < count; i++) 1174 namesHeader.format("void Frame%d();\n", i); 1175 namesHeader.format("extern void (* Frames[%d])();\n", count); 1176 namesSource.format("void (* Frames[%d])() = {\n", count); 1177 for (int i = 0; i < count; i++) { 1178 namesSource.format(" Frame%d,\n", i); 1179 } 1180 namesSource.write("};\n"); 1181 namesSource.format("const unsigned int FrameCount = %d;\n", count); 1182 codeGenCleanup(); 1183 progress.worked(1); 1184 } 1185 codeGenFrames(final DebugContext dbgCtx, int count, final Shell shell)1186 void codeGenFrames(final DebugContext dbgCtx, int count, final Shell shell) { 1187 this.dbgCtx = dbgCtx; 1188 this.count = count; 1189 ProgressMonitorDialog dialog = new ProgressMonitorDialog(shell); 1190 this.progress = dialog.getProgressMonitor(); 1191 try { 1192 dialog.run(false, true, this); 1193 } catch (InvocationTargetException e) { 1194 e.printStackTrace(); 1195 assert false; 1196 } catch (InterruptedException e) { 1197 e.printStackTrace(); 1198 } 1199 this.dbgCtx = null; 1200 this.count = 0; 1201 progress = null; 1202 } 1203 codeGenFrame(final Frame frame)1204 void codeGenFrame(final Frame frame) { 1205 Context ctx = frame.startContext.clone(); 1206 codeGenSetup(ctx); 1207 try { 1208 codeFile = new FileWriter("frame0.cpp", false); 1209 code = new PrintWriter(codeFile); 1210 } catch (IOException e1) { 1211 e1.printStackTrace(); 1212 assert false; 1213 } 1214 make.format(" frame0.cpp \\\n"); 1215 code.write("#include \"frame_names.h\"\n"); 1216 code.format("void Frame0(){\n"); 1217 for (int i = 0; i < frame.size(); i++) { 1218 final MessageData msgData = frame.get(i); 1219 code.format("/* frame function %d: %s %s*/\n", i, msgData.msg.getFunction(), 1220 MessageFormatter.format(msgData.msg, false)); 1221 ctx.processMessage(msgData.msg); 1222 try { 1223 codeGenFunction(ctx, msgData); 1224 } catch (IOException e) { 1225 e.printStackTrace(); 1226 assert false; 1227 } 1228 } 1229 code.write("}\n"); 1230 namesHeader.write("void Frame0();\n"); 1231 namesHeader.write("extern void (* Frames[1])();\n"); 1232 namesSource.write("void (* Frames[1])() = {Frame0};\n"); 1233 namesSource.write("const unsigned int FrameCount = 1;\n"); 1234 codeGenCleanup(); 1235 } 1236 } 1237