• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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