qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [6965] Implement and use shared memory framebuffer dev


From: andrzej zaborowski
Subject: Re: [Qemu-devel] [6965] Implement and use shared memory framebuffer device rendering reoutine.
Date: Thu, 2 Apr 2009 21:52:09 +0100

2009/4/1 Paul Brook <address@hidden>:
> Revision: 6965
>          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=6965
> Author:   pbrook
> Date:     2009-04-01 12:27:59 +0000 (Wed, 01 Apr 2009)
> Log Message:
> -----------
> Implement and use shared memory framebuffer device rendering reoutine.
> Use DMA mapping API.
>
> Signed-off-by: Paul Brook <address@hidden>
>
> Modified Paths:
> --------------
>    trunk/Makefile.target
>    trunk/hw/omap.h
>    trunk/hw/omap_lcd_template.h
>    trunk/hw/omap_lcdc.c
>    trunk/hw/pl110.c
>    trunk/hw/pl110_template.h
>    trunk/hw/pxa2xx_lcd.c
>    trunk/hw/pxa2xx_template.h
>
> Added Paths:
> -----------
>    trunk/hw/framebuffer.c
>    trunk/hw/framebuffer.h
>
> Modified: trunk/Makefile.target
> ===================================================================
> --- trunk/Makefile.target       2009-04-01 11:43:02 UTC (rev 6964)
> +++ trunk/Makefile.target       2009-04-01 12:27:59 UTC (rev 6965)
> @@ -672,6 +672,7 @@
>  OBJS+= tsc2005.o bt-hci-csr.o
>  OBJS+= mst_fpga.o mainstone.o
>  OBJS+= musicpal.o pflash_cfi02.o
> +OBJS+= framebuffer.o
>  CPPFLAGS += -DHAS_AUDIO
>  endif
>  ifeq ($(TARGET_BASE_ARCH), sh4)
>
> Added: trunk/hw/framebuffer.c
> ===================================================================
> --- trunk/hw/framebuffer.c                              (rev 0)
> +++ trunk/hw/framebuffer.c      2009-04-01 12:27:59 UTC (rev 6965)
> @@ -0,0 +1,119 @@
> +/*
> + * Framebuffer device helper routines
> + *
> + * Copyright (c) 2009 CodeSourcery
> + * Written by Paul Brook <address@hidden>
> + *
> + * This code is licensed under the GNU GPLv2.
> + */
> +
> +/* 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 "hw.h"
> +#include "console.h"
> +#include "framebuffer.h"
> +#include "kvm.h"
> +
> +/* Render an image from a shared memory framebuffer.  */
> +
> +void framebuffer_update_display(
> +    DisplayState *ds,
> +    target_phys_addr_t base,
> +    int cols, /* Width in pixels.  */
> +    int rows, /* Leight 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 */)
> +{
> +    target_phys_addr_t src_len;
> +    uint8_t *dest;
> +    uint8_t *src;
> +    uint8_t *src_base;
> +    int first, last = 0;
> +    int dirty;
> +    int i;
> +    ram_addr_t addr;
> +    ram_addr_t pd;
> +    ram_addr_t pd2;
> +
> +    i = *first_row;
> +    *first_row = -1;
> +    src_len = src_width * rows;
> +
> +    if (kvm_enabled()) {
> +        kvm_physical_sync_dirty_bitmap(base, src_len);
> +    }
> +    pd = cpu_get_physical_page_desc(base);
> +    pd2 = cpu_get_physical_page_desc(base + src_len - 1);
> +    /* We should reall check that this is a continuous ram region.
> +       Instead we just check that the first and last pages are
> +       both ram, and the right distance apart.  */
> +    if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM
> +        || (pd2 & ~TARGET_PAGE_MASK) > IO_MEM_ROM) {
> +        return;
> +    }
> +    pd = (pd & TARGET_PAGE_MASK) + (base & ~TARGET_PAGE_MASK);
> +    if (((pd + src_len - 1) & TARGET_PAGE_MASK) != (pd2 & TARGET_PAGE_MASK)) 
> {
> +        return;
> +    }
> +
> +    src_base = cpu_physical_memory_map(base, &src_len, 0);
> +    /* If we can't map the framebuffer then bail.  We could try harder,
> +       but it's not really worth it as dirty flag tracking will probably
> +       already have failed above.  */
> +    if (!src_base)
> +        return;
> +    if (src_len != src_width * rows) {
> +        cpu_physical_memory_unmap(src_base, src_len, 0, 0);
> +        return;
> +    }
> +    src = src_base;
> +    dest = ds_get_data(ds);
> +    if (dest_col_pitch < 0)
> +        dest -= dest_col_pitch * (cols - 1);
> +    first = -1;
> +    addr = pd;

If we must use the map/unmap api for framebuffers (even though we know
this memory is continuous in qemu) then we could map omly the region
we determined is dirty.

Cheers




reply via email to

[Prev in Thread] Current Thread [Next in Thread]