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);
+}
