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"?>
|
||||
<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