GLES2Dbg: added SETPROP expectResponse

To allow "stepping" in functions.
Also fix bug in reference frame.
Use reference frame for CopyTex(Sub)Image2D.

Change-Id: I70083200a1e911aaeb74ca85cb10bae16bd4db18
Signed-off-by: David Li <davidxli@google.com>
This commit is contained in:
David Li
2011-03-22 10:05:05 -07:00
parent 7bc448f9d5
commit 5089368bc7
8 changed files with 195 additions and 11 deletions

View File

@@ -59,6 +59,8 @@ import java.nio.ByteBuffer;
public class MessageFormatter { public class MessageFormatter {
static String FormatFloats(int count, final ByteBuffer data) { static String FormatFloats(int count, final ByteBuffer data) {
if (data.remaining() == 0)
return "[null]";
String ret = "["; String ret = "[";
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
@@ -70,6 +72,8 @@ public class MessageFormatter {
} }
static String FormatInts(int count, final ByteBuffer data) { static String FormatInts(int count, final ByteBuffer data) {
if (data.remaining() == 0)
return "[null]";
String ret = "["; String ret = "[";
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
@@ -81,6 +85,8 @@ public class MessageFormatter {
} }
static String FormatUints(int count, final ByteBuffer data) { static String FormatUints(int count, final ByteBuffer data) {
if (data.remaining() == 0)
return "[null]";
String ret = "["; String ret = "[";
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
@@ -93,12 +99,14 @@ public class MessageFormatter {
} }
static String FormatMatrix(int columns, int count, final ByteBuffer data) { static String FormatMatrix(int columns, int count, final ByteBuffer data) {
if (data.remaining() == 0)
return "[null]";
String ret = "["; String ret = "[";
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
ret += Float.intBitsToFloat(Integer.reverseBytes(data.getInt())); ret += Float.intBitsToFloat(Integer.reverseBytes(data.getInt()));
if (i % columns == columns - 1) if (i % columns == columns - 1)
ret += '\\n'; ret += "\\n ";
else if (i < count - 1) else if (i < count - 1)
ret += ", "; ret += ", ";
} }

View File

@@ -0,0 +1,134 @@
/*
** 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.glesv2debugger.DebuggerMessage.Message.Prop;
import com.android.glesv2debugger.DebuggerMessage.Message.Type;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Shell;
import java.util.HashMap;
public class BreakpointOption extends ScrolledComposite implements SelectionListener {
SampleView sampleView;
HashMap<Function, Button> buttons = new HashMap<Function, Button>();
BreakpointOption(SampleView sampleView, Composite parent) {
super(parent, SWT.NO_BACKGROUND | SWT.V_SCROLL | SWT.H_SCROLL);
this.sampleView = sampleView;
Composite composite = new Composite(this, 0);
GridLayout layout = new GridLayout();
layout.numColumns = 4;
composite.setLayout(layout);
this.setLayout(new FillLayout());
for (int i = 0; i < Function.values().length; i++) {
Group group = new Group(composite, 0);
group.setLayout(new RowLayout());
group.setText(Function.values()[i].toString());
Button btn = new Button(group, SWT.CHECK);
btn.addSelectionListener(this);
btn.setText("Break");
btn.setSelection(false);
buttons.put(Function.values()[i], btn);
}
Point size = composite.computeSize(SWT.DEFAULT, SWT.DEFAULT);
composite.setSize(size);
this.setContent(composite);
this.setExpandHorizontal(true);
this.setExpandVertical(true);
this.setMinSize(size);
this.layout();
// this.pack(true);
}
void SetBreakpoint(Function function, boolean enabled) {
Message.Builder builder = Message.newBuilder();
builder.setContextId(0); // FIXME: proper context id
builder.setType(Type.Response);
builder.setExpectResponse(false);
builder.setFunction(Function.SETPROP);
builder.setProp(Prop.ExpectResponse);
builder.setArg0(function.getNumber());
builder.setArg1(enabled ? 1 : 0);
sampleView.messageQueue.AddCommand(builder.build());
}
@Override
public void widgetSelected(SelectionEvent e) {
Button btn = (Button) e.widget;
Group group = (Group) btn.getParent();
SetBreakpoint(Function.valueOf(group.getText()), btn.getSelection());
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
public void BreakpointReached(final Message.Builder builder, final Message msg) {
final Shell shell = sampleView.getViewSite().getShell();
shell.getDisplay().syncExec(new Runnable() {
@Override
public void run() {
String[] btns = {
"&Continue", "&Skip", "&Remove"
};
int defaultBtn = 0;
if (msg.getType() == Type.AfterCall)
defaultBtn = 1;
String message = msg.getFunction().toString();
if (msg.hasTime())
message += String.format("\n%.3fms", msg.getTime());
message += "\n" + MessageFormatter.Format(msg);
MessageDialog dialog = new MessageDialog(shell, "Breakpoint " + msg.getType(),
null, message, MessageDialog.QUESTION, btns, defaultBtn);
int rc = dialog.open();
if (rc == SWT.DEFAULT || rc == 0)
builder.setFunction(Function.CONTINUE);
else if (rc == 1)
builder.setFunction(Function.SKIP);
else if (rc == 2)
{
Button btn = buttons.get(msg.getFunction());
btn.setSelection(false);
SetBreakpoint(msg.getFunction(), false);
}
else
assert false;
}
});
}
}

View File

@@ -526,6 +526,7 @@ public final class DebuggerMessage {
implements com.google.protobuf.Internal.EnumLite { implements com.google.protobuf.Internal.EnumLite {
Capture(0, 0), Capture(0, 0),
TimeMode(1, 1), TimeMode(1, 1),
ExpectResponse(2, 2),
; ;
@@ -535,6 +536,7 @@ public final class DebuggerMessage {
switch (value) { switch (value) {
case 0: return Capture; case 0: return Capture;
case 1: return TimeMode; case 1: return TimeMode;
case 2: return ExpectResponse;
default: return null; default: return null;
} }
} }

View File

@@ -55,6 +55,7 @@ public class MessageData {
switch (function) { switch (function) {
case glDrawArrays: // msg was modified by GLServerVertex case glDrawArrays: // msg was modified by GLServerVertex
case glDrawElements: case glDrawElements:
assert msg.hasData();
if (!msg.hasArg8() || !msg.hasData()) if (!msg.hasArg8() || !msg.hasData())
break; break;
dataType = GLEnum.valueOf(msg.getArg8()); dataType = GLEnum.valueOf(msg.getArg8());
@@ -84,15 +85,23 @@ public class MessageData {
image = new Image(device, imageData); image = new Image(device, imageData);
break; break;
case glCopyTexImage2D: case glCopyTexImage2D:
assert msg.getDataType() == DataType.ReferencedImage;
MessageProcessor.ref = context.readPixelRef;
imageData = MessageProcessor.ReceiveImage(msg.getArg5(), msg.getArg6(), imageData = MessageProcessor.ReceiveImage(msg.getArg5(), msg.getArg6(),
GLEnum.GL_RGBA.value, GLEnum.GL_UNSIGNED_BYTE.value, msg.getData() msg.getPixelFormat(), msg.getPixelType(), msg.getData()
.toByteArray()); .toByteArray());
MessageProcessor.ref = null;
image = new Image(device, imageData); image = new Image(device, imageData);
imageData = imageData.scaledTo(imageData.width, -imageData.height);
break; break;
case glCopyTexSubImage2D: case glCopyTexSubImage2D:
assert msg.getDataType() == DataType.ReferencedImage;
MessageProcessor.ref = context.readPixelRef;
imageData = MessageProcessor.ReceiveImage(msg.getArg6(), msg.getArg7(), imageData = MessageProcessor.ReceiveImage(msg.getArg6(), msg.getArg7(),
GLEnum.GL_RGBA.value, GLEnum.GL_UNSIGNED_BYTE.value, msg.getData() msg.getPixelFormat(), msg.getPixelType(), msg.getData()
.toByteArray()); .toByteArray());
MessageProcessor.ref = null;
imageData = imageData.scaledTo(imageData.width, -imageData.height);
image = new Image(device, imageData); image = new Image(device, imageData);
break; break;
case glReadPixels: case glReadPixels:

View File

@@ -23,6 +23,8 @@ import java.nio.ByteBuffer;
public class MessageFormatter { public class MessageFormatter {
static String FormatFloats(int count, final ByteBuffer data) { static String FormatFloats(int count, final ByteBuffer data) {
if (data.remaining() == 0)
return "[null]";
String ret = "["; String ret = "[";
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
@@ -34,6 +36,8 @@ public class MessageFormatter {
} }
static String FormatInts(int count, final ByteBuffer data) { static String FormatInts(int count, final ByteBuffer data) {
if (data.remaining() == 0)
return "[null]";
String ret = "["; String ret = "[";
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
@@ -45,6 +49,8 @@ public class MessageFormatter {
} }
static String FormatUints(int count, final ByteBuffer data) { static String FormatUints(int count, final ByteBuffer data) {
if (data.remaining() == 0)
return "[null]";
String ret = "["; String ret = "[";
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
@@ -57,12 +63,14 @@ public class MessageFormatter {
} }
static String FormatMatrix(int columns, int count, final ByteBuffer data) { static String FormatMatrix(int columns, int count, final ByteBuffer data) {
if (data.remaining() == 0)
return "[null]";
String ret = "["; String ret = "[";
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
ret += Float.intBitsToFloat(Integer.reverseBytes(data.getInt())); ret += Float.intBitsToFloat(Integer.reverseBytes(data.getInt()));
if (i % columns == columns - 1) if (i % columns == columns - 1)
ret += '\n'; ret += "\n ";
else if (i < count - 1) else if (i < count - 1)
ret += ", "; ret += ", ";
} }

View File

@@ -30,7 +30,7 @@ public class MessageProcessor {
MessageDialog.openError(null, "MessageProcessor", message); MessageDialog.openError(null, "MessageProcessor", message);
} }
public static byte [] ref; // inout; used for glReadPixels public static byte[] ref; // inout; used for glReadPixels
public static ImageData ReceiveImage(int width, int height, int format, public static ImageData ReceiveImage(int width, int height, int format,
int type, byte[] data) { int type, byte[] data) {
@@ -102,9 +102,11 @@ public class MessageProcessor {
PaletteData palette = new PaletteData(redMask, greenMask, blueMask); PaletteData palette = new PaletteData(redMask, greenMask, blueMask);
if (null != ref) { if (null != ref) {
if (ref.length < decompressed) if (ref.length < decompressed)
ref = new byte [width * height * (bpp / 8)]; ref = new byte[width * height * (bpp / 8)];
for (int i = 0; i < ref.length; i++) for (int i = 0; i < decompressed; i++)
ref[i] ^= pixels[i]; ref[i] ^= pixels[i];
for (int i = decompressed; i < ref.length; i++)
ref[i] = 0; // clear unused ref to maintain consistency
return new ImageData(width, height, bpp, palette, 1, ref); return new ImageData(width, height, bpp, palette, 1, ref);
} else } else
return new ImageData(width, height, bpp, palette, 1, pixels); return new ImageData(width, height, bpp, palette, 1, pixels);

View File

@@ -20,6 +20,10 @@ import com.android.glesv2debugger.DebuggerMessage.Message;
import com.android.glesv2debugger.DebuggerMessage.Message.Function; import com.android.glesv2debugger.DebuggerMessage.Message.Function;
import com.android.glesv2debugger.DebuggerMessage.Message.Type; import com.android.glesv2debugger.DebuggerMessage.Message.Type;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Shell;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.EOFException; import java.io.EOFException;
@@ -234,18 +238,20 @@ public class MessageQueue implements Runnable {
} }
void SendResponse(final DataOutputStream dos, final Message msg) throws IOException { void SendResponse(final DataOutputStream dos, final Message msg) throws IOException {
Message.Builder builder = Message.newBuilder(); final Message.Builder builder = Message.newBuilder();
builder.setContextId(msg.getContextId()); builder.setContextId(msg.getContextId());
if (msg.getType() == Type.BeforeCall) if (msg.getType() == Type.BeforeCall)
builder.setFunction(Function.CONTINUE); builder.setFunction(Function.CONTINUE);
else if (msg.getType() == Type.AfterCall) else if (msg.getType() == Type.AfterCall)
builder.setFunction(Function.SKIP); builder.setFunction(Function.SKIP);
else
assert false;
builder.setType(Type.Response); builder.setType(Type.Response);
builder.setExpectResponse(false); builder.setExpectResponse(false);
// FIXME: consider using proper context id if (msg.getExpectResponse())
sampleView.breakpointOption.BreakpointReached(builder, msg);
if (SendCommands(dos, 0) || msg.getExpectResponse()) if (SendCommands(dos, 0) || msg.getExpectResponse())
if (builder.hasFunction()) SendMessage(dos, builder.build());
SendMessage(dos, builder.build());
} }
void Error(Exception e) { void Error(Exception e) {

View File

@@ -99,6 +99,7 @@ public class SampleView extends ViewPart implements Runnable {
public static final String ID = "glesv2debuggerclient.views.SampleView"; public static final String ID = "glesv2debuggerclient.views.SampleView";
ListViewer viewer; ListViewer viewer;
BreakpointOption breakpointOption;
org.eclipse.swt.widgets.Canvas canvas; org.eclipse.swt.widgets.Canvas canvas;
Text text; Text text;
Action actionConnect; // connect / disconnect Action actionConnect; // connect / disconnect
@@ -263,6 +264,8 @@ public class SampleView extends ViewPart implements Runnable {
| SWT.V_SCROLL | SWT.H_SCROLL); | SWT.V_SCROLL | SWT.H_SCROLL);
canvas.setVisible(false); canvas.setVisible(false);
breakpointOption = new BreakpointOption(this, layoutComposite);
final ScrollBar hBar = canvas.getHorizontalBar(); final ScrollBar hBar = canvas.getHorizontalBar();
hBar.addListener(SWT.Selection, new Listener() { hBar.addListener(SWT.Selection, new Listener() {
@Override @Override
@@ -462,6 +465,18 @@ public class SampleView extends ViewPart implements Runnable {
} }
}; };
manager.add(actionPort); manager.add(actionPort);
Action action = new Action("Breakpoints", Action.AS_CHECK_BOX)
{
@Override
public void run()
{
breakpointOption.setVisible(!breakpointOption.isVisible());
manager.update(true);
}
};
action.setChecked(true);
manager.add(action);
} }
private void ConnectDisconnect() { private void ConnectDisconnect() {