GLES2Dbg: use mesa glsl_compiler for syntax checking
Also switch to TabFolder for GUI
Change-Id: If7f5b7d8d826ada17579ca4d031f46d1238bba27
Signed-off-by: David Li <davidxli@google.com>
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/BreakpointOption.java b/tools/glesv2debugger/src/com/android/glesv2debugger/BreakpointOption.java
index 46fa382..0974526 100644
--- a/tools/glesv2debugger/src/com/android/glesv2debugger/BreakpointOption.java
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/BreakpointOption.java
@@ -77,7 +77,7 @@
Message.Builder builder = Message.newBuilder();
builder.setContextId(0); // FIXME: proper context id
builder.setType(Type.Response);
- builder.setExpectResponse(true);
+ builder.setExpectResponse(false);
builder.setFunction(Function.SETPROP);
builder.setProp(Prop.ExpectResponse);
builder.setArg0(function.getNumber());
@@ -99,6 +99,10 @@
private Function lastFunction = Function.NEG;
public boolean ProcessMessage(final MessageQueue queue, final Message msg) throws IOException {
+ // use DefaultProcessMessage just to register the GL call
+ // but do not send response
+ if (msg.getType() == Type.BeforeCall || msg.getType() == Type.AfterCall)
+ queue.DefaultProcessMessage(msg, true, false);
final Message.Builder builder = Message.newBuilder();
builder.setContextId(msg.getContextId());
builder.setType(Type.Response);
@@ -118,7 +122,7 @@
}
if (msg.getType() == Type.AfterCall)
{
- call = "s";
+ call = "skip " + call;
builder.setFunction(Function.SKIP);
}
else if (msg.getType() == Type.BeforeCall)
@@ -130,6 +134,8 @@
{
assert msg.getType() == Type.AfterGeneratedCall;
assert msg.getFunction() == lastFunction;
+ call = "skip" + call;
+ builder.setFunction(Function.SKIP);
}
InputDialog inputDialog = new InputDialog(shell,
msg.getFunction().toString() + " " + msg.getType().toString(),
@@ -139,7 +145,12 @@
{
String s = inputDialog.getValue().substring(0, 1).toLowerCase();
if (s.startsWith("s"))
+ {
builder.setFunction(Function.SKIP);
+ // AfterCall is skipped, so push BeforeCall to complete
+ if (msg.getType() == Type.BeforeCall)
+ queue.CompletePartialMessage(msg.getContextId());
+ }
else if (s.startsWith("c"))
builder.setFunction(Function.CONTINUE);
else if (s.startsWith("r"))
@@ -147,6 +158,7 @@
Button btn = buttonsBreak.get(msg.getFunction());
btn.setSelection(false);
SetBreakpoint(msg.getFunction(), false);
+ builder.setExpectResponse(false);
}
else
{
@@ -154,9 +166,7 @@
lastFunction = builder.getFunction();
}
}
- else
- assert false; // TODO: cancel behaviour
- // TODO: add/modify/remove completed messages in queue
+ // else defaults to continue BeforeCall and skip AfterCall
}
});
queue.SendMessage(builder.build());
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/MessageQueue.java b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageQueue.java
index 02cf976..fecc24a 100644
--- a/tools/glesv2debugger/src/com/android/glesv2debugger/MessageQueue.java
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageQueue.java
@@ -150,11 +150,20 @@
return partials.get(contextId);
}
+ // used to add BeforeCall to complete if it was skipped
+ void CompletePartialMessage(final int contextId) {
+ final Message msg = partials.remove(contextId);
+ assert msg != null;
+ assert msg.getType() == Type.BeforeCall;
+ synchronized (complete) {
+ complete.add(msg);
+ }
+ }
+
// can be used by other message processor as default processor
void DefaultProcessMessage(final Message msg, boolean expectResponse,
boolean sendResponse)
throws IOException {
- assert !msg.getExpectResponse();
final int contextId = msg.getContextId();
final Message.Builder builder = Message.newBuilder();
builder.setContextId(contextId);
@@ -230,6 +239,7 @@
private void SendMessage(final DataOutputStream dos, final Message message)
throws IOException {
+ assert message.getFunction() != Function.NEG;
final byte[] data = message.toByteArray();
dos.writeInt(data.length);
dos.write(data);
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/SampleView.java b/tools/glesv2debugger/src/com/android/glesv2debugger/SampleView.java
index adce634..eb1a6ee 100644
--- a/tools/glesv2debugger/src/com/android/glesv2debugger/SampleView.java
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/SampleView.java
@@ -48,15 +48,15 @@
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISharedImages;
@@ -100,11 +100,12 @@
*/
public static final String ID = "glesv2debuggerclient.views.SampleView";
- LayoutComposite layoutComposite;
+ TabFolder tabFolder;
+ TabItem tabItemText, tabItemImage, tabItemBreakpointOption, tabItemShaderEditor;
ListViewer viewer;
BreakpointOption breakpointOption;
ShaderEditor shaderEditor;
- org.eclipse.swt.widgets.Canvas canvas;
+ Canvas canvas;
Text text;
Action actionConnect; // connect / disconnect
Action doubleClickAction;
@@ -241,19 +242,33 @@
PlatformUI.getWorkbench().getHelpSystem()
.setHelp(viewer.getControl(), "GLESv2DebuggerClient.viewer");
- layoutComposite = new LayoutComposite(parent, 0);
- layoutComposite.setLayout(new FillLayout());
+ // layoutComposite = new LayoutComposite(parent, 0);
+ // layoutComposite.setLayout(new FillLayout());
- text = new Text(layoutComposite, SWT.NO_BACKGROUND | SWT.READ_ONLY
+ tabFolder = new TabFolder(parent, SWT.BORDER);
+
+ text = new Text(tabFolder, SWT.NO_BACKGROUND | SWT.READ_ONLY
| SWT.V_SCROLL | SWT.H_SCROLL);
- text.setVisible(false);
- canvas = new Canvas(layoutComposite, SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE
+ tabItemText = new TabItem(tabFolder, SWT.NONE);
+ tabItemText.setText("Text");
+ tabItemText.setControl(text);
+
+ canvas = new Canvas(tabFolder, SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE
| SWT.V_SCROLL | SWT.H_SCROLL);
- canvas.setVisible(false);
+ tabItemImage = new TabItem(tabFolder, SWT.NONE);
+ tabItemImage.setText("Image");
+ tabItemImage.setControl(canvas);
- breakpointOption = new BreakpointOption(this, layoutComposite);
- shaderEditor = new ShaderEditor(this, layoutComposite);
+ breakpointOption = new BreakpointOption(this, tabFolder);
+ tabItemBreakpointOption = new TabItem(tabFolder, SWT.NONE);
+ tabItemBreakpointOption.setText("Breakpoint Option");
+ tabItemBreakpointOption.setControl(breakpointOption);
+
+ shaderEditor = new ShaderEditor(this, tabFolder);
+ tabItemShaderEditor = new TabItem(tabFolder, SWT.NONE);
+ tabItemShaderEditor.setText("Shader Editor");
+ tabItemShaderEditor.setControl(shaderEditor);
final ScrollBar hBar = canvas.getHorizontalBar();
hBar.addListener(SWT.Selection, new Listener() {
@@ -460,30 +475,6 @@
}
};
manager.add(actionPort);
-
- Action action = new Action("Breakpoints", Action.AS_CHECK_BOX)
- {
- @Override
- public void run()
- {
- breakpointOption.setVisible(!breakpointOption.isVisible());
- layoutComposite.layout(true);
- }
- };
- action.setChecked(true);
- manager.add(action);
-
- action = new Action("Shaders", Action.AS_CHECK_BOX)
- {
- @Override
- public void run()
- {
- shaderEditor.setVisible(!shaderEditor.isVisible());
- layoutComposite.layout(true);
- }
- };
- action.setChecked(true);
- manager.add(action);
}
private void ConnectDisconnect() {
@@ -550,10 +541,8 @@
return;
if (null != msgData.image)
{
- text.setVisible(false);
- canvas.setVisible(true);
canvas.setBackgroundImage(msgData.image);
- canvas.getParent().layout();
+ tabFolder.setSelection(tabItemImage);
}
else if (null != msgData.shader)
{
@@ -577,9 +566,7 @@
}
text.setText(builder.toString());
- text.setVisible(true);
- canvas.setVisible(false);
- text.getParent().layout();
+ tabFolder.setSelection(tabItemText);
}
}
@@ -675,20 +662,3 @@
}
}
}
-
-class LayoutComposite extends Composite {
- public LayoutComposite(Composite parent, int style) {
- super(parent, style);
- }
-
- @Override
- public Control[] getChildren() {
- Control[] children = super.getChildren();
- ArrayList<Control> controls = new ArrayList<Control>();
- for (int i = 0; i < children.length; i++)
- if (children[i].isVisible())
- controls.add(children[i]);
- children = new Control[controls.size()];
- return controls.toArray(children);
- }
-}
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/ShaderEditor.java b/tools/glesv2debugger/src/com/android/glesv2debugger/ShaderEditor.java
index 1694b7a..49bece3 100644
--- a/tools/glesv2debugger/src/com/android/glesv2debugger/ShaderEditor.java
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/ShaderEditor.java
@@ -28,22 +28,29 @@
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileWriter;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
import java.util.ArrayList;
public class ShaderEditor extends Composite implements SelectionListener, ExtendedModifyListener {
SampleView sampleView;
ToolBar toolbar;
- ToolItem uploadShader, restoreShader;
+ ToolItem uploadShader, restoreShader, currentPrograms;
List list;
StyledText styledText;
@@ -51,8 +58,6 @@
ArrayList<GLShader> shadersToUpload = new ArrayList<GLShader>();
- ArrayList<Message> cmds = new ArrayList<Message>();
-
ShaderEditor(SampleView sampleView, Composite parent) {
super(parent, 0);
this.sampleView = sampleView;
@@ -71,6 +76,9 @@
restoreShader.setText("Original Shader");
restoreShader.addSelectionListener(this);
+ currentPrograms = new ToolItem(toolbar, SWT.PUSH);
+ currentPrograms.setText("Current Programs: ");
+
list = new List(this, SWT.V_SCROLL);
list.setFont(new Font(parent.getDisplay(), "Courier", 10, 0));
list.addSelectionListener(this);
@@ -93,7 +101,12 @@
public void Update() {
list.removeAll();
+ String progs = "Current Programs: ";
for (Context context : sampleView.contexts.values()) {
+ if (context.serverShader.current != null) {
+ progs += context.serverShader.current.name + "(0x";
+ progs += Integer.toHexString(context.contextId) + ") ";
+ }
for (GLShader shader : context.serverShader.privateShaders.values()) {
StringBuilder builder = new StringBuilder();
builder.append(String.format("%08X", context.contextId));
@@ -117,16 +130,62 @@
list.add(builder.toString());
}
}
+ // if (!progs.equals(currentPrograms.getText())) {
+ currentPrograms.setText(progs);
+
+ // }
+ toolbar.update();
}
void UploadShader() {
current.source = styledText.getText();
+ try {
+ File file = File.createTempFile("shader",
+ current.type == GLEnum.GL_VERTEX_SHADER ? ".vert" : ".frag");
+ FileWriter fileWriter = new FileWriter(file, false);
+ fileWriter.write(current.source);
+ fileWriter.close();
+
+ ProcessBuilder processBuilder = new ProcessBuilder(
+ "./glsl_compiler", "--glsl-es", file.getAbsolutePath());
+ final Process process = processBuilder.start();
+ InputStream is = process.getInputStream();
+ InputStreamReader isr = new InputStreamReader(is);
+ BufferedReader br = new BufferedReader(isr);
+ String line;
+ String infolog = "";
+
+ styledText.setLineBackground(0, styledText.getLineCount(), null);
+
+ while ((line = br.readLine()) != null) {
+ infolog += line;
+ if (!line.startsWith("0:"))
+ continue;
+ String[] details = line.split(":|\\(|\\)");
+ final int ln = Integer.parseInt(details[1]);
+ if (ln > 0) // usually line 0 means errors other than syntax
+ styledText.setLineBackground(ln - 1, 1,
+ new Color(Display.getCurrent(), 255, 230, 230));
+ }
+ if (infolog.length() > 0) {
+ MessageDialog.openWarning(getShell(),
+ "Shader Syntax Error, Upload Aborted", infolog);
+ return;
+ }
+
+ } catch (IOException e) {
+ sampleView.showError(e);
+ }
+
// add the initial command, which when read by server will set
// expectResponse for the message loop and go into message exchange
synchronized (shadersToUpload) {
- if (shadersToUpload.size() > 0) {
- MessageDialog.openWarning(this.getShell(), "",
+ for (GLShader shader : shadersToUpload) {
+ if (shader.context.context.contextId != current.context.context.contextId)
+ continue;
+ MessageDialog.openWarning(this.getShell(), "Context 0x" +
+ Integer.toHexString(current.context.context.contextId),
"Previous shader upload not complete, try again");
return;
}
@@ -168,16 +227,22 @@
synchronized (shadersToUpload) {
if (shadersToUpload.size() == 0)
return false;
- shader = shadersToUpload.get(0);
boolean matchingContext = false;
- for (Context ctx : shader.context.context.shares)
- if (ctx.contextId == msg.getContextId()) {
- matchingContext = true;
+ for (int i = 0; i < shadersToUpload.size(); i++) {
+ shader = shadersToUpload.get(i);
+ for (Context ctx : shader.context.context.shares)
+ if (ctx.contextId == contextId) {
+ matchingContext = true;
+ break;
+ }
+ if (matchingContext)
+ {
+ shadersToUpload.remove(i);
break;
}
+ }
if (!matchingContext)
return false;
- shadersToUpload.remove(0);
}
// glShaderSource was already sent to trigger set expectResponse