Added state tracking and vertex data capturing.
Change-Id: I91604740aa73a5611f0eb511d02f09a767273700
Signed-off-by: David Li <davidxli@google.com>
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/Activator.java b/tools/glesv2debugger/src/com/android/glesv2debugger/Activator.java
index f859510..6083c0f 100755
--- a/tools/glesv2debugger/src/com/android/glesv2debugger/Activator.java
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/Activator.java
@@ -43,6 +43,7 @@
* org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
* )
*/
+ @Override
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
@@ -54,6 +55,7 @@
* org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
* )
*/
+ @Override
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/GLServerVertex.java b/tools/glesv2debugger/src/com/android/glesv2debugger/GLServerVertex.java
new file mode 100644
index 0000000..0ff0347
--- /dev/null
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/GLServerVertex.java
@@ -0,0 +1,348 @@
+/*
+ ** Copyright 2011, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+package com.android.glesv2debugger;
+
+import com.android.glesv2debugger.DebuggerMessage.Message;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+
+class GLBuffer {
+ GLEnum usage;
+ GLEnum target;
+ ByteBuffer data;
+}
+
+class GLAttribPointer {
+ int size; // number of values per vertex
+ GLEnum type; // data type
+ int stride; // bytes
+ int ptr; // pointer in debugger server or byte offset into buffer
+ GLBuffer buffer;
+ boolean normalized;
+ boolean enabled;
+}
+
+public class GLServerVertex {
+
+ HashMap<Integer, GLBuffer> buffers;
+ GLBuffer attribBuffer, indexBuffer; // current binding
+ GLAttribPointer attribPointers[];
+ float defaultAttribs[][];
+ int maxAttrib;
+
+ public GLServerVertex() {
+ buffers = new HashMap<Integer, GLBuffer>();
+ buffers.put(0, null);
+ attribPointers = new GLAttribPointer[16];
+ for (int i = 0; i < attribPointers.length; i++)
+ attribPointers[i] = new GLAttribPointer();
+ defaultAttribs = new float[16][4];
+ for (int i = 0; i < defaultAttribs.length; i++) {
+ defaultAttribs[i][0] = 0;
+ defaultAttribs[i][1] = 0;
+ defaultAttribs[i][2] = 0;
+ defaultAttribs[i][3] = 1;
+ }
+ }
+
+ // void API_ENTRY(glBindBuffer)(GLenum target, GLuint buffer)
+ public void glBindBuffer(Message msg) {
+ if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ARRAY_BUFFER) {
+ attribBuffer = buffers.get(msg.getArg1());
+ if (null != attribBuffer)
+ attribBuffer.target = GLEnum.GL_ARRAY_BUFFER;
+ } else if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ELEMENT_ARRAY_BUFFER) {
+ indexBuffer = buffers.get(msg.getArg1());
+ if (null != indexBuffer)
+ indexBuffer.target = GLEnum.GL_ELEMENT_ARRAY_BUFFER;
+ } else
+ assert false;
+ }
+
+ // void API_ENTRY(glBufferData)(GLenum target, GLsizeiptr size, const
+ // GLvoid:size:in data, GLenum usage)
+ public void glBufferData(Message msg) {
+ if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ARRAY_BUFFER) {
+ attribBuffer.usage = GLEnum.valueOf(msg.getArg3());
+ attribBuffer.data = msg.getData().asReadOnlyByteBuffer();
+ } else if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ELEMENT_ARRAY_BUFFER) {
+ indexBuffer.usage = GLEnum.valueOf(msg.getArg3());
+ indexBuffer.data = msg.getData().asReadOnlyByteBuffer();
+ } else
+ assert false;
+ }
+
+ // void API_ENTRY(glBufferSubData)(GLenum target, GLintptr offset,
+ // GLsizeiptr size, const GLvoid:size:in data)
+ public void glBufferSubData(Message msg) {
+ if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ARRAY_BUFFER) {
+ if (attribBuffer.data.isReadOnly()) {
+ ByteBuffer buffer = ByteBuffer.allocate(attribBuffer.data.capacity());
+ buffer.put(attribBuffer.data);
+ attribBuffer.data = buffer;
+ }
+ attribBuffer.data.position(msg.getArg1());
+ attribBuffer.data.put(msg.getData().asReadOnlyByteBuffer());
+ } else if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ELEMENT_ARRAY_BUFFER) {
+ if (indexBuffer.data.isReadOnly()) {
+ ByteBuffer buffer = ByteBuffer.allocate(indexBuffer.data.capacity());
+ buffer.put(indexBuffer.data);
+ indexBuffer.data = buffer;
+ }
+ indexBuffer.data.position(msg.getArg1());
+ indexBuffer.data.put(msg.getData().asReadOnlyByteBuffer());
+ } else
+ assert false;
+ }
+
+ // void glDeleteBuffers(GLsizei n, const GLuint* buffers)
+ public void glDeleteBuffers(Message msg) {
+ final int n = msg.getArg0();
+ final ByteBuffer names = msg.getData().asReadOnlyByteBuffer();
+ for (int i = 0; i < n; i++) {
+ int name = Integer.reverseBytes(names.getInt());
+ GLBuffer buffer = buffers.get(name);
+ for (int j = 0; j < attribPointers.length; j++)
+ if (attribPointers[j].buffer == buffer) {
+ attribPointers[j].buffer = null;
+ attribPointers[j].enabled = false;
+ }
+ if (attribBuffer == buffer)
+ attribBuffer = null;
+ if (indexBuffer == buffer)
+ indexBuffer = null;
+ buffers.remove(name);
+ }
+ }
+
+ // void glDisableVertexAttribArray(GLuint index)
+ public void glDisableVertexAttribArray(Message msg) {
+ attribPointers[msg.getArg0()].enabled = false;
+ }
+
+ float FetchConvert(final ByteBuffer src, final GLEnum type, final boolean normalized) {
+ if (GLEnum.GL_FLOAT == type)
+ return Float.intBitsToFloat(Integer.reverseBytes(src.getInt()));
+ else if (GLEnum.GL_UNSIGNED_INT == type)
+ if (normalized)
+ return (Integer.reverseBytes(src.getInt()) & 0xffffffffL) / (2e32f - 1);
+ else
+ return Integer.reverseBytes(src.getInt()) & 0xffffffffL;
+ else if (GLEnum.GL_INT == type)
+ if (normalized)
+ return (Integer.reverseBytes(src.getInt()) * 2 + 1) / (2e32f - 1);
+ else
+ return Integer.reverseBytes(src.getInt());
+ else if (GLEnum.GL_UNSIGNED_SHORT == type)
+ if (normalized)
+ return (Short.reverseBytes(src.getShort()) & 0xffff) / (2e16f - 1);
+ else
+ return Short.reverseBytes(src.getShort()) & 0xffff;
+ else if (GLEnum.GL_SHORT == type)
+ if (normalized)
+ return (Short.reverseBytes(src.getShort()) * 2 + 1) / (2e16f - 1);
+ else
+ return Short.reverseBytes(src.getShort());
+ else if (GLEnum.GL_UNSIGNED_BYTE == type)
+ if (normalized)
+ return (src.get() & 0xff) / (2e8f - 1);
+ else
+ return src.get() & 0xff;
+ else if (GLEnum.GL_BYTE == type)
+ if (normalized)
+ return (src.get() * 2 + 1) / (2e8f - 1);
+ else
+ return src.get();
+ else if (GLEnum.GL_FIXED == type)
+ if (normalized)
+ return (Integer.reverseBytes(src.getInt()) * 2 + 1) / (2e32f - 1);
+ else
+ return Integer.reverseBytes(src.getInt()) / (2e16f);
+ else
+ assert false;
+ return 0;
+ }
+
+ void Fetch(int index, final ByteBuffer nonVBO, final ByteBuffer dst) {
+ for (int i = 0; i < maxAttrib; i++) {
+ final GLAttribPointer attrib = attribPointers[i];
+ int size = 0;
+ if (attrib.enabled)
+ size = attrib.size;
+ if (null != attrib.buffer) {
+ final ByteBuffer src = attrib.buffer.data;
+ src.position(attrib.ptr + i * attrib.stride);
+ dst.putFloat(FetchConvert(src, attrib.type, attrib.normalized));
+ } else
+ for (int j = 0; j < size; j++)
+ dst.putFloat(FetchConvert(nonVBO, attrib.type, attrib.normalized));
+ if (size < 1)
+ dst.putFloat(defaultAttribs[i][0]);
+ if (size < 2)
+ dst.putFloat(defaultAttribs[i][1]);
+ if (size < 3)
+ dst.putFloat(defaultAttribs[i][2]);
+ if (size < 4)
+ dst.putFloat(defaultAttribs[i][3]);
+ }
+ }
+
+ // void glDrawArrays(GLenum mode, GLint first, GLsizei count)
+ public Message glDrawArrays(Message msg) {
+ maxAttrib = msg.getArg7();
+ final int first = msg.getArg1(), count = msg.getArg2();
+ final ByteBuffer buffer = ByteBuffer.allocate(4 * 4 * maxAttrib * count);
+ ByteBuffer arrays = null;
+ if (msg.hasData()) // server sends user pointer attribs
+ arrays = msg.getData().asReadOnlyByteBuffer();
+ for (int i = first; i < first + count; i++)
+ Fetch(i, arrays, buffer);
+ assert null == arrays || arrays.remaining() == 0;
+ buffer.rewind();
+ return msg.toBuilder().setData(com.google.protobuf.ByteString.copyFrom(buffer))
+ .setArg8(GLEnum.GL_FLOAT.value).build();
+ }
+
+ // void glDrawElements(GLenum mode, GLsizei count, GLenum type, const
+ // GLvoid* indices)
+ public Message glDrawElements(Message msg) {
+ maxAttrib = msg.getArg7();
+ final int count = msg.getArg1();
+ final GLEnum type = GLEnum.valueOf(msg.getArg2());
+ final ByteBuffer buffer = ByteBuffer.allocate(4 * 4 * maxAttrib * count);
+ ByteBuffer arrays = null, index = null;
+ if (msg.hasData()) // server sends user pointer attribs
+ arrays = msg.getData().asReadOnlyByteBuffer();
+ if (null == indexBuffer)
+ index = arrays; // server also interleaves user pointer indices
+ else {
+ index = indexBuffer.data;
+ index.position(msg.getArg3());
+ }
+ if (GLEnum.GL_UNSIGNED_SHORT == type)
+ for (int i = 0; i < count; i++)
+ Fetch(Short.reverseBytes(index.getShort()) & 0xffff, arrays, buffer);
+ else if (GLEnum.GL_UNSIGNED_BYTE == type)
+ for (int i = 0; i < count; i++)
+ Fetch(index.get() & 0xff, arrays, buffer);
+ else
+ assert false;
+ assert null == arrays || arrays.remaining() == 0;
+ buffer.rewind();
+ return msg.toBuilder().setData(com.google.protobuf.ByteString.copyFrom(buffer))
+ .setArg8(GLEnum.GL_FLOAT.value).build();
+ }
+
+ // void glEnableVertexAttribArray(GLuint index)
+ public void glEnableVertexAttribArray(Message msg) {
+ attribPointers[msg.getArg0()].enabled = true;
+ }
+
+ // void API_ENTRY(glGenBuffers)(GLsizei n, GLuint:n:out buffers)
+ public void glGenBuffers(Message msg) {
+ final int n = msg.getArg0();
+ final ByteBuffer buffer = msg.getData().asReadOnlyByteBuffer();
+ for (int i = 0; i < n; i++) {
+ int name = Integer.reverseBytes(buffer.getInt());
+ if (!buffers.containsKey(name))
+ buffers.put(name, new GLBuffer());
+ }
+ }
+
+ // void glVertexAttribPointer(GLuint index, GLint size, GLenum type,
+ // GLboolean normalized, GLsizei stride, const GLvoid* ptr)
+ public void glVertexAttribPointer(Message msg) {
+ GLAttribPointer attrib = attribPointers[msg.getArg0()];
+ attrib.size = msg.getArg1();
+ attrib.type = GLEnum.valueOf(msg.getArg2());
+ attrib.normalized = msg.getArg3() != 0;
+ attrib.stride = msg.getArg4();
+ if (0 == attrib.stride)
+ attrib.stride = attrib.size * 4;
+ attrib.ptr = msg.getArg5();
+ attrib.buffer = attribBuffer;
+ }
+
+ // void glVertexAttrib1f(GLuint indx, GLfloat x)
+ public void glVertexAttrib1f(Message msg) {
+ glVertexAttrib4f(msg.getArg0(), Float.intBitsToFloat(Integer.reverseBytes(msg.getArg1())),
+ 0, 0, 1);
+ }
+
+ // void glVertexAttrib1fv(GLuint indx, const GLfloat* values)
+ public void glVertexAttrib1fv(Message msg) {
+ final ByteBuffer values = msg.getData().asReadOnlyByteBuffer();
+ glVertexAttrib4f(msg.getArg0(),
+ Float.intBitsToFloat(Integer.reverseBytes(values.getInt())),
+ 0, 0, 1);
+ }
+
+ // void glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
+ public void glVertexAttrib2f(Message msg) {
+ glVertexAttrib4f(msg.getArg0(), Float.intBitsToFloat(Integer.reverseBytes(msg.getArg1())),
+ Float.intBitsToFloat(Integer.reverseBytes(msg.getArg2())), 0, 1);
+ }
+
+ // void glVertexAttrib2fv(GLuint indx, const GLfloat* values)
+ public void glVertexAttrib2fv(Message msg) {
+ final ByteBuffer values = msg.getData().asReadOnlyByteBuffer();
+ glVertexAttrib4f(msg.getArg0(),
+ Float.intBitsToFloat(Integer.reverseBytes(values.getInt())),
+ Float.intBitsToFloat(Integer.reverseBytes(values.getInt())), 0, 1);
+ }
+
+ // void glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
+ public void glVertexAttrib3f(Message msg) {
+ glVertexAttrib4f(msg.getArg0(), Float.intBitsToFloat(Integer.reverseBytes(msg.getArg1())),
+ Float.intBitsToFloat(Integer.reverseBytes(msg.getArg2())),
+ Float.intBitsToFloat(Integer.reverseBytes(msg.getArg3())), 1);
+ }
+
+ // void glVertexAttrib3fv(GLuint indx, const GLfloat* values)
+ public void glVertexAttrib3fv(Message msg) {
+ final ByteBuffer values = msg.getData().asReadOnlyByteBuffer();
+ glVertexAttrib4f(msg.getArg0(),
+ Float.intBitsToFloat(Integer.reverseBytes(values.getInt())),
+ Float.intBitsToFloat(Integer.reverseBytes(values.getInt())),
+ Float.intBitsToFloat(Integer.reverseBytes(values.getInt())), 1);
+ }
+
+ public void glVertexAttrib4f(Message msg) {
+ glVertexAttrib4f(msg.getArg0(), Float.intBitsToFloat(Integer.reverseBytes(msg.getArg1())),
+ Float.intBitsToFloat(Integer.reverseBytes(msg.getArg2())),
+ Float.intBitsToFloat(Integer.reverseBytes(msg.getArg3())),
+ Float.intBitsToFloat(Integer.reverseBytes(msg.getArg4())));
+ }
+
+ void glVertexAttrib4f(int indx, float x, float y, float z, float w) {
+ defaultAttribs[indx][0] = x;
+ defaultAttribs[indx][1] = y;
+ defaultAttribs[indx][2] = z;
+ defaultAttribs[indx][3] = w;
+ }
+
+ // void glVertexAttrib4fv(GLuint indx, const GLfloat* values)
+ public void glVertexAttrib4fv(Message msg) {
+ final ByteBuffer values = msg.getData().asReadOnlyByteBuffer();
+ glVertexAttrib4f(msg.getArg0(),
+ Float.intBitsToFloat(Integer.reverseBytes(values.getInt())),
+ Float.intBitsToFloat(Integer.reverseBytes(values.getInt())),
+ Float.intBitsToFloat(Integer.reverseBytes(values.getInt())),
+ Float.intBitsToFloat(Integer.reverseBytes(values.getInt())));
+ }
+}
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/MessageData.java b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageData.java
index 729592e..110c6f8 100644
--- a/tools/glesv2debugger/src/com/android/glesv2debugger/MessageData.java
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageData.java
@@ -25,8 +25,10 @@
public Image image; // texture
public String shader; // shader source
public String[] columns;
- public float[] data; // vertex attributes
-
+ public float[] data;
+ public int maxAttrib; // used for formatting data
+ public GLEnum dataType; // could be float, int; mainly for formatting use
+
public MessageData(final Device device, final DebuggerMessage.Message msg) {
image = null;
shader = null;
@@ -46,11 +48,13 @@
columns[2] = Integer.toHexString(msg.getContextId());
columns[3] = MessageFormatter.Format(msg);
switch (function) {
- case glBufferData:
- data = MessageProcessor.ReceiveData(msg.getArg0(), msg.getData());
- break;
- case glBufferSubData:
- data = MessageProcessor.ReceiveData(msg.getArg0(), msg.getData());
+ case glDrawArrays: // msg was modified by GLServerVertex
+ case glDrawElements:
+ if (!msg.hasArg8() || !msg.hasData())
+ break;
+ dataType = GLEnum.valueOf(msg.getArg8());
+ maxAttrib = msg.getArg7();
+ data = MessageProcessor.ReceiveData(dataType, msg.getData());
break;
case glShaderSource:
shader = msg.getData().toStringUtf8();
@@ -76,6 +80,14 @@
break;
image = new Image(device, imageData);
break;
+ case glCopyTexImage2D:
+ imageData = MessageProcessor.ReceiveImage(msg.getArg5(), msg.getArg6(), GLEnum.GL_RGBA.value, GLEnum.GL_UNSIGNED_BYTE.value, msg.getData().toByteArray());
+ image = new Image(device, imageData);
+ break;
+ case glCopyTexSubImage2D:
+ imageData = MessageProcessor.ReceiveImage(msg.getArg6(), msg.getArg7(), GLEnum.GL_RGBA.value, GLEnum.GL_UNSIGNED_BYTE.value, msg.getData().toByteArray());
+ image = new Image(device, imageData);
+ break;
case glReadPixels:
if (!msg.hasData())
break;
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/MessageProcessor.java b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageProcessor.java
index 0c4a005..da6a9b8 100644
--- a/tools/glesv2debugger/src/com/android/glesv2debugger/MessageProcessor.java
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageProcessor.java
@@ -126,23 +126,25 @@
return new ImageData(width, height, bpp, palette, 1, data);
}
- static public float[] ReceiveData(int target, final ByteString data) {
- ByteBuffer buffer = data.asReadOnlyByteBuffer();
- GLEnum type = GLEnum.valueOf(target);
- if (type == GLEnum.GL_ARRAY_BUFFER) {
+ static public float[] ReceiveData(final GLEnum type, final ByteString data) {
+ final ByteBuffer buffer = data.asReadOnlyByteBuffer();
+ if (type == GLEnum.GL_FLOAT) {
float[] elements = new float[buffer.remaining() / 4];
- buffer.asFloatBuffer().get(elements);
+ for (int i = 0; i < elements.length; i++)
+ elements[i] = buffer.getFloat();
return elements;
- } else if (type == GLEnum.GL_ELEMENT_ARRAY_BUFFER) {
- // usually unsigned short
+ } else if (type == GLEnum.GL_UNSIGNED_SHORT) {
float[] elements = new float[buffer.remaining() / 2];
- for (int i = 0; i < elements.length; i++) {
- int bits = Short.reverseBytes(buffer.getShort()) & 0xffff;
- elements[i] = bits;
- }
+ for (int i = 0; i < elements.length; i++)
+ elements[i] = buffer.getShort() & 0xffff;
+ return elements;
+ } else if (type == GLEnum.GL_UNSIGNED_BYTE) {
+ float[] elements = new float[buffer.remaining() / 4];
+ for (int i = 0; i < elements.length; i++)
+ elements[i] = buffer.get() & 0xff;
return elements;
} else
- return null;
-
+ assert false;
+ return null;
}
}
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/MessageQueue.java b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageQueue.java
index 9f91d40..afa7e91 100644
--- a/tools/glesv2debugger/src/com/android/glesv2debugger/MessageQueue.java
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageQueue.java
@@ -16,13 +16,12 @@
package com.android.glesv2debugger;
-import com.android.glesv2debugger.DebuggerMessage.Message.Function;
import com.android.glesv2debugger.DebuggerMessage.Message.Type;
-import java.io.EOFException;
-import java.io.IOException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
@@ -35,6 +34,8 @@
ArrayList<DebuggerMessage.Message> commands = new ArrayList<DebuggerMessage.Message>();
SampleView sampleView;
+ HashMap<Integer, GLServerVertex> serversVertex = new HashMap<Integer, GLServerVertex>();
+
public MessageQueue(SampleView sampleView) {
this.sampleView = sampleView;
}
@@ -95,19 +96,20 @@
Error(e);
}
- try {
- while (running) {
- DebuggerMessage.Message msg = null;
- if (incoming.size() > 0) { // find queued incoming
- for (ArrayList<DebuggerMessage.Message> messages : incoming
+ // try {
+ while (running) {
+ DebuggerMessage.Message msg = null;
+ if (incoming.size() > 0) { // find queued incoming
+ for (ArrayList<DebuggerMessage.Message> messages : incoming
.values())
- if (messages.size() > 0) {
- msg = messages.get(0);
- messages.remove(0);
- break;
- }
- }
- if (null == msg) { // get incoming from network
+ if (messages.size() > 0) {
+ msg = messages.get(0);
+ messages.remove(0);
+ break;
+ }
+ }
+ if (null == msg) { // get incoming from network
+ try {
msg = ReadMessage(dis);
if (msg.getExpectResponse()) {
if (msg.getType() == Type.BeforeCall)
@@ -119,28 +121,34 @@
// SendResponse(dos, msg.getContextId(),
// DebuggerMessage.Message.Function.SKIP);
else if (msg.getType() == Type.Response)
- ;
+ assert true;
else
assert false;
}
+ } catch (IOException e) {
+ Error(e);
+ running = false;
+ break;
}
+ }
- int contextId = msg.getContextId();
- if (!incoming.containsKey(contextId))
- incoming.put(contextId,
+ int contextId = msg.getContextId();
+ if (!incoming.containsKey(contextId))
+ incoming.put(contextId,
new ArrayList<DebuggerMessage.Message>());
- // FIXME: the expected sequence will change for interactive mode
- while (msg.getType() == Type.BeforeCall) {
- DebuggerMessage.Message next = null;
- // get existing message part for this context
- ArrayList<DebuggerMessage.Message> messages = incoming
+ // FIXME: the expected sequence will change for interactive mode
+ while (msg.getType() == Type.BeforeCall) {
+ DebuggerMessage.Message next = null;
+ // get existing message part for this context
+ ArrayList<DebuggerMessage.Message> messages = incoming
.get(contextId);
- if (messages.size() > 0) {
- next = messages.get(0);
- messages.remove(0);
- }
- if (null == next) { // read new part for message
+ if (messages.size() > 0) {
+ next = messages.get(0);
+ messages.remove(0);
+ }
+ if (null == next) { // read new part for message
+ try {
next = ReadMessage(dis);
if (next.getExpectResponse()) {
@@ -150,45 +158,123 @@
next.getContextId(),
DebuggerMessage.Message.Function.CONTINUE);
else if (next.getType() == Type.AfterCall)
- SendCommands(dos, 0); // FIXME: proper context id
+ SendCommands(dos, 0); // FIXME: proper context
+ // id
else if (msg.getType() == Type.Response)
- ;
+ assert true;
else
assert false;
}
-
- if (next.getContextId() != contextId) {
- // message part not for this context
- if (!incoming.containsKey(next.getContextId()))
- incoming.put(
- next.getContextId(),
- new ArrayList<DebuggerMessage.Message>());
- incoming.get(next.getContextId()).add(next);
- continue;
- }
+ } catch (IOException e) {
+ Error(e);
+ running = false;
+ break;
}
- DebuggerMessage.Message.Builder builder = msg.toBuilder();
- // builder.mergeFrom(next); seems to merge incorrectly
- if (next.hasRet())
- builder.setRet(next.getRet());
- if (next.hasTime())
- builder.setTime(next.getTime());
- if (next.hasData())
- builder.setData(next.getData());
- builder.setType(next.getType());
- msg = builder.build();
+ if (next.getContextId() != contextId) {
+ // message part not for this context
+ if (!incoming.containsKey(next.getContextId()))
+ incoming.put(
+ next.getContextId(),
+ new ArrayList<DebuggerMessage.Message>());
+ incoming.get(next.getContextId()).add(next);
+ continue;
+ }
}
- synchronized (complete) {
- complete.add(msg);
- }
+ DebuggerMessage.Message.Builder builder = msg.toBuilder();
+ // builder.mergeFrom(next); seems to merge incorrectly
+ if (next.hasRet())
+ builder.setRet(next.getRet());
+ if (next.hasTime())
+ builder.setTime(next.getTime());
+ if (next.hasData())
+ builder.setData(next.getData());
+ builder.setType(next.getType());
+ msg = builder.build();
}
+
+ GLServerVertex serverVertex = serversVertex.get(msg.getContextId());
+ if (null == serverVertex) {
+ serverVertex = new GLServerVertex();
+ serversVertex.put(msg.getContextId(), serverVertex);
+ }
+
+ // forward message to synchronize state
+ switch (msg.getFunction()) {
+ case glBindBuffer:
+ serverVertex.glBindBuffer(msg);
+ break;
+ case glBufferData:
+ serverVertex.glBufferData(msg);
+ break;
+ case glBufferSubData:
+ serverVertex.glBufferSubData(msg);
+ break;
+ case glDeleteBuffers:
+ serverVertex.glDeleteBuffers(msg);
+ break;
+ case glDrawArrays:
+ if (msg.hasArg7())
+ msg = serverVertex.glDrawArrays(msg);
+ break;
+ case glDrawElements:
+ if (msg.hasArg7())
+ msg = serverVertex.glDrawElements(msg);
+ break;
+ case glDisableVertexAttribArray:
+ serverVertex.glDisableVertexAttribArray(msg);
+ break;
+ case glEnableVertexAttribArray:
+ serverVertex.glEnableVertexAttribArray(msg);
+ break;
+ case glGenBuffers:
+ serverVertex.glGenBuffers(msg);
+ break;
+ case glVertexAttribPointer:
+ serverVertex.glVertexAttribPointer(msg);
+ break;
+ case glVertexAttrib1f:
+ serverVertex.glVertexAttrib1f(msg);
+ break;
+ case glVertexAttrib1fv:
+ serverVertex.glVertexAttrib1fv(msg);
+ break;
+ case glVertexAttrib2f:
+ serverVertex.glVertexAttrib2f(msg);
+ break;
+ case glVertexAttrib2fv:
+ serverVertex.glVertexAttrib2fv(msg);
+ break;
+ case glVertexAttrib3f:
+ serverVertex.glVertexAttrib3f(msg);
+ break;
+ case glVertexAttrib3fv:
+ serverVertex.glVertexAttrib3fv(msg);
+ break;
+ case glVertexAttrib4f:
+ serverVertex.glVertexAttrib4f(msg);
+ break;
+ case glVertexAttrib4fv:
+ serverVertex.glVertexAttrib4fv(msg);
+ break;
+ }
+
+ synchronized (complete) {
+ complete.add(msg);
+ }
+ }
+
+ try {
socket.close();
- } catch (Exception e) {
+ } catch (IOException e) {
Error(e);
running = false;
}
+ // } catch (Exception e) {
+ // Error(e);
+ // running = false;
+ // }
}
public DebuggerMessage.Message RemoveMessage(int contextId) {
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/SampleView.java b/tools/glesv2debugger/src/com/android/glesv2debugger/SampleView.java
index 05fe51b..41a0bb2 100755
--- a/tools/glesv2debugger/src/com/android/glesv2debugger/SampleView.java
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/SampleView.java
@@ -42,13 +42,16 @@
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
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;
@@ -56,6 +59,7 @@
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchActionConstants;
@@ -92,6 +96,7 @@
TableViewer viewer;
org.eclipse.swt.widgets.Canvas canvas;
+ Text text;
Action actionConnect; // connect / disconnect
Action doubleClickAction;
Action actionAutoScroll;
@@ -131,7 +136,6 @@
@Override
public void inputChanged(Viewer v, Object oldInput, Object newInput) {
- // showMessage("ViewContentProvider::inputChanged");
}
@Override
@@ -251,8 +255,35 @@
hookSelectionChanged();
contributeToActionBars();
- canvas = new Canvas(parent, SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE
+ 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);
+ }
+
+ }
+
+ LayoutComposite layoutComposite = new LayoutComposite(parent, 0);
+ layoutComposite.setLayout(new FillLayout());
+
+ text = new Text(layoutComposite, 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
+ | SWT.V_SCROLL | SWT.H_SCROLL);
+ canvas.setVisible(false);
+
final ScrollBar hBar = canvas.getHorizontalBar();
hBar.addListener(SWT.Selection, new Listener() {
@Override
@@ -383,7 +414,7 @@
shell, "Contains Filter",
"case sensitive substring or *",
actionFilter.getText(), null);
- if (dialog.OK == dialog.open()) {
+ if (Window.OK == dialog.open()) {
actionFilter.setText(dialog.getValue());
manager.update(true);
filters = dialog.getValue().split("\\|");
@@ -485,9 +516,13 @@
String str = "";
for (int i = 0; i < msgData.data.length; i++)
{
- str += str.format("%.2f", msgData.data[i]);
+ str += String.format("%f", msgData.data[i]);
+ if (i % (4 * msgData.maxAttrib) == (4 * msgData.maxAttrib - 1))
+ str += '\n';
+ else if (i % 4 == 3)
+ str += " -";
if (i < msgData.data.length - 1)
- str += ", ";
+ str += ' ';
}
showMessage(str);
}
@@ -515,12 +550,57 @@
if (null == selection)
return;
if (1 != selection.size())
+ {
+ Object[] objects = selection.toArray();
+ float totalTime = 0;
+ for (int i = 0; i < objects.length; i++)
+ {
+ MessageData msgData = (MessageData) objects[i];
+ if (null == msgData)
+ continue;
+ totalTime += Float.parseFloat(msgData.columns[1]);
+ }
+ viewer.getTable().getColumn(1).setText(Float.toString(totalTime));
return;
+ }
+ else
+ viewer.getTable().getColumn(1).setText("Elapsed (ms)");
MessageData msgData = (MessageData) selection.getFirstElement();
if (null == msgData)
return;
if (null != msgData.image)
+ {
+ text.setVisible(false);
+ canvas.setVisible(true);
canvas.setBackgroundImage(msgData.image);
+ canvas.getParent().layout();
+ }
+ else if (null != msgData.shader)
+ {
+ text.setText(msgData.shader);
+ text.setVisible(true);
+ canvas.setVisible(false);
+ text.getParent().layout();
+ }
+ else if (null != msgData.data)
+ {
+ String str = "";
+ for (int i = 0; i < msgData.data.length; i++)
+ {
+ str += String.format("%.3g", msgData.data[i]);
+ if (i % (4 * msgData.maxAttrib) == (4 * msgData.maxAttrib - 1))
+ str += '\n';
+ else if (i % 4 == 3)
+ str += " -";
+ if (i < msgData.data.length - 1)
+ str += ' ';
+ }
+
+ text.setText(str);
+ text.setVisible(true);
+ canvas.setVisible(false);
+ text.getParent().layout();
+ }
}
});