/* libs/pixelflinger/trap.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.
*/

#define LOG_TAG "pixelflinger-trap"

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#include <cutils/memory.h>
#include <log/log.h>

#include "trap.h"
#include "picker.h"

namespace android {

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

// enable to see triangles edges
#define DEBUG_TRANGLES  0

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

static void pointx_validate(void *con, const GGLcoord* c, GGLcoord r);
static void pointx(void *con, const GGLcoord* c, GGLcoord r);
static void aa_pointx(void *con, const GGLcoord* c, GGLcoord r);
static void aa_nice_pointx(void *con, const GGLcoord* c, GGLcoord r);

static void linex_validate(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord w);
static void linex(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord w);
static void aa_linex(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord w);

static void recti_validate(void* c, GGLint l, GGLint t, GGLint r, GGLint b); 
static void recti(void* c, GGLint l, GGLint t, GGLint r, GGLint b); 

static void trianglex_validate(void*,
        const GGLcoord*, const GGLcoord*, const GGLcoord*);
static void trianglex_small(void*,
        const GGLcoord*, const GGLcoord*, const GGLcoord*);
static void trianglex_big(void*,
        const GGLcoord*, const GGLcoord*, const GGLcoord*);
static void aa_trianglex(void*,
        const GGLcoord*, const GGLcoord*, const GGLcoord*);
static void trianglex_debug(void* con,
        const GGLcoord*, const GGLcoord*, const GGLcoord*);

static void aapolyx(void* con,
        const GGLcoord* pts, int count);

static inline int min(int a, int b) CONST;
static inline int max(int a, int b) CONST;
static inline int min(int a, int b, int c) CONST;
static inline int max(int a, int b, int c) CONST;

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

inline int min(int a, int b) {
    return a<b ? a : b;
}
inline int max(int a, int b) {
    return a<b ? b : a;
}
inline int min(int a, int b, int c) {
    return min(a,min(b,c));
}
inline int max(int a, int b, int c) {
    return max(a,max(b,c));
}

template <typename T>
static inline void swap(T& a, T& b) {
    T t(a);
    a = b;
    b = t;
}

static void
triangle_dump_points( const GGLcoord*  v0,
                      const GGLcoord*  v1,
                      const GGLcoord*  v2 )
{
    float tri = 1.0f / TRI_ONE;
    ALOGD("  P0=(%.3f, %.3f)  [%08x, %08x]\n"
          "  P1=(%.3f, %.3f)  [%08x, %08x]\n"
          "  P2=(%.3f, %.3f)  [%08x, %08x]\n",
          v0[0]*tri, v0[1]*tri, v0[0], v0[1],
          v1[0]*tri, v1[1]*tri, v1[0], v1[1],
          v2[0]*tri, v2[1]*tri, v2[0], v2[1] );
}

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

void ggl_init_trap(context_t* c)
{
    ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE|GGL_TMU_STATE|GGL_CB_STATE);
}

void ggl_state_changed(context_t* c, int flags)
{
    if (ggl_likely(!c->dirty)) {
        c->procs.pointx     = pointx_validate;
        c->procs.linex      = linex_validate;
        c->procs.recti      = recti_validate;
        c->procs.trianglex  = trianglex_validate;
    }
    c->dirty |= uint32_t(flags);
}

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

void pointx_validate(void *con, const GGLcoord* v, GGLcoord rad)
{
    GGL_CONTEXT(c, con);
    ggl_pick(c);
    if (c->state.needs.p & GGL_NEED_MASK(P_AA)) {
        if (c->state.enables & GGL_ENABLE_POINT_AA_NICE) {
            c->procs.pointx = aa_nice_pointx;
        } else {
            c->procs.pointx = aa_pointx;
        }
    } else {
        c->procs.pointx = pointx;
    }
    c->procs.pointx(con, v, rad);
}

void pointx(void *con, const GGLcoord* v, GGLcoord rad)
{
    GGL_CONTEXT(c, con);
    GGLcoord halfSize = TRI_ROUND(rad) >> 1;
    if (halfSize == 0)
        halfSize = TRI_HALF;
    GGLcoord xc = v[0]; 
    GGLcoord yc = v[1];
    if (halfSize & TRI_HALF) { // size odd
        xc = TRI_FLOOR(xc) + TRI_HALF;
        yc = TRI_FLOOR(yc) + TRI_HALF;
    } else { // size even
        xc = TRI_ROUND(xc);
        yc = TRI_ROUND(yc);
    }
    GGLint l = (xc - halfSize) >> TRI_FRACTION_BITS;
    GGLint t = (yc - halfSize) >> TRI_FRACTION_BITS;
    GGLint r = (xc + halfSize) >> TRI_FRACTION_BITS;
    GGLint b = (yc + halfSize) >> TRI_FRACTION_BITS;
    recti(c, l, t, r, b);
}

