/* 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"

#include <private/ui/android_natives_priv.h>

#ifdef LIBAGL_USE_GRALLOC_COPYBITS
#include "copybit.h"
#endif // LIBAGL_USE_GRALLOC_COPYBITS

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(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 the active textures are EGLImage, they need to be locked before
 * they can be used. 
 * 
 * FIXME: code below is far from being optimal
 * 
 */

void ogles_lock_textures(ogles_context_t* c)
{
    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
        if (c->rasterizer.state.texture[i].enable) {
            texture_unit_t& u(c->textures.tmu[i]);
            android_native_buffer_t* native_buffer = u.texture->buffer;
            if (native_buffer) {
                c->rasterizer.procs.activeTexture(c, i);
                hw_module_t const* pModule;
                if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule))
                    continue;

                gralloc_module_t const* module =
                    reinterpret_cast<gralloc_module_t const*>(pModule);

                void* vaddr;
                int err = module->lock(module, native_buffer->handle,
                        GRALLOC_USAGE_SW_READ_OFTEN,
                        0, 0, native_buffer->width, native_buffer->height,
                        &vaddr);

                u.texture->setImageBits(vaddr);
                c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
            }
        }
    }
}

void ogles_unlock_textures(ogles_context_t* c)
{
    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
        if (c->rasterizer.state.texture[i].enable) {
            texture_unit_t& u(c->textures.tmu[i]);
            android_native_buffer_t* native_buffer = u.texture->buffer;
            if (native_buffer) {
                c->rasterizer.procs.activeTexture(c, i);
                hw_module_t const* pModule;
                if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule))
                    continue;

                gralloc_module_t const* module =
                    reinterpret_cast<gralloc_module_t const*>(pModule);

                module->unlock(module, native_buffer->handle);
                u.texture->setImageBits(NULL);
                c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
            }
        }
    }
    c->rasterizer.procs.activeTexture(c, c->textures.active);
}

// ----------------------------------------------------------------------------
#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 drawTexxOESImp(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h,
        ogles_context_t* c)
{
    ogles_lock_textures(c);
    
    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);

    ogles_unlock_textures(c);
}

static void drawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h,
        ogles_context_t* c)
{
#ifdef LIBAGL_USE_GRALLOC_COPYBITS
    if (drawTexiOESWithCopybit(gglFixedToIntRound(x),
            gglFixedToIntRound(y), gglFixedToIntRound(z),
            gglFixedToIntRound(w), gglFixedToIntRound(h), c)) {
        return;
    }
#else
    // quickly reject empty rects
    if ((w|h) <= 0)
        return;
#endif
    drawTexxOESImp(x, y, z, w, h, c);
}

static void drawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h, ogles_context_t* c)
{
    // All coordinates are integer, so if we have only one
    // 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)) {
#ifdef LIBAGL_USE_GRALLOC_COPYBITS
        if (drawTexiOESWithCopybit(x, y, z, w, h, c)) {
            return;
        }
#endif
        const int tmu = 0;
        texture_unit_t& u(c->textures.tmu[tmu]);
        EGLTextureObject* textureObject = u.texture;
        const GLint Wcr = textureObject->crop_rect[2];
        const GLint Hcr = textureObject->crop_rect[3];

        if ((w == Wcr) && (h == -Hcr)) {
#ifndef LIBAGL_USE_GRALLOC_COPYBITS
            if ((w|h) <= 0) return; // quickly reject empty rects
#endif

            if (u.dirty) {
                c->rasterizer.procs.activeTexture(c, tmu);
                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;
            }

            ogles_lock_textures(c);

            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);
            
            ogles_unlock_textures(c);

            return;
        }
    }

slow_case:
    drawTexxOESImp(
            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:
        texParameterx(target, pname, GLfixed(params[0]), c);
        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);
}

void glTexParameteri(
        GLenum target, GLenum pname, GLint param)
{
    ogles_context_t* c = ogles_context_t::get();
    texParameterx(target, pname, GLfixed(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) {
        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 != (GLenum)internalformat) {
        ogles_error(c, GL_INVALID_OPERATION);
        return;
    }
    if (validFormatType(c, format, type)) {
        return;
    }

    int32_t size = 0;
    GGLSurface* surface = 0;
    int error = createTextureSurface(c, &surface, &size,
            level, format, type, width, height);
    if (error) {
        ogles_error(c, error);
        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;

        int err = copyPixels(c, *surface, 0, 0, userSurface, 0, 0, width, height);
        if (err) {
            ogles_error(c, err);
            return;
        }
        generateMipmap(c, level);
    }
}

// ----------------------------------------------------------------------------

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

// ----------------------------------------------------------------------------
#if 0
#pragma mark -
#pragma mark EGL Image Extension
#endif

void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
{
    ogles_context_t* c = ogles_context_t::get();
    if (target != GL_TEXTURE_2D) {
        ogles_error(c, GL_INVALID_ENUM);
        return;
    }

    android_native_buffer_t* native_buffer = (android_native_buffer_t*)image;
    if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
        ogles_error(c, GL_INVALID_VALUE);
        return;
    }
    if (native_buffer->common.version != sizeof(android_native_buffer_t)) {
        ogles_error(c, GL_INVALID_VALUE);
        return;
    }

    // bind it to the texture unit
    sp<EGLTextureObject> tex = getAndBindActiveTextureObject(c);
    tex->setImage(native_buffer);

#ifdef LIBAGL_USE_GRALLOC_COPYBITS
    tex->try_copybit = false;
    if (c->copybits.blitEngine != NULL) {
        tex->try_copybit = true;
    }
#endif // LIBAGL_USE_GRALLOC_COPYBITS
}

void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
{
}
