am f19518fc: am 9775ffe5: Merge "Update SDK files to API 12/Android 3.1" into honeycomb-mr1

* commit 'f19518fcb1ef26db56094cfaaf9d8082ad30f316':
  Update SDK files to API 12/Android 3.1
diff --git a/build/tools/mk_sdk_repo_xml.sh b/build/tools/mk_sdk_repo_xml.sh
index f7bbec1..56f426b 100755
--- a/build/tools/mk_sdk_repo_xml.sh
+++ b/build/tools/mk_sdk_repo_xml.sh
@@ -45,7 +45,7 @@
 shift
 
 # Get XML:NS for SDK from the schema
-XMLNS=$(sed -n '/xmlns:.*schemas.android.com\/sdk\/android\//s/.*"\(.*\)".*/\1/p' "$SCHEMA")
+XMLNS=$(sed -n '/xmlns:sdk="/s/.*"\(.*\)".*/\1/p' "$SCHEMA")
 [[ -z "$XMLNS" ]] && error "Failed to find xmlns:sdk in $SCHEMA."
 echo "## Using xmlns:sdk=$XMLNS"
 
diff --git a/ndk/platforms/android-9/samples/native-activity/Android.mk b/ndk/platforms/android-9/samples/native-activity/Android.mk
index ea961ca..73b3d87 100644
--- a/ndk/platforms/android-9/samples/native-activity/Android.mk
+++ b/ndk/platforms/android-9/samples/native-activity/Android.mk
@@ -44,7 +44,7 @@
 
 LOCAL_SHARED_LIBRARIES := liblog libandroid libEGL libGLESv1_CM
 
-LOCAL_PRELINK_MODULE := false
+
 
 LOCAL_MODULE := libnative-activity
 
diff --git a/pdk/docs/compatibility/downloads.jd b/pdk/docs/compatibility/downloads.jd
index 27a2109..79ad81b 100644
--- a/pdk/docs/compatibility/downloads.jd
+++ b/pdk/docs/compatibility/downloads.jd
@@ -11,7 +11,7 @@
 </p>
 <ul>
   <li><a href="{@docRoot}compatibility/android-2.3.3-cdd.pdf">Android 2.3.3 Compatibility Definition Document (CDD)</a></li>
-  <li><a href="http://dl.google.com/dl/android/cts/android-cts-2.3_r1-x86.zip">Android 2.3 R1 Compatibility Test Suite (CTS)</a></li>
+  <li><a href="http://dl.google.com/dl/android/cts/android-cts-2.3_r2-x86.zip">Android 2.3 R2 Compatibility Test Suite (CTS)</a></li>
 </ul>
 
 <h2>Android 2.2</h2>
@@ -21,7 +21,7 @@
 </p>
 <ul>
   <li><a href="{@docRoot}compatibility/android-2.2-cdd.pdf">Android 2.2 Compatibility Definition Document (CDD)</a></li>
-  <li><a href="http://dl.google.com/dl/android/cts/android-cts-2.2_r4-x86.zip">Android 2.2 R4 Compatibility Test Suite (CTS)</a></li>
+  <li><a href="http://dl.google.com/dl/android/cts/android-cts-2.2_r5-x86.zip">Android 2.2 R5 Compatibility Test Suite (CTS)</a></li>
 </ul>
 
 <h2>Android 2.1</h2>
@@ -41,6 +41,7 @@
 in the 'donut' branch in the open-source tree.
 <ul>
   <li><a href="{@docRoot}compatibility/android-1.6-cdd.pdf">Android 1.6 Compatibility Definition Document (CDD)</a></li>
+  <li><a href="http://dl.google.com/dl/android/cts/android-cts-1.6_r1-x86.zip">Android 1.6 R1 Compatibility Test Suite (CTS)</a></li>
 </ul>
 
 <h2>Compatibility Test Suite Manual</h2>
diff --git a/pdk/docs/porting/bluetooth.jd b/pdk/docs/porting/bluetooth.jd
index c792bd2..03b2d94 100755
--- a/pdk/docs/porting/bluetooth.jd
+++ b/pdk/docs/porting/bluetooth.jd
@@ -17,12 +17,15 @@
 </div>
 </div>
 
-<p>Android's Bluetooth stack uses BlueZ for GAP, SDP, and RFCOMM profiles, and
-is a SIG-qualified Bluetooth stack. </p>
+<p>Android's Bluetooth stack uses BlueZ as the host stack.</p>
 
 <p>Bluez is GPL licensed, so the Android framework interacts with userspace bluez code through D-BUS IPC to avoid proprietary code.</p>
 
-<p>Headset and Handsfree (v1.5) profiles are implemented in the Android framework and are both tightly coupled with the Phone App. These profiles are also SIG qualified.</p>
+<p>The qualification notes mentioned below are example qualifications of the particular device in question. Each company has to re-qualify their product with Bluetooth SIG even if no changes are made to the Bluetooth stack.</p>
+
+<p>Headset and Handsfree (v1.5) profiles are implemented in the Android framework and are both tightly coupled with the Phone App. Profiles like OPP and PBAP are based on java obex. These profiles open a rfcomm socket connection into Bluez kernel bypassing the Bluez userspace stack.</p>
+
+<p> Profiles like A2DP, AVRCP, HID, PAN and other bluetooth functionality like pairing and scanning use the Bluez userspace stack.</p>
 
 <p>The diagram below offers a library-oriented view of the Bluetooth stack. Click <a href="bluetooth/bluetooth_process.html">Bluetooth Process Diagram</a> for a process-oriented view.</p>
 
@@ -79,7 +82,7 @@
 </pre>
 
 <p><strong>Deamon Logs</strong></p>