// This way of computing the coverage factor, is more accurate and gives
// better results for small circles, but it is also a lot slower.
// Here we use super-sampling.
static int32_t coverageNice(GGLcoord x, GGLcoord y, 
        GGLcoord rmin, GGLcoord rmax, GGLcoord rr)
{
    const GGLcoord d2 = x*x + y*y;
    if (d2 >= rmax) return 0;
    if (d2 < rmin)  return 0x7FFF;

    const int kSamples              =  4;
    const int kInc                  =  4;    // 1/4 = 0.25
    const int kCoverageUnit         =  1;    // 1/(4^2) = 0.0625
    const GGLcoord kCoordOffset     = -6;    // -0.375

    int hits = 0;
    int x_sample = x + kCoordOffset;
    for (int i=0 ; i<kSamples ; i++, x_sample += kInc) {
        const int xval = rr - (x_sample * x_sample);
        int y_sample = y + kCoordOffset;
        for (int j=0 ; j<kSamples ; j++, y_sample += kInc) {
            if (xval - (y_sample * y_sample) > 0)
                hits += kCoverageUnit;
        }
    }
    return min(0x7FFF, hits << (15 - kSamples));
}


void aa_nice_pointx(void *con, const GGLcoord* v, GGLcoord size)
{
    GGL_CONTEXT(c, con);

    GGLcoord rad = ((size + 1)>>1);
    GGLint l = (v[0] - rad) >> TRI_FRACTION_BITS;
    GGLint t = (v[1] - rad) >> TRI_FRACTION_BITS;
    GGLint r = (v[0] + rad + (TRI_ONE-1)) >> TRI_FRACTION_BITS;
    GGLint b = (v[1] + rad + (TRI_ONE-1)) >> TRI_FRACTION_BITS;
    GGLcoord xstart = TRI_FROM_INT(l) - v[0] + TRI_HALF; 
    GGLcoord ystart = TRI_FROM_INT(t) - v[1] + TRI_HALF; 

    // scissor...
    if (l < GGLint(c->state.scissor.left)) {
        xstart += TRI_FROM_INT(c->state.scissor.left-l);
        l = GGLint(c->state.scissor.left);
    }
    if (t < GGLint(c->state.scissor.top)) {
        ystart += TRI_FROM_INT(c->state.scissor.top-t);
        t = GGLint(c->state.scissor.top);
    }
    if (r > GGLint(c->state.scissor.right)) {
        r = GGLint(c->state.scissor.right);
    }
    if (b > GGLint(c->state.scissor.bottom)) {
        b = GGLint(c->state.scissor.bottom);
    }

    int xc = r - l;
    int yc = b - t;
    if (xc>0 && yc>0) {
        int16_t* covPtr = c->state.buffers.coverage;
        const int32_t sqr2Over2 = 0xC; // rounded up
        GGLcoord rr = rad*rad;
        GGLcoord rmin = (rad - sqr2Over2)*(rad - sqr2Over2);
        GGLcoord rmax = (rad + sqr2Over2)*(rad + sqr2Over2);
        GGLcoord y = ystart;
        c->iterators.xl = l;
        c->iterators.xr = r;
        c->init_y(c, t);
        do {
            // compute coverage factors for each pixel
            GGLcoord x = xstart;
            for (int i=l ; i<r ; i++) {
                covPtr[i] = coverageNice(x, y, rmin, rmax, rr);
                x += TRI_ONE;
            }
            y += TRI_ONE;
            c->scanline(c);
            c->step_y(c);
        } while (--yc);
    }
}

// This is a cheap way of computing the coverage factor for a circle.
// We just lerp between the circles of radii r-sqrt(2)/2 and r+sqrt(2)/2
static inline int32_t coverageFast(GGLcoord x, GGLcoord y,
        GGLcoord rmin, GGLcoord rmax, GGLcoord scale)
{
    const GGLcoord d2 = x*x + y*y;
    if (d2 >= rmax) return 0;
    if (d2 < rmin)  return 0x7FFF;
    return 0x7FFF - (d2-rmin)*scale;
}

void aa_pointx(void *con, const GGLcoord* v, GGLcoord size)
{
    GGL_CONTEXT(c, con);

    GGLcoord rad = ((size + 1)>>1);
    GGLint l = (v[0] - rad) >> TRI_FRACTION_BITS;
    GGLint t = (v[1] - rad) >> TRI_FRACTION_BITS;
    GGLint r = (v[0] + rad + (TRI_ONE-1)) >> TRI_FRACTION_BITS;
    GGLint b = (v[1] + rad + (TRI_ONE-1)) >> TRI_FRACTION_BITS;
    GGLcoord xstart = TRI_FROM_INT(l) - v[0] + TRI_HALF; 
    GGLcoord ystart = TRI_FROM_INT(t) - v[1] + TRI_HALF; 

    // scissor...
    if (l < GGLint(c->state.scissor.left)) {
        xstart += TRI_FROM_INT(c->state.scissor.left-l);
        l = GGLint(c->state.scissor.left);
    }
    if (t < GGLint(c->state.scissor.top)) {
        ystart += TRI_FROM_INT(c->state.scissor.top-t);
        t = GGLint(c->state.scissor.top);
    }
    if (r > GGLint(c->state.scissor.right)) {
        r = GGLint(c->state.scissor.right);
    }
    if (b > GGLint(c->state.scissor.bottom)) {
        b = GGLint(c->state.scissor.bottom);
    }

    int xc = r - l;
    int yc = b - t;
    if (xc>0 && yc>0) {
        int16_t* covPtr = c->state.buffers.coverage;
        rad <<= 4;
        const int32_t sqr2Over2 = 0xB5;    // fixed-point 24.8
        GGLcoord rmin = rad - sqr2Over2;
        GGLcoord rmax = rad + sqr2Over2;
        GGLcoord scale;
        rmin *= rmin;
        rmax *= rmax;
        scale = 0x800000 / (rmax - rmin);
        rmin >>= 8;
        rmax >>= 8;

        GGLcoord y = ystart;
        c->iterators.xl = l;
        c->iterators.xr = r;
        c->init_y(c, t);

        do {
            // compute coverage factors for each pixel
            GGLcoord x = xstart;
            for (int i=l ; i<r ; i++) {
                covPtr[i] = coverageFast(x, y, rmin, rmax, scale);
                x += TRI_ONE;
            }
            y += TRI_ONE;
            c->scanline(c);
            c->step_y(c);
        } while (--yc);
    }
}

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

