/* libs/opengles/matrix.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 <stdlib.h>
#include <stdio.h>

#include "context.h"
#include "fp.h"
#include "state.h"
#include "matrix.h"
#include "vertex.h"
#include "light.h"

#if defined(__arm__) && defined(__thumb__)
#warning "matrix.cpp should not be compiled in thumb on ARM."
#endif

#define I(_i, _j) ((_j)+ 4*(_i))

namespace android {

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

static const GLfloat gIdentityf[16] = { 1,0,0,0,
                                        0,1,0,0,
                                        0,0,1,0,
                                        0,0,0,1 };

static const matrixx_t gIdentityx = { 
            {   0x10000,0,0,0,
                0,0x10000,0,0,
                0,0,0x10000,0,
                0,0,0,0x10000
            }
        };

static void point2__nop(transform_t const*, vec4_t* c, vec4_t const* o);
static void point3__nop(transform_t const*, vec4_t* c, vec4_t const* o);
static void point4__nop(transform_t const*, vec4_t* c, vec4_t const* o);
static void normal__nop(transform_t const*, vec4_t* c, vec4_t const* o);
static void point2__generic(transform_t const*, vec4_t* c, vec4_t const* o);
static void point3__generic(transform_t const*, vec4_t* c, vec4_t const* o);
static void point4__generic(transform_t const*, vec4_t* c, vec4_t const* o);
static void normal__generic(transform_t const*, vec4_t* c, vec4_t const* o);

// ----------------------------------------------------------------------------
#if 0
#pragma mark -
#endif

void ogles_init_matrix(ogles_context_t* c)
{
    c->transforms.modelview.init(OGLES_MODELVIEW_STACK_DEPTH);
    c->transforms.projection.init(OGLES_PROJECTION_STACK_DEPTH);
    for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++)
        c->transforms.texture[i].init(OGLES_TEXTURE_STACK_DEPTH);

    c->transforms.current = &c->transforms.modelview;
    c->transforms.matrixMode = GL_MODELVIEW;
    c->transforms.dirty =   transform_state_t::VIEWPORT | 
                            transform_state_t::MVUI |
                            transform_state_t::MVIT |
                            transform_state_t::MVP;
    c->transforms.mvp.loadIdentity();
    c->transforms.mvp4.loadIdentity();
    c->transforms.mvit4.loadIdentity();
    c->transforms.mvui.loadIdentity();
    c->transforms.vpt.loadIdentity();
    c->transforms.vpt.zNear = 0.0f;
    c->transforms.vpt.zFar  = 1.0f;
}

void ogles_uninit_matrix(ogles_context_t* c)
{
    c->transforms.modelview.uninit();
    c->transforms.projection.uninit();
    for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++)
        c->transforms.texture[i].uninit();
}

static void validate_perspective(ogles_context_t* c, vertex_t* v)
{
    const uint32_t enables = c->rasterizer.state.enables;
    c->arrays.perspective = (c->clipPlanes.enable) ?
        ogles_vertex_clipAllPerspective3D : ogles_vertex_perspective3D;
    if (enables & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)) {
        c->arrays.perspective = (c->clipPlanes.enable) ?
            ogles_vertex_clipAllPerspective3DZ : ogles_vertex_perspective3DZ;
    }
    if ((c->arrays.vertex.size != 4) &&
        (c->transforms.mvp4.flags & transform_t::FLAGS_2D_PROJECTION)) {
        c->arrays.perspective = ogles_vertex_perspective2D;
    }
    c->arrays.perspective(c, v);
}

void ogles_invalidate_perspective(ogles_context_t* c)
{
    c->arrays.perspective = validate_perspective;
}

void ogles_validate_transform_impl(ogles_context_t* c, uint32_t want)
{
    int dirty = c->transforms.dirty & want;

    // Validate the modelview
    if (dirty & transform_state_t::MODELVIEW) {
        c->transforms.modelview.validate();
    }

    // Validate the projection stack (in fact, it's never needed)
    if (dirty & transform_state_t::PROJECTION) {
        c->transforms.projection.validate();
    }

    // Validate the viewport transformation
    if (dirty & transform_state_t::VIEWPORT) {
        vp_transform_t& vpt = c->transforms.vpt;
        vpt.transform.matrix.load(vpt.matrix);
        vpt.transform.picker();
    }

    // We need to update the mvp (used to transform each vertex)
    if (dirty & transform_state_t::MVP) {
        c->transforms.update_mvp();
        // invalidate perspective (divide by W) and view volume clipping
        ogles_invalidate_perspective(c);
    }

    // Validate the mvui (for normal transformation)
    if (dirty & transform_state_t::MVUI) {
        c->transforms.update_mvui();
        ogles_invalidate_lighting_mvui(c);
    }

    // Validate the texture stack
    if (dirty & transform_state_t::TEXTURE) {
        for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++)
            c->transforms.texture[i].validate();
    }

    // Validate the mvit4 (user-clip planes)
    if (dirty & transform_state_t::MVIT) {
        c->transforms.update_mvit();
    }

    c->transforms.dirty &= ~want;
}

// ----------------------------------------------------------------------------
#if 0
#pragma mark -
#pragma mark transform_t
#endif

void transform_t::loadIdentity() {
    matrix = gIdentityx;
    flags = 0;
    ops = OP_IDENTITY;
    point2 = point2__nop;
    point3 = point3__nop;
    point4 = point4__nop;
}


static inline
int notZero(GLfixed v) {
    return abs(v) & ~0x3;
}

static inline
int notOne(GLfixed v) {
    return notZero(v - 0x10000);
}

void transform_t::picker()
{
    const GLfixed* const m = matrix.m;

    // XXX: picker needs to be smarter
    flags = 0;
    ops = OP_ALL;
    point2 = point2__generic;
    point3 = point3__generic;
    point4 = point4__generic;
    
    // find out if this is a 2D projection
    if (!(notZero(m[3]) | notZero(m[7]) | notZero(m[11]) | notOne(m[15]))) {
        flags |= FLAGS_2D_PROJECTION;
    }
}

void mvui_transform_t::picker()
{
    flags = 0;
    ops = OP_ALL;
    point3 = normal__generic;
}

void transform_t::dump(const char* what)
{
    GLfixed const * const m = matrix.m;
    LOGD("%s:", what);
    for (int i=0 ; i<4 ; i++)
        LOGD("[%08x %08x %08x %08x] [%f %f %f %f]\n",
            m[I(0,i)], m[I(1,i)], m[I(2,i)], m[I(3,i)],
            fixedToFloat(m[I(0,i)]),
            fixedToFloat(m[I(1,i)]), 
            fixedToFloat(m[I(2,i)]),
            fixedToFloat(m[I(3,i)]));
}

// ----------------------------------------------------------------------------
#if 0
#pragma mark -
#pragma mark matrixx_t
#endif

void matrixx_t::load(const matrixf_t& rhs) {
    GLfixed* xp = m;
    GLfloat const* fp = rhs.elements();
    unsigned int i = 16;
    do {
        const GLfloat f = *fp++;
        *xp++ = isZerof(f) ? 0 : gglFloatToFixed(f);
    } while (--i);
}

// ----------------------------------------------------------------------------
#if 0
#pragma mark -
#pragma mark matrixf_t
#endif

void matrixf_t::multiply(matrixf_t& r, const matrixf_t& lhs, const matrixf_t& rhs)
{
    GLfloat const* const m = lhs.m;
    for (int i=0 ; i<4 ; i++) {
        register const float rhs_i0 = rhs.m[ I(i,0) ];
        register float ri0 = m[ I(0,0) ] * rhs_i0;
        register float ri1 = m[ I(0,1) ] * rhs_i0;
        register float ri2 = m[ I(0,2) ] * rhs_i0;
        register float ri3 = m[ I(0,3) ] * rhs_i0;
        for (int j=1 ; j<4 ; j++) {
            register const float rhs_ij = rhs.m[ I(i,j) ];
            ri0 += m[ I(j,0) ] * rhs_ij;
            ri1 += m[ I(j,1) ] * rhs_ij;
            ri2 += m[ I(j,2) ] * rhs_ij;
            ri3 += m[ I(j,3) ] * rhs_ij;
        }
        r.m[ I(i,0) ] = ri0;
        r.m[ I(i,1) ] = ri1;
        r.m[ I(i,2) ] = ri2;
        r.m[ I(i,3) ] = ri3;
    }
}

void matrixf_t::dump(const char* what) {
    LOGD("%s", what);
    LOGD("[ %9f %9f %9f %9f ]", m[I(0,0)], m[I(1,0)], m[I(2,0)], m[I(3,0)]);
    LOGD("[ %9f %9f %9f %9f ]", m[I(0,1)], m[I(1,1)], m[I(2,1)], m[I(3,1)]);
    LOGD("[ %9f %9f %9f %9f ]", m[I(0,2)], m[I(1,2)], m[I(2,2)], m[I(3,2)]);
    LOGD("[ %9f %9f %9f %9f ]", m[I(0,3)], m[I(1,3)], m[I(2,3)], m[I(3,3)]);
}

void matrixf_t::loadIdentity() {
    memcpy(m, gIdentityf, sizeof(m));
}

void matrixf_t::set(const GLfixed* rhs) {
    load(rhs);
}

void matrixf_t::set(const GLfloat* rhs) {
    load(rhs);
}

void matrixf_t::load(const GLfixed* rhs) {
    GLfloat* fp = m;
    unsigned int i = 16;
    do {
        *fp++ = fixedToFloat(*rhs++);
    } while (--i);
}

void matrixf_t::load(const GLfloat* rhs) {
    memcpy(m, rhs, sizeof(m));
}

void matrixf_t::load(const matrixf_t& rhs) {
    operator = (rhs);
}

void matrixf_t::multiply(const matrixf_t& rhs) {
    matrixf_t r;
    multiply(r, *this, rhs);
    operator = (r);
}

void matrixf_t::translate(GLfloat x, GLfloat y, GLfloat z) {
    for (int i=0 ; i<4 ; i++) {
        m[12+i] += m[i]*x + m[4+i]*y + m[8+i]*z;
    }
}

void matrixf_t::scale(GLfloat x, GLfloat y, GLfloat z) {
    for (int i=0 ; i<4 ; i++) {
        m[  i] *= x;
        m[4+i] *= y;
        m[8+i] *= z;
    }
}

void matrixf_t::rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z)
{
    matrixf_t rotation;
    GLfloat* r = rotation.m;
    GLfloat c, s;
    r[3] = 0;   r[7] = 0;   r[11]= 0;
    r[12]= 0;   r[13]= 0;   r[14]= 0;   r[15]= 1;
    a *= GLfloat(M_PI / 180.0f);
    sincosf(a, &s, &c);
    if (isOnef(x) && isZerof(y) && isZerof(z)) {
        r[5] = c;   r[10]= c;
        r[6] = s;   r[9] = -s;
        r[1] = 0;   r[2] = 0;
        r[4] = 0;   r[8] = 0;
        r[0] = 1;
    } else if (isZerof(x) && isOnef(y) && isZerof(z)) {
        r[0] = c;   r[10]= c;
        r[8] = s;   r[2] = -s;
        r[1] = 0;   r[4] = 0;
        r[6] = 0;   r[9] = 0;
        r[5] = 1;
    } else if (isZerof(x) && isZerof(y) && isOnef(z)) {
        r[0] = c;   r[5] = c;
        r[1] = s;   r[4] = -s;
        r[2] = 0;   r[6] = 0;
        r[8] = 0;   r[9] = 0;
        r[10]= 1;
    } else {
        const GLfloat len = sqrtf(x*x + y*y + z*z);
        if (!isOnef(len)) {
            const GLfloat recipLen = reciprocalf(len);
            x *= recipLen;
            y *= recipLen;
            z *= recipLen;
        }
        const GLfloat nc = 1.0f - c;
        const GLfloat xy = x * y;
        const GLfloat yz = y * z;
        const GLfloat zx = z * x;
        const GLfloat xs = x * s;
        const GLfloat ys = y * s;
        const GLfloat zs = z * s;		
        r[ 0] = x*x*nc +  c;    r[ 4] =  xy*nc - zs;    r[ 8] =  zx*nc + ys;
        r[ 1] =  xy*nc + zs;    r[ 5] = y*y*nc +  c;    r[ 9] =  yz*nc - xs;
        r[ 2] =  zx*nc - ys;    r[ 6] =  yz*nc + xs;    r[10] = z*z*nc +  c;
    }
    multiply(rotation);
}

// ----------------------------------------------------------------------------
#if 0
#pragma mark -
#pragma mark matrix_stack_t
#endif

void matrix_stack_t::init(int depth) {
    stack = new matrixf_t[depth];
    ops = new uint8_t[depth];
    maxDepth = depth;
    depth = 0;
    dirty = 0;
    loadIdentity();
}

void matrix_stack_t::uninit() {
    delete [] stack;
    delete [] ops;
}

void matrix_stack_t::loadIdentity() {
    transform.loadIdentity();
    stack[depth].loadIdentity();
    ops[depth] = OP_IDENTITY;
}

void matrix_stack_t::load(const GLfixed* rhs)
{   
    memcpy(transform.matrix.m, rhs, sizeof(transform.matrix.m));
    stack[depth].load(rhs);
    ops[depth] = OP_ALL;    // TODO: we should look at the matrix
}

void matrix_stack_t::load(const GLfloat* rhs)
{
    stack[depth].load(rhs);
    ops[depth] = OP_ALL;    // TODO: we should look at the matrix
}

void matrix_stack_t::multiply(const matrixf_t& rhs)
{    
    stack[depth].multiply(rhs);
    ops[depth] = OP_ALL;    // TODO: we should look at the matrix
}

void matrix_stack_t::translate(GLfloat x, GLfloat y, GLfloat z)
{
    stack[depth].translate(x,y,z);
    ops[depth] |= OP_TRANSLATE;
}

void matrix_stack_t::scale(GLfloat x, GLfloat y, GLfloat z)
{
    stack[depth].scale(x,y,z);
    if (x==y && y==z) {
        ops[depth] |= OP_UNIFORM_SCALE;
    } else {
        ops[depth] |= OP_SCALE;
    }
}

void matrix_stack_t::rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z)
{
    stack[depth].rotate(a,x,y,z);
    ops[depth] |= OP_ROTATE;
}

void matrix_stack_t::validate()
{
    if (dirty & DO_FLOAT_TO_FIXED) {
        transform.matrix.load(top());
    }
    if (dirty & DO_PICKER) {
        transform.picker();
    }
    dirty = 0;
}

GLint matrix_stack_t::push()
{
    if (depth >= (maxDepth-1)) {
        return GL_STACK_OVERFLOW;
    }
    stack[depth+1] = stack[depth];
    ops[depth+1] = ops[depth];
    depth++;
    return 0;
}

GLint matrix_stack_t::pop()
{
    if (depth == 0) {
        return GL_STACK_UNDERFLOW;
    }
    depth--;
    return 0;
}

// ----------------------------------------------------------------------------
#if 0
#pragma mark -
#pragma mark vp_transform_t
#endif

void vp_transform_t::loadIdentity() {
    transform.loadIdentity();
    matrix.loadIdentity();
}

// ----------------------------------------------------------------------------
#if 0
#pragma mark -
#pragma mark transform_state_t
#endif

void transform_state_t::invalidate()
{
    switch (matrixMode) {
    case GL_MODELVIEW:  dirty |= MODELVIEW  | MVP | MVUI | MVIT;    break;
    case GL_PROJECTION: dirty |= PROJECTION | MVP;                  break;
    case GL_TEXTURE:    dirty |= TEXTURE    | MVP;                  break;
    }
    current->dirty =    matrix_stack_t::DO_PICKER |
                        matrix_stack_t::DO_FLOAT_TO_FIXED;
}

void transform_state_t::update_mvp()
{
    matrixf_t temp_mvp;
    matrixf_t::multiply(temp_mvp, projection.top(), modelview.top());
    mvp4.matrix.load(temp_mvp);
    mvp4.picker();

    if (mvp4.flags & transform_t::FLAGS_2D_PROJECTION) {
        // the mvp matrix doesn't transform W, in this case we can
        // premultiply it with the viewport transformation. In addition to
        // being more efficient, this is also much more accurate and in fact
        // is needed for 2D drawing with a resulting 1:1 mapping.
        matrixf_t mvpv;
        matrixf_t::multiply(mvpv, vpt.matrix, temp_mvp);
        mvp.matrix.load(mvpv);
        mvp.picker();
    } else {
        mvp = mvp4;
    }
}

static inline 
GLfloat det22(GLfloat a, GLfloat b, GLfloat c, GLfloat d) {
    return a*d - b*c;
}

static inline
GLfloat ndet22(GLfloat a, GLfloat b, GLfloat c, GLfloat d) {
    return b*c - a*d;
}

static __attribute__((noinline))
void invert(GLfloat* inverse, const GLfloat* src)
{
    double t;
    int i, j, k, swap;
    GLfloat tmp[4][4];
    
    memcpy(inverse, gIdentityf, sizeof(gIdentityf));
    memcpy(tmp, src, sizeof(GLfloat)*16);
    
    for (i = 0; i < 4; i++) {
        // look for largest element in column
        swap = i;
        for (j = i + 1; j < 4; j++) {
            if (fabs(tmp[j][i]) > fabs(tmp[i][i])) {
                swap = j;
            }
        }
        
        if (swap != i) {
            /* swap rows. */
            for (k = 0; k < 4; k++) {
                t = tmp[i][k];
                tmp[i][k] = tmp[swap][k];
                tmp[swap][k] = t;
                
                t = inverse[i*4+k];
                inverse[i*4+k] = inverse[swap*4+k];
                inverse[swap*4+k] = t;
            }
        }
        
        t = 1.0f / tmp[i][i];
        for (k = 0; k < 4; k++) {
            tmp[i][k] *= t;
            inverse[i*4+k] *= t;
        }
        for (j = 0; j < 4; j++) {
            if (j != i) {
                t = tmp[j][i];
                for (k = 0; k < 4; k++) {
                    tmp[j][k] -= tmp[i][k]*t;
                    inverse[j*4+k] -= inverse[i*4+k]*t;
                }
            }
        }
    }
}

