diff --git a/opengl/libagl/array.cpp b/opengl/libagl/array.cpp
new file mode 100644
index 0000000..8fa7566
--- /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 || (enables & GGL_ENABLE_FOG)) { 
+        want |= transform_state_t::MODELVIEW; // needs eye coords
+    }
+    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);
+}
