GLES2Dbg: added reference frame for glReadPixels
Change-Id: I7d6900e3101be61fb7801b3ca2eaea603d917e6b Signed-off-by: David Li <davidxli@google.com>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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++)
|
||||
|
||||
Reference in New Issue
Block a user