void transform_state_t::update_mvit()
{
    GLfloat r[16];
    const GLfloat* const mv = modelview.top().elements();
    invert(r, mv);
    // convert to fixed-point and transpose
    GLfixed* const x = mvit4.matrix.m;
    for (int i=0 ; i<4 ; i++)
        for (int j=0 ; j<4 ; j++)
            x[I(i,j)] = gglFloatToFixed(r[I(j,i)]);
    mvit4.picker();
}

void transform_state_t::update_mvui()
{
    const GLfloat* const mv = modelview.top().elements();

    /*
    When transforming normals, we can use the upper 3x3 matrix, see:
    http://www.opengl.org/documentation/specs/version1.1/glspec1.1/node26.html
    */
    
    // Also note that:
    //      l(obj) =  tr(M).l(eye) for infinite light
    //      l(obj) = inv(M).l(eye) for local light

    const uint32_t ops = modelview.top_ops() & ~OP_TRANSLATE;
    if (ggl_likely((!(ops & ~OP_ROTATE)) ||
        (rescaleNormals && modelview.isRigidBody()))) {
        // if the modelview matrix is a rigid body transformation
        // (translation, rotation, uniform scaling), then we can bypass
        // the inverse by transposing the matrix.
        GLfloat rescale = 1.0f;
        if (rescaleNormals == GL_RESCALE_NORMAL) {
            if (!(ops & ~OP_UNIFORM_SCALE)) {
                rescale = reciprocalf(mv[I(0,0)]);
            } else {
                rescale = rsqrtf(
                        sqrf(mv[I(2,0)]) + sqrf(mv[I(2,1)]) + sqrf(mv[I(2,2)]));
            }
        }
        GLfixed* const x = mvui.matrix.m;
        for (int i=0 ; i<3 ; i++) {
            x[I(i,0)] = gglFloatToFixed(mv[I(0,i)] * rescale);
            x[I(i,1)] = gglFloatToFixed(mv[I(1,i)] * rescale);
            x[I(i,2)] = gglFloatToFixed(mv[I(2,i)] * rescale);
        }
        mvui.picker();
        return;
    }

    GLfloat r[3][3];
    r[0][0] = det22(mv[I(1,1)], mv[I(2,1)], mv[I(1,2)], mv[I(2,2)]);
    r[0][1] =ndet22(mv[I(0,1)], mv[I(2,1)], mv[I(0,2)], mv[I(2,2)]);
    r[0][2] = det22(mv[I(0,1)], mv[I(1,1)], mv[I(0,2)], mv[I(1,2)]);
    r[1][0] =ndet22(mv[I(1,0)], mv[I(2,0)], mv[I(1,2)], mv[I(2,2)]);
    r[1][1] = det22(mv[I(0,0)], mv[I(2,0)], mv[I(0,2)], mv[I(2,2)]);
    r[1][2] =ndet22(mv[I(0,0)], mv[I(1,0)], mv[I(0,2)], mv[I(1,2)]);
    r[2][0] = det22(mv[I(1,0)], mv[I(2,0)], mv[I(1,1)], mv[I(2,1)]);
    r[2][1] =ndet22(mv[I(0,0)], mv[I(2,0)], mv[I(0,1)], mv[I(2,1)]);
    r[2][2] = det22(mv[I(0,0)], mv[I(1,0)], mv[I(0,1)], mv[I(1,1)]);        

    GLfloat rdet;
    if (rescaleNormals == GL_RESCALE_NORMAL) {
        rdet = rsqrtf(sqrf(r[0][2]) + sqrf(r[1][2]) + sqrf(r[2][2]));
    } else {
        rdet = reciprocalf( 
            r[0][0]*mv[I(0,0)] + r[0][1]*mv[I(1,0)] + r[0][2]*mv[I(2,0)]);
    }

    GLfixed* const x = mvui.matrix.m;
    for (int i=0 ; i<3 ; i++) {
        x[I(i,0)] = gglFloatToFixed(r[i][0] * rdet);
        x[I(i,1)] = gglFloatToFixed(r[i][1] * rdet);
        x[I(i,2)] = gglFloatToFixed(r[i][2] * rdet);
    }
    mvui.picker();
}


