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

/*
 * Contains core-side framebuffer service that sends framebuffer updates
 * to the UI connected to the core.
 */

#include "ui/console.h"
#include "android/looper.h"
#include "android/display-core.h"
#include "android/async-utils.h"
#include "android/protocol/fb-updates.h"
#include "android/protocol/fb-updates-proxy.h"
#include "android/utils/system.h"
#include "android/utils/debug.h"

/* Descriptor for the Core-side implementation of the "framebufer" service.
 */
struct ProxyFramebuffer {
    /* Writer used to send FB update notification messages. */
    AsyncWriter             fb_update_writer;

    /* Reader used to read FB requests from the client. */
    AsyncReader             fb_req_reader;

    /* I/O associated with this descriptor. */
    LoopIo                  io;

    /* Display state used for this service */
    DisplayState*           ds;
    DisplayUpdateListener*  ds_listener;

    /* Looper used to communicate framebuffer updates. */
    Looper* looper;

    /* Head of the list of pending FB update notifications. */
    struct FBUpdateNotify*  fb_update_head;

    /* Tail of the list of pending FB update notifications. */
    struct FBUpdateNotify*  fb_update_tail;

    /* Socket used to communicate framebuffer updates. */
    int     sock;

    /* Framebuffer request header. */
    FBRequestHeader         fb_req_header;
};

/* Framebuffer update notification descriptor. */
typedef struct FBUpdateNotify {
    /* Links all pending FB update notifications. */
    struct FBUpdateNotify*  next_fb_update;

    /* Core framebuffer instance that owns the message. */
    ProxyFramebuffer*       proxy_fb;

    /* Size of the message to transfer. */
    size_t                  message_size;

    /* Update message. */
    FBUpdateMessage         message;
} FBUpdateNotify;

/*
 * Gets pointer in framebuffer's pixels for the given pixel.
 * Param:
 *  fb Framebuffer containing pixels.
 *  x, and y identify the pixel to get pointer for.
 * Return:
 *  Pointer in framebuffer's pixels for the given pixel.
 */
static const uint8_t*
_pixel_offset(const DisplaySurface* dsu, int x, int y)
{
    return (const uint8_t*)dsu->data + y * dsu->linesize + x * dsu->pf.bytes_per_pixel;
}

/*
 * Copies pixels from a framebuffer rectangle.
 * Param:
 *  rect - Buffer where to copy pixel.
 *  fb - Framebuffer containing the rectangle to copy.
 *  x, y, w, and h - dimensions of the rectangle to copy.
 */
static void
_copy_fb_rect(uint8_t* rect, const DisplaySurface* dsu, int x, int y, int w, int h)
{
    const uint8_t* start = _pixel_offset(dsu, x, y);
    for (; h > 0; h--) {
        memcpy(rect, start, w * dsu->pf.bytes_per_pixel);
        start += dsu->linesize;
        rect += w * dsu->pf.bytes_per_pixel;
    }
}

/*
 * Allocates and initializes framebuffer update notification descriptor.
 * Param:
 *  ds - Display state for the framebuffer.
 *  fb Framebuffer containing pixels.
 *  x, y, w, and h identify the rectangle that is being updated.
 * Return:
 *  Initialized framebuffer update notification descriptor.
 */
static FBUpdateNotify*
fbupdatenotify_create(ProxyFramebuffer* proxy_fb,
                      int x, int y, int w, int h)
{
    const size_t rect_size = w * h * proxy_fb->ds->surface->pf.bytes_per_pixel;
    FBUpdateNotify* ret = malloc(sizeof(FBUpdateNotify) + rect_size);

    ret->next_fb_update = NULL;
    ret->proxy_fb = proxy_fb;
    ret->message_size = sizeof(FBUpdateMessage) + rect_size;
    ret->message.x = x;
    ret->message.y = y;
    ret->message.w = w;
    ret->message.h = h;
    _copy_fb_rect(ret->message.rect, proxy_fb->ds->surface, x, y, w, h);
    return ret;
}

/*
 * Deletes FBUpdateNotify descriptor, created with fbupdatenotify_create.
 * Param:
 *  desc - Descreptor to delete.
 */
static void
fbupdatenotify_delete(FBUpdateNotify* desc)
{
    if (desc != NULL) {
        free(desc);
    }
}

/*
 * Asynchronous write I/O callback launched when writing framebuffer
 * notifications to the socket.
 * Param:
 *  proxy_fb - ProxyFramebuffer instance.
 */
static void
_proxyFb_io_write(ProxyFramebuffer* proxy_fb)
{
    while (proxy_fb->fb_update_head != NULL) {
        FBUpdateNotify* current_update = proxy_fb->fb_update_head;
        // Lets continue writing of the current notification.
        const AsyncStatus status =
            asyncWriter_write(&proxy_fb->fb_update_writer);
        switch (status) {
            case ASYNC_COMPLETE:
                // Done with the current update. Move on to the next one.
                break;
            case ASYNC_ERROR:
                // Done with the current update. Move on to the next one.
                loopIo_dontWantWrite(&proxy_fb->io);
                break;

            case ASYNC_NEED_MORE:
                // Transfer will eventually come back into this routine.
                return;
        }

        // Advance the list of updates
        proxy_fb->fb_update_head = current_update->next_fb_update;
        if (proxy_fb->fb_update_head == NULL) {
            proxy_fb->fb_update_tail = NULL;
        }
        fbupdatenotify_delete(current_update);

        if (proxy_fb->fb_update_head != NULL) {
            // Schedule the next one.
            asyncWriter_init(&proxy_fb->fb_update_writer,
                             &proxy_fb->fb_update_head->message,
                             proxy_fb->fb_update_head->message_size,
                             &proxy_fb->io);
        }
    }
}