void linex_validate(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord w)
{
    GGL_CONTEXT(c, con);
    ggl_pick(c);
    if (c->state.needs.p & GGL_NEED_MASK(P_AA)) {
        c->procs.linex = aa_linex;
    } else {
        c->procs.linex = linex;
    }
    c->procs.linex(con, v0, v1, w);
}

static void linex(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord width)
{
    GGL_CONTEXT(c, con);
    GGLcoord v[4][2];
    v[0][0] = v0[0];    v[0][1] = v0[1];
    v[1][0] = v1[0];    v[1][1] = v1[1];
    v0 = v[0];
    v1 = v[1];
    const GGLcoord dx = abs(v0[0] - v1[0]);
    const GGLcoord dy = abs(v0[1] - v1[1]);
    GGLcoord nx, ny;
    nx = ny = 0;

    GGLcoord halfWidth = TRI_ROUND(width) >> 1;
    if (halfWidth == 0)
        halfWidth = TRI_HALF;

    ((dx > dy) ? ny : nx) = halfWidth;
    v[2][0] = v1[0];    v[2][1] = v1[1];
    v[3][0] = v0[0];    v[3][1] = v0[1];
    v[0][0] += nx;      v[0][1] += ny;
    v[1][0] += nx;      v[1][1] += ny;
    v[2][0] -= nx;      v[2][1] -= ny;
    v[3][0] -= nx;      v[3][1] -= ny;
    trianglex_big(con, v[0], v[1], v[2]);
    trianglex_big(con, v[0], v[2], v[3]);
}

static void aa_linex(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord width)
{
    GGL_CONTEXT(c, con);
    GGLcoord v[4][2];
    v[0][0] = v0[0];    v[0][1] = v0[1];
    v[1][0] = v1[0];    v[1][1] = v1[1];
    v0 = v[0];
    v1 = v[1];
    
    const GGLcoord dx = v0[0] - v1[0];
    const GGLcoord dy = v0[1] - v1[1];
    GGLcoord nx = -dy;
    GGLcoord ny =  dx;

    // generally, this will be well below 1.0
    const GGLfixed norm = gglMulx(width, gglSqrtRecipx(nx*nx+ny*ny), 4);
    nx = gglMulx(nx, norm, 21);
    ny = gglMulx(ny, norm, 21);
    
    v[2][0] = v1[0];    v[2][1] = v1[1];
    v[3][0] = v0[0];    v[3][1] = v0[1];
    v[0][0] += nx;      v[0][1] += ny;
    v[1][0] += nx;      v[1][1] += ny;
    v[2][0] -= nx;      v[2][1] -= ny;
    v[3][0] -= nx;      v[3][1] -= ny;
    aapolyx(con, v[0], 4);        
}


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

void recti_validate(void *con, GGLint l, GGLint t, GGLint r, GGLint b)
{
    GGL_CONTEXT(c, con);
    ggl_pick(c);
    c->procs.recti = recti;
    c->procs.recti(con, l, t, r, b);
}

void recti(void* con, GGLint l, GGLint t, GGLint r, GGLint b)
{
    GGL_CONTEXT(c, con);

    // scissor...
    if (l < GGLint(c->state.scissor.left))
        l = GGLint(c->state.scissor.left);
    if (t < GGLint(c->state.scissor.top))
        t = GGLint(c->state.scissor.top);
    if (r > GGLint(c->state.scissor.right))
        r = GGLint(c->state.scissor.right);
    if (b > GGLint(c->state.scissor.bottom))
        b = GGLint(c->state.scissor.bottom);

    int xc = r - l;
    int yc = b - t;
    if (xc>0 && yc>0) {
        c->iterators.xl = l;
        c->iterators.xr = r;
        c->init_y(c, t);
        c->rect(c, yc);
    }
}

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

static void scanline_set(context_t* c)
{
    int32_t x = c->iterators.xl;
    size_t ct = c->iterators.xr - x;
    int32_t y = c->iterators.y;
    surface_t* cb = &(c->state.buffers.color);
    const GGLFormat* fp = &(c->formats[cb->format]);
    uint8_t* dst = reinterpret_cast<uint8_t*>(cb->data) +
                            (x + (cb->stride * y)) * fp->size;
    const size_t size = ct * fp->size;
    memset(dst, 0xFF, size);
}