-<p>Deamon logs for <code>hcid</code> (<code>STDOUT</code>) and <code>hciattach</code> (<code>STDERR</code>) are sent to <code>/dev/null</code> by default. Edit <code>init.rc</code></span> and <code>init.PLATFORM.rc</code></span> to run these daemons under <code>logwrapper</code>, which redirects output to <code>logcat</code>.</p>
+<p>Deamon logs for <code>bluetoothd</code> (<code>STDOUT</code>) and <code>hciattach</code> (<code>STDERR</code>) are sent to <code>/dev/null</code> by default. Edit <code>init.rc</code></span> and <code>init.PLATFORM.rc</code></span> to run these daemons under <code>logwrapper</code>, which redirects output to <code>logcat</code>.</p>
 <p><strong>hciconfig -a and hcitool</strong></p>
 <p>If you compile your own system.img for Android, and <code>hciconfig -a</code> works but <code>hcitool</code> scan doesn't, try installing the firmware for the Bluetooth chipset. This firmware isn't yet available in the open source codebase, but you can <code>adb pull</code> and then <code>adb push</code>it from a stock T-Mobile G1 (located in <code>/etc/firmware/brf6300.bin</code>).<br />
   <a name="androidBluetoothTools"></a></p>
@@ -112,7 +115,7 @@
     </li>
   </ul>
 </ul>
-<h5>Qualifications</h5>
+<h5>Qualifications for HTC G1 product. Each company reusing this software version has to re-qualify with Bluetooth SIG</h5>
 <ul>
   <li>QDID B014524: Host stack (SDP, L2CAP, GAP, RFCOMM, SPP)</li>
   <li>QDID B014624: EPL for HTC Dream (HSP, HFP)</li>
@@ -154,7 +157,7 @@
     <li>play/pause/stop/prev/next</li>
   </ul>
 </ul>
-<h4>Qualifications</h4>
+<h5>Qualifications for HTC Sapphire product. Each company reusing this software version has to re-qualify with Bluetooth SIG</h5>
 <ul>
   <li>QDID B015261: Host stack (SDP, L2CAP, GAP, RFCOMM, SPP, AVCTP, AVRCP, GAVDP, AVDTP, A2DP)</li>
   <li>QDID B015262: EPL for HTC Sapphire (HSP, HFP)</li>
@@ -224,6 +227,22 @@
   <li>Improved compatibility with headsets and car kits. </li>
 </ul>
 
+<h4>Android 2.3  release (Gingerbread)</h4>
+<h4>Platform features</h4>
+<ul>
+  <li>Based on Bluez 4.69 with Linux Kernel 2.6.35</li>
+  <li>No new profiles added.</li>
+  <li>Improved compatibility with headsets and car kits. </li>
+</ul>
+
+<h4>Android 3.0 release (Honeycomb)</h4>
+<h4>Platform features</h4>
+<ul>
+  <li>Based on Bluez 4.69 with Linux Kernel 2.6.36</li>
+  <li>HID and PAN (NAP and PANU role) are the new profiles added.
+  <li>Improved compatibility with headsets and car kits. </li>
+</ul>
+
 <h5>&nbsp;</h5>
 <h4>Future releases</h4>
 <p>This section offers a rough guide of which features the team is developing for the next release. This feature list may change without notice. It isn't possible to post scheduling advice to the mailing lists.</p>
@@ -234,20 +253,3 @@
   <li>Bluetooth Low Energy </li>
 </ul>
 
-<p><strong>Development Notes</strong></p>
-<ul>
-  <li><strong>HID Support <br />
-  </strong>Cupcake features some early work&#151;Bluez has an HID plugin, <code>external/bluez/utils/input/Android.mk</code>, which gets compiled. <br />
-    <br />
-You can interact directly with this plugin using <code>dbus-send</code></span> and <code>dbus-monitor</code>. While not officially supported, you should be able to connect and use a HID keyboard and mouse using the Bluez HID plugin API. Next steps include plumbing the plugin API in the Android Java framework and offering better support for HID input methods (new keymaps and mouse support).<br />
-  <br />
-  </li>
-  <li>  <strong>Tethering - DUN and PAN Support</strong><br />
-    Cupcake features some early work&#151;Bluez has has DUN and PAN daemons which get compiled and <code>external/bluez/utils/dun/Android.mk
-  external/bluez/utils/pan/Android.mk
-BNEP</code> support is compiled into the kernel with cupcake. <br />
-<br />
-While not officially supported, you should be able to run <code>dund</code> or <code>pand</code> daemons and, using <code>pppd</code> or <code>iptables</code>, test tethering support. Next steps include plubming the DBUS APIs to these daemons up into the Android Java framework and adding code to setup the network paths via <code>pppd</code> and / or <code>iptables</code>.<br />
-  <br />
-  </li>
-</ul>
diff --git a/pdk/docs/porting/images/androidBluetooth.gif b/pdk/docs/porting/images/androidBluetooth.gif
index e62f5a8..1c1aa3f 100755
--- a/pdk/docs/porting/images/androidBluetooth.gif
+++ b/pdk/docs/porting/images/androidBluetooth.gif
Binary files differ
diff --git a/samples/BrowserPlugin/jni/Android.mk b/samples/BrowserPlugin/jni/Android.mk
index b153e37..f8cea4d 100644
--- a/samples/BrowserPlugin/jni/Android.mk
+++ b/samples/BrowserPlugin/jni/Android.mk
@@ -66,7 +66,7 @@
 	libskia
 
 LOCAL_CFLAGS += -fvisibility=hidden 
-LOCAL_PRELINK_MODULE:=false
+
 
 LOCAL_MODULE:= libsampleplugin
 