// ----------------------------------------------------------------------------
// transformation and matrices API
// ----------------------------------------------------------------------------
#if 0
#pragma mark -
#pragma mark transformation and matrices API
#endif

int ogles_surfaceport(ogles_context_t* c, GLint x, GLint y)
{
    c->viewport.surfaceport.x = x;
    c->viewport.surfaceport.y = y;

    ogles_viewport(c, 
            c->viewport.x,
            c->viewport.y,
            c->viewport.w,
            c->viewport.h);

    ogles_scissor(c,
            c->viewport.scissor.x,
            c->viewport.scissor.y,
            c->viewport.scissor.w,
            c->viewport.scissor.h);

    return 0;
}

void ogles_scissor(ogles_context_t* c, 
        GLint x, GLint y, GLsizei w, GLsizei h)
{
    if ((w|h) < 0) {
        ogles_error(c, GL_INVALID_VALUE);
        return;
    }
    c->viewport.scissor.x = x;
    c->viewport.scissor.y = y;
    c->viewport.scissor.w = w;
    c->viewport.scissor.h = h;
    
    x += c->viewport.surfaceport.x;
    y += c->viewport.surfaceport.y;

    y = c->rasterizer.state.buffers.color.height - (y + h);
    c->rasterizer.procs.scissor(c, x, y, w, h);
}

