Integrate from //sandbox/mathias/donut/...@145728

SurfaceFlinger rework for new EGL driver model support.
diff --git a/opengl/include/EGL/android_natives.h b/opengl/include/EGL/android_natives.h
new file mode 100644
index 0000000..e3c3b86
--- /dev/null
+++ b/opengl/include/EGL/android_natives.h
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2009 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.
+ */
+
+#ifndef ANDROID_ANDROID_NATIVES_H
+#define ANDROID_ANDROID_NATIVES_H
+
+#include <sys/types.h>
+#include <string.h>
+
+#include <hardware/gralloc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*****************************************************************************/
+
+#define ANDROID_NATIVE_MAKE_CONSTANT(a,b,c,d) \
+    (((unsigned)(a)<<24)|((unsigned)(b)<<16)|((unsigned)(c)<<8)|(unsigned)(d))
+
+#define ANDROID_NATIVE_WINDOW_MAGIC \
+    ANDROID_NATIVE_MAKE_CONSTANT('_','w','n','d')
+
+#define ANDROID_NATIVE_BUFFER_MAGIC \
+    ANDROID_NATIVE_MAKE_CONSTANT('_','b','f','r')
+
+// ---------------------------------------------------------------------------
+
+struct android_native_buffer_t;
+
+enum {
+    /* attributes of this surface or its updater */
+    SURFACE_FLAG_PRESERVE_CONTENT   = FRAMEBUFFER_RESERVED0,
+    SURFACE_FLAG_MAPPED             = FRAMEBUFFER_FLAG_MAPPED,
+};
+
+
+// ---------------------------------------------------------------------------
+
+struct android_native_base_t
+{
+    /* a magic value defined by the actual EGL native type */
+    int magic;
+    
+    /* the sizeof() of the actual EGL native type */
+    int version;
+
+    void* reserved[4];
+
+    /* reference-counting interface */
+    void (*incRef)(struct android_native_base_t* base);
+    void (*decRef)(struct android_native_base_t* base);
+};
+
+
+struct android_native_window_t 
+{
+#ifdef __cplusplus
+    android_native_window_t()
+        : flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0)
+    {
+        common.magic = ANDROID_NATIVE_WINDOW_MAGIC;
+        common.version = sizeof(android_native_window_t);
+        memset(common.reserved, 0, sizeof(common.reserved));
+    }
+#endif
+    
+    struct android_native_base_t common;
+
+    /* flags describing some attributes of this surface or its updater */
+    const uint32_t flags;
+    
+    /* min swap interval supported by this updated */
+    const int   minSwapInterval;
+
+    /* max swap interval supported by this updated */
+    const int   maxSwapInterval;
+
+    /* horizontal and vertical resolution in DPI */
+    const float xdpi;
+    const float ydpi;
+
+    /* Some storage reserved for the OEM's driver. */
+    intptr_t    oem[4];
+        
+    /*
+     * hook called by EGL when the native surface is made current 
+     * (eglMakeCurrent()). This hook can be NULL.
+     */
+    void    (*connect)(struct android_native_window_t* window);
+
+    /*
+     * hook called by EGL when the native surface in not current any-longer.
+     * This hook can be NULL.
+     */
+    void    (*disconnect)(struct android_native_window_t* window);
+
+
+    /*
+     * Set the swap interval for this surface.
+     * 
+     * Returns 0 on success or -errno on error.
+     */
+    int     (*setSwapInterval)(struct android_native_window_t* window,
+                int interval);
+    
+
+    /*
+     * FIXME: needs documentation for setSwapRectangle
+     * tentative: rect used during queueBuffer to indicate which part of
+     * the screen needs updating.
+     */
+    int     (*setSwapRectangle)(struct android_native_window_t* window,
+            int left, int top, int width, int height);
+    
+    
+    /*
+     * hook called by EGL to acquire a buffer. After this call, the buffer
+     * is not locked, so its content cannot be modified.
+     * this call may block if no buffers are availlable.
+     * 
+     * Returns 0 on success or -errno on error.
+     */
+    int     (*dequeueBuffer)(struct android_native_window_t* window, 
+                struct android_native_buffer_t** buffer);
+
+    /*
+     * hook called by EGL to lock a buffer. This MUST be called before modifying
+     * the content of a buffer. The buffer must have been acquired with 
+     * dequeueBuffer first.
+     * 
+     * Returns 0 on success or -errno on error.
+     */
+    int     (*lockBuffer)(struct android_native_window_t* window,
+                struct android_native_buffer_t* buffer);
+   /*
+    * hook called by EGL when modifications to the render buffer are done. 
+    * This unlocks and post the buffer.
+    * 
+    * Buffers MUST be queued in the same order than they were dequeued.
+    * 
+    * Returns 0 on success or -errno on error.
+    */
+    int     (*queueBuffer)(struct android_native_window_t* window,
+                struct android_native_buffer_t* buffer);
+
+    
+    void* reserved_proc[5];
+};
+
+
+struct android_native_buffer_t
+{
+#ifdef __cplusplus
+    android_native_buffer_t() { 
+        common.magic = ANDROID_NATIVE_BUFFER_MAGIC;
+        common.version = sizeof(android_native_buffer_t);
+        memset(common.reserved, 0, sizeof(common.reserved));
+    }
+#endif
+
+    struct android_native_base_t common;
+
+    int width;
+    int height;
+    int stride;
+    int format;
+    int usage;
+    void* bits;     // non-zero if buffer is mmaped
+
+    void* reserved[2];
+
+    int (*getHandle)(struct android_native_buffer_t const * base,
+            buffer_handle_t* handle);
+
+    void* reserved_proc[7];
+};
+
+
+/* FIXME: this is legacy for pixmaps */
+struct egl_native_pixmap_t
+{
+    int32_t     version;    /* must be 32 */
+    int32_t     width;
+    int32_t     height;
+    int32_t     stride;
+    uint8_t*    data;
+    uint8_t     format;
+    uint8_t     rfu[3];
+    union {
+        uint32_t    compressedFormat;
+        int32_t     vstride;
+    };
+    int32_t     reserved;
+};
+
+/*****************************************************************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/*****************************************************************************/
+
+#ifdef __cplusplus
+
+#include <utils/RefBase.h>
+
+namespace android {
+
+/*
+ * This helper class turns an EGL android_native_xxx type into a C++
+ * reference-counted object; with proper type conversions.
+ */
+template <typename NATIVE_TYPE, typename TYPE, typename REF>
+class EGLNativeBase : public NATIVE_TYPE, public REF
+{
+protected:
+    typedef EGLNativeBase<NATIVE_TYPE, TYPE, REF> BASE;
+    EGLNativeBase() : NATIVE_TYPE(), REF() {
+        NATIVE_TYPE::common.incRef = incRef;
+        NATIVE_TYPE::common.decRef = decRef;
+    }
+    static inline TYPE* getSelf(NATIVE_TYPE* self) {
+        return static_cast<TYPE*>(self);
+    }
+    static inline TYPE const* getSelf(NATIVE_TYPE const* self) {
+        return static_cast<TYPE const *>(self);
+    }
+    static inline TYPE* getSelf(android_native_base_t* base) {
+        return getSelf(reinterpret_cast<NATIVE_TYPE*>(base));
+    }
+    static inline TYPE const * getSelf(android_native_base_t const* base) {
+        return getSelf(reinterpret_cast<NATIVE_TYPE const*>(base));
+    }
+    static void incRef(android_native_base_t* base) {
+        EGLNativeBase* self = getSelf(base);
+        self->incStrong(self);
+    }
+    static void decRef(android_native_base_t* base) {
+        EGLNativeBase* self = getSelf(base);
+        self->decStrong(self);
+    }
+};
+
+} // namespace android
+#endif // __cplusplus
+
+/*****************************************************************************/
+
+#endif /* ANDROID_ANDROID_NATIVES_H */
diff --git a/opengl/include/EGL/eglplatform.h b/opengl/include/EGL/eglplatform.h
index ac00901..d428087 100644
--- a/opengl/include/EGL/eglplatform.h
+++ b/opengl/include/EGL/eglplatform.h
@@ -89,12 +89,17 @@
 
 #elif defined(ANDROID)
 
-#include <EGL/eglnatives.h>
+#include <EGL/android_natives.h>
 
-typedef struct egl_native_window_t*     EGLNativeWindowType;
+typedef struct android_native_window_t* EGLNativeWindowType;
 typedef struct egl_native_pixmap_t*     EGLNativePixmapType;
 typedef void*                           EGLNativeDisplayType;
 
+#ifndef EGL_ANDROID_image_native_buffer
+#define EGL_ANDROID_image_native_buffer 1
+#define EGL_NATIVE_BUFFER_ANDROID       0x6000  /* eglCreateImageKHR target */
+#endif
+
 #else
 #error "Platform not recognized"
 #endif
diff --git a/opengl/include/GLES/glplatform.h b/opengl/include/GLES/glplatform.h
index 0924cae..198e679 100644
--- a/opengl/include/GLES/glplatform.h
+++ b/opengl/include/GLES/glplatform.h
@@ -28,12 +28,6 @@
 
 #define GL_APIENTRY KHRONOS_APIENTRY
 
-// XXX: this should probably not be here
-#define GL_DIRECT_TEXTURE_2D_QUALCOMM               0x7E80
-
-// XXX: not sure how this is intended to be used
-#define GL_GLEXT_PROTOTYPES
-
 #endif
 
 #endif /* __glplatform_h_ */
diff --git a/opengl/libagl/Android.mk b/opengl/libagl/Android.mk
index 99efe4c..af5a700 100644
--- a/opengl/libagl/Android.mk
+++ b/opengl/libagl/Android.mk
@@ -6,6 +6,9 @@
 
 include $(CLEAR_VARS)
 
+# Set to 1 to use gralloc and copybits
+LIBAGL_USE_GRALLOC_COPYBITS := 1
+
 LOCAL_SRC_FILES:= \
 	egl.cpp                     \
 	state.cpp		            \
@@ -32,7 +35,15 @@
     LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../bionic/libc/private
 endif
 
-LOCAL_SHARED_LIBRARIES := libcutils libutils libpixelflinger
+ifeq ($(LIBAGL_USE_GRALLOC_COPYBITS),1)
+    LOCAL_CFLAGS += -DLIBAGL_USE_GRALLOC_COPYBITS -I$(LOCAL_PATH)/../../../../hardware/libhardware/modules/gralloc
+    LOCAL_SRC_FILES += copybit.cpp
+endif
+
+LOCAL_CFLAGS += -DLOG_TAG=\"libagl\"
+LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+
+LOCAL_SHARED_LIBRARIES := libcutils libhardware libutils libpixelflinger
 LOCAL_LDLIBS := -lpthread -ldl
 LOCAL_MODULE:= libagl
 
diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp
index ce31854..f927de9 100644
--- a/opengl/libagl/TextureObjectManager.cpp
+++ b/opengl/libagl/TextureObjectManager.cpp
@@ -1,16 +1,16 @@
 /*
  ** Copyright 2006, 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 
+ ** 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 
+ **     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 
+ ** 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.
  */
 
@@ -53,6 +53,9 @@
     memset(crop_rect, 0, sizeof(crop_rect));
     generate_mipmap = GL_FALSE;
     direct = GL_FALSE;
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+    copybits_fd = -1;
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
 }
 
 void EGLTextureObject::copyParameters(const sp<EGLTextureObject>& old)
