From c93109f05968d478d80f25180110dfd75ca074e5 Mon Sep 17 00:00:00 2001 From: David Li Date: Mon, 28 Mar 2011 17:55:56 -0700 Subject: [PATCH] GLES2Dbg: use mesa glsl_compiler for syntax checking Also switch to TabFolder for GUI Change-Id: If7f5b7d8d826ada17579ca4d031f46d1238bba27 Signed-off-by: David Li --- .../glesv2debugger/BreakpointOption.java | 20 +++-- .../android/glesv2debugger/MessageQueue.java | 12 ++- .../android/glesv2debugger/SampleView.java | 88 ++++++------------- .../android/glesv2debugger/ShaderEditor.java | 85 +++++++++++++++--- 4 files changed, 130 insertions(+), 75 deletions(-) diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/BreakpointOption.java b/tools/glesv2debugger/src/com/android/glesv2debugger/BreakpointOption.java index 46fa382c5..09745264a 100644 --- a/tools/glesv2debugger/src/com/android/glesv2debugger/BreakpointOption.java +++ b/tools/glesv2debugger/src/com/android/glesv2debugger/BreakpointOption.java @@ -77,7 +77,7 @@ public class BreakpointOption extends ScrolledComposite implements SelectionList 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 @@ public class BreakpointOption extends ScrolledComposite implements SelectionList 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 @@ public class BreakpointOption extends ScrolledComposite implements SelectionList } if (msg.getType() == Type.AfterCall) { - call = "s"; + call = "skip " + call; builder.setFunction(Function.SKIP); } else if (msg.getType() == Type.BeforeCall) @@ -130,6 +134,8 @@ public class BreakpointOption extends ScrolledComposite implements SelectionList { 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 @@ public class BreakpointOption extends ScrolledComposite implements SelectionList { 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 @@ public class BreakpointOption extends ScrolledComposite implements SelectionList Button btn = buttonsBreak.get(msg.getFunction()); btn.setSelection(false); SetBreakpoint(msg.getFunction(), false); + builder.setExpectResponse(false); } else { @@ -154,9 +166,7 @@ public class BreakpointOption extends ScrolledComposite implements SelectionList 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 02cf97676..fecc24a35 100644 --- a/tools/glesv2debugger/src/com/android/glesv2debugger/MessageQueue.java +++ b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageQueue.java @@ -150,11 +150,20 @@ public class MessageQueue implements Runnable { 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 @@ public class MessageQueue implements Runnable { 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 adce6340a..eb1a6ee60 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.GC; 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 class SampleView extends ViewPart implements Runnable { */ 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 @@ public class SampleView extends ViewPart implements Runnable { 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 @@ public class SampleView extends ViewPart implements Runnable { } }; 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 @@ public class SampleView extends ViewPart implements Runnable { 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 @@ public class SampleView extends ViewPart implements Runnable { } text.setText(builder.toString()); - text.setVisible(true); - canvas.setVisible(false); - text.getParent().layout(); + tabFolder.setSelection(tabItemText); } } @@ -675,20 +662,3 @@ public class SampleView extends ViewPart implements Runnable { } } } - -class LayoutComposite extends Composite { - public LayoutComposite(Composite parent, int style) { - super(parent, style); - } - - @Override - public Control[] getChildren() { - Control[] children = super.getChildren(); - ArrayList controls = new ArrayList(); - 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 1694b7ab2..49bece304 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.StyleRange; 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 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend ArrayList shadersToUpload = new ArrayList(); - ArrayList cmds = new ArrayList(); - ShaderEditor(SampleView sampleView, Composite parent) { super(parent, 0); this.sampleView = sampleView; @@ -71,6 +76,9 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend 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 class ShaderEditor extends Composite implements SelectionListener, Extend 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 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend 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 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend 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