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"?>
|
||||
<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="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="src" path="src"/>
|
||||
<classpathentry kind="lib" path="lib/liblzf.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
||||
@@ -10,4 +10,5 @@ Bundle-ActivationPolicy: lazy
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Bundle-ClassPath: lib/host-libprotobuf-java-2.3.0-lite.jar,
|
||||
lib/liblzf.jar,
|
||||
lib/sdklib.jar,
|
||||
.
|
||||
|
||||
@@ -6,4 +6,5 @@ bin.includes = plugin.xml,\
|
||||
icons/,\
|
||||
contexts.xml,\
|
||||
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;
|
||||
|
||||
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.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class Context {
|
||||
public class Context implements Cloneable {
|
||||
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 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) {
|
||||
this.contextId = contextId;
|
||||
shares.add(this);
|
||||
}
|
||||
|
||||
public Message ProcessMessage(Message msg) {
|
||||
switch (msg.getFunction()) {
|
||||
case glBindBuffer:
|
||||
serverVertex.glBindBuffer(msg);
|
||||
break;
|
||||
case glBufferData:
|
||||
serverVertex.glBufferData(msg);
|
||||
break;
|
||||
case glBufferSubData:
|
||||
serverVertex.glBufferSubData(msg);
|
||||
break;
|
||||
case glDeleteBuffers:
|
||||
serverVertex.glDeleteBuffers(msg);
|
||||
break;
|
||||
case glDrawArrays:
|
||||
if (msg.hasArg7())
|
||||
msg = serverVertex.glDrawArrays(msg);
|
||||
break;
|
||||
case glDrawElements:
|
||||
if (msg.hasArg7())
|
||||
msg = serverVertex.glDrawElements(msg);
|
||||
break;
|
||||
case glDisableVertexAttribArray:
|
||||
serverVertex.glDisableVertexAttribArray(msg);
|
||||
break;
|
||||
case glEnableVertexAttribArray:
|
||||
serverVertex.glEnableVertexAttribArray(msg);
|
||||
break;
|
||||
case glGenBuffers:
|
||||
serverVertex.glGenBuffers(msg);
|
||||
break;
|
||||
case glVertexAttribPointer:
|
||||
serverVertex.glVertexAttribPointer(msg);
|
||||
break;
|
||||
case glVertexAttrib1f:
|
||||
serverVertex.glVertexAttrib1f(msg);
|
||||
break;
|
||||
case glVertexAttrib1fv:
|
||||
serverVertex.glVertexAttrib1fv(msg);
|
||||
break;
|
||||
case glVertexAttrib2f:
|
||||
serverVertex.glVertexAttrib2f(msg);
|
||||
break;
|
||||
case glVertexAttrib2fv:
|
||||
serverVertex.glVertexAttrib2fv(msg);
|
||||
break;
|
||||
case glVertexAttrib3f:
|
||||
serverVertex.glVertexAttrib3f(msg);
|
||||
break;
|
||||
case glVertexAttrib3fv:
|
||||
serverVertex.glVertexAttrib3fv(msg);
|
||||
break;
|
||||
case glVertexAttrib4f:
|
||||
serverVertex.glVertexAttrib4f(msg);
|
||||
break;
|
||||
case glVertexAttrib4fv:
|
||||
serverVertex.glVertexAttrib4fv(msg);
|
||||
break;
|
||||
// returns instance TODO: return new instance if changed
|
||||
public Context ProcessMessage(Message msg) {
|
||||
GLServerVertex newVertex = serverVertex.Process(msg);
|
||||
if (newVertex != null) {
|
||||
processed = newVertex.processed;
|
||||
assert newVertex == serverVertex;
|
||||
return this;
|
||||
}
|
||||
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;
|
||||
|
||||
import com.android.glesv2debugger.DebuggerMessage.Message;
|
||||
import com.android.sdklib.util.SparseArray;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
class GLShader {
|
||||
final int name;
|
||||
class GLShader implements Cloneable {
|
||||
public final int name;
|
||||
final GLServerShader context; // the context this was created in
|
||||
final GLEnum type;
|
||||
boolean delete;
|
||||
ArrayList<GLProgram> programs = new ArrayList<GLProgram>();
|
||||
String source, originalSource;
|
||||
public final GLEnum type;
|
||||
public boolean delete;
|
||||
public ArrayList<Integer> programs = new ArrayList<Integer>();
|
||||
public String source, originalSource;
|
||||
|
||||
GLShader(final int name, final GLServerShader context, final GLEnum type) {
|
||||
this.name = name;
|
||||
this.context = context;
|
||||
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 {
|
||||
final int name;
|
||||
class GLProgram implements Cloneable {
|
||||
public final int name;
|
||||
final GLServerShader context; // the context this was created in
|
||||
boolean delete;
|
||||
GLShader vert, frag;
|
||||
public boolean delete;
|
||||
public int vert, frag;
|
||||
|
||||
GLProgram(final int name, final GLServerShader context) {
|
||||
this.name = name;
|
||||
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 {
|
||||
final Context context;
|
||||
HashMap<Integer, GLShader> privateShaders = new HashMap<Integer, GLShader>();
|
||||
HashMap<Integer, GLProgram> privatePrograms = new HashMap<Integer, GLProgram>();
|
||||
GLProgram current = null;
|
||||
public boolean uiUpdate = false;
|
||||
public class GLServerShader implements Cloneable {
|
||||
Context context;
|
||||
public SparseArray<GLShader> shaders = new SparseArray<GLShader>();
|
||||
public SparseArray<GLProgram> programs = new SparseArray<GLProgram>();
|
||||
public GLProgram current = null;
|
||||
boolean uiUpdate = false;
|
||||
|
||||
GLServerShader(final Context context) {
|
||||
GLServerShader(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;
|
||||
uiUpdate = true;
|
||||
switch (msg.getFunction()) {
|
||||
case glAttachShader:
|
||||
glAttachShader(msg);
|
||||
break;
|
||||
return this;
|
||||
case glCreateProgram:
|
||||
glCreateProgram(msg);
|
||||
break;
|
||||
return this;
|
||||
case glCreateShader:
|
||||
glCreateShader(msg);
|
||||
break;
|
||||
return this;
|
||||
case glDeleteProgram:
|
||||
glDeleteProgram(msg);
|
||||
break;
|
||||
return this;
|
||||
case glDeleteShader:
|
||||
glDeleteShader(msg);
|
||||
break;
|
||||
return this;
|
||||
case glDetachShader:
|
||||
glDetachShader(msg);
|
||||
break;
|
||||
return this;
|
||||
case glShaderSource:
|
||||
glShaderSource(msg);
|
||||
break;
|
||||
return this;
|
||||
case glUseProgram:
|
||||
glUseProgram(msg);
|
||||
break;
|
||||
return this;
|
||||
default:
|
||||
uiUpdate = oldUiUpdate;
|
||||
break;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +148,7 @@ public class GLServerShader {
|
||||
if (name == 0)
|
||||
return null;
|
||||
for (Context ctx : context.shares) {
|
||||
GLShader shader = ctx.serverShader.privateShaders.get(name);
|
||||
GLShader shader = ctx.serverShader.shaders.get(name);
|
||||
if (shader != null)
|
||||
return shader;
|
||||
}
|
||||
@@ -109,7 +160,7 @@ public class GLServerShader {
|
||||
if (name == 0)
|
||||
return null;
|
||||
for (Context ctx : context.shares) {
|
||||
GLProgram program = ctx.serverShader.privatePrograms.get(name);
|
||||
GLProgram program = ctx.serverShader.programs.get(name);
|
||||
if (program != null)
|
||||
return program;
|
||||
}
|
||||
@@ -122,20 +173,20 @@ public class GLServerShader {
|
||||
GLProgram program = GetProgram(msg.getArg0());
|
||||
GLShader shader = GetShader(msg.getArg1());
|
||||
if (GLEnum.GL_VERTEX_SHADER == shader.type)
|
||||
program.vert = shader;
|
||||
program.vert = shader.name;
|
||||
else
|
||||
program.frag = shader;
|
||||
shader.programs.add(program);
|
||||
program.frag = shader.name;
|
||||
shader.programs.add(program.name);
|
||||
}
|
||||
|
||||
// GLuint API_ENTRY(glCreateProgram)(void)
|
||||
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)
|
||||
void glCreateShader(final Message msg) {
|
||||
privateShaders.put(msg.getRet(),
|
||||
shaders.put(msg.getRet(),
|
||||
new GLShader(msg.getRet(), this, GLEnum.valueOf(msg.getArg0())));
|
||||
}
|
||||
|
||||
@@ -148,9 +199,9 @@ public class GLServerShader {
|
||||
for (Context ctx : context.shares)
|
||||
if (ctx.serverShader.current == program)
|
||||
return;
|
||||
glDetachShader(program, program.vert);
|
||||
glDetachShader(program, program.frag);
|
||||
privatePrograms.remove(program.name);
|
||||
glDetachShader(program, GetShader(program.vert));
|
||||
glDetachShader(program, GetShader(program.frag));
|
||||
programs.remove(program.name);
|
||||
}
|
||||
|
||||
// void API_ENTRY(glDeleteShader)(GLuint shader)
|
||||
@@ -160,7 +211,7 @@ public class GLServerShader {
|
||||
GLShader shader = GetShader(msg.getArg0());
|
||||
shader.delete = true;
|
||||
if (shader.programs.size() == 0)
|
||||
privateShaders.remove(shader.name);
|
||||
shaders.remove(shader.name);
|
||||
}
|
||||
|
||||
// void API_ENTRY(glDetachShader)(GLuint program, GLuint shader)
|
||||
@@ -171,15 +222,15 @@ public class GLServerShader {
|
||||
void glDetachShader(final GLProgram program, final GLShader shader) {
|
||||
if (program == null)
|
||||
return;
|
||||
if (program.vert == shader)
|
||||
program.vert = null;
|
||||
else if (program.frag == shader)
|
||||
program.frag = null;
|
||||
if (program.vert == shader.name)
|
||||
program.vert = 0;
|
||||
else if (program.frag == shader.name)
|
||||
program.frag = 0;
|
||||
else
|
||||
return;
|
||||
shader.programs.remove(program);
|
||||
shader.programs.remove(program.name);
|
||||
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
|
||||
@@ -195,12 +246,11 @@ public class GLServerShader {
|
||||
void glUseProgram(final Message msg) {
|
||||
GLProgram oldCurrent = current;
|
||||
current = GetProgram(msg.getArg0());
|
||||
if (null != oldCurrent && oldCurrent.delete && oldCurrent != current)
|
||||
{
|
||||
if (null != oldCurrent && oldCurrent.delete && oldCurrent != current) {
|
||||
for (Context ctx : context.shares)
|
||||
if (ctx.serverShader.current == oldCurrent)
|
||||
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;
|
||||
|
||||
class GLBuffer {
|
||||
GLEnum usage;
|
||||
GLEnum target;
|
||||
ByteBuffer data;
|
||||
public GLEnum usage;
|
||||
public GLEnum target;
|
||||
public ByteBuffer data;
|
||||
}
|
||||
|
||||
class GLAttribPointer {
|
||||
int size; // number of values per vertex
|
||||
GLEnum type; // data type
|
||||
int stride; // bytes
|
||||
int ptr; // pointer in debugger server or byte offset into buffer
|
||||
GLBuffer buffer;
|
||||
boolean normalized;
|
||||
boolean enabled;
|
||||
public int size; // number of values per vertex
|
||||
public GLEnum type; // data type
|
||||
public int stride; // bytes
|
||||
public int ptr; // pointer in debugger server or byte offset into buffer
|
||||
public GLBuffer buffer;
|
||||
public boolean normalized;
|
||||
public boolean enabled;
|
||||
}
|
||||
|
||||
public class GLServerVertex {
|
||||
|
||||
HashMap<Integer, GLBuffer> buffers;
|
||||
GLBuffer attribBuffer, indexBuffer; // current binding
|
||||
GLAttribPointer attribPointers[];
|
||||
float defaultAttribs[][];
|
||||
public HashMap<Integer, GLBuffer> buffers;
|
||||
public GLBuffer attribBuffer, indexBuffer; // current binding
|
||||
public GLAttribPointer attribPointers[];
|
||||
public float defaultAttribs[][];
|
||||
int maxAttrib;
|
||||
|
||||
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)
|
||||
public void glBindBuffer(Message msg) {
|
||||
if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ARRAY_BUFFER) {
|
||||
|
||||
@@ -33,9 +33,11 @@ public class MessageData {
|
||||
public float[] data;
|
||||
public int maxAttrib; // used for formatting data
|
||||
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) {
|
||||
this.msg = msg;
|
||||
this.context = context;
|
||||
image = null;
|
||||
shader = null;
|
||||
data = null;
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.eclipse.jface.viewers.LabelProvider;
|
||||
import org.eclipse.jface.viewers.ListViewer;
|
||||
import org.eclipse.jface.viewers.SelectionChangedEvent;
|
||||
import org.eclipse.jface.viewers.StructuredSelection;
|
||||
import org.eclipse.jface.viewers.TreeViewer;
|
||||
import org.eclipse.jface.viewers.Viewer;
|
||||
import org.eclipse.jface.viewers.ViewerFilter;
|
||||
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";
|
||||
|
||||
TabFolder tabFolder;
|
||||
TabItem tabItemText, tabItemImage, tabItemBreakpointOption, tabItemShaderEditor;
|
||||
TabItem tabItemText, tabItemImage, tabItemBreakpointOption;
|
||||
TabItem tabItemShaderEditor, tabContextViewer;
|
||||
ListViewer viewer;
|
||||
TreeViewer contextViewer;
|
||||
BreakpointOption breakpointOption;
|
||||
ShaderEditor shaderEditor;
|
||||
Canvas canvas;
|
||||
@@ -141,6 +144,7 @@ public class SampleView extends ViewPart implements Runnable {
|
||||
bar.setSelection(bar.getMaximum());
|
||||
viewer.getList().setSelection(
|
||||
entries.size() - 1);
|
||||
// MessageDataSelected(entries.get(entries.size() - 1));
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -228,6 +232,7 @@ public class SampleView extends ViewPart implements Runnable {
|
||||
viewer.setFilters(new ViewerFilter[] {
|
||||
new Filter()
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -270,6 +275,14 @@ public class SampleView extends ViewPart implements Runnable {
|
||||
tabItemShaderEditor.setText("Shader Editor");
|
||||
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();
|
||||
hBar.addListener(SWT.Selection, new Listener() {
|
||||
@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() {
|
||||
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
|
||||
@Override
|
||||
@@ -537,39 +577,8 @@ public class SampleView extends ViewPart implements Runnable {
|
||||
if (null == selection)
|
||||
return;
|
||||
MessageData msgData = (MessageData) selection.getFirstElement();
|
||||
if (null == msgData)
|
||||
return;
|
||||
if (null != msgData.image)
|
||||
{
|
||||
canvas.setBackgroundImage(msgData.image);
|
||||
tabFolder.setSelection(tabItemImage);
|
||||
MessageDataSelected(msgData);
|
||||
}
|
||||
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());
|
||||
contexts.put(msg.getContextId(), context);
|
||||
}
|
||||
msg = context.ProcessMessage(msg);
|
||||
shaderEditorUpdate |= context.serverShader.uiUpdate;
|
||||
Context newContext = context.ProcessMessage(msg);
|
||||
// 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()
|
||||
.getShell().getDisplay(), msg, context);
|
||||
|
||||
@@ -107,7 +107,8 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend
|
||||
progs += context.serverShader.current.name + "(0x";
|
||||
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();
|
||||
builder.append(String.format("%08X", context.contextId));
|
||||
builder.append(' ');
|
||||
@@ -123,17 +124,17 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend
|
||||
builder.append(' ');
|
||||
}
|
||||
builder.append(": ");
|
||||
for (GLProgram program : shader.programs) {
|
||||
builder.append(program.name);
|
||||
for (int program : shader.programs) {
|
||||
builder.append(program);
|
||||
builder.append(" ");
|
||||
}
|
||||
list.add(builder.toString());
|
||||
}
|
||||
}
|
||||
// if (!progs.equals(currentPrograms.getText())) {
|
||||
currentPrograms.setText(progs);
|
||||
|
||||
// }
|
||||
currentPrograms.setText(progs);
|
||||
toolbar.redraw();
|
||||
toolbar.pack(true);
|
||||
toolbar.update();
|
||||
}
|
||||
|
||||
@@ -169,11 +170,10 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend
|
||||
new Color(Display.getCurrent(), 255, 230, 230));
|
||||
}
|
||||
if (infolog.length() > 0) {
|
||||
MessageDialog.openWarning(getShell(),
|
||||
"Shader Syntax Error, Upload Aborted", infolog);
|
||||
if (!MessageDialog.openConfirm(getShell(),
|
||||
"Shader Syntax Error, Continue?", infolog))
|
||||
return;
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
sampleView.showError(e);
|
||||
}
|
||||
@@ -235,8 +235,7 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend
|
||||
matchingContext = true;
|
||||
break;
|
||||
}
|
||||
if (matchingContext)
|
||||
{
|
||||
if (matchingContext) {
|
||||
shadersToUpload.remove(i);
|
||||
break;
|
||||
}
|
||||
@@ -270,7 +269,8 @@ public class ShaderEditor extends Composite implements SelectionListener, Extend
|
||||
}
|
||||
});
|
||||
} else
|
||||
for (GLProgram program : shader.programs) {
|
||||
for (int programName : shader.programs) {
|
||||
GLProgram program = shader.context.GetProgram(programName);
|
||||
ExchangeMessage(contextId, queue, "glLinkProgram(%d)", program.name);
|
||||
rcv = ExchangeMessage(contextId, queue,
|
||||
"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+");
|
||||
final int contextId = Integer.parseInt(details[0], 16);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user