/* libs/pixelflinger/raster.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 <string.h>

#include "raster.h"
#include "trap.h"

namespace android {

static void ggl_rasterPos2x(void* con, GGLfixed x, GGLfixed y);
static void ggl_rasterPos2i(void* con, GGLint x, GGLint y);
static void ggl_copyPixels(void* con, GGLint xs, GGLint ys,
        GGLsizei width, GGLsizei height, GGLenum type);

void ggl_init_raster(context_t* c)
{
    GGLContext& procs = *(GGLContext*)c;
    GGL_INIT_PROC(procs, copyPixels);
    GGL_INIT_PROC(procs, rasterPos2x);
    GGL_INIT_PROC(procs, rasterPos2i);
}

void ggl_rasterPos2x(void* con, GGLfixed x, GGLfixed y)
{
    GGL_CONTEXT(c, con);
    // raster pos should be processed just like glVertex
    c->state.raster.x = x;
    c->state.raster.y = y;
}

void ggl_rasterPos2i(void* con, GGLint x, GGLint y)
{
    ggl_rasterPos2x(con, gglIntToFixed(x), gglIntToFixed(y));
}

void ggl_copyPixels(void* con, GGLint xs, GGLint ys,
        GGLsizei width, GGLsizei height, GGLenum type)
{
    GGL_CONTEXT(c, con);

    // color-buffer
    surface_t* cb = &(c->state.buffers.color);

    // undefined behaviour if we try to copy from outside the surface
    if (uint32_t(xs) > cb->width)
        return;
    if (uint32_t(ys) > cb->height)
        return;
    if (uint32_t(xs + width) > cb->width)
        return;
    if (uint32_t(ys + height) > cb->height)
        return;

    // copy to current raster position
    GGLint xd = gglFixedToIntRound(c->state.raster.x);
    GGLint yd = gglFixedToIntRound(c->state.raster.y);

    // clip to scissor
    if (xd < GGLint(c->state.scissor.left)) {
        GGLint offset = GGLint(c->state.scissor.left) - xd;
        xd = GGLint(c->state.scissor.left);
        xs += offset;
        width -= offset;
    }
    if (yd < GGLint(c->state.scissor.top)) {
        GGLint offset = GGLint(c->state.scissor.top) - yd;
        yd = GGLint(c->state.scissor.top);
        ys += offset;
        height -= offset;
    }
    if ((xd + width) > GGLint(c->state.scissor.right)) {
        width = GGLint(c->state.scissor.right) - xd;
    }
    if ((yd + height) > GGLint(c->state.scissor.bottom)) {
        height = GGLint(c->state.scissor.bottom) - yd;
    }

    if (width<=0 || height<=0) {
        return; // nothing to copy
    }

    if (xs==xd && ys==yd) {
        // nothing to do, but be careful, this might not be true when we support
        // gglPixelTransfer, gglPixelMap and gglPixelZoom
        return;
    }

    const GGLFormat* fp = &(c->formats[cb->format]);
    uint8_t* src = reinterpret_cast<uint8_t*>(cb->data)
            + (xs + (cb->stride * ys)) * fp->size;
    uint8_t* dst = reinterpret_cast<uint8_t*>(cb->data)
            + (xd + (cb->stride * yd)) * fp->size;
    const size_t bpr = cb->stride * fp->size;
    const size_t rowsize = width * fp->size;
    size_t yc = height;

    if (ys < yd) {
        // bottom to top
        src += height * bpr;
        dst += height * bpr;
        do {
            dst -= bpr;
            src -= bpr;
            memcpy(dst, src, rowsize);
        } while (--yc);
    } else {
        if (ys == yd) {
            // might be right to left
            do {
                memmove(dst, src, rowsize);
                dst += bpr;
                src += bpr;
            } while (--yc);
        } else {
            // top to bottom
            do {
                memcpy(dst, src, rowsize);
                dst += bpr;
                src += bpr;
            } while (--yc);
        }
    }
}

}; // namespace android

using namespace android;

GGLint gglBitBlti(GGLContext* con, int tmu, GGLint crop[4], GGLint where[4])
{
    GGL_CONTEXT(c, (void*)con);

     GGLint x = where[0];
     GGLint y = where[1];
     GGLint w = where[2];
     GGLint h = where[3];

    // exclsively enable this tmu
    const GGLSurface& cbSurface = c->state.buffers.color.s;
    c->procs.activeTexture(c, tmu);
    c->procs.disable(c, GGL_W_LERP);

    uint32_t tmus = 1UL<<tmu;
    if (c->state.enabled_tmu != tmus) {
        c->activeTMU->enable = 1;
        c->state.enabled_tmu = tmus;
        c->state.enables |= GGL_ENABLE_TMUS;
        ggl_state_changed(c, GGL_TMU_STATE);
    }

    const GGLint Wcr = crop[2];
    const GGLint Hcr = crop[3];
    if ((w == Wcr) && (h == Hcr)) {
        c->procs.texGeni(c, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
        c->procs.texGeni(c, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
        const GGLint Ucr = crop[0];
        const GGLint Vcr = crop[1];
        const GGLint s0  = Ucr - x;
        const GGLint t0  = Vcr - y;
        c->procs.texCoord2i(c, s0, t0);
        c->procs.recti(c, x, y, x+w, y+h);
    } else {
        int32_t texcoords[8];
        x = gglIntToFixed(x);
        y = gglIntToFixed(y); 
    
        // we CLAMP here, which works with premultiplied (s,t)
        c->procs.texParameteri(c, GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_S, GGL_CLAMP);
        c->procs.texParameteri(c, GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_T, GGL_CLAMP);
        c->procs.texGeni(c, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC);
        c->procs.texGeni(c, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC);
    
        const GGLint Ucr = crop[0] << 16;
        const GGLint Vcr = crop[1] << 16;
        const GGLint Wcr = crop[2] << 16;
        const GGLint Hcr = crop[3] << 16;
    
        // computes texture coordinates (pre-multiplied)
        int32_t dsdx = Wcr / w;   // dsdx = ((Wcr/w)/Wt)*Wt
        int32_t dtdy = Hcr / h;   // dtdy = ((Hcr/h)/Ht)*Ht
        int32_t s0   = Ucr - gglMulx(dsdx, x); // s0 = Ucr - x * dsdx
        int32_t t0   = Vcr - gglMulx(dtdy, y); // t0 = Vcr - y * dtdy
        texcoords[0] = s0;
        texcoords[1] = dsdx;
        texcoords[2] = 0;
        texcoords[3] = t0;
        texcoords[4] = 0;
        texcoords[5] = dtdy;
        texcoords[6] = 0;
        texcoords[7] = 0;
        c->procs.texCoordGradScale8xv(c, tmu, texcoords);
        c->procs.recti(c, 
                gglFixedToIntRound(x),
                gglFixedToIntRound(y),
                gglFixedToIntRound(x)+w,
                gglFixedToIntRound(y)+h);
    }
    return 0;
}

