[Top][All Lists]
[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