blob: 7f4bcefdd0a229d8609077e59777bb9fd5cd4c88 [file] [log] [blame]
/*
** Copyright 2011, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
package com.android.glesv2debugger;
import com.android.glesv2debugger.DebuggerMessage.Message;
import com.android.glesv2debugger.DebuggerMessage.Message.Function;
import com.android.sdklib.util.SparseIntArray;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.widgets.Shell;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.nio.ByteBuffer;
public class CodeGen implements IRunnableWithProgress {
private FileWriter codeFile, makeFile, namesHeaderFile, namesSourceFile;
private PrintWriter code, make, namesHeader, namesSource;
private FileOutputStream dataOut;
private SparseIntArray bufferNames,
framebufferNames, programNames, textureNames, shaderNames, renderbufferNames;
/** return true if msg was a texture upload */
private boolean CodeGenTextureUpload(final Message msg, final boolean replaceCopy) {
String s = null;
switch (msg.getFunction()) {
case glCompressedTexImage2D:
s = MessageFormatter.Format(msg, true).replace("arg7", "texData");
break;
case glCompressedTexSubImage2D:
case glTexImage2D:
case glTexSubImage2D:
s = MessageFormatter.Format(msg, true).replace("arg8", "texData");
break;
case glCopyTexImage2D:
if (!replaceCopy) {
code.write(MessageFormatter.Format(msg, true));
code.write(";CHKERR;\n");
return true;
}
assert msg.getArg2() == msg.getPixelFormat(); // TODO
s = "//" + MessageFormatter.Format(msg, true) + "\n";
s += String.format("glTexImage2D(%s, %d, %s, %d, %d, %d, %s, %s, texData);CHKERR;",
GLEnum.valueOf(msg.getArg0()), msg.getArg1(),
GLEnum.valueOf(msg.getArg2()), msg.getArg5(), msg.getArg6(),
msg.getArg7(), GLEnum.valueOf(msg.getPixelFormat()),
GLEnum.valueOf(msg.getPixelType()));
break;
case glCopyTexSubImage2D:
if (!replaceCopy) {
code.write(MessageFormatter.Format(msg, true));
code.write(";CHKERR;\n");
return true;
}
// FIXME: check the texture format & type, and convert
s = "//" + MessageFormatter.Format(msg, true) + "\n";
s += String.format(
"glTexSubImage2D(%s, %d, %d, %d, %d, %d, %s, %s, texData);CHKERR;",
GLEnum.valueOf(msg.getArg0()), msg.getArg1(), msg.getArg2(),
msg.getArg3(), msg.getArg6(), msg.getArg7(),
GLEnum.valueOf(msg.getPixelFormat()), GLEnum.valueOf(msg.getPixelType()));
break;
default:
return false;
}
if (msg.hasData()) {
final byte[] data = MessageProcessor.LZFDecompressChunks(msg.getData());
try {
code.write("{\n");
code.format(" void * texData = malloc(%d);CHKERR;\n", data.length);
code.format(" FILE * texFile = fopen(\"/sdcard/frame_data.bin\", \"rb\");CHKERR;\n");
code.format(" assert(texFile);CHKERR;\n");
code.format(" fseek(texFile, %d, SEEK_SET);CHKERR;\n", dataOut.getChannel()
.position());
dataOut.write(data);
code.format(" fread(texData, %d, 1, texFile);CHKERR;\n", data.length);
code.format(" fclose(texFile);CHKERR;\n");
code.format(" " + s + ";\n");
code.format(" free(texData);CHKERR;\n");
code.format("}\n");
} catch (IOException e) {
e.printStackTrace();
assert false;
}
} else
code.write(s.replace("texData", "NULL") + ";\n");
return true;
}
private void CodeGenServerState(final GLServerState serverState) {
code.write("// CodeGenServerState\n");
for (int i = 0; i < serverState.enableDisables.size(); i++) {
final GLEnum key = GLEnum.valueOf(serverState.enableDisables.keyAt(i));
if (serverState.enableDisables.valueAt(i) == 0)
code.format("glDisable(%s);CHKERR;\n", key);
else
code.format("glEnable(%s);CHKERR;\n", key);
}
for (int i = 0; i < serverState.lastSetter.size(); i++) {
final Function key = Function.valueOf(serverState.lastSetter.keyAt(i));
final Message msg = serverState.lastSetter.valueAt(i);
if (msg == null) {
code.format("// %s is default\n", key);
continue;
}
final String s = MessageFormatter.Format(msg, true);
code.write(s);
code.write(";\n");
}
// TODO: stencil and integers
}
private void CodeGenServerShader(final GLServerShader serverShader) {
code.write("// CodeGenServerShader\n");
for (int i = 0; i < serverShader.shaders.size(); i++) {
final int name = serverShader.shaders.keyAt(i);
final GLShader shader = serverShader.shaders.valueAt(i);
final String id = "shader_" + name;
if (shaderNames.indexOfKey(name) < 0) {
namesSource.format("GLuint %s = 0;\n", id);
namesHeader.format("extern GLuint %s;\n", id);
}
code.format("%s = glCreateShader(%s);CHKERR;\n", id, shader.type);
shaderNames.put(name, name);
if (shader.source != null) {
final String src = shader.source.replace("\r", "").replace("\n", "\\n\\\n")
.replace("\"", "\\\"");
code.format("glShaderSource(%s, 1, (const GLchar *[]){\"%s\"}, NULL);CHKERR;\n",
id, src);
code.format("glCompileShader(%s);CHKERR;\n", id);
}
}
for (int i = 0; i < serverShader.programs.size(); i++) {
final int name = serverShader.programs.keyAt(i);
final GLProgram program = serverShader.programs.valueAt(i);
final String id = "program_" + name;
if (programNames.indexOfKey(name) < 0) {
namesSource.format("GLuint %s = 0;\n", id);
namesHeader.format("extern GLuint %s;\n", id);
}
code.format("%s = glCreateProgram();CHKERR;\n", id);
programNames.put(name, name);
code.format("glAttachShader(%s, shader_%d);CHKERR;\n", id,
program.vert);
code.format("glAttachShader(%s, shader_%d);CHKERR;\n", id,
program.frag);
code.format("glLinkProgram(%s);CHKERR;\n", id);
if (serverShader.current == program)
code.format("glUseProgram(%s);CHKERR;\n", id);
}
}
private void CodeGenServerTexture(final GLServerTexture serverTexture, final boolean replaceCopy) {
code.write("// CodeGenServerTexture\n");
for (int i = 0; i < serverTexture.textures.size(); i++) {
final int name = serverTexture.textures.keyAt(i);
final GLTexture tex = serverTexture.textures.valueAt(i);
final String id = "texture_" + name;
if (textureNames.indexOfKey(name) < 0) {
namesHeader.format("extern GLuint %s;\n", id);
namesSource.format("GLuint %s = 0;\n", id);
}
code.format("%s = 0;\n", id);
textureNames.put(name, name);
if (name == 0)
continue;
code.format("glGenTextures(1, &%s);CHKERR;\n", id);
String s = String.format("glBindTexture(%s, texture_%d);CHKERR;\n", tex.target,
tex.name);
code.write(s);
for (final Message msg : tex.contentChanges) {
if (CodeGenTextureUpload(msg, replaceCopy))
continue;
switch (msg.getFunction()) {
case glGenerateMipmap:
s = MessageFormatter.Format(msg, true);
break;
default:
assert false;
}
code.write(s + ";\n");
}
code.format("glTexParameteriv(%s, GL_TEXTURE_WRAP_S, (GLint[]){%s});CHKERR;\n",
tex.target, tex.wrapS);
code.format("glTexParameteriv(%s, GL_TEXTURE_WRAP_T, (GLint[]){%s});CHKERR;\n",
tex.target, tex.wrapT);
code.format("glTexParameteriv(%s, GL_TEXTURE_MIN_FILTER, (GLint[]){%s});CHKERR;\n",
tex.target, tex.min);
code.format("glTexParameteriv(%s, GL_TEXTURE_MAG_FILTER, (GLint[]){%s});CHKERR;\n",
tex.target, tex.mag);
}
for (int i = 0; i < serverTexture.tmu2D.length && i < 16; i++) {
code.format("glActiveTexture(%s);CHKERR;\n",
GLEnum.valueOf(GLEnum.GL_TEXTURE0.value + i));
code.format("glBindTexture(GL_TEXTURE_2D, texture_%d);CHKERR;\n",
serverTexture.tmu2D[i]);
}
for (int i = 0; i < serverTexture.tmuCube.length && i < 16; i++) {
code.format("glActiveTexture(%s);CHKERR;\n",
GLEnum.valueOf(GLEnum.GL_TEXTURE0.value + i));
code.format("glBindTexture(GL_TEXTURE_CUBE_MAP, texture_%d);CHKERR;\n",
serverTexture.tmuCube[i]);
}
code.format("glActiveTexture(%s);CHKERR;\n", serverTexture.activeTexture);
if (serverTexture.tex2D == null)
code.format("glBindTexture(GL_TEXTURE_2D, 0);CHKERR;\n");
else
code.format("glBindTexture(GL_TEXTURE_2D, texture_%d);CHKERR;\n",
serverTexture.tex2D.name);
if (serverTexture.texCube == null)
code.format("glBindTexture(GL_TEXTURE_CUBE_MAP, 0);CHKERR;\n");
else
code.format("glBindTexture(GL_TEXTURE_CUBE_MAP, texture_%d);CHKERR;\n",
serverTexture.texCube.name);
}
private void CodeGenBufferData(final ByteBuffer buffer, final String call) {
ByteBuffer bfr = buffer;
if (buffer.isReadOnly()) {
bfr = ByteBuffer.allocate(buffer.capacity());
bfr.put(buffer);
}
final byte[] data = bfr.array();
try {
code.write("{\n");
code.format(" void * bufferData = malloc(%d);\n", data.length);
code.format(" FILE * bufferFile = fopen(\"/sdcard/frame_data.bin\", \"rb\");\n");
code.format(" assert(bufferFile);\n");
code.format(" fseek(bufferFile, %d, SEEK_SET);\n", dataOut.getChannel()
.position());
dataOut.write(data);
code.format(" fread(bufferData, %d, 1, bufferFile);\n", data.length);
code.format(" fclose(bufferFile);\n");
code.format(" " + call + ";CHKERR;\n");
code.format(" free(bufferData);\n");
code.format("}\n");
} catch (IOException e) {
e.printStackTrace();
assert false;
}
}
private void CodeGenServerVertex(final GLServerVertex v) {
code.write("// CodeGenServerVertex\n");
for (int i = 0; i < v.buffers.size(); i++) {
final int name = v.buffers.keyAt(i);
final String id = "buffer_" + name;
final GLBuffer buffer = v.buffers.valueAt(i);
if (bufferNames.indexOfKey(name) < 0) {
namesHeader.format("extern GLuint %s;\n", id);
namesSource.format("GLuint %s = 0;\n", id);
}
code.format("%s = 0;\n", id);
bufferNames.put(name, name);
if (name == 0)
continue;
code.format("glGenBuffers(1, &%s);CHKERR;\n", id);
if (buffer.target != null) {
code.format("glBindBuffer(%s, %s);CHKERR;\n", buffer.target, id);
if (buffer.data != null) {
String s = String.format("glBufferData(%s, %d, bufferData, %s)", buffer.target,
buffer.data.capacity(), buffer.usage);
CodeGenBufferData(buffer.data, s);
}
}
}
// TODO: use MAX_VERTEX_ATTRIBS
for (int i = 0; i < v.defaultAttribs.length; i++)
code.format("glVertexAttrib4f(%d, %f, %f, %f, %f);CHKERR;\n", i,
v.defaultAttribs[i][0],
v.defaultAttribs[i][1], v.defaultAttribs[i][2], v.defaultAttribs[i][3]);
for (int i = 0; i < v.attribPointers.length; i++) {
final GLAttribPointer att = v.attribPointers[i];
if (att.type == null)
continue;
if (att.buffer != null)
code.format("glBindBuffer(GL_ARRAY_BUFFER, buffer_%d);CHKERR;\n", att.buffer.name);
else
code.format("glBindBuffer(GL_ARRAY_BUFFER, 0);CHKERR;\n");
code.format("glVertexAttribPointer(%d, %d, %s, %b, %d, (const GLvoid *)%d);CHKERR;\n",
i, att.size, att.type, att.normalized, att.stride, att.ptr);
}
if (v.attribBuffer != null)
code.format("glBindBuffer(GL_ARRAY_BUFFER, buffer_%d);CHKERR;\n", v.attribBuffer.name);
else
code.write("glBindBuffer(GL_ARRAY_BUFFER, 0);CHKERR;\n");
if (v.indexBuffer != null)
code.format("glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_%d);CHKERR;\n",
v.indexBuffer.name);
else
code.write("glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);CHKERR;\n");
}
private void CodeGenGenNames(final Message msg) {
final ByteBuffer names = msg.getData().asReadOnlyByteBuffer();
names.order(SampleView.targetByteOrder);
SparseIntArray namesArray = null;
for (int i = 0; i < msg.getArg0(); i++) {
String id = "";
final int name = names.getInt();
switch (msg.getFunction()) {
case glGenBuffers:
id = "buffer";
namesArray = bufferNames;
break;
case glGenFramebuffers:
id = "framebuffer";
namesArray = framebufferNames;
break;
case glGenRenderbuffers:
id = "renderbuffer";
namesArray = renderbufferNames;
break;
case glGenTextures:
id = "texture";
namesArray = textureNames;
break;
default:
assert false;
}
id += "_" + name;
if (namesArray.indexOfKey(name) < 0) {
namesHeader.format("extern GLuint %s;\n", id);
namesSource.format("GLuint %s = 0;\n", id);
}
code.format("%s = 0;\n", id);
namesArray.put(name, name);
code.format("%s(1, &%s);CHKERR;\n", msg.getFunction(), id);
}
}
private void CodeGenDeleteNames(final Message msg) {
final ByteBuffer names = msg.getData().asReadOnlyByteBuffer();
names.order(SampleView.targetByteOrder);
SparseIntArray namesArray = null;
for (int i = 0; i < msg.getArg0(); i++) {
String id = null;
final int name = names.getInt();
switch (msg.getFunction()) {
case glDeleteBuffers:
id = "buffer";
namesArray = bufferNames;
break;
case glDeleteFramebuffers:
id = "framebuffer";
namesArray = framebufferNames;
break;
case glDeleteRenderbuffers:
id = "renderbuffer";
namesArray = renderbufferNames;
break;
case glDeleteTextures:
id = "texture";
namesArray = textureNames;
break;
default:
assert false;
}
id += "_" + name;
code.format("%s = 0;\n", id);
namesArray.put(name, 0);
code.format("%s(1, &%s);CHKERR;\n", msg.getFunction(), id);
}
}
private void CodeGenBindNames(final Message msg) {
String id = null;
SparseIntArray namesArray = null;
final int name = msg.getArg1();
switch (msg.getFunction()) {
case glBindBuffer:
id = "buffer";
namesArray = bufferNames;
break;
case glBindFramebuffer:
id = "framebuffer";
namesArray = framebufferNames;
break;
case glBindRenderbuffer:
id = "renderbuffer";
namesArray = renderbufferNames;
break;
case glBindTexture:
id = "texture";
namesArray = textureNames;
break;
default:
assert false;
}
id += "_" + name;
if (namesArray.indexOfKey(name) < 0) {
namesHeader.format("extern GLuint %s;\n", id);
namesSource.format("GLuint %s = 0;\n", id);
}
code.format("%s = %d;\n", id, name);
namesArray.put(name, name);
code.write(MessageFormatter.Format(msg, true));
code.write(";CHKERR;\n");
}
private void CodeGenDrawArrays(final GLServerVertex v, final ByteBuffer[] attribs,
final int mode, final int count) throws IOException {
code.write("{\n");
code.format(" FILE * attribFile = fopen(\"/sdcard/frame_data.bin\", \"rb\");CHKERR;\n");
code.format(" assert(attribFile);CHKERR;\n");
code.format(" fseek(attribFile, %d, SEEK_SET);CHKERR;\n", dataOut.getChannel()
.position());
code.format(" glBindBuffer(GL_ARRAY_BUFFER, 0);CHKERR;\n");
for (int i = 0; i < attribs.length; i++) {
final GLAttribPointer att = v.attribPointers[i];
if (!att.enabled)
continue;
final byte[] data = attribs[i].array();
final String typeName = "GL" + att.type.name().substring(3).toLowerCase();
code.format(" %s * attrib%d = (%s *)malloc(%d);CHKERR;\n", typeName, i, typeName,
data.length);
dataOut.write(data);
code.format(" fread(attrib%d, %d, 1, attribFile);CHKERR;\n", i, data.length);
// code.format(" for (unsigned int i = 0; i < %d; i++)\n", count
// * att.size);
// code.format(" printf(\"%%f \\n\", attrib%d[i]);CHKERR;\n",
// i);
code.format(" glVertexAttribPointer(%d, %d, %s, %b, %d, attrib%d);CHKERR;\n",
i, att.size, att.type, att.normalized,
att.size * GLServerVertex.TypeSize(att.type), i);
}
code.format(" fclose(attribFile);CHKERR;\n");
code.format(" glDrawArrays(%s, 0, %d);CHKERR;\n", GLEnum.valueOf(mode), count);
for (int i = 0; i < attribs.length; i++)
if (v.attribPointers[i].enabled)
code.format(" free(attrib%d);CHKERR;\n", i);
if (v.attribBuffer != null)
code.format(" glBindBuffer(GL_ARRAY_BUFFER, %d);CHKERR;\n",
v.attribBuffer.name);
code.write("};\n");
}
private void CodeGenFunction(final Context ctx, final MessageData msgData) throws IOException {
final Message msg = msgData.msg;
final Message oriMsg = msgData.oriMsg;
String call = MessageFormatter.Format(msg, true);
switch (msg.getFunction()) {
case glActiveTexture:
case glAttachShader:
case glBindAttribLocation:
break;
case glBindBuffer:
case glBindFramebuffer:
case glBindRenderbuffer:
case glBindTexture:
CodeGenBindNames(msg);
return;
case glBlendColor:
case glBlendEquation:
case glBlendEquationSeparate:
case glBlendFunc:
case glBlendFuncSeparate:
break;
case glBufferData:
call = MessageFormatter.Format(msg, true).replace("arg2", "bufferData");
CodeGenBufferData(msg.getData().asReadOnlyByteBuffer(), call);
return;
case glBufferSubData:
call = MessageFormatter.Format(msg, true).replace("arg3", "bufferData");
CodeGenBufferData(msg.getData().asReadOnlyByteBuffer(), call);
return;
case glCheckFramebufferStatus:
case glClear:
case glClearColor:
case glClearDepthf:
case glClearStencil:
case glColorMask:
case glCompileShader:
break;
case glCompressedTexImage2D:
case glCompressedTexSubImage2D:
case glCopyTexImage2D:
case glCopyTexSubImage2D:
CodeGenTextureUpload(msg, false);
return;
case glCreateProgram:
namesHeader.format("extern GLuint program_%d;\n", msg.getRet());
namesSource.format("GLuint program_%d = 0;\n", msg.getRet());
code.format("program_%d = glCreateProgram();CHKERR;\n", msg.getRet());
return;
case glCreateShader:
namesHeader.format("extern GLuint shader_%d;\n", msg.getRet());
namesSource.format("GLuint shader_%d = 0;\n", msg.getRet());
code.format("shader_%d = %s;\n", msg.getRet(), call);
return;
case glCullFace:
break;
case glDeleteBuffers:
case glDeleteFramebuffers:
case glDeleteProgram:
programNames.put(msg.getArg0(), 0);
break;
case glDeleteRenderbuffers:
CodeGenDeleteNames(msg);
return;
case glDeleteShader:
shaderNames.put(msg.getArg0(), 0);
return;
case glDeleteTextures:
CodeGenDeleteNames(msg);
return;
case glDepthFunc:
case glDepthMask:
case glDepthRangef:
case glDetachShader:
case glDisable:
case glDisableVertexAttribArray:
break;
case glDrawArrays:
CodeGenDrawArrays(ctx.serverVertex, msgData.attribs, msg.getArg0(), msg.getArg2());
return;
case glDrawElements:
CodeGenDrawArrays(ctx.serverVertex, msgData.attribs, msg.getArg0(), msg.getArg1());
return;
case glEnable:
case glEnableVertexAttribArray:
case glFinish:
case glFlush:
case glFramebufferRenderbuffer:
case glFramebufferTexture2D:
case glFrontFace:
break;
case glGenBuffers:
CodeGenGenNames(msg);
return;
case glGenerateMipmap:
break;
case glGenFramebuffers:
case glGenRenderbuffers:
case glGenTextures:
CodeGenGenNames(msg);
return;
case glGetActiveAttrib:
case glGetActiveUniform:
case glGetAttachedShaders:
break;
case glGetAttribLocation:
call = String.format("assert(%d == %s)", msg.getRet(), call);
break;
case glGetBooleanv:
case glGetBufferParameteriv:
return; // TODO
case glGetError:
code.write("CHKERR;\n");
return;
case glGetFloatv:
case glGetFramebufferAttachmentParameteriv:
case glGetIntegerv:
case glGetProgramiv:
case glGetProgramInfoLog:
case glGetRenderbufferParameteriv:
case glGetShaderiv:
case glGetShaderInfoLog:
case glGetShaderPrecisionFormat:
case glGetShaderSource:
case glGetString:
case glGetTexParameterfv:
case glGetTexParameteriv:
case glGetUniformfv:
case glGetUniformiv:
return;
case glGetUniformLocation:
call = String.format("assert(%d == %s)", msg.getRet(), call);
break;
case glGetVertexAttribfv:
case glGetVertexAttribiv:
case glGetVertexAttribPointerv:
return; // TODO
case glHint:
case glIsBuffer:
case glIsEnabled:
case glIsFramebuffer:
case glIsProgram:
case glIsRenderbuffer:
case glIsShader:
case glIsTexture:
case glLineWidth:
case glLinkProgram:
case glPixelStorei:
case glPolygonOffset:
break;
case glReadPixels:
return; // TODO
case glReleaseShaderCompiler:
case glRenderbufferStorage:
case glSampleCoverage:
case glScissor:
break;
case glShaderBinary:
return; // TODO
case glShaderSource:
call = String.format(
"glShaderSource(shader_%d, 1, (const char * []){\"%s\"}, NULL)",
msg.getArg0(),
msg.getData().toStringUtf8().replace("\r", "").replace("\n", "\\n\\\n")
.replace("\"", "\\\"")
);
break;
case glStencilFunc:
case glStencilFuncSeparate:
case glStencilMask:
case glStencilMaskSeparate:
case glStencilOp:
case glStencilOpSeparate:
break;
case glTexImage2D:
CodeGenTextureUpload(msg, false);
return;
case glTexParameterf:
break;
case glTexParameterfv:
return; // TODO
case glTexParameteri:
break;
case glTexParameteriv:
return; // TODO
case glTexSubImage2D:
CodeGenTextureUpload(msg, false);
return;
case glUniform1f:
case glUniform1fv:
case glUniform1i:
case glUniform1iv:
case glUniform2f:
case glUniform2fv:
case glUniform2i:
case glUniform2iv:
case glUniform3f:
case glUniform3fv:
case glUniform3i:
case glUniform3iv:
case glUniform4f:
case glUniform4fv:
case glUniform4i:
case glUniform4iv:
case glUniformMatrix2fv:
case glUniformMatrix3fv:
case glUniformMatrix4fv:
case glUseProgram:
case glValidateProgram:
case glVertexAttrib1f:
case glVertexAttrib1fv:
case glVertexAttrib2f:
case glVertexAttrib2fv:
case glVertexAttrib3f:
case glVertexAttrib3fv:
case glVertexAttrib4f:
case glVertexAttrib4fv:
break;
case glVertexAttribPointer:
// pointer set during glDrawArrays/Elements from captured data
call = call.replace("arg5", "NULL");
break;
case glViewport:
break;
case eglSwapBuffers:
return;
default:
assert false;
return;
}
code.write(call + ";CHKERR;\n");
}
private void CodeGenSetup(final Context ctx) {
try {
codeFile = new FileWriter("frame_setup.cpp", false);
code = new PrintWriter(codeFile);
dataOut = new FileOutputStream("frame_data.bin", false);
namesHeaderFile = new FileWriter("frame_names.h", false);
namesHeader = new PrintWriter(namesHeaderFile);
namesSourceFile = new FileWriter("frame_names.cpp", false);
namesSource = new PrintWriter(namesSourceFile);
} catch (IOException e) {
e.printStackTrace();
assert false;
}
bufferNames = new SparseIntArray();
framebufferNames = new SparseIntArray();
programNames = new SparseIntArray();
textureNames = new SparseIntArray();
shaderNames = new SparseIntArray();
renderbufferNames = new SparseIntArray();
namesHeader.write("#include <stdlib.h>\n");
namesHeader.write("#include <stdio.h>\n");
namesHeader.write("#include <assert.h>\n");
namesHeader.write("#include <GLES2/gl2.h>\n");
namesHeader.write("#include <GLES2/gl2ext.h>\n");
namesHeader.write("#define CHKERR /*assert(GL_NO_ERROR == glGetError());/**/\n");
namesHeader.write("void FrameSetup();\n");
namesHeader.write("extern const unsigned int FrameCount;\n");
namesHeader.write("extern const GLuint program_0;\n");
namesSource.write("#include \"frame_names.h\"\n");
namesSource.write("const GLuint program_0 = 0;\n");
code.write("#include \"frame_names.h\"\n");
code.write("void FrameSetup(){\n");
CodeGenServerState(ctx.serverState);
CodeGenServerShader(ctx.serverShader);
CodeGenServerTexture(ctx.serverTexture, true);
CodeGenServerVertex(ctx.serverVertex);
code.write("}\n");
try {
codeFile.close();
makeFile = new FileWriter("frame_src.mk", false);
make = new PrintWriter(makeFile);
make.write("LOCAL_SRC_FILES := \\\n");
} catch (IOException e) {
e.printStackTrace();
assert false;
}
}
private void CodeGenCleanup() {
make.write(" frame_setup.cpp \\\n");
make.write(" frame_names.cpp");
try {
dataOut.flush();
dataOut.close();
codeFile.close();
makeFile.close();
namesHeaderFile.close();
namesSourceFile.close();
} catch (IOException e) {
e.printStackTrace();
assert false;
}
dataOut = null;
code = null;
codeFile = null;
make = null;
makeFile = null;
bufferNames = null;
framebufferNames = null;
programNames = null;
textureNames = null;
shaderNames = null;
renderbufferNames = null;
}
private DebugContext dbgCtx;
private int count;
private IProgressMonitor progress;
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException,
InterruptedException {
progress.beginTask("CodeGenFrames", count + 2);
Context ctx = dbgCtx.GetFrame(0).startContext.clone();
CodeGenSetup(ctx);
progress.worked(1);
for (int i = 0; i < count; i++) {
try {
codeFile = new FileWriter("frame" + i + ".cpp", false);
code = new PrintWriter(codeFile);
} catch (IOException e1) {
e1.printStackTrace();
assert false;
}
make.format(" frame%d.cpp \\\n", i);
code.write("#include \"frame_names.h\"\n");
code.format("void Frame%d(){\n", i);
final Frame frame = dbgCtx.GetFrame(i);
for (int j = 0; j < frame.Size(); j++) {
final MessageData msgData = frame.Get(j);
code.format("/* frame function %d: %s %s*/\n", j, msgData.msg.getFunction(),
MessageFormatter.Format(msgData.msg, false));
ctx.ProcessMessage(msgData.oriMsg);
try {
CodeGenFunction(ctx, msgData);
} catch (IOException e) {
e.printStackTrace();
assert false;
}
}
code.write("}\n");
try {
codeFile.close();
} catch (IOException e) {
e.printStackTrace();
assert false;
}
progress.worked(1);
}
for (int i = 0; i < count; i++)
namesHeader.format("void Frame%d();\n", i);
namesHeader.format("extern void (* Frames[%d])();\n", count);
namesSource.format("void (* Frames[%d])() = {\n", count);
for (int i = 0; i < count; i++) {
namesSource.format(" Frame%d,\n", i);
}
namesSource.write("};\n");
namesSource.format("const unsigned int FrameCount = %d;\n", count);
CodeGenCleanup();
progress.worked(1);
}
void CodeGenFrames(final DebugContext dbgCtx, int count, final Shell shell) {
this.dbgCtx = dbgCtx;
this.count = count;
ProgressMonitorDialog dialog = new ProgressMonitorDialog(shell);
this.progress = dialog.getProgressMonitor();
try {
dialog.run(false, true, this);
} catch (InvocationTargetException e) {
e.printStackTrace();
assert false;
} catch (InterruptedException e) {
e.printStackTrace();
}
this.dbgCtx = null;
this.count = 0;
progress = null;
}
void CodeGenFrame(final Frame frame) {
Context ctx = frame.startContext.clone();
CodeGenSetup(ctx);
try {
codeFile = new FileWriter("frame0.cpp", false);
code = new PrintWriter(codeFile);
} catch (IOException e1) {
e1.printStackTrace();
assert false;
}
make.format(" frame0.cpp \\\n");
code.write("#include \"frame_names.h\"\n");
code.format("void Frame0(){\n");
for (int i = 0; i < frame.Size(); i++) {
final MessageData msgData = frame.Get(i);
code.format("/* frame function %d: %s %s*/\n", i, msgData.msg.getFunction(),
MessageFormatter.Format(msgData.msg, false));
ctx.ProcessMessage(msgData.oriMsg);
try {
CodeGenFunction(ctx, msgData);
} catch (IOException e) {
e.printStackTrace();
assert false;
}
}
code.write("}\n");
namesHeader.write("void Frame0();\n");
namesHeader.write("extern void (* Frames[1])();\n");
namesSource.write("void (* Frames[1])() = {Frame0};\n");
namesSource.write("const unsigned int FrameCount = 1;\n");
CodeGenCleanup();
}
}