/* libs/opengles/primitives.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 <math.h>

#include "context.h"
#include "primitives.h"
#include "light.h"
#include "matrix.h"
#include "vertex.h"
#include "fp.h"
#include "TextureObjectManager.h"

extern "C" void iterators0032(const void* that,
        int32_t* it, int32_t c0, int32_t c1, int32_t c2);

namespace android {

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

static void primitive_point(ogles_context_t* c, vertex_t* v);
static void primitive_line(ogles_context_t* c, vertex_t* v0, vertex_t* v1);
static void primitive_clip_triangle(ogles_context_t* c,
        vertex_t* v0, vertex_t* v1, vertex_t* v2);

static void primitive_nop_point(ogles_context_t* c, vertex_t* v);
static void primitive_nop_line(ogles_context_t* c, vertex_t* v0, vertex_t* v1);
static void primitive_nop_triangle(ogles_context_t* c,
        vertex_t* v0, vertex_t* v1, vertex_t* v2);

static inline bool cull_triangle(ogles_context_t* c,
        vertex_t* v0, vertex_t* v1, vertex_t* v2);

static void lerp_triangle(ogles_context_t* c,
        vertex_t* v0, vertex_t* v1, vertex_t* v2);

static void lerp_texcoords(ogles_context_t* c,
        vertex_t* v0, vertex_t* v1, vertex_t* v2);

static void lerp_texcoords_w(ogles_context_t* c,
        vertex_t* v0, vertex_t* v1, vertex_t* v2);

static void triangle(ogles_context_t* c,
        vertex_t* v0, vertex_t* v1, vertex_t* v2);

static void clip_triangle(ogles_context_t* c,
        vertex_t* v0, vertex_t* v1, vertex_t* v2);

static unsigned int clip_line(ogles_context_t* c,
        vertex_t* s, vertex_t* p);

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

static void lightTriangleDarkSmooth(ogles_context_t* c,
        vertex_t* v0, vertex_t* v1, vertex_t* v2)
{
    if (!(v0->flags & vertex_t::LIT)) {
        v0->flags |= vertex_t::LIT;
        const GLvoid* cp = c->arrays.color.element(
                v0->index & vertex_cache_t::INDEX_MASK);
        c->arrays.color.fetch(c, v0->color.v, cp);
    }
    if (!(v1->flags & vertex_t::LIT)) {
        v1->flags |= vertex_t::LIT;
        const GLvoid* cp = c->arrays.color.element(
                v1->index & vertex_cache_t::INDEX_MASK);
        c->arrays.color.fetch(c, v1->color.v, cp);
    }
    if(!(v2->flags & vertex_t::LIT)) {
        v2->flags |= vertex_t::LIT;
        const GLvoid* cp = c->arrays.color.element(
                v2->index & vertex_cache_t::INDEX_MASK);
        c->arrays.color.fetch(c, v2->color.v, cp);
    }
}

static void lightTriangleDarkFlat(ogles_context_t* c,
        vertex_t* /*v0*/, vertex_t* /*v1*/, vertex_t* v2)
{
    if (!(v2->flags & vertex_t::LIT)) {
        v2->flags |= vertex_t::LIT;
        const GLvoid* cp = c->arrays.color.element(
                v2->index & vertex_cache_t::INDEX_MASK);
        c->arrays.color.fetch(c, v2->color.v, cp);
    }
    // configure the rasterizer here, before we clip
    c->rasterizer.procs.color4xv(c, v2->color.v);
}

static void lightTriangleSmooth(ogles_context_t* c,
        vertex_t* v0, vertex_t* v1, vertex_t* v2)
{
    if (!(v0->flags & vertex_t::LIT))
        c->lighting.lightVertex(c, v0);
    if (!(v1->flags & vertex_t::LIT))
        c->lighting.lightVertex(c, v1);
    if(!(v2->flags & vertex_t::LIT))
        c->lighting.lightVertex(c, v2);
}

static void lightTriangleFlat(ogles_context_t* c,
        vertex_t* /*v0*/, vertex_t* /*v1*/, vertex_t* v2)
{
    if (!(v2->flags & vertex_t::LIT))
        c->lighting.lightVertex(c, v2);
    // configure the rasterizer here, before we clip
    c->rasterizer.procs.color4xv(c, v2->color.v);
}

// The fog versions...

static inline
void lightVertexDarkSmoothFog(ogles_context_t* c, vertex_t* v)
{
    if (!(v->flags & vertex_t::LIT)) {
        v->flags |= vertex_t::LIT;
        v->fog = c->fog.fog(c, v->eye.z);
        const GLvoid* cp = c->arrays.color.element(
                v->index & vertex_cache_t::INDEX_MASK);
        c->arrays.color.fetch(c, v->color.v, cp);
    }
}
static inline
void lightVertexDarkFlatFog(ogles_context_t* c, vertex_t* v)
{
    if (!(v->flags & vertex_t::LIT)) {
        v->flags |= vertex_t::LIT;
        v->fog = c->fog.fog(c, v->eye.z);
    }
}
static inline
void lightVertexSmoothFog(ogles_context_t* c, vertex_t* v)
{
    if (!(v->flags & vertex_t::LIT)) {
        v->fog = c->fog.fog(c, v->eye.z);
        c->lighting.lightVertex(c, v);
    }
}

