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>
This commit is contained in:
David Li
2011-03-28 17:55:56 -07:00
parent 9c4ef35e35
commit c93109f059
4 changed files with 130 additions and 75 deletions

View File

@@ -77,7 +77,7 @@ public class BreakpointOption extends ScrolledComposite implements SelectionList
Message.Builder builder = Message.newBuilder(); Message.Builder builder = Message.newBuilder();
builder.setContextId(0); // FIXME: proper context id builder.setContextId(0); // FIXME: proper context id
builder.setType(Type.Response); builder.setType(Type.Response);
builder.setExpectResponse(true); builder.setExpectResponse(false);
builder.setFunction(Function.SETPROP); builder.setFunction(Function.SETPROP);
builder.setProp(Prop.ExpectResponse); builder.setProp(Prop.ExpectResponse);
builder.setArg0(function.getNumber()); builder.setArg0(function.getNumber());
@@ -99,6 +99,10 @@ public class BreakpointOption extends ScrolledComposite implements SelectionList
private Function lastFunction = Function.NEG; private Function lastFunction = Function.NEG;
public boolean ProcessMessage(final MessageQueue queue, final Message msg) throws IOException { 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(); final Message.Builder builder = Message.newBuilder();
builder.setContextId(msg.getContextId()); builder.setContextId(msg.getContextId());
builder.setType(Type.Response); builder.setType(Type.Response);
@@ -118,7 +122,7 @@ public class BreakpointOption extends ScrolledComposite implements SelectionList
} }
if (msg.getType() == Type.AfterCall) if (msg.getType() == Type.AfterCall)
{ {
call = "s"; call = "skip " + call;
builder.setFunction(Function.SKIP); builder.setFunction(Function.SKIP);
} }
else if (msg.getType() == Type.BeforeCall) else if (msg.getType() == Type.BeforeCall)
@@ -130,6 +134,8 @@ public class BreakpointOption extends ScrolledComposite implements SelectionList
{ {
assert msg.getType() == Type.AfterGeneratedCall; assert msg.getType() == Type.AfterGeneratedCall;
assert msg.getFunction() == lastFunction; assert msg.getFunction() == lastFunction;
call = "skip" + call;
builder.setFunction(Function.SKIP);
} }
InputDialog inputDialog = new InputDialog(shell, InputDialog inputDialog = new InputDialog(shell,
msg.getFunction().toString() + " " + msg.getType().toString(), 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(); String s = inputDialog.getValue().substring(0, 1).toLowerCase();
if (s.startsWith("s")) if (s.startsWith("s"))
{
builder.setFunction(Function.SKIP); 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")) else if (s.startsWith("c"))
builder.setFunction(Function.CONTINUE); builder.setFunction(Function.CONTINUE);
else if (s.startsWith("r")) else if (s.startsWith("r"))
@@ -147,6 +158,7 @@ public class BreakpointOption extends ScrolledComposite implements SelectionList
Button btn = buttonsBreak.get(msg.getFunction()); Button btn = buttonsBreak.get(msg.getFunction());
btn.setSelection(false); btn.setSelection(false);
SetBreakpoint(msg.getFunction(), false); SetBreakpoint(msg.getFunction(), false);
builder.setExpectResponse(false);
} }
else else
{ {
@@ -154,9 +166,7 @@ public class BreakpointOption extends ScrolledComposite implements SelectionList
lastFunction = builder.getFunction(); lastFunction = builder.getFunction();
} }
} }
else // else defaults to continue BeforeCall and skip AfterCall
assert false; // TODO: cancel behaviour
// TODO: add/modify/remove completed messages in queue
} }
}); });
queue.SendMessage(builder.build()); queue.SendMessage(builder.build());

View File

