GLES2Dbg: more tests and minor fixes/improvements

Change-Id: I55c360372623c019da0c1ba2eebbc68f73f0f211
Signed-off-by: David Li <davidxli@google.com>
This commit is contained in:
David Li
2011-04-22 18:18:30 -07:00
parent 38c48e57fb
commit a130006227
10 changed files with 253 additions and 68 deletions

View File

@@ -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

View File

@@ -67,16 +67,21 @@ public abstract class MessageParser {
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 @@ public abstract class MessageParser {
}
ByteString parseMatrix(int columns, int count) {
return parseFloats(columns * count);
return parseFloats(columns * columns * count);
}
ByteString parseString() {
@@ -127,21 +132,22 @@ public abstract class MessageParser {
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 @@ public abstract class MessageParser {
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:

35
tools/glesv2debugger/setup.sh Executable file
View File

@@ -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

View File

@@ -359,9 +359,12 @@ class ContextViewProvider extends LabelProvider implements ITreeContentProvider,
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;
}

View File

@@ -75,7 +75,8 @@ class GLTexture implements Cloneable {
@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());
}
}

View File

@@ -521,6 +521,8 @@ public class GLServerVertex implements Cloneable {
}
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;

View File

@@ -31,16 +31,21 @@ public abstract class MessageParser {
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 @@ public abstract class MessageParser {
}
ByteString parseMatrix(int columns, int count) {
return parseFloats(columns * count);
return parseFloats(columns * columns * count);
}
ByteString parseString() {
@@ -91,21 +96,22 @@ public abstract class MessageParser {
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 @@ public abstract class MessageParser {
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

View File

@@ -192,12 +192,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,
"void glShaderSource(shader=4, count=1, string=\"dksjafhskjahourehghskjg\", length=0x0)");
}
public void createLeftPane(Composite parent) {

View File

@@ -146,6 +146,8 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend
void uploadShader() {
current.source = styledText.getText();
// 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");

View File

@@ -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());
}
}