/*
 * Framebuffer device helper routines
 *
 * Copyright (c) 2009 CodeSourcery
 * Written by Paul Brook <paul@codesourcery.com>
 *
 * This code is licensed under the GNU GPLv2.
 *
 * Contributions after 2012-01-13 are licensed under the terms of the
 * GNU GPL, version 2 or (at your option) any later version.
 */

/* TODO:
   - Do something similar for framebuffers with local ram
   - Handle rotation here instead of hacking dest_pitch
   - Use common pixel conversion routines instead of per-device drawfn
   - Remove all DisplayState knowledge from devices.
 */

#include "qemu/osdep.h"
#include "hw/hw.h"
#include "ui/console.h"
#include "framebuffer.h"

void framebuffer_update_memory_section(
    MemoryRegionSection *mem_section,
    MemoryRegion *root,
    hwaddr base,
    unsigned rows,
    unsigned src_width)
{
    hwaddr src_len = (hwaddr)rows * src_width;

    if (mem_section->mr) {
        memory_region_set_log(mem_section->mr, false, DIRTY_MEMORY_VGA);
        memory_region_unref(mem_section->mr);
        mem_section->mr = NULL;
    }

    *mem_section = memory_region_find(root, base, src_len);
    if (!mem_section->mr) {
        return;
    }

    if (int128_get64(mem_section->size) < src_len ||
            !memory_region_is_ram(mem_section->mr)) {
        memory_region_unref(mem_section->mr);
        mem_section->mr = NULL;
        return;
    }

    memory_region_set_log(mem_section->mr, true, DIRTY_MEMORY_VGA);
}

/* Render an image from a shared memory framebuffer.  */
void framebuffer_update_display(
    DisplaySurface *ds,
    MemoryRegionSection *mem_section,
    int cols, /* Width in pixels.  */
    int rows, /* Height in pixels.  */
    int src_width, /* Length of source line, in bytes.  */
    int dest_row_pitch, /* Bytes between adjacent horizontal output pixels.  */
    int dest_col_pitch, /* Bytes between adjacent vertical output pixels.  */
    int invalidate, /* nonzero to redraw the whole image.  */
    drawfn fn,
    void *opaque,
    int *first_row, /* Input and output.  */
    int *last_row /* Output only */)
{
    hwaddr src_len;
    uint8_t *dest;
    uint8_t *src;
    int first, last = 0;
    int dirty;
    int i;
    ram_addr_t addr;
    MemoryRegion *mem;

    i = *first_row;
    *first_row = -1;
    src_len = src_width * rows;

    mem = mem_section->mr;
    if (!mem) {
        return;
    }
    memory_region_sync_dirty_bitmap(mem);

    addr = mem_section->offset_within_region;
    src = memory_region_get_ram_ptr(mem) + addr;

    dest = surface_data(ds);
    if (dest_col_pitch < 0) {
        dest -= dest_col_pitch * (cols - 1);
    }
    if (dest_row_pitch < 0) {
        dest -= dest_row_pitch * (rows - 1);
    }
    first = -1;

    addr += i * src_width;
    src += i * src_width;
    dest += i * dest_row_pitch;

    for (; i < rows; i++) {
        dirty = memory_region_get_dirty(mem, addr, src_width,
                                             DIRTY_MEMORY_VGA);
        if (dirty || invalidate) {
            fn(opaque, dest, src, cols, dest_col_pitch);
            if (first == -1)
                first = i;
            last = i;
        }
        addr += src_width;
        src += src_width;
        dest += dest_row_pitch;
    }
    if (first < 0) {
        return;
    }
    memory_region_reset_dirty(mem, mem_section->offset_within_region, src_len,
                              DIRTY_MEMORY_VGA);
    *first_row = first;
    *last_row = last;
}
