aboutsummaryrefslogtreecommitdiff
path: root/hw/display/milkymist-vgafb.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2015-07-13 12:00:29 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2015-07-24 13:57:45 +0200
commitc1076c3e13a86140cc2ba29866512df8460cc7c2 (patch)
tree9aa1b98c2a7467e890539e2bb8cab4e2e989a725 /hw/display/milkymist-vgafb.c
parentdeb809edb85334c8e90530e1071b98f4da25ebaa (diff)
framebuffer: set DIRTY_MEMORY_VGA on RAM that is used for the framebuffer
The MemoryRegionSection contains enough information to access the RAM region underlying the framebuffer, and can be cached inside the display device. By doing this, the new framebuffer_update_memory_section function can enable dirty memory logging on the relevant RAM region. The function must be called whenever the stride or base of the framebuffer changes; a simple way to cover these cases is to call it on every full frame invalidation, which is a rare case. framebuffer_update_display now works entirely on a MemoryRegionSection, without going through cpu_physical_memory_map/unmap. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'hw/display/milkymist-vgafb.c')
-rw-r--r--hw/display/milkymist-vgafb.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/hw/display/milkymist-vgafb.c b/hw/display/milkymist-vgafb.c
index 9b35e76ff1..ab3074fadc 100644
--- a/hw/display/milkymist-vgafb.c
+++ b/hw/display/milkymist-vgafb.c
@@ -71,6 +71,7 @@ struct MilkymistVgafbState {
SysBusDevice parent_obj;
MemoryRegion regs_region;
+ MemoryRegionSection fbsection;
QemuConsole *con;
int invalidate;
@@ -91,6 +92,7 @@ static void vgafb_update_display(void *opaque)
MilkymistVgafbState *s = opaque;
SysBusDevice *sbd;
DisplaySurface *surface = qemu_console_surface(s->con);
+ int src_width;
int first = 0;
int last = 0;
drawfn fn;
@@ -129,11 +131,18 @@ static void vgafb_update_display(void *opaque)
break;
}
- framebuffer_update_display(surface, sysbus_address_space(sbd),
- s->regs[R_BASEADDRESS] + s->fb_offset,
+ src_width = s->regs[R_HRES] * 2;
+ if (s->invalidate) {
+ framebuffer_update_memory_section(&s->fbsection,
+ sysbus_address_space(sbd),
+ s->regs[R_BASEADDRESS] + s->fb_offset,
+ s->regs[R_VRES], src_width);
+ }
+
+ framebuffer_update_display(surface, &s->fbsection,
s->regs[R_HRES],
s->regs[R_VRES],
- s->regs[R_HRES] * 2,
+ src_width,
dest_width,
0,
s->invalidate,