static void trianglex_debug(void* con,
        const GGLcoord* v0, const GGLcoord* v1, const GGLcoord* v2)
{
    GGL_CONTEXT(c, con);
    if (c->state.needs.p & GGL_NEED_MASK(P_AA)) {
        aa_trianglex(con,v0,v1,v2);
    } else {
        trianglex_big(con,v0,v1,v2);
    }
	void (*save_scanline)(context_t*)  = c->scanline;
    c->scanline = scanline_set;
    linex(con, v0, v1, TRI_ONE);
    linex(con, v1, v2, TRI_ONE);
    linex(con, v2, v0, TRI_ONE);
    c->scanline = save_scanline;
}

static void trianglex_xor(void* con,
        const GGLcoord* v0, const GGLcoord* v1, const GGLcoord* v2)
{
    trianglex_big(con,v0,v1,v2);
    trianglex_small(con,v0,v1,v2);
}

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

void trianglex_validate(void *con,
        const GGLcoord* v0, const GGLcoord* v1, const GGLcoord* v2)
{
    GGL_CONTEXT(c, con);
    ggl_pick(c);
    if (c->state.needs.p & GGL_NEED_MASK(P_AA)) {
        c->procs.trianglex = DEBUG_TRANGLES ? trianglex_debug : aa_trianglex;
    } else {
        c->procs.trianglex = DEBUG_TRANGLES ? trianglex_debug : trianglex_big;
    }
    c->procs.trianglex(con, v0, v1, v2);
}

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

void trianglex_small(void* con,
        const GGLcoord* v0, const GGLcoord* v1, const GGLcoord* v2)
{
    GGL_CONTEXT(c, con);

    // vertices are in 28.4 fixed point, which allows
    // us to use 32 bits multiplies below.
    int32_t x0 = v0[0];
    int32_t y0 = v0[1];
    int32_t x1 = v1[0];
    int32_t y1 = v1[1];
    int32_t x2 = v2[0];
    int32_t y2 = v2[1];

    int32_t dx01 = x0 - x1;
    int32_t dy20 = y2 - y0;
    int32_t dy01 = y0 - y1;
    int32_t dx20 = x2 - x0;

    // The code below works only with CCW triangles
    // so if we get a CW triangle, we need to swap two of its vertices
    if (dx01*dy20 < dy01*dx20) {
        swap(x0, x1);
        swap(y0, y1);
        dx01 = x0 - x1;
        dy01 = y0 - y1;
        dx20 = x2 - x0;
        dy20 = y2 - y0;
    }
    int32_t dx12 = x1 - x2;
    int32_t dy12 = y1 - y2;

    // bounding box & scissor
    const int32_t bminx = TRI_FLOOR(min(x0, x1, x2)) >> TRI_FRACTION_BITS;
    const int32_t bminy = TRI_FLOOR(min(y0, y1, y2)) >> TRI_FRACTION_BITS;
    const int32_t bmaxx = TRI_CEIL( max(x0, x1, x2)) >> TRI_FRACTION_BITS;
    const int32_t bmaxy = TRI_CEIL( max(y0, y1, y2)) >> TRI_FRACTION_BITS;
    const int32_t minx = max(bminx, c->state.scissor.left);
    const int32_t miny = max(bminy, c->state.scissor.top);
    const int32_t maxx = min(bmaxx, c->state.scissor.right);
    const int32_t maxy = min(bmaxy, c->state.scissor.bottom);
    if ((minx >= maxx) || (miny >= maxy))
        return; // too small or clipped out...

    // step equations to the bounding box and snap to pixel center
    const int32_t my = (miny << TRI_FRACTION_BITS) + TRI_HALF;
    const int32_t mx = (minx << TRI_FRACTION_BITS) + TRI_HALF;
    int32_t ey0 = dy01 * (x0 - mx) - dx01 * (y0 - my);
    int32_t ey1 = dy12 * (x1 - mx) - dx12 * (y1 - my);
    int32_t ey2 = dy20 * (x2 - mx) - dx20 * (y2 - my);

    // right-exclusive fill rule, to avoid rare cases
    // of over drawing
    if (dy01<0 || (dy01 == 0 && dx01>0)) ey0++;
    if (dy12<0 || (dy12 == 0 && dx12>0)) ey1++;
    if (dy20<0 || (dy20 == 0 && dx20>0)) ey2++;
    
    c->init_y(c, miny);
    for (int32_t y = miny; y < maxy; y++) {
        int32_t ex0 = ey0;
        int32_t ex1 = ey1;
        int32_t ex2 = ey2;    
        int32_t xl, xr;
        for (xl=minx ; xl<maxx ; xl++) {
            if (ex0>0 && ex1>0 && ex2>0)
                break; // all strictly positive
            ex0 -= dy01 << TRI_FRACTION_BITS;
            ex1 -= dy12 << TRI_FRACTION_BITS;
            ex2 -= dy20 << TRI_FRACTION_BITS;
        }
        xr = xl;
        for ( ; xr<maxx ; xr++) {
            if (!(ex0>0 && ex1>0 && ex2>0))
                break; // not all strictly positive
            ex0 -= dy01 << TRI_FRACTION_BITS;
            ex1 -= dy12 << TRI_FRACTION_BITS;
            ex2 -= dy20 << TRI_FRACTION_BITS;
        }

        if (xl < xr) {
            c->iterators.xl = xl;
            c->iterators.xr = xr;
            c->scanline(c);
        }
        c->step_y(c);

        ey0 += dx01 << TRI_FRACTION_BITS;
        ey1 += dx12 << TRI_FRACTION_BITS;
        ey2 += dx20 << TRI_FRACTION_BITS;
    }
}

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

