diff --git a/opengl/libagl/Android.mk b/opengl/libagl/Android.mk
new file mode 100644
index 0000000..a3dff76
--- /dev/null
+++ b/opengl/libagl/Android.mk
@@ -0,0 +1,34 @@
+LOCAL_PATH:= $(call my-dir)
+
+#
+# Build the software OpenGL ES library
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	egl.cpp                     \
+	state.cpp		            \
+	texture.cpp		            \
+    Tokenizer.cpp               \
+    TokenManager.cpp            \
+    TextureObjectManager.cpp    \
+    BufferObjectManager.cpp     \
+	array.cpp.arm		        \
+	fp.cpp.arm		            \
+	light.cpp.arm		        \
+	matrix.cpp.arm		        \
+	mipmap.cpp.arm		        \
+	primitives.cpp.arm	        \
+	vertex.cpp.arm
+
+ifeq ($(TARGET_ARCH),arm)
+	LOCAL_SRC_FILES += fixed_asm.S iterators.S
+	LOCAL_CFLAGS += -fstrict-aliasing
+endif
+
+LOCAL_SHARED_LIBRARIES := libcutils libutils libpixelflinger
+LOCAL_LDLIBS := -lpthread -ldl
+LOCAL_MODULE:= libagl
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/opengl/libagl/BufferObjectManager.cpp b/opengl/libagl/BufferObjectManager.cpp
new file mode 100644
index 0000000..6bf28ee
--- /dev/null
+++ b/opengl/libagl/BufferObjectManager.cpp
@@ -0,0 +1,103 @@
+/*
+ ** Copyright 2008, 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 <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+#include <utils/Atomic.h>
+#include <utils/RefBase.h>
+#include <utils/KeyedVector.h>
+#include <utils/Errors.h>
+
+#include <GLES/gl.h>
+
+#include "BufferObjectManager.h"
+
+
+namespace android {
+
+using namespace gl;
+
+// ----------------------------------------------------------------------------
+
+EGLBufferObjectManager::EGLBufferObjectManager() 
+: TokenManager(), mCount(0)
+{
+}
+
+EGLBufferObjectManager::~EGLBufferObjectManager()
+{
+    // destroy all the buffer objects and their storage
+    GLsizei n = mBuffers.size();
+    for (GLsizei i=0 ; i<n ; i++) {
+        buffer_t* bo = mBuffers.valueAt(i);
+        free(bo->data);
+        delete bo;
+    }
+}
+
+buffer_t const* EGLBufferObjectManager::bind(GLuint buffer)
+{
+    Mutex::Autolock _l(mLock);
+    int32_t i = mBuffers.indexOfKey(buffer);
+    if (i >= 0) {
+        return mBuffers.valueAt(i);
+    }
+    buffer_t* bo = new buffer_t;
+    bo->data = 0;
+    bo->usage = GL_STATIC_DRAW;
+    bo->size = 0;
+    bo->name = buffer;
+    mBuffers.add(buffer, bo);
+    return bo;
+}
+
+int EGLBufferObjectManager::allocateStore(buffer_t* bo,
+        GLsizeiptr size, GLenum usage)
+{
+    Mutex::Autolock _l(mLock);
+    if (size != bo->size) {
+       uint8_t* data = (uint8_t*)malloc(size);
+        if (data == 0)
+            return -1;
+        free(bo->data);
+        bo->data = data;
+        bo->size = size;
+    }
+    bo->usage = usage;
+    return 0;
+}
+
+void EGLBufferObjectManager::deleteBuffers(GLsizei n, const GLuint* buffers)
+{
+    Mutex::Autolock _l(mLock);
+    while (n--) {
+        const GLuint t = *buffers++;
+        if (t) {
+            int32_t index = mBuffers.indexOfKey(t);
+            if (index >= 0) {
+                buffer_t* bo = mBuffers.valueAt(index);
+                free(bo->data);
+                mBuffers.removeItemsAt(index);
+                delete bo;
+            }
+        }
+    }
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/opengl/libagl/BufferObjectManager.h b/opengl/libagl/BufferObjectManager.h
new file mode 100644
index 0000000..9e9340a
--- /dev/null
+++ b/opengl/libagl/BufferObjectManager.h
@@ -0,0 +1,85 @@
+/*
+ **
+ ** 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 
+ **
+ **     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_BUFFER_OBJECT_MANAGER_H
+#define ANDROID_OPENGLES_BUFFER_OBJECT_MANAGER_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+#include <utils/Atomic.h>
+#include <utils/RefBase.h>
+#include <utils/KeyedVector.h>
+#include <utils/Errors.h>
+
+#include <GLES/gl.h>
+
+#include "Tokenizer.h"
+#include "TokenManager.h"
+
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+namespace gl {
+
+struct buffer_t {
+    GLsizeiptr      size;
+    GLenum          usage;
+    uint8_t*        data;
+    uint32_t        name;
+};
+
+};
+
+class EGLBufferObjectManager : public TokenManager
+{
+public:
+    EGLBufferObjectManager();
+    ~EGLBufferObjectManager();
+
+    // protocol for sp<>
+    inline  void    incStrong(const void* id) const;
+    inline  void    decStrong(const void* id) const;
+    typedef void    weakref_type;
+
+    gl::buffer_t const* bind(GLuint buffer);
+    int                 allocateStore(gl::buffer_t* bo, GLsizeiptr size, GLenum usage);
+    void                deleteBuffers(GLsizei n, const GLuint* buffers);
+
+private:
+    mutable volatile int32_t            mCount;
+    mutable Mutex                       mLock;
+    KeyedVector<GLuint, gl::buffer_t*>  mBuffers;
+};
+
+void EGLBufferObjectManager::incStrong(const void* id) const {
+    android_atomic_inc(&mCount);
+}
+void EGLBufferObjectManager::decStrong(const void* id) const {
+    if (android_atomic_dec(&mCount) == 1) {
+        delete this;
+    }
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_BUFFER_OBJECT_MANAGER_H
+
diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp
new file mode 100644
index 0000000..12fae63
--- /dev/null
+++ b/opengl/libagl/TextureObjectManager.cpp
@@ -0,0 +1,309 @@
+/*
+ ** 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 
+ **
+ **     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 <stdio.h>
+#include <stdlib.h>
+#include "context.h"
+#include "TextureObjectManager.h"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+EGLTextureObject::EGLTextureObject()
+    : mCount(0), mSize(0)
+{
+    init();
+}
+
+EGLTextureObject::~EGLTextureObject()
+{
+    if (!direct) {
+        if (mSize && surface.data)
+            free(surface.data);
+        if (mMipmaps)
+            freeMipmaps();
+    }
+}
+
+void EGLTextureObject::init()
+{
+    memset(&surface, 0, sizeof(surface));
+    surface.version = sizeof(surface);
+    mMipmaps = 0;
+    mNumExtraLod = 0;
+    mIsComplete = false;
+    wraps = GL_REPEAT;
+    wrapt = GL_REPEAT;
+    min_filter = GL_LINEAR;
+    mag_filter = GL_LINEAR;
+    internalformat = 0;
+    memset(crop_rect, 0, sizeof(crop_rect));
+    generate_mipmap = GL_FALSE;
+    direct = GL_FALSE;
+}
+
+void EGLTextureObject::copyParameters(const sp<EGLTextureObject>& old)
+{
+    wraps = old->wraps;
+    wrapt = old->wrapt;
+    min_filter = old->min_filter;
+    mag_filter = old->mag_filter;
+    memcpy(crop_rect, old->crop_rect, sizeof(crop_rect));
+    generate_mipmap = old->generate_mipmap;
+    direct = old->direct;
+}
+
+status_t EGLTextureObject::allocateMipmaps()
+{
+    // here, by construction, mMipmaps=0 && mNumExtraLod=0
+
+    if (!surface.data)
+        return NO_INIT;
+
+    int w = surface.width;
+    int h = surface.height;
+    const int numLods = 31 - gglClz(max(w,h));
+    if (numLods <= 0)
+        return NO_ERROR;
+
+    mMipmaps = (GGLSurface*)malloc(numLods * sizeof(GGLSurface));
+    if (!mMipmaps)
+        return NO_MEMORY;
+
+    memset(mMipmaps, 0, numLods * sizeof(GGLSurface));
+    mNumExtraLod = numLods;
+    return NO_ERROR;
+}
+
+void EGLTextureObject::freeMipmaps()
+{
+    if (mMipmaps) {
+        for (int i=0 ; i<mNumExtraLod ; i++) {
+            if (mMipmaps[i].data) {
+                free(mMipmaps[i].data);
+            }
+        }
+        free(mMipmaps);
+        mMipmaps = 0;
+        mNumExtraLod = 0;
+    }
+}
+
+const GGLSurface& EGLTextureObject::mip(int lod) const
+{
+    if (lod<=0 || !mMipmaps)
+        return surface;
+    lod = min(lod-1, mNumExtraLod-1);
+    return mMipmaps[lod];
+}
+
+GGLSurface& EGLTextureObject::editMip(int lod)
+{
+    return const_cast<GGLSurface&>(mip(lod));
+}
+
+status_t EGLTextureObject::setSurface(GGLSurface const* s)
+{
+    // XXX: glFlush() on 's'
+    if (mSize && surface.data) {
+        free(surface.data);
+    }
+    surface = *s;
+    internalformat = 0;
+
+    // we should keep the crop_rect, but it's delicate because
+    // the new size of the surface could make it invalid.
+    // so for now, we just loose it.
+    memset(crop_rect, 0, sizeof(crop_rect));
+
+    // it would be nice id we could keep the generate_mipmap flag
+    // we would have to generate them right now though.
+    generate_mipmap = GL_FALSE;
+
+    direct = GL_TRUE;
+    mSize = 0;  // we don't own this surface
+    if (mMipmaps)
+        freeMipmaps();
+    mIsComplete = true;
+    return NO_ERROR;
+}
+
+status_t EGLTextureObject::reallocate(
+        GLint level, int w, int h, int s,
+        int format, int compressedFormat, int bpr)
+{
+    const size_t size = h * bpr;
+    if (level == 0) 
+    {
+        if (size!=mSize || !surface.data) {
+            if (mSize && surface.data) {
+                free(surface.data);
+            }
+            surface.data = (GGLubyte*)malloc(size);
+            if (!surface.data) {
+                mSize = 0;
+                mIsComplete = false;
+                return NO_MEMORY;
+            }
+            mSize = size;
+        }
+        surface.version = sizeof(GGLSurface);
+        surface.width  = w;
+        surface.height = h;
+        surface.stride = s;
+        surface.format = format;
+        surface.compressedFormat = compressedFormat;
+        if (mMipmaps)
+            freeMipmaps();
+        mIsComplete = true;
+    }
+    else
+    {
+        if (!mMipmaps) {
+            if (allocateMipmaps() != NO_ERROR)
+                return NO_MEMORY;
+        }
+
+        LOGW_IF(level-1 >= mNumExtraLod, 
+                "specifying mipmap level %d, but # of level is %d",
+                level, mNumExtraLod+1);        
+
+        GGLSurface& mipmap = editMip(level);
+        if (mipmap.data)
+            free(mipmap.data);
+
+        mipmap.data = (GGLubyte*)malloc(size);
+        if (!mipmap.data) {
+            memset(&mipmap, 0, sizeof(GGLSurface));
+            mIsComplete = false;
+            return NO_MEMORY;
+        }
+
+        mipmap.version = sizeof(GGLSurface);
+        mipmap.width  = w;
+        mipmap.height = h;
+        mipmap.stride = s;
+        mipmap.format = format;
+        mipmap.compressedFormat = compressedFormat;
+
+        // check if the texture is complete
+        mIsComplete = true;
+        const GGLSurface* prev = &surface;
+        for (int i=0 ; i<mNumExtraLod ; i++) {
+            const GGLSurface* curr = mMipmaps + i;
+            if (curr->format != surface.format) {
+                mIsComplete = false;
+                break;
+            }
+
+            uint32_t w = (prev->width  >> 1) ? : 1;
+            uint32_t h = (prev->height >> 1) ? : 1;
+            if (w != curr->width || h != curr->height) {
+                mIsComplete = false;
+                break;
+            }
+            prev = curr;
+        }
+    }
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+EGLSurfaceManager::EGLSurfaceManager()
+    : TokenManager(), mCount(0)
+{
+}
+
+EGLSurfaceManager::~EGLSurfaceManager()
+{
+    // everything gets freed automatically here...
+}
+
+sp<EGLTextureObject> EGLSurfaceManager::createTexture(GLuint name)
+{
+    sp<EGLTextureObject> result;
+
+    Mutex::Autolock _l(mLock);
+    if (mTextures.indexOfKey(name) >= 0)
+        return result; // already exists!
+
+    result = new EGLTextureObject();
+
+    status_t err = mTextures.add(name, result);
+    if (err < 0)
+        result.clear();
+
+    return result;
+}
+
+sp<EGLTextureObject> EGLSurfaceManager::removeTexture(GLuint name)
+{
+    Mutex::Autolock _l(mLock);
+    const ssize_t index = mTextures.indexOfKey(name);
+    if (index >= 0) {
+        sp<EGLTextureObject> result(mTextures.valueAt(index));
+        mTextures.removeItemsAt(index);
+        return result;
+    }
+    return 0;
+}
+
+sp<EGLTextureObject> EGLSurfaceManager::replaceTexture(GLuint name)
+{
+    sp<EGLTextureObject> tex;
+    Mutex::Autolock _l(mLock);
+    const ssize_t index = mTextures.indexOfKey(name);
+    if (index >= 0) {
+        const sp<EGLTextureObject>& old = mTextures.valueAt(index);
+        const uint32_t refs = old->getStrongCount();
+        if (ggl_likely(refs == 1)) {
+            // we're the only owner
+            tex = old;
+        } else {
+            // keep the texture's parameters
+            tex = new EGLTextureObject();
+            tex->copyParameters(old);
+            mTextures.removeItemsAt(index);
+            mTextures.add(name, tex);
+        }
+    }
+    return tex;
+}
+
+void EGLSurfaceManager::deleteTextures(GLsizei n, const GLuint *tokens)
+{
+    // free all texures
+    Mutex::Autolock _l(mLock);
+    for (GLsizei i=0 ; i<n ; i++) {
+        const GLuint t(*tokens++);
+        if (t) {
+            mTextures.removeItem(t);
+        }
+    }
+}
+
+sp<EGLTextureObject> EGLSurfaceManager::texture(GLuint name)
+{
+    Mutex::Autolock _l(mLock);
+    const ssize_t index = mTextures.indexOfKey(name);
+    if (index >= 0)
+        return mTextures.valueAt(index);
+    return 0;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/opengl/libagl/TextureObjectManager.h b/opengl/libagl/TextureObjectManager.h
new file mode 100644
index 0000000..74ed1a4
--- /dev/null
+++ b/opengl/libagl/TextureObjectManager.h
@@ -0,0 +1,140 @@
+/*
+** 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 
+**
+**     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_SURFACE_H
+#define ANDROID_OPENGLES_SURFACE_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+#include <utils/Atomic.h>
+#include <utils/threads.h>
+#include <utils/RefBase.h>
+#include <utils/KeyedVector.h>
+#include <utils/Errors.h>
+
+#include <private/pixelflinger/ggl_context.h>
+
+#include <GLES/gl.h>
+
+#include "Tokenizer.h"
+#include "TokenManager.h"
+
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class EGLTextureObject
+{
+public:
+                    EGLTextureObject();
+                   ~EGLTextureObject();
+
+    // protocol for sp<>
+    inline  void        incStrong(const void* id) const;
+    inline  void        decStrong(const void* id) const;
+    inline  uint32_t    getStrongCount() const;
+
+    status_t            setSurface(GGLSurface const* s);
+    status_t            reallocate(GLint level,
+                            int w, int h, int s,
+                            int format, int compressedFormat, int bpr);
+    inline  size_t      size() const;
+    const GGLSurface&   mip(int lod) const;
+    GGLSurface&         editMip(int lod);
+    bool                hasMipmaps() const { return mMipmaps!=0; }
+    bool                isComplete() const { return mIsComplete; }
+    void                copyParameters(const sp<EGLTextureObject>& old);
+
+private:
+        status_t        allocateMipmaps();
+            void        freeMipmaps();
+            void        init();
+    mutable int32_t     mCount;
+    size_t              mSize;
+    GGLSurface          *mMipmaps;
+    int                 mNumExtraLod;
+    bool                mIsComplete;
+
+public:
+    GGLSurface          surface;
+    GLenum              wraps;
+    GLenum              wrapt;
+    GLenum              min_filter;
+    GLenum              mag_filter;
+    GLenum              internalformat;
+    GLint               crop_rect[4];
+    GLint               generate_mipmap;
+    GLint               direct;
+};
+
+void EGLTextureObject::incStrong(const void* id) const {
+    android_atomic_inc(&mCount);
+}
+void EGLTextureObject::decStrong(const void* id) const {
+    if (android_atomic_dec(&mCount) == 1) {
+        delete this;
+    }
+}
+uint32_t EGLTextureObject::getStrongCount() const {
+    return mCount;
+}
+size_t EGLTextureObject::size() const {
+    return mSize;
+}
+
+// ----------------------------------------------------------------------------
+
+class EGLSurfaceManager : public TokenManager
+{
+public:
+                EGLSurfaceManager();
+                ~EGLSurfaceManager();
+
+    // protocol for sp<>
+    inline  void    incStrong(const void* id) const;
+    inline  void    decStrong(const void* id) const;
+    typedef void    weakref_type;
+
+    sp<EGLTextureObject>    createTexture(GLuint name);
+    sp<EGLTextureObject>    removeTexture(GLuint name);
+    sp<EGLTextureObject>    replaceTexture(GLuint name);
+    void                    deleteTextures(GLsizei n, const GLuint *tokens);
+    sp<EGLTextureObject>    texture(GLuint name);
+
+private:
+    mutable int32_t                             mCount;
+    mutable Mutex                               mLock;
+    KeyedVector< GLuint, sp<EGLTextureObject> > mTextures;
+};
+
+void EGLSurfaceManager::incStrong(const void* id) const {
+    android_atomic_inc(&mCount);
+}
+void EGLSurfaceManager::decStrong(const void* id) const {
+    if (android_atomic_dec(&mCount) == 1) {
+        delete this;
+    }
+}
+
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_SURFACE_H
+
diff --git a/opengl/libagl/TokenManager.cpp b/opengl/libagl/TokenManager.cpp
new file mode 100644
index 0000000..eea6025
--- /dev/null
+++ b/opengl/libagl/TokenManager.cpp
@@ -0,0 +1,62 @@
+/* libs/opengles/surface.cpp
+**
+** 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 
+**
+**     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 <stdio.h>
+#include <stdlib.h>
+#include "TokenManager.h"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+TokenManager::TokenManager()
+{
+    // token 0 is always reserved
+    mTokenizer.reserve(0);
+}
+
+TokenManager::~TokenManager()
+{
+}
+
+status_t TokenManager::getToken(GLsizei n, GLuint *tokens)
+{
+    Mutex::Autolock _l(mLock);
+    for (GLsizei i=0 ; i<n ; i++)
+        *tokens++ = mTokenizer.acquire();
+    return NO_ERROR;
+}
+
+void TokenManager::recycleTokens(GLsizei n, const GLuint *tokens)
+{
+    Mutex::Autolock _l(mLock);
+    for (int i=0 ; i<n ; i++) {
+        const GLuint token = *tokens++;
+        if (token) {
+            mTokenizer.release(token);
+        }
+    }
+}
+
+bool TokenManager::isTokenValid(GLuint token) const
+{
+    Mutex::Autolock _l(mLock);
+    return mTokenizer.isAcquired(token);
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
diff --git a/opengl/libagl/TokenManager.h b/opengl/libagl/TokenManager.h
new file mode 100644
index 0000000..49c1469
--- /dev/null
+++ b/opengl/libagl/TokenManager.h
@@ -0,0 +1,53 @@
+/*
+** 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 
+**
+**     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_TOKEN_MANAGER_H
+#define ANDROID_OPENGLES_TOKEN_MANAGER_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+#include <utils/threads.h>
+
+#include <GLES/gl.h>
+
+#include "Tokenizer.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class TokenManager
+{
+public:
+                TokenManager();
+                ~TokenManager();
+
+    status_t    getToken(GLsizei n, GLuint *tokens);
+    void        recycleTokens(GLsizei n, const GLuint *tokens);
+    bool        isTokenValid(GLuint token) const;
+
+private:
+    mutable Mutex   mLock;
+    Tokenizer       mTokenizer;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_TOKEN_MANAGER_H
+
diff --git a/opengl/libagl/Tokenizer.cpp b/opengl/libagl/Tokenizer.cpp
new file mode 100644
index 0000000..9b3ea1a
--- /dev/null
+++ b/opengl/libagl/Tokenizer.cpp
@@ -0,0 +1,173 @@
+/* libs/opengles/Tokenizer.cpp
+**
+** 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 
+**
+**     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 <stdio.h>
+
+#include "Tokenizer.h"
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+ANDROID_BASIC_TYPES_TRAITS(Tokenizer::run_t)
+
+Tokenizer::Tokenizer()
+{
+}
+
+Tokenizer::Tokenizer(const Tokenizer& other)
+    : mRanges(other.mRanges)
+{
+}
+
+Tokenizer::~Tokenizer()
+{
+}
+
+uint32_t Tokenizer::acquire()
+{
+    if (!mRanges.size() || mRanges[0].first) {
+        _insertTokenAt(0,0);
+        return 0;
+    }
+    
+    // just extend the first run
+    const run_t& run = mRanges[0];
+    uint32_t token = run.first + run.length;
+    _insertTokenAt(token, 1);
+    return token;
+}
+
+bool Tokenizer::isAcquired(uint32_t token) const
+{
+    return (_indexOrderOf(token) >= 0);
+}
+
+status_t Tokenizer::reserve(uint32_t token)
+{
+    size_t o;
+    const ssize_t i = _indexOrderOf(token, &o);
+    if (i >= 0) {
+        return BAD_VALUE; // this token is already taken
+    }
+    ssize_t err = _insertTokenAt(token, o);
+    return (err<0) ? err : status_t(NO_ERROR);
+}
+
+status_t Tokenizer::release(uint32_t token)
+{
+    const ssize_t i = _indexOrderOf(token);
+    if (i >= 0) {
+        const run_t& run = mRanges[i];
+        if ((token >= run.first) && (token < run.first+run.length)) {
+            // token in this range, we need to split
+            run_t& run = mRanges.editItemAt(i);
+            if ((token == run.first) || (token == run.first+run.length-1)) {
+                if (token == run.first) {
+                    run.first += 1;
+                }
+                run.length -= 1;
+                if (run.length == 0) {
+                    // XXX: should we systematically remove a run that's empty?
+                    mRanges.removeItemsAt(i);
+                }
+            } else {
+                // split the run
+                run_t new_run;
+                new_run.first = token+1;
+                new_run.length = run.first+run.length - new_run.first;
+                run.length = token - run.first;
+                mRanges.insertAt(new_run, i+1);
+            }
+            return NO_ERROR;
+        }
+    }
+    return NAME_NOT_FOUND;
+}
+
+ssize_t Tokenizer::_indexOrderOf(uint32_t token, size_t* order) const
+{
+    // binary search
+    ssize_t err = NAME_NOT_FOUND;
+    ssize_t l = 0;
+    ssize_t h = mRanges.size()-1;
+    ssize_t mid;
+    const run_t* a = mRanges.array();
+    while (l <= h) {
+        mid = l + (h - l)/2;
+        const run_t* const curr = a + mid;
+        int c = 0;
+        if (token < curr->first)                        c = 1;
+        else if (token >= curr->first+curr->length)     c = -1;
+        if (c == 0) {
+            err = l = mid;
+            break;
+        } else if (c < 0) {
+            l = mid + 1;
+        } else {
+            h = mid - 1;
+        }
+    }
+    if (order) *order = l;
+    return err;
+}
+
+ssize_t Tokenizer::_insertTokenAt(uint32_t token, size_t index)
+{
+    const size_t c = mRanges.size();
+
+    if (index >= 1) {
+        // do we need to merge with the previous run?
+        run_t& p = mRanges.editItemAt(index-1);
+        if (p.first+p.length == token) {
+            p.length += 1;
+            if (index < c) {
+                const run_t& n = mRanges[index];
+                if (token+1 == n.first) {
+                    p.length += n.length;
+                    mRanges.removeItemsAt(index);
+                }
+            }
+            return index;
+        }
+    }
+    
+    if (index < c) {
+        // do we need to merge with the next run?
+        run_t& n = mRanges.editItemAt(index);
+        if (token+1 == n.first) {
+            n.first -= 1;
+            n.length += 1;
+            return index;
+        }
+    }
+
+    return mRanges.insertAt(run_t(token,1), index);
+}
+
+void Tokenizer::dump() const
+{
+    const run_t* ranges = mRanges.array();
+    const size_t c = mRanges.size();
+    LOGD("Tokenizer (%p, size = %u)\n", this, c);
+    for (size_t i=0 ; i<c ; i++) {
+        LOGD("%u: (%u, %u)\n", i, ranges[i].first, ranges[i].length);
+    }
+}
+
+}; // namespace android
+
diff --git a/opengl/libagl/Tokenizer.h b/opengl/libagl/Tokenizer.h
new file mode 100644
index 0000000..ac555cb
--- /dev/null
+++ b/opengl/libagl/Tokenizer.h
@@ -0,0 +1,59 @@
+/* libs/opengles/Tokenizer.h
+**
+** 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 
+**
+**     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_TOKENIZER_H
+#define ANDROID_OPENGLES_TOKENIZER_H
+
+#include <utils/Vector.h>
+#include <utils/Errors.h>
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+class Tokenizer
+{
+public:
+                Tokenizer();
+                Tokenizer(const Tokenizer& other);
+                ~Tokenizer();
+
+    uint32_t    acquire();
+    status_t    reserve(uint32_t token);
+    status_t    release(uint32_t token);
+    bool        isAcquired(uint32_t token) const;
+
+    void dump() const;
+
+    struct run_t {
+        run_t() {};
+        run_t(uint32_t f, uint32_t l) : first(f), length(l) {}
+        uint32_t    first;
+        uint32_t    length;
+    };
+private:
+    ssize_t _indexOrderOf(uint32_t token, size_t* order=0) const;
+    ssize_t _insertTokenAt(uint32_t token, size_t index);
+    Vector<run_t>   mRanges;
+};
+
+}; // namespace android
+
+// ----------------------------------------------------------------------------
+
+#endif // ANDROID_OPENGLES_TOKENIZER_H
diff --git a/opengl/libagl/array.cpp b/opengl/libagl/array.cpp
new file mode 100644
index 0000000..1f6757d
--- /dev/null
+++ b/opengl/libagl/array.cpp
@@ -0,0 +1,1557 @@
+/* 
+** 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 
+**
+**     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"
+
+// ----------------------------------------------------------------------------
+
+#define VC_CACHE_STATISTICS     0
+#define VC_CACHE_TYPE_NONE      0
+#define VC_CACHE_TYPE_INDEXED   1
+#define VC_CACHE_TYPE_LRU       2
+#define VC_CACHE_TYPE           VC_CACHE_TYPE_INDEXED
+
+#if VC_CACHE_STATISTICS
+#include <utils/Timers.h>
+#endif
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+static void validate_arrays(ogles_context_t* c, GLenum mode);
+
+static void compileElements__generic(ogles_context_t*,
+        vertex_t*, GLint, GLsizei);
+static void compileElement__generic(ogles_context_t*,
+        vertex_t*, GLint);
+
+static void drawPrimitivesPoints(ogles_context_t*, GLint, GLsizei);
+static void drawPrimitivesLineStrip(ogles_context_t*, GLint, GLsizei);
+static void drawPrimitivesLineLoop(ogles_context_t*, GLint, GLsizei);
+static void drawPrimitivesLines(ogles_context_t*, GLint, GLsizei);
+static void drawPrimitivesTriangleStrip(ogles_context_t*, GLint, GLsizei);
+static void drawPrimitivesTriangleFan(ogles_context_t*, GLint, GLsizei);
+static void drawPrimitivesTriangles(ogles_context_t*, GLint, GLsizei);
+
+static void drawIndexedPrimitivesPoints(ogles_context_t*,
+        GLsizei, const GLvoid*);
+static void drawIndexedPrimitivesLineStrip(ogles_context_t*,
+        GLsizei, const GLvoid*);
+static void drawIndexedPrimitivesLineLoop(ogles_context_t*,
+        GLsizei, const GLvoid*);
+static void drawIndexedPrimitivesLines(ogles_context_t*,
+        GLsizei, const GLvoid*);
+static void drawIndexedPrimitivesTriangleStrip(ogles_context_t*,
+        GLsizei, const GLvoid*);
+static void drawIndexedPrimitivesTriangleFan(ogles_context_t*,
+        GLsizei, const GLvoid*);
+static void drawIndexedPrimitivesTriangles(ogles_context_t*,
+        GLsizei, const GLvoid*);
+
+// ----------------------------------------------------------------------------
+
+typedef void (*arrays_prims_fct_t)(ogles_context_t*, GLint, GLsizei);
+static const arrays_prims_fct_t drawArraysPrims[] = {
+    drawPrimitivesPoints,
+    drawPrimitivesLines,
+    drawPrimitivesLineLoop,
+    drawPrimitivesLineStrip,
+    drawPrimitivesTriangles,
+    drawPrimitivesTriangleStrip,
+    drawPrimitivesTriangleFan
+};
+
+typedef void (*elements_prims_fct_t)(ogles_context_t*, GLsizei, const GLvoid*);
+static const elements_prims_fct_t drawElementsPrims[] = {
+    drawIndexedPrimitivesPoints,
+    drawIndexedPrimitivesLines,
+    drawIndexedPrimitivesLineLoop,
+    drawIndexedPrimitivesLineStrip,
+    drawIndexedPrimitivesTriangles,
+    drawIndexedPrimitivesTriangleStrip,
+    drawIndexedPrimitivesTriangleFan
+};
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+void ogles_init_array(ogles_context_t* c)
+{
+    c->arrays.vertex.size = 4;
+    c->arrays.vertex.type = GL_FLOAT;
+    c->arrays.color.size = 4;
+    c->arrays.color.type = GL_FLOAT;
+    c->arrays.normal.size = 4;
+    c->arrays.normal.type = GL_FLOAT;
+    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+        c->arrays.texture[i].size = 4;
+        c->arrays.texture[i].type = GL_FLOAT;
+    }
+    c->vc.init();
+
+    if (!c->vc.vBuffer) {
+        // this could have failed
+        ogles_error(c, GL_OUT_OF_MEMORY);
+    }
+}
+
+void ogles_uninit_array(ogles_context_t* c)
+{
+    c->vc.uninit();
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Array fetchers
+#endif
+
+static void currentColor(ogles_context_t* c, GLfixed* v, const GLvoid*) {
+    memcpy(v, c->current.color.v, sizeof(vec4_t));
+}
+static void currentColor_clamp(ogles_context_t* c, GLfixed* v, const GLvoid*) {
+    memcpy(v, c->currentColorClamped.v, sizeof(vec4_t));
+}
+static void currentNormal(ogles_context_t* c, GLfixed* v, const GLvoid*) {
+    memcpy(v, c->currentNormal.v, sizeof(vec3_t));
+}
+static void currentTexCoord(ogles_context_t* c, GLfixed* v, const GLvoid*) {
+    memcpy(v, c->current.texture[c->arrays.tmu].v, sizeof(vec4_t));
+}
+
+
+static void fetchNop(ogles_context_t*, GLfixed*, const GLvoid*) {
+}
+static void fetch2b(ogles_context_t*, GLfixed* v, const GLbyte* p) {
+    v[0] = gglIntToFixed(p[0]);
+    v[1] = gglIntToFixed(p[1]);
+}
+static void fetch2s(ogles_context_t*, GLfixed* v, const GLshort* p) {
+    v[0] = gglIntToFixed(p[0]);
+    v[1] = gglIntToFixed(p[1]);
+}
+static void fetch2x(ogles_context_t*, GLfixed* v, const GLfixed* p) {
+    memcpy(v, p, 2*sizeof(GLfixed));
+}
+static void fetch2f(ogles_context_t*, GLfixed* v, const GLfloat* p) {
+    v[0] = gglFloatToFixed(p[0]);
+    v[1] = gglFloatToFixed(p[1]);
+}
+static void fetch3b(ogles_context_t*, GLfixed* v, const GLbyte* p) {
+    v[0] = gglIntToFixed(p[0]);
+    v[1] = gglIntToFixed(p[1]);
+    v[2] = gglIntToFixed(p[2]);
+}
+static void fetch3s(ogles_context_t*, GLfixed* v, const GLshort* p) {
+    v[0] = gglIntToFixed(p[0]);
+    v[1] = gglIntToFixed(p[1]);
+    v[2] = gglIntToFixed(p[2]);
+}
+static void fetch3x(ogles_context_t*, GLfixed* v, const GLfixed* p) {
+    memcpy(v, p, 3*sizeof(GLfixed));
+}
+static void fetch3f(ogles_context_t*, GLfixed* v, const GLfloat* p) {
+    v[0] = gglFloatToFixed(p[0]);
+    v[1] = gglFloatToFixed(p[1]);
+    v[2] = gglFloatToFixed(p[2]);
+}
+static void fetch4b(ogles_context_t*, GLfixed* v, const GLbyte* p) {
+    v[0] = gglIntToFixed(p[0]);
+    v[1] = gglIntToFixed(p[1]);
+    v[2] = gglIntToFixed(p[2]);
+    v[3] = gglIntToFixed(p[3]);
+}
+static void fetch4s(ogles_context_t*, GLfixed* v, const GLshort* p) {
+    v[0] = gglIntToFixed(p[0]);
+    v[1] = gglIntToFixed(p[1]);
+    v[2] = gglIntToFixed(p[2]);
+    v[3] = gglIntToFixed(p[3]);
+}
+static void fetch4x(ogles_context_t*, GLfixed* v, const GLfixed* p) {
+    memcpy(v, p, 4*sizeof(GLfixed));
+}
+static void fetch4f(ogles_context_t*, GLfixed* v, const GLfloat* p) {
+    v[0] = gglFloatToFixed(p[0]);
+    v[1] = gglFloatToFixed(p[1]);
+    v[2] = gglFloatToFixed(p[2]);
+    v[3] = gglFloatToFixed(p[3]);
+}
+static void fetchExpand4ub(ogles_context_t*, GLfixed* v, const GLubyte* p) {
+    v[0] = GGL_UB_TO_X(p[0]);
+    v[1] = GGL_UB_TO_X(p[1]);
+    v[2] = GGL_UB_TO_X(p[2]);
+    v[3] = GGL_UB_TO_X(p[3]);
+}
+static void fetchClamp4x(ogles_context_t*, GLfixed* v, const GLfixed* p) {
+    v[0] = gglClampx(p[0]);
+    v[1] = gglClampx(p[1]);
+    v[2] = gglClampx(p[2]);
+    v[3] = gglClampx(p[3]);
+}
+static void fetchClamp4f(ogles_context_t*, GLfixed* v, const GLfloat* p) {
+    v[0] = gglClampx(gglFloatToFixed(p[0]));
+    v[1] = gglClampx(gglFloatToFixed(p[1]));
+    v[2] = gglClampx(gglFloatToFixed(p[2]));
+    v[3] = gglClampx(gglFloatToFixed(p[3]));
+}
+static void fetchExpand3ub(ogles_context_t*, GLfixed* v, const GLubyte* p) {
+    v[0] = GGL_UB_TO_X(p[0]);
+    v[1] = GGL_UB_TO_X(p[1]);
+    v[2] = GGL_UB_TO_X(p[2]);
+    v[3] = 0x10000;
+}
+static void fetchClamp3x(ogles_context_t*, GLfixed* v, const GLfixed* p) {
+    v[0] = gglClampx(p[0]);
+    v[1] = gglClampx(p[1]);
+    v[2] = gglClampx(p[2]);
+    v[3] = 0x10000;
+}
+static void fetchClamp3f(ogles_context_t*, GLfixed* v, const GLfloat* p) {
+    v[0] = gglClampx(gglFloatToFixed(p[0]));
+    v[1] = gglClampx(gglFloatToFixed(p[1]));
+    v[2] = gglClampx(gglFloatToFixed(p[2]));
+    v[3] = 0x10000;
+}
+static void fetchExpand3b(ogles_context_t*, GLfixed* v, const GLbyte* p) {
+    v[0] = GGL_B_TO_X(p[0]);
+    v[1] = GGL_B_TO_X(p[1]);
+    v[2] = GGL_B_TO_X(p[2]);
+}
+static void fetchExpand3s(ogles_context_t*, GLfixed* v, const GLshort* p) {
+    v[0] = GGL_S_TO_X(p[0]);
+    v[1] = GGL_S_TO_X(p[1]);
+    v[2] = GGL_S_TO_X(p[2]);
+}
+
+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,
+         (fn_t)fetch3f, 0, 0, 0, 0, 0,
+         (fn_t)fetch3x },
+    { 0, (fn_t)fetchExpand4ub, 0, 0, 0, 0,
+         (fn_t)fetch4f, 0, 0, 0, 0, 0,
+         (fn_t)fetch4x },
+};
+static const fn_t color_clamp_fct[2][16] = { // size={3,4}, type={ub,f,x}
+    { 0, (fn_t)fetchExpand3ub, 0, 0, 0, 0,
+         (fn_t)fetchClamp3f, 0, 0, 0, 0, 0,
+         (fn_t)fetchClamp3x },
+    { 0, (fn_t)fetchExpand4ub, 0, 0, 0, 0,
+         (fn_t)fetchClamp4f, 0, 0, 0, 0, 0,
+         (fn_t)fetchClamp4x },
+};
+static const fn_t normal_fct[1][16] = { // size={3}, type={b,s,f,x}
+    { (fn_t)fetchExpand3b, 0,
+      (fn_t)fetchExpand3s, 0, 0, 0,
+      (fn_t)fetch3f, 0, 0, 0, 0, 0,
+      (fn_t)fetch3x },
+};
+static const fn_t vertex_fct[3][16] = { // size={2,3,4}, type={b,s,f,x}
+    { (fn_t)fetch2b, 0,
+      (fn_t)fetch2s, 0, 0, 0,
+      (fn_t)fetch2f, 0, 0, 0, 0, 0,
+      (fn_t)fetch3x },
+    { (fn_t)fetch3b, 0,
+      (fn_t)fetch3s, 0, 0, 0,
+      (fn_t)fetch3f, 0, 0, 0, 0, 0,
+      (fn_t)fetch3x },
+    { (fn_t)fetch4b, 0,
+      (fn_t)fetch4s, 0, 0, 0,
+      (fn_t)fetch4f, 0, 0, 0, 0, 0,
+      (fn_t)fetch4x }
+};
+static const fn_t texture_fct[3][16] = { // size={2,3,4}, type={b,s,f,x}
+    { (fn_t)fetch2b, 0,
+      (fn_t)fetch2s, 0, 0, 0,
+      (fn_t)fetch2f, 0, 0, 0, 0, 0,
+      (fn_t)fetch2x },
+    { (fn_t)fetch3b, 0,
+      (fn_t)fetch3s, 0, 0, 0,
+      (fn_t)fetch3f, 0, 0, 0, 0, 0,
+      (fn_t)fetch3x },
+    { (fn_t)fetch4b, 0,
+      (fn_t)fetch4s, 0, 0, 0,
+      (fn_t)fetch4f, 0, 0, 0, 0, 0,
+      (fn_t)fetch4x }
+};
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark array_t
+#endif
+
+void array_t::init(
+        GLint size, GLenum type, GLsizei stride,
+        const GLvoid *pointer, const buffer_t* bo, GLsizei count)
+{
+    if (!stride) {
+        stride = size;
+        switch (type) {
+        case GL_SHORT:
+        case GL_UNSIGNED_SHORT:
+            stride *= 2;
+            break;
+        case GL_FLOAT:
+        case GL_FIXED:
+            stride *= 4;
+            break;
+        }
+    }
+    this->size = size;
+    this->type = type;
+    this->stride = stride;
+    this->pointer = pointer;
+    this->bo = bo;
+    this->bounds = count;
+}
+
+inline void array_t::resolve() 
+{
+    physical_pointer = (bo) ? (bo->data + uintptr_t(pointer)) : pointer;
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark vertex_cache_t
+#endif
+
+void vertex_cache_t::init()
+{
+    // make sure the size of vertex_t allows cache-line alignment
+    CTA<(sizeof(vertex_t) & 0x1F) == 0> assertAlignedSize;
+
+    const int align = 32;
+    const size_t s = VERTEX_BUFFER_SIZE + VERTEX_CACHE_SIZE;
+    const size_t size = s*sizeof(vertex_t) + align;
+    base = malloc(size);
+    if (base) {
+        memset(base, 0, size);
+        vBuffer = (vertex_t*)((size_t(base) + align - 1) & ~(align-1));
+        vCache = vBuffer + VERTEX_BUFFER_SIZE;
+        sequence = 0;
+    }
+}
+
+void vertex_cache_t::uninit()
+{
+    free(base);
+    base = vBuffer = vCache = 0;
+}
+
+void vertex_cache_t::clear()
+{
+#if VC_CACHE_STATISTICS
+    startTime = systemTime(SYSTEM_TIME_THREAD);
+    total = 0;
+    misses = 0;
+#endif
+
+#if VC_CACHE_TYPE == VC_CACHE_TYPE_LRU
+    vertex_t* v = vBuffer;
+    size_t count = VERTEX_BUFFER_SIZE + VERTEX_CACHE_SIZE;
+    do {
+        v->mru = 0;
+        v++;
+    } while (--count);
+#endif
+
+    sequence += INDEX_SEQ;
+    if (sequence >= 0x80000000LU) {
+        sequence = INDEX_SEQ;
+        vertex_t* v = vBuffer;
+        size_t count = VERTEX_BUFFER_SIZE + VERTEX_CACHE_SIZE;
+        do {
+            v->index = 0;
+            v++;
+        } while (--count);
+    }
+}
+
+void vertex_cache_t::dump_stats(GLenum mode)
+{
+#if VC_CACHE_STATISTICS
+    nsecs_t time = systemTime(SYSTEM_TIME_THREAD) - startTime;
+    uint32_t hits = total - misses;
+    uint32_t prim_count;
+    switch (mode) {
+    case GL_POINTS:             prim_count = total;         break;
+    case GL_LINE_STRIP:         prim_count = total - 1;     break;
+    case GL_LINE_LOOP:          prim_count = total - 1;     break;
+    case GL_LINES:              prim_count = total / 2;     break;
+    case GL_TRIANGLE_STRIP:     prim_count = total - 2;     break;
+    case GL_TRIANGLE_FAN:       prim_count = total - 2;     break;
+    case GL_TRIANGLES:          prim_count = total / 3;     break;
+    default:    return;
+    }
+    printf( "total=%5u, hits=%5u, miss=%5u, hitrate=%3u%%,"
+            " prims=%5u, time=%6u us, prims/s=%d, v/t=%f\n",
+            total, hits, misses, (hits*100)/total,
+            prim_count, int(ns2us(time)), int(prim_count*float(seconds(1))/time),
+            float(misses) / prim_count);
+#endif
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+static __attribute__((noinline))
+void enableDisableClientState(ogles_context_t* c, GLenum array, bool enable)
+{
+    const int tmu = c->arrays.activeTexture;
+    array_t* a;
+    switch (array) {
+    case GL_COLOR_ARRAY:            a = &c->arrays.color;           break;
+    case GL_NORMAL_ARRAY:           a = &c->arrays.normal;          break;
+    case GL_TEXTURE_COORD_ARRAY:    a = &c->arrays.texture[tmu];    break;
+    case GL_VERTEX_ARRAY:           a = &c->arrays.vertex;          break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    a->enable = enable ? GL_TRUE : GL_FALSE;
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Vertex Cache
+#endif
+
+static __attribute__((noinline))
+vertex_t* cache_vertex(ogles_context_t* c, vertex_t* v, uint32_t index)
+{
+    #if VC_CACHE_STATISTICS
+        c->vc.misses++;
+    #endif
+    if (ggl_unlikely(v->locked)) {
+        // we're just looking for an entry in the cache that is not locked.
+        // and we know that there cannot be more than 2 locked entries
+        // because a triangle needs at most 3 vertices.
+        // We never use the first and second entries because they might be in
+        // use by the striper or faner. Any other entry will do as long as
+        // it's not locked.
+        // 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);       
+    }
+    // note: compileElement clears v->flags
+    c->arrays.compileElement(c, v, index);
+    v->locked = 1;
+    return v;
+}
+
+static __attribute__((noinline))
+vertex_t* fetch_vertex(ogles_context_t* c, size_t index)
+{
+    index |= c->vc.sequence;
+
+#if VC_CACHE_TYPE == VC_CACHE_TYPE_INDEXED
+
+    vertex_t* const v = c->vc.vCache + 
+            (index & (vertex_cache_t::VERTEX_CACHE_SIZE-1));
+
+    if (ggl_likely(v->index == index)) {
+        v->locked = 1;
+        return v;
+    }
+    return cache_vertex(c, v, index);
+
+#elif VC_CACHE_TYPE == VC_CACHE_TYPE_LRU
+
+    vertex_t* v = c->vc.vCache + 
+            (index & ((vertex_cache_t::VERTEX_CACHE_SIZE-1)>>1))*2;
+
+    // always record LRU in v[0]
+    if (ggl_likely(v[0].index == index)) {
+        v[0].locked = 1;
+        v[0].mru = 0;
+        return &v[0];
+    }
+
+    if (ggl_likely(v[1].index == index)) {
+        v[1].locked = 1;
+        v[0].mru = 1;
+        return &v[1];
+    }
+
+    const int lru = 1 - v[0].mru;
+    v[0].mru = lru;
+    return cache_vertex(c, &v[lru], index);
+
+#elif VC_CACHE_TYPE == VC_CACHE_TYPE_NONE
+
+    // just for debugging...
+    vertex_t* v = c->vc.vBuffer + 2;
+    return cache_vertex(c, v, index);
+
+#endif
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Primitive Assembly
+#endif
+
+void drawPrimitivesPoints(ogles_context_t* c, GLint first, GLsizei count)
+{
+    if (ggl_unlikely(count < 1))
+        return;
+
+    // vertex cache size must be multiple of 1
+    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; 
+        c->arrays.cull = vertex_t::CLIP_ALL;
+        c->arrays.compileElements(c, v, first, num);
+        first += num;
+        count -= num;
+        if (!c->arrays.cull) {
+            // quick/trivial reject of the whole batch
+            do {
+                const uint32_t cc = v[0].flags;
+                if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+                    c->prims.renderPoint(c, v);
+                v++;
+                num--;
+            } while (num);
+        }
+    } while (count);
+}
+
+// ----------------------------------------------------------------------------
+
+void drawPrimitivesLineStrip(ogles_context_t* c, GLint first, GLsizei count)
+{
+    if (ggl_unlikely(count < 2))
+        return;
+
+    vertex_t *v, *v0, *v1;
+    c->arrays.cull = vertex_t::CLIP_ALL;
+    c->arrays.compileElement(c, c->vc.vBuffer, first);
+    first += 1;
+    count -= 1;
+
+    // vertex cache size must be multiple of 1
+    const GLsizei vcs = 
+        (vertex_cache_t::VERTEX_BUFFER_SIZE +
+         vertex_cache_t::VERTEX_CACHE_SIZE - 1);
+    do {
+        v0 = c->vc.vBuffer + 0; 
+        v  = c->vc.vBuffer + 1;
+        GLsizei num = count > vcs ? vcs : count; 
+        c->arrays.compileElements(c, v, first, num);
+        first += num;
+        count -= num;
+        if (!c->arrays.cull) {
+            // quick/trivial reject of the whole batch
+            do {
+                v1 = v++;
+                const uint32_t cc = v0->flags & v1->flags;
+                if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+                    c->prims.renderLine(c, v0, v1);
+                v0 = v1;
+                num--;
+            } while (num);
+        }
+        // copy back the last processed vertex
+        c->vc.vBuffer[0] = *v0;
+        c->arrays.cull = v0->flags & vertex_t::CLIP_ALL;
+    } while (count);
+}
+
+void drawPrimitivesLineLoop(ogles_context_t* c, GLint first, GLsizei count)
+{
+    if (ggl_unlikely(count < 2))
+        return;
+    drawPrimitivesLineStrip(c, first, count);
+    if (ggl_likely(count >= 3)) {
+        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;
+        if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+            c->prims.renderLine(c, v0, v1);
+    }
+}
+
+void drawPrimitivesLines(ogles_context_t* c, GLint first, GLsizei count)
+{
+    if (ggl_unlikely(count < 2))
+        return;
+
+    // vertex cache size must be multiple of 2
+    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; 
+        c->arrays.cull = vertex_t::CLIP_ALL;
+        c->arrays.compileElements(c, v, first, num);
+        first += num;
+        count -= num;
+        if (!c->arrays.cull) {
+            // quick/trivial reject of the whole batch
+            num -= 2;
+            do {
+                const uint32_t cc = v[0].flags & v[1].flags;
+                if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+                    c->prims.renderLine(c, v, v+1);
+                v += 2;
+                num -= 2;
+            } while (num >= 0);
+        }
+    } while (count >= 2);
+}
+
+// ----------------------------------------------------------------------------
+
+static void drawPrimitivesTriangleFanOrStrip(ogles_context_t* c,
+        GLint first, GLsizei count, int winding)
+{
+    // winding == 2 : fan
+    // winding == 1 : strip
+
+    if (ggl_unlikely(count < 3))
+        return;
+
+    vertex_t *v, *v0, *v1, *v2;
+    c->arrays.cull = vertex_t::CLIP_ALL;
+    c->arrays.compileElements(c, c->vc.vBuffer, first, 2);
+    first += 2;
+    count -= 2;
+
+    // vertex cache size must be multiple of 2. This is extremely important
+    // 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 = 
+        ((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; 
+        v  = c->vc.vBuffer + 2;
+        GLsizei num = count > vcs ? vcs : count; 
+        c->arrays.compileElements(c, v, first, num);
+        first += num;
+        count -= num;
+        if (!c->arrays.cull) {
+            // quick/trivial reject of the whole batch
+            do {
+                v2 = v++;
+                const uint32_t cc = v0->flags & v1->flags & v2->flags;
+                if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+                    c->prims.renderTriangle(c, v0, v1, v2);
+                swap(((winding^=1) ? v1 : v0), v2);
+                num--;
+            } while (num);
+        }
+        if (count) {
+            v0 = c->vc.vBuffer + 2 + num - 2;
+            v1 = c->vc.vBuffer + 2 + num - 1;
+            if ((winding&2) == 0) {
+                // for strips copy back the two last compiled vertices
+                c->vc.vBuffer[0] = *v0;
+            }
+            c->vc.vBuffer[1] = *v1;
+            c->arrays.cull = v0->flags & v1->flags & vertex_t::CLIP_ALL;
+        }
+    } while (count > 0);
+}
+
+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) {
+    drawPrimitivesTriangleFanOrStrip(c, first, count, 2);
+}
+
+void drawPrimitivesTriangles(ogles_context_t* c, GLint first, GLsizei count)
+{
+    if (ggl_unlikely(count < 3))
+        return;
+
+    // vertex cache size must be multiple of 3
+    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; 
+        c->arrays.cull = vertex_t::CLIP_ALL;
+        c->arrays.compileElements(c, v, first, num);
+        first += num;
+        count -= num;
+        if (!c->arrays.cull) {
+            // quick/trivial reject of the whole batch
+            num -= 3;
+            do {
+                const uint32_t cc = v[0].flags & v[1].flags & v[2].flags;
+                if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+                    c->prims.renderTriangle(c, v, v+1, v+2);
+                v += 3;
+                num -= 3;
+            } while (num >= 0);
+        }
+    } while (count >= 3);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+// this looks goofy, but gcc does a great job with this...
+static inline unsigned int read_index(int type, const GLvoid*& p) {
+    unsigned int r;
+    if (type) {
+        r = *(const GLubyte*)p;
+        p = (const GLubyte*)p + 1;
+    } else {
+        r = *(const GLushort*)p;
+        p = (const GLushort*)p + 1;
+    }
+    return r;
+}
+
+// ----------------------------------------------------------------------------
+
+void drawIndexedPrimitivesPoints(ogles_context_t* c,
+        GLsizei count, const GLvoid *indices)
+{
+    if (ggl_unlikely(count < 1))
+        return;
+    const int type = (c->arrays.indicesType == GL_UNSIGNED_BYTE);
+    do {
+        vertex_t * v = fetch_vertex(c, read_index(type, indices));
+        if (ggl_likely(!(v->flags & vertex_t::CLIP_ALL)))
+            c->prims.renderPoint(c, v);
+        v->locked = 0;
+        count--;
+    } while(count);
+}
+
+// ----------------------------------------------------------------------------
+
+void drawIndexedPrimitivesLineStrip(ogles_context_t* c,
+        GLsizei count, const GLvoid *indices)
+{
+    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;
+    do {
+        v1 = fetch_vertex(c, read_index(type, indices));
+        const uint32_t cc = v0->flags & v1->flags;
+        if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+            c->prims.renderLine(c, v0, v1);
+        v0->locked = 0;
+        v0 = v1;
+        count--;
+    } while (count);
+    v1->locked = 0;
+}
+
+void drawIndexedPrimitivesLineLoop(ogles_context_t* c,
+        GLsizei count, const GLvoid *indices)
+{
+    if (ggl_unlikely(count <= 2)) {
+        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;
+    do {
+        v1 = fetch_vertex(c, read_index(type, indices));
+        const uint32_t cc = v0->flags & v1->flags;
+        if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+            c->prims.renderLine(c, v0, v1);
+        v0->locked = 0;
+        v0 = v1;
+        count--;
+    } while (count);
+    v1->locked = 0;
+
+    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);
+}
+
+void drawIndexedPrimitivesLines(ogles_context_t* c,
+        GLsizei count, const GLvoid *indices)
+{
+    if (ggl_unlikely(count < 2))
+        return;
+
+    count -= 2;
+    const int type = (c->arrays.indicesType == GL_UNSIGNED_BYTE);
+    do {
+        vertex_t* const v0 = fetch_vertex(c, read_index(type, indices));
+        vertex_t* const v1 = fetch_vertex(c, read_index(type, indices));
+        const uint32_t cc = v0->flags & v1->flags;
+        if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+            c->prims.renderLine(c, v0, v1);
+        v0->locked = 0;
+        v1->locked = 0;
+        count -= 2;
+    } while (count >= 0);
+}
+
+// ----------------------------------------------------------------------------
+
+static void drawIndexedPrimitivesTriangleFanOrStrip(ogles_context_t* c,
+        GLsizei count, const GLvoid *indices, int winding)
+{
+    // winding == 2 : fan
+    // winding == 1 : strip
+
+    if (ggl_unlikely(count < 3))
+        return;
+    
+    vertex_t * const v = c->vc.vBuffer;
+    vertex_t* v0 = v;
+    vertex_t* v1 = v+1;
+    vertex_t* v2;
+
+    const int type = (c->arrays.indicesType == GL_UNSIGNED_BYTE);
+    c->arrays.compileElement(c, v0, read_index(type, indices));
+    c->arrays.compileElement(c, v1, read_index(type, indices));
+    count -= 2;
+
+    // note: GCC 4.1.1 here makes a prety interesting optimization
+    // where it duplicates the loop below based on c->arrays.indicesType
+
+    do {
+        v2 = fetch_vertex(c, read_index(type, indices));
+        const uint32_t cc = v0->flags & v1->flags & v2->flags;
+        if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+            c->prims.renderTriangle(c, v0, v1, v2);
+        vertex_t* & consumed = ((winding^=1) ? v1 : v0);
+        consumed->locked = 0;
+        consumed = v2;
+        count--;
+    } while (count);
+    v0->locked = v1->locked = 0;
+    v2->locked = 0;
+}
+
+void drawIndexedPrimitivesTriangleStrip(ogles_context_t* c,
+        GLsizei count, const GLvoid *indices) {
+    drawIndexedPrimitivesTriangleFanOrStrip(c, count, indices, 1);
+}
+
+void drawIndexedPrimitivesTriangleFan(ogles_context_t* c,
+        GLsizei count, const GLvoid *indices) {
+    drawIndexedPrimitivesTriangleFanOrStrip(c, count, indices, 2);
+}
+
+void drawIndexedPrimitivesTriangles(ogles_context_t* c,
+        GLsizei count, const GLvoid *indices)
+{
+    if (ggl_unlikely(count < 3))
+        return;
+
+    count -= 3;
+    if (ggl_likely(c->arrays.indicesType == GL_UNSIGNED_SHORT)) {
+        // This case is probably our most common case...
+        uint16_t const * p = (uint16_t const *)indices;
+        do {
+            vertex_t* const v0 = fetch_vertex(c, *p++);
+            vertex_t* const v1 = fetch_vertex(c, *p++);
+            vertex_t* const v2 = fetch_vertex(c, *p++);
+            const uint32_t cc = v0->flags & v1->flags & v2->flags;
+            if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+                c->prims.renderTriangle(c, v0, v1, v2);
+            v0->locked = 0;
+            v1->locked = 0;
+            v2->locked = 0;
+            count -= 3;
+        } while (count >= 0);
+    } else {
+        uint8_t const * p = (uint8_t const *)indices;
+        do {
+            vertex_t* const v0 = fetch_vertex(c, *p++);
+            vertex_t* const v1 = fetch_vertex(c, *p++);
+            vertex_t* const v2 = fetch_vertex(c, *p++);
+            const uint32_t cc = v0->flags & v1->flags & v2->flags;
+            if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
+                c->prims.renderTriangle(c, v0, v1, v2);
+            v0->locked = 0;
+            v1->locked = 0;
+            v2->locked = 0;
+            count -= 3;
+        } while (count >= 0);
+    }
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Array compilers
+#endif
+
+void compileElement__generic(ogles_context_t* c,
+        vertex_t* v, GLint first)
+{
+    v->flags = 0;
+    v->index = first;
+    first &= vertex_cache_t::INDEX_MASK;
+    const GLubyte* vp = c->arrays.vertex.element(first);
+    c->arrays.vertex.fetch(c, v->obj.v, vp);
+    c->arrays.mvp_transform(&c->transforms.mvp, &v->clip, &v->obj);
+    c->arrays.perspective(c, v);
+}
+
+void compileElements__generic(ogles_context_t* c,
+        vertex_t* v, GLint first, GLsizei count)
+{
+    const GLubyte* vp = c->arrays.vertex.element(
+            first & vertex_cache_t::INDEX_MASK);
+    const size_t stride = c->arrays.vertex.stride;
+    transform_t const* const mvp = &c->transforms.mvp;
+    do {
+        v->flags = 0;
+        v->index = first++;
+        c->arrays.vertex.fetch(c, v->obj.v, vp);
+        c->arrays.mvp_transform(mvp, &v->clip, &v->obj);
+        c->arrays.perspective(c, v);
+        vp += stride;
+        v++;
+    } while (--count);
+}
+
+/*
+void compileElements__3x_full(ogles_context_t* c,
+        vertex_t* v, GLint first, GLsizei count)
+{
+    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.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]);
+
+        const GLfixed w = v->clip.w;
+        uint32_t clip = 0;
+        if (v->clip.x < -w)   clip |= vertex_t::CLIP_L;
+        if (v->clip.x >  w)   clip |= vertex_t::CLIP_R;
+        if (v->clip.y < -w)   clip |= vertex_t::CLIP_B;
+        if (v->clip.y >  w)   clip |= vertex_t::CLIP_T;
+        if (v->clip.z < -w)   clip |= vertex_t::CLIP_N;
+        if (v->clip.z >  w)   clip |= vertex_t::CLIP_F;
+        v->flags = clip;
+        c->arrays.cull &= clip;
+
+        //c->arrays.perspective(c, v);
+        v++;
+    } while (--count);
+}
+*/
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark clippers
+#endif
+
+static void clipVec4(vec4_t& nv, 
+        GLfixed t, const vec4_t& s, const vec4_t& p)
+{
+    for (int i=0; i<4 ; i++)
+        nv.v[i] = gglMulAddx(t, s.v[i] - p.v[i], p.v[i], 28);
+}
+
+static void clipVertex(ogles_context_t* c, vertex_t* nv,
+        GLfixed t, const vertex_t* s, const vertex_t* p)
+{
+    clipVec4(nv->clip, t, s->clip, p->clip);
+    nv->fog = gglMulAddx(t, s->fog - p->fog, p->fog, 28);
+    ogles_vertex_project(c, nv);
+    nv->flags |=  vertex_t::LIT | vertex_t::EYE | vertex_t::TT;
+    nv->flags &= ~vertex_t::CLIP_ALL;
+}
+
+static void clipVertexC(ogles_context_t* c, vertex_t* nv,
+        GLfixed t, const vertex_t* s, const vertex_t* p)
+{
+    clipVec4(nv->color, t, s->color, p->color);
+    clipVertex(c, nv, t, s, p);
+}
+
+static void clipVertexT(ogles_context_t* c, vertex_t* nv,
+        GLfixed t, const vertex_t* s, const vertex_t* p)
+{
+    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+        if (c->rasterizer.state.texture[i].enable)
+            clipVec4(nv->texture[i], t, s->texture[i], p->texture[i]);
+    }
+    clipVertex(c, nv, t, s, p);
+}
+
+static void clipVertexAll(ogles_context_t* c, vertex_t* nv,
+        GLfixed t, const vertex_t* s, const vertex_t* p)
+{
+    clipVec4(nv->color, t, s->color, p->color);
+    clipVertexT(c, nv, t, s, p);
+}
+
+static void clipEye(ogles_context_t* c, vertex_t* nv,
+        GLfixed t, const vertex_t* s, const vertex_t* p)
+{
+    nv->clear();
+    c->arrays.clipVertex(c, nv, t, p, s);
+    clipVec4(nv->eye, t, s->eye, p->eye);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+void validate_arrays(ogles_context_t* c, GLenum mode)
+{
+    uint32_t enables = c->rasterizer.state.enables;
+
+    // Perspective correction is not need if Ortho transform, but
+    // the user can still provide the w coordinate manually, so we can't
+    // 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 = 
+        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) {
+    case GL_POINTS:
+        smooth = c->point.smooth;
+        break;
+    case GL_LINES:
+    case GL_LINE_LOOP:
+    case GL_LINE_STRIP:
+        smooth = c->line.smooth;
+        break;
+    }
+    if (((enables & GGL_ENABLE_AA)?1:0) != smooth)
+        c->rasterizer.procs.enableDisable(c, GGL_AA, smooth);
+
+    // set the shade model for this primitive
+    c->rasterizer.procs.shadeModel(c,
+            (mode == GL_POINTS) ? GL_FLAT : c->lighting.shadeModel);
+
+    // compute all the matrices we'll need...
+    uint32_t want =
+            transform_state_t::MVP |
+            transform_state_t::VIEWPORT;
+    if (c->lighting.enable) { // needs normal transforms and eye coords
+        want |= transform_state_t::MVUI;
+        want |= transform_state_t::MODELVIEW;
+    }
+    if (enables & GGL_ENABLE_TMUS) { // needs texture transforms
+        want |= transform_state_t::TEXTURE;
+    }
+    if (c->clipPlanes.enable) { // needs eye coords
+        want |= transform_state_t::MODELVIEW;
+    }
+    ogles_validate_transform(c, want);
+
+    // textures...
+    if (enables & GGL_ENABLE_TMUS)
+        ogles_validate_texture(c);
+
+    // vertex compilers
+    c->arrays.compileElement = compileElement__generic;
+    c->arrays.compileElements = compileElements__generic;
+
+    // vertex transform
+    c->arrays.mvp_transform =
+        c->transforms.mvp.pointv[c->arrays.vertex.size - 2];
+
+    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) {
+            am.vertex.fetch = vertex_fct[am.vertex.size-2][am.vertex.type & 0xF];
+        }
+    }
+
+    if (am.normal.enable) {
+        am.normal.resolve();
+        if (am.normal.bo || am.normal.pointer) {
+            am.normal.fetch = normal_fct[am.normal.size-3][am.normal.type & 0xF];
+        }
+    }
+
+    if (am.color.enable) {
+        am.color.resolve();
+        if (c->lighting.enable) {
+            if (am.color.bo || am.color.pointer) {
+                am.color.fetch = color_fct[am.color.size-3][am.color.type & 0xF];
+            }
+        } else {
+            if (am.color.bo || am.color.pointer) {
+                am.color.fetch = color_clamp_fct[am.color.size-3][am.color.type & 0xF];
+            }
+        }
+    }
+
+    int activeTmuCount = 0;
+    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+        am.texture[i].fetch = currentTexCoord;
+        if (c->rasterizer.state.texture[i].enable) {
+
+            // texture fetchers...
+            if (am.texture[i].enable) {
+                am.texture[i].resolve();
+                if (am.texture[i].bo || am.texture[i].pointer) {
+                    am.texture[i].fetch = texture_fct[am.texture[i].size-2][am.texture[i].type & 0xF];
+                }
+            }
+
+            // texture transform...
+            const int index = c->arrays.texture[i].size - 2;
+            c->arrays.tex_transform[i] =
+                c->transforms.texture[i].transform.pointv[index];
+
+            am.tmu = i;
+            activeTmuCount++;
+        }
+    }
+
+    // pick the vertex-clipper
+    uint32_t clipper = 0;
+    // we must reload 'enables' here
+    enables = c->rasterizer.state.enables;
+    if (enables & GGL_ENABLE_SMOOTH)
+        clipper |= 1;   // we need to interpolate colors
+    if (enables & GGL_ENABLE_TMUS)
+        clipper |= 2;   // we need to interpolate textures
+    switch (clipper) {
+    case 0: c->arrays.clipVertex = clipVertex;      break;
+    case 1: c->arrays.clipVertex = clipVertexC;     break;
+    case 2: c->arrays.clipVertex = clipVertexT;     break;
+    case 3: c->arrays.clipVertex = clipVertexAll;   break;
+    }
+    c->arrays.clipEye = clipEye;
+
+    // pick the primitive rasterizer
+    ogles_validate_primitives(c);
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
+using namespace android;
+
+#if 0
+#pragma mark -
+#pragma mark array API
+#endif
+
+void glVertexPointer(
+    GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (size<2 || size>4 || stride<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    switch (type) {
+    case GL_BYTE:
+    case GL_SHORT:
+    case GL_FIXED:
+    case GL_FLOAT:
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->arrays.vertex.init(size, type, stride, pointer, c->arrays.array_buffer, 0);
+}
+
+void glColorPointer(
+    GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    // in theory ogles doesn't allow color arrays of size 3
+    // but it is very useful to 'visualize' the normal array.
+    if (size<3 || size>4 || stride<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    switch (type) {
+    case GL_UNSIGNED_BYTE:
+    case GL_FIXED:
+    case GL_FLOAT:
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->arrays.color.init(size, type, stride, pointer, c->arrays.array_buffer, 0);
+}
+
+void glNormalPointer(
+    GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (stride<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    switch (type) {
+    case GL_BYTE:
+    case GL_SHORT:
+    case GL_FIXED:
+    case GL_FLOAT:
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->arrays.normal.init(3, type, stride, pointer, c->arrays.array_buffer, 0);
+}
+
+void glTexCoordPointer(
+    GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (size<2 || size>4 || stride<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    switch (type) {
+    case GL_BYTE:
+    case GL_SHORT:
+    case GL_FIXED:
+    case GL_FLOAT:
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    const int tmu = c->arrays.activeTexture;
+    c->arrays.texture[tmu].init(size, type, stride, pointer,
+            c->arrays.array_buffer, 0);
+}
+
+
+void glEnableClientState(GLenum array) {
+    ogles_context_t* c = ogles_context_t::get();
+    enableDisableClientState(c, array, true);
+}
+
+void glDisableClientState(GLenum array) {
+    ogles_context_t* c = ogles_context_t::get();
+    enableDisableClientState(c, array, false);
+}
+
+void glClientActiveTexture(GLenum texture)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (texture<GL_TEXTURE0 || texture>=GL_TEXTURE0+GGL_TEXTURE_UNIT_COUNT) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->arrays.activeTexture = texture - GL_TEXTURE0;
+}
+
+void glDrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (count<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    switch (mode) {
+    case GL_POINTS:
+    case GL_LINE_STRIP:
+    case GL_LINE_LOOP:
+    case GL_LINES:
+    case GL_TRIANGLE_STRIP:
+    case GL_TRIANGLE_FAN:
+    case GL_TRIANGLES:
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+
+    if (count == 0 || !c->arrays.vertex.enable)
+        return;
+    if ((c->cull.enable) && (c->cull.cullFace == GL_FRONT_AND_BACK))
+        return; // all triangles are culled
+
+    validate_arrays(c, mode);
+    drawArraysPrims[mode](c, first, count);
+
+#if VC_CACHE_STATISTICS
+    c->vc.total = count;
+    c->vc.dump_stats(mode);
+#endif
+}
+
+void glDrawElements(
+    GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (count<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    switch (mode) {
+    case GL_POINTS:
+    case GL_LINE_STRIP:
+    case GL_LINE_LOOP:
+    case GL_LINES:
+    case GL_TRIANGLE_STRIP:
+    case GL_TRIANGLE_FAN:
+    case GL_TRIANGLES:
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    switch (type) {
+    case GL_UNSIGNED_BYTE:
+    case GL_UNSIGNED_SHORT:
+        c->arrays.indicesType = type;
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if (count == 0 || !c->arrays.vertex.enable)
+        return;
+    if ((c->cull.enable) && (c->cull.cullFace == GL_FRONT_AND_BACK))
+        return; // all triangles are culled
+
+    // 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) {
+        indices = c->arrays.element_array_buffer->data + uintptr_t(indices);
+    }
+
+    drawElementsPrims[mode](c, count, indices);
+
+#if VC_CACHE_STATISTICS
+    c->vc.total = count;
+    c->vc.dump_stats(mode);
+#endif
+}
+
+// ----------------------------------------------------------------------------
+// buffers
+// ----------------------------------------------------------------------------
+
+void glBindBuffer(GLenum target, GLuint buffer)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if ((target!=GL_ARRAY_BUFFER) && (target!=GL_ELEMENT_ARRAY_BUFFER)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    // create a buffer object, or bind an existing one
+    buffer_t const* bo = 0;
+    if (buffer) {
+        bo = c->bufferObjectManager->bind(buffer);
+        if (!bo) {
+            ogles_error(c, GL_OUT_OF_MEMORY);
+            return;
+        }
+    }
+    ((target == GL_ARRAY_BUFFER) ? 
+            c->arrays.array_buffer : c->arrays.element_array_buffer) = bo;
+}
+
+void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if ((target!=GL_ARRAY_BUFFER) && (target!=GL_ELEMENT_ARRAY_BUFFER)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if (size<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    if ((usage!=GL_STATIC_DRAW) && (usage!=GL_DYNAMIC_DRAW)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    buffer_t const* bo = ((target == GL_ARRAY_BUFFER) ? 
+            c->arrays.array_buffer : c->arrays.element_array_buffer);
+
+    if (bo == 0) {
+        // can't modify buffer 0
+        ogles_error(c, GL_INVALID_OPERATION);
+        return;
+    }
+
+    buffer_t* edit_bo = const_cast<buffer_t*>(bo);
+    if (c->bufferObjectManager->allocateStore(edit_bo, size, usage) != 0) {
+        ogles_error(c, GL_OUT_OF_MEMORY);
+        return;
+    }
+    if (data) {
+        memcpy(bo->data, data, size);
+    }
+}
+
+void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if ((target!=GL_ARRAY_BUFFER) && (target!=GL_ELEMENT_ARRAY_BUFFER)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if (offset<0 || size<0 || data==0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    buffer_t const* bo = ((target == GL_ARRAY_BUFFER) ? 
+            c->arrays.array_buffer : c->arrays.element_array_buffer);
+
+    if (bo == 0) {
+        // can't modify buffer 0
+        ogles_error(c, GL_INVALID_OPERATION);
+        return;
+    }
+    if (offset+size > bo->size) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    memcpy(bo->data + offset, data, size);
+}
+
+void glDeleteBuffers(GLsizei n, const GLuint* buffers)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (n<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+
+    for (int i=0 ; i<n ; i++) {
+        GLuint name = buffers[i];
+        if (name) {
+            // unbind bound deleted buffers...
+            if (c->arrays.element_array_buffer->name == name) {
+                c->arrays.element_array_buffer = 0;
+            }
+            if (c->arrays.array_buffer->name == name) {
+                c->arrays.array_buffer = 0;
+            }
+            if (c->arrays.vertex.bo->name == name) {
+                c->arrays.vertex.bo = 0;
+            }
+            if (c->arrays.normal.bo->name == name) {
+                c->arrays.normal.bo = 0;
+            }
+            if (c->arrays.color.bo->name == name) {
+                c->arrays.color.bo = 0;
+            }
+            for (int t=0 ; t<GGL_TEXTURE_UNIT_COUNT ; t++) {
+                if (c->arrays.texture[t].bo->name == name) {
+                    c->arrays.texture[t].bo = 0;
+                }
+            }
+        }
+    }    
+    c->bufferObjectManager->deleteBuffers(n, buffers);
+    c->bufferObjectManager->recycleTokens(n, buffers);
+}
+
+void glGenBuffers(GLsizei n, GLuint* buffers)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (n<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    c->bufferObjectManager->getToken(n, buffers);
+}
diff --git a/opengl/libagl/array.h b/opengl/libagl/array.h
new file mode 100644
index 0000000..e156978
--- /dev/null
+++ b/opengl/libagl/array.h
@@ -0,0 +1,37 @@
+/* libs/opengles/array.h
+**
+** 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 
+**
+**     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_ARRAY_H
+#define ANDROID_OPENGLES_ARRAY_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+namespace android {
+
+namespace gl {
+struct ogles_context_t;
+};
+
+void ogles_init_array(ogles_context_t* c);
+void ogles_uninit_array(ogles_context_t* c);
+
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_ARRAY_H
+
diff --git a/opengl/libagl/context.h b/opengl/libagl/context.h
new file mode 100644
index 0000000..ef36b56
--- /dev/null
+++ b/opengl/libagl/context.h
@@ -0,0 +1,20 @@
+/* libs/opengles/context.h
+**
+** 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 
+**
+**     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 <private/opengles/gl_context.h>
+
+using namespace android::gl;
diff --git a/opengl/libagl/dxt.cpp b/opengl/libagl/dxt.cpp
new file mode 100644
index 0000000..238c81f
--- /dev/null
+++ b/opengl/libagl/dxt.cpp
@@ -0,0 +1,636 @@
+/* libs/opengles/dxt.cpp
+**
+** 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 
+**
+**     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.
+*/
+
+#define TIMING 0
+
+#if TIMING
+#include <sys/time.h> // for optimization timing
+#include <stdio.h>
+#include <stdlib.h>
+#endif
+
+#include <GLES/gl.h>
+#include <utils/Endian.h>
+
+#include "context.h"
+
+#define TIMING 0
+
+namespace android {
+
+static uint8_t avg23tab[64*64];
+static volatile int tables_initialized = 0;
+
+// Definitions below are equivalent to these over the valid range of arguments
+//  #define div5(x) ((x)/5)
+//  #define div7(x) ((x)/7)
+
+// Use fixed-point to divide by 5 and 7
+// 3277 = 2^14/5 + 1
+// 2341 = 2^14/7 + 1
+#define div5(x) (((x)*3277) >> 14)
+#define div7(x) (((x)*2341) >> 14)
+
+// Table with entry [a << 6 | b] = (2*a + b)/3 for 0 <= a,b < 64
+#define avg23(x0,x1) avg23tab[((x0) << 6) | (x1)]
+
+// Extract 5/6/5 RGB
+#define red(x)   (((x) >> 11) & 0x1f)
+#define green(x) (((x) >>  5) & 0x3f)
+#define blue(x)  ( (x)        & 0x1f)
+
+/*
+ * Convert 5/6/5 RGB (as 3 ints) to 8/8/8
+ *
+ * Operation count: 8 <<, 0 &, 5 |
+ */
+inline static int rgb565SepTo888(int r, int g, int b)
+
+{
+    return ((((r << 3) | (r >> 2)) << 16) |
+            (((g << 2) | (g >> 4)) <<  8) |
+             ((b << 3) | (b >> 2)));
+}
+
+/*
+ * Convert 5/6/5 RGB (as a single 16-bit word) to 8/8/8
+ *
+ *                   r4r3r2r1 r0g5g4g3 g2g1g0b4 b3b2b1b0   rgb
+ *            r4r3r2 r1r0g5g4 g3g2g1g0 b4b3b2b1 b0 0 0 0   rgb << 3
+ * r4r3r2r1 r0r4r3r2 g5g4g3g2 g1g0g5g4 b4b3b2b1 b0b4b3b2   desired result
+ *
+ * Construct the 24-bit RGB word as:
+ *
+ * r4r3r2r1 r0------ -------- -------- -------- --------  (rgb << 8) & 0xf80000
+ *            r4r3r2 -------- -------- -------- --------  (rgb << 3) & 0x070000
+ *                   g5g4g3g2 g1g0---- -------- --------  (rgb << 5) & 0x00fc00
+ *                                g5g4 -------- --------  (rgb >> 1) & 0x000300
+ *                                     b4b3b2b1 b0------  (rgb << 3) & 0x0000f8
+ *                                                b4b3b2  (rgb >> 2) & 0x000007
+ *
+ * Operation count: 5 <<, 6 &, 5 | (n.b. rgb >> 3 is used twice)
+ */
+inline static int rgb565To888(int rgb)
+
+{
+    int rgb3 = rgb >> 3;
+    return (((rgb << 8) & 0xf80000) |
+            ( rgb3      & 0x070000) |
+            ((rgb << 5) & 0x00fc00) |
+            ((rgb >> 1) & 0x000300) |
+            ( rgb3      & 0x0000f8) |
+            ((rgb >> 2) & 0x000007));
+}
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+static uint32_t swap(uint32_t x) {
+    int b0 = (x >> 24) & 0xff;
+    int b1 = (x >> 16) & 0xff;
+    int b2 = (x >>  8) & 0xff;
+    int b3 = (x      ) & 0xff;
+    
+    return (uint32_t)((b3 << 24) | (b2 << 16) | (b1 << 8) | b0);
+}
+#endif
+
+static void
+init_tables()
+{
+    if (tables_initialized) {
+        return;
+    }
+
+    for (int i = 0; i < 64; i++) {
+        for (int j = 0; j < 64; j++) {
+            int avg = (2*i + j)/3;
+            avg23tab[(i << 6) | j] = avg;
+        }
+    }
+
+    asm volatile ("" : : : "memory");
+    tables_initialized = 1;
+}
+
+/*
+ * Utility to scan a DXT1 compressed texture to determine whether it
+ * contains a transparent pixel (color0 < color1, code == 3).  This
+ * may be useful if the application lacks information as to whether
+ * the true format is GL_COMPRESSED_RGB_S3TC_DXT1_EXT or
+ * GL_COMPRESSED_RGBA_S3TC_DXT1_EXT.
+ */
+bool
+DXT1HasAlpha(const GLvoid *data, int width, int height) {    
+#if TIMING
+    struct timeval start_t, end_t;
+    struct timezone tz;
+    
+    gettimeofday(&start_t, &tz);
+#endif
+
+    bool hasAlpha = false;
+
+    int xblocks = (width + 3)/4;
+    int yblocks = (height + 3)/4;
+    int numblocks = xblocks*yblocks;
+
+    uint32_t const *d32 = (uint32_t *)data;
+    for (int b = 0; b < numblocks; b++) {
+        uint32_t colors = *d32++;
+        
+#if __BYTE_ORDER == __BIG_ENDIAN
+        colors = swap(colors);
+#endif
+        
+        uint16_t color0 = colors & 0xffff;
+        uint16_t color1 = colors >> 16;
+        
+        if (color0 < color1) {
+            // There's no need to endian-swap within 'bits'
+            // since we don't care which pixel is the transparent one
+            uint32_t bits = *d32++;
+            
+            // Detect if any (odd, even) pair of bits are '11'
+            //      bits: b31 b30 b29 ... b3 b2 b1 b0
+            // bits >> 1: b31 b31 b30 ... b4 b3 b2 b1
+            //         &: b31 (b31 & b30) (b29 & b28) ... (b2 & b1) (b1 & b0)
+            //  & 0x55..:   0 (b31 & b30)       0     ...     0     (b1 & b0)
+            if (((bits & (bits >> 1)) & 0x55555555) != 0) {
+                hasAlpha = true;
+                goto done;
+            }
+        } else {
+            // Skip 4 bytes
+            ++d32;
+        }
+    }
+    
+ done:
+#if TIMING
+    gettimeofday(&end_t, &tz);
+    long usec = (end_t.tv_sec - start_t.tv_sec)*1000000 +
+        (end_t.tv_usec - start_t.tv_usec);
+    
+    printf("Scanned w=%d h=%d in %ld usec\n", width, height, usec);
+#endif
+    
+    return hasAlpha;
+}
+
+static void
+decodeDXT1(const GLvoid *data, int width, int height,
+           void *surface, int stride,
+           bool hasAlpha)
+    
+{
+    init_tables();
+    
+    uint32_t const *d32 = (uint32_t *)data;
+    
+    // Color table for the current block
+    uint16_t c[4];
+    c[0] = c[1] = c[2] = c[3] = 0;
+    
+    // Specified colors from the previous block
+    uint16_t prev_color0 = 0x0000;
+    uint16_t prev_color1 = 0x0000;
+    
+    uint16_t* rowPtr = (uint16_t*)surface;
+    for (int base_y = 0; base_y < height; base_y += 4, rowPtr += 4*stride) {
+        uint16_t *blockPtr = rowPtr;
+        for (int base_x = 0; base_x < width; base_x += 4, blockPtr += 4) {
+            uint32_t colors = *d32++;
+            uint32_t bits = *d32++;
+            
+#if __BYTE_ORDER == __BIG_ENDIAN
+            colors = swap(colors);
+            bits = swap(bits);
+#endif
+            
+            // Raw colors
+            uint16_t color0 = colors & 0xffff;
+            uint16_t color1 = colors >> 16;
+            
+            // If the new block has the same base colors as the
+            // previous one, we don't need to recompute the color
+            // table c[]
+            if (color0 != prev_color0 || color1 != prev_color1) {
+                // Store raw colors for comparison with next block
+                prev_color0 = color0;
+                prev_color1 = color1;
+                
+                int r0 =   red(color0);
+                int g0 = green(color0);
+                int b0 =  blue(color0);
+
+                int r1 =   red(color1);
+                int g1 = green(color1);
+                int b1 =  blue(color1);                
+                
+                if (hasAlpha) {
+                    c[0] = (r0 << 11) | ((g0 >> 1) << 6) | (b0 << 1) | 0x1;
+                    c[1] = (r1 << 11) | ((g1 >> 1) << 6) | (b1 << 1) | 0x1;
+                } else {
+                    c[0] = color0;
+                    c[1] = color1;
+                }
+                
+                int r2, g2, b2, r3, g3, b3, a3;
+                
+                int bbits = bits >> 1;
+                bool has2 = ((bbits & ~bits) & 0x55555555) != 0;
+                bool has3 = ((bbits &  bits) & 0x55555555) != 0;
+                
+                if (has2 || has3) {
+                    if (color0 > color1) {
+                        r2 = avg23(r0, r1);
+                        g2 = avg23(g0, g1);
+                        b2 = avg23(b0, b1);
+                        
+                        r3 = avg23(r1, r0);
+                        g3 = avg23(g1, g0);
+                        b3 = avg23(b1, b0);
+                        a3 = 1;
+                    } else {
+                        r2 = (r0 + r1) >> 1;
+                        g2 = (g0 + g1) >> 1;
+                        b2 = (b0 + b1) >> 1;
+                        
+                        r3 = g3 = b3 = a3 = 0;
+                    }
+                    if (hasAlpha) {
+                        c[2] = (r2 << 11) | ((g2 >> 1) << 6) |
+                            (b2 << 1) | 0x1;
+                        c[3] = (r3 << 11) | ((g3 >> 1) << 6) |
+                            (b3 << 1) | a3;
+                    } else {
+                        c[2] = (r2 << 11) | (g2 << 5) | b2;
+                        c[3] = (r3 << 11) | (g3 << 5) | b3;
+                    }
+                }
+            }
+            
+            uint16_t* blockRowPtr = blockPtr;
+            for (int y = 0; y < 4; y++, blockRowPtr += stride) {
+                // Don't process rows past the botom
+                if (base_y + y >= height) {
+                    break;
+                }
+                
+                int w = min(width - base_x, 4);
+                for (int x = 0; x < w; x++) {
+                    int code = bits & 0x3;
+                    bits >>= 2;
+                    
+                    blockRowPtr[x] = c[code];
+                }
+            }
+        }
+    }
+}
+    
+// Output data as internalformat=GL_RGBA, type=GL_UNSIGNED_BYTE
+static void
+decodeDXT3(const GLvoid *data, int width, int height,
+           void *surface, int stride)
+
+{
+    init_tables();
+    
+    uint32_t const *d32 = (uint32_t *)data;
+    
+    // Specified colors from the previous block
+    uint16_t prev_color0 = 0x0000;
+    uint16_t prev_color1 = 0x0000;
+
+    // Color table for the current block
+    uint32_t c[4];
+    c[0] = c[1] = c[2] = c[3] = 0;
+
+    uint32_t* rowPtr = (uint32_t*)surface;
+    for (int base_y = 0; base_y < height; base_y += 4, rowPtr += 4*stride) {
+        uint32_t *blockPtr = rowPtr;
+        for (int base_x = 0; base_x < width; base_x += 4, blockPtr += 4) {
+            
+#if __BYTE_ORDER == __BIG_ENDIAN
+            uint32_t alphahi = *d32++;
+            uint32_t alphalo = *d32++;
+            alphahi = swap(alphahi);
+            alphalo = swap(alphalo);
+#else
+            uint32_t alphalo = *d32++;
+            uint32_t alphahi = *d32++;
+#endif
+
+            uint32_t colors = *d32++;
+            uint32_t bits = *d32++;
+            
+#if __BYTE_ORDER == __BIG_ENDIAN
+            colors = swap(colors);
+            bits = swap(bits);
+#endif
+            
+            uint64_t alpha = ((uint64_t)alphahi << 32) | alphalo;
+
+            // Raw colors
+            uint16_t color0 = colors & 0xffff;
+            uint16_t color1 = colors >> 16;
+
+            // If the new block has the same base colors as the
+            // previous one, we don't need to recompute the color
+            // table c[]
+            if (color0 != prev_color0 || color1 != prev_color1) {
+                // Store raw colors for comparison with next block
+                prev_color0 = color0;
+                prev_color1 = color1;
+                
+                int bbits = bits >> 1;
+                bool has2 = ((bbits & ~bits) & 0x55555555) != 0;
+                bool has3 = ((bbits &  bits) & 0x55555555) != 0;
+                
+                if (has2 || has3) {
+                    int r0 =   red(color0);
+                    int g0 = green(color0);
+                    int b0 =  blue(color0);
+                    
+                    int r1 =   red(color1);
+                    int g1 = green(color1);
+                    int b1 =  blue(color1);
+                    
+                    int r2 = avg23(r0, r1);
+                    int g2 = avg23(g0, g1);
+                    int b2 = avg23(b0, b1);
+                    
+                    int r3 = avg23(r1, r0);
+                    int g3 = avg23(g1, g0);
+                    int b3 = avg23(b1, b0);
+
+                    c[0] = rgb565SepTo888(r0, g0, b0);
+                    c[1] = rgb565SepTo888(r1, g1, b1);
+                    c[2] = rgb565SepTo888(r2, g2, b2);
+                    c[3] = rgb565SepTo888(r3, g3, b3);
+                } else {
+                    // Convert to 8 bits
+                    c[0] = rgb565To888(color0);
+                    c[1] = rgb565To888(color1);
+                }
+            }
+
+            uint32_t* blockRowPtr = blockPtr;
+            for (int y = 0; y < 4; y++, blockRowPtr += stride) {
+                // Don't process rows past the botom
+                if (base_y + y >= height) {
+                    break;
+                }
+                
+                int w = min(width - base_x, 4);
+                for (int x = 0; x < w; x++) {
+                    int a = alpha & 0xf;
+                    alpha >>= 4;
+
+                    int code = bits & 0x3;
+                    bits >>= 2;
+
+                    blockRowPtr[x] = c[code] | (a << 28) | (a << 24);
+                }
+            }
+        }
+    }
+}
+
+// Output data as internalformat=GL_RGBA, type=GL_UNSIGNED_BYTE
+static void
+decodeDXT5(const GLvoid *data, int width, int height,
+           void *surface, int stride)
+
+{
+    init_tables();
+    
+    uint32_t const *d32 = (uint32_t *)data;
+    
+    // Specified alphas from the previous block
+    uint8_t prev_alpha0 = 0x00;
+    uint8_t prev_alpha1 = 0x00;
+
+    // Specified colors from the previous block
+    uint16_t prev_color0 = 0x0000;
+     uint16_t prev_color1 = 0x0000;
+
+    // Alpha table for the current block
+    uint8_t a[8];
+    a[0] = a[1] = a[2] = a[3] = a[4] = a[5] = a[6] = a[7] = 0;
+
+    // Color table for the current block
+    uint32_t c[4];
+    c[0] = c[1] = c[2] = c[3] = 0;
+
+    int good_a5 = 0;
+    int bad_a5 = 0;
+    int good_a6 = 0;
+    int bad_a6 = 0;
+    int good_a7 = 0;
+    int bad_a7 = 0;
+
+    uint32_t* rowPtr = (uint32_t*)surface;
+    for (int base_y = 0; base_y < height; base_y += 4, rowPtr += 4*stride) {
+        uint32_t *blockPtr = rowPtr;
+        for (int base_x = 0; base_x < width; base_x += 4, blockPtr += 4) {
+            
+#if __BYTE_ORDER == __BIG_ENDIAN
+            uint32_t alphahi = *d32++;
+            uint32_t alphalo = *d32++;
+            alphahi = swap(alphahi);
+            alphalo = swap(alphalo);
+#else
+             uint32_t alphalo = *d32++;
+             uint32_t alphahi = *d32++;
+#endif
+
+            uint32_t colors = *d32++;
+            uint32_t bits = *d32++;
+            
+#if __BYTE_ORDER == __BIG_ENDIANx
+            colors = swap(colors);
+            bits = swap(bits);
+#endif
+            
+            uint64_t alpha = ((uint64_t)alphahi << 32) | alphalo;
+            uint64_t alpha0 = alpha & 0xff;
+            alpha >>= 8;
+            uint64_t alpha1 = alpha & 0xff;
+            alpha >>= 8;
+
+            if (alpha0 != prev_alpha0 || alpha1 != prev_alpha1) {
+                prev_alpha0 = alpha0;
+                prev_alpha1 = alpha1;
+                
+                a[0] = alpha0;
+                a[1] = alpha1;
+                int a01 = alpha0 + alpha1 - 1;
+                if (alpha0 > alpha1) {
+                    a[2] = div7(6*alpha0 +   alpha1);
+                    a[4] = div7(4*alpha0 + 3*alpha1);
+                    a[6] = div7(2*alpha0 + 5*alpha1);
+
+                    // Use symmetry to derive half of the values
+                    // A few values will be off by 1 (~.5%)
+                    // Alternate which values are computed directly
+                    // and which are derived to try to reduce bias
+                    a[3] = a01 - a[6];
+                    a[5] = a01 - a[4];
+                    a[7] = a01 - a[2];
+                } else {
+                    a[2] = div5(4*alpha0 +   alpha1);
+                    a[4] = div5(2*alpha0 + 3*alpha1);
+                    a[3] = a01 - a[4];
+                    a[5] = a01 - a[2];
+                    a[6] = 0x00;
+                    a[7] = 0xff;
+                }
+            }
+
+            // Raw colors
+            uint16_t color0 = colors & 0xffff;
+            uint16_t color1 = colors >> 16;
+
+            // If the new block has the same base colors as the
+            // previous one, we don't need to recompute the color
+            // table c[]
+            if (color0 != prev_color0 || color1 != prev_color1) {
+                // Store raw colors for comparison with next block
+                prev_color0 = color0;
+                prev_color1 = color1;
+                
+                int bbits = bits >> 1;
+                bool has2 = ((bbits & ~bits) & 0x55555555) != 0;
+                bool has3 = ((bbits &  bits) & 0x55555555) != 0;
+                
+                if (has2 || has3) {
+                    int r0 =   red(color0);
+                    int g0 = green(color0);
+                    int b0 =  blue(color0);
+                    
+                    int r1 =   red(color1);
+                    int g1 = green(color1);
+                    int b1 =  blue(color1);
+                
+                    int r2 = avg23(r0, r1);
+                    int g2 = avg23(g0, g1);
+                    int b2 = avg23(b0, b1);
+                    
+                    int r3 = avg23(r1, r0);
+                    int g3 = avg23(g1, g0);
+                    int b3 = avg23(b1, b0);
+
+                    c[0] = rgb565SepTo888(r0, g0, b0);
+                    c[1] = rgb565SepTo888(r1, g1, b1);
+                    c[2] = rgb565SepTo888(r2, g2, b2);
+                    c[3] = rgb565SepTo888(r3, g3, b3);
+                } else {
+                    // Convert to 8 bits
+                    c[0] = rgb565To888(color0);
+                    c[1] = rgb565To888(color1);
+                }                
+            }
+
+            uint32_t* blockRowPtr = blockPtr;
+            for (int y = 0; y < 4; y++, blockRowPtr += stride) {
+                // Don't process rows past the botom
+                if (base_y + y >= height) {
+                    break;
+                }
+                
+                int w = min(width - base_x, 4);
+                for (int x = 0; x < w; x++) {
+                    int acode = alpha & 0x7;
+                    alpha >>= 3;
+
+                    int code = bits & 0x3;
+                    bits >>= 2;
+
+                    blockRowPtr[x] = c[code] | (a[acode] << 24);
+                }
+            }
+        }
+    }
+}
+   
+/*
+ * Decode a DXT-compressed texture into memory.  DXT textures consist of
+ * a series of 4x4 pixel blocks in left-to-right, top-down order.
+ * The number of blocks is given by ceil(width/4)*ceil(height/4).
+ *
+ * 'data' points to the texture data. 'width' and 'height' indicate the
+ * dimensions of the texture.  We assume width and height are >= 0 but
+ * do not require them to be powers of 2 or divisible by any factor.
+ *
+ * The output is written to 'surface' with each scanline separated by
+ * 'stride' 2- or 4-byte words.
+ *
+ * 'format' indicates the type of compression and must be one of the following:
+ *
+ *   GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ *      The output is written as 5/6/5 opaque RGB (16 bit words).
+ *      8 bytes are read from 'data' for each block.
+ *
+ *   GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
+ *      The output is written as 5/5/5/1 RGBA (16 bit words)
+ *      8 bytes are read from 'data' for each block.
+ *
+ *   GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
+ *   GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
+ *      The output is written as 8/8/8/8 ARGB (32 bit words)
+ *      16 bytes are read from 'data' for each block.
+ */
+void
+decodeDXT(const GLvoid *data, int width, int height,
+          void *surface, int stride, int format)
+{
+#if TIMING
+    struct timeval start_t, end_t;
+    struct timezone tz;
+    
+    gettimeofday(&start_t, &tz);
+#endif
+
+    switch (format) {
+    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+        decodeDXT1(data, width, height, surface, stride, false);
+        break;
+        
+    case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+        decodeDXT1(data, width, height, surface, stride, true);
+        break;
+        
+    case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+        decodeDXT3(data, width, height, surface, stride);
+        break;
+        
+    case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+        decodeDXT5(data, width, height, surface, stride);
+        break;
+    }
+    
+#if TIMING
+    gettimeofday(&end_t, &tz);
+    long usec = (end_t.tv_sec - start_t.tv_sec)*1000000 +
+        (end_t.tv_usec - start_t.tv_usec);
+    
+    printf("Loaded w=%d h=%d in %ld usec\n", width, height, usec);
+#endif
+}
+
+} // namespace android
diff --git a/opengl/libagl/dxt.h b/opengl/libagl/dxt.h
new file mode 100644
index 0000000..d95a36c
--- /dev/null
+++ b/opengl/libagl/dxt.h
@@ -0,0 +1,33 @@
+/* libs/opengles/dxt.h
+**
+** 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 
+**
+**     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_TEXTURE_H
+#define ANDROID_OPENGLES_TEXTURE_H
+
+#include <stdlib.h>
+
+#include <GLES/gl.h>
+
+namespace android {
+
+  bool DXT1HasAlpha(const GLvoid *data, int width, int height);
+  void decodeDXT(const GLvoid *data, int width, int height,
+                 void *surface, int stride, int format);
+
+} // namespace android
+
+#endif // ANDROID_OPENGLES_TEXTURE_H
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
new file mode 100644
index 0000000..854a49e
--- /dev/null
+++ b/opengl/libagl/egl.cpp
@@ -0,0 +1,1513 @@
+/* 
+**
+** 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 
+**
+**     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.
+*/
+
+#define LOG_TAG "EGL"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+
+#include <utils/threads.h>
+
+#include <GLES/egl.h>
+
+#include <pixelflinger/format.h>
+
+#include "context.h"
+#include "state.h"
+#include "texture.h"
+#include "matrix.h"
+
+#undef NELEM
+#define NELEM(x) (sizeof(x)/sizeof(*(x)))
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+const unsigned int NUM_DISPLAYS = 1;
+
+static pthread_mutex_t gInitMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t gErrorKeyMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_key_t gEGLErrorKey = -1;
+#ifndef HAVE_ANDROID_OS
+namespace gl {
+pthread_key_t gGLKey = -1;
+}; // namspace gl
+#endif
+
+template<typename T>
+static T setError(GLint error, T returnValue) {
+    if (ggl_unlikely(gEGLErrorKey == -1)) {
+        pthread_mutex_lock(&gErrorKeyMutex);
+        if (gEGLErrorKey == -1)
+            pthread_key_create(&gEGLErrorKey, NULL);
+        pthread_mutex_unlock(&gErrorKeyMutex);
+    }
+    pthread_setspecific(gEGLErrorKey, (void*)error);
+    return returnValue;
+}
+
+static GLint getError() {
+    if (ggl_unlikely(gEGLErrorKey == -1))
+        return EGL_SUCCESS;
+    GLint error = (GLint)pthread_getspecific(gEGLErrorKey);
+    pthread_setspecific(gEGLErrorKey, (void*)EGL_SUCCESS);
+    return error;
+}
+
+// ----------------------------------------------------------------------------
+
+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;
+    }
+
+    NativeDisplayType   type;
+    volatile int32_t    initialized;
+};
+
+static egl_display_t gDisplays[NUM_DISPLAYS];
+
+egl_display_t& egl_display_t::get_display(EGLDisplay dpy) {
+    return gDisplays[uintptr_t(dpy)-1U];
+}
+
+struct egl_context_t {
+    enum {
+        IS_CURRENT      =   0x00010000,
+        NEVER_CURRENT   =   0x00020000
+    };
+    uint32_t            flags;
+    EGLDisplay          dpy;
+    EGLConfig           config;
+    EGLSurface          read;
+    EGLSurface          draw;
+
+    static inline egl_context_t* context(EGLContext ctx) {
+        ogles_context_t* const gl = static_cast<ogles_context_t*>(ctx);
+        return static_cast<egl_context_t*>(gl->rasterizer.base);
+    }
+};
+
+// ----------------------------------------------------------------------------
+
+struct egl_surface_t
+{
+    enum {
+        PAGE_FLIP = 0x00000001,
+        MAGIC     = 0x31415265
+    };
+
+    uint32_t            magic;
+    EGLDisplay          dpy;
+    EGLConfig           config;
+    EGLContext          ctx;
+
+                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;
+    virtual     EGLint      getHeight() const = 0;
+    virtual     void*       getBits() const = 0;
+
+    virtual     EGLint      getHorizontalResolution() const;
+    virtual     EGLint      getVerticalResolution() const;
+    virtual     EGLint      getRefreshRate() const;
+    virtual     EGLint      getSwapBehavior() const;
+    virtual     EGLBoolean  swapBuffers();
+    virtual     EGLBoolean  swapRectangle(EGLint l, EGLint t, EGLint w, EGLint h);
+protected:
+    GGLSurface              depth;
+};
+
+egl_surface_t::egl_surface_t(EGLDisplay dpy,
+        EGLConfig config,
+        int32_t depthFormat)
+    : magic(0x31415265), dpy(dpy), config(config), ctx(0)
+{
+    depth.version = sizeof(GGLSurface);
+    depth.data = 0;
+    depth.format = depthFormat;
+}
+egl_surface_t::~egl_surface_t()
+{
+    magic = 0;
+    free(depth.data);
+}
+EGLBoolean egl_surface_t::swapBuffers() {
+    return EGL_FALSE;
+}
+EGLBoolean egl_surface_t::swapRectangle(
+        EGLint l, EGLint t, EGLint w, EGLint h) {
+    return EGL_FALSE;
+}
+EGLint egl_surface_t::getHorizontalResolution() const {
+    return (0 * EGL_DISPLAY_SCALING) * (1.0f / 25.4f);
+}
+EGLint egl_surface_t::getVerticalResolution() const {
+    return (0 * EGL_DISPLAY_SCALING) * (1.0f / 25.4f);
+}
+EGLint egl_surface_t::getRefreshRate() const {
+    return (60 * EGL_DISPLAY_SCALING);
+}
+EGLint egl_surface_t::getSwapBehavior() const {
+    return EGL_BUFFER_PRESERVED;
+}
+
+// ----------------------------------------------------------------------------
+
+struct egl_window_surface_t : public egl_surface_t
+{
+    egl_window_surface_t(
+            EGLDisplay dpy, EGLConfig config,
+            int32_t depthFormat,
+            egl_native_window_t* window);
+
+     ~egl_window_surface_t();
+
+    virtual     bool        isValid() const { return nativeWindow->magic == 0x600913; }    
+    virtual     EGLBoolean  swapBuffers();
+    virtual     EGLBoolean  swapRectangle(EGLint l, EGLint t, EGLint w, EGLint h);
+    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     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;
+};
+
+egl_window_surface_t::egl_window_surface_t(EGLDisplay dpy,
+        EGLConfig config,
+        int32_t depthFormat,
+        egl_native_window_t* window)
+    : egl_surface_t(dpy, config, depthFormat), nativeWindow(window)
+{
+    if (depthFormat) {
+        depth.width   = window->width;
+        depth.height  = window->height;
+        depth.stride  = depth.width; // use the width here
+        depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
+        if (depth.data == 0) {
+            setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+            return;
+        }
+    }
+    nativeWindow->incRef(nativeWindow);
+}
+egl_window_surface_t::~egl_window_surface_t() {
+    nativeWindow->decRef(nativeWindow);
+}
+
+EGLBoolean egl_window_surface_t::swapBuffers()
+{
+    uint32_t flags = nativeWindow->swapBuffers(nativeWindow);
+    if (flags & EGL_NATIVES_FLAG_SIZE_CHANGED) {
+        // TODO: we probaly should reset the swap rect here
+        // if the window size has changed
+        //    window->setSwapRectangle(Rect(info.w, info.h));
+        if (depth.data) {
+            free(depth.data);
+            depth.width   = nativeWindow->width;
+            depth.height  = nativeWindow->height;
+            depth.stride  = nativeWindow->stride;
+            depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
+            if (depth.data == 0) {
+                setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+                return EGL_FALSE;
+            }
+        }
+    }
+    return EGL_TRUE;
+}
+
+EGLBoolean egl_window_surface_t::swapRectangle(
+        EGLint l, EGLint t, EGLint w, EGLint h)
+{
+    nativeWindow->setSwapRectangle(nativeWindow, l, t, w, h);
+    return EGL_TRUE;
+}
+EGLBoolean egl_window_surface_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;
+    gl->rasterizer.procs.colorBuffer(gl, &buffer);
+    if (depth.data != gl->rasterizer.state.buffers.depth.data)
+        gl->rasterizer.procs.depthBuffer(gl, &depth);
+    return EGL_TRUE;
+}
+EGLBoolean egl_window_surface_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;
+    gl->rasterizer.procs.readBuffer(gl, &buffer);
+    return EGL_TRUE;
+}
+void* egl_window_surface_t::getBits() const {
+    return (GGLubyte*)nativeWindow->base + nativeWindow->offset;
+}
+EGLint egl_window_surface_t::getHorizontalResolution() const {
+    return (nativeWindow->xdpi * EGL_DISPLAY_SCALING) * (1.0f / 25.4f);
+}
+EGLint egl_window_surface_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_t::getSwapBehavior() const {
+    uint32_t flags = nativeWindow->flags;
+    if (flags & EGL_NATIVES_FLAG_DESTROY_BACKBUFFER)
+        return EGL_BUFFER_DESTROYED;
+    return EGL_BUFFER_PRESERVED;
+}
+
+// ----------------------------------------------------------------------------
+
+struct egl_pixmap_surface_t : public egl_surface_t
+{
+    egl_pixmap_surface_t(
+            EGLDisplay dpy, EGLConfig config,
+            int32_t depthFormat,
+            egl_native_pixmap_t const * pixmap);
+
+    virtual ~egl_pixmap_surface_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;  }
+    virtual     EGLint      getHeight() const   { return nativePixmap.height; }
+    virtual     void*       getBits() const     { return nativePixmap.data; }
+private:
+    egl_native_pixmap_t     nativePixmap;
+};
+
+egl_pixmap_surface_t::egl_pixmap_surface_t(EGLDisplay dpy,
+        EGLConfig config,
+        int32_t depthFormat,
+        egl_native_pixmap_t const * pixmap)
+    : egl_surface_t(dpy, config, depthFormat), nativePixmap(*pixmap)
+{
+    if (depthFormat) {
+        depth.width   = pixmap->width;
+        depth.height  = pixmap->height;
+        depth.stride  = depth.width; // use the width here
+        depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
+        if (depth.data == 0) {
+            setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+            return;
+        }
+    }
+}
+EGLBoolean egl_pixmap_surface_t::bindDrawSurface(ogles_context_t* gl)
+{
+    GGLSurface buffer;
+    buffer.version = sizeof(GGLSurface);
+    buffer.width   = nativePixmap.width;
+    buffer.height  = nativePixmap.height;
+    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);
+    return EGL_TRUE;
+}
+EGLBoolean egl_pixmap_surface_t::bindReadSurface(ogles_context_t* gl)
+{
+    GGLSurface buffer;
+    buffer.version = sizeof(GGLSurface);
+    buffer.width   = nativePixmap.width;
+    buffer.height  = nativePixmap.height;
+    buffer.stride  = nativePixmap.stride;
+    buffer.data    = nativePixmap.data;
+    buffer.format  = nativePixmap.format;
+    gl->rasterizer.procs.readBuffer(gl, &buffer);
+    return EGL_TRUE;
+}
+
+// ----------------------------------------------------------------------------
+
+struct egl_pbuffer_surface_t : public egl_surface_t
+{
+    egl_pbuffer_surface_t(
+            EGLDisplay dpy, EGLConfig config, int32_t depthFormat,
+            int32_t w, int32_t h, int32_t f);
+
+    virtual ~egl_pbuffer_surface_t();
+
+    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;  }
+    virtual     EGLint      getHeight() const   { return pbuffer.height; }
+    virtual     void*       getBits() const     { return pbuffer.data; }
+private:
+    GGLSurface  pbuffer;
+};
+
+egl_pbuffer_surface_t::egl_pbuffer_surface_t(EGLDisplay dpy,
+        EGLConfig config, int32_t depthFormat,
+        int32_t w, int32_t h, int32_t f)
+    : egl_surface_t(dpy, config, depthFormat)
+{
+    size_t size = w*h;
+    switch (f) {
+    case GGL_PIXEL_FORMAT_RGB_565:      size *= 2; break;
+    case GGL_PIXEL_FORMAT_RGBA_8888:    size *= 4; break;
+    default:
+        LOGE("incompatible pixel format for pbuffer (format=%d)", f);
+        pbuffer.data = 0;
+        break;
+    }
+    pbuffer.version = sizeof(GGLSurface);
+    pbuffer.width   = w;
+    pbuffer.height  = h;
+    pbuffer.stride  = w;
+    pbuffer.data    = (GGLubyte*)malloc(size);
+    pbuffer.format  = f;
+    
+    if (depthFormat) {
+        depth.width   = pbuffer.width;
+        depth.height  = pbuffer.height;
+        depth.stride  = depth.width; // use the width here
+        depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
+        if (depth.data == 0) {
+            setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+            return;
+        }
+    }
+}
+egl_pbuffer_surface_t::~egl_pbuffer_surface_t() {
+    free(pbuffer.data);
+}
+EGLBoolean egl_pbuffer_surface_t::bindDrawSurface(ogles_context_t* gl)
+{
+    gl->rasterizer.procs.colorBuffer(gl, &pbuffer);
+    if (depth.data != gl->rasterizer.state.buffers.depth.data)
+        gl->rasterizer.procs.depthBuffer(gl, &depth);
+    return EGL_TRUE;
+}
+EGLBoolean egl_pbuffer_surface_t::bindReadSurface(ogles_context_t* gl)
+{
+    gl->rasterizer.procs.readBuffer(gl, &pbuffer);
+    return EGL_TRUE;
+}
+
+// ----------------------------------------------------------------------------
+
+struct config_pair_t {
+    GLint key;
+    GLint value;
+};
+
+struct configs_t {
+    const config_pair_t* array;
+    int                  size;
+};
+
+struct config_management_t {
+    GLint key;
+    bool (*match)(GLint reqValue, GLint confValue);
+    static bool atLeast(GLint reqValue, GLint confValue) {
+        return (reqValue == EGL_DONT_CARE) || (confValue >= reqValue);
+    }
+    static bool exact(GLint reqValue, GLint confValue) {
+        return (reqValue == EGL_DONT_CARE) || (confValue == reqValue);
+    }
+    static bool mask(GLint reqValue, GLint confValue) {
+        return (confValue & reqValue) == reqValue;
+    }
+};
+
+// ----------------------------------------------------------------------------
+
+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 =
+    "EGL_ANDROID_swap_rectangle"                " "
+    "EGL_ANDROID_copy_front_to_back"            " "
+    "EGL_ANDROID_get_render_buffer_address"
+    ;
+
+// ----------------------------------------------------------------------------
+
+struct extention_map_t {
+    const char * const name;
+    void (*address)(void);
+};
+
+static const extention_map_t gExtentionMap[] = {
+    { "eglSwapRectangleANDROID",            (void(*)())&eglSwapRectangleANDROID },
+    { "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 },
+};
+
+/* 
+ * In the lists below, attributes names MUST be sorted.
+ * Additinnaly, all configs must be sorted according to
+ * the EGL specification.
+ */
+
+static config_pair_t const config_base_attribute_list[] = {
+        { EGL_STENCIL_SIZE,               0                                 },
+        { EGL_CONFIG_CAVEAT,              EGL_SLOW_CONFIG                   },
+        { EGL_LEVEL,                      0                                 },
+        { EGL_MAX_PBUFFER_HEIGHT,         0                                 },
+        { EGL_MAX_PBUFFER_PIXELS,         0                                 },
+        { EGL_MAX_PBUFFER_WIDTH,          0                                 },
+        { EGL_NATIVE_RENDERABLE,          EGL_TRUE                          },
+        { EGL_NATIVE_VISUAL_ID,           0                                 },
+        { EGL_NATIVE_VISUAL_TYPE,         GGL_PIXEL_FORMAT_RGB_565          },
+        { EGL_SAMPLES,                    0                                 },
+        { EGL_SAMPLE_BUFFERS,             0                                 },
+        { EGL_TRANSPARENT_TYPE,           EGL_NONE                          },
+        { EGL_TRANSPARENT_BLUE_VALUE,     0                                 },
+        { EGL_TRANSPARENT_GREEN_VALUE,    0                                 },
+        { EGL_TRANSPARENT_RED_VALUE,      0                                 },
+        { EGL_BIND_TO_TEXTURE_RGBA,       EGL_FALSE                         },
+        { EGL_BIND_TO_TEXTURE_RGB,        EGL_FALSE                         },
+        { EGL_MIN_SWAP_INTERVAL,          1                                 },
+        { EGL_MAX_SWAP_INTERVAL,          4                                 },
+};
+
+// These configs can override the base attribute list
+
+static config_pair_t const config_0_attribute_list[] = {
+        { EGL_BUFFER_SIZE,        16 },
+        { EGL_ALPHA_SIZE,          0 },
+        { EGL_BLUE_SIZE,           5 },
+        { EGL_GREEN_SIZE,          6 },
+        { EGL_RED_SIZE,            5 },
+        { EGL_DEPTH_SIZE,          0 },
+        { EGL_CONFIG_ID,           0 },
+        { EGL_SURFACE_TYPE,        EGL_WINDOW_BIT | EGL_PIXMAP_BIT },
+};
+
+static config_pair_t const config_1_attribute_list[] = {
+        { EGL_BUFFER_SIZE,        16 },
+        { EGL_ALPHA_SIZE,          0 },
+        { EGL_BLUE_SIZE,           5 },
+        { EGL_GREEN_SIZE,          6 },
+        { EGL_RED_SIZE,            5 },
+        { EGL_DEPTH_SIZE,         16 },
+        { EGL_CONFIG_ID,           1 },
+        { EGL_SURFACE_TYPE,        EGL_WINDOW_BIT | EGL_PIXMAP_BIT },
+};
+
+static config_pair_t const config_2_attribute_list[] = {
+        { EGL_BUFFER_SIZE,        32 },
+        { EGL_ALPHA_SIZE,          8 },
+        { EGL_BLUE_SIZE,           8 },
+        { EGL_GREEN_SIZE,          8 },
+        { EGL_RED_SIZE,            8 },
+        { EGL_DEPTH_SIZE,          0 },
+        { EGL_CONFIG_ID,           2 },
+        { EGL_SURFACE_TYPE,        EGL_WINDOW_BIT | EGL_PIXMAP_BIT },
+};
+
+static config_pair_t const config_3_attribute_list[] = {
+        { EGL_BUFFER_SIZE,        32 },
+        { EGL_ALPHA_SIZE,          8 },
+        { EGL_BLUE_SIZE,           8 },
+        { EGL_GREEN_SIZE,          8 },
+        { EGL_RED_SIZE,            8 },
+        { EGL_DEPTH_SIZE,         16 },
+        { EGL_CONFIG_ID,           3 },
+        { EGL_SURFACE_TYPE,        EGL_WINDOW_BIT | EGL_PIXMAP_BIT },
+};
+
+static configs_t const gConfigs[] = {
+        { config_0_attribute_list, NELEM(config_0_attribute_list) },
+        { config_1_attribute_list, NELEM(config_1_attribute_list) },
+        { config_2_attribute_list, NELEM(config_2_attribute_list) },
+        { config_3_attribute_list, NELEM(config_3_attribute_list) },
+};
+
+static config_management_t const gConfigManagement[] = {
+        { EGL_BUFFER_SIZE,                config_management_t::atLeast },
+        { EGL_ALPHA_SIZE,                 config_management_t::atLeast },
+        { EGL_BLUE_SIZE,                  config_management_t::atLeast },
+        { EGL_GREEN_SIZE,                 config_management_t::atLeast },
+        { EGL_RED_SIZE,                   config_management_t::atLeast },
+        { EGL_DEPTH_SIZE,                 config_management_t::atLeast },
+        { EGL_STENCIL_SIZE,               config_management_t::atLeast },
+        { EGL_CONFIG_CAVEAT,              config_management_t::exact   },
+        { EGL_CONFIG_ID,                  config_management_t::exact   },
+        { EGL_LEVEL,                      config_management_t::exact   },
+        { EGL_MAX_PBUFFER_HEIGHT,         config_management_t::exact   },
+        { EGL_MAX_PBUFFER_PIXELS,         config_management_t::exact   },
+        { EGL_MAX_PBUFFER_WIDTH,          config_management_t::exact   },
+        { EGL_NATIVE_RENDERABLE,          config_management_t::exact   },
+        { EGL_NATIVE_VISUAL_ID,           config_management_t::exact   },
+        { EGL_NATIVE_VISUAL_TYPE,         config_management_t::exact   },
+        { EGL_SAMPLES,                    config_management_t::exact   },
+        { EGL_SAMPLE_BUFFERS,             config_management_t::exact   },
+        { EGL_SURFACE_TYPE,               config_management_t::mask    },
+        { EGL_TRANSPARENT_TYPE,           config_management_t::exact   },
+        { EGL_TRANSPARENT_BLUE_VALUE,     config_management_t::exact   },
+        { EGL_TRANSPARENT_GREEN_VALUE,    config_management_t::exact   },
+        { EGL_TRANSPARENT_RED_VALUE,      config_management_t::exact   },
+        { EGL_BIND_TO_TEXTURE_RGBA,       config_management_t::exact   },
+        { EGL_BIND_TO_TEXTURE_RGB,        config_management_t::exact   },
+        { EGL_MIN_SWAP_INTERVAL,          config_management_t::exact   },
+        { EGL_MAX_SWAP_INTERVAL,          config_management_t::exact   },
+};
+
+static config_pair_t const config_defaults[] = {
+        { EGL_SURFACE_TYPE,        EGL_WINDOW_BIT },
+};
+
+// ----------------------------------------------------------------------------
+
+template<typename T>
+static int binarySearch(T const sortedArray[], int first, int last, EGLint key)
+{
+   while (first <= last) {
+       int mid = (first + last) / 2;
+       if (key > sortedArray[mid].key) { 
+           first = mid + 1;
+       } else if (key < sortedArray[mid].key) { 
+           last = mid - 1;
+       } else {
+           return mid;
+       }
+   }
+   return -1;
+}
+
+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; 
+    int index = binarySearch<config_pair_t>(
+            gConfigs[i].array,
+            0, gConfigs[i].size-1,
+            attr);
+    if (index < 0) {
+        configFound = config_base_attribute_list; 
+        index = binarySearch<config_pair_t>(
+                config_base_attribute_list,
+                0, NELEM(config_base_attribute_list)-1,
+                attr);
+    }
+    if (index >= 0) {
+        // attribute found, check if this config could match
+        int cfgMgtIndex = binarySearch<config_management_t>(
+                gConfigManagement,
+                0, NELEM(gConfigManagement)-1,
+                attr);
+        if (index >= 0) {
+            bool match = gConfigManagement[cfgMgtIndex].match(
+                    val, configFound[index].value);
+            if (match) {
+                // this config matches
+                return 1;
+            }
+        } else {
+            // attribute nont found. this should NEVER happen.
+        }
+    } else {
+        // error, this attribute doesn't exist
+    }
+    return 0;
+}
+
+static int makeCurrent(ogles_context_t* gl)
+{
+    ogles_context_t* current = (ogles_context_t*)getGlThreadSpecific();
+    if (gl) {
+        egl_context_t* c = egl_context_t::context(gl);
+        if (c->flags & egl_context_t::IS_CURRENT) {
+            if (current != gl) {
+                // it is an error to set a context current, if it's already
+                // current to another thread
+                return -1;
+            }
+        } else {
+            if (current) {
+                // mark the current context as not current, and flush
+                glFlush();
+                egl_context_t::context(current)->flags &= ~egl_context_t::IS_CURRENT;
+            }
+        }
+        if (!(c->flags & egl_context_t::IS_CURRENT)) {
+            // The context is not current, make it current!
+            setGlThreadSpecific(gl);
+            c->flags |= egl_context_t::IS_CURRENT;
+        }
+    } else {
+        if (current) {
+            // mark the current context as not current, and flush
+            glFlush();
+            egl_context_t::context(current)->flags &= ~egl_context_t::IS_CURRENT;
+        }
+        // this thread has no context attached to it
+        setGlThreadSpecific(0);
+    }
+    return 0;
+}
+
+static EGLBoolean getConfigAttrib(EGLDisplay dpy, EGLConfig config,
+        EGLint attribute, EGLint *value)
+{
+    size_t numConfigs =  NELEM(gConfigs);
+    int index = (int)config;
+    if (uint32_t(index) >= numConfigs)
+        return setError(EGL_BAD_CONFIG, EGL_FALSE);
+
+    int attrIndex;
+    attrIndex = binarySearch<config_pair_t>(
+            gConfigs[index].array,
+            0, gConfigs[index].size-1,
+            attribute);
+    if (attrIndex>=0) {
+        *value = gConfigs[index].array[attrIndex].value;
+        return EGL_TRUE;
+    }
+
+    attrIndex = binarySearch<config_pair_t>(
+            config_base_attribute_list,
+            0, NELEM(config_base_attribute_list)-1,
+            attribute);
+    if (attrIndex>=0) {
+        *value = config_base_attribute_list[attrIndex].value;
+        return EGL_TRUE;
+    }
+    return setError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+}
+
+static EGLSurface createWindowSurface(EGLDisplay dpy, EGLConfig config,
+        NativeWindowType window, const EGLint *attrib_list)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
+    if (window == 0)
+        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+
+    EGLint surfaceType;
+    if (getConfigAttrib(dpy, config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE)
+        return EGL_FALSE;
+
+    if (!(surfaceType & EGL_WINDOW_BIT))
+        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+
+    EGLint configID;
+    if (getConfigAttrib(dpy, config, EGL_CONFIG_ID, &configID) == EGL_FALSE)
+        return EGL_FALSE;
+
+    int32_t depthFormat;
+    int32_t pixelFormat;
+    switch(configID) {
+    case 0: 
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+        depthFormat = 0;
+        break;
+    case 1:
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+        depthFormat = GGL_PIXEL_FORMAT_Z_16;
+        break;
+    case 2:
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        depthFormat = 0;
+        break;
+    case 3:
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        depthFormat = GGL_PIXEL_FORMAT_Z_16;
+        break;
+    default:
+        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+    }
+
+    // XXX: we don't have access to the pixelFormat here just yet.
+    // (it's possible that the surface is not fully initialized)
+    // maybe this should be done after the page-flip
+    //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));
+
+    if (!surface->isValid()) {
+        // there was a problem in the ctor, the error
+        // flag has been set.
+        delete surface;
+        surface = 0;
+    }
+    return surface;
+}
+
+static EGLSurface createPixmapSurface(EGLDisplay dpy, EGLConfig config,
+        NativePixmapType pixmap, const EGLint *attrib_list)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
+    if (pixmap == 0)
+        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+
+    EGLint surfaceType;
+    if (getConfigAttrib(dpy, config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE)
+        return EGL_FALSE;
+
+    if (!(surfaceType & EGL_PIXMAP_BIT))
+        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+
+    EGLint configID;
+    if (getConfigAttrib(dpy, config, EGL_CONFIG_ID, &configID) == EGL_FALSE)
+        return EGL_FALSE;
+
+    int32_t depthFormat;
+    int32_t pixelFormat;
+    switch(configID) {
+    case 0: 
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+        depthFormat = 0;
+        break;
+    case 1:
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+        depthFormat = GGL_PIXEL_FORMAT_Z_16;
+        break;
+    case 2:
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        depthFormat = 0;
+        break;
+    case 3:
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        depthFormat = GGL_PIXEL_FORMAT_Z_16;
+        break;
+    default:
+        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+    }
+
+    if (pixmap->format != pixelFormat)
+        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+
+    egl_surface_t* surface =
+        new egl_pixmap_surface_t(dpy, config, depthFormat,
+                static_cast<egl_native_pixmap_t*>(pixmap));
+
+    if (!surface->isValid()) {
+        // there was a problem in the ctor, the error
+        // flag has been set.
+        delete surface;
+        surface = 0;
+    }
+    return surface;
+}
+
+static EGLSurface createPbufferSurface(EGLDisplay dpy, EGLConfig config,
+        const EGLint *attrib_list)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
+
+    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;
+
+    int32_t depthFormat;
+    int32_t pixelFormat;
+    switch(configID) {
+    case 0: 
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+        depthFormat = 0;
+        break;
+    case 1:
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+        depthFormat = GGL_PIXEL_FORMAT_Z_16;
+        break;
+    case 2:
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        depthFormat = 0;
+        break;
+    case 3:
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        depthFormat = GGL_PIXEL_FORMAT_Z_16;
+        break;
+    default:
+        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
+    }
+
+    int32_t w = 0;
+    int32_t h = 0;
+    while (attrib_list[0]) {
+        if (attrib_list[0] == EGL_WIDTH)  w = attrib_list[1];
+        if (attrib_list[0] == EGL_HEIGHT) h = attrib_list[1];
+        attrib_list+=2;
+    }
+
+    egl_surface_t* surface =
+        new egl_pbuffer_surface_t(dpy, config, depthFormat, w, h, pixelFormat);
+
+    if (!surface->isValid()) {
+        // there was a problem in the ctor, the error
+        // flag has been set.
+        delete surface;
+        surface = 0;
+    }
+    return surface;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
+using namespace android;
+
+// ----------------------------------------------------------------------------
+// Initialization
+// ----------------------------------------------------------------------------
+
+EGLDisplay eglGetDisplay(NativeDisplayType display)
+{
+#ifndef HAVE_ANDROID_OS
+    // this just needs to be done once
+    if (gGLKey == -1) {
+        pthread_mutex_lock(&gInitMutex);
+        if (gGLKey == -1)
+            pthread_key_create(&gGLKey, NULL);
+        pthread_mutex_unlock(&gInitMutex);
+    }
+#endif
+    if (display == EGL_DEFAULT_DISPLAY) {
+        EGLDisplay dpy = (EGLDisplay)1;
+        egl_display_t& d = egl_display_t::get_display(dpy);
+        d.type = display;
+        return dpy;
+    }    
+    return EGL_NO_DISPLAY;
+}
+
+EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+    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);
+        //pthread_mutex_unlock(&gInitMutex);
+    }
+
+    if (res == EGL_TRUE) {
+        if (major != NULL) *major = 1;
+        if (minor != NULL) *minor = 2;
+    }
+    return res;
+}
+
+EGLBoolean eglTerminate(EGLDisplay dpy)
+{
+    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_dec(&d.initialized) == 1) {
+        // TODO: destroy all resources (surfaces, contextes, etc...)
+        //pthread_mutex_lock(&gInitMutex);
+        //pthread_mutex_unlock(&gInitMutex);
+    }
+    return res;
+}
+
+// ----------------------------------------------------------------------------
+// configuration
+// ----------------------------------------------------------------------------
+
+EGLBoolean eglGetConfigs(   EGLDisplay dpy,
+                            EGLConfig *configs,
+                            EGLint config_size, EGLint *num_config)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+    GLint numConfigs = NELEM(gConfigs);
+    if (!configs) {
+        *num_config = numConfigs;
+        return EGL_TRUE;
+    }
+    GLint i;
+    for (i=0 ; i<numConfigs && i<config_size ; i++) {
+        *configs++ = (EGLConfig)i;
+    }
+    *num_config = i;
+    return EGL_TRUE;
+}
+
+EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list,
+                            EGLConfig *configs, EGLint config_size,
+                            EGLint *num_config)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+    if (ggl_unlikely(configs==0 || attrib_list==0)) {
+        *num_config = 0;
+        return EGL_TRUE;
+    }
+    
+    int numAttributes = 0;
+    int numConfigs =  NELEM(gConfigs);
+    uint32_t possibleMatch = (1<<numConfigs)-1;
+    while(possibleMatch && *attrib_list != EGL_NONE) {
+        numAttributes++;
+        EGLint attr = *attrib_list++;
+        EGLint val  = *attrib_list++;
+        for (int i=0 ; i<numConfigs ; i++) {
+            if (!(possibleMatch & (1<<i)))
+                continue;
+            if (isAttributeMatching(i, attr, val) == 0) {
+                possibleMatch &= ~(1<<i);
+            }
+        }
+    }
+
+    // now, handle the attributes which have a useful default value
+    for (size_t j=0 ; j<NELEM(config_defaults) ; j++) {
+        // see if this attribute was specified, if not apply its
+        // default value
+        if (binarySearch<config_pair_t>(
+                (config_pair_t const*)attrib_list,
+                0, numAttributes,
+                config_defaults[j].key) < 0)
+        {
+            for (int i=0 ; i<numConfigs ; i++) {
+                if (!(possibleMatch & (1<<i)))
+                    continue;
+                if (isAttributeMatching(i,
+                        config_defaults[j].key,
+                        config_defaults[j].value) == 0)
+                {
+                    possibleMatch &= ~(1<<i);
+                }
+            }
+        }
+    }
+
+    // return the configurations found
+    int n=0;
+    if (possibleMatch) {
+        for (int i=0 ; config_size && i<numConfigs ; i++) {
+            if (possibleMatch & (1<<i)) {
+               *configs++ = (EGLConfig)i;
+                config_size--;
+                n++;
+            }
+        }
+    }
+    *num_config = n;
+     return EGL_TRUE;
+}
+
+EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
+        EGLint attribute, EGLint *value)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+    return getConfigAttrib(dpy, config, attribute, value);
+}
+
+// ----------------------------------------------------------------------------
+// surfaces
+// ----------------------------------------------------------------------------
+
+EGLSurface eglCreateWindowSurface(  EGLDisplay dpy, EGLConfig config,
+                                    NativeWindowType window,
+                                    const EGLint *attrib_list)
+{
+    return createWindowSurface(dpy, config, window, attrib_list);
+}
+    
+EGLSurface eglCreatePixmapSurface(  EGLDisplay dpy, EGLConfig config,
+                                    NativePixmapType pixmap,
+                                    const EGLint *attrib_list)
+{
+    return createPixmapSurface(dpy, config, pixmap, attrib_list);
+}
+
+EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config,
+                                    const EGLint *attrib_list)
+{
+    // none of our configs support pbuffers
+    // (in fact it's working but since we can't use them as 
+    // textures yet, it's not useful at all)
+    //createPbufferSurface(dpy, config, attrib_list);
+    return EGL_NO_SURFACE;
+}
+                                    
+EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface eglSurface)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    if (eglSurface != EGL_NO_SURFACE) {
+        egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) );
+        if (surface->magic != egl_surface_t::MAGIC)
+            return setError(EGL_BAD_SURFACE, EGL_FALSE);
+        if (surface->dpy != dpy)
+            return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+        delete surface;
+    }
+    return EGL_TRUE;
+}
+
+EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface eglSurface,
+                            EGLint attribute, EGLint *value)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    egl_surface_t* surface = static_cast<egl_surface_t*>(eglSurface);
+    if (surface->dpy != dpy)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+    EGLBoolean ret = EGL_TRUE;
+    switch (attribute) {
+        case EGL_CONFIG_ID:
+            ret = getConfigAttrib(dpy, surface->config, EGL_CONFIG_ID, value);
+            break;
+        case EGL_WIDTH:
+            *value = surface->getWidth();
+            break;
+        case EGL_HEIGHT:
+            *value = surface->getHeight();
+            break;
+        case EGL_LARGEST_PBUFFER:
+            // not modified for a window or pixmap surface
+            break;
+        case EGL_TEXTURE_FORMAT:
+            *value = EGL_NO_TEXTURE;
+            break;
+        case EGL_TEXTURE_TARGET:
+            *value = EGL_NO_TEXTURE;
+            break;
+        case EGL_MIPMAP_TEXTURE:
+            *value = EGL_FALSE;
+            break;
+        case EGL_MIPMAP_LEVEL:
+            *value = 0;
+            break;
+        case EGL_RENDER_BUFFER:
+            // TODO: return the real RENDER_BUFFER here
+            *value = EGL_BACK_BUFFER;
+            break;
+        case EGL_HORIZONTAL_RESOLUTION:
+            // pixel/mm * EGL_DISPLAY_SCALING
+            *value = surface->getHorizontalResolution();
+            break;
+        case EGL_VERTICAL_RESOLUTION:
+            // pixel/mm * EGL_DISPLAY_SCALING
+            *value = surface->getVerticalResolution();
+            break;
+        case EGL_PIXEL_ASPECT_RATIO: {
+            // w/h * EGL_DISPLAY_SCALING
+            int wr = surface->getHorizontalResolution();
+            int hr = surface->getVerticalResolution();
+            *value = (wr * EGL_DISPLAY_SCALING) / hr;
+        } break;
+        case EGL_SWAP_BEHAVIOR:
+            *value = surface->getSwapBehavior(); 
+            break;
+        default:
+            ret = setError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+    }
+    return ret;
+}
+
+EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
+                            EGLContext share_list, const EGLint *attrib_list)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
+
+    ogles_context_t* gl = ogles_init(sizeof(egl_context_t));
+    if (!gl) return setError(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
+
+    egl_context_t* c = static_cast<egl_context_t*>(gl->rasterizer.base);
+    c->flags = egl_context_t::NEVER_CURRENT;
+    c->dpy = dpy;
+    c->config = config;
+    c->read = 0;
+    c->draw = 0;
+    return (EGLContext)gl;
+}
+
+EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    egl_context_t* c = egl_context_t::context(ctx);
+    if (c->flags & egl_context_t::IS_CURRENT)
+        setGlThreadSpecific(0);
+    ogles_uninit((ogles_context_t*)ctx);
+    return EGL_TRUE;
+}
+
+EGLBoolean eglMakeCurrent(  EGLDisplay dpy, EGLSurface draw,
+                            EGLSurface read, EGLContext ctx)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    if (draw) {
+        egl_surface_t* s = (egl_surface_t*)draw;
+        if (s->dpy != dpy)
+            return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+        // TODO: check that draw and read are compatible with the context
+    }
+
+    EGLContext current_ctx = EGL_NO_CONTEXT;
+    if (ctx == EGL_NO_CONTEXT) {
+        // if we're detaching, we need the current context
+        current_ctx = (EGLContext)getGlThreadSpecific();
+    } else {
+        egl_context_t* c = egl_context_t::context(ctx);
+        egl_surface_t* d = (egl_surface_t*)draw;
+        egl_surface_t* r = (egl_surface_t*)read;
+        if ((d && d->ctx && d->ctx != ctx) ||
+            (r && r->ctx && r->ctx != ctx)) {
+            // once of the surface is bound to a context in another thread
+            return setError(EGL_BAD_ACCESS, EGL_FALSE);
+        }
+    }
+
+    ogles_context_t* gl = (ogles_context_t*)ctx;
+    if (makeCurrent(gl) == 0) {
+        if (ctx) {
+            egl_context_t* c = egl_context_t::context(ctx);
+            egl_surface_t* d = (egl_surface_t*)draw;
+            egl_surface_t* r = (egl_surface_t*)read;
+            c->read = read;
+            c->draw = draw;
+            if (c->flags & egl_context_t::NEVER_CURRENT) {
+                c->flags &= ~egl_context_t::NEVER_CURRENT;
+                GLint w = 0;
+                GLint h = 0;
+                if (draw) {
+                    w = d->getWidth();
+                    h = d->getHeight();
+                }
+                ogles_surfaceport(gl, 0, 0);
+                ogles_viewport(gl, 0, 0, w, h);
+                ogles_scissor(gl, 0, 0, w, h);
+            }
+            if (d) {
+                d->ctx = ctx;
+                d->bindDrawSurface(gl);
+            }
+            if (r) {
+                r->ctx = ctx;
+                r->bindReadSurface(gl);
+            }
+        } else {
+            // if surfaces were bound to the context bound to this thread
+            // mark then as unbound.
+            if (current_ctx) {
+                egl_context_t* c = egl_context_t::context(current_ctx);
+                egl_surface_t* d = (egl_surface_t*)c->draw;
+                egl_surface_t* r = (egl_surface_t*)c->read;
+                if (d) d->ctx = EGL_NO_CONTEXT;
+                if (r) r->ctx = EGL_NO_CONTEXT;
+            }
+        }
+        return EGL_TRUE;
+    }
+    return setError(EGL_BAD_ACCESS, EGL_FALSE);
+}
+
+EGLContext eglGetCurrentContext(void)
+{
+    // eglGetCurrentContext returns the current EGL rendering context,
+    // as specified by eglMakeCurrent. If no context is current,
+    // EGL_NO_CONTEXT is returned.
+    return (EGLContext)getGlThreadSpecific();
+}
+
+EGLSurface eglGetCurrentSurface(EGLint readdraw)
+{
+    // eglGetCurrentSurface returns the read or draw surface attached
+    // to the current EGL rendering context, as specified by eglMakeCurrent.
+    // If no context is current, EGL_NO_SURFACE is returned.
+    EGLContext ctx = (EGLContext)getGlThreadSpecific();
+    if (ctx == EGL_NO_CONTEXT) return EGL_NO_SURFACE;
+    egl_context_t* c = egl_context_t::context(ctx);
+    if (readdraw == EGL_READ) {
+        return c->read;
+    } else if (readdraw == EGL_DRAW) {
+        return c->draw;
+    }
+    return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+}
+
+EGLDisplay eglGetCurrentDisplay(void)
+{
+    // eglGetCurrentDisplay returns the current EGL display connection
+    // for the current EGL rendering context, as specified by eglMakeCurrent.
+    // If no context is current, EGL_NO_DISPLAY is returned.
+    EGLContext ctx = (EGLContext)getGlThreadSpecific();
+    if (ctx == EGL_NO_CONTEXT) return EGL_NO_DISPLAY;
+    egl_context_t* c = egl_context_t::context(ctx);
+    return c->dpy;
+}
+
+EGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx,
+                            EGLint attribute, EGLint *value)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    egl_context_t* c = egl_context_t::context(ctx);
+    switch (attribute) {
+        case EGL_CONFIG_ID:
+            // Returns the ID of the EGL frame buffer configuration with
+            // respect to which the context was created
+            return getConfigAttrib(dpy, c->config, EGL_CONFIG_ID, value);
+    }
+    return setError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+}
+
+EGLBoolean eglWaitGL(void)
+{
+    return EGL_TRUE;
+}
+
+EGLBoolean eglWaitNative(EGLint engine)
+{
+    return EGL_TRUE;
+}
+
+EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
+{
+    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);
+
+    // post the surface
+    d->swapBuffers();
+
+    // if it's bound to a context, update the buffer
+    if (d->ctx != EGL_NO_CONTEXT) {
+        d->bindDrawSurface((ogles_context_t*)d->ctx);
+        // if this surface is also the read surface of the context
+        // it is bound to, make sure to update the read buffer as well.
+        // The EGL spec is a little unclear about this.
+        egl_context_t* c = egl_context_t::context(d->ctx);
+        if (c->read == draw) {
+            d->bindReadSurface((ogles_context_t*)d->ctx);
+        }
+    }
+
+    return EGL_TRUE;
+}
+
+EGLBoolean eglCopyBuffers(  EGLDisplay dpy, EGLSurface surface,
+                            NativePixmapType target)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    // TODO: eglCopyBuffers()
+    return EGL_FALSE;
+}
+
+EGLint eglGetError(void)
+{
+    return getError();
+}
+
+const char* eglQueryString(EGLDisplay dpy, EGLint name)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, (const char*)0);
+
+    switch (name) {
+        case EGL_VENDOR:
+            return gVendorString;
+        case EGL_VERSION:
+            return gVersionString;
+        case EGL_EXTENSIONS:
+            return gExtensionsString;
+        case EGL_CLIENT_APIS:
+            return gClientApiString;
+    }
+    return setError(EGL_BAD_PARAMETER, (const char *)0);
+}
+
+// ----------------------------------------------------------------------------
+// EGL 1.1
+// ----------------------------------------------------------------------------
+
+EGLBoolean eglSurfaceAttrib(
+        EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    // TODO: eglSurfaceAttrib()
+    return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+}
+
+EGLBoolean eglBindTexImage(
+        EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    // TODO: eglBindTexImage()
+    return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+}
+
+EGLBoolean eglReleaseTexImage(
+        EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    // TODO: eglReleaseTexImage()
+    return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+}
+
+EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    // TODO: eglSwapInterval()
+    return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+}
+
+// ----------------------------------------------------------------------------
+// EGL 1.2
+// ----------------------------------------------------------------------------
+
+EGLBoolean eglBindAPI(EGLenum api)
+{
+    if (api != EGL_OPENGL_ES_API)
+        return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+    return EGL_TRUE;
+}
+
+EGLenum eglQueryAPI(void)
+{
+    return EGL_OPENGL_ES_API;
+}
+
+EGLBoolean eglWaitClient(void)
+{
+    glFinish();
+    return EGL_TRUE;
+}
+
+EGLBoolean eglReleaseThread(void)
+{
+    // TODO: eglReleaseThread()
+    return EGL_TRUE;
+}
+
+EGLSurface eglCreatePbufferFromClientBuffer(
+          EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
+          EGLConfig config, const EGLint *attrib_list)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
+    // TODO: eglCreatePbufferFromClientBuffer()
+    return setError(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+}
+
+// ----------------------------------------------------------------------------
+// Android extentions
+// ----------------------------------------------------------------------------
+
+void (*eglGetProcAddress (const char *procname))()
+{
+    extention_map_t const * const map = gExtentionMap;
+    for (uint32_t i=0 ; i<NELEM(gExtentionMap) ; i++) {
+        if (!strcmp(procname, map[i].name)) {
+            return map[i].address;
+        }
+    }
+    return NULL;
+}
+
+EGLBoolean eglSwapRectangleANDROID(
+        EGLDisplay dpy, EGLSurface draw,
+        EGLint l, EGLint t, EGLint w, EGLint h)
+{    
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    egl_surface_t* surface = (egl_surface_t*)draw;
+    if (surface->dpy != dpy)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    return surface->swapRectangle(l, t, w, h);
+}
diff --git a/opengl/libagl/fixed_asm.S b/opengl/libagl/fixed_asm.S
new file mode 100644
index 0000000..6cbc56f
--- /dev/null
+++ b/opengl/libagl/fixed_asm.S
@@ -0,0 +1,65 @@
+/* libs/opengles/fixed_asm.S
+**
+** 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 
+**
+**     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.
+*/
+
+
+    .text
+    .align
+    
+    .global gglFloatToFixed
+    .global gglFloatToFixedFast
+
+
+/*
+ * Converts a float to a s15.16 fixed-point number.
+ * this doesn't handle floats out of the [-32768, +32768[ range
+ * and doesn't performs round-to-nearest.
+ * however, it's very fast :-)
+ */
+
+gglFloatToFixedFast:
+        movs    r1, r0, lsl #1          /* remove bit sign */
+        mov     r2, #0x8E               /* 127 + 15 */
+        sub     r1, r2, r1, lsr #24     /* compute shift */
+        mov     r2, r0, lsl #8          /* mantissa<<8 */
+        orr     r2, r2, #0x80000000     /* add the missing 1 */
+        mov     r0, r2, lsr r1          /* scale to 16.16 */
+        rsbcs   r0, r0, #0              /* negate if needed */
+        bx      lr
+
+/*
+ * this version rounds-to-nearest and saturates numbers
+ * outside the range (but not NaNs).
+ */
+
+gglFloatToFixed:
+        mov     r1, r0, lsl #1          /* remove bit sign */
+        mov     r2, #0x8E               /* 127 + 15 */
+        subs    r1, r2, r1, lsr #24     /* compute shift */
+        bls     0f                      /* too big */
+        mov     r2, r0, lsl #8          /* mantissa<<8 */
+        orr     r2, r2, #0x80000000     /* add the missing 1 */
+        mov     r3, r0
+        movs    r0, r2, lsr r1          /* scale to 16.16 */
+        addcs   r0, r0, #1              /* round-to-nearest */
+        tst     r3, #0x80000000         /* negative? */
+        rsbne   r0, r0, #0              /* negate if needed */
+        bx      lr 
+ 
+0:      ands    r0, r0, #0x80000000     /* keep only the sign bit */
+        moveq   r0, #0x7fffffff         /* positive, maximum value */
+        bx      lr
+
diff --git a/opengl/libagl/fp.cpp b/opengl/libagl/fp.cpp
new file mode 100644
index 0000000..ae5f1fe
--- /dev/null
+++ b/opengl/libagl/fp.cpp
@@ -0,0 +1,87 @@
+/* libs/opengles/fp.cpp
+**
+** 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 
+**
+**     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 "fp.h"
+
+// ----------------------------------------------------------------------------
+
+#if !defined(__arm__)
+GGLfixed gglFloatToFixed(float v) {   
+    return GGLfixed(floorf(v * 65536.0f + 0.5f));
+}
+#endif
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+namespace gl {
+
+GLfloat fixedToFloat(GLfixed x)
+{
+#if DEBUG_USE_FLOATS
+    return x / 65536.0f;
+#else
+    if (!x) return 0;
+    const uint32_t s = x & 0x80000000;
+    union {
+        uint32_t i;
+        float f;
+    };
+    i = s ? -x : x;
+    const int c = gglClz(i) - 8;
+    i = (c>=0) ? (i<<c) : (i>>-c);
+    const uint32_t e = 134 - c;
+    i &= ~0x800000;
+    i |= e<<23;
+    i |= s;
+    return f;
+#endif
+}
+
+float sinef(float x)
+{
+    const float A =   1.0f / (2.0f*M_PI);
+    const float B = -16.0f;
+    const float C =   8.0f;
+
+    // scale angle for easy argument reduction
+    x *= A;
+    
+    if (fabsf(x) >= 0.5f) {
+        // Argument reduction
+        x = x - ceilf(x + 0.5f) + 1.0f; 
+    }
+
+    const float y = B*x*fabsf(x) + C*x;
+    return 0.2215f * (y*fabsf(y) - y) + y;
+}
+
+float cosinef(float x)
+{
+    return sinef(x + float(M_PI/2));
+}
+
+void sincosf(GLfloat angle, GLfloat* s, GLfloat* c) {
+    *s = sinef(angle);
+    *c = cosinef(angle);
+}
+
+}; // namespace fp_utils
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/opengl/libagl/fp.h b/opengl/libagl/fp.h
new file mode 100644
index 0000000..6d0c183
--- /dev/null
+++ b/opengl/libagl/fp.h
@@ -0,0 +1,243 @@
+/* libs/opengles/fp.h
+**
+** 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 
+**
+**     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_FP_H
+#define ANDROID_OPENGLES_FP_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <math.h>
+
+#include <private/pixelflinger/ggl_context.h>
+
+#include <GLES/gl.h>
+
+#define DEBUG_USE_FLOATS      0
+
+// ----------------------------------------------------------------------------
+
+extern "C" GLfixed gglFloatToFixed(float f) __attribute__((const));
+
+// ----------------------------------------------------------------------------
+namespace android {
+
+namespace gl {
+
+        GLfloat fixedToFloat(GLfixed) CONST;
+
+        void    sincosf(GLfloat angle, GLfloat* s, GLfloat* c);
+        float   sinef(GLfloat x) CONST;
+        float   cosinef(GLfloat x) CONST;
+
+inline bool     cmpf(GLfloat a, GLfloat b) CONST;
+inline bool     isZerof(GLfloat) CONST;
+inline bool     isOnef(GLfloat) CONST;
+
+inline int      isZeroOrNegativef(GLfloat) CONST;
+
+inline int      exponent(GLfloat) CONST;
+inline int32_t  mantissa(GLfloat) CONST;
+inline GLfloat  clampToZerof(GLfloat) CONST;
+inline GLfloat  reciprocalf(GLfloat) CONST;
+inline GLfloat  rsqrtf(GLfloat) CONST;
+inline GLfloat  sqrf(GLfloat) CONST;
+inline GLfloat  addExpf(GLfloat v, int e) CONST;
+inline GLfloat  mul2f(GLfloat v) CONST;
+inline GLfloat  div2f(GLfloat v) CONST;
+inline GLfloat  absf(GLfloat v) CONST;
+
+
+/* 
+ * float fastexpf(float) : a fast approximation of expf(x)
+ *		give somewhat accurate results for -88 <= x <= 88
+ *
+ * exp(x) = 2^(x/ln(2))
+ * we use the properties of float encoding
+ * to get a fast 2^ and linear interpolation
+ *
+ */
+
+inline float fastexpf(float y) __attribute__((const));
+
+inline float fastexpf(float y)
+{
+	union {
+		float	r;
+		int32_t	i;
+	} u;	
+
+	// 127*ln(2) = 88
+	if (y < -88.0f) {
+		u.r = 0.0f;
+	} else if (y > 88.0f) {
+		u.r = INFINITY;
+	} else {
+		const float kOneOverLogTwo = (1L<<23) / M_LN2;
+		const int32_t kExponentBias = 127L<<23;
+		const int32_t e = int32_t(y*kOneOverLogTwo);
+		u.i = e + kExponentBias;
+	}
+	
+	return u.r;
+}
+
+
+bool cmpf(GLfloat a, GLfloat b) {
+#if DEBUG_USE_FLOATS
+    return a == b;
+#else
+    union {
+        float       f;
+        uint32_t    i;
+    } ua, ub;
+    ua.f = a;
+    ub.f = b;
+    return ua.i == ub.i;
+#endif
+} 
+
+bool isZerof(GLfloat v) {
+#if DEBUG_USE_FLOATS
+    return v == 0;
+#else
+    union {
+        float       f;
+        int32_t     i;
+    };
+    f = v;
+    return (i<<1) == 0;
+#endif
+}
+
+bool isOnef(GLfloat v) {
+    return cmpf(v, 1.0f);
+}
+
+int isZeroOrNegativef(GLfloat v) {
+#if DEBUG_USE_FLOATS
+    return v <= 0;
+#else
+    union {
+        float       f;
+        int32_t     i;
+    };
+    f = v;
+    return isZerof(v) | (i>>31);
+#endif
+}
+
+int exponent(GLfloat v) {
+    union {
+        float    f;
+        uint32_t i;
+    };
+    f = v;
+    return ((i << 1) >> 24) - 127;
+}
+
+int32_t mantissa(GLfloat v) {
+    union {
+        float    f;
+        uint32_t i;
+    };
+    f = v;
+    if (!(i&0x7F800000)) return 0;
+    const int s = i >> 31;
+    i |= (1L<<23);
+    i &= ~0xFF000000;
+    return s ? -i : i;
+}
+
+GLfloat clampToZerof(GLfloat v) {
+#if DEBUG_USE_FLOATS
+    return v<0 ? 0 : (v>1 ? 1 : v);
+#else
+    union {
+        float       f;
+        int32_t     i;
+    };
+    f = v;
+    i &= ~(i>>31);
+    return f;
+#endif
+}
+
+GLfloat reciprocalf(GLfloat v) {
+    // XXX: do better
+    return 1.0f / v;
+}
+
+GLfloat rsqrtf(GLfloat v) {
+    // XXX: do better
+    return 1.0f / sqrtf(v);
+}
+
+GLfloat sqrf(GLfloat v) {
+    // XXX: do better
+    return v*v;
+}
+
+GLfloat addExpf(GLfloat v, int e) {
+    union {
+        float       f;
+        int32_t     i;
+    };
+    f = v;
+    if (i<<1) { // XXX: deal with over/underflow	
+        i += int32_t(e)<<23;
+    }
+    return f;
+}
+
+GLfloat mul2f(GLfloat v) {
+#if DEBUG_USE_FLOATS
+    return v*2;
+#else
+    return addExpf(v, 1);
+#endif
+}
+
+GLfloat div2f(GLfloat v) {
+#if DEBUG_USE_FLOATS
+    return v*0.5f;
+#else
+    return addExpf(v, -1);
+#endif
+}
+
+GLfloat  absf(GLfloat v) {
+#if DEBUG_USE_FLOATS
+    return v<0 ? -v : v;
+#else
+    union {
+        float       f;
+        int32_t     i;
+    };
+    f = v;
+    i &= ~0x80000000;
+    return f;
+#endif
+}
+
+};  // namespace gl
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_FP_H
+
diff --git a/opengl/libagl/iterators.S b/opengl/libagl/iterators.S
new file mode 100644
index 0000000..daf2937
--- /dev/null
+++ b/opengl/libagl/iterators.S
@@ -0,0 +1,88 @@
+/* libs/opengles/iterators.S
+**
+** 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 
+**
+**     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.
+*/
+
+
+    .text
+    .align
+    .arm
+    
+    .global iterators0032
+
+/*
+ * iterators0032
+ *
+ * MUST BE CALLED FROM ARM CODE
+ *
+ * r0: const compute_iterators_t* (this)
+ *      r0 + 0: m_dx01 
+ *      r0 + 4: m_dy10
+ *      r0 + 8: m_dx20
+ *      r0 +12: m_dy02
+ *      r0 +16: m_x0
+ *      r0 +20: m_y0
+ *      r0 +24: m_area
+ *		r0 +28: m_scale
+ *		r0 +29: m_area_scale;
+ * r1: int32_t* (out)
+ *      r1 + 0: c
+ *      r1 + 4: dcdx
+ *      r1 + 8: dcdy
+ *   r2: c0
+ *   r3: c1
+ * [sp]: c2
+ */
+ 
+iterators0032:
+        stmfd	sp!, {r4, r5, r6, r7, r8, lr}
+        ldr     r4, [sp, #4*6]
+
+        ldrb    r12, [r0, #29]
+        sub     r3, r3, r2
+        sub     r4, r4, r2
+        sub     r12, r12, #16
+        mov     r3, r3, asr r12
+        mov     r4, r4, asr r12
+        
+        ldr     r5, [r0, #0]
+        ldr     r12, [r0, #4]
+        smull   r8, lr, r4, r5
+        ldr     r5, [r0, #8]
+        smull   r6, r7, r4, r12
+        ldr     r12, [r0, #12]
+        smlal   r8, lr, r3, r5
+        smlal   r6, r7, r3, r12
+
+        ldr     r3, [r0, #16]        // m_x0
+        ldr     r4, [r0, #20]        // m_x1
+        
+        str     r6, [r1, #4]
+        str     r8, [r1, #8]
+
+        umull   r6, r5, r3, r6
+        umull   r8, r0, r4, r8
+        mla     r7, r3, r7, r5
+        mla     lr, r4, lr, r0
+        adds    r6, r6, r8
+        adc     r7, r7, lr
+
+        movs    r6, r6, lsr #4
+        adc     r6, r6, r7, lsl #28
+        rsb     r6, r6, r2, lsl #16
+        str     r6, [r1, #0]
+
+        ldmfd	sp!, {r4, r5, r6, r7, r8, pc}
+
diff --git a/opengl/libagl/light.cpp b/opengl/libagl/light.cpp
new file mode 100644
index 0000000..87725cb
--- /dev/null
+++ b/opengl/libagl/light.cpp
@@ -0,0 +1,852 @@
+/* libs/opengles/light.cpp
+**
+** 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 
+**
+**     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 <stdio.h>
+#include "context.h"
+#include "fp.h"
+#include "light.h"
+#include "state.h"
+#include "matrix.h"
+
+
+#if defined(__arm__) && defined(__thumb__)
+#warning "light.cpp should not be compiled in thumb on ARM."
+#endif
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static void invalidate_lighting(ogles_context_t* c);
+static void lightVertexValidate(ogles_context_t* c, vertex_t* v);
+static void lightVertexNop(ogles_context_t* c, vertex_t* v);
+static void lightVertex(ogles_context_t* c, vertex_t* v);
+static void lightVertexMaterial(ogles_context_t* c, vertex_t* v);
+
+static inline void vscale3(GLfixed* d, const GLfixed* m, GLfixed s);
+static inline void vsub3w(GLfixed* d, const GLfixed* a, const GLfixed* b);
+
+static __attribute__((noinline))
+void vnorm3(GLfixed* d, const GLfixed* a);
+
+static inline void vsa3(GLfixed* d,
+    const GLfixed* m, GLfixed s, const GLfixed* a);
+static inline void vmla3(GLfixed* d,
+    const GLfixed* m0, const GLfixed* m1, const GLfixed* a);
+static inline void vmul3(GLfixed* d,
+    const GLfixed* m0, const GLfixed* m1);
+
+static GLfixed fog_linear(ogles_context_t* c, GLfixed z);
+static GLfixed fog_exp(ogles_context_t* c, GLfixed z);
+static GLfixed fog_exp2(ogles_context_t* c, GLfixed z);
+
+
+// ----------------------------------------------------------------------------
+
+static void init_white(vec4_t& c) {
+    c.r = c.g = c.b = c.a = 0x10000;
+}
+
+void ogles_init_light(ogles_context_t* c)
+{
+    for (unsigned int i=0 ; i<OGLES_MAX_LIGHTS ; i++) {
+        c->lighting.lights[i].ambient.a = 0x10000;
+        c->lighting.lights[i].position.z = 0x10000;
+        c->lighting.lights[i].spotDir.z = -0x10000;
+        c->lighting.lights[i].spotCutoff = gglIntToFixed(180);
+        c->lighting.lights[i].attenuation[0] = 0x10000;
+    }
+    init_white(c->lighting.lights[0].diffuse);
+    init_white(c->lighting.lights[0].specular);
+
+    c->lighting.front.ambient.r =
+    c->lighting.front.ambient.g =
+    c->lighting.front.ambient.b = gglFloatToFixed(0.2f);
+    c->lighting.front.ambient.a = 0x10000;
+    c->lighting.front.diffuse.r =
+    c->lighting.front.diffuse.g =
+    c->lighting.front.diffuse.b = gglFloatToFixed(0.8f);
+    c->lighting.front.diffuse.a = 0x10000;
+    c->lighting.front.specular.a = 0x10000;
+    c->lighting.front.emission.a = 0x10000;
+
+    c->lighting.lightModel.ambient.r =
+    c->lighting.lightModel.ambient.g =
+    c->lighting.lightModel.ambient.b = gglFloatToFixed(0.2f);
+    c->lighting.lightModel.ambient.a = 0x10000;
+
+    c->lighting.colorMaterial.face = GL_FRONT_AND_BACK;
+    c->lighting.colorMaterial.mode = GL_AMBIENT_AND_DIFFUSE;
+
+    c->fog.mode = GL_EXP;
+    c->fog.fog = fog_exp;
+    c->fog.density = 0x10000;
+    c->fog.end = 0x10000;
+    c->fog.invEndMinusStart = 0x10000;
+
+    invalidate_lighting(c);
+       
+    c->rasterizer.procs.shadeModel(c, GL_SMOOTH);
+    c->lighting.shadeModel = GL_SMOOTH;
+}
+
+void ogles_uninit_light(ogles_context_t* c)
+{
+}
+
+static inline int32_t clampF(GLfixed f) CONST;
+int32_t clampF(GLfixed f) {
+    f = (f & ~(f>>31));
+    if (f >= 0x10000)
+        f = 0x10000;
+    return f;
+}
+
+static GLfixed fog_linear(ogles_context_t* c, GLfixed z) {
+    return clampF(gglMulx((c->fog.end - z), c->fog.invEndMinusStart));
+}
+
+static GLfixed fog_exp(ogles_context_t* c, GLfixed z) {
+    const float e = fixedToFloat(gglMulx(c->fog.density, z));
+    return clampF(gglFloatToFixed(fastexpf(-e)));
+}
+
+static GLfixed fog_exp2(ogles_context_t* c, GLfixed z) {
+    const float e = fixedToFloat(gglMulx(c->fog.density, z));
+    return clampF(gglFloatToFixed(fastexpf(-e*e)));
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark math helpers
+#endif
+
+static inline
+void vscale3(GLfixed* d, const GLfixed* m, GLfixed s) {
+    d[0] = gglMulx(m[0], s);
+    d[1] = gglMulx(m[1], s);
+    d[2] = gglMulx(m[2], s);
+}
+
+static inline
+void vsa3(GLfixed* d, const GLfixed* m, GLfixed s, const GLfixed* a) {
+    d[0] = gglMulAddx(m[0], s, a[0]);
+    d[1] = gglMulAddx(m[1], s, a[1]);
+    d[2] = gglMulAddx(m[2], s, a[2]);
+}
+
+static inline
+void vsub3w(GLfixed* d, const GLfixed* a, const GLfixed* b) {
+    const GLfixed wa = a[3];
+    const GLfixed wb = b[3];
+    if (ggl_likely(wa == wb)) {
+        d[0] = a[0] - b[0];
+        d[1] = a[1] - b[1];
+        d[2] = a[2] - b[2];
+    } else {
+        d[0] = gglMulSubx(a[0], wb, gglMulx(b[0], wa));
+        d[1] = gglMulSubx(a[1], wb, gglMulx(b[1], wa));
+        d[2] = gglMulSubx(a[2], wb, gglMulx(b[2], wa));
+    }
+}
+
+static inline
+void vmla3(GLfixed* d,
+        const GLfixed* m0, const GLfixed* m1, const GLfixed* a)
+{
+    d[0] = gglMulAddx(m0[0], m1[0], a[0]);
+    d[1] = gglMulAddx(m0[1], m1[1], a[1]);
+    d[2] = gglMulAddx(m0[2], m1[2], a[2]);
+}
+
+static inline
+void vmul3(GLfixed* d, const GLfixed* m0, const GLfixed* m1) {
+    d[0] = gglMulx(m0[0], m1[0]);
+    d[1] = gglMulx(m0[1], m1[1]);
+    d[2] = gglMulx(m0[2], m1[2]);
+}
+
+void vnorm3(GLfixed* d, const GLfixed* a)
+{
+    // we must take care of overflows when normalizing a vector
+    GLfixed n;
+    int32_t x = a[0];   x = x>=0 ? x : -x;
+    int32_t y = a[1];   y = y>=0 ? y : -y;
+    int32_t z = a[2];   z = z>=0 ? z : -z;
+    if (ggl_likely(x<=0x6800 && y<=0x6800 && z<= 0x6800)) {
+        // in this case this will all fit on 32 bits
+        n = x*x + y*y + z*z;
+        n = gglSqrtRecipx(n);
+        n <<= 8;
+    } else {
+        // here norm^2 is at least 0x7EC00000 (>>32 == 0.495117)
+        n = vsquare3(x, y, z);
+        n = gglSqrtRecipx(n);
+    }
+    vscale3(d, a, n);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark lighting equations
+#endif
+
+static inline void light_picker(ogles_context_t* c)
+{
+    if (ggl_likely(!c->lighting.enable)) {
+        c->lighting.lightVertex = lightVertexNop;
+        return;
+    }
+    if (c->lighting.colorMaterial.enable) {
+        c->lighting.lightVertex = lightVertexMaterial;
+    } else {
+        c->lighting.lightVertex = lightVertex;
+    }
+}
+
+static inline void validate_light_mvi(ogles_context_t* c)
+{
+    uint32_t en = c->lighting.enabledLights;
+    while (en) {
+        const int i = 31 - gglClz(en);
+        en &= ~(1<<i);
+        light_t& l = c->lighting.lights[i];
+        c->transforms.mvui.point3(&c->transforms.mvui,
+                &l.objPosition, &l.position);
+        vnorm3(l.normalizedObjPosition.v, l.objPosition.v);
+    }
+}
+
+static inline void validate_light(ogles_context_t* c)
+{
+    // if colorMaterial is enabled, we get the color from the vertex
+    if (!c->lighting.colorMaterial.enable) {
+        material_t& material = c->lighting.front;
+        uint32_t en = c->lighting.enabledLights;
+        while (en) {
+            const int i = 31 - gglClz(en);
+            en &= ~(1<<i);
+            light_t& l = c->lighting.lights[i];
+            vmul3(l.implicitAmbient.v,  material.ambient.v,  l.ambient.v);
+            vmul3(l.implicitDiffuse.v,  material.diffuse.v,  l.diffuse.v);
+            vmul3(l.implicitSpecular.v, material.specular.v, l.specular.v);
+            
+            // this is just a flag to tell if we have a specular component
+            l.implicitSpecular.v[3] =
+                    l.implicitSpecular.r |
+                    l.implicitSpecular.g |
+                    l.implicitSpecular.b;
+            
+            l.rConstAttenuation = (l.attenuation[1] | l.attenuation[2])==0;
+            if (l.rConstAttenuation)
+                l.rConstAttenuation = gglRecipFast(l.attenuation[0]);
+        }
+        // emission and ambient for the whole scene
+        vmla3(  c->lighting.implicitSceneEmissionAndAmbient.v,
+                c->lighting.lightModel.ambient.v,
+                material.ambient.v, 
+                material.emission.v);
+        c->lighting.implicitSceneEmissionAndAmbient.a = material.diffuse.a;
+    }
+    validate_light_mvi(c);
+}
+
+void invalidate_lighting(ogles_context_t* c)
+{
+    // TODO: pick lightVertexValidate or lightVertexValidateMVI
+    // instead of systematically the heavier lightVertexValidate()
+    c->lighting.lightVertex = lightVertexValidate;
+}
+
+void ogles_invalidate_lighting_mvui(ogles_context_t* c)
+{
+    invalidate_lighting(c);
+}
+
+void lightVertexNop(ogles_context_t*, vertex_t* v)
+{
+    // we should never end-up here
+}
+
+void lightVertexValidateMVI(ogles_context_t* c, vertex_t* v)
+{
+    validate_light_mvi(c);
+    light_picker(c);
+    c->lighting.lightVertex(c, v);
+}
+
+void lightVertexValidate(ogles_context_t* c, vertex_t* v)
+{
+    validate_light(c);
+    light_picker(c);
+    c->lighting.lightVertex(c, v);
+}
+
+void lightVertexMaterial(ogles_context_t* c, vertex_t* v)
+{
+    // fetch the material color
+    const GLvoid* cp = c->arrays.color.element(
+            v->index & vertex_cache_t::INDEX_MASK);
+    c->arrays.color.fetch(c, v->color.v, cp);
+
+    // acquire the color-material from the vertex
+    material_t& material = c->lighting.front;
+    material.ambient =
+    material.diffuse = v->color;
+    // implicit arguments need to be computed per/vertex
+    uint32_t en = c->lighting.enabledLights;
+    while (en) {
+        const int i = 31 - gglClz(en);
+        en &= ~(1<<i);
+        light_t& l = c->lighting.lights[i];
+        vmul3(l.implicitAmbient.v,  material.ambient.v,  l.ambient.v);
+        vmul3(l.implicitDiffuse.v,  material.diffuse.v,  l.diffuse.v);
+        vmul3(l.implicitSpecular.v, material.specular.v, l.specular.v);
+    }
+    // emission and ambient for the whole scene
+    vmla3(  c->lighting.implicitSceneEmissionAndAmbient.v,
+            c->lighting.lightModel.ambient.v,
+            material.ambient.v, 
+            material.emission.v);
+    c->lighting.implicitSceneEmissionAndAmbient.a = material.diffuse.a;
+
+    // now we can light our vertex as usual
+    lightVertex(c, v);
+}
+
+void lightVertex(ogles_context_t* c, vertex_t* v)
+{
+    // emission and ambient for the whole scene
+    vec4_t r = c->lighting.implicitSceneEmissionAndAmbient;
+
+    uint32_t en = c->lighting.enabledLights;
+    if (ggl_likely(en)) {
+        // since we do the lighting in object-space, we don't need to
+        // transform each normal. However, we might still have to normalize
+        // it if GL_NORMALIZE is enabled.
+        vec4_t n;
+        c->arrays.normal.fetch(c, n.v,
+            c->arrays.normal.element(v->index & vertex_cache_t::INDEX_MASK));
+        if (c->transforms.rescaleNormals == GL_NORMALIZE)
+            vnorm3(n.v, n.v);
+
+        const material_t& material = c->lighting.front;
+        const int twoSide = c->lighting.lightModel.twoSide;
+
+        while (en) {
+            const int i = 31 - gglClz(en);
+            en &= ~(1<<i);
+            const light_t& l = c->lighting.lights[i];
+            
+            vec4_t d, t;
+            GLfixed s;
+            GLfixed sqDist = 0x10000;
+
+            // compute vertex-to-light vector
+            if (ggl_unlikely(l.position.w)) {
+                vsub3w(d.v, l.objPosition.v, v->obj.v);
+                sqDist = dot3(d.v, d.v);
+                vscale3(d.v, d.v, gglSqrtRecipx(sqDist));
+            } else {
+                // TODO: avoid copy here
+                d = l.normalizedObjPosition;
+            }
+
+            // ambient & diffuse
+            s = dot3(n.v, d.v);
+            s = (s<0) ? (twoSide?(-s):0) : s;
+            vsa3(t.v, l.implicitDiffuse.v, s, l.implicitAmbient.v);
+            
+            // specular
+            if (ggl_unlikely(s && l.implicitSpecular.v[3])) {
+                vec4_t h;
+                h.x = d.x;
+                h.y = d.y;
+                h.z = d.z + 0x10000;
+                vnorm3(h.v, h.v);
+                s = dot3(n.v, h.v);
+                s = (s<0) ? (twoSide?(-s):0) : s;
+                if (s > 0) {
+                    s = gglPowx(s, material.shininess);
+                    vsa3(t.v, l.implicitSpecular.v, s, t.v);
+                }
+            }
+
+            // spot
+            if (ggl_unlikely(l.spotCutoff != gglIntToFixed(180))) {
+                GLfixed spotAtt = -dot3(l.normalizedSpotDir.v, d.v);
+                if (spotAtt >= l.spotCutoffCosine) {
+                    vscale3(t.v, t.v, gglPowx(spotAtt, l.spotExp));
+                }
+            }
+
+            // attenuation
+            if (ggl_unlikely(l.position.w)) {
+                if (l.rConstAttenuation) {
+                    s = l.rConstAttenuation;
+                } else {
+                    s = gglMulAddx(sqDist, l.attenuation[2], l.attenuation[0]);
+                    if (l.attenuation[1])
+                        s = gglMulAddx(gglSqrtx(sqDist), l.attenuation[1], s);
+                    s = gglRecipFast(s);
+                }
+                vscale3(t.v, t.v, s);
+            }
+
+            r.r += t.r;
+            r.g += t.g;
+            r.b += t.b;
+        }
+    }
+    v->color.r = gglClampx(r.r);
+    v->color.g = gglClampx(r.g);
+    v->color.b = gglClampx(r.b);
+    v->color.a = gglClampx(r.a);
+    v->flags |= vertex_t::LIT;
+}
+
+static void lightModelx(GLenum pname, GLfixed param, ogles_context_t* c)
+{
+    if (ggl_unlikely(pname != GL_LIGHT_MODEL_TWO_SIDE)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->lighting.lightModel.twoSide = param ? GL_TRUE : GL_FALSE;
+    invalidate_lighting(c);
+}
+
+static void lightx(GLenum i, GLenum pname, GLfixed param, ogles_context_t* c)
+{
+    if (ggl_unlikely(uint32_t(i-GL_LIGHT0) >= OGLES_MAX_LIGHTS)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+
+    light_t& light = c->lighting.lights[i-GL_LIGHT0];
+    const GLfixed kDegToRad = GLfixed((M_PI * gglIntToFixed(1)) / 180.0f);
+    switch (pname) {
+    case GL_SPOT_EXPONENT:
+        if (GGLfixed(param) >= gglIntToFixed(128)) {
+            ogles_error(c, GL_INVALID_VALUE);
+            return;
+        }
+        light.spotExp = param;
+        break;
+    case GL_SPOT_CUTOFF:
+        if (param!=gglIntToFixed(180) && GGLfixed(param)>=gglIntToFixed(90)) {
+            ogles_error(c, GL_INVALID_VALUE);
+            return;
+        }
+        light.spotCutoff = param;
+        light.spotCutoffCosine = 
+                gglFloatToFixed(cosinef((M_PI/(180.0f*65536.0f))*param));
+        break;
+    case GL_CONSTANT_ATTENUATION:
+        if (param < 0) {
+            ogles_error(c, GL_INVALID_VALUE);
+            return;
+        }
+        light.attenuation[0] = param;
+        break;
+    case GL_LINEAR_ATTENUATION:
+        if (param < 0) {
+            ogles_error(c, GL_INVALID_VALUE);
+            return;
+        }
+        light.attenuation[1] = param;
+        break;
+    case GL_QUADRATIC_ATTENUATION:
+        if (param < 0) {
+            ogles_error(c, GL_INVALID_VALUE);
+            return;
+        }
+        light.attenuation[2] = param;
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    invalidate_lighting(c);
+}
+
+static void lightxv(GLenum i, GLenum pname, const GLfixed *params, ogles_context_t* c)
+{
+    if (ggl_unlikely(uint32_t(i-GL_LIGHT0) >= OGLES_MAX_LIGHTS)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+
+    GLfixed* what;
+    light_t& light = c->lighting.lights[i-GL_LIGHT0];
+    switch (pname) {
+    case GL_AMBIENT:
+        what = light.ambient.v;
+        break;
+    case GL_DIFFUSE:
+        what = light.diffuse.v;
+        break;
+    case GL_SPECULAR:
+        what = light.specular.v;
+        break;
+    case GL_POSITION: {
+        ogles_validate_transform(c, transform_state_t::MODELVIEW);
+        transform_t& mv = c->transforms.modelview.transform;
+        memcpy(light.position.v, params, sizeof(light.position.v));
+        mv.point4(&mv, &light.position, &light.position);
+        invalidate_lighting(c);
+        return;
+    }
+    case GL_SPOT_DIRECTION: {
+        ogles_validate_transform(c, transform_state_t::MVUI);
+        transform_t& mvui = c->transforms.mvui;
+        mvui.point3(&mvui, &light.spotDir, (vec4_t*)params);
+        vnorm3(light.normalizedSpotDir.v, light.spotDir.v);
+        invalidate_lighting(c);
+        return;
+    }
+    default:
+        lightx(i, pname, params[0], c);
+        return;
+    }
+    what[0] = params[0];
+    what[1] = params[1];
+    what[2] = params[2];
+    what[3] = params[3];
+    invalidate_lighting(c);
+}
+
+static void materialx(GLenum face, GLenum pname, GLfixed param, ogles_context_t* c)
+{
+    if (ggl_unlikely(face != GL_FRONT_AND_BACK)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if (ggl_unlikely(pname != GL_SHININESS)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->lighting.front.shininess = param;
+    invalidate_lighting(c);
+}
+
+static void fogx(GLenum pname, GLfixed param, ogles_context_t* c)
+{
+    switch (pname) {
+    case GL_FOG_DENSITY:
+        if (param >= 0) {
+            c->fog.density = param;
+            break;
+        }
+        ogles_error(c, GL_INVALID_VALUE);
+        break;
+    case GL_FOG_START:
+        c->fog.start = gglClampx(param);
+        c->fog.invEndMinusStart = gglRecip(c->fog.end - c->fog.start);
+        break;
+    case GL_FOG_END:
+        c->fog.end = gglClampx(param);
+        c->fog.invEndMinusStart = gglRecip(c->fog.end - c->fog.start);
+        break;
+    case GL_FOG_MODE:
+        switch (param) {
+        case GL_LINEAR:
+            c->fog.mode = param;
+            c->fog.fog = fog_linear;
+            break;
+        case GL_EXP:
+            c->fog.mode = param;
+            c->fog.fog = fog_exp;
+            break;
+        case GL_EXP2:
+            c->fog.mode = param;
+            c->fog.fog = fog_exp2;
+            break;
+        default:
+            ogles_error(c, GL_INVALID_ENUM);
+            break;
+        }
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        break;
+    }
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
+using namespace android;
+
+#if 0
+#pragma mark -
+#pragma mark lighting APIs
+#endif
+
+void glShadeModel(GLenum mode)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (ggl_unlikely(mode != GL_SMOOTH && mode != GL_FLAT)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->lighting.shadeModel = mode;
+}
+
+void glLightModelf(GLenum pname, GLfloat param)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    lightModelx(pname, gglFloatToFixed(param), c);
+}
+
+void glLightModelx(GLenum pname, GLfixed param)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    lightModelx(pname, param, c);
+}
+
+void glLightModelfv(GLenum pname, const GLfloat *params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (pname == GL_LIGHT_MODEL_TWO_SIDE) {
+        lightModelx(pname, gglFloatToFixed(params[0]), c);
+        return;
+    }
+
+    if (ggl_unlikely(pname != GL_LIGHT_MODEL_AMBIENT)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+
+    c->lighting.lightModel.ambient.r = gglFloatToFixed(params[0]);
+    c->lighting.lightModel.ambient.g = gglFloatToFixed(params[1]);
+    c->lighting.lightModel.ambient.b = gglFloatToFixed(params[2]);
+    c->lighting.lightModel.ambient.a = gglFloatToFixed(params[3]);
+    invalidate_lighting(c);
+}
+
+void glLightModelxv(GLenum pname, const GLfixed *params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (pname == GL_LIGHT_MODEL_TWO_SIDE) {
+        lightModelx(pname, params[0], c);
+        return;
+    }
+
+    if (ggl_unlikely(pname != GL_LIGHT_MODEL_AMBIENT)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+
+    c->lighting.lightModel.ambient.r = params[0];
+    c->lighting.lightModel.ambient.g = params[1];
+    c->lighting.lightModel.ambient.b = params[2];
+    c->lighting.lightModel.ambient.a = params[3];
+    invalidate_lighting(c);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+void glLightf(GLenum i, GLenum pname, GLfloat param)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    lightx(i, pname, gglFloatToFixed(param), c);
+}
+
+void glLightx(GLenum i, GLenum pname, GLfixed param)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    lightx(i, pname, param, c);
+}
+
+void glLightfv(GLenum i, GLenum pname, const GLfloat *params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    switch (pname) {
+    case GL_SPOT_EXPONENT:
+    case GL_SPOT_CUTOFF:
+    case GL_CONSTANT_ATTENUATION:
+    case GL_LINEAR_ATTENUATION:
+    case GL_QUADRATIC_ATTENUATION:
+        lightx(i, pname, gglFloatToFixed(params[0]), c);
+        return;
+    }
+
+    GLfixed paramsx[4];
+    paramsx[0] = gglFloatToFixed(params[0]);
+    paramsx[1] = gglFloatToFixed(params[1]);
+    paramsx[2] = gglFloatToFixed(params[2]);
+    if (pname != GL_SPOT_DIRECTION)
+        paramsx[3] = gglFloatToFixed(params[3]);
+
+    lightxv(i, pname, paramsx, c);
+}
+
+void glLightxv(GLenum i, GLenum pname, const GLfixed *params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    lightxv(i, pname, params, c);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+void glMaterialf(GLenum face, GLenum pname, GLfloat param)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    materialx(face, pname, gglFloatToFixed(param), c);
+}
+
+void glMaterialx(GLenum face, GLenum pname, GLfixed param)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    materialx(face, pname, param, c);
+}
+
+void glMaterialfv(
+    GLenum face, GLenum pname, const GLfloat *params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (ggl_unlikely(face != GL_FRONT_AND_BACK)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    GLfixed* what=0;
+    GLfixed* other=0;
+    switch (pname) {
+    case GL_AMBIENT:    what = c->lighting.front.ambient.v; break;
+    case GL_DIFFUSE:    what = c->lighting.front.diffuse.v; break;
+    case GL_SPECULAR:   what = c->lighting.front.specular.v; break;
+    case GL_EMISSION:   what = c->lighting.front.emission.v; break;
+    case GL_AMBIENT_AND_DIFFUSE:
+        what  = c->lighting.front.ambient.v; break;
+        other = c->lighting.front.diffuse.v; break;
+        break;
+    case GL_SHININESS:
+        c->lighting.front.shininess = gglFloatToFixed(params[0]);
+        invalidate_lighting(c);
+        return;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    what[0] = gglFloatToFixed(params[0]);
+    what[1] = gglFloatToFixed(params[1]);
+    what[2] = gglFloatToFixed(params[2]);
+    what[3] = gglFloatToFixed(params[3]);
+    if (other) {
+        other[0] = what[0];
+        other[1] = what[1];
+        other[2] = what[2];
+        other[3] = what[3];
+    }
+    invalidate_lighting(c);
+}
+
+void glMaterialxv(
+    GLenum face, GLenum pname, const GLfixed *params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (ggl_unlikely(face != GL_FRONT_AND_BACK)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    GLfixed* what=0;
+    GLfixed* other=0;
+    switch (pname) {
+    case GL_AMBIENT:    what = c->lighting.front.ambient.v; break;
+    case GL_DIFFUSE:    what = c->lighting.front.diffuse.v; break;
+    case GL_SPECULAR:   what = c->lighting.front.specular.v; break;
+    case GL_EMISSION:   what = c->lighting.front.emission.v; break;
+    case GL_AMBIENT_AND_DIFFUSE:
+        what = c->lighting.front.ambient.v; break;
+        other= c->lighting.front.diffuse.v; break;
+        break;
+    case GL_SHININESS:
+        c->lighting.front.shininess = gglFloatToFixed(params[0]);
+        invalidate_lighting(c);
+        return;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    what[0] = params[0];
+    what[1] = params[1];
+    what[2] = params[2];
+    what[3] = params[3];
+    if (other) {
+        other[0] = what[0];
+        other[1] = what[1];
+        other[2] = what[2];
+        other[3] = what[3];
+    }
+    invalidate_lighting(c);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark fog
+#endif
+
+void glFogf(GLenum pname, GLfloat param) {
+    ogles_context_t* c = ogles_context_t::get();
+    GLfixed paramx = (GLfixed)param;
+    if (pname != GL_FOG_MODE)
+        paramx = gglFloatToFixed(param);
+    fogx(pname, paramx, c);
+}
+
+void glFogx(GLenum pname, GLfixed param) {
+    ogles_context_t* c = ogles_context_t::get();
+    fogx(pname, param, c);
+}
+
+void glFogfv(GLenum pname, const GLfloat *params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (pname != GL_FOG_COLOR) {
+        GLfixed paramx = (GLfixed)params[0];
+        if (pname != GL_FOG_MODE)
+            paramx = gglFloatToFixed(params[0]);
+        fogx(pname, paramx, c);
+        return;
+    }
+    GLfixed paramsx[4];
+    paramsx[0] = gglFloatToFixed(params[0]);
+    paramsx[1] = gglFloatToFixed(params[1]);
+    paramsx[2] = gglFloatToFixed(params[2]);
+    paramsx[3] = gglFloatToFixed(params[3]);
+    c->rasterizer.procs.fogColor3xv(c, paramsx);
+}
+
+void glFogxv(GLenum pname, const GLfixed *params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (pname != GL_FOG_COLOR) {
+        fogx(pname, params[0], c);
+        return;
+    }
+    c->rasterizer.procs.fogColor3xv(c, params);
+}
diff --git a/opengl/libagl/light.h b/opengl/libagl/light.h
new file mode 100644
index 0000000..6dae25f
--- /dev/null
+++ b/opengl/libagl/light.h
@@ -0,0 +1,38 @@
+/* libs/opengles/light.h
+**
+** 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 
+**
+**     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_LIGHT_H
+#define ANDROID_OPENGLES_LIGHT_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+namespace android {
+
+namespace gl {
+struct ogles_context_t;
+};
+
+void ogles_init_light(ogles_context_t* c);
+void ogles_uninit_light(ogles_context_t* c);
+void ogles_invalidate_lighting_mvui(ogles_context_t* c);
+
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_LIGHT_H
+
diff --git a/opengl/libagl/matrix.cpp b/opengl/libagl/matrix.cpp
new file mode 100644
index 0000000..441da38
--- /dev/null
+++ b/opengl/libagl/matrix.cpp
@@ -0,0 +1,1144 @@
+/* libs/opengles/matrix.cpp
+**
+** 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 
+**
+**     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"
+
+#if defined(__arm__) && defined(__thumb__)
+#warning "matrix.cpp should not be compiled in thumb on ARM."
+#endif
+
+#define I(_i, _j) ((_j)+ 4*(_i))
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static const GLfloat gIdentityf[16] = { 1,0,0,0,
+                                        0,1,0,0,
+                                        0,0,1,0,
+                                        0,0,0,1 };
+
+static const matrixx_t gIdentityx = { 
+            {   0x10000,0,0,0,
+                0,0x10000,0,0,
+                0,0,0x10000,0,
+                0,0,0,0x10000
+            }
+        };
+
+static void point2__nop(transform_t const*, vec4_t* c, vec4_t const* o);
+static void point3__nop(transform_t const*, vec4_t* c, vec4_t const* o);
+static void point4__nop(transform_t const*, vec4_t* c, vec4_t const* o);
+static void normal__nop(transform_t const*, vec4_t* c, vec4_t const* o);
+static void point2__generic(transform_t const*, vec4_t* c, vec4_t const* o);
+static void point3__generic(transform_t const*, vec4_t* c, vec4_t const* o);
+static void point4__generic(transform_t const*, vec4_t* c, vec4_t const* o);
+static void normal__generic(transform_t const*, vec4_t* c, vec4_t const* o);
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+void ogles_init_matrix(ogles_context_t* c)
+{
+    c->transforms.modelview.init(OGLES_MODELVIEW_STACK_DEPTH);
+    c->transforms.projection.init(OGLES_PROJECTION_STACK_DEPTH);
+    for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++)
+        c->transforms.texture[i].init(OGLES_TEXTURE_STACK_DEPTH);
+
+    c->transforms.current = &c->transforms.modelview;
+    c->transforms.matrixMode = GL_MODELVIEW;
+    c->transforms.dirty =   transform_state_t::VIEWPORT | 
+                            transform_state_t::MVUI |
+                            transform_state_t::MVIT |
+                            transform_state_t::MVP;
+    c->transforms.mvp.loadIdentity();
+    c->transforms.mvp4.loadIdentity();
+    c->transforms.mvit4.loadIdentity();
+    c->transforms.mvui.loadIdentity();
+    c->transforms.vpt.loadIdentity();
+    c->transforms.vpt.zNear = 0.0f;
+    c->transforms.vpt.zFar  = 1.0f;
+}
+
+void ogles_uninit_matrix(ogles_context_t* c)
+{
+    c->transforms.modelview.uninit();
+    c->transforms.projection.uninit();
+    for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++)
+        c->transforms.texture[i].uninit();
+}
+
+static void validate_perspective(ogles_context_t* c, vertex_t* v)
+{
+    const uint32_t enables = c->rasterizer.state.enables;
+    c->arrays.perspective = (c->clipPlanes.enable) ?
+        ogles_vertex_clipAllPerspective3D : ogles_vertex_perspective3D;
+    if (enables & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)) {
+        c->arrays.perspective = (c->clipPlanes.enable) ?
+            ogles_vertex_clipAllPerspective3DZ : ogles_vertex_perspective3DZ;
+    }
+    if ((c->arrays.vertex.size != 4) &&
+        (c->transforms.mvp4.flags & transform_t::FLAGS_2D_PROJECTION)) {
+        c->arrays.perspective = ogles_vertex_perspective2D;
+    }
+    c->arrays.perspective(c, v);
+}
+
+void ogles_invalidate_perspective(ogles_context_t* c)
+{
+    c->arrays.perspective = validate_perspective;
+}
+
+void ogles_validate_transform_impl(ogles_context_t* c, uint32_t want)
+{
+    int dirty = c->transforms.dirty & want;
+
+    // Validate the modelview
+    if (dirty & transform_state_t::MODELVIEW) {
+        c->transforms.modelview.validate();
+    }
+
+    // Validate the projection stack (in fact, it's never needed)
+    if (dirty & transform_state_t::PROJECTION) {
+        c->transforms.projection.validate();
+    }
+
+    // Validate the viewport transformation
+    if (dirty & transform_state_t::VIEWPORT) {
+        vp_transform_t& vpt = c->transforms.vpt;
+        vpt.transform.matrix.load(vpt.matrix);
+        vpt.transform.picker();
+    }
+
+    // We need to update the mvp (used to transform each vertex)
+    if (dirty & transform_state_t::MVP) {
+        c->transforms.update_mvp();
+        // invalidate perspective (divide by W) and view volume clipping
+        ogles_invalidate_perspective(c);
+    }
+
+    // Validate the mvui (for normal transformation)
+    if (dirty & transform_state_t::MVUI) {
+        c->transforms.update_mvui();
+        ogles_invalidate_lighting_mvui(c);
+    }
+
+    // Validate the texture stack
+    if (dirty & transform_state_t::TEXTURE) {
+        for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++)
+            c->transforms.texture[i].validate();
+    }
+
+    // Validate the mvit4 (user-clip planes)
+    if (dirty & transform_state_t::MVIT) {
+        c->transforms.update_mvit();
+    }
+
+    c->transforms.dirty &= ~want;
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark transform_t
+#endif
+
+void transform_t::loadIdentity() {
+    matrix = gIdentityx;
+    flags = 0;
+    ops = OP_IDENTITY;
+    point2 = point2__nop;
+    point3 = point3__nop;
+    point4 = point4__nop;
+}
+
+
+static inline
+int notZero(GLfixed v) {
+    return abs(v) & ~0x3;
+}
+
+static inline
+int notOne(GLfixed v) {
+    return notZero(v - 0x10000);
+}
+
+void transform_t::picker()
+{
+    const GLfixed* const m = matrix.m;
+
+    // XXX: picker needs to be smarter
+    flags = 0;
+    ops = OP_ALL;
+    point2 = point2__generic;
+    point3 = point3__generic;
+    point4 = point4__generic;
+    
+    // find out if this is a 2D projection
+    if (!(notZero(m[3]) | notZero(m[7]) | notZero(m[11]) | notOne(m[15]))) {
+        flags |= FLAGS_2D_PROJECTION;
+    }
+}
+
+void mvui_transform_t::picker()
+{
+    flags = 0;
+    ops = OP_ALL;
+    point3 = normal__generic;
+}
+
+void transform_t::dump(const char* what)
+{
+    GLfixed const * const m = matrix.m;
+    LOGD("%s:", what);
+    for (int i=0 ; i<4 ; i++)
+        LOGD("[%08x %08x %08x %08x] [%f %f %f %f]\n",
+            m[I(0,i)], m[I(1,i)], m[I(2,i)], m[I(3,i)],
+            fixedToFloat(m[I(0,i)]),
+            fixedToFloat(m[I(1,i)]), 
+            fixedToFloat(m[I(2,i)]),
+            fixedToFloat(m[I(3,i)]));
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark matrixx_t
+#endif
+
+void matrixx_t::load(const matrixf_t& rhs) {
+    GLfixed* xp = m;
+    GLfloat const* fp = rhs.elements();
+    unsigned int i = 16;
+    do {
+        const GLfloat f = *fp++;
+        *xp++ = isZerof(f) ? 0 : gglFloatToFixed(f);
+    } while (--i);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark matrixf_t
+#endif
+
+void matrixf_t::multiply(matrixf_t& r, const matrixf_t& lhs, const matrixf_t& rhs)
+{
+    GLfloat const* const m = lhs.m;
+    for (int i=0 ; i<4 ; i++) {
+        register const float rhs_i0 = rhs.m[ I(i,0) ];
+        register float ri0 = m[ I(0,0) ] * rhs_i0;
+        register float ri1 = m[ I(0,1) ] * rhs_i0;
+        register float ri2 = m[ I(0,2) ] * rhs_i0;
+        register float ri3 = m[ I(0,3) ] * rhs_i0;
+        for (int j=1 ; j<4 ; j++) {
+            register const float rhs_ij = rhs.m[ I(i,j) ];
+            ri0 += m[ I(j,0) ] * rhs_ij;
+            ri1 += m[ I(j,1) ] * rhs_ij;
+            ri2 += m[ I(j,2) ] * rhs_ij;
+            ri3 += m[ I(j,3) ] * rhs_ij;
+        }
+        r.m[ I(i,0) ] = ri0;
+        r.m[ I(i,1) ] = ri1;
+        r.m[ I(i,2) ] = ri2;
+        r.m[ I(i,3) ] = ri3;
+    }
+}
+
+void matrixf_t::dump(const char* what) {
+    LOGD("%s", what);
+    LOGD("[ %9f %9f %9f %9f ]", m[I(0,0)], m[I(1,0)], m[I(2,0)], m[I(3,0)]);
+    LOGD("[ %9f %9f %9f %9f ]", m[I(0,1)], m[I(1,1)], m[I(2,1)], m[I(3,1)]);
+    LOGD("[ %9f %9f %9f %9f ]", m[I(0,2)], m[I(1,2)], m[I(2,2)], m[I(3,2)]);
+    LOGD("[ %9f %9f %9f %9f ]", m[I(0,3)], m[I(1,3)], m[I(2,3)], m[I(3,3)]);
+}
+
+void matrixf_t::loadIdentity() {
+    memcpy(m, gIdentityf, sizeof(m));
+}
+
+void matrixf_t::set(const GLfixed* rhs) {
+    load(rhs);
+}
+
+void matrixf_t::set(const GLfloat* rhs) {
+    load(rhs);
+}
+
+void matrixf_t::load(const GLfixed* rhs) {
+    GLfloat* fp = m;
+    unsigned int i = 16;
+    do {
+        *fp++ = fixedToFloat(*rhs++);
+    } while (--i);
+}
+
+void matrixf_t::load(const GLfloat* rhs) {
+    memcpy(m, rhs, sizeof(m));
+}
+
+void matrixf_t::load(const matrixf_t& rhs) {
+    operator = (rhs);
+}
+
+void matrixf_t::multiply(const matrixf_t& rhs) {
+    matrixf_t r;
+    multiply(r, *this, rhs);
+    operator = (r);
+}
+
+void matrixf_t::translate(GLfloat x, GLfloat y, GLfloat z) {
+    for (int i=0 ; i<4 ; i++) {
+        m[12+i] += m[i]*x + m[4+i]*y + m[8+i]*z;
+    }
+}
+
+void matrixf_t::scale(GLfloat x, GLfloat y, GLfloat z) {
+    for (int i=0 ; i<4 ; i++) {
+        m[  i] *= x;
+        m[4+i] *= y;
+        m[8+i] *= z;
+    }
+}
+
+void matrixf_t::rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z)
+{
+    matrixf_t rotation;
+    GLfloat* r = rotation.m;
+    GLfloat c, s;
+    r[3] = 0;   r[7] = 0;   r[11]= 0;
+    r[12]= 0;   r[13]= 0;   r[14]= 0;   r[15]= 1;
+    a *= GLfloat(M_PI / 180.0f);
+    sincosf(a, &s, &c);
+    if (isOnef(x) && isZerof(y) && isZerof(z)) {
+        r[5] = c;   r[10]= c;
+        r[6] = s;   r[9] = -s;
+        r[1] = 0;   r[2] = 0;
+        r[4] = 0;   r[8] = 0;
+        r[0] = 1;
+    } else if (isZerof(x) && isOnef(y) && isZerof(z)) {
+        r[0] = c;   r[10]= c;
+        r[8] = s;   r[2] = -s;
+        r[1] = 0;   r[4] = 0;
+        r[6] = 0;   r[9] = 0;
+        r[5] = 1;
+    } else if (isZerof(x) && isZerof(y) && isOnef(z)) {
+        r[0] = c;   r[5] = c;
+        r[1] = s;   r[4] = -s;
+        r[2] = 0;   r[6] = 0;
+        r[8] = 0;   r[9] = 0;
+        r[10]= 1;
+    } else {
+        const GLfloat len = sqrtf(x*x + y*y + z*z);
+        if (!isOnef(len)) {
+            const GLfloat recipLen = reciprocalf(len);
+            x *= recipLen;
+            y *= recipLen;
+            z *= recipLen;
+        }
+        const GLfloat nc = 1.0f - c;
+        const GLfloat xy = x * y;
+        const GLfloat yz = y * z;
+        const GLfloat zx = z * x;
+        const GLfloat xs = x * s;
+        const GLfloat ys = y * s;
+        const GLfloat zs = z * s;		
+        r[ 0] = x*x*nc +  c;    r[ 4] =  xy*nc - zs;    r[ 8] =  zx*nc + ys;
+        r[ 1] =  xy*nc + zs;    r[ 5] = y*y*nc +  c;    r[ 9] =  yz*nc - xs;
+        r[ 2] =  zx*nc - ys;    r[ 6] =  yz*nc + xs;    r[10] = z*z*nc +  c;
+    }
+    multiply(rotation);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark matrix_stack_t
+#endif
+
+void matrix_stack_t::init(int depth) {
+    stack = new matrixf_t[depth];
+    ops = new uint8_t[depth];
+    maxDepth = depth;
+    depth = 0;
+    dirty = 0;
+    loadIdentity();
+}
+
+void matrix_stack_t::uninit() {
+    delete [] stack;
+    delete [] ops;
+}
+
+void matrix_stack_t::loadIdentity() {
+    transform.loadIdentity();
+    stack[depth].loadIdentity();
+    ops[depth] = OP_IDENTITY;
+}
+
+void matrix_stack_t::load(const GLfixed* rhs)
+{   
+    memcpy(transform.matrix.m, rhs, sizeof(transform.matrix.m));
+    stack[depth].load(rhs);
+    ops[depth] = OP_ALL;    // TODO: we should look at the matrix
+}
+
+void matrix_stack_t::load(const GLfloat* rhs)
+{
+    stack[depth].load(rhs);
+    ops[depth] = OP_ALL;    // TODO: we should look at the matrix
+}
+
+void matrix_stack_t::multiply(const matrixf_t& rhs)
+{    
+    stack[depth].multiply(rhs);
+    ops[depth] = OP_ALL;    // TODO: we should look at the matrix
+}
+
+void matrix_stack_t::translate(GLfloat x, GLfloat y, GLfloat z)
+{
+    stack[depth].translate(x,y,z);
+    ops[depth] |= OP_TRANSLATE;
+}
+
+void matrix_stack_t::scale(GLfloat x, GLfloat y, GLfloat z)
+{
+    stack[depth].scale(x,y,z);
+    if (x==y && y==z) {
+        ops[depth] |= OP_UNIFORM_SCALE;
+    } else {
+        ops[depth] |= OP_SCALE;
+    }
+}
+
+void matrix_stack_t::rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z)
+{
+    stack[depth].rotate(a,x,y,z);
+    ops[depth] |= OP_ROTATE;
+}
+
+void matrix_stack_t::validate()
+{
+    if (dirty & DO_FLOAT_TO_FIXED) {
+        transform.matrix.load(top());
+    }
+    if (dirty & DO_PICKER) {
+        transform.picker();
+    }
+    dirty = 0;
+}
+
+GLint matrix_stack_t::push()
+{
+    if (depth >= (maxDepth-1)) {
+        return GL_STACK_OVERFLOW;
+    }
+    stack[depth+1] = stack[depth];
+    ops[depth+1] = ops[depth];
+    depth++;
+    return 0;
+}
+
+GLint matrix_stack_t::pop()
+{
+    if (depth == 0) {
+        return GL_STACK_UNDERFLOW;
+    }
+    depth--;
+    return 0;
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark vp_transform_t
+#endif
+
+void vp_transform_t::loadIdentity() {
+    transform.loadIdentity();
+    matrix.loadIdentity();
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark transform_state_t
+#endif
+
+void transform_state_t::invalidate()
+{
+    switch (matrixMode) {
+    case GL_MODELVIEW:  dirty |= MODELVIEW  | MVP | MVUI | MVIT;    break;
+    case GL_PROJECTION: dirty |= PROJECTION | MVP;                  break;
+    case GL_TEXTURE:    dirty |= TEXTURE    | MVP;                  break;
+    }
+    current->dirty =    matrix_stack_t::DO_PICKER |
+                        matrix_stack_t::DO_FLOAT_TO_FIXED;
+}
+
+void transform_state_t::update_mvp()
+{
+    matrixf_t temp_mvp;
+    matrixf_t::multiply(temp_mvp, projection.top(), modelview.top());
+    mvp4.matrix.load(temp_mvp);
+    mvp4.picker();
+
+    if (mvp4.flags & transform_t::FLAGS_2D_PROJECTION) {
+        // the mvp matrix doesn't transform W, in this case we can
+        // premultiply it with the viewport transformation. In addition to
+        // being more efficient, this is also much more accurate and in fact
+        // is needed for 2D drawing with a resulting 1:1 mapping.
+        matrixf_t mvpv;
+        matrixf_t::multiply(mvpv, vpt.matrix, temp_mvp);
+        mvp.matrix.load(mvpv);
+        mvp.picker();
+    } else {
+        mvp = mvp4;
+    }
+}
+
+static inline 
+GLfloat det22(GLfloat a, GLfloat b, GLfloat c, GLfloat d) {
+    return a*d - b*c;
+}
+
+static inline
+GLfloat ndet22(GLfloat a, GLfloat b, GLfloat c, GLfloat d) {
+    return b*c - a*d;
+}
+
+static __attribute__((noinline))
+void invert(GLfloat* inverse, const GLfloat* src)
+{
+    double t;
+    int i, j, k, swap;
+    GLfloat tmp[4][4];
+    
+    memcpy(inverse, gIdentityf, sizeof(gIdentityf));
+    memcpy(tmp, src, sizeof(GLfloat)*16);
+    
+    for (i = 0; i < 4; i++) {
+        // look for largest element in column
+        swap = i;
+        for (j = i + 1; j < 4; j++) {
+            if (fabs(tmp[j][i]) > fabs(tmp[i][i])) {
+                swap = j;
+            }
+        }
+        
+        if (swap != i) {
+            /* swap rows. */
+            for (k = 0; k < 4; k++) {
+                t = tmp[i][k];
+                tmp[i][k] = tmp[swap][k];
+                tmp[swap][k] = t;
+                
+                t = inverse[i*4+k];
+                inverse[i*4+k] = inverse[swap*4+k];
+                inverse[swap*4+k] = t;
+            }
+        }
+        
+        t = 1.0f / tmp[i][i];
+        for (k = 0; k < 4; k++) {
+            tmp[i][k] *= t;
+            inverse[i*4+k] *= t;
+        }
+        for (j = 0; j < 4; j++) {
+            if (j != i) {
+                t = tmp[j][i];
+                for (k = 0; k < 4; k++) {
+                    tmp[j][k] -= tmp[i][k]*t;
+                    inverse[j*4+k] -= inverse[i*4+k]*t;
+                }
+            }
+        }
+    }
+}
+
+void transform_state_t::update_mvit()
+{
+    GLfloat r[16];
+    const GLfloat* const mv = modelview.top().elements();
+    invert(r, mv);
+    // convert to fixed-point and transpose
+    GLfixed* const x = mvit4.matrix.m;
+    for (int i=0 ; i<4 ; i++)
+        for (int j=0 ; j<4 ; j++)
+            x[I(i,j)] = gglFloatToFixed(r[I(j,i)]);
+    mvit4.picker();
+}
+
+void transform_state_t::update_mvui()
+{
+    const GLfloat* const mv = modelview.top().elements();
+
+    /*
+    When transforming normals, we can use the upper 3x3 matrix, see:
+    http://www.opengl.org/documentation/specs/version1.1/glspec1.1/node26.html
+    */
+    
+    // Also note that:
+    //      l(obj) =  tr(M).l(eye) for infinite light
+    //      l(obj) = inv(M).l(eye) for local light
+
+    const uint32_t ops = modelview.top_ops() & ~OP_TRANSLATE;
+    if (ggl_likely((!(ops & ~OP_ROTATE)) ||
+        (rescaleNormals && modelview.isRigidBody()))) {
+        // if the modelview matrix is a rigid body transformation
+        // (translation, rotation, uniform scaling), then we can bypass
+        // the inverse by transposing the matrix.
+        GLfloat rescale = 1.0f;
+        if (rescaleNormals == GL_RESCALE_NORMAL) {
+            if (!(ops & ~OP_UNIFORM_SCALE)) {
+                rescale = reciprocalf(mv[I(0,0)]);
+            } else {
+                rescale = rsqrtf(
+                        sqrf(mv[I(2,0)]) + sqrf(mv[I(2,1)]) + sqrf(mv[I(2,2)]));
+            }
+        }
+        GLfixed* const x = mvui.matrix.m;
+        for (int i=0 ; i<3 ; i++) {
+            x[I(i,0)] = gglFloatToFixed(mv[I(0,i)] * rescale);
+            x[I(i,1)] = gglFloatToFixed(mv[I(1,i)] * rescale);
+            x[I(i,2)] = gglFloatToFixed(mv[I(2,i)] * rescale);
+        }
+        mvui.picker();
+        return;
+    }
+
+    GLfloat r[3][3];
+    r[0][0] = det22(mv[I(1,1)], mv[I(2,1)], mv[I(1,2)], mv[I(2,2)]);
+    r[0][1] =ndet22(mv[I(0,1)], mv[I(2,1)], mv[I(0,2)], mv[I(2,2)]);
+    r[0][2] = det22(mv[I(0,1)], mv[I(1,1)], mv[I(0,2)], mv[I(1,2)]);
+    r[1][0] =ndet22(mv[I(1,0)], mv[I(2,0)], mv[I(1,2)], mv[I(2,2)]);
+    r[1][1] = det22(mv[I(0,0)], mv[I(2,0)], mv[I(0,2)], mv[I(2,2)]);
+    r[1][2] =ndet22(mv[I(0,0)], mv[I(1,0)], mv[I(0,2)], mv[I(1,2)]);
+    r[2][0] = det22(mv[I(1,0)], mv[I(2,0)], mv[I(1,1)], mv[I(2,1)]);
+    r[2][1] =ndet22(mv[I(0,0)], mv[I(2,0)], mv[I(0,1)], mv[I(2,1)]);
+    r[2][2] = det22(mv[I(0,0)], mv[I(1,0)], mv[I(0,1)], mv[I(1,1)]);        
+
+    GLfloat rdet;
+    if (rescaleNormals == GL_RESCALE_NORMAL) {
+        rdet = rsqrtf(sqrf(r[0][2]) + sqrf(r[1][2]) + sqrf(r[2][2]));
+    } else {
+        rdet = reciprocalf( 
+            r[0][0]*mv[I(0,0)] + r[0][1]*mv[I(1,0)] + r[0][2]*mv[I(2,0)]);
+    }
+
+    GLfixed* const x = mvui.matrix.m;
+    for (int i=0 ; i<3 ; i++) {
+        x[I(i,0)] = gglFloatToFixed(r[i][0] * rdet);
+        x[I(i,1)] = gglFloatToFixed(r[i][1] * rdet);
+        x[I(i,2)] = gglFloatToFixed(r[i][2] * rdet);
+    }
+    mvui.picker();
+}
+
+
+// ----------------------------------------------------------------------------
+// transformation and matrices API
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark transformation and matrices API
+#endif
+
+int ogles_surfaceport(ogles_context_t* c, GLint x, GLint y)
+{
+    c->viewport.surfaceport.x = x;
+    c->viewport.surfaceport.y = y;
+
+    ogles_viewport(c, 
+            c->viewport.x,
+            c->viewport.y,
+            c->viewport.w,
+            c->viewport.h);
+
+    ogles_scissor(c,
+            c->viewport.scissor.x,
+            c->viewport.scissor.y,
+            c->viewport.scissor.w,
+            c->viewport.scissor.h);
+
+    return 0;
+}
+
+void ogles_scissor(ogles_context_t* c, 
+        GLint x, GLint y, GLsizei w, GLsizei h)
+{
+    if ((w|h) < 0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    c->viewport.scissor.x = x;
+    c->viewport.scissor.y = y;
+    c->viewport.scissor.w = w;
+    c->viewport.scissor.h = h;
+    
+    x += c->viewport.surfaceport.x;
+    y += c->viewport.surfaceport.y;
+
+    y = c->rasterizer.state.buffers.color.height - (y + h);
+    c->rasterizer.procs.scissor(c, x, y, w, h);
+}
+
+void ogles_viewport(ogles_context_t* c,
+        GLint x, GLint y, GLsizei w, GLsizei h)
+{
+    if ((w|h)<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+
+    c->viewport.x = x;
+    c->viewport.y = y;
+    c->viewport.w = w;
+    c->viewport.h = h;
+
+    x += c->viewport.surfaceport.x;
+    y += c->viewport.surfaceport.y;
+
+    GLint H = c->rasterizer.state.buffers.color.height;
+    GLfloat sx = div2f(w);
+    GLfloat ox = sx + x;
+    GLfloat sy = div2f(h);
+    GLfloat oy = sy - y + (H - h);
+
+    GLfloat near = c->transforms.vpt.zNear;
+    GLfloat far  = c->transforms.vpt.zFar;
+    GLfloat A = div2f(far - near);
+    GLfloat B = div2f(far + near);
+
+    // compute viewport matrix
+    GLfloat* const f = c->transforms.vpt.matrix.editElements();
+    f[0] = sx;  f[4] = 0;   f[ 8] = 0;  f[12] = ox;
+    f[1] = 0;   f[5] =-sy;  f[ 9] = 0;  f[13] = oy;
+    f[2] = 0;   f[6] = 0;   f[10] = A;  f[14] = B;
+    f[3] = 0;   f[7] = 0;   f[11] = 0;  f[15] = 1;
+    c->transforms.dirty |= transform_state_t::VIEWPORT;
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark matrix * vertex
+#endif
+
+void point2__generic(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) {
+    const GLfixed* const m = mx->matrix.m;
+    const GLfixed rx = rhs->x;
+    const GLfixed ry = rhs->y;
+    lhs->x = mla2a(rx, m[ 0], ry, m[ 4], m[12]); 
+    lhs->y = mla2a(rx, m[ 1], ry, m[ 5], m[13]);
+    lhs->z = mla2a(rx, m[ 2], ry, m[ 6], m[14]);
+    lhs->w = mla2a(rx, m[ 3], ry, m[ 7], m[15]);
+}
+
+void point3__generic(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) {
+    const GLfixed* const m = mx->matrix.m;
+    const GLfixed rx = rhs->x;
+    const GLfixed ry = rhs->y;
+    const GLfixed rz = rhs->z;
+    lhs->x = mla3a(rx, m[ 0], ry, m[ 4], rz, m[ 8], m[12]); 
+    lhs->y = mla3a(rx, m[ 1], ry, m[ 5], rz, m[ 9], m[13]);
+    lhs->z = mla3a(rx, m[ 2], ry, m[ 6], rz, m[10], m[14]);
+    lhs->w = mla3a(rx, m[ 3], ry, m[ 7], rz, m[11], m[15]);
+}
+
+void point4__generic(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) {
+    const GLfixed* const m = mx->matrix.m;
+    const GLfixed rx = rhs->x;
+    const GLfixed ry = rhs->y;
+    const GLfixed rz = rhs->z;
+    const GLfixed rw = rhs->w;
+    lhs->x = mla4(rx, m[ 0], ry, m[ 4], rz, m[ 8], rw, m[12]); 
+    lhs->y = mla4(rx, m[ 1], ry, m[ 5], rz, m[ 9], rw, m[13]);
+    lhs->z = mla4(rx, m[ 2], ry, m[ 6], rz, m[10], rw, m[14]);
+    lhs->w = mla4(rx, m[ 3], ry, m[ 7], rz, m[11], rw, m[15]);
+}
+
+void normal__generic(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) {
+    const GLfixed* const m = mx->matrix.m;
+    const GLfixed rx = rhs->x;
+    const GLfixed ry = rhs->y;
+    const GLfixed rz = rhs->z;
+    lhs->x = mla3(rx, m[ 0], ry, m[ 4], rz, m[ 8]); 
+    lhs->y = mla3(rx, m[ 1], ry, m[ 5], rz, m[ 9]);
+    lhs->z = mla3(rx, m[ 2], ry, m[ 6], rz, m[10]);
+}
+
+
+void point2__nop(transform_t const*, vec4_t* lhs, vec4_t const* rhs) {
+    lhs->z = 0;
+    lhs->w = 0x10000;
+    if (lhs != rhs) {
+        lhs->x = rhs->x;
+        lhs->y = rhs->y;
+    }
+}
+
+void point3__nop(transform_t const*, vec4_t* lhs, vec4_t const* rhs) {
+    lhs->w = 0x10000;
+    if (lhs != rhs) {
+        lhs->x = rhs->x;
+        lhs->y = rhs->y;
+        lhs->z = rhs->z;
+    }
+}
+
+void point4__nop(transform_t const*, vec4_t* lhs, vec4_t const* rhs) {
+    if (lhs != rhs)
+        *lhs = *rhs;
+}
+
+
+static void frustumf(
+            GLfloat left, GLfloat right, 
+            GLfloat bottom, GLfloat top,
+            GLfloat zNear, GLfloat zFar,
+            ogles_context_t* c)
+    {
+    if (cmpf(left,right) ||
+        cmpf(top, bottom) ||
+        cmpf(zNear, zFar) ||
+        isZeroOrNegativef(zNear) ||
+        isZeroOrNegativef(zFar))
+    {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    const GLfloat r_width  = reciprocalf(right - left);
+    const GLfloat r_height = reciprocalf(top - bottom);
+    const GLfloat r_depth  = reciprocalf(zNear - zFar);
+    const GLfloat x = mul2f(zNear * r_width);
+    const GLfloat y = mul2f(zNear * r_height);
+    const GLfloat A = mul2f((right + left) * r_width);
+    const GLfloat B = (top + bottom) * r_height;
+    const GLfloat C = (zFar + zNear) * r_depth;
+    const GLfloat D = mul2f(zFar * zNear * r_depth);
+    GLfloat f[16];
+    f[ 0] = x;
+    f[ 5] = y;
+    f[ 8] = A;
+    f[ 9] = B;
+    f[10] = C;
+    f[14] = D;
+    f[11] = -1.0f;
+    f[ 1] = f[ 2] = f[ 3] =
+    f[ 4] = f[ 6] = f[ 7] =
+    f[12] = f[13] = f[15] = 0.0f;
+
+    matrixf_t rhs;
+    rhs.set(f);
+    c->transforms.current->multiply(rhs);
+    c->transforms.invalidate();
+}
+
+static void orthof( 
+        GLfloat left, GLfloat right, 
+        GLfloat bottom, GLfloat top,
+        GLfloat zNear, GLfloat zFar,
+        ogles_context_t* c)
+{
+    if (cmpf(left,right) ||
+        cmpf(top, bottom) ||
+        cmpf(zNear, zFar))
+    {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    const GLfloat r_width  = reciprocalf(right - left);
+    const GLfloat r_height = reciprocalf(top - bottom);
+    const GLfloat r_depth  = reciprocalf(zFar - zNear);
+    const GLfloat x =  mul2f(r_width);
+    const GLfloat y =  mul2f(r_height);
+    const GLfloat z = -mul2f(r_depth);
+    const GLfloat tx = -(right + left) * r_width;
+    const GLfloat ty = -(top + bottom) * r_height;
+    const GLfloat tz = -(zFar + zNear) * r_depth;
+    GLfloat f[16];
+    f[ 0] = x;
+    f[ 5] = y;
+    f[10] = z;
+    f[12] = tx;
+    f[13] = ty;
+    f[14] = tz;
+    f[15] = 1.0f;
+    f[ 1] = f[ 2] = f[ 3] =
+    f[ 4] = f[ 6] = f[ 7] =
+    f[ 8] = f[ 9] = f[11] = 0.0f;
+    matrixf_t rhs;
+    rhs.set(f);
+    c->transforms.current->multiply(rhs);
+    c->transforms.invalidate();
+}
+
+static void depthRangef(GLclampf zNear, GLclampf zFar, ogles_context_t* c)
+{
+    zNear = clampToZerof(zNear > 1 ? 1 : zNear);
+    zFar  = clampToZerof(zFar  > 1 ? 1 : zFar);
+    GLfloat* const f = c->transforms.vpt.matrix.editElements();
+    f[10] = div2f(zFar - zNear);
+    f[14] = div2f(zFar + zNear);
+    c->transforms.dirty |= transform_state_t::VIEWPORT;
+    c->transforms.vpt.zNear = zNear;
+    c->transforms.vpt.zFar  = zFar;
+}
+
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+using namespace android;
+
+void glMatrixMode(GLenum mode)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    matrix_stack_t* stack = 0;
+    switch (mode) {
+    case GL_MODELVIEW:
+        stack = &c->transforms.modelview;
+        break;
+    case GL_PROJECTION:
+        stack = &c->transforms.projection;
+        break;
+    case GL_TEXTURE:
+        stack = &c->transforms.texture[c->textures.active];
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->transforms.matrixMode = mode;
+    c->transforms.current = stack;
+}
+
+void glLoadIdentity()
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->transforms.current->loadIdentity(); // also loads the GLfixed transform
+    c->transforms.invalidate();
+    c->transforms.current->dirty = 0;
+}
+
+void glLoadMatrixf(const GLfloat* m)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->transforms.current->load(m);
+    c->transforms.invalidate();
+}
+
+void glLoadMatrixx(const GLfixed* m)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->transforms.current->load(m); // also loads the GLfixed transform
+    c->transforms.invalidate();
+    c->transforms.current->dirty &= ~matrix_stack_t::DO_FLOAT_TO_FIXED;
+}
+
+void glMultMatrixf(const GLfloat* m)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    matrixf_t rhs;
+    rhs.set(m);
+    c->transforms.current->multiply(rhs);
+    c->transforms.invalidate();
+}
+
+void glMultMatrixx(const GLfixed* m)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    matrixf_t rhs;
+    rhs.set(m);
+    c->transforms.current->multiply(rhs);
+    c->transforms.invalidate();
+}
+
+void glPopMatrix()
+{
+    ogles_context_t* c = ogles_context_t::get();
+    GLint err = c->transforms.current->pop();
+    if (ggl_unlikely(err)) {
+        ogles_error(c, err);
+        return;
+    }
+    c->transforms.invalidate();
+}
+
+void glPushMatrix()
+{
+    ogles_context_t* c = ogles_context_t::get();
+    GLint err = c->transforms.current->push();
+    if (ggl_unlikely(err)) {
+        ogles_error(c, err);
+        return;
+    }
+    c->transforms.invalidate();
+}
+
+void glFrustumf(
+        GLfloat left, GLfloat right, 
+        GLfloat bottom, GLfloat top,
+        GLfloat zNear, GLfloat zFar)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    frustumf(left, right, bottom, top, zNear, zFar, c);
+}
+
+void glFrustumx( 
+        GLfixed left, GLfixed right,
+        GLfixed bottom, GLfixed top,
+        GLfixed zNear, GLfixed zFar)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    frustumf( fixedToFloat(left), fixedToFloat(right),
+              fixedToFloat(bottom), fixedToFloat(top),
+              fixedToFloat(zNear), fixedToFloat(zFar),
+              c);
+}
+
+void glOrthof( 
+        GLfloat left, GLfloat right, 
+        GLfloat bottom, GLfloat top,
+        GLfloat zNear, GLfloat zFar)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    orthof(left, right, bottom, top, zNear, zFar, c);
+}
+
+void glOrthox(
+        GLfixed left, GLfixed right,
+        GLfixed bottom, GLfixed top,
+        GLfixed zNear, GLfixed zFar)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    orthof( fixedToFloat(left), fixedToFloat(right),
+            fixedToFloat(bottom), fixedToFloat(top),
+            fixedToFloat(zNear), fixedToFloat(zFar),
+            c);
+}
+
+void glRotatef(GLfloat a, GLfloat x, GLfloat y, GLfloat z)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->transforms.current->rotate(a, x, y, z);
+    c->transforms.invalidate();
+}
+
+void glRotatex(GLfixed a, GLfixed x, GLfixed y, GLfixed z)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->transforms.current->rotate( 
+            fixedToFloat(a), fixedToFloat(x),
+            fixedToFloat(y), fixedToFloat(z));
+    c->transforms.invalidate();
+}
+
+void glScalef(GLfloat x, GLfloat y, GLfloat z)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->transforms.current->scale(x, y, z);
+    c->transforms.invalidate();
+}
+
+void glScalex(GLfixed x, GLfixed y, GLfixed z)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->transforms.current->scale(
+            fixedToFloat(x), fixedToFloat(y), fixedToFloat(z));
+    c->transforms.invalidate();
+}
+
+void glTranslatef(GLfloat x, GLfloat y, GLfloat z)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->transforms.current->translate(x, y, z);
+    c->transforms.invalidate();
+}
+
+void glTranslatex(GLfixed x, GLfixed y, GLfixed z)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->transforms.current->translate(
+            fixedToFloat(x), fixedToFloat(y), fixedToFloat(z));
+    c->transforms.invalidate();
+}
+
+void glScissor(GLint x, GLint y, GLsizei w, GLsizei h)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    ogles_scissor(c, x, y, w, h);
+}
+
+void glViewport(GLint x, GLint y, GLsizei w, GLsizei h)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    ogles_viewport(c, x, y, w, h);
+}
+
+void glDepthRangef(GLclampf zNear, GLclampf zFar)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    depthRangef(zNear, zFar, c);
+}
+
+void glDepthRangex(GLclampx zNear, GLclampx zFar)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    depthRangef(fixedToFloat(zNear), fixedToFloat(zFar), c);
+}
+
+void glPolygonOffsetx(GLfixed factor, GLfixed units)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->polygonOffset.factor = factor;
+    c->polygonOffset.units = units;
+}
+
+void glPolygonOffset(GLfloat factor, GLfloat units)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->polygonOffset.factor = gglFloatToFixed(factor);
+    c->polygonOffset.units = gglFloatToFixed(units);
+}
+
+GLbitfield glQueryMatrixxOES(GLfixed* m, GLint* e)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    GLbitfield status = 0;
+    GLfloat const* f = c->transforms.current->top().elements();
+    for  (int i=0 ; i<16 ; i++) {
+        if (isnan(f[i]) || isinf(f[i])) {
+            status |= 1<<i;
+            continue;
+        }
+        e[i] = exponent(f[i]) - 7;
+        m[i] = mantissa(f[i]);
+    }
+    return status;
+}
diff --git a/opengl/libagl/matrix.h b/opengl/libagl/matrix.h
new file mode 100644
index 0000000..c9a38a9
--- /dev/null
+++ b/opengl/libagl/matrix.h
@@ -0,0 +1,355 @@
+/* libs/opengles/matrix.h
+**
+** 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 
+**
+**     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_MATRIX_H
+#define ANDROID_OPENGLES_MATRIX_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <utils/Log.h>
+
+#include <private/pixelflinger/ggl_context.h>
+
+#include <GLES/gl.h>
+
+namespace android {
+
+const int OGLES_MODELVIEW_STACK_DEPTH   = 16;
+const int OGLES_PROJECTION_STACK_DEPTH  =  2;
+const int OGLES_TEXTURE_STACK_DEPTH     =  2;
+
+void ogles_init_matrix(ogles_context_t*);
+void ogles_uninit_matrix(ogles_context_t*);
+void ogles_invalidate_perspective(ogles_context_t* c);
+void ogles_validate_transform_impl(ogles_context_t* c, uint32_t want);
+
+int ogles_surfaceport(ogles_context_t* c, GLint x, GLint y);
+
+void ogles_scissor(ogles_context_t* c, 
+        GLint x, GLint y, GLsizei w, GLsizei h);
+
+void ogles_viewport(ogles_context_t* c,
+        GLint x, GLint y, GLsizei w, GLsizei h);
+
+inline void ogles_validate_transform(
+        ogles_context_t* c, uint32_t want)
+{
+    if (c->transforms.dirty & want)
+        ogles_validate_transform_impl(c, want);
+}
+
+// ----------------------------------------------------------------------------
+
+inline
+GLfixed vsquare3(GLfixed a, GLfixed b, GLfixed c) 
+{
+#if defined(__arm__) && !defined(__thumb__)
+
+    GLfixed r;
+    int32_t t;
+    asm(
+        "smull %0, %1, %2, %2       \n"
+        "smlal %0, %1, %3, %3       \n"
+        "smlal %0, %1, %4, %4       \n"
+        "movs  %0, %0, lsr #16      \n"
+        "adc   %0, %0, %1, lsl #16  \n"
+        :   "=&r"(r), "=&r"(t) 
+        :   "%r"(a), "r"(b), "r"(c)
+        :   "cc"
+        ); 
+    return r;
+
+#else
+
+    return ((   int64_t(a)*a +
+                int64_t(b)*b +
+                int64_t(c)*c + 0x8000)>>16);
+
+#endif
+}
+
+static inline GLfixed mla2a( GLfixed a0, GLfixed b0,
+                            GLfixed a1, GLfixed b1,
+                            GLfixed c)
+{
+#if defined(__arm__) && !defined(__thumb__)
+                            
+    GLfixed r;
+    int32_t t;
+    asm(
+        "smull %0, %1, %2, %3       \n"
+        "smlal %0, %1, %4, %5       \n"
+        "add   %0, %6, %0, lsr #16  \n"
+        "add   %0, %0, %1, lsl #16  \n"
+        :   "=&r"(r), "=&r"(t) 
+        :   "%r"(a0), "r"(b0), 
+            "%r"(a1), "r"(b1),
+            "r"(c)
+        :
+        ); 
+    return r;
+    
+#else
+
+    return ((   int64_t(a0)*b0 +
+                int64_t(a1)*b1)>>16) + c;
+
+#endif
+}
+
+static inline GLfixed mla3a( GLfixed a0, GLfixed b0,
+                             GLfixed a1, GLfixed b1,
+                             GLfixed a2, GLfixed b2,
+                             GLfixed c)
+{
+#if defined(__arm__) && !defined(__thumb__)
+                            
+    GLfixed r;
+    int32_t t;
+    asm(
+        "smull %0, %1, %2, %3       \n"
+        "smlal %0, %1, %4, %5       \n"
+        "smlal %0, %1, %6, %7       \n"
+        "add   %0, %8, %0, lsr #16  \n"
+        "add   %0, %0, %1, lsl #16  \n"
+        :   "=&r"(r), "=&r"(t) 
+        :   "%r"(a0), "r"(b0),
+            "%r"(a1), "r"(b1),
+            "%r"(a2), "r"(b2),
+            "r"(c)
+        :
+        ); 
+    return r;
+    
+#else
+
+    return ((   int64_t(a0)*b0 +
+                int64_t(a1)*b1 +
+                int64_t(a2)*b2)>>16) + c;
+
+#endif
+}
+
+// b0, b1, b2 are signed 16-bit quanities
+// that have been shifted right by 'shift' bits relative to normal
+// S16.16 fixed point
+static inline GLfixed mla3a16( GLfixed a0, int32_t b1b0,
+                               GLfixed a1,
+                               GLfixed a2, int32_t b2,
+                               GLint shift,
+                               GLfixed c)
+{
+#if defined(__arm__) && !defined(__thumb__)
+                            
+    GLfixed r;
+    asm(
+        "smulwb %0, %1, %2          \n"
+        "smlawt %0, %3, %2, %0      \n" 
+        "smlawb %0, %4, %5, %0      \n"
+        "add    %0, %7, %0, lsl %6  \n"
+        :   "=&r"(r)
+        :   "r"(a0), "r"(b1b0),
+            "r"(a1),
+            "r"(a2), "r"(b2),
+            "r"(shift),
+            "r"(c)
+        :
+        ); 
+    return r;
+    
+#else
+
+    int32_t accum;
+    int16_t b0 = b1b0 & 0xffff;
+    int16_t b1 = (b1b0 >> 16) & 0xffff;
+    accum  = int64_t(a0)*int16_t(b0) >> 16;
+    accum += int64_t(a1)*int16_t(b1) >> 16;
+    accum += int64_t(a2)*int16_t(b2) >> 16;
+    accum = (accum << shift) + c;
+    return accum;
+
+#endif
+}
+
+
+static inline GLfixed mla3a16_btb( GLfixed a0,
+                                   GLfixed a1,
+                                   GLfixed a2,
+                                   int32_t b1b0, int32_t xxb2,
+                                   GLint shift,
+                                   GLfixed c)
+{
+#if defined(__arm__) && !defined(__thumb__)
+                            
+    GLfixed r;
+    asm(
+        "smulwb %0, %1, %4          \n"
+        "smlawt %0, %2, %4, %0      \n" 
+        "smlawb %0, %3, %5, %0      \n"
+        "add    %0, %7, %0, lsl %6  \n"
+        :   "=&r"(r)
+        :   "r"(a0),
+            "r"(a1),
+            "r"(a2),
+            "r"(b1b0), "r"(xxb2),
+            "r"(shift),
+            "r"(c)
+        :
+        ); 
+    return r;
+    
+#else
+
+    int32_t accum;
+    int16_t b0 =  b1b0        & 0xffff;
+    int16_t b1 = (b1b0 >> 16) & 0xffff;
+    int16_t b2 =  xxb2        & 0xffff;
+    accum  = int64_t(a0)*int16_t(b0) >> 16;
+    accum += int64_t(a1)*int16_t(b1) >> 16;
+    accum += int64_t(a2)*int16_t(b2) >> 16;
+    accum = (accum << shift) + c;
+    return accum;
+
+#endif
+}
+
+static inline GLfixed mla3a16_btt( GLfixed a0,
+                                   GLfixed a1,
+                                   GLfixed a2,
+                                   int32_t b1b0, int32_t b2xx,
+                                   GLint shift,
+                                   GLfixed c)
+{
+#if defined(__arm__) && !defined(__thumb__)
+                            
+    GLfixed r;
+    asm(
+        "smulwb %0, %1, %4          \n"
+        "smlawt %0, %2, %4, %0      \n" 
+        "smlawt %0, %3, %5, %0      \n"
+        "add    %0, %7, %0, lsl %6  \n"
+        :   "=&r"(r)
+        :   "r"(a0),
+            "r"(a1),
+            "r"(a2),
+            "r"(b1b0), "r"(b2xx),
+            "r"(shift),
+            "r"(c)
+        :
+        ); 
+    return r;
+    
+#else
+
+    int32_t accum;
+    int16_t b0 =  b1b0        & 0xffff;
+    int16_t b1 = (b1b0 >> 16) & 0xffff;
+    int16_t b2 = (b2xx >> 16) & 0xffff;
+    accum  = int64_t(a0)*int16_t(b0) >> 16;
+    accum += int64_t(a1)*int16_t(b1) >> 16;
+    accum += int64_t(a2)*int16_t(b2) >> 16;
+    accum = (accum << shift) + c;
+    return accum;
+
+#endif
+}
+
+static inline GLfixed mla3( GLfixed a0, GLfixed b0,
+                            GLfixed a1, GLfixed b1,
+                            GLfixed a2, GLfixed b2)
+{
+#if defined(__arm__) && !defined(__thumb__)
+                            
+    GLfixed r;
+    int32_t t;
+    asm(
+        "smull %0, %1, %2, %3       \n"
+        "smlal %0, %1, %4, %5       \n"
+        "smlal %0, %1, %6, %7       \n"
+        "movs  %0, %0, lsr #16      \n"
+        "adc   %0, %0, %1, lsl #16  \n"
+        :   "=&r"(r), "=&r"(t) 
+        :   "%r"(a0), "r"(b0),
+            "%r"(a1), "r"(b1),
+            "%r"(a2), "r"(b2)
+        :   "cc"
+        ); 
+    return r;
+    
+#else
+
+    return ((   int64_t(a0)*b0 +
+                int64_t(a1)*b1 +
+                int64_t(a2)*b2 + 0x8000)>>16);
+
+#endif
+}
+
+static inline GLfixed mla4( GLfixed a0, GLfixed b0,
+                            GLfixed a1, GLfixed b1,
+                            GLfixed a2, GLfixed b2,
+                            GLfixed a3, GLfixed b3)
+{
+#if defined(__arm__) && !defined(__thumb__)
+                            
+    GLfixed r;
+    int32_t t;
+    asm(
+        "smull %0, %1, %2, %3       \n"
+        "smlal %0, %1, %4, %5       \n"
+        "smlal %0, %1, %6, %7       \n"
+        "smlal %0, %1, %8, %9       \n"
+        "movs  %0, %0, lsr #16      \n"
+        "adc   %0, %0, %1, lsl #16  \n"
+        :   "=&r"(r), "=&r"(t) 
+        :   "%r"(a0), "r"(b0),
+            "%r"(a1), "r"(b1),
+            "%r"(a2), "r"(b2),
+            "%r"(a3), "r"(b3)
+        :   "cc"
+        ); 
+    return r;
+    
+#else
+
+    return ((   int64_t(a0)*b0 +
+                int64_t(a1)*b1 +
+                int64_t(a2)*b2 +
+                int64_t(a3)*b3 + 0x8000)>>16);
+
+#endif
+}
+
+inline
+GLfixed dot4(const GLfixed* a, const GLfixed* b) 
+{
+    return mla4(a[0], b[0], a[1], b[1], a[2], b[2], a[3], b[3]);
+}
+
+
+inline
+GLfixed dot3(const GLfixed* a, const GLfixed* b) 
+{
+    return mla3(a[0], b[0], a[1], b[1], a[2], b[2]);
+}
+
+
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_MATRIX_H
+
diff --git a/opengl/libagl/mipmap.cpp b/opengl/libagl/mipmap.cpp
new file mode 100644
index 0000000..ccd77b7
--- /dev/null
+++ b/opengl/libagl/mipmap.cpp
@@ -0,0 +1,192 @@
+/* libs/opengles/mipmap.cpp
+**
+** 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 
+**
+**     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 <stdio.h>
+#include <stdlib.h>
+
+#include "context.h"
+#include "state.h"
+#include "texture.h"
+#include "TextureObjectManager.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+status_t buildAPyramid(ogles_context_t* c, EGLTextureObject* tex)
+{
+    int level = 0;
+    const GGLSurface* base = &tex->surface;    
+    const GGLFormat& pixelFormat(c->rasterizer.formats[base->format]);
+
+    int w = base->width;
+    int h = base->height;
+    if ((w&h) == 1)
+        return NO_ERROR;
+
+    w = (w>>1) ? : 1;
+    h = (h>>1) ? : 1;
+
+    while(true) {
+        ++level;
+        const int bpr = w * pixelFormat.size;
+        if (tex->reallocate(level, w, h, w,
+                base->format, base->compressedFormat, bpr) != NO_ERROR) {
+            return NO_MEMORY;
+        }
+    
+        int stride = w;
+        int bs = base->stride;
+        GGLSurface& cur = tex->editMip(level);
+
+        if (base->format == GGL_PIXEL_FORMAT_RGB_565)
+        {
+            uint16_t const * src = (uint16_t const *)base->data;
+            uint16_t* dst = (uint16_t*)cur.data;
+            const uint32_t mask = 0x07E0F81F;
+            for (int y=0 ; y<h ; y++) {
+                size_t offset = (y*2) * bs;
+                for (int x=0 ; x<w ; x++) {
+                    uint32_t p00 = src[offset];
+                    uint32_t p10 = src[offset+1];
+                    uint32_t p01 = src[offset+bs];
+                    uint32_t p11 = src[offset+bs+1];
+                    p00 = (p00 | (p00 << 16)) & mask;
+                    p01 = (p01 | (p01 << 16)) & mask;
+                    p10 = (p10 | (p10 << 16)) & mask;
+                    p11 = (p11 | (p11 << 16)) & mask;
+                    uint32_t grb = ((p00 + p10 + p01 + p11) >> 2) & mask;
+                    uint32_t rgb = (grb & 0xFFFF) | (grb >> 16);
+                    dst[x + y*stride] = rgb;
+                    offset += 2;
+                }
+            }
+        }
+        else if (base->format == GGL_PIXEL_FORMAT_RGBA_5551)
+        {
+            uint16_t const * src = (uint16_t const *)base->data;
+            uint16_t* dst = (uint16_t*)cur.data;
+            for (int y=0 ; y<h ; y++) {
+                size_t offset = (y*2) * bs;
+                for (int x=0 ; x<w ; x++) {
+                    uint32_t p00 = src[offset];
+                    uint32_t p10 = src[offset+1];
+                    uint32_t p01 = src[offset+bs];
+                    uint32_t p11 = src[offset+bs+1];
+                    uint32_t r = ((p00>>11)+(p10>>11)+(p01>>11)+(p11>>11)+2)>>2;
+                    uint32_t g = (((p00>>6)+(p10>>6)+(p01>>6)+(p11>>6)+2)>>2)&0x3F;
+                    uint32_t b = ((p00&0x3E)+(p10&0x3E)+(p01&0x3E)+(p11&0x3E)+4)>>3;
+                    uint32_t a = ((p00&1)+(p10&1)+(p01&1)+(p11&1)+2)>>2;
+                    dst[x + y*stride] = (r<<11)|(g<<6)|(b<<1)|a;
+                    offset += 2;
+                }
+            }
+        }
+        else if (base->format == GGL_PIXEL_FORMAT_RGBA_8888)
+        {
+            uint32_t const * src = (uint32_t const *)base->data;
+            uint32_t* dst = (uint32_t*)cur.data;
+            for (int y=0 ; y<h ; y++) {
+                size_t offset = (y*2) * bs;
+                for (int x=0 ; x<w ; x++) {
+                    uint32_t p00 = src[offset];
+                    uint32_t p10 = src[offset+1];
+                    uint32_t p01 = src[offset+bs];
+                    uint32_t p11 = src[offset+bs+1];
+                    uint32_t rb00 = p00 & 0x00FF00FF;
+                    uint32_t rb01 = p01 & 0x00FF00FF;
+                    uint32_t rb10 = p10 & 0x00FF00FF;
+                    uint32_t rb11 = p11 & 0x00FF00FF;
+                    uint32_t ga00 = (p00 >> 8) & 0x00FF00FF;
+                    uint32_t ga01 = (p01 >> 8) & 0x00FF00FF;
+                    uint32_t ga10 = (p10 >> 8) & 0x00FF00FF;
+                    uint32_t ga11 = (p11 >> 8) & 0x00FF00FF;
+                    uint32_t rb = (rb00 + rb01 + rb10 + rb11)>>2;
+                    uint32_t ga = (ga00 + ga01 + ga10 + ga11)>>2;
+                    uint32_t rgba = (rb & 0x00FF00FF) | ((ga & 0x00FF00FF)<<8);
+                    dst[x + y*stride] = rgba;
+                    offset += 2;
+                }
+            }
+        }
+        else if ((base->format == GGL_PIXEL_FORMAT_RGB_888) ||
+                 (base->format == GGL_PIXEL_FORMAT_LA_88) ||
+                 (base->format == GGL_PIXEL_FORMAT_A_8) ||
+                 (base->format == GGL_PIXEL_FORMAT_L_8))
+        {
+            int skip;
+            switch (base->format) {
+            case GGL_PIXEL_FORMAT_RGB_888:  skip = 3;   break;
+            case GGL_PIXEL_FORMAT_LA_88:    skip = 2;   break;
+            default:                        skip = 1;   break;
+            }
+            uint8_t const * src = (uint8_t const *)base->data;
+            uint8_t* dst = (uint8_t*)cur.data;            
+            bs *= skip;
+            stride *= skip;
+            for (int y=0 ; y<h ; y++) {
+                size_t offset = (y*2) * bs;
+                for (int x=0 ; x<w ; x++) {
+                    for (int c=0 ; c<skip ; c++) {
+                        uint32_t p00 = src[c+offset];
+                        uint32_t p10 = src[c+offset+skip];
+                        uint32_t p01 = src[c+offset+bs];
+                        uint32_t p11 = src[c+offset+bs+skip];
+                        dst[x + y*stride + c] = (p00 + p10 + p01 + p11) >> 2;
+                    }
+                    offset += 2*skip;
+                }
+            }
+        }
+        else if (base->format == GGL_PIXEL_FORMAT_RGBA_4444)
+        {
+            uint16_t const * src = (uint16_t const *)base->data;
+            uint16_t* dst = (uint16_t*)cur.data;
+            for (int y=0 ; y<h ; y++) {
+                size_t offset = (y*2) * bs;
+                for (int x=0 ; x<w ; x++) {
+                    uint32_t p00 = src[offset];
+                    uint32_t p10 = src[offset+1];
+                    uint32_t p01 = src[offset+bs];
+                    uint32_t p11 = src[offset+bs+1];
+                    p00 = ((p00 << 12) & 0x0F0F0000) | (p00 & 0x0F0F);
+                    p10 = ((p10 << 12) & 0x0F0F0000) | (p10 & 0x0F0F);
+                    p01 = ((p01 << 12) & 0x0F0F0000) | (p01 & 0x0F0F);
+                    p11 = ((p11 << 12) & 0x0F0F0000) | (p11 & 0x0F0F);
+                    uint32_t rbga = (p00 + p10 + p01 + p11) >> 2;
+                    uint32_t rgba = (rbga & 0x0F0F) | ((rbga>>12) & 0xF0F0);
+                    dst[x + y*stride] = rgba;
+                    offset += 2;
+                }
+            }
+        } else {
+            LOGE("Unsupported format (%d)", base->format);
+            return BAD_TYPE;
+        }
+
+        // exit condition: we just processed the 1x1 LODs
+        if ((w&h) == 1)
+            break;
+
+        base = &cur;
+        w = (w>>1) ? : 1;
+        h = (h>>1) ? : 1;
+    }
+    return NO_ERROR;
+}
+
+}; // namespace android
diff --git a/opengl/libagl/primitives.cpp b/opengl/libagl/primitives.cpp
new file mode 100644
index 0000000..20e8d37
--- /dev/null
+++ b/opengl/libagl/primitives.cpp
@@ -0,0 +1,1095 @@
+/* libs/opengles/primitives.cpp
+**
+** 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 
+**
+**     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 <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "context.h"
+#include "primitives.h"
+#include "light.h"
+#include "matrix.h"
+#include "vertex.h"
+#include "fp.h"
+#include "TextureObjectManager.h"
+
+extern "C" void iterators0032(const void* that,
+        int32_t* it, int32_t c0, int32_t c1, int32_t c2);
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static void primitive_point(ogles_context_t* c, vertex_t* v);
+static void primitive_line(ogles_context_t* c, vertex_t* v0, vertex_t* v1);
+static void primitive_clip_triangle(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2);
+
+static void primitive_nop_point(ogles_context_t* c, vertex_t* v);
+static void primitive_nop_line(ogles_context_t* c, vertex_t* v0, vertex_t* v1);
+static void primitive_nop_triangle(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2);
+
+static inline bool cull_triangle(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2);
+
+static void lerp_triangle(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2);
+
+static void lerp_texcoords(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2);
+
+static void lerp_texcoords_w(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2);
+
+static void triangle(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2);
+
+static void clip_triangle(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2);
+
+static unsigned int clip_line(ogles_context_t* c,
+        vertex_t* s, vertex_t* p);
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+static void lightTriangleDarkSmooth(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    if (!(v0->flags & vertex_t::LIT)) {
+        v0->flags |= vertex_t::LIT;
+        const GLvoid* cp = c->arrays.color.element(
+                v0->index & vertex_cache_t::INDEX_MASK);
+        c->arrays.color.fetch(c, v0->color.v, cp);
+    }
+    if (!(v1->flags & vertex_t::LIT)) {
+        v1->flags |= vertex_t::LIT;
+        const GLvoid* cp = c->arrays.color.element(
+                v1->index & vertex_cache_t::INDEX_MASK);
+        c->arrays.color.fetch(c, v1->color.v, cp);
+    }
+    if(!(v2->flags & vertex_t::LIT)) {
+        v2->flags |= vertex_t::LIT;
+        const GLvoid* cp = c->arrays.color.element(
+                v2->index & vertex_cache_t::INDEX_MASK);
+        c->arrays.color.fetch(c, v2->color.v, cp);
+    }
+}
+
+static void lightTriangleDarkFlat(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    if (!(v2->flags & vertex_t::LIT)) {
+        v2->flags |= vertex_t::LIT;
+        const GLvoid* cp = c->arrays.color.element(
+                v2->index & vertex_cache_t::INDEX_MASK);
+        c->arrays.color.fetch(c, v2->color.v, cp);
+    }
+    // configure the rasterizer here, before we clip
+    c->rasterizer.procs.color4xv(c, v2->color.v);
+}
+
+static void lightTriangleSmooth(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    if (!(v0->flags & vertex_t::LIT))
+        c->lighting.lightVertex(c, v0);
+    if (!(v1->flags & vertex_t::LIT))
+        c->lighting.lightVertex(c, v1);
+    if(!(v2->flags & vertex_t::LIT))
+        c->lighting.lightVertex(c, v2);
+}
+
+static void lightTriangleFlat(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    if (!(v2->flags & vertex_t::LIT))
+        c->lighting.lightVertex(c, v2);
+    // configure the rasterizer here, before we clip
+    c->rasterizer.procs.color4xv(c, v2->color.v);
+}
+
+// The fog versions...
+
+static inline
+void lightVertexDarkSmoothFog(ogles_context_t* c, vertex_t* v)
+{
+    if (!(v->flags & vertex_t::LIT)) {
+        v->flags |= vertex_t::LIT;
+        v->fog = c->fog.fog(c, v->window.z);
+        const GLvoid* cp = c->arrays.color.element(
+                v->index & vertex_cache_t::INDEX_MASK);
+        c->arrays.color.fetch(c, v->color.v, cp);
+    }
+}
+static inline
+void lightVertexDarkFlatFog(ogles_context_t* c, vertex_t* v)
+{
+    if (!(v->flags & vertex_t::LIT)) {
+        v->flags |= vertex_t::LIT;
+        v->fog = c->fog.fog(c, v->window.z);
+    }
+}
+static inline
+void lightVertexSmoothFog(ogles_context_t* c, vertex_t* v)
+{
+    if (!(v->flags & vertex_t::LIT)) {
+        v->fog = c->fog.fog(c, v->window.z);
+        c->lighting.lightVertex(c, v);
+    }
+}
+
+static void lightTriangleDarkSmoothFog(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    lightVertexDarkSmoothFog(c, v0);
+    lightVertexDarkSmoothFog(c, v1);
+    lightVertexDarkSmoothFog(c, v2);
+}
+
+static void lightTriangleDarkFlatFog(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    lightVertexDarkFlatFog(c, v0);
+    lightVertexDarkFlatFog(c, v1);
+    lightVertexDarkSmoothFog(c, v2);
+    // configure the rasterizer here, before we clip
+    c->rasterizer.procs.color4xv(c, v2->color.v);
+}
+
+static void lightTriangleSmoothFog(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    lightVertexSmoothFog(c, v0);
+    lightVertexSmoothFog(c, v1);
+    lightVertexSmoothFog(c, v2);
+}
+
+static void lightTriangleFlatFog(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    lightVertexDarkFlatFog(c, v0);
+    lightVertexDarkFlatFog(c, v1);
+    lightVertexSmoothFog(c, v2);
+    // configure the rasterizer here, before we clip
+    c->rasterizer.procs.color4xv(c, v2->color.v);
+}
+
+
+
+typedef void (*light_primitive_t)(ogles_context_t*,
+        vertex_t*, vertex_t*, vertex_t*);
+
+// fog 0x4, light 0x2, smooth 0x1
+static const light_primitive_t lightPrimitive[8] = {
+    lightTriangleDarkFlat,          // no fog | dark  | flat
+    lightTriangleDarkSmooth,        // no fog | dark  | smooth
+    lightTriangleFlat,              // no fog | light | flat
+    lightTriangleSmooth,            // no fog | light | smooth
+    lightTriangleDarkFlatFog,       // fog    | dark  | flat
+    lightTriangleDarkSmoothFog,     // fog    | dark  | smooth
+    lightTriangleFlatFog,           // fog    | light | flat
+    lightTriangleSmoothFog          // fog    | light | smooth
+};
+
+void ogles_validate_primitives(ogles_context_t* c)
+{
+    const uint32_t enables = c->rasterizer.state.enables;
+
+    // set up the lighting/shading/smoothing/fogging function
+    int index = enables & GGL_ENABLE_SMOOTH ? 0x1 : 0;
+    index |= c->lighting.enable ? 0x2 : 0;
+    index |= enables & GGL_ENABLE_FOG ? 0x4 : 0;
+    c->lighting.lightTriangle = lightPrimitive[index];
+    
+    // set up the primitive renderers
+    if (ggl_likely(c->arrays.vertex.enable)) {
+        c->prims.renderPoint    = primitive_point;
+        c->prims.renderLine     = primitive_line;
+        c->prims.renderTriangle = primitive_clip_triangle;
+    } else {
+        c->prims.renderPoint    = primitive_nop_point;
+        c->prims.renderLine     = primitive_nop_line;
+        c->prims.renderTriangle = primitive_nop_triangle;
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+void compute_iterators_t::initTriangle(
+        vertex_t const* v0, vertex_t const* v1, vertex_t const* v2)
+{
+    m_dx01 = v1->window.x - v0->window.x;
+    m_dy10 = v0->window.y - v1->window.y;
+    m_dx20 = v0->window.x - v2->window.x;
+    m_dy02 = v2->window.y - v0->window.y;
+    m_area = m_dx01*m_dy02 + (-m_dy10)*m_dx20;
+}
+
+void compute_iterators_t::initLerp(vertex_t const* v0, uint32_t enables)
+{
+    m_x0 = v0->window.x;
+    m_y0 = v0->window.y;
+    const GGLcoord area = (m_area + TRI_HALF) >> TRI_FRACTION_BITS;
+    const GGLcoord minArea = 2; // cannot be inversed
+    // triangles with an area smaller than 1.0 are not smooth-shaded
+
+    int q=0, s=0, d=0;
+    if (abs(area) >= minArea) {
+        // Here we do some voodoo magic, to compute a suitable scale
+        // factor for deltas/area:
+
+        // First compute the 1/area with full 32-bits precision,
+        // gglRecipQNormalized returns a number [-0.5, 0.5[ and an exponent.
+        d = gglRecipQNormalized(area, &q);
+
+        // Then compute the minimum left-shift to not overflow the muls
+        // below. 
+        s = 32 - gglClz(abs(m_dy02)|abs(m_dy10)|abs(m_dx01)|abs(m_dx20));
+
+        // We'll keep 16-bits of precision for deltas/area. So we need
+        // to shift everything left an extra 15 bits.
+        s += 15;
+        
+        // make sure all final shifts are not > 32, because gglMulx
+        // can't handle it.
+        if (s < q) s = q;
+        if (s > 32) {
+            d >>= 32-s;
+            s = 32;
+        }
+    }
+
+    m_dx01 = gglMulx(m_dx01, d, s);
+    m_dy10 = gglMulx(m_dy10, d, s);
+    m_dx20 = gglMulx(m_dx20, d, s);
+    m_dy02 = gglMulx(m_dy02, d, s);
+    m_area_scale = 32 + q - s;
+    m_scale = 0;
+
+    if (enables & GGL_ENABLE_TMUS) {
+        const int A = gglClz(abs(m_dy02)|abs(m_dy10)|abs(m_dx01)|abs(m_dx20));
+        const int B = gglClz(abs(m_x0)|abs(m_y0));
+        m_scale = max(0, 32 - (A + 16)) +
+                  max(0, 32 - (B + TRI_FRACTION_BITS)) + 1;
+    }
+}
+
+int compute_iterators_t::iteratorsScale(GGLfixed* it,
+        int32_t c0, int32_t c1, int32_t c2) const
+{
+    int32_t dc01 = c1 - c0;
+    int32_t dc02 = c2 - c0;
+    const int A = gglClz(abs(c0));
+    const int B = gglClz(abs(dc01)|abs(dc02));
+    const int scale = min(A, B - m_scale) - 2;
+    if (scale >= 0) {
+        c0   <<= scale;
+        dc01 <<= scale;
+        dc02 <<= scale;
+    } else {
+        c0   >>= -scale;
+        dc01 >>= -scale;
+        dc02 >>= -scale;
+    }
+    const int s = m_area_scale;
+    int32_t dcdx = gglMulAddx(dc01, m_dy02, gglMulx(dc02, m_dy10, s), s);
+    int32_t dcdy = gglMulAddx(dc02, m_dx01, gglMulx(dc01, m_dx20, s), s);
+    int32_t c = c0 - (gglMulAddx(dcdx, m_x0, 
+            gglMulx(dcdy, m_y0, TRI_FRACTION_BITS), TRI_FRACTION_BITS));
+    it[0] = c;
+    it[1] = dcdx;
+    it[2] = dcdy;
+    return scale;
+}
+
+void compute_iterators_t::iterators1616(GGLfixed* it,
+        GGLfixed c0, GGLfixed c1, GGLfixed c2) const
+{
+    const GGLfixed dc01 = c1 - c0;
+    const GGLfixed dc02 = c2 - c0;
+    // 16.16 x 16.16 == 32.32 --> 16.16
+    const int s = m_area_scale;
+    int32_t dcdx = gglMulAddx(dc01, m_dy02, gglMulx(dc02, m_dy10, s), s);
+    int32_t dcdy = gglMulAddx(dc02, m_dx01, gglMulx(dc01, m_dx20, s), s);
+    int32_t c = c0 - (gglMulAddx(dcdx, m_x0,
+            gglMulx(dcdy, m_y0, TRI_FRACTION_BITS), TRI_FRACTION_BITS));
+    it[0] = c;
+    it[1] = dcdx;
+    it[2] = dcdy;
+}
+
+#if defined(__arm__) && !defined(__thumb__)
+inline void compute_iterators_t::iterators0032(int32_t* it,
+        int32_t c0, int32_t c1, int32_t c2) const
+{
+    ::iterators0032(this, it, c0, c1, c2);
+}
+#else
+void compute_iterators_t::iterators0032(int32_t* it,
+        int32_t c0, int32_t c1, int32_t c2) const
+{
+    const int s = m_area_scale - 16;
+    int32_t dc01 = (c1 - c0)>>s;
+    int32_t dc02 = (c2 - c0)>>s;
+    // 16.16 x 16.16 == 32.32
+    int64_t dcdx = gglMulii(dc01, m_dy02) + gglMulii(dc02, m_dy10);
+    int64_t dcdy = gglMulii(dc02, m_dx01) + gglMulii(dc01, m_dx20);
+    int32_t c = (c0<<16) - ((dcdx*m_x0 + dcdy*m_y0)>>4);
+    it[ 0] = c;
+    it[ 1] = dcdx;
+    it[ 2] = dcdy;
+}
+#endif
+
+// ----------------------------------------------------------------------------
+
+static inline int32_t clampZ(GLfixed z) CONST;
+int32_t clampZ(GLfixed z) {
+    z = (z & ~(z>>31));
+    if (z >= 0x10000)
+        z = 0xFFFF;
+    return z;
+}
+
+static __attribute__((noinline))
+void fetch_texcoord_impl(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    vertex_t* const vtx[3] = { v0, v1, v2 };
+    array_t const * const texcoordArray = c->arrays.texture;
+    
+    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+        if (!(c->rasterizer.state.texture[i].enable))
+            continue;
+        
+        for (int j=0 ; j<3 ; j++) {
+            vertex_t* const v = vtx[j];
+            if (v->flags & vertex_t::TT)
+                continue;
+
+            // NOTE: here we could compute automatic texgen
+            // such as sphere/cube maps, instead of fetching them
+            // from the textcoord array.
+
+            vec4_t& coords = v->texture[i];
+            const GLubyte* tp = texcoordArray[i].element(
+                    v->index & vertex_cache_t::INDEX_MASK);
+            texcoordArray[i].fetch(c, coords.v, tp);
+
+            // transform texture coordinates...
+            coords.Q = 0x10000;
+            const transform_t& tr = c->transforms.texture[i].transform; 
+            if (ggl_unlikely(tr.ops)) {
+                c->arrays.tex_transform[i](&tr, &coords, &coords);
+            }
+
+            // divide by Q
+            const GGLfixed q = coords.Q;
+            if (ggl_unlikely(q != 0x10000)) {
+                const int32_t qinv = gglRecip28(q);
+                coords.S = gglMulx(coords.S, qinv, 28);
+                coords.T = gglMulx(coords.T, qinv, 28);
+            }
+        }
+    }
+    v0->flags |= vertex_t::TT;
+    v1->flags |= vertex_t::TT;
+    v2->flags |= vertex_t::TT;
+}
+
+inline void fetch_texcoord(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    const uint32_t enables = c->rasterizer.state.enables;
+    if (!(enables & GGL_ENABLE_TMUS))
+        return;
+
+    // Fetch & transform texture coordinates...
+    if (ggl_likely(v0->flags & v1->flags & v2->flags & vertex_t::TT)) {
+        // already done for all three vertices, bail...
+        return;
+    }
+    fetch_texcoord_impl(c, v0, v1, v2);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Point
+#endif
+
+void primitive_nop_point(ogles_context_t*, vertex_t*) {
+}
+
+void primitive_point(ogles_context_t* c, vertex_t* v)
+{
+    // lighting & clamping...
+    const uint32_t enables = c->rasterizer.state.enables;
+
+    if (ggl_unlikely(!(v->flags & vertex_t::LIT))) {
+        if (c->lighting.enable) {
+            c->lighting.lightVertex(c, v);
+        } else {
+            v->flags |= vertex_t::LIT;
+            const GLvoid* cp = c->arrays.color.element(
+                    v->index & vertex_cache_t::INDEX_MASK);
+            c->arrays.color.fetch(c, v->color.v, cp);
+        }
+        if (enables & GGL_ENABLE_FOG) {
+            v->fog = c->fog.fog(c, v->window.z);
+        }
+    }
+
+    // XXX: we don't need to do that each-time
+    // if color array and lighting not enabled 
+    c->rasterizer.procs.color4xv(c, v->color.v);
+
+    // XXX: look into ES point-sprite extension
+    if (enables & GGL_ENABLE_TMUS) {
+        fetch_texcoord(c, v,v,v);
+        for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+            if (!c->rasterizer.state.texture[i].enable) 
+                continue;
+            int32_t itt[8];
+            itt[1] = itt[2] = itt[4] = itt[5] = 0;
+            itt[6] = itt[7] = 16; // XXX: check that
+            if (c->rasterizer.state.texture[i].s_wrap == GGL_CLAMP) {
+                int width = c->textures.tmu[i].texture->surface.width;
+                itt[0] = v->texture[i].S * width;
+                itt[6] = 0;
+            }
+            if (c->rasterizer.state.texture[i].t_wrap == GGL_CLAMP) {
+                int height = c->textures.tmu[i].texture->surface.height;
+                itt[3] = v->texture[i].T * height;
+                itt[7] = 0;
+            }
+            c->rasterizer.procs.texCoordGradScale8xv(c, i, itt);
+        }
+    }
+    
+    if (enables & GGL_ENABLE_DEPTH_TEST) {
+        int32_t itz[3];
+        itz[0] = clampZ(v->window.z) * 0x00010001;
+        itz[1] = itz[2] = 0;
+        c->rasterizer.procs.zGrad3xv(c, itz);
+    }
+
+    if (enables & GGL_ENABLE_FOG) {
+        GLfixed itf[3];
+        itf[0] = v->fog;
+        itf[1] = itf[2] = 0;
+        c->rasterizer.procs.fogGrad3xv(c, itf);
+    }
+
+    // Render our point...
+    c->rasterizer.procs.pointx(c, v->window.v, c->point.size);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Line
+#endif
+
+void primitive_nop_line(ogles_context_t*, vertex_t*, vertex_t*) {
+}
+
+void primitive_line(ogles_context_t* c, vertex_t* v0, vertex_t* v1)
+{
+    // This is a cheezy implementation of line drawing that
+    // uses 2 triangles per line. 
+    // That said, how often line drawing is used?
+
+    // get texture coordinates
+    fetch_texcoord(c, v0, v1, v1);
+
+    // light/shade the vertices first (they're copied below)
+    c->lighting.lightTriangle(c, v0, v1, v1);
+
+    vertex_t v[4];
+    v[0] = *v0;
+    v[1] = *v1;
+    v0 = &v[0];
+    v1 = &v[1];
+
+    // clip the line if needed
+    if (ggl_unlikely((v0->flags | v1->flags) & vertex_t::CLIP_ALL)) {
+        unsigned int count = clip_line(c, v0, v1);
+        if (ggl_unlikely(count == 0))
+            return;
+    }
+
+    // compute iterators...
+    const uint32_t enables = c->rasterizer.state.enables;
+    const uint32_t mask =   GGL_ENABLE_TMUS |
+                            GGL_ENABLE_SMOOTH |
+                            GGL_ENABLE_W | 
+                            GGL_ENABLE_FOG |
+                            GGL_ENABLE_DEPTH_TEST;
+
+    if (ggl_unlikely(enables & mask)) {
+        c->lerp.initTriangle(v0, v1, v1);
+        lerp_triangle(c, v0, v1, v1);
+    }
+
+    // render our line
+    c->rasterizer.procs.linex(c, v0->window.v, v1->window.v, c->line.width);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Triangle
+#endif
+
+void primitive_nop_triangle(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2) {
+}
+
+void primitive_clip_triangle(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    uint32_t cc = (v0->flags | v1->flags | v2->flags) & vertex_t::CLIP_ALL;
+    if (ggl_likely(!cc)) {
+        // code below must be as optimized as possible, this is the
+        // common code path.
+
+        // This triangle is not clipped, test if it's culled
+        // unclipped triangle...
+        c->lerp.initTriangle(v0, v1, v2);
+        if (cull_triangle(c, v0, v1, v2))
+            return; // culled!
+
+        // Fetch all texture coordinates if needed
+        fetch_texcoord(c, v0, v1, v2);
+
+        // light (or shade) our triangle!
+        c->lighting.lightTriangle(c, v0, v1, v2);
+
+        triangle(c, v0, v1, v2);
+        return;
+    }
+
+    // The assumption here is that we're not going to clip very often,
+    // and even more rarely will we clip a triangle that ends up
+    // being culled out. So it's okay to light the vertices here, even though
+    // in a few cases we won't render the triangle (if culled).
+
+    // Fetch texture coordinates...
+    fetch_texcoord(c, v0, v1, v2);
+
+    // light (or shade) our triangle!
+    c->lighting.lightTriangle(c, v0, v1, v2);
+
+    clip_triangle(c, v0, v1, v2);
+}
+
+// -----------------------------------------------------------------------
+
+void triangle(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    // compute iterators...
+    const uint32_t enables = c->rasterizer.state.enables;
+    const uint32_t mask =   GGL_ENABLE_TMUS |
+                            GGL_ENABLE_SMOOTH |
+                            GGL_ENABLE_W | 
+                            GGL_ENABLE_FOG |
+                            GGL_ENABLE_DEPTH_TEST;
+
+    if (ggl_likely(enables & mask))
+        lerp_triangle(c, v0, v1, v2);
+
+    c->rasterizer.procs.trianglex(c, v0->window.v, v1->window.v, v2->window.v);
+}
+
+void lerp_triangle(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    const uint32_t enables = c->rasterizer.state.enables;
+    c->lerp.initLerp(v0, enables);
+
+    // set up texture iterators
+    if (enables & GGL_ENABLE_TMUS) {
+        if (enables & GGL_ENABLE_W) {
+            lerp_texcoords_w(c, v0, v1, v2);
+        } else {
+            lerp_texcoords(c, v0, v1, v2);
+        }
+    }
+
+    // set up the color iterators
+    const compute_iterators_t& lerp = c->lerp;
+    if (enables & GGL_ENABLE_SMOOTH) {
+        GLfixed itc[12];
+        for (int i=0 ; i<4 ; i++) {
+            const GGLcolor c0 = v0->color.v[i] * 255;
+            const GGLcolor c1 = v1->color.v[i] * 255;
+            const GGLcolor c2 = v2->color.v[i] * 255;
+            lerp.iterators1616(&itc[i*3], c0, c1, c2);
+        }
+        c->rasterizer.procs.colorGrad12xv(c, itc);
+    }
+
+    if (enables & GGL_ENABLE_DEPTH_TEST) {
+        int32_t itz[3];
+        const int32_t v0z = clampZ(v0->window.z);
+        const int32_t v1z = clampZ(v1->window.z);
+        const int32_t v2z = clampZ(v2->window.z);
+        lerp.iterators0032(itz, v0z, v1z, v2z);
+        if (ggl_unlikely(c->polygonOffset.enable)) {
+            const GLfixed factor = c->polygonOffset.factor;
+            const GLfixed units = c->polygonOffset.units;
+            int32_t maxDepthSlope = max(abs(itz[1]), abs(itz[2]));
+            int32_t offset = (int64_t(maxDepthSlope)*factor +
+                    (int64_t(units) << 16)) >> 16;
+            itz[0] += offset; // XXX: this can cause overflows
+        }
+        c->rasterizer.procs.zGrad3xv(c, itz);
+    }
+
+    if (ggl_unlikely(enables & GGL_ENABLE_FOG)) {
+        GLfixed itf[3];
+        lerp.iterators1616(itf, v0->fog, v1->fog, v2->fog);
+        c->rasterizer.procs.fogGrad3xv(c, itf);
+    }
+}
+
+
+static inline
+int compute_lod(ogles_context_t* c, int i,
+        int32_t s0, int32_t t0, int32_t s1, int32_t t1, int32_t s2, int32_t t2)
+{
+    // Compute mipmap level / primitive
+    // rho = sqrt( texelArea / area )
+    // lod = log2( rho )
+    // lod = log2( texelArea / area ) / 2
+    // lod = (log2( texelArea ) - log2( area )) / 2
+    const compute_iterators_t& lerp = c->lerp;
+    const GGLcoord area = abs(lerp.area());
+    const int w = c->textures.tmu[i].texture->surface.width;
+    const int h = c->textures.tmu[i].texture->surface.height;
+    const int shift = 16 + (16 - TRI_FRACTION_BITS);
+    int32_t texelArea = abs( gglMulx(s1-s0, t2-t0, shift) -
+            gglMulx(s2-s0, t1-t0, shift) )*w*h;
+    int log2TArea = (32-TRI_FRACTION_BITS  -1) - gglClz(texelArea);
+    int log2Area  = (32-TRI_FRACTION_BITS*2-1) - gglClz(area);
+    int lod = (log2TArea - log2Area + 1) >> 1;
+    return lod;
+}
+
+void lerp_texcoords(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    const compute_iterators_t& lerp = c->lerp;
+    int32_t itt[8] __attribute__((aligned(16)));
+    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+        const texture_t& tmu = c->rasterizer.state.texture[i];
+        if (!tmu.enable) 
+            continue;
+
+        // compute the jacobians using block floating-point
+        int32_t s0 = v0->texture[i].S;
+        int32_t t0 = v0->texture[i].T;
+        int32_t s1 = v1->texture[i].S;
+        int32_t t1 = v1->texture[i].T;
+        int32_t s2 = v2->texture[i].S;
+        int32_t t2 = v2->texture[i].T;
+
+        const GLenum min_filter = c->textures.tmu[i].texture->min_filter;
+        if (ggl_unlikely(min_filter >= GL_NEAREST_MIPMAP_NEAREST)) {
+            int lod = compute_lod(c, i, s0, t0, s1, t1, s2, t2);
+            c->rasterizer.procs.bindTextureLod(c, i,
+                    &c->textures.tmu[i].texture->mip(lod));
+        }
+
+        // premultiply (s,t) when clampling
+        if (tmu.s_wrap == GGL_CLAMP) {
+            const int width = tmu.surface.width;
+            s0 *= width;
+            s1 *= width;
+            s2 *= width;
+        }
+        if (tmu.t_wrap == GGL_CLAMP) {
+            const int height = tmu.surface.height;
+            t0 *= height;
+            t1 *= height;
+            t2 *= height;
+        }
+        itt[6] = -lerp.iteratorsScale(itt+0, s0, s1, s2);
+        itt[7] = -lerp.iteratorsScale(itt+3, t0, t1, t2);
+        c->rasterizer.procs.texCoordGradScale8xv(c, i, itt);
+    }
+}
+
+void lerp_texcoords_w(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    const compute_iterators_t& lerp = c->lerp;
+    int32_t itt[8] __attribute__((aligned(16)));
+    int32_t itw[3];
+
+    // compute W's scale to 2.30
+    int32_t w0 = v0->window.w;
+    int32_t w1 = v1->window.w;
+    int32_t w2 = v2->window.w;
+    int wscale = 32 - gglClz(w0|w1|w2);
+
+    // compute the jacobian using block floating-point    
+    int sc = lerp.iteratorsScale(itw, w0, w1, w2);
+    sc +=  wscale - 16;
+    c->rasterizer.procs.wGrad3xv(c, itw);
+
+    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+        const texture_t& tmu = c->rasterizer.state.texture[i];
+        if (!tmu.enable) 
+            continue;
+
+        // compute the jacobians using block floating-point
+        int32_t s0 = v0->texture[i].S;
+        int32_t t0 = v0->texture[i].T;
+        int32_t s1 = v1->texture[i].S;
+        int32_t t1 = v1->texture[i].T;
+        int32_t s2 = v2->texture[i].S;
+        int32_t t2 = v2->texture[i].T;
+
+        const GLenum min_filter = c->textures.tmu[i].texture->min_filter;
+        if (ggl_unlikely(min_filter >= GL_NEAREST_MIPMAP_NEAREST)) {
+            int lod = compute_lod(c, i, s0, t0, s1, t1, s2, t2);
+            c->rasterizer.procs.bindTextureLod(c, i,
+                    &c->textures.tmu[i].texture->mip(lod));
+        }
+
+        // premultiply (s,t) when clampling
+        if (tmu.s_wrap == GGL_CLAMP) {
+            const int width = tmu.surface.width;
+            s0 *= width;
+            s1 *= width;
+            s2 *= width;
+        }
+        if (tmu.t_wrap == GGL_CLAMP) {
+            const int height = tmu.surface.height;
+            t0 *= height;
+            t1 *= height;
+            t2 *= height;
+        }
+
+        s0 = gglMulx(s0, w0, wscale);
+        t0 = gglMulx(t0, w0, wscale);
+        s1 = gglMulx(s1, w1, wscale);
+        t1 = gglMulx(t1, w1, wscale);
+        s2 = gglMulx(s2, w2, wscale);
+        t2 = gglMulx(t2, w2, wscale);
+
+        itt[6] = sc - lerp.iteratorsScale(itt+0, s0, s1, s2);
+        itt[7] = sc - lerp.iteratorsScale(itt+3, t0, t1, t2);
+        c->rasterizer.procs.texCoordGradScale8xv(c, i, itt);
+    }
+}
+
+
+static inline
+bool cull_triangle(ogles_context_t* c, vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    if (ggl_likely(c->cull.enable)) {
+        const GLenum winding = (c->lerp.area() > 0) ? GL_CW : GL_CCW;
+        const GLenum face = (winding == c->cull.frontFace) ? GL_FRONT : GL_BACK;
+        if (face == c->cull.cullFace)
+            return true; // culled!
+    }
+    return false;
+}
+
+static inline
+GLfixed frustumPlaneDist(int plane, const vec4_t& s)
+{
+    const GLfixed d = s.v[ plane >> 1 ];
+    return  ((plane & 1) ? (s.w - d) : (s.w + d)); 
+}
+
+static inline
+int32_t clipDivide(GLfixed a, GLfixed b) {
+    // returns a 4.28 fixed-point
+    return gglMulDivi(1LU<<28, a, b);
+} 
+
+void clip_triangle(ogles_context_t* c,
+        vertex_t* v0, vertex_t* v1, vertex_t* v2)
+{
+    uint32_t all_cc = (v0->flags | v1->flags | v2->flags) & vertex_t::CLIP_ALL;
+
+    vertex_t *p0, *p1, *p2;
+    const int MAX_CLIPPING_PLANES = 6 + OGLES_MAX_CLIP_PLANES;
+    const int MAX_VERTICES = 3;
+
+    // Temporary buffer to hold the new vertices. Each plane can add up to 
+    // two new vertices (because the polygon is convex).
+    // We need one extra element, to handle an overflow case when
+    // the polygon degenerates into something non convex.
+    vertex_t buffer[MAX_CLIPPING_PLANES * 2 + 1];   // ~3KB
+    vertex_t* buf = buffer;
+
+    // original list of vertices (polygon to clip, in fact this
+    // function works with an arbitrary polygon).
+    vertex_t* in[3] = { v0, v1, v2 };
+    
+    // output lists (we need 2, which we use back and forth)
+    // (maximum outpout list's size is MAX_CLIPPING_PLANES + MAX_VERTICES)
+    // 2 more elements for overflow when non convex polygons.
+    vertex_t* out[2][MAX_CLIPPING_PLANES + MAX_VERTICES + 2];
+    unsigned int outi = 0;
+    
+    // current input list
+    vertex_t** ivl = in;
+
+    // 3 input vertices, 0 in the output list, first plane
+    unsigned int ic = 3;
+
+    // User clip-planes first, the clipping is always done in eye-coordinate
+    // this is basically the same algorithm than for the view-volume
+    // clipping, except for the computation of the distance (vertex, plane)
+    // and the fact that we need to compute the eye-coordinates of each
+    // new vertex we create.
+    
+    if (ggl_unlikely(all_cc & vertex_t::USER_CLIP_ALL))
+    {
+        unsigned int plane = 0;
+        uint32_t cc = (all_cc & vertex_t::USER_CLIP_ALL) >> 8;
+        do {
+            if (cc & 1) {        
+                // pointers to our output list (head and current)
+                vertex_t** const ovl = &out[outi][0];
+                vertex_t** output = ovl;
+                unsigned int oc = 0;
+                unsigned int sentinel = 0;
+                // previous vertice, compute distance to the plane
+                vertex_t* s = ivl[ic-1];
+                const vec4_t& equation = c->clipPlanes.plane[plane].equation;
+                GLfixed sd = dot4(equation.v, s->eye.v);
+                // clip each vertice against this plane...
+                for (unsigned int i=0 ; i<ic ; i++) {            
+                    vertex_t* p = ivl[i];
+                    const GLfixed pd = dot4(equation.v, p->eye.v);
+                    if (sd >= 0) {
+                        if (pd >= 0) {
+                            // both inside
+                            *output++ = p;
+                            oc++;
+                        } else {
+                            // s inside, p outside (exiting)
+                            const GLfixed t = clipDivide(sd, sd-pd);
+                            c->arrays.clipEye(c, buf, t, p, s);
+                            *output++ = buf++;
+                            oc++;
+                            if (++sentinel >= 3)
+                                return; // non-convex polygon!
+                        }
+                    } else {
+                        if (pd >= 0) {
+                            // s outside (entering)
+                            if (pd) {
+                                const GLfixed t = clipDivide(pd, pd-sd);
+                                c->arrays.clipEye(c, buf, t, s, p);
+                                *output++ = buf++;
+                                oc++;
+                                if (++sentinel >= 3)
+                                    return; // non-convex polygon!
+                            }
+                            *output++ = p;
+                            oc++;
+                        } else {
+                           // both outside
+                        }
+                    }
+                    s = p;
+                    sd = pd;
+                }
+                // output list become the new input list
+                if (oc<3)
+                    return; // less than 3 vertices left? we're done!
+                ivl = ovl;
+                ic = oc;
+                outi = 1-outi;
+            }
+            cc >>= 1;
+            plane++;
+        } while (cc);
+    }
+
+    // frustum clip-planes
+    if (all_cc & vertex_t::FRUSTUM_CLIP_ALL)
+    {
+        unsigned int plane = 0;
+        uint32_t cc = all_cc & vertex_t::FRUSTUM_CLIP_ALL;
+        do {
+            if (cc & 1) {        
+                // pointers to our output list (head and current)
+                vertex_t** const ovl = &out[outi][0];
+                vertex_t** output = ovl;
+                unsigned int oc = 0;
+                unsigned int sentinel = 0;
+                // previous vertice, compute distance to the plane
+                vertex_t* s = ivl[ic-1];
+                GLfixed sd = frustumPlaneDist(plane, s->clip);
+                // clip each vertice against this plane...
+                for (unsigned int i=0 ; i<ic ; i++) {            
+                    vertex_t* p = ivl[i];
+                    const GLfixed pd = frustumPlaneDist(plane, p->clip);
+                    if (sd >= 0) {
+                        if (pd >= 0) {
+                            // both inside
+                            *output++ = p;
+                            oc++;
+                        } else {
+                            // s inside, p outside (exiting)
+                            const GLfixed t = clipDivide(sd, sd-pd);
+                            c->arrays.clipVertex(c, buf, t, p, s);
+                            *output++ = buf++;
+                            oc++;
+                            if (++sentinel >= 3)
+                                return; // non-convex polygon!
+                        }
+                    } else {
+                        if (pd >= 0) {
+                            // s outside (entering)
+                            if (pd) {
+                                const GLfixed t = clipDivide(pd, pd-sd);
+                                c->arrays.clipVertex(c, buf, t, s, p);
+                                *output++ = buf++;
+                                oc++;
+                                if (++sentinel >= 3)
+                                    return; // non-convex polygon!
+                            }
+                            *output++ = p;
+                            oc++;
+                        } else {
+                           // both outside
+                        }
+                    }
+                    s = p;
+                    sd = pd;
+                }
+                // output list become the new input list
+                if (oc<3)
+                    return; // less than 3 vertices left? we're done!
+                ivl = ovl;
+                ic = oc;
+                outi = 1-outi;
+            }
+            cc >>= 1;
+            plane++;
+        } while (cc);
+    }
+    
+    // finally we can render our triangles...
+    p0 = ivl[0];
+    p1 = ivl[1];
+    for (unsigned int i=2 ; i<ic ; i++) {
+        p2 = ivl[i];
+        c->lerp.initTriangle(p0, p1, p2);
+        if (cull_triangle(c, p0, p1, p2)) {
+            p1 = p2;
+            continue; // culled!
+        }
+        triangle(c, p0, p1, p2);
+        p1 = p2;
+    }
+}
+
+unsigned int clip_line(ogles_context_t* c, vertex_t* s, vertex_t* p)
+{
+    const uint32_t all_cc = (s->flags | p->flags) & vertex_t::CLIP_ALL;
+
+    if (ggl_unlikely(all_cc & vertex_t::USER_CLIP_ALL))
+    {
+        unsigned int plane = 0;
+        uint32_t cc = (all_cc & vertex_t::USER_CLIP_ALL) >> 8;
+        do {
+            if (cc & 1) {
+                const vec4_t& equation = c->clipPlanes.plane[plane].equation;
+                const GLfixed sd = dot4(equation.v, s->eye.v);
+                const GLfixed pd = dot4(equation.v, p->eye.v);
+                if (sd >= 0) {
+                    if (pd >= 0) {
+                        // both inside
+                    } else {
+                        // s inside, p outside (exiting)
+                        const GLfixed t = clipDivide(sd, sd-pd);
+                        c->arrays.clipEye(c, p, t, p, s);
+                    }
+                } else {
+                    if (pd >= 0) {
+                        // s outside (entering)
+                        if (pd) {
+                            const GLfixed t = clipDivide(pd, pd-sd);
+                            c->arrays.clipEye(c, s, t, s, p);
+                        }
+                    } else {
+                       // both outside
+                       return 0;
+                    }
+                }
+            }
+            cc >>= 1;
+            plane++;
+        } while (cc);
+    }
+
+    // frustum clip-planes
+    if (all_cc & vertex_t::FRUSTUM_CLIP_ALL)
+    {
+        unsigned int plane = 0;
+        uint32_t cc = all_cc & vertex_t::FRUSTUM_CLIP_ALL;
+        do {
+            if (cc & 1) {
+                const GLfixed sd = frustumPlaneDist(plane, s->clip);
+                const GLfixed pd = frustumPlaneDist(plane, p->clip);
+                if (sd >= 0) {
+                    if (pd >= 0) {
+                        // both inside
+                    } else {
+                        // s inside, p outside (exiting)
+                        const GLfixed t = clipDivide(sd, sd-pd);
+                        c->arrays.clipVertex(c, p, t, p, s);
+                    }
+                } else {
+                    if (pd >= 0) {
+                        // s outside (entering)
+                        if (pd) {
+                            const GLfixed t = clipDivide(pd, pd-sd);
+                            c->arrays.clipVertex(c, s, t, s, p);
+                        }
+                    } else {
+                       // both outside
+                       return 0;
+                    }
+                }
+            }
+            cc >>= 1;
+            plane++;
+        } while (cc);
+    }
+
+    return 2;
+}
+
+
+}; // namespace android
diff --git a/opengl/libagl/primitives.h b/opengl/libagl/primitives.h
new file mode 100644
index 0000000..1bef604
--- /dev/null
+++ b/opengl/libagl/primitives.h
@@ -0,0 +1,37 @@
+/* libs/opengles/primitives.h
+**
+** 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 
+**
+**     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_PRIMITIVES_H
+#define ANDROID_OPENGLES_PRIMITIVES_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+
+namespace android {
+
+namespace gl {
+struct ogles_context_t;
+};
+
+void ogles_validate_primitives(ogles_context_t* c);
+
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_PRIMITIVES_H
+
diff --git a/opengl/libagl/state.cpp b/opengl/libagl/state.cpp
new file mode 100644
index 0000000..c2f9f12
--- /dev/null
+++ b/opengl/libagl/state.cpp
@@ -0,0 +1,592 @@
+/* libs/opengles/state.cpp
+**
+** 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 
+**
+**     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 "context.h"
+#include "fp.h"
+#include "state.h"
+#include "array.h"
+#include "matrix.h"
+#include "vertex.h"
+#include "light.h"
+#include "texture.h"
+#include "BufferObjectManager.h"
+#include "TextureObjectManager.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static char const * const gVendorString     = "Android";
+static char const * const gRendererString   = "Android PixelFlinger 1.0";
+static char const * const gVersionString    = "OpenGL ES-CM 1.0";
+static char const * const gExtensionsString =
+    "GL_OES_byte_coordinates "              // OK
+    "GL_OES_fixed_point "                   // OK
+    "GL_OES_single_precision "              // OK
+    "GL_OES_read_format "                   // OK
+    "GL_OES_compressed_paletted_texture "   // OK
+    "GL_OES_draw_texture "                  // OK
+    "GL_OES_matrix_get "                    // OK
+    "GL_OES_query_matrix "                  // OK
+    //        "GL_OES_point_size_array "              // TODO
+    //        "GL_OES_point_sprite "                  // TODO
+    "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
+    ;
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+ogles_context_t *ogles_init(size_t extra)
+{
+    void* const base = malloc(extra + sizeof(ogles_context_t) + 32);
+	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();
+    c->surfaceManager->incStrong(c);
+
+    sp<EGLBufferObjectManager> bomgr(new EGLBufferObjectManager());
+    c->bufferObjectManager = bomgr.get();
+    c->bufferObjectManager->incStrong(c);
+
+    ogles_init_array(c);
+    ogles_init_matrix(c);
+    ogles_init_vertex(c);
+    ogles_init_light(c);
+    ogles_init_texture(c);
+
+    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);
+
+    return c;
+}
+
+void ogles_uninit(ogles_context_t* c)
+{
+    ogles_uninit_array(c);
+    ogles_uninit_matrix(c);
+    ogles_uninit_vertex(c);
+    ogles_uninit_light(c);
+    ogles_uninit_texture(c);
+    c->surfaceManager->decStrong(c);
+    c->bufferObjectManager->decStrong(c);
+    ggl_uninit_context(&(c->rasterizer));
+	free(c->rasterizer.base);
+}
+
+void _ogles_error(ogles_context_t* c, GLenum error)
+{
+    if (c->error == GL_NO_ERROR)
+        c->error = error;
+}
+
+static bool stencilop_valid(GLenum op) {
+    switch (op) {
+    case GL_KEEP:
+    case GL_ZERO:
+    case GL_REPLACE:
+    case GL_INCR:
+    case GL_DECR:
+    case GL_INVERT:
+        return true;
+    }
+    return false;
+}
+
+static void enable_disable(ogles_context_t* c, GLenum cap, int enabled)
+{
+    if ((cap >= GL_LIGHT0) && (cap<GL_LIGHT0+OGLES_MAX_LIGHTS)) {
+        c->lighting.lights[cap-GL_LIGHT0].enable = enabled;
+        c->lighting.enabledLights &= ~(1<<(cap-GL_LIGHT0));
+        c->lighting.enabledLights |= (enabled<<(cap-GL_LIGHT0));
+        return;
+    }
+
+    switch (cap) {
+    case GL_POINT_SMOOTH:
+        c->point.smooth = enabled;
+        break;
+    case GL_LINE_SMOOTH:
+        c->line.smooth = enabled;
+        break;
+    case GL_POLYGON_OFFSET_FILL:
+        c->polygonOffset.enable = enabled;
+        break;
+    case GL_CULL_FACE:
+        c->cull.enable = enabled;
+        break;
+    case GL_LIGHTING:
+        c->lighting.enable = enabled;
+        break;
+    case GL_COLOR_MATERIAL:
+        c->lighting.colorMaterial.enable = enabled;
+        break;
+    case GL_NORMALIZE:
+    case GL_RESCALE_NORMAL:
+        c->transforms.rescaleNormals = enabled ? cap : 0;
+        // XXX: invalidate mvit
+        break;
+
+    case GL_CLIP_PLANE0:
+    case GL_CLIP_PLANE1:
+    case GL_CLIP_PLANE2:
+    case GL_CLIP_PLANE3:
+    case GL_CLIP_PLANE4:
+    case GL_CLIP_PLANE5:
+        c->clipPlanes.enable &= ~(1<<(cap-GL_CLIP_PLANE0));
+        c->clipPlanes.enable |= (enabled<<(cap-GL_CLIP_PLANE0));
+        ogles_invalidate_perspective(c);
+        break;
+
+    case GL_FOG:
+    case GL_DEPTH_TEST:
+        ogles_invalidate_perspective(c);
+        // fall-through...
+    case GL_BLEND:
+    case GL_SCISSOR_TEST:
+    case GL_ALPHA_TEST:
+    case GL_COLOR_LOGIC_OP:
+    case GL_DITHER:
+    case GL_STENCIL_TEST:
+    case GL_TEXTURE_2D:
+        // 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:
+    case GL_SAMPLE_COVERAGE:
+        // not supported in this implementation
+        break;
+
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+using namespace android;
+
+#if 0
+#pragma mark -
+#endif
+
+// These ones are super-easy, we're not supporting those features!
+void glSampleCoverage(GLclampf value, GLboolean invert) {
+}
+void glSampleCoveragex(GLclampx value, GLboolean invert) {
+}
+void glStencilFunc(GLenum func, GLint ref, GLuint mask) {
+    ogles_context_t* c = ogles_context_t::get();
+    if (func < GL_NEVER || func > GL_ALWAYS) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    // from OpenGL|ES 1.0 sepcification:
+    // If there is no stencil buffer, no stencil modification can occur
+    // and it is as if the stencil test always passes.
+}
+
+void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass) {
+    ogles_context_t* c = ogles_context_t::get();
+    if ((stencilop_valid(fail) &
+         stencilop_valid(zfail) &
+         stencilop_valid(zpass)) == 0) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+void glAlphaFunc(GLenum func, GLclampf ref)
+{
+    glAlphaFuncx(func, gglFloatToFixed(ref));
+}
+
+void glCullFace(GLenum mode)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    switch (mode) {
+    case GL_FRONT:
+    case GL_BACK:
+    case GL_FRONT_AND_BACK:
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+    }
+    c->cull.cullFace = mode;
+}
+
+void glFrontFace(GLenum mode)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    switch (mode) {
+    case GL_CW:
+    case GL_CCW:
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->cull.frontFace = mode;
+}
+
+void glHint(GLenum target, GLenum mode)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    switch (target) {
+    case GL_FOG_HINT:
+    case GL_GENERATE_MIPMAP_HINT:
+    case GL_LINE_SMOOTH_HINT:
+        break;
+    case GL_POINT_SMOOTH_HINT:
+        c->rasterizer.procs.enableDisable(c, 
+                GGL_POINT_SMOOTH_NICE, mode==GL_NICEST);
+        break;
+    case GL_PERSPECTIVE_CORRECTION_HINT:
+        c->perspective = (mode == GL_NICEST) ? 1 : 0;
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+    }
+}
+
+void glEnable(GLenum cap) {
+    ogles_context_t* c = ogles_context_t::get();
+    enable_disable(c, cap, 1);
+}
+void glDisable(GLenum cap) {
+    ogles_context_t* c = ogles_context_t::get();
+    enable_disable(c, cap, 0);
+}
+
+void glFinish()
+{ // nothing to do for our software implementation
+}
+
+void glFlush()
+{ // nothing to do for our software implementation
+}
+
+GLenum glGetError()
+{
+    // From OpenGL|ES 1.0 specification:
+    // If more than one flag has recorded an error, glGetError returns
+    // and clears an arbitrary error flag value. Thus, glGetError should
+    // always be called in a loop, until it returns GL_NO_ERROR,
+    // if all error flags are to be reset.
+
+    ogles_context_t* c = ogles_context_t::get();
+    if (c->error) {
+        const GLenum ret(c->error);
+        c->error = 0;
+        return ret;
+    }
+    
+    if (c->rasterizer.error) {
+        const GLenum ret(c->rasterizer.error);
+        c->rasterizer.error = 0;
+        return ret;
+    }
+
+    return GL_NO_ERROR;
+}
+
+const GLubyte* glGetString(GLenum string)
+{
+    switch (string) {
+    case GL_VENDOR:     return (const GLubyte*)gVendorString;
+    case GL_RENDERER:   return (const GLubyte*)gRendererString;
+    case GL_VERSION:    return (const GLubyte*)gVersionString;
+    case GL_EXTENSIONS: return (const GLubyte*)gExtensionsString;
+    }
+    ogles_context_t* c = ogles_context_t::get();
+    ogles_error(c, GL_INVALID_ENUM);
+    return 0;
+}
+
+void glGetIntegerv(GLenum pname, GLint *params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    switch (pname) {
+    case GL_ALIASED_POINT_SIZE_RANGE:
+        params[0] = 0;
+        params[1] = GGL_MAX_ALIASED_POINT_SIZE;
+        break;
+    case GL_ALIASED_LINE_WIDTH_RANGE:
+        params[0] = 0;
+        params[1] = GGL_MAX_ALIASED_POINT_SIZE;
+        break;
+    case GL_ALPHA_BITS: {
+        int index = c->rasterizer.state.buffers.color.format;
+        GGLFormat const * formats = gglGetPixelFormatTable();
+        params[0] = formats[index].ah - formats[index].al;
+        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; 
+        }
+    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; 
+        }
+    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; 
+        }
+    case GL_COMPRESSED_TEXTURE_FORMATS:
+        params[ 0] = GL_PALETTE4_RGB8_OES;
+        params[ 1] = GL_PALETTE4_RGBA8_OES;
+        params[ 2] = GL_PALETTE4_R5_G6_B5_OES;
+        params[ 3] = GL_PALETTE4_RGBA4_OES;
+        params[ 4] = GL_PALETTE4_RGB5_A1_OES;
+        params[ 5] = GL_PALETTE8_RGB8_OES;
+        params[ 6] = GL_PALETTE8_RGBA8_OES;
+        params[ 7] = GL_PALETTE8_R5_G6_B5_OES;
+        params[ 8] = GL_PALETTE8_RGBA4_OES;
+        params[ 9] = GL_PALETTE8_RGB5_A1_OES;
+        break;
+    case GL_DEPTH_BITS:
+        params[0] = c->rasterizer.state.buffers.depth.format ? 0 : 16;
+        break;
+    case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
+        params[0] = GL_RGB;
+        break;
+    case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
+        params[0] = GL_UNSIGNED_SHORT_5_6_5;
+        break;
+    case GL_MAX_ELEMENTS_INDICES:
+        params[0] = 65536;
+        break;
+    case GL_MAX_ELEMENTS_VERTICES:
+        params[0] = 0x7FFFFFFF;
+        break;
+    case GL_MAX_LIGHTS:
+        params[0] = OGLES_MAX_LIGHTS;
+        break;
+    case GL_MAX_CLIP_PLANES:
+        params[0] = OGLES_MAX_CLIP_PLANES;
+        break;
+    case GL_MAX_MODELVIEW_STACK_DEPTH:
+        params[0] = OGLES_MODELVIEW_STACK_DEPTH;
+        break;
+    case GL_MAX_PROJECTION_STACK_DEPTH:
+        params[0] = OGLES_PROJECTION_STACK_DEPTH;
+        break;
+    case GL_MAX_TEXTURE_STACK_DEPTH:
+        params[0] = OGLES_TEXTURE_STACK_DEPTH;
+        break;
+    case GL_MAX_TEXTURE_SIZE:
+        params[0] = GGL_MAX_TEXTURE_SIZE;
+        break;
+    case GL_MAX_TEXTURE_UNITS:
+        params[0] = GGL_TEXTURE_UNIT_COUNT;
+        break;
+    case GL_MAX_VIEWPORT_DIMS:
+        params[0] = GGL_MAX_VIEWPORT_DIMS;
+        params[1] = GGL_MAX_VIEWPORT_DIMS;
+        break;
+    case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+        params[0] = OGLES_NUM_COMPRESSED_TEXTURE_FORMATS;
+        break;
+    case GL_SMOOTH_LINE_WIDTH_RANGE:
+        params[0] = 0;
+        params[1] = GGL_MAX_SMOOTH_LINE_WIDTH;
+        break;
+    case GL_SMOOTH_POINT_SIZE_RANGE:
+        params[0] = 0;
+        params[1] = GGL_MAX_SMOOTH_POINT_SIZE;
+        break;
+    case GL_STENCIL_BITS:
+        params[0] = 0;
+        break;
+    case GL_SUBPIXEL_BITS:
+        params[0] = GGL_SUBPIXEL_BITS;
+        break;
+
+    case GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES:
+        memcpy( params,
+                c->transforms.modelview.top().elements(),
+                16*sizeof(GLint));
+        break;
+    case GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES:
+        memcpy( params,
+                c->transforms.projection.top().elements(),
+                16*sizeof(GLint));
+        break;
+    case GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES:
+        memcpy( params,
+                c->transforms.texture[c->textures.active].top().elements(),
+                16*sizeof(GLint));
+        break;
+
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        break;
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+void glPointSize(GLfloat size)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (size <= 0) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->point.size = TRI_FROM_FIXED(gglFloatToFixed(size));
+}
+
+void glPointSizex(GLfixed size)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (size <= 0) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->point.size = TRI_FROM_FIXED(size);
+}
+
+// ----------------------------------------------------------------------------
+
+void glLineWidth(GLfloat width)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (width <= 0) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->line.width = TRI_FROM_FIXED(gglFloatToFixed(width));
+}
+
+void glLineWidthx(GLfixed width)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (width <= 0) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->line.width = TRI_FROM_FIXED(width);
+}
+
+// ----------------------------------------------------------------------------
+
+void glColorMask(GLboolean r, GLboolean g, GLboolean b, GLboolean a) {
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.colorMask(c, r, g, b, a);
+}
+
+void glDepthMask(GLboolean flag) {
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.depthMask(c, flag);
+}
+
+void glStencilMask(GLuint mask) {
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.stencilMask(c, mask);
+}
+
+void glDepthFunc(GLenum func) {
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.depthFunc(c, func);
+}
+
+void glLogicOp(GLenum opcode) {
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.logicOp(c, opcode);
+}
+
+void glAlphaFuncx(GLenum func, GLclampx ref) {
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.alphaFuncx(c, func, ref);
+}
+
+void glBlendFunc(GLenum sfactor, GLenum dfactor) {
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.blendFunc(c, sfactor, dfactor);
+}
+
+void glClear(GLbitfield mask) {
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.clear(c, mask);
+}
+
+void glClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) {
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.clearColorx(c, red, green, blue, alpha);
+}
+
+void glClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.clearColorx(c,
+                    gglFloatToFixed(r),
+                    gglFloatToFixed(g),
+                    gglFloatToFixed(b),
+                    gglFloatToFixed(a));
+}
+
+void glClearDepthx(GLclampx depth) {
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.clearDepthx(c, depth);
+}
+
+void glClearDepthf(GLclampf depth)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.clearDepthx(c, gglFloatToFixed(depth));
+}
+
+void glClearStencil(GLint s) {
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.clearStencil(c, s);
+}
diff --git a/opengl/libagl/state.h b/opengl/libagl/state.h
new file mode 100644
index 0000000..55a5ccb
--- /dev/null
+++ b/opengl/libagl/state.h
@@ -0,0 +1,54 @@
+/* libs/opengles/state.h
+**
+** 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 
+**
+**     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_STATE_H
+#define ANDROID_OPENGLES_STATE_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+#include <private/pixelflinger/ggl_context.h>
+
+#include <GLES/gl.h>
+
+#include <stdio.h>
+
+namespace android {
+
+ogles_context_t *ogles_init(size_t extra);
+void ogles_uninit(ogles_context_t* c);
+void _ogles_error(ogles_context_t* c, GLenum error);
+
+#ifndef TRACE_GL_ERRORS
+#define TRACE_GL_ERRORS 0
+#endif
+
+#if TRACE_GL_ERRORS
+#define ogles_error(c, error) \
+do { \
+  printf("ogles_error at file %s line %d\n", __FILE__, __LINE__); \
+  _ogles_error(c, error); \
+} while (0)
+#else /* !TRACE_GL_ERRORS */
+#define ogles_error(c, error) _ogles_error((c), (error))
+#endif
+
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_STATE_H
+
diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp
new file mode 100644
index 0000000..6b2640a
--- /dev/null
+++ b/opengl/libagl/texture.cpp
@@ -0,0 +1,1423 @@
+/* libs/opengles/texture.cpp
+**
+** 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 
+**
+**     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 <stdio.h>
+#include <stdlib.h>
+#include "context.h"
+#include "fp.h"
+#include "state.h"
+#include "texture.h"
+#include "TextureObjectManager.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static void bindTextureTmu(
+    ogles_context_t* c, int tmu, GLuint texture, const sp<EGLTextureObject>& tex);
+
+static __attribute__((noinline))
+void generateMipmap(ogles_context_t* c, GLint level);
+
+// ----------------------------------------------------------------------------
+
+#if 0
+#pragma mark -
+#pragma mark Init
+#endif
+
+void ogles_init_texture(ogles_context_t* c)
+{
+    c->textures.packAlignment   = 4;
+    c->textures.unpackAlignment = 4;
+
+    // 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);
+        memset(c->current.texture[i].v, 0, sizeof(vec4_t));
+        c->current.texture[i].Q = 0x10000;
+    }
+}
+
+void ogles_uninit_texture(ogles_context_t* c)
+{
+    if (c->textures.ggl)
+        gglUninit(c->textures.ggl);
+    c->textures.defaultTexture->decStrong(c);
+    for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+        if (c->textures.tmu[i].texture)
+            c->textures.tmu[i].texture->decStrong(c);
+    }
+}
+
+static __attribute__((noinline))
+void validate_tmu(ogles_context_t* c, int i)
+{
+    texture_unit_t& u(c->textures.tmu[i]);
+    if (u.dirty) {
+        u.dirty = 0;
+        c->rasterizer.procs.activeTexture(c, i);
+        c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
+        c->rasterizer.procs.texGeni(c, GGL_S,
+                GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC);
+        c->rasterizer.procs.texGeni(c, GGL_T,
+                GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC);
+        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
+                GGL_TEXTURE_WRAP_S, u.texture->wraps);
+        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
+                GGL_TEXTURE_WRAP_T, u.texture->wrapt);
+        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
+                GGL_TEXTURE_MIN_FILTER, u.texture->min_filter);
+        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
+                GGL_TEXTURE_MAG_FILTER, u.texture->mag_filter);
+
+        // disable this texture unit if it's not complete
+        if (!u.texture->isComplete()) {
+            c->rasterizer.procs.disable(c, GGL_TEXTURE_2D);
+        }
+    }
+}
+
+void ogles_validate_texture_impl(ogles_context_t* c)
+{
+    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+        if (c->rasterizer.state.texture[i].enable)
+            validate_tmu(c, i);
+    }
+    c->rasterizer.procs.activeTexture(c, c->textures.active);
+}
+
+static
+void invalidate_texture(ogles_context_t* c, int tmu, uint8_t flags = 0xFF) {
+    c->textures.tmu[tmu].dirty = flags;
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Format conversion
+#endif
+
+static uint32_t gl2format_table[6][4] = {
+    // BYTE, 565, 4444, 5551
+    { GGL_PIXEL_FORMAT_A_8,
+      0, 0, 0 },                        // GL_ALPHA
+    { GGL_PIXEL_FORMAT_RGB_888,
+      GGL_PIXEL_FORMAT_RGB_565,
+      0, 0 },                           // GL_RGB
+    { GGL_PIXEL_FORMAT_RGBA_8888,
+      0,
+      GGL_PIXEL_FORMAT_RGBA_4444,
+      GGL_PIXEL_FORMAT_RGBA_5551 },     // GL_RGBA
+    { GGL_PIXEL_FORMAT_L_8,
+      0, 0, 0 },                        // GL_LUMINANCE
+    { GGL_PIXEL_FORMAT_LA_88,
+      0, 0, 0 },                        // GL_LUMINANCE_ALPHA
+};
+
+static int32_t convertGLPixelFormat(GLint format, GLenum type)
+{
+    int32_t fi = -1;
+    int32_t ti = -1;
+    switch (format) {
+    case GL_ALPHA:              fi = 0;     break;
+    case GL_RGB:                fi = 1;     break;
+    case GL_RGBA:               fi = 2;     break;
+    case GL_LUMINANCE:          fi = 3;     break;
+    case GL_LUMINANCE_ALPHA:    fi = 4;     break;
+    }
+    switch (type) {
+    case GL_UNSIGNED_BYTE:          ti = 0; break;
+    case GL_UNSIGNED_SHORT_5_6_5:   ti = 1; break;
+    case GL_UNSIGNED_SHORT_4_4_4_4: ti = 2; break;
+    case GL_UNSIGNED_SHORT_5_5_5_1: ti = 3; break;
+    }
+    if (fi==-1 || ti==-1)
+        return 0;
+    return gl2format_table[fi][ti];
+}
+
+// ----------------------------------------------------------------------------
+
+static GLenum validFormatType(ogles_context_t* c, GLenum format, GLenum type)
+{
+    GLenum error = 0;
+    if (format<GL_ALPHA || format>GL_LUMINANCE_ALPHA) {
+        error = GL_INVALID_ENUM;
+    }
+    if (type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT_4_4_4_4 &&
+        type != GL_UNSIGNED_SHORT_5_5_5_1 && type != GL_UNSIGNED_SHORT_5_6_5) {
+        error = GL_INVALID_ENUM;
+    }
+    if (type == GL_UNSIGNED_SHORT_5_6_5 && format != GL_RGB) {
+        error = GL_INVALID_OPERATION;
+    }
+    if ((type == GL_UNSIGNED_SHORT_4_4_4_4 ||
+         type == GL_UNSIGNED_SHORT_5_5_5_1)  && format != GL_RGBA) {
+        error = GL_INVALID_OPERATION;
+    }
+    if (error) {
+        ogles_error(c, error);
+    }
+    return error;
+}
+
+// ----------------------------------------------------------------------------
+
+GGLContext* getRasterizer(ogles_context_t* c)
+{
+    GGLContext* ggl = c->textures.ggl;
+    if (ggl_unlikely(!ggl)) {
+        // this is quite heavy the first time...
+        gglInit(&ggl);
+        if (!ggl) {
+            return 0;
+        }
+        GGLfixed colors[4] = { 0, 0, 0, 0x10000 };
+        c->textures.ggl = ggl;
+        ggl->activeTexture(ggl, 0);
+        ggl->enable(ggl, GGL_TEXTURE_2D);
+        ggl->texEnvi(ggl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE);
+        ggl->disable(ggl, GGL_DITHER);
+        ggl->shadeModel(ggl, GGL_FLAT);
+        ggl->color4xv(ggl, colors);
+    }
+    return ggl;
+}
+
+static __attribute__((noinline))
+int copyPixels(
+        ogles_context_t* c,
+        const GGLSurface& dst,
+        GLint xoffset, GLint yoffset,
+        const GGLSurface& src,
+        GLint x, GLint y, GLsizei w, GLsizei h)
+{
+    if ((dst.format == src.format) &&
+        (dst.stride == src.stride) &&
+        (dst.width == src.width) &&
+        (dst.height == src.height) &&
+        (dst.stride > 0) &&
+        ((x|y) == 0) &&
+        ((xoffset|yoffset) == 0))
+    {
+        // this is a common case...
+        const GGLFormat& pixelFormat(c->rasterizer.formats[src.format]);
+        const size_t size = src.height * src.stride * pixelFormat.size;
+        memcpy(dst.data, src.data, size);
+        return 0;
+    }
+
+    // use pixel-flinger to handle all the conversions
+    GGLContext* ggl = getRasterizer(c);
+    if (!ggl) {
+        // the only reason this would fail is because we ran out of memory
+        return GL_OUT_OF_MEMORY;
+    }
+
+    ggl->colorBuffer(ggl, &dst);
+    ggl->bindTexture(ggl, &src);
+    ggl->texCoord2i(ggl, x-xoffset, y-yoffset);
+    ggl->recti(ggl, xoffset, yoffset, xoffset+w, yoffset+h);
+    return 0;
+}
+
+// ----------------------------------------------------------------------------
+
+static __attribute__((noinline))
+sp<EGLTextureObject> getAndBindActiveTextureObject(ogles_context_t* c)
+{
+    sp<EGLTextureObject> tex;
+    const int active = c->textures.active;
+    const GLuint name = c->textures.tmu[active].name;
+
+    // free the reference to the previously bound object
+    texture_unit_t& u(c->textures.tmu[active]);
+    if (u.texture)
+        u.texture->decStrong(c);
+
+    if (name == 0) {
+        // 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;
+        for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+            if (c->textures.tmu[i].texture == tex.get())
+                invalidate_texture(c, i);
+        }
+    } else {
+        // get a new texture object for that name
+        tex = c->surfaceManager->replaceTexture(name);
+    }
+
+    // bind this texture to the current active texture unit
+    // and add a reference to this texture object
+    u.texture = tex.get();
+    u.texture->incStrong(c);
+    u.name = name;
+    invalidate_texture(c, active);    
+    return tex;
+}
+
+void bindTextureTmu(
+    ogles_context_t* c, int tmu, GLuint texture, const sp<EGLTextureObject>& tex)
+{
+    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)
+        u.texture->decStrong(c);
+
+    // bind this texture to the current active texture unit
+    // and add a reference to this texture object
+    u.texture = tex.get();
+    u.texture->incStrong(c);
+    u.name = texture;
+    invalidate_texture(c, tmu);
+}
+
+int createTextureSurface(ogles_context_t* c,
+        GGLSurface** outSurface, int32_t* outSize, GLint level,
+        GLenum format, GLenum type, GLsizei width, GLsizei height,
+        GLenum compressedFormat = 0)
+{
+    // find out which texture is bound to the current unit
+    const int active = c->textures.active;
+    const GLuint name = c->textures.tmu[active].name;
+
+    // convert the pixelformat to one we can handle
+    const int32_t formatIdx = convertGLPixelFormat(format, type);
+    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;
+    const int32_t bpr = ((width * pixelFormat.size) + align) & ~align;
+    const size_t size = bpr * height;
+    const int32_t stride = bpr / pixelFormat.size;
+
+    if (level > 0) {
+        const int active = c->textures.active;
+        EGLTextureObject* tex = c->textures.tmu[active].texture;
+        status_t err = tex->reallocate(level,
+                width, height, stride, formatIdx, compressedFormat, bpr);
+        if (err != NO_ERROR)
+            return GL_OUT_OF_MEMORY;
+        GGLSurface& surface = tex->editMip(level);
+        *outSurface = &surface;
+        *outSize = size;
+        return 0;
+    }
+
+    sp<EGLTextureObject> tex = getAndBindActiveTextureObject(c);
+    status_t err = tex->reallocate(level,
+            width, height, stride, formatIdx, compressedFormat, bpr);
+    if (err != NO_ERROR)
+        return GL_OUT_OF_MEMORY;
+
+    tex->internalformat = format;
+    *outSurface = &tex->surface;
+    *outSize = size;
+    return 0;
+}
+
+static void decodePalette4(const GLvoid *data, int level, int width, int height,
+                           void *surface, int stride, int format)
+
+{
+    int indexBits = 8;
+    int entrySize = 0;
+    switch (format) {
+    case GL_PALETTE4_RGB8_OES:
+        indexBits = 4;
+        /* FALLTHROUGH */
+    case GL_PALETTE8_RGB8_OES:
+        entrySize = 3;
+        break;
+
+    case GL_PALETTE4_RGBA8_OES:
+        indexBits = 4;
+        /* FALLTHROUGH */
+    case GL_PALETTE8_RGBA8_OES:
+        entrySize = 4;
+        break;
+
+    case GL_PALETTE4_R5_G6_B5_OES:
+    case GL_PALETTE4_RGBA4_OES:
+    case GL_PALETTE4_RGB5_A1_OES:
+        indexBits = 4;
+        /* FALLTHROUGH */
+    case GL_PALETTE8_R5_G6_B5_OES:
+    case GL_PALETTE8_RGBA4_OES:
+    case GL_PALETTE8_RGB5_A1_OES:
+        entrySize = 2;
+        break;
+    }
+
+    const int paletteSize = (1 << indexBits) * entrySize;
+    uint8_t const* pixels = (uint8_t *)data + paletteSize;
+    for (int i=0 ; i<level ; i++) {
+        int w = (width  >> i) ? : 1;
+        int h = (height >> i) ? : 1;
+        pixels += h * ((w * indexBits) / 8);
+    }
+    width  = (width  >> level) ? : 1;
+    height = (height >> level) ? : 1;
+
+    if (entrySize == 2) {
+        uint8_t const* const palette = (uint8_t*)data;
+        for (int y=0 ; y<height ; y++) {
+            uint8_t* p = (uint8_t*)surface + y*stride*2;
+            if (indexBits == 8) {
+                for (int x=0 ; x<width ; x++) {
+                    int index = 2 * (*pixels++);
+                    *p++ = palette[index + 0];
+                    *p++ = palette[index + 1];
+                }
+            } else {
+                for (int x=0 ; x<width ; x+=2) {
+                    int v = *pixels++;
+                    int index = 2 * (v >> 4);
+                    *p++ = palette[index + 0];
+                    *p++ = palette[index + 1];
+                    if (x+1 < width) {
+                        index = 2 * (v & 0xF);
+                        *p++ = palette[index + 0];
+                        *p++ = palette[index + 1];
+                    }
+                }
+            }
+        }
+    } else if (entrySize == 3) {
+        uint8_t const* const palette = (uint8_t*)data;
+        for (int y=0 ; y<height ; y++) {
+            uint8_t* p = (uint8_t*)surface + y*stride*3;
+            if (indexBits == 8) {
+                for (int x=0 ; x<width ; x++) {
+                    int index = 3 * (*pixels++);
+                    *p++ = palette[index + 0];
+                    *p++ = palette[index + 1];
+                    *p++ = palette[index + 2];
+                }
+            } else {
+                for (int x=0 ; x<width ; x+=2) {
+                    int v = *pixels++;
+                    int index = 3 * (v >> 4);
+                    *p++ = palette[index + 0];
+                    *p++ = palette[index + 1];
+                    *p++ = palette[index + 2];
+                    if (x+1 < width) {
+                        index = 3 * (v & 0xF);
+                        *p++ = palette[index + 0];
+                        *p++ = palette[index + 1];
+                        *p++ = palette[index + 2];
+                    }
+                }
+            }
+        }
+    } else if (entrySize == 4) {
+        uint8_t const* const palette = (uint8_t*)data;
+        for (int y=0 ; y<height ; y++) {
+            uint8_t* p = (uint8_t*)surface + y*stride*4;
+            if (indexBits == 8) {
+                for (int x=0 ; x<width ; x++) {
+                    int index = 4 * (*pixels++);
+                    *p++ = palette[index + 0];
+                    *p++ = palette[index + 1];
+                    *p++ = palette[index + 2];
+                    *p++ = palette[index + 3];
+                }
+            } else {
+                for (int x=0 ; x<width ; x+=2) {
+                    int v = *pixels++;
+                    int index = 4 * (v >> 4);
+                    *p++ = palette[index + 0];
+                    *p++ = palette[index + 1];
+                    *p++ = palette[index + 2];
+                    *p++ = palette[index + 3];
+                    if (x+1 < width) {
+                        index = 4 * (v & 0xF);
+                        *p++ = palette[index + 0];
+                        *p++ = palette[index + 1];
+                        *p++ = palette[index + 2];
+                        *p++ = palette[index + 3];
+                    }
+                }
+            }
+        }
+    }
+}
+
+
+
+static __attribute__((noinline))
+void set_depth_and_fog(ogles_context_t* c, GLint z)
+{
+    const uint32_t enables = c->rasterizer.state.enables;
+    // we need to compute Zw
+    int32_t iterators[3];
+    iterators[1] = iterators[2] = 0;
+    GGLfixed Zw;
+    GGLfixed n = gglFloatToFixed(c->transforms.vpt.zNear);
+    GGLfixed f = gglFloatToFixed(c->transforms.vpt.zFar);
+    if (z<=0)       Zw = n;
+    else if (z>=1)  Zw = f;
+    else            Zw = gglMulAddx(z, (f-n), n);
+    if (enables & GGL_ENABLE_FOG) {
+        // set up fog if needed...
+        iterators[0] = c->fog.fog(c, Zw);
+        c->rasterizer.procs.fogGrad3xv(c, iterators);
+    }
+    if (enables & GGL_ENABLE_DEPTH_TEST) {
+        // set up z-test if needed...
+        int32_t z = (Zw & ~(Zw>>31));
+        if (z >= 0x10000)
+            z = 0xFFFF;
+        iterators[0] = (z << 16) | z;
+        c->rasterizer.procs.zGrad3xv(c, iterators);
+    }
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Generate mimaps
+#endif
+
+extern status_t buildAPyramid(ogles_context_t* c, EGLTextureObject* tex);
+
+void generateMipmap(ogles_context_t* c, GLint level)
+{
+    if (level == 0) {
+        const int active = c->textures.active;
+        EGLTextureObject* tex = c->textures.tmu[active].texture;
+        if (tex->generate_mipmap) {
+            if (buildAPyramid(c, tex) != NO_ERROR) {
+                ogles_error(c, GL_OUT_OF_MEMORY);
+                return;
+            }
+        }
+    }
+}
+
+
+static void texParameterx(
+        GLenum target, GLenum pname, GLfixed param, ogles_context_t* c)
+{
+    if (target != GGL_TEXTURE_2D) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    
+    EGLTextureObject* textureObject = c->textures.tmu[c->textures.active].texture;    
+    switch (pname) {
+    case GL_TEXTURE_WRAP_S:
+        if ((param == GL_CLAMP) ||
+            (param == GL_REPEAT) ||
+            (param == GL_CLAMP_TO_EDGE)) {
+            textureObject->wraps = param;
+        } else {
+            goto invalid_enum;
+        }
+        break;
+    case GL_TEXTURE_WRAP_T:
+        if ((param == GGL_CLAMP) ||
+            (param == GGL_REPEAT) ||
+            (param == GGL_CLAMP_TO_EDGE)) {
+            textureObject->wrapt = param;
+        } else {
+            goto invalid_enum;
+        }
+        break;
+    case GL_TEXTURE_MIN_FILTER:
+        if ((param == GL_NEAREST) ||
+            (param == GL_LINEAR) ||
+            (param == GL_NEAREST_MIPMAP_NEAREST) ||
+            (param == GL_LINEAR_MIPMAP_NEAREST) ||
+            (param == GL_NEAREST_MIPMAP_LINEAR) ||
+            (param == GL_LINEAR_MIPMAP_LINEAR)) {
+            textureObject->min_filter = param;
+        } else {
+            goto invalid_enum;
+        }
+        break;
+    case GL_TEXTURE_MAG_FILTER:
+        if ((param == GL_NEAREST) ||
+            (param == GL_LINEAR)) {
+            textureObject->mag_filter = param;
+        } else {
+            goto invalid_enum;
+        }
+        break;
+    case GL_GENERATE_MIPMAP:
+        textureObject->generate_mipmap = param;
+        break;
+    default:
+invalid_enum:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    invalidate_texture(c, c->textures.active);
+}
+
+
+static void drawTexxOES(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;
+    h >>= FIXED_BITS;
+
+    // set up all texture units
+    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+        if (!c->rasterizer.state.texture[i].enable)
+            continue;
+
+        int32_t texcoords[8];
+        texture_unit_t& u(c->textures.tmu[i]);
+
+        // validate this tmu (bind, wrap, filter)
+        validate_tmu(c, i);
+        // we CLAMP here, which works with premultiplied (s,t)
+        c->rasterizer.procs.texParameteri(c,
+                GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_S, GGL_CLAMP);
+        c->rasterizer.procs.texParameteri(c,
+                GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_T, GGL_CLAMP);
+        u.dirty = 0xFF; // XXX: should be more subtle
+
+        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;
+        const GLint Hcr = textureObject->crop_rect[3] << 16;
+
+        // computes texture coordinates (pre-multiplied)
+        int32_t dsdx = Wcr / w;   // dsdx =  ((Wcr/w)/Wt)*Wt
+        int32_t dtdy =-Hcr / h;   // dtdy = -((Hcr/h)/Ht)*Ht
+        int32_t s0   = Ucr       - gglMulx(dsdx, x); // s0 = Ucr - x * dsdx
+        int32_t t0   = (Vcr+Hcr) - gglMulx(dtdy, y); // t0 = (Vcr+Hcr) - y*dtdy
+        texcoords[0] = s0;
+        texcoords[1] = dsdx;
+        texcoords[2] = 0;
+        texcoords[3] = t0;
+        texcoords[4] = 0;
+        texcoords[5] = dtdy;
+        texcoords[6] = 0;
+        texcoords[7] = 0;
+        c->rasterizer.procs.texCoordGradScale8xv(c, i, texcoords);
+    }
+
+    const uint32_t enables = c->rasterizer.state.enables;
+    if (ggl_unlikely(enables & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)))
+        set_depth_and_fog(c, z);
+
+    c->rasterizer.procs.activeTexture(c, c->textures.active);
+    c->rasterizer.procs.color4xv(c, c->currentColorClamped.v);
+    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, 
+            gglFixedToIntRound(x),
+            gglFixedToIntRound(y),
+            gglFixedToIntRound(x)+w,
+            gglFixedToIntRound(y)+h);
+}
+
+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
+    // texture unit active and no scaling is required
+    // THEN, we can use our special 1:1 mapping
+    // which is a lot faster.
+
+    if (ggl_likely(c->rasterizer.state.enabled_tmu == 1)) {
+        const int tmu = 0;
+        texture_unit_t& u(c->textures.tmu[tmu]);
+        EGLTextureObject* textureObject = u.texture;  
+        const GLint Wcr = textureObject->crop_rect[2];
+        const GLint Hcr = textureObject->crop_rect[3];
+
+        if ((w == Wcr) && (h == -Hcr)) {
+            if ((w|h) <= 0) return; // quickly reject empty rects
+
+            if (u.dirty) {
+                c->rasterizer.procs.activeTexture(c, tmu);
+                c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
+                c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
+                        GGL_TEXTURE_MIN_FILTER, u.texture->min_filter);
+                c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
+                        GGL_TEXTURE_MAG_FILTER, u.texture->mag_filter);
+            }
+            c->rasterizer.procs.texGeni(c, GGL_S,
+                    GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
+            c->rasterizer.procs.texGeni(c, GGL_T,
+                    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)) {
+                // The GL spec is unclear about what should happen
+                // 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;
+            if (ggl_unlikely(enables & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)))
+                set_depth_and_fog(c, z);
+
+            c->rasterizer.procs.color4xv(c, c->currentColorClamped.v);
+            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, x, y, x+w, y+h);
+            return;
+        }
+    }
+
+slow_case:
+    drawTexxOES(
+            gglIntToFixed(x), gglIntToFixed(y), gglIntToFixed(z),
+            gglIntToFixed(w), gglIntToFixed(h),
+            c);
+}
+
+
+}; // namespace android
+// ----------------------------------------------------------------------------
+
+using namespace android;
+
+
+#if 0
+#pragma mark -
+#pragma mark Texture API
+#endif
+
+void glActiveTexture(GLenum texture)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (uint32_t(texture-GL_TEXTURE0) > uint32_t(GGL_TEXTURE_UNIT_COUNT)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    c->textures.active = texture - GL_TEXTURE0;
+    c->rasterizer.procs.activeTexture(c, c->textures.active);
+}
+
+void glBindTexture(GLenum target, GLuint texture)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (target != GL_TEXTURE_2D) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+
+    // Bind or create a texture
+    sp<EGLTextureObject> tex;    
+    if (texture == 0) {
+        // 0 is our local texture object
+        tex = c->textures.defaultTexture;
+    } else {
+        tex = c->surfaceManager->texture(texture);
+        if (ggl_unlikely(tex == 0)) {
+            tex = c->surfaceManager->createTexture(texture);
+            if (tex == 0) {
+                ogles_error(c, GL_OUT_OF_MEMORY);
+                return;
+            }
+        }
+    }
+    bindTextureTmu(c, c->textures.active, texture, tex);
+}
+
+void glGenTextures(GLsizei n, GLuint *textures)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (n<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    // generate unique (shared) texture names
+    c->surfaceManager->getToken(n, textures);
+}
+
+void glDeleteTextures(GLsizei n, const GLuint *textures)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (n<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+
+    // If deleting a bound texture, bind this unit to 0
+    for (int t=0 ; t<GGL_TEXTURE_UNIT_COUNT ; t++) {
+        if (c->textures.tmu[t].name == 0)
+            continue;
+        for (int i=0 ; i<n ; i++) {
+            if (textures[i] && (textures[i] == c->textures.tmu[t].name)) {
+                // bind this tmu to texture 0
+                sp<EGLTextureObject> tex(c->textures.defaultTexture);
+                bindTextureTmu(c, t, 0, tex);
+            }
+        }
+    }
+    c->surfaceManager->deleteTextures(n, textures);
+    c->surfaceManager->recycleTokens(n, textures);
+}
+
+void glMultiTexCoord4f(
+        GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (uint32_t(target-GL_TEXTURE0) > uint32_t(GGL_TEXTURE_UNIT_COUNT)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    const int tmu = target-GL_TEXTURE0;
+    c->current.texture[tmu].S = gglFloatToFixed(s);
+    c->current.texture[tmu].T = gglFloatToFixed(t);
+    c->current.texture[tmu].R = gglFloatToFixed(r);
+    c->current.texture[tmu].Q = gglFloatToFixed(q);
+}
+
+void glMultiTexCoord4x(
+        GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (uint32_t(target-GL_TEXTURE0) > uint32_t(GGL_TEXTURE_UNIT_COUNT)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    const int tmu = target-GL_TEXTURE0;
+    c->current.texture[tmu].S = s;
+    c->current.texture[tmu].T = t;
+    c->current.texture[tmu].R = r;
+    c->current.texture[tmu].Q = q;
+}
+
+void glPixelStorei(GLenum pname, GLint param)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    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;
+    }
+    if (pname == GL_PACK_ALIGNMENT)
+        c->textures.packAlignment = param;
+    if (pname == GL_UNPACK_ALIGNMENT)
+        c->textures.unpackAlignment = param;
+}
+
+void glTexEnvf(GLenum target, GLenum pname, GLfloat param)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.texEnvi(c, target, pname, GLint(param));
+}
+
+void glTexEnvfv(
+        GLenum target, GLenum pname, const GLfloat *params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (pname == GL_TEXTURE_ENV_MODE) {
+        c->rasterizer.procs.texEnvi(c, target, pname, GLint(*params));
+        return;
+    }
+    if (pname == GL_TEXTURE_ENV_COLOR) {
+        GGLfixed fixed[4];
+        for (int i=0 ; i<4 ; i++)
+            fixed[i] = gglFloatToFixed(params[i]);
+        c->rasterizer.procs.texEnvxv(c, target, pname, fixed);
+        return;
+    }
+    ogles_error(c, GL_INVALID_ENUM);
+}
+
+void glTexEnvx(GLenum target, GLenum pname, GLfixed param)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.texEnvi(c, target, pname, param);
+}
+
+void glTexEnvxv(
+        GLenum target, GLenum pname, const GLfixed *params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->rasterizer.procs.texEnvxv(c, target, pname, params);
+}
+
+void glTexParameteriv(
+        GLenum target, GLenum pname, const GLint* params)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (target != GGL_TEXTURE_2D) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+
+    EGLTextureObject* textureObject = c->textures.tmu[c->textures.active].texture;
+    switch (pname) {
+    case GL_TEXTURE_CROP_RECT_OES:
+        memcpy(textureObject->crop_rect, params, 4*sizeof(GLint));
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+}
+
+void glTexParameterf(
+        GLenum target, GLenum pname, GLfloat param)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    texParameterx(target, pname, GLfixed(param), c);
+}
+
+void glTexParameterx(
+        GLenum target, GLenum pname, GLfixed param)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    texParameterx(target, pname, param, c);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+void glCompressedTexImage2D(
+        GLenum target, GLint level, GLenum internalformat,
+        GLsizei width, GLsizei height, GLint border,
+        GLsizei imageSize, const GLvoid *data)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (target != GL_TEXTURE_2D) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if ((internalformat < GL_PALETTE4_RGB8_OES ||
+         internalformat > GL_PALETTE8_RGB5_A1_OES)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if (width<0 || height<0 || border!=0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+
+    // "uncompress" the texture since pixelflinger doesn't support
+    // any compressed texture format natively. 
+    GLenum format;
+    GLenum type;
+    switch (internalformat) {
+    case GL_PALETTE8_RGB8_OES:
+    case GL_PALETTE4_RGB8_OES:
+        format      = GL_RGB;
+        type        = GL_UNSIGNED_BYTE;
+        break;
+    case GL_PALETTE8_RGBA8_OES:
+    case GL_PALETTE4_RGBA8_OES:
+        format      = GL_RGBA;
+        type        = GL_UNSIGNED_BYTE;
+        break;
+    case GL_PALETTE8_R5_G6_B5_OES:
+    case GL_PALETTE4_R5_G6_B5_OES:
+        format      = GL_RGB;
+        type        = GL_UNSIGNED_SHORT_5_6_5;
+        break;
+    case GL_PALETTE8_RGBA4_OES:
+    case GL_PALETTE4_RGBA4_OES:
+        format      = GL_RGBA;
+        type        = GL_UNSIGNED_SHORT_4_4_4_4;
+        break;
+    case GL_PALETTE8_RGB5_A1_OES:
+    case GL_PALETTE4_RGB5_A1_OES:
+        format      = GL_RGBA;
+        type        = GL_UNSIGNED_SHORT_5_5_5_1;
+        break;
+    default:
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+
+    if (!data || !width || !height) {
+        // unclear if this is an error or not...
+        return;
+    }
+
+    int32_t size;
+    GGLSurface* surface;
+    // all mipmap levels are specified at once.
+    const int numLevels = level<0 ? -level : 1;
+    for (int i=0 ; i<numLevels ; i++) {
+        int lod_w = (width  >> i) ? : 1;
+        int lod_h = (height >> i) ? : 1;
+        int error = createTextureSurface(c, &surface, &size,
+                i, format, type, lod_w, lod_h);
+        if (error) {
+            ogles_error(c, error);
+            return;
+        }
+        decodePalette4(data, i, width, height,
+                surface->data, surface->stride, internalformat);
+    }
+}
+
+
+void glTexImage2D(
+        GLenum target, GLint level, GLenum internalformat,
+        GLsizei width, GLsizei height, GLint border,
+        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) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if (width<0 || height<0 || border!=0 || level < 0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    if (format != internalformat) {
+        ogles_error(c, GL_INVALID_OPERATION);
+        return;
+    }
+    if (validFormatType(c, format, type)) {
+        return;
+    }
+
+    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);
+        return;
+    }
+
+    if (pixels) {
+        const int32_t formatIdx = convertGLPixelFormat(format, type);
+        const GGLFormat& pixelFormat(c->rasterizer.formats[formatIdx]);
+        const int32_t align = c->textures.unpackAlignment-1;
+        const int32_t bpr = ((width * pixelFormat.size) + align) & ~align;
+        const size_t size = bpr * height;
+        const int32_t stride = bpr / pixelFormat.size;
+
+        GGLSurface userSurface;
+        userSurface.version = sizeof(userSurface);
+        userSurface.width  = width;
+        userSurface.height = height;
+        userSurface.stride = stride;
+        userSurface.format = formatIdx;
+        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);
+        }
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+void glCompressedTexSubImage2D(
+        GLenum target, GLint level, GLint xoffset,
+        GLint yoffset, GLsizei width, GLsizei height,
+        GLenum format, GLsizei imageSize,
+        const GLvoid *data)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    ogles_error(c, GL_INVALID_ENUM);
+}
+
+void glTexSubImage2D(
+        GLenum target, GLint level, GLint xoffset,
+        GLint yoffset, GLsizei width, GLsizei height,
+        GLenum format, GLenum type, const GLvoid *pixels)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (target != GL_TEXTURE_2D) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if (xoffset<0 || yoffset<0 || width<0 || height<0 || level<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    if (validFormatType(c, format, type)) {
+        return;
+    }
+
+    // find out which texture is bound to the current unit
+    const int active = c->textures.active;
+    EGLTextureObject* tex = c->textures.tmu[active].texture;
+    const GGLSurface& surface(tex->mip(level));
+
+    if (!tex->internalformat || tex->direct) {
+        ogles_error(c, GL_INVALID_OPERATION);
+        return;
+    }
+    if ((xoffset + width  > GLsizei(surface.width)) ||
+        (yoffset + height > GLsizei(surface.height))) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    if (!width || !height) {
+        return; // okay, but no-op.
+    }
+
+    // figure out the size we need as well as the stride
+    const int32_t formatIdx = convertGLPixelFormat(format, type);
+    if (formatIdx == 0) { // we don't know what to do with this
+        ogles_error(c, GL_INVALID_OPERATION);
+        return;
+    }
+
+    const GGLFormat& pixelFormat(c->rasterizer.formats[formatIdx]);
+    const int32_t align = c->textures.unpackAlignment-1;
+    const int32_t bpr = ((width * pixelFormat.size) + align) & ~align;
+    const size_t size = bpr * height;
+    const int32_t stride = bpr / pixelFormat.size;
+    GGLSurface userSurface;
+    userSurface.version = sizeof(userSurface);
+    userSurface.width  = width;
+    userSurface.height = height;
+    userSurface.stride = stride;
+    userSurface.format = formatIdx;
+    userSurface.compressedFormat = 0;
+    userSurface.data = (GLubyte*)pixels;
+
+    int err = copyPixels(c,
+            surface, xoffset, yoffset,
+            userSurface, 0, 0, width, height); 
+    if (err) {
+        ogles_error(c, err);
+        return;
+    }
+
+    generateMipmap(c, level);
+
+    // since we only changed the content of the texture, we don't need
+    // to call bindTexture on the main rasterizer.
+}
+
+// ----------------------------------------------------------------------------
+
+void glCopyTexImage2D(
+        GLenum target, GLint level, GLenum internalformat,
+        GLint x, GLint y, GLsizei width, GLsizei height,
+        GLint border)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (target != GL_TEXTURE_2D) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if (internalformat<GL_ALPHA || internalformat>GL_LUMINANCE_ALPHA) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if (width<0 || height<0 || border!=0 || level<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+
+    GLenum format = 0;
+    GLenum type = GL_UNSIGNED_BYTE;
+    const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
+    const int cbFormatIdx = cbSurface.format;
+    switch (cbFormatIdx) {
+    case GGL_PIXEL_FORMAT_RGB_565:
+        type = GL_UNSIGNED_SHORT_5_6_5;
+        break;
+    case GGL_PIXEL_FORMAT_RGBA_5551:
+        type = GL_UNSIGNED_SHORT_5_5_5_1;
+        break;
+    case GGL_PIXEL_FORMAT_RGBA_4444:
+        type = GL_UNSIGNED_SHORT_4_4_4_4;
+        break;
+    }
+    switch (internalformat) {
+    case GL_ALPHA:
+    case GL_LUMINANCE_ALPHA:
+    case GL_LUMINANCE:
+        type = GL_UNSIGNED_BYTE;
+        break;    
+    }
+
+    // figure out the format to use for the new texture
+    switch (cbFormatIdx) {
+    case GGL_PIXEL_FORMAT_RGBA_8888:
+    case GGL_PIXEL_FORMAT_A_8:
+    case GGL_PIXEL_FORMAT_RGBA_5551:
+    case GGL_PIXEL_FORMAT_RGBA_4444:
+        format = internalformat;
+        break;    
+    case GGL_PIXEL_FORMAT_RGBX_8888:
+    case GGL_PIXEL_FORMAT_RGB_888:
+    case GGL_PIXEL_FORMAT_RGB_565:
+    case GGL_PIXEL_FORMAT_L_8:
+        switch (internalformat) {
+        case GL_LUMINANCE:
+        case GL_RGB:
+            format = internalformat;
+            break;    
+        }
+        break;
+    }
+
+    if (format == 0) {
+        // invalid combination
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+
+    // create the new texture...
+    int32_t size;
+    GGLSurface* surface;
+    int error = createTextureSurface(c, &surface, &size,
+            level, format, type, width, height);
+    if (error) {
+        ogles_error(c, error);
+        return;
+    }
+    
+    // The bottom row is stored first in textures
+    GGLSurface txSurface(*surface);
+    txSurface.stride = -txSurface.stride;
+
+    // (x,y) is the lower-left corner of colorBuffer
+    y = cbSurface.height - (y + height);
+
+    int err = copyPixels(c,
+            txSurface, 0, 0,
+            cbSurface, x, y, cbSurface.width, cbSurface.height);  
+    if (err) {
+        ogles_error(c, err);
+    }
+
+    generateMipmap(c, level);
+}
+
+void glCopyTexSubImage2D(
+        GLenum target, GLint level, GLint xoffset, GLint yoffset,
+        GLint x, GLint y, GLsizei width, GLsizei height)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (target != GL_TEXTURE_2D) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if (xoffset<0 || yoffset<0 || width<0 || height<0 || level<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    if (!width || !height) {
+        return; // okay, but no-op.
+    }
+
+    // find out which texture is bound to the current unit
+    const int active = c->textures.active;
+    EGLTextureObject* tex = c->textures.tmu[active].texture;
+    const GGLSurface& surface(tex->mip(level));
+
+    if (!tex->internalformat) {
+        ogles_error(c, GL_INVALID_OPERATION);
+        return;
+    }
+    if ((xoffset + width  > GLsizei(surface.width)) ||
+        (yoffset + height > GLsizei(surface.height))) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+
+    // The bottom row is stored first in textures
+    GGLSurface txSurface(surface);
+    txSurface.stride = -txSurface.stride;
+
+    // (x,y) is the lower-left corner of colorBuffer
+    const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
+    y = cbSurface.height - (y + height);
+
+    int err = copyPixels(c,
+            surface, xoffset, yoffset,
+            cbSurface, x, y, width, height);  
+    if (err) {
+        ogles_error(c, err);
+        return;
+    }
+
+    generateMipmap(c, level);
+}
+
+void glReadPixels(
+        GLint x, GLint y, GLsizei width, GLsizei height,
+        GLenum format, GLenum type, GLvoid *pixels)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if ((format != GL_RGBA) && (format != GL_RGB)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if ((type != GL_UNSIGNED_BYTE) && (type != GL_UNSIGNED_SHORT_5_6_5)) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+    if (width<0 || height<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    if (x<0 || x<0) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+
+    int32_t formatIdx = GGL_PIXEL_FORMAT_NONE;
+    if ((format == GL_RGBA) && (type == GL_UNSIGNED_BYTE)) {
+        formatIdx = GGL_PIXEL_FORMAT_RGBA_8888;
+    } else if ((format == GL_RGB) && (type == GL_UNSIGNED_SHORT_5_6_5)) {
+        formatIdx = GGL_PIXEL_FORMAT_RGB_565;
+    } else {
+        ogles_error(c, GL_INVALID_OPERATION);
+        return;
+    }
+
+    const GGLSurface& readSurface = c->rasterizer.state.buffers.read.s;
+    if ((x+width > GLint(readSurface.width)) ||
+            (y+height > GLint(readSurface.height))) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+
+    const GGLFormat& pixelFormat(c->rasterizer.formats[formatIdx]);
+    const int32_t align = c->textures.packAlignment-1;
+    const int32_t bpr = ((width * pixelFormat.size) + align) & ~align;
+    const int32_t stride = bpr / pixelFormat.size;
+
+    GGLSurface userSurface;
+    userSurface.version = sizeof(userSurface);
+    userSurface.width  = width;
+    userSurface.height = height;
+    userSurface.stride = -stride; // bottom row is transfered first
+    userSurface.format = formatIdx;
+    userSurface.compressedFormat = 0;
+    userSurface.data = (GLubyte*)pixels;
+
+    // use pixel-flinger to handle all the conversions
+    GGLContext* ggl = getRasterizer(c);
+    if (!ggl) {
+        // the only reason this would fail is because we ran out of memory
+        ogles_error(c, GL_OUT_OF_MEMORY);
+        return;
+    }
+
+    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);
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark DrawTexture Extension
+#endif
+
+void glDrawTexsvOES(const GLshort* coords) {
+    ogles_context_t* c = ogles_context_t::get();
+    drawTexiOES(coords[0], coords[1], coords[2], coords[3], coords[4], c);
+}
+void glDrawTexivOES(const GLint* coords) {
+    ogles_context_t* c = ogles_context_t::get();
+    drawTexiOES(coords[0], coords[1], coords[2], coords[3], coords[4], c);
+}
+void glDrawTexsOES(GLshort x , GLshort y, GLshort z, GLshort w, GLshort h) {
+    ogles_context_t* c = ogles_context_t::get();
+    drawTexiOES(x, y, z, w, h, c);
+}
+void glDrawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h) {
+    ogles_context_t* c = ogles_context_t::get();
+    drawTexiOES(x, y, z, w, h, c);
+}
+
+void glDrawTexfvOES(const GLfloat* coords) {
+    ogles_context_t* c = ogles_context_t::get();
+    drawTexxOES(
+            gglFloatToFixed(coords[0]),
+            gglFloatToFixed(coords[1]),
+            gglFloatToFixed(coords[2]),
+            gglFloatToFixed(coords[3]),
+            gglFloatToFixed(coords[4]),
+            c);
+}
+void glDrawTexxvOES(const GLfixed* coords) {
+    ogles_context_t* c = ogles_context_t::get();
+    drawTexxOES(coords[0], coords[1], coords[2], coords[3], coords[4], c);
+}
+void glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h){
+    ogles_context_t* c = ogles_context_t::get();
+    drawTexxOES(
+            gglFloatToFixed(x), gglFloatToFixed(y), gglFloatToFixed(z),
+            gglFloatToFixed(w), gglFloatToFixed(h),
+            c);
+}
+void glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h) {
+    ogles_context_t* c = ogles_context_t::get();
+    drawTexxOES(x, y, z, w, h, c);
+}
diff --git a/opengl/libagl/texture.h b/opengl/libagl/texture.h
new file mode 100644
index 0000000..5c57948
--- /dev/null
+++ b/opengl/libagl/texture.h
@@ -0,0 +1,45 @@
+/* libs/opengles/texture.h
+**
+** 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 
+**
+**     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_TEXTURE_H
+#define ANDROID_OPENGLES_TEXTURE_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+#include <private/pixelflinger/ggl_context.h>
+
+#include <GLES/gl.h>
+
+#include "context.h"
+
+namespace android {
+
+void ogles_init_texture(ogles_context_t* c);
+void ogles_uninit_texture(ogles_context_t* c);
+void ogles_validate_texture_impl(ogles_context_t* c);
+
+inline void ogles_validate_texture(ogles_context_t* c) {
+    if (c->rasterizer.state.enables & GGL_ENABLE_TMUS)
+        ogles_validate_texture_impl(c);
+}
+
+
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_TEXTURE_H
diff --git a/opengl/libagl/vertex.cpp b/opengl/libagl/vertex.cpp
new file mode 100644
index 0000000..5bcc9dc
--- /dev/null
+++ b/opengl/libagl/vertex.cpp
@@ -0,0 +1,247 @@
+/* libs/opengles/vertex.cpp
+**
+** 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 
+**
+**     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 <stdio.h>
+#include <stdlib.h>
+#include "context.h"
+#include "fp.h"
+#include "vertex.h"
+#include "state.h"
+#include "matrix.h"
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+void ogles_init_vertex(ogles_context_t* c)
+{
+    c->cull.enable = GL_FALSE;
+    c->cull.cullFace = GL_BACK;
+    c->cull.frontFace = GL_CCW;
+
+    c->current.color.r = 0x10000;
+    c->current.color.g = 0x10000;
+    c->current.color.b = 0x10000;
+    c->current.color.a = 0x10000;
+
+    c->currentNormal.z = 0x10000;
+}
+
+void ogles_uninit_vertex(ogles_context_t* c)
+{
+}
+
+// ----------------------------------------------------------------------------
+// vertex processing
+// ----------------------------------------------------------------------------
+
+// Divides a vertex clip coordinates by W
+static inline
+void perspective(ogles_context_t* c, vertex_t* v, uint32_t enables)
+{
+    // [x,y,z]window = vpt * ([x,y,z]clip / clip.w)
+    // [w]window = 1/w
+
+    // With a regular projection generated by glFrustum(),
+    // we have w=-z, therefore, w is in [zNear, zFar].
+    // Also, zNear and zFar are stricly positive,
+    // and 1/w (window.w) is in [1/zFar, 1/zNear], usually this
+    // means ]0, +inf[ -- however, it is always recommended
+    // to use as large values as possible for zNear.
+    // All in all, w is usually smaller than 1.0 (assuming
+    // zNear is at least 1.0); and even if zNear is smaller than 1.0
+    // values of w won't be too big.
+
+    const int32_t rw = gglRecip28(v->clip.w);
+    const GLfixed* const m = c->transforms.vpt.transform.matrix.m;
+    v->window.w = rw;
+    v->window.x = gglMulAddx(gglMulx(v->clip.x, rw, 16), m[ 0], m[12], 28); 
+    v->window.y = gglMulAddx(gglMulx(v->clip.y, rw, 16), m[ 5], m[13], 28);
+    v->window.x = TRI_FROM_FIXED(v->window.x);
+    v->window.y = TRI_FROM_FIXED(v->window.y);
+    if (enables & GGL_ENABLE_DEPTH_TEST) {
+        v->window.z = gglMulAddx(gglMulx(v->clip.z, rw, 16), m[10], m[14], 28);
+    }
+}
+
+// frustum clipping and W-divide
+static inline
+void clipFrustumPerspective(ogles_context_t* c, vertex_t* v, uint32_t enables)
+{
+    // ndc = clip / W
+    // window = ncd * viewport
+    
+    // clip to the view-volume
+    uint32_t clip = v->flags & vertex_t::CLIP_ALL;
+    const GLfixed w = v->clip.w;
+    if (v->clip.x < -w)   clip |= vertex_t::CLIP_L;
+    if (v->clip.x >  w)   clip |= vertex_t::CLIP_R;
+    if (v->clip.y < -w)   clip |= vertex_t::CLIP_B;
+    if (v->clip.y >  w)   clip |= vertex_t::CLIP_T;
+    if (v->clip.z < -w)   clip |= vertex_t::CLIP_N;
+    if (v->clip.z >  w)   clip |= vertex_t::CLIP_F;
+
+    v->flags |= clip;
+    c->arrays.cull &= clip;
+
+    if (ggl_likely(!clip)) {
+        // if the vertice is clipped, we don't do the perspective
+        // divide, since we don't need its window coordinates.
+        perspective(c, v, enables);
+    }
+}
+
+// frustum clipping, user clipping and W-divide
+static inline
+void clipAllPerspective(ogles_context_t* c, vertex_t* v, uint32_t enables)
+{
+    // compute eye coordinates
+    c->arrays.mv_transform(
+            &c->transforms.modelview.transform, &v->eye, &v->obj);
+    v->flags |= vertex_t::EYE;
+
+    // clip this vertex against each user clip plane
+    uint32_t clip = 0;
+    int planes = c->clipPlanes.enable;
+    while (planes) {
+        const int i = 31 - gglClz(planes);
+        planes &= ~(1<<i);
+        // XXX: we should have a special dot() for 2,3,4 coords vertices
+        GLfixed d = dot4(c->clipPlanes.plane[i].equation.v, v->eye.v);
+        if (d < 0) {
+            clip |= 0x100<<i;
+        }
+    }
+    v->flags |= clip;
+
+    clipFrustumPerspective(c, v, enables);
+}
+
+// ----------------------------------------------------------------------------
+
+void ogles_vertex_project(ogles_context_t* c, vertex_t* v) {
+    perspective(c, v, c->rasterizer.state.enables);
+}
+
+void ogles_vertex_perspective2D(ogles_context_t* c, vertex_t* v)
+{
+    // here we assume w=1.0 and the viewport transformation
+    // has been applied already.
+    c->arrays.cull = 0;
+    v->window.x = TRI_FROM_FIXED(v->clip.x);
+    v->window.y = TRI_FROM_FIXED(v->clip.y);
+    v->window.z = v->clip.z;
+    v->window.w = v->clip.w << 12;
+}
+
+void ogles_vertex_perspective3DZ(ogles_context_t* c, vertex_t* v) {
+    clipFrustumPerspective(c, v, GGL_ENABLE_DEPTH_TEST);
+}
+void ogles_vertex_perspective3D(ogles_context_t* c, vertex_t* v) {
+    clipFrustumPerspective(c, v, 0);
+}
+void ogles_vertex_clipAllPerspective3DZ(ogles_context_t* c, vertex_t* v) {
+    clipAllPerspective(c, v, GGL_ENABLE_DEPTH_TEST);
+}
+void ogles_vertex_clipAllPerspective3D(ogles_context_t* c, vertex_t* v) {
+    clipAllPerspective(c, v, 0);
+}
+
+static void clipPlanex(GLenum plane, const GLfixed* equ, ogles_context_t* c)
+{
+    const int p = plane - GL_CLIP_PLANE0;
+    if (ggl_unlikely(uint32_t(p) > (GL_CLIP_PLANE5 - GL_CLIP_PLANE0))) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+
+    vec4_t& equation = c->clipPlanes.plane[p].equation;
+    memcpy(equation.v, equ, sizeof(vec4_t));
+
+    ogles_validate_transform(c, transform_state_t::MVIT);
+    transform_t& mvit = c->transforms.mvit4;
+    mvit.point4(&mvit, &equation, &equation);
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
+using namespace android;
+
+
+void glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->current.color.r       = gglFloatToFixed(r);
+    c->currentColorClamped.r = gglClampx(c->current.color.r);
+    c->current.color.g       = gglFloatToFixed(g);
+    c->currentColorClamped.g = gglClampx(c->current.color.g);
+    c->current.color.b       = gglFloatToFixed(b);
+    c->currentColorClamped.b = gglClampx(c->current.color.b);
+    c->current.color.a       = gglFloatToFixed(a);
+    c->currentColorClamped.a = gglClampx(c->current.color.a);
+}
+
+void glColor4x(GLfixed r, GLfixed g, GLfixed b, GLfixed a)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->current.color.r = r;
+    c->current.color.g = g;
+    c->current.color.b = b;
+    c->current.color.a = a;
+    c->currentColorClamped.r = gglClampx(r);
+    c->currentColorClamped.g = gglClampx(g);
+    c->currentColorClamped.b = gglClampx(b);
+    c->currentColorClamped.a = gglClampx(a);
+}
+
+void glNormal3f(GLfloat x, GLfloat y, GLfloat z)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->currentNormal.x = gglFloatToFixed(x);
+    c->currentNormal.y = gglFloatToFixed(y);
+    c->currentNormal.z = gglFloatToFixed(z);
+}
+
+void glNormal3x(GLfixed x, GLfixed y, GLfixed z)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    c->currentNormal.x = x;
+    c->currentNormal.y = y;
+    c->currentNormal.z = z;
+}
+
+// ----------------------------------------------------------------------------
+
+void glClipPlanef(GLenum plane, const GLfloat* equ)
+{
+    const GLfixed equx[4] = {
+            gglFloatToFixed(equ[0]),
+            gglFloatToFixed(equ[1]),
+            gglFloatToFixed(equ[2]),
+            gglFloatToFixed(equ[3])
+    };
+    ogles_context_t* c = ogles_context_t::get();
+    clipPlanex(plane, equx, c);
+}
+
+void glClipPlanex(GLenum plane, const GLfixed* equ)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    clipPlanex(plane, equ, c);
+}
diff --git a/opengl/libagl/vertex.h b/opengl/libagl/vertex.h
new file mode 100644
index 0000000..55e6213
--- /dev/null
+++ b/opengl/libagl/vertex.h
@@ -0,0 +1,48 @@
+/* libs/opengles/vertex.h
+**
+** 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 
+**
+**     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_VERTEX_H
+#define ANDROID_OPENGLES_VERTEX_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+
+namespace android {
+
+namespace gl {
+struct vertex_t;
+struct ogles_context_t;
+};
+
+void ogles_init_vertex(ogles_context_t* c);
+void ogles_uninit_vertex(ogles_context_t* c);
+
+void ogles_vertex_perspective2D(ogles_context_t*, vertex_t*);
+
+void ogles_vertex_perspective3D(ogles_context_t*, vertex_t*);
+void ogles_vertex_perspective3DZ(ogles_context_t*, vertex_t*);
+void ogles_vertex_clipAllPerspective3D(ogles_context_t*, vertex_t*);
+void ogles_vertex_clipAllPerspective3DZ(ogles_context_t*, vertex_t*);
+
+
+void ogles_vertex_project(ogles_context_t* c, vertex_t*);
+
+}; // namespace android
+
+#endif // ANDROID_OPENGLES_VERTEX_H
+
