/* 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.
*/

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

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

#include <cutils/log.h>
#include <cutils/memory.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;
  LOGD(     "  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++) {
        register int32_t ex0 = ey0;
        register int32_t ex1 = ey1;
        register int32_t ex2 = ey2;    
        register 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 )
{
  LOGI( "  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 )
{ 
    LOGI( "%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;
    LOGD(   "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