// the following routine fills a triangle via edge stepping, which
// unfortunately requires divisions in the setup phase to get right,
// it should probably only be used for relatively large trianges


// x = y*DX/DY    (ou DX and DY are constants, DY > 0, et y >= 0)
// 
// for an equation of the type:
//      x' = y*K/2^p     (with K and p constants "carefully chosen")
// 
// We can now do a DDA without precision loss. We define 'e' by:
//      x' - x = y*(DX/DY - K/2^p) = y*e
// 
// If we choose K = round(DX*2^p/DY) then,
//      abs(e) <= 1/2^(p+1) by construction
// 
// therefore abs(x'-x) = y*abs(e) <= y/2^(p+1) <= DY/2^(p+1) <= DMAX/2^(p+1)
// 
// which means that if DMAX <= 2^p, therefore abs(x-x') <= 1/2, including
// at the last line. In fact, it's even a strict inequality except in one
// extrem case (DY == DMAX et e = +/- 1/2)
// 
// Applying that to our coordinates, we need 2^p >= 4096*16 = 65536
// so p = 16 is enough, we're so lucky!

const int TRI_ITERATORS_BITS = 16;

struct Edge
{
  int32_t  x;      // edge position in 16.16 coordinates
  int32_t  x_incr; // on each step, increment x by that amount
  int32_t  y_top;  // starting scanline, 16.4 format
  int32_t  y_bot;
};

static void
edge_dump( Edge*  edge )
{
  ALOGI( "  top=%d (%.3f)  bot=%d (%.3f)  x=%d (%.3f)  ix=%d (%.3f)",
        edge->y_top, edge->y_top/float(TRI_ONE),
		edge->y_bot, edge->y_bot/float(TRI_ONE),
		edge->x, edge->x/float(FIXED_ONE),
		edge->x_incr, edge->x_incr/float(FIXED_ONE) );
}

static void
triangle_dump_edges( Edge*  edges,
                     int            count )
{ 
    ALOGI( "%d edge%s:\n", count, count == 1 ? "" : "s" );
	for ( ; count > 0; count--, edges++ )
	  edge_dump( edges );
}

// the following function sets up an edge, it assumes
// that ymin and ymax are in already in the 'reduced'
// format
static __attribute__((noinline))
void edge_setup(
        Edge*           edges,
        int*            pcount,
        const GGLcoord* p1,
        const GGLcoord* p2,
        int32_t         ymin,
        int32_t         ymax )
{
	const GGLfixed*  top = p1;
	const GGLfixed*  bot = p2;
	Edge*    edge = edges + *pcount;

	if (top[1] > bot[1]) {
        swap(top, bot);
	}

	int  y1 = top[1] | 1;
	int  y2 = bot[1] | 1;
	int  dy = y2 - y1;

	if ( dy == 0 || y1 > ymax || y2 < ymin )
		return;

	if ( y1 > ymin )
		ymin = TRI_SNAP_NEXT_HALF(y1);
	
	if ( y2 < ymax )
		ymax = TRI_SNAP_PREV_HALF(y2);

	if ( ymin > ymax )  // when the edge doesn't cross any scanline
	  return;

	const int x1 = top[0];
	const int dx = bot[0] - x1;
    const int shift = TRI_ITERATORS_BITS - TRI_FRACTION_BITS;

	// setup edge fields
    // We add 0.5 to edge->x here because it simplifies the rounding
    // in triangle_sweep_edges() -- this doesn't change the ordering of 'x'
	edge->x      = (x1 << shift) + (1LU << (TRI_ITERATORS_BITS-1));
	edge->x_incr = 0;
	edge->y_top  = ymin;
	edge->y_bot  = ymax;

	if (ggl_likely(ymin <= ymax && dx)) {
        edge->x_incr = gglDivQ16(dx, dy);
    }
    if (ggl_likely(y1 < ymin)) {
        int32_t xadjust = (edge->x_incr * (ymin-y1)) >> TRI_FRACTION_BITS;
        edge->x += xadjust;
    }
  
	++*pcount;
}


static void
triangle_sweep_edges( Edge*  left,
                      Edge*  right,
					  int            ytop,
					  int            ybot,
					  context_t*     c )
{
    int count = ((ybot - ytop)>>TRI_FRACTION_BITS) + 1;
    if (count<=0) return;

    // sort the edges horizontally
    if ((left->x > right->x) || 
        ((left->x == right->x) && (left->x_incr > right->x_incr))) {
        swap(left, right);
    }

    int left_x = left->x;
    int right_x = right->x;
    const int left_xi = left->x_incr;
    const int right_xi  = right->x_incr;
    left->x  += left_xi * count;
    right->x += right_xi * count;

	const int xmin = c->state.scissor.left;
	const int xmax = c->state.scissor.right;
    do {
        // horizontal scissoring
        const int32_t xl = max(left_x  >> TRI_ITERATORS_BITS, xmin);
        const int32_t xr = min(right_x >> TRI_ITERATORS_BITS, xmax);
        left_x  += left_xi;
        right_x += right_xi;
        // invoke the scanline rasterizer
        if (ggl_likely(xl < xr)) {
            c->iterators.xl = xl;
            c->iterators.xr = xr;
            c->scanline(c);
        }
		c->step_y(c);
	} while (--count);
}


