/* 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 size_t dataSizePalette4(int numLevels, int width, int height, 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;
    }

    size_t size = (1 << indexBits) * entrySize; // palette size

    for (int i=0 ; i< numLevels ; i++) {
        int w = (width  >> i) ? : 1;
        int h = (height >> i) ? : 1;
        int levelSize = h * ((w * indexBits) / 8) ? : 1;
        size += levelSize;
    }

    return size;
}

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;

    if (dataSizePalette4(numLevels, width, height, format) > imageSize) {
        ogles_error(c, GL_INVALID_VALUE);
        return;
    }

    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 (format != 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;
    }
    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)
{
}
