GLES2Dbg: code gen for frame

Also loading *.gles2dbg dump files.

Change-Id: I87e5ae6fda22b3cad920d2a06671efef5adb2e8a
Signed-off-by: David Li <davidxli@google.com>
This commit is contained in:
David Li
2011-04-11 11:11:32 -07:00
parent 1768bb7806
commit 7ec777341e
16 changed files with 2565 additions and 446 deletions

View File

@@ -60,64 +60,66 @@ public class MessageFormatter {
static String FormatFloats(int count, final ByteBuffer data) {
if (data.remaining() == 0)
return "[null]";
return "{}";
data.order(SampleView.targetByteOrder);
String ret = "[";
String ret = "{";
for (int i = 0; i < count; i++) {
ret += Float.intBitsToFloat(data.getInt());
if (i < count - 1)
ret += ", ";
}
return ret + "]";
return ret + "}";
}
static String FormatInts(int count, final ByteBuffer data) {
if (data.remaining() == 0)
return "[null]";
return "{}";
data.order(SampleView.targetByteOrder);
String ret = "[";
String ret = "{";
for (int i = 0; i < count; i++) {
ret += data.getInt();
if (i < count - 1)
ret += ", ";
}
return ret + "]";
return ret + "}";
}
static String FormatUints(int count, final ByteBuffer data) {
if (data.remaining() == 0)
return "[null]";
return "{}";
data.order(SampleView.targetByteOrder);
String ret = "[";
String ret = "{";
for (int i = 0; i < count; i++) {
long bits = data.getInt() & 0xffffffff;
ret += bits;
if (i < count - 1)
ret += ", ";
}
return ret + "]";
return ret + "}";
}
static String FormatMatrix(int columns, int count, final ByteBuffer data) {
if (data.remaining() == 0)
return "[null]";
return "{}";
data.order(SampleView.targetByteOrder);
String ret = "[";
String ret = "{";
for (int i = 0; i < count; i++) {
ret += Float.intBitsToFloat(data.getInt());
if (i < count - 1)
ret += ", ";
if (i % columns == columns - 1)
ret += "\\n ";
else if (i < count - 1)
ret += ", ";
}
return ret + "]";
return ret + "}";
}
public static String Format(final DebuggerMessage.Message msg) {
public static String Format(final DebuggerMessage.Message msg,
final boolean code) {
String str;
switch (msg.getFunction()) {
""")
#in source code these turn into program_%d etc.
nameReplaces = ["program", "shader", "texture", "buffer", "framebuffer", "renderbuffer"]
for line in lines:
if line.find("API_ENTRY(") >= 0: # a function prototype
returnType = line[0: line.find(" API_ENTRY(")].replace("const ", "")
@@ -127,19 +129,22 @@ public class MessageFormatter {
parameters = parameterList.split(',')
paramIndex = 0
formatString = "%s "
formatString = "%s"
formatArgs = ""
if returnType != "void":
if returnType == "GLenum":
formatArgs += "GLEnum.valueOf(msg.getRet())"
formatArgs += '\
(code ? "%s" : GLEnum.valueOf(msg.getRet()))\n' % (functionName)
elif returnType.find("*") >= 0:
formatArgs += '"0x" + Integer.toHexString(msg.getRet())'
formatArgs += '\
(code ? "%s" : "0x" + Integer.toHexString(msg.getRet()))\n' % (functionName)
else:
formatArgs += "msg.getRet()"
formatArgs += '\
(code ? "%s" : msg.getRet())\n' % (functionName)
else:
formatArgs += '"void"'
formatArgs += '\
(code ? "%s" : "void")\n' % (functionName)
#formatString += "%s(" % (functionName)
formatString += "("
if parameterList == "void":
@@ -155,8 +160,9 @@ public class MessageFormatter {
paramName = parameter.split(' ')[1]
annotation = ""
formatString += paramName + "=%s"
formatString += "%s%s"
formatArgs += '\
, (code ? "/*%s*/ " : "%s=")\n' % (paramName, paramName)
if parameter.find(":") >= 0:
assert inout == "" # only one parameter should be annotated
inout = paramType.split(":")[2]
@@ -193,26 +199,42 @@ public class MessageFormatter {
assert columns * columns == count
assert countArg != ""
assert paramType == "GLfloat"
formatArgs += ", FormatMatrix(%d, %d * msg.getArg%d(), msg.getData().asReadOnlyByteBuffer())" % (columns, count, paramNames.index(countArg))
formatArgs += '\
, (code ? "(GLfloat [])" : "") + FormatMatrix(%d, %d * msg.getArg%d(), msg.getData().asReadOnlyByteBuffer())' % (
columns, count, paramNames.index(countArg))
elif annotation == "GLstring":
formatArgs += ", msg.getData().toStringUtf8()"
formatArgs += '\
, (code ? "\\"" : "") + msg.getData().toStringUtf8() + (code ? "\\"" : "")'
elif paramType.find("void") >= 0:
formatArgs += ', "0x" + Integer.toHexString(msg.getArg%d())' % (paramIndex)
formatArgs += '\
, (code ? "arg%d" : "0x" + Integer.toHexString(msg.getArg%d()))' % (paramIndex, paramIndex)
elif countArg == "":
formatArgs += ", %s(%d, msg.getData().asReadOnlyByteBuffer())" % (dataFormatter, count)
formatArgs += '\
, (code ? "(%s [])" : "") + %s(%d, msg.getData().asReadOnlyByteBuffer())' % (
paramType, dataFormatter, count)
else:
formatArgs += ", %s(%d * msg.getArg%d(), msg.getData().asReadOnlyByteBuffer())" % (dataFormatter, count, paramNames.index(countArg))
formatArgs += '\
, (code ? "(%s [])" : "") + %s(%d * msg.getArg%d(), msg.getData().asReadOnlyByteBuffer())' % (
paramType, dataFormatter, count, paramNames.index(countArg))
else:
if paramType == "GLfloat" or paramType == "GLclampf":
formatArgs += ", Float.intBitsToFloat(msg.getArg%d())" % (paramIndex)
formatArgs += "\
, Float.intBitsToFloat(msg.getArg%d())" % (paramIndex)
elif paramType == "GLenum":
formatArgs += ", GLEnum.valueOf(msg.getArg%d())" % (paramIndex)
formatArgs += "\
, GLEnum.valueOf(msg.getArg%d())" % (paramIndex)
elif paramType.find("*") >= 0:
formatArgs += ', "0x" + Integer.toHexString(msg.getArg%d())' % (paramIndex)
formatArgs += '\
, (code ? "arg%d" : "0x" + Integer.toHexString(msg.getArg%d()))' % (paramIndex, paramIndex)
elif paramName in nameReplaces:
formatArgs += '\
, (code ? "%s_" : "") + msg.getArg%d()' % (paramName, paramIndex)
else:
formatArgs += ", msg.getArg%d()" % (paramIndex)
formatArgs += "\
, msg.getArg%d()" % (paramIndex)
if paramIndex < len(parameters) - 1:
formatString += ", "
formatArgs += '\n'
paramNames.append(paramName)
paramIndex += 1
@@ -223,7 +245,9 @@ public class MessageFormatter {
if line.find("*") >= 0 and (line.find("*") < line.find(":") or line.find("*") > line.rfind(":")):
sys.stderr.write(line)
output.write(" // FIXME: this function uses pointers, debugger may send data in msg.data\n")
output.write(' str = String.format("%s", %s); break;\n' % (formatString, formatArgs))
output.write('\
str = String.format("%s",\n%s);\n\
break;\n' % (formatString, formatArgs))
output.write(""" default:

View File

@@ -67,15 +67,15 @@ public abstract class MessageParser {
String[] GetList()
{
assert args.charAt(0) == '[';
assert args.charAt(0) == '{';
String arg = args;
args = args.substring(args.indexOf(']') + 1);
args = args.substring(args.lastIndexOf('}') + 1);
int comma = args.indexOf(',');
if (comma >= 0)
args = args.substring(comma + 1).trim();
else
args = null;
arg = arg.substring(1, arg.indexOf(']')).trim();
arg = arg.substring(1, arg.lastIndexOf('}')).trim();
return arg.split(",");
}

View File

@@ -20,6 +20,7 @@ import com.android.glesv2debugger.DebuggerMessage.Message;
import com.android.glesv2debugger.DebuggerMessage.Message.Function;
import com.android.glesv2debugger.DebuggerMessage.Message.Prop;
import com.android.glesv2debugger.DebuggerMessage.Message.Type;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
@@ -111,9 +112,9 @@ public class BreakpointOption extends ScrolledComposite implements SelectionList
shell.getDisplay().syncExec(new Runnable() {
@Override
public void run() {
String call = MessageFormatter.Format(msg);
call = call.substring(0, call.indexOf("(")) + msg.getFunction().toString()
+ call.substring(call.indexOf("("));
String call = MessageFormatter.Format(msg, false);
call = call.substring(0, call.indexOf("(")) + ' ' +
msg.getFunction() + call.substring(call.indexOf("("));
if (msg.hasData() && msg.getFunction() == Function.glShaderSource)
{
int index = call.indexOf("string=") + 7;
@@ -134,7 +135,7 @@ public class BreakpointOption extends ScrolledComposite implements SelectionList
{
assert msg.getType() == Type.AfterGeneratedCall;
assert msg.getFunction() == lastFunction;
call = "skip" + call;
call = "skip " + call;
builder.setFunction(Function.SKIP);
}
InputDialog inputDialog = new InputDialog(shell,
@@ -164,6 +165,9 @@ public class BreakpointOption extends ScrolledComposite implements SelectionList
{
MessageParserEx.instance.Parse(builder, inputDialog.getValue());
lastFunction = builder.getFunction();
// AfterCall is skipped, so push BeforeCall to complete
if (msg.getType() == Type.BeforeCall)
queue.CompletePartialMessage(msg.getContextId());
}
}
// else defaults to continue BeforeCall and skip AfterCall

View File

@@ -0,0 +1,850 @@
/*
** 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 java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
public class CodeGen {
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;
}
assert msg.getArg2() == msg.getPixelFormat(); // TODO
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;
}
void CodeGenFrames(final DebugContext dbgCtx, int count) {
Context ctx = dbgCtx.frames.get(0).startContext.clone();
CodeGenSetup(ctx);
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.frames.get(i);
for (int j = 0; j < frame.calls.size(); j++) {
final MessageData msgData = frame.calls.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;
}
}
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();
}
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.calls.size(); i++) {
final MessageData msgData = frame.calls.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();
}
}

View File

@@ -66,6 +66,7 @@ class DebugContext {
msg = currentContext.processed;
currentContext.processed = null;
MessageData msgData = new MessageData(Display.getCurrent(), msg, oriMsg, currentContext);
msgData.attribs = currentContext.serverVertex.fetchedAttribs;
currentFrame.calls.add(msgData);
if (msg.getFunction() != Function.eglSwapBuffers)
return msgData;
@@ -107,6 +108,9 @@ public class Context implements Cloneable {
public Context clone() {
try {
Context copy = (Context) super.clone();
// FIXME: context sharing list clone
copy.shares = new ArrayList<Context>(1);
copy.shares.add(copy);
copy.serverVertex = serverVertex.clone();
copy.serverShader = serverShader.clone(copy);
copy.serverState = serverState.clone();
@@ -156,7 +160,7 @@ class ContextViewProvider extends LabelProvider implements ITreeContentProvider,
if (entry.obj != null) {
objStr = entry.obj.toString();
if (entry.obj instanceof Message)
objStr = MessageFormatter.Format((Message) entry.obj);
objStr = MessageFormatter.Format((Message) entry.obj, false);
}
return entry.name + " = " + objStr;
}
@@ -240,7 +244,7 @@ class ContextViewProvider extends LabelProvider implements ITreeContentProvider,
final Message val = context.serverState.integers.valueAt(i);
if (val != null)
children.add(GLEnum.valueOf(key).name() + " : " +
MessageFormatter.Format(val));
MessageFormatter.Format(val, false));
else
children.add(GLEnum.valueOf(key).name() + " : default");
}
@@ -252,7 +256,7 @@ class ContextViewProvider extends LabelProvider implements ITreeContentProvider,
children.add(Function.valueOf(key).name() + " : default");
else
children.add(Function.valueOf(key).name() + " : "
+ MessageFormatter.Format(msg));
+ MessageFormatter.Format(msg, false));
}
} else if (entry.obj instanceof SparseArray) {
SparseArray<?> sa = (SparseArray<?>) entry.obj;

View File

@@ -53,7 +53,7 @@ public enum GLEnum {
GL_STACK_OVERFLOW(0x0503),
GL_STACK_UNDERFLOW(0x0504),
GL_OUT_OF_MEMORY(0x0505),
GL_INVALID_FRAMEBUFFER_OPERATION_OES(0x0506),
GL_INVALID_FRAMEBUFFER_OPERATION(0x0506),
GL_EXP(0x0800),
GL_EXP2(0x0801),
GL_CW(0x0900),
@@ -207,7 +207,7 @@ public enum GLEnum {
GL_TEXTURE_ENV_MODE(0x2200),
GL_TEXTURE_ENV_COLOR(0x2201),
GL_TEXTURE_ENV(0x2300),
GL_TEXTURE_GEN_MODE_OES(0x2500),
GL_TEXTURE_GEN_MODE(0x2500),
GL_NEAREST(0x2600),
GL_LINEAR(0x2601),
GL_NEAREST_MIPMAP_NEAREST(0x2700),
@@ -240,26 +240,26 @@ public enum GLEnum {
GL_CONSTANT_ALPHA(0x8003),
GL_ONE_MINUS_CONSTANT_ALPHA(0x8004),
GL_BLEND_COLOR(0x8005),
GL_FUNC_ADD_OES(0x8006),
GL_FUNC_ADD(0x8006),
GL_MIN_EXT(0x8007),
GL_MAX_EXT(0x8008),
GL_BLEND_EQUATION_RGB_OES(0x8009),
GL_FUNC_SUBTRACT_OES(0x800A),
GL_FUNC_REVERSE_SUBTRACT_OES(0x800B),
GL_BLEND_EQUATION_RGB(0x8009),
GL_FUNC_SUBTRACT(0x800A),
GL_FUNC_REVERSE_SUBTRACT(0x800B),
GL_UNSIGNED_SHORT_4_4_4_4(0x8033),
GL_UNSIGNED_SHORT_5_5_5_1(0x8034),
GL_POLYGON_OFFSET_FILL(0x8037),
GL_POLYGON_OFFSET_FACTOR(0x8038),
GL_RESCALE_NORMAL(0x803A),
GL_RGB8_OES(0x8051),
GL_RGBA4_OES(0x8056),
GL_RGB5_A1_OES(0x8057),
GL_RGBA8_OES(0x8058),
GL_RGB8(0x8051),
GL_RGBA4(0x8056),
GL_RGB5_A1(0x8057),
GL_RGBA8(0x8058),
GL_TEXTURE_BINDING_2D(0x8069),
GL_TEXTURE_BINDING_3D_OES(0x806A),
GL_TEXTURE_3D_OES(0x806F),
GL_TEXTURE_WRAP_R_OES(0x8072),
GL_MAX_3D_TEXTURE_SIZE_OES(0x8073),
GL_TEXTURE_BINDING_3D(0x806A),
GL_TEXTURE_3D(0x806F),
GL_TEXTURE_WRAP_R(0x8072),
GL_MAX_3D_TEXTURE_SIZE(0x8073),
GL_VERTEX_ARRAY(0x8074),
GL_NORMAL_ARRAY(0x8075),
GL_COLOR_ARRAY(0x8076),
@@ -287,10 +287,10 @@ public enum GLEnum {
GL_SAMPLES(0x80A9),
GL_SAMPLE_COVERAGE_VALUE(0x80AA),
GL_SAMPLE_COVERAGE_INVERT(0x80AB),
GL_BLEND_DST_RGB_OES(0x80C8),
GL_BLEND_SRC_RGB_OES(0x80C9),
GL_BLEND_DST_ALPHA_OES(0x80CA),
GL_BLEND_SRC_ALPHA_OES(0x80CB),
GL_BLEND_DST_RGB(0x80C8),
GL_BLEND_SRC_RGB(0x80C9),
GL_BLEND_DST_ALPHA(0x80CA),
GL_BLEND_SRC_ALPHA(0x80CB),
GL_BGRA_EXT(0x80E1),
GL_POINT_SIZE_MIN(0x8126),
GL_POINT_SIZE_MAX(0x8127),
@@ -299,14 +299,14 @@ public enum GLEnum {
GL_CLAMP_TO_EDGE(0x812F),
GL_GENERATE_MIPMAP(0x8191),
GL_GENERATE_MIPMAP_HINT(0x8192),
GL_DEPTH_COMPONENT16_OES(0x81A5),
GL_DEPTH_COMPONENT24_OES(0x81A6),
GL_DEPTH_COMPONENT32_OES(0x81A7),
GL_DEPTH_COMPONENT16(0x81A5),
GL_DEPTH_COMPONENT24(0x81A6),
GL_DEPTH_COMPONENT32(0x81A7),
GL_UNSIGNED_SHORT_5_6_5(0x8363),
GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT(0x8365),
GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT(0x8366),
GL_UNSIGNED_INT_2_10_10_10_REV_EXT(0x8368),
GL_MIRRORED_REPEAT_OES(0x8370),
GL_MIRRORED_REPEAT(0x8370),
GL_COMPRESSED_RGB_S3TC_DXT1_EXT(0x83F0),
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT(0x83F1),
GL_ALIASED_POINT_SIZE_RANGE(0x846D),
@@ -347,30 +347,30 @@ public enum GLEnum {
GL_CLIENT_ACTIVE_TEXTURE(0x84E1),
GL_MAX_TEXTURE_UNITS(0x84E2),
GL_SUBTRACT(0x84E7),
GL_MAX_RENDERBUFFER_SIZE_OES(0x84E8),
GL_MAX_RENDERBUFFER_SIZE(0x84E8),
GL_ALL_COMPLETED_NV(0x84F2),
GL_FENCE_STATUS_NV(0x84F3),
GL_FENCE_CONDITION_NV(0x84F4),
GL_DEPTH_STENCIL_OES(0x84F9),
GL_UNSIGNED_INT_24_8_OES(0x84FA),
GL_DEPTH_STENCIL(0x84F9),
GL_UNSIGNED_INT_24_8(0x84FA),
GL_MAX_TEXTURE_LOD_BIAS_EXT(0x84FD),
GL_TEXTURE_MAX_ANISOTROPY_EXT(0x84FE),
GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT(0x84FF),
GL_TEXTURE_FILTER_CONTROL_EXT(0x8500),
GL_TEXTURE_LOD_BIAS_EXT(0x8501),
GL_INCR_WRAP_OES(0x8507),
GL_DECR_WRAP_OES(0x8508),
GL_NORMAL_MAP_OES(0x8511),
GL_REFLECTION_MAP_OES(0x8512),
GL_TEXTURE_CUBE_MAP_OES(0x8513),
GL_TEXTURE_BINDING_CUBE_MAP_OES(0x8514),
GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES(0x8515),
GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES(0x8516),
GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES(0x8517),
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES(0x8518),
GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES(0x8519),
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES(0x851A),
GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES(0x851C),
GL_INCR_WRAP(0x8507),
GL_DECR_WRAP(0x8508),
GL_NORMAL_MAP(0x8511),
GL_REFLECTION_MAP(0x8512),
GL_TEXTURE_CUBE_MAP(0x8513),
GL_TEXTURE_BINDING_CUBE_MAP(0x8514),
GL_TEXTURE_CUBE_MAP_POSITIVE_X(0x8515),
GL_TEXTURE_CUBE_MAP_NEGATIVE_X(0x8516),
GL_TEXTURE_CUBE_MAP_POSITIVE_Y(0x8517),
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y(0x8518),
GL_TEXTURE_CUBE_MAP_POSITIVE_Z(0x8519),
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z(0x851A),
GL_MAX_CUBE_MAP_TEXTURE_SIZE(0x851C),
GL_COMBINE(0x8570),
GL_COMBINE_RGB(0x8571),
GL_COMBINE_ALPHA(0x8572),
@@ -392,7 +392,7 @@ public enum GLEnum {
GL_OPERAND0_ALPHA(0x8598),
GL_OPERAND1_ALPHA(0x8599),
GL_OPERAND2_ALPHA(0x859A),
GL_VERTEX_ARRAY_BINDING_OES(0x85B5),
GL_VERTEX_ARRAY_BINDING(0x85B5),
GL_VERTEX_ATTRIB_ARRAY_ENABLED(0x8622),
GL_VERTEX_ATTRIB_ARRAY_SIZE(0x8623),
GL_VERTEX_ATTRIB_ARRAY_STRIDE(0x8624),
@@ -401,39 +401,39 @@ public enum GLEnum {
GL_VERTEX_ATTRIB_ARRAY_POINTER(0x8645),
GL_NUM_COMPRESSED_TEXTURE_FORMATS(0x86A2),
GL_COMPRESSED_TEXTURE_FORMATS(0x86A3),
GL_MAX_VERTEX_UNITS_OES(0x86A4),
GL_WEIGHT_ARRAY_TYPE_OES(0x86A9),
GL_WEIGHT_ARRAY_STRIDE_OES(0x86AA),
GL_WEIGHT_ARRAY_SIZE_OES(0x86AB),
GL_WEIGHT_ARRAY_POINTER_OES(0x86AC),
GL_WEIGHT_ARRAY_OES(0x86AD),
GL_MAX_VERTEX_UNITS(0x86A4),
GL_WEIGHT_ARRAY_TYPE(0x86A9),
GL_WEIGHT_ARRAY_STRIDE(0x86AA),
GL_WEIGHT_ARRAY_SIZE(0x86AB),
GL_WEIGHT_ARRAY_POINTER(0x86AC),
GL_WEIGHT_ARRAY(0x86AD),
GL_DOT3_RGB(0x86AE),
GL_DOT3_RGBA(0x86AF),
GL_Z400_BINARY_AMD(0x8740),
GL_PROGRAM_BINARY_LENGTH_OES(0x8741),
GL_PROGRAM_BINARY_LENGTH(0x8741),
GL_BUFFER_SIZE(0x8764),
GL_BUFFER_USAGE(0x8765),
GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD(0x87EE),
GL_3DC_X_AMD(0x87F9),
GL_3DC_XY_AMD(0x87FA),
GL_NUM_PROGRAM_BINARY_FORMATS_OES(0x87FE),
GL_PROGRAM_BINARY_FORMATS_OES(0x87FF),
GL_NUM_PROGRAM_BINARY_FORMATS(0x87FE),
GL_PROGRAM_BINARY_FORMATS(0x87FF),
GL_STENCIL_BACK_FUNC(0x8800),
GL_STENCIL_BACK_FAIL(0x8801),
GL_STENCIL_BACK_PASS_DEPTH_FAIL(0x8802),
GL_STENCIL_BACK_PASS_DEPTH_PASS(0x8803),
GL_WRITEONLY_RENDERING_QCOM(0x8823),
GL_BLEND_EQUATION_ALPHA_OES(0x883D),
GL_MATRIX_PALETTE_OES(0x8840),
GL_MAX_PALETTE_MATRICES_OES(0x8842),
GL_CURRENT_PALETTE_MATRIX_OES(0x8843),
GL_MATRIX_INDEX_ARRAY_OES(0x8844),
GL_MATRIX_INDEX_ARRAY_SIZE_OES(0x8846),
GL_MATRIX_INDEX_ARRAY_TYPE_OES(0x8847),
GL_MATRIX_INDEX_ARRAY_STRIDE_OES(0x8848),
GL_MATRIX_INDEX_ARRAY_POINTER_OES(0x8849),
GL_POINT_SPRITE_OES(0x8861),
GL_COORD_REPLACE_OES(0x8862),
GL_BLEND_EQUATION_ALPHA(0x883D),
GL_MATRIX_PALETTE(0x8840),
GL_MAX_PALETTE_MATRICES(0x8842),
GL_CURRENT_PALETTE_MATRIX(0x8843),
GL_MATRIX_INDEX_ARRAY(0x8844),
GL_MATRIX_INDEX_ARRAY_SIZE(0x8846),
GL_MATRIX_INDEX_ARRAY_TYPE(0x8847),
GL_MATRIX_INDEX_ARRAY_STRIDE(0x8848),
GL_MATRIX_INDEX_ARRAY_POINTER(0x8849),
GL_POINT_SPRITE(0x8861),
GL_COORD_REPLACE(0x8862),
GL_MAX_VERTEX_ATTRIBS(0x8869),
GL_VERTEX_ATTRIB_ARRAY_NORMALIZED(0x886A),
GL_MAX_TEXTURE_IMAGE_UNITS(0x8872),
@@ -445,22 +445,22 @@ public enum GLEnum {
GL_NORMAL_ARRAY_BUFFER_BINDING(0x8897),
GL_COLOR_ARRAY_BUFFER_BINDING(0x8898),
GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING(0x889A),
GL_WEIGHT_ARRAY_BUFFER_BINDING_OES(0x889E),
GL_WEIGHT_ARRAY_BUFFER_BINDING(0x889E),
GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING(0x889F),
GL_WRITE_ONLY_OES(0x88B9),
GL_BUFFER_ACCESS_OES(0x88BB),
GL_BUFFER_MAPPED_OES(0x88BC),
GL_BUFFER_MAP_POINTER_OES(0x88BD),
GL_WRITE_ONLY(0x88B9),
GL_BUFFER_ACCESS(0x88BB),
GL_BUFFER_MAPPED(0x88BC),
GL_BUFFER_MAP_POINTER(0x88BD),
GL_STREAM_DRAW(0x88E0),
GL_STATIC_DRAW(0x88E4),
GL_DYNAMIC_DRAW(0x88E8),
GL_DEPTH24_STENCIL8_OES(0x88F0),
GL_POINT_SIZE_ARRAY_TYPE_OES(0x898A),
GL_POINT_SIZE_ARRAY_STRIDE_OES(0x898B),
GL_POINT_SIZE_ARRAY_POINTER_OES(0x898C),
GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES(0x898D),
GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES(0x898E),
GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES(0x898F),
GL_DEPTH24_STENCIL8(0x88F0),
GL_POINT_SIZE_ARRAY_TYPE(0x898A),
GL_POINT_SIZE_ARRAY_STRIDE(0x898B),
GL_POINT_SIZE_ARRAY_POINTER(0x898C),
GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS(0x898D),
GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS(0x898E),
GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS(0x898F),
GL_FRAGMENT_SHADER(0x8B30),
GL_VERTEX_SHADER(0x8B31),
GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS(0x8B4C),
@@ -480,7 +480,7 @@ public enum GLEnum {
GL_FLOAT_MAT3(0x8B5B),
GL_FLOAT_MAT4(0x8B5C),
GL_SAMPLER_2D(0x8B5E),
GL_SAMPLER_3D_OES(0x8B5F),
GL_SAMPLER_3D(0x8B5F),
GL_SAMPLER_CUBE(0x8B60),
GL_DELETE_STATUS(0x8B80),
GL_COMPILE_STATUS(0x8B81),
@@ -493,25 +493,25 @@ public enum GLEnum {
GL_SHADER_SOURCE_LENGTH(0x8B88),
GL_ACTIVE_ATTRIBUTES(0x8B89),
GL_ACTIVE_ATTRIBUTE_MAX_LENGTH(0x8B8A),
GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES(0x8B8B),
GL_FRAGMENT_SHADER_DERIVATIVE_HINT(0x8B8B),
GL_SHADING_LANGUAGE_VERSION(0x8B8C),
GL_CURRENT_PROGRAM(0x8B8D),
GL_PALETTE4_RGB8_OES(0x8B90),
GL_PALETTE4_RGBA8_OES(0x8B91),
GL_PALETTE4_R5_G6_B5_OES(0x8B92),
GL_PALETTE4_RGBA4_OES(0x8B93),
GL_PALETTE4_RGB5_A1_OES(0x8B94),
GL_PALETTE8_RGB8_OES(0x8B95),
GL_PALETTE8_RGBA8_OES(0x8B96),
GL_PALETTE8_R5_G6_B5_OES(0x8B97),
GL_PALETTE8_RGBA4_OES(0x8B98),
GL_PALETTE8_RGB5_A1_OES(0x8B99),
GL_IMPLEMENTATION_COLOR_READ_TYPE_OES(0x8B9A),
GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES(0x8B9B),
GL_POINT_SIZE_ARRAY_OES(0x8B9C),
GL_TEXTURE_CROP_RECT_OES(0x8B9D),
GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES(0x8B9E),
GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES(0x8B9F),
GL_PALETTE4_RGB8(0x8B90),
GL_PALETTE4_RGBA8(0x8B91),
GL_PALETTE4_R5_G6_B5(0x8B92),
GL_PALETTE4_RGBA4(0x8B93),
GL_PALETTE4_RGB5_A1(0x8B94),
GL_PALETTE8_RGB8(0x8B95),
GL_PALETTE8_RGBA8(0x8B96),
GL_PALETTE8_R5_G6_B5(0x8B97),
GL_PALETTE8_RGBA4(0x8B98),
GL_PALETTE8_RGB5_A1(0x8B99),
GL_IMPLEMENTATION_COLOR_READ_TYPE(0x8B9A),
GL_IMPLEMENTATION_COLOR_READ_FORMAT(0x8B9B),
GL_POINT_SIZE_ARRAY(0x8B9C),
GL_TEXTURE_CROP_RECT(0x8B9D),
GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING(0x8B9E),
GL_POINT_SIZE_ARRAY_BUFFER_BINDING(0x8B9F),
GL_COUNTER_TYPE_AMD(0x8BC0),
GL_COUNTER_RANGE_AMD(0x8BC1),
GL_UNSIGNED_INT64_AMD(0x8BC2),
@@ -546,52 +546,52 @@ public enum GLEnum {
GL_STENCIL_BACK_REF(0x8CA3),
GL_STENCIL_BACK_VALUE_MASK(0x8CA4),
GL_STENCIL_BACK_WRITEMASK(0x8CA5),
GL_FRAMEBUFFER_BINDING_OES(0x8CA6),
GL_RENDERBUFFER_BINDING_OES(0x8CA7),
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES(0x8CD0),
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES(0x8CD1),
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES(0x8CD2),
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES(0x8CD3),
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES(0x8CD4),
GL_FRAMEBUFFER_COMPLETE_OES(0x8CD5),
GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES(0x8CD6),
GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES(0x8CD7),
GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES(0x8CD9),
GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES(0x8CDA),
GL_FRAMEBUFFER_UNSUPPORTED_OES(0x8CDD),
GL_COLOR_ATTACHMENT0_OES(0x8CE0),
GL_DEPTH_ATTACHMENT_OES(0x8D00),
GL_STENCIL_ATTACHMENT_OES(0x8D20),
GL_FRAMEBUFFER_OES(0x8D40),
GL_RENDERBUFFER_OES(0x8D41),
GL_RENDERBUFFER_WIDTH_OES(0x8D42),
GL_RENDERBUFFER_HEIGHT_OES(0x8D43),
GL_RENDERBUFFER_INTERNAL_FORMAT_OES(0x8D44),
GL_STENCIL_INDEX1_OES(0x8D46),
GL_STENCIL_INDEX4_OES(0x8D47),
GL_STENCIL_INDEX8_OES(0x8D48),
GL_RENDERBUFFER_RED_SIZE_OES(0x8D50),
GL_RENDERBUFFER_GREEN_SIZE_OES(0x8D51),
GL_RENDERBUFFER_BLUE_SIZE_OES(0x8D52),
GL_RENDERBUFFER_ALPHA_SIZE_OES(0x8D53),
GL_RENDERBUFFER_DEPTH_SIZE_OES(0x8D54),
GL_RENDERBUFFER_STENCIL_SIZE_OES(0x8D55),
GL_TEXTURE_GEN_STR_OES(0x8D60),
GL_HALF_FLOAT_OES(0x8D61),
GL_RGB565_OES(0x8D62),
GL_ETC1_RGB8_OES(0x8D64),
GL_TEXTURE_EXTERNAL_OES(0x8D65),
GL_SAMPLER_EXTERNAL_OES(0x8D66),
GL_TEXTURE_BINDING_EXTERNAL_OES(0x8D67),
GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES(0x8D68),
GL_FRAMEBUFFER_BINDING(0x8CA6),
GL_RENDERBUFFER_BINDING(0x8CA7),
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE(0x8CD0),
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME(0x8CD1),
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL(0x8CD2),
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE(0x8CD3),
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET(0x8CD4),
GL_FRAMEBUFFER_COMPLETE(0x8CD5),
GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT(0x8CD6),
GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT(0x8CD7),
GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS(0x8CD9),
GL_FRAMEBUFFER_INCOMPLETE_FORMATS(0x8CDA),
GL_FRAMEBUFFER_UNSUPPORTED(0x8CDD),
GL_COLOR_ATTACHMENT0(0x8CE0),
GL_DEPTH_ATTACHMENT(0x8D00),
GL_STENCIL_ATTACHMENT(0x8D20),
GL_FRAMEBUFFER(0x8D40),
GL_RENDERBUFFER(0x8D41),
GL_RENDERBUFFER_WIDTH(0x8D42),
GL_RENDERBUFFER_HEIGHT(0x8D43),
GL_RENDERBUFFER_INTERNAL_FORMAT(0x8D44),
GL_STENCIL_INDEX1(0x8D46),
GL_STENCIL_INDEX4(0x8D47),
GL_STENCIL_INDEX8(0x8D48),
GL_RENDERBUFFER_RED_SIZE(0x8D50),
GL_RENDERBUFFER_GREEN_SIZE(0x8D51),
GL_RENDERBUFFER_BLUE_SIZE(0x8D52),
GL_RENDERBUFFER_ALPHA_SIZE(0x8D53),
GL_RENDERBUFFER_DEPTH_SIZE(0x8D54),
GL_RENDERBUFFER_STENCIL_SIZE(0x8D55),
GL_TEXTURE_GEN_STR(0x8D60),
GL_HALF_FLOAT(0x8D61),
GL_RGB565(0x8D62),
GL_ETC1_RGB8(0x8D64),
GL_TEXTURE_EXTERNAL(0x8D65),
GL_SAMPLER_EXTERNAL(0x8D66),
GL_TEXTURE_BINDING_EXTERNAL(0x8D67),
GL_REQUIRED_TEXTURE_IMAGE_UNITS(0x8D68),
GL_LOW_FLOAT(0x8DF0),
GL_MEDIUM_FLOAT(0x8DF1),
GL_HIGH_FLOAT(0x8DF2),
GL_LOW_INT(0x8DF3),
GL_MEDIUM_INT(0x8DF4),
GL_HIGH_INT(0x8DF5),
GL_UNSIGNED_INT_10_10_10_2_OES(0x8DF6),
GL_INT_10_10_10_2_OES(0x8DF7),
GL_UNSIGNED_INT_10_10_10_2(0x8DF6),
GL_INT_10_10_10_2(0x8DF7),
GL_SHADER_BINARY_FORMATS(0x8DF8),
GL_NUM_SHADER_BINARY_FORMATS(0x8DF9),
GL_SHADER_COMPILER(0x8DFA),

View File

@@ -172,7 +172,9 @@ public class GLServerShader implements Cloneable {
// void API_ENTRY(glAttachShader)(GLuint program, GLuint shader)
void glAttachShader(final Message msg) {
GLProgram program = GetProgram(msg.getArg0());
assert program != null;
GLShader shader = GetShader(msg.getArg1());
assert program != null;
if (GLEnum.GL_VERTEX_SHADER == shader.type)
program.vert = shader.name;
else
@@ -229,7 +231,7 @@ public class GLServerShader implements Cloneable {
program.frag = 0;
else
return;
shader.programs.remove(program.name);
shader.programs.remove(new Integer(program.name));
if (shader.delete && shader.programs.size() == 0)
shaders.remove(shader.name);
}
@@ -251,7 +253,7 @@ public class GLServerShader implements Cloneable {
for (Context ctx : context.shares)
if (ctx.serverShader.current == oldCurrent)
return;
oldCurrent.context.programs.remove(oldCurrent.name);
oldCurrent.context.programs.remove(new Integer(oldCurrent.name));
}
}
}

View File

@@ -50,7 +50,7 @@ public class GLServerState implements Cloneable {
GLServerState(final Context context) {
this.context = context;
enableDisables = new SparseIntArray(9);
enableDisables = new SparseIntArray();
enableDisables.put(GLEnum.GL_BLEND.value, 0);
enableDisables.put(GLEnum.GL_DITHER.value, 1);
enableDisables.put(GLEnum.GL_DEPTH_TEST.value, 0);
@@ -60,6 +60,7 @@ public class GLServerState implements Cloneable {
enableDisables.put(GLEnum.GL_SAMPLE_ALPHA_TO_COVERAGE.value, 0);
enableDisables.put(GLEnum.GL_POLYGON_OFFSET_FILL.value, 0);
enableDisables.put(GLEnum.GL_CULL_FACE.value, 0);
// enableDisables.put(GLEnum.GL_TEXTURE_2D.value, 1);
lastSetter = new SparseArray<Message>();
lastSetter.put(Function.glBlendColor.getNumber(), null);
@@ -173,7 +174,11 @@ public class GLServerState implements Cloneable {
boolean EnableDisable(boolean enable, final Message msg) {
int index = enableDisables.indexOfKey(msg.getArg0());
assert index >= 0;
if (index < 0) {
System.out.print("invalid glDisable/Enable: ");
System.out.println(MessageFormatter.Format(msg, false));
return true;
}
if ((enableDisables.valueAt(index) != 0) == enable)
return true; // TODO: redundant
enableDisables.put(msg.getArg0(), enable ? 1 : 0);

View File

@@ -139,12 +139,12 @@ public class GLServerTexture implements Cloneable {
if (tex2D != null)
return tex2D.ProcessMessage(msg);
return true;
case GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES:
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
if (texCube != null)
return texCube.ProcessMessage(msg);
return true;
@@ -159,7 +159,7 @@ public class GLServerTexture implements Cloneable {
if (tex2D != null && tex2D.name == name)
BindTexture(GLEnum.GL_TEXTURE_2D.value, 0);
if (texCube != null && texCube.name == name)
BindTexture(GLEnum.GL_TEXTURE_CUBE_MAP_OES.value, 0);
BindTexture(GLEnum.GL_TEXTURE_CUBE_MAP.value, 0);
if (name != 0)
textures.remove(name);
}
@@ -168,7 +168,7 @@ public class GLServerTexture implements Cloneable {
case glGenerateMipmap:
if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_TEXTURE_2D && tex2D != null)
return tex2D.ProcessMessage(msg);
else if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_TEXTURE_CUBE_MAP_OES
else if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_TEXTURE_CUBE_MAP
&& texCube != null)
return texCube.ProcessMessage(msg);
return true;
@@ -191,11 +191,11 @@ public class GLServerTexture implements Cloneable {
GLEnum.GL_TEXTURE_2D));
if (index >= 0 && index < tmu2D.length)
tmu2D[index] = name;
} else if (GLEnum.valueOf(target) == GLEnum.GL_TEXTURE_CUBE_MAP_OES) {
} else if (GLEnum.valueOf(target) == GLEnum.GL_TEXTURE_CUBE_MAP) {
texCube = textures.get(name);
if (name != 0 && texCube == null)
textures.put(name, texCube = new GLTexture(name,
GLEnum.GL_TEXTURE_CUBE_MAP_OES));
GLEnum.GL_TEXTURE_CUBE_MAP));
if (index >= 0 && index < tmu2D.length)
tmu2D[index] = name;
} else
@@ -207,7 +207,7 @@ public class GLServerTexture implements Cloneable {
GLTexture tex = null;
if (GLEnum.valueOf(target) == GLEnum.GL_TEXTURE_2D)
tex = tex2D;
else if (GLEnum.valueOf(target) == GLEnum.GL_TEXTURE_CUBE_MAP_OES)
else if (GLEnum.valueOf(target) == GLEnum.GL_TEXTURE_CUBE_MAP)
tex = texCube;
if (tex == null)
return true;

View File

@@ -25,6 +25,7 @@ class GLBuffer implements Cloneable {
public final int name;
public GLEnum usage;
public GLEnum target;
/** in SampleView.targetByteOrder */
public ByteBuffer data;
public GLBuffer(final int name) {
@@ -81,6 +82,8 @@ public class GLServerVertex implements Cloneable {
public float defaultAttribs[][];
int maxAttrib;
ByteBuffer[] fetchedAttribs;
public GLServerVertex() {
buffers.append(0, null);
// TODO: get MAX_VERTEX_ATTRIBS from server
@@ -215,9 +218,11 @@ public class GLServerVertex implements Cloneable {
if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ARRAY_BUFFER) {
attribBuffer.usage = GLEnum.valueOf(msg.getArg3());
attribBuffer.data = msg.getData().asReadOnlyByteBuffer();
attribBuffer.data.order(SampleView.targetByteOrder);
} else if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ELEMENT_ARRAY_BUFFER) {
indexBuffer.usage = GLEnum.valueOf(msg.getArg3());
indexBuffer.data = msg.getData().asReadOnlyByteBuffer();
indexBuffer.data.order(SampleView.targetByteOrder);
} else
assert false;
}
@@ -228,6 +233,7 @@ public class GLServerVertex implements Cloneable {
if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ARRAY_BUFFER) {
if (attribBuffer.data.isReadOnly()) {
ByteBuffer buffer = ByteBuffer.allocate(attribBuffer.data.capacity());
buffer.order(SampleView.targetByteOrder);
buffer.put(attribBuffer.data);
attribBuffer.data = buffer;
}
@@ -236,6 +242,7 @@ public class GLServerVertex implements Cloneable {
} else if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ELEMENT_ARRAY_BUFFER) {
if (indexBuffer.data.isReadOnly()) {
ByteBuffer buffer = ByteBuffer.allocate(indexBuffer.data.capacity());
buffer.order(SampleView.targetByteOrder);
buffer.put(indexBuffer.data);
indexBuffer.data = buffer;
}
@@ -268,6 +275,7 @@ public class GLServerVertex implements Cloneable {
// void glDisableVertexAttribArray(GLuint index)
public void glDisableVertexAttribArray(Message msg) {
if (msg.getArg0() >= 0 && msg.getArg0() < attribPointers.length)
attribPointers[msg.getArg0()].enabled = false;
}
@@ -314,19 +322,49 @@ public class GLServerVertex implements Cloneable {
return 0;
}
static int TypeSize(final GLEnum type) {
switch (type) {
case GL_FLOAT:
case GL_UNSIGNED_INT:
case GL_INT:
case GL_FIXED:
return 4;
case GL_UNSIGNED_SHORT:
case GL_SHORT:
return 2;
case GL_UNSIGNED_BYTE:
case GL_BYTE:
return 1;
default:
assert false;
return 0;
}
}
void Fetch(int index, final ByteBuffer nonVBO, final ByteBuffer dst) {
for (int i = 0; i < maxAttrib; i++) {
final GLAttribPointer attrib = attribPointers[i];
int size = 0;
if (attrib.enabled)
if (attrib.enabled) {
size = attrib.size;
final ByteBuffer fetched = fetchedAttribs[i];
final byte[] element = new byte[TypeSize(attrib.type) * size];
if (null != attrib.buffer) {
final ByteBuffer src = attrib.buffer.data;
src.position(attrib.ptr + i * attrib.stride);
src.position(attrib.ptr + index * attrib.stride);
src.get(element);
src.position(attrib.ptr + index * attrib.stride);
for (int j = 0; j < size; j++)
dst.putFloat(FetchConvert(src, attrib.type, attrib.normalized));
} else
} else {
final int position = nonVBO.position();
nonVBO.get(element);
nonVBO.position(position);
for (int j = 0; j < size; j++)
dst.putFloat(FetchConvert(nonVBO, attrib.type, attrib.normalized));
}
fetched.put(element);
}
if (size < 1)
dst.putFloat(defaultAttribs[i][0]);
if (size < 2)
@@ -341,6 +379,13 @@ public class GLServerVertex implements Cloneable {
// void glDrawArrays(GLenum mode, GLint first, GLsizei count)
public Message glDrawArrays(Message msg) {
maxAttrib = msg.getArg7();
fetchedAttribs = new ByteBuffer[maxAttrib];
for (int i = 0; i < maxAttrib; i++) {
if (!attribPointers[i].enabled)
continue;
fetchedAttribs[i] = ByteBuffer.allocate(TypeSize(attribPointers[i].type)
* attribPointers[i].size * msg.getArg2());
}
final int first = msg.getArg1(), count = msg.getArg2();
final ByteBuffer buffer = ByteBuffer.allocate(4 * 4 * maxAttrib * count);
ByteBuffer arrays = null;
@@ -352,6 +397,11 @@ public class GLServerVertex implements Cloneable {
for (int i = first; i < first + count; i++)
Fetch(i, arrays, buffer);
assert null == arrays || arrays.remaining() == 0;
for (int i = 0; i < maxAttrib; i++) {
if (!attribPointers[i].enabled)
continue;
assert fetchedAttribs[i].remaining() == 0;
}
buffer.rewind();
return msg.toBuilder().setData(com.google.protobuf.ByteString.copyFrom(buffer))
.setArg8(GLEnum.GL_FLOAT.value).build();
@@ -361,6 +411,13 @@ public class GLServerVertex implements Cloneable {
// GLvoid* indices)
public Message glDrawElements(Message msg) {
maxAttrib = msg.getArg7();
fetchedAttribs = new ByteBuffer[maxAttrib];
for (int i = 0; i < maxAttrib; i++) {
if (!attribPointers[i].enabled)
continue;
fetchedAttribs[i] = ByteBuffer.allocate(TypeSize(attribPointers[i].type)
* attribPointers[i].size * msg.getArg1());
}
final int count = msg.getArg1();
final GLEnum type = GLEnum.valueOf(msg.getArg2());
final ByteBuffer buffer = ByteBuffer.allocate(4 * 4 * maxAttrib * count);
@@ -386,6 +443,11 @@ public class GLServerVertex implements Cloneable {
else
assert false;
assert null == arrays || arrays.remaining() == 0;
for (int i = 0; i < maxAttrib; i++) {
if (!attribPointers[i].enabled)
continue;
assert fetchedAttribs[i].remaining() == 0;
}
buffer.rewind();
return msg.toBuilder().setData(com.google.protobuf.ByteString.copyFrom(buffer))
.setArg8(GLEnum.GL_FLOAT.value).build();
@@ -393,6 +455,7 @@ public class GLServerVertex implements Cloneable {
// void glEnableVertexAttribArray(GLuint index)
public void glEnableVertexAttribArray(Message msg) {
if (msg.getArg0() >= 0 && msg.getArg0() < attribPointers.length)
attribPointers[msg.getArg0()].enabled = true;
}
@@ -418,7 +481,7 @@ public class GLServerVertex implements Cloneable {
attrib.normalized = msg.getArg3() != 0;
attrib.stride = msg.getArg4();
if (0 == attrib.stride)
attrib.stride = attrib.size * 4;
attrib.stride = attrib.size * TypeSize(attrib.type);
attrib.ptr = msg.getArg5();
attrib.buffer = attribBuffer;
}

View File

@@ -25,6 +25,8 @@ import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import java.nio.ByteBuffer;
public class MessageData {
public final Message msg, oriMsg;
public Image image; // texture
@@ -36,6 +38,8 @@ public class MessageData {
public GLEnum dataType; // could be float, int; mainly for formatting use
Context context; // the context before this call
ByteBuffer[] attribs = null;
public MessageData(final Device device, final Message msg, final Message oriMsg,
final Context context) {
this.msg = msg;
@@ -67,7 +71,7 @@ public class MessageData {
columns[2] = "[AfterGeneratedCall] ";
else
assert msg.getType() == Type.AfterCall;
columns[2] += MessageFormatter.Format(msg);
columns[2] += MessageFormatter.Format(msg, false);
builder.append(columns[2]);
switch (function) {
case glDrawArrays: // msg was modified by GLServerVertex

View File

@@ -31,15 +31,15 @@ public abstract class MessageParser {
String[] GetList()
{
assert args.charAt(0) == '[';
assert args.charAt(0) == '{';
String arg = args;
args = args.substring(args.indexOf(']') + 1);
args = args.substring(args.lastIndexOf('}') + 1);
int comma = args.indexOf(',');
if (comma >= 0)
args = args.substring(comma + 1).trim();
else
args = null;
arg = arg.substring(1, arg.indexOf(']')).trim();
arg = arg.substring(1, arg.lastIndexOf('}')).trim();
return arg.split(",");
}

View File

@@ -23,14 +23,18 @@ import com.android.glesv2debugger.DebuggerMessage.Message.Type;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.Socket;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.HashMap;
public class MessageQueue implements Runnable {
boolean running = false;
private ByteOrder byteOrder;
private FileInputStream file; // if null, create and use socket
Thread thread = null;
ArrayList<Message> complete = new ArrayList<Message>(); // need synchronized
ArrayList<Message> commands = new ArrayList<Message>(); // need synchronized
@@ -40,10 +44,12 @@ public class MessageQueue implements Runnable {
this.sampleView = sampleView;
}
public void Start() {
public void Start(final ByteOrder byteOrder, final FileInputStream file) {
if (running)
return;
running = true;
this.byteOrder = byteOrder;
this.file = file;
thread = new Thread(this);
thread.start();
}
@@ -84,8 +90,10 @@ public class MessageQueue implements Runnable {
@Override
public void run() {
Socket socket = new Socket();
Socket socket = null;
if (file == null)
try {
socket = new Socket();
socket.connect(new java.net.InetSocketAddress("127.0.0.1", Integer
.parseInt(sampleView.actionPort.getText())));
dis = new DataInputStream(socket.getInputStream());
@@ -94,8 +102,20 @@ public class MessageQueue implements Runnable {
running = false;
Error(e);
}
else
dis = new DataInputStream(file);
while (running) {
try {
if (file != null && file.available() == 0) {
running = false;
break;
}
} catch (IOException e1) {
e1.printStackTrace();
assert false;
}
Message msg = null;
if (incoming.size() > 0) { // find queued incoming
for (ArrayList<Message> messages : incoming.values())
@@ -116,11 +136,15 @@ public class MessageQueue implements Runnable {
}
try {
if (socket != null)
socket.close();
else
file.close();
} catch (IOException e) {
Error(e);
running = false;
}
}
private void PutMessage(final Message msg) {
@@ -214,6 +238,8 @@ public class MessageQueue implements Runnable {
int len = 0;
try {
len = dis.readInt();
if (byteOrder == ByteOrder.LITTLE_ENDIAN)
len = Integer.reverseBytes(len); // readInt reads BIT_ENDIAN
} catch (EOFException e) {
Error(new Exception("EOF"));
}
@@ -241,12 +267,16 @@ public class MessageQueue implements Runnable {
throws IOException {
assert message.getFunction() != Function.NEG;
final byte[] data = message.toByteArray();
if (byteOrder == ByteOrder.BIG_ENDIAN)
dos.writeInt(data.length);
else
dos.writeInt(Integer.reverseBytes(data.length));
dos.write(data);
}
private void ProcessMessage(final DataOutputStream dos, final Message msg) throws IOException {
if (msg.getExpectResponse()) {
assert file == null; // file cannot be interactive mode
if (sampleView.shaderEditor.ProcessMessage(this, msg))
return;
else if (sampleView.breakpointOption.ProcessMessage(this, msg))

View File

@@ -28,6 +28,7 @@ import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ISelectionChangedListener;
@@ -56,6 +57,7 @@ import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.ScrollBar;
@@ -71,6 +73,8 @@ import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
@@ -204,7 +208,7 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
public SampleView() {
MessageParserEx messageParserEx = new MessageParserEx();
Message.Builder builder = Message.newBuilder();
messageParserEx.Parse(builder, "glUniform4fv(1,2,[0,1,2,3,4,5,6,7])");
messageParserEx.Parse(builder, "glUniform4fv(1,2,{0,1,2,3,4,5,6,7})");
messageParserEx
.Parse(builder,
"void glShaderSource(shader=4, count=1, string=\"dksjafhskjahourehghskjg\", length=0x0)");
@@ -394,7 +398,6 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
}
});
makeActions();
hookContextMenu();
hookSelectionChanged();
contributeToActionBars();
@@ -434,7 +437,24 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
}
private void fillLocalToolBar(final IToolBarManager manager) {
actionConnect = new Action("Connect", Action.AS_PUSH_BUTTON) {
@Override
public void run() {
ConnectDisconnect();
}
};
manager.add(actionConnect);
manager.add(new Action("Open File", Action.AS_PUSH_BUTTON)
{
@Override
public void run()
{
if (!running)
OpenFile();
}
});
final Shell shell = this.getViewSite().getShell();
actionAutoScroll = new Action("Auto Scroll", Action.AS_CHECK_BOX) {
@Override
@@ -507,8 +527,7 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
actContext = new Action("Context: 0x", Action.AS_DROP_DOWN_MENU) {
@Override
public void run()
{
public void run() {
if (debugContexts.size() < 2)
return;
final String idStr = this.getText().substring(
@@ -527,9 +546,7 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
{
@Override
public void run() {
org.eclipse.jface.dialogs.InputDialog dialog = new org.eclipse.jface.dialogs.InputDialog(
shell, "Port",
"Debugger port",
InputDialog dialog = new InputDialog(shell, "Port", "Debugger port",
actionPort.getText(), null);
if (Window.OK == dialog.open()) {
actionPort.setText(dialog.getValue());
@@ -538,21 +555,63 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
}
};
manager.add(actionPort);
manager.add(new Action("CodeGen Frame", Action.AS_PUSH_BUTTON)
{
@Override
public void run()
{
if (current != null)
new CodeGen().CodeGenFrame((Frame) viewer.getInput());
}
});
manager.add(new Action("CodeGen Frames", Action.AS_PUSH_BUTTON)
{
@Override
public void run()
{
if (current != null)
new CodeGen().CodeGenFrames(current, frameNum.getSelection() + 1);
}
});
}
private void OpenFile() {
FileDialog dialog = new FileDialog(getSite().getShell(), SWT.OPEN);
dialog.setText("Open");
dialog.setFilterExtensions(new String[] {
"*.gles2dbg"
});
String filePath = dialog.open();
if (filePath == null)
return;
FileInputStream file = null;
try {
file = new FileInputStream(filePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
return;
}
running = true;
messageQueue.Start(targetByteOrder, file);
thread = new Thread(this);
thread.start();
actionConnect.setText("Disconnect");
getViewSite().getActionBars().getToolBarManager().update(true);
}
private void ConnectDisconnect() {
if (!running) {
running = true;
messageQueue.Start();
messageQueue.Start(targetByteOrder, null);
thread = new Thread(this);
thread.start();
actionConnect.setText("Disconnect");
actionConnect.setToolTipText("Disconnect from debuggee");
} else {
running = false;
messageQueue.Stop();
actionConnect.setText("Connect");
actionConnect.setToolTipText("Connect to debuggee");
}
this.getSite().getShell().getDisplay().syncExec(new Runnable() {
@Override
@@ -562,17 +621,6 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
});
}
private void makeActions() {
actionConnect = new Action() {
@Override
public void run() {
ConnectDisconnect();
}
};
actionConnect.setText("Connect");
actionConnect.setToolTipText("Connect to debuggee");
}
void MessageDataSelected(final MessageData msgData) {
if (null == msgData)
return;
@@ -626,7 +674,6 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
"GL ES 2.0 Debugger Client", e.getMessage());
}
});
}
/**
@@ -656,10 +703,9 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
boolean shaderEditorUpdate = false, currentUpdate = false;
while (running) {
if (!messageQueue.IsRunning())
break;
final Message oriMsg = messageQueue.RemoveCompleteMessage(0);
if (oriMsg == null && !messageQueue.IsRunning())
break;
if (newMessages > 60 || (newMessages > 0 && null == oriMsg)) {
newMessages = 0;
@@ -669,11 +715,14 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
public void run() {
if (current == null)
ChangeContext(debugContexts.valueAt(0));
else
else if (frameNum.getSelection() == current.frames.size() - 1)
{
viewer.refresh(false);
frameNum.setMaximum(current.frames.size());
if (actionAutoScroll.isChecked())
viewer.getList().setSelection(viewer.getList().getItemCount() - 1);
viewer.getList().setSelection(
viewer.getList().getItemCount() - 1);
}
frameNum.setMaximum(current.frames.size());
}
});
currentUpdate = false;

View File

@@ -253,9 +253,9 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend
ExchangeMessage(contextId, queue, "glCompileShader(%d)", shader.name);
// the 0, "" and [0] are dummies for the parser
// the 0, "" and {0} are dummies for the parser
Message rcv = ExchangeMessage(contextId, queue,
"glGetShaderiv(%d, GL_COMPILE_STATUS, [0])", shader.name);
"glGetShaderiv(%d, GL_COMPILE_STATUS, {0})", shader.name);
assert rcv.hasData();
if (rcv.getData().asReadOnlyByteBuffer().getInt() == 0) {
// compile failed
@@ -276,7 +276,7 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend
GLProgram program = shader.context.GetProgram(programName);
ExchangeMessage(contextId, queue, "glLinkProgram(%d)", program.name);
rcv = ExchangeMessage(contextId, queue,
"glGetProgramiv(%d, GL_LINK_STATUS, [0])", program.name);
"glGetProgramiv(%d, GL_LINK_STATUS, {0})", program.name);
assert rcv.hasData();
if (rcv.getData().asReadOnlyByteBuffer().getInt() != 0)
continue;