Merge "GLES2Dbg: add more state tracking and snapshot of state per GL call"
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