diff --git a/samples/SimpleJNI/jni/Android.mk b/samples/SimpleJNI/jni/Android.mk
index 528196b..a704fcf 100644
--- a/samples/SimpleJNI/jni/Android.mk
+++ b/samples/SimpleJNI/jni/Android.mk
@@ -44,11 +44,4 @@
 # No special compiler flags.
 LOCAL_CFLAGS +=
 
-# Don't prelink this library.  For more efficient code, you may want
-# to add this library to the prelink map and set this to true. However,
-# it's difficult to do this for applications that are not supplied as
-# part of a system image.
-
-LOCAL_PRELINK_MODULE := false
-
 include $(BUILD_SHARED_LIBRARY)
diff --git a/tools/emulator/system/gps/Android.mk b/tools/emulator/system/gps/Android.mk
index 41bdc64..41de596 100644
--- a/tools/emulator/system/gps/Android.mk
+++ b/tools/emulator/system/gps/Android.mk
@@ -23,10 +23,10 @@
 LOCAL_PATH := $(call my-dir)
 
 ifneq ($(TARGET_PRODUCT),sim)
-# HAL module implemenation, not prelinked and stored in
+# HAL module implemenation stored in
 # hw/<GPS_HARDWARE_MODULE_ID>.<ro.hardware>.so
 include $(CLEAR_VARS)
-LOCAL_PRELINK_MODULE := false
+
 LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
 LOCAL_CFLAGS += -DQEMU_HARDWARE
 LOCAL_SHARED_LIBRARIES := liblog libcutils libhardware
diff --git a/tools/emulator/system/sensors/Android.mk b/tools/emulator/system/sensors/Android.mk
index 9b0e83d..b6dcaf6 100644
--- a/tools/emulator/system/sensors/Android.mk
+++ b/tools/emulator/system/sensors/Android.mk
@@ -23,10 +23,10 @@
 LOCAL_PATH := $(call my-dir)
 
 ifneq ($(TARGET_PRODUCT),sim)
-# HAL module implemenation, not prelinked and stored in
+# HAL module implemenation stored in
 # hw/<SENSORS_HARDWARE_MODULE_ID>.<ro.hardware>.so
 include $(CLEAR_VARS)
-LOCAL_PRELINK_MODULE := false
+
 LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
 LOCAL_SHARED_LIBRARIES := liblog libcutils
 LOCAL_SRC_FILES := sensors_qemu.c
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
index 0000000..6083c0f
--- /dev/null
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/Activator.java
@@ -0,0 +1,83 @@
+/*

+ ** 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

+     * )

+     */

+    @Override

+    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

+     * )

+     */

+    @Override