void ogles_viewport(ogles_context_t* c,
        GLint x, GLint y, GLsizei w, GLsizei h)
{
    if ((w|h)<0) {
        ogles_error(c, GL_INVALID_VALUE);
        return;
    }

    c->viewport.x = x;
    c->viewport.y = y;
    c->viewport.w = w;
    c->viewport.h = h;

    x += c->viewport.surfaceport.x;
    y += c->viewport.surfaceport.y;

    GLint H = c->rasterizer.state.buffers.color.height;
    GLfloat sx = div2f(w);
    GLfloat ox = sx + x;
    GLfloat sy = div2f(h);
    GLfloat oy = sy - y + (H - h);

    GLfloat near = c->transforms.vpt.zNear;
    GLfloat far  = c->transforms.vpt.zFar;
    GLfloat A = div2f(far - near);
    GLfloat B = div2f(far + near);

    // compute viewport matrix
    GLfloat* const f = c->transforms.vpt.matrix.editElements();
    f[0] = sx;  f[4] = 0;   f[ 8] = 0;  f[12] = ox;
    f[1] = 0;   f[5] =-sy;  f[ 9] = 0;  f[13] = oy;
    f[2] = 0;   f[6] = 0;   f[10] = A;  f[14] = B;
    f[3] = 0;   f[7] = 0;   f[11] = 0;  f[15] = 1;
    c->transforms.dirty |= transform_state_t::VIEWPORT;
}

