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()
|
String[] getList()
|
||||||
{
|
{
|
||||||
assert args.charAt(0) == '{';
|
|
||||||
String arg = args;
|
String arg = args;
|
||||||
args = args.substring(args.lastIndexOf('}') + 1);
|
args = args.substring(args.lastIndexOf('}') + 1);
|
||||||
int comma = args.indexOf(',');
|
final int comma = args.indexOf(',');
|
||||||
if (comma >= 0)
|
if (comma >= 0)
|
||||||
args = args.substring(comma + 1).trim();
|
args = args.substring(comma + 1).trim();
|
||||||
else
|
else
|
||||||
args = null;
|
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();
|
arg = arg.substring(1, arg.lastIndexOf('}')).trim();
|
||||||
return arg.split(",");
|
return arg.split("\\s*,\\s*");
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteString parseFloats(int count) {
|
ByteString parseFloats(int count) {
|
||||||
@@ -110,7 +115,7 @@ public abstract class MessageParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ByteString parseMatrix(int columns, int count) {
|
ByteString parseMatrix(int columns, int count) {
|
||||||
return parseFloats(columns * count);
|
return parseFloats(columns * columns * count);
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteString parseString() {
|
ByteString parseString() {
|
||||||
@@ -127,21 +132,22 @@ public abstract class MessageParser {
|
|||||||
|
|
||||||
String getArgument()
|
String getArgument()
|
||||||
{
|
{
|
||||||
int comma = args.indexOf(",");
|
final int comma = args.indexOf(',');
|
||||||
String arg = null;
|
String arg = null;
|
||||||
if (comma >= 0)
|
if (comma >= 0)
|
||||||
{
|
{
|
||||||
arg = args.substring(0, comma).trim();
|
arg = args.substring(0, comma);
|
||||||
args = args.substring(comma + 1).trim();
|
args = args.substring(comma + 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
arg = args;
|
arg = args;
|
||||||
args = null;
|
args = null;
|
||||||
}
|
}
|
||||||
if (arg.indexOf("=") >= 0)
|
final int comment = arg.indexOf('=');
|
||||||
arg = arg.substring(arg.indexOf("=") + 1);
|
if (comment >= 0)
|
||||||
return arg;
|
arg = arg.substring(comment + 1);
|
||||||
|
return arg.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
int parseArgument()
|
int parseArgument()
|
||||||
@@ -242,8 +248,8 @@ public abstract class MessageParser {
|
|||||||
assert columns * columns == count
|
assert columns * columns == count
|
||||||
assert countArg != ""
|
assert countArg != ""
|
||||||
assert paramType == "GLfloat"
|
assert paramType == "GLfloat"
|
||||||
dataSetter = "builder.setData(parseMatrix(%d, %d * builder.getArg%d()));" % (
|
dataSetter = "builder.setData(parseMatrix(%d, builder.getArg%d()));" % (
|
||||||
columns, count, paramNames.index(countArg))
|
columns, paramNames.index(countArg))
|
||||||
elif annotation == "GLstring":
|
elif annotation == "GLstring":
|
||||||
dataSetter = "builder.setData(parseString());"
|
dataSetter = "builder.setData(parseString());"
|
||||||
elif paramType.find("void") >= 0:
|
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 glTexImage2D:
|
||||||
case glTexSubImage2D:
|
case glTexSubImage2D:
|
||||||
case glCopyTexImage2D:
|
case glCopyTexImage2D:
|
||||||
case glCopyTexSubImage2D:
|
case glCopyTexSubImage2D: {
|
||||||
return entry.image = new MessageData(Display.getCurrent(), msg, null)
|
entry.image = new MessageData(Display.getCurrent(), msg, null).getImage();
|
||||||
.getImage();
|
if (entry.image == null)
|
||||||
|
return null;
|
||||||
|
return new Image(Display.getCurrent(), entry.image.getImageData().scaledTo(96, 96));
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,8 @@ class GLTexture implements Cloneable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
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) {
|
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][0] = x;
|
||||||
defaultAttribs[indx][1] = y;
|
defaultAttribs[indx][1] = y;
|
||||||
defaultAttribs[indx][2] = z;
|
defaultAttribs[indx][2] = z;
|
||||||
|
|||||||
@@ -31,16 +31,21 @@ public abstract class MessageParser {
|
|||||||
|
|
||||||
String[] getList()
|
String[] getList()
|
||||||
{
|
{
|
||||||
assert args.charAt(0) == '{';
|
|
||||||
String arg = args;
|
String arg = args;
|
||||||
args = args.substring(args.lastIndexOf('}') + 1);
|
args = args.substring(args.lastIndexOf('}') + 1);
|
||||||
int comma = args.indexOf(',');
|
final int comma = args.indexOf(',');
|
||||||
if (comma >= 0)
|
if (comma >= 0)
|
||||||
args = args.substring(comma + 1).trim();
|
args = args.substring(comma + 1).trim();
|
||||||
else
|
else
|
||||||
args = null;
|
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();
|
arg = arg.substring(1, arg.lastIndexOf('}')).trim();
|
||||||
return arg.split(",");
|
return arg.split("\\s*,\\s*");
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteString parseFloats(int count) {
|
ByteString parseFloats(int count) {
|
||||||
@@ -74,7 +79,7 @@ public abstract class MessageParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ByteString parseMatrix(int columns, int count) {
|
ByteString parseMatrix(int columns, int count) {
|
||||||
return parseFloats(columns * count);
|
return parseFloats(columns * columns * count);
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteString parseString() {
|
ByteString parseString() {
|
||||||
@@ -91,21 +96,22 @@ public abstract class MessageParser {
|
|||||||
|
|
||||||
String getArgument()
|
String getArgument()
|
||||||
{
|
{
|
||||||
int comma = args.indexOf(",");
|
final int comma = args.indexOf(',');
|
||||||
String arg = null;
|
String arg = null;
|
||||||
if (comma >= 0)
|
if (comma >= 0)
|
||||||
{
|
{
|
||||||
arg = args.substring(0, comma).trim();
|
arg = args.substring(0, comma);
|
||||||
args = args.substring(comma + 1).trim();
|
args = args.substring(comma + 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
arg = args;
|
arg = args;
|
||||||
args = null;
|
args = null;
|
||||||
}
|
}
|
||||||
if (arg.indexOf("=") >= 0)
|
final int comment = arg.indexOf('=');
|
||||||
arg = arg.substring(arg.indexOf("=") + 1);
|
if (comment >= 0)
|
||||||
return arg;
|
arg = arg.substring(comment + 1);
|
||||||
|
return arg.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
int parseArgument()
|
int parseArgument()
|
||||||
@@ -634,19 +640,19 @@ public abstract class MessageParser {
|
|||||||
builder.setArg0(parseArgument()); // GLint location
|
builder.setArg0(parseArgument()); // GLint location
|
||||||
builder.setArg1(parseArgument()); // GLsizei count
|
builder.setArg1(parseArgument()); // GLsizei count
|
||||||
builder.setArg2(parseArgument()); // GLboolean transpose
|
builder.setArg2(parseArgument()); // GLboolean transpose
|
||||||
builder.setData(parseMatrix(2, 4 * builder.getArg1())); // GLfloat value
|
builder.setData(parseMatrix(2, builder.getArg1())); // GLfloat value
|
||||||
break;
|
break;
|
||||||
case glUniformMatrix3fv:
|
case glUniformMatrix3fv:
|
||||||
builder.setArg0(parseArgument()); // GLint location
|
builder.setArg0(parseArgument()); // GLint location
|
||||||
builder.setArg1(parseArgument()); // GLsizei count
|
builder.setArg1(parseArgument()); // GLsizei count
|
||||||
builder.setArg2(parseArgument()); // GLboolean transpose
|
builder.setArg2(parseArgument()); // GLboolean transpose
|
||||||
builder.setData(parseMatrix(3, 9 * builder.getArg1())); // GLfloat value
|
builder.setData(parseMatrix(3, builder.getArg1())); // GLfloat value
|
||||||
break;
|
break;
|
||||||
case glUniformMatrix4fv:
|
case glUniformMatrix4fv:
|
||||||
builder.setArg0(parseArgument()); // GLint location
|
builder.setArg0(parseArgument()); // GLint location
|
||||||
builder.setArg1(parseArgument()); // GLsizei count
|
builder.setArg1(parseArgument()); // GLsizei count
|
||||||
builder.setArg2(parseArgument()); // GLboolean transpose
|
builder.setArg2(parseArgument()); // GLboolean transpose
|
||||||
builder.setData(parseMatrix(4, 16 * builder.getArg1())); // GLfloat value
|
builder.setData(parseMatrix(4, builder.getArg1())); // GLfloat value
|
||||||
break;
|
break;
|
||||||
case glUseProgram:
|
case glUseProgram:
|
||||||
builder.setArg0(parseArgument()); // GLuint program
|
builder.setArg0(parseArgument()); // GLuint program
|
||||||
|
|||||||
@@ -192,12 +192,7 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SampleView() {
|
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) {
|
public void createLeftPane(Composite parent) {
|
||||||
|
|||||||
@@ -146,6 +146,8 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend
|
|||||||
void uploadShader() {
|
void uploadShader() {
|
||||||
current.source = styledText.getText();
|
current.source = styledText.getText();
|
||||||
|
|
||||||
|
// optional syntax check by glsl_compiler, built from external/mesa3d
|
||||||
|
if (new File("./glsl_compiler").exists())
|
||||||
try {
|
try {
|
||||||
File file = File.createTempFile("shader",
|
File file = File.createTempFile("shader",
|
||||||
current.type == GLEnum.GL_VERTEX_SHADER ? ".vert" : ".frag");
|
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