static void proxyFb_update(void* opaque, int x, int y, int w, int h);

/*
 * Asynchronous read I/O callback launched when reading framebuffer requests
 * from the socket.
 * Param:
 *  proxy_fb - ProxyFramebuffer instance.
 */
static void
_proxyFb_io_read(ProxyFramebuffer* proxy_fb)
{
    // Read the request header.
    DisplaySurface* dsu;
    const AsyncStatus status =
        asyncReader_read(&proxy_fb->fb_req_reader);
    switch (status) {
        case ASYNC_COMPLETE:
            // Request header is received
            switch (proxy_fb->fb_req_header.request_type) {
                case AFB_REQUEST_REFRESH:
                    // Force full screen update to be sent
                    dsu = proxy_fb->ds->surface;
                    proxyFb_update(proxy_fb,
                                  0, 0, dsu->width, dsu->height);
                    break;
                default:
                    derror("Unknown framebuffer request %d\n",
                           proxy_fb->fb_req_header.request_type);
                    break;
            }
            proxy_fb->fb_req_header.request_type = -1;
            asyncReader_init(&proxy_fb->fb_req_reader, &proxy_fb->fb_req_header,
                             sizeof(proxy_fb->fb_req_header), &proxy_fb->io);
            break;
        case ASYNC_ERROR:
            loopIo_dontWantRead(&proxy_fb->io);
            if (errno == ECONNRESET) {
                // UI has exited. We need to destroy framebuffer service.
                proxyFb_destroy(proxy_fb);
            }
            break;

        case ASYNC_NEED_MORE:
            // Transfer will eventually come back into this routine.
            return;
    }
}

/*
 * Asynchronous I/O callback launched when writing framebuffer notifications
 * to the socket.
 * Param:
 *  opaque - ProxyFramebuffer instance.
 */
static void
_proxyFb_io_fun(void* opaque, int fd, unsigned events)
{
    if (events & LOOP_IO_READ) {
        _proxyFb_io_read((ProxyFramebuffer*)opaque);
    } else if (events & LOOP_IO_WRITE) {
        _proxyFb_io_write((ProxyFramebuffer*)opaque);
    }
}

ProxyFramebuffer*
proxyFb_create(int sock, const char* protocol)
{
    // At this point we're implementing the -raw protocol only.
    ProxyFramebuffer* ret;
    DisplayState* ds = get_displaystate();
    DisplayUpdateListener* dul;

    ANEW0(ret);
    ret->sock = sock;
    ret->looper = looper_newCore();
    ret->ds = ds;

    ANEW0(dul);
    dul->opaque = ret;
    dul->dpy_update = proxyFb_update;
    register_displayupdatelistener(ds, dul);
    ret->ds_listener = dul;

    ret->fb_update_head = NULL;
    ret->fb_update_tail = NULL;
    loopIo_init(&ret->io, ret->looper, sock, _proxyFb_io_fun, ret);
    asyncReader_init(&ret->fb_req_reader, &ret->fb_req_header,
                     sizeof(ret->fb_req_header), &ret->io);
    return ret;
}

void
proxyFb_destroy(ProxyFramebuffer* proxy_fb)
{
    if (proxy_fb != NULL) {
        unregister_displayupdatelistener(proxy_fb->ds, proxy_fb->ds_listener);
        if (proxy_fb->looper != NULL) {
            // Stop all I/O that may still be going on.
            loopIo_done(&proxy_fb->io);
            // Delete all pending frame updates.
            while (proxy_fb->fb_update_head != NULL) {
                FBUpdateNotify* pending_update = proxy_fb->fb_update_head;
                proxy_fb->fb_update_head = pending_update->next_fb_update;
                fbupdatenotify_delete(pending_update);
            }
            proxy_fb->fb_update_tail = NULL;
            looper_free(proxy_fb->looper);
            proxy_fb->looper = NULL;
        }
        AFREE(proxy_fb);
    }
}

static void
proxyFb_update(void* opaque, int x, int y, int w, int h)
{
    ProxyFramebuffer* proxy_fb = opaque;
    AsyncStatus status;
    FBUpdateNotify* descr = fbupdatenotify_create(proxy_fb, x, y, w, h);

    // Lets see if we should list it behind other pending updates.
    if (proxy_fb->fb_update_tail != NULL) {
        proxy_fb->fb_update_tail->next_fb_update = descr;
        proxy_fb->fb_update_tail = descr;
        return;
    }

    // We're first in the list. Just send it now.
    proxy_fb->fb_update_head = proxy_fb->fb_update_tail = descr;
    asyncWriter_init(&proxy_fb->fb_update_writer,
                     &proxy_fb->fb_update_head->message,
                     proxy_fb->fb_update_head->message_size, &proxy_fb->io);
    status = asyncWriter_write(&proxy_fb->fb_update_writer);
    switch (status) {
        case ASYNC_COMPLETE:
            fbupdatenotify_delete(descr);
            proxy_fb->fb_update_head = proxy_fb->fb_update_tail = NULL;
            return;
        case ASYNC_ERROR:
            fbupdatenotify_delete(descr);
            proxy_fb->fb_update_head = proxy_fb->fb_update_tail = NULL;
            return;
        case ASYNC_NEED_MORE:
            // Update transfer will eventually complete in _proxyFb_io_fun
            return;
    }
}

int
proxyFb_get_bits_per_pixel(ProxyFramebuffer* proxy_fb)
{
    if (proxy_fb == NULL || proxy_fb->ds == NULL)
        return -1;

    return proxy_fb->ds->surface->pf.bits_per_pixel;
}
