/*
 * Copyright (C) 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.
 */

#ifndef ANDROID_GGL_CONTEXT_H
#define ANDROID_GGL_CONTEXT_H

#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <sys/types.h>
#include <endian.h>

#include <pixelflinger/pixelflinger.h>
#include <private/pixelflinger/ggl_fixed.h>

namespace android {

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

#if BYTE_ORDER == LITTLE_ENDIAN

inline uint32_t GGL_RGBA_TO_HOST(uint32_t v) {
    return v;
}
inline uint32_t GGL_HOST_TO_RGBA(uint32_t v) {
    return v;
}

#else

inline uint32_t GGL_RGBA_TO_HOST(uint32_t v) {
#if defined(__mips__) && __mips_isa_rev>=2
    uint32_t r;
    __asm__("wsbh %0, %1;"
        "rotr %0, %0, 16"
        : "=r" (r)
        : "r" (v)
        );
    return r;
#else
    return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00);
#endif
}
inline uint32_t GGL_HOST_TO_RGBA(uint32_t v) {
#if defined(__mips__) && __mips_isa_rev>=2
    uint32_t r;
    __asm__("wsbh %0, %1;"
        "rotr %0, %0, 16"
        : "=r" (r)
        : "r" (v)
        );
    return r;
#else
    return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00);
#endif
}

#endif

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

const int GGL_DITHER_BITS = 6;  // dither weights stored on 6 bits
const int GGL_DITHER_ORDER_SHIFT= 3;
const int GGL_DITHER_ORDER      = (1<<GGL_DITHER_ORDER_SHIFT);
const int GGL_DITHER_SIZE       = GGL_DITHER_ORDER * GGL_DITHER_ORDER;
const int GGL_DITHER_MASK       = GGL_DITHER_ORDER-1;

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

const int GGL_SUBPIXEL_BITS = 4;

// TRI_FRACTION_BITS defines the number of bits we want to use
// for the sub-pixel coordinates during the edge stepping, the
// value shouldn't be more than 7, or bad things are going to
// happen when drawing large triangles (8 doesn't work because
// 32 bit muls will loose the sign bit)

#define  TRI_FRACTION_BITS  (GGL_SUBPIXEL_BITS)
#define  TRI_ONE            (1 << TRI_FRACTION_BITS)
#define  TRI_HALF           (1 << (TRI_FRACTION_BITS-1))
#define  TRI_FROM_INT(x)    ((x) << TRI_FRACTION_BITS)
#define  TRI_FRAC(x)        ((x)                 &  (TRI_ONE-1))
#define  TRI_FLOOR(x)       ((x)                 & ~(TRI_ONE-1))
#define  TRI_CEIL(x)        (((x) + (TRI_ONE-1)) & ~(TRI_ONE-1))
#define  TRI_ROUND(x)       (((x) +  TRI_HALF  ) & ~(TRI_ONE-1))

#define  TRI_ROUDNING       (1 << (16 - TRI_FRACTION_BITS - 1))
#define  TRI_FROM_FIXED(x)  (((x)+TRI_ROUDNING) >> (16-TRI_FRACTION_BITS))

#define  TRI_SNAP_NEXT_HALF(x)   (TRI_CEIL((x)+TRI_HALF) - TRI_HALF)
#define  TRI_SNAP_PREV_HALF(x)   (TRI_CEIL((x)-TRI_HALF) - TRI_HALF)

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

const int GGL_COLOR_BITS = 24;

// To maintain 8-bits color chanels, with a maximum GGLSurface
// size of 4096 and GGL_SUBPIXEL_BITS=4, we need 8 + 12 + 4 = 24 bits
// for encoding the color iterators

inline GGLcolor gglFixedToIteratedColor(GGLfixed c) {
    return (c << 8) - c;
}

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

template<bool> struct CTA;
template<> struct CTA<true> { };

#define GGL_CONTEXT(con, c)         context_t *con = static_cast<context_t *>(c)
#define GGL_OFFSETOF(field)         uintptr_t(&(((context_t*)0)->field))
#define GGL_INIT_PROC(p, f)         p.f = ggl_ ## f;
#define GGL_BETWEEN(x, L, H)        (uint32_t((x)-(L)) <= ((H)-(L)))

#define ggl_likely(x)	__builtin_expect(!!(x), 1)
#define ggl_unlikely(x)	__builtin_expect(!!(x), 0)

const int GGL_TEXTURE_UNIT_COUNT    = 2;
const int GGL_TMU_STATE             = 0x00000001;
const int GGL_CB_STATE              = 0x00000002;
const int GGL_PIXEL_PIPELINE_STATE  = 0x00000004;

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

