GLES2Dbg: more tests and minor fixes/improvements
Change-Id: I55c360372623c019da0c1ba2eebbc68f73f0f211
Signed-off-by: David Li <davidxli@google.com>
diff --git a/tools/glesv2debugger/README.android b/tools/glesv2debugger/README.android
new file mode 100644
index 0000000..ae95463
--- /dev/null
+++ b/tools/glesv2debugger/README.android
@@ -0,0 +1,20 @@
+The following is taken from slide 3 & 4 of https://docs.google.com/a/google.com/present/edit?id=0AcZLV3icFYi0ZGZxa3NqZndfMGRqa2tiOXB4&authkey=CMfb8ukI&hl=en
+The spec doc is at https://docs.google.com/a/google.com/document/d/1dsASXCF9Suq8KOGcxwB2mAwgdRlrFj4QhMxkfaRJlA0/edit?hl=en&authkey=CPj4tKkO#
+
+
+Building and Running
+
+Debugger server is linked into EGL, code is in framework/base/opengl/libs/GLES2_dbg and already included in latest master builds, no action needed.
+Use development/tools/glesv2debugger/setup.sh to build and copy the jars: libprotobuf-java-2.3.0-lite, liblzf, sdklib into development/tools/glesv2debugger/lib
+Install Eclipse SDK for Eclipse: Eclipse->Help->Install New Software. Select "All Available Sites" in the "Work with:" drop down, then find "Eclipse SDK". (If Eclipse reports dependency conflicts, try install updates first)
+Debugger client is an Eclipse plug-in, code is at development/tools/glesv2debugger, built in Eclipse
+Optional: build glsl_compiler and copy to plug-in working directory; this is used for shader syntax check
+
+
+"Attaching" to a Process
+
+adb shell setprop debug.egl.debug_proc <process name> before running process. ie: com.example.android.apis
+EGL checks /proc/<proc_id>/cmdline for match during init and sets debug functions in eglMakeCurrent
+EGL will bind to socket and wait for incoming connection, so need to adb forward tcp:5039 tcp:5039. Port can be overridden by adb shell setprop debug.egl.debug_port <port>
+If create socket failed, EGL will try to open /data/local/tmp/dump.gles2dbg for write, and exit when 8MB is written. The relevant properties are ...debug_forceUseFile, ...debug_maxFileSize, and ...debug_filePath
+Now manually start the process on device; on host, open development/tools/glesv2debugger/.project and run/debug as Eclipse application, then Window->Show View->Other->Debug->OpenGL ES 2.0 Debugger, then Connect or Open File
diff --git a/tools/glesv2debugger/generate_MessageParser_java.py b/tools/glesv2debugger/generate_MessageParser_java.py
index 8dcb50f..b6e8282 100755
--- a/tools/glesv2debugger/generate_MessageParser_java.py
+++ b/tools/glesv2debugger/generate_MessageParser_java.py
@@ -67,16 +67,21 @@
String[] getList()
{
- assert args.charAt(0) == '{';
String arg = args;
args = args.substring(args.lastIndexOf('}') + 1);
- int comma = args.indexOf(',');
+ final int comma = args.indexOf(',');
if (comma >= 0)
args = args.substring(comma + 1).trim();
else
args = null;
+
+ final int comment = arg.indexOf('=');
+ if (comment >= 0)
+ arg = arg.substring(comment + 1);
+ arg = arg.trim();
+ assert arg.charAt(0) == '{';
arg = arg.substring(1, arg.lastIndexOf('}')).trim();
- return arg.split(",");
+ return arg.split("\\s*,\\s*");
}
ByteString parseFloats(int count) {
@@ -110,7 +115,7 @@
}
ByteString parseMatrix(int columns, int count) {
- return parseFloats(columns * count);
+ return parseFloats(columns * columns * count);
}
ByteString parseString() {
@@ -127,21 +132,22 @@
String getArgument()
{
- int comma = args.indexOf(",");
+ final int comma = args.indexOf(',');
String arg = null;
if (comma >= 0)
{
- arg = args.substring(0, comma).trim();
- args = args.substring(comma + 1).trim();
+ arg = args.substring(0, comma);
+ args = args.substring(comma + 1);
}
else
{
arg = args;
args = null;
}
- if (arg.indexOf("=") >= 0)
- arg = arg.substring(arg.indexOf("=") + 1);
- return arg;
+ final int comment = arg.indexOf('=');
+ if (comment >= 0)
+ arg = arg.substring(comment + 1);
+ return arg.trim();
}
int parseArgument()
@@ -242,8 +248,8 @@
assert columns * columns == count
assert countArg != ""
assert paramType == "GLfloat"
- dataSetter = "builder.setData(parseMatrix(%d, %d * builder.getArg%d()));" % (
- columns, count, paramNames.index(countArg))
+ dataSetter = "builder.setData(parseMatrix(%d, builder.getArg%d()));" % (
+ columns, paramNames.index(countArg))
elif annotation == "GLstring":
dataSetter = "builder.setData(parseString());"
elif paramType.find("void") >= 0:
diff --git a/tools/glesv2debugger/setup.sh b/tools/glesv2debugger/setup.sh
new file mode 100755
index 0000000..839019d
--- /dev/null
+++ b/tools/glesv2debugger/setup.sh
@@ -0,0 +1,35 @@
+source ../../../build/envsetup.sh
+pushd ../../../
+
+# need lunch before building jars
+if [ -z "$TARGET_PRODUCT" ]; then
+ lunch
+fi
+
+pushd external/liblzf/
+mm
+popd
+
+pushd external/protobuf/
+mm
+popd
+
+pushd sdk/sdkmanager/libs/sdklib
+mm
+popd
+
+# glsl_compiler is optional
+# make glsl_compiler -j3
+
+popd
+
+mkdir -p lib
+cp "$ANDROID_HOST_OUT/framework/host-libprotobuf-java-2.3.0-lite.jar" lib/
+cp "$ANDROID_HOST_OUT/framework/liblzf.jar" lib/
+cp "$ANDROID_HOST_OUT/framework/sdklib.jar" lib/
+
+# optional; usually for linux
+#cp "$ANDROID_HOST_OUT/bin/glsl_compiler" ~/
+
+# optional; usually for mac, need to replace eclipse.app with actual path
+#cp "$ANDROID_HOST_OUT/bin/glsl_compiler" eclipse.app/Contents/MacOS
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/Context.java b/tools/glesv2debugger/src/com/android/glesv2debugger/Context.java
index e1395d7..122695b 100644
--- a/tools/glesv2debugger/src/com/android/glesv2debugger/Context.java
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/Context.java
@@ -359,9 +359,12 @@
case glTexImage2D:
case glTexSubImage2D:
case glCopyTexImage2D:
- case glCopyTexSubImage2D:
- return entry.image = new MessageData(Display.getCurrent(), msg, null)
- .getImage();
+ case glCopyTexSubImage2D: {
+ entry.image = new MessageData(Display.getCurrent(), msg, null).getImage();
+ if (entry.image == null)
+ return null;
+ return new Image(Display.getCurrent(), entry.image.getImageData().scaledTo(96, 96));
+ }
default:
return null;
}
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/GLServerTexture.java b/tools/glesv2debugger/src/com/android/glesv2debugger/GLServerTexture.java
index 4d95684..27676dd 100644
--- a/tools/glesv2debugger/src/com/android/glesv2debugger/GLServerTexture.java
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/GLServerTexture.java
@@ -75,7 +75,8 @@
@Override
public String toString() {
- return target.name() + " " + contentChanges.size() + " content change(s)";
+ return String.format("%s %s %d*%d %d change(s)", target, format, width, height,
+ contentChanges.size());
}
}
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/GLServerVertex.java b/tools/glesv2debugger/src/com/android/glesv2debugger/GLServerVertex.java
index a07f0a4..5f9d513 100644
--- a/tools/glesv2debugger/src/com/android/glesv2debugger/GLServerVertex.java
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/GLServerVertex.java
@@ -521,6 +521,8 @@
}
void glVertexAttrib4f(int indx, float x, float y, float z, float w) {
+ if (indx < 0 || indx >= defaultAttribs.length)
+ return;
defaultAttribs[indx][0] = x;
defaultAttribs[indx][1] = y;
defaultAttribs[indx][2] = z;
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/MessageParser.java b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageParser.java
index 8a0c0ec..8536728 100644
--- a/tools/glesv2debugger/src/com/android/glesv2debugger/MessageParser.java
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageParser.java
@@ -31,16 +31,21 @@
String[] getList()
{
- assert args.charAt(0) == '{';
String arg = args;
args = args.substring(args.lastIndexOf('}') + 1);
- int comma = args.indexOf(',');
+ final int comma = args.indexOf(',');
if (comma >= 0)
args = args.substring(comma + 1).trim();
else
args = null;
+
+ final int comment = arg.indexOf('=');
+ if (comment >= 0)
+ arg = arg.substring(comment + 1);
+ arg = arg.trim();
+ assert arg.charAt(0) == '{';
arg = arg.substring(1, arg.lastIndexOf('}')).trim();
- return arg.split(",");
+ return arg.split("\\s*,\\s*");
}
ByteString parseFloats(int count) {
@@ -74,7 +79,7 @@
}
ByteString parseMatrix(int columns, int count) {
- return parseFloats(columns * count);
+ return parseFloats(columns * columns * count);
}
ByteString parseString() {
@@ -91,21 +96,22 @@
String getArgument()
{
- int comma = args.indexOf(",");
+ final int comma = args.indexOf(',');
String arg = null;
if (comma >= 0)
{
- arg = args.substring(0, comma).trim();
- args = args.substring(comma + 1).trim();
+ arg = args.substring(0, comma);
+ args = args.substring(comma + 1);
}
else
{
arg = args;
args = null;
}
- if (arg.indexOf("=") >= 0)
- arg = arg.substring(arg.indexOf("=") + 1);
- return arg;
+ final int comment = arg.indexOf('=');
+ if (comment >= 0)
+ arg = arg.substring(comment + 1);
+ return arg.trim();
}
int parseArgument()
@@ -634,19 +640,19 @@
builder.setArg0(parseArgument()); // GLint location
builder.setArg1(parseArgument()); // GLsizei count
builder.setArg2(parseArgument()); // GLboolean transpose
- builder.setData(parseMatrix(2, 4 * builder.getArg1())); // GLfloat value
+ builder.setData(parseMatrix(2, builder.getArg1())); // GLfloat value
break;
case glUniformMatrix3fv:
builder.setArg0(parseArgument()); // GLint location
builder.setArg1(parseArgument()); // GLsizei count
builder.setArg2(parseArgument()); // GLboolean transpose
- builder.setData(parseMatrix(3, 9 * builder.getArg1())); // GLfloat value
+ builder.setData(parseMatrix(3, builder.getArg1())); // GLfloat value
break;
case glUniformMatrix4fv:
builder.setArg0(parseArgument()); // GLint location
builder.setArg1(parseArgument()); // GLsizei count
builder.setArg2(parseArgument()); // GLboolean transpose
- builder.setData(parseMatrix(4, 16 * builder.getArg1())); // GLfloat value
+ builder.setData(parseMatrix(4, builder.getArg1())); // GLfloat value
break;
case glUseProgram:
builder.setArg0(parseArgument()); // GLuint program
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/SampleView.java b/tools/glesv2debugger/src/com/android/glesv2debugger/SampleView.java
index 91e352e..4a8cdc9 100644
--- a/tools/glesv2debugger/src/com/android/glesv2debugger/SampleView.java
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/SampleView.java
@@ -192,12 +192,7 @@
}
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,
- "void glShaderSource(shader=4, count=1, string=\"dksjafhskjahourehghskjg\", length=0x0)");
+
}
public void createLeftPane(Composite parent) {
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/ShaderEditor.java b/tools/glesv2debugger/src/com/android/glesv2debugger/ShaderEditor.java
index cdd55c2..c125143 100644
--- a/tools/glesv2debugger/src/com/android/glesv2debugger/ShaderEditor.java
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/ShaderEditor.java
@@ -146,43 +146,45 @@
void uploadShader() {
current.source = styledText.getText();
- try {
- File file = File.createTempFile("shader",
- current.type == GLEnum.GL_VERTEX_SHADER ? ".vert" : ".frag");
- FileWriter fileWriter = new FileWriter(file, false);
- fileWriter.write(current.source);
- fileWriter.close();
+ // optional syntax check by glsl_compiler, built from external/mesa3d
+ if (new File("./glsl_compiler").exists())
+ try {
+ File file = File.createTempFile("shader",
+ current.type == GLEnum.GL_VERTEX_SHADER ? ".vert" : ".frag");
+ FileWriter fileWriter = new FileWriter(file, false);
+ fileWriter.write(current.source);
+ fileWriter.close();
- ProcessBuilder processBuilder = new ProcessBuilder(
- "./glsl_compiler", "--glsl-es", file.getAbsolutePath());
- final Process process = processBuilder.start();
- InputStream is = process.getInputStream();
- InputStreamReader isr = new InputStreamReader(is);
- BufferedReader br = new BufferedReader(isr);
- String line;
- String infolog = "";
+ ProcessBuilder processBuilder = new ProcessBuilder(
+ "./glsl_compiler", "--glsl-es", file.getAbsolutePath());
+ final Process process = processBuilder.start();
+ InputStream is = process.getInputStream();
+ InputStreamReader isr = new InputStreamReader(is);
+ BufferedReader br = new BufferedReader(isr);
+ String line;
+ String infolog = "";
- styledText.setLineBackground(0, styledText.getLineCount(), null);
+ styledText.setLineBackground(0, styledText.getLineCount(), null);
- while ((line = br.readLine()) != null) {
- infolog += line;
- if (!line.startsWith("0:"))
- continue;
- String[] details = line.split(":|\\(|\\)");
- final int ln = Integer.parseInt(details[1]);
- if (ln > 0) // usually line 0 means errors other than syntax
- styledText.setLineBackground(ln - 1, 1,
- new Color(Display.getCurrent(), 255, 230, 230));
+ while ((line = br.readLine()) != null) {
+ infolog += line;
+ if (!line.startsWith("0:"))
+ continue;
+ String[] details = line.split(":|\\(|\\)");
+ final int ln = Integer.parseInt(details[1]);
+ if (ln > 0) // usually line 0 means errors other than syntax
+ styledText.setLineBackground(ln - 1, 1,
+ new Color(Display.getCurrent(), 255, 230, 230));
+ }
+ file.delete();
+ if (infolog.length() > 0) {
+ if (!MessageDialog.openConfirm(getShell(),
+ "Shader Syntax Error, Continue?", infolog))
+ return;
+ }
+ } catch (IOException e) {
+ sampleView.showError(e);
}
- file.delete();
- if (infolog.length() > 0) {
- if (!MessageDialog.openConfirm(getShell(),
- "Shader Syntax Error, Continue?", infolog))
- return;
- }
- } catch (IOException e) {
- sampleView.showError(e);
- }
// add the initial command, which when read by server will set
// expectResponse for the message loop and go into message exchange
diff --git a/tools/glesv2debugger/test/com/android/glesv2debugger/MessageParserExTest.java b/tools/glesv2debugger/test/com/android/glesv2debugger/MessageParserExTest.java
new file mode 100644
index 0000000..d2a9a7e
--- /dev/null
+++ b/tools/glesv2debugger/test/com/android/glesv2debugger/MessageParserExTest.java
@@ -0,0 +1,115 @@
+/*
+ ** 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import com.android.glesv2debugger.DebuggerMessage.Message;
+import com.android.glesv2debugger.DebuggerMessage.Message.Function;
+import com.android.glesv2debugger.DebuggerMessage.Message.Type;
+import com.google.protobuf.ByteString;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.nio.ByteBuffer;
+
+public class MessageParserExTest {
+ /**
+ * @throws java.lang.Exception
+ */
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @Test
+ public void testParseFloats() {
+ final MessageParserEx parser = new MessageParserEx();
+ final String args = "{0, 1 ,2,3 }";
+ parser.args = args;
+ final ByteBuffer data = parser.parseFloats(4).asReadOnlyByteBuffer();
+ data.order(SampleView.targetByteOrder);
+ for (int i = 0; i < 4; i++)
+ assertEquals(i, data.getFloat(), 0);
+ }
+
+ @Test
+ public void testParseArgument() {
+ final MessageParserEx parser = new MessageParserEx();
+ final String args = "sdfa = GL_VERTEX_SHADER , -5421 ,0x443=0x54f";
+ parser.args = args;
+ assertEquals(GLEnum.GL_VERTEX_SHADER.value, parser.parseArgument());
+ assertEquals(-5421, parser.parseArgument());
+ assertEquals(0x54f, parser.parseArgument());
+ }
+
+ /**
+ * Test method for
+ * {@link com.android.glesv2debugger.MessageParserEx#parse_glShaderSource(com.android.glesv2debugger.DebuggerMessage.Message.Builder)}
+ * .
+ */
+ @Test
+ public void testParse_glShaderSource() {
+ final Message.Builder builder = Message.newBuilder();
+ final MessageParserEx messageParserEx = new MessageParserEx();
+ final String source = "dks \n jafhskjaho { urehg ; } hskjg";
+ messageParserEx.parse(builder, "void glShaderSource ( shader=4, count= 1, "
+ + "string =\"" + source + "\" , 0x0)");
+ assertEquals(Function.glShaderSource, builder.getFunction());
+ assertEquals(4, builder.getArg0());
+ assertEquals(1, builder.getArg1());
+ assertEquals(source, builder.getData().toStringUtf8());
+ assertEquals(0, builder.getArg3());
+ }
+
+ @Test
+ public void testParse_glBlendEquation() {
+ assertNotNull(MessageParserEx.instance);
+ final Message.Builder builder = Message.newBuilder();
+ MessageParserEx.instance.parse(builder, "void glBlendEquation ( mode= GL_ADD ) ; ");
+ assertEquals(Function.glBlendEquation, builder.getFunction());
+ assertEquals(GLEnum.GL_ADD.value, builder.getArg0());
+ }
+
+ /** loopback testing of typical generated MessageFormatter and MessageParser */
+ @Test
+ public void testParseFormatterMessage() {
+ final ByteBuffer srcData = ByteBuffer.allocate(4 * 2 * 4);
+ srcData.order(SampleView.targetByteOrder);
+ for (int i = 0; i < 4 * 2; i++)
+ srcData.putFloat(i);
+ srcData.rewind();
+ Message.Builder builder = Message.newBuilder();
+ builder.setContextId(3752).setExpectResponse(false).setType(Type.CompleteCall);
+ builder.setFunction(Function.glUniformMatrix2fv);
+ builder.setArg0(54).setArg1(2).setArg2(0).setData(ByteString.copyFrom(srcData));
+ Message msg = builder.build();
+ builder = msg.toBuilder();
+ String formatted = MessageFormatter.format(msg, false);
+ formatted = formatted.substring(0, formatted.indexOf('(')) + ' ' + builder.getFunction() +
+ formatted.substring(formatted.indexOf('('));
+ Message.Builder parsed = Message.newBuilder();
+ MessageParserEx.instance.parse(parsed, formatted);
+ assertEquals(builder.getFunction(), parsed.getFunction());
+ assertEquals(builder.getArg0(), parsed.getArg0());
+ assertEquals(builder.getArg1(), parsed.getArg1());
+ assertEquals(builder.getArg2(), parsed.getArg2());
+ assertEquals(builder.getData().toStringUtf8(), parsed.getData().toStringUtf8());
+ }
+
+}