@@ -150,11 +150,20 @@ public class MessageQueue implements Runnable {
return partials.get(contextId); 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 // can be used by other message processor as default processor
void DefaultProcessMessage(final Message msg, boolean expectResponse, void DefaultProcessMessage(final Message msg, boolean expectResponse,
boolean sendResponse) boolean sendResponse)
throws IOException { throws IOException {
assert !msg.getExpectResponse();
final int contextId = msg.getContextId(); final int contextId = msg.getContextId();
final Message.Builder builder = Message.newBuilder(); final Message.Builder builder = Message.newBuilder();
builder.setContextId(contextId); builder.setContextId(contextId);
@@ -230,6 +239,7 @@ public class MessageQueue implements Runnable {
private void SendMessage(final DataOutputStream dos, final Message message) private void SendMessage(final DataOutputStream dos, final Message message)
throws IOException { throws IOException {
assert message.getFunction() != Function.NEG;
final byte[] data = message.toByteArray(); final byte[] data = message.toByteArray();
dos.writeInt(data.length); dos.writeInt(data.length);
dos.write(data); dos.write(data);

View File

@@ -48,15 +48,15 @@ import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.ScrollBar; import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Shell; 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.swt.widgets.Text;
import org.eclipse.ui.IActionBars; import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISharedImages; import org.eclipse.ui.ISharedImages;
@@ -100,11 +100,12 @@ public class SampleView extends ViewPart implements Runnable {
*/ */
public static final String ID = "glesv2debuggerclient.views.SampleView"; public static final String ID = "glesv2debuggerclient.views.SampleView";
LayoutComposite layoutComposite; TabFolder tabFolder;
TabItem tabItemText, tabItemImage, tabItemBreakpointOption, tabItemShaderEditor;
ListViewer viewer; ListViewer viewer;
BreakpointOption breakpointOption; BreakpointOption breakpointOption;
ShaderEditor shaderEditor; ShaderEditor shaderEditor;
org.eclipse.swt.widgets.Canvas canvas; Canvas canvas;
Text text; Text text;
Action actionConnect; // connect / disconnect Action actionConnect; // connect / disconnect
Action doubleClickAction; Action doubleClickAction;
@@ -241,19 +242,33 @@ public class SampleView extends ViewPart implements Runnable {
PlatformUI.getWorkbench().getHelpSystem() PlatformUI.getWorkbench().getHelpSystem()
.setHelp(viewer.getControl(), "GLESv2DebuggerClient.viewer"); .setHelp(viewer.getControl(), "GLESv2DebuggerClient.viewer");
layoutComposite = new LayoutComposite(parent, 0); // layoutComposite = new LayoutComposite(parent, 0);
layoutComposite.setLayout(new FillLayout()); // 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); | 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); | 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); breakpointOption = new BreakpointOption(this, tabFolder);
shaderEditor = new ShaderEditor(this, layoutComposite); 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(); final ScrollBar hBar = canvas.getHorizontalBar();
hBar.addListener(SWT.Selection, new Listener() { hBar.addListener(SWT.Selection, new Listener() {
@@ -460,30 +475,6 @@ 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());
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() { private void ConnectDisconnect() {
@@ -550,10 +541,8 @@ public class SampleView extends ViewPart implements Runnable {
return; return;
if (null != msgData.image) if (null != msgData.image)
{ {
text.setVisible(false);
canvas.setVisible(true);
canvas.setBackgroundImage(msgData.image); canvas.setBackgroundImage(msgData.image);
canvas.getParent().layout(); tabFolder.setSelection(tabItemImage);
} }
else if (null != msgData.shader) else if (null != msgData.shader)
{ {
@@ -577,9 +566,7 @@ public class SampleView extends ViewPart implements Runnable {
} }
text.setText(builder.toString()); text.setText(builder.toString());
text.setVisible(true); tabFolder.setSelection(tabItemText);
canvas.setVisible(false);
text.getParent().layout();
} }
} }
@@ -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<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);
}
}

View File

@@ -28,22 +28,29 @@ import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.List; import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem; 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.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList; import java.util.ArrayList;
public class ShaderEditor extends Composite implements SelectionListener, ExtendedModifyListener { public class ShaderEditor extends Composite implements SelectionListener, ExtendedModifyListener {
SampleView sampleView; SampleView sampleView;
ToolBar toolbar; ToolBar toolbar;
ToolItem uploadShader, restoreShader; ToolItem uploadShader, restoreShader, currentPrograms;
List list; List list;
StyledText styledText; StyledText styledText;
@@ -51,8 +58,6 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend
ArrayList<GLShader> shadersToUpload = new ArrayList<GLShader>(); ArrayList<GLShader> shadersToUpload = new ArrayList<GLShader>();
ArrayList<Message> cmds = new ArrayList<Message>();
ShaderEditor(SampleView sampleView, Composite parent) { ShaderEditor(SampleView sampleView, Composite parent) {
super(parent, 0); super(parent, 0);
this.sampleView = sampleView; this.sampleView = sampleView;
@@ -71,6 +76,9 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend
restoreShader.setText("Original Shader"); restoreShader.setText("Original Shader");
restoreShader.addSelectionListener(this); restoreShader.addSelectionListener(this);
currentPrograms = new ToolItem(toolbar, SWT.PUSH);
currentPrograms.setText("Current Programs: ");
list = new List(this, SWT.V_SCROLL); list = new List(this, SWT.V_SCROLL);
list.setFont(new Font(parent.getDisplay(), "Courier", 10, 0)); list.setFont(new Font(parent.getDisplay(), "Courier", 10, 0));
list.addSelectionListener(this); list.addSelectionListener(this);
@@ -93,7 +101,12 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend
public void Update() { public void Update() {
list.removeAll(); list.removeAll();
String progs = "Current Programs: ";
for (Context context : sampleView.contexts.values()) { 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()) { for (GLShader shader : context.serverShader.privateShaders.values()) {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.append(String.format("%08X", context.contextId)); builder.append(String.format("%08X", context.contextId));
@@ -117,16 +130,62 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend
list.add(builder.toString()); list.add(builder.toString());
} }
} }
// if (!progs.equals(currentPrograms.getText())) {
currentPrograms.setText(progs);
// }
toolbar.update();
} }
void UploadShader() { void UploadShader() {
current.source = styledText.getText(); 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 // add the initial command, which when read by server will set
// expectResponse for the message loop and go into message exchange // expectResponse for the message loop and go into message exchange
synchronized (shadersToUpload) { synchronized (shadersToUpload) {
if (shadersToUpload.size() > 0) { for (GLShader shader : shadersToUpload) {
MessageDialog.openWarning(this.getShell(), "", 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"); "Previous shader upload not complete, try again");
return; return;
} }
@@ -168,16 +227,22 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend
synchronized (shadersToUpload) { synchronized (shadersToUpload) {
if (shadersToUpload.size() == 0) if (shadersToUpload.size() == 0)
return false; return false;
shader = shadersToUpload.get(0);
boolean matchingContext = false; boolean matchingContext = false;
for (int i = 0; i < shadersToUpload.size(); i++) {
shader = shadersToUpload.get(i);
for (Context ctx : shader.context.context.shares) for (Context ctx : shader.context.context.shares)
if (ctx.contextId == msg.getContextId()) { if (ctx.contextId == contextId) {
matchingContext = true; matchingContext = true;
break; break;
} }
if (matchingContext)
{
shadersToUpload.remove(i);
break;
}
}
if (!matchingContext) if (!matchingContext)
return false; return false;
shadersToUpload.remove(0);
} }
// glShaderSource was already sent to trigger set expectResponse // glShaderSource was already sent to trigger set expectResponse