/* 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)
{
    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)
{
    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