@@ -146,7 +149,7 @@
         int format, int compressedFormat, int bpr)
 {
     const size_t size = h * bpr;
-    if (level == 0) 
+    if (level == 0)
     {
         if (size!=mSize || !surface.data) {
             if (mSize && surface.data) {
@@ -177,9 +180,9 @@
                 return NO_MEMORY;
         }
 
-        LOGW_IF(level-1 >= mNumExtraLod, 
+        LOGW_IF(level-1 >= mNumExtraLod,
                 "specifying mipmap level %d, but # of level is %d",
-                level, mNumExtraLod+1);        
+                level, mNumExtraLod+1);
 
         GGLSurface& mipmap = editMip(level);
         if (mipmap.data)
diff --git a/opengl/libagl/TextureObjectManager.h b/opengl/libagl/TextureObjectManager.h
index 74ed1a4..497528c 100644
--- a/opengl/libagl/TextureObjectManager.h
+++ b/opengl/libagl/TextureObjectManager.h
@@ -1,16 +1,16 @@
 /*
 ** Copyright 2006, 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 
+** 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 
+**     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 
+** 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.
 */
 
@@ -81,6 +81,9 @@
     GLint               crop_rect[4];
     GLint               generate_mipmap;
     GLint               direct;
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+    int                 copybits_fd;
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
 };
 
 void EGLTextureObject::incStrong(const void* id) const {
diff --git a/opengl/libagl/array.cpp b/opengl/libagl/array.cpp
index 8fa7566..eefe614 100644
--- a/opengl/libagl/array.cpp
+++ b/opengl/libagl/array.cpp
@@ -1,16 +1,16 @@
-/* 
+/*
 ** Copyright 2006, 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 
+** 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 
+**     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 
+** 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.
 */
 
@@ -26,6 +26,9 @@
 #include "primitives.h"
 #include "texture.h"
 #include "BufferObjectManager.h"
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+#include "copybit.h"
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
 
 // ----------------------------------------------------------------------------
 
@@ -250,7 +253,7 @@
     v[2] = GGL_S_TO_X(p[2]);
 }
 
-typedef array_t::fetcher_t fn_t; 
+typedef array_t::fetcher_t fn_t;
 
 static const fn_t color_fct[2][16] = { // size={3,4}, type={ub,f,x}
     { 0, (fn_t)fetchExpand3ub, 0, 0, 0, 0,
@@ -334,7 +337,7 @@
     this->bounds = count;
 }
 
-inline void array_t::resolve() 
+inline void array_t::resolve()
 {
     physical_pointer = (bo) ? (bo->data + uintptr_t(pointer)) : pointer;
 }
@@ -465,7 +468,7 @@
         // We compute directly the index of a "free" entry from the locked
         // state of v[2] and v[3].
         v = c->vc.vBuffer + 2;
-        v += v[0].locked | (v[1].locked<<1);       
+        v += v[0].locked | (v[1].locked<<1);
     }
     // note: compileElement clears v->flags
     c->arrays.compileElement(c, v, index);
@@ -480,7 +483,7 @@
 
 #if VC_CACHE_TYPE == VC_CACHE_TYPE_INDEXED
 
-    vertex_t* const v = c->vc.vCache + 
+    vertex_t* const v = c->vc.vCache +
             (index & (vertex_cache_t::VERTEX_CACHE_SIZE-1));
 
     if (ggl_likely(v->index == index)) {
@@ -491,7 +494,7 @@
 
 #elif VC_CACHE_TYPE == VC_CACHE_TYPE_LRU
 
-    vertex_t* v = c->vc.vCache + 
+    vertex_t* v = c->vc.vCache +
             (index & ((vertex_cache_t::VERTEX_CACHE_SIZE-1)>>1))*2;
 
     // always record LRU in v[0]
@@ -532,12 +535,12 @@
         return;
 
     // vertex cache size must be multiple of 1
-    const GLsizei vcs = 
+    const GLsizei vcs =
             (vertex_cache_t::VERTEX_BUFFER_SIZE +
              vertex_cache_t::VERTEX_CACHE_SIZE);
     do {
         vertex_t* v = c->vc.vBuffer;
-        GLsizei num = count > vcs ? vcs : count; 
+        GLsizei num = count > vcs ? vcs : count;
         c->arrays.cull = vertex_t::CLIP_ALL;
         c->arrays.compileElements(c, v, first, num);
         first += num;
@@ -569,13 +572,13 @@
     count -= 1;
 
     // vertex cache size must be multiple of 1
-    const GLsizei vcs = 
+    const GLsizei vcs =
         (vertex_cache_t::VERTEX_BUFFER_SIZE +
          vertex_cache_t::VERTEX_CACHE_SIZE - 1);
     do {
-        v0 = c->vc.vBuffer + 0; 
+        v0 = c->vc.vBuffer + 0;
         v  = c->vc.vBuffer + 1;
-        GLsizei num = count > vcs ? vcs : count; 
+        GLsizei num = count > vcs ? vcs : count;
         c->arrays.compileElements(c, v, first, num);
         first += num;
         count -= num;
@@ -602,7 +605,7 @@
         return;
     drawPrimitivesLineStrip(c, first, count);
     if (ggl_likely(count >= 3)) {
-        vertex_t* v0 = c->vc.vBuffer; 
+        vertex_t* v0 = c->vc.vBuffer;
         vertex_t* v1 = c->vc.vBuffer + 1;
         c->arrays.compileElement(c, v1, first);
         const uint32_t cc = v0->flags & v1->flags;
@@ -617,12 +620,12 @@
         return;
 
     // vertex cache size must be multiple of 2
-    const GLsizei vcs = 
+    const GLsizei vcs =
         ((vertex_cache_t::VERTEX_BUFFER_SIZE +
         vertex_cache_t::VERTEX_CACHE_SIZE) / 2) * 2;
     do {
         vertex_t* v = c->vc.vBuffer;
-        GLsizei num = count > vcs ? vcs : count; 
+        GLsizei num = count > vcs ? vcs : count;
         c->arrays.cull = vertex_t::CLIP_ALL;
         c->arrays.compileElements(c, v, first, num);
         first += num;
@@ -662,14 +665,14 @@
     // because it allows us to preserve the same winding when the whole
     // batch is culled. We also need 2 extra vertices in the array, because
     // we always keep the two first ones.
-    const GLsizei vcs = 
+    const GLsizei vcs =
         ((vertex_cache_t::VERTEX_BUFFER_SIZE +
           vertex_cache_t::VERTEX_CACHE_SIZE - 2) / 2) * 2;
     do {
-        v0 = c->vc.vBuffer + 0; 
-        v1 = c->vc.vBuffer + 1; 
+        v0 = c->vc.vBuffer + 0;
+        v1 = c->vc.vBuffer + 1;
         v  = c->vc.vBuffer + 2;
-        GLsizei num = count > vcs ? vcs : count; 
+        GLsizei num = count > vcs ? vcs : count;
         c->arrays.compileElements(c, v, first, num);
         first += num;
         count -= num;
@@ -697,13 +700,19 @@
     } while (count > 0);
 }
 
-void drawPrimitivesTriangleStrip(ogles_context_t* c, 
+void drawPrimitivesTriangleStrip(ogles_context_t* c,
         GLint first, GLsizei count) {
     drawPrimitivesTriangleFanOrStrip(c, first, count, 1);
 }
 
 void drawPrimitivesTriangleFan(ogles_context_t* c,
         GLint first, GLsizei count) {
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+    if (drawTrangleFanWithCopybit(c, first, count)) {
+        return;
+    }
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
+
     drawPrimitivesTriangleFanOrStrip(c, first, count, 2);
 }
 
@@ -713,12 +722,12 @@
         return;
 
     // vertex cache size must be multiple of 3
-    const GLsizei vcs = 
+    const GLsizei vcs =
         ((vertex_cache_t::VERTEX_BUFFER_SIZE +
         vertex_cache_t::VERTEX_CACHE_SIZE) / 3) * 3;
     do {
         vertex_t* v = c->vc.vBuffer;
-        GLsizei num = count > vcs ? vcs : count; 
+        GLsizei num = count > vcs ? vcs : count;
         c->arrays.cull = vertex_t::CLIP_ALL;
         c->arrays.compileElements(c, v, first, num);
         first += num;
@@ -779,11 +788,11 @@
 {
     if (ggl_unlikely(count < 2))
         return;
-    
+
     vertex_t * const v = c->vc.vBuffer;
     vertex_t* v0 = v;
     vertex_t* v1;
-    
+
     const int type = (c->arrays.indicesType == GL_UNSIGNED_BYTE);
     c->arrays.compileElement(c, v0, read_index(type, indices));
     count -= 1;
@@ -806,11 +815,11 @@
         drawIndexedPrimitivesLines(c, count, indices);
         return;
     }
- 
+
     vertex_t * const v = c->vc.vBuffer;
     vertex_t* v0 = v;
     vertex_t* v1;
-    
+
     const int type = (c->arrays.indicesType == GL_UNSIGNED_BYTE);
     c->arrays.compileElement(c, v0, read_index(type, indices));
     count -= 1;
@@ -825,7 +834,7 @@
     } while (count);
     v1->locked = 0;
 
-    v1 = c->vc.vBuffer; 
+    v1 = c->vc.vBuffer;
     const uint32_t cc = v0->flags & v1->flags;
     if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
         c->prims.renderLine(c, v0, v1);
@@ -861,7 +870,7 @@
 
     if (ggl_unlikely(count < 3))
         return;
-    
+
     vertex_t * const v = c->vc.vBuffer;
     vertex_t* v0 = v;
     vertex_t* v1 = v+1;
@@ -981,17 +990,17 @@
     const GLfixed* vp = (const GLfixed*)c->arrays.vertex.element(first);
     const size_t stride = c->arrays.vertex.stride / 4;
 //    const GLfixed* const& m = c->transforms.mvp.matrix.m;
-    
+
     GLfixed m[16];
     memcpy(&m, c->transforms.mvp.matrix.m, sizeof(m));
-    
+
     do {
         const GLfixed rx = vp[0];
         const GLfixed ry = vp[1];
         const GLfixed rz = vp[2];
         vp += stride;
         v->index = first++;
-        v->clip.x = mla3a(rx, m[ 0], ry, m[ 4], rz, m[ 8], m[12]); 
+        v->clip.x = mla3a(rx, m[ 0], ry, m[ 4], rz, m[ 8], m[12]);
         v->clip.y = mla3a(rx, m[ 1], ry, m[ 5], rz, m[ 9], m[13]);
         v->clip.z = mla3a(rx, m[ 2], ry, m[ 6], rz, m[10], m[14]);
         v->clip.w = mla3a(rx, m[ 3], ry, m[ 7], rz, m[11], m[15]);
@@ -1019,7 +1028,7 @@
 #pragma mark clippers
 #endif
 
-static void clipVec4(vec4_t& nv, 
+static void clipVec4(vec4_t& nv,
         GLfixed t, const vec4_t& s, const vec4_t& p)
 {
     for (int i=0; i<4 ; i++)
@@ -1082,10 +1091,10 @@
     // automatically turn it off (in fact we could when the 4th coordinate
     // is not spcified in the vertex array).
     // W interpolation is never needed for points.
-    GLboolean perspective = 
+    GLboolean perspective =
         c->perspective && mode!=GL_POINTS && (enables & GGL_ENABLE_TMUS);
     c->rasterizer.procs.enableDisable(c, GGL_W_LERP, perspective);
-    
+
     // set anti-aliasing
     GLboolean smooth = GL_FALSE;
     switch (mode) {
@@ -1116,7 +1125,7 @@
     if (enables & GGL_ENABLE_TMUS) { // needs texture transforms
         want |= transform_state_t::TEXTURE;
     }
-    if (c->clipPlanes.enable || (enables & GGL_ENABLE_FOG)) { 
+    if (c->clipPlanes.enable || (enables & GGL_ENABLE_FOG)) {
         want |= transform_state_t::MODELVIEW; // needs eye coords
     }
     ogles_validate_transform(c, want);
@@ -1135,18 +1144,18 @@
 
     c->arrays.mv_transform =
         c->transforms.modelview.transform.pointv[c->arrays.vertex.size - 2];
-    
+
     /*
      * ***********************************************************************
      *  pick fetchers
      * ***********************************************************************
      */
-    
+
     array_machine_t& am = c->arrays;
     am.vertex.fetch = fetchNop;
     am.normal.fetch = currentNormal;
     am.color.fetch = currentColor;
-    
+
     if (am.vertex.enable) {
         am.vertex.resolve();
         if (am.vertex.bo || am.vertex.pointer) {
@@ -1409,7 +1418,7 @@
     // clear the vertex-cache
     c->vc.clear();
     validate_arrays(c, mode);
-    
+
     // if indices are in a buffer object, the pointer is treated as an
     // offset in that buffer.
     if (c->arrays.element_array_buffer) {
@@ -1444,7 +1453,7 @@
             return;
         }
     }
-    ((target == GL_ARRAY_BUFFER) ? 
+    ((target == GL_ARRAY_BUFFER) ?
             c->arrays.array_buffer : c->arrays.element_array_buffer) = bo;
 }
 
@@ -1463,7 +1472,7 @@
         ogles_error(c, GL_INVALID_ENUM);
         return;
     }
-    buffer_t const* bo = ((target == GL_ARRAY_BUFFER) ? 
+    buffer_t const* bo = ((target == GL_ARRAY_BUFFER) ?
             c->arrays.array_buffer : c->arrays.element_array_buffer);
 
     if (bo == 0) {
@@ -1493,7 +1502,7 @@
         ogles_error(c, GL_INVALID_VALUE);
         return;
     }
-    buffer_t const* bo = ((target == GL_ARRAY_BUFFER) ? 
+    buffer_t const* bo = ((target == GL_ARRAY_BUFFER) ?
             c->arrays.array_buffer : c->arrays.element_array_buffer);
 
     if (bo == 0) {
@@ -1541,7 +1550,7 @@
                 }
             }
         }
-    }    
+    }
     c->bufferObjectManager->deleteBuffers(n, buffers);
     c->bufferObjectManager->recycleTokens(n, buffers);
 }
diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp
new file mode 100644
index 0000000..427e42a
--- /dev/null
+++ b/opengl/libagl/copybit.cpp
@@ -0,0 +1,370 @@
+/*
+**
+** Copyright 2009, 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 <stdlib.h>
+#include <stdio.h>
+
+#include "context.h"
+#include "fp.h"
+#include "state.h"
+#include "matrix.h"
+#include "vertex.h"
+#include "light.h"
+#include "primitives.h"
+#include "texture.h"
+#include "BufferObjectManager.h"
+
+#include "TextureObjectManager.h"
+#include <hardware/gralloc.h>
+#include <hardware/copybit.h>
+#include "gralloc_priv.h"
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+static void textureToCopyBitImage(const GGLSurface* surface, int fd, copybit_image_t* img) {
+    img->w      = surface->stride;
+    img->h      = surface->height;
+    img->format = surface->format;
+    img->offset = 0;
+    img->base   = surface->data;
+    img->fd     = fd;
+}
+
+struct clipRectRegion : public copybit_region_t {
+    clipRectRegion(ogles_context_t* c) {
+        next = iterate;
+        int x = c->viewport.scissor.x;
+        int y = c->viewport.scissor.y;
+        r.l = x;
+        r.t = y;
+        r.r = x + c->viewport.scissor.w;
+        r.b = y + c->viewport.scissor.h;
+        firstTime = true;
+    }
+private:
+    static int iterate(copybit_region_t const * self, copybit_rect_t* rect) {
+        clipRectRegion* myself = (clipRectRegion*) self;
+        if (myself->firstTime) {
+            myself->firstTime = false;
+            *rect = myself->r;
+            return 1;
+        }
+        return 0;
+    }
+    mutable copybit_rect_t r;
+    mutable bool firstTime;
+};
+
+static bool supportedCopybitsFormat(int format) {
+    switch (format) {
+    case COPYBIT_FORMAT_RGBA_8888:
+    case COPYBIT_FORMAT_RGB_565:
+    case COPYBIT_FORMAT_BGRA_8888:
+    case COPYBIT_FORMAT_RGBA_5551:
+    case COPYBIT_FORMAT_RGBA_4444:
+    case COPYBIT_FORMAT_YCbCr_422_SP:
+    case COPYBIT_FORMAT_YCbCr_420_SP:
+        return true;
+    default:
+        return false;
+    }
+}
+
+static bool hasAlpha(int format) {
+    switch (format) {
+    case COPYBIT_FORMAT_RGBA_8888:
+    case COPYBIT_FORMAT_BGRA_8888:
+    case COPYBIT_FORMAT_RGBA_5551:
+    case COPYBIT_FORMAT_RGBA_4444:
+        return true;
+    default:
+        return false;
+    }
+}
+
+static inline int fixedToByte(GGLfixed val) {
+    return (val - (val >> 8)) >> 8;
+}
+
+/**
+ * Performs a quick check of the rendering state. If this function returns
+ * false we cannot use the copybit driver.
+ */
+
+static bool checkContext(ogles_context_t* c) {
+
+	// By convenction copybitQuickCheckContext() has already returned true.
+	// avoid checking the same information again.
+	
+    if (c->copybits.blitEngine == NULL
+            || (c->rasterizer.state.enables
+                    & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)) != 0) {
+        return false;
+    }
+
+    // Note: The drawSurfaceFd is only set for destination
+    // surfaces types that are supported by the hardware and
+    // do not have an alpha channel. So we don't have to re-check that here.
+
+    static const int tmu = 0;
+    texture_unit_t& u(c->textures.tmu[tmu]);
+    EGLTextureObject* textureObject = u.texture;
+
+    if (!supportedCopybitsFormat(textureObject->surface.format)) {
+        return false;
+    }
+    return true;
+}
+
+
+static bool copybit(GLint x, GLint y,
+        GLint w, GLint h,
+        EGLTextureObject* textureObject,
+        const GLint* crop_rect,
+        int transform,
+        ogles_context_t* c)
+{
+    // We assume checkContext has already been called and has already
+    // returned true.
+
+    const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
+
+    y = cbSurface.height - (y + h);
+
+    const GLint Ucr = crop_rect[0];
+    const GLint Vcr = crop_rect[1];
+    const GLint Wcr = crop_rect[2];
+    const GLint Hcr = crop_rect[3];
+
+    int32_t dsdx = (Wcr << 16) / w;   // dsdx =  ((Wcr/w)/Wt)*Wt
+    int32_t dtdy = ((-Hcr) <<  16) / h;   // dtdy = -((Hcr/h)/Ht)*Ht
+
+    if (dsdx < c->copybits.minScale || dsdx > c->copybits.maxScale
+            || dtdy < c->copybits.minScale || dtdy > c->copybits.maxScale) {
+        // The requested scale is out of the range the hardware
+        // can support.
+        return false;
+    }
+
+    int32_t texelArea = gglMulx(dtdy, dsdx);
+    if (texelArea < FIXED_ONE && textureObject->mag_filter != GL_LINEAR) {
+        // Non-linear filtering on a texture enlargement.
+        return false;
+    }
+
+    if (texelArea > FIXED_ONE && textureObject->min_filter != GL_LINEAR) {
+        // Non-linear filtering on an texture shrink.
+        return false;
+    }
+
+    const uint32_t enables = c->rasterizer.state.enables;
+    int planeAlpha = 255;
+    static const int tmu = 0;
+    texture_t& tev(c->rasterizer.state.texture[tmu]);
+    bool srcTextureHasAlpha = hasAlpha(textureObject->surface.format);
+    switch (tev.env) {
+
+    case GGL_REPLACE:
+        if (!srcTextureHasAlpha) {
+            planeAlpha = fixedToByte(c->currentColorClamped.a);
+        }
+        break;
+
+    case GGL_MODULATE:
+        if (! (c->currentColorClamped.r == FIXED_ONE
+                && c->currentColorClamped.g == FIXED_ONE
+                && c->currentColorClamped.b == FIXED_ONE)) {
+            return false;
+        }
+        planeAlpha = fixedToByte(c->currentColorClamped.a);
+        break;
+
+    default:
+        // Incompatible texture environment.
+        return false;
+    }
+
+    bool blending = false;
+
+    if ((enables & GGL_ENABLE_BLENDING)
+            && !(c->rasterizer.state.blend.src == GL_ONE
+                    && c->rasterizer.state.blend.dst == GL_ZERO)) {
+        // Blending is OK if it is
+        // the exact kind of blending that the copybits hardware supports.
+        // Note: The hardware only supports
+        // GL_SRC_ALPHA / GL_ONE_MINUS_SRC_ALPHA,
+        // But the surface flinger uses GL_ONE / GL_ONE_MINUS_SRC_ALPHA.
+        // We substitute GL_SRC_ALPHA / GL_ONE_MINUS_SRC_ALPHA in that case,
+        // because the performance is worth it, even if the results are
+        // not correct.
+        if (!((c->rasterizer.state.blend.src == GL_SRC_ALPHA
+                || c->rasterizer.state.blend.src == GL_ONE)
+                && c->rasterizer.state.blend.dst == GL_ONE_MINUS_SRC_ALPHA
+                && c->rasterizer.state.blend.alpha_separate == 0)) {
+            // Incompatible blend mode.
+            return false;
+        }
+        blending = true;
+    } else {
+        // No blending is OK if we are not using alpha.
+        if (srcTextureHasAlpha || planeAlpha != 255) {
+            // Incompatible alpha
+            return false;
+        }
+    }
+
+    if (srcTextureHasAlpha && planeAlpha != 255) {
+        // Can't do two types of alpha at once.
+        return false;
+    }
+
+    // LOGW("calling copybits");
+
+    copybit_device_t* copybit = c->copybits.blitEngine;
+    copybit_image_t dst;
+    textureToCopyBitImage(&cbSurface, c->copybits.drawSurfaceFd, &dst);
+    copybit_rect_t drect = {x, y, x+w, y+h};
+
+    copybit_image_t src;
+    textureToCopyBitImage(&textureObject->surface, textureObject->copybits_fd,
+            &src);
+    copybit_rect_t srect = { Ucr, Vcr + Hcr, Ucr + Wcr, Vcr };
+
+    copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform);
+    copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, planeAlpha);
+
+    copybit->set_parameter(copybit, COPYBIT_DITHER,
+            (enables & GGL_ENABLE_DITHER) ? COPYBIT_ENABLE : COPYBIT_DISABLE);
+
+    clipRectRegion it(c);
+    copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
+    return true;
+}
+
+/*
+ * Try to draw a triangle fan with copybit, return false if we fail.
+ */
+bool drawTrangleFanWithCopybit_impl(ogles_context_t* c, GLint first, GLsizei count) {
+    if (! checkContext(c)) {
+        return false;
+    }
+
+    c->arrays.compileElements(c, c->vc.vBuffer, 0, 4);
+    // Is the result a screen aligned rectangle?
+    int sx[4];
+    int sy[4];
+    for (int i = 0; i < 4; i++) {
+        GLfixed x = c->vc.vBuffer[i].window.x;
+        GLfixed y = c->vc.vBuffer[i].window.y;
+        if (x < 0 || y < 0 || (x & 0xf) != 0 || (y & 0xf) != 0) {
+            return false;
+        }
+        sx[i] = x >> 4;
+        sy[i] = y >> 4;
+    }
+
+    /*
+     * This is the pattern we're looking for:
+     *    (2)--(3)
+     *     |\   |
+     *     | \  |
+     *     |  \ |
+     *     |   \|
+     *    (1)--(0)
+     *
+     */
+    int dx[4];
+    int dy[4];
+    for (int i = 0; i < 4; i++) {
+        int i1 = (i + 1) & 3;
+        dx[i] = sx[i] - sx[i1];
+        dy[i] = sy[i] - sy[i1];
+    }
+    if (dx[1] | dx[3] | dy[0] | dy[2]) {
+        return false;
+    }
+    if (dx[0] != -dx[2] || dy[1] != -dy[3]) {
+        return false;
+    }
+
+    int x = sx[1];
+    int y = sy[1];
+    int w = dx[0];
+    int h = dy[3];
+
+    // We expect the texture coordinates to always be the unit square:
+
+    static const GLfixed kExpectedUV[8] = {
+        0, 0,
+        0, FIXED_ONE,
+        FIXED_ONE, FIXED_ONE,
+        FIXED_ONE, 0
+    };
+    {
+        const GLfixed* pExpected = &kExpectedUV[0];
+        for (int i = 0; i < 4; i++) {
+            GLfixed u = c->vc.vBuffer[i].texture[0].x;
+            GLfixed v = c->vc.vBuffer[i].texture[0].y;
+            if (u != *pExpected++ || v != *pExpected++) {
+                return false;
+            }
+        }
+    }
+
+    static const int tmu = 0;
+    texture_unit_t& u(c->textures.tmu[tmu]);
+    EGLTextureObject* textureObject = u.texture;
+
+    GLint tWidth = textureObject->surface.width;
+    GLint tHeight = textureObject->surface.height;
+    GLint crop_rect[4] = {0, tHeight, tWidth, -tHeight};
+
+    const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
+    y = cbSurface.height - (y + h);
+
+    return copybit(x, y, w, h, textureObject, crop_rect,
+            COPYBIT_TRANSFORM_ROT_90, c);
+}
+
+/*
+ * Try to drawTexiOESWithCopybit, return false if we fail.
+ */
+
+bool drawTexiOESWithCopybit_impl(GLint x, GLint y, GLint z,
+        GLint w, GLint h, ogles_context_t* c)
+{
+    // quickly process empty rects
+    if ((w|h) <= 0) {
+        return true;
+    }
+
+    if (! checkContext(c)) {
+        return false;
+    }
+
+    static const int tmu = 0;
+    texture_unit_t& u(c->textures.tmu[tmu]);
+    EGLTextureObject* textureObject = u.texture;
+
+    return copybit(x, y, w, h, textureObject, textureObject->crop_rect,
+            0, c);
+}
+
+} // namespace android
+
diff --git a/opengl/libagl/copybit.h b/opengl/libagl/copybit.h
new file mode 100644
index 0000000..1888aee
--- /dev/null
+++ b/opengl/libagl/copybit.h
@@ -0,0 +1,75 @@
+/*
+**
+** Copyright 2009, 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.
+*/
+
+#ifndef ANDROID_OPENGLES_COPYBIT_H
+#define ANDROID_OPENGLES_COPYBIT_H
+
+#include <stdlib.h>
+
+#include <GLES/gl.h>
+
+#include "TextureObjectManager.h"
+namespace android {
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+
+bool drawTexiOESWithCopybit_impl(GLint x, GLint y, GLint z,
+        GLint w, GLint h, ogles_context_t* c);
+bool drawTrangleFanWithCopybit_impl(ogles_context_t* c, GLint first,
+        GLsizei count);
+
+inline bool copybitQuickCheckContext(ogles_context_t* c) {
+        return  c->copybits.drawSurfaceFd >= 0
+            && c->rasterizer.state.enabled_tmu == 1
+            && c->textures.tmu[0].texture->copybits_fd >= 0;
+}
+
+/*
+ * Tries to draw a drawTexiOES using copybit hardware.
+ * Returns true if successful.
+ */
+inline bool drawTexiOESWithCopybit(GLint x, GLint y, GLint z,
+        GLint w, GLint h, ogles_context_t* c) {
+    if (!copybitQuickCheckContext(c)) {
+    	return false;
+   	}
+   	
+   	return drawTexiOESWithCopybit_impl(x, y, z, w, h, c);
+}
+
+/*
+ * Tries to draw a triangle fan using copybit hardware.
+ * Returns true if successful.
+ */
+inline bool drawTrangleFanWithCopybit(ogles_context_t* c, GLint first,
+        GLsizei count) {
+    /*
+     * We are looking for the glDrawArrays call made by SurfaceFlinger.
+     */
+
+    if (!(copybitQuickCheckContext(c) && first == 0 && count == 4)) {
+        return false;
+    }
+    
+    return drawTrangleFanWithCopybit_impl(c, first, count);
+}
+
+
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
+
+} // namespace android
+
+#endif // ANDROID_OPENGLES_COPYBIT_H
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 3b4c041..5c91c92 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -1,22 +1,20 @@
-/* 
+/*
 **
 ** Copyright 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 
+** 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 
+**     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 
+** 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.
 */
 
-#define LOG_TAG "EGL"
-
 #include <assert.h>
 #include <errno.h>
 #include <stdlib.h>
@@ -35,6 +33,7 @@
 
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
+#include <EGL/android_natives.h>
 #include <GLES/gl.h>
 #include <GLES/glext.h>
 
@@ -46,6 +45,10 @@
 #include "texture.h"
 #include "matrix.h"
 
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+#include "gralloc_priv.h"
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
+
 #undef NELEM
 #define NELEM(x) (sizeof(x)/sizeof(*(x)))
 
@@ -89,9 +92,9 @@
 struct egl_display_t
 {
     egl_display_t() : type(0), initialized(0) { }
-    
+
     static egl_display_t& get_display(EGLDisplay dpy);
-    
+
     static EGLBoolean is_valid(EGLDisplay dpy) {
         return ((uintptr_t(dpy)-1U) >= NUM_DISPLAYS) ? EGL_FALSE : EGL_TRUE;
     }
@@ -140,7 +143,7 @@
                 egl_surface_t(EGLDisplay dpy, EGLConfig config, int32_t depthFormat);
     virtual     ~egl_surface_t();
     virtual     bool    isValid() const = 0;
-    
+
     virtual     EGLBoolean  bindDrawSurface(ogles_context_t* gl) = 0;
     virtual     EGLBoolean  bindReadSurface(ogles_context_t* gl) = 0;
     virtual     EGLint      getWidth() const = 0;
@@ -188,39 +191,48 @@
 
 // ----------------------------------------------------------------------------
 
-struct egl_window_surface_t : public egl_surface_t
+struct egl_window_surface_v2_t : public egl_surface_t
 {
-    egl_window_surface_t(
+    egl_window_surface_v2_t(
             EGLDisplay dpy, EGLConfig config,
             int32_t depthFormat,
-            egl_native_window_t* window);
+            android_native_window_t* window);
 
-     ~egl_window_surface_t();
+     ~egl_window_surface_v2_t();
 
-    virtual     bool        isValid() const { return nativeWindow->magic == 0x600913; }    
+    virtual     bool        isValid() const { return nativeWindow->common.magic == ANDROID_NATIVE_WINDOW_MAGIC; }
     virtual     EGLBoolean  swapBuffers();
     virtual     EGLBoolean  bindDrawSurface(ogles_context_t* gl);
     virtual     EGLBoolean  bindReadSurface(ogles_context_t* gl);
-    virtual     EGLint      getWidth() const    { return nativeWindow->width;  }
-    virtual     EGLint      getHeight() const   { return nativeWindow->height; }
+    virtual     EGLint      getWidth() const    { return buffer->width;  }
+    virtual     EGLint      getHeight() const   { return buffer->height; }
     virtual     void*       getBits() const;
     virtual     EGLint      getHorizontalResolution() const;
     virtual     EGLint      getVerticalResolution() const;
     virtual     EGLint      getRefreshRate() const;
     virtual     EGLint      getSwapBehavior() const;
 private:
-    egl_native_window_t*    nativeWindow;
+    android_native_window_t*   nativeWindow;
+    android_native_buffer_t*   buffer;
+    int width;
+    int height;
 };
 
-egl_window_surface_t::egl_window_surface_t(EGLDisplay dpy,
+egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy,
         EGLConfig config,
         int32_t depthFormat,
-        egl_native_window_t* window)
-    : egl_surface_t(dpy, config, depthFormat), nativeWindow(window)
+        android_native_window_t* window)
+    : egl_surface_t(dpy, config, depthFormat), nativeWindow(window), buffer(0)
 {
+    nativeWindow->common.incRef(&nativeWindow->common);
+
+    nativeWindow->dequeueBuffer(nativeWindow, &buffer);
+    
+    width = buffer->width;
+    height = buffer->height;
     if (depthFormat) {
-        depth.width   = window->width;
-        depth.height  = window->height;
+        depth.width   = width;
+        depth.height  = height;
         depth.stride  = depth.width; // use the width here
         depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
         if (depth.data == 0) {
@@ -228,23 +240,56 @@
             return;
         }
     }
-    nativeWindow->incRef(nativeWindow);
-}
-egl_window_surface_t::~egl_window_surface_t() {
-    nativeWindow->decRef(nativeWindow);
+
+    // TODO: lockBuffer should rather be executed when the very first
+    // direct rendering occurs.    
+    buffer->common.incRef(&buffer->common);
+    nativeWindow->lockBuffer(nativeWindow, buffer);
+
+    // FIXME: we need to gralloc lock the buffer
+    // FIXME: we need to handle the copy-back if needed, but
+    // for now we're a "non preserving" implementation.
 }
 
-EGLBoolean egl_window_surface_t::swapBuffers()
+egl_window_surface_v2_t::~egl_window_surface_v2_t() {
+    if (buffer) {
+        buffer->common.decRef(&buffer->common);
+    }
+    nativeWindow->common.decRef(&nativeWindow->common);
+}
+
+EGLBoolean egl_window_surface_v2_t::swapBuffers()
 {
-    uint32_t flags = nativeWindow->swapBuffers(nativeWindow);
-    if (flags & EGL_NATIVES_FLAG_SIZE_CHANGED) {
+    // TODO: this is roughly the code needed for preserving the back buffer
+    // efficiently. dirty is the area that has been modified.
+    //Region newDirty(dirty);
+    //newDirty.andSelf(Rect(nativeWindow->width, nativeWindow->height));
+    //mDirty = newDirty;
+    //const Region copyback(mDirty.subtract(newDirty));
+    //mDisplaySurface->copyFrontToBack(copyback);
+
+    
+    nativeWindow->queueBuffer(nativeWindow, buffer);
+    buffer->common.decRef(&buffer->common); buffer = 0;
+
+    nativeWindow->dequeueBuffer(nativeWindow, &buffer);
+    buffer->common.incRef(&buffer->common);
+
+    // TODO: lockBuffer should rather be executed when the very first
+    // direct rendering occurs.
+    nativeWindow->lockBuffer(nativeWindow, buffer);
+
+    
+    if ((width != buffer->width) || (height != buffer->height)) {
         // TODO: we probably should reset the swap rect here
         // if the window size has changed
+        width = buffer->width;
+        height = buffer->height;
         if (depth.data) {
             free(depth.data);
-            depth.width   = nativeWindow->width;
-            depth.height  = nativeWindow->height;
-            depth.stride  = nativeWindow->stride;
+            depth.width   = width;
+            depth.height  = height;
+            depth.stride  = buffer->stride;
             depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
             if (depth.data == 0) {
                 setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
@@ -255,49 +300,81 @@
     return EGL_TRUE;
 }
 
-EGLBoolean egl_window_surface_t::bindDrawSurface(ogles_context_t* gl)
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+
+static bool supportedCopybitsDestinationFormat(int format) {
+    // Hardware supported and no destination alpha
+    switch (format) {
+    case HAL_PIXEL_FORMAT_RGB_565:
+    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+        return true;
+    default:
+        return false;
+    }
+}
+#endif
+
+EGLBoolean egl_window_surface_v2_t::bindDrawSurface(ogles_context_t* gl)
 {
     GGLSurface buffer;
     buffer.version = sizeof(GGLSurface);
-    buffer.width   = nativeWindow->width;
-    buffer.height  = nativeWindow->height;
-    buffer.stride  = nativeWindow->stride;
-    buffer.data    = (GGLubyte*)nativeWindow->base + nativeWindow->offset;
-    buffer.format  = nativeWindow->format;
+    buffer.width   = this->buffer->width;
+    buffer.height  = this->buffer->height;
+    buffer.stride  = this->buffer->stride;
+    buffer.data    = (GGLubyte*)this->buffer->bits;
+    buffer.format  = this->buffer->format;
     gl->rasterizer.procs.colorBuffer(gl, &buffer);
     if (depth.data != gl->rasterizer.state.buffers.depth.data)
         gl->rasterizer.procs.depthBuffer(gl, &depth);
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+    gl->copybits.drawSurfaceFd = -1;
+    if (supportedCopybitsDestinationFormat(buffer.format)) {
+        buffer_handle_t handle;
+        this->buffer->getHandle(this->buffer, &handle);
+        if (handle != NULL) {
+            private_handle_t* hand = private_handle_t::dynamicCast(handle);
+            if (hand != NULL) {
+                if (hand->usesPhysicallyContiguousMemory()) {
+                    gl->copybits.drawSurfaceFd = hand->fd;
+                }
+            }
+        }
+    }
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
     return EGL_TRUE;
 }
-EGLBoolean egl_window_surface_t::bindReadSurface(ogles_context_t* gl)
+EGLBoolean egl_window_surface_v2_t::bindReadSurface(ogles_context_t* gl)
 {
     GGLSurface buffer;
     buffer.version = sizeof(GGLSurface);
-    buffer.width   = nativeWindow->width;
-    buffer.height  = nativeWindow->height;
-    buffer.stride  = nativeWindow->stride;
-    buffer.data    = (GGLubyte*)nativeWindow->base + nativeWindow->offset;
-    buffer.format  = nativeWindow->format;
+    buffer.width   = this->buffer->width;
+    buffer.height  = this->buffer->height;
+    buffer.stride  = this->buffer->stride;
+    buffer.data    = (GGLubyte*)this->buffer->bits;
+    buffer.format  = this->buffer->format;
     gl->rasterizer.procs.readBuffer(gl, &buffer);
     return EGL_TRUE;
 }
-void* egl_window_surface_t::getBits() const {
-    return (GGLubyte*)nativeWindow->base + nativeWindow->offset;
+void* egl_window_surface_v2_t::getBits() const {
+    return (GGLubyte*)buffer->bits;
 }
-EGLint egl_window_surface_t::getHorizontalResolution() const {
+EGLint egl_window_surface_v2_t::getHorizontalResolution() const {
     return (nativeWindow->xdpi * EGL_DISPLAY_SCALING) * (1.0f / 25.4f);
 }
-EGLint egl_window_surface_t::getVerticalResolution() const {
+EGLint egl_window_surface_v2_t::getVerticalResolution() const {
     return (nativeWindow->ydpi * EGL_DISPLAY_SCALING) * (1.0f / 25.4f);
 }
-EGLint egl_window_surface_t::getRefreshRate() const {
-    return (nativeWindow->fps * EGL_DISPLAY_SCALING);
+EGLint egl_window_surface_v2_t::getRefreshRate() const {
+    return (60 * EGL_DISPLAY_SCALING); // FIXME
 }
-EGLint egl_window_surface_t::getSwapBehavior() const {
-    uint32_t flags = nativeWindow->flags;
-    if (flags & EGL_NATIVES_FLAG_DESTROY_BACKBUFFER)
-        return EGL_BUFFER_DESTROYED;
-    return EGL_BUFFER_PRESERVED;
+EGLint egl_window_surface_v2_t::getSwapBehavior() const {
+    //uint32_t flags = nativeWindow->flags;
+    //if (flags & SURFACE_FLAG_PRESERVE_CONTENT)
+    //    return EGL_BUFFER_PRESERVED;
+    // This is now a feature of EGL, currently we don't preserve
+    // the content of the buffers.
+    return EGL_BUFFER_DESTROYED;
 }
 
 // ----------------------------------------------------------------------------
@@ -311,7 +388,7 @@
 
     virtual ~egl_pixmap_surface_t() { }
 
-    virtual     bool        isValid() const { return nativePixmap.version == sizeof(egl_native_pixmap_t); }    
+    virtual     bool        isValid() const { return nativePixmap.version == sizeof(egl_native_pixmap_t); }
     virtual     EGLBoolean  bindDrawSurface(ogles_context_t* gl);
     virtual     EGLBoolean  bindReadSurface(ogles_context_t* gl);
     virtual     EGLint      getWidth() const    { return nativePixmap.width;  }
@@ -347,7 +424,7 @@
     buffer.stride  = nativePixmap.stride;
     buffer.data    = nativePixmap.data;
     buffer.format  = nativePixmap.format;
-    
+
     gl->rasterizer.procs.colorBuffer(gl, &buffer);
     if (depth.data != gl->rasterizer.state.buffers.depth.data)
         gl->rasterizer.procs.depthBuffer(gl, &depth);
@@ -376,7 +453,7 @@
 
     virtual ~egl_pbuffer_surface_t();
 
-    virtual     bool        isValid() const { return pbuffer.data != 0; }    
+    virtual     bool        isValid() const { return pbuffer.data != 0; }
     virtual     EGLBoolean  bindDrawSurface(ogles_context_t* gl);
     virtual     EGLBoolean  bindReadSurface(ogles_context_t* gl);
     virtual     EGLint      getWidth() const    { return pbuffer.width;  }
@@ -407,7 +484,7 @@
     pbuffer.stride  = w;
     pbuffer.data    = (GGLubyte*)malloc(size);
     pbuffer.format  = f;
-    
+
     if (depthFormat) {
         depth.width   = pbuffer.width;
         depth.height  = pbuffer.height;
@@ -468,7 +545,11 @@
 static char const * const gVendorString     = "Google Inc.";
 static char const * const gVersionString    = "1.2 Android Driver";
 static char const * const gClientApiString  = "OpenGL ES";
-static char const * const gExtensionsString = "";
+static char const * const gExtensionsString =
+        "KHR_image_base "
+        // "KHR_image_pixmap "
+        "EGL_ANDROID_image_native_buffer "
+        ;
 
 // ----------------------------------------------------------------------------
 
@@ -478,25 +559,45 @@
 };
 
 static const extention_map_t gExtentionMap[] = {
-    { "glDrawTexsOES",              (void(*)())&glDrawTexsOES },
-    { "glDrawTexiOES",              (void(*)())&glDrawTexiOES },
-    { "glDrawTexfOES",              (void(*)())&glDrawTexfOES },
-    { "glDrawTexxOES",              (void(*)())&glDrawTexxOES },
-    { "glDrawTexsvOES",             (void(*)())&glDrawTexsvOES },
-    { "glDrawTexivOES",             (void(*)())&glDrawTexivOES },
-    { "glDrawTexfvOES",             (void(*)())&glDrawTexfvOES },
-    { "glDrawTexxvOES",             (void(*)())&glDrawTexxvOES },
-    { "glQueryMatrixxOES",          (void(*)())&glQueryMatrixxOES },
-    { "glClipPlanef",               (void(*)())&glClipPlanef },
-    { "glClipPlanex",               (void(*)())&glClipPlanex },
-    { "glBindBuffer",               (void(*)())&glBindBuffer },
-    { "glBufferData",               (void(*)())&glBufferData },
-    { "glBufferSubData",            (void(*)())&glBufferSubData },
-    { "glDeleteBuffers",            (void(*)())&glDeleteBuffers },
-    { "glGenBuffers",               (void(*)())&glGenBuffers },
+    { "glDrawTexsOES",
+            (__eglMustCastToProperFunctionPointerType)&glDrawTexsOES },
+    { "glDrawTexiOES",
+            (__eglMustCastToProperFunctionPointerType)&glDrawTexiOES },
+    { "glDrawTexfOES",
+            (__eglMustCastToProperFunctionPointerType)&glDrawTexfOES },
+    { "glDrawTexxOES",
+            (__eglMustCastToProperFunctionPointerType)&glDrawTexxOES },
+    { "glDrawTexsvOES",
+            (__eglMustCastToProperFunctionPointerType)&glDrawTexsvOES },
+    { "glDrawTexivOES",
+            (__eglMustCastToProperFunctionPointerType)&glDrawTexivOES },
+    { "glDrawTexfvOES",
+            (__eglMustCastToProperFunctionPointerType)&glDrawTexfvOES },
+    { "glDrawTexxvOES",
+            (__eglMustCastToProperFunctionPointerType)&glDrawTexxvOES },
+    { "glQueryMatrixxOES",
+            (__eglMustCastToProperFunctionPointerType)&glQueryMatrixxOES },
+    { "glEGLImageTargetTexture2DOES",
+            (__eglMustCastToProperFunctionPointerType)&glEGLImageTargetTexture2DOES },
+    { "glEGLImageTargetRenderbufferStorageOES",
+            (__eglMustCastToProperFunctionPointerType)&glEGLImageTargetRenderbufferStorageOES },
+    { "glClipPlanef",
+            (__eglMustCastToProperFunctionPointerType)&glClipPlanef },
+    { "glClipPlanex",
+            (__eglMustCastToProperFunctionPointerType)&glClipPlanex },
+    { "glBindBuffer",
+            (__eglMustCastToProperFunctionPointerType)&glBindBuffer },
+    { "glBufferData",
+            (__eglMustCastToProperFunctionPointerType)&glBufferData },
+    { "glBufferSubData",
+            (__eglMustCastToProperFunctionPointerType)&glBufferSubData },
+    { "glDeleteBuffers",
+            (__eglMustCastToProperFunctionPointerType)&glDeleteBuffers },
+    { "glGenBuffers",
+            (__eglMustCastToProperFunctionPointerType)&glGenBuffers },
 };
 
-/* 
+/*
  * In the lists below, attributes names MUST be sorted.
  * Additionally, all configs must be sorted according to
  * the EGL specification.
@@ -507,7 +608,7 @@
         { EGL_CONFIG_CAVEAT,              EGL_SLOW_CONFIG                   },
         { EGL_LEVEL,                      0                                 },
         { EGL_MAX_PBUFFER_HEIGHT,         GGL_MAX_VIEWPORT_DIMS             },
-        { EGL_MAX_PBUFFER_PIXELS,         
+        { EGL_MAX_PBUFFER_PIXELS,
                 GGL_MAX_VIEWPORT_DIMS*GGL_MAX_VIEWPORT_DIMS                 },
         { EGL_MAX_PBUFFER_WIDTH,          GGL_MAX_VIEWPORT_DIMS             },
         { EGL_NATIVE_RENDERABLE,          EGL_TRUE                          },
@@ -644,9 +745,9 @@
 {
    while (first <= last) {
        int mid = (first + last) / 2;
-       if (key > sortedArray[mid].key) { 
+       if (key > sortedArray[mid].key) {
            first = mid + 1;
-       } else if (key < sortedArray[mid].key) { 
+       } else if (key < sortedArray[mid].key) {
            last = mid - 1;
        } else {
            return mid;
@@ -658,13 +759,13 @@
 static int isAttributeMatching(int i, EGLint attr, EGLint val)
 {
     // look for the attribute in all of our configs
-    config_pair_t const* configFound = gConfigs[i].array; 
+    config_pair_t const* configFound = gConfigs[i].array;
     int index = binarySearch<config_pair_t>(
             gConfigs[i].array,
             0, gConfigs[i].size-1,
             attr);
     if (index < 0) {
-        configFound = config_base_attribute_list; 
+        configFound = config_base_attribute_list;
         index = binarySearch<config_pair_t>(
                 config_base_attribute_list,
                 0, NELEM(config_base_attribute_list)-1,
@@ -778,28 +879,28 @@
     int32_t depthFormat;
     int32_t pixelFormat;
     switch(configID) {
-    case 0: 
-        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+    case 0:
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565;
         depthFormat = 0;
         break;
     case 1:
-        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565;
         depthFormat = GGL_PIXEL_FORMAT_Z_16;
         break;
     case 2:
-        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888;
         depthFormat = 0;
         break;
     case 3:
-        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888;
         depthFormat = GGL_PIXEL_FORMAT_Z_16;
         break;
     case 4:
-        pixelFormat = GGL_PIXEL_FORMAT_A_8; 
+        pixelFormat = GGL_PIXEL_FORMAT_A_8;
         depthFormat = 0;
         break;
     case 5:
-        pixelFormat = GGL_PIXEL_FORMAT_A_8; 
+        pixelFormat = GGL_PIXEL_FORMAT_A_8;
         depthFormat = GGL_PIXEL_FORMAT_Z_16;
         break;
     default:
@@ -812,9 +913,9 @@
     //if (EGLint(info.format) != pixelFormat)
     //    return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
 
-    egl_surface_t* surface =
-        new egl_window_surface_t(dpy, config, depthFormat,
-                static_cast<egl_native_window_t*>(window));
+    egl_surface_t* surface;
+    surface = new egl_window_surface_v2_t(dpy, config, depthFormat,
+            static_cast<android_native_window_t*>(window));
 
     if (!surface->isValid()) {
         // there was a problem in the ctor, the error
@@ -847,28 +948,28 @@
     int32_t depthFormat;
     int32_t pixelFormat;
     switch(configID) {
-    case 0: 
-        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+    case 0:
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565;
         depthFormat = 0;
         break;
     case 1:
-        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565;
         depthFormat = GGL_PIXEL_FORMAT_Z_16;
         break;
     case 2:
-        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888;
         depthFormat = 0;
         break;
     case 3:
-        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888;
         depthFormat = GGL_PIXEL_FORMAT_Z_16;
         break;
     case 4:
-        pixelFormat = GGL_PIXEL_FORMAT_A_8; 
+        pixelFormat = GGL_PIXEL_FORMAT_A_8;
         depthFormat = 0;
         break;
     case 5:
-        pixelFormat = GGL_PIXEL_FORMAT_A_8; 
+        pixelFormat = GGL_PIXEL_FORMAT_A_8;
         depthFormat = GGL_PIXEL_FORMAT_Z_16;
         break;
     default:
@@ -900,10 +1001,10 @@
     EGLint surfaceType;
     if (getConfigAttrib(dpy, config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE)
         return EGL_FALSE;
-    
+
     if (!(surfaceType & EGL_PBUFFER_BIT))
         return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
-        
+
     EGLint configID;
     if (getConfigAttrib(dpy, config, EGL_CONFIG_ID, &configID) == EGL_FALSE)
         return EGL_FALSE;
@@ -911,28 +1012,28 @@
     int32_t depthFormat;
     int32_t pixelFormat;
     switch(configID) {
-    case 0: 
-        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+    case 0:
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565;
         depthFormat = 0;
         break;
     case 1:
-        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565;
         depthFormat = GGL_PIXEL_FORMAT_Z_16;
         break;
     case 2:
-        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888;
         depthFormat = 0;
         break;
     case 3:
-        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888;
         depthFormat = GGL_PIXEL_FORMAT_Z_16;
         break;
     case 4:
-        pixelFormat = GGL_PIXEL_FORMAT_A_8; 
+        pixelFormat = GGL_PIXEL_FORMAT_A_8;
         depthFormat = 0;
         break;
     case 5:
-        pixelFormat = GGL_PIXEL_FORMAT_A_8; 
+        pixelFormat = GGL_PIXEL_FORMAT_A_8;
         depthFormat = GGL_PIXEL_FORMAT_Z_16;
         break;
     default:
@@ -985,7 +1086,7 @@
         egl_display_t& d = egl_display_t::get_display(dpy);
         d.type = display;
         return dpy;
-    }    
+    }
     return EGL_NO_DISPLAY;
 }
 
@@ -993,10 +1094,10 @@
 {
     if (egl_display_t::is_valid(dpy) == EGL_FALSE)
         return setError(EGL_BAD_DISPLAY, EGL_FALSE);
-    
+
     EGLBoolean res = EGL_TRUE;
     egl_display_t& d = egl_display_t::get_display(dpy);
-    
+
     if (android_atomic_inc(&d.initialized) == 0) {
         // initialize stuff here if needed
         //pthread_mutex_lock(&gInitMutex);
@@ -1064,7 +1165,7 @@
         *num_config = 0;
         return EGL_TRUE;
     }
-    
+
     int numAttributes = 0;
     int numConfigs =  NELEM(gConfigs);
     uint32_t possibleMatch = (1<<numConfigs)-1;
@@ -1145,7 +1246,7 @@
 {
     return createWindowSurface(dpy, config, window, attrib_list);
 }
-    
+
 EGLSurface eglCreatePixmapSurface(  EGLDisplay dpy, EGLConfig config,
                                     NativePixmapType pixmap,
                                     const EGLint *attrib_list)
@@ -1158,7 +1259,7 @@
 {
     return createPbufferSurface(dpy, config, attrib_list);
 }
-                                    
+
 EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface eglSurface)
 {
     if (egl_display_t::is_valid(dpy) == EGL_FALSE)
@@ -1228,7 +1329,7 @@
             *value = (wr * EGL_DISPLAY_SCALING) / hr;
         } break;
         case EGL_SWAP_BEHAVIOR:
-            *value = surface->getSwapBehavior(); 
+            *value = surface->getSwapBehavior();
             break;
         default:
             ret = setError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
@@ -1278,7 +1379,7 @@
     }
 
     EGLContext current_ctx = EGL_NO_CONTEXT;
-    
+
     if ((read == EGL_NO_SURFACE && draw == EGL_NO_SURFACE) && (ctx != EGL_NO_CONTEXT))
         return setError(EGL_BAD_MATCH, EGL_FALSE);
 
@@ -1299,6 +1400,8 @@
         }
     }
 
+    // TODO: call connect / disconnect on the surface
+
     ogles_context_t* gl = (ogles_context_t*)ctx;
     if (makeCurrent(gl) == 0) {
         if (ctx) {
@@ -1407,7 +1510,7 @@
 {
     if (egl_display_t::is_valid(dpy) == EGL_FALSE)
         return setError(EGL_BAD_DISPLAY, EGL_FALSE);
-    
+
     egl_surface_t* d = static_cast<egl_surface_t*>(draw);
     if (d->dpy != dpy)
         return setError(EGL_BAD_DISPLAY, EGL_FALSE);
@@ -1540,7 +1643,7 @@
 }
 
 // ----------------------------------------------------------------------------
-// Android extensions
+// EGL_EGLEXT_VERSION 3
 // ----------------------------------------------------------------------------
 
 void (*eglGetProcAddress (const char *procname))()
@@ -1553,3 +1656,81 @@
     }
     return NULL;
 }
+
+EGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface,
+        const EGLint *attrib_list)
+{
+    EGLBoolean result = EGL_FALSE;
+    return result;
+}
+
+EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
+{
+    EGLBoolean result = EGL_FALSE;
+    return result;
+}
+
+EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
+        EGLClientBuffer buffer, const EGLint *attrib_list)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE) {
+        return setError(EGL_BAD_DISPLAY, EGL_NO_IMAGE_KHR);
+    }
+    if (ctx != EGL_NO_CONTEXT) {
+        return setError(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
+    }
+    if (target != EGL_NATIVE_BUFFER_ANDROID) {
+        return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+    }
+
+    android_native_buffer_t* native_buffer = (android_native_buffer_t*)buffer;
+
+    if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
+        return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+
+    if (native_buffer->common.version != sizeof(android_native_buffer_t))
+        return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+
+    hw_module_t const* pModule;
+    if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule))
+        return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+    buffer_handle_t bufferHandle;
+    gralloc_module_t const* module =
+        reinterpret_cast<gralloc_module_t const*>(pModule);
+    if (native_buffer->getHandle(native_buffer, &bufferHandle) < 0)
+        return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+    if (module->map(module, bufferHandle, &native_buffer->bits) < 0)
+        return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+
+    native_buffer->common.incRef(&native_buffer->common);
+    return (EGLImageKHR)native_buffer;
+}
+
+EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE) {
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    }
+
+    android_native_buffer_t* native_buffer = (android_native_buffer_t*)img;
+
+    if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
+        return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+
+    if (native_buffer->common.version != sizeof(android_native_buffer_t))
+        return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+
+    hw_module_t const* pModule;
+    if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule) == 0) {
+        buffer_handle_t bufferHandle;
+        gralloc_module_t const* module =
+            reinterpret_cast<gralloc_module_t const*>(pModule);
+        if (native_buffer->getHandle(native_buffer, &bufferHandle) == 0) {
+            module->unmap(module, bufferHandle);
+        }
+    }
+
+    native_buffer->common.decRef(&native_buffer->common);
+
+    return EGL_TRUE;
+}
diff --git a/opengl/libagl/state.cpp b/opengl/libagl/state.cpp
index 5cbabea..a00f779 100644
--- a/opengl/libagl/state.cpp
+++ b/opengl/libagl/state.cpp
@@ -2,16 +2,16 @@
 **
 ** Copyright 2006, 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 
+** 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 
+**     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 
+** 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.
 */
 
@@ -28,12 +28,16 @@
 #include "BufferObjectManager.h"
 #include "TextureObjectManager.h"
 
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+#include <hardware/copybit.h>
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
+
 namespace android {
 
 // ----------------------------------------------------------------------------
 
 static char const * const gVendorString     = "Android";
-static char const * const gRendererString   = "Android PixelFlinger 1.0";
+static char const * const gRendererString   = "Android PixelFlinger 1.1";
 static char const * const gVersionString    = "OpenGL ES-CM 1.0";
 static char const * const gExtensionsString =
     "GL_OES_byte_coordinates "              // OK
@@ -46,9 +50,9 @@
     "GL_OES_query_matrix "                  // OK
     //        "GL_OES_point_size_array "              // TODO
     //        "GL_OES_point_sprite "                  // TODO
+    "GL_OES_EGL_image "                     // OK
     "GL_ARB_texture_compression "           // OK
     "GL_ARB_texture_non_power_of_two "      // OK
-    "GL_ANDROID_direct_texture "            // OK
     "GL_ANDROID_user_clip_plane "           // OK
     "GL_ANDROID_vertex_buffer_object "      // OK
     "GL_ANDROID_generate_mipmap "           // OK
@@ -62,13 +66,13 @@
 ogles_context_t *ogles_init(size_t extra)
 {
     void* const base = malloc(extra + sizeof(ogles_context_t) + 32);
-	if (!base) return 0;
+    if (!base) return 0;
 
     ogles_context_t *c =
             (ogles_context_t *)((ptrdiff_t(base) + extra + 31) & ~0x1FL);
     memset(c, 0, sizeof(ogles_context_t));
     ggl_init_context(&(c->rasterizer));
-    
+
     // XXX: this should be passed as an argument
     sp<EGLSurfaceManager> smgr(new EGLSurfaceManager());
     c->surfaceManager = smgr.get();
@@ -87,13 +91,42 @@
     c->rasterizer.base = base;
     c->point.size = TRI_ONE;
     c->line.width = TRI_ONE;
-            
+
     // in OpenGL, writing to the depth buffer is enabled by default.
     c->rasterizer.procs.depthMask(c, 1);
-    
+
     // OpenGL enables dithering by default
     c->rasterizer.procs.enable(c, GL_DITHER);
 
+    c->copybits.blitEngine = NULL;
+    c->copybits.minScale = 0;
+    c->copybits.maxScale = 0;
+    c->copybits.drawSurfaceFd = -1;
+
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+    hw_module_t const* module;
+    if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
+        struct copybit_device_t* copyBits;
+        if (copybit_open(module, &copyBits) == 0) {
+            c->copybits.blitEngine = copyBits;
+            {
+                int minLim = copyBits->get(copyBits,
+                        COPYBIT_MINIFICATION_LIMIT);
+                if (minLim != -EINVAL && minLim > 0) {
+                    c->copybits.minScale = (1 << 16) / minLim;
+                }
+            }
+            {
+                int magLim = copyBits->get(copyBits,
+                        COPYBIT_MAGNIFICATION_LIMIT);
+                if (magLim != -EINVAL && magLim > 0) {
+                    c->copybits.maxScale = min(32*1024-1, magLim) << 16;
+                }
+            }
+        }
+    }
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
+
     return c;
 }
 
@@ -107,7 +140,12 @@
     c->surfaceManager->decStrong(c);
     c->bufferObjectManager->decStrong(c);
     ggl_uninit_context(&(c->rasterizer));
-	free(c->rasterizer.base);
+    free(c->rasterizer.base);
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+    if (c->copybits.blitEngine != NULL) {
+        copybit_close((struct copybit_device_t*) c->copybits.blitEngine);
+    }
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
 }
 
 void _ogles_error(ogles_context_t* c, GLenum error)
@@ -188,7 +226,7 @@
         // these need to fall through into the rasterizer
         c->rasterizer.procs.enableDisable(c, cap, enabled);
         break;
-        
+
     case GL_MULTISAMPLE:
     case GL_SAMPLE_ALPHA_TO_COVERAGE:
     case GL_SAMPLE_ALPHA_TO_ONE:
@@ -281,7 +319,7 @@
     case GL_LINE_SMOOTH_HINT:
         break;
     case GL_POINT_SMOOTH_HINT:
-        c->rasterizer.procs.enableDisable(c, 
+        c->rasterizer.procs.enableDisable(c,
                 GGL_POINT_SMOOTH_NICE, mode==GL_NICEST);
         break;
     case GL_PERSPECTIVE_CORRECTION_HINT:
@@ -323,7 +361,7 @@
         c->error = 0;
         return ret;
     }
-    
+
     if (c->rasterizer.error) {
         const GLenum ret(c->rasterizer.error);
         c->rasterizer.error = 0;
@@ -362,25 +400,25 @@
         int index = c->rasterizer.state.buffers.color.format;
         GGLFormat const * formats = gglGetPixelFormatTable();
         params[0] = formats[index].ah - formats[index].al;
-        break; 
+        break;
         }
     case GL_RED_BITS: {
         int index = c->rasterizer.state.buffers.color.format;
         GGLFormat const * formats = gglGetPixelFormatTable();
         params[0] = formats[index].rh - formats[index].rl;
-        break; 
+        break;
         }
     case GL_GREEN_BITS: {
         int index = c->rasterizer.state.buffers.color.format;
         GGLFormat const * formats = gglGetPixelFormatTable();
         params[0] = formats[index].gh - formats[index].gl;
-        break; 
+        break;
         }
     case GL_BLUE_BITS: {
         int index = c->rasterizer.state.buffers.color.format;
         GGLFormat const * formats = gglGetPixelFormatTable();
         params[0] = formats[index].bh - formats[index].bl;
-        break; 
+        break;
         }
     case GL_COMPRESSED_TEXTURE_FORMATS:
         params[ 0] = GL_PALETTE4_RGB8_OES;
diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp
index b6f534b..9dca133 100644
--- a/opengl/libagl/texture.cpp
+++ b/opengl/libagl/texture.cpp
@@ -2,16 +2,16 @@
 **
 ** Copyright 2006, 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 
+** 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 
+**     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 
+** 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.
 */
 
@@ -23,6 +23,13 @@
 #include "texture.h"
 #include "TextureObjectManager.h"
 
+#include <EGL/android_natives.h>
+
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+#include "copybit.h"
+#include "gralloc_priv.h"
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
+
 namespace android {
 
 // ----------------------------------------------------------------------------
@@ -48,7 +55,7 @@
     // each context has a default named (0) texture (not shared)
     c->textures.defaultTexture = new EGLTextureObject();
     c->textures.defaultTexture->incStrong(c);
-    
+
     // bind the default texture to each texture unit
     for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
         bindTextureTmu(c, i, 0, c->textures.defaultTexture);
@@ -255,7 +262,7 @@
         u.texture->decStrong(c);
 
     if (name == 0) {
-        // 0 is our local texture object, not shared with anyone. 
+        // 0 is our local texture object, not shared with anyone.
         // But it affects all bound TMUs immediately.
         // (we need to invalidate all units bound to this texture object)
         tex = c->textures.defaultTexture;
@@ -273,7 +280,7 @@
     u.texture = tex.get();
     u.texture->incStrong(c);
     u.name = name;
-    invalidate_texture(c, active);    
+    invalidate_texture(c, active);
     return tex;
 }
 
@@ -282,7 +289,7 @@
 {
     if (tex.get() == c->textures.tmu[tmu].texture)
         return;
-    
+
     // free the reference to the previously bound object
     texture_unit_t& u(c->textures.tmu[tmu]);
     if (u.texture)
@@ -310,7 +317,7 @@
     if (formatIdx == 0) { // we don't know what to do with this
         return GL_INVALID_OPERATION;
     }
-    
+
     // figure out the size we need as well as the stride
     const GGLFormat& pixelFormat(c->rasterizer.formats[formatIdx]);
     const int32_t align = c->textures.unpackAlignment-1;
@@ -530,8 +537,8 @@
         ogles_error(c, GL_INVALID_ENUM);
         return;
     }
-    
-    EGLTextureObject* textureObject = c->textures.tmu[c->textures.active].texture;    
+
+    EGLTextureObject* textureObject = c->textures.tmu[c->textures.active].texture;
     switch (pname) {
     case GL_TEXTURE_WRAP_S:
         if ((param == GL_REPEAT) ||
@@ -581,13 +588,10 @@
 }
 
 
-static void drawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h,
+
+static void drawTexxOESImp(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h,
         ogles_context_t* c)
 {
-    // quickly reject empty rects
-    if ((w|h) <= 0)
-        return;                
-
     const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
     y = gglIntToFixed(cbSurface.height) - (y + h);
     w >>= FIXED_BITS;
@@ -610,7 +614,7 @@
                 GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_T, GGL_CLAMP);
         u.dirty = 0xFF; // XXX: should be more subtle
 
-        EGLTextureObject* textureObject = u.texture;  
+        EGLTextureObject* textureObject = u.texture;
         const GLint Ucr = textureObject->crop_rect[0] << 16;
         const GLint Vcr = textureObject->crop_rect[1] << 16;
         const GLint Wcr = textureObject->crop_rect[2] << 16;
@@ -641,13 +645,30 @@
     c->rasterizer.procs.disable(c, GGL_W_LERP);
     c->rasterizer.procs.disable(c, GGL_AA);
     c->rasterizer.procs.shadeModel(c, GL_FLAT);
-    c->rasterizer.procs.recti(c, 
+    c->rasterizer.procs.recti(c,
             gglFixedToIntRound(x),
             gglFixedToIntRound(y),
             gglFixedToIntRound(x)+w,
             gglFixedToIntRound(y)+h);
 }
 
+static void drawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h,
+        ogles_context_t* c)
+{
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+    if (drawTexiOESWithCopybit(gglFixedToIntRound(x),
+            gglFixedToIntRound(y), gglFixedToIntRound(z),
+            gglFixedToIntRound(w), gglFixedToIntRound(h), c)) {
+        return;
+    }
+#else
+    // quickly reject empty rects
+    if ((w|h) <= 0)
+        return;
+#endif
+    drawTexxOESImp(x, y, z, w, h, c);
+}
+
 static void drawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h, ogles_context_t* c)
 {
     // All coordinates are integer, so if we have only one
@@ -656,14 +677,21 @@
     // which is a lot faster.
 
     if (ggl_likely(c->rasterizer.state.enabled_tmu == 1)) {
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+        if (drawTexiOESWithCopybit(x, y, z, w, h, c)) {
+            return;
+        }
+#endif
         const int tmu = 0;
         texture_unit_t& u(c->textures.tmu[tmu]);
-        EGLTextureObject* textureObject = u.texture;  
+        EGLTextureObject* textureObject = u.texture;
         const GLint Wcr = textureObject->crop_rect[2];
         const GLint Hcr = textureObject->crop_rect[3];
 
         if ((w == Wcr) && (h == -Hcr)) {
+#ifndef LIBAGL_USE_GRALLOC_COPYBITS
             if ((w|h) <= 0) return; // quickly reject empty rects
+#endif
 
             if (u.dirty) {
                 c->rasterizer.procs.activeTexture(c, tmu);
@@ -679,14 +707,14 @@
                     GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
             u.dirty = 0xFF; // XXX: should be more subtle
             c->rasterizer.procs.activeTexture(c, c->textures.active);
-            
+
             const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
             y = cbSurface.height - (y + h);
             const GLint Ucr = textureObject->crop_rect[0];
             const GLint Vcr = textureObject->crop_rect[1];
             const GLint s0  = Ucr - x;
             const GLint t0  = (Vcr + Hcr) - y;
-            
+
             const GLuint tw = textureObject->surface.width;
             const GLuint th = textureObject->surface.height;
             if ((uint32_t(s0+x+w) > tw) || (uint32_t(t0+y+h) > th)) {
@@ -694,7 +722,7 @@
                 // in this case, so we just use the slow case, which
                 // at least won't crash
                 goto slow_case;
-            } 
+            }
 
             c->rasterizer.procs.texCoord2i(c, s0, t0);
             const uint32_t enables = c->rasterizer.state.enables;
@@ -711,7 +739,7 @@
     }
 
 slow_case:
-    drawTexxOES(
+    drawTexxOESImp(
             gglIntToFixed(x), gglIntToFixed(y), gglIntToFixed(z),
             gglIntToFixed(w), gglIntToFixed(h),
             c);
@@ -749,7 +777,7 @@
     }
 
     // Bind or create a texture
-    sp<EGLTextureObject> tex;    
+    sp<EGLTextureObject> tex;
     if (texture == 0) {
         // 0 is our local texture object
         tex = c->textures.defaultTexture;
@@ -837,7 +865,7 @@
     if ((pname != GL_PACK_ALIGNMENT) && (pname != GL_UNPACK_ALIGNMENT)) {
         ogles_error(c, GL_INVALID_ENUM);
         return;
-    }    
+    }
     if ((param<=0 || param>8) || (param & (param-1))) {
         ogles_error(c, GL_INVALID_VALUE);
         return;
@@ -945,7 +973,7 @@
     }
 
     // "uncompress" the texture since pixelflinger doesn't support
-    // any compressed texture format natively. 
+    // any compressed texture format natively.
     GLenum format;
     GLenum type;
     switch (internalformat) {
@@ -1009,7 +1037,7 @@
         GLenum format, GLenum type, const GLvoid *pixels)
 {
     ogles_context_t* c = ogles_context_t::get();
-    if (target != GL_TEXTURE_2D && target != GL_DIRECT_TEXTURE_2D_QUALCOMM) {
+    if (target != GL_TEXTURE_2D) {
         ogles_error(c, GL_INVALID_ENUM);
         return;
     }
@@ -1017,7 +1045,7 @@
         ogles_error(c, GL_INVALID_VALUE);
         return;
     }
-    if (format != internalformat) {
+    if (format != (GLenum)internalformat) {
         ogles_error(c, GL_INVALID_OPERATION);
         return;
     }
@@ -1027,16 +1055,10 @@
 
     int32_t size = 0;
     GGLSurface* surface = 0;
-    if (target != GL_DIRECT_TEXTURE_2D_QUALCOMM) {
-        int error = createTextureSurface(c, &surface, &size,
-                level, format, type, width, height);
-        if (error) {
-            ogles_error(c, error);
-            return;
-        }
-    } else if (pixels == 0 || level != 0) {
-        // pixel can't be null for direct texture
-        ogles_error(c, GL_INVALID_OPERATION);
+    int error = createTextureSurface(c, &surface, &size,
+            level, format, type, width, height);
+    if (error) {
+        ogles_error(c, error);
         return;
     }
 
@@ -1057,18 +1079,12 @@
         userSurface.compressedFormat = 0;
         userSurface.data = (GLubyte*)pixels;
 
-        if (target != GL_DIRECT_TEXTURE_2D_QUALCOMM) {
-            int err = copyPixels(c, *surface, 0, 0, userSurface, 0, 0, width, height); 
-            if (err) {
-                ogles_error(c, err);
-                return;
-            }
-            generateMipmap(c, level);
-        } else {
-            // bind it to the texture unit
-            sp<EGLTextureObject> tex = getAndBindActiveTextureObject(c);
-            tex->setSurface(&userSurface);
+        int err = copyPixels(c, *surface, 0, 0, userSurface, 0, 0, width, height);
+        if (err) {
+            ogles_error(c, err);
+            return;
         }
+        generateMipmap(c, level);
     }
 }
 
@@ -1143,7 +1159,7 @@
 
     int err = copyPixels(c,
             surface, xoffset, yoffset,
-            userSurface, 0, 0, width, height); 
+            userSurface, 0, 0, width, height);
     if (err) {
         ogles_error(c, err);
         return;
@@ -1196,7 +1212,7 @@
     case GL_LUMINANCE_ALPHA:
     case GL_LUMINANCE:
         type = GL_UNSIGNED_BYTE;
-        break;    
+        break;
     }
 
     // figure out the format to use for the new texture
@@ -1206,7 +1222,7 @@
     case GGL_PIXEL_FORMAT_RGBA_5551:
     case GGL_PIXEL_FORMAT_RGBA_4444:
         format = internalformat;
-        break;    
+        break;
     case GGL_PIXEL_FORMAT_RGBX_8888:
     case GGL_PIXEL_FORMAT_RGB_888:
     case GGL_PIXEL_FORMAT_RGB_565:
@@ -1215,7 +1231,7 @@
         case GL_LUMINANCE:
         case GL_RGB:
             format = internalformat;
-            break;    
+            break;
         }
         break;
     }
@@ -1235,7 +1251,7 @@
         ogles_error(c, error);
         return;
     }
-    
+
     // The bottom row is stored first in textures
     GGLSurface txSurface(*surface);
     txSurface.stride = -txSurface.stride;
@@ -1245,7 +1261,7 @@
 
     int err = copyPixels(c,
             txSurface, 0, 0,
-            cbSurface, x, y, cbSurface.width, cbSurface.height);  
+            cbSurface, x, y, cbSurface.width, cbSurface.height);
     if (err) {
         ogles_error(c, err);
     }
@@ -1295,7 +1311,7 @@
 
     int err = copyPixels(c,
             surface, xoffset, yoffset,
-            cbSurface, x, y, width, height);  
+            cbSurface, x, y, width, height);
     if (err) {
         ogles_error(c, err);
         return;
@@ -1365,7 +1381,7 @@
         return;
     }
 
-    ggl->colorBuffer(ggl, &userSurface);  // destination is user buffer 
+    ggl->colorBuffer(ggl, &userSurface);  // destination is user buffer
     ggl->bindTexture(ggl, &readSurface);  // source is read-buffer
     ggl->texCoord2i(ggl, x, readSurface.height - (y + height));
     ggl->recti(ggl, 0, 0, width, height);
@@ -1419,3 +1435,73 @@
     ogles_context_t* c = ogles_context_t::get();
     drawTexxOES(x, y, z, w, h, c);
 }
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark EGL Image Extension
+#endif
+
+void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (target != GL_TEXTURE_2D) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+
+    android_native_buffer_t* native_buffer = (android_native_buffer_t*)image;
+    if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    if (native_buffer->common.version != sizeof(android_native_buffer_t)) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+
+    if (native_buffer->bits == NULL) {
+        // this buffer cannot be used with this implementation
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+
+    GGLSurface sur;
+    sur.version = sizeof(GGLSurface);
+    sur.width = native_buffer->width;
+    sur.height= native_buffer->height;
+    sur.stride= native_buffer->stride;
+    sur.format= native_buffer->format;
+    sur.data  = (GGLubyte*)native_buffer->bits;
+
+    // bind it to the texture unit
+    sp<EGLTextureObject> tex = getAndBindActiveTextureObject(c);
+    tex->setSurface(&sur);
+
+    /*
+     * Here an implementation can retrieve the buffer_handle_t of this buffer
+     * which gives it access to an arbitrary-defined kernel resource
+     * (or anything else for that matter).
+     * There needs to be an intimate knowledge between GLES and buffer_handle_t,
+     * so make sure to validate the handle before using it.
+     * Typically, buffer_handle_t comes from the gralloc HAL which is provided
+     * by the implementor of GLES.
+     *
+     */
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+    tex->copybits_fd = -1;
+    buffer_handle_t handle;
+    if (native_buffer->getHandle(native_buffer, &handle) == 0) {
+        private_handle_t* hand;
+        if ((hand = private_handle_t::dynamicCast(handle)) != NULL) {
+            if (hand->usesPhysicallyContiguousMemory()) {
+                tex->copybits_fd = hand->fd;
+            }
+        }
+    }
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
+}
+
+void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
+{
+}
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index 2ecc776..da00cc5 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -7,8 +7,7 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= 	\
-	EGL/egl.cpp 		\
-	EGL/gpu.cpp			\
+	EGL/egl.cpp 	\
 #
 
 LOCAL_SHARED_LIBRARIES += libcutils libutils libui
@@ -23,6 +22,9 @@
     LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../bionic/libc/private
 endif
 
+LOCAL_CFLAGS += -DLOG_TAG=\"libEGL\"
+LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+
 include $(BUILD_SHARED_LIBRARY)
 
 
@@ -35,7 +37,6 @@
 
 LOCAL_SRC_FILES:= 	\
 	GLES_CM/gl.cpp.arm 		\
-	GLES_CM/gl_logger.cpp 	\
 #
 
 LOCAL_SHARED_LIBRARIES += libcutils libutils libui libEGL
@@ -50,4 +51,7 @@
     LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../bionic/libc/private
 endif
 
+LOCAL_CFLAGS += -DLOG_TAG=\"libGLESv1\"
+LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+
 include $(BUILD_SHARED_LIBRARY)
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 0b4bcce..c58fff8 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -14,8 +14,6 @@
  ** limitations under the License.
  */
 
-#define LOG_TAG "GLLogger"
-
 #include <ctype.h>
 #include <string.h>
 #include <errno.h>
@@ -38,6 +36,8 @@
 #include <cutils/memory.h>
 
 #include <utils/RefBase.h>
+#include <utils/threads.h>
+#include <utils/KeyedVector.h>
 
 #include "hooks.h"
 #include "egl_impl.h"
@@ -55,7 +55,14 @@
 static char const * const gVendorString     = "Android";
 static char const * const gVersionString    = "1.31 Android META-EGL";
 static char const * const gClientApiString  = "OpenGL ES";
-static char const * const gExtensionString  = "";
+static char const * const gExtensionString  = 
+        "EGL_KHR_image "
+        "KHR_image_base "
+        "KHR_image_pixmap "
+        "EGL_ANDROID_image_native_buffer "
+        ;
+
+// ----------------------------------------------------------------------------
 
 template <int MAGIC>
 struct egl_object_t
@@ -69,9 +76,9 @@
 
 struct egl_display_t : public egl_object_t<'_dpy'>
 {
-    EGLDisplay  dpys[2];
-    EGLConfig*  configs[2];
-    EGLint      numConfigs[2];
+    EGLDisplay  dpys[IMPL_NUM_DRIVERS_IMPLEMENTATIONS];
+    EGLConfig*  configs[IMPL_NUM_DRIVERS_IMPLEMENTATIONS];
+    EGLint      numConfigs[IMPL_NUM_DRIVERS_IMPLEMENTATIONS];
     EGLint      numTotalConfigs;
     char const* extensionsString;
     volatile int32_t refs;
@@ -81,27 +88,21 @@
         char const * clientApi;
         char const * extensions;
     };
-    strings_t   queryString[2];
+    strings_t   queryString[IMPL_NUM_DRIVERS_IMPLEMENTATIONS];
 };
 
 struct egl_surface_t : public egl_object_t<'_srf'>
 {
     egl_surface_t(EGLDisplay dpy, EGLSurface surface,
-            NativeWindowType window, int impl, egl_connection_t const* cnx) 
-    : dpy(dpy), surface(surface), window(window), impl(impl), cnx(cnx)
+            int impl, egl_connection_t const* cnx) 
+    : dpy(dpy), surface(surface), impl(impl), cnx(cnx)
     {
         // NOTE: window must be incRef'ed and connected already
     }
     ~egl_surface_t() {
-        if (window) {
-            if (window->disconnect)
-                window->disconnect(window);
-            window->decRef(window);
-        }
     }
     EGLDisplay                  dpy;
     EGLSurface                  surface;
-    NativeWindowType            window;
     int                         impl;
     egl_connection_t const*     cnx;
 };
@@ -121,6 +122,18 @@
     egl_connection_t const*     cnx;
 };
 
+struct egl_image_t : public egl_object_t<'_img'>
+{
+    egl_image_t(EGLDisplay dpy, EGLContext context)
+        : dpy(dpy), context(context)
+    {
+        memset(images, 0, sizeof(images));
+    }
+    EGLDisplay dpy;
+    EGLConfig context;
+    EGLImageKHR images[IMPL_NUM_DRIVERS_IMPLEMENTATIONS];
+};
+
 struct tls_t
 {
     tls_t() : error(EGL_SUCCESS), ctx(0) { }
@@ -156,7 +169,7 @@
 
 // ----------------------------------------------------------------------------
 
-egl_connection_t gEGLImpl[2];
+egl_connection_t gEGLImpl[IMPL_NUM_DRIVERS_IMPLEMENTATIONS];
 static egl_display_t gDisplay[NUM_DISPLAYS];
 static pthread_mutex_t gThreadLocalStorageKeyMutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_key_t gEGLThreadLocalStorageKey = -1;
@@ -261,14 +274,8 @@
     return tls->ctx;
 }
 
-
 /*****************************************************************************/
 
-class ISurfaceComposer;
-const sp<ISurfaceComposer>& getSurfaceFlinger();
-request_gpu_t* gpu_acquire(void* user);
-int gpu_release(void*, request_gpu_t* gpu);
-
 static __attribute__((noinline))
 void *load_driver(const char* driver, gl_hooks_t* hooks)
 {
@@ -278,42 +285,59 @@
             driver, dlerror());
 
     if (dso) {
-        void** curr;
+        // first find the symbol for eglGetProcAddress
+        
+        typedef __eglMustCastToProperFunctionPointerType (*getProcAddressType)(
+                const char*);
+        
+        getProcAddressType getProcAddress = 
+            (getProcAddressType)dlsym(dso, "eglGetProcAddress");
+        
+        LOGE_IF(!getProcAddress, 
+                "can't find eglGetProcAddress() in %s", driver);        
+        
+        __eglMustCastToProperFunctionPointerType* curr;
         char const * const * api;
-        gl_hooks_t::gl_t* gl = &hooks->gl;
-        curr = (void**)gl;
-        api = gl_names;
-        while (*api) {
-            void* f = dlsym(dso, *api);
-            //LOGD("<%s> @ 0x%p", *api, f);
-            if (f == NULL) {
-                //LOGW("<%s> not found in %s", *api, driver);
-                f = (void*)gl_unimplemented;
-            }
-            *curr++ = f;
-            api++;
-        }
+
         gl_hooks_t::egl_t* egl = &hooks->egl;
-        curr = (void**)egl;
+        curr = (__eglMustCastToProperFunctionPointerType*)egl;
         api = egl_names;
         while (*api) {
-            void* f = dlsym(dso, *api);
+            char const * name = *api;
+            __eglMustCastToProperFunctionPointerType f = 
+                (__eglMustCastToProperFunctionPointerType)dlsym(dso, name);
             if (f == NULL) {
-                //LOGW("<%s> not found in %s", *api, driver);
-                f = (void*)0;
+                // couldn't find the entry-point, use eglGetProcAddress()
+                f = getProcAddress(name);
+                if (f == NULL) {
+                    f = (__eglMustCastToProperFunctionPointerType)0;
+                }
             }
             *curr++ = f;
             api++;
         }
-
-        // hook this driver up with surfaceflinger if needed
-        register_gpu_t register_gpu = 
-            (register_gpu_t)dlsym(dso, "oem_register_gpu");
-
-        if (register_gpu != NULL) {
-            if (getSurfaceFlinger() != 0) {
-                register_gpu(dso, gpu_acquire, gpu_release);
+        
+        gl_hooks_t::gl_t* gl = &hooks->gl;
+        curr = (__eglMustCastToProperFunctionPointerType*)gl;
+        api = gl_names;
+        while (*api) {
+            char const * name = *api;
+            // if the function starts with '__' it's a special case that
+            // uses a wrapper. skip the '__' when looking into the real lib.
+            if (name[0] == '_' && name[1] == '_') {
+                name += 2;
             }
+            __eglMustCastToProperFunctionPointerType f = 
+                (__eglMustCastToProperFunctionPointerType)dlsym(dso, name);
+            if (f == NULL) {
+                // couldn't find the entry-point, use eglGetProcAddress()
+                f = getProcAddress(name);
+                if (f == NULL) {
+                    f = (__eglMustCastToProperFunctionPointerType)gl_unimplemented;
+                }
+            }
+            *curr++ = f;
+            api++;
         }
     }
     return dso;
@@ -365,6 +389,14 @@
 };
 
 static const extention_map_t gExtentionMap[] = {
+    { "eglLockSurfaceKHR",  
+            (__eglMustCastToProperFunctionPointerType)&eglLockSurfaceKHR }, 
+    { "eglUnlockSurfaceKHR", 
+            (__eglMustCastToProperFunctionPointerType)&eglUnlockSurfaceKHR }, 
+    { "eglCreateImageKHR",  
+            (__eglMustCastToProperFunctionPointerType)&eglCreateImageKHR }, 
+    { "eglDestroyImageKHR", 
+            (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR }, 
 };
 
 static extention_map_t gGLExtentionMap[MAX_NUMBER_OF_GL_EXTENSIONS];
@@ -382,6 +414,12 @@
 
 // ----------------------------------------------------------------------------
 
+/*
+ * To "loose" the GPU, use something like
+ *    gEGLImpl[IMPL_HARDWARE].hooks = &gHooks[IMPL_CONTEXT_LOST];
+ * 
+ */
+
 static int gl_context_lost() {
     setGlThreadSpecific(&gHooks[IMPL_CONTEXT_LOST]);
     return 0;
@@ -429,18 +467,24 @@
     return (index >= NUM_DISPLAYS) ? NULL : &gDisplay[index];
 }
 
-static inline
-egl_surface_t* get_surface(EGLSurface surface)
-{
-    egl_surface_t* s = (egl_surface_t *)surface;
-    return s;
+template<typename NATIVE, typename EGL>
+static inline NATIVE* egl_to_native_cast(EGL arg) {
+    return reinterpret_cast<NATIVE*>(arg);
 }
 
 static inline
-egl_context_t* get_context(EGLContext context)
-{
-    egl_context_t* c = (egl_context_t *)context;
-    return c;
+egl_surface_t* get_surface(EGLSurface surface) {   
+    return egl_to_native_cast<egl_surface_t>(surface);
+}
+
+static inline
+egl_context_t* get_context(EGLContext context) {
+    return egl_to_native_cast<egl_context_t>(context);
+}
+
+static inline
+egl_image_t* get_image(EGLImageKHR image) {
+    return egl_to_native_cast<egl_image_t>(image);
 }
 
 static egl_connection_t* validate_display_config(
@@ -451,7 +495,7 @@
     if (!dp) return setError(EGL_BAD_DISPLAY, (egl_connection_t*)NULL);
 
     impl = uintptr_t(config)>>24;
-    if (uint32_t(impl) >= 2) {
+    if (uint32_t(impl) >= IMPL_NUM_DRIVERS_IMPLEMENTATIONS) {
         return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL);
     } 
     index = uintptr_t(config) & 0xFFFFFF;
@@ -491,13 +535,26 @@
     return EGL_TRUE;
 }
 
-// ----------------------------------------------------------------------------
-}; // namespace android
-// ----------------------------------------------------------------------------
 
-using namespace android;
+EGLImageKHR egl_get_image_for_current_context(EGLImageKHR image)
+{
+    EGLContext context = getContext();
+    if (context == EGL_NO_CONTEXT || image == EGL_NO_IMAGE_KHR)
+        return EGL_NO_IMAGE_KHR;
+    
+    egl_context_t const * const c = get_context(context);
+    if (!c->isValid())
+        return EGL_NO_IMAGE_KHR;
 
-EGLDisplay eglGetDisplay(NativeDisplayType display)
+    egl_image_t const * const i = get_image(image);
+    if (!i->isValid())
+        return EGL_NO_IMAGE_KHR;
+
+    return i->images[c->impl];
+}
+
+
+EGLDisplay egl_init_displays(NativeDisplayType display)
 {
     if (sEarlyInitState) {
         return EGL_NO_DISPLAY;
@@ -510,7 +567,7 @@
     
     EGLDisplay dpy = EGLDisplay(uintptr_t(display) + 1LU);
     egl_display_t* d = &gDisplay[index];
-        
+
     // dynamically load all our EGL implementations for that display
     // and call into the real eglGetGisplay()
     egl_connection_t* cnx = &gEGLImpl[IMPL_SOFTWARE];
@@ -530,7 +587,7 @@
         property_get("debug.egl.hw", value, "1");
         if (atoi(value) != 0) {
             cnx->hooks = &gHooks[IMPL_HARDWARE];
-            cnx->dso = load_driver("libhgl.so", cnx->hooks);
+            cnx->dso = load_driver("libhgl2.so", cnx->hooks);
         } else {
             LOGD("3D hardware acceleration is disabled");
         }
@@ -573,6 +630,18 @@
     return dpy;
 }
 
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
+using namespace android;
+
+EGLDisplay eglGetDisplay(NativeDisplayType display)
+{
+    return egl_init_displays(display);
+}
+
 // ----------------------------------------------------------------------------
 // Initialization
 // ----------------------------------------------------------------------------
@@ -594,7 +663,7 @@
     // build our own extension string first, based on the extension we know
     // and the extension supported by our client implementation
     dp->extensionsString = strdup(gExtensionString);
-    for (int i=0 ; i<2 ; i++) {
+    for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
         egl_connection_t* const cnx = &gEGLImpl[i];
         cnx->major = -1;
         cnx->minor = -1;
@@ -624,7 +693,7 @@
     }
 
     EGLBoolean res = EGL_FALSE;
-    for (int i=0 ; i<2 ; i++) {
+    for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
         egl_connection_t* const cnx = &gEGLImpl[i];
         if (cnx->dso && cnx->major>=0 && cnx->minor>=0) {
             EGLint n;
@@ -663,7 +732,7 @@
         return EGL_TRUE;
         
     EGLBoolean res = EGL_FALSE;
-    for (int i=0 ; i<2 ; i++) {
+    for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
         egl_connection_t* const cnx = &gEGLImpl[i];
         if (cnx->dso) {
             cnx->hooks->egl.eglTerminate(dp->dpys[i]);
@@ -706,7 +775,7 @@
         return EGL_TRUE;
     }
     GLint n = 0;
-    for (int j=0 ; j<2 ; j++) {
+    for (int j=0 ; j<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; j++) {
         for (int i=0 ; i<dp->numConfigs[j] && config_size ; i++) {
             *configs++ = MAKE_CONFIG(j, i);
             config_size--;
@@ -794,7 +863,7 @@
         return res;
     }
 
-    for (int i=0 ; i<2 ; i++) {
+    for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
         egl_connection_t* const cnx = &gEGLImpl[i];
         if (cnx->dso) {
             if (cnx->hooks->egl.eglChooseConfig(
@@ -854,26 +923,12 @@
     int i=0, index=0;
     egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index);
     if (cnx) {
-        // window must be connected upon calling underlying
-        // eglCreateWindowSurface
-        if (window) {
-            window->incRef(window);
-            if (window->connect)
-                window->connect(window);
-        }
-
         EGLSurface surface = cnx->hooks->egl.eglCreateWindowSurface(
                 dp->dpys[i], dp->configs[i][index], window, attrib_list);       
         if (surface != EGL_NO_SURFACE) {
-            egl_surface_t* s = new egl_surface_t(dpy, surface, window, i, cnx);
+            egl_surface_t* s = new egl_surface_t(dpy, surface, i, cnx);
             return s;
         }
-        
-        // something went wrong, disconnect and free window
-        // (will disconnect() automatically)
-        if (window) {
-            window->decRef(window);
-        }        
     }
     return EGL_NO_SURFACE;
 }
@@ -889,7 +944,7 @@
         EGLSurface surface = cnx->hooks->egl.eglCreatePixmapSurface(
                 dp->dpys[i], dp->configs[i][index], pixmap, attrib_list);
         if (surface != EGL_NO_SURFACE) {
-            egl_surface_t* s = new egl_surface_t(dpy, surface, NULL, i, cnx);
+            egl_surface_t* s = new egl_surface_t(dpy, surface, i, cnx);
             return s;
         }
     }
@@ -906,7 +961,7 @@
         EGLSurface surface = cnx->hooks->egl.eglCreatePbufferSurface(
                 dp->dpys[i], dp->configs[i][index], attrib_list);
         if (surface != EGL_NO_SURFACE) {
-            egl_surface_t* s = new egl_surface_t(dpy, surface, NULL, i, cnx);
+            egl_surface_t* s = new egl_surface_t(dpy, surface, i, cnx);
             return s;
         }
     }
@@ -1107,7 +1162,7 @@
 EGLint eglGetError(void)
 {
     EGLint result = EGL_SUCCESS;
-    for (int i=0 ; i<2 ; i++) {
+    for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
         EGLint err = EGL_SUCCESS;
         egl_connection_t* const cnx = &gEGLImpl[i];
         if (cnx->dso)
@@ -1120,8 +1175,15 @@
     return result;
 }
 
-void (*eglGetProcAddress(const char *procname))()
+__eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
 {
+    // eglGetProcAddress() could be the very first function called
+    // in which case we must make sure we've initialized ourselves, this
+    // happens the first time egl_get_display() is called.
+    
+    if (egl_init_displays(EGL_DEFAULT_DISPLAY) == EGL_NO_DISPLAY)
+        return NULL;
+
     __eglMustCastToProperFunctionPointerType addr;
     addr = findProcAddress(procname, gExtentionMap, NELEM(gExtentionMap));
     if (addr) return addr;
@@ -1133,7 +1195,7 @@
     
     addr = 0;
     int slot = -1;
-    for (int i=0 ; i<2 ; i++) {
+    for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
         egl_connection_t* const cnx = &gEGLImpl[i];
         if (cnx->dso) {
             if (cnx->hooks->egl.eglGetProcAddress) {
@@ -1266,7 +1328,7 @@
     if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
 
     EGLBoolean res = EGL_TRUE;
-    for (int i=0 ; i<2 ; i++) {
+    for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
         egl_connection_t* const cnx = &gEGLImpl[i];
         if (cnx->dso) {
             if (cnx->hooks->egl.eglSwapInterval) {
@@ -1309,7 +1371,7 @@
 {
     // bind this API on all EGLs
     EGLBoolean res = EGL_TRUE;
-    for (int i=0 ; i<2 ; i++) {
+    for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
         egl_connection_t* const cnx = &gEGLImpl[i];
         if (cnx->dso) {
             if (cnx->hooks->egl.eglBindAPI) {
@@ -1324,7 +1386,7 @@
 
 EGLenum eglQueryAPI(void)
 {
-    for (int i=0 ; i<2 ; i++) {
+    for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
         egl_connection_t* const cnx = &gEGLImpl[i];
         if (cnx->dso) {
             if (cnx->hooks->egl.eglQueryAPI) {
@@ -1340,7 +1402,7 @@
 
 EGLBoolean eglReleaseThread(void)
 {
-    for (int i=0 ; i<2 ; i++) {
+    for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
         egl_connection_t* const cnx = &gEGLImpl[i];
         if (cnx->dso) {
             if (cnx->hooks->egl.eglReleaseThread) {
@@ -1366,3 +1428,124 @@
     }
     return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
 }
+
+// ----------------------------------------------------------------------------
+// EGL_EGLEXT_VERSION 3
+// ----------------------------------------------------------------------------
+
+EGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface,
+        const EGLint *attrib_list)
+{
+    EGLBoolean result = EGL_FALSE;
+    if (!validate_display_surface(dpy, surface))
+        return result;
+
+    egl_display_t const * const dp = get_display(dpy);
+    egl_surface_t const * const s = get_surface(surface);
+
+    if (s->cnx->hooks->egl.eglLockSurfaceKHR) {
+        result = s->cnx->hooks->egl.eglLockSurfaceKHR(
+                dp->dpys[s->impl], s->surface, attrib_list);
+    }
+    return result;
+}
+
+EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
+{
+    EGLBoolean result = EGL_FALSE;
+    if (!validate_display_surface(dpy, surface))
+        return result;
+
+    egl_display_t const * const dp = get_display(dpy);
+    egl_surface_t const * const s = get_surface(surface);
+
+    if (s->cnx->hooks->egl.eglUnlockSurfaceKHR) {
+        result = s->cnx->hooks->egl.eglUnlockSurfaceKHR(
+                dp->dpys[s->impl], s->surface);
+    }
+    return result;
+}
+
+EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
+        EGLClientBuffer buffer, const EGLint *attrib_list)
+{
+    if (ctx != EGL_NO_CONTEXT) {
+        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->hooks->egl.eglCreateImageKHR(
+                dp->dpys[c->impl], c->context, target, buffer, attrib_list);
+        if (image == EGL_NO_IMAGE_KHR)
+            return image;
+            
+        egl_image_t* result = new egl_image_t(dpy, ctx);
+        result->images[c->impl] = image;
+        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
+
+        EGLImageKHR implImages[IMPL_NUM_DRIVERS_IMPLEMENTATIONS];
+        bool success = false;
+        for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
+            egl_connection_t* const cnx = &gEGLImpl[i];
+            implImages[i] = EGL_NO_IMAGE_KHR;
+            if (cnx->dso) {
+                if (cnx->hooks->egl.eglCreateImageKHR) {
+                    implImages[i] = cnx->hooks->egl.eglCreateImageKHR(
+                            dp->dpys[i], ctx, target, buffer, attrib_list);
+                    if (implImages[i] != EGL_NO_IMAGE_KHR) {
+                        success = true;
+                    }
+                }
+            }
+        }
+        if (!success)
+            return EGL_NO_IMAGE_KHR;
+        
+        egl_image_t* result = new egl_image_t(dpy, ctx);
+        memcpy(result->images, implImages, sizeof(implImages));
+        return (EGLImageKHR)result;
+    }
+}
+
+EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
+{
+     egl_display_t const * const dp = get_display(dpy);
+     if (dp == 0) {
+         return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+     }
+
+     egl_image_t* image = get_image(img);
+     if (!image->isValid()) {
+         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+     }
+
+     bool success = false;
+     for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
+         egl_connection_t* const cnx = &gEGLImpl[i];
+         if (image->images[i] != EGL_NO_IMAGE_KHR) {
+             if (cnx->dso) {
+                 if (cnx->hooks->egl.eglCreateImageKHR) {
+                     if (cnx->hooks->egl.eglDestroyImageKHR(
+                             dp->dpys[i], image->images[i])) {
+                         success = true;
+                     }
+                 }
+             }
+         }
+     }
+     if (!success)
+         return EGL_FALSE;
+
+     delete image;
+
+     return EGL_FALSE;
+}
diff --git a/opengl/libs/GLES_CM/gl.cpp b/opengl/libs/GLES_CM/gl.cpp
index 865cf44..a175343 100644
--- a/opengl/libs/GLES_CM/gl.cpp
+++ b/opengl/libs/GLES_CM/gl.cpp
@@ -14,8 +14,6 @@
  ** limitations under the License.
  */
 
-#define LOG_TAG "GLES_CM"
-
 #include <ctype.h>
 #include <string.h>
 #include <errno.h>
@@ -29,6 +27,7 @@
 #include <cutils/properties.h>
 
 #include "hooks.h"
+#include "egl_impl.h"
 
 using namespace android;
 
@@ -57,13 +56,6 @@
 // Actual GL entry-points
 // ----------------------------------------------------------------------------
 
-#if GL_LOGGER
-#   include "gl_logger.h"
-#   define GL_LOGGER_IMPL(_x) _x
-#else
-#   define GL_LOGGER_IMPL(_x)
-#endif
-
 #undef API_ENTRY
 #undef CALL_GL_API
 #undef CALL_GL_API_RETURN
@@ -96,16 +88,15 @@
 
     #define CALL_GL_API(_api, ...)                                      \
         gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
-        GL_LOGGER_IMPL( log_##_api(__VA_ARGS__); )                      \
         _c->_api(__VA_ARGS__)
     
     #define CALL_GL_API_RETURN(_api, ...)                               \
         gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
-        GL_LOGGER_IMPL( log_##_api(__VA_ARGS__); )                      \
         return _c->_api(__VA_ARGS__)
 
 #endif
 
+
 extern "C" {
 #include "gl_api.in"
 }
@@ -114,3 +105,27 @@
 #undef CALL_GL_API
 #undef CALL_GL_API_RETURN
 
+
+/*
+ * These GL calls are special because they need to EGL to retrieve some
+ * informations before they can execute.
+ */
+
+extern "C" void __glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image);
+extern "C" void __glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image);
+
+
+void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
+{
+    GLeglImageOES implImage = 
+        (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image);
+    __glEGLImageTargetTexture2DOES(target, implImage);
+}
+
+void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
+{
+    GLeglImageOES implImage = 
+        (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image);
+    __glEGLImageTargetRenderbufferStorageOES(target, image);
+}
+
diff --git a/opengl/libs/GLES_CM/gl_api.in b/opengl/libs/GLES_CM/gl_api.in
index 9234ef2..f36b8c0 100644
--- a/opengl/libs/GLES_CM/gl_api.in
+++ b/opengl/libs/GLES_CM/gl_api.in
@@ -1,144 +1,33 @@
-void API_ENTRY(glActiveTexture)(GLenum texture) {
-    CALL_GL_API(glActiveTexture, texture);
+void API_ENTRY(glColor4f)(GLfloat arg0,  GLfloat arg1,  GLfloat arg2,  GLfloat arg3) {
+    CALL_GL_API(glColor4f, arg0, arg1, arg2, arg3);
 }
 
-void API_ENTRY(glAlphaFunc)(GLenum func, GLclampf ref) {
-    CALL_GL_API(glAlphaFunc, func, ref);
+void API_ENTRY(glColor4x)(GLfixed arg0,  GLfixed arg1,  GLfixed arg2,  GLfixed arg3) {
+    CALL_GL_API(glColor4x, arg0, arg1, arg2, arg3);
 }
 
-void API_ENTRY(glAlphaFuncx)(GLenum func, GLclampx ref) {
-    CALL_GL_API(glAlphaFuncx, func, ref);
+void API_ENTRY(glNormal3f)(GLfloat arg0,  GLfloat arg1,  GLfloat arg2) {
+    CALL_GL_API(glNormal3f, arg0, arg1, arg2);
 }
 
-void API_ENTRY(glBindTexture)(GLenum target, GLuint texture) {
-    CALL_GL_API(glBindTexture, target, texture);
+void API_ENTRY(glNormal3x)(GLfixed arg0,  GLfixed arg1,  GLfixed arg2) {
+    CALL_GL_API(glNormal3x, arg0, arg1, arg2);
 }
 
-void API_ENTRY(glBlendFunc)(GLenum sfactor, GLenum dfactor) {
-    CALL_GL_API(glBlendFunc, sfactor, dfactor);
+void API_ENTRY(glCullFace)(GLenum arg0) {
+    CALL_GL_API(glCullFace, arg0);
 }
 
-void API_ENTRY(glClear)(GLbitfield mask) {
-    CALL_GL_API(glClear, mask);
+void API_ENTRY(glFrontFace)(GLenum arg0) {
+    CALL_GL_API(glFrontFace, arg0);
 }
 
-void API_ENTRY(glClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
-    CALL_GL_API(glClearColor, red, green, blue, alpha);
+void API_ENTRY(glDisable)(GLenum arg0) {
+    CALL_GL_API(glDisable, arg0);
 }
 
-void API_ENTRY(glClearColorx)(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) {
-    CALL_GL_API(glClearColorx, red, green, blue, alpha);
-}
-
-void API_ENTRY(glClearDepthf)(GLclampf depth) {
-    CALL_GL_API(glClearDepthf, depth);
-}
-
-void API_ENTRY(glClearDepthx)(GLclampx depth) {
-    CALL_GL_API(glClearDepthx, depth);
-}
-
-void API_ENTRY(glClearStencil)(GLint s) {
-    CALL_GL_API(glClearStencil, s);
-}
-
-void API_ENTRY(glClientActiveTexture)(GLenum texture) {
-    CALL_GL_API(glClientActiveTexture, texture);
-}
-
-void API_ENTRY(glColor4f)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
-    CALL_GL_API(glColor4f, red, green, blue, alpha);
-}
-
-void API_ENTRY(glColor4x)(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) {
-    CALL_GL_API(glColor4x, red, green, blue, alpha);
-}
-
-void API_ENTRY(glColorMask)(GLboolean r, GLboolean g, GLboolean b, GLboolean a) {
-    CALL_GL_API(glColorMask, r, g, b, a);
-}
-
-void API_ENTRY(glColorPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
-{
-    CALL_GL_API(glColorPointer, size, type, stride, ptr);
-}
-
-void API_ENTRY(glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat,
-                            GLsizei width, GLsizei height, GLint border,
-                            GLsizei imageSize, const GLvoid *data) {
-    CALL_GL_API(glCompressedTexImage2D, target, level, internalformat,
-            width, height, border, imageSize, data);
-}
-
-void API_ENTRY(glCompressedTexSubImage2D)( GLenum target, GLint level, GLint xoffset,
-                                GLint yoffset, GLsizei width, GLsizei height,
-                                GLenum format, GLsizei imageSize,
-                                const GLvoid *data) {
-    CALL_GL_API(glCompressedTexSubImage2D, target, level, xoffset, yoffset,
-            width, height, format, imageSize, data);
-}
-
-void API_ENTRY(glCopyTexImage2D)(  GLenum target, GLint level, GLenum internalformat,
-                        GLint x, GLint y, GLsizei width, GLsizei height,
-                        GLint border) {
-    CALL_GL_API(glCopyTexImage2D, target, level, internalformat, x, y,
-            width, height, border);
-}
-
-void API_ENTRY(glCopyTexSubImage2D)(   GLenum target, GLint level, GLint xoffset,
-                            GLint yoffset, GLint x, GLint y, GLsizei width,
-                            GLsizei height) {
-    CALL_GL_API(glCopyTexSubImage2D, target, level, xoffset, yoffset, x, y,
-            width, height);
-}
-
-void API_ENTRY(glCullFace)(GLenum mode) {
-    CALL_GL_API(glCullFace, mode);
-}
-
-void API_ENTRY(glDeleteTextures)(GLsizei n, const GLuint *textures) {
-    CALL_GL_API(glDeleteTextures, n, textures);
-}
-
-void API_ENTRY(glDepthFunc)(GLenum func) {
-    CALL_GL_API(glDepthFunc, func);
-}
-
-void API_ENTRY(glDepthMask)(GLboolean flag) {
-    CALL_GL_API(glDepthMask, flag);
-}
-
-void API_ENTRY(glDepthRangef)(GLclampf zNear, GLclampf zFar) {
-    CALL_GL_API(glDepthRangef, zNear, zFar);
-}
-
-void API_ENTRY(glDepthRangex)(GLclampx zNear, GLclampx zFar) {
-    CALL_GL_API(glDepthRangex, zNear, zFar);
-}
-
-void API_ENTRY(glDisable)(GLenum cap) {
-    CALL_GL_API(glDisable, cap);
-}
-
-void API_ENTRY(glDisableClientState)(GLenum array) {
-    CALL_GL_API(glDisableClientState, array);
-}
-
-void API_ENTRY(glDrawArrays)(GLenum mode, GLint first, GLsizei count) {
-    CALL_GL_API(glDrawArrays, mode, first, count);
-}
-
-void API_ENTRY(glDrawElements)(GLenum mode, GLsizei count,
-                    GLenum type, const GLvoid *indices) {
-    CALL_GL_API(glDrawElements, mode, count, type, indices);
-}
-
-void API_ENTRY(glEnable)(GLenum cap) {
-    CALL_GL_API(glEnable, cap);
-}
-
-void API_ENTRY(glEnableClientState)(GLenum array) {
-    CALL_GL_API(glEnableClientState, array);
+void API_ENTRY(glEnable)(GLenum arg0) {
+    CALL_GL_API(glEnable, arg0);
 }
 
 void API_ENTRY(glFinish)(void) {
@@ -149,192 +38,256 @@
     CALL_GL_API(glFlush);
 }
 
-void API_ENTRY(glFogf)(GLenum pname, GLfloat param) {
-    CALL_GL_API(glFogf, pname, param);
-}
-
-void API_ENTRY(glFogfv)(GLenum pname, const GLfloat *params) {
-    CALL_GL_API(glFogfv, pname, params);
-}
-
-void API_ENTRY(glFogx)(GLenum pname, GLfixed param) {
-    CALL_GL_API(glFogx, pname, param);
-}
-
-void API_ENTRY(glFogxv)(GLenum pname, const GLfixed *params) {
-    CALL_GL_API(glFogxv, pname, params);
-}
-
-void API_ENTRY(glFrontFace)(GLenum mode) {
-    CALL_GL_API(glFrontFace, mode);
-}
-
-void API_ENTRY(glFrustumf)(GLfloat left, GLfloat right,
-                GLfloat bottom, GLfloat top,
-                GLfloat zNear, GLfloat zFar) {
-    CALL_GL_API(glFrustumf, left, right, bottom, top, zNear, zFar);
-}
-
-void API_ENTRY(glFrustumx)(GLfixed left, GLfixed right,
-                GLfixed bottom, GLfixed top,
-                GLfixed zNear, GLfixed zFar) {
-    CALL_GL_API(glFrustumx, left, right, bottom, top, zNear, zFar);
-}
-
-void API_ENTRY(glGenTextures)(GLsizei n, GLuint *textures) {
-    CALL_GL_API(glGenTextures, n, textures);
-}
-
 GLenum API_ENTRY(glGetError)(void) {
     CALL_GL_API_RETURN(glGetError);
 }
 
-void API_ENTRY(glGetIntegerv)(GLenum pname, GLint *params) {
-    CALL_GL_API(glGetIntegerv, pname, params);
+const GLubyte* API_ENTRY(glGetString)(GLenum arg0) {
+    CALL_GL_API_RETURN(glGetString, arg0);
 }
 
-const GLubyte * API_ENTRY(glGetString)(GLenum name) {
-    CALL_GL_API_RETURN(glGetString, name);
+void API_ENTRY(glGetIntegerv)(GLenum arg0,  GLint * arg1) {
+    CALL_GL_API(glGetIntegerv, arg0, arg1);
 }
 
-void API_ENTRY(glHint)(GLenum target, GLenum mode) {
-    CALL_GL_API(glHint, target, mode);
+void API_ENTRY(glColorMask)(GLboolean arg0,  GLboolean arg1,  GLboolean arg2,  GLboolean arg3) {
+    CALL_GL_API(glColorMask, arg0, arg1, arg2, arg3);
 }
 
-void API_ENTRY(glLightModelf)(GLenum pname, GLfloat param) {
-    CALL_GL_API(glLightModelf, pname, param);
+void API_ENTRY(glDepthMask)(GLboolean arg0) {
+    CALL_GL_API(glDepthMask, arg0);
 }
 
-void API_ENTRY(glLightModelfv)(GLenum pname, const GLfloat *params) {
-    CALL_GL_API(glLightModelfv, pname, params);
+void API_ENTRY(glStencilMask)(GLuint arg0) {
+    CALL_GL_API(glStencilMask, arg0);
 }
 
-void API_ENTRY(glLightModelx)(GLenum pname, GLfixed param) {
-    CALL_GL_API(glLightModelx, pname, param);
+void API_ENTRY(glDepthFunc)(GLenum arg0) {
+    CALL_GL_API(glDepthFunc, arg0);
 }
 
-void API_ENTRY(glLightModelxv)(GLenum pname, const GLfixed *params) {
-    CALL_GL_API(glLightModelxv, pname, params);
+void API_ENTRY(glDepthRangef)(GLclampf arg0,  GLclampf arg1) {
+    CALL_GL_API(glDepthRangef, arg0, arg1);
 }
 
-void API_ENTRY(glLightf)(GLenum light, GLenum pname, GLfloat param) {
-    CALL_GL_API(glLightf, light, pname, param);
+void API_ENTRY(glDepthRangex)(GLclampx arg0,  GLclampx arg1) {
+    CALL_GL_API(glDepthRangex, arg0, arg1);
 }
 
-void API_ENTRY(glLightfv)(GLenum light, GLenum pname, const GLfloat *params) {
-    CALL_GL_API(glLightfv, light, pname, params);
+void API_ENTRY(glPolygonOffset)(GLfloat arg0,  GLfloat arg1) {
+    CALL_GL_API(glPolygonOffset, arg0, arg1);
 }
 
-void API_ENTRY(glLightx)(GLenum light, GLenum pname, GLfixed param) {
-    CALL_GL_API(glLightx, light, pname, param);
+void API_ENTRY(glPolygonOffsetx)(GLfixed arg0,  GLfixed arg1) {
+    CALL_GL_API(glPolygonOffsetx, arg0, arg1);
 }
 
-void API_ENTRY(glLightxv)(GLenum light, GLenum pname, const GLfixed *params) {
-    CALL_GL_API(glLightxv, light, pname, params);
+void API_ENTRY(glLogicOp)(GLenum arg0) {
+    CALL_GL_API(glLogicOp, arg0);
 }
 
-void API_ENTRY(glLineWidth)(GLfloat width) {
-    CALL_GL_API(glLineWidth, width);
+void API_ENTRY(glAlphaFuncx)(GLenum arg0,  GLclampx arg1) {
+    CALL_GL_API(glAlphaFuncx, arg0, arg1);
 }
 
-void API_ENTRY(glLineWidthx)(GLfixed width) {
-    CALL_GL_API(glLineWidthx, width);
+void API_ENTRY(glAlphaFunc)(GLenum arg0,  GLclampf arg1) {
+    CALL_GL_API(glAlphaFunc, arg0, arg1);
+}
+
+void API_ENTRY(glBlendFunc)(GLenum arg0,  GLenum arg1) {
+    CALL_GL_API(glBlendFunc, arg0, arg1);
+}
+
+void API_ENTRY(glClear)(GLbitfield arg0) {
+    CALL_GL_API(glClear, arg0);
+}
+
+void API_ENTRY(glClearColor)(GLclampf arg0,  GLclampf arg1,  GLclampf arg2,  GLclampf arg3) {
+    CALL_GL_API(glClearColor, arg0, arg1, arg2, arg3);
+}
+
+void API_ENTRY(glClearColorx)(GLclampx arg0,  GLclampx arg1,  GLclampx arg2,  GLclampx arg3) {
+    CALL_GL_API(glClearColorx, arg0, arg1, arg2, arg3);
+}
+
+void API_ENTRY(glClearDepthf)(GLclampf arg0) {
+    CALL_GL_API(glClearDepthf, arg0);
+}
+
+void API_ENTRY(glClearDepthx)(GLclampx arg0) {
+    CALL_GL_API(glClearDepthx, arg0);
+}
+
+void API_ENTRY(glClearStencil)(GLint arg0) {
+    CALL_GL_API(glClearStencil, arg0);
+}
+
+void API_ENTRY(glPointSize)(GLfloat arg0) {
+    CALL_GL_API(glPointSize, arg0);
+}
+
+void API_ENTRY(glPointSizex)(GLfixed arg0) {
+    CALL_GL_API(glPointSizex, arg0);
+}
+
+void API_ENTRY(glSampleCoverage)(GLclampf arg0,  GLboolean arg1) {
+    CALL_GL_API(glSampleCoverage, arg0, arg1);
+}
+
+void API_ENTRY(glSampleCoveragex)(GLclampx arg0,  GLboolean arg1) {
+    CALL_GL_API(glSampleCoveragex, arg0, arg1);
+}
+
+void API_ENTRY(glStencilFunc)(GLenum arg0,  GLint arg1,  GLuint arg2) {
+    CALL_GL_API(glStencilFunc, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glStencilOp)(GLenum arg0,  GLenum arg1,  GLenum arg2) {
+    CALL_GL_API(glStencilOp, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glScissor)(GLint arg0,  GLint arg1,  GLsizei arg2,  GLsizei arg3) {
+    CALL_GL_API(glScissor, arg0, arg1, arg2, arg3);
+}
+
+void API_ENTRY(glHint)(GLenum arg0,  GLenum arg1) {
+    CALL_GL_API(glHint, arg0, arg1);
+}
+
+void API_ENTRY(glLineWidth)(GLfloat arg0) {
+    CALL_GL_API(glLineWidth, arg0);
+}
+
+void API_ENTRY(glLineWidthx)(GLfixed arg0) {
+    CALL_GL_API(glLineWidthx, arg0);
+}
+
+void API_ENTRY(glShadeModel)(GLenum arg0) {
+    CALL_GL_API(glShadeModel, arg0);
+}
+
+void API_ENTRY(glLightModelf)(GLenum arg0,  GLfloat arg1) {
+    CALL_GL_API(glLightModelf, arg0, arg1);
+}
+
+void API_ENTRY(glLightModelfv)(GLenum arg0,  const GLfloat * arg1) {
+    CALL_GL_API(glLightModelfv, arg0, arg1);
+}
+
+void API_ENTRY(glLightModelx)(GLenum arg0,  GLfixed arg1) {
+    CALL_GL_API(glLightModelx, arg0, arg1);
+}
+
+void API_ENTRY(glLightModelxv)(GLenum arg0,  const GLfixed * arg1) {
+    CALL_GL_API(glLightModelxv, arg0, arg1);
+}
+
+void API_ENTRY(glLightf)(GLenum arg0,  GLenum arg1,  GLfloat arg2) {
+    CALL_GL_API(glLightf, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glLightfv)(GLenum arg0,  GLenum arg1,  const GLfloat * arg2) {
+    CALL_GL_API(glLightfv, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glLightx)(GLenum arg0,  GLenum arg1,  GLfixed arg2) {
+    CALL_GL_API(glLightx, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glLightxv)(GLenum arg0,  GLenum arg1,  const GLfixed * arg2) {
+    CALL_GL_API(glLightxv, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glMaterialf)(GLenum arg0,  GLenum arg1,  GLfloat arg2) {
+    CALL_GL_API(glMaterialf, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glMaterialfv)(GLenum arg0,  GLenum arg1,  const GLfloat * arg2) {
+    CALL_GL_API(glMaterialfv, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glMaterialx)(GLenum arg0,  GLenum arg1,  GLfixed arg2) {
+    CALL_GL_API(glMaterialx, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glMaterialxv)(GLenum arg0,  GLenum arg1,  const GLfixed * arg2) {
+    CALL_GL_API(glMaterialxv, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glFogf)(GLenum arg0,  GLfloat arg1) {
+    CALL_GL_API(glFogf, arg0, arg1);
+}
+
+void API_ENTRY(glFogfv)(GLenum arg0,  const GLfloat * arg1) {
+    CALL_GL_API(glFogfv, arg0, arg1);
+}
+
+void API_ENTRY(glFogx)(GLenum arg0,  GLfixed arg1) {
+    CALL_GL_API(glFogx, arg0, arg1);
+}
+
+void API_ENTRY(glFogxv)(GLenum arg0,  const GLfixed * arg1) {
+    CALL_GL_API(glFogxv, arg0, arg1);
+}
+
+void API_ENTRY(glVertexPointer)(GLint arg0,  GLenum arg1,  GLsizei arg2,  const GLvoid * arg3) {
+    CALL_GL_API(glVertexPointer, arg0, arg1, arg2, arg3);
+}
+
+void API_ENTRY(glColorPointer)(GLint arg0,  GLenum arg1,  GLsizei arg2,  const GLvoid * arg3) {
+    CALL_GL_API(glColorPointer, arg0, arg1, arg2, arg3);
+}
+
+void API_ENTRY(glNormalPointer)(GLenum arg0,  GLsizei arg1,  const GLvoid * arg2) {
+    CALL_GL_API(glNormalPointer, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glTexCoordPointer)(GLint arg0,  GLenum arg1,  GLsizei arg2,  const GLvoid * arg3) {
+    CALL_GL_API(glTexCoordPointer, arg0, arg1, arg2, arg3);
+}
+
+void API_ENTRY(glEnableClientState)(GLenum arg0) {
+    CALL_GL_API(glEnableClientState, arg0);
+}
+
+void API_ENTRY(glDisableClientState)(GLenum arg0) {
+    CALL_GL_API(glDisableClientState, arg0);
+}
+
+void API_ENTRY(glClientActiveTexture)(GLenum arg0) {
+    CALL_GL_API(glClientActiveTexture, arg0);
+}
+
+void API_ENTRY(glDrawArrays)(GLenum arg0,  GLint arg1,  GLsizei arg2) {
+    CALL_GL_API(glDrawArrays, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glDrawElements)(GLenum arg0,  GLsizei arg1,  GLenum arg2,  const GLvoid * arg3) {
+    CALL_GL_API(glDrawElements, arg0, arg1, arg2, arg3);
 }
 
 void API_ENTRY(glLoadIdentity)(void) {
     CALL_GL_API(glLoadIdentity);
 }
 
-void API_ENTRY(glLoadMatrixf)(const GLfloat *m) {
-    CALL_GL_API(glLoadMatrixf, m);
+void API_ENTRY(glLoadMatrixf)(const GLfloat* arg0) {
+    CALL_GL_API(glLoadMatrixf, arg0);
 }
 
-void API_ENTRY(glLoadMatrixx)(const GLfixed *m) {
-    CALL_GL_API(glLoadMatrixx, m);
+void API_ENTRY(glLoadMatrixx)(const GLfixed* arg0) {
+    CALL_GL_API(glLoadMatrixx, arg0);
 }
 
-void API_ENTRY(glLogicOp)(GLenum opcode) {
-    CALL_GL_API(glLogicOp, opcode);
+void API_ENTRY(glMatrixMode)(GLenum arg0) {
+    CALL_GL_API(glMatrixMode, arg0);
 }
 
-void API_ENTRY(glMaterialf)(GLenum face, GLenum pname, GLfloat param) {
-    CALL_GL_API(glMaterialf, face, pname, param);
+void API_ENTRY(glMultMatrixf)(const GLfloat* arg0) {
+    CALL_GL_API(glMultMatrixf, arg0);
 }
 
-void API_ENTRY(glMaterialfv)(GLenum face, GLenum pname, const GLfloat *params) {
-    CALL_GL_API(glMaterialfv, face, pname, params);
-}
-
-void API_ENTRY(glMaterialx)(GLenum face, GLenum pname, GLfixed param) {
-    CALL_GL_API(glMaterialx, face, pname, param);
-}
-
-void API_ENTRY(glMaterialxv)(GLenum face, GLenum pname, const GLfixed *params) {
-    CALL_GL_API(glMaterialxv, face, pname, params);
-}
-
-void API_ENTRY(glMatrixMode)(GLenum mode) {
-    CALL_GL_API(glMatrixMode, mode);
-}
-
-void API_ENTRY(glMultMatrixf)(const GLfloat *m) {
-    CALL_GL_API(glMultMatrixf, m);
-}
-
-void API_ENTRY(glMultMatrixx)(const GLfixed *m) {
-    CALL_GL_API(glMultMatrixx, m);
-}
-
-void API_ENTRY(glMultiTexCoord4f)(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {
-    CALL_GL_API(glMultiTexCoord4f, target, s, t, r, q);
-}
-
-void API_ENTRY(glMultiTexCoord4x)(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q) {
-    CALL_GL_API(glMultiTexCoord4x, target, s, t, r, q);
-}
-
-void API_ENTRY(glNormal3f)(GLfloat nx, GLfloat ny, GLfloat nz) {
-    CALL_GL_API(glNormal3f, nx, ny, nz);
-}
-
-void API_ENTRY(glNormal3x)(GLfixed nx, GLfixed ny, GLfixed nz) {
-    CALL_GL_API(glNormal3x, nx, ny, nz);
-}
-
-void API_ENTRY(glNormalPointer)(GLenum type, GLsizei stride, const GLvoid *pointer) {
-    CALL_GL_API(glNormalPointer, type, stride, pointer);
-}
-
-void API_ENTRY(glOrthof)(  GLfloat left, GLfloat right,
-                GLfloat bottom, GLfloat top,
-                GLfloat zNear, GLfloat zFar) {
-    CALL_GL_API(glOrthof, left, right, bottom, top, zNear, zFar);
-}
-
-void API_ENTRY(glOrthox)(  GLfixed left, GLfixed right,
-                GLfixed bottom, GLfixed top,
-                GLfixed zNear, GLfixed zFar) {
-    CALL_GL_API(glOrthox, left, right, bottom, top, zNear, zFar);
-}
-
-void API_ENTRY(glPixelStorei)(GLenum pname, GLint param) {
-    CALL_GL_API(glPixelStorei, pname, param);
-}
-
-void API_ENTRY(glPointSize)(GLfloat size) {
-    CALL_GL_API(glPointSize, size);
-}
-
-void API_ENTRY(glPointSizex)(GLfixed size) {
-    CALL_GL_API(glPointSizex, size);
-}
-
-void API_ENTRY(glPolygonOffset)(GLfloat factor, GLfloat units) {
-    CALL_GL_API(glPolygonOffset, factor, units);
-}
-
-void API_ENTRY(glPolygonOffsetx)(GLfixed factor, GLfixed units) {
-    CALL_GL_API(glPolygonOffsetx, factor, units);
+void API_ENTRY(glMultMatrixx)(const GLfixed* arg0) {
+    CALL_GL_API(glMultMatrixx, arg0);
 }
 
 void API_ENTRY(glPopMatrix)(void) {
@@ -345,262 +298,463 @@
     CALL_GL_API(glPushMatrix);
 }
 
-void API_ENTRY(glReadPixels)(  GLint x, GLint y, GLsizei width, GLsizei height,
-                    GLenum format, GLenum type, GLvoid *pixels) {
-    CALL_GL_API(glReadPixels, x, y, width, height, format, type, pixels);
+void API_ENTRY(glFrustumf)(GLfloat arg0,  GLfloat arg1,  GLfloat arg2,  GLfloat arg3,  GLfloat arg4,  GLfloat arg5) {
+    CALL_GL_API(glFrustumf, arg0, arg1, arg2, arg3, arg4, arg5);
 }
 
-void API_ENTRY(glRotatef)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
-    CALL_GL_API(glRotatef, angle, x, y, z);
+void API_ENTRY(glFrustumx)(GLfixed arg0,  GLfixed arg1,  GLfixed arg2,  GLfixed arg3,  GLfixed arg4,  GLfixed arg5) {
+    CALL_GL_API(glFrustumx, arg0, arg1, arg2, arg3, arg4, arg5);
 }
 
-void API_ENTRY(glRotatex)(GLfixed angle, GLfixed x, GLfixed y, GLfixed z) {
-    CALL_GL_API(glRotatex, angle, x, y, z);
+void API_ENTRY(glOrthof)(GLfloat arg0,  GLfloat arg1,  GLfloat arg2,  GLfloat arg3,  GLfloat arg4,  GLfloat arg5) {
+    CALL_GL_API(glOrthof, arg0, arg1, arg2, arg3, arg4, arg5);
 }
 
-void API_ENTRY(glSampleCoverage)(GLclampf value, GLboolean invert) {
-    CALL_GL_API(glSampleCoverage, value, invert);
+void API_ENTRY(glOrthox)(GLfixed arg0,  GLfixed arg1,  GLfixed arg2,  GLfixed arg3,  GLfixed arg4,  GLfixed arg5) {
+    CALL_GL_API(glOrthox, arg0, arg1, arg2, arg3, arg4, arg5);
 }
 
-void API_ENTRY(glSampleCoveragex)(GLclampx value, GLboolean invert) {
-    CALL_GL_API(glSampleCoveragex, value, invert);
+void API_ENTRY(glRotatef)(GLfloat arg0,  GLfloat arg1,  GLfloat arg2,  GLfloat arg3) {
+    CALL_GL_API(glRotatef, arg0, arg1, arg2, arg3);
 }
 
-void API_ENTRY(glScalef)(GLfloat x, GLfloat y, GLfloat z) {
-    CALL_GL_API(glScalef, x, y, z);
+void API_ENTRY(glRotatex)(GLfixed arg0,  GLfixed arg1,  GLfixed arg2,  GLfixed arg3) {
+    CALL_GL_API(glRotatex, arg0, arg1, arg2, arg3);
 }
 
-void API_ENTRY(glScalex)(GLfixed x, GLfixed y, GLfixed z) {
-    CALL_GL_API(glScalex, x, y, z);
+void API_ENTRY(glScalef)(GLfloat arg0,  GLfloat arg1,  GLfloat arg2) {
+    CALL_GL_API(glScalef, arg0, arg1, arg2);
 }
 
-void API_ENTRY(glScissor)(GLint x, GLint y, GLsizei width, GLsizei height) {
-    CALL_GL_API(glScissor, x, y, width, height);
+void API_ENTRY(glScalex)(GLfixed arg0,  GLfixed arg1,  GLfixed arg2) {
+    CALL_GL_API(glScalex, arg0, arg1, arg2);
 }
 
-void API_ENTRY(glShadeModel)(GLenum mode) {
-    CALL_GL_API(glShadeModel, mode);
+void API_ENTRY(glTranslatef)(GLfloat arg0,  GLfloat arg1,  GLfloat arg2) {
+    CALL_GL_API(glTranslatef, arg0, arg1, arg2);
 }
 
-void API_ENTRY(glStencilFunc)(GLenum func, GLint ref, GLuint mask) {
-    CALL_GL_API(glStencilFunc, func, ref, mask);
+void API_ENTRY(glTranslatex)(GLfixed arg0,  GLfixed arg1,  GLfixed arg2) {
+    CALL_GL_API(glTranslatex, arg0, arg1, arg2);
 }
 
-void API_ENTRY(glStencilMask)(GLuint mask) {
-    CALL_GL_API(glStencilMask, mask);
+void API_ENTRY(glViewport)(GLint arg0,  GLint arg1,  GLsizei arg2,  GLsizei arg3) {
+    CALL_GL_API(glViewport, arg0, arg1, arg2, arg3);
 }
 
-void API_ENTRY(glStencilOp)(GLenum fail, GLenum zfail, GLenum zpass) {
-    CALL_GL_API(glStencilOp, fail, zfail, zpass);
+void API_ENTRY(glActiveTexture)(GLenum arg0) {
+    CALL_GL_API(glActiveTexture, arg0);
 }
 
-void API_ENTRY(glTexCoordPointer)( GLint size, GLenum type,
-                        GLsizei stride, const GLvoid *pointer) {
-    CALL_GL_API(glTexCoordPointer, size, type, stride, pointer);
+void API_ENTRY(glBindTexture)(GLenum arg0,  GLuint arg1) {
+    CALL_GL_API(glBindTexture, arg0, arg1);
 }
 
-void API_ENTRY(glTexEnvf)(GLenum target, GLenum pname, GLfloat param) {
-    CALL_GL_API(glTexEnvf, target, pname, param);
+void API_ENTRY(glGenTextures)(GLsizei arg0,  GLuint* arg1) {
+    CALL_GL_API(glGenTextures, arg0, arg1);
 }
 
-void API_ENTRY(glTexEnvfv)(GLenum target, GLenum pname, const GLfloat *params) {
-    CALL_GL_API(glTexEnvfv, target, pname, params);
+void API_ENTRY(glDeleteTextures)(GLsizei arg0,  const GLuint * arg1) {
+    CALL_GL_API(glDeleteTextures, arg0, arg1);
 }
 
-void API_ENTRY(glTexEnvx)(GLenum target, GLenum pname, GLfixed param) {
-    CALL_GL_API(glTexEnvx, target, pname, param);
+void API_ENTRY(glMultiTexCoord4f)(GLenum arg0,  GLfloat arg1,  GLfloat arg2,  GLfloat arg3,  GLfloat arg4) {
+    CALL_GL_API(glMultiTexCoord4f, arg0, arg1, arg2, arg3, arg4);
 }
 
-void API_ENTRY(glTexEnvxv)(GLenum target, GLenum pname, const GLfixed *params) {
-    CALL_GL_API(glTexEnvxv, target, pname, params);
+void API_ENTRY(glMultiTexCoord4x)(GLenum arg0,  GLfixed arg1,  GLfixed arg2,  GLfixed arg3,  GLfixed arg4) {
+    CALL_GL_API(glMultiTexCoord4x, arg0, arg1, arg2, arg3, arg4);
 }
 
-void API_ENTRY(glTexImage2D)(  GLenum target, GLint level, GLint internalformat,
-                    GLsizei width, GLsizei height, GLint border, GLenum format,
-                    GLenum type, const GLvoid *pixels) {
-    CALL_GL_API(glTexImage2D, target, level, internalformat, width, height,
-            border, format, type, pixels);
+void API_ENTRY(glPixelStorei)(GLenum arg0,  GLint arg1) {
+    CALL_GL_API(glPixelStorei, arg0, arg1);
 }
 
-void API_ENTRY(glTexParameterf)(GLenum target, GLenum pname, GLfloat param) {
-    CALL_GL_API(glTexParameterf, target, pname, param);
+void API_ENTRY(glTexEnvf)(GLenum arg0,  GLenum arg1,  GLfloat arg2) {
+    CALL_GL_API(glTexEnvf, arg0, arg1, arg2);
 }
 
-void API_ENTRY(glTexParameterx)(GLenum target, GLenum pname, GLfixed param) {
-    CALL_GL_API(glTexParameterx, target, pname, param);
+void API_ENTRY(glTexEnvfv)(GLenum arg0,  GLenum arg1,  const GLfloat* arg2) {
+    CALL_GL_API(glTexEnvfv, arg0, arg1, arg2);
 }
 
-void API_ENTRY(glTexSubImage2D)(   GLenum target, GLint level, GLint xoffset,
-                        GLint yoffset, GLsizei width, GLsizei height,
-                        GLenum format, GLenum type, const GLvoid *pixels) {
-    CALL_GL_API(glTexSubImage2D, target, level, xoffset, yoffset,
-            width, height, format, type, pixels);
+void API_ENTRY(glTexEnvx)(GLenum arg0,  GLenum arg1,  GLfixed arg2) {
+    CALL_GL_API(glTexEnvx, arg0, arg1, arg2);
 }
 
-void API_ENTRY(glTranslatef)(GLfloat x, GLfloat y, GLfloat z) {
-    CALL_GL_API(glTranslatef, x, y, z);
+void API_ENTRY(glTexEnvxv)(GLenum arg0,  GLenum arg1,  const GLfixed* arg2) {
+    CALL_GL_API(glTexEnvxv, arg0, arg1, arg2);
 }
 
-void API_ENTRY(glTranslatex)(GLfixed x, GLfixed y, GLfixed z) {
-    CALL_GL_API(glTranslatex, x, y, z);
+void API_ENTRY(glTexParameterf)(GLenum arg0,  GLenum arg1,  GLfloat arg2) {
+    CALL_GL_API(glTexParameterf, arg0, arg1, arg2);
 }
 
-void API_ENTRY(glVertexPointer)(   GLint size, GLenum type,
-                        GLsizei stride, const GLvoid *pointer) {
-    CALL_GL_API(glVertexPointer, size, type, stride, pointer);
+void API_ENTRY(glTexParameterx)(GLenum arg0,  GLenum arg1,  GLfixed arg2) {
+    CALL_GL_API(glTexParameterx, arg0, arg1, arg2);
 }
 
-void API_ENTRY(glViewport)(GLint x, GLint y, GLsizei width, GLsizei height) {
-    CALL_GL_API(glViewport, x, y, width, height);
+void API_ENTRY(glCompressedTexImage2D)(GLenum arg0,  GLint arg1,  GLenum arg2,  GLsizei arg3,  GLsizei arg4,  GLint arg5,  GLsizei arg6,  const GLvoid* arg7) {
+    CALL_GL_API(glCompressedTexImage2D, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
 }
 
-// ES 1.1
-void API_ENTRY(glClipPlanef)(GLenum plane, const GLfloat *equation) {
-    CALL_GL_API(glClipPlanef, plane, equation);
-}
-void API_ENTRY(glClipPlanex)(GLenum plane, const GLfixed *equation) {
-    CALL_GL_API(glClipPlanex, plane, equation);
-}
-void API_ENTRY(glBindBuffer)(GLenum target, GLuint buffer) {
-    CALL_GL_API(glBindBuffer, target, buffer);
-}
-void API_ENTRY(glBufferData)(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) {
-    CALL_GL_API(glBufferData, target, size, data, usage);
-}
-void API_ENTRY(glBufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) {
-    CALL_GL_API(glBufferSubData, target, offset, size, data);
-}
-void API_ENTRY(glDeleteBuffers)(GLsizei n, const GLuint* buffers) {
-    CALL_GL_API(glDeleteBuffers, n, buffers);
-}
-void API_ENTRY(glGenBuffers)(GLsizei n, GLuint* buffers) {
-    CALL_GL_API(glGenBuffers, n, buffers);
-}
-void API_ENTRY(glGetBooleanv)(GLenum pname, GLboolean *params) {
-    CALL_GL_API(glGetBooleanv, pname, params);
-}
-void API_ENTRY(glGetFixedv)(GLenum pname, GLfixed *params) {
-    CALL_GL_API(glGetFixedv, pname, params);
-}
-void API_ENTRY(glGetFloatv)(GLenum pname, GLfloat *params) {
-    CALL_GL_API(glGetFloatv, pname, params);
-}
-void API_ENTRY(glGetPointerv)(GLenum pname, void **params) {
-    CALL_GL_API(glGetPointerv, pname, params);
-}
-void API_ENTRY(glGetBufferParameteriv)(GLenum target, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetBufferParameteriv, target, pname, params);
-}
-void API_ENTRY(glGetClipPlanef)(GLenum pname, GLfloat eqn[4]) {
-    CALL_GL_API(glGetClipPlanef, pname, eqn);
-}
-void API_ENTRY(glGetClipPlanex)(GLenum pname, GLfixed eqn[4]) {
-    CALL_GL_API(glGetClipPlanex, pname, eqn);
-}
-void API_ENTRY(glGetLightxv)(GLenum light, GLenum pname, GLfixed *params) {
-    CALL_GL_API(glGetLightxv, light, pname, params);
-}
-void API_ENTRY(glGetLightfv)(GLenum light, GLenum pname, GLfloat *params) {
-    CALL_GL_API(glGetLightfv, light, pname, params);
-}
-void API_ENTRY(glGetMaterialxv)(GLenum face, GLenum pname, GLfixed *params) {
-    CALL_GL_API(glGetMaterialxv, face, pname, params);
-}
-void API_ENTRY(glGetMaterialfv)(GLenum face, GLenum pname, GLfloat *params) {
-    CALL_GL_API(glGetMaterialfv, face, pname, params);
-}
-void API_ENTRY(glGetTexEnvfv)(GLenum env, GLenum pname, GLfloat *params) {
-    CALL_GL_API(glGetTexEnvfv, env, pname, params);
-}
-void API_ENTRY(glGetTexEnviv)(GLenum env, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetTexEnviv, env, pname, params);
-}
-void API_ENTRY(glGetTexEnvxv)(GLenum env, GLenum pname, GLfixed *params) {
-    CALL_GL_API(glGetTexEnvxv, env, pname, params);
-}
-void API_ENTRY(glGetTexParameterfv)(GLenum target, GLenum pname, GLfloat *params) {
-    CALL_GL_API(glGetTexParameterfv, target, pname, params);
-}
-void API_ENTRY(glGetTexParameteriv)(GLenum target, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetTexParameteriv, target, pname, params);
-}
-void API_ENTRY(glGetTexParameterxv)(GLenum target, GLenum pname, GLfixed *params) {
-    CALL_GL_API(glGetTexParameterxv, target, pname, params);
-}
-GLboolean API_ENTRY(glIsBuffer)(GLuint buffer) {
-    CALL_GL_API_RETURN(glIsBuffer, buffer);
-}
-GLboolean API_ENTRY(glIsEnabled)(GLenum cap) {
-    CALL_GL_API_RETURN(glIsEnabled, cap);
-}
-GLboolean API_ENTRY(glIsTexture)(GLuint texture) {
-    CALL_GL_API_RETURN(glIsTexture, texture);
-}
-void API_ENTRY(glPointParameterf)(GLenum pname, GLfloat param) {
-    CALL_GL_API(glPointParameterf, pname, param);
-}
-void API_ENTRY(glPointParameterfv)(GLenum pname, const GLfloat *params) {
-    CALL_GL_API(glPointParameterfv, pname, params);
-}
-void API_ENTRY(glPointParameterx)(GLenum pname, GLfixed param) {
-    CALL_GL_API(glPointParameterx, pname, param);
-}
-void API_ENTRY(glPointParameterxv)(GLenum pname, const GLfixed *params) {
-    CALL_GL_API(glPointParameterxv, pname, params);
-}
-void API_ENTRY(glColor4ub)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) {
-    CALL_GL_API(glColor4ub, red, green, blue, alpha);
-}
-void API_ENTRY(glTexEnvi)(GLenum target, GLenum pname, GLint param) {
-    CALL_GL_API(glTexEnvi, target, pname, param);
-}
-void API_ENTRY(glTexEnviv)(GLenum target, GLenum pname, const GLint *params) {
-    CALL_GL_API(glTexEnviv, target, pname, params);
+void API_ENTRY(glCompressedTexSubImage2D)(GLenum arg0,  GLint arg1,  GLint arg2,  GLint arg3,  GLsizei arg4,  GLsizei arg5,  GLenum arg6,  GLsizei arg7,  const GLvoid* arg8) {
+    CALL_GL_API(glCompressedTexSubImage2D, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
 }
 
-void API_ENTRY(glTexParameterfv)(GLenum target, GLenum pname, const GLfloat *params) {
-    CALL_GL_API(glTexParameterfv, target, pname, params);
+void API_ENTRY(glCopyTexImage2D)(GLenum arg0,  GLint arg1,  GLenum arg2,  GLint arg3,  GLint arg4,  GLsizei arg5,  GLsizei arg6,  GLint arg7) {
+    CALL_GL_API(glCopyTexImage2D, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
 }
 
-void API_ENTRY(glTexParameteriv)(GLenum target, GLenum pname, const GLint *params) {
-    CALL_GL_API(glTexParameteriv, target, pname, params);
+void API_ENTRY(glCopyTexSubImage2D)(GLenum arg0,  GLint arg1,  GLint arg2,  GLint arg3,  GLint arg4,  GLint arg5,  GLsizei arg6,  GLsizei arg7) {
+    CALL_GL_API(glCopyTexSubImage2D, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
 }
 
-void API_ENTRY(glTexParameteri)(GLenum target, GLenum pname, GLint param) {
-    CALL_GL_API(glTexParameteri, target, pname, param);
-}
-void API_ENTRY(glTexParameterxv)(GLenum target, GLenum pname, const GLfixed *params) {
-    CALL_GL_API(glTexParameterxv, target, pname, params);
-}
-void API_ENTRY(glPointSizePointerOES)(GLenum type, GLsizei stride, const GLvoid *pointer) {
-    CALL_GL_API(glPointSizePointerOES, type, stride, pointer);
+void API_ENTRY(glTexImage2D)(GLenum arg0,  GLint arg1,  GLint arg2,  GLsizei arg3,  GLsizei arg4,  GLint arg5,  GLenum arg6,  GLenum arg7,  const GLvoid* arg8) {
+    CALL_GL_API(glTexImage2D, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
 }
 
-// Extensions
-void API_ENTRY(glDrawTexsOES)(GLshort x , GLshort y, GLshort z, GLshort w, GLshort h) {
-    CALL_GL_API(glDrawTexsOES, x, y, z, w, h);
+void API_ENTRY(glTexSubImage2D)(GLenum arg0,  GLint arg1,  GLint arg2,  GLint arg3,  GLsizei arg4,  GLsizei arg5,  GLenum arg6,  GLenum arg7,  const GLvoid* arg8) {
+    CALL_GL_API(glTexSubImage2D, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
 }
-void API_ENTRY(glDrawTexiOES)(GLint x, GLint y, GLint z, GLint w, GLint h) {
-    CALL_GL_API(glDrawTexiOES, x, y, z, w, h);
+
+void API_ENTRY(glReadPixels)(GLint arg0,  GLint arg1,  GLsizei arg2,  GLsizei arg3,  GLenum arg4,  GLenum arg5,  GLvoid * arg6) {
+    CALL_GL_API(glReadPixels, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
 }
-void API_ENTRY(glDrawTexfOES)(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h) {
-    CALL_GL_API(glDrawTexfOES, x, y, z, w, h);
+
+void API_ENTRY(glClipPlanef)(GLenum arg0,  const GLfloat* arg1) {
+    CALL_GL_API(glClipPlanef, arg0, arg1);
 }
-void API_ENTRY(glDrawTexxOES)(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h) {
-    CALL_GL_API(glDrawTexxOES, x, y, z, w, h);
+
+void API_ENTRY(glClipPlanex)(GLenum arg0,  const GLfixed* arg1) {
+    CALL_GL_API(glClipPlanex, arg0, arg1);
 }
-void API_ENTRY(glDrawTexsvOES)(const GLshort* coords) {
-    CALL_GL_API(glDrawTexsvOES, coords);
+
+void API_ENTRY(glBindBuffer)(GLenum arg0,  GLuint arg1) {
+    CALL_GL_API(glBindBuffer, arg0, arg1);
 }
-void API_ENTRY(glDrawTexivOES)(const GLint* coords) {
-    CALL_GL_API(glDrawTexivOES, coords);
+
+void API_ENTRY(glBufferData)(GLenum arg0,  GLsizeiptr arg1,  const GLvoid* arg2,  GLenum arg3) {
+    CALL_GL_API(glBufferData, arg0, arg1, arg2, arg3);
 }
-void API_ENTRY(glDrawTexfvOES)(const GLfloat* coords) {
-    CALL_GL_API(glDrawTexfvOES, coords);
+
+void API_ENTRY(glBufferSubData)(GLenum arg0,  GLintptr arg1,  GLsizeiptr arg2,  const GLvoid* arg3) {
+    CALL_GL_API(glBufferSubData, arg0, arg1, arg2, arg3);
 }
-void API_ENTRY(glDrawTexxvOES)(const GLfixed* coords) {
-    CALL_GL_API(glDrawTexxvOES, coords);
+
+void API_ENTRY(glDeleteBuffers)(GLsizei arg0,  const GLuint* arg1) {
+    CALL_GL_API(glDeleteBuffers, arg0, arg1);
 }
-GLbitfield API_ENTRY(glQueryMatrixxOES)(GLfixed* mantissa, GLint* exponent) {
-    CALL_GL_API_RETURN(glQueryMatrixxOES, mantissa, exponent);
+
+void API_ENTRY(glGenBuffers)(GLsizei arg0,  GLuint* arg1) {
+    CALL_GL_API(glGenBuffers, arg0, arg1);
 }
+
+void API_ENTRY(glGetBooleanv)(GLenum arg0,  GLboolean * arg1) {
+    CALL_GL_API(glGetBooleanv, arg0, arg1);
+}
+
+void API_ENTRY(glGetFixedv)(GLenum arg0,  GLfixed * arg1) {
+    CALL_GL_API(glGetFixedv, arg0, arg1);
+}
+
+void API_ENTRY(glGetFloatv)(GLenum arg0,  GLfloat * arg1) {
+    CALL_GL_API(glGetFloatv, arg0, arg1);
+}
+
+void API_ENTRY(glGetPointerv)(GLenum arg0,  void ** arg1) {
+    CALL_GL_API(glGetPointerv, arg0, arg1);
+}
+
+void API_ENTRY(glGetBufferParameteriv)(GLenum arg0,  GLenum arg1,  GLint * arg2) {
+    CALL_GL_API(glGetBufferParameteriv, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glGetClipPlanef)(GLenum arg0,  GLfloat arg1[4]) {
+    CALL_GL_API(glGetClipPlanef, arg0, arg1);
+}
+
+void API_ENTRY(glGetClipPlanex)(GLenum arg0,  GLfixed arg1[4]) {
+    CALL_GL_API(glGetClipPlanex, arg0, arg1);
+}
+
+void API_ENTRY(glGetLightxv)(GLenum arg0,  GLenum arg1,  GLfixed * arg2) {
+    CALL_GL_API(glGetLightxv, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glGetLightfv)(GLenum arg0,  GLenum arg1,  GLfloat * arg2) {
+    CALL_GL_API(glGetLightfv, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glGetMaterialxv)(GLenum arg0,  GLenum arg1,  GLfixed * arg2) {
+    CALL_GL_API(glGetMaterialxv, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glGetMaterialfv)(GLenum arg0,  GLenum arg1,  GLfloat * arg2) {
+    CALL_GL_API(glGetMaterialfv, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glGetTexEnvfv)(GLenum arg0,  GLenum arg1,  GLfloat * arg2) {
+    CALL_GL_API(glGetTexEnvfv, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glGetTexEnviv)(GLenum arg0,  GLenum arg1,  GLint * arg2) {
+    CALL_GL_API(glGetTexEnviv, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glGetTexEnvxv)(GLenum arg0,  GLenum arg1,  GLfixed * arg2) {
+    CALL_GL_API(glGetTexEnvxv, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glGetTexParameterfv)(GLenum arg0,  GLenum arg1,  GLfloat * arg2) {
+    CALL_GL_API(glGetTexParameterfv, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glGetTexParameteriv)(GLenum arg0,  GLenum arg1,  GLint * arg2) {
+    CALL_GL_API(glGetTexParameteriv, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glGetTexParameterxv)(GLenum arg0,  GLenum arg1,  GLfixed * arg2) {
+    CALL_GL_API(glGetTexParameterxv, arg0, arg1, arg2);
+}
+
+GLboolean API_ENTRY(glIsBuffer)(GLuint arg0) {
+    CALL_GL_API_RETURN(glIsBuffer, arg0);
+}
+
+GLboolean API_ENTRY(glIsEnabled)(GLenum arg0) {
+    CALL_GL_API_RETURN(glIsEnabled, arg0);
+}
+
+GLboolean API_ENTRY(glIsTexture)(GLuint arg0) {
+    CALL_GL_API_RETURN(glIsTexture, arg0);
+}
+
+void API_ENTRY(glPointParameterf)(GLenum arg0,  GLfloat arg1) {
+    CALL_GL_API(glPointParameterf, arg0, arg1);
+}
+
+void API_ENTRY(glPointParameterfv)(GLenum arg0,  const GLfloat * arg1) {
+    CALL_GL_API(glPointParameterfv, arg0, arg1);
+}
+
+void API_ENTRY(glPointParameterx)(GLenum arg0,  GLfixed arg1) {
+    CALL_GL_API(glPointParameterx, arg0, arg1);
+}
+
+void API_ENTRY(glPointParameterxv)(GLenum arg0,  const GLfixed * arg1) {
+    CALL_GL_API(glPointParameterxv, arg0, arg1);
+}
+
+void API_ENTRY(glColor4ub)(GLubyte arg0,  GLubyte arg1,  GLubyte arg2,  GLubyte arg3) {
+    CALL_GL_API(glColor4ub, arg0, arg1, arg2, arg3);
+}
+
+void API_ENTRY(glTexEnvi)(GLenum arg0,  GLenum arg1,  GLint arg2) {
+    CALL_GL_API(glTexEnvi, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glTexEnviv)(GLenum arg0,  GLenum arg1,  const GLint * arg2) {
+    CALL_GL_API(glTexEnviv, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glTexParameterfv)(GLenum arg0,  GLenum arg1,  const GLfloat * arg2) {
+    CALL_GL_API(glTexParameterfv, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glTexParameteriv)(GLenum arg0,  GLenum arg1,  const GLint * arg2) {
+    CALL_GL_API(glTexParameteriv, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glTexParameteri)(GLenum arg0,  GLenum arg1,  GLint arg2) {
+    CALL_GL_API(glTexParameteri, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glTexParameterxv)(GLenum arg0,  GLenum arg1,  const GLfixed * arg2) {
+    CALL_GL_API(glTexParameterxv, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glPointSizePointerOES)(GLenum arg0,  GLsizei arg1,  const GLvoid* arg2) {
+    CALL_GL_API(glPointSizePointerOES, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glDrawTexsOES)(GLshort arg0,  GLshort arg1,  GLshort arg2,  GLshort arg3,  GLshort arg4) {
+    CALL_GL_API(glDrawTexsOES, arg0, arg1, arg2, arg3, arg4);
+}
+
+void API_ENTRY(glDrawTexiOES)(GLint arg0,  GLint arg1,  GLint arg2,  GLint arg3,  GLint arg4) {
+    CALL_GL_API(glDrawTexiOES, arg0, arg1, arg2, arg3, arg4);
+}
+
+void API_ENTRY(glDrawTexfOES)(GLfloat arg0,  GLfloat arg1,  GLfloat arg2,  GLfloat arg3,  GLfloat arg4) {
+    CALL_GL_API(glDrawTexfOES, arg0, arg1, arg2, arg3, arg4);
+}
+
+void API_ENTRY(glDrawTexxOES)(GLfixed arg0,  GLfixed arg1,  GLfixed arg2,  GLfixed arg3,  GLfixed arg4) {
+    CALL_GL_API(glDrawTexxOES, arg0, arg1, arg2, arg3, arg4);
+}
+
+void API_ENTRY(glDrawTexsvOES)(const GLshort* arg0) {
+    CALL_GL_API(glDrawTexsvOES, arg0);
+}
+
+void API_ENTRY(glDrawTexivOES)(const GLint* arg0) {
+    CALL_GL_API(glDrawTexivOES, arg0);
+}
+
+void API_ENTRY(glDrawTexfvOES)(const GLfloat* arg0) {
+    CALL_GL_API(glDrawTexfvOES, arg0);
+}
+
+void API_ENTRY(glDrawTexxvOES)(const GLfixed* arg0) {
+    CALL_GL_API(glDrawTexxvOES, arg0);
+}
+
+GLbitfield API_ENTRY(glQueryMatrixxOES)(GLfixed* arg0,  GLint* arg1) {
+    CALL_GL_API_RETURN(glQueryMatrixxOES, arg0, arg1);
+}
+
+void API_ENTRY(__glEGLImageTargetTexture2DOES)(GLenum arg0,  GLeglImageOES arg1) {
+    CALL_GL_API(__glEGLImageTargetTexture2DOES, arg0, arg1);
+}
+
+void API_ENTRY(__glEGLImageTargetRenderbufferStorageOES)(GLenum arg0,  GLeglImageOES arg1) {
+    CALL_GL_API(__glEGLImageTargetRenderbufferStorageOES, arg0, arg1);
+}
+
+void API_ENTRY(glBlendEquationSeparateOES)(GLenum arg0,  GLenum arg1) {
+    CALL_GL_API(glBlendEquationSeparateOES, arg0, arg1);
+}
+
+void API_ENTRY(glBlendFuncSeparateOES)(GLenum arg0,  GLenum arg1,  GLenum arg2,  GLenum arg3) {
+    CALL_GL_API(glBlendFuncSeparateOES, arg0, arg1, arg2, arg3);
+}
+
+void API_ENTRY(glBlendEquationOES)(GLenum arg0) {
+    CALL_GL_API(glBlendEquationOES, arg0);
+}
+
+GLboolean API_ENTRY(glIsRenderbufferOES)(GLuint arg0) {
+    CALL_GL_API_RETURN(glIsRenderbufferOES, arg0);
+}
+
+void API_ENTRY(glBindRenderbufferOES)(GLenum arg0,  GLuint arg1) {
+    CALL_GL_API(glBindRenderbufferOES, arg0, arg1);
+}
+
+void API_ENTRY(glDeleteRenderbuffersOES)(GLsizei arg0,  const GLuint* arg1) {
+    CALL_GL_API(glDeleteRenderbuffersOES, arg0, arg1);
+}
+
+void API_ENTRY(glGenRenderbuffersOES)(GLsizei arg0,  GLuint* arg1) {
+    CALL_GL_API(glGenRenderbuffersOES, arg0, arg1);
+}
+
+void API_ENTRY(glRenderbufferStorageOES)(GLenum arg0,  GLenum arg1,  GLsizei arg2,  GLsizei arg3) {
+    CALL_GL_API(glRenderbufferStorageOES, arg0, arg1, arg2, arg3);
+}
+
+void API_ENTRY(glGetRenderbufferParameterivOES)(GLenum arg0,  GLenum arg1,  GLint* arg2) {
+    CALL_GL_API(glGetRenderbufferParameterivOES, arg0, arg1, arg2);
+}
+
+GLboolean API_ENTRY(glIsFramebufferOES)(GLuint arg0) {
+    CALL_GL_API_RETURN(glIsFramebufferOES, arg0);
+}
+
+void API_ENTRY(glBindFramebufferOES)(GLenum arg0,  GLuint arg1) {
+    CALL_GL_API(glBindFramebufferOES, arg0, arg1);
+}
+
+void API_ENTRY(glDeleteFramebuffersOES)(GLsizei arg0,  const GLuint* arg1) {
+    CALL_GL_API(glDeleteFramebuffersOES, arg0, arg1);
+}
+
+void API_ENTRY(glGenFramebuffersOES)(GLsizei arg0,  GLuint* arg1) {
+    CALL_GL_API(glGenFramebuffersOES, arg0, arg1);
+}
+
+GLenum API_ENTRY(glCheckFramebufferStatusOES)(GLenum arg0) {
+    CALL_GL_API_RETURN(glCheckFramebufferStatusOES, arg0);
+}
+
+void API_ENTRY(glFramebufferRenderbufferOES)(GLenum arg0,  GLenum arg1,  GLenum arg2,  GLuint arg3) {
+    CALL_GL_API(glFramebufferRenderbufferOES, arg0, arg1, arg2, arg3);
+}
+
+void API_ENTRY(glFramebufferTexture2DOES)(GLenum arg0,  GLenum arg1,  GLenum arg2,  GLuint arg3,  GLint arg4) {
+    CALL_GL_API(glFramebufferTexture2DOES, arg0, arg1, arg2, arg3, arg4);
+}
+
+void API_ENTRY(glGetFramebufferAttachmentParameterivOES)(GLenum arg0,  GLenum arg1,  GLenum arg2,  GLint* arg3) {
+    CALL_GL_API(glGetFramebufferAttachmentParameterivOES, arg0, arg1, arg2, arg3);
+}
+
+void API_ENTRY(glGenerateMipmapOES)(GLenum arg0) {
+    CALL_GL_API(glGenerateMipmapOES, arg0);
+}
+
+void* API_ENTRY(glMapBufferOES)(GLenum arg0,  GLenum arg1) {
+    CALL_GL_API_RETURN(glMapBufferOES, arg0, arg1);
+}
+
+GLboolean API_ENTRY(glUnmapBufferOES)(GLenum arg0) {
+    CALL_GL_API_RETURN(glUnmapBufferOES, arg0);
+}
+
+void API_ENTRY(glGetBufferPointervOES)(GLenum arg0,  GLenum arg1,  void** arg2) {
+    CALL_GL_API(glGetBufferPointervOES, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glCurrentPaletteMatrixOES)(GLuint arg0) {
+    CALL_GL_API(glCurrentPaletteMatrixOES, arg0);
+}
+
+void API_ENTRY(glLoadPaletteFromModelViewMatrixOES)(void) {
+    CALL_GL_API(glLoadPaletteFromModelViewMatrixOES);
+}
+
+void API_ENTRY(glMatrixIndexPointerOES)(GLint arg0,  GLenum arg1,  GLsizei arg2,  const GLvoid * arg3) {
+    CALL_GL_API(glMatrixIndexPointerOES, arg0, arg1, arg2, arg3);
+}
+
+void API_ENTRY(glWeightPointerOES)(GLint arg0,  GLenum arg1,  GLsizei arg2,  const GLvoid * arg3) {
+    CALL_GL_API(glWeightPointerOES, arg0, arg1, arg2, arg3);
+}
+
+void API_ENTRY(glTexGenfOES)(GLenum arg0,  GLenum arg1,  GLfloat arg2) {
+    CALL_GL_API(glTexGenfOES, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glTexGenfvOES)(GLenum arg0,  GLenum arg1,  const GLfloat * arg2) {
+    CALL_GL_API(glTexGenfvOES, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glTexGeniOES)(GLenum arg0,  GLenum arg1,  GLint arg2) {
+    CALL_GL_API(glTexGeniOES, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glTexGenivOES)(GLenum arg0,  GLenum arg1,  const GLint * arg2) {
+    CALL_GL_API(glTexGenivOES, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glTexGenxOES)(GLenum arg0,  GLenum arg1,  GLfixed arg2) {
+    CALL_GL_API(glTexGenxOES, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glTexGenxvOES)(GLenum arg0,  GLenum arg1,  const GLfixed * arg2) {
+    CALL_GL_API(glTexGenxvOES, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glGetTexGenfvOES)(GLenum arg0,  GLenum arg1,  GLfloat * arg2) {
+    CALL_GL_API(glGetTexGenfvOES, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glGetTexGenivOES)(GLenum arg0,  GLenum arg1,  GLint * arg2) {
+    CALL_GL_API(glGetTexGenivOES, arg0, arg1, arg2);
+}
+
+void API_ENTRY(glGetTexGenxvOES)(GLenum arg0,  GLenum arg1,  GLfixed * arg2) {
+    CALL_GL_API(glGetTexGenxvOES, arg0, arg1, arg2);
+}
+
diff --git a/opengl/libs/egl_entries.in b/opengl/libs/egl_entries.in
index 33b4c65..3b4551b 100644
--- a/opengl/libs/egl_entries.in
+++ b/opengl/libs/egl_entries.in
@@ -43,3 +43,10 @@
 /* EGL 1.3 */
 
 /* EGL 1.4 */
+
+/* EGL_EGLEXT_VERSION 3 */
+
+EGL_ENTRY(EGLBoolean,  eglLockSurfaceKHR,   EGLDisplay, EGLSurface, const EGLint *)
+EGL_ENTRY(EGLBoolean,  eglUnlockSurfaceKHR, EGLDisplay, EGLSurface)
+EGL_ENTRY(EGLImageKHR, eglCreateImageKHR,   EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint *)
+EGL_ENTRY(EGLBoolean,  eglDestroyImageKHR,  EGLDisplay, EGLImageKHR)
diff --git a/opengl/libs/egl_impl.h b/opengl/libs/egl_impl.h
index 62ce3fc..4e0c7bf 100644
--- a/opengl/libs/egl_impl.h
+++ b/opengl/libs/egl_impl.h
@@ -20,6 +20,7 @@
 #include <ctype.h>
 
 #include <EGL/egl.h>
+#include <EGL/eglext.h>
 
 // ----------------------------------------------------------------------------
 namespace android {
@@ -36,6 +37,8 @@
     int                 unavailable;
 };
 
+EGLImageKHR egl_get_image_for_current_context(EGLImageKHR image);
+
 // ----------------------------------------------------------------------------
 }; // namespace android
 // ----------------------------------------------------------------------------
diff --git a/opengl/libs/gl_entries.in b/opengl/libs/gl_entries.in
index b97e8fe..4e8f828 100644
--- a/opengl/libs/gl_entries.in
+++ b/opengl/libs/gl_entries.in
@@ -15,30 +15,30 @@
 GL_ENTRY(void, glDepthMask, GLboolean)
 GL_ENTRY(void, glStencilMask, GLuint)
 GL_ENTRY(void, glDepthFunc, GLenum)
-GL_ENTRY(void, glDepthRangef, GLclampf zNear, GLclampf zFar)
-GL_ENTRY(void, glDepthRangex, GLclampx zNear, GLclampx zFar)
-GL_ENTRY(void, glPolygonOffset, GLfloat factor, GLfloat units)
-GL_ENTRY(void, glPolygonOffsetx, GLfixed factor, GLfixed units)
-GL_ENTRY(void, glLogicOp, GLenum opcode)
-GL_ENTRY(void, glAlphaFuncx, GLenum func, GLclampx ref)
-GL_ENTRY(void, glAlphaFunc, GLenum func, GLclampf ref)
-GL_ENTRY(void, glBlendFunc, GLenum sfactor, GLenum dfactor)
-GL_ENTRY(void, glClear, GLbitfield mask)
-GL_ENTRY(void, glClearColor, GLclampf r, GLclampf g, GLclampf b, GLclampf a)
-GL_ENTRY(void, glClearColorx, GLclampx r, GLclampx g, GLclampx b, GLclampx a)
-GL_ENTRY(void, glClearDepthf, GLclampf depth)
-GL_ENTRY(void, glClearDepthx, GLclampx depth)
-GL_ENTRY(void, glClearStencil, GLint s)
+GL_ENTRY(void, glDepthRangef, GLclampf, GLclampf)
+GL_ENTRY(void, glDepthRangex, GLclampx, GLclampx)
+GL_ENTRY(void, glPolygonOffset, GLfloat, GLfloat)
+GL_ENTRY(void, glPolygonOffsetx, GLfixed, GLfixed)
+GL_ENTRY(void, glLogicOp, GLenum)
+GL_ENTRY(void, glAlphaFuncx, GLenum, GLclampx)
+GL_ENTRY(void, glAlphaFunc, GLenum, GLclampf)
+GL_ENTRY(void, glBlendFunc, GLenum, GLenum)
+GL_ENTRY(void, glClear, GLbitfield)
+GL_ENTRY(void, glClearColor, GLclampf, GLclampf, GLclampf, GLclampf)
+GL_ENTRY(void, glClearColorx, GLclampx, GLclampx, GLclampx, GLclampx)
+GL_ENTRY(void, glClearDepthf, GLclampf)
+GL_ENTRY(void, glClearDepthx, GLclampx)
+GL_ENTRY(void, glClearStencil, GLint)
 GL_ENTRY(void, glPointSize, GLfloat)
 GL_ENTRY(void, glPointSizex, GLfixed)
-GL_ENTRY(void, glSampleCoverage, GLclampf value, GLboolean invert)
-GL_ENTRY(void, glSampleCoveragex, GLclampx value, GLboolean invert)
-GL_ENTRY(void, glStencilFunc, GLenum func, GLint ref, GLuint mask)
-GL_ENTRY(void, glStencilOp, GLenum fail, GLenum zfail, GLenum zpass)
-GL_ENTRY(void, glScissor, GLint x, GLint y, GLsizei width, GLsizei height)
-GL_ENTRY(void, glHint, GLenum, GLenum mode)
-GL_ENTRY(void, glLineWidth, GLfloat width)
-GL_ENTRY(void, glLineWidthx, GLfixed width)
+GL_ENTRY(void, glSampleCoverage, GLclampf, GLboolean)
+GL_ENTRY(void, glSampleCoveragex, GLclampx, GLboolean)
+GL_ENTRY(void, glStencilFunc, GLenum, GLint, GLuint)
+GL_ENTRY(void, glStencilOp, GLenum, GLenum, GLenum)
+GL_ENTRY(void, glScissor, GLint, GLint, GLsizei, GLsizei)
+GL_ENTRY(void, glHint, GLenum, GLenum)
+GL_ENTRY(void, glLineWidth, GLfloat)
+GL_ENTRY(void, glLineWidthx, GLfixed)
 GL_ENTRY(void, glShadeModel, GLenum)
 GL_ENTRY(void, glLightModelf, GLenum, GLfloat)
 GL_ENTRY(void, glLightModelfv, GLenum, const GLfloat *)
@@ -63,12 +63,12 @@
 GL_ENTRY(void, glEnableClientState, GLenum)
 GL_ENTRY(void, glDisableClientState, GLenum)
 GL_ENTRY(void, glClientActiveTexture, GLenum)
-GL_ENTRY(void, glDrawArrays, GLenum, GLint first, GLsizei)
+GL_ENTRY(void, glDrawArrays, GLenum, GLint, GLsizei)
 GL_ENTRY(void, glDrawElements, GLenum, GLsizei, GLenum, const GLvoid *)
 GL_ENTRY(void, glLoadIdentity, void)
 GL_ENTRY(void, glLoadMatrixf, const GLfloat*)
 GL_ENTRY(void, glLoadMatrixx, const GLfixed*)
-GL_ENTRY(void, glMatrixMode, GLenum mode)
+GL_ENTRY(void, glMatrixMode, GLenum)
 GL_ENTRY(void, glMultMatrixf, const GLfloat*)
 GL_ENTRY(void, glMultMatrixx, const GLfixed*)
 GL_ENTRY(void, glPopMatrix, void)
@@ -87,7 +87,7 @@
 GL_ENTRY(void, glActiveTexture, GLenum)
 GL_ENTRY(void, glBindTexture, GLenum, GLuint)
 GL_ENTRY(void, glGenTextures, GLsizei, GLuint*)
-GL_ENTRY(void, glDeleteTextures, GLsizei n, const GLuint *)
+GL_ENTRY(void, glDeleteTextures, GLsizei, const GLuint *)
 GL_ENTRY(void, glMultiTexCoord4f, GLenum, GLfloat, GLfloat, GLfloat, GLfloat)
 GL_ENTRY(void, glMultiTexCoord4x, GLenum, GLfixed, GLfixed, GLfixed, GLfixed)
 GL_ENTRY(void, glPixelStorei, GLenum, GLint)
@@ -106,8 +106,8 @@
 GL_ENTRY(void, glReadPixels, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid *)
 
 // 1.1 additions
-GL_ENTRY(void, glClipPlanef, GLenum plane, const GLfloat*)
-GL_ENTRY(void, glClipPlanex, GLenum plane, const GLfixed*)
+GL_ENTRY(void, glClipPlanef, GLenum, const GLfloat*)
+GL_ENTRY(void, glClipPlanex, GLenum, const GLfixed*)
 GL_ENTRY(void, glBindBuffer, GLenum, GLuint)
 GL_ENTRY(void, glBufferData, GLenum, GLsizeiptr, const GLvoid*, GLenum)
 GL_ENTRY(void, glBufferSubData, GLenum, GLintptr, GLsizeiptr, const GLvoid*)
@@ -144,7 +144,7 @@
 GL_ENTRY(void, glTexParameteriv, GLenum, GLenum, const GLint *)
 GL_ENTRY(void, glTexParameteri, GLenum, GLenum, GLint)
 GL_ENTRY(void, glTexParameterxv, GLenum, GLenum, const GLfixed *)
-GL_ENTRY(void, glPointSizePointerOES, GLenum type, GLsizei stride, const GLvoid*)
+GL_ENTRY(void, glPointSizePointerOES, GLenum, GLsizei, const GLvoid*)
 
 // Extensions
 GL_ENTRY(void, glDrawTexsOES, GLshort, GLshort, GLshort, GLshort, GLshort)
@@ -155,5 +155,40 @@
 GL_ENTRY(void, glDrawTexivOES, const GLint*)
 GL_ENTRY(void, glDrawTexfvOES, const GLfloat*)
 GL_ENTRY(void, glDrawTexxvOES, const GLfixed*)
-GL_ENTRY(GLbitfield, glQueryMatrixxOES, GLfixed* mantissa, GLint* exponent)
-
+GL_ENTRY(GLbitfield, glQueryMatrixxOES, GLfixed*, GLint*)
+GL_ENTRY(void, __glEGLImageTargetTexture2DOES, GLenum, GLeglImageOES)
+GL_ENTRY(void, __glEGLImageTargetRenderbufferStorageOES, GLenum, GLeglImageOES)
+GL_ENTRY(void, glBlendEquationSeparateOES, GLenum, GLenum)
+GL_ENTRY(void, glBlendFuncSeparateOES, GLenum, GLenum, GLenum, GLenum)
+GL_ENTRY(void, glBlendEquationOES, GLenum)
+GL_ENTRY(GLboolean, glIsRenderbufferOES, GLuint)
+GL_ENTRY(void, glBindRenderbufferOES, GLenum, GLuint)
+GL_ENTRY(void, glDeleteRenderbuffersOES, GLsizei, const GLuint*)
+GL_ENTRY(void, glGenRenderbuffersOES, GLsizei, GLuint*)
+GL_ENTRY(void, glRenderbufferStorageOES, GLenum, GLenum, GLsizei, GLsizei)
+GL_ENTRY(void, glGetRenderbufferParameterivOES, GLenum, GLenum, GLint*)
+GL_ENTRY(GLboolean,  glIsFramebufferOES, GLuint)
+GL_ENTRY(void, glBindFramebufferOES, GLenum, GLuint)
+GL_ENTRY(void, glDeleteFramebuffersOES, GLsizei, const GLuint*)
+GL_ENTRY(void, glGenFramebuffersOES, GLsizei, GLuint*)
+GL_ENTRY(GLenum, glCheckFramebufferStatusOES, GLenum)
+GL_ENTRY(void, glFramebufferRenderbufferOES, GLenum, GLenum, GLenum, GLuint)
+GL_ENTRY(void, glFramebufferTexture2DOES, GLenum, GLenum, GLenum, GLuint, GLint)
+GL_ENTRY(void, glGetFramebufferAttachmentParameterivOES, GLenum, GLenum, GLenum, GLint*)
+GL_ENTRY(void, glGenerateMipmapOES, GLenum)
+GL_ENTRY(void*, glMapBufferOES, GLenum, GLenum)
+GL_ENTRY(GLboolean,  glUnmapBufferOES, GLenum)
+GL_ENTRY(void, glGetBufferPointervOES, GLenum, GLenum, void**)
+GL_ENTRY(void, glCurrentPaletteMatrixOES, GLuint)
+GL_ENTRY(void, glLoadPaletteFromModelViewMatrixOES, void)
+GL_ENTRY(void, glMatrixIndexPointerOES, GLint, GLenum, GLsizei, const GLvoid *)
+GL_ENTRY(void, glWeightPointerOES, GLint, GLenum, GLsizei, const GLvoid *)
+GL_ENTRY(void, glTexGenfOES, GLenum, GLenum, GLfloat)
+GL_ENTRY(void, glTexGenfvOES, GLenum, GLenum, const GLfloat *)
+GL_ENTRY(void, glTexGeniOES, GLenum, GLenum, GLint)
+GL_ENTRY(void, glTexGenivOES, GLenum, GLenum, const GLint *)
+GL_ENTRY(void, glTexGenxOES, GLenum, GLenum, GLfixed)
+GL_ENTRY(void, glTexGenxvOES, GLenum, GLenum, const GLfixed *)
+GL_ENTRY(void, glGetTexGenfvOES, GLenum, GLenum, GLfloat *)
+GL_ENTRY(void, glGetTexGenivOES, GLenum, GLenum, GLint *)
+GL_ENTRY(void, glGetTexGenxvOES, GLenum, GLenum, GLfixed *)
diff --git a/opengl/libs/hooks.h b/opengl/libs/hooks.h
index 63fb017..392724f 100644
--- a/opengl/libs/hooks.h
+++ b/opengl/libs/hooks.h
@@ -22,9 +22,10 @@
 #include <errno.h>
 
 #include <EGL/egl.h>
+#include <EGL/eglext.h>
 #include <GLES/gl.h>
+#include <GLES/glext.h>
 
-#define GL_LOGGER                   0
 #if !defined(__arm__)
 #define USE_SLOW_BINDING            1
 #else
@@ -35,7 +36,7 @@
 #define MAX_NUMBER_OF_GL_EXTENSIONS 32
 
 
-#if defined(HAVE_ANDROID_OS) && !USE_SLOW_BINDING && !GL_LOGGER && __OPTIMIZE__
+#if defined(HAVE_ANDROID_OS) && !USE_SLOW_BINDING && __OPTIMIZE__
 #define USE_FAST_TLS_KEY            1
 #else
 #define USE_FAST_TLS_KEY            0
@@ -55,7 +56,10 @@
 enum {
     IMPL_HARDWARE = 0,
     IMPL_SOFTWARE,
-    IMPL_CONTEXT_LOST,
+    
+    IMPL_NUM_DRIVERS_IMPLEMENTATIONS,
+
+    IMPL_CONTEXT_LOST = IMPL_NUM_DRIVERS_IMPLEMENTATIONS,
     IMPL_NO_CONTEXT,
     
     IMPL_NUM_IMPLEMENTATIONS
diff --git a/opengl/libs/tools/glapigen b/opengl/libs/tools/glapigen
new file mode 100755
index 0000000..0333294
--- /dev/null
+++ b/opengl/libs/tools/glapigen
@@ -0,0 +1,51 @@
+#! /usr/bin/perl
+
+use strict;
+
+my $lineNum = 0;
+while (my $line = <>) {
+  $lineNum += 1;
+  next if $line =~ /^\//;
+  next if $line =~ /^#/;
+  next if $line =~ /^\s*$/;
+  if ($line !~ /^GL_ENTRY\(([^,]+),\s*([^,]+),\s*([^)]+)\)/) {
+    printf STDERR "Cannot parse line number $lineNum:\n$line";
+    next;
+  }
+  my $type = $1;
+  my $name = $2;
+  my $args = $3;
+
+  printf("%s API_ENTRY(%s)(", $type, $name);
+  my @args = split ',', $args;
+
+  my $len = scalar(@args);
+  for (my $num = 0; $num < $len; $num++) {
+    print ", " if $num > 0;
+    my $arg = $args[$num];
+    if ($arg =~ /([^]]+)(\[[^]]\])/) {
+      my $argtype = $1;
+      my $array = $2;
+      printf("%s arg%d%s", $argtype, $num, $array);
+    } else {
+      if ($arg eq "void") {
+        printf("void");
+      } else {
+        printf("%s arg%d", $arg, $num);
+      }
+    }
+  }
+  printf(") {\n");
+  if ($type eq "void") {
+    printf("    CALL_GL_API(%s", $name);
+  } else {
+    printf("    CALL_GL_API_RETURN(%s", $name);
+  }
+  for (my $num = 0; $num < $len; $num++) {
+    if ($args[$num] ne "void") {
+      print ", ";
+      printf("arg%d", $num);
+    }
+  }
+  printf(");\n}\n\n");
+}
diff --git a/opengl/tests/copybits/Android.mk b/opengl/tests/copybits/Android.mk
new file mode 100644
index 0000000..d5ded42
--- /dev/null
+++ b/opengl/tests/copybits/Android.mk
@@ -0,0 +1,18 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	copybits.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+    libEGL \
+    libGLESv1_CM \
+    libui
+
+LOCAL_MODULE:= test-opengl-copybits
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
+
diff --git a/opengl/tests/copybits/copybits.cpp b/opengl/tests/copybits/copybits.cpp
new file mode 100644
index 0000000..ff17cc9
--- /dev/null
+++ b/opengl/tests/copybits/copybits.cpp
@@ -0,0 +1,752 @@
+// Test software OpenGL hardware accelleration using copybits.
+
+#define LOG_TAG "copybits_test"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include <ui/PixelFormat.h>
+
+#include <cutils/log.h>
+#include <cutils/native_handle.h>
+
+#include <utils/Atomic.h>
+
+#include <private/ui/SharedState.h>
+
+#include <hardware/gralloc.h>
+#include <hardware/hardware.h>
+
+#define EGL_EGLEXT_PROTOTYPES
+#define GL_GLEXT_PROTOTYPES
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+extern "C" EGLNativeWindowType android_createDisplaySurface(void);
+
+using namespace android;
+
+EGLDisplay eglDisplay;
+EGLSurface eglSurface;
+EGLContext eglContext;
+GLuint texture;
+
+hw_module_t const* gralloc_module;
+alloc_device_t  *sAllocDev;
+
+#define FIXED_ONE 0x10000
+
+int init_gl_surface();
+void free_gl_surface();
+void init_scene();
+
+int create_physical_texture();
+int readTimer();
+
+// ===========================================================================
+// Buffer and implementation of android_native_buffer_t
+// ===========================================================================
+
+class NativeBuffer;
+
+class Buffer :  public android_native_buffer_t,
+                public LightRefBase<Buffer>
+{
+public:
+
+    // creates w * h buffer
+    Buffer(uint32_t w, uint32_t h, PixelFormat format, int usage);
+
+    // return status
+    status_t initCheck() const;
+
+
+    uint32_t getWidth() const           { return mWidth; }
+    uint32_t getHeight() const          { return mHeight; }
+    uint32_t getStride() const          { return mStride; }
+    uint32_t getUsage() const           { return mUsage; }
+    PixelFormat getPixelFormat() const  { return mFormat; }
+    buffer_handle_t getHandle() const   { return mBufferHandle; }
+
+    android_native_buffer_t* getNativeBuffer() const;
+
+    void setPixel(int x, int y, int r, int g, int b, int a);
+
+private:
+    friend class LightRefBase<Buffer>;
+    Buffer(const Buffer& rhs);
+    ~Buffer();
+    Buffer& operator = (const Buffer& rhs);
+    const Buffer& operator = (const Buffer& rhs) const;
+
+    status_t initSize(uint32_t w, uint32_t h);
+
+    static void incRef(android_native_base_t* buffer);
+    static void decRef(android_native_base_t* buffer);
+    static int getHandlePriv(android_native_buffer_t const * buffer,
+            buffer_handle_t* handle);
+
+    buffer_handle_t         mBufferHandle;
+    ssize_t                 mInitCheck;
+
+    uint32_t                mWidth;
+    uint32_t                mHeight;
+    uint32_t                mStride;
+    uint32_t                mVStride;
+    PixelFormat             mFormat;
+    void*                   mData;
+    uint32_t                mUsage;
+};
+
+Buffer::Buffer(uint32_t w, uint32_t h, PixelFormat format, int usage)
+    : mBufferHandle(0), mInitCheck(NO_INIT),
+    mWidth(0), mHeight(0), mStride(0), mVStride(0), mFormat(format), mData(0),
+    mUsage(usage)
+{
+    common.magic = ANDROID_NATIVE_BUFFER_MAGIC;
+    common.version = sizeof(android_native_buffer_t);
+    common.incRef = incRef;
+    common.decRef = decRef;
+    android_native_buffer_t::getHandle = getHandlePriv;
+    if (w>0 && h>0) {
+        mInitCheck = initSize(w, h);
+    }
+}
+
+Buffer::~Buffer()
+{
+    if (mBufferHandle) {
+
+        gralloc_module_t* mod = (gralloc_module_t*)sAllocDev->common.module;
+        mod->unmap(mod, mBufferHandle);
+
+        sAllocDev->free(sAllocDev, mBufferHandle);
+    }
+}
+
+void Buffer::incRef(android_native_base_t* buffer) {
+    Buffer* self = static_cast<Buffer*>(
+            reinterpret_cast<android_native_buffer_t *>(buffer));
+    self->incStrong(self);
+}
+
+void Buffer::decRef(android_native_base_t* buffer) {
+    Buffer* self = static_cast<Buffer*>(
+            reinterpret_cast<android_native_buffer_t *>(buffer));
+    self->decStrong(self);
+}
+
+int Buffer::getHandlePriv(android_native_buffer_t const * buffer,
+        buffer_handle_t* handle) {
+    Buffer const * self = static_cast<Buffer const *>(buffer);
+    *handle = self->getHandle();
+    return 0;
+}
+
+status_t Buffer::initCheck() const {
+    return mInitCheck;
+}
+
+android_native_buffer_t* Buffer::getNativeBuffer() const
+{
+    Buffer* that = const_cast<Buffer*>(this);
+    that->android_native_buffer_t::width = mWidth;
+    that->android_native_buffer_t::height = mHeight;
+    that->android_native_buffer_t::stride = mStride;
+    that->android_native_buffer_t::format = mFormat;
+    that->android_native_buffer_t::usage = mUsage;
+    that->android_native_buffer_t::bits = mData;
+    return static_cast<android_native_buffer_t*>(that);
+}
+
+status_t Buffer::initSize(uint32_t w, uint32_t h)
+{
+    status_t err = NO_ERROR;
+
+    int32_t stride;
+    err = sAllocDev->alloc(sAllocDev, w, h, mFormat, mUsage, &mBufferHandle, &stride);
+
+    if (err == NO_ERROR) {
+        void* addr = 0;
+        gralloc_module_t* mod = (gralloc_module_t*)sAllocDev->common.module;
+        err = mod->map(mod, mBufferHandle, &addr);
+        if (err == NO_ERROR) {
+            mData = addr;
+            mWidth  = w;
+            mHeight = h;
+            mStride = stride;
+            mVStride = 0;
+        }
+    }
+
+    return err;
+}
+
+void Buffer::setPixel(int x, int y, int r, int g, int b, int a) {
+    if (x < 0 || (unsigned int) x >= mWidth
+            || y < 0 || (unsigned int) y >= mHeight) {
+        // clipped
+        return;
+    }
+    int index = mStride * y + x;
+    switch (mFormat) {
+    case HAL_PIXEL_FORMAT_RGB_565: {
+            unsigned short val = (unsigned short) (
+                    ((0x1f & (r >> 3)) << 11)
+                    | ((0x3f & (g >> 2)) << 5)
+                    | (0x1f & (b >> 3)));
+            ((unsigned short*) mData)[index]= val;
+        }
+        break;
+    case HAL_PIXEL_FORMAT_RGBA_8888: { // ABGR
+        unsigned int val = (unsigned int)
+            (((a & 0xff) << 24)
+                    | ((b & 0xff) << 16)
+                    | ((g & 0xff) << 8)
+                    | (r & 0xff));
+            ((unsigned int*) mData)[index] = val;
+        }
+        break;
+    default:
+        // Unsupported pixel format
+        break;
+    }
+}
+
+
+static void gluLookAt(float eyeX, float eyeY, float eyeZ,
+        float centerX, float centerY, float centerZ, float upX, float upY,
+        float upZ)
+{
+    // See the OpenGL GLUT documentation for gluLookAt for a description
+    // of the algorithm. We implement it in a straightforward way:
+
+    float fx = centerX - eyeX;
+    float fy = centerY - eyeY;
+    float fz = centerZ - eyeZ;
+
+    // Normalize f
+    float rlf = 1.0f / sqrtf(fx*fx + fy*fy + fz*fz);
+    fx *= rlf;
+    fy *= rlf;
+    fz *= rlf;
+
+    // Normalize up
+    float rlup = 1.0f / sqrtf(upX*upX + upY*upY + upZ*upZ);
+    upX *= rlup;
+    upY *= rlup;
+    upZ *= rlup;
+
+    // compute s = f x up (x means "cross product")
+
+    float sx = fy * upZ - fz * upY;
+    float sy = fz * upX - fx * upZ;
+    float sz = fx * upY - fy * upX;
+
+    // compute u = s x f
+    float ux = sy * fz - sz * fy;
+    float uy = sz * fx - sx * fz;
+    float uz = sx * fy - sy * fx;
+
+    float m[16] ;
+    m[0] = sx;
+    m[1] = ux;
+    m[2] = -fx;
+    m[3] = 0.0f;
+
+    m[4] = sy;
+    m[5] = uy;
+    m[6] = -fy;
+    m[7] = 0.0f;
+
+    m[8] = sz;
+    m[9] = uz;
+    m[10] = -fz;
+    m[11] = 0.0f;
+
+    m[12] = 0.0f;
+    m[13] = 0.0f;
+    m[14] = 0.0f;
+    m[15] = 1.0f;
+
+    glMultMatrixf(m);
+    glTranslatef(-eyeX, -eyeY, -eyeZ);
+}
+
+int init_gralloc() {
+    int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &gralloc_module);
+    LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
+
+    if (err == 0) {
+        gralloc_open(gralloc_module, &sAllocDev);
+    }
+    return err;
+}
+
+int init_gl_surface(void)
+{
+    EGLint numConfigs = 1;
+    EGLConfig myConfig = {0};
+    EGLint attrib[] =
+    {
+            EGL_DEPTH_SIZE,     16,
+            EGL_NONE
+    };
+
+    printf("init_gl_surface\n");
+    if ( (eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY )
+    {
+        printf("eglGetDisplay failed\n");
+        return 0;
+    }
+
+    if ( eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE )
+    {
+        printf("eglInitialize failed\n");
+        return 0;
+    }
+
+    if ( eglChooseConfig(eglDisplay, attrib, &myConfig, 1, &numConfigs) != EGL_TRUE )
+    {
+        printf("eglChooseConfig failed\n");
+        return 0;
+    }
+
+    if ( (eglSurface = eglCreateWindowSurface(eglDisplay, myConfig,
+            android_createDisplaySurface(), 0)) == EGL_NO_SURFACE )
+    {
+        printf("eglCreateWindowSurface failed\n");
+        return 0;
+    }
+
+    if ( (eglContext = eglCreateContext(eglDisplay, myConfig, 0, 0)) == EGL_NO_CONTEXT )
+    {
+        printf("eglCreateContext failed\n");
+        return 0;
+    }
+
+    if ( eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) != EGL_TRUE )
+    {
+        printf("eglMakeCurrent failed\n");
+        return 0;
+    }
+
+    return 1;
+}
+
+void free_gl_surface(void)
+{
+    if (eglDisplay != EGL_NO_DISPLAY)
+    {
+        eglMakeCurrent( EGL_NO_DISPLAY, EGL_NO_SURFACE,
+                EGL_NO_SURFACE, EGL_NO_CONTEXT );
+        eglDestroyContext( eglDisplay, eglContext );
+        eglDestroySurface( eglDisplay, eglSurface );
+        eglTerminate( eglDisplay );
+        eglDisplay = EGL_NO_DISPLAY;
+    }
+}
+
+void init_scene(void)
+{
+    glDisable(GL_DITHER);
+    glEnable(GL_CULL_FACE);
+    float ratio = 320.0f /  480.0f;
+    glViewport(0, 0, 320, 480);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glFrustumf(-ratio, ratio, -1, 1, 1, 10);
+
+    glMatrixMode(GL_MODELVIEW);
+
+    glLoadIdentity();
+    gluLookAt(
+            0, 0, 3,  // eye
+            0, 0, 0,  // center
+            0, 1, 0); // up
+
+    glEnable(GL_TEXTURE_2D);
+}
+
+// #define USE_ALPHA_COLOR
+
+#define USE_GL_REPLACE
+// #define USE_GL_MODULATE
+
+// #define USE_BLEND
+
+#define USE_565
+// #define USE_8888
+
+// #define USE_NEAREST
+#define USE_LINEAR
+
+#define USE_SCALE
+
+void setSmoothGradient(Buffer* bufferObject) {
+    int pixels = bufferObject->getHeight() * bufferObject->getWidth();
+    int step = 0;
+    for (unsigned int y = 0; y < bufferObject->getHeight(); y++) {
+        for(unsigned int x = 0; x < bufferObject->getWidth() ; x++) {
+            int grey = step * 255 / pixels;
+            bufferObject->setPixel(x, y, grey, grey, grey, 255);
+            ++step;
+        }
+    }
+}
+
+void setSmoothAlphaGradient(Buffer* bufferObject) {
+    int pixels = bufferObject->getHeight() * bufferObject->getWidth();
+    int step = 0;
+    for (unsigned int y = 0; y < bufferObject->getHeight(); y++) {
+        for(unsigned int x = 0; x < bufferObject->getWidth() ; x++) {
+            int grey = step * 255 / pixels;
+            bufferObject->setPixel(x, y, 255, 255, 255, grey);
+            ++step;
+        }
+    }
+}
+
+void setOrientedCheckerboard(Buffer* bufferObject) {
+    bufferObject->setPixel(0, 0, 0, 0, 0, 255);
+    for(unsigned int x = 1; x < bufferObject->getWidth() ; x++) {
+        bufferObject->setPixel(x, 0, 0, 255, 0, 255);
+    }
+    for (unsigned int y = 1; y < bufferObject->getHeight(); y++) {
+        for(unsigned int x = 0; x < bufferObject->getWidth() ; x++) {
+            if ((x ^ y ) & 1) {
+                bufferObject->setPixel(x, y, 255, 255, 255, 255);
+            } else {
+                bufferObject->setPixel(x, y, 255, 0, 0, 255);
+            }
+        }
+    }
+}
+
+int create_physical_texture(unsigned int w, unsigned int h)
+{
+
+#ifdef USE_565
+    PixelFormat format = HAL_PIXEL_FORMAT_RGB_565;
+#else
+    PixelFormat format = HAL_PIXEL_FORMAT_RGBA_8888;
+#endif
+    int usage = GRALLOC_USAGE_SW_READ_OFTEN |
+        GRALLOC_USAGE_SW_WRITE_OFTEN |
+        GRALLOC_USAGE_HW_TEXTURE |
+        GRALLOC_USAGE_HW_2D; /* This is the key to allocating the texture in pmem. */
+    int32_t stride;
+    buffer_handle_t handle;
+
+    // Allocate the hardware buffer
+    Buffer* bufferObject = new Buffer(w, h, format, usage);
+
+    android_native_buffer_t* buffer = bufferObject->getNativeBuffer();
+
+    buffer->common.incRef(&buffer->common);
+
+    // create the new EGLImageKHR
+    EGLint attrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_NONE };
+    EGLDisplay dpy = eglGetCurrentDisplay();
+    EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
+            (EGLClientBuffer)buffer, attrs);
+    if (image == EGL_NO_IMAGE_KHR) {
+        printf("Could not create an image %d\n", eglGetError());
+        return -1;
+    }
+
+    if (buffer->bits == NULL) {
+        printf("No bits allocated for image.\n");
+        return -2;
+    }
+
+    setOrientedCheckerboard(bufferObject);
+    // setSmoothGradient(bufferObject);
+    // setSmoothAlphaGradient(bufferObject);
+
+    glGenTextures(1, &texture);
+    glBindTexture(GL_TEXTURE_2D, texture);
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
+#ifdef USE_LINEAR
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+#elif defined(USE_NEAREST)
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+#endif
+
+#ifdef USE_GL_REPLACE
+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+#elif defined(USE_GL_MODULATE)
+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+#endif
+
+#ifdef USE_ALPHA_COLOR
+    glColor4f(1.0f, 1.0f, 1.0f, 0.4f);
+#else
+    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+#endif
+
+#ifdef USE_BLEND
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+#endif
+    return 0;
+}
+
+static const int SCALE_COUNT = 12;
+
+int scale(int base, int factor) {
+    static const float kTable[SCALE_COUNT] = {
+            0.1f, 0.25f, 0.5f, 0.75f, 1.0f,
+            1.5f, 2.0f, 2.5f, 3.0f, 3.5f, 4.0f, 5.0f
+    };
+    return base * kTable[factor];
+}
+
+class Timer {
+    struct timeval  first;
+    double elapsedSeconds;
+
+public:
+    Timer() {}
+    void start() {
+        gettimeofday(&first, NULL);
+    }
+
+    void stop() {
+        struct timeval  second,
+                        elapsed;
+        gettimeofday(&second, NULL);
+
+        if (first.tv_usec > second.tv_usec) {
+           second.tv_usec += 1000000;
+           second.tv_sec--;
+        }
+
+        elapsedSeconds = (second.tv_sec  - first.tv_sec) +
+            (second.tv_usec - first.tv_usec) / 1000000.0;
+    }
+
+    double getElapsedSeconds() {
+        return elapsedSeconds;
+    }
+
+    double getElapsedMs() {
+        return elapsedSeconds* 1000.0f;
+    }
+};
+
+int testTime()
+{
+    static const int WIDTH = 320;
+    static const int HEIGHT = 480;
+    static const int SCALE = 8;
+
+    if (create_physical_texture(WIDTH, HEIGHT) != 0) {
+        return -1;
+    }
+    // Need to do a dummy eglSwapBuffers first. Don't know why.
+    glClearColor(0.4, 1.0, 0.4, 0.4);
+    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    eglSwapBuffers(eglDisplay, eglSurface);
+
+    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+
+#if defined(USE_SCALE)
+    static const int scaleOffset = 0;
+#else
+    static const int scaleOffset = 1;
+#endif
+    printf("ms\n");
+    for(int j = 0; j < SCALE; j++) {
+        int w = WIDTH >> (j + scaleOffset);
+        int h = HEIGHT >> j;
+        int cropRect[4] = {0,h,w,-h}; // Left bottom width height. Width and Height can be neg to flip.
+        glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect);
+        Timer timer;
+        timer.start();
+
+        int copyCount = 1000;
+        for (int i = 0; i < copyCount; i++) {
+            glDrawTexiOES(0, 0, 0, w, h);
+        }
+
+        timer.stop();
+        printf("%g\n", timer.getElapsedMs() / copyCount);
+    }
+
+    eglSwapBuffers(eglDisplay, eglSurface);
+    return 0;
+}
+
+int testStretch()
+{
+    static const int WIDTH = 8;
+    static const int HEIGHT = 8;
+
+    if (create_physical_texture(WIDTH, HEIGHT) != 0) {
+        return -1;
+    }
+    // Need to do a dummy eglSwapBuffers first. Don't know why.
+    glClearColor(0.4, 1.0, 0.4, 0.4);
+    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    eglSwapBuffers(eglDisplay, eglSurface);
+
+    int cropRect[4] = {0,HEIGHT,WIDTH,-HEIGHT}; // Left bottom width height. Width and Height can be neg to flip.
+    glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect);
+
+    for(int frame = 0; frame < 2; frame++) {
+        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+        int baseX = 10;
+        for (int x = 0; x < SCALE_COUNT; x++) {
+            int baseY = 10;
+            int width = scale(WIDTH, x);
+            for (int y = 0; y < SCALE_COUNT; y++) {
+                int height = scale(HEIGHT, y);
+                glDrawTexxOES(baseX << 16, baseY << 16, 0, width << 16, height << 16);
+                baseY += height + 10;
+            }
+            baseX += width + 10;
+        }
+
+        eglSwapBuffers(eglDisplay, eglSurface);
+    }
+    return 0;
+}
+
+int testRot90()
+{
+    static const int WIDTH = 8;
+    static const int HEIGHT = 8;
+
+    if (create_physical_texture(WIDTH, HEIGHT) != 0) {
+        return -1;
+    }
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glOrthof(0, 320, 480, 0, 0, 1);
+
+    glMatrixMode(GL_MODELVIEW);
+
+    glLoadIdentity();
+
+    // Need to do a dummy eglSwapBuffers first. Don't know why.
+    glClearColor(0.4, 0.4, 0.4, 0.4);
+    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    eglSwapBuffers(eglDisplay, eglSurface);
+
+    glEnable(GL_TEXTURE_2D);
+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
+    glDisable(GL_BLEND);
+    glShadeModel(GL_FLAT);
+    glDisable(GL_DITHER);
+    glDisable(GL_CULL_FACE);
+
+    for(int frame = 0; frame < 2; frame++) {
+        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+        int baseX = 10;
+        for (int x = 0; x < SCALE_COUNT; x++) {
+            int baseY = 10;
+            int width = scale(WIDTH, x);
+            for (int y = 0; y < SCALE_COUNT; y++) {
+                int height = scale(HEIGHT, y);
+
+                // Code copied from SurfaceFlinger LayerBase.cpp
+
+                const GLfixed texCoords[4][2] = {
+                        { 0,        0 },
+                        { 0,        0x10000 },
+                        { 0x10000,  0x10000 },
+                        { 0x10000,  0 }
+                };
+
+                GLfixed fx = baseX << 16;
+                GLfixed fy = baseY << 16;
+                GLfixed fw = width << 16;
+                GLfixed fh = height << 16;
+
+                /*
+                 * Vertex pattern:
+                 *    (2)--(3)
+                 *     |\   |
+                 *     | \  |
+                 *     |  \ |
+                 *     |   \|
+                 *    (1)--(0)
+                 *
+                 */
+
+                const GLfixed vertices[4][2] = {
+                        {fx + fw, fy},
+                        {fx,      fy},
+                        {fx,      fy + fh},
+                        {fx + fw, fy + fh}
+                };
+
+                static const bool rotate90 = true;
+
+                glMatrixMode(GL_TEXTURE);
+                glLoadIdentity();
+
+                glEnableClientState(GL_VERTEX_ARRAY);
+                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+                glVertexPointer(2, GL_FIXED, 0, vertices);
+                glTexCoordPointer(2, GL_FIXED, 0, texCoords);
+
+                LOGW("testRot90 %d, %d %d, %d", baseX, baseY, width, height);
+                glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+                baseY += height + 10;
+            }
+            baseX += width + 10;
+        }
+
+        eglSwapBuffers(eglDisplay, eglSurface);
+    }
+    return 0;
+}
+
+int main(int argc, char **argv)
+{
+
+    int q;
+    int start, end;
+
+    if (init_gralloc()) {
+        printf("gralloc initialization failed - exiting\n");
+        return 0;
+    }
+
+    printf("Initializing EGL...\n");
+
+    if(!init_gl_surface())
+    {
+        printf("GL initialisation failed - exiting\n");
+        return 0;
+    }
+
+    init_scene();
+
+    printf("Start test...\n");
+    // testTime();
+    // testStretch();
+    testRot90();
+    free_gl_surface();
+
+    return 0;
+}