From 8b2eabd60deaaa1c8198dacba382f793503bed2b Mon Sep 17 00:00:00 2001 From: David Li Date: Tue, 8 Mar 2011 16:57:24 -0800 Subject: [PATCH] Added state tracking and vertex data capturing. Change-Id: I91604740aa73a5611f0eb511d02f09a767273700 Signed-off-by: David Li --- .../com/android/glesv2debugger/Activator.java | 2 + .../glesv2debugger/GLServerVertex.java | 348 ++++++++++++++++++ .../android/glesv2debugger/MessageData.java | 26 +- .../glesv2debugger/MessageProcessor.java | 28 +- .../android/glesv2debugger/MessageQueue.java | 196 +++++++--- .../android/glesv2debugger/SampleView.java | 90 ++++- 6 files changed, 610 insertions(+), 80 deletions(-) create mode 100644 tools/glesv2debugger/src/com/android/glesv2debugger/GLServerVertex.java diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/Activator.java b/tools/glesv2debugger/src/com/android/glesv2debugger/Activator.java index f859510d5..6083c0f9c 100755 --- a/tools/glesv2debugger/src/com/android/glesv2debugger/Activator.java +++ b/tools/glesv2debugger/src/com/android/glesv2debugger/Activator.java @@ -43,6 +43,7 @@ public class Activator extends AbstractUIPlugin { * 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 @@ public class Activator extends AbstractUIPlugin { * 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 000000000..0ff03475b --- /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 buffers; + GLBuffer attribBuffer, indexBuffer; // current binding + GLAttribPointer attribPointers[]; + float defaultAttribs[][]; + int maxAttrib; + + public GLServerVertex() { + buffers = new HashMap(); + 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 729592e70..110c6f8b9 100644 --- a/tools/glesv2debugger/src/com/android/glesv2debugger/MessageData.java +++ b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageData.java @@ -25,8 +25,10 @@ public class MessageData { 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 @@ public class MessageData { 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 @@ public class MessageData { 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 0c4a0053a..da6a9b839 100644 --- a/tools/glesv2debugger/src/com/android/glesv2debugger/MessageProcessor.java +++ b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageProcessor.java @@ -126,23 +126,25 @@ public class MessageProcessor { 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 9f91d404b..afa7e91ea 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 @@ public class MessageQueue implements Runnable { ArrayList commands = new ArrayList(); SampleView sampleView; + HashMap serversVertex = new HashMap(); + public MessageQueue(SampleView sampleView) { this.sampleView = sampleView; } @@ -95,19 +96,20 @@ public class MessageQueue implements Runnable { Error(e); } - try { - while (running) { - DebuggerMessage.Message msg = null; - if (incoming.size() > 0) { // find queued incoming - for (ArrayList messages : incoming + // try { + while (running) { + DebuggerMessage.Message msg = null; + if (incoming.size() > 0) { // find queued incoming + for (ArrayList 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 @@ public class MessageQueue implements Runnable { // 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()); - // 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 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 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 @@ public class MessageQueue implements Runnable { 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()); - 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()); + 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 05fe51bbd..41a0bb2b9 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.TableViewer; 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.ScrollBar; 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 @@ public class SampleView extends ViewPart implements Runnable { TableViewer viewer; org.eclipse.swt.widgets.Canvas canvas; + Text text; Action actionConnect; // connect / disconnect Action doubleClickAction; Action actionAutoScroll; @@ -131,7 +136,6 @@ public class SampleView extends ViewPart implements Runnable { @Override public void inputChanged(Viewer v, Object oldInput, Object newInput) { - // showMessage("ViewContentProvider::inputChanged"); } @Override @@ -251,8 +255,35 @@ public class SampleView extends ViewPart implements Runnable { 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 controls = new ArrayList(); + for (int i = 0; i < children.length; i++) + if (children[i].isVisible()) + controls.add(children[i]); + children = new Control[controls.size()]; + return controls.toArray(children); + } + + } + + 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 @@ public class SampleView extends ViewPart implements Runnable { 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 @@ public class SampleView extends ViewPart implements Runnable { 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 @@ public class SampleView extends ViewPart implements Runnable { 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(); + } } });