// ----------------------------------------------------------------------------
#if 0
#pragma mark -
#pragma mark matrix * vertex
#endif

void point2__generic(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) {
    const GLfixed* const m = mx->matrix.m;
    const GLfixed rx = rhs->x;
    const GLfixed ry = rhs->y;
    lhs->x = mla2a(rx, m[ 0], ry, m[ 4], m[12]); 
    lhs->y = mla2a(rx, m[ 1], ry, m[ 5], m[13]);
    lhs->z = mla2a(rx, m[ 2], ry, m[ 6], m[14]);
    lhs->w = mla2a(rx, m[ 3], ry, m[ 7], m[15]);
}

void point3__generic(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) {
    const GLfixed* const m = mx->matrix.m;
    const GLfixed rx = rhs->x;
    const GLfixed ry = rhs->y;
    const GLfixed rz = rhs->z;
    lhs->x = mla3a(rx, m[ 0], ry, m[ 4], rz, m[ 8], m[12]); 
    lhs->y = mla3a(rx, m[ 1], ry, m[ 5], rz, m[ 9], m[13]);
    lhs->z = mla3a(rx, m[ 2], ry, m[ 6], rz, m[10], m[14]);
    lhs->w = mla3a(rx, m[ 3], ry, m[ 7], rz, m[11], m[15]);
}

