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:
@@ -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 += ", ";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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 += ", ";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
Reference in New Issue
Block a user