static void lightTriangleDarkSmoothFog(ogles_context_t* c,
        vertex_t* v0, vertex_t* v1, vertex_t* v2)
{
    lightVertexDarkSmoothFog(c, v0);
    lightVertexDarkSmoothFog(c, v1);
    lightVertexDarkSmoothFog(c, v2);
}

static void lightTriangleDarkFlatFog(ogles_context_t* c,
        vertex_t* v0, vertex_t* v1, vertex_t* v2)
{
    lightVertexDarkFlatFog(c, v0);
    lightVertexDarkFlatFog(c, v1);
    lightVertexDarkSmoothFog(c, v2);
    // configure the rasterizer here, before we clip
    c->rasterizer.procs.color4xv(c, v2->color.v);
}

static void lightTriangleSmoothFog(ogles_context_t* c,
        vertex_t* v0, vertex_t* v1, vertex_t* v2)
{
    lightVertexSmoothFog(c, v0);
    lightVertexSmoothFog(c, v1);
    lightVertexSmoothFog(c, v2);
}

static void lightTriangleFlatFog(ogles_context_t* c,
        vertex_t* v0, vertex_t* v1, vertex_t* v2)
{
    lightVertexDarkFlatFog(c, v0);
    lightVertexDarkFlatFog(c, v1);
    lightVertexSmoothFog(c, v2);
    // configure the rasterizer here, before we clip
    c->rasterizer.procs.color4xv(c, v2->color.v);
}



typedef void (*light_primitive_t)(ogles_context_t*,
        vertex_t*, vertex_t*, vertex_t*);

// fog 0x4, light 0x2, smooth 0x1
static const light_primitive_t lightPrimitive[8] = {
    lightTriangleDarkFlat,          // no fog | dark  | flat
    lightTriangleDarkSmooth,        // no fog | dark  | smooth
    lightTriangleFlat,              // no fog | light | flat
    lightTriangleSmooth,            // no fog | light | smooth
    lightTriangleDarkFlatFog,       // fog    | dark  | flat
    lightTriangleDarkSmoothFog,     // fog    | dark  | smooth
    lightTriangleFlatFog,           // fog    | light | flat
    lightTriangleSmoothFog          // fog    | light | smooth
};

void ogles_validate_primitives(ogles_context_t* c)
{
    const uint32_t enables = c->rasterizer.state.enables;

    // set up the lighting/shading/smoothing/fogging function
    int index = enables & GGL_ENABLE_SMOOTH ? 0x1 : 0;
    index |= c->lighting.enable ? 0x2 : 0;
    index |= enables & GGL_ENABLE_FOG ? 0x4 : 0;
    c->lighting.lightTriangle = lightPrimitive[index];
    
    // set up the primitive renderers
    if (ggl_likely(c->arrays.vertex.enable)) {
        c->prims.renderPoint    = primitive_point;
        c->prims.renderLine     = primitive_line;
        c->prims.renderTriangle = primitive_clip_triangle;
    } else {
        c->prims.renderPoint    = primitive_nop_point;
        c->prims.renderLine     = primitive_nop_line;
        c->prims.renderTriangle = primitive_nop_triangle;
    }
}

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

void compute_iterators_t::initTriangle(
        vertex_t const* v0, vertex_t const* v1, vertex_t const* v2)
{
    m_dx01 = v1->window.x - v0->window.x;
    m_dy10 = v0->window.y - v1->window.y;
    m_dx20 = v0->window.x - v2->window.x;
    m_dy02 = v2->window.y - v0->window.y;
    m_area = m_dx01*m_dy02 + (-m_dy10)*m_dx20;
    (void)m_reserved; // suppress unused warning
}

void compute_iterators_t::initLine(
        vertex_t const* v0, vertex_t const* v1)
{
    m_dx01 = m_dy02 = v1->window.x - v0->window.x;
    m_dy10 = m_dx20 = v0->window.y - v1->window.y;
    m_area = m_dx01*m_dy02 + (-m_dy10)*m_dx20;
}