+    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..ddc875a
--- /dev/null
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/DebuggerMessage.java
@@ -0,0 +1,1461 @@
+// 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),
+      ;
+      
+      
+      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;
+          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/GLServerVertex.java b/tools/glesv2debugger/src/com/android/glesv2debugger/GLServerVertex.java
new file mode 100644
index 0000000..0ff0347
--- /dev/null
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/GLServerVertex.java
@@ -0,0 +1,348 @@
+/*
+ ** Copyright 2011, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ **     http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+package com.android.glesv2debugger;
+
+import com.android.glesv2debugger.DebuggerMessage.Message;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+
+class GLBuffer {
+    GLEnum usage;
+    GLEnum target;
+    ByteBuffer data;
+}
+
+class GLAttribPointer {
+    int size; // number of values per vertex
+    GLEnum type; // data type
+    int stride; // bytes
+    int ptr; // pointer in debugger server or byte offset into buffer
+    GLBuffer buffer;
+    boolean normalized;
+    boolean enabled;
+}
+
+public class GLServerVertex {
+
+    HashMap<Integer, GLBuffer> buffers;
+    GLBuffer attribBuffer, indexBuffer; // current binding
+    GLAttribPointer attribPointers[];
+    float defaultAttribs[][];
+    int maxAttrib;
+
+    public GLServerVertex() {
+        buffers = new HashMap<Integer, GLBuffer>();
+        buffers.put(0, null);
+        attribPointers = new GLAttribPointer[16];
+        for (int i = 0; i < attribPointers.length; i++)
+            attribPointers[i] = new GLAttribPointer();
+        defaultAttribs = new float[16][4];
+        for (int i = 0; i < defaultAttribs.length; i++) {
+            defaultAttribs[i][0] = 0;
+            defaultAttribs[i][1] = 0;
+            defaultAttribs[i][2] = 0;
+            defaultAttribs[i][3] = 1;
+        }
+    }
+
+    // void API_ENTRY(glBindBuffer)(GLenum target, GLuint buffer)
+    public void glBindBuffer(Message msg) {
+        if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ARRAY_BUFFER) {
+            attribBuffer = buffers.get(msg.getArg1());
+            if (null != attribBuffer)
+                attribBuffer.target = GLEnum.GL_ARRAY_BUFFER;
+        } else if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ELEMENT_ARRAY_BUFFER) {
+            indexBuffer = buffers.get(msg.getArg1());
+            if (null != indexBuffer)
+                indexBuffer.target = GLEnum.GL_ELEMENT_ARRAY_BUFFER;
+        } else
+            assert false;
+    }
+
+    // void API_ENTRY(glBufferData)(GLenum target, GLsizeiptr size, const
+    // GLvoid:size:in data, GLenum usage)
+    public void glBufferData(Message msg) {
+        if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ARRAY_BUFFER) {
+            attribBuffer.usage = GLEnum.valueOf(msg.getArg3());
+            attribBuffer.data = msg.getData().asReadOnlyByteBuffer();
+        } else if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ELEMENT_ARRAY_BUFFER) {
+            indexBuffer.usage = GLEnum.valueOf(msg.getArg3());
+            indexBuffer.data = msg.getData().asReadOnlyByteBuffer();
+        } else
+            assert false;
+    }
+
+    // void API_ENTRY(glBufferSubData)(GLenum target, GLintptr offset,
+    // GLsizeiptr size, const GLvoid:size:in data)
+    public void glBufferSubData(Message msg) {
+        if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ARRAY_BUFFER) {
+            if (attribBuffer.data.isReadOnly()) {
+                ByteBuffer buffer = ByteBuffer.allocate(attribBuffer.data.capacity());
+                buffer.put(attribBuffer.data);
+                attribBuffer.data = buffer;
+            }
+            attribBuffer.data.position(msg.getArg1());
+            attribBuffer.data.put(msg.getData().asReadOnlyByteBuffer());
+        } else if (GLEnum.valueOf(msg.getArg0()) == GLEnum.GL_ELEMENT_ARRAY_BUFFER) {
+            if (indexBuffer.data.isReadOnly()) {
+                ByteBuffer buffer = ByteBuffer.allocate(indexBuffer.data.capacity());
+                buffer.put(indexBuffer.data);
+                indexBuffer.data = buffer;
+            }
+            indexBuffer.data.position(msg.getArg1());
+            indexBuffer.data.put(msg.getData().asReadOnlyByteBuffer());
+        } else
+            assert false;
+    }
+
+    // void glDeleteBuffers(GLsizei n, const GLuint* buffers)
+    public void glDeleteBuffers(Message msg) {
+        final int n = msg.getArg0();
+        final ByteBuffer names = msg.getData().asReadOnlyByteBuffer();
+        for (int i = 0; i < n; i++) {
+            int name = Integer.reverseBytes(names.getInt());
+            GLBuffer buffer = buffers.get(name);
+            for (int j = 0; j < attribPointers.length; j++)
+                if (attribPointers[j].buffer == buffer) {
+                    attribPointers[j].buffer = null;
+                    attribPointers[j].enabled = false;
+                }
+            if (attribBuffer == buffer)
+                attribBuffer = null;
+            if (indexBuffer == buffer)
+                indexBuffer = null;
+            buffers.remove(name);
+        }
+    }
+
+    // void glDisableVertexAttribArray(GLuint index)
+    public void glDisableVertexAttribArray(Message msg) {
+        attribPointers[msg.getArg0()].enabled = false;
+    }
+
+    float FetchConvert(final ByteBuffer src, final GLEnum type, final boolean normalized) {
+        if (GLEnum.GL_FLOAT == type)
+            return Float.intBitsToFloat(Integer.reverseBytes(src.getInt()));
+        else if (GLEnum.GL_UNSIGNED_INT == type)
+            if (normalized)
+                return (Integer.reverseBytes(src.getInt()) & 0xffffffffL) / (2e32f - 1);
+            else 
+                return Integer.reverseBytes(src.getInt()) & 0xffffffffL;
+        else if (GLEnum.GL_INT == type)
+            if (normalized)
+                return (Integer.reverseBytes(src.getInt()) * 2 + 1) / (2e32f - 1);
+            else 
+                return Integer.reverseBytes(src.getInt());
+        else if (GLEnum.GL_UNSIGNED_SHORT == type)
+            if (normalized)
+                return (Short.reverseBytes(src.getShort()) & 0xffff) / (2e16f - 1);
+            else 
+                return Short.reverseBytes(src.getShort()) & 0xffff;
+        else if (GLEnum.GL_SHORT == type)
+            if (normalized)
+                return (Short.reverseBytes(src.getShort()) * 2 + 1) / (2e16f - 1);
+            else 
+                return Short.reverseBytes(src.getShort());
+        else if (GLEnum.GL_UNSIGNED_BYTE == type)
+            if (normalized)
+                return (src.get() & 0xff) / (2e8f - 1);
+            else 
+                return src.get() & 0xff;
+        else if (GLEnum.GL_BYTE == type)
+            if (normalized)
+                return (src.get() * 2 + 1) / (2e8f - 1);
+            else 
+                return src.get();
+        else if (GLEnum.GL_FIXED == type)
+            if (normalized)
+                return (Integer.reverseBytes(src.getInt()) * 2 + 1) / (2e32f - 1);
+            else
+                return Integer.reverseBytes(src.getInt()) / (2e16f);
+        else
+            assert false;
+        return 0;
+    }
+
+    void Fetch(int index, final ByteBuffer nonVBO, final ByteBuffer dst) {
+        for (int i = 0; i < maxAttrib; i++) {
+            final GLAttribPointer attrib = attribPointers[i];
+            int size = 0;
+            if (attrib.enabled)
+                size = attrib.size;
+            if (null != attrib.buffer) {
+                final ByteBuffer src = attrib.buffer.data;
+                src.position(attrib.ptr + i * attrib.stride);
+                dst.putFloat(FetchConvert(src, attrib.type, attrib.normalized));
+            } else
+                for (int j = 0; j < size; j++)
+                    dst.putFloat(FetchConvert(nonVBO, attrib.type, attrib.normalized));
+            if (size < 1)
+                dst.putFloat(defaultAttribs[i][0]);
+            if (size < 2)
+                dst.putFloat(defaultAttribs[i][1]);
+            if (size < 3)
+                dst.putFloat(defaultAttribs[i][2]);
+            if (size < 4)
+                dst.putFloat(defaultAttribs[i][3]);
+        }
+    }
+
+    // void glDrawArrays(GLenum mode, GLint first, GLsizei count)
+    public Message glDrawArrays(Message msg) {
+        maxAttrib = msg.getArg7();
+        final int first = msg.getArg1(), count = msg.getArg2();
+        final ByteBuffer buffer = ByteBuffer.allocate(4 * 4 * maxAttrib * count);
+        ByteBuffer arrays = null;
+        if (msg.hasData()) // server sends user pointer attribs
+            arrays = msg.getData().asReadOnlyByteBuffer();
+        for (int i = first; i < first + count; i++)
+            Fetch(i, arrays, buffer);
+        assert null == arrays || arrays.remaining() == 0;
+        buffer.rewind();
+        return msg.toBuilder().setData(com.google.protobuf.ByteString.copyFrom(buffer))
+                .setArg8(GLEnum.GL_FLOAT.value).build();
+    }
+
+    // void glDrawElements(GLenum mode, GLsizei count, GLenum type, const
+    // GLvoid* indices)
+    public Message glDrawElements(Message msg) {
+        maxAttrib = msg.getArg7();
+        final int count = msg.getArg1();
+        final GLEnum type = GLEnum.valueOf(msg.getArg2());
+        final ByteBuffer buffer = ByteBuffer.allocate(4 * 4 * maxAttrib * count);
+        ByteBuffer arrays = null, index = null;
+        if (msg.hasData()) // server sends user pointer attribs
+            arrays = msg.getData().asReadOnlyByteBuffer();
+        if (null == indexBuffer)
+            index = arrays; // server also interleaves user pointer indices
+        else {
+            index = indexBuffer.data;
+            index.position(msg.getArg3());
+        }
+        if (GLEnum.GL_UNSIGNED_SHORT == type)
+            for (int i = 0; i < count; i++)
+                Fetch(Short.reverseBytes(index.getShort()) & 0xffff, arrays, buffer);
+        else if (GLEnum.GL_UNSIGNED_BYTE == type)
+            for (int i = 0; i < count; i++)
+                Fetch(index.get() & 0xff, arrays, buffer);
+        else
+            assert false;
+        assert null == arrays || arrays.remaining() == 0;
+        buffer.rewind();
+        return msg.toBuilder().setData(com.google.protobuf.ByteString.copyFrom(buffer))
+                .setArg8(GLEnum.GL_FLOAT.value).build();
+    }
+
+    // void glEnableVertexAttribArray(GLuint index)
+    public void glEnableVertexAttribArray(Message msg) {
+        attribPointers[msg.getArg0()].enabled = true;
+    }
+
+    // void API_ENTRY(glGenBuffers)(GLsizei n, GLuint:n:out buffers)
+    public void glGenBuffers(Message msg) {
+        final int n = msg.getArg0();
+        final ByteBuffer buffer = msg.getData().asReadOnlyByteBuffer();
+        for (int i = 0; i < n; i++) {
+            int name = Integer.reverseBytes(buffer.getInt());
+            if (!buffers.containsKey(name))
+                buffers.put(name, new GLBuffer());
+        }
+    }
+
+    // void glVertexAttribPointer(GLuint index, GLint size, GLenum type,
+    // GLboolean normalized, GLsizei stride, const GLvoid* ptr)
+    public void glVertexAttribPointer(Message msg) {
+        GLAttribPointer attrib = attribPointers[msg.getArg0()];
+        attrib.size = msg.getArg1();
+        attrib.type = GLEnum.valueOf(msg.getArg2());
+        attrib.normalized = msg.getArg3() != 0;
+        attrib.stride = msg.getArg4();
+        if (0 == attrib.stride)
+            attrib.stride = attrib.size * 4;
+        attrib.ptr = msg.getArg5();
+        attrib.buffer = attribBuffer;
+    }
+
+    // void glVertexAttrib1f(GLuint indx, GLfloat x)
+    public void glVertexAttrib1f(Message msg) {
+        glVertexAttrib4f(msg.getArg0(), Float.intBitsToFloat(Integer.reverseBytes(msg.getArg1())),
+                0, 0, 1);
+    }
+
+    // void glVertexAttrib1fv(GLuint indx, const GLfloat* values)
+    public void glVertexAttrib1fv(Message msg) {
+        final ByteBuffer values = msg.getData().asReadOnlyByteBuffer();
+        glVertexAttrib4f(msg.getArg0(),
+                Float.intBitsToFloat(Integer.reverseBytes(values.getInt())),
+                0, 0, 1);
+    }
+
+    // void glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
+    public void glVertexAttrib2f(Message msg) {
+        glVertexAttrib4f(msg.getArg0(), Float.intBitsToFloat(Integer.reverseBytes(msg.getArg1())),
+                Float.intBitsToFloat(Integer.reverseBytes(msg.getArg2())), 0, 1);
+    }
+
+    // void glVertexAttrib2fv(GLuint indx, const GLfloat* values)
+    public void glVertexAttrib2fv(Message msg) {
+        final ByteBuffer values = msg.getData().asReadOnlyByteBuffer();
+        glVertexAttrib4f(msg.getArg0(),
+                Float.intBitsToFloat(Integer.reverseBytes(values.getInt())),
+                Float.intBitsToFloat(Integer.reverseBytes(values.getInt())), 0, 1);
+    }
+
+    // void glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
+    public void glVertexAttrib3f(Message msg) {
+        glVertexAttrib4f(msg.getArg0(), Float.intBitsToFloat(Integer.reverseBytes(msg.getArg1())),
+                Float.intBitsToFloat(Integer.reverseBytes(msg.getArg2())),
+                Float.intBitsToFloat(Integer.reverseBytes(msg.getArg3())), 1);
+    }
+
+    // void glVertexAttrib3fv(GLuint indx, const GLfloat* values)
+    public void glVertexAttrib3fv(Message msg) {
+        final ByteBuffer values = msg.getData().asReadOnlyByteBuffer();
+        glVertexAttrib4f(msg.getArg0(),
+                Float.intBitsToFloat(Integer.reverseBytes(values.getInt())),
+                Float.intBitsToFloat(Integer.reverseBytes(values.getInt())),
+                Float.intBitsToFloat(Integer.reverseBytes(values.getInt())), 1);
+    }
+
+    public void glVertexAttrib4f(Message msg) {
+        glVertexAttrib4f(msg.getArg0(), Float.intBitsToFloat(Integer.reverseBytes(msg.getArg1())),
+                Float.intBitsToFloat(Integer.reverseBytes(msg.getArg2())),
+                Float.intBitsToFloat(Integer.reverseBytes(msg.getArg3())),
+                Float.intBitsToFloat(Integer.reverseBytes(msg.getArg4())));
+    }
+
+    void glVertexAttrib4f(int indx, float x, float y, float z, float w) {
+        defaultAttribs[indx][0] = x;
+        defaultAttribs[indx][1] = y;
+        defaultAttribs[indx][2] = z;
+        defaultAttribs[indx][3] = w;
+    }
+
+    // void glVertexAttrib4fv(GLuint indx, const GLfloat* values)
+    public void glVertexAttrib4fv(Message msg) {
+        final ByteBuffer values = msg.getData().asReadOnlyByteBuffer();
+        glVertexAttrib4f(msg.getArg0(),
+                Float.intBitsToFloat(Integer.reverseBytes(values.getInt())),
+                Float.intBitsToFloat(Integer.reverseBytes(values.getInt())),
+                Float.intBitsToFloat(Integer.reverseBytes(values.getInt())),
+                Float.intBitsToFloat(Integer.reverseBytes(values.getInt())));
+    }
+}
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..e622830
--- /dev/null
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageData.java
@@ -0,0 +1,103 @@
+/*
+ ** Copyright 2011, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ **     http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+package com.android.glesv2debugger;
+
+import com.android.glesv2debugger.DebuggerMessage.Message;
+
+import org.eclipse.swt.graphics.Device;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+
+public class MessageData {
+    public Message.Function function;
+    public Image image; // texture
+    public String shader; // shader source
+    public String[] columns;
+    public float[] data;
+    public int maxAttrib; // used for formatting data
+    public GLEnum dataType; // could be float, int; mainly for formatting use
+    
+    public MessageData(final Device device, final Message msg) {
+        image = null;
+        shader = null;
+        data = null;
+        StringBuilder builder = new StringBuilder();
+        function = msg.getFunction();
+        ImageData imageData = null;
+        if (function != 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 glDrawArrays: // msg was modified by GLServerVertex
+            case glDrawElements:
+                if (!msg.hasArg8() || !msg.hasData())
+                    break;
+                dataType = GLEnum.valueOf(msg.getArg8());
+                maxAttrib = msg.getArg7();
+                data = MessageProcessor.ReceiveData(dataType, 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 glCopyTexImage2D:
+                imageData = MessageProcessor.ReceiveImage(msg.getArg5(), msg.getArg6(), GLEnum.GL_RGBA.value, GLEnum.GL_UNSIGNED_BYTE.value, msg.getData().toByteArray());
+                image = new Image(device, imageData);
+                break;
+            case glCopyTexSubImage2D:
+                imageData = MessageProcessor.ReceiveImage(msg.getArg6(), msg.getArg7(), GLEnum.GL_RGBA.value, GLEnum.GL_UNSIGNED_BYTE.value, msg.getData().toByteArray());
+                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..da6a9b8
--- /dev/null
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageProcessor.java
@@ -0,0 +1,150 @@
+/*
+ ** 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(final GLEnum type, final ByteString data) {
+        final ByteBuffer buffer = data.asReadOnlyByteBuffer();
+        if (type == GLEnum.GL_FLOAT) {
+            float[] elements = new float[buffer.remaining() / 4];
+            for (int i = 0; i < elements.length; i++)
+                elements[i] = buffer.getFloat();
+            return elements;
+        } else if (type == GLEnum.GL_UNSIGNED_SHORT) {
+            float[] elements = new float[buffer.remaining() / 2];
+            for (int i = 0; i < elements.length; i++)
+                elements[i] = buffer.getShort() & 0xffff;
+            return elements;
+        } else if (type == GLEnum.GL_UNSIGNED_BYTE) {
+            float[] elements = new float[buffer.remaining() / 4];
+            for (int i = 0; i < elements.length; i++)
+                elements[i] = buffer.get() & 0xff;
+            return elements;
+        } else
+            assert false;
+        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..454fbf1
--- /dev/null
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/MessageQueue.java
@@ -0,0 +1,328 @@
+/*
+ ** Copyright 2011, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ **     http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+package com.android.glesv2debugger;
+
+import com.android.glesv2debugger.DebuggerMessage.Message;
+import com.android.glesv2debugger.DebuggerMessage.Message.Function;
+import com.android.glesv2debugger.DebuggerMessage.Message.Type;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class MessageQueue implements Runnable {
+
+    boolean running = false;
+    Thread thread = null;
+    ArrayList<Message> complete = new ArrayList<Message>();
+    ArrayList<Message> commands = new ArrayList<Message>();
+    SampleView sampleView;
+
+    HashMap<Integer, GLServerVertex> serversVertex = new HashMap<Integer, GLServerVertex>();
+
+    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;
+    }
+
+    boolean SendCommands(final DataOutputStream dos, final int contextId) throws IOException {
+        boolean sent = false;
+        synchronized (commands) {
+            for (int i = 0; i < commands.size(); i++) {
+                Message command = commands.get(i);
+                // FIXME: proper context id
+                if (command.getContextId() == contextId || contextId == 0) {
+                    SendMessage(dos, command);
+                    commands.remove(i);
+                    i--;
+                    sent = true;
+                }
+            }
+        }
+        return sent;
+    }
+
+    public void AddCommand(Message command) {
+        synchronized (commands) {
+            commands.add(command);
+        }
+    }
+
+    @Override
+    public void run() {
+        Socket socket = new Socket();
+        DataInputStream dis = null;
+        DataOutputStream dos = null;
+        HashMap<Integer, ArrayList<Message>> incoming = new HashMap<Integer, ArrayList<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) {
+            Message msg = null;
+            if (incoming.size() > 0) { // find queued incoming
+                for (ArrayList<Message> messages : incoming
+                            .values())
+                    if (messages.size() > 0) {
+                        msg = messages.get(0);
+                        messages.remove(0);
+                        break;
+                    }
+            }
+            if (null == msg) { // get incoming from network
+                try {
+                    msg = ReadMessage(dis);
+                    SendResponse(dos, msg);
+                } catch (IOException e) {
+                    Error(e);
+                    running = false;
+                    break;
+                }
+            }
+
+            int contextId = msg.getContextId();
+            if (!incoming.containsKey(contextId))
+                incoming.put(contextId,
+                            new ArrayList<Message>());
+
+            // FIXME: the expected sequence will change for interactive mode
+            while (msg.getType() == Type.BeforeCall) {
+                Message next = null;
+                // get existing message part for this context
+                ArrayList<Message> messages = incoming
+                            .get(contextId);
+                if (messages.size() > 0) {
+                    next = messages.get(0);
+                    messages.remove(0);
+                }
+                if (null == next) { // read new part for message
+                    try {
+                        next = ReadMessage(dis);
+                        SendResponse(dos, next);
+                    } catch (IOException e) {
+                        Error(e);
+                        running = false;
+                        break;
+                    }
+
+                    if (next.getContextId() != contextId) {
+                        // message part not for this context
+                        if (!incoming.containsKey(next.getContextId()))
+                            incoming.put(
+                                        next.getContextId(),
+                                        new ArrayList<Message>());
+                        incoming.get(next.getContextId()).add(next);
+                        continue;
+                    }
+                }
+
+                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();
+            }
+
+            GLServerVertex serverVertex = serversVertex.get(msg.getContextId());
+            if (null == serverVertex) {
+                serverVertex = new GLServerVertex();
+                serversVertex.put(msg.getContextId(), serverVertex);
+            }
+
+            // forward message to synchronize state
+            switch (msg.getFunction()) {
+                case glBindBuffer:
+                    serverVertex.glBindBuffer(msg);
+                    break;
+                case glBufferData:
+                    serverVertex.glBufferData(msg);
+                    break;
+                case glBufferSubData:
+                    serverVertex.glBufferSubData(msg);
+                    break;
+                case glDeleteBuffers:
+                    serverVertex.glDeleteBuffers(msg);
+                    break;
+                case glDrawArrays:
+                    if (msg.hasArg7())
+                        msg = serverVertex.glDrawArrays(msg);
+                    break;
+                case glDrawElements:
+                    if (msg.hasArg7())
+                        msg = serverVertex.glDrawElements(msg);
+                    break;
+                case glDisableVertexAttribArray:
+                    serverVertex.glDisableVertexAttribArray(msg);
+                    break;
+                case glEnableVertexAttribArray:
+                    serverVertex.glEnableVertexAttribArray(msg);
+                    break;
+                case glGenBuffers:
+                    serverVertex.glGenBuffers(msg);
+                    break;
+                case glVertexAttribPointer:
+                    serverVertex.glVertexAttribPointer(msg);
+                    break;
+                case glVertexAttrib1f:
+                    serverVertex.glVertexAttrib1f(msg);
+                    break;
+                case glVertexAttrib1fv:
+                    serverVertex.glVertexAttrib1fv(msg);
+                    break;
+                case glVertexAttrib2f:
+                    serverVertex.glVertexAttrib2f(msg);
+                    break;
+                case glVertexAttrib2fv:
+                    serverVertex.glVertexAttrib2fv(msg);
+                    break;
+                case glVertexAttrib3f:
+                    serverVertex.glVertexAttrib3f(msg);
+                    break;
+                case glVertexAttrib3fv:
+                    serverVertex.glVertexAttrib3fv(msg);
+                    break;
+                case glVertexAttrib4f:
+                    serverVertex.glVertexAttrib4f(msg);
+                    break;
+                case glVertexAttrib4fv:
+                    serverVertex.glVertexAttrib4fv(msg);
+                    break;
+            }
+
+            synchronized (complete) {
+                complete.add(msg);
+            }
+        }
+
+        try {
+            socket.close();
+        } catch (IOException e) {
+            Error(e);
+            running = false;
+        }
+        // } catch (Exception e) {
+        // Error(e);
+        // running = false;
+        // }
+    }
+
+    public Message RemoveMessage(int contextId) {
+        synchronized (complete) {
+            if (complete.size() == 0)
+                return null;
+            if (0 == contextId) // get a message for any context
+            {
+                Message msg = complete.get(0);
+                complete.remove(0);
+                return msg;
+            }
+            for (int i = 0; i < complete.size(); i++) {
+                Message msg = complete.get(i);
+                if (msg.getContextId() == contextId) {
+                    complete.remove(i);
+                    return msg;
+                }
+            }
+        }
+        return null;
+    }
+
+    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;
+        }
+        Message msg = Message.parseFrom(buffer);
+        return msg;
+    }
+
+    void SendMessage(final DataOutputStream dos, final Message message)
+            throws IOException {
+        final byte[] data = message.toByteArray();
+        dos.writeInt(data.length);
+        dos.write(data);
+    }
+
+    void SendResponse(final DataOutputStream dos, final Message msg) throws IOException {
+        Message.Builder builder = Message.newBuilder();
+        builder.setContextId(msg.getContextId());
+        if (msg.getType() == Type.BeforeCall)
+            builder.setFunction(Function.CONTINUE);
+        else if (msg.getType() == Type.AfterCall)
+            builder.setFunction(Function.SKIP);
+        builder.setType(Type.Response);
+        builder.setExpectResponse(false);
+        // FIXME: consider using proper context id
+        if (SendCommands(dos, 0) || msg.getExpectResponse())
+            if (builder.hasFunction())
+                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 100644
index 0000000..6905565
--- /dev/null
+++ b/tools/glesv2debugger/src/com/android/glesv2debugger/SampleView.java
@@ -0,0 +1,700 @@
+/*
+ ** Copyright 2011, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ **     http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+package com.android.glesv2debugger;
+
+import com.android.glesv2debugger.DebuggerMessage.Message;
+import com.android.glesv2debugger.DebuggerMessage.Message.Function;
+import com.android.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.jface.window.Window;
+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.layout.FillLayout;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+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.swt.widgets.Text;
+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.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+
+/**
+ * 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;
+    Text text;
+    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<MessageData> entries = new ArrayList<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) {
+        }
+
+        @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) {
+            MessageData msgData = (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;
+            MessageData msgData = (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) {
+            MessageData msgData = (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();
+
+        class LayoutComposite extends Composite {
+            public LayoutComposite(Composite parent, int style) {
+                super(parent, style);
+            }
+
+            @Override
+            public Control[] getChildren() {
+                Control[] children = super.getChildren();
+                ArrayList<Control> controls = new ArrayList<Control>();
+                for (int i = 0; i < children.length; i++)
+                    if (children[i].isVisible())
+                        controls.add(children[i]);
+                children = new Control[controls.size()];
+                return controls.toArray(children);
+            }
+
+        }
+
+        LayoutComposite layoutComposite = new LayoutComposite(parent, 0);
+        layoutComposite.setLayout(new FillLayout());
+
+        text = new Text(layoutComposite, SWT.NO_BACKGROUND | SWT.READ_ONLY
+                | SWT.V_SCROLL | SWT.H_SCROLL);
+        text.setVisible(false);
+
+        canvas = new Canvas(layoutComposite, SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE
+                | SWT.V_SCROLL | SWT.H_SCROLL);
+        canvas.setVisible(false);
+
+        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 (Window.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() {
+                Message.Builder builder = 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;
+                Message.Builder builder = Message.newBuilder();
+                builder.setContextId(0); // FIXME: proper context id
+                builder.setType(Type.Response);
+                builder.setExpectResponse(false);
+                builder.setFunction(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 += String.format("%f", msgData.data[i]);
+                        if (i % (4 * msgData.maxAttrib) == (4 * msgData.maxAttrib - 1))
+                            str += '\n';
+                        else if (i % 4 == 3)
+                            str += " -";
+                        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())
+                {
+                    Object[] objects = selection.toArray();
+                    float totalTime = 0;
+                    for (int i = 0; i < objects.length; i++)
+                    {
+                        MessageData msgData = (MessageData) objects[i];
+                        if (null == msgData)
+                            continue;
+                        totalTime += Float.parseFloat(msgData.columns[1]);
+                    }
+                    viewer.getTable().getColumn(1).setText(Float.toString(totalTime));
+                    return;
+                }
+                else
+                    viewer.getTable().getColumn(1).setText("Elapsed (ms)");
+                MessageData msgData = (MessageData) selection.getFirstElement();
+                if (null == msgData)
+                    return;
+                if (null != msgData.image)
+                {
+                    text.setVisible(false);
+                    canvas.setVisible(true);
+                    canvas.setBackgroundImage(msgData.image);
+                    canvas.getParent().layout();
+                }
+                else if (null != msgData.shader)
+                {
+                    text.setText(msgData.shader);
+                    text.setVisible(true);
+                    canvas.setVisible(false);
+                    text.getParent().layout();
+                }
+                else if (null != msgData.data)
+                {
+                    String str = "";
+                    for (int i = 0; i < msgData.data.length; i++)
+                    {
+                        str += String.format("%.3g", msgData.data[i]);
+                        if (i % (4 * msgData.maxAttrib) == (4 * msgData.maxAttrib - 1))
+                            str += '\n';
+                        else if (i % 4 == 3)
+                            str += " -";
+                        if (i < msgData.data.length - 1)
+                            str += ' ';
+                    }
+
+                    text.setText(str);
+                    text.setVisible(true);
+                    canvas.setVisible(false);
+                    text.getParent().layout();
+                }
+            }
+
+        });
+    }
+
+    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() {
+        FileWriter file = null;
+        PrintWriter writer = null;
+        try {
+            file = new FileWriter("GLES2Debugger.log", true);
+            writer = new PrintWriter(file);
+            writer.write("\n\n");
+            writer.write(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance()
+                    .getTime()));
+        } catch (IOException e1) {
+            showError(e1);
+        }
+        ArrayList<MessageData> msgs = new ArrayList<MessageData>();
+        while (running) {
+            if (!messageQueue.IsRunning())
+                break;
+
+            Message msg = messageQueue.RemoveMessage(0);
+            if (msgs.size() > 40) {
+                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);
+            if (null != writer) {
+                writer.write(msgData.columns[0]);
+                for (int i = 0; i < 30 - msgData.columns[0].length(); i++)
+                    writer.write(" ");
+                writer.write("\t");
+                writer.write(msgData.columns[1] + " \t ");
+                writer.write(msgData.columns[2] + " \t ");
+                writer.write(msgData.columns[3] + " \n");
+                if (msgData.columns[0] == "eglSwapBuffers") {
+                    writer.write("\n-------\n");
+                    writer.flush();
+                }
+            }
+            msgs.add(msgData);
+        }
+        if (running)
+            ConnectDisconnect(); // error occurred, disconnect
+        if (null != writer) {
+            writer.flush();
+            writer.close();
+        }
+    }
+}