void trianglex_big(void* con,
        const GGLcoord* v0, const GGLcoord* v1, const GGLcoord* v2)
{
    GGL_CONTEXT(c, con);

    Edge edges[3];
	int num_edges = 0;
	int32_t ymin = TRI_FROM_INT(c->state.scissor.top)    + TRI_HALF;
	int32_t ymax = TRI_FROM_INT(c->state.scissor.bottom) - TRI_HALF;
	    
	edge_setup( edges, &num_edges, v0, v1, ymin, ymax );
	edge_setup( edges, &num_edges, v0, v2, ymin, ymax );
	edge_setup( edges, &num_edges, v1, v2, ymin, ymax );

    if (ggl_unlikely(num_edges<2))  // for really tiny triangles that don't
		return;                     // cross any scanline centers

    Edge* left  = &edges[0];
    Edge* right = &edges[1];
    Edge* other = &edges[2];
    int32_t y_top = min(left->y_top, right->y_top);
    int32_t y_bot = max(left->y_bot, right->y_bot);

	if (ggl_likely(num_edges==3)) {
        y_top = min(y_top, edges[2].y_top);
        y_bot = max(y_bot, edges[2].y_bot);
		if (edges[0].y_top > y_top) {
            other = &edges[0];
            left  = &edges[2];
		} else if (edges[1].y_top > y_top) {
            other = &edges[1];
            right = &edges[2];
		}
    }

    c->init_y(c, y_top >> TRI_FRACTION_BITS);

    int32_t y_mid = min(left->y_bot, right->y_bot);
    triangle_sweep_edges( left, right, y_top, y_mid, c );

    // second scanline sweep loop, if necessary
    y_mid += TRI_ONE;
    if (y_mid <= y_bot) {
        ((left->y_bot == y_bot) ? right : left) = other;
        if (other->y_top < y_mid) {
            other->x += other->x_incr;
        }
        triangle_sweep_edges( left, right, y_mid, y_bot, c );
    }
}

void aa_trianglex(void* con,
        const GGLcoord* a, const GGLcoord* b, const GGLcoord* c)
{
    GGLcoord pts[6] = { a[0], a[1], b[0], b[1], c[0], c[1] };
    aapolyx(con, pts, 3);
}

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

struct AAEdge
{
    GGLfixed x;         // edge position in 12.16 coordinates
    GGLfixed x_incr;    // on each y step, increment x by that amount
    GGLfixed y_incr;    // on each x step, increment y by that amount
    int16_t y_top;      // starting scanline, 12.4 format
    int16_t y_bot;      // starting scanline, 12.4 format
    void dump();
};

void AAEdge::dump()
{
    float tri  = 1.0f / TRI_ONE;
    float iter = 1.0f / (1<<TRI_ITERATORS_BITS);
    float fix  = 1.0f / FIXED_ONE;
    ALOGD(   "x=%08x (%.3f), "
            "x_incr=%08x (%.3f), y_incr=%08x (%.3f), "
            "y_top=%08x (%.3f), y_bot=%08x (%.3f) ",
        x, x*fix,
        x_incr, x_incr*iter,
        y_incr, y_incr*iter,
        y_top, y_top*tri,
        y_bot, y_bot*tri );
}

// the following function sets up an edge, it assumes
// that ymin and ymax are in already in the 'reduced'
// format
static __attribute__((noinline))
void aa_edge_setup(
        AAEdge*         edges,
        int*            pcount,
        const GGLcoord* p1,
        const GGLcoord* p2,
        int32_t         ymin,
        int32_t         ymax )
{
    const GGLfixed*  top = p1;
    const GGLfixed*  bot = p2;
    AAEdge* edge = edges + *pcount;

    if (top[1] > bot[1])
        swap(top, bot);

    int  y1 = top[1];
    int  y2 = bot[1];
    int  dy = y2 - y1;

    if (dy==0 || y1>ymax || y2<ymin)
        return;

    if (y1 > ymin)
        ymin = y1;
    
    if (y2 < ymax)
        ymax = y2;

    const int x1 = top[0];
    const int dx = bot[0] - x1;
    const int shift = FIXED_BITS - TRI_FRACTION_BITS;

    // setup edge fields
    edge->x      = x1 << shift;
    edge->x_incr = 0;
    edge->y_top  = ymin;
    edge->y_bot  = ymax;
    edge->y_incr = 0x7FFFFFFF;

    if (ggl_likely(ymin <= ymax && dx)) {
        edge->x_incr = gglDivQ16(dx, dy);
        if (dx != 0) {
            edge->y_incr = abs(gglDivQ16(dy, dx));
        }
    }
    if (ggl_likely(y1 < ymin)) {
        int32_t xadjust = (edge->x_incr * (ymin-y1))
                >> (TRI_FRACTION_BITS + TRI_ITERATORS_BITS - FIXED_BITS);
        edge->x += xadjust;
    }
  
    ++*pcount;
}


