GLES2Dbg: add more state tracking and snapshot of state per GL call
Use TreeView and Reflection to display the states per GL call. Need to implement more state cloning and tacking. Prepare to group calls by frame, and clone the context for each frame. Change-Id: Ib1e5c175da779610204003e352cc1fcf66af969b Signed-off-by: David Li <davidxli@google.com>
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<classpath>
|
<classpath>
|
||||||
|
<classpathentry kind="lib" path="lib/sdklib.jar"/>
|
||||||
|
<classpathentry kind="lib" path="lib/liblzf.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/host-libprotobuf-java-2.3.0-lite.jar"/>
|
<classpathentry kind="lib" path="lib/host-libprotobuf-java-2.3.0-lite.jar"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||||
<classpathentry kind="src" path="src"/>
|
<classpathentry kind="src" path="src"/>
|
||||||
<classpathentry kind="lib" path="lib/liblzf.jar"/>
|
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|||||||
@@ -10,4 +10,5 @@ Bundle-ActivationPolicy: lazy
|
|||||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||||
Bundle-ClassPath: lib/host-libprotobuf-java-2.3.0-lite.jar,
|
Bundle-ClassPath: lib/host-libprotobuf-java-2.3.0-lite.jar,
|
||||||
lib/liblzf.jar,
|
lib/liblzf.jar,
|
||||||
|
lib/sdklib.jar,
|
||||||
.
|
.
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ output.. = bin/
|
|||||||
bin.includes = plugin.xml,\
|
bin.includes = plugin.xml,\
|
||||||
META-INF/,\
|
META-INF/,\
|
||||||
.,\
|
.,\
|
||||||
icons/,\
|
icons/,\
|
||||||
contexts.xml,\
|
contexts.xml,\
|
||||||
lib/host-libprotobuf-java-2.3.0-lite.jar,\
|
lib/host-libprotobuf-java-2.3.0-lite.jar,\
|
||||||
lib/liblzf.jar
|
lib/liblzf.jar,\
|
||||||
|
lib/sdklib.jar
|
||||||
|
|||||||
@@ -17,81 +17,205 @@
|
|||||||
package com.android.glesv2debugger;
|
package com.android.glesv2debugger;
|
||||||
|
|
||||||
import com.android.glesv2debugger.DebuggerMessage.Message;
|
import com.android.glesv2debugger.DebuggerMessage.Message;
|
||||||
|
import com.android.glesv2debugger.DebuggerMessage.Message.Function;
|
||||||
|
import com.android.sdklib.util.SparseArray;
|
||||||
|
import com.android.sdklib.util.SparseIntArray;
|
||||||
|
|
||||||
|
import org.eclipse.jface.viewers.ITreeContentProvider;
|
||||||
|
import org.eclipse.jface.viewers.LabelProvider;
|
||||||
|
import org.eclipse.jface.viewers.Viewer;
|
||||||
|
import org.eclipse.swt.graphics.Image;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class Context {
|
public class Context implements Cloneable {
|
||||||
public final int contextId;
|
public final int contextId;
|
||||||
ArrayList<Context> shares = new ArrayList<Context>(); // includes self
|
public ArrayList<Context> shares = new ArrayList<Context>(); // self too
|
||||||
public GLServerVertex serverVertex = new GLServerVertex();
|
public GLServerVertex serverVertex = new GLServerVertex();
|
||||||
public GLServerShader serverShader = new GLServerShader(this);
|
public GLServerShader serverShader = new GLServerShader(this);
|
||||||
public byte[] readPixelRef = new byte[0];
|
public GLServerState serverState = new GLServerState(this);
|
||||||
|
|
||||||
|
byte[] readPixelRef = new byte[0];
|
||||||
|
|
||||||
|
Message processed = null; // return; processed Message
|
||||||
|
|
||||||
public Context(int contextId) {
|
public Context(int contextId) {
|
||||||
this.contextId = contextId;
|
this.contextId = contextId;
|
||||||
shares.add(this);
|
shares.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Message ProcessMessage(Message msg) {
|
// returns instance TODO: return new instance if changed
|
||||||
switch (msg.getFunction()) {
|
public Context ProcessMessage(Message msg) {
|
||||||
case glBindBuffer:
|
GLServerVertex newVertex = serverVertex.Process(msg);
|
||||||
serverVertex.glBindBuffer(msg);
|
if (newVertex != null) {
|
||||||
break;
|
processed = newVertex.processed;
|
||||||
case glBufferData:
|
assert newVertex == serverVertex;
|
||||||
serverVertex.glBufferData(msg);
|
return this;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
serverShader.ProcessMessage(msg);
|
|
||||||
return msg;
|
GLServerShader newShader = serverShader.ProcessMessage(msg);
|
||||||
|
if (newShader != null) {
|
||||||
|
assert newShader == serverShader;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLServerState newState = serverState.ProcessMessage(msg);
|
||||||
|
if (newState != null) {
|
||||||
|
if (newState == serverState)
|
||||||
|
return this;
|
||||||
|
Context newContext = null;
|
||||||
|
try {
|
||||||
|
newContext = (Context) clone();
|
||||||
|
} catch (CloneNotSupportedException e) {
|
||||||
|
assert false;
|
||||||
|
}
|
||||||
|
newContext.serverState = newState;
|
||||||
|
newContext.serverShader.context = newContext;
|
||||||
|
return newContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ContextViewProvider extends LabelProvider implements ITreeContentProvider {
|
||||||
|
Context context;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getText(Object obj) {
|
||||||
|
if (obj == null)
|
||||||
|
return "null";
|
||||||
|
if (obj instanceof Entry) {
|
||||||
|
Entry entry = (Entry) obj;
|
||||||
|
if (entry != null)
|
||||||
|
return entry.name + " = " + entry.obj;
|
||||||
|
}
|
||||||
|
return obj.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Image getImage(Object obj) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
|
||||||
|
context = (Context) newInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Entry {
|
||||||
|
String name;
|
||||||
|
Object obj;
|
||||||
|
|
||||||
|
Entry(String name, Object obj) {
|
||||||
|
this.name = name;
|
||||||
|
this.obj = obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object[] getElements(Object inputElement) {
|
||||||
|
if (inputElement != context)
|
||||||
|
return null;
|
||||||
|
return getChildren(new Entry("Context", inputElement));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object[] getChildren(Object parentElement) {
|
||||||
|
if (!(parentElement instanceof Entry))
|
||||||
|
return null;
|
||||||
|
Entry entry = (Entry) parentElement;
|
||||||
|
ArrayList<Object> children = new ArrayList<Object>();
|
||||||
|
if (entry.obj == context.serverState.enableDisables) {
|
||||||
|
for (int i = 0; i < context.serverState.enableDisables.size(); i++) {
|
||||||
|
final int key = context.serverState.enableDisables.keyAt(i);
|
||||||
|
final int value = context.serverState.enableDisables.valueAt(i);
|
||||||
|
children.add(GLEnum.valueOf(key).name() + " = " + value);
|
||||||
|
}
|
||||||
|
} else if (entry.obj == context.serverState.lastSetter) {
|
||||||
|
for (int i = 0; i < context.serverState.lastSetter.size(); i++) {
|
||||||
|
final int key = context.serverState.lastSetter.keyAt(i);
|
||||||
|
final Message msg = context.serverState.lastSetter.valueAt(i);
|
||||||
|
if (msg == null)
|
||||||
|
children.add(Function.valueOf(key).name() + " : default");
|
||||||
|
else
|
||||||
|
children.add(Function.valueOf(key).name() + " : "
|
||||||
|
+ MessageFormatter.Format(msg));
|
||||||
|
}
|
||||||
|
} else if (entry.obj instanceof SparseArray) {
|
||||||
|
SparseArray sa = (SparseArray) entry.obj;
|
||||||
|
for (int i = 0; i < sa.size(); i++)
|
||||||
|
children.add(new Entry(entry.name + "[" + sa.keyAt(i) + "]", sa.valueAt(i)));
|
||||||
|
} else if (entry.obj instanceof Map) {
|
||||||
|
Set set = ((Map) entry.obj).entrySet();
|
||||||
|
for (Object o : set) {
|
||||||
|
Map.Entry e = (Map.Entry) o;
|
||||||
|
children.add(new Entry(e.getKey().toString(), e.getValue()));
|
||||||
|
}
|
||||||
|
} else if (entry.obj instanceof SparseIntArray) {
|
||||||
|
SparseIntArray sa = (SparseIntArray) entry.obj;
|
||||||
|
for (int i = 0; i < sa.size(); i++)
|
||||||
|
children.add(entry.name + "[" + sa.keyAt(i) + "] = " + sa.valueAt(i));
|
||||||
|
} else if (entry.obj instanceof Collection) {
|
||||||
|
Collection collection = (Collection) entry.obj;
|
||||||
|
for (Object o : collection)
|
||||||
|
children.add(new Entry(entry.name, o));
|
||||||
|
} else if (entry.obj.getClass().isArray()) {
|
||||||
|
Object[] list = (Object[]) entry.obj;
|
||||||
|
for (Object o : list)
|
||||||
|
children.add(new Entry(entry.name, o));
|
||||||
|
} else {
|
||||||
|
Field[] fields = entry.obj.getClass().getFields();
|
||||||
|
for (Field f : fields) {
|
||||||
|
try {
|
||||||
|
children.add(new Entry(f.getName(), f.get(entry.obj)));
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return children.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getParent(Object element) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasChildren(Object element) {
|
||||||
|
if (element == null)
|
||||||
|
return false;
|
||||||
|
if (element.getClass().isPrimitive())
|
||||||
|
return false;
|
||||||
|
if (element.getClass().equals(String.class))
|
||||||
|
return false;
|
||||||
|
if (element instanceof Entry) {
|
||||||
|
Entry entry = (Entry) element;
|
||||||
|
if (entry.obj != null) {
|
||||||
|
if (entry.obj instanceof SparseArray)
|
||||||
|
return ((SparseArray) entry.obj).size() > 0;
|
||||||
|
else if (entry.obj instanceof SparseIntArray)
|
||||||
|
return ((SparseIntArray) entry.obj).size() > 0;
|
||||||
|
else if (entry.obj instanceof Collection)
|
||||||
|
return ((Collection) entry.obj).size() > 0;
|
||||||
|
else if (entry.obj instanceof Map)
|
||||||
|
return ((Map) entry.obj).size() > 0;
|
||||||
|
else if (entry.obj.getClass().isArray())
|
||||||
|
return ((Object[]) entry.obj).length > 0;
|
||||||
|
return entry.obj.getClass().getFields().length > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,79 +17,130 @@
|
|||||||
package com.android.glesv2debugger;
|
package com.android.glesv2debugger;
|
||||||
|
|
||||||
import com.android.glesv2debugger.DebuggerMessage.Message;
|
import com.android.glesv2debugger.DebuggerMessage.Message;
|
||||||
|
import com.android.sdklib.util.SparseArray;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
class GLShader {
|
class GLShader implements Cloneable {
|
||||||
final int name;
|
public final int name;
|
||||||
final GLServerShader context; // the context this was created in
|
final GLServerShader context; // the context this was created in
|
||||||
final GLEnum type;
|
public final GLEnum type;
|
||||||
boolean delete;
|
public boolean delete;
|
||||||
ArrayList<GLProgram> programs = new ArrayList<GLProgram>();
|
public ArrayList<Integer> programs = new ArrayList<Integer>();
|
||||||
String source, originalSource;
|
public String source, originalSource;
|
||||||
|
|
||||||
GLShader(final int name, final GLServerShader context, final GLEnum type) {
|
GLShader(final int name, final GLServerShader context, final GLEnum type) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
// deep copy except for context, which is set afterwards
|
||||||
|
public Object clone() {
|
||||||
|
try {
|
||||||
|
GLShader shader = (GLShader) super.clone();
|
||||||
|
shader.programs = (ArrayList<Integer>) programs.clone();
|
||||||
|
return shader;
|
||||||
|
} catch (CloneNotSupportedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
assert false;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class GLProgram {
|
class GLProgram implements Cloneable {
|
||||||
final int name;
|
public final int name;
|
||||||
final GLServerShader context; // the context this was created in
|
final GLServerShader context; // the context this was created in
|
||||||
boolean delete;
|
public boolean delete;
|
||||||
GLShader vert, frag;
|
public int vert, frag;
|
||||||
|
|
||||||
GLProgram(final int name, final GLServerShader context) {
|
GLProgram(final int name, final GLServerShader context) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
// deep copy except for context, which is set afterwards
|
||||||
|
public Object clone() {
|
||||||
|
try {
|
||||||
|
return super.clone();
|
||||||
|
} catch (CloneNotSupportedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
assert false;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GLServerShader {
|
public class GLServerShader implements Cloneable {
|
||||||
final Context context;
|
Context context;
|
||||||
HashMap<Integer, GLShader> privateShaders = new HashMap<Integer, GLShader>();
|
public SparseArray<GLShader> shaders = new SparseArray<GLShader>();
|
||||||
HashMap<Integer, GLProgram> privatePrograms = new HashMap<Integer, GLProgram>();
|
public SparseArray<GLProgram> programs = new SparseArray<GLProgram>();
|
||||||
GLProgram current = null;
|
public GLProgram current = null;
|
||||||
public boolean uiUpdate = false;
|
boolean uiUpdate = false;
|
||||||
|
|
||||||
GLServerShader(final Context context) {
|
GLServerShader(Context context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ProcessMessage(final Message msg) {
|
@Override
|
||||||
|
// deep copy except for context, which is set afterwards
|
||||||
|
public Object clone() {
|
||||||
|
try {
|
||||||
|
GLServerShader copy = (GLServerShader) super.clone();
|
||||||
|
|
||||||
|
copy.shaders = new SparseArray<GLShader>(shaders.size());
|
||||||
|
for (int i = 0; i < shaders.size(); i++)
|
||||||
|
copy.shaders.append(shaders.keyAt(i), (GLShader) shaders.valueAt(i).clone());
|
||||||
|
|
||||||
|
copy.programs = new SparseArray<GLProgram>(programs.size());
|
||||||
|
for (int i = 0; i < programs.size(); i++)
|
||||||
|
copy.programs.append(programs.keyAt(i), (GLProgram) programs.valueAt(i).clone());
|
||||||
|
|
||||||
|
if (current != null)
|
||||||
|
copy.current = (GLProgram) current.clone();
|
||||||
|
return copy;
|
||||||
|
} catch (CloneNotSupportedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
assert false;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns instance if processed
|
||||||
|
public GLServerShader ProcessMessage(final Message msg) {
|
||||||
boolean oldUiUpdate = uiUpdate;
|
boolean oldUiUpdate = uiUpdate;
|
||||||
uiUpdate = true;
|
uiUpdate = true;
|
||||||
switch (msg.getFunction()) {
|
switch (msg.getFunction()) {
|
||||||
case glAttachShader:
|
case glAttachShader:
|
||||||
glAttachShader(msg);
|
glAttachShader(msg);
|
||||||
break;
|
return this;
|
||||||
case glCreateProgram:
|
case glCreateProgram:
|
||||||
glCreateProgram(msg);
|
glCreateProgram(msg);
|
||||||
break;
|
return this;
|
||||||
case glCreateShader:
|
case glCreateShader:
|
||||||
glCreateShader(msg);
|
glCreateShader(msg);
|
||||||
break;
|
return this;
|
||||||
case glDeleteProgram:
|
case glDeleteProgram:
|
||||||
glDeleteProgram(msg);
|
glDeleteProgram(msg);
|
||||||
break;
|
return this;
|
||||||
case glDeleteShader:
|
case glDeleteShader:
|
||||||
glDeleteShader(msg);
|
glDeleteShader(msg);
|
||||||
break;
|
return this;
|
||||||
case glDetachShader:
|
case glDetachShader:
|
||||||
glDetachShader(msg);
|
glDetachShader(msg);
|
||||||
break;
|
return this;
|
||||||
case glShaderSource:
|
case glShaderSource:
|
||||||
glShaderSource(msg);
|
glShaderSource(msg);
|
||||||
break;
|
return this;
|
||||||
case glUseProgram:
|
case glUseProgram:
|
||||||
glUseProgram(msg);
|
glUseProgram(msg);
|
||||||
break;
|
return this;
|
||||||
default:
|
default:
|
||||||
uiUpdate = oldUiUpdate;
|
uiUpdate = oldUiUpdate;
|
||||||
break;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,7 +148,7 @@ public class GLServerShader {
|
|||||||
if (name == 0)
|
if (name == 0)
|
||||||
return null;
|
return null;
|
||||||
for (Context ctx : context.shares) {
|
for (Context ctx : context.shares) {
|
||||||
GLShader shader = ctx.serverShader.privateShaders.get(name);
|
GLShader shader = ctx.serverShader.shaders.get(name);
|
||||||
if (shader != null)
|
if (shader != null)
|
||||||
return shader;
|
return shader;
|
||||||
}
|
}
|
||||||
@@ -109,7 +160,7 @@ public class GLServerShader {
|
|||||||
if (name == 0)
|
if (name == 0)
|
||||||
return null;
|
return null;
|
||||||
for (Context ctx : context.shares) {
|
for (Context ctx : context.shares) {
|
||||||
GLProgram program = ctx.serverShader.privatePrograms.get(name);
|
GLProgram program = ctx.serverShader.programs.get(name);
|
||||||
if (program != null)
|
if (program != null)
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
@@ -122,20 +173,20 @@ public class GLServerShader {
|
|||||||
GLProgram program = GetProgram(msg.getArg0());
|
GLProgram program = GetProgram(msg.getArg0());
|
||||||
GLShader shader = GetShader(msg.getArg1());
|
GLShader shader = GetShader(msg.getArg1());
|
||||||
if (GLEnum.GL_VERTEX_SHADER == shader.type)
|
if (GLEnum.GL_VERTEX_SHADER == shader.type)
|
||||||
program.vert = shader;
|
program.vert = shader.name;
|
||||||
else
|
else
|
||||||
program.frag = shader;
|
program.frag = shader.name;
|
||||||
shader.programs.add(program);
|
shader.programs.add(program.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// GLuint API_ENTRY(glCreateProgram)(void)
|
// GLuint API_ENTRY(glCreateProgram)(void)
|
||||||
void glCreateProgram(final Message msg) {
|
void glCreateProgram(final Message msg) {
|
||||||
privatePrograms.put(msg.getRet(), new GLProgram(msg.getRet(), this));
|
programs.put(msg.getRet(), new GLProgram(msg.getRet(), this));
|
||||||
}
|
}
|
||||||
|
|
||||||
// GLuint API_ENTRY(glCreateShader)(GLenum type)
|
// GLuint API_ENTRY(glCreateShader)(GLenum type)
|
||||||
void glCreateShader(final Message msg) {
|
void glCreateShader(final Message msg) {
|
||||||
privateShaders.put(msg.getRet(),
|
shaders.put(msg.getRet(),
|
||||||
new GLShader(msg.getRet(), this, GLEnum.valueOf(msg.getArg0())));
|
new GLShader(msg.getRet(), this, GLEnum.valueOf(msg.getArg0())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,9 +199,9 @@ public class GLServerShader {
|
|||||||
for (Context ctx : context.shares)
|
for (Context ctx : context.shares)
|
||||||
if (ctx.serverShader.current == program)
|
if (ctx.serverShader.current == program)
|
||||||
return;
|
return;
|
||||||
glDetachShader(program, program.vert);
|
glDetachShader(program, GetShader(program.vert));
|
||||||
glDetachShader(program, program.frag);
|
glDetachShader(program, GetShader(program.frag));
|
||||||
privatePrograms.remove(program.name);
|
programs.remove(program.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// void API_ENTRY(glDeleteShader)(GLuint shader)
|
// void API_ENTRY(glDeleteShader)(GLuint shader)
|
||||||
@@ -160,7 +211,7 @@ public class GLServerShader {
|
|||||||
GLShader shader = GetShader(msg.getArg0());
|
GLShader shader = GetShader(msg.getArg0());
|
||||||
shader.delete = true;
|
shader.delete = true;
|
||||||
if (shader.programs.size() == 0)
|
if (shader.programs.size() == 0)
|
||||||
privateShaders.remove(shader.name);
|
shaders.remove(shader.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// void API_ENTRY(glDetachShader)(GLuint program, GLuint shader)
|
// void API_ENTRY(glDetachShader)(GLuint program, GLuint shader)
|
||||||
@@ -171,15 +222,15 @@ public class GLServerShader {
|
|||||||
void glDetachShader(final GLProgram program, final GLShader shader) {
|
void glDetachShader(final GLProgram program, final GLShader shader) {
|
||||||
if (program == null)
|
if (program == null)
|
||||||
return;
|
return;
|
||||||
if (program.vert == shader)
|
if (program.vert == shader.name)
|
||||||
program.vert = null;
|
program.vert = 0;
|
||||||
else if (program.frag == shader)
|
else if (program.frag == shader.name)
|
||||||
program.frag = null;
|
program.frag = 0;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
shader.programs.remove(program);
|
shader.programs.remove(program.name);
|
||||||
if (shader.delete && shader.programs.size() == 0)
|
if (shader.delete && shader.programs.size() == 0)
|
||||||
shader.context.privateShaders.remove(shader.name);
|
shaders.remove(shader.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// void API_ENTRY(glShaderSource)(GLuint shader, GLsizei count, const
|
// void API_ENTRY(glShaderSource)(GLuint shader, GLsizei count, const
|
||||||
@@ -195,12 +246,11 @@ public class GLServerShader {
|
|||||||
void glUseProgram(final Message msg) {
|
void glUseProgram(final Message msg) {
|
||||||
GLProgram oldCurrent = current;
|
GLProgram oldCurrent = current;
|
||||||
current = GetProgram(msg.getArg0());
|
current = GetProgram(msg.getArg0());
|
||||||
if (null != oldCurrent && oldCurrent.delete && oldCurrent != current)
|
if (null != oldCurrent && oldCurrent.delete && oldCurrent != current) {
|
||||||
{
|
|
||||||
for (Context ctx : context.shares)
|
for (Context ctx : context.shares)
|
||||||
if (ctx.serverShader.current == oldCurrent)
|
if (ctx.serverShader.current == oldCurrent)
|
||||||
return;
|
return;
|
||||||
oldCurrent.context.privatePrograms.remove(oldCurrent.name);
|
oldCurrent.context.programs.remove(oldCurrent.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,237 @@
|
|||||||
|
/*
|
||||||
|
** 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 com.android.glesv2debugger.DebuggerMessage.Message.Function;
|
||||||
|
import com.android.sdklib.util.SparseArray;
|
||||||
|
import com.android.sdklib.util.SparseIntArray;
|
||||||
|
|
||||||
|
class GLStencilState implements Cloneable {
|
||||||
|
public int ref, mask;
|
||||||
|
public GLEnum func;
|
||||||
|
public GLEnum sf, df, dp; // operation
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object clone() {
|
||||||
|
try {
|
||||||
|
return super.clone();
|
||||||
|
} catch (CloneNotSupportedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GLServerState implements Cloneable {
|
||||||
|
final Context context;
|
||||||
|
public GLStencilState front = new GLStencilState(), back = new GLStencilState();
|
||||||
|
public SparseIntArray enableDisables;
|
||||||
|
public SparseArray<Message> lastSetter; // keyed by Function.getNumber()
|
||||||
|
|
||||||
|
GLServerState(final Context context) {
|
||||||
|
this.context = context;
|
||||||
|
enableDisables = new SparseIntArray(9);
|
||||||
|
enableDisables.put(GLEnum.GL_BLEND.value, 0);
|
||||||
|
enableDisables.put(GLEnum.GL_DITHER.value, 1);
|
||||||
|
enableDisables.put(GLEnum.GL_DEPTH_TEST.value, 0);
|
||||||
|
enableDisables.put(GLEnum.GL_STENCIL_TEST.value, 0);
|
||||||
|
enableDisables.put(GLEnum.GL_SCISSOR_TEST.value, 0);
|
||||||
|
enableDisables.put(GLEnum.GL_SAMPLE_COVERAGE.value, 0);
|
||||||
|
enableDisables.put(GLEnum.GL_SAMPLE_ALPHA_TO_COVERAGE.value, 0);
|
||||||
|
enableDisables.put(GLEnum.GL_POLYGON_OFFSET_FILL.value, 0);
|
||||||
|
enableDisables.put(GLEnum.GL_CULL_FACE.value, 0);
|
||||||
|
|
||||||
|
lastSetter = new SparseArray<Message>();
|
||||||
|
lastSetter.put(Function.glBlendColor.getNumber(), null);
|
||||||
|
// glBlendEquation overwrites glBlendEquationSeparate
|
||||||
|
lastSetter.put(Function.glBlendEquationSeparate.getNumber(), null);
|
||||||
|
// glBlendFunc overwrites glBlendFuncSeparate
|
||||||
|
lastSetter.put(Function.glBlendFuncSeparate.getNumber(), null);
|
||||||
|
lastSetter.put(Function.glColorMask.getNumber(), null);
|
||||||
|
lastSetter.put(Function.glDepthMask.getNumber(), null);
|
||||||
|
lastSetter.put(Function.glDepthFunc.getNumber(), null);
|
||||||
|
lastSetter.put(Function.glScissor.getNumber(), null);
|
||||||
|
lastSetter.put(Function.glStencilMaskSeparate.getNumber(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns instance if processed (returns new instance if changed)
|
||||||
|
public GLServerState ProcessMessage(final Message msg) {
|
||||||
|
switch (msg.getFunction()) {
|
||||||
|
case glBlendColor:
|
||||||
|
return Setter(msg);
|
||||||
|
case glBlendEquation:
|
||||||
|
return Setter(msg);
|
||||||
|
case glBlendEquationSeparate:
|
||||||
|
return Setter(msg);
|
||||||
|
case glBlendFunc:
|
||||||
|
return Setter(msg);
|
||||||
|
case glBlendFuncSeparate:
|
||||||
|
return Setter(msg);
|
||||||
|
case glColorMask:
|
||||||
|
return Setter(msg);
|
||||||
|
case glDepthMask:
|
||||||
|
return Setter(msg);
|
||||||
|
case glDepthFunc:
|
||||||
|
return Setter(msg);
|
||||||
|
case glDisable:
|
||||||
|
return EnableDisable(false, msg);
|
||||||
|
case glEnable:
|
||||||
|
return EnableDisable(true, msg);
|
||||||
|
case glScissor:
|
||||||
|
return Setter(msg);
|
||||||
|
case glStencilFunc: {
|
||||||
|
Message.Builder builder = msg.toBuilder();
|
||||||
|
builder.setArg2(msg.getArg1());
|
||||||
|
builder.setArg1(msg.getArg0());
|
||||||
|
builder.setArg0(GLEnum.GL_FRONT_AND_BACK.value);
|
||||||
|
return glStencilFuncSeparate(builder.build());
|
||||||
|
}
|
||||||
|
case glStencilFuncSeparate:
|
||||||
|
return glStencilFuncSeparate(msg);
|
||||||
|
case glStencilMask:
|
||||||
|
return Setter(msg);
|
||||||
|
case glStencilMaskSeparate:
|
||||||
|
return Setter(msg);
|
||||||
|
case glStencilOp: {
|
||||||
|
Message.Builder builder = msg.toBuilder();
|
||||||
|
builder.setArg3(msg.getArg2());
|
||||||
|
builder.setArg2(msg.getArg1());
|
||||||
|
builder.setArg1(msg.getArg0());
|
||||||
|
builder.setArg0(GLEnum.GL_FRONT_AND_BACK.value);
|
||||||
|
return glStencilOpSeparate(builder.build());
|
||||||
|
}
|
||||||
|
case glStencilOpSeparate:
|
||||||
|
return glStencilOpSeparate(msg);
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GLServerState Setter(final Message msg) {
|
||||||
|
GLServerState newState = (GLServerState) this.clone();
|
||||||
|
// TODO: compare for change
|
||||||
|
switch (msg.getFunction()) {
|
||||||
|
case glBlendFunc:
|
||||||
|
newState.lastSetter.put(Function.glBlendFuncSeparate.getNumber(), msg);
|
||||||
|
break;
|
||||||
|
case glBlendEquation:
|
||||||
|
newState.lastSetter.put(Function.glBlendEquationSeparate.getNumber(), msg);
|
||||||
|
break;
|
||||||
|
case glStencilMask:
|
||||||
|
newState.lastSetter.put(Function.glStencilMaskSeparate.getNumber(), msg);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
newState.lastSetter.put(msg.getFunction().getNumber(), msg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return newState;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLServerState EnableDisable(boolean enable, final Message msg) {
|
||||||
|
int index = enableDisables.indexOfKey(msg.getArg0());
|
||||||
|
assert index >= 0;
|
||||||
|
if ((enableDisables.valueAt(index) != 0) == enable)
|
||||||
|
return this;
|
||||||
|
GLServerState newState0 = (GLServerState) this.clone();
|
||||||
|
newState0.enableDisables.put(msg.getArg0(), enable ? 1 : 0);
|
||||||
|
return newState0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// void StencilFuncSeparate( enum face, enum func, int ref, uint mask )
|
||||||
|
GLServerState glStencilFuncSeparate(final Message msg) {
|
||||||
|
GLEnum ff = front.func, bf = back.func;
|
||||||
|
int fr = front.ref, br = back.ref;
|
||||||
|
int fm = front.mask, bm = back.mask;
|
||||||
|
final GLEnum face = GLEnum.valueOf(msg.getArg0());
|
||||||
|
if (face == GLEnum.GL_FRONT || face == GLEnum.GL_FRONT_AND_BACK) {
|
||||||
|
ff = GLEnum.valueOf(msg.getArg1());
|
||||||
|
fr = msg.getArg2();
|
||||||
|
fm = msg.getArg3();
|
||||||
|
}
|
||||||
|
if (face == GLEnum.GL_BACK || face == GLEnum.GL_FRONT_AND_BACK) {
|
||||||
|
bf = GLEnum.valueOf(msg.getArg1());
|
||||||
|
br = msg.getArg2();
|
||||||
|
bm = msg.getArg3();
|
||||||
|
}
|
||||||
|
if (ff == front.func && fr == front.ref && fm == front.mask)
|
||||||
|
if (bf == back.func && br == back.ref && bm == back.mask)
|
||||||
|
return this;
|
||||||
|
GLServerState newState = (GLServerState) this.clone();
|
||||||
|
newState.front.func = ff;
|
||||||
|
newState.front.ref = fr;
|
||||||
|
newState.front.mask = fm;
|
||||||
|
newState.back.func = bf;
|
||||||
|
newState.back.ref = br;
|
||||||
|
newState.back.mask = bm;
|
||||||
|
return newState;
|
||||||
|
}
|
||||||
|
|
||||||
|
// void StencilOpSeparate( enum face, enum sfail, enum dpfail, enum dppass )
|
||||||
|
GLServerState glStencilOpSeparate(final Message msg) {
|
||||||
|
GLEnum fsf = front.sf, fdf = front.df, fdp = front.dp;
|
||||||
|
GLEnum bsf = back.sf, bdf = back.df, bdp = back.dp;
|
||||||
|
final GLEnum face = GLEnum.valueOf(msg.getArg0());
|
||||||
|
if (face == GLEnum.GL_FRONT || face == GLEnum.GL_FRONT_AND_BACK) {
|
||||||
|
fsf = GLEnum.valueOf(msg.getArg1());
|
||||||
|
fdf = GLEnum.valueOf(msg.getArg2());
|
||||||
|
fdp = GLEnum.valueOf(msg.getArg3());
|
||||||
|
}
|
||||||
|
if (face == GLEnum.GL_BACK || face == GLEnum.GL_FRONT_AND_BACK) {
|
||||||
|
bsf = GLEnum.valueOf(msg.getArg1());
|
||||||
|
bdf = GLEnum.valueOf(msg.getArg2());
|
||||||
|
bdp = GLEnum.valueOf(msg.getArg3());
|
||||||
|
}
|
||||||
|
if (fsf == front.sf && fdf == front.df && fdp == front.dp)
|
||||||
|
if (bsf == back.sf && bdf == back.df && bdp == back.dp)
|
||||||
|
return this;
|
||||||
|
GLServerState newState = (GLServerState) this.clone();
|
||||||
|
newState.front.sf = fsf;
|
||||||
|
newState.front.df = fdf;
|
||||||
|
newState.front.dp = fdp;
|
||||||
|
newState.back.sf = bsf;
|
||||||
|
newState.back.df = bdf;
|
||||||
|
newState.back.dp = bdp;
|
||||||
|
return newState;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object clone() {
|
||||||
|
try {
|
||||||
|
GLServerState newState = (GLServerState) super.clone();
|
||||||
|
newState.front = (GLStencilState) front.clone();
|
||||||
|
newState.back = (GLStencilState) back.clone();
|
||||||
|
|
||||||
|
newState.enableDisables = new SparseIntArray(enableDisables.size());
|
||||||
|
for (int i = 0; i < enableDisables.size(); i++) {
|
||||||
|
final int key = enableDisables.keyAt(i);
|
||||||
|
newState.enableDisables.append(key, enableDisables.valueAt(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
newState.lastSetter = new SparseArray<Message>(lastSetter.size());
|
||||||
|
for (int i = 0; i < lastSetter.size(); i++) {
|
||||||
|
final int key = lastSetter.keyAt(i);
|
||||||
|
newState.lastSetter.append(key, lastSetter.valueAt(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return newState;
|
||||||
|
} catch (CloneNotSupportedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,27 +22,27 @@ import java.nio.ByteBuffer;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
class GLBuffer {
|
class GLBuffer {
|
||||||
GLEnum usage;
|
public GLEnum usage;
|
||||||
GLEnum target;
|
public GLEnum target;
|
||||||
ByteBuffer data;
|
public ByteBuffer data;
|
||||||
}
|
}
|
||||||
|
|
||||||
class GLAttribPointer {
|
class GLAttribPointer {
|
||||||
int size; // number of values per vertex
|
public int size; // number of values per vertex
|
||||||
GLEnum type; // data type
|
public GLEnum type; // data type
|
||||||
int stride; // bytes
|
public int stride; // bytes
|
||||||
int ptr; // pointer in debugger server or byte offset into buffer
|
public int ptr; // pointer in debugger server or byte offset into buffer
|
||||||
GLBuffer buffer;
|
public GLBuffer buffer;
|
||||||
boolean normalized;
|
public boolean normalized;
|
||||||
boolean enabled;
|
public boolean enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GLServerVertex {
|
public class GLServerVertex {
|
||||||
|
|
||||||
HashMap<Integer, GLBuffer> buffers;
|
public HashMap<Integer, GLBuffer> buffers;
|
||||||
GLBuffer attribBuffer, indexBuffer; // current binding
|
public GLBuffer attribBuffer, indexBuffer; // current binding
|
||||||
GLAttribPointer attribPointers[];
|
public GLAttribPointer attribPointers[];
|
||||||
float defaultAttribs[][];
|
public float defaultAttribs[][];
|
||||||
int maxAttrib;
|
int maxAttrib;
|
||||||
|
|
||||||
public GLServerVertex() {
|
public GLServerVertex() {
|
||||||
@@ -60,6 +60,73 @@ public class GLServerVertex {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Message processed = null; // return; glDrawArrays/Elements with fetched data
|
||||||
|
|
||||||
|
// returns instance if processed TODO: return new instance if changed
|
||||||
|
public GLServerVertex Process(final Message msg) {
|
||||||
|
processed = null;
|
||||||
|
switch (msg.getFunction()) {
|
||||||
|
case glBindBuffer:
|
||||||
|
glBindBuffer(msg);
|
||||||
|
return this;
|
||||||
|
case glBufferData:
|
||||||
|
glBufferData(msg);
|
||||||
|
return this;
|
||||||
|
case glBufferSubData:
|
||||||
|
glBufferSubData(msg);
|
||||||
|
return this;
|
||||||
|
case glDeleteBuffers:
|
||||||
|
glDeleteBuffers(msg);
|
||||||
|
return this;
|
||||||
|
case glDrawArrays:
|
||||||
|
if (msg.hasArg7())
|
||||||
|
processed = glDrawArrays(msg);
|
||||||
|
return this;
|
||||||
|
case glDrawElements:
|
||||||
|
if (msg.hasArg7())
|
||||||
|
processed = glDrawElements(msg);
|
||||||
|
return this;
|
||||||
|
case glDisableVertexAttribArray:
|
||||||
|
glDisableVertexAttribArray(msg);
|
||||||
|
return this;
|
||||||
|
case glEnableVertexAttribArray:
|
||||||
|
glEnableVertexAttribArray(msg);
|
||||||
|
return this;
|
||||||
|
case glGenBuffers:
|
||||||
|
glGenBuffers(msg);
|
||||||
|
return this;
|
||||||
|
case glVertexAttribPointer:
|
||||||
|
glVertexAttribPointer(msg);
|
||||||
|
return this;
|
||||||
|
case glVertexAttrib1f:
|
||||||
|
glVertexAttrib1f(msg);
|
||||||
|
return this;
|
||||||
|
case glVertexAttrib1fv:
|
||||||
|
glVertexAttrib1fv(msg);
|
||||||
|
return this;
|
||||||
|
case glVertexAttrib2f:
|
||||||
|
glVertexAttrib2f(msg);
|
||||||
|
return this;
|
||||||
|
case glVertexAttrib2fv:
|
||||||
|
glVertexAttrib2fv(msg);
|
||||||
|
return this;
|
||||||
|
case glVertexAttrib3f:
|
||||||
|
glVertexAttrib3f(msg);
|
||||||
|
return this;
|
||||||
|
case glVertexAttrib3fv:
|
||||||
|
glVertexAttrib3fv(msg);
|
||||||
|
return this;
|
||||||
|
case glVertexAttrib4f:
|
||||||
|
glVertexAttrib4f(msg);
|
||||||
|
return this;
|
||||||
|
case glVertexAttrib4fv:
|
||||||
|
glVertexAttrib4fv(msg);
|
||||||
|
return this;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// void API_ENTRY(glBindBuffer)(GLenum target, GLuint buffer)
|
// void API_ENTRY(glBindBuffer)(GLenum target, GLuint buffer)
|
||||||
public void glBindBuffer(Message msg) {
|
public void glBindBuffer(Message msg) {
|
||||||
if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ARRAY_BUFFER) {
|
if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ARRAY_BUFFER) {
|
||||||
@@ -141,32 +208,32 @@ public class GLServerVertex {
|
|||||||
else if (GLEnum.GL_UNSIGNED_INT == type)
|
else if (GLEnum.GL_UNSIGNED_INT == type)
|
||||||
if (normalized)
|
if (normalized)
|
||||||
return (Integer.reverseBytes(src.getInt()) & 0xffffffffL) / (2e32f - 1);
|
return (Integer.reverseBytes(src.getInt()) & 0xffffffffL) / (2e32f - 1);
|
||||||
else
|
else
|
||||||
return Integer.reverseBytes(src.getInt()) & 0xffffffffL;
|
return Integer.reverseBytes(src.getInt()) & 0xffffffffL;
|
||||||
else if (GLEnum.GL_INT == type)
|
else if (GLEnum.GL_INT == type)
|
||||||
if (normalized)
|
if (normalized)
|
||||||
return (Integer.reverseBytes(src.getInt()) * 2 + 1) / (2e32f - 1);
|
return (Integer.reverseBytes(src.getInt()) * 2 + 1) / (2e32f - 1);
|
||||||
else
|
else
|
||||||
return Integer.reverseBytes(src.getInt());
|
return Integer.reverseBytes(src.getInt());
|
||||||
else if (GLEnum.GL_UNSIGNED_SHORT == type)
|
else if (GLEnum.GL_UNSIGNED_SHORT == type)
|
||||||
if (normalized)
|
if (normalized)
|
||||||
return (Short.reverseBytes(src.getShort()) & 0xffff) / (2e16f - 1);
|
return (Short.reverseBytes(src.getShort()) & 0xffff) / (2e16f - 1);
|
||||||
else
|
else
|
||||||
return Short.reverseBytes(src.getShort()) & 0xffff;
|
return Short.reverseBytes(src.getShort()) & 0xffff;
|
||||||
else if (GLEnum.GL_SHORT == type)
|
else if (GLEnum.GL_SHORT == type)
|
||||||
if (normalized)
|
if (normalized)
|
||||||
return (Short.reverseBytes(src.getShort()) * 2 + 1) / (2e16f - 1);
|
return (Short.reverseBytes(src.getShort()) * 2 + 1) / (2e16f - 1);
|
||||||
else
|
else
|
||||||
return Short.reverseBytes(src.getShort());
|
return Short.reverseBytes(src.getShort());
|
||||||
else if (GLEnum.GL_UNSIGNED_BYTE == type)
|
else if (GLEnum.GL_UNSIGNED_BYTE == type)
|
||||||
if (normalized)
|
if (normalized)
|
||||||
return (src.get() & 0xff) / (2e8f - 1);
|
return (src.get() & 0xff) / (2e8f - 1);
|
||||||
else
|
else
|
||||||
return src.get() & 0xff;
|
return src.get() & 0xff;
|
||||||
else if (GLEnum.GL_BYTE == type)
|
else if (GLEnum.GL_BYTE == type)
|
||||||
if (normalized)
|
if (normalized)
|
||||||
return (src.get() * 2 + 1) / (2e8f - 1);
|
return (src.get() * 2 + 1) / (2e8f - 1);
|
||||||
else
|
else
|
||||||
return src.get();
|
return src.get();
|
||||||
else if (GLEnum.GL_FIXED == type)
|
else if (GLEnum.GL_FIXED == type)
|
||||||
if (normalized)
|
if (normalized)
|
||||||
|
|||||||
@@ -33,9 +33,11 @@ public class MessageData {
|
|||||||
public float[] data;
|
public float[] data;
|
||||||
public int maxAttrib; // used for formatting data
|
public int maxAttrib; // used for formatting data
|
||||||
public GLEnum dataType; // could be float, int; mainly for formatting use
|
public GLEnum dataType; // could be float, int; mainly for formatting use
|
||||||
|
Context context; // the context before this call
|
||||||
|
|
||||||
public MessageData(final Device device, final Message msg, final Context context) {
|
public MessageData(final Device device, final Message msg, final Context context) {
|
||||||
this.msg = msg;
|
this.msg = msg;
|
||||||
|
this.context = context;
|
||||||
image = null;
|
image = null;
|
||||||
shader = null;
|
shader = null;
|
||||||
data = null;
|
data = null;
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import org.eclipse.jface.viewers.LabelProvider;
|
|||||||
import org.eclipse.jface.viewers.ListViewer;
|
import org.eclipse.jface.viewers.ListViewer;
|
||||||
import org.eclipse.jface.viewers.SelectionChangedEvent;
|
import org.eclipse.jface.viewers.SelectionChangedEvent;
|
||||||
import org.eclipse.jface.viewers.StructuredSelection;
|
import org.eclipse.jface.viewers.StructuredSelection;
|
||||||
|
import org.eclipse.jface.viewers.TreeViewer;
|
||||||
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;
|
||||||
@@ -101,8 +102,10 @@ public class SampleView extends ViewPart implements Runnable {
|
|||||||
public static final String ID = "glesv2debuggerclient.views.SampleView";
|
public static final String ID = "glesv2debuggerclient.views.SampleView";
|
||||||
|
|
||||||
TabFolder tabFolder;
|
TabFolder tabFolder;
|
||||||
TabItem tabItemText, tabItemImage, tabItemBreakpointOption, tabItemShaderEditor;
|
TabItem tabItemText, tabItemImage, tabItemBreakpointOption;
|
||||||
|
TabItem tabItemShaderEditor, tabContextViewer;
|
||||||
ListViewer viewer;
|
ListViewer viewer;
|
||||||
|
TreeViewer contextViewer;
|
||||||
BreakpointOption breakpointOption;
|
BreakpointOption breakpointOption;
|
||||||
ShaderEditor shaderEditor;
|
ShaderEditor shaderEditor;
|
||||||
Canvas canvas;
|
Canvas canvas;
|
||||||
@@ -141,6 +144,7 @@ public class SampleView extends ViewPart implements Runnable {
|
|||||||
bar.setSelection(bar.getMaximum());
|
bar.setSelection(bar.getMaximum());
|
||||||
viewer.getList().setSelection(
|
viewer.getList().setSelection(
|
||||||
entries.size() - 1);
|
entries.size() - 1);
|
||||||
|
// MessageDataSelected(entries.get(entries.size() - 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -228,6 +232,7 @@ public class SampleView extends ViewPart implements Runnable {
|
|||||||
viewer.setFilters(new ViewerFilter[] {
|
viewer.setFilters(new ViewerFilter[] {
|
||||||
new Filter()
|
new Filter()
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -270,6 +275,14 @@ public class SampleView extends ViewPart implements Runnable {
|
|||||||
tabItemShaderEditor.setText("Shader Editor");
|
tabItemShaderEditor.setText("Shader Editor");
|
||||||
tabItemShaderEditor.setControl(shaderEditor);
|
tabItemShaderEditor.setControl(shaderEditor);
|
||||||
|
|
||||||
|
contextViewer = new TreeViewer(tabFolder);
|
||||||
|
ContextViewProvider contextViewProvider = new ContextViewProvider();
|
||||||
|
contextViewer.setContentProvider(contextViewProvider);
|
||||||
|
contextViewer.setLabelProvider(contextViewProvider);
|
||||||
|
tabContextViewer = new TabItem(tabFolder, SWT.NONE);
|
||||||
|
tabContextViewer.setText("Context Viewer");
|
||||||
|
tabContextViewer.setControl(contextViewer.getTree());
|
||||||
|
|
||||||
final ScrollBar hBar = canvas.getHorizontalBar();
|
final ScrollBar hBar = canvas.getHorizontalBar();
|
||||||
hBar.addListener(SWT.Selection, new Listener() {
|
hBar.addListener(SWT.Selection, new Listener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -528,6 +541,33 @@ public class SampleView extends ViewPart implements Runnable {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MessageDataSelected(final MessageData msgData) {
|
||||||
|
if (null == msgData)
|
||||||
|
return;
|
||||||
|
contextViewer.setInput(msgData.context);
|
||||||
|
if (null != msgData.image) {
|
||||||
|
canvas.setBackgroundImage(msgData.image);
|
||||||
|
tabFolder.setSelection(tabItemImage);
|
||||||
|
canvas.redraw();
|
||||||
|
} else if (null != msgData.shader) {
|
||||||
|
text.setText(msgData.shader);
|
||||||
|
tabFolder.setSelection(tabItemText);
|
||||||
|
} else if (null != msgData.data) {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
for (int i = 0; i < msgData.data.length; i++) {
|
||||||
|
builder.append(String.format("%.3g", msgData.data[i]));
|
||||||
|
if (i % (4 * msgData.maxAttrib) == (4 * msgData.maxAttrib - 1))
|
||||||
|
builder.append('\n');
|
||||||
|
else if (i % 4 == 3)
|
||||||
|
builder.append(" -");
|
||||||
|
if (i < msgData.data.length - 1)
|
||||||
|
builder.append(' ');
|
||||||
|
}
|
||||||
|
text.setText(builder.toString());
|
||||||
|
tabFolder.setSelection(tabItemText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void hookSelectionChanged() {
|
private void hookSelectionChanged() {
|
||||||
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
|
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -537,39 +577,8 @@ public class SampleView extends ViewPart implements Runnable {
|
|||||||
if (null == selection)
|
if (null == selection)
|
||||||
return;
|
return;
|
||||||
MessageData msgData = (MessageData) selection.getFirstElement();
|
MessageData msgData = (MessageData) selection.getFirstElement();
|
||||||
if (null == msgData)
|
MessageDataSelected(msgData);
|
||||||
return;
|
|
||||||
if (null != msgData.image)
|
|
||||||
{
|
|
||||||
canvas.setBackgroundImage(msgData.image);
|
|
||||||
tabFolder.setSelection(tabItemImage);
|
|
||||||
}
|
|
||||||
else if (null != msgData.shader)
|
|
||||||
{
|
|
||||||
text.setText(msgData.shader);
|
|
||||||
text.setVisible(true);
|
|
||||||
canvas.setVisible(false);
|
|
||||||
text.getParent().layout();
|
|
||||||
}
|
|
||||||
else if (null != msgData.data)
|
|
||||||
{
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
for (int i = 0; i < msgData.data.length; i++)
|
|
||||||
{
|
|
||||||
builder.append(String.format("%.3g", msgData.data[i]));
|
|
||||||
if (i % (4 * msgData.maxAttrib) == (4 * msgData.maxAttrib - 1))
|
|
||||||
builder.append('\n');
|
|
||||||
else if (i % 4 == 3)
|
|
||||||
builder.append(" -");
|
|
||||||
if (i < msgData.data.length - 1)
|
|
||||||
builder.append(' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
text.setText(builder.toString());
|
|
||||||
tabFolder.setSelection(tabItemText);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -640,8 +649,13 @@ public class SampleView extends ViewPart implements Runnable {
|
|||||||
context = new Context(msg.getContextId());
|
context = new Context(msg.getContextId());
|
||||||
contexts.put(msg.getContextId(), context);
|
contexts.put(msg.getContextId(), context);
|
||||||
}
|
}
|
||||||
msg = context.ProcessMessage(msg);
|
Context newContext = context.ProcessMessage(msg);
|
||||||
shaderEditorUpdate |= context.serverShader.uiUpdate;
|
// TODO: full cloning on change not implemented yet
|
||||||
|
if (newContext.processed != null)
|
||||||
|
msg = newContext.processed;
|
||||||
|
contexts.put(msg.getContextId(), newContext);
|
||||||
|
shaderEditorUpdate |= newContext.serverShader.uiUpdate;
|
||||||
|
newContext.serverShader.uiUpdate = false;
|
||||||
|
|
||||||
final MessageData msgData = new MessageData(this.getViewSite()
|
final MessageData msgData = new MessageData(this.getViewSite()
|
||||||
.getShell().getDisplay(), msg, context);
|
.getShell().getDisplay(), msg, context);
|
||||||
|
|||||||
@@ -107,7 +107,8 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend
|
|||||||
progs += context.serverShader.current.name + "(0x";
|
progs += context.serverShader.current.name + "(0x";
|
||||||
progs += Integer.toHexString(context.contextId) + ") ";
|
progs += Integer.toHexString(context.contextId) + ") ";
|
||||||
}
|
}
|
||||||
for (GLShader shader : context.serverShader.privateShaders.values()) {
|
for (int i = 0; i < context.serverShader.shaders.size(); i++) {
|
||||||
|
GLShader shader = context.serverShader.shaders.valueAt(i);
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append(String.format("%08X", context.contextId));
|
builder.append(String.format("%08X", context.contextId));
|
||||||
builder.append(' ');
|
builder.append(' ');
|
||||||
@@ -123,17 +124,17 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend
|
|||||||
builder.append(' ');
|
builder.append(' ');
|
||||||
}
|
}
|
||||||
builder.append(": ");
|
builder.append(": ");
|
||||||
for (GLProgram program : shader.programs) {
|
for (int program : shader.programs) {
|
||||||
builder.append(program.name);
|
builder.append(program);
|
||||||
builder.append(" ");
|
builder.append(" ");
|
||||||
}
|
}
|
||||||
list.add(builder.toString());
|
list.add(builder.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if (!progs.equals(currentPrograms.getText())) {
|
|
||||||
currentPrograms.setText(progs);
|
|
||||||
|
|
||||||
// }
|
currentPrograms.setText(progs);
|
||||||
|
toolbar.redraw();
|
||||||
|
toolbar.pack(true);
|
||||||
toolbar.update();
|
toolbar.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,11 +170,10 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend
|
|||||||
new Color(Display.getCurrent(), 255, 230, 230));
|
new Color(Display.getCurrent(), 255, 230, 230));
|
||||||
}
|
}
|
||||||
if (infolog.length() > 0) {
|
if (infolog.length() > 0) {
|
||||||
MessageDialog.openWarning(getShell(),
|
if (!MessageDialog.openConfirm(getShell(),
|
||||||
"Shader Syntax Error, Upload Aborted", infolog);
|
"Shader Syntax Error, Continue?", infolog))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
sampleView.showError(e);
|
sampleView.showError(e);
|
||||||
}
|
}
|
||||||
@@ -235,8 +235,7 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend
|
|||||||
matchingContext = true;
|
matchingContext = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (matchingContext)
|
if (matchingContext) {
|
||||||
{
|
|
||||||
shadersToUpload.remove(i);
|
shadersToUpload.remove(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -270,7 +269,8 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else
|
} else
|
||||||
for (GLProgram program : shader.programs) {
|
for (int programName : shader.programs) {
|
||||||
|
GLProgram program = shader.context.GetProgram(programName);
|
||||||
ExchangeMessage(contextId, queue, "glLinkProgram(%d)", program.name);
|
ExchangeMessage(contextId, queue, "glLinkProgram(%d)", program.name);
|
||||||
rcv = ExchangeMessage(contextId, queue,
|
rcv = ExchangeMessage(contextId, queue,
|
||||||
"glGetProgramiv(%d, GL_LINK_STATUS, [0])", program.name);
|
"glGetProgramiv(%d, GL_LINK_STATUS, [0])", program.name);
|
||||||
@@ -336,7 +336,7 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend
|
|||||||
String[] details = list.getSelection()[0].split("\\s+");
|
String[] details = list.getSelection()[0].split("\\s+");
|
||||||
final int contextId = Integer.parseInt(details[0], 16);
|
final int contextId = Integer.parseInt(details[0], 16);
|
||||||
int name = Integer.parseInt(details[2]);
|
int name = Integer.parseInt(details[2]);
|
||||||
current = sampleView.contexts.get(contextId).serverShader.privateShaders.get(name);
|
current = sampleView.contexts.get(contextId).serverShader.shaders.get(name);
|
||||||
styledText.setText(current.source);
|
styledText.setText(current.source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user