Merge "Support primitive ALT-TAB style navigation using Recent Apps."
diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h
index 0a6e4fb..972e799 100644
--- a/include/ui/egl/android_natives.h
+++ b/include/ui/egl/android_natives.h
@@ -291,9 +291,6 @@
     void* reserved_proc[2];
 };
 
-// Backwards compatibility...  please switch to ANativeWindow.
-typedef struct ANativeWindow android_native_window_t;
-
 /*
  *  native_window_set_usage(..., usage)
  *  Sets the intended usage flags for the next buffers
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
index d1a6af1..58bb0d3 100644
--- a/libs/gui/Android.mk
+++ b/libs/gui/Android.mk
@@ -10,7 +10,15 @@
 	SensorEventQueue.cpp \
 	SensorManager.cpp \
 	SurfaceTexture.cpp \
-	SurfaceTextureClient.cpp
+	SurfaceTextureClient.cpp \
+	ISurfaceComposer.cpp \
+	ISurface.cpp \
+	ISurfaceComposerClient.cpp \
+	IGraphicBufferAlloc.cpp \
+	LayerState.cpp \
+	SharedBufferStack.cpp \
+	Surface.cpp \
+	SurfaceComposerClient.cpp \
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
@@ -21,7 +29,6 @@
 	libui \
 	libEGL \
 	libGLESv2 \
-	libsurfaceflinger_client
 
 
 LOCAL_MODULE:= libgui
diff --git a/libs/surfaceflinger_client/IGraphicBufferAlloc.cpp b/libs/gui/IGraphicBufferAlloc.cpp
similarity index 100%
rename from libs/surfaceflinger_client/IGraphicBufferAlloc.cpp
rename to libs/gui/IGraphicBufferAlloc.cpp
diff --git a/libs/surfaceflinger_client/ISurface.cpp b/libs/gui/ISurface.cpp
similarity index 100%
rename from libs/surfaceflinger_client/ISurface.cpp
rename to libs/gui/ISurface.cpp
diff --git a/libs/surfaceflinger_client/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
similarity index 100%
rename from libs/surfaceflinger_client/ISurfaceComposer.cpp
rename to libs/gui/ISurfaceComposer.cpp
diff --git a/libs/surfaceflinger_client/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
similarity index 100%
rename from libs/surfaceflinger_client/ISurfaceComposerClient.cpp
rename to libs/gui/ISurfaceComposerClient.cpp
diff --git a/libs/surfaceflinger_client/LayerState.cpp b/libs/gui/LayerState.cpp
similarity index 100%
rename from libs/surfaceflinger_client/LayerState.cpp
rename to libs/gui/LayerState.cpp
diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/gui/SharedBufferStack.cpp
similarity index 100%
rename from libs/surfaceflinger_client/SharedBufferStack.cpp
rename to libs/gui/SharedBufferStack.cpp
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/gui/Surface.cpp
similarity index 100%
rename from libs/surfaceflinger_client/Surface.cpp
rename to libs/gui/Surface.cpp
diff --git a/libs/surfaceflinger_client/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
similarity index 100%
rename from libs/surfaceflinger_client/SurfaceComposerClient.cpp
rename to libs/gui/SurfaceComposerClient.cpp
diff --git a/libs/gui/tests/Android.mk b/libs/gui/tests/Android.mk
index 7516299..ecd0995 100644
--- a/libs/gui/tests/Android.mk
+++ b/libs/gui/tests/Android.mk
@@ -9,6 +9,7 @@
 LOCAL_MODULE_TAGS := tests
 
 LOCAL_SRC_FILES := \
+    Surface_test.cpp \
     SurfaceTextureClient_test.cpp \
     SurfaceTexture_test.cpp \
 
@@ -20,7 +21,6 @@
 	libcutils \
 	libgui \
 	libstlport \
-	libsurfaceflinger_client \
 	libui \
 	libutils \
 
diff --git a/libs/surfaceflinger_client/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
similarity index 100%
rename from libs/surfaceflinger_client/tests/Surface_test.cpp
rename to libs/gui/tests/Surface_test.cpp
diff --git a/libs/surfaceflinger_client/Android.mk b/libs/surfaceflinger_client/Android.mk
index 4a0faf0..267e3ed 100644
--- a/libs/surfaceflinger_client/Android.mk
+++ b/libs/surfaceflinger_client/Android.mk
@@ -1,22 +1,9 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= \
-	ISurfaceComposer.cpp \
-	ISurface.cpp \
-	ISurfaceComposerClient.cpp \
-	IGraphicBufferAlloc.cpp \
-	LayerState.cpp \
-	SharedBufferStack.cpp \
-	Surface.cpp \
-	SurfaceComposerClient.cpp
+LOCAL_SRC_FILES:=
 
-LOCAL_SHARED_LIBRARIES := \
-	libcutils \
-	libutils \
-	libbinder \
-	libhardware \
-	libui
+LOCAL_SHARED_LIBRARIES := 
 
 LOCAL_MODULE:= libsurfaceflinger_client
 
diff --git a/libs/surfaceflinger_client/tests/Android.mk b/libs/surfaceflinger_client/tests/Android.mk
deleted file mode 100644
index 212b8e7..0000000
--- a/libs/surfaceflinger_client/tests/Android.mk
+++ /dev/null
@@ -1,53 +0,0 @@
-# Build the unit tests.
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-ifneq ($(TARGET_SIMULATOR),true)
-
-# Build the unit tests.
-test_src_files := \
-    Surface_test.cpp \
-
-shared_libraries := \
-	libcutils \
-	libutils \
-	libbinder \
-	libsurfaceflinger_client \
-	libstlport \
-
-static_libraries := \
-	libgtest \
-	libgtest_main \
-
-c_includes := \
-    bionic \
-    bionic/libstdc++/include \
-    external/gtest/include \
-    external/stlport/stlport \
-
-module_tags := tests
-
-$(foreach file,$(test_src_files), \
-    $(eval include $(CLEAR_VARS)) \
-    $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
-    $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
-    $(eval LOCAL_C_INCLUDES := $(c_includes)) \
-    $(eval LOCAL_SRC_FILES := $(file)) \
-    $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
-    $(eval LOCAL_MODULE_TAGS := $(module_tags)) \
-    $(eval include $(BUILD_EXECUTABLE)) \
-)
-
-# Build the manual test programs.
-include $(call all-subdir-makefiles)
-
-endif
-
-# Include subdirectory makefiles
-# ============================================================
-
-# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework
-# team really wants is to build the stuff defined by this makefile.
-ifeq (,$(ONE_SHOT_MAKEFILE))
-include $(call first-makefiles-under,$(LOCAL_PATH))
-endif
diff --git a/libs/surfaceflinger_client/tests/SharedBufferStack/Android.mk b/libs/surfaceflinger_client/tests/SharedBufferStack/Android.mk
deleted file mode 100644
index d3dfe04..0000000
--- a/libs/surfaceflinger_client/tests/SharedBufferStack/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-	SharedBufferStackTest.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-	libcutils \
-	libutils \
-    libui \
-    libsurfaceflinger_client
-
-LOCAL_MODULE:= test-sharedbufferstack
-
-LOCAL_MODULE_TAGS := tests
-
-include $(BUILD_EXECUTABLE)
diff --git a/libs/surfaceflinger_client/tests/SharedBufferStack/SharedBufferStackTest.cpp b/libs/surfaceflinger_client/tests/SharedBufferStack/SharedBufferStackTest.cpp
deleted file mode 100644
index 7ef5926..0000000
--- a/libs/surfaceflinger_client/tests/SharedBufferStack/SharedBufferStackTest.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (C) 2007 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.
- */
-
-#undef NDEBUG
-
-#include <assert.h>
-#include <cutils/memory.h>
-#include <cutils/log.h>
-#include <utils/Errors.h>
-#include <private/surfaceflinger/SharedBufferStack.h>
-
-using namespace android;
-
-void log(const char* prefix, int *b, size_t num);
-void test0(SharedBufferServer& s, SharedBufferClient& c, size_t num, int* list);
-
-// ----------------------------------------------------------------------------
-
-int main(int argc, char** argv)
-{
-    SharedClient client;
-    sp<SharedBufferServer> ps(new SharedBufferServer(&client, 0, 4, 0));
-    SharedBufferServer& s(*ps);
-    SharedBufferClient c(&client, 0, 4, 0);
-
-    printf("basic test 0\n");
-    int list0[4] = {0, 1, 2, 3};
-    test0(s, c, 4, list0);
-
-    printf("basic test 1\n");
-    int list1[4] = {2, 1, 0, 3};
-    test0(s, c, 4, list1);
-
-    int b = c.dequeue();
-    c.lock(b);
-    c.queue(b);
-    s.retireAndLock();
-
-    printf("basic test 2\n");
-    int list2[4] = {1, 2, 3, 0};
-    test0(s, c, 4, list2);
-
-
-    printf("resize test\n");
-    class SetBufferCountIPC : public SharedBufferClient::SetBufferCountCallback {
-        SharedBufferServer& s;
-        virtual status_t operator()(int bufferCount) const {
-            return s.resize(bufferCount);
-        }
-    public:
-        SetBufferCountIPC(SharedBufferServer& s) : s(s) { }
-    } resize(s);
-
-    c.setBufferCount(6, resize);
-    int list3[6] = {3, 2, 1, 4, 5, 0};
-    test0(s, c, 6, list3);
-
-    c.setBufferCount(4, resize);
-    int list4[4] = {1, 2, 3, 0};
-    test0(s, c, 4, list4);
-
-    return 0;
-}
-
-void log(const char* prefix, int *b, size_t num)
-{
-    printf("%s: ", prefix);
-    for (size_t i=0 ; i<num ; i++) {
-        printf("%d ", b[i]);
-    }
-    printf("\n");
-}
-
-// ----------------------------------------------------------------------------
-
-void test0(
-        SharedBufferServer& s,
-        SharedBufferClient& c,
-        size_t num,
-        int* list)
-{
-    status_t err;
-    int b[num], u[num], r[num];
-
-    for (size_t i=0 ; i<num ; i++) {
-        b[i] = c.dequeue();
-        assert(b[i]==list[i]);
-    }
-    log("DQ", b, num);
-
-    for (size_t i=0 ; i<num-1 ; i++) {
-        err = c.lock(b[i]);
-        assert(err==0);
-    }
-    log("LK", b, num-1);
-
-    for (size_t i=0 ; i<num-1 ; i++) {
-        err = c.queue(b[i]);
-        assert(err==0);
-    }
-    log(" Q", b, num-1);
-
-
-    for (size_t i=0 ; i<num-1 ; i++) {
-        r[i] = s.retireAndLock();
-        assert(r[i]==list[i]);
-        err = s.unlock(r[i]);
-        assert(err == 0);
-    }
-    log("RT", r, num-1);
-
-    err = c.lock(b[num-1]);
-    assert(err == 0);
-    log("LK", b+num-1, 1);
-
-    err = c.queue(b[num-1]);
-    assert(err == 0);
-    log(" Q", b+num-1, 1);
-
-    r[num-1] = s.retireAndLock();
-    assert(r[num-1]==list[num-1]);
-    err = s.unlock(r[num-1]);
-    assert(err == 0);
-    log("RT", r+num-1, 1);
-
-    // ------------------------------------
-    printf("\n");
-
-    for (size_t i=0 ; i<num ; i++) {
-        b[i] = c.dequeue();
-        assert(b[i]==list[i]);
-    }
-    log("DQ", b, num);
-
-    for (size_t i=0 ; i<num-1 ; i++) {
-        err = c.lock(b[i]);
-        assert(err==0);
-    }
-    log("LK", b, num-1);
-
-    for (size_t i=0 ; i<num-1 ; i++) {
-        u[i] = b[num-2-i];
-    }
-    u[num-1] = b[num-1];
-
-    for (size_t i=0 ; i<num-1 ; i++) {
-        err = c.queue(u[i]);
-        assert(err==0);
-    }
-    log(" Q", u, num-1);
-
-    for (size_t i=0 ; i<num-1 ; i++) {
-        r[i] = s.retireAndLock();
-        assert(r[i]==u[i]);
-        err = s.unlock(r[i]);
-        assert(err == 0);
-    }
-    log("RT", r, num-1);
-
-    err = c.lock(b[num-1]);
-    assert(err == 0);
-    log("LK", b+num-1, 1);
-
-    err = c.queue(b[num-1]);
-    assert(err == 0);
-    log(" Q", b+num-1, 1);
-
-    r[num-1] = s.retireAndLock();
-    assert(r[num-1]==list[num-1]);
-    err = s.unlock(r[num-1]);
-    assert(err == 0);
-    log("RT", r+num-1, 1);
-
-    // ------------------------------------
-    printf("\n");
-
-    for (size_t i=0 ; i<num ; i++) {
-        b[i] = c.dequeue();
-        assert(b[i]==u[i]);
-    }
-    log("DQ", b, num);
-
-    for (size_t i=0 ; i<num-1 ; i++) {
-        err = c.lock(b[i]);
-        assert(err==0);
-    }
-    log("LK", b, num-1);
-
-    for (size_t i=0 ; i<num-1 ; i++) {
-        err = c.queue(b[i]);
-        assert(err==0);
-    }
-    log(" Q", b, num-1);
-
-    for (size_t i=0 ; i<num-1 ; i++) {
-        r[i] = s.retireAndLock();
-        assert(r[i]==u[i]);
-        err = s.unlock(r[i]);
-        assert(err == 0);
-    }
-    log("RT", r, num-1);
-
-    err = c.lock(u[num-1]);
-    assert(err == 0);
-    log("LK", u+num-1, 1);
-
-    err = c.queue(u[num-1]);
-    assert(err == 0);
-    log(" Q", u+num-1, 1);
-
-    r[num-1] = s.retireAndLock();
-    assert(r[num-1]==u[num-1]);
-    err = s.unlock(r[num-1]);
-    assert(err == 0);
-    log("RT", r+num-1, 1);
-
-    // ------------------------------------
-    printf("\n");
-
-    b[0] = c.dequeue();
-    assert(b[0]==u[0]);
-    log("DQ", b, 1);
-
-    c.undoDequeue(b[0]);
-    assert(err == 0);
-    log("UDQ", b, 1);
-
-    // ------------------------------------
-    printf("\n");
-
-    for (size_t i=0 ; i<num ; i++) {
-        b[i] = c.dequeue();
-        assert(b[i]==u[i]);
-    }
-    log("DQ", b, num);
-
-    for (size_t i=0 ; i<num-1 ; i++) {
-        err = c.lock(b[i]);
-        assert(err==0);
-    }
-    log("LK", b, num-1);
-
-    for (size_t i=0 ; i<num-1 ; i++) {
-        err = c.queue(b[i]);
-        assert(err==0);
-    }
-    log(" Q", b, num-1);
-
-    for (size_t i=0 ; i<num-1 ; i++) {
-        r[i] = s.retireAndLock();
-        assert(r[i]==u[i]);
-        err = s.unlock(r[i]);
-        assert(err == 0);
-    }
-    log("RT", r, num-1);
-
-    err = c.lock(u[num-1]);
-    assert(err == 0);
-    log("LK", u+num-1, 1);
-
-    err = c.queue(u[num-1]);
-    assert(err == 0);
-    log(" Q", u+num-1, 1);
-
-    r[num-1] = s.retireAndLock();
-    assert(r[num-1]==u[num-1]);
-    err = s.unlock(r[num-1]);
-    assert(err == 0);
-    log("RT", r+num-1, 1);
-    printf("\n");
-}
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index 123306b..7d72729 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -13,7 +13,7 @@
 	EGL/hooks.cpp 	       \
 	EGL/Loader.cpp 	       \
 #
-LOCAL_STATIC_LIBRARIES += libGLESv2_dbg libprotobuf-cpp-2.3.0-lite
+LOCAL_STATIC_LIBRARIES += libGLESv2_dbg libprotobuf-cpp-2.3.0-lite liblzf
 LOCAL_SHARED_LIBRARIES += libcutils libutils libstlport
 LOCAL_LDLIBS := -lpthread -ldl
 LOCAL_MODULE:= libEGL
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 75f7078..a53b375 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -72,25 +72,78 @@
 
 // ----------------------------------------------------------------------------
 
