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.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.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.nio.ByteBuffer;
public class CodeGen {
public class CodeGen implements IRunnableWithProgress {
private FileWriter codeFile, makeFile, namesHeaderFile, namesSourceFile;
private PrintWriter code, make, namesHeader, namesSource;
private FileOutputStream dataOut;
@@ -65,7 +71,7 @@ public class CodeGen {
code.write(";CHKERR;\n");
return true;
}
assert msg.getArg2() == msg.getPixelFormat(); // TODO
// FIXME: check the texture format & type, and convert
s = "//" + MessageFormatter.Format(msg, true) + "\n";
s += String.format(
"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 <GLES2/gl2.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("extern const unsigned int FrameCount;\n");
namesHeader.write("extern const GLuint program_0;\n");
@@ -767,9 +773,16 @@ public class CodeGen {
renderbufferNames = null;
}
void CodeGenFrames(final DebugContext dbgCtx, int count) {
Context ctx = dbgCtx.frames.get(0).startContext.clone();
private DebugContext dbgCtx;
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);
progress.worked(1);
for (int i = 0; i < count; i++) {
try {
codeFile = new FileWriter("frame" + i + ".cpp", false);
@@ -782,9 +795,9 @@ public class CodeGen {
code.write("#include \"frame_names.h\"\n");
code.format("void Frame%d(){\n", i);
final Frame frame = dbgCtx.frames.get(i);
for (int j = 0; j < frame.calls.size(); j++) {
final MessageData msgData = frame.calls.get(j);
final Frame frame = dbgCtx.GetFrame(i);
for (int j = 0; j < frame.Size(); j++) {
final MessageData msgData = frame.Get(j);
code.format("/* frame function %d: %s %s*/\n", j, msgData.msg.getFunction(),
MessageFormatter.Format(msgData.msg, false));
ctx.ProcessMessage(msgData.oriMsg);
@@ -802,6 +815,7 @@ public class CodeGen {
e.printStackTrace();
assert false;
}
progress.worked(1);
}
for (int i = 0; i < count; i++)
namesHeader.format("void Frame%d();\n", i);
@@ -813,6 +827,25 @@ public class CodeGen {
namesSource.write("};\n");
namesSource.format("const unsigned int FrameCount = %d;\n", count);
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) {
@@ -828,8 +861,8 @@ public class CodeGen {
make.format(" frame0.cpp \\\n");
code.write("#include \"frame_names.h\"\n");
code.format("void Frame0(){\n");
for (int i = 0; i < frame.calls.size(); i++) {
final MessageData msgData = frame.calls.get(i);
for (int i = 0; i < frame.Size(); i++) {
final MessageData msgData = frame.Get(i);
code.format("/* frame function %d: %s %s*/\n", i, msgData.msg.getFunction(),
MessageFormatter.Format(msgData.msg, false));
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.widgets.Display;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
class Frame {
final Context startContext;
ArrayList<MessageData> calls = new ArrayList<MessageData>();
public final long filePosition;
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.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 {
boolean uiUpdate = false;
final int contextId;
Context currentContext;
ArrayList<Frame> frames = new ArrayList<Frame>(128);
private Frame currentFrame;
private ArrayList<Frame> frames = new ArrayList<Frame>(128);
private Frame lastFrame;
private Frame loadedFrame;
private RandomAccessFile file;
DebugContext(final int contextId) {
this.contextId = contextId;
currentContext = new Context(contextId);
frames.add(new Frame(currentContext));
currentFrame = frames.get(0);
try {
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) {
currentContext.ProcessMessage(oriMsg);
Message msg = oriMsg;
if (currentContext.processed != null)
msg = currentContext.processed;
currentContext.processed = null;
MessageData msgData = new MessageData(Display.getCurrent(), msg, oriMsg, currentContext);
msgData.attribs = currentContext.serverVertex.fetchedAttribs;
currentFrame.calls.add(msgData);
/** Writes oriMsg to file, and formats into MessageData for current frame */
void ProcessMessage(final Message oriMsg) {
synchronized (file) {
final byte[] data = oriMsg.toByteArray();
final ByteBuffer len = ByteBuffer.allocate(4);
len.order(SampleView.targetByteOrder);
len.putInt(data.length);
try {
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)
return msgData;
frames.add(currentFrame = new Frame(currentContext));
return msgData;
return;
synchronized (frames) {
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) {
Context ctx = frame.startContext.clone();
for (int i = 0; i < frame.calls.size(); i++)
if (call == frame.calls.get(i))
return ctx;
else
ctx.ProcessMessage(frame.calls.get(i).oriMsg);
assert false;
return ctx;
Frame GetFrame(int index) {
synchronized (frames) {
Frame newFrame = frames.get(index);
if (loadedFrame != null && loadedFrame != lastFrame && newFrame != loadedFrame) {
loadedFrame.Unload();
uiUpdate = true;
}
loadedFrame = newFrame;
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];
Message processed = null; // return; processed Message
public Context(int contextId) {
this.contextId = contextId;
shares.add(this);
@@ -115,6 +242,7 @@ public class Context implements Cloneable {
copy.serverShader = serverShader.clone(copy);
copy.serverState = serverState.clone();
copy.serverTexture = serverTexture.clone(copy);
copy.readPixelRef = readPixelRef.clone();
return copy;
} catch (CloneNotSupportedException e) {
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)) {
processed = serverVertex.processed;
return;
if (serverVertex.processed != null)
return serverVertex.processed;
else
return msg;
}
if (serverShader.ProcessMessage(msg))
return;
return msg;
if (serverState.ProcessMessage(msg))
return;
return 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))
return null;
final Message msg = (Message) entry.obj;
for (int i = 0; i <= sampleView.frameNum.getSelection(); i++) {
if (i == sampleView.current.frames.size())
switch (msg.getFunction()) {
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;
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

View File

@@ -448,6 +448,7 @@ public final class DebuggerMessage {
AfterCall(1, 1),
AfterGeneratedCall(2, 2),
Response(3, 3),
CompleteCall(4, 4),
;
@@ -459,6 +460,7 @@ public final class DebuggerMessage {
case 1: return AfterCall;
case 2: return AfterGeneratedCall;
case 3: return Response;
case 4: return CompleteCall;
default: return null;
}
}
@@ -490,10 +492,10 @@ public final class DebuggerMessage {
ReferencedImage(0, 0),
NonreferencedImage(1, 1),
;
public final int getNumber() { return value; }
public static DataType valueOf(int value) {
switch (value) {
case 0: return ReferencedImage;
@@ -501,7 +503,7 @@ public final class DebuggerMessage {
default: return null;
}
}
public static com.google.protobuf.Internal.EnumLiteMap<DataType>
internalGetValueMap() {
return internalValueMap;
@@ -513,17 +515,17 @@ public final class DebuggerMessage {
return DataType.valueOf(number)
; }
};
private final int index;
private final int value;
private DataType(int index, int value) {
this.index = index;
this.value = value;
}
// @@protoc_insertion_point(enum_scope:com.android.glesv2debugger.Message.DataType)
}
public enum Prop
implements com.google.protobuf.Internal.EnumLite {
Capture(0, 0),
@@ -676,21 +678,21 @@ public final class DebuggerMessage {
private com.android.glesv2debugger.DebuggerMessage.Message.DataType dataType_;
public boolean hasDataType() { return hasDataType; }
public com.android.glesv2debugger.DebuggerMessage.Message.DataType getDataType() { return dataType_; }
// optional int32 pixel_format = 24;
public static final int PIXEL_FORMAT_FIELD_NUMBER = 24;
private boolean hasPixelFormat;
private int pixelFormat_ = 0;
public boolean hasPixelFormat() { return hasPixelFormat; }
public int getPixelFormat() { return pixelFormat_; }
// optional int32 pixel_type = 25;
public static final int PIXEL_TYPE_FIELD_NUMBER = 25;
private boolean hasPixelType;
private int pixelType_ = 0;
public boolean hasPixelType() { return hasPixelType; }
public int getPixelType() { return pixelType_; }
// optional float time = 11;
public static final int TIME_FIELD_NUMBER = 11;
private boolean hasTime;
@@ -1513,7 +1515,7 @@ public final class DebuggerMessage {
result.dataType_ = com.android.glesv2debugger.DebuggerMessage.Message.DataType.ReferencedImage;
return this;
}
// optional int32 pixel_format = 24;
public boolean hasPixelFormat() {
return result.hasPixelFormat();
@@ -1531,7 +1533,7 @@ public final class DebuggerMessage {
result.pixelFormat_ = 0;
return this;
}
// optional int32 pixel_type = 25;
public boolean hasPixelType() {
return result.hasPixelType();
@@ -1549,7 +1551,7 @@ public final class DebuggerMessage {
result.pixelType_ = 0;
return this;
}
// optional float time = 11;
public boolean hasTime() {
return result.hasTime();

View File

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

View File

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

View File

@@ -75,12 +75,7 @@ import org.eclipse.ui.part.ViewPart;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
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
@@ -148,7 +143,7 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
@Override
public Object[] getElements(Object parent) {
return frame.calls.toArray();
return frame.Get().toArray();
}
@Override
@@ -562,7 +557,11 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
public void run()
{
if (current != null)
{
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()
{
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;
if (frameNum.getSelection() == frameNum.getMaximum())
return; // scale max cannot overlap min, so max is array size
final Frame frame = current.frames.get(frameNum.getSelection());
final Context context = current.ComputeContext(frame, msgData);
final Frame frame = current.GetFrame(frameNum.getSelection());
final Context context = frame.ComputeContext(msgData);
contextViewer.setInput(context);
if (null != msgData.image) {
canvas.setBackgroundImage(msgData.image);
@@ -686,46 +690,32 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
@Override
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;
boolean shaderEditorUpdate = false, currentUpdate = false;
boolean shaderEditorUpdate = false;
while (running) {
final Message oriMsg = messageQueue.RemoveCompleteMessage(0);
if (oriMsg == null && !messageQueue.IsRunning())
break;
if (newMessages > 60 || (newMessages > 0 && null == oriMsg)) {
newMessages = 0;
if (currentUpdate || current == null)
if (current == null || current.uiUpdate)
getSite().getShell().getDisplay().syncExec(new Runnable() {
@Override
public void run() {
if (current == null)
ChangeContext(debugContexts.valueAt(0));
else if (frameNum.getSelection() == current.frames.size() - 1)
else if (frameNum.getSelection() == current.FrameCount() - 1)
{
viewer.refresh(false);
if (actionAutoScroll.isChecked())
viewer.getList().setSelection(
viewer.getList().getItemCount() - 1);
}
frameNum.setMaximum(current.frames.size());
frameNum.setMaximum(current.FrameCount());
}
});
currentUpdate = false;
current.uiUpdate = false;
if (shaderEditorUpdate)
this.getSite().getShell().getDisplay().syncExec(new Runnable() {
@@ -751,29 +741,15 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
debugContexts.put(oriMsg.getContextId(), debugContext);
}
final MessageData msgData = debugContext.ProcessMessage(oriMsg);
if (current == debugContext) {
currentUpdate = true;
}
debugContext.ProcessMessage(oriMsg);
shaderEditorUpdate |= debugContext.currentContext.serverShader.uiUpdate;
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++;
}
if (running)
ConnectDisconnect(); // error occurred, disconnect
if (null != writer) {
writer.flush();
writer.close();
}
}
/** can be called from non-UI thread */
@@ -782,9 +758,9 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
@Override
public void run() {
current = newContext;
frameNum.setMaximum(current.frames.size());
frameNum.setMaximum(current.FrameCount());
frameNum.setSelection(0);
viewer.setInput(current.frames.get(frameNum.getSelection()));
viewer.setInput(current.GetFrame(frameNum.getSelection()));
shaderEditor.Update();
actContext.setText("Context: 0x" + Integer.toHexString(current.contextId));
getViewSite().getActionBars().getToolBarManager().update(true);
@@ -798,9 +774,9 @@ public class SampleView extends ViewPart implements Runnable, SelectionListener
assert false;
if (current == null)
return;
if (frameNum.getSelection() == current.frames.size())
if (frameNum.getSelection() == current.FrameCount())
return; // scale maximum cannot overlap minimum
Frame frame = current.frames.get(frameNum.getSelection());
Frame frame = current.GetFrame(frameNum.getSelection());
viewer.setInput(frame);
}

View File

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