GLES2Dbg: more tests and minor fixes/improvements
Change-Id: I55c360372623c019da0c1ba2eebbc68f73f0f211 Signed-off-by: David Li <davidxli@google.com>
This commit is contained in:
20
tools/glesv2debugger/README.android
Normal file
20
tools/glesv2debugger/README.android
Normal 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
|
||||
@@ -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
35
tools/glesv2debugger/setup.sh
Executable 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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user