/* 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 <ETC1/etc1.h>

#include <ui/GraphicBufferMapper.h>
#include <ui/Rect.h>

namespace android {

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

static void bindTextureTmu(
    ogles_context_t* c, int tmu, GLuint texture, const sp<EGLTextureObject>& tex);

static __attribute__((noinline))
void generateMipmap(ogles_context_t* c, GLint level);

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

#if 0
#pragma mark -
#pragma mark Init
#endif

void ogles_init_texture(ogles_context_t* c)
{
    c->textures.packAlignment   = 4;
    c->textures.unpackAlignment = 4;

    // each context has a default named (0) texture (not shared)
    c->textures.defaultTexture = new EGLTextureObject();
    c->textures.defaultTexture->incStrong(c);

    // bind the default texture to each texture unit
    for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
        bindTextureTmu(c, i, 0, c->textures.defaultTexture);
        memset(c->current.texture[i].v, 0, sizeof(vec4_t));
        c->current.texture[i].Q = 0x10000;
    }
}

void ogles_uninit_texture(ogles_context_t* c)
{
    if (c->textures.ggl)
        gglUninit(c->textures.ggl);
    c->textures.defaultTexture->decStrong(c);
    for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
        if (c->textures.tmu[i].texture)
            c->textures.tmu[i].texture->decStrong(c);
    }
}

static __attribute__((noinline))
void validate_tmu(ogles_context_t* c, int i)
{
    texture_unit_t& u(c->textures.tmu[i]);
    if (u.dirty) {
        u.dirty = 0;
        c->rasterizer.procs.activeTexture(c, i);
        c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
        c->rasterizer.procs.texGeni(c, GGL_S,
                GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC);
        c->rasterizer.procs.texGeni(c, GGL_T,
                GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC);
        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
                GGL_TEXTURE_WRAP_S, u.texture->wraps);
        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
                GGL_TEXTURE_WRAP_T, u.texture->wrapt);
        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
                GGL_TEXTURE_MIN_FILTER, u.texture->min_filter);
        c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
                GGL_TEXTURE_MAG_FILTER, u.texture->mag_filter);

        // disable this texture unit if it's not complete
        if (!u.texture->isComplete()) {
            c->rasterizer.procs.disable(c, GGL_TEXTURE_2D);
        }
    }
}

void ogles_validate_texture(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]);
            ANativeWindowBuffer* native_buffer = u.texture->buffer;
            if (native_buffer) {
                c->rasterizer.procs.activeTexture(c, i);

                auto& mapper = GraphicBufferMapper::get();
                void* vaddr;
                mapper.lock(native_buffer->handle, GRALLOC_USAGE_SW_READ_OFTEN,
                        Rect(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]);
            ANativeWindowBuffer* native_buffer = u.texture->buffer;
            if (native_buffer) {
                c->rasterizer.procs.activeTexture(c, i);

                auto& mapper = GraphicBufferMapper::get();
                mapper.unlock(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)
{
    // 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 GLsizei 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, GGLfixed 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>=0x10000)    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 && target != GL_TEXTURE_EXTERNAL_OES) {
        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)
{
    // quickly reject empty rects
    if ((w|h) <= 0)
        return;

    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)) {
        const int tmu = 0;
        texture_unit_t& u(c->textures.tmu[tmu]);
        EGLTextureObject* textureObject = u.texture;
        const GLint Wcr = textureObject->crop_rect[2];
        const GLint Hcr = textureObject->crop_rect[3];

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

            if (u.dirty) {
                c->rasterizer.procs.activeTexture(c, tmu);
                c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
                c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
                        GGL_TEXTURE_MIN_FILTER, u.texture->min_filter);
                c->rasterizer.procs.texParameteri(c, GGL_TEXTURE_2D,
                        GGL_TEXTURE_MAG_FILTER, u.texture->mag_filter);
            }
            c->rasterizer.procs.texGeni(c, GGL_S,
                    GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
            c->rasterizer.procs.texGeni(c, GGL_T,
                    GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
            u.dirty = 0xFF; // XXX: should be more subtle
            c->rasterizer.procs.activeTexture(c, c->textures.active);

            const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
            y = cbSurface.height - (y + h);
            const GLint Ucr = textureObject->crop_rect[0];
            const GLint Vcr = textureObject->crop_rect[1];
            const GLint s0  = Ucr - x;
            const GLint t0  = (Vcr + Hcr) - y;

            const GLuint tw = textureObject->surface.width;
            const GLuint th = textureObject->surface.height;
            if ((uint32_t(s0+x+w) > tw) || (uint32_t(t0+y+h) > th)) {
                // The GL spec is unclear about what should happen
                // in this case, so we just use the slow case, which
                // at least won't crash
                goto slow_case;
            }

            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, gglIntToFixed(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 && target != GL_TEXTURE_EXTERNAL_OES) {
        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 != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) {
        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 (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;
#ifdef GL_OES_compressed_ETC1_RGB8_texture
    case GL_ETC1_RGB8_OES:
        format      = GL_RGB;
        type        = GL_UNSIGNED_BYTE;
        break;
#endif
    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;

#ifdef GL_OES_compressed_ETC1_RGB8_texture
    if (internalformat == GL_ETC1_RGB8_OES) {
        GLsizei compressedSize = etc1_get_encoded_data_size(width, height);
        if (compressedSize > imageSize) {
            ogles_error(c, GL_INVALID_VALUE);
            return;
        }
        int error = createTextureSurface(c, &surface, &size,
                level, format, type, width, height);
        if (error) {
            ogles_error(c, error);
            return;
        }
        if (etc1_decode_image(
                (const etc1_byte*)data,
                (etc1_byte*)surface->data,
                width, height, 3, surface->stride*3) != 0) {
            ogles_error(c, GL_INVALID_OPERATION);
        }
        return;
    }
#endif

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

    /* The GLES spec says:
     * If any of the pixels within the specified rectangle are outside
     * the framebuffer associated with the current rendering context,
     * then the values obtained for those pixels are undefined.
     */
    if (x+width > GLint(cbSurface.width))
        width = cbSurface.width - x;

    if (y+height > GLint(cbSurface.height))
        height = cbSurface.height - y;

    int err = copyPixels(c,
            txSurface, 0, 0,
            cbSurface, x, y, width, 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);

    /* The GLES spec says:
     * If any of the pixels within the specified rectangle are outside
     * the framebuffer associated with the current rendering context,
     * then the values obtained for those pixels are undefined.
     */
    if (x+width > GLint(cbSurface.width))
        width = cbSurface.width - x;

    if (y+height > GLint(cbSurface.height))
        height = cbSurface.height - y;

    int err = copyPixels(c,
            txSurface, 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 || y<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 && target != GL_TEXTURE_EXTERNAL_OES) {
        ogles_error(c, GL_INVALID_ENUM);
        return;
    }

    if (image == EGL_NO_IMAGE_KHR) {
        ogles_error(c, GL_INVALID_VALUE);
        return;
    }

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

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

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

    if (image == EGL_NO_IMAGE_KHR) {
        ogles_error(c, GL_INVALID_VALUE);
        return;
    }

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

    // well, we're not supporting this extension anyways
}
