Added state tracking and vertex data capturing.
Change-Id: I91604740aa73a5611f0eb511d02f09a767273700 Signed-off-by: David Li <davidxli@google.com>
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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())));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<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 @@ public class MessageQueue implements Runnable {
|
||||
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 @@ 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<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 @@ 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<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) {
|
||||
|
||||
@@ -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<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 @@ 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();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user