void compute_iterators_t::initLerp(vertex_t const* v0, uint32_t enables)
{
    m_x0 = v0->window.x;
    m_y0 = v0->window.y;
    const GGLcoord area = (m_area + TRI_HALF) >> TRI_FRACTION_BITS;
    const GGLcoord minArea = 2; // cannot be inverted
    // triangles with an area smaller than 1.0 are not smooth-shaded

    int q=0, s=0, d=0;
    if (abs(area) >= minArea) {
        // Here we do some voodoo magic, to compute a suitable scale
        // factor for deltas/area:

        // First compute the 1/area with full 32-bits precision,
        // gglRecipQNormalized returns a number [-0.5, 0.5[ and an exponent.
        d = gglRecipQNormalized(area, &q);

        // Then compute the minimum left-shift to not overflow the muls
        // below. 
        s = 32 - gglClz(abs(m_dy02)|abs(m_dy10)|abs(m_dx01)|abs(m_dx20));

        // We'll keep 16-bits of precision for deltas/area. So we need
        // to shift everything left an extra 15 bits.
        s += 15;
        
        // make sure all final shifts are not > 32, because gglMulx
        // can't handle it.
        if (s < q) s = q;
        if (s > 32) {
            d >>= 32-s;
            s = 32;
        }
    }

    m_dx01 = gglMulx(m_dx01, d, s);
    m_dy10 = gglMulx(m_dy10, d, s);
    m_dx20 = gglMulx(m_dx20, d, s);
    m_dy02 = gglMulx(m_dy02, d, s);
    m_area_scale = 32 + q - s;
    m_scale = 0;

    if (enables & GGL_ENABLE_TMUS) {
        const int A = gglClz(abs(m_dy02)|abs(m_dy10)|abs(m_dx01)|abs(m_dx20));
        const int B = gglClz(abs(m_x0)|abs(m_y0));
        m_scale = max(0, 32 - (A + 16)) +
                  max(0, 32 - (B + TRI_FRACTION_BITS)) + 1;
    }
}

int compute_iterators_t::iteratorsScale(GGLfixed* it,
        int32_t c0, int32_t c1, int32_t c2) const
{
    int32_t dc01 = c1 - c0;
    int32_t dc02 = c2 - c0;
    const int A = gglClz(abs(c0));
    const int B = gglClz(abs(dc01)|abs(dc02));
    const int scale = min(A, B - m_scale) - 2;
    if (scale >= 0) {
        c0   <<= scale;
        dc01 <<= scale;
        dc02 <<= scale;
    } else {
        c0   >>= -scale;
        dc01 >>= -scale;
        dc02 >>= -scale;
    }
    const int s = m_area_scale;
    int32_t dcdx = gglMulAddx(dc01, m_dy02, gglMulx(dc02, m_dy10, s), s);
    int32_t dcdy = gglMulAddx(dc02, m_dx01, gglMulx(dc01, m_dx20, s), s);
    int32_t c = c0 - (gglMulAddx(dcdx, m_x0, 
            gglMulx(dcdy, m_y0, TRI_FRACTION_BITS), TRI_FRACTION_BITS));
    it[0] = c;
    it[1] = dcdx;
    it[2] = dcdy;
    return scale;
}

void compute_iterators_t::iterators1616(GGLfixed* it,
        GGLfixed c0, GGLfixed c1, GGLfixed c2) const
{
    const GGLfixed dc01 = c1 - c0;
    const GGLfixed dc02 = c2 - c0;
    // 16.16 x 16.16 == 32.32 --> 16.16
    const int s = m_area_scale;
    int32_t dcdx = gglMulAddx(dc01, m_dy02, gglMulx(dc02, m_dy10, s), s);
    int32_t dcdy = gglMulAddx(dc02, m_dx01, gglMulx(dc01, m_dx20, s), s);
    int32_t c = c0 - (gglMulAddx(dcdx, m_x0,
            gglMulx(dcdy, m_y0, TRI_FRACTION_BITS), TRI_FRACTION_BITS));
    it[0] = c;
    it[1] = dcdx;
    it[2] = dcdy;
}

void compute_iterators_t::iterators0032(int64_t* it,
        int32_t c0, int32_t c1, int32_t c2) const
{
    const int s = m_area_scale - 16;
    int32_t dc01 = (c1 - c0)>>s;
    int32_t dc02 = (c2 - c0)>>s;
    // 16.16 x 16.16 == 32.32
    int64_t dcdx = gglMulii(dc01, m_dy02) + gglMulii(dc02, m_dy10);
    int64_t dcdy = gglMulii(dc02, m_dx01) + gglMulii(dc01, m_dx20);
    it[ 0] = (c0<<16) - ((dcdx*m_x0 + dcdy*m_y0)>>4);
    it[ 1] = dcdx;
    it[ 2] = dcdy;
}

#if defined(__arm__) && !defined(__thumb__)
inline void compute_iterators_t::iterators0032(int32_t* it,
        int32_t c0, int32_t c1, int32_t c2) const
{
    ::iterators0032(this, it, c0, c1, c2);
}
#else
void compute_iterators_t::iterators0032(int32_t* it,
        int32_t c0, int32_t c1, int32_t c2) const
{
    int64_t it64[3];
    iterators0032(it64, c0, c1, c2);
    it[0] = it64[0];
    it[1] = it64[1];
    it[2] = it64[2];
}
#endif

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

static inline int32_t clampZ(GLfixed z) CONST;
int32_t clampZ(GLfixed z) {
    z = (z & ~(z>>31));
    if (z >= 0x10000)
        z = 0xFFFF;
    return z;
}

