Initial commit of OpenGL ES 2.0 Debugger Client

Displays GL call parameters, textures, screen captures and shader source.
Server code is in frameworks/base/opengl/libs/GLES2_dbg.
Protobuf code is generated using generate_debugger_message_proto.py in server code.

Change-Id: Ibe105b60dbe59af84f721c077d2c138a4d04767e
Signed-off-by: David Li <davidxli@google.com>
diff --git a/tools/glesv2debugger/.classpath b/tools/glesv2debugger/.classpath
new file mode 100755
index 0000000..1ef2c20
--- /dev/null
+++ b/tools/glesv2debugger/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry exported="true" 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="output" path="bin"/>
+</classpath>
diff --git a/tools/glesv2debugger/.project b/tools/glesv2debugger/.project
new file mode 100755
index 0000000..0c974ca
--- /dev/null
+++ b/tools/glesv2debugger/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>GLESv2DebuggerClient</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/glesv2debugger/META-INF/MANIFEST.MF b/tools/glesv2debugger/META-INF/MANIFEST.MF
new file mode 100755
index 0000000..70b330f
--- /dev/null
+++ b/tools/glesv2debugger/META-INF/MANIFEST.MF
@@ -0,0 +1,12 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: GLESv2DebuggerClient
+Bundle-SymbolicName: GLESv2DebuggerClient; singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: com.android.glesv2debugger.Activator
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-ClassPath: lib/host-libprotobuf-java-2.3.0-lite.jar,
+ .
diff --git a/tools/glesv2debugger/build.properties b/tools/glesv2debugger/build.properties
new file mode 100755
index 0000000..6272a36
--- /dev/null
+++ b/tools/glesv2debugger/build.properties
@@ -0,0 +1,8 @@
+source.. = src/

+output.. = bin/

+bin.includes = plugin.xml,\

+               META-INF/,\

+               .,\

+               icons/,\

+               contexts.xml,\

+               lib/host-libprotobuf-java-2.3.0-lite.jar

diff --git a/tools/glesv2debugger/contexts.xml b/tools/glesv2debugger/contexts.xml
new file mode 100755
index 0000000..02e26e4
--- /dev/null
+++ b/tools/glesv2debugger/contexts.xml
@@ -0,0 +1,12 @@
+<contexts>
+	<context id="viewer" title="Sample View">
+		<description>This is the context help for the sample view with a table viewer. It was generated by a PDE template.</description>
+		<topic href="/PLUGINS_ROOT/org.eclipse.platform.doc.isv/guide/ua_help_context.htm" label="Context-sensitive help">
+			<enablement>
+				<with variable="platform">
+	            	<test property="org.eclipse.core.runtime.isBundleInstalled" args="org.eclipse.platform.doc.isv"/>
+	     		</with>
+			</enablement>
+		</topic>
+	</context>
+</contexts>
diff --git a/tools/glesv2debugger/generate_GLEnum_java.py b/tools/glesv2debugger/generate_GLEnum_java.py
new file mode 100755
index 0000000..cf543c8
--- /dev/null
+++ b/tools/glesv2debugger/generate_GLEnum_java.py
@@ -0,0 +1,73 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+#
+# 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.
+#
+
+if __name__ == "__main__":
+    externs = []
+    lines = open("../../../frameworks/base/opengl/libs/enums.in").readlines()
+    output = open("src/com/android/glesv2debugger/GLEnum.java", "w")
+    i = 0
+    output.write(
+"""/*
+ ** 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.
+ */
+
+// auto generated by generate_GLEnum_java.py"
+
+package com.android.glesv2debugger;
+
+public enum GLEnum {
+""")
+    
+    index = 0
+    for line in lines:
+        value = line[line.find("(") + 1: line.find(",")]
+        name = line[line.find(",") + 1: line.find(")")]    
+        output.write("    %s(%s),\n" % (name, value))
+
+    output.write("""    ;
+
+    public final int value;
+    GLEnum(final int value) {
+        this.value = value;
+    }
+
+    private static final java.util.HashMap<Integer, GLEnum> reverseMap = new java.util.HashMap<Integer, GLEnum>();
+    static {
+        for (GLEnum e : GLEnum.values())
+        reverseMap.put(e.value, e);
+    }
+
+    public static GLEnum valueOf(final int value) {
+        return reverseMap.get(value);
+    }
+}""")
+
+
diff --git a/tools/glesv2debugger/generate_GLFunction_java.py b/tools/glesv2debugger/generate_GLFunction_java.py
new file mode 100755
index 0000000..da05690
--- /dev/null
+++ b/tools/glesv2debugger/generate_GLFunction_java.py
@@ -0,0 +1,67 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+#
+# 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.
+#
+ 
+if __name__ == "__main__":
+    externs = []
+    lines = open("../../../frameworks/base/opengl/libs/GLES2_dbg/gl2_api_annotated.in").readlines()
+    output = open("src/com/android/glesv2debugger/GLFunction.java", "w")
+    i = 0
+    output.write(
+"""/*
+ ** 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.
+ */
+
+// auto generated by generate_GLFunction_java.py"
+
+package com.android.glesv2debugger;
+
+public enum GLFunction {
+""")
+    
+    index = 0
+    for line in lines:
+        if line.find("API_ENTRY(") >= 0: # a function prototype
+            returnType = line[0: line.find(" API_ENTRY(")]
+            functionName = line[line.find("(") + 1: line.find(")")] #extract GL function name
+            output.write("    %s(%d, DebuggerMessage.Message.Function.%s),\n" % (functionName, index, functionName))
+            index += 1
+    output.write("""    ;
+
+    public final int index;
+    public final DebuggerMessage.Message.Function function;
+
+    GLFunction(final int index, final DebuggerMessage.Message.Function function) {
+        this.index = index;
+        this.function = function;
+    }
+}""")
+            
+
diff --git a/tools/glesv2debugger/generate_MessageFormatter_java.py b/tools/glesv2debugger/generate_MessageFormatter_java.py
new file mode 100755
index 0000000..b6c67a9
--- /dev/null
+++ b/tools/glesv2debugger/generate_MessageFormatter_java.py
@@ -0,0 +1,249 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+#
+# 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.
+#
+
+import os
+import sys
+
+def RemoveAnnotation(line):
+    if line.find(":") >= 0:
+        annotation = line[line.find(":"): line.find(" ", line.find(":"))]
+        return line.replace(annotation, "*")
+    else:
+        return line
+        
+if __name__ == "__main__":
+    externs = []
+    lines = open("../../../frameworks/base/opengl/libs/GLES2_dbg/gl2_api_annotated.in").readlines()
+    output = open("src/com/android/glesv2debugger/MessageFormatter.java", "w")
+    
+    i = 0
+    output.write(
+"""/*
+ ** 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.
+ */
+
+// auto generated by generate_MessageFormatter_java.py"
+
+package com.android.glesv2debugger;
+
+import java.nio.ByteBuffer;
+
+public class MessageFormatter {
+
+    static String FormatFloats(int count, final ByteBuffer data) {
+        String ret = "[";
+        for (int i = 0; i < count; i++)
+        {
+            ret += Float.intBitsToFloat(Integer.reverseBytes(data.getInt()));
+            if (i < count - 1)
+                ret += ", ";
+        }
+        return ret + "]";
+    }
+    
+    static String FormatInts(int count, final ByteBuffer data) {
+        String ret = "[";
+        for (int i = 0; i < count; i++)
+        {
+            ret += Integer.reverseBytes(data.getInt());
+            if (i < count - 1)
+                ret += ", ";
+        }
+        return ret + "]";
+    }
+    
+    static String FormatUints(int count, final ByteBuffer data) {
+        String ret = "[";
+        for (int i = 0; i < count; i++)
+        {
+            long bits = Integer.reverseBytes(data.getInt()) & 0xffffffff;
+            ret += bits;
+            if (i < count - 1)
+                ret += ", ";
+        }
+        return ret + "]";
+    }
+    
+    static String FormatMatrix(int columns, int count, final ByteBuffer data) {
+        String ret = "[";
+        for (int i = 0; i < count; i++)
+        {
+            ret += Float.intBitsToFloat(Integer.reverseBytes(data.getInt()));
+            if (i % columns == columns - 1)
+                ret += '\\n';
+            else if (i < count - 1)
+                ret += ", ";
+        }
+        return ret + "]";
+    }
+
+    public static String Format(final DebuggerMessage.Message msg) {
+        String str;
+        switch (msg.getFunction()) {
+""")
+            
+    for line in lines:
+        if line.find("API_ENTRY(") >= 0: # a function prototype
+            returnType = line[0: line.find(" API_ENTRY(")].replace("const ", "")
+            functionName = line[line.find("(") + 1: line.find(")")] #extract GL function name
+            parameterList = line[line.find(")(") + 2: line.find(") {")]
+                        
+            parameters = parameterList.split(',')
+            paramIndex = 0
+            
+            formatString = "%s "
+            formatArgs = ""
+            if returnType != "void":
+                if returnType == "GLenum":
+                    formatArgs += "GLEnum.valueOf(msg.getRet())"
+                elif returnType.find("*") >= 0:
+                    formatArgs += '"0x" + Integer.toHexString(msg.getRet())'
+                else:
+                    formatArgs += "msg.getRet()"
+            else:
+                formatArgs += '"void"'
+            
+            #formatString += "%s(" % (functionName)
+            formatString += "("
+            
+            if parameterList == "void":
+                parameters = []
+            inout = ""
+            
+            paramNames = []
+            
+            for parameter in parameters:
+                parameter = parameter.replace("const","")
+                parameter = parameter.strip()
+                paramType = parameter.split(' ')[0]
+                paramName = parameter.split(' ')[1]
+                annotation = ""
+                
+                formatString += paramName + "=%s"
+                    
+                if parameter.find(":") >= 0:
+                    assert inout == "" # only one parameter should be annotated
+                    inout = paramType.split(":")[2]
+                    annotation = paramType.split(":")[1]
+                    paramType = paramType.split(":")[0]
+                    count = 1
+                    countArg = ""
+                    if annotation.find("*") >= 0: # [1,n] * param
+                        count = int(annotation.split("*")[0])
+                        countArg = annotation.split("*")[1]
+                        assert countArg in paramNames
+                    elif annotation in paramNames:
+                        count = 1
+                        countArg = annotation
+                    elif annotation == "GLstring":
+                        annotation = annotation
+                    else:
+                        count = int(annotation)
+                    dataFormatter = ""
+                    if paramType == "GLfloat":
+                        dataFormatter = "FormatFloats"
+                    elif paramType == "GLint":
+                        dataFormatter = "FormatInts"
+                    elif paramType == "GLuint":
+                        dataFormatter = "FormatUints"
+                    elif annotation == "GLstring":
+                        assert paramType == "GLchar"
+                    elif paramType.find("void") >= 0:
+                        assert 1
+                    else:
+                        assert 0
+                    if functionName.find("Matrix") >= 0:
+                        columns = int(functionName[functionName.find("fv") - 1: functionName.find("fv")])
+                        assert columns * columns == count
+                        assert countArg != ""
+                        assert paramType == "GLfloat"
+                        formatArgs += ", FormatMatrix(%d, %d * msg.getArg%d(), msg.getData().asReadOnlyByteBuffer())" % (columns, count, paramNames.index(countArg))
+                    elif annotation == "GLstring":
+                        formatArgs += ", msg.getData().toStringUtf8()"
+                    elif paramType.find("void") >= 0:
+                        formatArgs += ', "0x" + Integer.toHexString(msg.getArg%d())' % (paramIndex)
+                    elif countArg == "":
+                        formatArgs += ", %s(%d, msg.getData().asReadOnlyByteBuffer())" % (dataFormatter, count)
+                    else:
+                        formatArgs += ", %s(%d * msg.getArg%d(), msg.getData().asReadOnlyByteBuffer())" % (dataFormatter, count, paramNames.index(countArg))
+                else:
+                    if paramType == "GLfloat" or paramType == "GLclampf":
+                        formatArgs += ", Float.intBitsToFloat(msg.getArg%d())" % (paramIndex)
+                    elif paramType == "GLenum": 
+                        formatArgs += ", GLEnum.valueOf(msg.getArg%d())" % (paramIndex)
+                    elif paramType.find("*") >= 0:
+                        formatArgs += ', "0x" + Integer.toHexString(msg.getArg%d())' % (paramIndex)
+                    else:
+                        formatArgs += ", msg.getArg%d()" % (paramIndex)
+                if paramIndex < len(parameters) - 1:
+                    formatString += ", "
+                paramNames.append(paramName)
+                paramIndex += 1  
+
+                
+            formatString += ")"
+             
+            output.write("            case %s:\n" % (functionName))
+            if line.find("*") >= 0 and (line.find("*") < line.find(":") or line.find("*") > line.rfind(":")):
+                sys.stderr.write(line)
+                output.write("                // FIXME: this function uses pointers, debugger may send data in msg.data\n")
+            output.write('                str = String.format("%s", %s); break;\n' % (formatString, formatArgs))
+            
+
+    output.write("""            default:
+                str = msg.toString();
+        }
+        return str;
+    }
+}""")
+
+'''    print """/*
+package GLESv2Debugger;
+
+public class MessageFormatterCustom {
+
+    public static String Format(final DebuggerMessage.Message msg) {
+        String str;
+        switch (msg.getFunction()) {"""
+
+    for extern in externs:
+        print "        case %s" % (extern)
+        print "            // TODO:"
+
+print """        default:
+            str = msg.toString();
+        }
+        return str;
+    }
+}
+*/"""    '''
+        
+        
diff --git a/tools/glesv2debugger/icons/sample.gif b/tools/glesv2debugger/icons/sample.gif
new file mode 100755
index 0000000..34fb3c9
--- /dev/null
+++ b/tools/glesv2debugger/icons/sample.gif
Binary files differ
diff --git a/tools/glesv2debugger/lib/host-libprotobuf-java-2.3.0-lite.jar b/tools/glesv2debugger/lib/host-libprotobuf-java-2.3.0-lite.jar
new file mode 100644
index 0000000..667d407
--- /dev/null
+++ b/tools/glesv2debugger/lib/host-libprotobuf-java-2.3.0-lite.jar
Binary files differ
diff --git a/tools/glesv2debugger/plugin.xml b/tools/glesv2debugger/plugin.xml
new file mode 100755
index 0000000..f1512a5
--- /dev/null
+++ b/tools/glesv2debugger/plugin.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<?eclipse version="3.4"?>

+<plugin>

+

+   <extension

+         point="org.eclipse.ui.views">

+      <view

+            name="OpenGL ES 2.0 Debugger"

+            icon="icons/sample.gif"

+            category="org.eclipse.debug.ui"

+            class="com.android.glesv2debugger.SampleView"

+            id="glesv2debuggerclient.views.SampleView">

+      </view>

+   </extension>

+   <extension

+         point="org.eclipse.ui.perspectiveExtensions">

+      <perspectiveExtension

+            targetID="org.eclipse.jdt.ui.JavaPerspective">

+         <view

+               ratio="0.5"

+               relative="org.eclipse.ui.views.TaskList"

+               relationship="right"

+               id="glesv2debuggerclient.views.SampleView">

+         </view>

+      </perspectiveExtension>

+   </extension>

+   <extension

+         point="org.eclipse.help.contexts">

+      <contexts

+            file="contexts.xml">

+      </contexts>

+   </extension>

+

+</plugin>

diff --git a/tools/glesv2debugger/src/META-INF/MANIFEST.MF b/tools/glesv2debugger/src/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..212b27a
--- /dev/null
+++ b/tools/glesv2debugger/src/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0

+Created-By: 1.6.0_22 (Sun Microsystems Inc.)

+

diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/Activator.java b/tools/glesv2debugger/src/com/android/glesv2debugger/Activator.java
new file mode 100755
index 0000000..f859510
--- /dev/null
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/Activator.java
@@ -0,0 +1,81 @@
+/*

+ ** 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 org.eclipse.jface.resource.ImageDescriptor;

+import org.eclipse.ui.plugin.AbstractUIPlugin;

+import org.osgi.framework.BundleContext;

+

+/**

+ * The activator class controls the plug-in life cycle

+ */

+public class Activator extends AbstractUIPlugin {

+

+    // The plug-in ID

+    public static final String PLUGIN_ID = "GLESv2DebuggerClient"; //$NON-NLS-1$

+

+    // The shared instance

+    private static Activator plugin;

+

+    /**

+     * The constructor

+     */

+    public Activator() {

+    }

+

+    /*

+     * (non-Javadoc)

+     * @see

+     * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext

+     * )

+     */

+    public void start(BundleContext context) throws Exception {

+        super.start(context);

+        plugin = this;

+    }

+

+    /*

+     * (non-Javadoc)

+     * @see

+     * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext

+     * )

+     */

+    public void stop(BundleContext context) throws Exception {

+        plugin = null;

+        super.stop(context);

+    }

+

+    /**

+     * Returns the shared instance

+     * 

+     * @return the shared instance

+     */

+    public static Activator getDefault() {

+        return plugin;

+    }

+

+    /**

+     * Returns an image descriptor for the image file at the given plug-in

+     * relative path

+     * 

+     * @param path the path

+     * @return the image descriptor

+     */

+    public static ImageDescriptor getImageDescriptor(String path) {

+        return imageDescriptorFromPlugin(PLUGIN_ID, path);

+    }

+}

diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/DebuggerMessage.java b/tools/glesv2debugger/src/com/android/glesv2debugger/DebuggerMessage.java
new file mode 100644
index 0000000..fa1d7ed
--- /dev/null
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/DebuggerMessage.java
@@ -0,0 +1,1463 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: debugger_message.proto
+
+package com.android.glesv2debugger;
+
+public final class DebuggerMessage {
+  private DebuggerMessage() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+  public static final class Message extends
+      com.google.protobuf.GeneratedMessageLite {
+    // Use Message.newBuilder() to construct.
+    private Message() {
+      initFields();
+    }
+    private Message(boolean noInit) {}
+    
+    private static final Message defaultInstance;
+    public static Message getDefaultInstance() {
+      return defaultInstance;
+    }
+    
+    public Message getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+    
+    public enum Function
+        implements com.google.protobuf.Internal.EnumLite {
+      glActiveTexture(0, 0),
+      glAttachShader(1, 1),
+      glBindAttribLocation(2, 2),
+      glBindBuffer(3, 3),
+      glBindFramebuffer(4, 4),
+      glBindRenderbuffer(5, 5),
+      glBindTexture(6, 6),
+      glBlendColor(7, 7),
+      glBlendEquation(8, 8),
+      glBlendEquationSeparate(9, 9),
+      glBlendFunc(10, 10),
+      glBlendFuncSeparate(11, 11),
+      glBufferData(12, 12),
+      glBufferSubData(13, 13),
+      glCheckFramebufferStatus(14, 14),
+      glClear(15, 15),
+      glClearColor(16, 16),
+      glClearDepthf(17, 17),
+      glClearStencil(18, 18),
+      glColorMask(19, 19),
+      glCompileShader(20, 20),
+      glCompressedTexImage2D(21, 21),
+      glCompressedTexSubImage2D(22, 22),
+      glCopyTexImage2D(23, 23),
+      glCopyTexSubImage2D(24, 24),
+      glCreateProgram(25, 25),
+      glCreateShader(26, 26),
+      glCullFace(27, 27),
+      glDeleteBuffers(28, 28),
+      glDeleteFramebuffers(29, 29),
+      glDeleteProgram(30, 30),
+      glDeleteRenderbuffers(31, 31),
+      glDeleteShader(32, 32),
+      glDeleteTextures(33, 33),
+      glDepthFunc(34, 34),
+      glDepthMask(35, 35),
+      glDepthRangef(36, 36),
+      glDetachShader(37, 37),
+      glDisable(38, 38),
+      glDisableVertexAttribArray(39, 39),
+      glDrawArrays(40, 40),
+      glDrawElements(41, 41),
+      glEnable(42, 42),
+      glEnableVertexAttribArray(43, 43),
+      glFinish(44, 44),
+      glFlush(45, 45),
+      glFramebufferRenderbuffer(46, 46),
+      glFramebufferTexture2D(47, 47),
+      glFrontFace(48, 48),
+      glGenBuffers(49, 49),
+      glGenerateMipmap(50, 50),
+      glGenFramebuffers(51, 51),
+      glGenRenderbuffers(52, 52),
+      glGenTextures(53, 53),
+      glGetActiveAttrib(54, 54),
+      glGetActiveUniform(55, 55),
+      glGetAttachedShaders(56, 56),
+      glGetAttribLocation(57, 57),
+      glGetBooleanv(58, 58),
+      glGetBufferParameteriv(59, 59),
+      glGetError(60, 60),
+      glGetFloatv(61, 61),
+      glGetFramebufferAttachmentParameteriv(62, 62),
+      glGetIntegerv(63, 63),
+      glGetProgramiv(64, 64),
+      glGetProgramInfoLog(65, 65),
+      glGetRenderbufferParameteriv(66, 66),
+      glGetShaderiv(67, 67),
+      glGetShaderInfoLog(68, 68),
+      glGetShaderPrecisionFormat(69, 69),
+      glGetShaderSource(70, 70),
+      glGetString(71, 71),
+      glGetTexParameterfv(72, 72),
+      glGetTexParameteriv(73, 73),
+      glGetUniformfv(74, 74),
+      glGetUniformiv(75, 75),
+      glGetUniformLocation(76, 76),
+      glGetVertexAttribfv(77, 77),
+      glGetVertexAttribiv(78, 78),
+      glGetVertexAttribPointerv(79, 79),
+      glHint(80, 80),
+      glIsBuffer(81, 81),
+      glIsEnabled(82, 82),
+      glIsFramebuffer(83, 83),
+      glIsProgram(84, 84),
+      glIsRenderbuffer(85, 85),
+      glIsShader(86, 86),
+      glIsTexture(87, 87),
+      glLineWidth(88, 88),
+      glLinkProgram(89, 89),
+      glPixelStorei(90, 90),
+      glPolygonOffset(91, 91),
+      glReadPixels(92, 92),
+      glReleaseShaderCompiler(93, 93),
+      glRenderbufferStorage(94, 94),
+      glSampleCoverage(95, 95),
+      glScissor(96, 96),
+      glShaderBinary(97, 97),
+      glShaderSource(98, 98),
+      glStencilFunc(99, 99),
+      glStencilFuncSeparate(100, 100),
+      glStencilMask(101, 101),
+      glStencilMaskSeparate(102, 102),
+      glStencilOp(103, 103),
+      glStencilOpSeparate(104, 104),
+      glTexImage2D(105, 105),
+      glTexParameterf(106, 106),
+      glTexParameterfv(107, 107),
+      glTexParameteri(108, 108),
+      glTexParameteriv(109, 109),
+      glTexSubImage2D(110, 110),
+      glUniform1f(111, 111),
+      glUniform1fv(112, 112),
+      glUniform1i(113, 113),
+      glUniform1iv(114, 114),
+      glUniform2f(115, 115),
+      glUniform2fv(116, 116),
+      glUniform2i(117, 117),
+      glUniform2iv(118, 118),
+      glUniform3f(119, 119),
+      glUniform3fv(120, 120),
+      glUniform3i(121, 121),
+      glUniform3iv(122, 122),
+      glUniform4f(123, 123),
+      glUniform4fv(124, 124),
+      glUniform4i(125, 125),
+      glUniform4iv(126, 126),
+      glUniformMatrix2fv(127, 127),
+      glUniformMatrix3fv(128, 128),
+      glUniformMatrix4fv(129, 129),
+      glUseProgram(130, 130),
+      glValidateProgram(131, 131),
+      glVertexAttrib1f(132, 132),
+      glVertexAttrib1fv(133, 133),
+      glVertexAttrib2f(134, 134),
+      glVertexAttrib2fv(135, 135),
+      glVertexAttrib3f(136, 136),
+      glVertexAttrib3fv(137, 137),
+      glVertexAttrib4f(138, 138),
+      glVertexAttrib4fv(139, 139),
+      glVertexAttribPointer(140, 140),
+      glViewport(141, 141),
+      eglGetDisplay(142, 142),
+      eglInitialize(143, 143),
+      eglTerminate(144, 144),
+      eglGetConfigs(145, 145),
+      eglChooseConfig(146, 146),
+      eglGetConfigAttrib(147, 147),
+      eglCreateWindowSurface(148, 148),
+      eglCreatePixmapSurface(149, 149),
+      eglCreatePbufferSurface(150, 150),
+      eglDestroySurface(151, 151),
+      eglQuerySurface(152, 152),
+      eglCreateContext(153, 153),
+      eglDestroyContext(154, 154),
+      eglMakeCurrent(155, 155),
+      eglGetCurrentContext(156, 156),
+      eglGetCurrentSurface(157, 157),
+      eglGetCurrentDisplay(158, 158),
+      eglQueryContext(159, 159),
+      eglWaitGL(160, 160),
+      eglWaitNative(161, 161),
+      eglSwapBuffers(162, 162),
+      eglCopyBuffers(163, 163),
+      eglGetError(164, 164),
+      eglQueryString(165, 165),
+      eglGetProcAddress(166, 166),
+      eglSurfaceAttrib(167, 167),
+      eglBindTexImage(168, 168),
+      eglReleaseTexImage(169, 169),
+      eglSwapInterval(170, 170),
+      eglBindAPI(171, 171),
+      eglQueryAPI(172, 172),
+      eglWaitClient(173, 173),
+      eglReleaseThread(174, 174),
+      eglCreatePbufferFromClientBuffer(175, 175),
+      eglLockSurfaceKHR(176, 176),
+      eglUnlockSurfaceKHR(177, 177),
+      eglCreateImageKHR(178, 178),
+      eglDestroyImageKHR(179, 179),
+      eglCreateSyncKHR(180, 180),
+      eglDestroySyncKHR(181, 181),
+      eglClientWaitSyncKHR(182, 182),
+      eglGetSyncAttribKHR(183, 183),
+      eglSetSwapRectangleANDROID(184, 184),
+      eglGetRenderBufferANDROID(185, 185),
+      ACK(186, 186),
+      NEG(187, 187),
+      CONTINUE(188, 188),
+      SKIP(189, 189),
+      SETPROP(190, 190),
+      CAPTURE(191, 191),
+      ;
+      
+      
+      public final int getNumber() { return value; }
+      
+      public static Function valueOf(int value) {
+        switch (value) {
+          case 0: return glActiveTexture;
+          case 1: return glAttachShader;
+          case 2: return glBindAttribLocation;
+          case 3: return glBindBuffer;
+          case 4: return glBindFramebuffer;
+          case 5: return glBindRenderbuffer;
+          case 6: return glBindTexture;
+          case 7: return glBlendColor;
+          case 8: return glBlendEquation;
+          case 9: return glBlendEquationSeparate;
+          case 10: return glBlendFunc;
+          case 11: return glBlendFuncSeparate;
+          case 12: return glBufferData;
+          case 13: return glBufferSubData;
+          case 14: return glCheckFramebufferStatus;
+          case 15: return glClear;
+          case 16: return glClearColor;
+          case 17: return glClearDepthf;
+          case 18: return glClearStencil;
+          case 19: return glColorMask;
+          case 20: return glCompileShader;
+          case 21: return glCompressedTexImage2D;
+          case 22: return glCompressedTexSubImage2D;
+          case 23: return glCopyTexImage2D;
+          case 24: return glCopyTexSubImage2D;
+          case 25: return glCreateProgram;
+          case 26: return glCreateShader;
+          case 27: return glCullFace;
+          case 28: return glDeleteBuffers;
+          case 29: return glDeleteFramebuffers;
+          case 30: return glDeleteProgram;
+          case 31: return glDeleteRenderbuffers;
+          case 32: return glDeleteShader;
+          case 33: return glDeleteTextures;
+          case 34: return glDepthFunc;
+          case 35: return glDepthMask;
+          case 36: return glDepthRangef;
+          case 37: return glDetachShader;
+          case 38: return glDisable;
+          case 39: return glDisableVertexAttribArray;
+          case 40: return glDrawArrays;
+          case 41: return glDrawElements;
+          case 42: return glEnable;
+          case 43: return glEnableVertexAttribArray;
+          case 44: return glFinish;
+          case 45: return glFlush;
+          case 46: return glFramebufferRenderbuffer;
+          case 47: return glFramebufferTexture2D;
+          case 48: return glFrontFace;
+          case 49: return glGenBuffers;
+          case 50: return glGenerateMipmap;
+          case 51: return glGenFramebuffers;
+          case 52: return glGenRenderbuffers;
+          case 53: return glGenTextures;
+          case 54: return glGetActiveAttrib;
+          case 55: return glGetActiveUniform;
+          case 56: return glGetAttachedShaders;
+          case 57: return glGetAttribLocation;
+          case 58: return glGetBooleanv;
+          case 59: return glGetBufferParameteriv;
+          case 60: return glGetError;
+          case 61: return glGetFloatv;
+          case 62: return glGetFramebufferAttachmentParameteriv;
+          case 63: return glGetIntegerv;
+          case 64: return glGetProgramiv;
+          case 65: return glGetProgramInfoLog;
+          case 66: return glGetRenderbufferParameteriv;
+          case 67: return glGetShaderiv;
+          case 68: return glGetShaderInfoLog;
+          case 69: return glGetShaderPrecisionFormat;
+          case 70: return glGetShaderSource;
+          case 71: return glGetString;
+          case 72: return glGetTexParameterfv;
+          case 73: return glGetTexParameteriv;
+          case 74: return glGetUniformfv;
+          case 75: return glGetUniformiv;
+          case 76: return glGetUniformLocation;
+          case 77: return glGetVertexAttribfv;
+          case 78: return glGetVertexAttribiv;
+          case 79: return glGetVertexAttribPointerv;
+          case 80: return glHint;
+          case 81: return glIsBuffer;
+          case 82: return glIsEnabled;
+          case 83: return glIsFramebuffer;
+          case 84: return glIsProgram;
+          case 85: return glIsRenderbuffer;
+          case 86: return glIsShader;
+          case 87: return glIsTexture;
+          case 88: return glLineWidth;
+          case 89: return glLinkProgram;
+          case 90: return glPixelStorei;
+          case 91: return glPolygonOffset;
+          case 92: return glReadPixels;
+          case 93: return glReleaseShaderCompiler;
+          case 94: return glRenderbufferStorage;
+          case 95: return glSampleCoverage;
+          case 96: return glScissor;
+          case 97: return glShaderBinary;
+          case 98: return glShaderSource;
+          case 99: return glStencilFunc;
+          case 100: return glStencilFuncSeparate;
+          case 101: return glStencilMask;
+          case 102: return glStencilMaskSeparate;
+          case 103: return glStencilOp;
+          case 104: return glStencilOpSeparate;
+          case 105: return glTexImage2D;
+          case 106: return glTexParameterf;
+          case 107: return glTexParameterfv;
+          case 108: return glTexParameteri;
+          case 109: return glTexParameteriv;
+          case 110: return glTexSubImage2D;
+          case 111: return glUniform1f;
+          case 112: return glUniform1fv;
+          case 113: return glUniform1i;
+          case 114: return glUniform1iv;
+          case 115: return glUniform2f;
+          case 116: return glUniform2fv;
+          case 117: return glUniform2i;
+          case 118: return glUniform2iv;
+          case 119: return glUniform3f;
+          case 120: return glUniform3fv;
+          case 121: return glUniform3i;
+          case 122: return glUniform3iv;
+          case 123: return glUniform4f;
+          case 124: return glUniform4fv;
+          case 125: return glUniform4i;
+          case 126: return glUniform4iv;
+          case 127: return glUniformMatrix2fv;
+          case 128: return glUniformMatrix3fv;
+          case 129: return glUniformMatrix4fv;
+          case 130: return glUseProgram;
+          case 131: return glValidateProgram;
+          case 132: return glVertexAttrib1f;
+          case 133: return glVertexAttrib1fv;
+          case 134: return glVertexAttrib2f;
+          case 135: return glVertexAttrib2fv;
+          case 136: return glVertexAttrib3f;
+          case 137: return glVertexAttrib3fv;
+          case 138: return glVertexAttrib4f;
+          case 139: return glVertexAttrib4fv;
+          case 140: return glVertexAttribPointer;
+          case 141: return glViewport;
+          case 142: return eglGetDisplay;
+          case 143: return eglInitialize;
+          case 144: return eglTerminate;
+          case 145: return eglGetConfigs;
+          case 146: return eglChooseConfig;
+          case 147: return eglGetConfigAttrib;
+          case 148: return eglCreateWindowSurface;
+          case 149: return eglCreatePixmapSurface;
+          case 150: return eglCreatePbufferSurface;
+          case 151: return eglDestroySurface;
+          case 152: return eglQuerySurface;
+          case 153: return eglCreateContext;
+          case 154: return eglDestroyContext;
+          case 155: return eglMakeCurrent;
+          case 156: return eglGetCurrentContext;
+          case 157: return eglGetCurrentSurface;
+          case 158: return eglGetCurrentDisplay;
+          case 159: return eglQueryContext;
+          case 160: return eglWaitGL;
+          case 161: return eglWaitNative;
+          case 162: return eglSwapBuffers;
+          case 163: return eglCopyBuffers;
+          case 164: return eglGetError;
+          case 165: return eglQueryString;
+          case 166: return eglGetProcAddress;
+          case 167: return eglSurfaceAttrib;
+          case 168: return eglBindTexImage;
+          case 169: return eglReleaseTexImage;
+          case 170: return eglSwapInterval;
+          case 171: return eglBindAPI;
+          case 172: return eglQueryAPI;
+          case 173: return eglWaitClient;
+          case 174: return eglReleaseThread;
+          case 175: return eglCreatePbufferFromClientBuffer;
+          case 176: return eglLockSurfaceKHR;
+          case 177: return eglUnlockSurfaceKHR;
+          case 178: return eglCreateImageKHR;
+          case 179: return eglDestroyImageKHR;
+          case 180: return eglCreateSyncKHR;
+          case 181: return eglDestroySyncKHR;
+          case 182: return eglClientWaitSyncKHR;
+          case 183: return eglGetSyncAttribKHR;
+          case 184: return eglSetSwapRectangleANDROID;
+          case 185: return eglGetRenderBufferANDROID;
+          case 186: return ACK;
+          case 187: return NEG;
+          case 188: return CONTINUE;
+          case 189: return SKIP;
+          case 190: return SETPROP;
+          case 191: return CAPTURE;
+          default: return null;
+        }
+      }
+      
+      public static com.google.protobuf.Internal.EnumLiteMap<Function>
+          internalGetValueMap() {
+        return internalValueMap;
+      }
+      private static com.google.protobuf.Internal.EnumLiteMap<Function>
+          internalValueMap =
+            new com.google.protobuf.Internal.EnumLiteMap<Function>() {
+              public Function findValueByNumber(int number) {
+                return Function.valueOf(number)
+      ;        }
+            };
+      
+      private final int index;
+      private final int value;
+      private Function(int index, int value) {
+        this.index = index;
+        this.value = value;
+      }
+      
+      // @@protoc_insertion_point(enum_scope:com.android.glesv2debugger.Message.Function)
+    }
+    
+    public enum Type
+        implements com.google.protobuf.Internal.EnumLite {
+      BeforeCall(0, 0),
+      AfterCall(1, 1),
+      Response(2, 2),
+      ;
+      
+      
+      public final int getNumber() { return value; }
+      
+      public static Type valueOf(int value) {
+        switch (value) {
+          case 0: return BeforeCall;
+          case 1: return AfterCall;
+          case 2: return Response;
+          default: return null;
+        }
+      }
+      
+      public static com.google.protobuf.Internal.EnumLiteMap<Type>
+          internalGetValueMap() {
+        return internalValueMap;
+      }
+      private static com.google.protobuf.Internal.EnumLiteMap<Type>
+          internalValueMap =
+            new com.google.protobuf.Internal.EnumLiteMap<Type>() {
+              public Type findValueByNumber(int number) {
+                return Type.valueOf(number)
+      ;        }
+            };
+      
+      private final int index;
+      private final int value;
+      private Type(int index, int value) {
+        this.index = index;
+        this.value = value;
+      }
+      
+      // @@protoc_insertion_point(enum_scope:com.android.glesv2debugger.Message.Type)
+    }
+    
+    public enum Prop
+        implements com.google.protobuf.Internal.EnumLite {
+      Capture(0, 0),
+      TimeMode(1, 1),
+      ;
+      
+      
+      public final int getNumber() { return value; }
+      
+      public static Prop valueOf(int value) {
+        switch (value) {
+          case 0: return Capture;
+          case 1: return TimeMode;
+          default: return null;
+        }
+      }
+      
+      public static com.google.protobuf.Internal.EnumLiteMap<Prop>
+          internalGetValueMap() {
+        return internalValueMap;
+      }
+      private static com.google.protobuf.Internal.EnumLiteMap<Prop>
+          internalValueMap =
+            new com.google.protobuf.Internal.EnumLiteMap<Prop>() {
+              public Prop findValueByNumber(int number) {
+                return Prop.valueOf(number)
+      ;        }
+            };
+      
+      private final int index;
+      private final int value;
+      private Prop(int index, int value) {
+        this.index = index;
+        this.value = value;
+      }
+      
+      // @@protoc_insertion_point(enum_scope:com.android.glesv2debugger.Message.Prop)
+    }
+    
+    // required int32 context_id = 1;
+    public static final int CONTEXT_ID_FIELD_NUMBER = 1;
+    private boolean hasContextId;
+    private int contextId_ = 0;
+    public boolean hasContextId() { return hasContextId; }
+    public int getContextId() { return contextId_; }
+    
+    // required .com.android.glesv2debugger.Message.Function function = 2 [default = NEG];
+    public static final int FUNCTION_FIELD_NUMBER = 2;
+    private boolean hasFunction;
+    private com.android.glesv2debugger.DebuggerMessage.Message.Function function_;
+    public boolean hasFunction() { return hasFunction; }
+    public com.android.glesv2debugger.DebuggerMessage.Message.Function getFunction() { return function_; }
+    
+    // required .com.android.glesv2debugger.Message.Type type = 3;
+    public static final int TYPE_FIELD_NUMBER = 3;
+    private boolean hasType;
+    private com.android.glesv2debugger.DebuggerMessage.Message.Type type_;
+    public boolean hasType() { return hasType; }
+    public com.android.glesv2debugger.DebuggerMessage.Message.Type getType() { return type_; }
+    
+    // required bool expect_response = 4;
+    public static final int EXPECT_RESPONSE_FIELD_NUMBER = 4;
+    private boolean hasExpectResponse;
+    private boolean expectResponse_ = false;
+    public boolean hasExpectResponse() { return hasExpectResponse; }
+    public boolean getExpectResponse() { return expectResponse_; }
+    
+    // optional int32 ret = 5;
+    public static final int RET_FIELD_NUMBER = 5;
+    private boolean hasRet;
+    private int ret_ = 0;
+    public boolean hasRet() { return hasRet; }
+    public int getRet() { return ret_; }
+    
+    // optional int32 arg0 = 6;
+    public static final int ARG0_FIELD_NUMBER = 6;
+    private boolean hasArg0;
+    private int arg0_ = 0;
+    public boolean hasArg0() { return hasArg0; }
+    public int getArg0() { return arg0_; }
+    
+    // optional int32 arg1 = 7;
+    public static final int ARG1_FIELD_NUMBER = 7;
+    private boolean hasArg1;
+    private int arg1_ = 0;
+    public boolean hasArg1() { return hasArg1; }
+    public int getArg1() { return arg1_; }
+    
+    // optional int32 arg2 = 8;
+    public static final int ARG2_FIELD_NUMBER = 8;
+    private boolean hasArg2;
+    private int arg2_ = 0;
+    public boolean hasArg2() { return hasArg2; }
+    public int getArg2() { return arg2_; }
+    
+    // optional int32 arg3 = 9;
+    public static final int ARG3_FIELD_NUMBER = 9;
+    private boolean hasArg3;
+    private int arg3_ = 0;
+    public boolean hasArg3() { return hasArg3; }
+    public int getArg3() { return arg3_; }
+    
+    // optional int32 arg4 = 16;
+    public static final int ARG4_FIELD_NUMBER = 16;
+    private boolean hasArg4;
+    private int arg4_ = 0;
+    public boolean hasArg4() { return hasArg4; }
+    public int getArg4() { return arg4_; }
+    
+    // optional int32 arg5 = 17;
+    public static final int ARG5_FIELD_NUMBER = 17;
+    private boolean hasArg5;
+    private int arg5_ = 0;
+    public boolean hasArg5() { return hasArg5; }
+    public int getArg5() { return arg5_; }
+    
+    // optional int32 arg6 = 18;
+    public static final int ARG6_FIELD_NUMBER = 18;
+    private boolean hasArg6;
+    private int arg6_ = 0;
+    public boolean hasArg6() { return hasArg6; }
+    public int getArg6() { return arg6_; }
+    
+    // optional int32 arg7 = 19;
+    public static final int ARG7_FIELD_NUMBER = 19;
+    private boolean hasArg7;
+    private int arg7_ = 0;
+    public boolean hasArg7() { return hasArg7; }
+    public int getArg7() { return arg7_; }
+    
+    // optional int32 arg8 = 20;
+    public static final int ARG8_FIELD_NUMBER = 20;
+    private boolean hasArg8;
+    private int arg8_ = 0;
+    public boolean hasArg8() { return hasArg8; }
+    public int getArg8() { return arg8_; }
+    
+    // optional bytes data = 10;
+    public static final int DATA_FIELD_NUMBER = 10;
+    private boolean hasData;
+    private com.google.protobuf.ByteString data_ = com.google.protobuf.ByteString.EMPTY;
+    public boolean hasData() { return hasData; }
+    public com.google.protobuf.ByteString getData() { return data_; }
+    
+    // optional float time = 11;
+    public static final int TIME_FIELD_NUMBER = 11;
+    private boolean hasTime;
+    private float time_ = 0F;
+    public boolean hasTime() { return hasTime; }
+    public float getTime() { return time_; }
+    
+    // optional .com.android.glesv2debugger.Message.Prop prop = 21;
+    public static final int PROP_FIELD_NUMBER = 21;
+    private boolean hasProp;
+    private com.android.glesv2debugger.DebuggerMessage.Message.Prop prop_;
+    public boolean hasProp() { return hasProp; }
+    public com.android.glesv2debugger.DebuggerMessage.Message.Prop getProp() { return prop_; }
+    
+    // optional float clock = 22;
+    public static final int CLOCK_FIELD_NUMBER = 22;
+    private boolean hasClock;
+    private float clock_ = 0F;
+    public boolean hasClock() { return hasClock; }
+    public float getClock() { return clock_; }
+    
+    private void initFields() {
+      function_ = com.android.glesv2debugger.DebuggerMessage.Message.Function.NEG;
+      type_ = com.android.glesv2debugger.DebuggerMessage.Message.Type.BeforeCall;
+      prop_ = com.android.glesv2debugger.DebuggerMessage.Message.Prop.Capture;
+    }
+    public final boolean isInitialized() {
+      if (!hasContextId) return false;
+      if (!hasFunction) return false;
+      if (!hasType) return false;
+      if (!hasExpectResponse) return false;
+      return true;
+    }
+    
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (hasContextId()) {
+        output.writeInt32(1, getContextId());
+      }
+      if (hasFunction()) {
+        output.writeEnum(2, getFunction().getNumber());
+      }
+      if (hasType()) {
+        output.writeEnum(3, getType().getNumber());
+      }
+      if (hasExpectResponse()) {
+        output.writeBool(4, getExpectResponse());
+      }
+      if (hasRet()) {
+        output.writeInt32(5, getRet());
+      }
+      if (hasArg0()) {
+        output.writeInt32(6, getArg0());
+      }
+      if (hasArg1()) {
+        output.writeInt32(7, getArg1());
+      }
+      if (hasArg2()) {
+        output.writeInt32(8, getArg2());
+      }
+      if (hasArg3()) {
+        output.writeInt32(9, getArg3());
+      }
+      if (hasData()) {
+        output.writeBytes(10, getData());
+      }
+      if (hasTime()) {
+        output.writeFloat(11, getTime());
+      }
+      if (hasArg4()) {
+        output.writeInt32(16, getArg4());
+      }
+      if (hasArg5()) {
+        output.writeInt32(17, getArg5());
+      }
+      if (hasArg6()) {
+        output.writeInt32(18, getArg6());
+      }
+      if (hasArg7()) {
+        output.writeInt32(19, getArg7());
+      }
+      if (hasArg8()) {
+        output.writeInt32(20, getArg8());
+      }
+      if (hasProp()) {
+        output.writeEnum(21, getProp().getNumber());
+      }
+      if (hasClock()) {
+        output.writeFloat(22, getClock());
+      }
+    }
+    
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+    
+      size = 0;
+      if (hasContextId()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(1, getContextId());
+      }
+      if (hasFunction()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeEnumSize(2, getFunction().getNumber());
+      }
+      if (hasType()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeEnumSize(3, getType().getNumber());
+      }
+      if (hasExpectResponse()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(4, getExpectResponse());
+      }
+      if (hasRet()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(5, getRet());
+      }
+      if (hasArg0()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(6, getArg0());
+      }
+      if (hasArg1()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(7, getArg1());
+      }
+      if (hasArg2()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(8, getArg2());
+      }
+      if (hasArg3()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(9, getArg3());
+      }
+      if (hasData()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(10, getData());
+      }
+      if (hasTime()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeFloatSize(11, getTime());
+      }
+      if (hasArg4()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(16, getArg4());
+      }
+      if (hasArg5()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(17, getArg5());
+      }
+      if (hasArg6()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(18, getArg6());
+      }
+      if (hasArg7()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(19, getArg7());
+      }
+      if (hasArg8()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(20, getArg8());
+      }
+      if (hasProp()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeEnumSize(21, getProp().getNumber());
+      }
+      if (hasClock()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeFloatSize(22, getClock());
+      }
+      memoizedSerializedSize = size;
+      return size;
+    }
+    
+    public static com.android.glesv2debugger.DebuggerMessage.Message parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return newBuilder().mergeFrom(data).buildParsed();
+    }
+    public static com.android.glesv2debugger.DebuggerMessage.Message parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return newBuilder().mergeFrom(data, extensionRegistry)
+               .buildParsed();
+    }
+    public static com.android.glesv2debugger.DebuggerMessage.Message parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return newBuilder().mergeFrom(data).buildParsed();
+    }
+    public static com.android.glesv2debugger.DebuggerMessage.Message parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return newBuilder().mergeFrom(data, extensionRegistry)
+               .buildParsed();
+    }
+    public static com.android.glesv2debugger.DebuggerMessage.Message parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return newBuilder().mergeFrom(input).buildParsed();
+    }
+    public static com.android.glesv2debugger.DebuggerMessage.Message parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return newBuilder().mergeFrom(input, extensionRegistry)
+               .buildParsed();
+    }
+    public static com.android.glesv2debugger.DebuggerMessage.Message parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      Builder builder = newBuilder();
+      if (builder.mergeDelimitedFrom(input)) {
+        return builder.buildParsed();
+      } else {
+        return null;
+      }
+    }
+    public static com.android.glesv2debugger.DebuggerMessage.Message parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      Builder builder = newBuilder();
+      if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
+        return builder.buildParsed();
+      } else {
+        return null;
+      }
+    }
+    public static com.android.glesv2debugger.DebuggerMessage.Message parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return newBuilder().mergeFrom(input).buildParsed();
+    }
+    public static com.android.glesv2debugger.DebuggerMessage.Message parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return newBuilder().mergeFrom(input, extensionRegistry)
+               .buildParsed();
+    }
+    
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(com.android.glesv2debugger.DebuggerMessage.Message prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+    
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageLite.Builder<
+          com.android.glesv2debugger.DebuggerMessage.Message, Builder> {
+      private com.android.glesv2debugger.DebuggerMessage.Message result;
+      
+      // Construct using com.android.glesv2debugger.DebuggerMessage.Message.newBuilder()
+      private Builder() {}
+      
+      private static Builder create() {
+        Builder builder = new Builder();
+        builder.result = new com.android.glesv2debugger.DebuggerMessage.Message();
+        return builder;
+      }
+      
+      protected com.android.glesv2debugger.DebuggerMessage.Message internalGetResult() {
+        return result;
+      }
+      
+      public Builder clear() {
+        if (result == null) {
+          throw new IllegalStateException(
+            "Cannot call clear() after build().");
+        }
+        result = new com.android.glesv2debugger.DebuggerMessage.Message();
+        return this;
+      }
+      
+      public Builder clone() {
+        return create().mergeFrom(result);
+      }
+      
+      public com.android.glesv2debugger.DebuggerMessage.Message getDefaultInstanceForType() {
+        return com.android.glesv2debugger.DebuggerMessage.Message.getDefaultInstance();
+      }
+      
+      public boolean isInitialized() {
+        return result.isInitialized();
+      }
+      public com.android.glesv2debugger.DebuggerMessage.Message build() {
+        if (result != null && !isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return buildPartial();
+      }
+      
+      private com.android.glesv2debugger.DebuggerMessage.Message buildParsed()
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        if (!isInitialized()) {
+          throw newUninitializedMessageException(
+            result).asInvalidProtocolBufferException();
+        }
+        return buildPartial();
+      }
+      
+      public com.android.glesv2debugger.DebuggerMessage.Message buildPartial() {
+        if (result == null) {
+          throw new IllegalStateException(
+            "build() has already been called on this Builder.");
+        }
+        com.android.glesv2debugger.DebuggerMessage.Message returnMe = result;
+        result = null;
+        return returnMe;
+      }
+      
+      public Builder mergeFrom(com.android.glesv2debugger.DebuggerMessage.Message other) {
+        if (other == com.android.glesv2debugger.DebuggerMessage.Message.getDefaultInstance()) return this;
+        if (other.hasContextId()) {
+          setContextId(other.getContextId());
+        }
+        if (other.hasFunction()) {
+          setFunction(other.getFunction());
+        }
+        if (other.hasType()) {
+          setType(other.getType());
+        }
+        if (other.hasExpectResponse()) {
+          setExpectResponse(other.getExpectResponse());
+        }
+        if (other.hasRet()) {
+          setRet(other.getRet());
+        }
+        if (other.hasArg0()) {
+          setArg0(other.getArg0());
+        }
+        if (other.hasArg1()) {
+          setArg1(other.getArg1());
+        }
+        if (other.hasArg2()) {
+          setArg2(other.getArg2());
+        }
+        if (other.hasArg3()) {
+          setArg3(other.getArg3());
+        }
+        if (other.hasArg4()) {
+          setArg4(other.getArg4());
+        }
+        if (other.hasArg5()) {
+          setArg5(other.getArg5());
+        }
+        if (other.hasArg6()) {
+          setArg6(other.getArg6());
+        }
+        if (other.hasArg7()) {
+          setArg7(other.getArg7());
+        }
+        if (other.hasArg8()) {
+          setArg8(other.getArg8());
+        }
+        if (other.hasData()) {
+          setData(other.getData());
+        }
+        if (other.hasTime()) {
+          setTime(other.getTime());
+        }
+        if (other.hasProp()) {
+          setProp(other.getProp());
+        }
+        if (other.hasClock()) {
+          setClock(other.getClock());
+        }
+        return this;
+      }
+      
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        while (true) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              return this;
+            default: {
+              if (!parseUnknownField(input, extensionRegistry, tag)) {
+                return this;
+              }
+              break;
+            }
+            case 8: {
+              setContextId(input.readInt32());
+              break;
+            }
+            case 16: {
+              int rawValue = input.readEnum();
+              com.android.glesv2debugger.DebuggerMessage.Message.Function value = com.android.glesv2debugger.DebuggerMessage.Message.Function.valueOf(rawValue);
+              if (value != null) {
+                setFunction(value);
+              }
+              break;
+            }
+            case 24: {
+              int rawValue = input.readEnum();
+              com.android.glesv2debugger.DebuggerMessage.Message.Type value = com.android.glesv2debugger.DebuggerMessage.Message.Type.valueOf(rawValue);
+              if (value != null) {
+                setType(value);
+              }
+              break;
+            }
+            case 32: {
+              setExpectResponse(input.readBool());
+              break;
+            }
+            case 40: {
+              setRet(input.readInt32());
+              break;
+            }
+            case 48: {
+              setArg0(input.readInt32());
+              break;
+            }
+            case 56: {
+              setArg1(input.readInt32());
+              break;
+            }
+            case 64: {
+              setArg2(input.readInt32());
+              break;
+            }
+            case 72: {
+              setArg3(input.readInt32());
+              break;
+            }
+            case 82: {
+              setData(input.readBytes());
+              break;
+            }
+            case 93: {
+              setTime(input.readFloat());
+              break;
+            }
+            case 128: {
+              setArg4(input.readInt32());
+              break;
+            }
+            case 136: {
+              setArg5(input.readInt32());
+              break;
+            }
+            case 144: {
+              setArg6(input.readInt32());
+              break;
+            }
+            case 152: {
+              setArg7(input.readInt32());
+              break;
+            }
+            case 160: {
+              setArg8(input.readInt32());
+              break;
+            }
+            case 168: {
+              int rawValue = input.readEnum();
+              com.android.glesv2debugger.DebuggerMessage.Message.Prop value = com.android.glesv2debugger.DebuggerMessage.Message.Prop.valueOf(rawValue);
+              if (value != null) {
+                setProp(value);
+              }
+              break;
+            }
+            case 181: {
+              setClock(input.readFloat());
+              break;
+            }
+          }
+        }
+      }
+      
+      
+      // required int32 context_id = 1;
+      public boolean hasContextId() {
+        return result.hasContextId();
+      }
+      public int getContextId() {
+        return result.getContextId();
+      }
+      public Builder setContextId(int value) {
+        result.hasContextId = true;
+        result.contextId_ = value;
+        return this;
+      }
+      public Builder clearContextId() {
+        result.hasContextId = false;
+        result.contextId_ = 0;
+        return this;
+      }
+      
+      // required .com.android.glesv2debugger.Message.Function function = 2 [default = NEG];
+      public boolean hasFunction() {
+        return result.hasFunction();
+      }
+      public com.android.glesv2debugger.DebuggerMessage.Message.Function getFunction() {
+        return result.getFunction();
+      }
+      public Builder setFunction(com.android.glesv2debugger.DebuggerMessage.Message.Function value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        result.hasFunction = true;
+        result.function_ = value;
+        return this;
+      }
+      public Builder clearFunction() {
+        result.hasFunction = false;
+        result.function_ = com.android.glesv2debugger.DebuggerMessage.Message.Function.NEG;
+        return this;
+      }
+      
+      // required .com.android.glesv2debugger.Message.Type type = 3;
+      public boolean hasType() {
+        return result.hasType();
+      }
+      public com.android.glesv2debugger.DebuggerMessage.Message.Type getType() {
+        return result.getType();
+      }
+      public Builder setType(com.android.glesv2debugger.DebuggerMessage.Message.Type value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        result.hasType = true;
+        result.type_ = value;
+        return this;
+      }
+      public Builder clearType() {
+        result.hasType = false;
+        result.type_ = com.android.glesv2debugger.DebuggerMessage.Message.Type.BeforeCall;
+        return this;
+      }
+      
+      // required bool expect_response = 4;
+      public boolean hasExpectResponse() {
+        return result.hasExpectResponse();
+      }
+      public boolean getExpectResponse() {
+        return result.getExpectResponse();
+      }
+      public Builder setExpectResponse(boolean value) {
+        result.hasExpectResponse = true;
+        result.expectResponse_ = value;
+        return this;
+      }
+      public Builder clearExpectResponse() {
+        result.hasExpectResponse = false;
+        result.expectResponse_ = false;
+        return this;
+      }
+      
+      // optional int32 ret = 5;
+      public boolean hasRet() {
+        return result.hasRet();
+      }
+      public int getRet() {
+        return result.getRet();
+      }
+      public Builder setRet(int value) {
+        result.hasRet = true;
+        result.ret_ = value;
+        return this;
+      }
+      public Builder clearRet() {
+        result.hasRet = false;
+        result.ret_ = 0;
+        return this;
+      }
+      
+      // optional int32 arg0 = 6;
+      public boolean hasArg0() {
+        return result.hasArg0();
+      }
+      public int getArg0() {
+        return result.getArg0();
+      }
+      public Builder setArg0(int value) {
+        result.hasArg0 = true;
+        result.arg0_ = value;
+        return this;
+      }
+      public Builder clearArg0() {
+        result.hasArg0 = false;
+        result.arg0_ = 0;
+        return this;
+      }
+      
+      // optional int32 arg1 = 7;
+      public boolean hasArg1() {
+        return result.hasArg1();
+      }
+      public int getArg1() {
+        return result.getArg1();
+      }
+      public Builder setArg1(int value) {
+        result.hasArg1 = true;
+        result.arg1_ = value;
+        return this;
+      }
+      public Builder clearArg1() {
+        result.hasArg1 = false;
+        result.arg1_ = 0;
+        return this;
+      }
+      
+      // optional int32 arg2 = 8;
+      public boolean hasArg2() {
+        return result.hasArg2();
+      }
+      public int getArg2() {
+        return result.getArg2();
+      }
+      public Builder setArg2(int value) {
+        result.hasArg2 = true;
+        result.arg2_ = value;
+        return this;
+      }
+      public Builder clearArg2() {
+        result.hasArg2 = false;
+        result.arg2_ = 0;
+        return this;
+      }
+      
+      // optional int32 arg3 = 9;
+      public boolean hasArg3() {
+        return result.hasArg3();
+      }
+      public int getArg3() {
+        return result.getArg3();
+      }
+      public Builder setArg3(int value) {
+        result.hasArg3 = true;
+        result.arg3_ = value;
+        return this;
+      }
+      public Builder clearArg3() {
+        result.hasArg3 = false;
+        result.arg3_ = 0;
+        return this;
+      }
+      
+      // optional int32 arg4 = 16;
+      public boolean hasArg4() {
+        return result.hasArg4();
+      }
+      public int getArg4() {
+        return result.getArg4();
+      }
+      public Builder setArg4(int value) {
+        result.hasArg4 = true;
+        result.arg4_ = value;
+        return this;
+      }
+      public Builder clearArg4() {
+        result.hasArg4 = false;
+        result.arg4_ = 0;
+        return this;
+      }
+      
+      // optional int32 arg5 = 17;
+      public boolean hasArg5() {
+        return result.hasArg5();
+      }
+      public int getArg5() {
+        return result.getArg5();
+      }
+      public Builder setArg5(int value) {
+        result.hasArg5 = true;
+        result.arg5_ = value;
+        return this;
+      }
+      public Builder clearArg5() {
+        result.hasArg5 = false;
+        result.arg5_ = 0;
+        return this;
+      }
+      
+      // optional int32 arg6 = 18;
+      public boolean hasArg6() {
+        return result.hasArg6();
+      }
+      public int getArg6() {
+        return result.getArg6();
+      }
+      public Builder setArg6(int value) {
+        result.hasArg6 = true;
+        result.arg6_ = value;
+        return this;
+      }
+      public Builder clearArg6() {
+        result.hasArg6 = false;
+        result.arg6_ = 0;
+        return this;
+      }
+      
+      // optional int32 arg7 = 19;
+      public boolean hasArg7() {
+        return result.hasArg7();
+      }
+      public int getArg7() {
+        return result.getArg7();
+      }
+      public Builder setArg7(int value) {
+        result.hasArg7 = true;
+        result.arg7_ = value;
+        return this;
+      }
+      public Builder clearArg7() {
+        result.hasArg7 = false;
+        result.arg7_ = 0;
+        return this;
+      }
+      
+      // optional int32 arg8 = 20;
+      public boolean hasArg8() {
+        return result.hasArg8();
+      }
+      public int getArg8() {
+        return result.getArg8();
+      }
+      public Builder setArg8(int value) {
+        result.hasArg8 = true;
+        result.arg8_ = value;
+        return this;
+      }
+      public Builder clearArg8() {
+        result.hasArg8 = false;
+        result.arg8_ = 0;
+        return this;
+      }
+      
+      // optional bytes data = 10;
+      public boolean hasData() {
+        return result.hasData();
+      }
+      public com.google.protobuf.ByteString getData() {
+        return result.getData();
+      }
+      public Builder setData(com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  result.hasData = true;
+        result.data_ = value;
+        return this;
+      }
+      public Builder clearData() {
+        result.hasData = false;
+        result.data_ = getDefaultInstance().getData();
+        return this;
+      }
+      
+      // optional float time = 11;
+      public boolean hasTime() {
+        return result.hasTime();
+      }
+      public float getTime() {
+        return result.getTime();
+      }
+      public Builder setTime(float value) {
+        result.hasTime = true;
+        result.time_ = value;
+        return this;
+      }
+      public Builder clearTime() {
+        result.hasTime = false;
+        result.time_ = 0F;
+        return this;
+      }
+      
+      // optional .com.android.glesv2debugger.Message.Prop prop = 21;
+      public boolean hasProp() {
+        return result.hasProp();
+      }
+      public com.android.glesv2debugger.DebuggerMessage.Message.Prop getProp() {
+        return result.getProp();
+      }
+      public Builder setProp(com.android.glesv2debugger.DebuggerMessage.Message.Prop value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        result.hasProp = true;
+        result.prop_ = value;
+        return this;
+      }
+      public Builder clearProp() {
+        result.hasProp = false;
+        result.prop_ = com.android.glesv2debugger.DebuggerMessage.Message.Prop.Capture;
+        return this;
+      }
+      
+      // optional float clock = 22;
+      public boolean hasClock() {
+        return result.hasClock();
+      }
+      public float getClock() {
+        return result.getClock();
+      }
+      public Builder setClock(float value) {
+        result.hasClock = true;
+        result.clock_ = value;
+        return this;
+      }
+      public Builder clearClock() {
+        result.hasClock = false;
+        result.clock_ = 0F;
+        return this;
+      }
+      
+      // @@protoc_insertion_point(builder_scope:com.android.glesv2debugger.Message)
+    }
+    
+    static {
+      defaultInstance = new Message(true);
+      com.android.glesv2debugger.DebuggerMessage.internalForceInit();
+      defaultInstance.initFields();
+    }
+    
+    // @@protoc_insertion_point(class_scope:com.android.glesv2debugger.Message)
+  }
+  
+  
+  static {
+  }
+  
+  public static void internalForceInit() {}
+  
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/GLEnum.java b/tools/glesv2debugger/src/com/android/glesv2debugger/GLEnum.java
new file mode 100644
index 0000000..8fd3014
--- /dev/null
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/GLEnum.java
@@ -0,0 +1,632 @@
+/*
+ ** 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.
+ */
+
+// auto generated by generate_GLEnum_java.py"
+
+package com.android.glesv2debugger;
+
+public enum GLEnum {
+    GL_POINTS(0x0000),
+    GL_LINES(0x0001),
+    GL_LINE_LOOP(0x0002),
+    GL_LINE_STRIP(0x0003),
+    GL_TRIANGLES(0x0004),
+    GL_TRIANGLE_STRIP(0x0005),
+    GL_TRIANGLE_FAN(0x0006),
+    GL_ADD(0x0104),
+    GL_NEVER(0x0200),
+    GL_LESS(0x0201),
+    GL_EQUAL(0x0202),
+    GL_LEQUAL(0x0203),
+    GL_GREATER(0x0204),
+    GL_NOTEQUAL(0x0205),
+    GL_GEQUAL(0x0206),
+    GL_ALWAYS(0x0207),
+    GL_SRC_COLOR(0x0300),
+    GL_ONE_MINUS_SRC_COLOR(0x0301),
+    GL_SRC_ALPHA(0x0302),
+    GL_ONE_MINUS_SRC_ALPHA(0x0303),
+    GL_DST_ALPHA(0x0304),
+    GL_ONE_MINUS_DST_ALPHA(0x0305),
+    GL_DST_COLOR(0x0306),
+    GL_ONE_MINUS_DST_COLOR(0x0307),
+    GL_SRC_ALPHA_SATURATE(0x0308),
+    GL_FRONT(0x0404),
+    GL_BACK(0x0405),
+    GL_FRONT_AND_BACK(0x0408),
+    GL_INVALID_ENUM(0x0500),
+    GL_INVALID_VALUE(0x0501),
+    GL_INVALID_OPERATION(0x0502),
+    GL_STACK_OVERFLOW(0x0503),
+    GL_STACK_UNDERFLOW(0x0504),
+    GL_OUT_OF_MEMORY(0x0505),
+    GL_INVALID_FRAMEBUFFER_OPERATION_OES(0x0506),
+    GL_EXP(0x0800),
+    GL_EXP2(0x0801),
+    GL_CW(0x0900),
+    GL_CCW(0x0901),
+    GL_CURRENT_COLOR(0x0B00),
+    GL_CURRENT_NORMAL(0x0B02),
+    GL_CURRENT_TEXTURE_COORDS(0x0B03),
+    GL_POINT_SMOOTH(0x0B10),
+    GL_POINT_SIZE(0x0B11),
+    GL_SMOOTH_POINT_SIZE_RANGE(0x0B12),
+    GL_LINE_SMOOTH(0x0B20),
+    GL_LINE_WIDTH(0x0B21),
+    GL_SMOOTH_LINE_WIDTH_RANGE(0x0B22),
+    GL_CULL_FACE(0x0B44),
+    GL_CULL_FACE_MODE(0x0B45),
+    GL_FRONT_FACE(0x0B46),
+    GL_LIGHTING(0x0B50),
+    GL_LIGHT_MODEL_TWO_SIDE(0x0B52),
+    GL_LIGHT_MODEL_AMBIENT(0x0B53),
+    GL_SHADE_MODEL(0x0B54),
+    GL_COLOR_MATERIAL(0x0B57),
+    GL_FOG(0x0B60),
+    GL_FOG_DENSITY(0x0B62),
+    GL_FOG_START(0x0B63),
+    GL_FOG_END(0x0B64),
+    GL_FOG_MODE(0x0B65),
+    GL_FOG_COLOR(0x0B66),
+    GL_DEPTH_RANGE(0x0B70),
+    GL_DEPTH_TEST(0x0B71),
+    GL_DEPTH_WRITEMASK(0x0B72),
+    GL_DEPTH_CLEAR_VALUE(0x0B73),
+    GL_DEPTH_FUNC(0x0B74),
+    GL_STENCIL_TEST(0x0B90),
+    GL_STENCIL_CLEAR_VALUE(0x0B91),
+    GL_STENCIL_FUNC(0x0B92),
+    GL_STENCIL_VALUE_MASK(0x0B93),
+    GL_STENCIL_FAIL(0x0B94),
+    GL_STENCIL_PASS_DEPTH_FAIL(0x0B95),
+    GL_STENCIL_PASS_DEPTH_PASS(0x0B96),
+    GL_STENCIL_REF(0x0B97),
+    GL_STENCIL_WRITEMASK(0x0B98),
+    GL_MATRIX_MODE(0x0BA0),
+    GL_NORMALIZE(0x0BA1),
+    GL_VIEWPORT(0x0BA2),
+    GL_MODELVIEW_STACK_DEPTH(0x0BA3),
+    GL_PROJECTION_STACK_DEPTH(0x0BA4),
+    GL_TEXTURE_STACK_DEPTH(0x0BA5),
+    GL_MODELVIEW_MATRIX(0x0BA6),
+    GL_PROJECTION_MATRIX(0x0BA7),
+    GL_TEXTURE_MATRIX(0x0BA8),
+    GL_ALPHA_TEST(0x0BC0),
+    GL_ALPHA_TEST_FUNC(0x0BC1),
+    GL_ALPHA_TEST_REF(0x0BC2),
+    GL_DITHER(0x0BD0),
+    GL_BLEND_DST(0x0BE0),
+    GL_BLEND_SRC(0x0BE1),
+    GL_BLEND(0x0BE2),
+    GL_LOGIC_OP_MODE(0x0BF0),
+    GL_COLOR_LOGIC_OP(0x0BF2),
+    GL_SCISSOR_BOX(0x0C10),
+    GL_SCISSOR_TEST(0x0C11),
+    GL_COLOR_CLEAR_VALUE(0x0C22),
+    GL_COLOR_WRITEMASK(0x0C23),
+    GL_PERSPECTIVE_CORRECTION_HINT(0x0C50),
+    GL_POINT_SMOOTH_HINT(0x0C51),
+    GL_LINE_SMOOTH_HINT(0x0C52),
+    GL_FOG_HINT(0x0C54),
+    GL_UNPACK_ALIGNMENT(0x0CF5),
+    GL_PACK_ALIGNMENT(0x0D05),
+    GL_ALPHA_SCALE(0x0D1C),
+    GL_MAX_LIGHTS(0x0D31),
+    GL_MAX_CLIP_PLANES(0x0D32),
+    GL_MAX_TEXTURE_SIZE(0x0D33),
+    GL_MAX_MODELVIEW_STACK_DEPTH(0x0D36),
+    GL_MAX_PROJECTION_STACK_DEPTH(0x0D38),
+    GL_MAX_TEXTURE_STACK_DEPTH(0x0D39),
+    GL_MAX_VIEWPORT_DIMS(0x0D3A),
+    GL_SUBPIXEL_BITS(0x0D50),
+    GL_RED_BITS(0x0D52),
+    GL_GREEN_BITS(0x0D53),
+    GL_BLUE_BITS(0x0D54),
+    GL_ALPHA_BITS(0x0D55),
+    GL_DEPTH_BITS(0x0D56),
+    GL_STENCIL_BITS(0x0D57),
+    GL_TEXTURE_2D(0x0DE1),
+    GL_DONT_CARE(0x1100),
+    GL_FASTEST(0x1101),
+    GL_NICEST(0x1102),
+    GL_AMBIENT(0x1200),
+    GL_DIFFUSE(0x1201),
+    GL_SPECULAR(0x1202),
+    GL_POSITION(0x1203),
+    GL_SPOT_DIRECTION(0x1204),
+    GL_SPOT_EXPONENT(0x1205),
+    GL_SPOT_CUTOFF(0x1206),
+    GL_CONSTANT_ATTENUATION(0x1207),
+    GL_LINEAR_ATTENUATION(0x1208),
+    GL_QUADRATIC_ATTENUATION(0x1209),
+    GL_BYTE(0x1400),
+    GL_UNSIGNED_BYTE(0x1401),
+    GL_SHORT(0x1402),
+    GL_UNSIGNED_SHORT(0x1403),
+    GL_INT(0x1404),
+    GL_UNSIGNED_INT(0x1405),
+    GL_FLOAT(0x1406),
+    GL_FIXED(0x140C),
+    GL_CLEAR(0x1500),
+    GL_AND(0x1501),
+    GL_AND_REVERSE(0x1502),
+    GL_COPY(0x1503),
+    GL_AND_INVERTED(0x1504),
+    GL_NOOP(0x1505),
+    GL_XOR(0x1506),
+    GL_OR(0x1507),
+    GL_NOR(0x1508),
+    GL_EQUIV(0x1509),
+    GL_INVERT(0x150A),
+    GL_OR_REVERSE(0x150B),
+    GL_COPY_INVERTED(0x150C),
+    GL_OR_INVERTED(0x150D),
+    GL_NAND(0x150E),
+    GL_SET(0x150F),
+    GL_EMISSION(0x1600),
+    GL_SHININESS(0x1601),
+    GL_AMBIENT_AND_DIFFUSE(0x1602),
+    GL_MODELVIEW(0x1700),
+    GL_PROJECTION(0x1701),
+    GL_TEXTURE(0x1702),
+    GL_COLOR_EXT(0x1800),
+    GL_DEPTH_EXT(0x1801),
+    GL_STENCIL_EXT(0x1802),
+    GL_STENCIL_INDEX(0x1901),
+    GL_DEPTH_COMPONENT(0x1902),
+    GL_ALPHA(0x1906),
+    GL_RGB(0x1907),
+    GL_RGBA(0x1908),
+    GL_LUMINANCE(0x1909),
+    GL_LUMINANCE_ALPHA(0x190A),
+    GL_FLAT(0x1D00),
+    GL_SMOOTH(0x1D01),
+    GL_KEEP(0x1E00),
+    GL_REPLACE(0x1E01),
+    GL_INCR(0x1E02),
+    GL_DECR(0x1E03),
+    GL_VENDOR(0x1F00),
+    GL_RENDERER(0x1F01),
+    GL_VERSION(0x1F02),
+    GL_EXTENSIONS(0x1F03),
+    GL_MODULATE(0x2100),
+    GL_DECAL(0x2101),
+    GL_TEXTURE_ENV_MODE(0x2200),
+    GL_TEXTURE_ENV_COLOR(0x2201),
+    GL_TEXTURE_ENV(0x2300),
+    GL_TEXTURE_GEN_MODE_OES(0x2500),
+    GL_NEAREST(0x2600),
+    GL_LINEAR(0x2601),
+    GL_NEAREST_MIPMAP_NEAREST(0x2700),
+    GL_LINEAR_MIPMAP_NEAREST(0x2701),
+    GL_NEAREST_MIPMAP_LINEAR(0x2702),
+    GL_LINEAR_MIPMAP_LINEAR(0x2703),
+    GL_TEXTURE_MAG_FILTER(0x2800),
+    GL_TEXTURE_MIN_FILTER(0x2801),
+    GL_TEXTURE_WRAP_S(0x2802),
+    GL_TEXTURE_WRAP_T(0x2803),
+    GL_REPEAT(0x2901),
+    GL_POLYGON_OFFSET_UNITS(0x2A00),
+    GL_CLIP_PLANE0(0x3000),
+    GL_CLIP_PLANE1(0x3001),
+    GL_CLIP_PLANE2(0x3002),
+    GL_CLIP_PLANE3(0x3003),
+    GL_CLIP_PLANE4(0x3004),
+    GL_CLIP_PLANE5(0x3005),
+    GL_LIGHT0(0x4000),
+    GL_LIGHT1(0x4001),
+    GL_LIGHT2(0x4002),
+    GL_LIGHT3(0x4003),
+    GL_LIGHT4(0x4004),
+    GL_LIGHT5(0x4005),
+    GL_LIGHT6(0x4006),
+    GL_LIGHT7(0x4007),
+    GL_COVERAGE_BUFFER_BIT_NV(0x8000),
+    GL_CONSTANT_COLOR(0x8001),
+    GL_ONE_MINUS_CONSTANT_COLOR(0x8002),
+    GL_CONSTANT_ALPHA(0x8003),
+    GL_ONE_MINUS_CONSTANT_ALPHA(0x8004),
+    GL_BLEND_COLOR(0x8005),
+    GL_FUNC_ADD_OES(0x8006),
+    GL_MIN_EXT(0x8007),
+    GL_MAX_EXT(0x8008),
+    GL_BLEND_EQUATION_RGB_OES(0x8009),
+    GL_FUNC_SUBTRACT_OES(0x800A),
+    GL_FUNC_REVERSE_SUBTRACT_OES(0x800B),
+    GL_UNSIGNED_SHORT_4_4_4_4(0x8033),
+    GL_UNSIGNED_SHORT_5_5_5_1(0x8034),
+    GL_POLYGON_OFFSET_FILL(0x8037),
+    GL_POLYGON_OFFSET_FACTOR(0x8038),
+    GL_RESCALE_NORMAL(0x803A),
+    GL_RGB8_OES(0x8051),
+    GL_RGBA4_OES(0x8056),
+    GL_RGB5_A1_OES(0x8057),
+    GL_RGBA8_OES(0x8058),
+    GL_TEXTURE_BINDING_2D(0x8069),
+    GL_TEXTURE_BINDING_3D_OES(0x806A),
+    GL_TEXTURE_3D_OES(0x806F),
+    GL_TEXTURE_WRAP_R_OES(0x8072),
+    GL_MAX_3D_TEXTURE_SIZE_OES(0x8073),
+    GL_VERTEX_ARRAY(0x8074),
+    GL_NORMAL_ARRAY(0x8075),
+    GL_COLOR_ARRAY(0x8076),
+    GL_TEXTURE_COORD_ARRAY(0x8078),
+    GL_VERTEX_ARRAY_SIZE(0x807A),
+    GL_VERTEX_ARRAY_TYPE(0x807B),
+    GL_VERTEX_ARRAY_STRIDE(0x807C),
+    GL_NORMAL_ARRAY_TYPE(0x807E),
+    GL_NORMAL_ARRAY_STRIDE(0x807F),
+    GL_COLOR_ARRAY_SIZE(0x8081),
+    GL_COLOR_ARRAY_TYPE(0x8082),
+    GL_COLOR_ARRAY_STRIDE(0x8083),
+    GL_TEXTURE_COORD_ARRAY_SIZE(0x8088),
+    GL_TEXTURE_COORD_ARRAY_TYPE(0x8089),
+    GL_TEXTURE_COORD_ARRAY_STRIDE(0x808A),
+    GL_VERTEX_ARRAY_POINTER(0x808E),
+    GL_NORMAL_ARRAY_POINTER(0x808F),
+    GL_COLOR_ARRAY_POINTER(0x8090),
+    GL_TEXTURE_COORD_ARRAY_POINTER(0x8092),
+    GL_MULTISAMPLE(0x809D),
+    GL_SAMPLE_ALPHA_TO_COVERAGE(0x809E),
+    GL_SAMPLE_ALPHA_TO_ONE(0x809F),
+    GL_SAMPLE_COVERAGE(0x80A0),
+    GL_SAMPLE_BUFFERS(0x80A8),
+    GL_SAMPLES(0x80A9),
+    GL_SAMPLE_COVERAGE_VALUE(0x80AA),
+    GL_SAMPLE_COVERAGE_INVERT(0x80AB),
+    GL_BLEND_DST_RGB_OES(0x80C8),
+    GL_BLEND_SRC_RGB_OES(0x80C9),
+    GL_BLEND_DST_ALPHA_OES(0x80CA),
+    GL_BLEND_SRC_ALPHA_OES(0x80CB),
+    GL_BGRA_EXT(0x80E1),
+    GL_POINT_SIZE_MIN(0x8126),
+    GL_POINT_SIZE_MAX(0x8127),
+    GL_POINT_FADE_THRESHOLD_SIZE(0x8128),
+    GL_POINT_DISTANCE_ATTENUATION(0x8129),
+    GL_CLAMP_TO_EDGE(0x812F),
+    GL_GENERATE_MIPMAP(0x8191),
+    GL_GENERATE_MIPMAP_HINT(0x8192),
+    GL_DEPTH_COMPONENT16_OES(0x81A5),
+    GL_DEPTH_COMPONENT24_OES(0x81A6),
+    GL_DEPTH_COMPONENT32_OES(0x81A7),
+    GL_UNSIGNED_SHORT_5_6_5(0x8363),
+    GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT(0x8365),
+    GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT(0x8366),
+    GL_UNSIGNED_INT_2_10_10_10_REV_EXT(0x8368),
+    GL_MIRRORED_REPEAT_OES(0x8370),
+    GL_COMPRESSED_RGB_S3TC_DXT1_EXT(0x83F0),
+    GL_COMPRESSED_RGBA_S3TC_DXT1_EXT(0x83F1),
+    GL_ALIASED_POINT_SIZE_RANGE(0x846D),
+    GL_ALIASED_LINE_WIDTH_RANGE(0x846E),
+    GL_TEXTURE0(0x84C0),
+    GL_TEXTURE1(0x84C1),
+    GL_TEXTURE2(0x84C2),
+    GL_TEXTURE3(0x84C3),
+    GL_TEXTURE4(0x84C4),
+    GL_TEXTURE5(0x84C5),
+    GL_TEXTURE6(0x84C6),
+    GL_TEXTURE7(0x84C7),
+    GL_TEXTURE8(0x84C8),
+    GL_TEXTURE9(0x84C9),
+    GL_TEXTURE10(0x84CA),
+    GL_TEXTURE11(0x84CB),
+    GL_TEXTURE12(0x84CC),
+    GL_TEXTURE13(0x84CD),
+    GL_TEXTURE14(0x84CE),
+    GL_TEXTURE15(0x84CF),
+    GL_TEXTURE16(0x84D0),
+    GL_TEXTURE17(0x84D1),
+    GL_TEXTURE18(0x84D2),
+    GL_TEXTURE19(0x84D3),
+    GL_TEXTURE20(0x84D4),
+    GL_TEXTURE21(0x84D5),
+    GL_TEXTURE22(0x84D6),
+    GL_TEXTURE23(0x84D7),
+    GL_TEXTURE24(0x84D8),
+    GL_TEXTURE25(0x84D9),
+    GL_TEXTURE26(0x84DA),
+    GL_TEXTURE27(0x84DB),
+    GL_TEXTURE28(0x84DC),
+    GL_TEXTURE29(0x84DD),
+    GL_TEXTURE30(0x84DE),
+    GL_TEXTURE31(0x84DF),
+    GL_ACTIVE_TEXTURE(0x84E0),
+    GL_CLIENT_ACTIVE_TEXTURE(0x84E1),
+    GL_MAX_TEXTURE_UNITS(0x84E2),
+    GL_SUBTRACT(0x84E7),
+    GL_MAX_RENDERBUFFER_SIZE_OES(0x84E8),
+    GL_ALL_COMPLETED_NV(0x84F2),
+    GL_FENCE_STATUS_NV(0x84F3),
+    GL_FENCE_CONDITION_NV(0x84F4),
+    GL_DEPTH_STENCIL_OES(0x84F9),
+    GL_UNSIGNED_INT_24_8_OES(0x84FA),
+    GL_MAX_TEXTURE_LOD_BIAS_EXT(0x84FD),
+    GL_TEXTURE_MAX_ANISOTROPY_EXT(0x84FE),
+    GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT(0x84FF),
+    GL_TEXTURE_FILTER_CONTROL_EXT(0x8500),
+    GL_TEXTURE_LOD_BIAS_EXT(0x8501),
+    GL_INCR_WRAP_OES(0x8507),
+    GL_DECR_WRAP_OES(0x8508),
+    GL_NORMAL_MAP_OES(0x8511),
+    GL_REFLECTION_MAP_OES(0x8512),
+    GL_TEXTURE_CUBE_MAP_OES(0x8513),
+    GL_TEXTURE_BINDING_CUBE_MAP_OES(0x8514),
+    GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES(0x8515),
+    GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES(0x8516),
+    GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES(0x8517),
+    GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES(0x8518),
+    GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES(0x8519),
+    GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES(0x851A),
+    GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES(0x851C),
+    GL_COMBINE(0x8570),
+    GL_COMBINE_RGB(0x8571),
+    GL_COMBINE_ALPHA(0x8572),
+    GL_RGB_SCALE(0x8573),
+    GL_ADD_SIGNED(0x8574),
+    GL_INTERPOLATE(0x8575),
+    GL_CONSTANT(0x8576),
+    GL_PRIMARY_COLOR(0x8577),
+    GL_PREVIOUS(0x8578),
+    GL_SRC0_RGB(0x8580),
+    GL_SRC1_RGB(0x8581),
+    GL_SRC2_RGB(0x8582),
+    GL_SRC0_ALPHA(0x8588),
+    GL_SRC1_ALPHA(0x8589),
+    GL_SRC2_ALPHA(0x858A),
+    GL_OPERAND0_RGB(0x8590),
+    GL_OPERAND1_RGB(0x8591),
+    GL_OPERAND2_RGB(0x8592),
+    GL_OPERAND0_ALPHA(0x8598),
+    GL_OPERAND1_ALPHA(0x8599),
+    GL_OPERAND2_ALPHA(0x859A),
+    GL_VERTEX_ARRAY_BINDING_OES(0x85B5),
+    GL_VERTEX_ATTRIB_ARRAY_ENABLED(0x8622),
+    GL_VERTEX_ATTRIB_ARRAY_SIZE(0x8623),
+    GL_VERTEX_ATTRIB_ARRAY_STRIDE(0x8624),
+    GL_VERTEX_ATTRIB_ARRAY_TYPE(0x8625),
+    GL_CURRENT_VERTEX_ATTRIB(0x8626),
+    GL_VERTEX_ATTRIB_ARRAY_POINTER(0x8645),
+    GL_NUM_COMPRESSED_TEXTURE_FORMATS(0x86A2),
+    GL_COMPRESSED_TEXTURE_FORMATS(0x86A3),
+    GL_MAX_VERTEX_UNITS_OES(0x86A4),
+    GL_WEIGHT_ARRAY_TYPE_OES(0x86A9),
+    GL_WEIGHT_ARRAY_STRIDE_OES(0x86AA),
+    GL_WEIGHT_ARRAY_SIZE_OES(0x86AB),
+    GL_WEIGHT_ARRAY_POINTER_OES(0x86AC),
+    GL_WEIGHT_ARRAY_OES(0x86AD),
+    GL_DOT3_RGB(0x86AE),
+    GL_DOT3_RGBA(0x86AF),
+    GL_Z400_BINARY_AMD(0x8740),
+    GL_PROGRAM_BINARY_LENGTH_OES(0x8741),
+    GL_BUFFER_SIZE(0x8764),
+    GL_BUFFER_USAGE(0x8765),
+    GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD(0x87EE),
+    GL_3DC_X_AMD(0x87F9),
+    GL_3DC_XY_AMD(0x87FA),
+    GL_NUM_PROGRAM_BINARY_FORMATS_OES(0x87FE),
+    GL_PROGRAM_BINARY_FORMATS_OES(0x87FF),
+    GL_STENCIL_BACK_FUNC(0x8800),
+    GL_STENCIL_BACK_FAIL(0x8801),
+    GL_STENCIL_BACK_PASS_DEPTH_FAIL(0x8802),
+    GL_STENCIL_BACK_PASS_DEPTH_PASS(0x8803),
+    GL_WRITEONLY_RENDERING_QCOM(0x8823),
+    GL_BLEND_EQUATION_ALPHA_OES(0x883D),
+    GL_MATRIX_PALETTE_OES(0x8840),
+    GL_MAX_PALETTE_MATRICES_OES(0x8842),
+    GL_CURRENT_PALETTE_MATRIX_OES(0x8843),
+    GL_MATRIX_INDEX_ARRAY_OES(0x8844),
+    GL_MATRIX_INDEX_ARRAY_SIZE_OES(0x8846),
+    GL_MATRIX_INDEX_ARRAY_TYPE_OES(0x8847),
+    GL_MATRIX_INDEX_ARRAY_STRIDE_OES(0x8848),
+    GL_MATRIX_INDEX_ARRAY_POINTER_OES(0x8849),
+    GL_POINT_SPRITE_OES(0x8861),
+    GL_COORD_REPLACE_OES(0x8862),
+    GL_MAX_VERTEX_ATTRIBS(0x8869),
+    GL_VERTEX_ATTRIB_ARRAY_NORMALIZED(0x886A),
+    GL_MAX_TEXTURE_IMAGE_UNITS(0x8872),
+    GL_ARRAY_BUFFER(0x8892),
+    GL_ELEMENT_ARRAY_BUFFER(0x8893),
+    GL_ARRAY_BUFFER_BINDING(0x8894),
+    GL_ELEMENT_ARRAY_BUFFER_BINDING(0x8895),
+    GL_VERTEX_ARRAY_BUFFER_BINDING(0x8896),
+    GL_NORMAL_ARRAY_BUFFER_BINDING(0x8897),
+    GL_COLOR_ARRAY_BUFFER_BINDING(0x8898),
+    GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING(0x889A),
+    GL_WEIGHT_ARRAY_BUFFER_BINDING_OES(0x889E),
+    GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING(0x889F),
+    GL_WRITE_ONLY_OES(0x88B9),
+    GL_BUFFER_ACCESS_OES(0x88BB),
+    GL_BUFFER_MAPPED_OES(0x88BC),
+    GL_BUFFER_MAP_POINTER_OES(0x88BD),
+    GL_STREAM_DRAW(0x88E0),
+    GL_STATIC_DRAW(0x88E4),
+    GL_DYNAMIC_DRAW(0x88E8),
+    GL_DEPTH24_STENCIL8_OES(0x88F0),
+    GL_POINT_SIZE_ARRAY_TYPE_OES(0x898A),
+    GL_POINT_SIZE_ARRAY_STRIDE_OES(0x898B),
+    GL_POINT_SIZE_ARRAY_POINTER_OES(0x898C),
+    GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES(0x898D),
+    GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES(0x898E),
+    GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES(0x898F),
+    GL_FRAGMENT_SHADER(0x8B30),
+    GL_VERTEX_SHADER(0x8B31),
+    GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS(0x8B4C),
+    GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS(0x8B4D),
+    GL_SHADER_TYPE(0x8B4F),
+    GL_FLOAT_VEC2(0x8B50),
+    GL_FLOAT_VEC3(0x8B51),
+    GL_FLOAT_VEC4(0x8B52),
+    GL_INT_VEC2(0x8B53),
+    GL_INT_VEC3(0x8B54),
+    GL_INT_VEC4(0x8B55),
+    GL_BOOL(0x8B56),
+    GL_BOOL_VEC2(0x8B57),
+    GL_BOOL_VEC3(0x8B58),
+    GL_BOOL_VEC4(0x8B59),
+    GL_FLOAT_MAT2(0x8B5A),
+    GL_FLOAT_MAT3(0x8B5B),
+    GL_FLOAT_MAT4(0x8B5C),
+    GL_SAMPLER_2D(0x8B5E),
+    GL_SAMPLER_3D_OES(0x8B5F),
+    GL_SAMPLER_CUBE(0x8B60),
+    GL_DELETE_STATUS(0x8B80),
+    GL_COMPILE_STATUS(0x8B81),
+    GL_LINK_STATUS(0x8B82),
+    GL_VALIDATE_STATUS(0x8B83),
+    GL_INFO_LOG_LENGTH(0x8B84),
+    GL_ATTACHED_SHADERS(0x8B85),
+    GL_ACTIVE_UNIFORMS(0x8B86),
+    GL_ACTIVE_UNIFORM_MAX_LENGTH(0x8B87),
+    GL_SHADER_SOURCE_LENGTH(0x8B88),
+    GL_ACTIVE_ATTRIBUTES(0x8B89),
+    GL_ACTIVE_ATTRIBUTE_MAX_LENGTH(0x8B8A),
+    GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES(0x8B8B),
+    GL_SHADING_LANGUAGE_VERSION(0x8B8C),
+    GL_CURRENT_PROGRAM(0x8B8D),
+    GL_PALETTE4_RGB8_OES(0x8B90),
+    GL_PALETTE4_RGBA8_OES(0x8B91),
+    GL_PALETTE4_R5_G6_B5_OES(0x8B92),
+    GL_PALETTE4_RGBA4_OES(0x8B93),
+    GL_PALETTE4_RGB5_A1_OES(0x8B94),
+    GL_PALETTE8_RGB8_OES(0x8B95),
+    GL_PALETTE8_RGBA8_OES(0x8B96),
+    GL_PALETTE8_R5_G6_B5_OES(0x8B97),
+    GL_PALETTE8_RGBA4_OES(0x8B98),
+    GL_PALETTE8_RGB5_A1_OES(0x8B99),
+    GL_IMPLEMENTATION_COLOR_READ_TYPE_OES(0x8B9A),
+    GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES(0x8B9B),
+    GL_POINT_SIZE_ARRAY_OES(0x8B9C),
+    GL_TEXTURE_CROP_RECT_OES(0x8B9D),
+    GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES(0x8B9E),
+    GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES(0x8B9F),
+    GL_COUNTER_TYPE_AMD(0x8BC0),
+    GL_COUNTER_RANGE_AMD(0x8BC1),
+    GL_UNSIGNED_INT64_AMD(0x8BC2),
+    GL_PERCENTAGE_AMD(0x8BC3),
+    GL_PERFMON_RESULT_AVAILABLE_AMD(0x8BC4),
+    GL_PERFMON_RESULT_SIZE_AMD(0x8BC5),
+    GL_PERFMON_RESULT_AMD(0x8BC6),
+    GL_TEXTURE_WIDTH_QCOM(0x8BD2),
+    GL_TEXTURE_HEIGHT_QCOM(0x8BD3),
+    GL_TEXTURE_DEPTH_QCOM(0x8BD4),
+    GL_TEXTURE_INTERNAL_FORMAT_QCOM(0x8BD5),
+    GL_TEXTURE_FORMAT_QCOM(0x8BD6),
+    GL_TEXTURE_TYPE_QCOM(0x8BD7),
+    GL_TEXTURE_IMAGE_VALID_QCOM(0x8BD8),
+    GL_TEXTURE_NUM_LEVELS_QCOM(0x8BD9),
+    GL_TEXTURE_TARGET_QCOM(0x8BDA),
+    GL_TEXTURE_OBJECT_VALID_QCOM(0x8BDB),
+    GL_STATE_RESTORE(0x8BDC),
+    GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG(0x8C00),
+    GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG(0x8C01),
+    GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG(0x8C02),
+    GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG(0x8C03),
+    GL_MODULATE_COLOR_IMG(0x8C04),
+    GL_RECIP_ADD_SIGNED_ALPHA_IMG(0x8C05),
+    GL_TEXTURE_ALPHA_MODULATE_IMG(0x8C06),
+    GL_FACTOR_ALPHA_MODULATE_IMG(0x8C07),
+    GL_FRAGMENT_ALPHA_MODULATE_IMG(0x8C08),
+    GL_ADD_BLEND_IMG(0x8C09),
+    GL_SGX_BINARY_IMG(0x8C0A),
+    GL_ATC_RGB_AMD(0x8C92),
+    GL_ATC_RGBA_EXPLICIT_ALPHA_AMD(0x8C93),
+    GL_STENCIL_BACK_REF(0x8CA3),
+    GL_STENCIL_BACK_VALUE_MASK(0x8CA4),
+    GL_STENCIL_BACK_WRITEMASK(0x8CA5),
+    GL_FRAMEBUFFER_BINDING_OES(0x8CA6),
+    GL_RENDERBUFFER_BINDING_OES(0x8CA7),
+    GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES(0x8CD0),
+    GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES(0x8CD1),
+    GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES(0x8CD2),
+    GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES(0x8CD3),
+    GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES(0x8CD4),
+    GL_FRAMEBUFFER_COMPLETE_OES(0x8CD5),
+    GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES(0x8CD6),
+    GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES(0x8CD7),
+    GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES(0x8CD9),
+    GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES(0x8CDA),
+    GL_FRAMEBUFFER_UNSUPPORTED_OES(0x8CDD),
+    GL_COLOR_ATTACHMENT0_OES(0x8CE0),
+    GL_DEPTH_ATTACHMENT_OES(0x8D00),
+    GL_STENCIL_ATTACHMENT_OES(0x8D20),
+    GL_FRAMEBUFFER_OES(0x8D40),
+    GL_RENDERBUFFER_OES(0x8D41),
+    GL_RENDERBUFFER_WIDTH_OES(0x8D42),
+    GL_RENDERBUFFER_HEIGHT_OES(0x8D43),
+    GL_RENDERBUFFER_INTERNAL_FORMAT_OES(0x8D44),
+    GL_STENCIL_INDEX1_OES(0x8D46),
+    GL_STENCIL_INDEX4_OES(0x8D47),
+    GL_STENCIL_INDEX8_OES(0x8D48),
+    GL_RENDERBUFFER_RED_SIZE_OES(0x8D50),
+    GL_RENDERBUFFER_GREEN_SIZE_OES(0x8D51),
+    GL_RENDERBUFFER_BLUE_SIZE_OES(0x8D52),
+    GL_RENDERBUFFER_ALPHA_SIZE_OES(0x8D53),
+    GL_RENDERBUFFER_DEPTH_SIZE_OES(0x8D54),
+    GL_RENDERBUFFER_STENCIL_SIZE_OES(0x8D55),
+    GL_TEXTURE_GEN_STR_OES(0x8D60),
+    GL_HALF_FLOAT_OES(0x8D61),
+    GL_RGB565_OES(0x8D62),
+    GL_ETC1_RGB8_OES(0x8D64),
+    GL_TEXTURE_EXTERNAL_OES(0x8D65),
+    GL_SAMPLER_EXTERNAL_OES(0x8D66),
+    GL_TEXTURE_BINDING_EXTERNAL_OES(0x8D67),
+    GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES(0x8D68),
+    GL_LOW_FLOAT(0x8DF0),
+    GL_MEDIUM_FLOAT(0x8DF1),
+    GL_HIGH_FLOAT(0x8DF2),
+    GL_LOW_INT(0x8DF3),
+    GL_MEDIUM_INT(0x8DF4),
+    GL_HIGH_INT(0x8DF5),
+    GL_UNSIGNED_INT_10_10_10_2_OES(0x8DF6),
+    GL_INT_10_10_10_2_OES(0x8DF7),
+    GL_SHADER_BINARY_FORMATS(0x8DF8),
+    GL_NUM_SHADER_BINARY_FORMATS(0x8DF9),
+    GL_SHADER_COMPILER(0x8DFA),
+    GL_MAX_VERTEX_UNIFORM_VECTORS(0x8DFB),
+    GL_MAX_VARYING_VECTORS(0x8DFC),
+    GL_MAX_FRAGMENT_UNIFORM_VECTORS(0x8DFD),
+    GL_DEPTH_COMPONENT16_NONLINEAR_NV(0x8E2C),
+    GL_COVERAGE_COMPONENT_NV(0x8ED0),
+    GL_COVERAGE_COMPONENT4_NV(0x8ED1),
+    GL_COVERAGE_ATTACHMENT_NV(0x8ED2),
+    GL_COVERAGE_BUFFERS_NV(0x8ED3),
+    GL_COVERAGE_SAMPLES_NV(0x8ED4),
+    GL_COVERAGE_ALL_FRAGMENTS_NV(0x8ED5),
+    GL_COVERAGE_EDGE_FRAGMENTS_NV(0x8ED6),
+    GL_COVERAGE_AUTOMATIC_NV(0x8ED7),
+    GL_PERFMON_GLOBAL_MODE_QCOM(0x8FA0),
+    GL_SGX_PROGRAM_BINARY_IMG(0x9130),
+    GL_RENDERBUFFER_SAMPLES_IMG(0x9133),
+    GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG(0x9134),
+    GL_MAX_SAMPLES_IMG(0x9135),
+    GL_TEXTURE_SAMPLES_IMG(0x9136),
+    ;
+
+    public final int value;
+    GLEnum(final int value) {
+        this.value = value;
+    }
+
+    private static final java.util.HashMap<Integer, GLEnum> reverseMap = new java.util.HashMap<Integer, GLEnum>();
+    static {
+        for (GLEnum e : GLEnum.values())
+        reverseMap.put(e.value, e);
+    }
+
+    public static GLEnum valueOf(final int value) {
+        return reverseMap.get(value);
+    }
+}
\ No newline at end of file
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/GLFunction.java b/tools/glesv2debugger/src/com/android/glesv2debugger/GLFunction.java
new file mode 100644
index 0000000..081f1b2
--- /dev/null
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/GLFunction.java
@@ -0,0 +1,173 @@
+/*
+ ** 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.
+ */
+
+// auto generated by generate_GLFunction_java.py"
+
+package com.android.glesv2debugger;
+
+public enum GLFunction {
+    glActiveTexture(0, DebuggerMessage.Message.Function.glActiveTexture),
+    glAttachShader(1, DebuggerMessage.Message.Function.glAttachShader),
+    glBindAttribLocation(2, DebuggerMessage.Message.Function.glBindAttribLocation),
+    glBindBuffer(3, DebuggerMessage.Message.Function.glBindBuffer),
+    glBindFramebuffer(4, DebuggerMessage.Message.Function.glBindFramebuffer),
+    glBindRenderbuffer(5, DebuggerMessage.Message.Function.glBindRenderbuffer),
+    glBindTexture(6, DebuggerMessage.Message.Function.glBindTexture),
+    glBlendColor(7, DebuggerMessage.Message.Function.glBlendColor),
+    glBlendEquation(8, DebuggerMessage.Message.Function.glBlendEquation),
+    glBlendEquationSeparate(9, DebuggerMessage.Message.Function.glBlendEquationSeparate),
+    glBlendFunc(10, DebuggerMessage.Message.Function.glBlendFunc),
+    glBlendFuncSeparate(11, DebuggerMessage.Message.Function.glBlendFuncSeparate),
+    glBufferData(12, DebuggerMessage.Message.Function.glBufferData),
+    glBufferSubData(13, DebuggerMessage.Message.Function.glBufferSubData),
+    glCheckFramebufferStatus(14, DebuggerMessage.Message.Function.glCheckFramebufferStatus),
+    glClear(15, DebuggerMessage.Message.Function.glClear),
+    glClearColor(16, DebuggerMessage.Message.Function.glClearColor),
+    glClearDepthf(17, DebuggerMessage.Message.Function.glClearDepthf),
+    glClearStencil(18, DebuggerMessage.Message.Function.glClearStencil),
+    glColorMask(19, DebuggerMessage.Message.Function.glColorMask),
+    glCompileShader(20, DebuggerMessage.Message.Function.glCompileShader),
+    glCompressedTexImage2D(21, DebuggerMessage.Message.Function.glCompressedTexImage2D),
+    glCompressedTexSubImage2D(22, DebuggerMessage.Message.Function.glCompressedTexSubImage2D),
+    glCopyTexImage2D(23, DebuggerMessage.Message.Function.glCopyTexImage2D),
+    glCopyTexSubImage2D(24, DebuggerMessage.Message.Function.glCopyTexSubImage2D),
+    glCreateProgram(25, DebuggerMessage.Message.Function.glCreateProgram),
+    glCreateShader(26, DebuggerMessage.Message.Function.glCreateShader),
+    glCullFace(27, DebuggerMessage.Message.Function.glCullFace),
+    glDeleteBuffers(28, DebuggerMessage.Message.Function.glDeleteBuffers),
+    glDeleteFramebuffers(29, DebuggerMessage.Message.Function.glDeleteFramebuffers),
+    glDeleteProgram(30, DebuggerMessage.Message.Function.glDeleteProgram),
+    glDeleteRenderbuffers(31, DebuggerMessage.Message.Function.glDeleteRenderbuffers),
+    glDeleteShader(32, DebuggerMessage.Message.Function.glDeleteShader),
+    glDeleteTextures(33, DebuggerMessage.Message.Function.glDeleteTextures),
+    glDepthFunc(34, DebuggerMessage.Message.Function.glDepthFunc),
+    glDepthMask(35, DebuggerMessage.Message.Function.glDepthMask),
+    glDepthRangef(36, DebuggerMessage.Message.Function.glDepthRangef),
+    glDetachShader(37, DebuggerMessage.Message.Function.glDetachShader),
+    glDisable(38, DebuggerMessage.Message.Function.glDisable),
+    glDisableVertexAttribArray(39, DebuggerMessage.Message.Function.glDisableVertexAttribArray),
+    glDrawArrays(40, DebuggerMessage.Message.Function.glDrawArrays),
+    glDrawElements(41, DebuggerMessage.Message.Function.glDrawElements),
+    glEnable(42, DebuggerMessage.Message.Function.glEnable),
+    glEnableVertexAttribArray(43, DebuggerMessage.Message.Function.glEnableVertexAttribArray),
+    glFinish(44, DebuggerMessage.Message.Function.glFinish),
+    glFlush(45, DebuggerMessage.Message.Function.glFlush),
+    glFramebufferRenderbuffer(46, DebuggerMessage.Message.Function.glFramebufferRenderbuffer),
+    glFramebufferTexture2D(47, DebuggerMessage.Message.Function.glFramebufferTexture2D),
+    glFrontFace(48, DebuggerMessage.Message.Function.glFrontFace),
+    glGenBuffers(49, DebuggerMessage.Message.Function.glGenBuffers),
+    glGenerateMipmap(50, DebuggerMessage.Message.Function.glGenerateMipmap),
+    glGenFramebuffers(51, DebuggerMessage.Message.Function.glGenFramebuffers),
+    glGenRenderbuffers(52, DebuggerMessage.Message.Function.glGenRenderbuffers),
+    glGenTextures(53, DebuggerMessage.Message.Function.glGenTextures),
+    glGetActiveAttrib(54, DebuggerMessage.Message.Function.glGetActiveAttrib),
+    glGetActiveUniform(55, DebuggerMessage.Message.Function.glGetActiveUniform),
+    glGetAttachedShaders(56, DebuggerMessage.Message.Function.glGetAttachedShaders),
+    glGetAttribLocation(57, DebuggerMessage.Message.Function.glGetAttribLocation),
+    glGetBooleanv(58, DebuggerMessage.Message.Function.glGetBooleanv),
+    glGetBufferParameteriv(59, DebuggerMessage.Message.Function.glGetBufferParameteriv),
+    glGetError(60, DebuggerMessage.Message.Function.glGetError),
+    glGetFloatv(61, DebuggerMessage.Message.Function.glGetFloatv),
+    glGetFramebufferAttachmentParameteriv(62, DebuggerMessage.Message.Function.glGetFramebufferAttachmentParameteriv),
+    glGetIntegerv(63, DebuggerMessage.Message.Function.glGetIntegerv),
+    glGetProgramiv(64, DebuggerMessage.Message.Function.glGetProgramiv),
+    glGetProgramInfoLog(65, DebuggerMessage.Message.Function.glGetProgramInfoLog),
+    glGetRenderbufferParameteriv(66, DebuggerMessage.Message.Function.glGetRenderbufferParameteriv),
+    glGetShaderiv(67, DebuggerMessage.Message.Function.glGetShaderiv),
+    glGetShaderInfoLog(68, DebuggerMessage.Message.Function.glGetShaderInfoLog),
+    glGetShaderPrecisionFormat(69, DebuggerMessage.Message.Function.glGetShaderPrecisionFormat),
+    glGetShaderSource(70, DebuggerMessage.Message.Function.glGetShaderSource),
+    glGetString(71, DebuggerMessage.Message.Function.glGetString),
+    glGetTexParameterfv(72, DebuggerMessage.Message.Function.glGetTexParameterfv),
+    glGetTexParameteriv(73, DebuggerMessage.Message.Function.glGetTexParameteriv),
+    glGetUniformfv(74, DebuggerMessage.Message.Function.glGetUniformfv),
+    glGetUniformiv(75, DebuggerMessage.Message.Function.glGetUniformiv),
+    glGetUniformLocation(76, DebuggerMessage.Message.Function.glGetUniformLocation),
+    glGetVertexAttribfv(77, DebuggerMessage.Message.Function.glGetVertexAttribfv),
+    glGetVertexAttribiv(78, DebuggerMessage.Message.Function.glGetVertexAttribiv),
+    glGetVertexAttribPointerv(79, DebuggerMessage.Message.Function.glGetVertexAttribPointerv),
+    glHint(80, DebuggerMessage.Message.Function.glHint),
+    glIsBuffer(81, DebuggerMessage.Message.Function.glIsBuffer),
+    glIsEnabled(82, DebuggerMessage.Message.Function.glIsEnabled),
+    glIsFramebuffer(83, DebuggerMessage.Message.Function.glIsFramebuffer),
+    glIsProgram(84, DebuggerMessage.Message.Function.glIsProgram),
+    glIsRenderbuffer(85, DebuggerMessage.Message.Function.glIsRenderbuffer),
+    glIsShader(86, DebuggerMessage.Message.Function.glIsShader),
+    glIsTexture(87, DebuggerMessage.Message.Function.glIsTexture),
+    glLineWidth(88, DebuggerMessage.Message.Function.glLineWidth),
+    glLinkProgram(89, DebuggerMessage.Message.Function.glLinkProgram),
+    glPixelStorei(90, DebuggerMessage.Message.Function.glPixelStorei),
+    glPolygonOffset(91, DebuggerMessage.Message.Function.glPolygonOffset),
+    glReadPixels(92, DebuggerMessage.Message.Function.glReadPixels),
+    glReleaseShaderCompiler(93, DebuggerMessage.Message.Function.glReleaseShaderCompiler),
+    glRenderbufferStorage(94, DebuggerMessage.Message.Function.glRenderbufferStorage),
+    glSampleCoverage(95, DebuggerMessage.Message.Function.glSampleCoverage),
+    glScissor(96, DebuggerMessage.Message.Function.glScissor),
+    glShaderBinary(97, DebuggerMessage.Message.Function.glShaderBinary),
+    glShaderSource(98, DebuggerMessage.Message.Function.glShaderSource),
+    glStencilFunc(99, DebuggerMessage.Message.Function.glStencilFunc),
+    glStencilFuncSeparate(100, DebuggerMessage.Message.Function.glStencilFuncSeparate),
+    glStencilMask(101, DebuggerMessage.Message.Function.glStencilMask),
+    glStencilMaskSeparate(102, DebuggerMessage.Message.Function.glStencilMaskSeparate),
+    glStencilOp(103, DebuggerMessage.Message.Function.glStencilOp),
+    glStencilOpSeparate(104, DebuggerMessage.Message.Function.glStencilOpSeparate),
+    glTexImage2D(105, DebuggerMessage.Message.Function.glTexImage2D),
+    glTexParameterf(106, DebuggerMessage.Message.Function.glTexParameterf),
+    glTexParameterfv(107, DebuggerMessage.Message.Function.glTexParameterfv),
+    glTexParameteri(108, DebuggerMessage.Message.Function.glTexParameteri),
+    glTexParameteriv(109, DebuggerMessage.Message.Function.glTexParameteriv),
+    glTexSubImage2D(110, DebuggerMessage.Message.Function.glTexSubImage2D),
+    glUniform1f(111, DebuggerMessage.Message.Function.glUniform1f),
+    glUniform1fv(112, DebuggerMessage.Message.Function.glUniform1fv),
+    glUniform1i(113, DebuggerMessage.Message.Function.glUniform1i),
+    glUniform1iv(114, DebuggerMessage.Message.Function.glUniform1iv),
+    glUniform2f(115, DebuggerMessage.Message.Function.glUniform2f),
+    glUniform2fv(116, DebuggerMessage.Message.Function.glUniform2fv),
+    glUniform2i(117, DebuggerMessage.Message.Function.glUniform2i),
+    glUniform2iv(118, DebuggerMessage.Message.Function.glUniform2iv),
+    glUniform3f(119, DebuggerMessage.Message.Function.glUniform3f),
+    glUniform3fv(120, DebuggerMessage.Message.Function.glUniform3fv),
+    glUniform3i(121, DebuggerMessage.Message.Function.glUniform3i),
+    glUniform3iv(122, DebuggerMessage.Message.Function.glUniform3iv),
+    glUniform4f(123, DebuggerMessage.Message.Function.glUniform4f),
+    glUniform4fv(124, DebuggerMessage.Message.Function.glUniform4fv),
+    glUniform4i(125, DebuggerMessage.Message.Function.glUniform4i),
+    glUniform4iv(126, DebuggerMessage.Message.Function.glUniform4iv),
+    glUniformMatrix2fv(127, DebuggerMessage.Message.Function.glUniformMatrix2fv),
+    glUniformMatrix3fv(128, DebuggerMessage.Message.Function.glUniformMatrix3fv),
+    glUniformMatrix4fv(129, DebuggerMessage.Message.Function.glUniformMatrix4fv),
+    glUseProgram(130, DebuggerMessage.Message.Function.glUseProgram),
+    glValidateProgram(131, DebuggerMessage.Message.Function.glValidateProgram),
+    glVertexAttrib1f(132, DebuggerMessage.Message.Function.glVertexAttrib1f),
+    glVertexAttrib1fv(133, DebuggerMessage.Message.Function.glVertexAttrib1fv),
+    glVertexAttrib2f(134, DebuggerMessage.Message.Function.glVertexAttrib2f),
+    glVertexAttrib2fv(135, DebuggerMessage.Message.Function.glVertexAttrib2fv),
+    glVertexAttrib3f(136, DebuggerMessage.Message.Function.glVertexAttrib3f),
+    glVertexAttrib3fv(137, DebuggerMessage.Message.Function.glVertexAttrib3fv),
+    glVertexAttrib4f(138, DebuggerMessage.Message.Function.glVertexAttrib4f),
+    glVertexAttrib4fv(139, DebuggerMessage.Message.Function.glVertexAttrib4fv),
+    glVertexAttribPointer(140, DebuggerMessage.Message.Function.glVertexAttribPointer),
+    glViewport(141, DebuggerMessage.Message.Function.glViewport),
+    ;
+
+    public final int index;
+    public final DebuggerMessage.Message.Function function;
+
+    GLFunction(final int index, final DebuggerMessage.Message.Function function) {
+        this.index = index;
+        this.function = function;
+    }
+}
\ No newline at end of file
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/MessageData.java b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageData.java
new file mode 100644
index 0000000..729592e
--- /dev/null
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageData.java
@@ -0,0 +1,89 @@
+/*
+ ** 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 org.eclipse.swt.graphics.Device;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+
+public class MessageData {
+    public DebuggerMessage.Message.Function function;
+    public Image image; // texture
+    public String shader; // shader source
+    public String[] columns;
+    public float[] data; // vertex attributes
+
+    public MessageData(final Device device, final DebuggerMessage.Message msg) {
+        image = null;
+        shader = null;
+        data = null;
+        StringBuilder builder = new StringBuilder();
+        function = msg.getFunction();
+        ImageData imageData = null;
+        if (function != DebuggerMessage.Message.Function.ACK)
+            assert msg.hasTime();
+        columns = new String [4];
+        columns[0] = function.toString();
+        columns[1] = "";
+        if (msg.hasTime())
+            columns[1] += Float.toString(msg.getTime());
+        if (msg.hasClock())
+            columns[1] += ":" + Float.toString(msg.getClock());
+        columns[2] = Integer.toHexString(msg.getContextId());
+        columns[3] = MessageFormatter.Format(msg);
+        switch (function) {
+            case glBufferData:
+                data = MessageProcessor.ReceiveData(msg.getArg0(), msg.getData());
+                break;
+            case glBufferSubData:
+                data = MessageProcessor.ReceiveData(msg.getArg0(), msg.getData());
+                break;
+            case glShaderSource:
+                shader = msg.getData().toStringUtf8();
+                int index = shader.indexOf('\n');
+                columns[3] += " source: " + shader.substring(0, index >= 0 ? index : shader.length()) + "...";
+                break;
+            case glTexImage2D:
+                if (!msg.hasData())
+                    break;
+                imageData = MessageProcessor.ReceiveImage(msg.getArg3(), msg
+                        .getArg4(), msg.getArg6(), msg.getArg7(), msg.getData()
+                        .toByteArray());
+                if (null == imageData)
+                    break;
+                image = new Image(device, imageData);
+                break;
+            case glTexSubImage2D:
+                assert msg.hasData();
+                imageData = MessageProcessor.ReceiveImage(msg.getArg4(), msg
+                        .getArg5(), msg.getArg6(), msg.getArg7(), msg.getData()
+                        .toByteArray());
+                if (null == imageData)
+                    break;
+                image = new Image(device, imageData);
+                break;
+            case glReadPixels:
+                if (!msg.hasData())
+                    break;
+                imageData = MessageProcessor.ReceiveImage(msg.getArg2(), msg.getArg3(),
+                        msg.getArg4(), msg.getArg5(), msg.getData().toByteArray());
+                imageData = imageData.scaledTo(imageData.width, -imageData.height);
+                image = new Image(device, imageData);
+                break;
+        }
+    }
+}
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/MessageFormatter.java b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageFormatter.java
new file mode 100644
index 0000000..899cf5f
--- /dev/null
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageFormatter.java
@@ -0,0 +1,396 @@
+/*
+ ** 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.
+ */
+
+// auto generated by generate_MessageFormatter_java.py"
+
+package com.android.glesv2debugger;
+
+import java.nio.ByteBuffer;
+
+public class MessageFormatter {
+
+    static String FormatFloats(int count, final ByteBuffer data) {
+        String ret = "[";
+        for (int i = 0; i < count; i++)
+        {
+            ret += Float.intBitsToFloat(Integer.reverseBytes(data.getInt()));
+            if (i < count - 1)
+                ret += ", ";
+        }
+        return ret + "]";
+    }
+    
+    static String FormatInts(int count, final ByteBuffer data) {
+        String ret = "[";
+        for (int i = 0; i < count; i++)
+        {
+            ret += Integer.reverseBytes(data.getInt());
+            if (i < count - 1)
+                ret += ", ";
+        }
+        return ret + "]";
+    }
+    
+    static String FormatUints(int count, final ByteBuffer data) {
+        String ret = "[";
+        for (int i = 0; i < count; i++)
+        {
+            long bits = Integer.reverseBytes(data.getInt()) & 0xffffffff;
+            ret += bits;
+            if (i < count - 1)
+                ret += ", ";
+        }
+        return ret + "]";
+    }
+    
+    static String FormatMatrix(int columns, int count, final ByteBuffer data) {
+        String ret = "[";
+        for (int i = 0; i < count; i++)
+        {
+            ret += Float.intBitsToFloat(Integer.reverseBytes(data.getInt()));
+            if (i % columns == columns - 1)
+                ret += '\n';
+            else if (i < count - 1)
+                ret += ", ";
+        }
+        return ret + "]";
+    }
+
+    public static String Format(final DebuggerMessage.Message msg) {
+        String str;
+        switch (msg.getFunction()) {
+            case glActiveTexture:
+                str = String.format("%s (texture=%s)", "void", GLEnum.valueOf(msg.getArg0())); break;
+            case glAttachShader:
+                str = String.format("%s (program=%s, shader=%s)", "void", msg.getArg0(), msg.getArg1()); break;
+            case glBindAttribLocation:
+                str = String.format("%s (program=%s, index=%s, name=%s)", "void", msg.getArg0(), msg.getArg1(), msg.getData().toStringUtf8()); break;
+            case glBindBuffer:
+                str = String.format("%s (target=%s, buffer=%s)", "void", GLEnum.valueOf(msg.getArg0()), msg.getArg1()); break;
+            case glBindFramebuffer:
+                str = String.format("%s (target=%s, framebuffer=%s)", "void", GLEnum.valueOf(msg.getArg0()), msg.getArg1()); break;
+            case glBindRenderbuffer:
+                str = String.format("%s (target=%s, renderbuffer=%s)", "void", GLEnum.valueOf(msg.getArg0()), msg.getArg1()); break;
+            case glBindTexture:
+                str = String.format("%s (target=%s, texture=%s)", "void", GLEnum.valueOf(msg.getArg0()), msg.getArg1()); break;
+            case glBlendColor:
+                str = String.format("%s (red=%s, green=%s, blue=%s, alpha=%s)", "void", Float.intBitsToFloat(msg.getArg0()), Float.intBitsToFloat(msg.getArg1()), Float.intBitsToFloat(msg.getArg2()), Float.intBitsToFloat(msg.getArg3())); break;
+            case glBlendEquation:
+                str = String.format("%s (mode=%s)", "void", GLEnum.valueOf(msg.getArg0())); break;
+            case glBlendEquationSeparate:
+                str = String.format("%s (modeRGB=%s, modeAlpha=%s)", "void", GLEnum.valueOf(msg.getArg0()), GLEnum.valueOf(msg.getArg1())); break;
+            case glBlendFunc:
+                str = String.format("%s (sfactor=%s, dfactor=%s)", "void", GLEnum.valueOf(msg.getArg0()), GLEnum.valueOf(msg.getArg1())); break;
+            case glBlendFuncSeparate:
+                str = String.format("%s (srcRGB=%s, dstRGB=%s, srcAlpha=%s, dstAlpha=%s)", "void", GLEnum.valueOf(msg.getArg0()), GLEnum.valueOf(msg.getArg1()), GLEnum.valueOf(msg.getArg2()), GLEnum.valueOf(msg.getArg3())); break;
+            case glBufferData:
+                str = String.format("%s (target=%s, size=%s, data=%s, usage=%s)", "void", GLEnum.valueOf(msg.getArg0()), msg.getArg1(), "0x" + Integer.toHexString(msg.getArg2()), GLEnum.valueOf(msg.getArg3())); break;
+            case glBufferSubData:
+                str = String.format("%s (target=%s, offset=%s, size=%s, data=%s)", "void", GLEnum.valueOf(msg.getArg0()), msg.getArg1(), msg.getArg2(), "0x" + Integer.toHexString(msg.getArg3())); break;
+            case glCheckFramebufferStatus:
+                str = String.format("%s (target=%s)", GLEnum.valueOf(msg.getRet()), GLEnum.valueOf(msg.getArg0())); break;
+            case glClear:
+                str = String.format("%s (mask=%s)", "void", msg.getArg0()); break;
+            case glClearColor:
+                str = String.format("%s (red=%s, green=%s, blue=%s, alpha=%s)", "void", Float.intBitsToFloat(msg.getArg0()), Float.intBitsToFloat(msg.getArg1()), Float.intBitsToFloat(msg.getArg2()), Float.intBitsToFloat(msg.getArg3())); break;
+            case glClearDepthf:
+                str = String.format("%s (depth=%s)", "void", Float.intBitsToFloat(msg.getArg0())); break;
+            case glClearStencil:
+                str = String.format("%s (s=%s)", "void", msg.getArg0()); break;
+            case glColorMask:
+                str = String.format("%s (red=%s, green=%s, blue=%s, alpha=%s)", "void", msg.getArg0(), msg.getArg1(), msg.getArg2(), msg.getArg3()); break;
+            case glCompileShader:
+                str = String.format("%s (shader=%s)", "void", msg.getArg0()); break;
+            case glCompressedTexImage2D:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (target=%s, level=%s, internalformat=%s, width=%s, height=%s, border=%s, imageSize=%s, data=%s)", "void", GLEnum.valueOf(msg.getArg0()), msg.getArg1(), GLEnum.valueOf(msg.getArg2()), msg.getArg3(), msg.getArg4(), msg.getArg5(), msg.getArg6(), "0x" + Integer.toHexString(msg.getArg7())); break;
+            case glCompressedTexSubImage2D:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (target=%s, level=%s, xoffset=%s, yoffset=%s, width=%s, height=%s, format=%s, imageSize=%s, data=%s)", "void", GLEnum.valueOf(msg.getArg0()), msg.getArg1(), msg.getArg2(), msg.getArg3(), msg.getArg4(), msg.getArg5(), GLEnum.valueOf(msg.getArg6()), msg.getArg7(), "0x" + Integer.toHexString(msg.getArg8())); break;
+            case glCopyTexImage2D:
+                str = String.format("%s (target=%s, level=%s, internalformat=%s, x=%s, y=%s, width=%s, height=%s, border=%s)", "void", GLEnum.valueOf(msg.getArg0()), msg.getArg1(), GLEnum.valueOf(msg.getArg2()), msg.getArg3(), msg.getArg4(), msg.getArg5(), msg.getArg6(), msg.getArg7()); break;
+            case glCopyTexSubImage2D:
+                str = String.format("%s (target=%s, level=%s, xoffset=%s, yoffset=%s, x=%s, y=%s, width=%s, height=%s)", "void", GLEnum.valueOf(msg.getArg0()), msg.getArg1(), msg.getArg2(), msg.getArg3(), msg.getArg4(), msg.getArg5(), msg.getArg6(), msg.getArg7()); break;
+            case glCreateProgram:
+                str = String.format("%s ()", msg.getRet()); break;
+            case glCreateShader:
+                str = String.format("%s (type=%s)", msg.getRet(), GLEnum.valueOf(msg.getArg0())); break;
+            case glCullFace:
+                str = String.format("%s (mode=%s)", "void", GLEnum.valueOf(msg.getArg0())); break;
+            case glDeleteBuffers:
+                str = String.format("%s (n=%s, buffers=%s)", "void", msg.getArg0(), FormatUints(1 * msg.getArg0(), msg.getData().asReadOnlyByteBuffer())); break;
+            case glDeleteFramebuffers:
+                str = String.format("%s (n=%s, framebuffers=%s)", "void", msg.getArg0(), FormatUints(1 * msg.getArg0(), msg.getData().asReadOnlyByteBuffer())); break;
+            case glDeleteProgram:
+                str = String.format("%s (program=%s)", "void", msg.getArg0()); break;
+            case glDeleteRenderbuffers:
+                str = String.format("%s (n=%s, renderbuffers=%s)", "void", msg.getArg0(), FormatUints(1 * msg.getArg0(), msg.getData().asReadOnlyByteBuffer())); break;
+            case glDeleteShader:
+                str = String.format("%s (shader=%s)", "void", msg.getArg0()); break;
+            case glDeleteTextures:
+                str = String.format("%s (n=%s, textures=%s)", "void", msg.getArg0(), FormatUints(1 * msg.getArg0(), msg.getData().asReadOnlyByteBuffer())); break;
+            case glDepthFunc:
+                str = String.format("%s (func=%s)", "void", GLEnum.valueOf(msg.getArg0())); break;
+            case glDepthMask:
+                str = String.format("%s (flag=%s)", "void", msg.getArg0()); break;
+            case glDepthRangef:
+                str = String.format("%s (zNear=%s, zFar=%s)", "void", Float.intBitsToFloat(msg.getArg0()), Float.intBitsToFloat(msg.getArg1())); break;
+            case glDetachShader:
+                str = String.format("%s (program=%s, shader=%s)", "void", msg.getArg0(), msg.getArg1()); break;
+            case glDisable:
+                str = String.format("%s (cap=%s)", "void", GLEnum.valueOf(msg.getArg0())); break;
+            case glDisableVertexAttribArray:
+                str = String.format("%s (index=%s)", "void", msg.getArg0()); break;
+            case glDrawArrays:
+                str = String.format("%s (mode=%s, first=%s, count=%s)", "void", GLEnum.valueOf(msg.getArg0()), msg.getArg1(), msg.getArg2()); break;
+            case glDrawElements:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (mode=%s, count=%s, type=%s, indices=%s)", "void", GLEnum.valueOf(msg.getArg0()), msg.getArg1(), GLEnum.valueOf(msg.getArg2()), "0x" + Integer.toHexString(msg.getArg3())); break;
+            case glEnable:
+                str = String.format("%s (cap=%s)", "void", GLEnum.valueOf(msg.getArg0())); break;
+            case glEnableVertexAttribArray:
+                str = String.format("%s (index=%s)", "void", msg.getArg0()); break;
+            case glFinish:
+                str = String.format("%s ()", "void"); break;
+            case glFlush:
+                str = String.format("%s ()", "void"); break;
+            case glFramebufferRenderbuffer:
+                str = String.format("%s (target=%s, attachment=%s, renderbuffertarget=%s, renderbuffer=%s)", "void", GLEnum.valueOf(msg.getArg0()), GLEnum.valueOf(msg.getArg1()), GLEnum.valueOf(msg.getArg2()), msg.getArg3()); break;
+            case glFramebufferTexture2D:
+                str = String.format("%s (target=%s, attachment=%s, textarget=%s, texture=%s, level=%s)", "void", GLEnum.valueOf(msg.getArg0()), GLEnum.valueOf(msg.getArg1()), GLEnum.valueOf(msg.getArg2()), msg.getArg3(), msg.getArg4()); break;
+            case glFrontFace:
+                str = String.format("%s (mode=%s)", "void", GLEnum.valueOf(msg.getArg0())); break;
+            case glGenBuffers:
+                str = String.format("%s (n=%s, buffers=%s)", "void", msg.getArg0(), FormatUints(1 * msg.getArg0(), msg.getData().asReadOnlyByteBuffer())); break;
+            case glGenerateMipmap:
+                str = String.format("%s (target=%s)", "void", GLEnum.valueOf(msg.getArg0())); break;
+            case glGenFramebuffers:
+                str = String.format("%s (n=%s, framebuffers=%s)", "void", msg.getArg0(), FormatUints(1 * msg.getArg0(), msg.getData().asReadOnlyByteBuffer())); break;
+            case glGenRenderbuffers:
+                str = String.format("%s (n=%s, renderbuffers=%s)", "void", msg.getArg0(), FormatUints(1 * msg.getArg0(), msg.getData().asReadOnlyByteBuffer())); break;
+            case glGenTextures:
+                str = String.format("%s (n=%s, textures=%s)", "void", msg.getArg0(), FormatUints(1 * msg.getArg0(), msg.getData().asReadOnlyByteBuffer())); break;
+            case glGetActiveAttrib:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (program=%s, index=%s, bufsize=%s, length=%s, size=%s, type=%s, name=%s)", "void", msg.getArg0(), msg.getArg1(), msg.getArg2(), "0x" + Integer.toHexString(msg.getArg3()), "0x" + Integer.toHexString(msg.getArg4()), "0x" + Integer.toHexString(msg.getArg5()), msg.getData().toStringUtf8()); break;
+            case glGetActiveUniform:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (program=%s, index=%s, bufsize=%s, length=%s, size=%s, type=%s, name=%s)", "void", msg.getArg0(), msg.getArg1(), msg.getArg2(), "0x" + Integer.toHexString(msg.getArg3()), "0x" + Integer.toHexString(msg.getArg4()), "0x" + Integer.toHexString(msg.getArg5()), msg.getData().toStringUtf8()); break;
+            case glGetAttachedShaders:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (program=%s, maxcount=%s, count=%s, shaders=%s)", "void", msg.getArg0(), msg.getArg1(), "0x" + Integer.toHexString(msg.getArg2()), "0x" + Integer.toHexString(msg.getArg3())); break;
+            case glGetAttribLocation:
+                str = String.format("%s (program=%s, name=%s)", msg.getRet(), msg.getArg0(), msg.getData().toStringUtf8()); break;
+            case glGetBooleanv:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (pname=%s, params=%s)", "void", GLEnum.valueOf(msg.getArg0()), "0x" + Integer.toHexString(msg.getArg1())); break;
+            case glGetBufferParameteriv:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (target=%s, pname=%s, params=%s)", "void", GLEnum.valueOf(msg.getArg0()), GLEnum.valueOf(msg.getArg1()), "0x" + Integer.toHexString(msg.getArg2())); break;
+            case glGetError:
+                str = String.format("%s ()", GLEnum.valueOf(msg.getRet())); break;
+            case glGetFloatv:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (pname=%s, params=%s)", "void", GLEnum.valueOf(msg.getArg0()), "0x" + Integer.toHexString(msg.getArg1())); break;
+            case glGetFramebufferAttachmentParameteriv:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (target=%s, attachment=%s, pname=%s, params=%s)", "void", GLEnum.valueOf(msg.getArg0()), GLEnum.valueOf(msg.getArg1()), GLEnum.valueOf(msg.getArg2()), "0x" + Integer.toHexString(msg.getArg3())); break;
+            case glGetIntegerv:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (pname=%s, params=%s)", "void", GLEnum.valueOf(msg.getArg0()), "0x" + Integer.toHexString(msg.getArg1())); break;
+            case glGetProgramiv:
+                str = String.format("%s (program=%s, pname=%s, params=%s)", "void", msg.getArg0(), GLEnum.valueOf(msg.getArg1()), FormatInts(1, msg.getData().asReadOnlyByteBuffer())); break;
+            case glGetProgramInfoLog:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (program=%s, bufsize=%s, length=%s, infolog=%s)", "void", msg.getArg0(), msg.getArg1(), "0x" + Integer.toHexString(msg.getArg2()), msg.getData().toStringUtf8()); break;
+            case glGetRenderbufferParameteriv:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (target=%s, pname=%s, params=%s)", "void", GLEnum.valueOf(msg.getArg0()), GLEnum.valueOf(msg.getArg1()), "0x" + Integer.toHexString(msg.getArg2())); break;
+            case glGetShaderiv:
+                str = String.format("%s (shader=%s, pname=%s, params=%s)", "void", msg.getArg0(), GLEnum.valueOf(msg.getArg1()), FormatInts(1, msg.getData().asReadOnlyByteBuffer())); break;
+            case glGetShaderInfoLog:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (shader=%s, bufsize=%s, length=%s, infolog=%s)", "void", msg.getArg0(), msg.getArg1(), "0x" + Integer.toHexString(msg.getArg2()), msg.getData().toStringUtf8()); break;
+            case glGetShaderPrecisionFormat:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (shadertype=%s, precisiontype=%s, range=%s, precision=%s)", "void", GLEnum.valueOf(msg.getArg0()), GLEnum.valueOf(msg.getArg1()), "0x" + Integer.toHexString(msg.getArg2()), "0x" + Integer.toHexString(msg.getArg3())); break;
+            case glGetShaderSource:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (shader=%s, bufsize=%s, length=%s, source=%s)", "void", msg.getArg0(), msg.getArg1(), "0x" + Integer.toHexString(msg.getArg2()), msg.getData().toStringUtf8()); break;
+            case glGetString:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (name=%s)", "0x" + Integer.toHexString(msg.getRet()), GLEnum.valueOf(msg.getArg0())); break;
+            case glGetTexParameterfv:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (target=%s, pname=%s, params=%s)", "void", GLEnum.valueOf(msg.getArg0()), GLEnum.valueOf(msg.getArg1()), "0x" + Integer.toHexString(msg.getArg2())); break;
+            case glGetTexParameteriv:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (target=%s, pname=%s, params=%s)", "void", GLEnum.valueOf(msg.getArg0()), GLEnum.valueOf(msg.getArg1()), "0x" + Integer.toHexString(msg.getArg2())); break;
+            case glGetUniformfv:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (program=%s, location=%s, params=%s)", "void", msg.getArg0(), msg.getArg1(), "0x" + Integer.toHexString(msg.getArg2())); break;
+            case glGetUniformiv:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (program=%s, location=%s, params=%s)", "void", msg.getArg0(), msg.getArg1(), "0x" + Integer.toHexString(msg.getArg2())); break;
+            case glGetUniformLocation:
+                str = String.format("%s (program=%s, name=%s)", msg.getRet(), msg.getArg0(), msg.getData().toStringUtf8()); break;
+            case glGetVertexAttribfv:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (index=%s, pname=%s, params=%s)", "void", msg.getArg0(), GLEnum.valueOf(msg.getArg1()), "0x" + Integer.toHexString(msg.getArg2())); break;
+            case glGetVertexAttribiv:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (index=%s, pname=%s, params=%s)", "void", msg.getArg0(), GLEnum.valueOf(msg.getArg1()), "0x" + Integer.toHexString(msg.getArg2())); break;
+            case glGetVertexAttribPointerv:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (index=%s, pname=%s, pointer=%s)", "void", msg.getArg0(), GLEnum.valueOf(msg.getArg1()), "0x" + Integer.toHexString(msg.getArg2())); break;
+            case glHint:
+                str = String.format("%s (target=%s, mode=%s)", "void", GLEnum.valueOf(msg.getArg0()), GLEnum.valueOf(msg.getArg1())); break;
+            case glIsBuffer:
+                str = String.format("%s (buffer=%s)", msg.getRet(), msg.getArg0()); break;
+            case glIsEnabled:
+                str = String.format("%s (cap=%s)", msg.getRet(), GLEnum.valueOf(msg.getArg0())); break;
+            case glIsFramebuffer:
+                str = String.format("%s (framebuffer=%s)", msg.getRet(), msg.getArg0()); break;
+            case glIsProgram:
+                str = String.format("%s (program=%s)", msg.getRet(), msg.getArg0()); break;
+            case glIsRenderbuffer:
+                str = String.format("%s (renderbuffer=%s)", msg.getRet(), msg.getArg0()); break;
+            case glIsShader:
+                str = String.format("%s (shader=%s)", msg.getRet(), msg.getArg0()); break;
+            case glIsTexture:
+                str = String.format("%s (texture=%s)", msg.getRet(), msg.getArg0()); break;
+            case glLineWidth:
+                str = String.format("%s (width=%s)", "void", Float.intBitsToFloat(msg.getArg0())); break;
+            case glLinkProgram:
+                str = String.format("%s (program=%s)", "void", msg.getArg0()); break;
+            case glPixelStorei:
+                str = String.format("%s (pname=%s, param=%s)", "void", GLEnum.valueOf(msg.getArg0()), msg.getArg1()); break;
+            case glPolygonOffset:
+                str = String.format("%s (factor=%s, units=%s)", "void", Float.intBitsToFloat(msg.getArg0()), Float.intBitsToFloat(msg.getArg1())); break;
+            case glReadPixels:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (x=%s, y=%s, width=%s, height=%s, format=%s, type=%s, pixels=%s)", "void", msg.getArg0(), msg.getArg1(), msg.getArg2(), msg.getArg3(), GLEnum.valueOf(msg.getArg4()), GLEnum.valueOf(msg.getArg5()), "0x" + Integer.toHexString(msg.getArg6())); break;
+            case glReleaseShaderCompiler:
+                str = String.format("%s ()", "void"); break;
+            case glRenderbufferStorage:
+                str = String.format("%s (target=%s, internalformat=%s, width=%s, height=%s)", "void", GLEnum.valueOf(msg.getArg0()), GLEnum.valueOf(msg.getArg1()), msg.getArg2(), msg.getArg3()); break;
+            case glSampleCoverage:
+                str = String.format("%s (value=%s, invert=%s)", "void", Float.intBitsToFloat(msg.getArg0()), msg.getArg1()); break;
+            case glScissor:
+                str = String.format("%s (x=%s, y=%s, width=%s, height=%s)", "void", msg.getArg0(), msg.getArg1(), msg.getArg2(), msg.getArg3()); break;
+            case glShaderBinary:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (n=%s, shaders=%s, binaryformat=%s, binary=%s, length=%s)", "void", msg.getArg0(), "0x" + Integer.toHexString(msg.getArg1()), GLEnum.valueOf(msg.getArg2()), "0x" + Integer.toHexString(msg.getArg3()), msg.getArg4()); break;
+            case glShaderSource:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (shader=%s, count=%s, string=%s, length=%s)", "void", msg.getArg0(), msg.getArg1(), "0x" + Integer.toHexString(msg.getArg2()), "0x" + Integer.toHexString(msg.getArg3())); break;
+            case glStencilFunc:
+                str = String.format("%s (func=%s, ref=%s, mask=%s)", "void", GLEnum.valueOf(msg.getArg0()), msg.getArg1(), msg.getArg2()); break;
+            case glStencilFuncSeparate:
+                str = String.format("%s (face=%s, func=%s, ref=%s, mask=%s)", "void", GLEnum.valueOf(msg.getArg0()), GLEnum.valueOf(msg.getArg1()), msg.getArg2(), msg.getArg3()); break;
+            case glStencilMask:
+                str = String.format("%s (mask=%s)", "void", msg.getArg0()); break;
+            case glStencilMaskSeparate:
+                str = String.format("%s (face=%s, mask=%s)", "void", GLEnum.valueOf(msg.getArg0()), msg.getArg1()); break;
+            case glStencilOp:
+                str = String.format("%s (fail=%s, zfail=%s, zpass=%s)", "void", GLEnum.valueOf(msg.getArg0()), GLEnum.valueOf(msg.getArg1()), GLEnum.valueOf(msg.getArg2())); break;
+            case glStencilOpSeparate:
+                str = String.format("%s (face=%s, fail=%s, zfail=%s, zpass=%s)", "void", GLEnum.valueOf(msg.getArg0()), GLEnum.valueOf(msg.getArg1()), GLEnum.valueOf(msg.getArg2()), GLEnum.valueOf(msg.getArg3())); break;
+            case glTexImage2D:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (target=%s, level=%s, internalformat=%s, width=%s, height=%s, border=%s, format=%s, type=%s, pixels=%s)", "void", GLEnum.valueOf(msg.getArg0()), msg.getArg1(), msg.getArg2(), msg.getArg3(), msg.getArg4(), msg.getArg5(), GLEnum.valueOf(msg.getArg6()), GLEnum.valueOf(msg.getArg7()), "0x" + Integer.toHexString(msg.getArg8())); break;
+            case glTexParameterf:
+                str = String.format("%s (target=%s, pname=%s, param=%s)", "void", GLEnum.valueOf(msg.getArg0()), GLEnum.valueOf(msg.getArg1()), Float.intBitsToFloat(msg.getArg2())); break;
+            case glTexParameterfv:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (target=%s, pname=%s, params=%s)", "void", GLEnum.valueOf(msg.getArg0()), GLEnum.valueOf(msg.getArg1()), "0x" + Integer.toHexString(msg.getArg2())); break;
+            case glTexParameteri:
+                str = String.format("%s (target=%s, pname=%s, param=%s)", "void", GLEnum.valueOf(msg.getArg0()), GLEnum.valueOf(msg.getArg1()), msg.getArg2()); break;
+            case glTexParameteriv:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (target=%s, pname=%s, params=%s)", "void", GLEnum.valueOf(msg.getArg0()), GLEnum.valueOf(msg.getArg1()), "0x" + Integer.toHexString(msg.getArg2())); break;
+            case glTexSubImage2D:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (target=%s, level=%s, xoffset=%s, yoffset=%s, width=%s, height=%s, format=%s, type=%s, pixels=%s)", "void", GLEnum.valueOf(msg.getArg0()), msg.getArg1(), msg.getArg2(), msg.getArg3(), msg.getArg4(), msg.getArg5(), GLEnum.valueOf(msg.getArg6()), GLEnum.valueOf(msg.getArg7()), "0x" + Integer.toHexString(msg.getArg8())); break;
+            case glUniform1f:
+                str = String.format("%s (location=%s, x=%s)", "void", msg.getArg0(), Float.intBitsToFloat(msg.getArg1())); break;
+            case glUniform1fv:
+                str = String.format("%s (location=%s, count=%s, v=%s)", "void", msg.getArg0(), msg.getArg1(), FormatFloats(1 * msg.getArg1(), msg.getData().asReadOnlyByteBuffer())); break;
+            case glUniform1i:
+                str = String.format("%s (location=%s, x=%s)", "void", msg.getArg0(), msg.getArg1()); break;
+            case glUniform1iv:
+                str = String.format("%s (location=%s, count=%s, v=%s)", "void", msg.getArg0(), msg.getArg1(), FormatInts(1 * msg.getArg1(), msg.getData().asReadOnlyByteBuffer())); break;
+            case glUniform2f:
+                str = String.format("%s (location=%s, x=%s, y=%s)", "void", msg.getArg0(), Float.intBitsToFloat(msg.getArg1()), Float.intBitsToFloat(msg.getArg2())); break;
+            case glUniform2fv:
+                str = String.format("%s (location=%s, count=%s, v=%s)", "void", msg.getArg0(), msg.getArg1(), FormatFloats(2 * msg.getArg1(), msg.getData().asReadOnlyByteBuffer())); break;
+            case glUniform2i:
+                str = String.format("%s (location=%s, x=%s, y=%s)", "void", msg.getArg0(), msg.getArg1(), msg.getArg2()); break;
+            case glUniform2iv:
+                str = String.format("%s (location=%s, count=%s, v=%s)", "void", msg.getArg0(), msg.getArg1(), FormatInts(2 * msg.getArg1(), msg.getData().asReadOnlyByteBuffer())); break;
+            case glUniform3f:
+                str = String.format("%s (location=%s, x=%s, y=%s, z=%s)", "void", msg.getArg0(), Float.intBitsToFloat(msg.getArg1()), Float.intBitsToFloat(msg.getArg2()), Float.intBitsToFloat(msg.getArg3())); break;
+            case glUniform3fv:
+                str = String.format("%s (location=%s, count=%s, v=%s)", "void", msg.getArg0(), msg.getArg1(), FormatFloats(3 * msg.getArg1(), msg.getData().asReadOnlyByteBuffer())); break;
+            case glUniform3i:
+                str = String.format("%s (location=%s, x=%s, y=%s, z=%s)", "void", msg.getArg0(), msg.getArg1(), msg.getArg2(), msg.getArg3()); break;
+            case glUniform3iv:
+                str = String.format("%s (location=%s, count=%s, v=%s)", "void", msg.getArg0(), msg.getArg1(), FormatInts(3 * msg.getArg1(), msg.getData().asReadOnlyByteBuffer())); break;
+            case glUniform4f:
+                str = String.format("%s (location=%s, x=%s, y=%s, z=%s, w=%s)", "void", msg.getArg0(), Float.intBitsToFloat(msg.getArg1()), Float.intBitsToFloat(msg.getArg2()), Float.intBitsToFloat(msg.getArg3()), Float.intBitsToFloat(msg.getArg4())); break;
+            case glUniform4fv:
+                str = String.format("%s (location=%s, count=%s, v=%s)", "void", msg.getArg0(), msg.getArg1(), FormatFloats(4 * msg.getArg1(), msg.getData().asReadOnlyByteBuffer())); break;
+            case glUniform4i:
+                str = String.format("%s (location=%s, x=%s, y=%s, z=%s, w=%s)", "void", msg.getArg0(), msg.getArg1(), msg.getArg2(), msg.getArg3(), msg.getArg4()); break;
+            case glUniform4iv:
+                str = String.format("%s (location=%s, count=%s, v=%s)", "void", msg.getArg0(), msg.getArg1(), FormatInts(4 * msg.getArg1(), msg.getData().asReadOnlyByteBuffer())); break;
+            case glUniformMatrix2fv:
+                str = String.format("%s (location=%s, count=%s, transpose=%s, value=%s)", "void", msg.getArg0(), msg.getArg1(), msg.getArg2(), FormatMatrix(2, 4 * msg.getArg1(), msg.getData().asReadOnlyByteBuffer())); break;
+            case glUniformMatrix3fv:
+                str = String.format("%s (location=%s, count=%s, transpose=%s, value=%s)", "void", msg.getArg0(), msg.getArg1(), msg.getArg2(), FormatMatrix(3, 9 * msg.getArg1(), msg.getData().asReadOnlyByteBuffer())); break;
+            case glUniformMatrix4fv:
+                str = String.format("%s (location=%s, count=%s, transpose=%s, value=%s)", "void", msg.getArg0(), msg.getArg1(), msg.getArg2(), FormatMatrix(4, 16 * msg.getArg1(), msg.getData().asReadOnlyByteBuffer())); break;
+            case glUseProgram:
+                str = String.format("%s (program=%s)", "void", msg.getArg0()); break;
+            case glValidateProgram:
+                str = String.format("%s (program=%s)", "void", msg.getArg0()); break;
+            case glVertexAttrib1f:
+                str = String.format("%s (indx=%s, x=%s)", "void", msg.getArg0(), Float.intBitsToFloat(msg.getArg1())); break;
+            case glVertexAttrib1fv:
+                str = String.format("%s (indx=%s, values=%s)", "void", msg.getArg0(), FormatFloats(1, msg.getData().asReadOnlyByteBuffer())); break;
+            case glVertexAttrib2f:
+                str = String.format("%s (indx=%s, x=%s, y=%s)", "void", msg.getArg0(), Float.intBitsToFloat(msg.getArg1()), Float.intBitsToFloat(msg.getArg2())); break;
+            case glVertexAttrib2fv:
+                str = String.format("%s (indx=%s, values=%s)", "void", msg.getArg0(), FormatFloats(2, msg.getData().asReadOnlyByteBuffer())); break;
+            case glVertexAttrib3f:
+                str = String.format("%s (indx=%s, x=%s, y=%s, z=%s)", "void", msg.getArg0(), Float.intBitsToFloat(msg.getArg1()), Float.intBitsToFloat(msg.getArg2()), Float.intBitsToFloat(msg.getArg3())); break;
+            case glVertexAttrib3fv:
+                str = String.format("%s (indx=%s, values=%s)", "void", msg.getArg0(), FormatFloats(3, msg.getData().asReadOnlyByteBuffer())); break;
+            case glVertexAttrib4f:
+                str = String.format("%s (indx=%s, x=%s, y=%s, z=%s, w=%s)", "void", msg.getArg0(), Float.intBitsToFloat(msg.getArg1()), Float.intBitsToFloat(msg.getArg2()), Float.intBitsToFloat(msg.getArg3()), Float.intBitsToFloat(msg.getArg4())); break;
+            case glVertexAttrib4fv:
+                str = String.format("%s (indx=%s, values=%s)", "void", msg.getArg0(), FormatFloats(4, msg.getData().asReadOnlyByteBuffer())); break;
+            case glVertexAttribPointer:
+                // FIXME: this function uses pointers, debugger may send data in msg.data
+                str = String.format("%s (indx=%s, size=%s, type=%s, normalized=%s, stride=%s, ptr=%s)", "void", msg.getArg0(), msg.getArg1(), GLEnum.valueOf(msg.getArg2()), msg.getArg3(), msg.getArg4(), "0x" + Integer.toHexString(msg.getArg5())); break;
+            case glViewport:
+                str = String.format("%s (x=%s, y=%s, width=%s, height=%s)", "void", msg.getArg0(), msg.getArg1(), msg.getArg2(), msg.getArg3()); break;
+            default:
+                str = msg.toString();
+        }
+        return str;
+    }
+}
\ No newline at end of file
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/MessageProcessor.java b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageProcessor.java
new file mode 100644
index 0000000..0c4a005
--- /dev/null
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageProcessor.java
@@ -0,0 +1,148 @@
+/*
+ ** 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.google.protobuf.ByteString;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.PaletteData;
+
+import java.nio.ByteBuffer;
+
+public class MessageProcessor {
+    static void showError(final String message) {
+        // need to call SWT from UI thread
+        MessageDialog.openError(null, "MessageProcessor", message);
+    }
+
+    static byte[] RLEDecode(final byte[] data) {
+        byte dataSize = data[0];
+        int a = data[1] & 0xff, b = data[2] & 0xff, c = data[3] & 0xff, d = data[4] & 0xff;
+        int count = (d << 24) | (c << 16) | (b << 8) | a;
+        byte[] buffer = new byte[count * dataSize];
+        int write = 0;
+        int i = 5;
+        for (i = 5; i < data.length;) {
+            byte flag = data[i];
+            int repeat = (flag & 0x7f) + 1;
+            assert 0 < repeat && repeat < 129;
+            i++;
+            if (0x80 == (flag & 0x80)) {
+                for (int j = 0; j < repeat; j++)
+                    for (int k = 0; k < dataSize; k++)
+                        buffer[write++] = data[i + k];
+                i += dataSize;
+            } else // literal runs
+            {
+                for (int j = 0; j < repeat; j++)
+                    for (int k = 0; k < dataSize; k++)
+                        buffer[write++] = data[i++];
+            }
+        }
+        assert write == count * dataSize;
+        assert i == data.length;
+        return buffer;
+    }
+
+    public static ImageData ReceiveImage(int width, int height, int format,
+            int type, byte[] data) {
+        assert width > 0 && height > 0;
+        int bpp = 0;
+        int redMask = 0, blueMask = 0, greenMask = 0;
+        switch (GLEnum.valueOf(type)) {
+            case GL_UNSIGNED_SHORT_5_6_5:
+            case GL_UNSIGNED_SHORT_4_4_4_4:
+            case GL_UNSIGNED_SHORT_5_5_5_1:
+                format = type;
+                break;
+            case GL_UNSIGNED_BYTE:
+                break;
+            default:
+                showError("unsupported texture type " + type);
+        }
+
+        switch (GLEnum.valueOf(format)) {
+            case GL_ALPHA:
+            case GL_LUMINANCE:
+                redMask = blueMask = greenMask = 0xff;
+                bpp = 8;
+                break;
+            case GL_LUMINANCE_ALPHA:
+                blueMask = 0xff;
+                redMask = 0xff00;
+                bpp = 16;
+                break;
+            case GL_RGB:
+                blueMask = 0xff;
+                greenMask = 0xff00;
+                redMask = 0xff0000;
+                bpp = 24;
+                break;
+            case GL_RGBA:
+                blueMask = 0xff00;
+                greenMask = 0xff0000;
+                redMask = 0xff000000;
+                bpp = 32;
+                break;
+            case GL_UNSIGNED_SHORT_5_6_5:
+                blueMask = ((1 << 5) - 1) << 0;
+                greenMask = ((1 << 6) - 1) << 5;
+                redMask = ((1 << 5) - 1) << 11;
+                bpp = 16;
+                break;
+            case GL_UNSIGNED_SHORT_4_4_4_4:
+                blueMask = ((1 << 4) - 1) << 4;
+                greenMask = ((1 << 4) - 1) << 8;
+                redMask = ((1 << 4) - 1) << 12;
+                bpp = 16;
+                break;
+            case GL_UNSIGNED_SHORT_5_5_5_1:
+                blueMask = ((1 << 5) - 1) << 1;
+                greenMask = ((1 << 5) - 1) << 6;
+                redMask = ((1 << 5) - 1) << 11;
+                bpp = 16;
+                break;
+            default:
+                showError("unsupported texture format: " + format);
+                return null;
+        }
+        // data = RLEDecode(data);
+        PaletteData palette = new PaletteData(redMask, greenMask, blueMask);
+        return new ImageData(width, height, bpp, palette, 1, data);
+    }
+
+    static public float[] ReceiveData(int target, final ByteString data) {
+        ByteBuffer buffer = data.asReadOnlyByteBuffer();
+        GLEnum type = GLEnum.valueOf(target);
+        if (type == GLEnum.GL_ARRAY_BUFFER) {
+            float[] elements = new float[buffer.remaining() / 4];
+            buffer.asFloatBuffer().get(elements);
+            return elements;
+        } else if (type == GLEnum.GL_ELEMENT_ARRAY_BUFFER) {
+            // usually unsigned short
+            float[] elements = new float[buffer.remaining() / 2];
+            for (int i = 0; i < elements.length; i++) {
+                int bits = Short.reverseBytes(buffer.getShort()) & 0xffff;
+                elements[i] = bits;
+            }
+            return elements;
+        } else
+            return null;
+
+    }
+}
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/MessageQueue.java b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageQueue.java
new file mode 100644
index 0000000..9f91d40
--- /dev/null
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageQueue.java
@@ -0,0 +1,263 @@
+/*
+ ** 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.Function;
+import com.android.glesv2debugger.DebuggerMessage.Message.Type;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class MessageQueue implements Runnable {
+
+    boolean running = false;
+    Thread thread = null;
+    ArrayList<DebuggerMessage.Message> complete = new ArrayList<DebuggerMessage.Message>();
+    ArrayList<DebuggerMessage.Message> commands = new ArrayList<DebuggerMessage.Message>();
+    SampleView sampleView;
+
+    public MessageQueue(SampleView sampleView) {
+        this.sampleView = sampleView;
+    }
+
+    public void Start() {
+        if (running)
+            return;
+        running = true;
+        thread = new Thread(this);
+        thread.start();
+    }
+
+    public void Stop() {
+        if (!running)
+            return;
+        running = false;
+    }
+
+    public boolean IsRunning() {
+        return running;
+    }
+
+    void SendCommands(final DataOutputStream dos, final int contextId) throws IOException {
+        synchronized (commands) {
+            for (int i = 0; i < commands.size(); i++) {
+                DebuggerMessage.Message command = commands.get(i);
+                if (command.getContextId() == contextId || contextId == 0) { // FIXME:
+                                                                             // proper
+                                                                             // context
+                                                                             // id
+                    SendMessage(dos, command);
+                    commands.remove(i);
+                    i--;
+                }
+            }
+        }
+        SendResponse(dos, contextId, DebuggerMessage.Message.Function.SKIP);
+    }
+
+    public void AddCommand(DebuggerMessage.Message command) {
+        synchronized (commands) {
+            commands.add(command);
+        }
+    }
+
+    @Override
+    public void run() {
+        Socket socket = new Socket();
+        DataInputStream dis = null;
+        DataOutputStream dos = null;
+        HashMap<Integer, ArrayList<DebuggerMessage.Message>> incoming = new HashMap<Integer, ArrayList<DebuggerMessage.Message>>();
+        try {
+            socket.connect(new java.net.InetSocketAddress("127.0.0.1", 5039));
+            dis = new DataInputStream(socket.getInputStream());
+            dos = new DataOutputStream(socket.getOutputStream());
+        } catch (Exception e) {
+            running = false;
+            Error(e);
+        }
+
+        try {
+            while (running) {
+                DebuggerMessage.Message msg = null;
+                if (incoming.size() > 0) { // find queued incoming
+                    for (ArrayList<DebuggerMessage.Message> messages : incoming
+                            .values())
+                        if (messages.size() > 0) {
+                            msg = messages.get(0);
+                            messages.remove(0);
+                            break;
+                        }
+                }
+                if (null == msg) { // get incoming from network
+                    msg = ReadMessage(dis);
+                    if (msg.getExpectResponse()) {
+                        if (msg.getType() == Type.BeforeCall)
+                            SendResponse(dos, msg.getContextId(),
+                                    DebuggerMessage.Message.Function.CONTINUE);
+                        else if (msg.getType() == Type.AfterCall)
+                            // after GL function call
+                            SendCommands(dos, 0); // FIXME: proper context id
+                        // SendResponse(dos, msg.getContextId(),
+                        // DebuggerMessage.Message.Function.SKIP);
+                        else if (msg.getType() == Type.Response)
+                            ;
+                        else
+                            assert false;
+                    }
+                }
+
+                int contextId = msg.getContextId();
+                if (!incoming.containsKey(contextId))
+                    incoming.put(contextId,
+                            new ArrayList<DebuggerMessage.Message>());
+
+                // FIXME: the expected sequence will change for interactive mode
+                while (msg.getType() == Type.BeforeCall) {
+                    DebuggerMessage.Message next = null;
+                    // get existing message part for this context
+                    ArrayList<DebuggerMessage.Message> messages = incoming
+                            .get(contextId);
+                    if (messages.size() > 0) {
+                        next = messages.get(0);
+                        messages.remove(0);
+                    }
+                    if (null == next) { // read new part for message
+                        next = ReadMessage(dis);
+
+                        if (next.getExpectResponse()) {
+                            if (next.getType() == Type.BeforeCall)
+                                SendResponse(
+                                        dos,
+                                        next.getContextId(),
+                                        DebuggerMessage.Message.Function.CONTINUE);
+                            else if (next.getType() == Type.AfterCall)
+                                SendCommands(dos, 0); // FIXME: proper context id
+                            else if (msg.getType() == Type.Response)
+                                ;
+                            else
+                                assert false;
+                        }
+
+                        if (next.getContextId() != contextId) {
+                            // message part not for this context
+                            if (!incoming.containsKey(next.getContextId()))
+                                incoming.put(
+                                        next.getContextId(),
+                                        new ArrayList<DebuggerMessage.Message>());
+                            incoming.get(next.getContextId()).add(next);
+                            continue;
+                        }
+                    }
+
+                    DebuggerMessage.Message.Builder builder = msg.toBuilder();
+                    // builder.mergeFrom(next); seems to merge incorrectly
+                    if (next.hasRet())
+                        builder.setRet(next.getRet());
+                    if (next.hasTime())
+                        builder.setTime(next.getTime());
+                    if (next.hasData())
+                        builder.setData(next.getData());
+                    builder.setType(next.getType());
+                    msg = builder.build();
+                }
+
+                synchronized (complete) {
+                    complete.add(msg);
+                }
+            }
+            socket.close();
+        } catch (Exception e) {
+            Error(e);
+            running = false;
+        }
+    }
+
+    public DebuggerMessage.Message RemoveMessage(int contextId) {
+        synchronized (complete) {
+            if (complete.size() == 0)
+                return null;
+            if (0 == contextId) // get a message of any
+            {
+                DebuggerMessage.Message msg = complete.get(0);
+                complete.remove(0);
+                return msg;
+            }
+            for (int i = 0; i < complete.size(); i++) {
+                DebuggerMessage.Message msg = complete.get(i);
+                if (msg.getContextId() == contextId) {
+                    complete.remove(i);
+                    return msg;
+                }
+            }
+        }
+        return null;
+    }
+
+    DebuggerMessage.Message ReadMessage(final DataInputStream dis)
+            throws IOException {
+        int len = 0;
+        try {
+            len = dis.readInt();
+        } catch (EOFException e) {
+            Error(new Exception("EOF"));
+        }
+        byte[] buffer = new byte[len];
+        int readLen = 0;
+        while (readLen < len) {
+            int read = -1;
+            try {
+                read = dis.read(buffer, readLen, len - readLen);
+            } catch (EOFException e) {
+                Error(new Exception("EOF"));
+            }
+            if (read < 0) {
+                Error(new Exception("read length = " + read));
+                return null;
+            } else
+                readLen += read;
+        }
+        DebuggerMessage.Message msg = DebuggerMessage.Message.parseFrom(buffer);
+        return msg;
+    }
+
+    void SendMessage(final DataOutputStream dos, final DebuggerMessage.Message message)
+            throws IOException {
+        final byte[] data = message.toByteArray();
+        dos.writeInt(data.length);
+        dos.write(data);
+    }
+
+    void SendResponse(final DataOutputStream dos, final int contextId,
+            final DebuggerMessage.Message.Function function) throws IOException {
+        DebuggerMessage.Message.Builder builder = DebuggerMessage.Message
+                .newBuilder();
+        builder.setContextId(contextId);
+        builder.setFunction(function);
+        builder.setType(Type.Response);
+        builder.setExpectResponse(false);
+        SendMessage(dos, builder.build());
+    }
+
+    void Error(Exception e) {
+        sampleView.showError(e);
+    }
+}
diff --git a/tools/glesv2debugger/src/com/android/glesv2debugger/SampleView.java b/tools/glesv2debugger/src/com/android/glesv2debugger/SampleView.java
new file mode 100755
index 0000000..05fe51b
--- /dev/null
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/SampleView.java
@@ -0,0 +1,587 @@
+/*
+ ** 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.Function;
+import com.android.glesv2debugger.DebuggerMessage.Message.Prop;
+import com.android.glesv2debugger.DebuggerMessage.Message.Type;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableLayout;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.ScrollBar;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.ViewPart;
+
+import java.util.ArrayList;
+
+/**
+ * This sample class demonstrates how to plug-in a new workbench view. The view
+ * shows data obtained from the model. The sample creates a dummy model on the
+ * fly, but a real implementation would connect to the model available either in
+ * this or another plug-in (e.g. the workspace). The view is connected to the
+ * model using a content provider.
+ * <p>
+ * The view uses a label provider to define how model objects should be
+ * presented in the view. Each view can present the same model objects using
+ * different labels and icons, if needed. Alternatively, a single label provider
+ * can be shared between views in order to ensure that objects of the same type
+ * are presented in the same way everywhere.
+ * <p>
+ */
+
+public class SampleView extends ViewPart implements Runnable {
+
+    boolean running = false;
+    Thread thread;
+    MessageQueue messageQueue;
+    ViewContentProvider viewContentProvider;
+    /**
+     * The ID of the view as specified by the extension.
+     */
+    public static final String ID = "glesv2debuggerclient.views.SampleView";
+
+    TableViewer viewer;
+    org.eclipse.swt.widgets.Canvas canvas;
+    Action actionConnect; // connect / disconnect
+    Action doubleClickAction;
+    Action actionAutoScroll;
+    Action actionFilter;
+    Action actionCapture;
+
+    Point origin = new Point(0, 0); // for smooth scrolling canvas
+    String[] filters = null;
+
+    /*
+     * The content provider class is responsible for providing objects to the
+     * view. It can wrap existing objects in adapters or simply return objects
+     * as-is. These objects may be sensitive to the current input of the view,
+     * or ignore it and always show the same content (like Task List, for
+     * example).
+     */
+
+    class ViewContentProvider implements IStructuredContentProvider {
+        ArrayList<com.android.glesv2debugger.MessageData> entries = new ArrayList<com.android.glesv2debugger.MessageData>();
+
+        public void add(final ArrayList<MessageData> msgs) {
+            entries.addAll(msgs);
+            viewer.getTable().getDisplay().syncExec(new Runnable() {
+                @Override
+                public void run() {
+                    viewer.add(msgs.toArray());
+                    org.eclipse.swt.widgets.ScrollBar bar = viewer
+                            .getTable().getVerticalBar();
+                    if (null != bar && actionAutoScroll.isChecked()) {
+                        bar.setSelection(bar.getMaximum());
+                        viewer.getTable().setSelection(
+                                entries.size() - 1);
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void inputChanged(Viewer v, Object oldInput, Object newInput) {
+            // showMessage("ViewContentProvider::inputChanged");
+        }
+
+        @Override
+        public void dispose() {
+        }
+
+        @Override
+        public Object[] getElements(Object parent) {
+            return entries.toArray();
+        }
+    }
+
+    class ViewLabelProvider extends LabelProvider implements
+            ITableLabelProvider {
+        @Override
+        public String getColumnText(Object obj, int index) {
+            com.android.glesv2debugger.MessageData msgData = (com.android.glesv2debugger.MessageData) obj;
+            if (null == msgData)
+                return getText(obj);
+            if (index >= msgData.columns.length)
+                return null;
+            return msgData.columns[index];
+        }
+
+        @Override
+        public Image getColumnImage(Object obj, int index) {
+            if (index > 0)
+                return null;
+            com.android.glesv2debugger.MessageData msgData = (com.android.glesv2debugger.MessageData) obj;
+            if (null == msgData)
+                return getImage(obj);
+            if (null == msgData.image)
+                return getImage(obj);
+            return msgData.image;
+        }
+
+        @Override
+        public Image getImage(Object obj) {
+            return PlatformUI.getWorkbench().getSharedImages()
+                    .getImage(ISharedImages.IMG_OBJ_ELEMENT);
+        }
+    }
+
+    class NameSorter extends ViewerSorter {
+    }
+
+    class Filter extends ViewerFilter {
+        @Override
+        public boolean select(Viewer viewer, Object parentElement,
+                Object element) {
+            com.android.glesv2debugger.MessageData msgData = (com.android.glesv2debugger.MessageData) element;
+            if (null == filters)
+                return true;
+            for (int i = 0; i < filters.length; i++)
+                if (msgData.columns[0].contains(filters[i]))
+                    return true;
+            return false;
+        }
+    }
+
+    /**
+     * The constructor.
+     */
+    public SampleView() {
+        messageQueue = new MessageQueue(this);
+    }
+
+    public void CreateTable(Composite parent) {
+        Table table = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI
+                | SWT.FULL_SELECTION);
+        TableLayout layout = new TableLayout();
+        table.setLayout(layout);
+        table.setLinesVisible(true);
+        table.setHeaderVisible(true);
+
+        String[] headings = {
+                "Name", "Elapsed (ms)", "Context", "Detail"
+        };
+        int[] weights = {
+                35, 16, 16, 60
+        };
+        int[] widths = {
+                120, 90, 90, 100
+        };
+        for (int i = 0; i < headings.length; i++) {
+            layout.addColumnData(new ColumnWeightData(weights[i], widths[i],
+                    true));
+            TableColumn nameCol = new TableColumn(table, SWT.NONE, i);
+            nameCol.setText(headings[i]);
+        }
+
+        viewer = new TableViewer(table);
+        viewContentProvider = new ViewContentProvider();
+        viewer.setContentProvider(viewContentProvider);
+        viewer.setLabelProvider(new ViewLabelProvider());
+        // viewer.setSorter(new NameSorter());
+        viewer.setInput(getViewSite());
+        viewer.setFilters(new ViewerFilter[] {
+                new Filter()
+        });
+    }
+
+    /**
+     * This is a callback that will allow us to create the viewer and initialize
+     * it.
+     */
+    @Override
+    public void createPartControl(Composite parent) {
+        CreateTable(parent);
+
+        // Create the help context id for the viewer's control
+        PlatformUI.getWorkbench().getHelpSystem()
+                .setHelp(viewer.getControl(), "GLESv2DebuggerClient.viewer");
+        makeActions();
+        hookContextMenu();
+        hookDoubleClickAction();
+        hookSelectionChanged();
+        contributeToActionBars();
+
+        canvas = new Canvas(parent, SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE
+                | SWT.V_SCROLL | SWT.H_SCROLL);
+        final ScrollBar hBar = canvas.getHorizontalBar();
+        hBar.addListener(SWT.Selection, new Listener() {
+            @Override
+            public void handleEvent(Event e) {
+                if (null == canvas.getBackgroundImage())
+                    return;
+                Image image = canvas.getBackgroundImage();
+                int hSelection = hBar.getSelection();
+                int destX = -hSelection - origin.x;
+                Rectangle rect = image.getBounds();
+                canvas.scroll(destX, 0, 0, 0, rect.width, rect.height, false);
+                origin.x = -hSelection;
+            }
+        });
+        final ScrollBar vBar = canvas.getVerticalBar();
+        vBar.addListener(SWT.Selection, new Listener() {
+            @Override
+            public void handleEvent(Event e) {
+                if (null == canvas.getBackgroundImage())
+                    return;
+                Image image = canvas.getBackgroundImage();
+                int vSelection = vBar.getSelection();
+                int destY = -vSelection - origin.y;
+                Rectangle rect = image.getBounds();
+                canvas.scroll(0, destY, 0, 0, rect.width, rect.height, false);
+                origin.y = -vSelection;
+            }
+        });
+        canvas.addListener(SWT.Resize, new Listener() {
+            @Override
+            public void handleEvent(Event e) {
+                if (null == canvas.getBackgroundImage())
+                    return;
+                Image image = canvas.getBackgroundImage();
+                Rectangle rect = image.getBounds();
+                Rectangle client = canvas.getClientArea();
+                hBar.setMaximum(rect.width);
+                vBar.setMaximum(rect.height);
+                hBar.setThumb(Math.min(rect.width, client.width));
+                vBar.setThumb(Math.min(rect.height, client.height));
+                int hPage = rect.width - client.width;
+                int vPage = rect.height - client.height;
+                int hSelection = hBar.getSelection();
+                int vSelection = vBar.getSelection();
+                if (hSelection >= hPage) {
+                    if (hPage <= 0)
+                        hSelection = 0;
+                    origin.x = -hSelection;
+                }
+                if (vSelection >= vPage) {
+                    if (vPage <= 0)
+                        vSelection = 0;
+                    origin.y = -vSelection;
+                }
+                canvas.redraw();
+            }
+        });
+        canvas.addListener(SWT.Paint, new Listener() {
+            @Override
+            public void handleEvent(Event e) {
+                if (null == canvas.getBackgroundImage())
+                    return;
+                Image image = canvas.getBackgroundImage();
+                GC gc = e.gc;
+                gc.drawImage(image, origin.x, origin.y);
+                Rectangle rect = image.getBounds();
+                Rectangle client = canvas.getClientArea();
+                int marginWidth = client.width - rect.width;
+                if (marginWidth > 0) {
+                    gc.fillRectangle(rect.width, 0, marginWidth, client.height);
+                }
+                int marginHeight = client.height - rect.height;
+                if (marginHeight > 0) {
+                    gc.fillRectangle(0, rect.height, client.width, marginHeight);
+                }
+            }
+        });
+    }
+
+    private void hookContextMenu() {
+        MenuManager menuMgr = new MenuManager("#PopupMenu");
+        menuMgr.setRemoveAllWhenShown(true);
+        menuMgr.addMenuListener(new IMenuListener() {
+            @Override
+            public void menuAboutToShow(IMenuManager manager) {
+                SampleView.this.fillContextMenu(manager);
+            }
+        });
+        Menu menu = menuMgr.createContextMenu(viewer.getControl());
+        viewer.getControl().setMenu(menu);
+        getSite().registerContextMenu(menuMgr, viewer);
+    }
+
+    private void contributeToActionBars() {
+        IActionBars bars = getViewSite().getActionBars();
+        fillLocalPullDown(bars.getMenuManager());
+        fillLocalToolBar(bars.getToolBarManager());
+    }
+
+    private void fillLocalPullDown(IMenuManager manager) {
+        // manager.add(actionConnect);
+        // manager.add(new Separator());
+        // manager.add(actionDisconnect);
+    }
+
+    private void fillContextMenu(IMenuManager manager) {
+        // manager.add(actionConnect);
+        // manager.add(actionDisconnect);
+        // Other plug-ins can contribute there actions here
+        manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+    }
+
+    private void fillLocalToolBar(final IToolBarManager manager) {
+        manager.add(actionConnect);
+        final Shell shell = this.getViewSite().getShell();
+        actionAutoScroll = new Action("Auto Scroll", Action.AS_CHECK_BOX) {
+            @Override
+            public void run() {
+            }
+        };
+        actionAutoScroll.setChecked(true);
+        manager.add(actionAutoScroll);
+
+        actionFilter = new Action("*", Action.AS_DROP_DOWN_MENU) {
+            @Override
+            public void run() {
+                org.eclipse.jface.dialogs.InputDialog dialog = new org.eclipse.jface.dialogs.InputDialog(
+                        shell, "Contains Filter",
+                        "case sensitive substring or *",
+                        actionFilter.getText(), null);
+                if (dialog.OK == dialog.open()) {
+                    actionFilter.setText(dialog.getValue());
+                    manager.update(true);
+                    filters = dialog.getValue().split("\\|");
+                    if (filters.length == 1 && filters[0].equals("*"))
+                        filters = null;
+                    viewer.refresh();
+                }
+
+            }
+        };
+        manager.add(actionFilter);
+
+        actionCapture = new Action("Capture", Action.AS_CHECK_BOX) {
+            @Override
+            public void run() {
+                DebuggerMessage.Message.Builder builder = DebuggerMessage.Message.newBuilder();
+                builder.setContextId(0); // FIXME: proper context id
+                builder.setType(Type.Response);
+                builder.setExpectResponse(false);
+                builder.setFunction(Function.SETPROP);
+                builder.setProp(Prop.Capture);
+                builder.setArg0(isChecked() ? 1 : 0);
+                messageQueue.AddCommand(builder.build());
+                manager.update(true);
+            }
+        };
+        actionCapture.setChecked(false);
+        manager.add(actionCapture);
+
+        manager.add(new Action("SYSTEM_TIME_THREAD", Action.AS_DROP_DOWN_MENU)
+        {
+            @Override
+            public void run()
+            {
+                final String[] timeModes = {
+                        "SYSTEM_TIME_REALTIME", "SYSTEM_TIME_MONOTONIC", "SYSTEM_TIME_PROCESS",
+                        "SYSTEM_TIME_THREAD"
+                };
+                int i = java.util.Arrays.asList(timeModes).indexOf(this.getText());
+                i = (i + 1) % timeModes.length;
+                DebuggerMessage.Message.Builder builder = DebuggerMessage.Message.newBuilder();
+                builder.setContextId(0); // FIXME: proper context id
+                builder.setType(Type.Response);
+                builder.setExpectResponse(false);
+                builder.setFunction(DebuggerMessage.Message.Function.SETPROP);
+                builder.setProp(Prop.TimeMode);
+                builder.setArg0(i);
+                messageQueue.AddCommand(builder.build());
+                this.setText(timeModes[i]);
+                manager.update(true);
+            }
+        });
+    }
+
+    private void ConnectDisconnect() {
+        if (!running) {
+            running = true;
+            messageQueue.Start();
+            thread = new Thread(this);
+            thread.start();
+            actionConnect.setText("Disconnect");
+            actionConnect.setToolTipText("Disconnect from debuggee");
+        } else {
+            running = false;
+            messageQueue.Stop();
+            actionConnect.setText("Connect");
+            actionConnect.setToolTipText("Connect to debuggee");
+        }
+        this.getSite().getShell().getDisplay().syncExec(new Runnable() {
+            @Override
+            public void run() {
+                getViewSite().getActionBars().getToolBarManager().update(true);
+            }
+        });
+    }
+
+    private void makeActions() {
+        actionConnect = new Action() {
+            @Override
+            public void run() {
+                ConnectDisconnect();
+            }
+        };
+        actionConnect.setText("Connect");
+        actionConnect.setToolTipText("Connect to debuggee");
+        // action1.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages()
+        // .getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
+
+        doubleClickAction = new Action() {
+            @Override
+            public void run() {
+                IStructuredSelection selection = (IStructuredSelection) viewer
+                        .getSelection();
+                MessageData msgData = (MessageData) selection.getFirstElement();
+                if (null != msgData.shader)
+                    showMessage(msgData.shader);
+                else if (null != msgData.data)
+                {
+                    String str = "";
+                    for (int i = 0; i < msgData.data.length; i++)
+                    {
+                        str += str.format("%.2f", msgData.data[i]);
+                        if (i < msgData.data.length - 1)
+                            str += ", ";
+                    }
+                    showMessage(str);
+                }
+                else
+                    showMessage(msgData.columns[3].toString());
+            }
+        };
+    }
+
+    private void hookDoubleClickAction() {
+        viewer.addDoubleClickListener(new IDoubleClickListener() {
+            @Override
+            public void doubleClick(DoubleClickEvent event) {
+                doubleClickAction.run();
+            }
+        });
+    }
+
+    private void hookSelectionChanged() {
+        viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+            @Override
+            public void selectionChanged(SelectionChangedEvent event) {
+                StructuredSelection selection = (StructuredSelection) event
+                        .getSelection();
+                if (null == selection)
+                    return;
+                if (1 != selection.size())
+                    return;
+                MessageData msgData = (MessageData) selection.getFirstElement();
+                if (null == msgData)
+                    return;
+                if (null != msgData.image)
+                    canvas.setBackgroundImage(msgData.image);
+            }
+
+        });
+    }
+
+    private void showMessage(final String message) {
+        viewer.getControl().getDisplay().syncExec(new Runnable() {
+            @Override
+            public void run() {
+                MessageDialog.openInformation(viewer.getControl().getShell(),
+                        "GL ES 2.0 Debugger Client", message);
+            }
+        });
+
+    }
+
+    public void showError(final Exception e) {
+        viewer.getControl().getDisplay().syncExec(new Runnable() {
+            @Override
+            public void run() {
+                MessageDialog.openError(viewer.getControl().getShell(),
+                        "GL ES 2.0 Debugger Client", e.getMessage());
+            }
+        });
+
+    }
+
+    /**
+     * Passing the focus request to the viewer's control.
+     */
+    @Override
+    public void setFocus() {
+        viewer.getControl().setFocus();
+    }
+
+    @Override
+    public void run() {
+        boolean refresh = false;
+        ArrayList<MessageData> msgs = new ArrayList<MessageData>();
+        while (running) {
+            if (!messageQueue.IsRunning())
+                break;
+
+            DebuggerMessage.Message msg = messageQueue.RemoveMessage(0);
+            if (msgs.size() > 20) {
+                viewContentProvider.add(msgs);
+                msgs.clear();
+            }
+            if (null == msg) {
+                try {
+                    Thread.sleep(1);
+                    continue;
+                } catch (InterruptedException e) {
+                    showError(e);
+                }
+            }
+            final MessageData msgData = new MessageData(this.getViewSite()
+                    .getShell().getDisplay(), msg);
+            msgs.add(msgData);
+        }
+        if (running)
+            ConnectDisconnect(); // error occurred, disconnect
+    }
+}