typedef int (*compar_t)(const void*, const void*);
static int compare_edges(const AAEdge *e0, const AAEdge *e1) {
    if (e0->y_top > e1->y_top)      return 1;
    if (e0->y_top < e1->y_top)      return -1;
    if (e0->x > e1->x)              return 1;
    if (e0->x < e1->x)              return -1;
    if (e0->x_incr > e1->x_incr)    return 1;
    if (e0->x_incr < e1->x_incr)    return -1;
    return 0; // same edges, should never happen
}

static inline 
void SET_COVERAGE(int16_t*& p, int32_t value, ssize_t n)
{
    android_memset16((uint16_t*)p, value, n*2);
    p += n;
}

static inline 
void ADD_COVERAGE(int16_t*& p, int32_t value)
{
    value = *p + value;
    if (value >= 0x8000)
        value = 0x7FFF;
    *p++ = value;
}

static inline
void SUB_COVERAGE(int16_t*& p, int32_t value)
{
    value = *p - value;
    value &= ~(value>>31);
    *p++ = value;
}

void aapolyx(void* con,
        const GGLcoord* pts, int count)
{
    /*
     * NOTE: This routine assumes that the polygon has been clipped to the
     * viewport already, that is, no vertex lies outside of the framebuffer.
     * If this happens, the code below won't corrupt memory but the 
     * coverage values may not be correct.
     */
    
    GGL_CONTEXT(c, con);

    // we do only quads for now (it's used for thick lines)
    if ((count>4) || (count<2)) return;

    // take scissor into account
    const int xmin = c->state.scissor.left;
    const int xmax = c->state.scissor.right;
    if (xmin >= xmax) return;

    // generate edges from the vertices
    int32_t ymin = TRI_FROM_INT(c->state.scissor.top);
    int32_t ymax = TRI_FROM_INT(c->state.scissor.bottom);
    if (ymin >= ymax) return;

    AAEdge edges[4];
    int num_edges = 0;
    GGLcoord const * p = pts;
    for (int i=0 ; i<count-1 ; i++, p+=2) {
        aa_edge_setup(edges, &num_edges, p, p+2, ymin, ymax);
    }
    aa_edge_setup(edges, &num_edges, p, pts, ymin, ymax );
    if (ggl_unlikely(num_edges<2))
        return;

    // sort the edge list top to bottom, left to right.
    qsort(edges, num_edges, sizeof(AAEdge), (compar_t)compare_edges);

    int16_t* const covPtr = c->state.buffers.coverage;
    memset(covPtr+xmin, 0, (xmax-xmin)*sizeof(*covPtr));

    // now, sweep all edges in order
    // start with the 2 first edges. We know that they share their top
    // vertex, by construction.
    int i = 2;
    AAEdge* left  = &edges[0];
    AAEdge* right = &edges[1];
    int32_t yt = left->y_top;
    GGLfixed l = left->x;
    GGLfixed r = right->x;
    int retire = 0;
    int16_t* coverage;

    // at this point we can initialize the rasterizer    
    c->init_y(c, yt>>TRI_FRACTION_BITS);
    c->iterators.xl = xmax;
    c->iterators.xr = xmin;

    do {
        int32_t y = min(min(left->y_bot, right->y_bot), TRI_FLOOR(yt + TRI_ONE));
        const int32_t shift = TRI_FRACTION_BITS + TRI_ITERATORS_BITS - FIXED_BITS;
        const int cf_shift = (1 + TRI_FRACTION_BITS*2 + TRI_ITERATORS_BITS - 15);

        // compute xmin and xmax for the left edge
        GGLfixed l_min = gglMulAddx(left->x_incr, y - left->y_top, left->x, shift);
        GGLfixed l_max = l;
        l = l_min;
        if (l_min > l_max)
            swap(l_min, l_max);

        // compute xmin and xmax for the right edge
        GGLfixed r_min = gglMulAddx(right->x_incr, y - right->y_top, right->x, shift);
        GGLfixed r_max = r;
        r = r_min;
        if (r_min > r_max)
            swap(r_min, r_max);

        // make sure we're not touching coverage values outside of the
        // framebuffer
        l_min &= ~(l_min>>31);
        r_min &= ~(r_min>>31);
        l_max &= ~(l_max>>31);
        r_max &= ~(r_max>>31);
        if (gglFixedToIntFloor(l_min) >= xmax) l_min = gglIntToFixed(xmax)-1;
        if (gglFixedToIntFloor(r_min) >= xmax) r_min = gglIntToFixed(xmax)-1;
        if (gglFixedToIntCeil(l_max) >= xmax)  l_max = gglIntToFixed(xmax)-1;
        if (gglFixedToIntCeil(r_max) >= xmax)  r_max = gglIntToFixed(xmax)-1;

        // compute the integer versions of the above
        const GGLfixed l_min_i = gglFloorx(l_min);
        const GGLfixed l_max_i = gglCeilx (l_max);
        const GGLfixed r_min_i = gglFloorx(r_min);
        const GGLfixed r_max_i = gglCeilx (r_max);

        // clip horizontally using the scissor
        const int xml = max(xmin, gglFixedToIntFloor(l_min_i));
        const int xmr = min(xmax, gglFixedToIntFloor(r_max_i));

        // if we just stepped to a new scanline, render the previous one.
        // and clear the coverage buffer
        if (retire) {
            if (c->iterators.xl < c->iterators.xr)
                c->scanline(c);
            c->step_y(c);
            memset(covPtr+xmin, 0, (xmax-xmin)*sizeof(*covPtr));
            c->iterators.xl = xml;
            c->iterators.xr = xmr;
        } else {
            // update the horizontal range of this scanline
            c->iterators.xl = min(c->iterators.xl, xml);
            c->iterators.xr = max(c->iterators.xr, xmr);
        }

        coverage = covPtr + gglFixedToIntFloor(l_min_i);
        if (l_min_i == gglFloorx(l_max)) {
            
            /*
             *  fully traverse this pixel vertically
             *       l_max
             *  +-----/--+  yt
             *  |    /   |  
             *  |   /    |
             *  |  /     |
             *  +-/------+  y
             *   l_min  (l_min_i + TRI_ONE)
             */
              
            GGLfixed dx = l_max - l_min;
            int32_t dy = y - yt;
            int cf = gglMulx((dx >> 1) + (l_min_i + FIXED_ONE - l_max), dy,
                FIXED_BITS + TRI_FRACTION_BITS - 15);
            ADD_COVERAGE(coverage, cf);
            // all pixels on the right have cf = 1.0
        } else {
            /*
             *  spans several pixels in one scanline
             *            l_max
             *  +--------+--/-----+  yt
             *  |        |/       |
             *  |       /|        |
             *  |     /  |        |
             *  +---/----+--------+  y
             *   l_min (l_min_i + TRI_ONE)
             */

            // handle the first pixel separately...
            const int32_t y_incr = left->y_incr;
            int32_t dx = TRI_FROM_FIXED(l_min_i - l_min) + TRI_ONE;
            int32_t cf = (dx * dx * y_incr) >> cf_shift;
            ADD_COVERAGE(coverage, cf);

            // following pixels get covered by y_incr, but we need
            // to fix-up the cf to account for previous partial pixel
            dx = TRI_FROM_FIXED(l_min - l_min_i);
            cf -= (dx * dx * y_incr) >> cf_shift;
            for (int x = l_min_i+FIXED_ONE ; x < l_max_i-FIXED_ONE ; x += FIXED_ONE) {
                cf += y_incr >> (TRI_ITERATORS_BITS-15);
                ADD_COVERAGE(coverage, cf);
            }
            
            // and the last pixel
            dx = TRI_FROM_FIXED(l_max - l_max_i) - TRI_ONE;
            cf += (dx * dx * y_incr) >> cf_shift;
            ADD_COVERAGE(coverage, cf);
        }
        
        // now, fill up all fully covered pixels
        coverage = covPtr + gglFixedToIntFloor(l_max_i);
        int cf = ((y - yt) << (15 - TRI_FRACTION_BITS));
        if (ggl_likely(cf >= 0x8000)) {
            SET_COVERAGE(coverage, 0x7FFF, ((r_max - l_max_i)>>FIXED_BITS)+1);
        } else {
            for (int x=l_max_i ; x<r_max ; x+=FIXED_ONE) {
                ADD_COVERAGE(coverage, cf);
            }
        }
        
        // subtract the coverage of the right edge
        coverage = covPtr + gglFixedToIntFloor(r_min_i); 
        if (r_min_i == gglFloorx(r_max)) {
            GGLfixed dx = r_max - r_min;
            int32_t dy = y - yt;
            int cf = gglMulx((dx >> 1) + (r_min_i + FIXED_ONE - r_max), dy,
                FIXED_BITS + TRI_FRACTION_BITS - 15);
            SUB_COVERAGE(coverage, cf);
            // all pixels on the right have cf = 1.0
        } else {
            // handle the first pixel separately...
            const int32_t y_incr = right->y_incr;
            int32_t dx = TRI_FROM_FIXED(r_min_i - r_min) + TRI_ONE;
            int32_t cf = (dx * dx * y_incr) >> cf_shift;
            SUB_COVERAGE(coverage, cf);
            
            // following pixels get covered by y_incr, but we need
            // to fix-up the cf to account for previous partial pixel
            dx = TRI_FROM_FIXED(r_min - r_min_i);
            cf -= (dx * dx * y_incr) >> cf_shift;
            for (int x = r_min_i+FIXED_ONE ; x < r_max_i-FIXED_ONE ; x += FIXED_ONE) {
                cf += y_incr >> (TRI_ITERATORS_BITS-15);
                SUB_COVERAGE(coverage, cf);
            }
            
            // and the last pixel
            dx = TRI_FROM_FIXED(r_max - r_max_i) - TRI_ONE;
            cf += (dx * dx * y_incr) >> cf_shift;
            SUB_COVERAGE(coverage, cf);
        }

        // did we reach the end of an edge? if so, get a new one.
        if (y == left->y_bot || y == right->y_bot) {
            // bail out if we're done
            if (i>=num_edges)
                break;
            if (y == left->y_bot)
                left = &edges[i++];
            if (y == right->y_bot)
                right = &edges[i++];
        }

        // next scanline
        yt = y;
        
        // did we just finish a scanline?        
        retire = (y << (32-TRI_FRACTION_BITS)) == 0;
    } while (true);

    // render the last scanline
    if (c->iterators.xl < c->iterators.xr)
        c->scanline(c);
}

}; // namespace android