-class egl_object_t {
-    static SortedVector<egl_object_t*> sObjects;
-    static Mutex sLock;
+class egl_object_t;
+struct egl_display_t;
+static egl_display_t* get_display(EGLDisplay dpy);
 
+struct egl_config_t {
+    egl_config_t() {}
+    egl_config_t(int impl, EGLConfig config)
+        : impl(impl), config(config), configId(0), implConfigId(0) { }
+    int         impl;           // the implementation this config is for
+    EGLConfig   config;         // the implementation's EGLConfig
+    EGLint      configId;       // our CONFIG_ID
+    EGLint      implConfigId;   // the implementation's CONFIG_ID
+    inline bool operator < (const egl_config_t& rhs) const {
+        if (impl < rhs.impl) return true;
+        if (impl > rhs.impl) return false;
+        return config < rhs.config;
+    }
+};
+
+struct egl_display_t {
+    enum { NOT_INITIALIZED, INITIALIZED, TERMINATED };
+
+    struct strings_t {
+        char const * vendor;
+        char const * version;
+        char const * clientApi;
+        char const * extensions;
+    };
+
+    struct DisplayImpl {
+        DisplayImpl() : dpy(EGL_NO_DISPLAY), config(0),
+                        state(NOT_INITIALIZED), numConfigs(0) { }
+        EGLDisplay  dpy;
+        EGLConfig*  config;
+        EGLint      state;
+        EGLint      numConfigs;
+        strings_t   queryString;
+    };
+
+    uint32_t        magic;
+    DisplayImpl     disp[IMPL_NUM_IMPLEMENTATIONS];
+    EGLint          numTotalConfigs;
+    egl_config_t*   configs;
+    uint32_t        refs;
+    Mutex           lock;
+
+    SortedVector<egl_object_t*> objects;
+
+    egl_display_t() : magic('_dpy'), numTotalConfigs(0), configs(0) { }
+    ~egl_display_t() { magic = 0; }
+    inline bool isReady() const { return (refs > 0); }
+    inline bool isValid() const { return magic == '_dpy'; }
+    inline bool isAlive() const { return isValid(); }
+};
+
+class egl_object_t {
+    egl_display_t *display;
             volatile int32_t  terminated;
     mutable volatile int32_t  count;
 
 public:
-    egl_object_t() : terminated(0), count(1) { 
-        Mutex::Autolock _l(sLock);
-        sObjects.add(this);
+    egl_object_t(EGLDisplay dpy) : display(get_display(dpy)), terminated(0), count(1) {
+        Mutex::Autolock _l(display->lock);
+        display->objects.add(this);
     }
 
     inline bool isAlive() const { return !terminated; }
 
 private:
     bool get() {
-        Mutex::Autolock _l(sLock);
-        if (egl_object_t::sObjects.indexOf(this) >= 0) {
+        Mutex::Autolock _l(display->lock);
+        if (display->objects.indexOf(this) >= 0) {
             android_atomic_inc(&count);
             return true;
         }
@@ -98,9 +151,9 @@
     }
 
     bool put() {
-        Mutex::Autolock _l(sLock);
+        Mutex::Autolock _l(display->lock);
         if (android_atomic_dec(&count) == 1) {
-            sObjects.remove(this);
+            display->objects.remove(this);
             return true;
         }
         return false;
@@ -147,65 +200,13 @@
     };
 };
 
-SortedVector<egl_object_t*> egl_object_t::sObjects;
-Mutex egl_object_t::sLock;
-
-
-struct egl_config_t {
-    egl_config_t() {}
-    egl_config_t(int impl, EGLConfig config)
-        : impl(impl), config(config), configId(0), implConfigId(0) { }
-    int         impl;           // the implementation this config is for
-    EGLConfig   config;         // the implementation's EGLConfig
-    EGLint      configId;       // our CONFIG_ID
-    EGLint      implConfigId;   // the implementation's CONFIG_ID
-    inline bool operator < (const egl_config_t& rhs) const {
-        if (impl < rhs.impl) return true;
-        if (impl > rhs.impl) return false;
-        return config < rhs.config;
-    }
-};
-
-struct egl_display_t {
-    enum { NOT_INITIALIZED, INITIALIZED, TERMINATED };
-    
-    struct strings_t {
-        char const * vendor;
-        char const * version;
-        char const * clientApi;
-        char const * extensions;
-    };
-
-    struct DisplayImpl {
-        DisplayImpl() : dpy(EGL_NO_DISPLAY), config(0),
-                        state(NOT_INITIALIZED), numConfigs(0) { }
-        EGLDisplay  dpy;
-        EGLConfig*  config;
-        EGLint      state;
-        EGLint      numConfigs;
-        strings_t   queryString;
-    };
-
-    uint32_t        magic;
-    DisplayImpl     disp[IMPL_NUM_IMPLEMENTATIONS];
-    EGLint          numTotalConfigs;
-    egl_config_t*   configs;
-    uint32_t        refs;
-    Mutex           lock;
-    
-    egl_display_t() : magic('_dpy'), numTotalConfigs(0), configs(0) { }
-    ~egl_display_t() { magic = 0; }
-    inline bool isValid() const { return magic == '_dpy'; }
-    inline bool isAlive() const { return isValid(); }
-};
-
 struct egl_surface_t : public egl_object_t
 {
     typedef egl_object_t::LocalRef<egl_surface_t, EGLSurface> Ref;
 
     egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win,
             EGLSurface surface, int impl, egl_connection_t const* cnx)
-    : dpy(dpy), surface(surface), config(config), win(win), impl(impl), cnx(cnx) {
+      : egl_object_t(dpy), dpy(dpy), surface(surface), config(config), win(win), impl(impl), cnx(cnx) {
     }
     ~egl_surface_t() {
     }
@@ -223,8 +224,8 @@
     
     egl_context_t(EGLDisplay dpy, EGLContext context, EGLConfig config,
             int impl, egl_connection_t const* cnx, int version) 
-    : dpy(dpy), context(context), config(config), read(0), draw(0), impl(impl),
-      cnx(cnx), version(version), dbg(NULL)
+    : egl_object_t(dpy), dpy(dpy), context(context), config(config), read(0), draw(0), 
+      impl(impl), cnx(cnx), version(version), dbg(NULL)
     {
     }
     ~egl_context_t()
@@ -249,7 +250,7 @@
     typedef egl_object_t::LocalRef<egl_image_t, EGLImageKHR> Ref;
 
     egl_image_t(EGLDisplay dpy, EGLContext context)
-        : dpy(dpy), context(context)
+        : egl_object_t(dpy), dpy(dpy), context(context)
     {
         memset(images, 0, sizeof(images));
     }
@@ -263,7 +264,7 @@
     typedef egl_object_t::LocalRef<egl_sync_t, EGLSyncKHR> Ref;
 
     egl_sync_t(EGLDisplay dpy, EGLContext context, EGLSyncKHR sync)
-        : dpy(dpy), context(context), sync(sync)
+        : egl_object_t(dpy), dpy(dpy), context(context), sync(sync)
     {
     }
     EGLDisplay dpy;
@@ -609,12 +610,22 @@
     return egl_to_native_cast<egl_sync_t>(sync);
 }
 
+static inline
+egl_display_t* validate_display(EGLDisplay dpy)
+{
+    egl_display_t * const dp = get_display(dpy);
+    if (!dp) return setError(EGL_BAD_DISPLAY, (egl_display_t*)NULL);
+    if (!dp->isReady()) return setError(EGL_NOT_INITIALIZED, (egl_display_t*)NULL);
+
+    return dp;
+}
+
 static egl_connection_t* validate_display_config(
         EGLDisplay dpy, EGLConfig config,
         egl_display_t const*& dp)
 {
-    dp = get_display(dpy);
-    if (!dp) return setError(EGL_BAD_DISPLAY, (egl_connection_t*)NULL);
+    dp = validate_display(dpy);
+    if (!dp) return (egl_connection_t*) NULL;
 
     if (intptr_t(config) >= dp->numTotalConfigs) {
         return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL);
@@ -628,9 +639,9 @@
 
 static EGLBoolean validate_display_context(EGLDisplay dpy, EGLContext ctx)
 {
-    if ((uintptr_t(dpy)-1U) >= NUM_DISPLAYS)
-        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
-    if (!get_display(dpy)->isAlive())
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
+    if (!dp->isAlive())
         return setError(EGL_BAD_DISPLAY, EGL_FALSE);
     if (!get_context(ctx)->isAlive())
         return setError(EGL_BAD_CONTEXT, EGL_FALSE);
@@ -639,9 +650,9 @@
 
 static EGLBoolean validate_display_surface(EGLDisplay dpy, EGLSurface surface)
 {
-    if ((uintptr_t(dpy)-1U) >= NUM_DISPLAYS)
-        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
-    if (!get_display(dpy)->isAlive())
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
+    if (!dp->isAlive())
         return setError(EGL_BAD_DISPLAY, EGL_FALSE);
     if (!get_surface(surface)->isAlive())
         return setError(EGL_BAD_SURFACE, EGL_FALSE);
@@ -961,8 +972,8 @@
 {
     clearError();
 
-    egl_display_t const * const dp = get_display(dpy);
-    if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
 
     GLint numConfigs = dp->numTotalConfigs;
     if (!configs) {
@@ -987,8 +998,8 @@
 {
     clearError();
 
-    egl_display_t const * const dp = get_display(dpy);
-    if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
 
     if (num_config==0) {
         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
@@ -1206,12 +1217,14 @@
 {
     clearError();
 
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
+
     SurfaceRef _s(surface);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
     if (!validate_display_surface(dpy, surface))
         return EGL_FALSE;    
-    egl_display_t const * const dp = get_display(dpy);
 
     egl_surface_t * const s = get_surface(surface);
     EGLBoolean result = s->cnx->egl.eglDestroySurface(
@@ -1230,12 +1243,14 @@
 {
     clearError();
 
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
+
     SurfaceRef _s(surface);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
     if (!validate_display_surface(dpy, surface))
         return EGL_FALSE;    
-    egl_display_t const * const dp = get_display(dpy);
     egl_surface_t const * const s = get_surface(surface);
 
     EGLBoolean result(EGL_TRUE);
@@ -1298,12 +1313,14 @@
 {
     clearError();
 
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
+
     ContextRef _c(ctx);
     if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
     
     if (!validate_display_context(dpy, ctx))
         return EGL_FALSE;
-    egl_display_t const * const dp = get_display(dpy);
     egl_context_t * const c = get_context(ctx);
     EGLBoolean result = c->cnx->egl.eglDestroyContext(
             dp->disp[c->impl].dpy, c->context);
@@ -1339,14 +1356,23 @@
 {
     clearError();
 
+    egl_display_t const * const dp = get_display(dpy);
+    if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+    /* If ctx is not EGL_NO_CONTEXT, read is not EGL_NO_SURFACE, or draw is not
+       EGL_NO_SURFACE, then an EGL_NOT_INITIALIZED error is generated if dpy is
+       a valid but uninitialized display. */
+    if ( (ctx != EGL_NO_CONTEXT) || (read != EGL_NO_SURFACE) ||
+         (draw != EGL_NO_SURFACE) ) {
+        if (!dp->isReady()) return setError(EGL_NOT_INITIALIZED, EGL_FALSE);
+    }
+
     // get a reference to the object passed in
     ContextRef _c(ctx);
     SurfaceRef _d(draw);
     SurfaceRef _r(read);
 
-    // validate the display and the context (if not EGL_NO_CONTEXT)
-    egl_display_t const * const dp = get_display(dpy);
-    if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    // validate the context (if not EGL_NO_CONTEXT)
     if ((ctx != EGL_NO_CONTEXT) && (!validate_display_context(dpy, ctx))) {
         // EGL_NO_CONTEXT is valid
         return EGL_FALSE;
@@ -1439,13 +1465,15 @@
 {
     clearError();
 
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
+
     ContextRef _c(ctx);
     if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
 
     if (!validate_display_context(dpy, ctx))
         return EGL_FALSE;    
     
-    egl_display_t const * const dp = get_display(dpy);
     egl_context_t * const c = get_context(ctx);
 
     EGLBoolean result(EGL_TRUE);
@@ -1681,12 +1709,14 @@
 
     clearError();
 
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
+
     SurfaceRef _s(draw);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
     if (!validate_display_surface(dpy, draw))
         return EGL_FALSE;    
-    egl_display_t const * const dp = get_display(dpy);
     egl_surface_t const * const s = get_surface(draw);
     return s->cnx->egl.eglSwapBuffers(dp->disp[s->impl].dpy, s->surface);
 }
@@ -1696,12 +1726,14 @@
 {
     clearError();
 
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
+
     SurfaceRef _s(surface);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
     if (!validate_display_surface(dpy, surface))
         return EGL_FALSE;    
-    egl_display_t const * const dp = get_display(dpy);
     egl_surface_t const * const s = get_surface(surface);
     return s->cnx->egl.eglCopyBuffers(
             dp->disp[s->impl].dpy, s->surface, target);
@@ -1711,7 +1743,9 @@
 {
     clearError();
 
-    egl_display_t const * const dp = get_display(dpy);
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return (const char *) NULL;
+
     switch (name) {
         case EGL_VENDOR:
             return gVendorString;
@@ -1735,12 +1769,14 @@
 {
     clearError();
 
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
+
     SurfaceRef _s(surface);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
     if (!validate_display_surface(dpy, surface))
         return EGL_FALSE;    
-    egl_display_t const * const dp = get_display(dpy);
     egl_surface_t const * const s = get_surface(surface);
     if (s->cnx->egl.eglSurfaceAttrib) {
         return s->cnx->egl.eglSurfaceAttrib(
@@ -1754,12 +1790,14 @@
 {
     clearError();
 
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
+
     SurfaceRef _s(surface);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
     if (!validate_display_surface(dpy, surface))
         return EGL_FALSE;    
-    egl_display_t const * const dp = get_display(dpy);
     egl_surface_t const * const s = get_surface(surface);
     if (s->cnx->egl.eglBindTexImage) {
         return s->cnx->egl.eglBindTexImage(
@@ -1773,12 +1811,14 @@
 {
     clearError();
 
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
+
     SurfaceRef _s(surface);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
     if (!validate_display_surface(dpy, surface))
         return EGL_FALSE;    
-    egl_display_t const * const dp = get_display(dpy);
     egl_surface_t const * const s = get_surface(surface);
     if (s->cnx->egl.eglReleaseTexImage) {
         return s->cnx->egl.eglReleaseTexImage(
@@ -1791,8 +1831,8 @@
 {
     clearError();
 
-    egl_display_t * const dp = get_display(dpy);
-    if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
 
     EGLBoolean res = EGL_TRUE;
     for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
@@ -1930,13 +1970,15 @@
 {
     clearError();
 
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
+
     SurfaceRef _s(surface);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
     if (!validate_display_surface(dpy, surface))
         return EGL_FALSE;
 
-    egl_display_t const * const dp = get_display(dpy);
     egl_surface_t const * const s = get_surface(surface);
 
     if (s->cnx->egl.eglLockSurfaceKHR) {
@@ -1950,13 +1992,15 @@
 {
     clearError();
 
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
+
     SurfaceRef _s(surface);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
     if (!validate_display_surface(dpy, surface))
         return EGL_FALSE;
 
-    egl_display_t const * const dp = get_display(dpy);
     egl_surface_t const * const s = get_surface(surface);
 
     if (s->cnx->egl.eglUnlockSurfaceKHR) {
@@ -1971,12 +2015,14 @@
 {
     clearError();
 
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_NO_IMAGE_KHR;
+
     if (ctx != EGL_NO_CONTEXT) {
         ContextRef _c(ctx);
         if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
         if (!validate_display_context(dpy, ctx))
             return EGL_NO_IMAGE_KHR;
-        egl_display_t const * const dp = get_display(dpy);
         egl_context_t * const c = get_context(ctx);
         // since we have an EGLContext, we know which implementation to use
         EGLImageKHR image = c->cnx->egl.eglCreateImageKHR(
@@ -1989,10 +2035,6 @@
         return (EGLImageKHR)result;
     } else {
         // EGL_NO_CONTEXT is a valid parameter
-        egl_display_t const * const dp = get_display(dpy);
-        if (dp == 0) {
-            return setError(EGL_BAD_DISPLAY, EGL_NO_IMAGE_KHR);
-        }
 
         /* Since we don't have a way to know which implementation to call,
          * we're calling all of them. If at least one of the implementation
@@ -2044,35 +2086,33 @@
 {
     clearError();
 
-    egl_display_t const * const dp = get_display(dpy);
-     if (dp == 0) {
-         return setError(EGL_BAD_DISPLAY, EGL_FALSE);
-     }
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
 
-     ImageRef _i(img);
-     if (!_i.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+    ImageRef _i(img);
+    if (!_i.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE);
 
-     egl_image_t* image = get_image(img);
-     bool success = false;
-     for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
-         egl_connection_t* const cnx = &gEGLImpl[i];
-         if (image->images[i] != EGL_NO_IMAGE_KHR) {
-             if (cnx->dso) {
-                 if (cnx->egl.eglDestroyImageKHR) {
-                     if (cnx->egl.eglDestroyImageKHR(
-                             dp->disp[i].dpy, image->images[i])) {
-                         success = true;
-                     }
-                 }
-             }
-         }
-     }
-     if (!success)
-         return EGL_FALSE;
+    egl_image_t* image = get_image(img);
+    bool success = false;
+    for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
+        egl_connection_t* const cnx = &gEGLImpl[i];
+        if (image->images[i] != EGL_NO_IMAGE_KHR) {
+            if (cnx->dso) {
+                if (cnx->egl.eglDestroyImageKHR) {
+                    if (cnx->egl.eglDestroyImageKHR(
+                            dp->disp[i].dpy, image->images[i])) {
+                        success = true;
+                    }
+                }
+            }
+        }
+    }
+    if (!success)
+        return EGL_FALSE;
 
-     _i.terminate();
+    _i.terminate();
 
-     return EGL_TRUE;
+    return EGL_TRUE;
 }
 
 // ----------------------------------------------------------------------------
@@ -2084,12 +2124,14 @@
 {
     clearError();
 
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_NO_SYNC_KHR;
+
     EGLContext ctx = eglGetCurrentContext();
     ContextRef _c(ctx);
     if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_NO_SYNC_KHR);
     if (!validate_display_context(dpy, ctx))
         return EGL_NO_SYNC_KHR;
-    egl_display_t const * const dp = get_display(dpy);
     egl_context_t * const c = get_context(ctx);
     EGLSyncKHR result = EGL_NO_SYNC_KHR;
     if (c->cnx->egl.eglCreateSyncKHR) {
@@ -2106,10 +2148,8 @@
 {
     clearError();
 
-    egl_display_t const * const dp = get_display(dpy);
-    if (dp == 0) {
-        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
-    }
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
 
     SyncRef _s(sync);
     if (!_s.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE);
@@ -2136,10 +2176,8 @@
 {
     clearError();
 
-    egl_display_t const * const dp = get_display(dpy);
-    if (dp == 0) {
-        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
-    }
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
 
     SyncRef _s(sync);
     if (!_s.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE);
@@ -2165,10 +2203,8 @@
 {
     clearError();
 
-    egl_display_t const * const dp = get_display(dpy);
-    if (dp == 0) {
-        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
-    }
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
 
     SyncRef _s(sync);
     if (!_s.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE);
@@ -2199,12 +2235,14 @@
 {
     clearError();
 
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
+
     SurfaceRef _s(draw);
     if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
     if (!validate_display_surface(dpy, draw))
         return EGL_FALSE;    
-    egl_display_t const * const dp = get_display(dpy);
     egl_surface_t const * const s = get_surface(draw);
     if (s->cnx->egl.eglSetSwapRectangleANDROID) {
         return s->cnx->egl.eglSetSwapRectangleANDROID(
diff --git a/opengl/libs/GLES2_dbg/Android.mk b/opengl/libs/GLES2_dbg/Android.mk
index e593c32..fc40799 100644
--- a/opengl/libs/GLES2_dbg/Android.mk
+++ b/opengl/libs/GLES2_dbg/Android.mk
@@ -4,11 +4,11 @@
 
 LOCAL_SRC_FILES := \
     src/api.cpp \
+    src/caller.cpp \
     src/dbgcontext.cpp \
     src/debugger_message.pb.cpp \
     src/egl.cpp \
     src/server.cpp \
-    src/texture.cpp \
     src/vertex.cpp
 
 LOCAL_C_INCLUDES :=	\
@@ -16,6 +16,7 @@
     $(LOCAL_PATH)/../ \
     external/stlport/stlport \
     external/protobuf/src \
+    external \
     bionic
 
 #LOCAL_CFLAGS += -O0 -g -DDEBUG -UNDEBUG
diff --git a/opengl/libs/GLES2_dbg/generate_api_cpp.py b/opengl/libs/GLES2_dbg/generate_api_cpp.py
index 5b024ad..66c110f 100755
--- a/opengl/libs/GLES2_dbg/generate_api_cpp.py
+++ b/opengl/libs/GLES2_dbg/generate_api_cpp.py
@@ -31,11 +31,11 @@
     externs = []
     i = 0
     # these have been hand written
-    skipFunctions = ["glTexImage2D", "glTexSubImage2D", "glReadPixels",
-"glDrawArrays", "glDrawElements"]
+    skipFunctions = ["glReadPixels", "glDrawArrays", "glDrawElements"]
     
     # these have an EXTEND_Debug_* macro for getting data
-    extendFunctions = ["glCopyTexImage2D", "glCopyTexSubImage2D", "glShaderSource"]
+    extendFunctions = ["glCopyTexImage2D", "glCopyTexSubImage2D", "glShaderSource",
+"glTexImage2D", "glTexSubImage2D"]
     
     # these also needs to be forwarded to DbgContext
     contextFunctions = ["glUseProgram", "glEnableVertexAttribArray", "glDisableVertexAttribArray", 
@@ -67,8 +67,7 @@
                     externs.append(extern)
                 
             print "%s Debug_%s(%s)\n{" % (returnType, functionName, RemoveAnnotation(parameterList))
-            print """    glesv2debugger::Message msg;
-    const bool expectResponse = false;"""
+            print "    glesv2debugger::Message msg;"
     
             if parameterList == "void":
                 parameters = []
@@ -159,8 +158,8 @@
                 print getData
             if functionName in extendFunctions:
                 print "    EXTEND_Debug_%s;" % (functionName) 
-            print "    int * ret = MessageLoop(caller, msg, expectResponse,"
-            print "                            glesv2debugger::Message_Function_%s);" % (functionName)
+            print "    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_%s);"\
+                % (functionName)
             if returnType != "void":
                 if returnType == "GLboolean":
                     print "    return static_cast<GLboolean>(reinterpret_cast<int>(ret));"
diff --git a/opengl/libs/GLES2_dbg/generate_caller_cpp.py b/opengl/libs/GLES2_dbg/generate_caller_cpp.py
new file mode 100755
index 0000000..eac2292
--- /dev/null
+++ b/opengl/libs/GLES2_dbg/generate_caller_cpp.py
@@ -0,0 +1,200 @@
+#!/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
+
+externs = []
+    
+def generate_caller(lines):
+    i = 0
+    output = ""
+    skipFunctions = []
+    
+    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
+            parameterList = line[line.find(")(") + 2: line.find(") {")]
+            
+            #if line.find("*") >= 0:
+            #    extern = "%s Debug_%s(%s);" % (returnType, functionName, parameterList)
+            #    externs.append(extern)
+            #    continue
+            
+            if functionName in skipFunctions:
+                sys.stderr.write("!\n! skipping function '%s'\n!\n" % functionName)
+                continue
+            output += "\
+    case glesv2debugger::Message_Function_%s:\n" % functionName
+            parameters = parameterList.split(',')
+            paramIndex = 0
+            if line.find("*") >= 0 and (line.find("*") < line.find(":") or line.find("*") > line.rfind(":")): # unannotated pointer
+                # add function to list of functions that should be hand written, but generate code anyways
+                externs.append(functionName)
+                output += "\
+        ret = GenerateCall_%s(dbg, cmd, msg, prevRet);\n\
+        break;\n" % (functionName)
+                continue
+            elif line.find(":out") >= 0 or line.find(":inout") >= 0:
+                externs.append(functionName)
+                output += "\
+        ret = GenerateCall_%s(dbg, cmd, msg, prevRet);\n\
+        break; // annotated output pointers\n" % (functionName)
+                continue
+                
+            if parameterList == "void":
+                parameters = []
+            arguments = ""
+            paramNames = []
+            inout = ""
+            getData = ""
+            
+            callerMembers = ""
+
+            for parameter in parameters:
+                const = parameter.find("const")
+                parameter = parameter.replace("const", "")
+                parameter = parameter.strip()
+                paramType = parameter.split(' ')[0]
+                paramName = parameter.split(' ')[1]
+                annotation = ""
+                if parameter.find(":") >= 0: # has annotation
+                    assert inout == "" # only one parameter should be annotated
+                    sys.stderr.write("%s is annotated: %s \n" % (functionName, paramType))
+                    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 = "strlen(%s)" % (paramName)
+                    else:
+                        count = int(annotation)
+            
+                    paramType += "*"
+                    arguments += "reinterpret_cast<%s>(const_cast<char *>(cmd.data().data()))" % (paramType)
+                elif paramType == "GLboolean":
+                    arguments += "GLboolean(cmd.arg%d())" % (paramIndex)
+                else:
+                    arguments += "static_cast<%s>(cmd.arg%d())" % (paramType, paramIndex)
+
+                if paramIndex < len(parameters) - 1:
+                        arguments += ", "
+                if len(arguments) - arguments.rfind("\n") > 60 :
+                    arguments += "\n\
+            "
+                if const >= 0:
+                    paramType = "const " + paramType
+                paramNames.append(paramName)
+                paramIndex += 1
+                
+            if returnType == "void":
+                output += "\
+        dbg->hooks->gl.%s(\n\
+            %s);\n\
+        break;\n" % (functionName, arguments)
+            else:
+                output += "\
+        msg.set_ret(static_cast<int>(dbg->hooks->gl.%s(\n\
+            %s)));\n\
+        if (cmd.has_ret())\n\
+            ret = reinterpret_cast<int *>(msg.ret());\n\
+        break;\n" % (functionName, arguments)
+    return output
+
+if __name__ == "__main__":
+
+    lines = open("gl2_api_annotated.in").readlines()
+    output = generate_caller(lines)
+    
+    out = open("src/caller.cpp", "w")
+    out.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_caller_cpp.py
+// implement declarations in caller.h
+
+#include "header.h"
+
+namespace android {
+
+""")
+
+    for extern in externs:
+        out.write("\
+static const int * GenerateCall_%s(DbgContext * const dbg,\n\
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);\n" % (extern))
+        print("\
+static const int * GenerateCall_%s(DbgContext * const dbg,\n\
+                            const glesv2debugger::Message & cmd,\n\
+                            glesv2debugger::Message & msg, const int * const prevRet)\n\
+{ assert(0); return prevRet; }\n" % (extern))
+                     
+    out.write(
+"""
+#include "caller.h"
+
+const int * GenerateCall(DbgContext * const dbg, const glesv2debugger::Message & cmd,
+                  glesv2debugger::Message & msg, const int * const prevRet)
+{
+    LOGD("GenerateCall function=%u", cmd.function());
+    const int * ret = prevRet; // only some functions have return value
+    gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl;
+    nsecs_t c0 = systemTime(timeMode);
+    switch (cmd.function()) {""")
+    
+    out.write(output)
+    
+    out.write("""\
+    default:
+        assert(0);
+    }
+    msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
+    msg.set_context_id(reinterpret_cast<int>(dbg));
+    msg.set_function(cmd.function());
+    msg.set_type(glesv2debugger::Message_Type_AfterCall);
+    return ret;
+}
+
+}; // name space android {
+""")           
+    
+            
diff --git a/opengl/libs/GLES2_dbg/generate_debugger_message_proto.py b/opengl/libs/GLES2_dbg/generate_debugger_message_proto.py
index 48a29da..466c447 100755
--- a/opengl/libs/GLES2_dbg/generate_debugger_message_proto.py
+++ b/opengl/libs/GLES2_dbg/generate_debugger_message_proto.py
@@ -118,12 +118,23 @@
     optional int32 arg6 = 18;
     optional int32 arg7 = 19;
     optional int32 arg8 = 20;
+
     optional bytes data = 10; // variable length data used for GL call
+    enum DataType
+    {
+        ReferencedImage = 0; // for image sourced from ReadPixels
+        NonreferencedImage = 1; // for image sourced from ReadPixels
+    };
+    optional DataType data_type = 23; // most data types can be inferred from function
+    optional int32 pixel_format = 24; // used for image data if format and type 
+    optional int32 pixel_type = 25;   //     cannot be determined from arg 
+    
     optional float time = 11; // duration of previous GL call (ms)
     enum Prop
     {
         Capture = 0; // arg0 = true | false
         TimeMode = 1; // arg0 = SYSTEM_TIME_* in utils/Timers.h
+        ExpectResponse = 2; // arg0 = enum Function, arg1 = true/false
     };
     optional Prop prop = 21; // used with SETPROP, value in arg0
     optional float clock = 22; // wall clock in seconds
diff --git a/opengl/libs/GLES2_dbg/src/api.cpp b/opengl/libs/GLES2_dbg/src/api.cpp
index 7094ca7..130ca7e 100644
--- a/opengl/libs/GLES2_dbg/src/api.cpp
+++ b/opengl/libs/GLES2_dbg/src/api.cpp
@@ -25,7 +25,6 @@
 void Debug_glActiveTexture(GLenum texture)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum texture;
 
@@ -38,14 +37,12 @@
 
     msg.set_arg0(texture);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glActiveTexture);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glActiveTexture);
 }
 
 void Debug_glAttachShader(GLuint program, GLuint shader)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint program;
         GLuint shader;
@@ -61,14 +58,12 @@
     msg.set_arg0(program);
     msg.set_arg1(shader);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glAttachShader);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glAttachShader);
 }
 
 void Debug_glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint program;
         GLuint index;
@@ -89,14 +84,12 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(name), strlen(name) * sizeof(GLchar));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glBindAttribLocation);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBindAttribLocation);
 }
 
 void Debug_glBindBuffer(GLenum target, GLuint buffer)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLuint buffer;
@@ -113,14 +106,12 @@
     msg.set_arg0(target);
     msg.set_arg1(buffer);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glBindBuffer);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBindBuffer);
 }
 
 void Debug_glBindFramebuffer(GLenum target, GLuint framebuffer)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLuint framebuffer;
@@ -136,14 +127,12 @@
     msg.set_arg0(target);
     msg.set_arg1(framebuffer);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glBindFramebuffer);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBindFramebuffer);
 }
 
 void Debug_glBindRenderbuffer(GLenum target, GLuint renderbuffer)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLuint renderbuffer;
@@ -159,14 +148,12 @@
     msg.set_arg0(target);
     msg.set_arg1(renderbuffer);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glBindRenderbuffer);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBindRenderbuffer);
 }
 
 void Debug_glBindTexture(GLenum target, GLuint texture)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLuint texture;
@@ -182,14 +169,12 @@
     msg.set_arg0(target);
     msg.set_arg1(texture);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glBindTexture);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBindTexture);
 }
 
 void Debug_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLclampf red;
         GLclampf green;
@@ -211,14 +196,12 @@
     msg.set_arg2(ToInt(blue));
     msg.set_arg3(ToInt(alpha));
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glBlendColor);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBlendColor);
 }
 
 void Debug_glBlendEquation( GLenum mode )
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum mode;
 
@@ -231,14 +214,12 @@
 
     msg.set_arg0(mode);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glBlendEquation);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBlendEquation);
 }
 
 void Debug_glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum modeRGB;
         GLenum modeAlpha;
@@ -254,14 +235,12 @@
     msg.set_arg0(modeRGB);
     msg.set_arg1(modeAlpha);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glBlendEquationSeparate);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBlendEquationSeparate);
 }
 
 void Debug_glBlendFunc(GLenum sfactor, GLenum dfactor)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum sfactor;
         GLenum dfactor;
@@ -277,14 +256,12 @@
     msg.set_arg0(sfactor);
     msg.set_arg1(dfactor);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glBlendFunc);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBlendFunc);
 }
 
 void Debug_glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum srcRGB;
         GLenum dstRGB;
@@ -306,14 +283,12 @@
     msg.set_arg2(srcAlpha);
     msg.set_arg3(dstAlpha);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glBlendFuncSeparate);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBlendFuncSeparate);
 }
 
 void Debug_glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLsizeiptr size;
@@ -338,14 +313,12 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(data), size * sizeof(char));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glBufferData);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBufferData);
 }
 
 void Debug_glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLintptr offset;
@@ -370,14 +343,12 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(data), size * sizeof(char));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glBufferSubData);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBufferSubData);
 }
 
 GLenum Debug_glCheckFramebufferStatus(GLenum target)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
 
@@ -391,15 +362,13 @@
 
     msg.set_arg0(target);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glCheckFramebufferStatus);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCheckFramebufferStatus);
     return reinterpret_cast<GLenum>(ret);
 }
 
 void Debug_glClear(GLbitfield mask)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLbitfield mask;
 
@@ -412,14 +381,12 @@
 
     msg.set_arg0(mask);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glClear);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glClear);
 }
 
 void Debug_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLclampf red;
         GLclampf green;
@@ -441,14 +408,12 @@
     msg.set_arg2(ToInt(blue));
     msg.set_arg3(ToInt(alpha));
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glClearColor);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glClearColor);
 }
 
 void Debug_glClearDepthf(GLclampf depth)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLclampf depth;
 
@@ -461,14 +426,12 @@
 
     msg.set_arg0(ToInt(depth));
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glClearDepthf);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glClearDepthf);
 }
 
 void Debug_glClearStencil(GLint s)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLint s;
 
@@ -481,14 +444,12 @@
 
     msg.set_arg0(s);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glClearStencil);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glClearStencil);
 }
 
 void Debug_glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLboolean red;
         GLboolean green;
@@ -510,14 +471,12 @@
     msg.set_arg2(blue);
     msg.set_arg3(alpha);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glColorMask);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glColorMask);
 }
 
 void Debug_glCompileShader(GLuint shader)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint shader;
 
@@ -530,15 +489,13 @@
 
     msg.set_arg0(shader);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glCompileShader);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCompileShader);
 }
 
 // FIXME: this function has pointers, it should be hand written
 void Debug_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLint level;
@@ -573,15 +530,13 @@
     msg.set_arg7(ToInt(data));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glCompressedTexImage2D);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCompressedTexImage2D);
 }
 
 // FIXME: this function has pointers, it should be hand written
 void Debug_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLint level;
@@ -619,14 +574,12 @@
     msg.set_arg8(ToInt(data));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glCompressedTexSubImage2D);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCompressedTexSubImage2D);
 }
 
 void Debug_glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLint level;
@@ -661,14 +614,12 @@
     msg.set_arg7(border);
 
     EXTEND_Debug_glCopyTexImage2D;
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glCopyTexImage2D);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCopyTexImage2D);
 }
 
 void Debug_glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLint level;
@@ -703,14 +654,12 @@
     msg.set_arg7(height);
 
     EXTEND_Debug_glCopyTexSubImage2D;
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glCopyTexSubImage2D);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCopyTexSubImage2D);
 }
 
 GLuint Debug_glCreateProgram(void)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
 
         const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
@@ -721,15 +670,13 @@
     } caller;
 
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glCreateProgram);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCreateProgram);
     return reinterpret_cast<GLuint>(ret);
 }
 
 GLuint Debug_glCreateShader(GLenum type)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum type;
 
@@ -743,15 +690,13 @@
 
     msg.set_arg0(type);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glCreateShader);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCreateShader);
     return reinterpret_cast<GLuint>(ret);
 }
 
 void Debug_glCullFace(GLenum mode)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum mode;
 
@@ -764,14 +709,12 @@
 
     msg.set_arg0(mode);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glCullFace);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCullFace);
 }
 
 void Debug_glDeleteBuffers(GLsizei n, const GLuint* buffers)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLsizei n;
         const GLuint* buffers;
@@ -790,14 +733,12 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(buffers), n * sizeof(GLuint));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glDeleteBuffers);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDeleteBuffers);
 }
 
 void Debug_glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLsizei n;
         const GLuint* framebuffers;
@@ -815,14 +756,12 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(framebuffers), n * sizeof(GLuint));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glDeleteFramebuffers);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDeleteFramebuffers);
 }
 
 void Debug_glDeleteProgram(GLuint program)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint program;
 
@@ -835,14 +774,12 @@
 
     msg.set_arg0(program);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glDeleteProgram);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDeleteProgram);
 }
 
 void Debug_glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLsizei n;
         const GLuint* renderbuffers;
@@ -860,14 +797,12 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(renderbuffers), n * sizeof(GLuint));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glDeleteRenderbuffers);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDeleteRenderbuffers);
 }
 
 void Debug_glDeleteShader(GLuint shader)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint shader;
 
@@ -880,14 +815,12 @@
 
     msg.set_arg0(shader);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glDeleteShader);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDeleteShader);
 }
 
 void Debug_glDeleteTextures(GLsizei n, const GLuint* textures)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLsizei n;
         const GLuint* textures;
@@ -905,14 +838,12 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(textures), n * sizeof(GLuint));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glDeleteTextures);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDeleteTextures);
 }
 
 void Debug_glDepthFunc(GLenum func)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum func;
 
@@ -925,14 +856,12 @@
 
     msg.set_arg0(func);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glDepthFunc);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDepthFunc);
 }
 
 void Debug_glDepthMask(GLboolean flag)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLboolean flag;
 
@@ -945,14 +874,12 @@
 
     msg.set_arg0(flag);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glDepthMask);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDepthMask);
 }
 
 void Debug_glDepthRangef(GLclampf zNear, GLclampf zFar)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLclampf zNear;
         GLclampf zFar;
@@ -968,14 +895,12 @@
     msg.set_arg0(ToInt(zNear));
     msg.set_arg1(ToInt(zFar));
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glDepthRangef);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDepthRangef);
 }
 
 void Debug_glDetachShader(GLuint program, GLuint shader)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint program;
         GLuint shader;
@@ -991,14 +916,12 @@
     msg.set_arg0(program);
     msg.set_arg1(shader);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glDetachShader);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDetachShader);
 }
 
 void Debug_glDisable(GLenum cap)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum cap;
 
@@ -1011,14 +934,12 @@
 
     msg.set_arg0(cap);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glDisable);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDisable);
 }
 
 void Debug_glDisableVertexAttribArray(GLuint index)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint index;
 
@@ -1032,14 +953,12 @@
 
     msg.set_arg0(index);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glDisableVertexAttribArray);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDisableVertexAttribArray);
 }
 
 void Debug_glEnable(GLenum cap)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum cap;
 
@@ -1052,14 +971,12 @@
 
     msg.set_arg0(cap);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glEnable);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glEnable);
 }
 
 void Debug_glEnableVertexAttribArray(GLuint index)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint index;
 
@@ -1073,14 +990,12 @@
 
     msg.set_arg0(index);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glEnableVertexAttribArray);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glEnableVertexAttribArray);
 }
 
 void Debug_glFinish(void)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
 
         const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
@@ -1090,14 +1005,12 @@
     } caller;
 
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glFinish);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glFinish);
 }
 
 void Debug_glFlush(void)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
 
         const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
@@ -1107,14 +1020,12 @@
     } caller;
 
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glFlush);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glFlush);
 }
 
 void Debug_glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLenum attachment;
@@ -1136,14 +1047,12 @@
     msg.set_arg2(renderbuffertarget);
     msg.set_arg3(renderbuffer);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glFramebufferRenderbuffer);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glFramebufferRenderbuffer);
 }
 
 void Debug_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLenum attachment;
@@ -1168,14 +1077,12 @@
     msg.set_arg3(texture);
     msg.set_arg4(level);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glFramebufferTexture2D);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glFramebufferTexture2D);
 }
 
 void Debug_glFrontFace(GLenum mode)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum mode;
 
@@ -1188,14 +1095,12 @@
 
     msg.set_arg0(mode);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glFrontFace);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glFrontFace);
 }
 
 void Debug_glGenBuffers(GLsizei n, GLuint* buffers)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLsizei n;
         GLuint* buffers;
@@ -1215,14 +1120,12 @@
     msg.set_arg1(ToInt(buffers));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGenBuffers);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGenBuffers);
 }
 
 void Debug_glGenerateMipmap(GLenum target)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
 
@@ -1235,14 +1138,12 @@
 
     msg.set_arg0(target);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGenerateMipmap);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGenerateMipmap);
 }
 
 void Debug_glGenFramebuffers(GLsizei n, GLuint* framebuffers)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLsizei n;
         GLuint* framebuffers;
@@ -1262,14 +1163,12 @@
     msg.set_arg1(ToInt(framebuffers));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGenFramebuffers);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGenFramebuffers);
 }
 
 void Debug_glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLsizei n;
         GLuint* renderbuffers;
@@ -1289,14 +1188,12 @@
     msg.set_arg1(ToInt(renderbuffers));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGenRenderbuffers);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGenRenderbuffers);
 }
 
 void Debug_glGenTextures(GLsizei n, GLuint* textures)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLsizei n;
         GLuint* textures;
@@ -1316,15 +1213,13 @@
     msg.set_arg1(ToInt(textures));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGenTextures);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGenTextures);
 }
 
 // FIXME: this function has pointers, it should be hand written
 void Debug_glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint program;
         GLuint index;
@@ -1357,15 +1252,13 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(name), strlen(name) * sizeof(GLchar));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetActiveAttrib);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetActiveAttrib);
 }
 
 // FIXME: this function has pointers, it should be hand written
 void Debug_glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint program;
         GLuint index;
@@ -1398,15 +1291,13 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(name), strlen(name) * sizeof(GLchar));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetActiveUniform);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetActiveUniform);
 }
 
 // FIXME: this function has pointers, it should be hand written
 void Debug_glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint program;
         GLsizei maxcount;
@@ -1429,14 +1320,12 @@
     msg.set_arg3(ToInt(shaders));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetAttachedShaders);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetAttachedShaders);
 }
 
 int Debug_glGetAttribLocation(GLuint program, const GLchar* name)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint program;
         const GLchar* name;
@@ -1455,8 +1344,7 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(name), strlen(name) * sizeof(GLchar));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetAttribLocation);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetAttribLocation);
     return reinterpret_cast<int>(ret);
 }
 
@@ -1464,7 +1352,6 @@
 void Debug_glGetBooleanv(GLenum pname, GLboolean* params)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum pname;
         GLboolean* params;
@@ -1481,15 +1368,13 @@
     msg.set_arg1(ToInt(params));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetBooleanv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetBooleanv);
 }
 
 // FIXME: this function has pointers, it should be hand written
 void Debug_glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLenum pname;
@@ -1509,14 +1394,12 @@
     msg.set_arg2(ToInt(params));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetBufferParameteriv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetBufferParameteriv);
 }
 
 GLenum Debug_glGetError(void)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
 
         const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
@@ -1527,8 +1410,7 @@
     } caller;
 
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetError);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetError);
     return reinterpret_cast<GLenum>(ret);
 }
 
@@ -1536,7 +1418,6 @@
 void Debug_glGetFloatv(GLenum pname, GLfloat* params)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum pname;
         GLfloat* params;
@@ -1553,15 +1434,13 @@
     msg.set_arg1(ToInt(params));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetFloatv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetFloatv);
 }
 
 // FIXME: this function has pointers, it should be hand written
 void Debug_glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLenum attachment;
@@ -1584,15 +1463,13 @@
     msg.set_arg3(ToInt(params));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetFramebufferAttachmentParameteriv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetFramebufferAttachmentParameteriv);
 }
 
 // FIXME: this function has pointers, it should be hand written
 void Debug_glGetIntegerv(GLenum pname, GLint* params)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum pname;
         GLint* params;
@@ -1609,14 +1486,12 @@
     msg.set_arg1(ToInt(params));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetIntegerv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetIntegerv);
 }
 
 void Debug_glGetProgramiv(GLuint program, GLenum pname, GLint* params)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint program;
         GLenum pname;
@@ -1639,15 +1514,13 @@
     msg.set_arg2(ToInt(params));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetProgramiv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetProgramiv);
 }
 
 // FIXME: this function has pointers, it should be hand written
 void Debug_glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint program;
         GLsizei bufsize;
@@ -1673,15 +1546,13 @@
     msg.set_arg3(ToInt(infolog));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetProgramInfoLog);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetProgramInfoLog);
 }
 
 // FIXME: this function has pointers, it should be hand written
 void Debug_glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLenum pname;
@@ -1701,14 +1572,12 @@
     msg.set_arg2(ToInt(params));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetRenderbufferParameteriv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetRenderbufferParameteriv);
 }
 
 void Debug_glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint shader;
         GLenum pname;
@@ -1731,15 +1600,13 @@
     msg.set_arg2(ToInt(params));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetShaderiv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetShaderiv);
 }
 
 // FIXME: this function has pointers, it should be hand written
 void Debug_glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint shader;
         GLsizei bufsize;
@@ -1765,15 +1632,13 @@
     msg.set_arg3(ToInt(infolog));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetShaderInfoLog);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetShaderInfoLog);
 }
 
 // FIXME: this function has pointers, it should be hand written
 void Debug_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum shadertype;
         GLenum precisiontype;
@@ -1796,15 +1661,13 @@
     msg.set_arg3(ToInt(precision));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetShaderPrecisionFormat);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetShaderPrecisionFormat);
 }
 
 // FIXME: this function has pointers, it should be hand written
 void Debug_glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint shader;
         GLsizei bufsize;
@@ -1830,15 +1693,13 @@
     msg.set_arg3(ToInt(source));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetShaderSource);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetShaderSource);
 }
 
 // FIXME: this function has pointers, it should be hand written
 const GLubyte* Debug_glGetString(GLenum name)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum name;
 
@@ -1853,8 +1714,7 @@
     msg.set_arg0(name);
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetString);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetString);
     return reinterpret_cast<const GLubyte*>(ret);
 }
 
@@ -1862,7 +1722,6 @@
 void Debug_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLenum pname;
@@ -1882,15 +1741,13 @@
     msg.set_arg2(ToInt(params));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetTexParameterfv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetTexParameterfv);
 }
 
 // FIXME: this function has pointers, it should be hand written
 void Debug_glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLenum pname;
@@ -1910,15 +1767,13 @@
     msg.set_arg2(ToInt(params));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetTexParameteriv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetTexParameteriv);
 }
 
 // FIXME: this function has pointers, it should be hand written
 void Debug_glGetUniformfv(GLuint program, GLint location, GLfloat* params)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint program;
         GLint location;
@@ -1938,15 +1793,13 @@
     msg.set_arg2(ToInt(params));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetUniformfv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetUniformfv);
 }
 
 // FIXME: this function has pointers, it should be hand written
 void Debug_glGetUniformiv(GLuint program, GLint location, GLint* params)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint program;
         GLint location;
@@ -1966,14 +1819,12 @@
     msg.set_arg2(ToInt(params));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetUniformiv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetUniformiv);
 }
 
 int Debug_glGetUniformLocation(GLuint program, const GLchar* name)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint program;
         const GLchar* name;
@@ -1992,8 +1843,7 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(name), strlen(name) * sizeof(GLchar));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetUniformLocation);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetUniformLocation);
     return reinterpret_cast<int>(ret);
 }
 
@@ -2001,7 +1851,6 @@
 void Debug_glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint index;
         GLenum pname;
@@ -2021,15 +1870,13 @@
     msg.set_arg2(ToInt(params));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetVertexAttribfv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetVertexAttribfv);
 }
 
 // FIXME: this function has pointers, it should be hand written
 void Debug_glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint index;
         GLenum pname;
@@ -2049,15 +1896,13 @@
     msg.set_arg2(ToInt(params));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetVertexAttribiv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetVertexAttribiv);
 }
 
 // FIXME: this function has pointers, it should be hand written
 void Debug_glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint index;
         GLenum pname;
@@ -2077,14 +1922,12 @@
     msg.set_arg2(ToInt(pointer));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glGetVertexAttribPointerv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetVertexAttribPointerv);
 }
 
 void Debug_glHint(GLenum target, GLenum mode)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLenum mode;
@@ -2100,14 +1943,12 @@
     msg.set_arg0(target);
     msg.set_arg1(mode);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glHint);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glHint);
 }
 
 GLboolean Debug_glIsBuffer(GLuint buffer)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint buffer;
 
@@ -2121,15 +1962,13 @@
 
     msg.set_arg0(buffer);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glIsBuffer);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glIsBuffer);
     return static_cast<GLboolean>(reinterpret_cast<int>(ret));
 }
 
 GLboolean Debug_glIsEnabled(GLenum cap)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum cap;
 
@@ -2143,15 +1982,13 @@
 
     msg.set_arg0(cap);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glIsEnabled);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glIsEnabled);
     return static_cast<GLboolean>(reinterpret_cast<int>(ret));
 }
 
 GLboolean Debug_glIsFramebuffer(GLuint framebuffer)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint framebuffer;
 
@@ -2165,15 +2002,13 @@
 
     msg.set_arg0(framebuffer);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glIsFramebuffer);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glIsFramebuffer);
     return static_cast<GLboolean>(reinterpret_cast<int>(ret));
 }
 
 GLboolean Debug_glIsProgram(GLuint program)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint program;
 
@@ -2187,15 +2022,13 @@
 
     msg.set_arg0(program);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glIsProgram);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glIsProgram);
     return static_cast<GLboolean>(reinterpret_cast<int>(ret));
 }
 
 GLboolean Debug_glIsRenderbuffer(GLuint renderbuffer)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint renderbuffer;
 
@@ -2209,15 +2042,13 @@
 
     msg.set_arg0(renderbuffer);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glIsRenderbuffer);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glIsRenderbuffer);
     return static_cast<GLboolean>(reinterpret_cast<int>(ret));
 }
 
 GLboolean Debug_glIsShader(GLuint shader)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint shader;
 
@@ -2231,15 +2062,13 @@
 
     msg.set_arg0(shader);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glIsShader);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glIsShader);
     return static_cast<GLboolean>(reinterpret_cast<int>(ret));
 }
 
 GLboolean Debug_glIsTexture(GLuint texture)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint texture;
 
@@ -2253,15 +2082,13 @@
 
     msg.set_arg0(texture);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glIsTexture);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glIsTexture);
     return static_cast<GLboolean>(reinterpret_cast<int>(ret));
 }
 
 void Debug_glLineWidth(GLfloat width)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLfloat width;
 
@@ -2274,14 +2101,12 @@
 
     msg.set_arg0(ToInt(width));
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glLineWidth);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glLineWidth);
 }
 
 void Debug_glLinkProgram(GLuint program)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint program;
 
@@ -2294,14 +2119,12 @@
 
     msg.set_arg0(program);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glLinkProgram);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glLinkProgram);
 }
 
 void Debug_glPixelStorei(GLenum pname, GLint param)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum pname;
         GLint param;
@@ -2317,14 +2140,12 @@
     msg.set_arg0(pname);
     msg.set_arg1(param);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glPixelStorei);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glPixelStorei);
 }
 
 void Debug_glPolygonOffset(GLfloat factor, GLfloat units)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLfloat factor;
         GLfloat units;
@@ -2340,14 +2161,12 @@
     msg.set_arg0(ToInt(factor));
     msg.set_arg1(ToInt(units));
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glPolygonOffset);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glPolygonOffset);
 }
 
 void Debug_glReleaseShaderCompiler(void)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
 
         const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
@@ -2357,14 +2176,12 @@
     } caller;
 
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glReleaseShaderCompiler);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glReleaseShaderCompiler);
 }
 
 void Debug_glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLenum internalformat;
@@ -2386,14 +2203,12 @@
     msg.set_arg2(width);
     msg.set_arg3(height);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glRenderbufferStorage);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glRenderbufferStorage);
 }
 
 void Debug_glSampleCoverage(GLclampf value, GLboolean invert)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLclampf value;
         GLboolean invert;
@@ -2409,14 +2224,12 @@
     msg.set_arg0(ToInt(value));
     msg.set_arg1(invert);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glSampleCoverage);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glSampleCoverage);
 }
 
 void Debug_glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLint x;
         GLint y;
@@ -2438,15 +2251,13 @@
     msg.set_arg2(width);
     msg.set_arg3(height);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glScissor);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glScissor);
 }
 
 // FIXME: this function has pointers, it should be hand written
 void Debug_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLsizei n;
         const GLuint* shaders;
@@ -2472,14 +2283,12 @@
     msg.set_arg4(length);
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glShaderBinary);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glShaderBinary);
 }
 
 void Debug_glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint shader;
         GLsizei count;
@@ -2503,14 +2312,12 @@
 
     // FIXME: check for pointer usage
     EXTEND_Debug_glShaderSource;
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glShaderSource);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glShaderSource);
 }
 
 void Debug_glStencilFunc(GLenum func, GLint ref, GLuint mask)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum func;
         GLint ref;
@@ -2529,14 +2336,12 @@
     msg.set_arg1(ref);
     msg.set_arg2(mask);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glStencilFunc);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glStencilFunc);
 }
 
 void Debug_glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum face;
         GLenum func;
@@ -2558,14 +2363,12 @@
     msg.set_arg2(ref);
     msg.set_arg3(mask);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glStencilFuncSeparate);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glStencilFuncSeparate);
 }
 
 void Debug_glStencilMask(GLuint mask)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint mask;
 
@@ -2578,14 +2381,12 @@
 
     msg.set_arg0(mask);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glStencilMask);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glStencilMask);
 }
 
 void Debug_glStencilMaskSeparate(GLenum face, GLuint mask)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum face;
         GLuint mask;
@@ -2601,14 +2402,12 @@
     msg.set_arg0(face);
     msg.set_arg1(mask);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glStencilMaskSeparate);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glStencilMaskSeparate);
 }
 
 void Debug_glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum fail;
         GLenum zfail;
@@ -2627,14 +2426,12 @@
     msg.set_arg1(zfail);
     msg.set_arg2(zpass);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glStencilOp);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glStencilOp);
 }
 
 void Debug_glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum face;
         GLenum fail;
@@ -2656,14 +2453,56 @@
     msg.set_arg2(zfail);
     msg.set_arg3(zpass);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glStencilOpSeparate);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glStencilOpSeparate);
+}
+
+void Debug_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+    glesv2debugger::Message msg;
+    struct : public FunctionCall {
+        GLenum target;
+        GLint level;
+        GLint internalformat;
+        GLsizei width;
+        GLsizei height;
+        GLint border;
+        GLenum format;
+        GLenum type;
+        const GLvoid* pixels;
+
+        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+            _c->glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+            return 0;
+        }
+    } caller;
+    caller.target = target;
+    caller.level = level;
+    caller.internalformat = internalformat;
+    caller.width = width;
+    caller.height = height;
+    caller.border = border;
+    caller.format = format;
+    caller.type = type;
+    caller.pixels = pixels;
+
+    msg.set_arg0(target);
+    msg.set_arg1(level);
+    msg.set_arg2(internalformat);
+    msg.set_arg3(width);
+    msg.set_arg4(height);
+    msg.set_arg5(border);
+    msg.set_arg6(format);
+    msg.set_arg7(type);
+    msg.set_arg8(ToInt(pixels));
+
+    // FIXME: check for pointer usage
+    EXTEND_Debug_glTexImage2D;
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glTexImage2D);
 }
 
 void Debug_glTexParameterf(GLenum target, GLenum pname, GLfloat param)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLenum pname;
@@ -2682,15 +2521,13 @@
     msg.set_arg1(pname);
     msg.set_arg2(ToInt(param));
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glTexParameterf);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glTexParameterf);
 }
 
 // FIXME: this function has pointers, it should be hand written
 void Debug_glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLenum pname;
@@ -2710,14 +2547,12 @@
     msg.set_arg2(ToInt(params));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glTexParameterfv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glTexParameterfv);
 }
 
 void Debug_glTexParameteri(GLenum target, GLenum pname, GLint param)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLenum pname;
@@ -2736,15 +2571,13 @@
     msg.set_arg1(pname);
     msg.set_arg2(param);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glTexParameteri);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glTexParameteri);
 }
 
 // FIXME: this function has pointers, it should be hand written
 void Debug_glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLenum target;
         GLenum pname;
@@ -2764,14 +2597,56 @@
     msg.set_arg2(ToInt(params));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glTexParameteriv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glTexParameteriv);
+}
+
+void Debug_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels)
+{
+    glesv2debugger::Message msg;
+    struct : public FunctionCall {
+        GLenum target;
+        GLint level;
+        GLint xoffset;
+        GLint yoffset;
+        GLsizei width;
+        GLsizei height;
+        GLenum format;
+        GLenum type;
+        const GLvoid* pixels;
+
+        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
+            _c->glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+            return 0;
+        }
+    } caller;
+    caller.target = target;
+    caller.level = level;
+    caller.xoffset = xoffset;
+    caller.yoffset = yoffset;
+    caller.width = width;
+    caller.height = height;
+    caller.format = format;
+    caller.type = type;
+    caller.pixels = pixels;
+
+    msg.set_arg0(target);
+    msg.set_arg1(level);
+    msg.set_arg2(xoffset);
+    msg.set_arg3(yoffset);
+    msg.set_arg4(width);
+    msg.set_arg5(height);
+    msg.set_arg6(format);
+    msg.set_arg7(type);
+    msg.set_arg8(ToInt(pixels));
+
+    // FIXME: check for pointer usage
+    EXTEND_Debug_glTexSubImage2D;
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glTexSubImage2D);
 }
 
 void Debug_glUniform1f(GLint location, GLfloat x)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLint location;
         GLfloat x;
@@ -2787,14 +2662,12 @@
     msg.set_arg0(location);
     msg.set_arg1(ToInt(x));
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glUniform1f);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform1f);
 }
 
 void Debug_glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLint location;
         GLsizei count;
@@ -2815,14 +2688,12 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 1*count * sizeof(GLfloat));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glUniform1fv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform1fv);
 }
 
 void Debug_glUniform1i(GLint location, GLint x)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLint location;
         GLint x;
@@ -2838,14 +2709,12 @@
     msg.set_arg0(location);
     msg.set_arg1(x);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glUniform1i);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform1i);
 }
 
 void Debug_glUniform1iv(GLint location, GLsizei count, const GLint* v)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLint location;
         GLsizei count;
@@ -2866,14 +2735,12 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 1*count * sizeof(GLint));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glUniform1iv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform1iv);
 }
 
 void Debug_glUniform2f(GLint location, GLfloat x, GLfloat y)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLint location;
         GLfloat x;
@@ -2892,14 +2759,12 @@
     msg.set_arg1(ToInt(x));
     msg.set_arg2(ToInt(y));
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glUniform2f);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform2f);
 }
 
 void Debug_glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLint location;
         GLsizei count;
@@ -2920,14 +2785,12 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 2*count * sizeof(GLfloat));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glUniform2fv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform2fv);
 }
 
 void Debug_glUniform2i(GLint location, GLint x, GLint y)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLint location;
         GLint x;
@@ -2946,14 +2809,12 @@
     msg.set_arg1(x);
     msg.set_arg2(y);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glUniform2i);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform2i);
 }
 
 void Debug_glUniform2iv(GLint location, GLsizei count, const GLint* v)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLint location;
         GLsizei count;
@@ -2974,14 +2835,12 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 2*count * sizeof(GLint));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glUniform2iv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform2iv);
 }
 
 void Debug_glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLint location;
         GLfloat x;
@@ -3003,14 +2862,12 @@
     msg.set_arg2(ToInt(y));
     msg.set_arg3(ToInt(z));
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glUniform3f);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform3f);
 }
 
 void Debug_glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLint location;
         GLsizei count;
@@ -3031,14 +2888,12 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 3*count * sizeof(GLfloat));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glUniform3fv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform3fv);
 }
 
 void Debug_glUniform3i(GLint location, GLint x, GLint y, GLint z)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLint location;
         GLint x;
@@ -3060,14 +2915,12 @@
     msg.set_arg2(y);
     msg.set_arg3(z);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glUniform3i);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform3i);
 }
 
 void Debug_glUniform3iv(GLint location, GLsizei count, const GLint* v)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLint location;
         GLsizei count;
@@ -3088,14 +2941,12 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 3*count * sizeof(GLint));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glUniform3iv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform3iv);
 }
 
 void Debug_glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLint location;
         GLfloat x;
@@ -3120,14 +2971,12 @@
     msg.set_arg3(ToInt(z));
     msg.set_arg4(ToInt(w));
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glUniform4f);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform4f);
 }
 
 void Debug_glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLint location;
         GLsizei count;
@@ -3148,14 +2997,12 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 4*count * sizeof(GLfloat));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glUniform4fv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform4fv);
 }
 
 void Debug_glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLint location;
         GLint x;
@@ -3180,14 +3027,12 @@
     msg.set_arg3(z);
     msg.set_arg4(w);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glUniform4i);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform4i);
 }
 
 void Debug_glUniform4iv(GLint location, GLsizei count, const GLint* v)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLint location;
         GLsizei count;
@@ -3208,14 +3053,12 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 4*count * sizeof(GLint));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glUniform4iv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform4iv);
 }
 
 void Debug_glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLint location;
         GLsizei count;
@@ -3239,14 +3082,12 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(value), 4*count * sizeof(GLfloat));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glUniformMatrix2fv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniformMatrix2fv);
 }
 
 void Debug_glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLint location;
         GLsizei count;
@@ -3270,14 +3111,12 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(value), 9*count * sizeof(GLfloat));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glUniformMatrix3fv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniformMatrix3fv);
 }
 
 void Debug_glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLint location;
         GLsizei count;
@@ -3301,14 +3140,12 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(value), 16*count * sizeof(GLfloat));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glUniformMatrix4fv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniformMatrix4fv);
 }
 
 void Debug_glUseProgram(GLuint program)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint program;
 
@@ -3322,14 +3159,12 @@
 
     msg.set_arg0(program);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glUseProgram);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUseProgram);
 }
 
 void Debug_glValidateProgram(GLuint program)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint program;
 
@@ -3342,14 +3177,12 @@
 
     msg.set_arg0(program);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glValidateProgram);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glValidateProgram);
 }
 
 void Debug_glVertexAttrib1f(GLuint indx, GLfloat x)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint indx;
         GLfloat x;
@@ -3365,14 +3198,12 @@
     msg.set_arg0(indx);
     msg.set_arg1(ToInt(x));
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glVertexAttrib1f);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib1f);
 }
 
 void Debug_glVertexAttrib1fv(GLuint indx, const GLfloat* values)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint indx;
         const GLfloat* values;
@@ -3390,14 +3221,12 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(values), 1 * sizeof(GLfloat));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glVertexAttrib1fv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib1fv);
 }
 
 void Debug_glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint indx;
         GLfloat x;
@@ -3416,14 +3245,12 @@
     msg.set_arg1(ToInt(x));
     msg.set_arg2(ToInt(y));
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glVertexAttrib2f);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib2f);
 }
 
 void Debug_glVertexAttrib2fv(GLuint indx, const GLfloat* values)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint indx;
         const GLfloat* values;
@@ -3441,14 +3268,12 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(values), 2 * sizeof(GLfloat));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glVertexAttrib2fv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib2fv);
 }
 
 void Debug_glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint indx;
         GLfloat x;
@@ -3470,14 +3295,12 @@
     msg.set_arg2(ToInt(y));
     msg.set_arg3(ToInt(z));
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glVertexAttrib3f);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib3f);
 }
 
 void Debug_glVertexAttrib3fv(GLuint indx, const GLfloat* values)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint indx;
         const GLfloat* values;
@@ -3495,14 +3318,12 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(values), 3 * sizeof(GLfloat));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glVertexAttrib3fv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib3fv);
 }
 
 void Debug_glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint indx;
         GLfloat x;
@@ -3527,14 +3348,12 @@
     msg.set_arg3(ToInt(z));
     msg.set_arg4(ToInt(w));
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glVertexAttrib4f);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib4f);
 }
 
 void Debug_glVertexAttrib4fv(GLuint indx, const GLfloat* values)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint indx;
         const GLfloat* values;
@@ -3552,15 +3371,13 @@
 
     // FIXME: check for pointer usage
     msg.mutable_data()->assign(reinterpret_cast<const char *>(values), 4 * sizeof(GLfloat));
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glVertexAttrib4fv);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib4fv);
 }
 
 // FIXME: this function has pointers, it should be hand written
 void Debug_glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLuint indx;
         GLint size;
@@ -3590,14 +3407,12 @@
     msg.set_arg5(ToInt(ptr));
 
     // FIXME: check for pointer usage
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glVertexAttribPointer);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttribPointer);
 }
 
 void Debug_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         GLint x;
         GLint y;
@@ -3619,8 +3434,7 @@
     msg.set_arg2(width);
     msg.set_arg3(height);
 
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glViewport);
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glViewport);
 }
 
 // FIXME: the following functions should be written by hand
diff --git a/opengl/libs/GLES2_dbg/src/api.h b/opengl/libs/GLES2_dbg/src/api.h
index be94dfc..b9fc341 100644
--- a/opengl/libs/GLES2_dbg/src/api.h
+++ b/opengl/libs/GLES2_dbg/src/api.h
@@ -15,11 +15,18 @@
  */
 
 #define EXTEND_Debug_glCopyTexImage2D \
-    void * pixels = malloc(width * height * 4); \
-    getGLTraceThreadSpecific()->gl.glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); \
-    msg.set_data(pixels, width * height * 4); \
-    free(pixels);
-    
+    DbgContext * const dbg = getDbgContextThreadSpecific(); \
+    GLint readFormat, readType; \
+    dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat); \
+    dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType); \
+    unsigned readSize = GetBytesPerPixel(readFormat, readType) * width * height; \
+    void * readData = dbg->GetReadPixelsBuffer(readSize); \
+    dbg->hooks->gl.glReadPixels(x, y, width, height, readFormat, readType, readData); \
+    dbg->CompressReadPixelBuffer(msg.mutable_data()); \
+    msg.set_data_type(msg.ReferencedImage); \
+    msg.set_pixel_format(readFormat); \
+    msg.set_pixel_type(readType);
+
 #define EXTEND_Debug_glCopyTexSubImage2D EXTEND_Debug_glCopyTexImage2D
 
 #define EXTEND_Debug_glShaderSource \
@@ -28,4 +35,14 @@
         if (!length || length[i] < 0) \
             data->append(string[i]); \
         else \
-            data->append(string[i], length[i]);
\ No newline at end of file
+            data->append(string[i], length[i]);
+
+#define EXTEND_Debug_glTexImage2D \
+    if (pixels) { \
+        DbgContext * const dbg = getDbgContextThreadSpecific(); \
+        const unsigned size = GetBytesPerPixel(format, type) * width * height; \
+        assert(0 < size); \
+        dbg->Compress(pixels, size, msg.mutable_data()); \
+    }
+
+#define EXTEND_Debug_glTexSubImage2D EXTEND_Debug_glTexImage2D
diff --git a/opengl/libs/GLES2_dbg/src/caller.cpp b/opengl/libs/GLES2_dbg/src/caller.cpp
new file mode 100644
index 0000000..9992f05
--- /dev/null
+++ b/opengl/libs/GLES2_dbg/src/caller.cpp
@@ -0,0 +1,779 @@
+/*
+ ** 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_caller_cpp.py
+// implement declarations in caller.h
+
+#include "header.h"
+
+namespace android {
+
+static const int * GenerateCall_glCompressedTexImage2D(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glCompressedTexSubImage2D(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glDrawElements(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGenBuffers(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGenFramebuffers(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGenRenderbuffers(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGenTextures(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetActiveAttrib(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetActiveUniform(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetAttachedShaders(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetBooleanv(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetBufferParameteriv(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetFloatv(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetFramebufferAttachmentParameteriv(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetIntegerv(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetProgramiv(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetProgramInfoLog(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetRenderbufferParameteriv(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetShaderiv(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetShaderInfoLog(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetShaderPrecisionFormat(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetShaderSource(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetString(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetTexParameterfv(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetTexParameteriv(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetUniformfv(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetUniformiv(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetVertexAttribfv(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetVertexAttribiv(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glGetVertexAttribPointerv(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glReadPixels(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glShaderBinary(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glShaderSource(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glTexImage2D(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glTexParameterfv(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glTexParameteriv(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glTexSubImage2D(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+static const int * GenerateCall_glVertexAttribPointer(DbgContext * const dbg,
+    const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
+
+#include "caller.h"
+
+const int * GenerateCall(DbgContext * const dbg, const glesv2debugger::Message & cmd,
+                  glesv2debugger::Message & msg, const int * const prevRet)
+{
+    LOGD("GenerateCall function=%u", cmd.function());
+    const int * ret = prevRet; // only some functions have return value
+    gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl;
+    nsecs_t c0 = systemTime(timeMode);
+    switch (cmd.function()) {    case glesv2debugger::Message_Function_glActiveTexture:
+        dbg->hooks->gl.glActiveTexture(
+            static_cast<GLenum>(cmd.arg0()));
+        break;
+    case glesv2debugger::Message_Function_glAttachShader:
+        dbg->hooks->gl.glAttachShader(
+            static_cast<GLuint>(cmd.arg0()), static_cast<GLuint>(cmd.arg1())
+            );
+        break;
+    case glesv2debugger::Message_Function_glBindAttribLocation:
+        dbg->hooks->gl.glBindAttribLocation(
+            static_cast<GLuint>(cmd.arg0()), static_cast<GLuint>(cmd.arg1()), 
+            reinterpret_cast<GLchar*>(const_cast<char *>(cmd.data().data()))
+            );
+        break;
+    case glesv2debugger::Message_Function_glBindBuffer:
+        dbg->hooks->gl.glBindBuffer(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLuint>(cmd.arg1())
+            );
+        break;
+    case glesv2debugger::Message_Function_glBindFramebuffer:
+        dbg->hooks->gl.glBindFramebuffer(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLuint>(cmd.arg1())
+            );
+        break;
+    case glesv2debugger::Message_Function_glBindRenderbuffer:
+        dbg->hooks->gl.glBindRenderbuffer(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLuint>(cmd.arg1())
+            );
+        break;
+    case glesv2debugger::Message_Function_glBindTexture:
+        dbg->hooks->gl.glBindTexture(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLuint>(cmd.arg1())
+            );
+        break;
+    case glesv2debugger::Message_Function_glBlendColor:
+        dbg->hooks->gl.glBlendColor(
+            static_cast<GLclampf>(cmd.arg0()), static_cast<GLclampf>(cmd.arg1()), 
+            static_cast<GLclampf>(cmd.arg2()), static_cast<GLclampf>(cmd.arg3())
+            );
+        break;
+    case glesv2debugger::Message_Function_glBlendEquation:
+        dbg->hooks->gl.glBlendEquation(
+            static_cast<GLenum>(cmd.arg0()));
+        break;
+    case glesv2debugger::Message_Function_glBlendEquationSeparate:
+        dbg->hooks->gl.glBlendEquationSeparate(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1())
+            );
+        break;
+    case glesv2debugger::Message_Function_glBlendFunc:
+        dbg->hooks->gl.glBlendFunc(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1())
+            );
+        break;
+    case glesv2debugger::Message_Function_glBlendFuncSeparate:
+        dbg->hooks->gl.glBlendFuncSeparate(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1()), 
+            static_cast<GLenum>(cmd.arg2()), static_cast<GLenum>(cmd.arg3())
+            );
+        break;
+    case glesv2debugger::Message_Function_glBufferData:
+        dbg->hooks->gl.glBufferData(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLsizeiptr>(cmd.arg1()), 
+            reinterpret_cast<GLvoid*>(const_cast<char *>(cmd.data().data())), 
+            static_cast<GLenum>(cmd.arg3()));
+        break;
+    case glesv2debugger::Message_Function_glBufferSubData:
+        dbg->hooks->gl.glBufferSubData(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLintptr>(cmd.arg1()), 
+            static_cast<GLsizeiptr>(cmd.arg2()), reinterpret_cast<GLvoid*>(const_cast<char *>(cmd.data().data()))
+            );
+        break;
+    case glesv2debugger::Message_Function_glCheckFramebufferStatus:
+        msg.set_ret(static_cast<int>(dbg->hooks->gl.glCheckFramebufferStatus(
+            static_cast<GLenum>(cmd.arg0()))));
+        if (cmd.has_ret())
+            ret = reinterpret_cast<int *>(msg.ret());
+        break;
+    case glesv2debugger::Message_Function_glClear:
+        dbg->hooks->gl.glClear(
+            static_cast<GLbitfield>(cmd.arg0()));
+        break;
+    case glesv2debugger::Message_Function_glClearColor:
+        dbg->hooks->gl.glClearColor(
+            static_cast<GLclampf>(cmd.arg0()), static_cast<GLclampf>(cmd.arg1()), 
+            static_cast<GLclampf>(cmd.arg2()), static_cast<GLclampf>(cmd.arg3())
+            );
+        break;
+    case glesv2debugger::Message_Function_glClearDepthf:
+        dbg->hooks->gl.glClearDepthf(
+            static_cast<GLclampf>(cmd.arg0()));
+        break;
+    case glesv2debugger::Message_Function_glClearStencil:
+        dbg->hooks->gl.glClearStencil(
+            static_cast<GLint>(cmd.arg0()));
+        break;
+    case glesv2debugger::Message_Function_glColorMask:
+        dbg->hooks->gl.glColorMask(
+            GLboolean(cmd.arg0()), GLboolean(cmd.arg1()), GLboolean(cmd.arg2()), 
+            GLboolean(cmd.arg3()));
+        break;
+    case glesv2debugger::Message_Function_glCompileShader:
+        dbg->hooks->gl.glCompileShader(
+            static_cast<GLuint>(cmd.arg0()));
+        break;
+    case glesv2debugger::Message_Function_glCompressedTexImage2D:
+        ret = GenerateCall_glCompressedTexImage2D(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glCompressedTexSubImage2D:
+        ret = GenerateCall_glCompressedTexSubImage2D(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glCopyTexImage2D:
+        dbg->hooks->gl.glCopyTexImage2D(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLint>(cmd.arg1()), 
+            static_cast<GLenum>(cmd.arg2()), static_cast<GLint>(cmd.arg3()), 
+            static_cast<GLint>(cmd.arg4()), static_cast<GLsizei>(cmd.arg5()), 
+            static_cast<GLsizei>(cmd.arg6()), static_cast<GLint>(cmd.arg7())
+            );
+        break;
+    case glesv2debugger::Message_Function_glCopyTexSubImage2D:
+        dbg->hooks->gl.glCopyTexSubImage2D(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLint>(cmd.arg1()), 
+            static_cast<GLint>(cmd.arg2()), static_cast<GLint>(cmd.arg3()), 
+            static_cast<GLint>(cmd.arg4()), static_cast<GLint>(cmd.arg5()), 
+            static_cast<GLsizei>(cmd.arg6()), static_cast<GLsizei>(cmd.arg7())
+            );
+        break;
+    case glesv2debugger::Message_Function_glCreateProgram:
+        msg.set_ret(static_cast<int>(dbg->hooks->gl.glCreateProgram(
+            )));
+        if (cmd.has_ret())
+            ret = reinterpret_cast<int *>(msg.ret());
+        break;
+    case glesv2debugger::Message_Function_glCreateShader:
+        msg.set_ret(static_cast<int>(dbg->hooks->gl.glCreateShader(
+            static_cast<GLenum>(cmd.arg0()))));
+        if (cmd.has_ret())
+            ret = reinterpret_cast<int *>(msg.ret());
+        break;
+    case glesv2debugger::Message_Function_glCullFace:
+        dbg->hooks->gl.glCullFace(
+            static_cast<GLenum>(cmd.arg0()));
+        break;
+    case glesv2debugger::Message_Function_glDeleteBuffers:
+        dbg->hooks->gl.glDeleteBuffers(
+            static_cast<GLsizei>(cmd.arg0()), reinterpret_cast<GLuint*>(const_cast<char *>(cmd.data().data()))
+            );
+        break;
+    case glesv2debugger::Message_Function_glDeleteFramebuffers:
+        dbg->hooks->gl.glDeleteFramebuffers(
+            static_cast<GLsizei>(cmd.arg0()), reinterpret_cast<GLuint*>(const_cast<char *>(cmd.data().data()))
+            );
+        break;
+    case glesv2debugger::Message_Function_glDeleteProgram:
+        dbg->hooks->gl.glDeleteProgram(
+            static_cast<GLuint>(cmd.arg0()));
+        break;
+    case glesv2debugger::Message_Function_glDeleteRenderbuffers:
+        dbg->hooks->gl.glDeleteRenderbuffers(
+            static_cast<GLsizei>(cmd.arg0()), reinterpret_cast<GLuint*>(const_cast<char *>(cmd.data().data()))
+            );
+        break;
+    case glesv2debugger::Message_Function_glDeleteShader:
+        dbg->hooks->gl.glDeleteShader(
+            static_cast<GLuint>(cmd.arg0()));
+        break;
+    case glesv2debugger::Message_Function_glDeleteTextures:
+        dbg->hooks->gl.glDeleteTextures(
+            static_cast<GLsizei>(cmd.arg0()), reinterpret_cast<GLuint*>(const_cast<char *>(cmd.data().data()))
+            );
+        break;
+    case glesv2debugger::Message_Function_glDepthFunc:
+        dbg->hooks->gl.glDepthFunc(
+            static_cast<GLenum>(cmd.arg0()));
+        break;
+    case glesv2debugger::Message_Function_glDepthMask:
+        dbg->hooks->gl.glDepthMask(
+            GLboolean(cmd.arg0()));
+        break;
+    case glesv2debugger::Message_Function_glDepthRangef:
+        dbg->hooks->gl.glDepthRangef(
+            static_cast<GLclampf>(cmd.arg0()), static_cast<GLclampf>(cmd.arg1())
+            );
+        break;
+    case glesv2debugger::Message_Function_glDetachShader:
+        dbg->hooks->gl.glDetachShader(
+            static_cast<GLuint>(cmd.arg0()), static_cast<GLuint>(cmd.arg1())
+            );
+        break;
+    case glesv2debugger::Message_Function_glDisable:
+        dbg->hooks->gl.glDisable(
+            static_cast<GLenum>(cmd.arg0()));
+        break;
+    case glesv2debugger::Message_Function_glDisableVertexAttribArray:
+        dbg->hooks->gl.glDisableVertexAttribArray(
+            static_cast<GLuint>(cmd.arg0()));
+        break;
+    case glesv2debugger::Message_Function_glDrawArrays:
+        dbg->hooks->gl.glDrawArrays(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLint>(cmd.arg1()), 
+            static_cast<GLsizei>(cmd.arg2()));
+        break;
+    case glesv2debugger::Message_Function_glDrawElements:
+        ret = GenerateCall_glDrawElements(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glEnable:
+        dbg->hooks->gl.glEnable(
+            static_cast<GLenum>(cmd.arg0()));
+        break;
+    case glesv2debugger::Message_Function_glEnableVertexAttribArray:
+        dbg->hooks->gl.glEnableVertexAttribArray(
+            static_cast<GLuint>(cmd.arg0()));
+        break;
+    case glesv2debugger::Message_Function_glFinish:
+        dbg->hooks->gl.glFinish(
+            );
+        break;
+    case glesv2debugger::Message_Function_glFlush:
+        dbg->hooks->gl.glFlush(
+            );
+        break;
+    case glesv2debugger::Message_Function_glFramebufferRenderbuffer:
+        dbg->hooks->gl.glFramebufferRenderbuffer(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1()), 
+            static_cast<GLenum>(cmd.arg2()), static_cast<GLuint>(cmd.arg3())
+            );
+        break;
+    case glesv2debugger::Message_Function_glFramebufferTexture2D:
+        dbg->hooks->gl.glFramebufferTexture2D(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1()), 
+            static_cast<GLenum>(cmd.arg2()), static_cast<GLuint>(cmd.arg3()), 
+            static_cast<GLint>(cmd.arg4()));
+        break;
+    case glesv2debugger::Message_Function_glFrontFace:
+        dbg->hooks->gl.glFrontFace(
+            static_cast<GLenum>(cmd.arg0()));
+        break;
+    case glesv2debugger::Message_Function_glGenBuffers:
+        ret = GenerateCall_glGenBuffers(dbg, cmd, msg, prevRet);
+        break; // annotated output pointers
+    case glesv2debugger::Message_Function_glGenerateMipmap:
+        dbg->hooks->gl.glGenerateMipmap(
+            static_cast<GLenum>(cmd.arg0()));
+        break;
+    case glesv2debugger::Message_Function_glGenFramebuffers:
+        ret = GenerateCall_glGenFramebuffers(dbg, cmd, msg, prevRet);
+        break; // annotated output pointers
+    case glesv2debugger::Message_Function_glGenRenderbuffers:
+        ret = GenerateCall_glGenRenderbuffers(dbg, cmd, msg, prevRet);
+        break; // annotated output pointers
+    case glesv2debugger::Message_Function_glGenTextures:
+        ret = GenerateCall_glGenTextures(dbg, cmd, msg, prevRet);
+        break; // annotated output pointers
+    case glesv2debugger::Message_Function_glGetActiveAttrib:
+        ret = GenerateCall_glGetActiveAttrib(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glGetActiveUniform:
+        ret = GenerateCall_glGetActiveUniform(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glGetAttachedShaders:
+        ret = GenerateCall_glGetAttachedShaders(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glGetAttribLocation:
+        msg.set_ret(static_cast<int>(dbg->hooks->gl.glGetAttribLocation(
+            static_cast<GLuint>(cmd.arg0()), reinterpret_cast<GLchar*>(const_cast<char *>(cmd.data().data()))
+            )));
+        if (cmd.has_ret())
+            ret = reinterpret_cast<int *>(msg.ret());
+        break;
+    case glesv2debugger::Message_Function_glGetBooleanv:
+        ret = GenerateCall_glGetBooleanv(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glGetBufferParameteriv:
+        ret = GenerateCall_glGetBufferParameteriv(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glGetError:
+        msg.set_ret(static_cast<int>(dbg->hooks->gl.glGetError(
+            )));
+        if (cmd.has_ret())
+            ret = reinterpret_cast<int *>(msg.ret());
+        break;
+    case glesv2debugger::Message_Function_glGetFloatv:
+        ret = GenerateCall_glGetFloatv(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glGetFramebufferAttachmentParameteriv:
+        ret = GenerateCall_glGetFramebufferAttachmentParameteriv(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glGetIntegerv:
+        ret = GenerateCall_glGetIntegerv(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glGetProgramiv:
+        ret = GenerateCall_glGetProgramiv(dbg, cmd, msg, prevRet);
+        break; // annotated output pointers
+    case glesv2debugger::Message_Function_glGetProgramInfoLog:
+        ret = GenerateCall_glGetProgramInfoLog(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glGetRenderbufferParameteriv:
+        ret = GenerateCall_glGetRenderbufferParameteriv(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glGetShaderiv:
+        ret = GenerateCall_glGetShaderiv(dbg, cmd, msg, prevRet);
+        break; // annotated output pointers
+    case glesv2debugger::Message_Function_glGetShaderInfoLog:
+        ret = GenerateCall_glGetShaderInfoLog(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glGetShaderPrecisionFormat:
+        ret = GenerateCall_glGetShaderPrecisionFormat(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glGetShaderSource:
+        ret = GenerateCall_glGetShaderSource(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glGetString:
+        ret = GenerateCall_glGetString(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glGetTexParameterfv:
+        ret = GenerateCall_glGetTexParameterfv(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glGetTexParameteriv:
+        ret = GenerateCall_glGetTexParameteriv(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glGetUniformfv:
+        ret = GenerateCall_glGetUniformfv(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glGetUniformiv:
+        ret = GenerateCall_glGetUniformiv(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glGetUniformLocation:
+        msg.set_ret(static_cast<int>(dbg->hooks->gl.glGetUniformLocation(
+            static_cast<GLuint>(cmd.arg0()), reinterpret_cast<GLchar*>(const_cast<char *>(cmd.data().data()))
+            )));
+        if (cmd.has_ret())
+            ret = reinterpret_cast<int *>(msg.ret());
+        break;
+    case glesv2debugger::Message_Function_glGetVertexAttribfv:
+        ret = GenerateCall_glGetVertexAttribfv(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glGetVertexAttribiv:
+        ret = GenerateCall_glGetVertexAttribiv(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glGetVertexAttribPointerv:
+        ret = GenerateCall_glGetVertexAttribPointerv(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glHint:
+        dbg->hooks->gl.glHint(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1())
+            );
+        break;
+    case glesv2debugger::Message_Function_glIsBuffer:
+        msg.set_ret(static_cast<int>(dbg->hooks->gl.glIsBuffer(
+            static_cast<GLuint>(cmd.arg0()))));
+        if (cmd.has_ret())
+            ret = reinterpret_cast<int *>(msg.ret());
+        break;
+    case glesv2debugger::Message_Function_glIsEnabled:
+        msg.set_ret(static_cast<int>(dbg->hooks->gl.glIsEnabled(
+            static_cast<GLenum>(cmd.arg0()))));
+        if (cmd.has_ret())
+            ret = reinterpret_cast<int *>(msg.ret());
+        break;
+    case glesv2debugger::Message_Function_glIsFramebuffer:
+        msg.set_ret(static_cast<int>(dbg->hooks->gl.glIsFramebuffer(
+            static_cast<GLuint>(cmd.arg0()))));
+        if (cmd.has_ret())
+            ret = reinterpret_cast<int *>(msg.ret());
+        break;
+    case glesv2debugger::Message_Function_glIsProgram:
+        msg.set_ret(static_cast<int>(dbg->hooks->gl.glIsProgram(
+            static_cast<GLuint>(cmd.arg0()))));
+        if (cmd.has_ret())
+            ret = reinterpret_cast<int *>(msg.ret());
+        break;
+    case glesv2debugger::Message_Function_glIsRenderbuffer:
+        msg.set_ret(static_cast<int>(dbg->hooks->gl.glIsRenderbuffer(
+            static_cast<GLuint>(cmd.arg0()))));
+        if (cmd.has_ret())
+            ret = reinterpret_cast<int *>(msg.ret());
+        break;
+    case glesv2debugger::Message_Function_glIsShader:
+        msg.set_ret(static_cast<int>(dbg->hooks->gl.glIsShader(
+            static_cast<GLuint>(cmd.arg0()))));
+        if (cmd.has_ret())
+            ret = reinterpret_cast<int *>(msg.ret());
+        break;
+    case glesv2debugger::Message_Function_glIsTexture:
+        msg.set_ret(static_cast<int>(dbg->hooks->gl.glIsTexture(
+            static_cast<GLuint>(cmd.arg0()))));
+        if (cmd.has_ret())
+            ret = reinterpret_cast<int *>(msg.ret());
+        break;
+    case glesv2debugger::Message_Function_glLineWidth:
+        dbg->hooks->gl.glLineWidth(
+            static_cast<GLfloat>(cmd.arg0()));
+        break;
+    case glesv2debugger::Message_Function_glLinkProgram:
+        dbg->hooks->gl.glLinkProgram(
+            static_cast<GLuint>(cmd.arg0()));
+        break;
+    case glesv2debugger::Message_Function_glPixelStorei:
+        dbg->hooks->gl.glPixelStorei(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLint>(cmd.arg1())
+            );
+        break;
+    case glesv2debugger::Message_Function_glPolygonOffset:
+        dbg->hooks->gl.glPolygonOffset(
+            static_cast<GLfloat>(cmd.arg0()), static_cast<GLfloat>(cmd.arg1())
+            );
+        break;
+    case glesv2debugger::Message_Function_glReadPixels:
+        ret = GenerateCall_glReadPixels(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glReleaseShaderCompiler:
+        dbg->hooks->gl.glReleaseShaderCompiler(
+            );
+        break;
+    case glesv2debugger::Message_Function_glRenderbufferStorage:
+        dbg->hooks->gl.glRenderbufferStorage(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1()), 
+            static_cast<GLsizei>(cmd.arg2()), static_cast<GLsizei>(cmd.arg3())
+            );
+        break;
+    case glesv2debugger::Message_Function_glSampleCoverage:
+        dbg->hooks->gl.glSampleCoverage(
+            static_cast<GLclampf>(cmd.arg0()), GLboolean(cmd.arg1()));
+        break;
+    case glesv2debugger::Message_Function_glScissor:
+        dbg->hooks->gl.glScissor(
+            static_cast<GLint>(cmd.arg0()), static_cast<GLint>(cmd.arg1()), 
+            static_cast<GLsizei>(cmd.arg2()), static_cast<GLsizei>(cmd.arg3())
+            );
+        break;
+    case glesv2debugger::Message_Function_glShaderBinary:
+        ret = GenerateCall_glShaderBinary(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glShaderSource:
+        ret = GenerateCall_glShaderSource(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glStencilFunc:
+        dbg->hooks->gl.glStencilFunc(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLint>(cmd.arg1()), 
+            static_cast<GLuint>(cmd.arg2()));
+        break;
+    case glesv2debugger::Message_Function_glStencilFuncSeparate:
+        dbg->hooks->gl.glStencilFuncSeparate(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1()), 
+            static_cast<GLint>(cmd.arg2()), static_cast<GLuint>(cmd.arg3())
+            );
+        break;
+    case glesv2debugger::Message_Function_glStencilMask:
+        dbg->hooks->gl.glStencilMask(
+            static_cast<GLuint>(cmd.arg0()));
+        break;
+    case glesv2debugger::Message_Function_glStencilMaskSeparate:
+        dbg->hooks->gl.glStencilMaskSeparate(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLuint>(cmd.arg1())
+            );
+        break;
+    case glesv2debugger::Message_Function_glStencilOp:
+        dbg->hooks->gl.glStencilOp(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1()), 
+            static_cast<GLenum>(cmd.arg2()));
+        break;
+    case glesv2debugger::Message_Function_glStencilOpSeparate:
+        dbg->hooks->gl.glStencilOpSeparate(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1()), 
+            static_cast<GLenum>(cmd.arg2()), static_cast<GLenum>(cmd.arg3())
+            );
+        break;
+    case glesv2debugger::Message_Function_glTexImage2D:
+        ret = GenerateCall_glTexImage2D(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glTexParameterf:
+        dbg->hooks->gl.glTexParameterf(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1()), 
+            static_cast<GLfloat>(cmd.arg2()));
+        break;
+    case glesv2debugger::Message_Function_glTexParameterfv:
+        ret = GenerateCall_glTexParameterfv(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glTexParameteri:
+        dbg->hooks->gl.glTexParameteri(
+            static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1()), 
+            static_cast<GLint>(cmd.arg2()));
+        break;
+    case glesv2debugger::Message_Function_glTexParameteriv:
+        ret = GenerateCall_glTexParameteriv(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glTexSubImage2D:
+        ret = GenerateCall_glTexSubImage2D(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glUniform1f:
+        dbg->hooks->gl.glUniform1f(
+            static_cast<GLint>(cmd.arg0()), static_cast<GLfloat>(cmd.arg1())
+            );
+        break;
+    case glesv2debugger::Message_Function_glUniform1fv:
+        dbg->hooks->gl.glUniform1fv(
+            static_cast<GLint>(cmd.arg0()), static_cast<GLsizei>(cmd.arg1()), 
+            reinterpret_cast<GLfloat*>(const_cast<char *>(cmd.data().data()))
+            );
+        break;
+    case glesv2debugger::Message_Function_glUniform1i:
+        dbg->hooks->gl.glUniform1i(
+            static_cast<GLint>(cmd.arg0()), static_cast<GLint>(cmd.arg1())
+            );
+        break;
+    case glesv2debugger::Message_Function_glUniform1iv:
+        dbg->hooks->gl.glUniform1iv(
+            static_cast<GLint>(cmd.arg0()), static_cast<GLsizei>(cmd.arg1()), 
+            reinterpret_cast<GLint*>(const_cast<char *>(cmd.data().data()))
+            );
+        break;
+    case glesv2debugger::Message_Function_glUniform2f:
+        dbg->hooks->gl.glUniform2f(
+            static_cast<GLint>(cmd.arg0()), static_cast<GLfloat>(cmd.arg1()), 
+            static_cast<GLfloat>(cmd.arg2()));
+        break;
+    case glesv2debugger::Message_Function_glUniform2fv:
+        dbg->hooks->gl.glUniform2fv(
+            static_cast<GLint>(cmd.arg0()), static_cast<GLsizei>(cmd.arg1()), 
+            reinterpret_cast<GLfloat*>(const_cast<char *>(cmd.data().data()))
+            );
+        break;
+    case glesv2debugger::Message_Function_glUniform2i:
+        dbg->hooks->gl.glUniform2i(
+            static_cast<GLint>(cmd.arg0()), static_cast<GLint>(cmd.arg1()), 
+            static_cast<GLint>(cmd.arg2()));
+        break;
+    case glesv2debugger::Message_Function_glUniform2iv:
+        dbg->hooks->gl.glUniform2iv(
+            static_cast<GLint>(cmd.arg0()), static_cast<GLsizei>(cmd.arg1()), 
+            reinterpret_cast<GLint*>(const_cast<char *>(cmd.data().data()))
+            );
+        break;
+    case glesv2debugger::Message_Function_glUniform3f:
+        dbg->hooks->gl.glUniform3f(
+            static_cast<GLint>(cmd.arg0()), static_cast<GLfloat>(cmd.arg1()), 
+            static_cast<GLfloat>(cmd.arg2()), static_cast<GLfloat>(cmd.arg3())
+            );
+        break;
+    case glesv2debugger::Message_Function_glUniform3fv:
+        dbg->hooks->gl.glUniform3fv(
+            static_cast<GLint>(cmd.arg0()), static_cast<GLsizei>(cmd.arg1()), 
+            reinterpret_cast<GLfloat*>(const_cast<char *>(cmd.data().data()))
+            );
+        break;
+    case glesv2debugger::Message_Function_glUniform3i:
+        dbg->hooks->gl.glUniform3i(
+            static_cast<GLint>(cmd.arg0()), static_cast<GLint>(cmd.arg1()), 
+            static_cast<GLint>(cmd.arg2()), static_cast<GLint>(cmd.arg3())
+            );
+        break;
+    case glesv2debugger::Message_Function_glUniform3iv:
+        dbg->hooks->gl.glUniform3iv(
+            static_cast<GLint>(cmd.arg0()), static_cast<GLsizei>(cmd.arg1()), 
+            reinterpret_cast<GLint*>(const_cast<char *>(cmd.data().data()))
+            );
+        break;
+    case glesv2debugger::Message_Function_glUniform4f:
+        dbg->hooks->gl.glUniform4f(
+            static_cast<GLint>(cmd.arg0()), static_cast<GLfloat>(cmd.arg1()), 
+            static_cast<GLfloat>(cmd.arg2()), static_cast<GLfloat>(cmd.arg3()), 
+            static_cast<GLfloat>(cmd.arg4()));
+        break;
+    case glesv2debugger::Message_Function_glUniform4fv:
+        dbg->hooks->gl.glUniform4fv(
+            static_cast<GLint>(cmd.arg0()), static_cast<GLsizei>(cmd.arg1()), 
+            reinterpret_cast<GLfloat*>(const_cast<char *>(cmd.data().data()))
+            );
+        break;
+    case glesv2debugger::Message_Function_glUniform4i:
+        dbg->hooks->gl.glUniform4i(
+            static_cast<GLint>(cmd.arg0()), static_cast<GLint>(cmd.arg1()), 
+            static_cast<GLint>(cmd.arg2()), static_cast<GLint>(cmd.arg3()), 
+            static_cast<GLint>(cmd.arg4()));
+        break;
+    case glesv2debugger::Message_Function_glUniform4iv:
+        dbg->hooks->gl.glUniform4iv(
+            static_cast<GLint>(cmd.arg0()), static_cast<GLsizei>(cmd.arg1()), 
+            reinterpret_cast<GLint*>(const_cast<char *>(cmd.data().data()))
+            );
+        break;
+    case glesv2debugger::Message_Function_glUniformMatrix2fv:
+        dbg->hooks->gl.glUniformMatrix2fv(
+            static_cast<GLint>(cmd.arg0()), static_cast<GLsizei>(cmd.arg1()), 
+            GLboolean(cmd.arg2()), reinterpret_cast<GLfloat*>(const_cast<char *>(cmd.data().data()))
+            );
+        break;
+    case glesv2debugger::Message_Function_glUniformMatrix3fv:
+        dbg->hooks->gl.glUniformMatrix3fv(
+            static_cast<GLint>(cmd.arg0()), static_cast<GLsizei>(cmd.arg1()), 
+            GLboolean(cmd.arg2()), reinterpret_cast<GLfloat*>(const_cast<char *>(cmd.data().data()))
+            );
+        break;
+    case glesv2debugger::Message_Function_glUniformMatrix4fv:
+        dbg->hooks->gl.glUniformMatrix4fv(
+            static_cast<GLint>(cmd.arg0()), static_cast<GLsizei>(cmd.arg1()), 
+            GLboolean(cmd.arg2()), reinterpret_cast<GLfloat*>(const_cast<char *>(cmd.data().data()))
+            );
+        break;
+    case glesv2debugger::Message_Function_glUseProgram:
+        dbg->hooks->gl.glUseProgram(
+            static_cast<GLuint>(cmd.arg0()));
+        break;
+    case glesv2debugger::Message_Function_glValidateProgram:
+        dbg->hooks->gl.glValidateProgram(
+            static_cast<GLuint>(cmd.arg0()));
+        break;
+    case glesv2debugger::Message_Function_glVertexAttrib1f:
+        dbg->hooks->gl.glVertexAttrib1f(
+            static_cast<GLuint>(cmd.arg0()), static_cast<GLfloat>(cmd.arg1())
+            );
+        break;
+    case glesv2debugger::Message_Function_glVertexAttrib1fv:
+        dbg->hooks->gl.glVertexAttrib1fv(
+            static_cast<GLuint>(cmd.arg0()), reinterpret_cast<GLfloat*>(const_cast<char *>(cmd.data().data()))
+            );
+        break;
+    case glesv2debugger::Message_Function_glVertexAttrib2f:
+        dbg->hooks->gl.glVertexAttrib2f(
+            static_cast<GLuint>(cmd.arg0()), static_cast<GLfloat>(cmd.arg1()), 
+            static_cast<GLfloat>(cmd.arg2()));
+        break;
+    case glesv2debugger::Message_Function_glVertexAttrib2fv:
+        dbg->hooks->gl.glVertexAttrib2fv(
+            static_cast<GLuint>(cmd.arg0()), reinterpret_cast<GLfloat*>(const_cast<char *>(cmd.data().data()))
+            );
+        break;
+    case glesv2debugger::Message_Function_glVertexAttrib3f:
+        dbg->hooks->gl.glVertexAttrib3f(
+            static_cast<GLuint>(cmd.arg0()), static_cast<GLfloat>(cmd.arg1()), 
+            static_cast<GLfloat>(cmd.arg2()), static_cast<GLfloat>(cmd.arg3())
+            );
+        break;
+    case glesv2debugger::Message_Function_glVertexAttrib3fv:
+        dbg->hooks->gl.glVertexAttrib3fv(
+            static_cast<GLuint>(cmd.arg0()), reinterpret_cast<GLfloat*>(const_cast<char *>(cmd.data().data()))
+            );
+        break;
+    case glesv2debugger::Message_Function_glVertexAttrib4f:
+        dbg->hooks->gl.glVertexAttrib4f(
+            static_cast<GLuint>(cmd.arg0()), static_cast<GLfloat>(cmd.arg1()), 
+            static_cast<GLfloat>(cmd.arg2()), static_cast<GLfloat>(cmd.arg3()), 
+            static_cast<GLfloat>(cmd.arg4()));
+        break;
+    case glesv2debugger::Message_Function_glVertexAttrib4fv:
+        dbg->hooks->gl.glVertexAttrib4fv(
+            static_cast<GLuint>(cmd.arg0()), reinterpret_cast<GLfloat*>(const_cast<char *>(cmd.data().data()))
+            );
+        break;
+    case glesv2debugger::Message_Function_glVertexAttribPointer:
+        ret = GenerateCall_glVertexAttribPointer(dbg, cmd, msg, prevRet);
+        break;
+    case glesv2debugger::Message_Function_glViewport:
+        dbg->hooks->gl.glViewport(
+            static_cast<GLint>(cmd.arg0()), static_cast<GLint>(cmd.arg1()), 
+            static_cast<GLsizei>(cmd.arg2()), static_cast<GLsizei>(cmd.arg3())
+            );
+        break;
+    default:
+        assert(0);
+    }
+    msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
+    msg.set_context_id(reinterpret_cast<int>(dbg));
+    msg.set_function(cmd.function());
+    msg.set_type(glesv2debugger::Message_Type_AfterCall);
+    return ret;
+}
+
+}; // name space android {
diff --git a/opengl/libs/GLES2_dbg/src/caller.h b/opengl/libs/GLES2_dbg/src/caller.h
index 01bc4ea..5447757 100644
--- a/opengl/libs/GLES2_dbg/src/caller.h
+++ b/opengl/libs/GLES2_dbg/src/caller.h
@@ -1,7 +1,7 @@
 /*
  ** Copyright 2011, The Android Open Source Project
  **
- ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** 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
  **
@@ -14,6 +14,307 @@
  ** limitations under the License.
  */
 
-#include "src/header.h"
+static const int * GenerateCall_glCompressedTexImage2D(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
 
+static const int * GenerateCall_glCompressedTexSubImage2D(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
 
+static const int * GenerateCall_glDrawElements(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGenBuffers(DbgContext * const dbg,
+                                       const glesv2debugger::Message & cmd,
+                                       glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGenFramebuffers(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGenRenderbuffers(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGenTextures(DbgContext * const dbg,
+                                        const glesv2debugger::Message & cmd,
+                                        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetActiveAttrib(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetActiveUniform(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetAttachedShaders(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetBooleanv(DbgContext * const dbg,
+                                        const glesv2debugger::Message & cmd,
+                                        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetBufferParameteriv(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetFloatv(DbgContext * const dbg,
+                                      const glesv2debugger::Message & cmd,
+                                      glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetFramebufferAttachmentParameteriv(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetIntegerv(DbgContext * const dbg,
+                                        const glesv2debugger::Message & cmd,
+                                        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetProgramiv(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetProgramInfoLog(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetRenderbufferParameteriv(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetShaderiv(DbgContext * const dbg,
+                                        const glesv2debugger::Message & cmd,
+                                        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetShaderInfoLog(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetShaderPrecisionFormat(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetShaderSource(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetString(DbgContext * const dbg,
+                                      const glesv2debugger::Message & cmd,
+                                      glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetTexParameterfv(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetTexParameteriv(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetUniformfv(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetUniformiv(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetVertexAttribfv(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetVertexAttribiv(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glGetVertexAttribPointerv(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glReadPixels(DbgContext * const dbg,
+                                       const glesv2debugger::Message & cmd,
+                                       glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glShaderBinary(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glShaderSource(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    const char * string = cmd.data().data();
+    dbg->hooks->gl.glShaderSource(cmd.arg0(), 1, &string, NULL);
+    return prevRet;
+}
+
+static const int * GenerateCall_glTexImage2D(DbgContext * const dbg,
+                                       const glesv2debugger::Message & cmd,
+                                       glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glTexParameterfv(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glTexParameteriv(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glTexSubImage2D(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
+
+static const int * GenerateCall_glVertexAttribPointer(DbgContext * const dbg,
+        const glesv2debugger::Message & cmd,
+        glesv2debugger::Message & msg, const int * const prevRet)
+{
+    assert(0);
+    return prevRet;
+}
diff --git a/opengl/libs/GLES2_dbg/src/dbgcontext.cpp b/opengl/libs/GLES2_dbg/src/dbgcontext.cpp
index 5c41825..cc7336c 100644
--- a/opengl/libs/GLES2_dbg/src/dbgcontext.cpp
+++ b/opengl/libs/GLES2_dbg/src/dbgcontext.cpp
@@ -13,26 +13,38 @@
  ** See the License for the specific language governing permissions and
  ** limitations under the License.
  */
- 
+
 #include "header.h"
 
+extern "C"
+{
+#include "liblzf/lzf.h"
+}
+
 namespace android
 {
 
 DbgContext::DbgContext(const unsigned version, const gl_hooks_t * const hooks,
                        const unsigned MAX_VERTEX_ATTRIBS)
-        : version(version), hooks(hooks)
+        : lzf_buf(NULL), lzf_readIndex(0), lzf_refSize(0), lzf_refBufSize(0)
+        , version(version), hooks(hooks)
         , MAX_VERTEX_ATTRIBS(MAX_VERTEX_ATTRIBS)
         , vertexAttribs(new VertexAttrib[MAX_VERTEX_ATTRIBS])
         , hasNonVBOAttribs(false), indexBuffers(NULL), indexBuffer(NULL)
+        , program(0), maxAttrib(0)
 {
+    lzf_ref[0] = lzf_ref[1] = NULL;
     for (unsigned i = 0; i < MAX_VERTEX_ATTRIBS; i++)
         vertexAttribs[i] = VertexAttrib();
+    memset(&expectResponse, 0, sizeof(expectResponse));
 }
 
 DbgContext::~DbgContext()
 {
     delete vertexAttribs;
+    free(lzf_buf);
+    free(lzf_ref[0]);
+    free(lzf_ref[1]);
 }
 
 DbgContext * CreateDbgContext(const unsigned version, const gl_hooks_t * const hooks)
@@ -49,6 +61,39 @@
     delete dbg;
 }
 
+unsigned GetBytesPerPixel(const GLenum format, const GLenum type)
+{
+    switch (type) {
+    case GL_UNSIGNED_SHORT_5_6_5:
+        return 2;
+    case GL_UNSIGNED_SHORT_4_4_4_4:
+        return 2;
+    case GL_UNSIGNED_SHORT_5_5_5_1:
+        return 2;
+    case GL_UNSIGNED_BYTE:
+        break;
+    default:
+        assert(0);
+    }
+
+    switch (format) {
+    case GL_ALPHA:
+        return 1;
+    case GL_LUMINANCE:
+        return 1;
+        break;
+    case GL_LUMINANCE_ALPHA:
+        return 2;
+    case GL_RGB:
+        return 3;
+    case GL_RGBA:
+        return 4;
+    default:
+        assert(0);
+        return 0;
+    }
+}
+
 void DbgContext::Fetch(const unsigned index, std::string * const data) const
 {
     // VBO data is already on client, just send user pointer data
@@ -63,11 +108,61 @@
     }
 }
 
+void DbgContext::Compress(const void * in_data, unsigned int in_len,
+                          std::string * const outStr)
+{
+    if (!lzf_buf)
+        lzf_buf = (char *)malloc(LZF_CHUNK_SIZE);
+    const uint32_t totalDecompSize = in_len;
+    outStr->append((const char *)&totalDecompSize, sizeof(totalDecompSize));
+    for (unsigned int i = 0; i < in_len; i += LZF_CHUNK_SIZE) {
+        uint32_t chunkSize = LZF_CHUNK_SIZE;
+        if (i + LZF_CHUNK_SIZE > in_len)
+            chunkSize = in_len - i;
+        const uint32_t compSize = lzf_compress((const char *)in_data + i, chunkSize,
+                                               lzf_buf, LZF_CHUNK_SIZE);
+        outStr->append((const char *)&chunkSize, sizeof(chunkSize));
+        outStr->append((const char *)&compSize, sizeof(compSize));
+        if (compSize > 0)
+            outStr->append(lzf_buf, compSize);
+        else // compressed chunk bigger than LZF_CHUNK_SIZE (and uncompressed)
+            outStr->append((const char *)in_data + i, chunkSize);
+    }
+}
+
+void * DbgContext::GetReadPixelsBuffer(const unsigned size)
+{
+    if (lzf_refBufSize < size + 8) {
+        lzf_refBufSize = size + 8;
+        lzf_ref[0] = (unsigned *)realloc(lzf_ref[0], lzf_refBufSize);
+        memset(lzf_ref[0], 0, lzf_refBufSize);
+        lzf_ref[1] = (unsigned *)realloc(lzf_ref[1], lzf_refBufSize);
+        memset(lzf_ref[1], 0, lzf_refBufSize);
+    }
+    if (lzf_refSize != size) // need to clear unused ref to maintain consistency
+    { // since ref and src are swapped each time
+        memset((char *)lzf_ref[0] + lzf_refSize, 0, lzf_refBufSize - lzf_refSize);
+        memset((char *)lzf_ref[1] + lzf_refSize, 0, lzf_refBufSize - lzf_refSize);
+    }
+    lzf_refSize = size;
+    lzf_readIndex ^= 1;
+    return lzf_ref[lzf_readIndex];
+}
+
+void DbgContext::CompressReadPixelBuffer(std::string * const outStr)
+{
+    unsigned * const ref = lzf_ref[lzf_readIndex ^ 1];
+    unsigned * const src = lzf_ref[lzf_readIndex];
+    for (unsigned i = 0; i < lzf_refSize / sizeof(*ref) + 1; i++)
+        ref[i] ^= src[i];
+    Compress(ref, lzf_refSize, outStr);
+}
+
 void DbgContext::glUseProgram(GLuint program)
 {
     while (GLenum error = hooks->gl.glGetError())
         LOGD("DbgContext::glUseProgram: before glGetError() = 0x%.4X", error);
-        
+
     this->program = program;
 
     GLint activeAttributes = 0;
@@ -107,7 +202,7 @@
             maxAttrib = slot;
     }
     delete name;
-    
+
     while (GLenum error = hooks->gl.glGetError())
         LOGD("DbgContext::glUseProgram: after glGetError() = 0x%.4X", error);
 }
diff --git a/opengl/libs/GLES2_dbg/src/debugger_message.pb.cpp b/opengl/libs/GLES2_dbg/src/debugger_message.pb.cpp
index 1f404c2..046c954 100644
--- a/opengl/libs/GLES2_dbg/src/debugger_message.pb.cpp
+++ b/opengl/libs/GLES2_dbg/src/debugger_message.pb.cpp
@@ -450,7 +450,7 @@
 const Message_Type Message::Type_MAX;
 const int Message::Type_ARRAYSIZE;
 #endif  // _MSC_VER
-bool Message_Prop_IsValid(int value) {
+bool Message_DataType_IsValid(int value) {
   switch(value) {
     case 0:
     case 1:
@@ -461,8 +461,27 @@
 }
 
 #ifndef _MSC_VER
+const Message_DataType Message::ReferencedImage;
+const Message_DataType Message::NonreferencedImage;
+const Message_DataType Message::DataType_MIN;
+const Message_DataType Message::DataType_MAX;
+const int Message::DataType_ARRAYSIZE;
+#endif  // _MSC_VER
+bool Message_Prop_IsValid(int value) {
+  switch(value) {
+    case 0:
+    case 1:
+    case 2:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#ifndef _MSC_VER
 const Message_Prop Message::Capture;
 const Message_Prop Message::TimeMode;
+const Message_Prop Message::ExpectResponse;
 const Message_Prop Message::Prop_MIN;
 const Message_Prop Message::Prop_MAX;
 const int Message::Prop_ARRAYSIZE;
@@ -484,6 +503,9 @@
 const int Message::kArg7FieldNumber;
 const int Message::kArg8FieldNumber;
 const int Message::kDataFieldNumber;
+const int Message::kDataTypeFieldNumber;
+const int Message::kPixelFormatFieldNumber;
+const int Message::kPixelTypeFieldNumber;
 const int Message::kTimeFieldNumber;
 const int Message::kPropFieldNumber;
 const int Message::kClockFieldNumber;
@@ -520,6 +542,9 @@
   arg7_ = 0;
   arg8_ = 0;
   data_ = const_cast< ::std::string*>(&_default_data_);
+  data_type_ = 0;
+  pixel_format_ = 0;
+  pixel_type_ = 0;
   time_ = 0;
   prop_ = 0;
   clock_ = 0;
@@ -576,9 +601,12 @@
         data_->clear();
       }
     }
-    time_ = 0;
+    data_type_ = 0;
   }
   if (_has_bits_[16 / 32] & (0xffu << (16 % 32))) {
+    pixel_format_ = 0;
+    pixel_type_ = 0;
+    time_ = 0;
     prop_ = 0;
     clock_ = 0;
   }
@@ -762,7 +790,7 @@
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>(
                  input, &time_)));
-          _set_bit(15);
+          _set_bit(18);
         } else {
           goto handle_uninterpreted;
         }
@@ -877,6 +905,57 @@
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>(
                  input, &clock_)));
+          _set_bit(20);
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(184)) goto parse_data_type;
+        break;
+      }
+      
+      // optional .com.android.glesv2debugger.Message.DataType data_type = 23;
+      case 23: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+         parse_data_type:
+          int value;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          if (::com::android::glesv2debugger::Message_DataType_IsValid(value)) {
+            set_data_type(static_cast< ::com::android::glesv2debugger::Message_DataType >(value));
+          }
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(192)) goto parse_pixel_format;
+        break;
+      }
+      
+      // optional int32 pixel_format = 24;
+      case 24: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+         parse_pixel_format:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &pixel_format_)));
+          _set_bit(16);
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(200)) goto parse_pixel_type;
+        break;
+      }
+      
+      // optional int32 pixel_type = 25;
+      case 25: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+         parse_pixel_type:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &pixel_type_)));
           _set_bit(17);
         } else {
           goto handle_uninterpreted;
@@ -956,7 +1035,7 @@
   }
   
   // optional float time = 11;
-  if (_has_bit(15)) {
+  if (_has_bit(18)) {
     ::google::protobuf::internal::WireFormatLite::WriteFloat(11, this->time(), output);
   }
   
@@ -986,16 +1065,32 @@
   }
   
   // optional .com.android.glesv2debugger.Message.Prop prop = 21;
-  if (_has_bit(16)) {
+  if (_has_bit(19)) {
     ::google::protobuf::internal::WireFormatLite::WriteEnum(
       21, this->prop(), output);
   }
   
   // optional float clock = 22;
-  if (_has_bit(17)) {
+  if (_has_bit(20)) {
     ::google::protobuf::internal::WireFormatLite::WriteFloat(22, this->clock(), output);
   }
   
+  // optional .com.android.glesv2debugger.Message.DataType data_type = 23;
+  if (_has_bit(15)) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      23, this->data_type(), output);
+  }
+  
+  // optional int32 pixel_format = 24;
+  if (_has_bit(16)) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(24, this->pixel_format(), output);
+  }
+  
+  // optional int32 pixel_type = 25;
+  if (_has_bit(17)) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(25, this->pixel_type(), output);
+  }
+  
 }
 
 int Message::ByteSize() const {
@@ -1105,13 +1200,33 @@
           this->data());
     }
     
+    // optional .com.android.glesv2debugger.Message.DataType data_type = 23;
+    if (has_data_type()) {
+      total_size += 2 +
+        ::google::protobuf::internal::WireFormatLite::EnumSize(this->data_type());
+    }
+    
+  }
+  if (_has_bits_[16 / 32] & (0xffu << (16 % 32))) {
+    // optional int32 pixel_format = 24;
+    if (has_pixel_format()) {
+      total_size += 2 +
+        ::google::protobuf::internal::WireFormatLite::Int32Size(
+          this->pixel_format());
+    }
+    
+    // optional int32 pixel_type = 25;
+    if (has_pixel_type()) {
+      total_size += 2 +
+        ::google::protobuf::internal::WireFormatLite::Int32Size(
+          this->pixel_type());
+    }
+    
     // optional float time = 11;
     if (has_time()) {
       total_size += 1 + 4;
     }
     
-  }
-  if (_has_bits_[16 / 32] & (0xffu << (16 % 32))) {
     // optional .com.android.glesv2debugger.Message.Prop prop = 21;
     if (has_prop()) {
       total_size += 2 +
@@ -1186,14 +1301,23 @@
       set_data(from.data());
     }
     if (from._has_bit(15)) {
-      set_time(from.time());
+      set_data_type(from.data_type());
     }
   }
   if (from._has_bits_[16 / 32] & (0xffu << (16 % 32))) {
     if (from._has_bit(16)) {
-      set_prop(from.prop());
+      set_pixel_format(from.pixel_format());
     }
     if (from._has_bit(17)) {
+      set_pixel_type(from.pixel_type());
+    }
+    if (from._has_bit(18)) {
+      set_time(from.time());
+    }
+    if (from._has_bit(19)) {
+      set_prop(from.prop());
+    }
+    if (from._has_bit(20)) {
       set_clock(from.clock());
     }
   }
@@ -1228,6 +1352,9 @@
     std::swap(arg7_, other->arg7_);
     std::swap(arg8_, other->arg8_);
     std::swap(data_, other->data_);
+    std::swap(data_type_, other->data_type_);
+    std::swap(pixel_format_, other->pixel_format_);
+    std::swap(pixel_type_, other->pixel_type_);
     std::swap(time_, other->time_);
     std::swap(prop_, other->prop_);
     std::swap(clock_, other->clock_);
diff --git a/opengl/libs/GLES2_dbg/src/debugger_message.pb.h b/opengl/libs/GLES2_dbg/src/debugger_message.pb.h
index 59e7bab..b2ec5a0 100644
--- a/opengl/libs/GLES2_dbg/src/debugger_message.pb.h
+++ b/opengl/libs/GLES2_dbg/src/debugger_message.pb.h
@@ -243,13 +243,23 @@
 const Message_Type Message_Type_Type_MAX = Message_Type_Response;
 const int Message_Type_Type_ARRAYSIZE = Message_Type_Type_MAX + 1;
 
+enum Message_DataType {
+  Message_DataType_ReferencedImage = 0,
+  Message_DataType_NonreferencedImage = 1
+};
+bool Message_DataType_IsValid(int value);
+const Message_DataType Message_DataType_DataType_MIN = Message_DataType_ReferencedImage;
+const Message_DataType Message_DataType_DataType_MAX = Message_DataType_NonreferencedImage;
+const int Message_DataType_DataType_ARRAYSIZE = Message_DataType_DataType_MAX + 1;
+
 enum Message_Prop {
   Message_Prop_Capture = 0,
-  Message_Prop_TimeMode = 1
+  Message_Prop_TimeMode = 1,
+  Message_Prop_ExpectResponse = 2
 };
 bool Message_Prop_IsValid(int value);
 const Message_Prop Message_Prop_Prop_MIN = Message_Prop_Capture;
-const Message_Prop Message_Prop_Prop_MAX = Message_Prop_TimeMode;
+const Message_Prop Message_Prop_Prop_MAX = Message_Prop_ExpectResponse;
 const int Message_Prop_Prop_ARRAYSIZE = Message_Prop_Prop_MAX + 1;
 
 // ===================================================================
@@ -511,9 +521,23 @@
   static const int Type_ARRAYSIZE =
     Message_Type_Type_ARRAYSIZE;
   
+  typedef Message_DataType DataType;
+  static const DataType ReferencedImage = Message_DataType_ReferencedImage;
+  static const DataType NonreferencedImage = Message_DataType_NonreferencedImage;
+  static inline bool DataType_IsValid(int value) {
+    return Message_DataType_IsValid(value);
+  }
+  static const DataType DataType_MIN =
+    Message_DataType_DataType_MIN;
+  static const DataType DataType_MAX =
+    Message_DataType_DataType_MAX;
+  static const int DataType_ARRAYSIZE =
+    Message_DataType_DataType_ARRAYSIZE;
+  
   typedef Message_Prop Prop;
   static const Prop Capture = Message_Prop_Capture;
   static const Prop TimeMode = Message_Prop_TimeMode;
+  static const Prop ExpectResponse = Message_Prop_ExpectResponse;
   static inline bool Prop_IsValid(int value) {
     return Message_Prop_IsValid(value);
   }
@@ -634,6 +658,27 @@
   inline void set_data(const void* value, size_t size);
   inline ::std::string* mutable_data();
   
+  // optional .com.android.glesv2debugger.Message.DataType data_type = 23;
+  inline bool has_data_type() const;
+  inline void clear_data_type();
+  static const int kDataTypeFieldNumber = 23;
+  inline ::com::android::glesv2debugger::Message_DataType data_type() const;
+  inline void set_data_type(::com::android::glesv2debugger::Message_DataType value);
+  
+  // optional int32 pixel_format = 24;
+  inline bool has_pixel_format() const;
+  inline void clear_pixel_format();
+  static const int kPixelFormatFieldNumber = 24;
+  inline ::google::protobuf::int32 pixel_format() const;
+  inline void set_pixel_format(::google::protobuf::int32 value);
+  
+  // optional int32 pixel_type = 25;
+  inline bool has_pixel_type() const;
+  inline void clear_pixel_type();
+  static const int kPixelTypeFieldNumber = 25;
+  inline ::google::protobuf::int32 pixel_type() const;
+  inline void set_pixel_type(::google::protobuf::int32 value);
+  
   // optional float time = 11;
   inline bool has_time() const;
   inline void clear_time();
@@ -675,6 +720,9 @@
   ::google::protobuf::int32 arg8_;
   ::std::string* data_;
   static const ::std::string _default_data_;
+  int data_type_;
+  ::google::protobuf::int32 pixel_format_;
+  ::google::protobuf::int32 pixel_type_;
   float time_;
   int prop_;
   float clock_;
@@ -682,7 +730,7 @@
   friend void protobuf_AssignDesc_debugger_5fmessage_2eproto();
   friend void protobuf_ShutdownFile_debugger_5fmessage_2eproto();
   
-  ::google::protobuf::uint32 _has_bits_[(18 + 31) / 32];
+  ::google::protobuf::uint32 _has_bits_[(21 + 31) / 32];
   
   // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
   inline bool _has_bit(int index) const {
@@ -973,52 +1021,101 @@
   return data_;
 }
 
+// optional .com.android.glesv2debugger.Message.DataType data_type = 23;
+inline bool Message::has_data_type() const {
+  return _has_bit(15);
+}
+inline void Message::clear_data_type() {
+  data_type_ = 0;
+  _clear_bit(15);
+}
+inline ::com::android::glesv2debugger::Message_DataType Message::data_type() const {
+  return static_cast< ::com::android::glesv2debugger::Message_DataType >(data_type_);
+}
+inline void Message::set_data_type(::com::android::glesv2debugger::Message_DataType value) {
+  GOOGLE_DCHECK(::com::android::glesv2debugger::Message_DataType_IsValid(value));
+  _set_bit(15);
+  data_type_ = value;
+}
+
+// optional int32 pixel_format = 24;
+inline bool Message::has_pixel_format() const {
+  return _has_bit(16);
+}
+inline void Message::clear_pixel_format() {
+  pixel_format_ = 0;
+  _clear_bit(16);
+}
+inline ::google::protobuf::int32 Message::pixel_format() const {
+  return pixel_format_;
+}
+inline void Message::set_pixel_format(::google::protobuf::int32 value) {
+  _set_bit(16);
+  pixel_format_ = value;
+}
+
+// optional int32 pixel_type = 25;
+inline bool Message::has_pixel_type() const {
+  return _has_bit(17);
+}
+inline void Message::clear_pixel_type() {
+  pixel_type_ = 0;
+  _clear_bit(17);
+}
+inline ::google::protobuf::int32 Message::pixel_type() const {
+  return pixel_type_;
+}
+inline void Message::set_pixel_type(::google::protobuf::int32 value) {
+  _set_bit(17);
+  pixel_type_ = value;
+}
+
 // optional float time = 11;
 inline bool Message::has_time() const {
-  return _has_bit(15);
+  return _has_bit(18);
 }
 inline void Message::clear_time() {
   time_ = 0;
-  _clear_bit(15);
+  _clear_bit(18);
 }
 inline float Message::time() const {
   return time_;
 }
 inline void Message::set_time(float value) {
-  _set_bit(15);
+  _set_bit(18);
   time_ = value;
 }
 
 // optional .com.android.glesv2debugger.Message.Prop prop = 21;
 inline bool Message::has_prop() const {
-  return _has_bit(16);
+  return _has_bit(19);
 }
 inline void Message::clear_prop() {
   prop_ = 0;
-  _clear_bit(16);
+  _clear_bit(19);
 }
 inline ::com::android::glesv2debugger::Message_Prop Message::prop() const {
   return static_cast< ::com::android::glesv2debugger::Message_Prop >(prop_);
 }
 inline void Message::set_prop(::com::android::glesv2debugger::Message_Prop value) {
   GOOGLE_DCHECK(::com::android::glesv2debugger::Message_Prop_IsValid(value));
-  _set_bit(16);
+  _set_bit(19);
   prop_ = value;
 }
 
 // optional float clock = 22;
 inline bool Message::has_clock() const {
-  return _has_bit(17);
+  return _has_bit(20);
 }
 inline void Message::clear_clock() {
   clock_ = 0;
-  _clear_bit(17);
+  _clear_bit(20);
 }
 inline float Message::clock() const {
   return clock_;
 }
 inline void Message::set_clock(float value) {
-  _set_bit(17);
+  _set_bit(20);
   clock_ = value;
 }
 
diff --git a/opengl/libs/GLES2_dbg/src/egl.cpp b/opengl/libs/GLES2_dbg/src/egl.cpp
index 27c7f7e..3a20e21 100644
--- a/opengl/libs/GLES2_dbg/src/egl.cpp
+++ b/opengl/libs/GLES2_dbg/src/egl.cpp
@@ -19,11 +19,10 @@
 EGLBoolean Debug_eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
 {
     glesv2debugger::Message msg;
-    const bool expectResponse = false;
     struct : public FunctionCall {
         EGLDisplay dpy;
         EGLSurface draw;
-        
+
         const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
             msg.set_time(-1);
             return reinterpret_cast<const int *>(true);
@@ -31,11 +30,10 @@
     } caller;
     caller.dpy = dpy;
     caller.draw = draw;
-    
+
     msg.set_arg0(reinterpret_cast<int>(dpy));
     msg.set_arg1(reinterpret_cast<int>(draw));
-    
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_eglSwapBuffers);
+
+    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_eglSwapBuffers);
     return static_cast<EGLBoolean>(reinterpret_cast<int>(ret));
 }
diff --git a/opengl/libs/GLES2_dbg/src/header.h b/opengl/libs/GLES2_dbg/src/header.h
index b79cc0f..9218da5 100644
--- a/opengl/libs/GLES2_dbg/src/header.h
+++ b/opengl/libs/GLES2_dbg/src/header.h
@@ -56,11 +56,40 @@
 namespace android
 {
 
+struct GLFunctionBitfield {
+    unsigned char field [24]; // 8 * 24 = 192
+
+    void Bit(const glesv2debugger::Message_Function function, bool bit) {
+        const unsigned byte = function / 8, mask = 1 << (function % 8);
+        if (bit)
+            field[byte] |= mask;
+        else
+            field[byte] &= ~mask;
+    }
+
+    bool Bit(const glesv2debugger::Message_Function function) const {
+        const unsigned byte = function / 8, mask = 1 << (function % 8);
+        return field[byte] & mask;
+    }
+};
+
 struct DbgContext {
+private:
+    static const unsigned int LZF_CHUNK_SIZE = 256 * 1024;
+    char * lzf_buf; // malloc / free; for lzf chunk compression
+
+    // used as buffer and reference frame for ReadPixels; malloc/free
+    unsigned * lzf_ref [2];
+    unsigned lzf_readIndex; // 0 or 1
+    unsigned lzf_refSize, lzf_refBufSize; // bytes
+
+public:
     const unsigned version; // 0 is GLES1, 1 is GLES2
     const gl_hooks_t * const hooks;
     const unsigned MAX_VERTEX_ATTRIBS;
-    
+
+    GLFunctionBitfield expectResponse;
+
     struct VertexAttrib {
         GLenum type; // element data type
         unsigned size; // number of data per element
@@ -89,15 +118,23 @@
     GLuint program;
     unsigned maxAttrib; // number of slots used by program
 
-    DbgContext(const unsigned version, const gl_hooks_t * const hooks, const unsigned MAX_VERTEX_ATTRIBS);
+    DbgContext(const unsigned version, const gl_hooks_t * const hooks,
+               const unsigned MAX_VERTEX_ATTRIBS);
     ~DbgContext();
 
     void Fetch(const unsigned index, std::string * const data) const;
+    void Compress(const void * in_data, unsigned in_len, std::string * const outStr);
+    void * GetReadPixelsBuffer(const unsigned size);
+    bool IsReadPixelBuffer(const void * const ptr)  {
+        return ptr == lzf_ref[lzf_readIndex];
+    }
+    void CompressReadPixelBuffer(std::string * const outStr);
 
     void glUseProgram(GLuint program);
     void glEnableVertexAttribArray(GLuint index);
     void glDisableVertexAttribArray(GLuint index);
-    void glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
+    void glVertexAttribPointer(GLuint indx, GLint size, GLenum type,
+                               GLboolean normalized, GLsizei stride, const GLvoid* ptr);
     void glBindBuffer(GLenum target, GLuint buffer);
     void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
     void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
@@ -109,7 +146,8 @@
 #define DBGCONTEXT(ctx) DbgContext * const ctx = getDbgContextThreadSpecific();
 
 struct FunctionCall {
-    virtual const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) = 0;
+    virtual const int * operator()(gl_hooks_t::gl_t const * const _c,
+                                   glesv2debugger::Message & msg) = 0;
     virtual ~FunctionCall() {}
 };
 
@@ -123,9 +161,11 @@
 
 // every Debug_gl* function calls this to send message to client and possibly receive commands
 int * MessageLoop(FunctionCall & functionCall, glesv2debugger::Message & msg,
-                  const bool expectResponse, const glesv2debugger::Message_Function function);
+                  const glesv2debugger::Message_Function function);
 
 void Receive(glesv2debugger::Message & cmd);
 float Send(const glesv2debugger::Message & msg, glesv2debugger::Message & cmd);
-void SetProp(const glesv2debugger::Message & cmd);
+void SetProp(DbgContext * const dbg, const glesv2debugger::Message & cmd);
+const int * GenerateCall(DbgContext * const dbg, const glesv2debugger::Message & cmd,
+                         glesv2debugger::Message & msg, const int * const prevRet);
 }; // namespace android {
diff --git a/opengl/libs/GLES2_dbg/src/server.cpp b/opengl/libs/GLES2_dbg/src/server.cpp
index 03c3dae..7039c84 100644
--- a/opengl/libs/GLES2_dbg/src/server.cpp
+++ b/opengl/libs/GLES2_dbg/src/server.cpp
@@ -153,10 +153,9 @@
         assert(msg.has_context_id() && msg.context_id() != 0);
     static std::string str;
     msg.SerializeToString(&str);
-    unsigned len = str.length();
-    len = htonl(len);
+    uint32_t len = htonl(str.length());
     int sent = -1;
-    sent = send(clientSock, (const char *)&len, sizeof(len), 0);
+    sent = send(clientSock, &len, sizeof(len), 0);
     if (sent != sizeof(len)) {
         LOGD("actual sent=%d expected=%d clientSock=%d", sent, sizeof(len), clientSock);
         Die("Failed to send message length");
@@ -182,12 +181,11 @@
     } else
         Receive(cmd);
 
-    //LOGD("Message sent tid=%lu len=%d", pthread_self(), str.length());
     pthread_mutex_unlock(&mutex);
     return t;
 }
 
-void SetProp(const glesv2debugger::Message & cmd)
+void SetProp(DbgContext * const dbg, const glesv2debugger::Message & cmd)
 {
     switch (cmd.prop()) {
     case glesv2debugger::Message_Prop_Capture:
@@ -198,19 +196,24 @@
         LOGD("SetProp Message_Prop_TimeMode %d", cmd.arg0());
         timeMode = cmd.arg0();
         break;
+    case glesv2debugger::Message_Prop_ExpectResponse:
+        LOGD("SetProp Message_Prop_ExpectResponse %d=%d", cmd.arg0(), cmd.arg1());
+        dbg->expectResponse.Bit((glesv2debugger::Message_Function)cmd.arg0(), cmd.arg1());
+        break;
     default:
         assert(0);
     }
 }
 
 int * MessageLoop(FunctionCall & functionCall, glesv2debugger::Message & msg,
-                  const bool expectResponse, const glesv2debugger::Message_Function function)
+                  const glesv2debugger::Message_Function function)
 {
     DbgContext * const dbg = getDbgContextThreadSpecific();
     const int * ret = 0;
     glesv2debugger::Message cmd;
     msg.set_context_id(reinterpret_cast<int>(dbg));
     msg.set_type(glesv2debugger::Message_Type_BeforeCall);
+    const bool expectResponse = dbg->expectResponse.Bit(function);
     msg.set_expect_response(expectResponse);
     msg.set_function(function);
     if (!expectResponse)
@@ -237,11 +240,15 @@
         case glesv2debugger::Message_Function_SKIP:
             return const_cast<int *>(ret);
         case glesv2debugger::Message_Function_SETPROP:
-            SetProp(cmd);
+            SetProp(dbg, cmd);
             Receive(cmd);
             break;
         default:
-            assert(0); //GenerateCall(msg, cmd);
+            ret = GenerateCall(dbg, cmd, msg, ret);
+            msg.set_expect_response(expectResponse);
+            if (!expectResponse)
+                cmd.set_function(cmd.SKIP);
+            Send(msg, cmd);
             break;
         }
     }
diff --git a/opengl/libs/GLES2_dbg/src/texture.cpp b/opengl/libs/GLES2_dbg/src/texture.cpp
deleted file mode 100644
index 3aa0aab..0000000
--- a/opengl/libs/GLES2_dbg/src/texture.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- ** 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.
- */
-
-#include "header.h"
-
-namespace android
-{
-unsigned GetBytesPerPixel(const GLenum format, const GLenum type)
-{
-    switch (type) {
-    case GL_UNSIGNED_SHORT_5_6_5:
-        return 2;
-    case GL_UNSIGNED_SHORT_4_4_4_4:
-        return 2;
-    case GL_UNSIGNED_SHORT_5_5_5_1:
-        return 2;
-    case GL_UNSIGNED_BYTE:
-        break;
-    default:
-        assert(0);
-    }
-
-    switch (format) {
-    case GL_ALPHA:
-        return 1;
-    case GL_LUMINANCE:
-        return 1;
-        break;
-    case GL_LUMINANCE_ALPHA:
-        return 2;
-    case GL_RGB:
-        return 3;
-    case GL_RGBA:
-        return 4;
-    default:
-        assert(0);
-        return 0;
-    }
-}
-
-#define USE_RLE 0
-#if USE_RLE
-export template<typename T>
-void * RLEEncode(const void * pixels, unsigned count, unsigned * encodedSize)
-{
-    // first is a byte indicating data size [1,2,4] bytes
-    // then an unsigned indicating decompressed size
-    // then a byte of header: MSB == 1 indicates run, else literal
-    // LSB7 is run or literal length (actual length - 1)
-
-    const T * data = (T *)pixels;
-    unsigned bufferSize = sizeof(T) * count / 2 + 8;
-    unsigned char * buffer = (unsigned char *)malloc(bufferSize);
-    buffer[0] = sizeof(T);
-    unsigned bufferWritten = 1; // number of bytes written
-    *(unsigned *)(buffer + bufferWritten) = count;
-    bufferWritten += sizeof(count);
-    while (count) {
-        unsigned char run = 1;
-        bool repeat = true;
-        for (run = 1; run < count; run++)
-            if (data[0] != data[run]) {
-                repeat = false;
-                break;
-            } else if (run > 126)
-                break;
-        if (!repeat) {
-            // find literal length
-            for (run = 1; run < count; run++)
-                if (data[run - 1] == data[run])
-                    break;
-                else if (run > 126)
-                    break;
-            unsigned bytesToWrite = 1 + sizeof(T) * run;
-            if (bufferWritten + bytesToWrite > bufferSize) {
-                bufferSize += sizeof(T) * run + 256;
-                buffer = (unsigned char *)realloc(buffer, bufferSize);
-            }
-            buffer[bufferWritten++] = run - 1;
-            for (unsigned i = 0; i < run; i++) {
-                *(T *)(buffer + bufferWritten) = *data;
-                bufferWritten += sizeof(T);
-                data++;
-            }
-            count -= run;
-        } else {
-            unsigned bytesToWrite = 1 + sizeof(T);
-            if (bufferWritten + bytesToWrite > bufferSize) {
-                bufferSize += 256;
-                buffer = (unsigned char *)realloc(buffer, bufferSize);
-            }
-            buffer[bufferWritten++] = (run - 1) | 0x80;
-            *(T *)(buffer + bufferWritten) = data[0];
-            bufferWritten += sizeof(T);
-            data += run;
-            count -= run;
-        }
-    }
-    if (encodedSize)
-        *encodedSize = bufferWritten;
-    return buffer;
-}
-
-void * RLEEncode(const void * pixels, const unsigned bytesPerPixel, const unsigned count, unsigned * encodedSize)
-{
-    switch (bytesPerPixel) {
-    case 4:
-        return RLEEncode<int>(pixels, count, encodedSize);
-    case 2:
-        return RLEEncode<short>(pixels, count, encodedSize);
-    case 1:
-        return RLEEncode<char>(pixels, count, encodedSize);
-    default:
-        assert(0);
-        return NULL;
-    }
-}
-#endif
-}; // namespace android
-
-void Debug_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
-{
-    glesv2debugger::Message msg;
-    const bool expectResponse = false;
-    struct : public FunctionCall {
-        GLenum target;
-        GLint level;
-        GLint internalformat;
-        GLsizei width;
-        GLsizei height;
-        GLint border;
-        GLenum format;
-        GLenum type;
-        const GLvoid* pixels;
-
-        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
-            nsecs_t c0 = systemTime(timeMode);
-            _c->glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
-            msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
-            return 0;
-        }
-    } caller;
-    caller.target = target;
-    caller.level = level;
-    caller.internalformat = internalformat;
-    caller.width = width;
-    caller.height = height;
-    caller.border = border;
-    caller.format = format;
-    caller.type = type;
-    caller.pixels = pixels;
-
-    msg.set_arg0(target);
-    msg.set_arg1(level);
-    msg.set_arg2(internalformat);
-    msg.set_arg3(width);
-    msg.set_arg4(height);
-    msg.set_arg5(border);
-    msg.set_arg6(format);
-    msg.set_arg7(type);
-    msg.set_arg8(reinterpret_cast<int>(pixels));
-
-    if (pixels) {
-        assert(internalformat == format);
-        assert(0 == border);
-
-        unsigned bytesPerPixel = GetBytesPerPixel(format, type);
-        assert(0 < bytesPerPixel);
-
-//        LOGD("GLESv2_dbg: glTexImage2D width=%d height=%d level=%d bytesPerPixel=%d",
-//             width, height, level, bytesPerPixel);
-#if USE_RLE
-        unsigned encodedSize = 0;
-        void * data = RLEEncode(pixels, bytesPerPixel, width * height, &encodedSize);
-        msg.set_data(data, encodedSize);
-        free(data);
-        if (encodedSize > bytesPerPixel * width * height)
-            LOGD("GLESv2_dbg: glTexImage2D sending data encodedSize=%d size=%d", encodedSize, bytesPerPixel * width * height);
-#else
-        msg.set_data(pixels, bytesPerPixel * width * height);
-#endif
-    }
-    
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glTexImage2D);
-}
-
-void Debug_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels)
-{
-    glesv2debugger::Message msg;
-    const bool expectResponse = false;
-    struct : public FunctionCall {
-        GLenum target;
-        GLint level;
-        GLint xoffset;
-        GLint yoffset;
-        GLsizei width;
-        GLsizei height;
-        GLenum format;
-        GLenum type;
-        const GLvoid* pixels;
-
-        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
-            nsecs_t c0 = systemTime(timeMode);
-            _c->glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
-            msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
-            return 0;
-        }
-    } caller;
-    caller.target = target;
-    caller.level = level;
-    caller.xoffset = xoffset;
-    caller.yoffset = yoffset;
-    caller.width = width;
-    caller.height = height;
-    caller.format = format;
-    caller.type = type;
-    caller.pixels = pixels;
-
-    msg.set_arg0(target);
-    msg.set_arg1(level);
-    msg.set_arg2(xoffset);
-    msg.set_arg3(yoffset);
-    msg.set_arg4(width);
-    msg.set_arg5(height);
-    msg.set_arg6(format);
-    msg.set_arg7(type);
-    msg.set_arg8(reinterpret_cast<int>(pixels));
-
-    assert(pixels);
-    if (pixels) {
-        unsigned bytesPerPixel = GetBytesPerPixel(format, type);
-        assert(0 < bytesPerPixel);
-
-//        LOGD("GLESv2_dbg: glTexSubImage2D width=%d height=%d level=%d bytesPerPixel=%d",
-//             width, height, level, bytesPerPixel);
-
-#if USE_RLE
-        unsigned encodedSize = 0;
-        void * data = RLEEncode(pixels, bytesPerPixel, width * height, &encodedSize);
-        msg.set_data(data, encodedSize);
-        free(data);
-        if (encodedSize > bytesPerPixel * width * height)
-            LOGD("GLESv2_dbg: glTexImage2D sending data encodedSize=%d size=%d", encodedSize, bytesPerPixel * width * height);
-#else
-        msg.set_data(pixels, bytesPerPixel * width * height);
-#endif
-    }
-    
-    int * ret = MessageLoop(caller, msg, expectResponse,
-                            glesv2debugger::Message_Function_glTexSubImage2D);
-}
\ No newline at end of file
diff --git a/opengl/libs/GLES2_dbg/src/vertex.cpp b/opengl/libs/GLES2_dbg/src/vertex.cpp
index a73967f..471e5ad 100644
--- a/opengl/libs/GLES2_dbg/src/vertex.cpp
+++ b/opengl/libs/GLES2_dbg/src/vertex.cpp
@@ -19,8 +19,6 @@
 namespace android
 {
 bool capture; // capture after each glDraw*
-
-void * RLEEncode(const void * pixels, const unsigned bytesPerPixel, const unsigned count, unsigned * encodedSize);
 }
 
 void Debug_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
@@ -29,7 +27,7 @@
     glesv2debugger::Message msg, cmd;
     msg.set_context_id(reinterpret_cast<int>(dbg));
     msg.set_type(glesv2debugger::Message_Type_BeforeCall);
-    const bool expectResponse = false;
+    const bool expectResponse = dbg->expectResponse.Bit(glesv2debugger::Message_Function_glReadPixels);
     msg.set_expect_response(expectResponse);
     msg.set_function(glesv2debugger::Message_Function_glReadPixels);
     msg.set_arg0(x);
@@ -39,8 +37,8 @@
     msg.set_arg4(format);
     msg.set_arg5(type);
     msg.set_arg6(reinterpret_cast<int>(pixels));
-    //void * data = NULL;
-    //unsigned encodedSize = 0;
+
+    const unsigned size = width * height * GetBytesPerPixel(format, type);
     if (!expectResponse)
         cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
     Send(msg, cmd);
@@ -56,30 +54,29 @@
             msg.set_function(glesv2debugger::Message_Function_glReadPixels);
             msg.set_type(glesv2debugger::Message_Type_AfterCall);
             msg.set_expect_response(expectResponse);
-            //data = RLEEncode(pixels, GetBytesPerPixel(format, type), width * height, &encodedSize);
-            msg.set_data(pixels, width * height * GetBytesPerPixel(format, type));
-            //msg.set_data(data, encodedSize);
-            //free(data);
-            c0 = systemTime(timeMode);
+            if (dbg->IsReadPixelBuffer(pixels)) {
+                dbg->CompressReadPixelBuffer(msg.mutable_data());
+                msg.set_data_type(msg.ReferencedImage);
+            } else {
+                dbg->Compress(pixels, size, msg.mutable_data());
+                msg.set_data_type(msg.NonreferencedImage);
+            }
             if (!expectResponse)
                 cmd.set_function(glesv2debugger::Message_Function_SKIP);
-            t = Send(msg, cmd);
-            msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
-            msg.set_clock(t);
-            // time is total send time in seconds, clock is msg serialization time in seconds
-            msg.clear_data();
-            msg.set_expect_response(false);
-            msg.set_type(glesv2debugger::Message_Type_AfterCall);
-            //Send(msg, cmd);
+            Send(msg, cmd);
             break;
         case glesv2debugger::Message_Function_SKIP:
             return;
         case glesv2debugger::Message_Function_SETPROP:
-            SetProp(cmd);
+            SetProp(dbg, cmd);
             Receive(cmd);
             break;
         default:
-            assert(0); //GenerateCall(msg, cmd);
+            GenerateCall(dbg, cmd, msg, NULL);
+            msg.set_expect_response(expectResponse);
+            if (!expectResponse)
+                cmd.set_function(cmd.SKIP);
+            Send(msg, cmd);
             break;
         }
     }
@@ -91,7 +88,7 @@
     glesv2debugger::Message msg, cmd;
     msg.set_context_id(reinterpret_cast<int>(dbg));
     msg.set_type(glesv2debugger::Message_Type_BeforeCall);
-    const bool expectResponse = false;
+    const bool expectResponse = dbg->expectResponse.Bit(glesv2debugger::Message_Function_glDrawArrays);
     msg.set_expect_response(expectResponse);
     msg.set_function(glesv2debugger::Message_Function_glDrawArrays);
     msg.set_arg0(mode);
@@ -129,22 +126,26 @@
                 dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
                 dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat);
                 dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType);
-                LOGD("glDrawArrays CAPTURE: x=%d y=%d width=%d height=%d format=0x%.4X type=0x%.4X",
-                     viewport[0], viewport[1], viewport[2], viewport[3], readFormat, readType);
-                pixels = malloc(viewport[2] * viewport[3] * 4);
+//                LOGD("glDrawArrays CAPTURE: x=%d y=%d width=%d height=%d format=0x%.4X type=0x%.4X",
+//                     viewport[0], viewport[1], viewport[2], viewport[3], readFormat, readType);
+                pixels = dbg->GetReadPixelsBuffer(viewport[2] * viewport[3] *
+                                                  GetBytesPerPixel(readFormat, readType));
                 Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
                                    readFormat, readType, pixels);
-                free(pixels);
             }
             break;
         case glesv2debugger::Message_Function_SKIP:
             return;
         case glesv2debugger::Message_Function_SETPROP:
-            SetProp(cmd);
+            SetProp(dbg, cmd);
             Receive(cmd);
             break;
         default:
-            assert(0); //GenerateCall(msg, cmd);
+            GenerateCall(dbg, cmd, msg, NULL);
+            msg.set_expect_response(expectResponse);
+            if (!expectResponse)
+                cmd.set_function(cmd.SKIP);
+            Send(msg, cmd);
             break;
         }
     }
@@ -168,7 +169,7 @@
     glesv2debugger::Message msg, cmd;
     msg.set_context_id(reinterpret_cast<int>(dbg));
     msg.set_type(glesv2debugger::Message_Type_BeforeCall);
-    const bool expectResponse = false;
+    const bool expectResponse = dbg->expectResponse.Bit(glesv2debugger::Message_Function_glDrawElements);
     msg.set_expect_response(expectResponse);
     msg.set_function(glesv2debugger::Message_Function_glDrawElements);
     msg.set_arg0(mode);
@@ -180,12 +181,14 @@
     std::string * const data = msg.mutable_data();
     if (GL_UNSIGNED_BYTE == type) {
         if (dbg->indexBuffer)
-            FetchIndexed(count, (unsigned char *)dbg->indexBuffer->data + (unsigned long)indices, data, dbg);
+            FetchIndexed(count, (unsigned char *)dbg->indexBuffer->data +
+                         (unsigned long)indices, data, dbg);
         else
             FetchIndexed(count, (unsigned char *)indices, data, dbg);
     } else if (GL_UNSIGNED_SHORT == type) {
         if (dbg->indexBuffer)
-            FetchIndexed(count, (unsigned short *)((char *)dbg->indexBuffer->data + (unsigned long)indices), data, dbg);
+            FetchIndexed(count, (unsigned short *)((char *)dbg->indexBuffer->data +
+                                                   (unsigned long)indices), data, dbg);
         else
             FetchIndexed(count, (unsigned short *)indices, data, dbg);
     } else
@@ -215,22 +218,26 @@
                 dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
                 dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat);
                 dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType);
-                LOGD("glDrawArrays CAPTURE: x=%d y=%d width=%d height=%d format=0x%.4X type=0x%.4X",
-                     viewport[0], viewport[1], viewport[2], viewport[3], readFormat, readType);
-                pixels = malloc(viewport[2] * viewport[3] * 4);
+//                LOGD("glDrawArrays CAPTURE: x=%d y=%d width=%d height=%d format=0x%.4X type=0x%.4X",
+//                     viewport[0], viewport[1], viewport[2], viewport[3], readFormat, readType);
+                pixels = dbg->GetReadPixelsBuffer(viewport[2] * viewport[3] *
+                                                  GetBytesPerPixel(readFormat, readType));
                 Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
                                    readFormat, readType, pixels);
-                free(pixels);
             }
             break;
         case glesv2debugger::Message_Function_SKIP:
             return;
         case glesv2debugger::Message_Function_SETPROP:
-            SetProp(cmd);
+            SetProp(dbg, cmd);
             Receive(cmd);
             break;
         default:
-            assert(0); //GenerateCall(msg, cmd);
+            GenerateCall(dbg, cmd, msg, NULL);
+            msg.set_expect_response(expectResponse);
+            if (!expectResponse)
+                cmd.set_function(cmd.SKIP);
+            Send(msg, cmd);
             break;
         }
     }
diff --git a/opengl/tests/gl2_cameraeye/Android.mk b/opengl/tests/gl2_cameraeye/Android.mk
new file mode 100644
index 0000000..4a43a9e
--- /dev/null
+++ b/opengl/tests/gl2_cameraeye/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := GL2CameraEye
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
+
+# Use the following include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/opengl/tests/gl2_cameraeye/AndroidManifest.xml b/opengl/tests/gl2_cameraeye/AndroidManifest.xml
new file mode 100644
index 0000000..c53f7be
--- /dev/null
+++ b/opengl/tests/gl2_cameraeye/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+
+<!-- Declare the contents of this Android application.  The namespace
+     attribute brings in the Android platform namespace, and the package
+     supplies a unique name for the application.  When writing your
+     own application, the package name must be changed from "com.example.*"
+     to come from a domain that you own or have control over. -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.gl2cameraeye">
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-feature android:name="android.hardware.camera" />
+    <uses-feature android:name="android.hardware.camera.autofocus" />
+    <uses-feature android:glEsVersion="0x00020000" />
+    <application android:label="@string/gl2cameraeye_name">
+        <activity android:name="GL2CameraEye">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/opengl/tests/gl2_cameraeye/res/values/strings.xml b/opengl/tests/gl2_cameraeye/res/values/strings.xml
new file mode 100644
index 0000000..386b930
--- /dev/null
+++ b/opengl/tests/gl2_cameraeye/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 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.
+-->
+
+<resources>
+
+    <string name="gl2cameraeye_name">GL2CameraEye</string>
+
+</resources>
diff --git a/opengl/tests/gl2_cameraeye/src/com/android/gl2cameraeye/GL2CameraEye.java b/opengl/tests/gl2_cameraeye/src/com/android/gl2cameraeye/GL2CameraEye.java
new file mode 100644
index 0000000..561e4c5
--- /dev/null
+++ b/opengl/tests/gl2_cameraeye/src/com/android/gl2cameraeye/GL2CameraEye.java
@@ -0,0 +1,508 @@
+/*
+ * Copyright (C) 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.gl2cameraeye;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.app.Activity;
+import android.content.pm.ActivityInfo;
+import android.os.Bundle;
+import android.view.MotionEvent;
+import android.content.Context;
+import android.util.Log;
+
+import android.opengl.GLES20;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLUtils;
+import android.opengl.Matrix;
+
+import android.graphics.SurfaceTexture;
+
+import android.hardware.Camera;
+import android.hardware.SensorManager;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.Sensor;
+
+public class GL2CameraEye extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mGLView = new CamGLSurfaceView(this);
+        setContentView(mGLView);
+        setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        mGLView.onPause();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mGLView.onResume();
+    }
+
+    private GLSurfaceView mGLView;
+}
+
+class CamGLSurfaceView extends GLSurfaceView implements SensorEventListener {
+    public CamGLSurfaceView(Context context) {
+        super(context);
+        setEGLContextClientVersion(2);
+        mRenderer = new CamRenderer(context);
+        setRenderer(mRenderer);
+
+        mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
+        mAcceleration = mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
+    }
+
+    public boolean onTouchEvent(final MotionEvent event) {
+        queueEvent(new Runnable(){
+                public void run() {
+                mRenderer.setPosition(event.getX() / getWidth(),
+                                      event.getY() / getHeight());
+            }});
+        return true;
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mCamera.stopPreview();
+        mCamera.release();
+
+        mSensorManager.unregisterListener(this);
+    }
+
+    @Override
+    public void onResume() {
+        mCamera = Camera.open();
+        Camera.Parameters p = mCamera.getParameters();
+        // No changes to default camera parameters
+        mCamera.setParameters(p);
+
+        queueEvent(new Runnable(){
+                public void run() {
+                    mRenderer.setCamera(mCamera);
+                }});
+
+        mSensorManager.registerListener(this, mAcceleration, SensorManager.SENSOR_DELAY_GAME);
+        super.onResume();
+    }
+
+    public void onSensorChanged(SensorEvent event) {
+        if (event.sensor.getType() == Sensor.TYPE_LINEAR_ACCELERATION) {
+            final float[] accelerationVector = event.values;
+            queueEvent(new Runnable(){
+                    public void run() {
+                        mRenderer.setAcceleration(accelerationVector);
+                    }});
+        }
+    }
+
+    public void onAccuracyChanged(Sensor sensor, int accuracy) {
+        // Ignoring sensor accuracy changes.
+    }
+
+    CamRenderer mRenderer;
+    Camera mCamera;
+
+    SensorManager mSensorManager;
+    Sensor mAcceleration;
+}
+
+class CamRenderer implements GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener {
+
+    public CamRenderer(Context context) {
+        mContext = context;
+
+        mTriangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length
+                * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
+        mTriangleVertices.put(mTriangleVerticesData).position(0);
+
+        Matrix.setIdentityM(mSTMatrix, 0);
+        Matrix.setIdentityM(mMMatrix, 0);
+
+        float[] defaultAcceleration = {0.f,0.f,0.f};
+        setAcceleration(defaultAcceleration);
+        mPos[0] = 0.f;
+        mPos[1] = 0.f;
+        mPos[2] = 0.f;
+        mVel[0] = 0.f;
+        mVel[1] = 0.f;
+        mVel[2] = 0.f;
+
+    }
+
+    /* The following set methods are not synchronized, so should only
+     * be called within the rendering thread context. Use GLSurfaceView.queueEvent for safe access.
+     */
+    public void setPosition(float x, float y) {
+        /* Map from screen (0,0)-(1,1) to scene coordinates */
+        mPos[0] = (x*2-1)*mRatio;
+        mPos[1] = (-y)*2+1;
+        mPos[2] = 0.f;
+        mVel[0] = 0;
+        mVel[1] = 0;
+        mVel[2] = 0;
+    }
+
+    public void setCamera(Camera camera) {
+        mCamera = camera;
+        Camera.Size previewSize = camera.getParameters().getPreviewSize();
+        mCameraRatio = (float)previewSize.width/previewSize.height;
+    }
+
+    public void setAcceleration(float[] accelerationVector) {
+        mGForce[0] = accelerationVector[0];
+        mGForce[1] = accelerationVector[1];
+        mGForce[2] = accelerationVector[2];
+    }
+
+    public void onDrawFrame(GL10 glUnused) {
+        synchronized(this) {
+            if (updateSurface) {
+                mSurface.updateTexImage();
+
+                mSurface.getTransformMatrix(mSTMatrix);
+                long timestamp = mSurface.getTimestamp();
+                doPhysics(timestamp);
+
+                updateSurface = false;
+            }
+        }
+
+        // Ignore the passed-in GL10 interface, and use the GLES20
+        // class's static methods instead.
+        GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
+        GLES20.glUseProgram(mProgram);
+        checkGlError("glUseProgram");
+
+        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
+        GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID);
+
+        mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
+        GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false,
+                TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
+        checkGlError("glVertexAttribPointer maPosition");
+        GLES20.glEnableVertexAttribArray(maPositionHandle);
+        checkGlError("glEnableVertexAttribArray maPositionHandle");
+
+        mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
+        GLES20.glVertexAttribPointer(maTextureHandle, 3, GLES20.GL_FLOAT, false,
+                TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
+        checkGlError("glVertexAttribPointer maTextureHandle");
+        GLES20.glEnableVertexAttribArray(maTextureHandle);
+        checkGlError("glEnableVertexAttribArray maTextureHandle");
+
+        Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
+        Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
+
+        GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
+        GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0);
+        GLES20.glUniform1f(muCRatioHandle, mCameraRatio);
+
+        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
+        checkGlError("glDrawArrays");
+    }
+
+    public void onSurfaceChanged(GL10 glUnused, int width, int height) {
+        // Ignore the passed-in GL10 interface, and use the GLES20
+        // class's static methods instead.
+        GLES20.glViewport(0, 0, width, height);
+        mRatio = (float) width / height;
+        Matrix.frustumM(mProjMatrix, 0, -mRatio, mRatio, -1, 1, 3, 7);
+    }
+
+    public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {
+        // Ignore the passed-in GL10 interface, and use the GLES20
+        // class's static methods instead.
+
+        /* Set up alpha blending and an Android background color */
+        GLES20.glEnable(GLES20.GL_BLEND);
+        GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
+        GLES20.glClearColor(0.643f, 0.776f, 0.223f, 1.0f);
+
+        /* Set up shaders and handles to their variables */
+        mProgram = createProgram(mVertexShader, mFragmentShader);
+        if (mProgram == 0) {
+            return;
+        }
+        maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
+        checkGlError("glGetAttribLocation aPosition");
+        if (maPositionHandle == -1) {
+            throw new RuntimeException("Could not get attrib location for aPosition");
+        }
+        maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");
+        checkGlError("glGetAttribLocation aTextureCoord");
+        if (maTextureHandle == -1) {
+            throw new RuntimeException("Could not get attrib location for aTextureCoord");
+        }
+
+        muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
+        checkGlError("glGetUniformLocation uMVPMatrix");
+        if (muMVPMatrixHandle == -1) {
+            throw new RuntimeException("Could not get attrib location for uMVPMatrix");
+        }
+
+        muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uSTMatrix");
+        checkGlError("glGetUniformLocation uSTMatrix");
+        if (muMVPMatrixHandle == -1) {
+            throw new RuntimeException("Could not get attrib location for uSTMatrix");
+        }
+
+        muCRatioHandle = GLES20.glGetUniformLocation(mProgram, "uCRatio");
+        checkGlError("glGetUniformLocation uCRatio");
+        if (muMVPMatrixHandle == -1) {
+            throw new RuntimeException("Could not get attrib location for uCRatio");
+        }
+
+        /*
+         * Create our texture. This has to be done each time the
+         * surface is created.
+         */
+
+        int[] textures = new int[1];
+        GLES20.glGenTextures(1, textures, 0);
+
+        mTextureID = textures[0];
+        GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID);
+        checkGlError("glBindTexture mTextureID");
+
+        // Can't do mipmapping with camera source
+        GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER,
+                GLES20.GL_NEAREST);
+        GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER,
+                GLES20.GL_LINEAR);
+        // Clamp to edge is the only option
+        GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S,
+                GLES20.GL_CLAMP_TO_EDGE);
+        GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T,
+                GLES20.GL_CLAMP_TO_EDGE);
+        checkGlError("glTexParameteri mTextureID");
+
+        /*
+         * Create the SurfaceTexture that will feed this textureID, and pass it to the camera
+         */
+
+        mSurface = new SurfaceTexture(mTextureID);
+        mSurface.setOnFrameAvailableListener(this);
+        try {
+            mCamera.setPreviewTexture(mSurface);
+        } catch (IOException t) {
+            Log.e(TAG, "Cannot set preview texture target!");
+        }
+
+        /* Start the camera */
+        mCamera.startPreview();
+
+        Matrix.setLookAtM(mVMatrix, 0, 0, 0, 5f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
+
+        mLastTime = 0;
+
+        synchronized(this) {
+            updateSurface = false;
+        }
+    }
+
+    synchronized public void onFrameAvailable(SurfaceTexture surface) {
+        /* For simplicity, SurfaceTexture calls here when it has new
+         * data available.  Call may come in from some random thread,
+         * so let's be safe and use synchronize. No OpenGL calls can be done here.
+         */
+        updateSurface = true;
+    }
+
+    private void doPhysics(long timestamp) {
+        /*
+         * Move the camera surface around based on some simple spring physics with drag
+         */
+
+        if (mLastTime == 0)
+            mLastTime = timestamp;
+
+        float deltaT = (timestamp - mLastTime)/1000000000.f; // To seconds
+
+        float springStrength = 20.f;
+        float frictionCoeff = 10.f;
+        float mass = 10.f;
+        float gMultiplier = 4.f;
+        /* Only update physics every 30 ms */
+        if (deltaT > 0.030f) {
+            mLastTime = timestamp;
+
+            float[] totalForce = new float[3];
+            totalForce[0] = -mPos[0] * springStrength - mVel[0]*frictionCoeff + gMultiplier*mGForce[0]*mass;
+            totalForce[1] = -mPos[1] * springStrength - mVel[1]*frictionCoeff + gMultiplier*mGForce[1]*mass;
+            totalForce[2] = -mPos[2] * springStrength - mVel[2]*frictionCoeff + gMultiplier*mGForce[2]*mass;
+
+            float[] accel = new float[3];
+            accel[0] = totalForce[0]/mass;
+            accel[1] = totalForce[1]/mass;
+            accel[2] = totalForce[2]/mass;
+
+            /* Not a very accurate integrator */
+            mVel[0] = mVel[0] + accel[0]*deltaT;
+            mVel[1] = mVel[1] + accel[1]*deltaT;
+            mVel[2] = mVel[2] + accel[2]*deltaT;
+
+            mPos[0] = mPos[0] + mVel[0]*deltaT;
+            mPos[1] = mPos[1] + mVel[1]*deltaT;
+            mPos[2] = mPos[2] + mVel[2]*deltaT;
+
+            Matrix.setIdentityM(mMMatrix, 0);
+            Matrix.translateM(mMMatrix, 0, mPos[0], mPos[1], mPos[2]);
+        }
+
+    }
+
+    private int loadShader(int shaderType, String source) {
+        int shader = GLES20.glCreateShader(shaderType);
+        if (shader != 0) {
+            GLES20.glShaderSource(shader, source);
+            GLES20.glCompileShader(shader);
+            int[] compiled = new int[1];
+            GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
+            if (compiled[0] == 0) {
+                Log.e(TAG, "Could not compile shader " + shaderType + ":");
+                Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
+                GLES20.glDeleteShader(shader);
+                shader = 0;
+            }
+        }
+        return shader;
+    }
+
+    private int createProgram(String vertexSource, String fragmentSource) {
+        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
+        if (vertexShader == 0) {
+            return 0;
+        }
+        int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
+        if (pixelShader == 0) {
+            return 0;
+        }
+
+        int program = GLES20.glCreateProgram();
+        if (program != 0) {
+            GLES20.glAttachShader(program, vertexShader);
+            checkGlError("glAttachShader");
+            GLES20.glAttachShader(program, pixelShader);
+            checkGlError("glAttachShader");
+            GLES20.glLinkProgram(program);
+            int[] linkStatus = new int[1];
+            GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
+            if (linkStatus[0] != GLES20.GL_TRUE) {
+                Log.e(TAG, "Could not link program: ");
+                Log.e(TAG, GLES20.glGetProgramInfoLog(program));
+                GLES20.glDeleteProgram(program);
+                program = 0;
+            }
+        }
+        return program;
+    }
+
+    private void checkGlError(String op) {
+        int error;
+        while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
+            Log.e(TAG, op + ": glError " + error);
+            throw new RuntimeException(op + ": glError " + error);
+        }
+    }
+
+    private static final int FLOAT_SIZE_BYTES = 4;
+    private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES;
+    private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;
+    private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3;
+    private final float[] mTriangleVerticesData = {
+        // X, Y, Z, U, V
+        -1.0f, -1.0f, 0, 0.f, 0.f,
+        1.0f, -1.0f, 0, 1.f, 0.f,
+        -1.0f,  1.0f, 0, 0.f, 1.f,
+        1.0f,   1.0f, 0, 1.f, 1.f,
+    };
+
+    private FloatBuffer mTriangleVertices;
+
+    private final String mVertexShader =
+        "uniform mat4 uMVPMatrix;\n" +
+        "uniform mat4 uSTMatrix;\n" +
+        "uniform float uCRatio;\n" +
+        "attribute vec4 aPosition;\n" +
+        "attribute vec4 aTextureCoord;\n" +
+        "varying vec2 vTextureCoord;\n" +
+        "varying vec2 vTextureNormCoord;\n" +
+        "void main() {\n" +
+        "  vec4 scaledPos = aPosition;\n" +
+        "  scaledPos.x = scaledPos.x * uCRatio;\n" +
+        "  gl_Position = uMVPMatrix * scaledPos;\n" +
+        "  vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" +
+        "  vTextureNormCoord = aTextureCoord.xy;\n" +
+        "}\n";
+
+    private final String mFragmentShader =
+        "#extension GL_OES_EGL_image_external : require\n" +
+        "precision mediump float;\n" +
+        "varying vec2 vTextureCoord;\n" +
+        "varying vec2 vTextureNormCoord;\n" +
+        "uniform samplerExternalOES sTexture;\n" +
+        "void main() {\n" +
+        "  gl_FragColor = texture2D(sTexture, vTextureCoord);\n" +
+        "  gl_FragColor.a = 1.0-min(length(vTextureNormCoord-0.5)*2.0,1.0);\n" +
+        "}\n";
+
+    private float[] mMVPMatrix = new float[16];
+    private float[] mProjMatrix = new float[16];
+    private float[] mMMatrix = new float[16];
+    private float[] mVMatrix = new float[16];
+    private float[] mSTMatrix = new float[16];
+
+    private int mProgram;
+    private int mTextureID;
+    private int muMVPMatrixHandle;
+    private int muSTMatrixHandle;
+    private int muCRatioHandle;
+    private int maPositionHandle;
+    private int maTextureHandle;
+
+    private float mRatio = 1.0f;
+    private float mCameraRatio = 1.0f;
+    private float[] mVel = new float[3];
+    private float[] mPos = new float[3];
+    private float[] mGForce = new float[3];
+
+    private long mLastTime;
+
+    private SurfaceTexture mSurface;
+    private Camera mCamera;
+    private boolean updateSurface = false;
+
+    private Context mContext;
+    private static String TAG = "CamRenderer";
+
+    // Magic key
+    private static int GL_TEXTURE_EXTERNAL_OES = 0x8D65;
+}
diff --git a/opengl/tools/glgen/specs/gles11/checks.spec b/opengl/tools/glgen/specs/gles11/checks.spec
index f917128..f478a32 100644
--- a/opengl/tools/glgen/specs/gles11/checks.spec
+++ b/opengl/tools/glgen/specs/gles11/checks.spec
@@ -31,28 +31,12 @@
 glDrawTexivOES check coords 5
 glDrawTexsvOES check coords 5
 glDrawTexxvOES check coords 5
-glBindFramebufferOES unsupported
-glBindRenderbufferOES unsupported
-glBlendEquation unsupported
-glBlendEquationSeparate unsupported
-glBlendFuncSeparate unsupported
-glCheckFramebufferStatusOES unsupported return 0
-glDeleteFramebuffersOES unsupported
-glDeleteRenderbuffersOES unsupported
-glFramebufferRenderbufferOES unsupported
-glFramebufferStorageOES unsupported
-glFramebufferTexture2DOES unsupported
-glGenFramebuffersOES unsupported
-glGenRenderbuffersOES unsupported
-glGenerateMipmapOES unsupported
-glGetBufferParameter unsupported
-glGetFramebufferAttachmentParameterivOES unsupported
-glGetRenderbufferParameterivOES unsupported
-glGetTexGen unsupported
-glIsFramebufferOES unsupported return JNI_FALSE
-glIsRenderbufferOES unsupported return JNI_FALSE
-glRenderbufferStorageOES unsupported return false
-glTexGen unsupported
-glTexGenf unsupported
-glTexGeni unsupported
-glTexGenx unsupported
+glDeleteFramebuffersOES check framebuffers n
+glDeleteRenderbuffersOES check renderbuffers n
+glGenFramebuffersOES check framebuffers n
+glGenRenderbuffersOES check renderbuffers n
+glGetBufferParameter check params 1
+glGetFramebufferAttachmentParameterivOES check params 1
+glGetRenderbufferParameterivOES check params 1
+glGetTexGen ifcheck params 1 pname GL_TEXTURE_GEN_MODE ifcheck params 4 pname GL_OBJECT_PLANE,GL_EYE_PLANE
+
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 8a00a2e..9daaad8 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -41,7 +41,7 @@
 	libGLESv1_CM \
 	libbinder \
 	libui \
-	libsurfaceflinger_client
+	libgui
 
 LOCAL_C_INCLUDES := \
 	$(call include-path-for, corecg graphics)
diff --git a/services/surfaceflinger/tests/resize/Android.mk b/services/surfaceflinger/tests/resize/Android.mk
index 24c2d01..d81679e 100644
--- a/services/surfaceflinger/tests/resize/Android.mk
+++ b/services/surfaceflinger/tests/resize/Android.mk
@@ -8,7 +8,7 @@
 	libcutils \
 	libutils \
     libui \
-    libsurfaceflinger_client
+    libgui
 
 LOCAL_MODULE:= test-resize
 
diff --git a/services/surfaceflinger/tests/screencap/Android.mk b/services/surfaceflinger/tests/screencap/Android.mk
index 1cfb471..5cdd1a8 100644
--- a/services/surfaceflinger/tests/screencap/Android.mk
+++ b/services/surfaceflinger/tests/screencap/Android.mk
@@ -10,7 +10,7 @@
 	libbinder \
 	libskia \
     libui \
-    libsurfaceflinger_client
+    libgui
 
 LOCAL_MODULE:= test-screencap
 
diff --git a/services/surfaceflinger/tests/surface/Android.mk b/services/surfaceflinger/tests/surface/Android.mk
index ce0e807..c59060e 100644
--- a/services/surfaceflinger/tests/surface/Android.mk
+++ b/services/surfaceflinger/tests/surface/Android.mk
@@ -9,7 +9,7 @@
 	libutils \
 	libbinder \
     libui \
-    libsurfaceflinger_client
+    libgui
 
 LOCAL_MODULE:= test-surface