/* Copyright (C) 2007-2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/
#include "framebuffer.h"
#include <memory.h>
#include <stdlib.h>

typedef struct {
    /* client fields, these correspond to code that waits for updates before displaying them */
    /* at the moment, only one client is supported */
    void*                        fb_opaque;
    QFrameBufferUpdateFunc       fb_update;
    QFrameBufferRotateFunc       fb_rotate;
    QFrameBufferPollFunc         fb_poll;
    QFrameBufferDoneFunc         fb_done;

    void*                        pr_opaque;
    QFrameBufferCheckUpdateFunc  pr_check;
    QFrameBufferInvalidateFunc   pr_invalidate;
    QFrameBufferDetachFunc       pr_detach;

} QFrameBufferExtra;


static int
_get_pitch( int  width, QFrameBufferFormat  format )
{

    switch (format) {
        case QFRAME_BUFFER_RGB565:
            return width*2;
        default:
            return -1;
    }
}


int
qframebuffer_init( QFrameBuffer*       qfbuff,
                   int                 width,
                   int                 height,
                   int                 rotation,
                   QFrameBufferFormat  format )
{
    int   pitch;

    rotation &= 3;

    if (!qfbuff || width < 0 || height < 0)
        return -1;

    pitch = _get_pitch( width, format );
    if (pitch < 0)
        return -1;

    memset( qfbuff, 0, sizeof(*qfbuff) );

    qfbuff->extra = calloc( 1, sizeof(QFrameBufferExtra) );
    if (qfbuff->extra == NULL)
        return -1;

    qfbuff->pixels = calloc( pitch, height );
    if (qfbuff->pixels == NULL && (height > 0 && pitch > 0)) {
        free( qfbuff->extra );
        return -1;
    }

    qfbuff->width  = width;
    qfbuff->height = height;
    qfbuff->pitch  = pitch;
    qfbuff->format = format;

    qframebuffer_set_dpi( qfbuff, DEFAULT_FRAMEBUFFER_DPI, DEFAULT_FRAMEBUFFER_DPI );
    return 0;
}


void
qframebuffer_set_dpi( QFrameBuffer*   qfbuff,
                      int             x_dpi,
                      int             y_dpi )
{
    /* dpi = dots / inch
    ** inch = dots / dpi
    ** mm / 25.4 = dots / dpi
    ** mm = (dots * 25.4)/dpi
    */
    qfbuff->phys_width_mm  = (int)(0.5 + 25.4 * qfbuff->width  / x_dpi);
    qfbuff->phys_height_mm = (int)(0.5 + 25.4 * qfbuff->height / y_dpi);
}

/* alternative to qframebuffer_set_dpi where one can set the physical dimensions directly */
/* in millimeters. for the record 1 inch = 25.4 mm */
void
qframebuffer_set_mm( QFrameBuffer*   qfbuff,
                     int             width_mm,
                     int             height_mm )
{
    qfbuff->phys_width_mm  = width_mm;
    qfbuff->phys_height_mm = height_mm;
}

void
qframebuffer_update( QFrameBuffer*  qfbuff, int  x, int  y, int  w, int  h )
{
    QFrameBufferExtra*  extra = qfbuff->extra;

    if (extra->fb_update)
        extra->fb_update( extra->fb_opaque, x, y, w, h );
}


void
qframebuffer_add_client( QFrameBuffer*           qfbuff,
                         void*                   fb_opaque,
                         QFrameBufferUpdateFunc  fb_update,
                         QFrameBufferRotateFunc  fb_rotate,
                         QFrameBufferPollFunc    fb_poll,
                         QFrameBufferDoneFunc    fb_done )
{
    QFrameBufferExtra*  extra = qfbuff->extra;

    extra->fb_opaque = fb_opaque;
    extra->fb_update = fb_update;
    extra->fb_rotate = fb_rotate;
    extra->fb_poll   = fb_poll;
    extra->fb_done   = fb_done;
}

void
qframebuffer_set_producer( QFrameBuffer*                qfbuff,
                           void*                        opaque,
                           QFrameBufferCheckUpdateFunc  pr_check,
                           QFrameBufferInvalidateFunc   pr_invalidate,
                           QFrameBufferDetachFunc       pr_detach )
{
    QFrameBufferExtra*  extra = qfbuff->extra;

    extra->pr_opaque     = opaque;
    extra->pr_check      = pr_check;
    extra->pr_invalidate = pr_invalidate;
    extra->pr_detach     = pr_detach;
}


void
qframebuffer_rotate( QFrameBuffer*  qfbuff, int  rotation )
{
    QFrameBufferExtra*  extra = qfbuff->extra;

    if ((rotation ^ qfbuff->rotation) & 1) {
        /* swap width and height if new rotation requires it */
        int  temp = qfbuff->width;
        qfbuff->width  = qfbuff->height;
        qfbuff->height = temp;
        qfbuff->pitch  = _get_pitch( qfbuff->width, qfbuff->format );

        temp = qfbuff->phys_width_mm;
        qfbuff->phys_width_mm  = qfbuff->phys_height_mm;
        qfbuff->phys_height_mm = temp;
    }
    qfbuff->rotation = rotation;

    if (extra->fb_rotate)
        extra->fb_rotate( extra->fb_opaque, rotation );
}

void
qframebuffer_poll( QFrameBuffer* qfbuff )
{
    QFrameBufferExtra*  extra = qfbuff->extra;

    if (extra->fb_poll)
        extra->fb_poll( extra->fb_opaque );
}


extern void
qframebuffer_done( QFrameBuffer*   qfbuff )
{
    QFrameBufferExtra*  extra = qfbuff->extra;

    if (extra) {
        if (extra->pr_detach)
            extra->pr_detach( extra->pr_opaque );

        if (extra->fb_done)
            extra->fb_done( extra->fb_opaque );
    }

    free( qfbuff->pixels );
    free( qfbuff->extra );
    memset( qfbuff, 0, sizeof(*qfbuff) );
}


#define  MAX_FRAME_BUFFERS  8

static QFrameBuffer* framebuffer_fifo[ MAX_FRAME_BUFFERS ];
static int           framebuffer_fifo_rpos;
static int           framebuffer_fifo_count;

void
qframebuffer_fifo_add( QFrameBuffer*  qfbuff )
{
    if (framebuffer_fifo_count >= MAX_FRAME_BUFFERS)
        return;

    framebuffer_fifo[ framebuffer_fifo_count++ ] = qfbuff;
}


QFrameBuffer*
qframebuffer_fifo_get( void )
{
    if (framebuffer_fifo_rpos >= framebuffer_fifo_count)
        return NULL;

    return framebuffer_fifo[ framebuffer_fifo_rpos++ ];
}


void
qframebuffer_check_updates( void )
{
    int  nn;
    for (nn = 0; nn < framebuffer_fifo_count; nn++) {
        QFrameBuffer*       q     = framebuffer_fifo[nn];
        QFrameBufferExtra*  extra = q->extra;

        if (extra->pr_check)
            extra->pr_check( extra->pr_opaque );
    }
}

void
qframebuffer_invalidate_all( void )
{
    int  nn;
    for (nn = 0; nn < framebuffer_fifo_count; nn++) {
        QFrameBuffer*       q     = framebuffer_fifo[nn];
        QFrameBufferExtra*  extra = q->extra;

        if (extra->pr_invalidate)
            extra->pr_invalidate( extra->pr_opaque );
    }
}
