diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp
new file mode 100644
index 0000000..b6f534b
--- /dev/null
+++ b/opengl/libagl/texture.cpp
@@ -0,0 +1,1421 @@
+/* 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 != GL_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_REPEAT) ||
+            (param == GL_CLAMP_TO_EDGE)) {
+            textureObject->wraps = param;
+        } else {
+            goto invalid_enum;
+        }
+        break;
+    case GL_TEXTURE_WRAP_T:
+        if ((param == GL_REPEAT) ||
+            (param == GL_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, GLint 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);
+}
