GLES2Dbg: cache Messages to RandomAccessFile

-Load and format Message when the frame is selected to save memory.

Change-Id: I4ff9edf049dc724a73d6643bde1d53ec8b625114
Signed-off-by: David Li <davidxli@google.com>
This commit is contained in:
David Li
2011-04-07 11:38:56 -07:00
parent e80cdf2ade
commit 7befbd7dee
7 changed files with 304 additions and 144 deletions

View File

@@ -20,13 +20,19 @@ import com.android.glesv2debugger.DebuggerMessage.Message;
import com.android.glesv2debugger.DebuggerMessage.Message.Function; import com.android.glesv2debugger.DebuggerMessage.Message.Function;
import com.android.sdklib.util.SparseIntArray; import com.android.sdklib.util.SparseIntArray;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.widgets.Shell;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
public class CodeGen { public class CodeGen implements IRunnableWithProgress {
private FileWriter codeFile, makeFile, namesHeaderFile, namesSourceFile; private FileWriter codeFile, makeFile, namesHeaderFile, namesSourceFile;
private PrintWriter code, make, namesHeader, namesSource; private PrintWriter code, make, namesHeader, namesSource;
private FileOutputStream dataOut; private FileOutputStream dataOut;
@@ -65,7 +71,7 @@ public class CodeGen {
code.write(";CHKERR;\n"); code.write(";CHKERR;\n");
return true; return true;
} }
assert msg.getArg2() == msg.getPixelFormat(); // TODO // FIXME: check the texture format & type, and convert
s = "//" + MessageFormatter.Format(msg, true) + "\n"; s = "//" + MessageFormatter.Format(msg, true) + "\n";
s += String.format( s += String.format(
"glTexSubImage2D(%s, %d, %d, %d, %d, %d, %s, %s, texData);CHKERR;", "glTexSubImage2D(%s, %d, %d, %d, %d, %d, %s, %s, texData);CHKERR;",
@@ -710,7 +716,7 @@ public class CodeGen {
namesHeader.write("#include <assert.h>\n"); namesHeader.write("#include <assert.h>\n");
namesHeader.write("#include <GLES2/gl2.h>\n"); namesHeader.write("#include <GLES2/gl2.h>\n");
namesHeader.write("#include <GLES2/gl2ext.h>\n"); namesHeader.write("#include <GLES2/gl2ext.h>\n");
namesHeader.write("#define CHKERR assert(GL_NO_ERROR == glGetError());/**/\n"); namesHeader.write("#define CHKERR /*assert(GL_NO_ERROR == glGetError());/**/\n");
namesHeader.write("void FrameSetup();\n"); namesHeader.write("void FrameSetup();\n");
namesHeader.write("extern const unsigned int FrameCount;\n"); namesHeader.write("extern const unsigned int FrameCount;\n");
namesHeader.write("extern const GLuint program_0;\n"); namesHeader.write("extern const GLuint program_0;\n");
@@ -767,9 +773,16 @@ public class CodeGen {
renderbufferNames = null; renderbufferNames = null;
} }
void CodeGenFrames(final DebugContext dbgCtx, int count) { private DebugContext dbgCtx;
Context ctx = dbgCtx.frames.get(0).startContext.clone(); private int count;
private IProgressMonitor progress;
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException,
InterruptedException {
progress.beginTask("CodeGenFrames", count + 2);
Context ctx = dbgCtx.GetFrame(0).startContext.clone();
CodeGenSetup(ctx); CodeGenSetup(ctx);
progress.worked(1);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
try { try {
codeFile = new FileWriter("frame" + i + ".cpp", false); codeFile = new FileWriter("frame" + i + ".cpp", false);
@@ -782,9 +795,9 @@ public class CodeGen {
code.write("#include \"frame_names.h\"\n"); code.write("#include \"frame_names.h\"\n");
code.format("void Frame%d(){\n", i); code.format("void Frame%d(){\n", i);
final Frame frame = dbgCtx.frames.get(i); final Frame frame = dbgCtx.GetFrame(i);
for (int j = 0; j < frame.calls.size(); j++) { for (int j = 0; j < frame.Size(); j++) {
final MessageData msgData = frame.calls.get(j); final MessageData msgData = frame.Get(j);
code.format("/* frame function %d: %s %s*/\n", j, msgData.msg.getFunction(), code.format("/* frame function %d: %s %s*/\n", j, msgData.msg.getFunction(),
MessageFormatter.Format(msgData.msg, false)); MessageFormatter.Format(msgData.msg, false));
ctx.ProcessMessage(msgData.oriMsg); ctx.ProcessMessage(msgData.oriMsg);
@@ -802,6 +815,7 @@ public class CodeGen {
e.printStackTrace(); e.printStackTrace();
assert false; assert false;
} }
progress.worked(1);
} }
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
namesHeader.format("void Frame%d();\n", i); namesHeader.format("void Frame%d();\n", i);
@@ -813,6 +827,25 @@ public class CodeGen {
namesSource.write("};\n"); namesSource.write("};\n");
namesSource.format("const unsigned int FrameCount = %d;\n", count); namesSource.format("const unsigned int FrameCount = %d;\n", count);
CodeGenCleanup(); CodeGenCleanup();
progress.worked(1);
}
void CodeGenFrames(final DebugContext dbgCtx, int count, final Shell shell) {
this.dbgCtx = dbgCtx;
this.count = count;
ProgressMonitorDialog dialog = new ProgressMonitorDialog(shell);
this.progress = dialog.getProgressMonitor();
try {
dialog.run(false, true, this);
} catch (InvocationTargetException e) {
e.printStackTrace();
assert false;
} catch (InterruptedException e) {
e.printStackTrace();
}
this.dbgCtx = null;
this.count = 0;
progress = null;
} }
void CodeGenFrame(final Frame frame) { void CodeGenFrame(final Frame frame) {
@@ -828,8 +861,8 @@ public class CodeGen {
make.format(" frame0.cpp \\\n"); make.format(" frame0.cpp \\\n");
code.write("#include \"frame_names.h\"\n"); code.write("#include \"frame_names.h\"\n");
code.format("void Frame0(){\n"); code.format("void Frame0(){\n");
for (int i = 0; i < frame.calls.size(); i++) { for (int i = 0; i < frame.Size(); i++) {
final MessageData msgData = frame.calls.get(i); final MessageData msgData = frame.Get(i);
code.format("/* frame function %d: %s %s*/\n", i, msgData.msg.getFunction(), code.format("/* frame function %d: %s %s*/\n", i, msgData.msg.getFunction(),
MessageFormatter.Format(msgData.msg, false)); MessageFormatter.Format(msgData.msg, false));
ctx.ProcessMessage(msgData.oriMsg); ctx.ProcessMessage(msgData.oriMsg);

View File

@@ -30,59 +30,188 @@ import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Display;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
class Frame { class Frame {
final Context startContext; public final long filePosition;
ArrayList<MessageData> calls = new ArrayList<MessageData>(); private int callsCount;
Frame(final Context context) { final Context startContext;
private ArrayList<MessageData> calls = new ArrayList<MessageData>();
Frame(final Context context, final long filePosition) {
this.startContext = context.clone(); this.startContext = context.clone();
this.filePosition = filePosition;
}
void Add(final MessageData msgData) {
calls.add(msgData);
}
void IncreaseCallsCount() {
callsCount++;
}
Context ComputeContext(final MessageData call) {
Context ctx = startContext.clone();
for (int i = 0; i < calls.size(); i++)
if (call == calls.get(i))
return ctx;
else
ctx.ProcessMessage(calls.get(i).oriMsg);
assert false;
return ctx;
}
int Size() {
return callsCount;
}
MessageData Get(final int i) {
return calls.get(i);
}
ArrayList<MessageData> Get() {
return calls;
}
void Unload() {
if (calls == null)
return;
calls.clear();
calls = null;
}
void Load(final RandomAccessFile file) {
if (calls != null && calls.size() == callsCount)
return;
try {
Context ctx = startContext.clone();
calls = new ArrayList<MessageData>(callsCount);
final long oriPosition = file.getFilePointer();
file.seek(filePosition);
for (int i = 0; i < callsCount; i++) {
int len = file.readInt();
if (SampleView.targetByteOrder == ByteOrder.LITTLE_ENDIAN)
len = Integer.reverseBytes(len);
final byte[] data = new byte[len];
file.read(data);
final Message oriMsg = Message.parseFrom(data);
final Message msg = ctx.ProcessMessage(oriMsg);
final MessageData msgData = new MessageData(Display.getCurrent(), msg, oriMsg, ctx);
msgData.attribs = ctx.serverVertex.fetchedAttribs;
calls.add(msgData);
}
file.seek(oriPosition);
} catch (IOException e) {
e.printStackTrace();
assert false;
}
} }
} }
class DebugContext { class DebugContext {
boolean uiUpdate = false;
final int contextId; final int contextId;
Context currentContext; Context currentContext;
ArrayList<Frame> frames = new ArrayList<Frame>(128); private ArrayList<Frame> frames = new ArrayList<Frame>(128);
private Frame currentFrame; private Frame lastFrame;
private Frame loadedFrame;
private RandomAccessFile file;
DebugContext(final int contextId) { DebugContext(final int contextId) {
this.contextId = contextId; this.contextId = contextId;
currentContext = new Context(contextId); currentContext = new Context(contextId);
frames.add(new Frame(currentContext)); try {
currentFrame = frames.get(0); file = new RandomAccessFile(Integer.toHexString(contextId) + ".gles2dbg",
"rw");
frames.add(new Frame(currentContext, file.getFilePointer()));
} catch (FileNotFoundException e) {
e.printStackTrace();
assert false;
} catch (IOException e) {
e.printStackTrace();
assert false;
}
lastFrame = frames.get(0);
loadedFrame = lastFrame;
} }
MessageData ProcessMessage(final Message oriMsg) { /** Writes oriMsg to file, and formats into MessageData for current frame */
currentContext.ProcessMessage(oriMsg); void ProcessMessage(final Message oriMsg) {
Message msg = oriMsg; synchronized (file) {
if (currentContext.processed != null) final byte[] data = oriMsg.toByteArray();
msg = currentContext.processed; final ByteBuffer len = ByteBuffer.allocate(4);
currentContext.processed = null; len.order(SampleView.targetByteOrder);
MessageData msgData = new MessageData(Display.getCurrent(), msg, oriMsg, currentContext); len.putInt(data.length);
msgData.attribs = currentContext.serverVertex.fetchedAttribs; try {
currentFrame.calls.add(msgData); if (SampleView.targetByteOrder == ByteOrder.BIG_ENDIAN)
file.writeInt(data.length);
else
file.writeInt(Integer.reverseBytes(data.length));
file.write(data);
} catch (IOException e) {
e.printStackTrace();
assert false;
}
}
lastFrame.IncreaseCallsCount();
final Message msg = currentContext.ProcessMessage(oriMsg);
if (loadedFrame == lastFrame) {
final MessageData msgData = new MessageData(Display.getCurrent(), msg, oriMsg,
currentContext);
msgData.attribs = currentContext.serverVertex.fetchedAttribs;
lastFrame.Add(msgData);
uiUpdate = true;
}
if (msg.getFunction() != Function.eglSwapBuffers) if (msg.getFunction() != Function.eglSwapBuffers)
return msgData; return;
frames.add(currentFrame = new Frame(currentContext)); synchronized (frames) {
return msgData; if (loadedFrame != lastFrame)
lastFrame.Unload();
try {
frames.add(lastFrame = new Frame(currentContext, file.getFilePointer()));
// file.getChannel().force(false);
uiUpdate = true;
} catch (IOException e) {
e.printStackTrace();
assert false;
}
}
return;
} }
Context ComputeContext(final Frame frame, final MessageData call) { Frame GetFrame(int index) {
Context ctx = frame.startContext.clone(); synchronized (frames) {
for (int i = 0; i < frame.calls.size(); i++) Frame newFrame = frames.get(index);
if (call == frame.calls.get(i)) if (loadedFrame != null && loadedFrame != lastFrame && newFrame != loadedFrame) {
return ctx; loadedFrame.Unload();
else uiUpdate = true;
ctx.ProcessMessage(frame.calls.get(i).oriMsg); }
assert false; loadedFrame = newFrame;
return ctx; synchronized (file) {
loadedFrame.Load(file);
}
return loadedFrame;
}
}
int FrameCount() {
synchronized (frames) {
return frames.size();
}
} }
} }
@@ -97,8 +226,6 @@ public class Context implements Cloneable {
byte[] readPixelRef = new byte[0]; byte[] readPixelRef = new byte[0];
Message processed = null; // return; processed Message
public Context(int contextId) { public Context(int contextId) {
this.contextId = contextId; this.contextId = contextId;
shares.add(this); shares.add(this);
@@ -115,6 +242,7 @@ public class Context implements Cloneable {
copy.serverShader = serverShader.clone(copy); copy.serverShader = serverShader.clone(copy);
copy.serverState = serverState.clone(); copy.serverState = serverState.clone();
copy.serverTexture = serverTexture.clone(copy); copy.serverTexture = serverTexture.clone(copy);
copy.readPixelRef = readPixelRef.clone();
return copy; return copy;
} catch (CloneNotSupportedException e) { } catch (CloneNotSupportedException e) {
e.printStackTrace(); e.printStackTrace();
@@ -123,17 +251,21 @@ public class Context implements Cloneable {
} }
} }
public void ProcessMessage(Message msg) { /** returns processed Message, which could be a new Message */
public Message ProcessMessage(Message msg) {
if (serverVertex.Process(msg)) { if (serverVertex.Process(msg)) {
processed = serverVertex.processed; if (serverVertex.processed != null)
return; return serverVertex.processed;
else
return msg;
} }
if (serverShader.ProcessMessage(msg)) if (serverShader.ProcessMessage(msg))
return; return msg;
if (serverState.ProcessMessage(msg)) if (serverState.ProcessMessage(msg))
return; return msg;
if (serverTexture.ProcessMessage(msg)) if (serverTexture.ProcessMessage(msg))
return; return msg;
return msg;
} }
} }
@@ -175,15 +307,16 @@ class ContextViewProvider extends LabelProvider implements ITreeContentProvider,
if (!(entry.obj instanceof Message)) if (!(entry.obj instanceof Message))
return null; return null;
final Message msg = (Message) entry.obj; final Message msg = (Message) entry.obj;
for (int i = 0; i <= sampleView.frameNum.getSelection(); i++) { switch (msg.getFunction()) {
if (i == sampleView.current.frames.size()) case glTexImage2D:
case glTexSubImage2D:
return entry.image = new MessageData(Display.getCurrent(), msg, msg, null).image;
case glCopyTexImage2D:
case glCopyTexSubImage2D:
return null; // TODO: compute context for reference frame
default:
return null; return null;
final Frame frame = sampleView.current.frames.get(i);
for (final MessageData msgData : frame.calls)
if (msgData.oriMsg == msg)
return entry.image = msgData.image;
} }
return null;
} }
@Override @Override

View File

@@ -448,6 +448,7 @@ public final class DebuggerMessage {
AfterCall(1, 1), AfterCall(1, 1),
AfterGeneratedCall(2, 2), AfterGeneratedCall(2, 2),
Response(3, 3), Response(3, 3),
CompleteCall(4, 4),
; ;
@@ -459,6 +460,7 @@ public final class DebuggerMessage {
case 1: return AfterCall; case 1: return AfterCall;
case 2: return AfterGeneratedCall; case 2: return AfterGeneratedCall;
case 3: return Response; case 3: return Response;
case 4: return CompleteCall;
default: return null; default: return null;
} }
} }

View File

@@ -29,14 +29,13 @@ import java.nio.ByteBuffer;
public class MessageData { public class MessageData {
public final Message msg, oriMsg; public final Message msg, oriMsg;
public Image image; // texture public Image image = null; // texture
public String shader; // shader source public String shader = null; // shader source
public String text; public String text;
public String[] columns = new String[3]; public String[] columns = new String[3];
public float[] data; public float[] data = null;
public int maxAttrib; // used for formatting data public int maxAttrib; // used for formatting data
public GLEnum dataType; // could be float, int; mainly for formatting use public GLEnum dataType; // could be float, int; mainly for formatting use
Context context; // the context before this call
ByteBuffer[] attribs = null; ByteBuffer[] attribs = null;
@@ -44,14 +43,10 @@ public class MessageData {
final Context context) { final Context context) {
this.msg = msg; this.msg = msg;
this.oriMsg = oriMsg; this.oriMsg = oriMsg;
this.context = context;
image = null;
shader = null;
data = null;
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
final Function function = msg.getFunction(); final Function function = msg.getFunction();
ImageData imageData = null; ImageData imageData = null;
if (function != Message.Function.ACK) if (function != Message.Function.ACK && msg.getType() != Type.BeforeCall)
assert msg.hasTime(); assert msg.hasTime();
builder.append(columns[0] = function.name()); builder.append(columns[0] = function.name());
while (builder.length() < 30) while (builder.length() < 30)
@@ -70,7 +65,7 @@ public class MessageData {
else if (msg.getType() == Type.AfterGeneratedCall) else if (msg.getType() == Type.AfterGeneratedCall)
columns[2] = "[AfterGeneratedCall] "; columns[2] = "[AfterGeneratedCall] ";
else else
assert msg.getType() == Type.AfterCall; assert msg.getType() == Type.CompleteCall;
columns[2] += MessageFormatter.Format(msg, false); columns[2] += MessageFormatter.Format(msg, false);
builder.append(columns[2]); builder.append(columns[2]);
switch (function) { switch (function) {

View File

@@ -19,6 +19,7 @@ package com.android.glesv2debugger;
import com.android.glesv2debugger.DebuggerMessage.Message; 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 com.android.sdklib.util.SparseArray;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
@@ -28,17 +29,16 @@ import java.io.IOException;
import java.net.Socket; import java.net.Socket;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
public class MessageQueue implements Runnable { public class MessageQueue implements Runnable {
boolean running = false; private boolean running = false;
private ByteOrder byteOrder; private ByteOrder byteOrder;
private FileInputStream file; // if null, create and use socket private FileInputStream file; // if null, create and use socket
Thread thread = null; private Thread thread = null;
ArrayList<Message> complete = new ArrayList<Message>(); // need synchronized private ArrayList<Message> complete = new ArrayList<Message>(); // synchronized
ArrayList<Message> commands = new ArrayList<Message>(); // need synchronized private ArrayList<Message> commands = new ArrayList<Message>(); // synchronized
SampleView sampleView; private SampleView sampleView;
public MessageQueue(SampleView sampleView) { public MessageQueue(SampleView sampleView) {
this.sampleView = sampleView; this.sampleView = sampleView;
@@ -64,7 +64,7 @@ public class MessageQueue implements Runnable {
return running; return running;
} }
void SendCommands(final int contextId) throws IOException { private void SendCommands(final int contextId) throws IOException {
synchronized (commands) { synchronized (commands) {
for (int i = 0; i < commands.size(); i++) { for (int i = 0; i < commands.size(); i++) {
Message command = commands.get(i); Message command = commands.get(i);
@@ -86,7 +86,7 @@ public class MessageQueue implements Runnable {
// access call chain starts with run() // access call chain starts with run()
private DataInputStream dis = null; private DataInputStream dis = null;
private DataOutputStream dos = null; private DataOutputStream dos = null;
private HashMap<Integer, ArrayList<Message>> incoming = new HashMap<Integer, ArrayList<Message>>(); private SparseArray<ArrayList<Message>> incoming = new SparseArray<ArrayList<Message>>();
@Override @Override
public void run() { public void run() {
@@ -118,11 +118,13 @@ public class MessageQueue implements Runnable {
Message msg = null; Message msg = null;
if (incoming.size() > 0) { // find queued incoming if (incoming.size() > 0) { // find queued incoming
for (ArrayList<Message> messages : incoming.values()) for (int i = 0; i < incoming.size(); i++) {
final ArrayList<Message> messages = incoming.valueAt(i);
if (messages.size() > 0) { if (messages.size() > 0) {
msg = messages.remove(0); msg = messages.remove(0);
break; break;
} }
}
} }
try { try {
if (null == msg) // get incoming from network if (null == msg) // get incoming from network
@@ -167,8 +169,8 @@ public class MessageQueue implements Runnable {
SendMessage(dos, msg); SendMessage(dos, msg);
} }
// should only used by DefaultProcessMessage // should only be used by DefaultProcessMessage
private HashMap<Integer, Message> partials = new HashMap<Integer, Message>(); private SparseArray<Message> partials = new SparseArray<Message>();
Message GetPartialMessage(final int contextId) { Message GetPartialMessage(final int contextId) {
return partials.get(contextId); return partials.get(contextId);
@@ -176,7 +178,8 @@ public class MessageQueue implements Runnable {
// used to add BeforeCall to complete if it was skipped // used to add BeforeCall to complete if it was skipped
void CompletePartialMessage(final int contextId) { void CompletePartialMessage(final int contextId) {
final Message msg = partials.remove(contextId); final Message msg = partials.get(contextId);
partials.remove(contextId);
assert msg != null; assert msg != null;
assert msg.getType() == Type.BeforeCall; assert msg.getType() == Type.BeforeCall;
synchronized (complete) { synchronized (complete) {
@@ -189,29 +192,44 @@ public class MessageQueue implements Runnable {
boolean sendResponse) boolean sendResponse)
throws IOException { throws IOException {
final int contextId = msg.getContextId(); final int contextId = msg.getContextId();
final Message.Builder builder = Message.newBuilder();
builder.setContextId(contextId);
builder.setType(Type.Response);
builder.setExpectResponse(expectResponse);
if (msg.getType() == Type.BeforeCall) { if (msg.getType() == Type.BeforeCall) {
if (sendResponse) { if (sendResponse) {
final Message.Builder builder = Message.newBuilder();
builder.setContextId(contextId);
builder.setType(Type.Response);
builder.setExpectResponse(expectResponse);
builder.setFunction(Function.CONTINUE); builder.setFunction(Function.CONTINUE);
SendMessage(dos, builder.build()); SendMessage(dos, builder.build());
} }
assert !partials.containsKey(contextId); assert partials.indexOfKey(contextId) < 0;
partials.put(contextId, msg); partials.put(contextId, msg);
} else if (msg.getType() == Type.AfterCall) { } else if (msg.getType() == Type.AfterCall) {
if (sendResponse) { if (sendResponse) {
builder.setFunction(Function.CONTINUE); final Message.Builder builder = Message.newBuilder();
builder.setContextId(contextId);
builder.setType(Type.Response);
builder.setExpectResponse(expectResponse);
builder.setFunction(Function.SKIP);
SendMessage(dos, builder.build()); SendMessage(dos, builder.build());
} }
assert partials.containsKey(contextId); assert partials.indexOfKey(contextId) >= 0;
final Message before = partials.remove(contextId); final Message before = partials.get(contextId);
partials.remove(contextId);
assert before.getFunction() == msg.getFunction(); assert before.getFunction() == msg.getFunction();
final Message completed = before.toBuilder().mergeFrom(msg).build(); final Message completed = before.toBuilder().mergeFrom(msg)
.setType(Type.CompleteCall).build();
synchronized (complete) { synchronized (complete) {
complete.add(completed); complete.add(completed);
} }
} else if (msg.getType() == Type.CompleteCall) {
// this type should only be encountered on client after processing
assert file != null;
assert !msg.getExpectResponse();
assert !sendResponse;
assert partials.indexOfKey(contextId) < 0;
synchronized (complete) {
complete.add(msg);
}
} else } else
assert false; assert false;
} }
@@ -265,6 +283,8 @@ 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 {
if (dos == null)
return;
assert message.getFunction() != Function.NEG; assert message.getFunction() != Function.NEG;
final byte[] data = message.toByteArray(); final byte[] data = message.toByteArray();
if (byteOrder == ByteOrder.BIG_ENDIAN) if (byteOrder == ByteOrder.BIG_ENDIAN)

View File

@@ -75,12 +75,7 @@ import org.eclipse.ui.part.ViewPart;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.text.SimpleDateFormat;
import java.util.Calendar;
/** /**
* This sample class demonstrates how to plug-in a new workbench view. The view * This sample class demonstrates how to plug-in a new workbench view. The view
@@ -148,7 +143,7 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
@Override @Override
public Object[] getElements(Object parent) { public Object[] getElements(Object parent) {
return frame.calls.toArray(); return frame.Get().toArray();
} }
@Override @Override
@@ -562,7 +557,11 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
public void run() public void run()
{ {
if (current != null) if (current != null)
{
new CodeGen().CodeGenFrame((Frame) viewer.getInput()); new CodeGen().CodeGenFrame((Frame) viewer.getInput());
// need to reload current frame
viewer.setInput(current.GetFrame(frameNum.getSelection()));
}
} }
}); });
@@ -572,7 +571,12 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
public void run() public void run()
{ {
if (current != null) if (current != null)
new CodeGen().CodeGenFrames(current, frameNum.getSelection() + 1); {
new CodeGen().CodeGenFrames(current, frameNum.getSelection() + 1,
getSite().getShell());
// need to reload current frame
viewer.setInput(current.GetFrame(frameNum.getSelection()));
}
} }
}); });
} }
@@ -626,8 +630,8 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
return; return;
if (frameNum.getSelection() == frameNum.getMaximum()) if (frameNum.getSelection() == frameNum.getMaximum())
return; // scale max cannot overlap min, so max is array size return; // scale max cannot overlap min, so max is array size
final Frame frame = current.frames.get(frameNum.getSelection()); final Frame frame = current.GetFrame(frameNum.getSelection());
final Context context = current.ComputeContext(frame, msgData); final Context context = frame.ComputeContext(msgData);
contextViewer.setInput(context); contextViewer.setInput(context);
if (null != msgData.image) { if (null != msgData.image) {
canvas.setBackgroundImage(msgData.image); canvas.setBackgroundImage(msgData.image);
@@ -686,46 +690,32 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
@Override @Override
public void run() { public void run() {
FileWriter file = null;
PrintWriter writer = null;
try {
file = new FileWriter("GLES2Debugger.log", true);
writer = new PrintWriter(file);
writer.write("\n\n");
writer.write(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance()
.getTime()));
writer.write("\n\n");
} catch (IOException e1) {
showError(e1);
}
int newMessages = 0; int newMessages = 0;
boolean shaderEditorUpdate = false, currentUpdate = false; boolean shaderEditorUpdate = false;
while (running) { while (running) {
final Message oriMsg = messageQueue.RemoveCompleteMessage(0); final Message oriMsg = messageQueue.RemoveCompleteMessage(0);
if (oriMsg == null && !messageQueue.IsRunning()) if (oriMsg == null && !messageQueue.IsRunning())
break; break;
if (newMessages > 60 || (newMessages > 0 && null == oriMsg)) { if (newMessages > 60 || (newMessages > 0 && null == oriMsg)) {
newMessages = 0; newMessages = 0;
if (current == null || current.uiUpdate)
if (currentUpdate || current == null)
getSite().getShell().getDisplay().syncExec(new Runnable() { getSite().getShell().getDisplay().syncExec(new Runnable() {
@Override @Override
public void run() { public void run() {
if (current == null) if (current == null)
ChangeContext(debugContexts.valueAt(0)); ChangeContext(debugContexts.valueAt(0));
else if (frameNum.getSelection() == current.frames.size() - 1) else if (frameNum.getSelection() == current.FrameCount() - 1)
{ {
viewer.refresh(false); viewer.refresh(false);
if (actionAutoScroll.isChecked()) if (actionAutoScroll.isChecked())
viewer.getList().setSelection( viewer.getList().setSelection(
viewer.getList().getItemCount() - 1); viewer.getList().getItemCount() - 1);
} }
frameNum.setMaximum(current.frames.size()); frameNum.setMaximum(current.FrameCount());
} }
}); });
currentUpdate = false; current.uiUpdate = false;
if (shaderEditorUpdate) if (shaderEditorUpdate)
this.getSite().getShell().getDisplay().syncExec(new Runnable() { this.getSite().getShell().getDisplay().syncExec(new Runnable() {
@@ -751,29 +741,15 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
debugContexts.put(oriMsg.getContextId(), debugContext); debugContexts.put(oriMsg.getContextId(), debugContext);
} }
final MessageData msgData = debugContext.ProcessMessage(oriMsg); debugContext.ProcessMessage(oriMsg);
if (current == debugContext) {
currentUpdate = true;
}
shaderEditorUpdate |= debugContext.currentContext.serverShader.uiUpdate; shaderEditorUpdate |= debugContext.currentContext.serverShader.uiUpdate;
debugContext.currentContext.serverShader.uiUpdate = false; debugContext.currentContext.serverShader.uiUpdate = false;
if (null != writer) {
writer.write(msgData.text + "\n");
if (msgData.msg.getFunction() == Function.eglSwapBuffers) {
writer.write("\n-------\n");
writer.flush();
}
}
newMessages++; newMessages++;
} }
if (running) if (running)
ConnectDisconnect(); // error occurred, disconnect ConnectDisconnect(); // error occurred, disconnect
if (null != writer) {
writer.flush();
writer.close();
}
} }
/** can be called from non-UI thread */ /** can be called from non-UI thread */
@@ -782,9 +758,9 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
@Override @Override
public void run() { public void run() {
current = newContext; current = newContext;
frameNum.setMaximum(current.frames.size()); frameNum.setMaximum(current.FrameCount());
frameNum.setSelection(0); frameNum.setSelection(0);
viewer.setInput(current.frames.get(frameNum.getSelection())); viewer.setInput(current.GetFrame(frameNum.getSelection()));
shaderEditor.Update(); shaderEditor.Update();
actContext.setText("Context: 0x" + Integer.toHexString(current.contextId)); actContext.setText("Context: 0x" + Integer.toHexString(current.contextId));
getViewSite().getActionBars().getToolBarManager().update(true); getViewSite().getActionBars().getToolBarManager().update(true);
@@ -798,9 +774,9 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
assert false; assert false;
if (current == null) if (current == null)
return; return;
if (frameNum.getSelection() == current.frames.size()) if (frameNum.getSelection() == current.FrameCount())
return; // scale maximum cannot overlap minimum return; // scale maximum cannot overlap minimum
Frame frame = current.frames.get(frameNum.getSelection()); Frame frame = current.GetFrame(frameNum.getSelection());
viewer.setInput(frame); viewer.setInput(frame);
} }

View File

@@ -95,6 +95,7 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend
gridData.grabExcessHorizontalSpace = true; gridData.grabExcessHorizontalSpace = true;
gridData.verticalAlignment = SWT.FILL; gridData.verticalAlignment = SWT.FILL;
gridData.grabExcessVerticalSpace = true; gridData.grabExcessVerticalSpace = true;
gridData.verticalSpan = 2;
styledText.setLayoutData(gridData); styledText.setLayoutData(gridData);
styledText.addExtendedModifyListener(this); styledText.addExtendedModifyListener(this);
} }