static __attribute__((noinline))
void fetch_texcoord_impl(ogles_context_t* c,
        vertex_t* v0, vertex_t* v1, vertex_t* v2)
{
    vertex_t* const vtx[3] = { v0, v1, v2 };
    array_t const * const texcoordArray = c->arrays.texture;
    
    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
        if (!(c->rasterizer.state.texture[i].enable))
            continue;
        
        for (int j=0 ; j<3 ; j++) {
            vertex_t* const v = vtx[j];
            if (v->flags & vertex_t::TT)
                continue;

            // NOTE: here we could compute automatic texgen
            // such as sphere/cube maps, instead of fetching them
            // from the textcoord array.

            vec4_t& coords = v->texture[i];
            const GLubyte* tp = texcoordArray[i].element(
                    v->index & vertex_cache_t::INDEX_MASK);
            texcoordArray[i].fetch(c, coords.v, tp);

            // transform texture coordinates...
            coords.Q = 0x10000;
            const transform_t& tr = c->transforms.texture[i].transform; 
            if (ggl_unlikely(tr.ops)) {
                c->arrays.tex_transform[i](&tr, &coords, &coords);
            }

            // divide by Q
            const GGLfixed q = coords.Q;
            if (ggl_unlikely(q != 0x10000)) {
                const int32_t qinv = gglRecip28(q);
                coords.S = gglMulx(coords.S, qinv, 28);
                coords.T = gglMulx(coords.T, qinv, 28);
            }
        }
    }
    v0->flags |= vertex_t::TT;
    v1->flags |= vertex_t::TT;
    v2->flags |= vertex_t::TT;
}

inline void fetch_texcoord(ogles_context_t* c,
        vertex_t* v0, vertex_t* v1, vertex_t* v2)
{
    const uint32_t enables = c->rasterizer.state.enables;
    if (!(enables & GGL_ENABLE_TMUS))
        return;

    // Fetch & transform texture coordinates...
    if (ggl_likely(v0->flags & v1->flags & v2->flags & vertex_t::TT)) {
        // already done for all three vertices, bail...
        return;
    }
    fetch_texcoord_impl(c, v0, v1, v2);
}

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

void primitive_nop_point(ogles_context_t*, vertex_t*) {
}

void primitive_point(ogles_context_t* c, vertex_t* v)
{
    // lighting & clamping...
    const uint32_t enables = c->rasterizer.state.enables;

    if (ggl_unlikely(!(v->flags & vertex_t::LIT))) {
        if (c->lighting.enable) {
            c->lighting.lightVertex(c, v);
        } else {
            v->flags |= vertex_t::LIT;
            const GLvoid* cp = c->arrays.color.element(
                    v->index & vertex_cache_t::INDEX_MASK);
            c->arrays.color.fetch(c, v->color.v, cp);
        }
        if (enables & GGL_ENABLE_FOG) {
            v->fog = c->fog.fog(c, v->eye.z);
        }
    }

    // XXX: we don't need to do that each-time
    // if color array and lighting not enabled 
    c->rasterizer.procs.color4xv(c, v->color.v);

    // XXX: look into ES point-sprite extension
    if (enables & GGL_ENABLE_TMUS) {
        fetch_texcoord(c, v,v,v);
        for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
            if (!c->rasterizer.state.texture[i].enable) 
                continue;
            int32_t itt[8];
            itt[1] = itt[2] = itt[4] = itt[5] = 0;
            itt[6] = itt[7] = 16; // XXX: check that
            if (c->rasterizer.state.texture[i].s_wrap == GGL_CLAMP) {
                int width = c->textures.tmu[i].texture->surface.width;
                itt[0] = v->texture[i].S * width;
                itt[6] = 0;
            }
            if (c->rasterizer.state.texture[i].t_wrap == GGL_CLAMP) {
                int height = c->textures.tmu[i].texture->surface.height;
                itt[3] = v->texture[i].T * height;
                itt[7] = 0;
            }
            c->rasterizer.procs.texCoordGradScale8xv(c, i, itt);
        }
    }
    
    if (enables & GGL_ENABLE_DEPTH_TEST) {
        int32_t itz[3];
        itz[0] = clampZ(v->window.z) * 0x00010001;
        itz[1] = itz[2] = 0;
        c->rasterizer.procs.zGrad3xv(c, itz);
    }

    if (enables & GGL_ENABLE_FOG) {
        GLfixed itf[3];
        itf[0] = v->fog;
        itf[1] = itf[2] = 0;
        c->rasterizer.procs.fogGrad3xv(c, itf);
    }

    // Render our point...
    c->rasterizer.procs.pointx(c, v->window.v, c->point.size);
}

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

void primitive_nop_line(ogles_context_t*, vertex_t*, vertex_t*) {
}

void primitive_line(ogles_context_t* c, vertex_t* v0, vertex_t* v1)
{
    // get texture coordinates
    fetch_texcoord(c, v0, v1, v1);

    // light/shade the vertices first (they're copied below)
    c->lighting.lightTriangle(c, v0, v1, v1);

    // clip the line if needed
    if (ggl_unlikely((v0->flags | v1->flags) & vertex_t::CLIP_ALL)) {
        unsigned int count = clip_line(c, v0, v1);
        if (ggl_unlikely(count == 0))
            return;
    }

    // compute iterators...
    const uint32_t enables = c->rasterizer.state.enables;
    const uint32_t mask =   GGL_ENABLE_TMUS |
                            GGL_ENABLE_SMOOTH |
                            GGL_ENABLE_W | 
                            GGL_ENABLE_FOG |
                            GGL_ENABLE_DEPTH_TEST;

    if (ggl_unlikely(enables & mask)) {
        c->lerp.initLine(v0, v1);
        lerp_triangle(c, v0, v1, v0);
    }

    // render our line
    c->rasterizer.procs.linex(c, v0->window.v, v1->window.v, c->line.width);
}

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

