GLES2Dbg: added reference frame for glReadPixels

Change-Id: I7d6900e3101be61fb7801b3ca2eaea603d917e6b
Signed-off-by: David Li <davidxli@google.com>
This commit is contained in:
David Li
2011-03-22 10:02:51 -07:00
parent 0a5638a10b
commit 0ad029674b
6 changed files with 295 additions and 85 deletions

View File

@@ -0,0 +1,88 @@
/*
** 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;
public class Context {
public int contextId;
public GLServerVertex serverVertex = new GLServerVertex();
public byte [] readPixelRef = new byte [0];
public Message ProcessMessage(Message msg)
{
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;
}
return msg;
}
}

View File

@@ -483,6 +483,45 @@ public final class DebuggerMessage {
// @@protoc_insertion_point(enum_scope:com.android.glesv2debugger.Message.Type)
}
public enum DataType
implements com.google.protobuf.Internal.EnumLite {
ReferencedImage(0, 0),
NonreferencedImage(1, 1),
;
public final int getNumber() { return value; }
public static DataType valueOf(int value) {
switch (value) {
case 0: return ReferencedImage;
case 1: return NonreferencedImage;
default: return null;
}
}
public static com.google.protobuf.Internal.EnumLiteMap<DataType>
internalGetValueMap() {
return internalValueMap;
}
private static com.google.protobuf.Internal.EnumLiteMap<DataType>
internalValueMap =
new com.google.protobuf.Internal.EnumLiteMap<DataType>() {
public DataType findValueByNumber(int number) {
return DataType.valueOf(number)
; }
};
private final int index;
private final int value;
private DataType(int index, int value) {
this.index = index;
this.value = value;
}
// @@protoc_insertion_point(enum_scope:com.android.glesv2debugger.Message.DataType)
}
public enum Prop
implements com.google.protobuf.Internal.EnumLite {
Capture(0, 0),
@@ -627,6 +666,27 @@ public final class DebuggerMessage {
public boolean hasData() { return hasData; }
public com.google.protobuf.ByteString getData() { return data_; }
// optional .com.android.glesv2debugger.Message.DataType data_type = 23;
public static final int DATA_TYPE_FIELD_NUMBER = 23;
private boolean hasDataType;
private com.android.glesv2debugger.DebuggerMessage.Message.DataType dataType_;
public boolean hasDataType() { return hasDataType; }
public com.android.glesv2debugger.DebuggerMessage.Message.DataType getDataType() { return dataType_; }
// optional int32 pixel_format = 24;
public static final int PIXEL_FORMAT_FIELD_NUMBER = 24;
private boolean hasPixelFormat;
private int pixelFormat_ = 0;
public boolean hasPixelFormat() { return hasPixelFormat; }
public int getPixelFormat() { return pixelFormat_; }
// optional int32 pixel_type = 25;
public static final int PIXEL_TYPE_FIELD_NUMBER = 25;
private boolean hasPixelType;
private int pixelType_ = 0;
public boolean hasPixelType() { return hasPixelType; }
public int getPixelType() { return pixelType_; }
// optional float time = 11;
public static final int TIME_FIELD_NUMBER = 11;
private boolean hasTime;
@@ -651,6 +711,7 @@ public final class DebuggerMessage {
private void initFields() {
function_ = com.android.glesv2debugger.DebuggerMessage.Message.Function.NEG;
type_ = com.android.glesv2debugger.DebuggerMessage.Message.Type.BeforeCall;
dataType_ = com.android.glesv2debugger.DebuggerMessage.Message.DataType.ReferencedImage;
prop_ = com.android.glesv2debugger.DebuggerMessage.Message.Prop.Capture;
}
public final boolean isInitialized() {
@@ -718,6 +779,15 @@ public final class DebuggerMessage {
if (hasClock()) {
output.writeFloat(22, getClock());
}
if (hasDataType()) {
output.writeEnum(23, getDataType().getNumber());
}
if (hasPixelFormat()) {
output.writeInt32(24, getPixelFormat());
}
if (hasPixelType()) {
output.writeInt32(25, getPixelType());
}
}
private int memoizedSerializedSize = -1;
@@ -798,6 +868,18 @@ public final class DebuggerMessage {
size += com.google.protobuf.CodedOutputStream
.computeFloatSize(22, getClock());
}
if (hasDataType()) {
size += com.google.protobuf.CodedOutputStream
.computeEnumSize(23, getDataType().getNumber());
}
if (hasPixelFormat()) {
size += com.google.protobuf.CodedOutputStream
.computeInt32Size(24, getPixelFormat());
}
if (hasPixelType()) {
size += com.google.protobuf.CodedOutputStream
.computeInt32Size(25, getPixelType());
}
memoizedSerializedSize = size;
return size;
}
@@ -987,6 +1069,15 @@ public final class DebuggerMessage {
if (other.hasData()) {
setData(other.getData());
}
if (other.hasDataType()) {
setDataType(other.getDataType());
}
if (other.hasPixelFormat()) {
setPixelFormat(other.getPixelFormat());
}
if (other.hasPixelType()) {
setPixelType(other.getPixelType());
}
if (other.hasTime()) {
setTime(other.getTime());
}
@@ -1098,6 +1189,22 @@ public final class DebuggerMessage {
setClock(input.readFloat());
break;
}
case 184: {
int rawValue = input.readEnum();
com.android.glesv2debugger.DebuggerMessage.Message.DataType value = com.android.glesv2debugger.DebuggerMessage.Message.DataType.valueOf(rawValue);
if (value != null) {
setDataType(value);
}
break;
}
case 192: {
setPixelFormat(input.readInt32());
break;
}
case 200: {
setPixelType(input.readInt32());
break;
}
}
}
}
@@ -1382,6 +1489,63 @@ public final class DebuggerMessage {
return this;
}
// optional .com.android.glesv2debugger.Message.DataType data_type = 23;
public boolean hasDataType() {
return result.hasDataType();
}
public com.android.glesv2debugger.DebuggerMessage.Message.DataType getDataType() {
return result.getDataType();
}
public Builder setDataType(com.android.glesv2debugger.DebuggerMessage.Message.DataType value) {
if (value == null) {
throw new NullPointerException();
}
result.hasDataType = true;
result.dataType_ = value;
return this;
}
public Builder clearDataType() {
result.hasDataType = false;
result.dataType_ = com.android.glesv2debugger.DebuggerMessage.Message.DataType.ReferencedImage;
return this;
}
// optional int32 pixel_format = 24;
public boolean hasPixelFormat() {
return result.hasPixelFormat();
}
public int getPixelFormat() {
return result.getPixelFormat();
}
public Builder setPixelFormat(int value) {
result.hasPixelFormat = true;
result.pixelFormat_ = value;
return this;
}
public Builder clearPixelFormat() {
result.hasPixelFormat = false;
result.pixelFormat_ = 0;
return this;
}
// optional int32 pixel_type = 25;
public boolean hasPixelType() {
return result.hasPixelType();
}
public int getPixelType() {
return result.getPixelType();
}
public Builder setPixelType(int value) {
result.hasPixelType = true;
result.pixelType_ = value;
return this;
}
public Builder clearPixelType() {
result.hasPixelType = false;
result.pixelType_ = 0;
return this;
}
// optional float time = 11;
public boolean hasTime() {
return result.hasTime();

View File

@@ -17,11 +17,15 @@
package com.android.glesv2debugger;
import com.android.glesv2debugger.DebuggerMessage.Message;
import com.android.glesv2debugger.DebuggerMessage.Message.DataType;
import com.android.glesv2debugger.DebuggerMessage.Message.Function;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.widgets.Display;
import java.util.HashMap;
public class MessageData {
public final Message msg;
@@ -31,8 +35,8 @@ public class MessageData {
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 Message msg) {
public MessageData(final Device device, final Message msg, final Context context) {
this.msg = msg;
image = null;
shader = null;
@@ -42,7 +46,7 @@ public class MessageData {
ImageData imageData = null;
if (function != Message.Function.ACK)
assert msg.hasTime();
columns = new String [4];
columns = new String[4];
columns[0] = function.toString();
columns[1] = "";
if (msg.hasTime())
@@ -63,7 +67,8 @@ public class MessageData {
case glShaderSource:
shader = msg.getData().toStringUtf8();
int index = shader.indexOf('\n');
columns[3] += " source: " + shader.substring(0, index >= 0 ? index : shader.length()) + "...";
columns[3] += " source: "
+ shader.substring(0, index >= 0 ? index : shader.length()) + "...";
break;
case glTexImage2D:
if (!msg.hasData())
@@ -85,18 +90,26 @@ public class MessageData {
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());
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());
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;
if (msg.getDataType() == DataType.ReferencedImage)
MessageProcessor.ref = context.readPixelRef;
imageData = MessageProcessor.ReceiveImage(msg.getArg2(), msg.getArg3(),
msg.getArg4(), msg.getArg5(), msg.getData().toByteArray());
context.readPixelRef = MessageProcessor.ref;
MessageProcessor.ref = null;
imageData = imageData.scaledTo(imageData.width, -imageData.height);
image = new Image(device, imageData);
break;

View File

@@ -30,6 +30,8 @@ public class MessageProcessor {
MessageDialog.openError(null, "MessageProcessor", message);
}
public static byte [] ref; // inout; used for glReadPixels
public static ImageData ReceiveImage(int width, int height, int format,
int type, byte[] data) {
assert width > 0 && height > 0;
@@ -92,12 +94,20 @@ public class MessageProcessor {
showError("unsupported texture format: " + format);
return null;
}
byte[] pixels = new byte[width * height * (bpp / 8)];
int decompressed = org.liblzf.CLZF.lzf_decompress(data, data.length, pixels, pixels.length);
assert decompressed == width * height * (bpp / 8);
PaletteData palette = new PaletteData(redMask, greenMask, blueMask);
return new ImageData(width, height, bpp, palette, 1, pixels);
if (null != ref) {
if (ref.length < decompressed)
ref = new byte [width * height * (bpp / 8)];
for (int i = 0; i < ref.length; i++)
ref[i] ^= pixels[i];
return new ImageData(width, height, bpp, palette, 1, ref);
} else
return new ImageData(width, height, bpp, palette, 1, pixels);
}
static public float[] ReceiveData(final GLEnum type, final ByteString data) {

View File

@@ -36,8 +36,6 @@ public class MessageQueue implements Runnable {
ArrayList<Message> commands = new ArrayList<Message>();
SampleView sampleView;
HashMap<Integer, GLServerVertex> serversVertex = new HashMap<Integer, GLServerVertex>();
public MessageQueue(SampleView sampleView) {
this.sampleView = sampleView;
}
@@ -159,83 +157,10 @@ public class MessageQueue implements Runnable {
}
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());
builder.mergeFrom(next);
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);
}

View File

@@ -73,6 +73,7 @@ import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
/**
* This sample class demonstrates how to plug-in a new workbench view. The view
@@ -112,6 +113,7 @@ public class SampleView extends ViewPart implements Runnable {
Point origin = new Point(0, 0); // for smooth scrolling canvas
String[] filters = null;
public HashMap<Integer, Context> contexts = new HashMap<Integer, Context>();
/*
* The content provider class is responsible for providing objects to the
@@ -678,7 +680,7 @@ public class SampleView extends ViewPart implements Runnable {
break;
Message msg = messageQueue.RemoveMessage(0);
if (msgs.size() > 40) {
if (msgs.size() > 60 || null == msg) {
viewContentProvider.add(msgs);
msgs.clear();
}
@@ -690,8 +692,16 @@ public class SampleView extends ViewPart implements Runnable {
showError(e);
}
}
Context context = contexts.get(msg.getContextId());
if (null == context) {
context = new Context();
contexts.put(msg.getContextId(), context);
}
msg = context.ProcessMessage(msg);
final MessageData msgData = new MessageData(this.getViewSite()
.getShell().getDisplay(), msg);
.getShell().getDisplay(), msg, context);
if (null != writer) {
writer.write(msgData.columns[0]);
for (int i = 0; i < 30 - msgData.columns[0].length(); i++)