void point4__generic(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) {
    const GLfixed* const m = mx->matrix.m;
    const GLfixed rx = rhs->x;
    const GLfixed ry = rhs->y;
    const GLfixed rz = rhs->z;
    const GLfixed rw = rhs->w;
    lhs->x = mla4(rx, m[ 0], ry, m[ 4], rz, m[ 8], rw, m[12]); 
    lhs->y = mla4(rx, m[ 1], ry, m[ 5], rz, m[ 9], rw, m[13]);
    lhs->z = mla4(rx, m[ 2], ry, m[ 6], rz, m[10], rw, m[14]);
    lhs->w = mla4(rx, m[ 3], ry, m[ 7], rz, m[11], rw, m[15]);
}

void normal__generic(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) {
    const GLfixed* const m = mx->matrix.m;
    const GLfixed rx = rhs->x;
    const GLfixed ry = rhs->y;
    const GLfixed rz = rhs->z;
    lhs->x = mla3(rx, m[ 0], ry, m[ 4], rz, m[ 8]); 
    lhs->y = mla3(rx, m[ 1], ry, m[ 5], rz, m[ 9]);
    lhs->z = mla3(rx, m[ 2], ry, m[ 6], rz, m[10]);
}


void point2__nop(transform_t const*, vec4_t* lhs, vec4_t const* rhs) {
    lhs->z = 0;
    lhs->w = 0x10000;
    if (lhs != rhs) {
        lhs->x = rhs->x;
        lhs->y = rhs->y;
    }
}

void point3__nop(transform_t const*, vec4_t* lhs, vec4_t const* rhs) {
    lhs->w = 0x10000;
    if (lhs != rhs) {
        lhs->x = rhs->x;
        lhs->y = rhs->y;
        lhs->z = rhs->z;
    }
}

void point4__nop(transform_t const*, vec4_t* lhs, vec4_t const* rhs) {
    if (lhs != rhs)
        *lhs = *rhs;
}


static void frustumf(
            GLfloat left, GLfloat right, 
            GLfloat bottom, GLfloat top,
            GLfloat zNear, GLfloat zFar,
            ogles_context_t* c)
    {
    if (cmpf(left,right) ||
        cmpf(top, bottom) ||
        cmpf(zNear, zFar) ||
        isZeroOrNegativef(zNear) ||
        isZeroOrNegativef(zFar))
    {
        ogles_error(c, GL_INVALID_VALUE);
        return;
    }
    const GLfloat r_width  = reciprocalf(right - left);
    const GLfloat r_height = reciprocalf(top - bottom);
    const GLfloat r_depth  = reciprocalf(zNear - zFar);
    const GLfloat x = mul2f(zNear * r_width);
    const GLfloat y = mul2f(zNear * r_height);
    const GLfloat A = mul2f((right + left) * r_width);
    const GLfloat B = (top + bottom) * r_height;
    const GLfloat C = (zFar + zNear) * r_depth;
    const GLfloat D = mul2f(zFar * zNear * r_depth);
    GLfloat f[16];
    f[ 0] = x;
    f[ 5] = y;
    f[ 8] = A;
    f[ 9] = B;
    f[10] = C;
    f[14] = D;
    f[11] = -1.0f;
    f[ 1] = f[ 2] = f[ 3] =
    f[ 4] = f[ 6] = f[ 7] =
    f[12] = f[13] = f[15] = 0.0f;

    matrixf_t rhs;
    rhs.set(f);
    c->transforms.current->multiply(rhs);
    c->transforms.invalidate();
}