#define GGL_RESERVE_NEEDS(name, l, s)                               \
    const uint32_t  GGL_NEEDS_##name##_MASK = (((1LU<<(s))-1)<<l);  \
    const uint32_t  GGL_NEEDS_##name##_SHIFT = (l);

#define GGL_BUILD_NEEDS(val, name)                                  \
    (((val)<<(GGL_NEEDS_##name##_SHIFT)) & GGL_NEEDS_##name##_MASK)

#define GGL_READ_NEEDS(name, n)                                     \
    (uint32_t(n & GGL_NEEDS_##name##_MASK) >> GGL_NEEDS_##name##_SHIFT)

#define GGL_NEED_MASK(name)     (uint32_t(GGL_NEEDS_##name##_MASK))
#define GGL_NEED(name, val)     GGL_BUILD_NEEDS(val, name)

GGL_RESERVE_NEEDS( CB_FORMAT,       0, 6 )
GGL_RESERVE_NEEDS( SHADE,           6, 1 )
GGL_RESERVE_NEEDS( W,               7, 1 )
GGL_RESERVE_NEEDS( BLEND_SRC,       8, 4 )
GGL_RESERVE_NEEDS( BLEND_DST,      12, 4 )
GGL_RESERVE_NEEDS( BLEND_SRCA,     16, 4 )
GGL_RESERVE_NEEDS( BLEND_DSTA,     20, 4 )
GGL_RESERVE_NEEDS( LOGIC_OP,       24, 4 )
GGL_RESERVE_NEEDS( MASK_ARGB,      28, 4 )

GGL_RESERVE_NEEDS( P_ALPHA_TEST,    0, 3 )
GGL_RESERVE_NEEDS( P_AA,            3, 1 )
GGL_RESERVE_NEEDS( P_DEPTH_TEST,    4, 3 )
GGL_RESERVE_NEEDS( P_MASK_Z,        7, 1 )
GGL_RESERVE_NEEDS( P_DITHER,        8, 1 )
GGL_RESERVE_NEEDS( P_FOG,           9, 1 )
GGL_RESERVE_NEEDS( P_RESERVED1,    10,22 )

GGL_RESERVE_NEEDS( T_FORMAT,        0, 6 )
GGL_RESERVE_NEEDS( T_RESERVED0,     6, 1 )
GGL_RESERVE_NEEDS( T_POT,           7, 1 )
GGL_RESERVE_NEEDS( T_S_WRAP,        8, 2 )
GGL_RESERVE_NEEDS( T_T_WRAP,       10, 2 )
GGL_RESERVE_NEEDS( T_ENV,          12, 3 )
GGL_RESERVE_NEEDS( T_LINEAR,       15, 1 )

const int GGL_NEEDS_WRAP_CLAMP_TO_EDGE  = 0;
const int GGL_NEEDS_WRAP_REPEAT         = 1;
const int GGL_NEEDS_WRAP_11             = 2;

inline uint32_t ggl_wrap_to_needs(uint32_t e) {
    switch (e) {
    case GGL_CLAMP:         return GGL_NEEDS_WRAP_CLAMP_TO_EDGE;
    case GGL_REPEAT:        return GGL_NEEDS_WRAP_REPEAT;
    }
    return 0;
}

inline uint32_t ggl_blendfactor_to_needs(uint32_t b) {
    if (b <= 1) return b;
    return (b & 0xF)+2;
}

inline uint32_t ggl_needs_to_blendfactor(uint32_t n) {
    if (n <= 1) return n;
    return (n - 2) + 0x300;
}

inline uint32_t ggl_env_to_needs(uint32_t e) {
    switch (e) {
    case GGL_REPLACE:   return 0;
    case GGL_MODULATE:  return 1;
    case GGL_DECAL:     return 2;
    case GGL_BLEND:     return 3;
    case GGL_ADD:       return 4;
    }
    return 0;
}

inline uint32_t ggl_needs_to_env(uint32_t n) {
    const uint32_t envs[] = { GGL_REPLACE, GGL_MODULATE, 
            GGL_DECAL, GGL_BLEND, GGL_ADD };
    return envs[n];

}

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

enum {
    GGL_ENABLE_BLENDING     = 0x00000001,
    GGL_ENABLE_SMOOTH       = 0x00000002,
    GGL_ENABLE_AA           = 0x00000004,
    GGL_ENABLE_LOGIC_OP     = 0x00000008,
    GGL_ENABLE_ALPHA_TEST   = 0x00000010,
    GGL_ENABLE_SCISSOR_TEST = 0x00000020,
    GGL_ENABLE_TMUS         = 0x00000040,
    GGL_ENABLE_DEPTH_TEST   = 0x00000080,
    GGL_ENABLE_STENCIL_TEST = 0x00000100,
    GGL_ENABLE_W            = 0x00000200,
    GGL_ENABLE_DITHER       = 0x00000400,
    GGL_ENABLE_FOG          = 0x00000800,
    GGL_ENABLE_POINT_AA_NICE= 0x00001000
};

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

struct needs_filter_t;
struct needs_t {
    inline int match(const needs_filter_t& filter);
    inline bool operator == (const needs_t& rhs) const {
        return  (n==rhs.n) &&
                (p==rhs.p) &&
                (t[0]==rhs.t[0]) &&
                (t[1]==rhs.t[1]);
    }
    inline bool operator != (const needs_t& rhs) const {
        return !operator == (rhs);
    }
    uint32_t    n;
    uint32_t    p;
    uint32_t    t[GGL_TEXTURE_UNIT_COUNT];
};

inline int compare_type(const needs_t& lhs, const needs_t& rhs) {
    return memcmp(&lhs, &rhs, sizeof(needs_t));
}

struct needs_filter_t {
    needs_t     value;
    needs_t     mask;
};

int needs_t::match(const needs_filter_t& filter) {
    uint32_t result = 
        ((filter.value.n ^ n)       & filter.mask.n)    |
        ((filter.value.p ^ p)       & filter.mask.p)    |
        ((filter.value.t[0] ^ t[0]) & filter.mask.t[0]) |
        ((filter.value.t[1] ^ t[1]) & filter.mask.t[1]);
    return (result == 0);
}

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

struct context_t;
class Assembly;

struct blend_state_t {
	uint32_t			src;
	uint32_t			dst;
	uint32_t			src_alpha;
	uint32_t			dst_alpha;
	uint8_t				reserved;
	uint8_t				alpha_separate;
	uint8_t				operation;
	uint8_t				equation;
};

struct mask_state_t {
    uint8_t             color;
    uint8_t             depth;
    uint32_t            stencil;
};

struct clear_state_t {
    GGLclampx           r;
    GGLclampx           g;
    GGLclampx           b;
    GGLclampx           a;
    GGLclampx           depth;
    GGLint              stencil;
    uint32_t            colorPacked;
    uint32_t            depthPacked;
    uint32_t            stencilPacked;
    uint32_t            dirty;
};

struct fog_state_t {
    uint8_t     color[4];
};

struct logic_op_state_t {
    uint16_t            opcode;
};

struct alpha_test_state_t {
    uint16_t            func;
    GGLcolor            ref;
};

struct depth_test_state_t {
    uint16_t            func;
    GGLclampx           clearValue;
};

struct scissor_t {
    uint32_t            user_left;
    uint32_t            user_right;
    uint32_t            user_top;
    uint32_t            user_bottom;
    uint32_t            left;
    uint32_t            right;
    uint32_t            top;
    uint32_t            bottom;
};

struct pixel_t {
    uint32_t    c[4];
    uint8_t     s[4];
};

struct surface_t {
    union {
        GGLSurface          s;
        // Keep the following struct field types in line with the corresponding
        // GGLSurface fields to avoid mismatches leading to errors.
        struct {
            GGLsizei        reserved;
            GGLuint         width;
            GGLuint         height;
            GGLint          stride;
            GGLubyte*       data;
            GGLubyte        format;
            GGLubyte        dirty;
            GGLubyte        pad[2];
        };
    };
    void                (*read) (const surface_t* s, context_t* c,
                                uint32_t x, uint32_t y, pixel_t* pixel);
    void                (*write)(const surface_t* s, context_t* c,
                                uint32_t x, uint32_t y, const pixel_t* pixel);
};

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

struct texture_shade_t {
    union {
        struct {
            int32_t             is0;
            int32_t             idsdx;
            int32_t             idsdy;
            int                 sscale;
            int32_t             it0;
            int32_t             idtdx;
            int32_t             idtdy;
            int                 tscale;
        };
        struct {
            int32_t             v;
            int32_t             dx;
            int32_t             dy;
            int                 scale;
        } st[2];
    };
};

struct texture_iterators_t {
    // these are not encoded in the same way than in the
    // texture_shade_t structure
    union {
        struct {
            GGLfixed			ydsdy;
            GGLfixed            dsdx;
            GGLfixed            dsdy;
            int                 sscale;
            GGLfixed			ydtdy;
            GGLfixed            dtdx;
            GGLfixed            dtdy;
            int                 tscale;
        };
        struct {
            GGLfixed			ydvdy;
            GGLfixed            dvdx;
            GGLfixed            dvdy;
            int                 scale;
        } st[2];
    };
};

struct texture_t {
	surface_t			surface;
	texture_iterators_t	iterators;
    texture_shade_t     shade;
	uint32_t			s_coord;
	uint32_t            t_coord;
	uint16_t			s_wrap;
	uint16_t            t_wrap;
	uint16_t            min_filter;
	uint16_t            mag_filter;
    uint16_t            env;
    uint8_t             env_color[4];
	uint8_t				enable;
	uint8_t				dirty;
};

struct raster_t {
    GGLfixed            x;
    GGLfixed            y;
};

struct framebuffer_t {
    surface_t           color;
    surface_t           read;
	surface_t			depth;
	surface_t			stencil;
    int16_t             *coverage;
    size_t              coverageBufferSize;
};

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

struct iterators_t {
	int32_t             xl;
	int32_t             xr;
    int32_t             y;
	GGLcolor			ydady;
	GGLcolor			ydrdy;
	GGLcolor			ydgdy;
	GGLcolor			ydbdy;
	GGLfixed			ydzdy;
	GGLfixed			ydwdy;
	GGLfixed			ydfdy;
};

struct shade_t {
	GGLcolor			a0;
    GGLcolor            dadx;
    GGLcolor            dady;
	GGLcolor			r0;
    GGLcolor            drdx;
    GGLcolor            drdy;
	GGLcolor			g0;
    GGLcolor            dgdx;
    GGLcolor            dgdy;
	GGLcolor			b0;
    GGLcolor            dbdx;
    GGLcolor            dbdy;
	uint32_t            z0;
    GGLfixed32          dzdx;
    GGLfixed32          dzdy;
	GGLfixed            w0;
    GGLfixed            dwdx;
    GGLfixed            dwdy;
	uint32_t			f0;
    GGLfixed            dfdx;
    GGLfixed            dfdy;
};

// these are used in the generated code
// we use this mirror structure to improve
// data locality in the pixel pipeline
struct generated_tex_vars_t {
    uint32_t    width;
    uint32_t    height;
    uint32_t    stride;
    uintptr_t   data;
    int32_t     dsdx;
    int32_t     dtdx;
    int32_t     spill[2];
};

struct generated_vars_t {
    struct {
        int32_t c;
        int32_t dx;
    } argb[4];
    int32_t     aref;
    int32_t     dzdx;
    int32_t     zbase;
    int32_t     f;
    int32_t     dfdx;
    int32_t     spill[3];
    generated_tex_vars_t    texture[GGL_TEXTURE_UNIT_COUNT];
    int32_t     rt;
    int32_t     lb;
};

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

struct state_t {
	framebuffer_t		buffers;
	texture_t			texture[GGL_TEXTURE_UNIT_COUNT];
    scissor_t           scissor;
    raster_t            raster;
	blend_state_t		blend;
    alpha_test_state_t  alpha_test;
    depth_test_state_t  depth_test;
    mask_state_t        mask;
    clear_state_t       clear;
    fog_state_t         fog;
    logic_op_state_t    logic_op;
    uint32_t            enables;
    uint32_t            enabled_tmu;
    needs_t             needs;
};

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

struct context_t {
	GGLContext          procs;
	state_t             state;
    shade_t             shade;
	iterators_t         iterators;
    generated_vars_t    generated_vars                __attribute__((aligned(32)));
    uint8_t             ditherMatrix[GGL_DITHER_SIZE] __attribute__((aligned(32)));
    uint32_t            packed;
    uint32_t            packed8888;
    const GGLFormat*    formats;
    uint32_t            dirty;
    texture_t*          activeTMU;
    uint32_t            activeTMUIndex;

    void                (*init_y)(context_t* c, int32_t y);
	void                (*step_y)(context_t* c);
	void                (*scanline)(context_t* c);
    void                (*span)(context_t* c);
    void                (*rect)(context_t* c, size_t yc);
    
    void*               base;
    Assembly*           scanline_as;
    GGLenum             error;
};

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

void ggl_init_context(context_t* context);
void ggl_uninit_context(context_t* context);
void ggl_error(context_t* c, GGLenum error);
int64_t ggl_system_time();

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

};

#endif // ANDROID_GGL_CONTEXT_H