void primitive_nop_triangle(ogles_context_t* /*c*/,
        vertex_t* /*v0*/, vertex_t* /*v1*/, vertex_t* /*v2*/) {
}

void primitive_clip_triangle(ogles_context_t* c,
        vertex_t* v0, vertex_t* v1, vertex_t* v2)
{
    uint32_t cc = (v0->flags | v1->flags | v2->flags) & vertex_t::CLIP_ALL;
    if (ggl_likely(!cc)) {
        // code below must be as optimized as possible, this is the
        // common code path.

        // This triangle is not clipped, test if it's culled
        // unclipped triangle...
        c->lerp.initTriangle(v0, v1, v2);
        if (cull_triangle(c, v0, v1, v2))
            return; // culled!

        // Fetch all texture coordinates if needed
        fetch_texcoord(c, v0, v1, v2);

        // light (or shade) our triangle!
        c->lighting.lightTriangle(c, v0, v1, v2);

        triangle(c, v0, v1, v2);
        return;
    }

    // The assumption here is that we're not going to clip very often,
    // and even more rarely will we clip a triangle that ends up
    // being culled out. So it's okay to light the vertices here, even though
    // in a few cases we won't render the triangle (if culled).

    // Fetch texture coordinates...
    fetch_texcoord(c, v0, v1, v2);

    // light (or shade) our triangle!
    c->lighting.lightTriangle(c, v0, v1, v2);

    clip_triangle(c, v0, v1, v2);
}

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

void triangle(ogles_context_t* c,
        vertex_t* v0, vertex_t* v1, vertex_t* v2)
{
    // compute iterators...
    const uint32_t enables = c->rasterizer.state.enables;
    const uint32_t mask =   GGL_ENABLE_TMUS |
                            GGL_ENABLE_SMOOTH |
                            GGL_ENABLE_W | 
                            GGL_ENABLE_FOG |
                            GGL_ENABLE_DEPTH_TEST;

    if (ggl_likely(enables & mask))
        lerp_triangle(c, v0, v1, v2);

    c->rasterizer.procs.trianglex(c, v0->window.v, v1->window.v, v2->window.v);
}

void lerp_triangle(ogles_context_t* c,
        vertex_t* v0, vertex_t* v1, vertex_t* v2)
{
    const uint32_t enables = c->rasterizer.state.enables;
    c->lerp.initLerp(v0, enables);

    // set up texture iterators
    if (enables & GGL_ENABLE_TMUS) {
        if (enables & GGL_ENABLE_W) {
            lerp_texcoords_w(c, v0, v1, v2);
        } else {
            lerp_texcoords(c, v0, v1, v2);
        }
    }

    // set up the color iterators
    const compute_iterators_t& lerp = c->lerp;
    if (enables & GGL_ENABLE_SMOOTH) {
        GLfixed itc[12];
        for (int i=0 ; i<4 ; i++) {
            const GGLcolor c0 = v0->color.v[i] * 255;
            const GGLcolor c1 = v1->color.v[i] * 255;
            const GGLcolor c2 = v2->color.v[i] * 255;
            lerp.iterators1616(&itc[i*3], c0, c1, c2);
        }
        c->rasterizer.procs.colorGrad12xv(c, itc);
    }

    if (enables & GGL_ENABLE_DEPTH_TEST) {
        int32_t itz[3];
        const int32_t v0z = clampZ(v0->window.z);
        const int32_t v1z = clampZ(v1->window.z);
        const int32_t v2z = clampZ(v2->window.z);
        if (ggl_unlikely(c->polygonOffset.enable)) {
            const int32_t units = (c->polygonOffset.units << 16);
            const GLfixed factor = c->polygonOffset.factor;
            if (factor) {
                int64_t itz64[3];
                lerp.iterators0032(itz64, v0z, v1z, v2z);
                int64_t maxDepthSlope = max(itz64[1], itz64[2]);
                itz[0] = uint32_t(itz64[0]) 
                        + uint32_t((maxDepthSlope*factor)>>16) + units;
                itz[1] = uint32_t(itz64[1]);
                itz[2] = uint32_t(itz64[2]);
            } else {
                lerp.iterators0032(itz, v0z, v1z, v2z);
                itz[0] += units; 
            }
        } else {
            lerp.iterators0032(itz, v0z, v1z, v2z);
        }
        c->rasterizer.procs.zGrad3xv(c, itz);
    }    

    if (ggl_unlikely(enables & GGL_ENABLE_FOG)) {
        GLfixed itf[3];
        lerp.iterators1616(itf, v0->fog, v1->fog, v2->fog);
        c->rasterizer.procs.fogGrad3xv(c, itf);
    }
}