static void orthof( 
        GLfloat left, GLfloat right, 
        GLfloat bottom, GLfloat top,
        GLfloat zNear, GLfloat zFar,
        ogles_context_t* c)
{
    if (cmpf(left,right) ||
        cmpf(top, bottom) ||
        cmpf(zNear, zFar))
    {
        ogles_error(c, GL_INVALID_VALUE);
        return;
    }
    const GLfloat r_width  = reciprocalf(right - left);
    const GLfloat r_height = reciprocalf(top - bottom);
    const GLfloat r_depth  = reciprocalf(zFar - zNear);
    const GLfloat x =  mul2f(r_width);
    const GLfloat y =  mul2f(r_height);
    const GLfloat z = -mul2f(r_depth);
    const GLfloat tx = -(right + left) * r_width;
    const GLfloat ty = -(top + bottom) * r_height;
    const GLfloat tz = -(zFar + zNear) * r_depth;
    GLfloat f[16];
    f[ 0] = x;
    f[ 5] = y;
    f[10] = z;
    f[12] = tx;
    f[13] = ty;
    f[14] = tz;
    f[15] = 1.0f;
    f[ 1] = f[ 2] = f[ 3] =
    f[ 4] = f[ 6] = f[ 7] =
    f[ 8] = f[ 9] = f[11] = 0.0f;
    matrixf_t rhs;
    rhs.set(f);
    c->transforms.current->multiply(rhs);
    c->transforms.invalidate();
}

static void depthRangef(GLclampf zNear, GLclampf zFar, ogles_context_t* c)
{
    zNear = clampToZerof(zNear > 1 ? 1 : zNear);
    zFar  = clampToZerof(zFar  > 1 ? 1 : zFar);
    GLfloat* const f = c->transforms.vpt.matrix.editElements();
    f[10] = div2f(zFar - zNear);
    f[14] = div2f(zFar + zNear);
    c->transforms.dirty |= transform_state_t::VIEWPORT;
    c->transforms.vpt.zNear = zNear;
    c->transforms.vpt.zFar  = zFar;
}


// ----------------------------------------------------------------------------
}; // namespace android

using namespace android;

void glMatrixMode(GLenum mode)
{
    ogles_context_t* c = ogles_context_t::get();
    matrix_stack_t* stack = 0;
    switch (mode) {
    case GL_MODELVIEW:
        stack = &c->transforms.modelview;
        break;
    case GL_PROJECTION:
        stack = &c->transforms.projection;
        break;
    case GL_TEXTURE:
        stack = &c->transforms.texture[c->textures.active];
        break;
    default:
        ogles_error(c, GL_INVALID_ENUM);
        return;
    }
    c->transforms.matrixMode = mode;
    c->transforms.current = stack;
}

void glLoadIdentity()
{
    ogles_context_t* c = ogles_context_t::get();
    c->transforms.current->loadIdentity(); // also loads the GLfixed transform
    c->transforms.invalidate();
    c->transforms.current->dirty = 0;
}

void glLoadMatrixf(const GLfloat* m)
{
    ogles_context_t* c = ogles_context_t::get();
    c->transforms.current->load(m);
    c->transforms.invalidate();
}

void glLoadMatrixx(const GLfixed* m)
{
    ogles_context_t* c = ogles_context_t::get();
    c->transforms.current->load(m); // also loads the GLfixed transform
    c->transforms.invalidate();
    c->transforms.current->dirty &= ~matrix_stack_t::DO_FLOAT_TO_FIXED;
}

void glMultMatrixf(const GLfloat* m)
{
    ogles_context_t* c = ogles_context_t::get();
    matrixf_t rhs;
    rhs.set(m);
    c->transforms.current->multiply(rhs);
    c->transforms.invalidate();
}

void glMultMatrixx(const GLfixed* m)
{
    ogles_context_t* c = ogles_context_t::get();
    matrixf_t rhs;
    rhs.set(m);
    c->transforms.current->multiply(rhs);
    c->transforms.invalidate();
}

void glPopMatrix()
{
    ogles_context_t* c = ogles_context_t::get();
    GLint err = c->transforms.current->pop();
    if (ggl_unlikely(err)) {
        ogles_error(c, err);
        return;
    }
    c->transforms.invalidate();
}

