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
|
* org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
|
||||||
* )
|
* )
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void start(BundleContext context) throws Exception {
|
public void start(BundleContext context) throws Exception {
|
||||||
super.start(context);
|
super.start(context);
|
||||||
plugin = this;
|
plugin = this;
|
||||||
@@ -54,6 +55,7 @@ public class Activator extends AbstractUIPlugin {
|
|||||||
* org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
|
* org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
|
||||||
* )
|
* )
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void stop(BundleContext context) throws Exception {
|
public void stop(BundleContext context) throws Exception {
|
||||||
plugin = null;
|
plugin = null;
|
||||||
super.stop(context);
|
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,7 +25,9 @@ public class MessageData {
|
|||||||
public Image image; // texture
|
public Image image; // texture
|
||||||
public String shader; // shader source
|
public String shader; // shader source
|
||||||
public String[] columns;
|
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) {
|
public MessageData(final Device device, final DebuggerMessage.Message msg) {
|
||||||
image = null;
|
image = null;
|
||||||
@@ -46,11 +48,13 @@ public class MessageData {
|
|||||||
columns[2] = Integer.toHexString(msg.getContextId());
|
columns[2] = Integer.toHexString(msg.getContextId());
|
||||||
columns[3] = MessageFormatter.Format(msg);
|
columns[3] = MessageFormatter.Format(msg);
|
||||||
switch (function) {
|
switch (function) {
|
||||||
case glBufferData:
|
case glDrawArrays: // msg was modified by GLServerVertex
|
||||||
data = MessageProcessor.ReceiveData(msg.getArg0(), msg.getData());
|
case glDrawElements:
|
||||||
|
if (!msg.hasArg8() || !msg.hasData())
|
||||||
break;
|
break;
|
||||||
case glBufferSubData:
|
dataType = GLEnum.valueOf(msg.getArg8());
|
||||||
data = MessageProcessor.ReceiveData(msg.getArg0(), msg.getData());
|
maxAttrib = msg.getArg7();
|
||||||
|
data = MessageProcessor.ReceiveData(dataType, msg.getData());
|
||||||
break;
|
break;
|
||||||
case glShaderSource:
|
case glShaderSource:
|
||||||
shader = msg.getData().toStringUtf8();
|
shader = msg.getData().toStringUtf8();
|
||||||
@@ -76,6 +80,14 @@ public class MessageData {
|
|||||||
break;
|
break;
|
||||||
image = new Image(device, imageData);
|
image = new Image(device, imageData);
|
||||||
break;
|
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:
|
case glReadPixels:
|
||||||
if (!msg.hasData())
|
if (!msg.hasData())
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -126,23 +126,25 @@ public class MessageProcessor {
|
|||||||
return new ImageData(width, height, bpp, palette, 1, data);
|
return new ImageData(width, height, bpp, palette, 1, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public float[] ReceiveData(int target, final ByteString data) {
|
static public float[] ReceiveData(final GLEnum type, final ByteString data) {
|
||||||
ByteBuffer buffer = data.asReadOnlyByteBuffer();
|
final ByteBuffer buffer = data.asReadOnlyByteBuffer();
|
||||||
GLEnum type = GLEnum.valueOf(target);
|
if (type == GLEnum.GL_FLOAT) {
|
||||||
if (type == GLEnum.GL_ARRAY_BUFFER) {
|
|
||||||
float[] elements = new float[buffer.remaining() / 4];
|
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;
|
return elements;
|
||||||
} else if (type == GLEnum.GL_ELEMENT_ARRAY_BUFFER) {
|
} else if (type == GLEnum.GL_UNSIGNED_SHORT) {
|
||||||
// usually unsigned short
|
|
||||||
float[] elements = new float[buffer.remaining() / 2];
|
float[] elements = new float[buffer.remaining() / 2];
|
||||||
for (int i = 0; i < elements.length; i++) {
|
for (int i = 0; i < elements.length; i++)
|
||||||
int bits = Short.reverseBytes(buffer.getShort()) & 0xffff;
|
elements[i] = buffer.getShort() & 0xffff;
|
||||||
elements[i] = bits;
|
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;
|
return elements;
|
||||||
} else
|
} else
|
||||||
|
assert false;
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,13 +16,12 @@
|
|||||||
|
|
||||||
package com.android.glesv2debugger;
|
package com.android.glesv2debugger;
|
||||||
|
|
||||||
import com.android.glesv2debugger.DebuggerMessage.Message.Function;
|
|
||||||
import com.android.glesv2debugger.DebuggerMessage.Message.Type;
|
import com.android.glesv2debugger.DebuggerMessage.Message.Type;
|
||||||
|
|
||||||
import java.io.EOFException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.EOFException;
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -35,6 +34,8 @@ public class MessageQueue implements Runnable {
|
|||||||
ArrayList<DebuggerMessage.Message> commands = new ArrayList<DebuggerMessage.Message>();
|
ArrayList<DebuggerMessage.Message> commands = new ArrayList<DebuggerMessage.Message>();
|
||||||
SampleView sampleView;
|
SampleView sampleView;
|
||||||
|
|
||||||
|
HashMap<Integer, GLServerVertex> serversVertex = new HashMap<Integer, GLServerVertex>();
|
||||||
|
|
||||||
public MessageQueue(SampleView sampleView) {
|
public MessageQueue(SampleView sampleView) {
|
||||||
this.sampleView = sampleView;
|
this.sampleView = sampleView;
|
||||||
}
|
}
|
||||||
@@ -95,7 +96,7 @@ public class MessageQueue implements Runnable {
|
|||||||
Error(e);
|
Error(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
// try {
|
||||||
while (running) {
|
while (running) {
|
||||||
DebuggerMessage.Message msg = null;
|
DebuggerMessage.Message msg = null;
|
||||||
if (incoming.size() > 0) { // find queued incoming
|
if (incoming.size() > 0) { // find queued incoming
|
||||||
@@ -108,6 +109,7 @@ public class MessageQueue implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (null == msg) { // get incoming from network
|
if (null == msg) { // get incoming from network
|
||||||
|
try {
|
||||||
msg = ReadMessage(dis);
|
msg = ReadMessage(dis);
|
||||||
if (msg.getExpectResponse()) {
|
if (msg.getExpectResponse()) {
|
||||||
if (msg.getType() == Type.BeforeCall)
|
if (msg.getType() == Type.BeforeCall)
|
||||||
@@ -119,10 +121,15 @@ public class MessageQueue implements Runnable {
|
|||||||
// SendResponse(dos, msg.getContextId(),
|
// SendResponse(dos, msg.getContextId(),
|
||||||
// DebuggerMessage.Message.Function.SKIP);
|
// DebuggerMessage.Message.Function.SKIP);
|
||||||
else if (msg.getType() == Type.Response)
|
else if (msg.getType() == Type.Response)
|
||||||
;
|
assert true;
|
||||||
else
|
else
|
||||||
assert false;
|
assert false;
|
||||||
}
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
Error(e);
|
||||||
|
running = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int contextId = msg.getContextId();
|
int contextId = msg.getContextId();
|
||||||
@@ -141,6 +148,7 @@ public class MessageQueue implements Runnable {
|
|||||||
messages.remove(0);
|
messages.remove(0);
|
||||||
}
|
}
|
||||||
if (null == next) { // read new part for message
|
if (null == next) { // read new part for message
|
||||||
|
try {
|
||||||
next = ReadMessage(dis);
|
next = ReadMessage(dis);
|
||||||
|
|
||||||
if (next.getExpectResponse()) {
|
if (next.getExpectResponse()) {
|
||||||
@@ -150,12 +158,18 @@ public class MessageQueue implements Runnable {
|
|||||||
next.getContextId(),
|
next.getContextId(),
|
||||||
DebuggerMessage.Message.Function.CONTINUE);
|
DebuggerMessage.Message.Function.CONTINUE);
|
||||||
else if (next.getType() == Type.AfterCall)
|
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)
|
else if (msg.getType() == Type.Response)
|
||||||
;
|
assert true;
|
||||||
else
|
else
|
||||||
assert false;
|
assert false;
|
||||||
}
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
Error(e);
|
||||||
|
running = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (next.getContextId() != contextId) {
|
if (next.getContextId() != contextId) {
|
||||||
// message part not for this context
|
// message part not for this context
|
||||||
@@ -180,15 +194,87 @@ public class MessageQueue implements Runnable {
|
|||||||
msg = builder.build();
|
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) {
|
synchronized (complete) {
|
||||||
complete.add(msg);
|
complete.add(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
socket.close();
|
socket.close();
|
||||||
} catch (Exception e) {
|
} catch (IOException e) {
|
||||||
Error(e);
|
Error(e);
|
||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// Error(e);
|
||||||
|
// running = false;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
public DebuggerMessage.Message RemoveMessage(int contextId) {
|
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.Viewer;
|
||||||
import org.eclipse.jface.viewers.ViewerFilter;
|
import org.eclipse.jface.viewers.ViewerFilter;
|
||||||
import org.eclipse.jface.viewers.ViewerSorter;
|
import org.eclipse.jface.viewers.ViewerSorter;
|
||||||
|
import org.eclipse.jface.window.Window;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.graphics.GC;
|
import org.eclipse.swt.graphics.GC;
|
||||||
import org.eclipse.swt.graphics.Image;
|
import org.eclipse.swt.graphics.Image;
|
||||||
import org.eclipse.swt.graphics.Point;
|
import org.eclipse.swt.graphics.Point;
|
||||||
import org.eclipse.swt.graphics.Rectangle;
|
import org.eclipse.swt.graphics.Rectangle;
|
||||||
|
import org.eclipse.swt.layout.FillLayout;
|
||||||
import org.eclipse.swt.widgets.Canvas;
|
import org.eclipse.swt.widgets.Canvas;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Control;
|
||||||
import org.eclipse.swt.widgets.Event;
|
import org.eclipse.swt.widgets.Event;
|
||||||
import org.eclipse.swt.widgets.Listener;
|
import org.eclipse.swt.widgets.Listener;
|
||||||
import org.eclipse.swt.widgets.Menu;
|
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.Shell;
|
||||||
import org.eclipse.swt.widgets.Table;
|
import org.eclipse.swt.widgets.Table;
|
||||||
import org.eclipse.swt.widgets.TableColumn;
|
import org.eclipse.swt.widgets.TableColumn;
|
||||||
|
import org.eclipse.swt.widgets.Text;
|
||||||
import org.eclipse.ui.IActionBars;
|
import org.eclipse.ui.IActionBars;
|
||||||
import org.eclipse.ui.ISharedImages;
|
import org.eclipse.ui.ISharedImages;
|
||||||
import org.eclipse.ui.IWorkbenchActionConstants;
|
import org.eclipse.ui.IWorkbenchActionConstants;
|
||||||
@@ -92,6 +96,7 @@ public class SampleView extends ViewPart implements Runnable {
|
|||||||
|
|
||||||
TableViewer viewer;
|
TableViewer viewer;
|
||||||
org.eclipse.swt.widgets.Canvas canvas;
|
org.eclipse.swt.widgets.Canvas canvas;
|
||||||
|
Text text;
|
||||||
Action actionConnect; // connect / disconnect
|
Action actionConnect; // connect / disconnect
|
||||||
Action doubleClickAction;
|
Action doubleClickAction;
|
||||||
Action actionAutoScroll;
|
Action actionAutoScroll;
|
||||||
@@ -131,7 +136,6 @@ public class SampleView extends ViewPart implements Runnable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void inputChanged(Viewer v, Object oldInput, Object newInput) {
|
public void inputChanged(Viewer v, Object oldInput, Object newInput) {
|
||||||
// showMessage("ViewContentProvider::inputChanged");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -251,8 +255,35 @@ public class SampleView extends ViewPart implements Runnable {
|
|||||||
hookSelectionChanged();
|
hookSelectionChanged();
|
||||||
contributeToActionBars();
|
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);
|
| 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();
|
final ScrollBar hBar = canvas.getHorizontalBar();
|
||||||
hBar.addListener(SWT.Selection, new Listener() {
|
hBar.addListener(SWT.Selection, new Listener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -383,7 +414,7 @@ public class SampleView extends ViewPart implements Runnable {
|
|||||||
shell, "Contains Filter",
|
shell, "Contains Filter",
|
||||||
"case sensitive substring or *",
|
"case sensitive substring or *",
|
||||||
actionFilter.getText(), null);
|
actionFilter.getText(), null);
|
||||||
if (dialog.OK == dialog.open()) {
|
if (Window.OK == dialog.open()) {
|
||||||
actionFilter.setText(dialog.getValue());
|
actionFilter.setText(dialog.getValue());
|
||||||
manager.update(true);
|
manager.update(true);
|
||||||
filters = dialog.getValue().split("\\|");
|
filters = dialog.getValue().split("\\|");
|
||||||
@@ -485,9 +516,13 @@ public class SampleView extends ViewPart implements Runnable {
|
|||||||
String str = "";
|
String str = "";
|
||||||
for (int i = 0; i < msgData.data.length; i++)
|
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)
|
if (i < msgData.data.length - 1)
|
||||||
str += ", ";
|
str += ' ';
|
||||||
}
|
}
|
||||||
showMessage(str);
|
showMessage(str);
|
||||||
}
|
}
|
||||||
@@ -515,12 +550,57 @@ public class SampleView extends ViewPart implements Runnable {
|
|||||||
if (null == selection)
|
if (null == selection)
|
||||||
return;
|
return;
|
||||||
if (1 != selection.size())
|
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;
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
viewer.getTable().getColumn(1).setText("Elapsed (ms)");
|
||||||
MessageData msgData = (MessageData) selection.getFirstElement();
|
MessageData msgData = (MessageData) selection.getFirstElement();
|
||||||
if (null == msgData)
|
if (null == msgData)
|
||||||
return;
|
return;
|
||||||
if (null != msgData.image)
|
if (null != msgData.image)
|
||||||
|
{
|
||||||
|
text.setVisible(false);
|
||||||
|
canvas.setVisible(true);
|
||||||
canvas.setBackgroundImage(msgData.image);
|
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