static inline
int compute_lod(ogles_context_t* c, int i,
        int32_t s0, int32_t t0, int32_t s1, int32_t t1, int32_t s2, int32_t t2)
{
    // Compute mipmap level / primitive
    // rho = sqrt( texelArea / area )
    // lod = log2( rho )
    // lod = log2( texelArea / area ) / 2
    // lod = (log2( texelArea ) - log2( area )) / 2
    const compute_iterators_t& lerp = c->lerp;
    const GGLcoord area = abs(lerp.area());
    const int w = c->textures.tmu[i].texture->surface.width;
    const int h = c->textures.tmu[i].texture->surface.height;
    const int shift = 16 + (16 - TRI_FRACTION_BITS);
    int32_t texelArea = abs( gglMulx(s1-s0, t2-t0, shift) -
            gglMulx(s2-s0, t1-t0, shift) )*w*h;
    int log2TArea = (32-TRI_FRACTION_BITS  -1) - gglClz(texelArea);
    int log2Area  = (32-TRI_FRACTION_BITS*2-1) - gglClz(area);
    int lod = (log2TArea - log2Area + 1) >> 1;
    return lod;
}

void lerp_texcoords(ogles_context_t* c,
        vertex_t* v0, vertex_t* v1, vertex_t* v2)
{
    const compute_iterators_t& lerp = c->lerp;
    int32_t itt[8] __attribute__((aligned(16)));
    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
        const texture_t& tmu = c->rasterizer.state.texture[i];
        if (!tmu.enable) 
            continue;

        // compute the jacobians using block floating-point
        int32_t s0 = v0->texture[i].S;
        int32_t t0 = v0->texture[i].T;
        int32_t s1 = v1->texture[i].S;
        int32_t t1 = v1->texture[i].T;
        int32_t s2 = v2->texture[i].S;
        int32_t t2 = v2->texture[i].T;

        const GLenum min_filter = c->textures.tmu[i].texture->min_filter;
        if (ggl_unlikely(min_filter >= GL_NEAREST_MIPMAP_NEAREST)) {
            int lod = compute_lod(c, i, s0, t0, s1, t1, s2, t2);
            c->rasterizer.procs.bindTextureLod(c, i,
                    &c->textures.tmu[i].texture->mip(lod));
        }

        // premultiply (s,t) when clampling
        if (tmu.s_wrap == GGL_CLAMP) {
            const int width = tmu.surface.width;
            s0 *= width;
            s1 *= width;
            s2 *= width;
        }
        if (tmu.t_wrap == GGL_CLAMP) {
            const int height = tmu.surface.height;
            t0 *= height;
            t1 *= height;
            t2 *= height;
        }
        itt[6] = -lerp.iteratorsScale(itt+0, s0, s1, s2);
        itt[7] = -lerp.iteratorsScale(itt+3, t0, t1, t2);
        c->rasterizer.procs.texCoordGradScale8xv(c, i, itt);
    }
}

void lerp_texcoords_w(ogles_context_t* c,
        vertex_t* v0, vertex_t* v1, vertex_t* v2)
{
    const compute_iterators_t& lerp = c->lerp;
    int32_t itt[8] __attribute__((aligned(16)));
    int32_t itw[3];

    // compute W's scale to 2.30
    int32_t w0 = v0->window.w;
    int32_t w1 = v1->window.w;
    int32_t w2 = v2->window.w;
    int wscale = 32 - gglClz(w0|w1|w2);

    // compute the jacobian using block floating-point    
    int sc = lerp.iteratorsScale(itw, w0, w1, w2);
    sc +=  wscale - 16;
    c->rasterizer.procs.wGrad3xv(c, itw);

    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
        const texture_t& tmu = c->rasterizer.state.texture[i];
        if (!tmu.enable) 
            continue;

        // compute the jacobians using block floating-point
        int32_t s0 = v0->texture[i].S;
        int32_t t0 = v0->texture[i].T;
        int32_t s1 = v1->texture[i].S;
        int32_t t1 = v1->texture[i].T;
        int32_t s2 = v2->texture[i].S;
        int32_t t2 = v2->texture[i].T;

        const GLenum min_filter = c->textures.tmu[i].texture->min_filter;
        if (ggl_unlikely(min_filter >= GL_NEAREST_MIPMAP_NEAREST)) {
            int lod = compute_lod(c, i, s0, t0, s1, t1, s2, t2);
            c->rasterizer.procs.bindTextureLod(c, i,
                    &c->textures.tmu[i].texture->mip(lod));
        }

        // premultiply (s,t) when clampling
        if (tmu.s_wrap == GGL_CLAMP) {
            const int width = tmu.surface.width;
            s0 *= width;
            s1 *= width;
            s2 *= width;
        }
        if (tmu.t_wrap == GGL_CLAMP) {
            const int height = tmu.surface.height;
            t0 *= height;
            t1 *= height;
            t2 *= height;
        }

        s0 = gglMulx(s0, w0, wscale);
        t0 = gglMulx(t0, w0, wscale);
        s1 = gglMulx(s1, w1, wscale);
        t1 = gglMulx(t1, w1, wscale);
        s2 = gglMulx(s2, w2, wscale);
        t2 = gglMulx(t2, w2, wscale);

        itt[6] = sc - lerp.iteratorsScale(itt+0, s0, s1, s2);
        itt[7] = sc - lerp.iteratorsScale(itt+3, t0, t1, t2);
        c->rasterizer.procs.texCoordGradScale8xv(c, i, itt);
    }
}