void glPushMatrix()
{
    ogles_context_t* c = ogles_context_t::get();
    GLint err = c->transforms.current->push();
    if (ggl_unlikely(err)) {
        ogles_error(c, err);
        return;
    }
    c->transforms.invalidate();
}

void glFrustumf(
        GLfloat left, GLfloat right, 
        GLfloat bottom, GLfloat top,
        GLfloat zNear, GLfloat zFar)
{
    ogles_context_t* c = ogles_context_t::get();
    frustumf(left, right, bottom, top, zNear, zFar, c);
}

void glFrustumx( 
        GLfixed left, GLfixed right,
        GLfixed bottom, GLfixed top,
        GLfixed zNear, GLfixed zFar)
{
    ogles_context_t* c = ogles_context_t::get();
    frustumf( fixedToFloat(left), fixedToFloat(right),
              fixedToFloat(bottom), fixedToFloat(top),
              fixedToFloat(zNear), fixedToFloat(zFar),
              c);
}

void glOrthof( 
        GLfloat left, GLfloat right, 
        GLfloat bottom, GLfloat top,
        GLfloat zNear, GLfloat zFar)
{
    ogles_context_t* c = ogles_context_t::get();
    orthof(left, right, bottom, top, zNear, zFar, c);
}

void glOrthox(
        GLfixed left, GLfixed right,
        GLfixed bottom, GLfixed top,
        GLfixed zNear, GLfixed zFar)
{
    ogles_context_t* c = ogles_context_t::get();
    orthof( fixedToFloat(left), fixedToFloat(right),
            fixedToFloat(bottom), fixedToFloat(top),
            fixedToFloat(zNear), fixedToFloat(zFar),
            c);
}

void glRotatef(GLfloat a, GLfloat x, GLfloat y, GLfloat z)
{
    ogles_context_t* c = ogles_context_t::get();
    c->transforms.current->rotate(a, x, y, z);
    c->transforms.invalidate();
}

void glRotatex(GLfixed a, GLfixed x, GLfixed y, GLfixed z)
{
    ogles_context_t* c = ogles_context_t::get();
    c->transforms.current->rotate( 
            fixedToFloat(a), fixedToFloat(x),
            fixedToFloat(y), fixedToFloat(z));
    c->transforms.invalidate();
}

void glScalef(GLfloat x, GLfloat y, GLfloat z)
{
    ogles_context_t* c = ogles_context_t::get();
    c->transforms.current->scale(x, y, z);
    c->transforms.invalidate();
}

void glScalex(GLfixed x, GLfixed y, GLfixed z)
{
    ogles_context_t* c = ogles_context_t::get();
    c->transforms.current->scale(
            fixedToFloat(x), fixedToFloat(y), fixedToFloat(z));
    c->transforms.invalidate();
}

void glTranslatef(GLfloat x, GLfloat y, GLfloat z)
{
    ogles_context_t* c = ogles_context_t::get();
    c->transforms.current->translate(x, y, z);
    c->transforms.invalidate();
}

void glTranslatex(GLfixed x, GLfixed y, GLfixed z)
{
    ogles_context_t* c = ogles_context_t::get();
    c->transforms.current->translate(
            fixedToFloat(x), fixedToFloat(y), fixedToFloat(z));
    c->transforms.invalidate();
}

void glScissor(GLint x, GLint y, GLsizei w, GLsizei h)
{
    ogles_context_t* c = ogles_context_t::get();
    ogles_scissor(c, x, y, w, h);
}

void glViewport(GLint x, GLint y, GLsizei w, GLsizei h)
{
    ogles_context_t* c = ogles_context_t::get();
    ogles_viewport(c, x, y, w, h);
}

void glDepthRangef(GLclampf zNear, GLclampf zFar)
{
    ogles_context_t* c = ogles_context_t::get();
    depthRangef(zNear, zFar, c);
}

void glDepthRangex(GLclampx zNear, GLclampx zFar)
{
    ogles_context_t* c = ogles_context_t::get();
    depthRangef(fixedToFloat(zNear), fixedToFloat(zFar), c);
}

void glPolygonOffsetx(GLfixed factor, GLfixed units)
{
    ogles_context_t* c = ogles_context_t::get();
    c->polygonOffset.factor = factor;
    c->polygonOffset.units = units;
}

void glPolygonOffset(GLfloat factor, GLfloat units)
{
    ogles_context_t* c = ogles_context_t::get();
    c->polygonOffset.factor = gglFloatToFixed(factor);
    c->polygonOffset.units = gglFloatToFixed(units);
}

GLbitfield glQueryMatrixxOES(GLfixed* m, GLint* e)
{
    ogles_context_t* c = ogles_context_t::get();
    GLbitfield status = 0;
    GLfloat const* f = c->transforms.current->top().elements();
    for  (int i=0 ; i<16 ; i++) {
        if (isnan(f[i]) || isinf(f[i])) {
            status |= 1<<i;
            continue;
        }
        e[i] = exponent(f[i]) - 7;
        m[i] = mantissa(f[i]);
    }
    return status;
}
