qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 06/14] console: add dpy_gfx_update_dirty


From: Gerd Hoffmann
Subject: [Qemu-devel] [PATCH 06/14] console: add dpy_gfx_update_dirty
Date: Tue, 2 Sep 2014 10:00:19 +0200

Calls dpy_gfx_update for all dirty scanlines. Works for
DisplaySurfaces backed by guest memory (i.e. the ones created
using qemu_create_displaysurface_guestmem).

Signed-off-by: Gerd Hoffmann <address@hidden>
---
 include/ui/console.h |  4 ++++
 ui/console.c         | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)

diff --git a/include/ui/console.h b/include/ui/console.h
index 61901f7..58a7d4b 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -232,6 +232,10 @@ void dpy_text_resize(QemuConsole *con, int w, int h);
 void dpy_mouse_set(QemuConsole *con, int x, int y, int on);
 void dpy_cursor_define(QemuConsole *con, QEMUCursor *cursor);
 bool dpy_cursor_define_supported(QemuConsole *con);
+void dpy_gfx_update_dirty(QemuConsole *con,
+                          MemoryRegion *address_space,
+                          uint64_t base,
+                          bool invalidate);
 
 static inline int surface_stride(DisplaySurface *s)
 {
diff --git a/ui/console.c b/ui/console.c
index 654c0d3..d1342ca 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1581,6 +1581,67 @@ bool dpy_cursor_define_supported(QemuConsole *con)
     return false;
 }
 
+/*
+ * Call dpy_gfx_update for all dirity scanlines.  Works for
+ * DisplaySurfaces backed by guest memory (i.e. the ones created
+ * using qemu_create_displaysurface_guestmem).
+ */
+void dpy_gfx_update_dirty(QemuConsole *con,
+                          MemoryRegion *address_space,
+                          hwaddr base,
+                          bool invalidate)
+{
+    DisplaySurface *ds = qemu_console_surface(con);
+    int width = surface_stride(ds);
+    int height = surface_height(ds);
+    hwaddr size = width * height;
+    MemoryRegionSection mem_section;
+    MemoryRegion *mem;
+    ram_addr_t addr;
+    int first, last, i;
+    bool dirty;
+
+    mem_section = memory_region_find(address_space, base, size);
+    mem = mem_section.mr;
+    if (int128_get64(mem_section.size) != size ||
+        !memory_region_is_ram(mem_section.mr)) {
+        goto out;
+    }
+    assert(mem);
+
+    memory_region_sync_dirty_bitmap(mem);
+    addr = mem_section.offset_within_region;
+
+    first = -1;
+    last = -1;
+    for (i = 0; i < height; i++, addr += width) {
+        dirty = invalidate ||
+            memory_region_get_dirty(mem, addr, width, DIRTY_MEMORY_VGA);
+        if (dirty) {
+            if (first == -1) {
+                first = i;
+            }
+            last = i;
+        }
+        if (first != -1 && !dirty) {
+            assert(last != -1 && last >= first);
+            dpy_gfx_update(con, 0, first, surface_width(ds),
+                           last - first + 1);
+            first = -1;
+        }
+    }
+    if (first != -1) {
+        assert(last != -1 && last >= first);
+        dpy_gfx_update(con, 0, first, surface_width(ds),
+                       last - first + 1);
+    }
+
+    memory_region_reset_dirty(mem, mem_section.offset_within_region, size,
+                              DIRTY_MEMORY_VGA);
+out:
+    memory_region_unref(mem);
+}
+
 /***********************************************************/
 /* register display */
 
-- 
1.8.3.1




reply via email to

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