static inline
bool cull_triangle(ogles_context_t* c, vertex_t* /*v0*/, vertex_t* /*v1*/, vertex_t* /*v2*/)
{
    if (ggl_likely(c->cull.enable)) {
        const GLenum winding = (c->lerp.area() > 0) ? GL_CW : GL_CCW;
        const GLenum face = (winding == c->cull.frontFace) ? GL_FRONT : GL_BACK;
        if (face == c->cull.cullFace)
            return true; // culled!
    }
    return false;
}

static inline
GLfixed frustumPlaneDist(int plane, const vec4_t& s)
{
    const GLfixed d = s.v[ plane >> 1 ];
    return  ((plane & 1) ? (s.w - d) : (s.w + d)); 
}

static inline
int32_t clipDivide(GLfixed a, GLfixed b) {
    // returns a 4.28 fixed-point
    return gglMulDivi(1LU<<28, a, b);
} 

void clip_triangle(ogles_context_t* c,
        vertex_t* v0, vertex_t* v1, vertex_t* v2)
{
    uint32_t all_cc = (v0->flags | v1->flags | v2->flags) & vertex_t::CLIP_ALL;

    vertex_t *p0, *p1, *p2;
    const int MAX_CLIPPING_PLANES = 6 + OGLES_MAX_CLIP_PLANES;
    const int MAX_VERTICES = 3;

    // Temporary buffer to hold the new vertices. Each plane can add up to 
    // two new vertices (because the polygon is convex).
    // We need one extra element, to handle an overflow case when
    // the polygon degenerates into something non convex.
    vertex_t buffer[MAX_CLIPPING_PLANES * 2 + 1];   // ~3KB
    vertex_t* buf = buffer;

    // original list of vertices (polygon to clip, in fact this
    // function works with an arbitrary polygon).
    vertex_t* in[3] = { v0, v1, v2 };
    
    // output lists (we need 2, which we use back and forth)
    // (maximum outpout list's size is MAX_CLIPPING_PLANES + MAX_VERTICES)
    // 2 more elements for overflow when non convex polygons.
    vertex_t* out[2][MAX_CLIPPING_PLANES + MAX_VERTICES + 2];
    unsigned int outi = 0;
    
    // current input list
    vertex_t** ivl = in;

    // 3 input vertices, 0 in the output list, first plane
    unsigned int ic = 3;

    // User clip-planes first, the clipping is always done in eye-coordinate
    // this is basically the same algorithm than for the view-volume
    // clipping, except for the computation of the distance (vertex, plane)
    // and the fact that we need to compute the eye-coordinates of each
    // new vertex we create.
    
    if (ggl_unlikely(all_cc & vertex_t::USER_CLIP_ALL))
    {
        unsigned int plane = 0;
        uint32_t cc = (all_cc & vertex_t::USER_CLIP_ALL) >> 8;
        do {
            if (cc & 1) {        
                // pointers to our output list (head and current)
                vertex_t** const ovl = &out[outi][0];
                vertex_t** output = ovl;
                unsigned int oc = 0;
                unsigned int sentinel = 0;
                // previous vertex, compute distance to the plane
                vertex_t* s = ivl[ic-1];
                const vec4_t& equation = c->clipPlanes.plane[plane].equation;
                GLfixed sd = dot4(equation.v, s->eye.v);
                // clip each vertex against this plane...
                for (unsigned int i=0 ; i<ic ; i++) {            
                    vertex_t* p = ivl[i];
                    const GLfixed pd = dot4(equation.v, p->eye.v);
                    if (sd >= 0) {
                        if (pd >= 0) {
                            // both inside
                            *output++ = p;
                            oc++;
                        } else {
                            // s inside, p outside (exiting)
                            const GLfixed t = clipDivide(sd, sd-pd);
                            c->arrays.clipEye(c, buf, t, p, s);
                            *output++ = buf++;
                            oc++;
                            if (++sentinel >= 3)
                                return; // non-convex polygon!
                        }
                    } else {
                        if (pd >= 0) {
                            // s outside (entering)
                            if (pd) {
                                const GLfixed t = clipDivide(pd, pd-sd);
                                c->arrays.clipEye(c, buf, t, s, p);
                                *output++ = buf++;
                                oc++;
                                if (++sentinel >= 3)
                                    return; // non-convex polygon!
                            }
                            *output++ = p;
                            oc++;
                        } else {
                           // both outside
                        }
                    }
                    s = p;
                    sd = pd;
                }
                // output list become the new input list
                if (oc<3)
                    return; // less than 3 vertices left? we're done!
                ivl = ovl;
                ic = oc;
                outi = 1-outi;
            }
            cc >>= 1;
            plane++;
        } while (cc);
    }

    // frustum clip-planes
    if (all_cc & vertex_t::FRUSTUM_CLIP_ALL)
    {
        unsigned int plane = 0;
        uint32_t cc = all_cc & vertex_t::FRUSTUM_CLIP_ALL;
        do {
            if (cc & 1) {        
                // pointers to our output list (head and current)
                vertex_t** const ovl = &out[outi][0];
                vertex_t** output = ovl;
                unsigned int oc = 0;
                unsigned int sentinel = 0;
                // previous vertex, compute distance to the plane
                vertex_t* s = ivl[ic-1];
                GLfixed sd = frustumPlaneDist(plane, s->clip);
                // clip each vertex against this plane...
                for (unsigned int i=0 ; i<ic ; i++) {            
                    vertex_t* p = ivl[i];
                    const GLfixed pd = frustumPlaneDist(plane, p->clip);
                    if (sd >= 0) {
                        if (pd >= 0) {
                            // both inside
                            *output++ = p;
                            oc++;
                        } else {
                            // s inside, p outside (exiting)
                            const GLfixed t = clipDivide(sd, sd-pd);
                            c->arrays.clipVertex(c, buf, t, p, s);
                            *output++ = buf++;
                            oc++;
                            if (++sentinel >= 3)
                                return; // non-convex polygon!
                        }
                    } else {
                        if (pd >= 0) {
                            // s outside (entering)
                            if (pd) {
                                const GLfixed t = clipDivide(pd, pd-sd);
                                c->arrays.clipVertex(c, buf, t, s, p);
                                *output++ = buf++;
                                oc++;
                                if (++sentinel >= 3)
                                    return; // non-convex polygon!
                            }
                            *output++ = p;
                            oc++;
                        } else {
                           // both outside
                        }
                    }
                    s = p;
                    sd = pd;
                }
                // output list become the new input list
                if (oc<3)
                    return; // less than 3 vertices left? we're done!
                ivl = ovl;
                ic = oc;
                outi = 1-outi;
            }
            cc >>= 1;
            plane++;
        } while (cc);
    }
    
    // finally we can render our triangles...
    p0 = ivl[0];
    p1 = ivl[1];
    for (unsigned int i=2 ; i<ic ; i++) {
        p2 = ivl[i];
        c->lerp.initTriangle(p0, p1, p2);
        if (cull_triangle(c, p0, p1, p2)) {
            p1 = p2;
            continue; // culled!
        }
        triangle(c, p0, p1, p2);
        p1 = p2;
    }
}

unsigned int clip_line(ogles_context_t* c, vertex_t* s, vertex_t* p)
{
    const uint32_t all_cc = (s->flags | p->flags) & vertex_t::CLIP_ALL;

    if (ggl_unlikely(all_cc & vertex_t::USER_CLIP_ALL))
    {
        unsigned int plane = 0;
        uint32_t cc = (all_cc & vertex_t::USER_CLIP_ALL) >> 8;
        do {
            if (cc & 1) {
                const vec4_t& equation = c->clipPlanes.plane[plane].equation;
                const GLfixed sd = dot4(equation.v, s->eye.v);
                const GLfixed pd = dot4(equation.v, p->eye.v);
                if (sd >= 0) {
                    if (pd >= 0) {
                        // both inside
                    } else {
                        // s inside, p outside (exiting)
                        const GLfixed t = clipDivide(sd, sd-pd);
                        c->arrays.clipEye(c, p, t, p, s);
                    }
                } else {
                    if (pd >= 0) {
                        // s outside (entering)
                        if (pd) {
                            const GLfixed t = clipDivide(pd, pd-sd);
                            c->arrays.clipEye(c, s, t, s, p);
                        }
                    } else {
                       // both outside
                       return 0;
                    }
                }
            }
            cc >>= 1;
            plane++;
        } while (cc);
    }

    // frustum clip-planes
    if (all_cc & vertex_t::FRUSTUM_CLIP_ALL)
    {
        unsigned int plane = 0;
        uint32_t cc = all_cc & vertex_t::FRUSTUM_CLIP_ALL;
        do {
            if (cc & 1) {
                const GLfixed sd = frustumPlaneDist(plane, s->clip);
                const GLfixed pd = frustumPlaneDist(plane, p->clip);
                if (sd >= 0) {
                    if (pd >= 0) {
                        // both inside
                    } else {
                        // s inside, p outside (exiting)
                        const GLfixed t = clipDivide(sd, sd-pd);
                        c->arrays.clipVertex(c, p, t, p, s);
                    }
                } else {
                    if (pd >= 0) {
                        // s outside (entering)
                        if (pd) {
                            const GLfixed t = clipDivide(pd, pd-sd);
                            c->arrays.clipVertex(c, s, t, s, p);
                        }
                    } else {
                       // both outside
                       return 0;
                    }
                }
            }
            cc >>= 1;
            plane++;
        } while (cc);
    }

    return 2;
}


}; // namespace android
