All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Paolo Bonzini" <pbonzini@redhat.com>,
	"Mark Cave-Ayland" <mark.cave-ayland@ilande.co.uk>,
	"Alex Bennée" <alex.bennee@linaro.org>
Subject: [Qemu-devel] [PATCH 09/10] tcx: make display updates thread safe
Date: Tue,  4 Apr 2017 12:23:14 +0200	[thread overview]
Message-ID: <20170404102315.24923-10-kraxel@redhat.com> (raw)
In-Reply-To: <20170404102315.24923-1-kraxel@redhat.com>

From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/display/tcx.c | 85 +++++++++++++++++++-------------------------------------
 1 file changed, 29 insertions(+), 56 deletions(-)

diff --git a/hw/display/tcx.c b/hw/display/tcx.c
index 15172f0..a890e49 100644
--- a/hw/display/tcx.c
+++ b/hw/display/tcx.c
@@ -98,44 +98,28 @@ static void tcx_set_dirty(TCXState *s)
     memory_region_set_dirty(&s->vram_mem, 0, MAXX * MAXY);
 }
 
-static inline int tcx_check_dirty(TCXState *s, ram_addr_t page)
+static inline int tcx_check_dirty(TCXState *s, DirtyBitmapSnapshot *snap,
+                                  ram_addr_t page)
 {
-    return memory_region_get_dirty(&s->vram_mem, page, TARGET_PAGE_SIZE,
-                                   DIRTY_MEMORY_VGA);
+    return memory_region_snapshot_get_dirty(&s->vram_mem, snap, page,
+                                            TARGET_PAGE_SIZE - 1);
 }
 
-static inline int tcx24_check_dirty(TCXState *s, ram_addr_t page,
-                                    ram_addr_t page24, ram_addr_t cpage)
+static inline int tcx24_check_dirty(TCXState *s, DirtyBitmapSnapshot *snap,
+                                    ram_addr_t page, ram_addr_t page24,
+                                    ram_addr_t cpage)
 {
     int ret;
 
-    ret = memory_region_get_dirty(&s->vram_mem, page, TARGET_PAGE_SIZE,
-                                  DIRTY_MEMORY_VGA);
-    ret |= memory_region_get_dirty(&s->vram_mem, page24, TARGET_PAGE_SIZE * 4,
-                                   DIRTY_MEMORY_VGA);
-    ret |= memory_region_get_dirty(&s->vram_mem, cpage, TARGET_PAGE_SIZE * 4,
-                                   DIRTY_MEMORY_VGA);
+    ret = memory_region_snapshot_get_dirty(&s->vram_mem, snap, page,
+                                           TARGET_PAGE_SIZE);
+    ret |= memory_region_snapshot_get_dirty(&s->vram_mem, snap, page24,
+                                            TARGET_PAGE_SIZE * 4);
+    ret |= memory_region_snapshot_get_dirty(&s->vram_mem, snap, cpage,
+                                            TARGET_PAGE_SIZE * 4);
     return ret;
 }
 
-static inline void tcx24_reset_dirty(TCXState *ts, ram_addr_t page_min,
-                               ram_addr_t page_max, ram_addr_t page24,
-                              ram_addr_t cpage)
-{
-    memory_region_reset_dirty(&ts->vram_mem,
-                              page_min,
-                              (page_max - page_min) + TARGET_PAGE_SIZE,
-                              DIRTY_MEMORY_VGA);
-    memory_region_reset_dirty(&ts->vram_mem,
-                              page24 + page_min * 4,
-                              (page_max - page_min) * 4 + TARGET_PAGE_SIZE,
-                              DIRTY_MEMORY_VGA);
-    memory_region_reset_dirty(&ts->vram_mem,
-                              cpage + page_min * 4,
-                              (page_max - page_min) * 4 + TARGET_PAGE_SIZE,
-                              DIRTY_MEMORY_VGA);
-}
-
 static void update_palette_entries(TCXState *s, int start, int end)
 {
     DisplaySurface *surface = qemu_console_surface(s->con);
@@ -325,7 +309,8 @@ static void tcx_update_display(void *opaque)
 {
     TCXState *ts = opaque;
     DisplaySurface *surface = qemu_console_surface(ts->con);
-    ram_addr_t page, page_min, page_max;
+    ram_addr_t page;
+    DirtyBitmapSnapshot *snap = NULL;
     int y, y_start, dd, ds;
     uint8_t *d, *s;
     void (*f)(TCXState *s1, uint8_t *dst, const uint8_t *src, int width);
@@ -337,8 +322,6 @@ static void tcx_update_display(void *opaque)
 
     page = 0;
     y_start = -1;
-    page_min = -1;
-    page_max = 0;
     d = surface_data(surface);
     s = ts->vram;
     dd = surface_stride(surface);
@@ -364,14 +347,14 @@ static void tcx_update_display(void *opaque)
     }
 
     memory_region_sync_dirty_bitmap(&ts->vram_mem);
+    snap = memory_region_snapshot_and_clear_dirty(&ts->vram_mem, 0x0,
+                                                  memory_region_size(&ts->vram_mem),
+                                                  DIRTY_MEMORY_VGA);
+
     for (y = 0; y < ts->height; page += TARGET_PAGE_SIZE) {
-        if (tcx_check_dirty(ts, page)) {
+        if (tcx_check_dirty(ts, snap, page)) {
             if (y_start < 0)
                 y_start = y;
-            if (page < page_min)
-                page_min = page;
-            if (page > page_max)
-                page_max = page;
 
             f(ts, d, s, ts->width);
             if (y >= ts->cursy && y < ts->cursy + 32 && ts->cursx < ts->width) {
@@ -421,20 +404,15 @@ static void tcx_update_display(void *opaque)
         dpy_gfx_update(ts->con, 0, y_start,
                        ts->width, y - y_start);
     }
-    /* reset modified pages */
-    if (page_max >= page_min) {
-        memory_region_reset_dirty(&ts->vram_mem,
-                                  page_min,
-                                  (page_max - page_min) + TARGET_PAGE_SIZE,
-                                  DIRTY_MEMORY_VGA);
-    }
+    g_free(snap);
 }
 
 static void tcx24_update_display(void *opaque)
 {
     TCXState *ts = opaque;
     DisplaySurface *surface = qemu_console_surface(ts->con);
-    ram_addr_t page, page_min, page_max, cpage, page24;
+    ram_addr_t page, cpage, page24;
+    DirtyBitmapSnapshot *snap = NULL;
     int y, y_start, dd, ds;
     uint8_t *d, *s;
     uint32_t *cptr, *s24;
@@ -447,8 +425,6 @@ static void tcx24_update_display(void *opaque)
     page24 = ts->vram24_offset;
     cpage = ts->cplane_offset;
     y_start = -1;
-    page_min = -1;
-    page_max = 0;
     d = surface_data(surface);
     s = ts->vram;
     s24 = ts->vram24;
@@ -457,15 +433,15 @@ static void tcx24_update_display(void *opaque)
     ds = 1024;
 
     memory_region_sync_dirty_bitmap(&ts->vram_mem);
+    snap = memory_region_snapshot_and_clear_dirty(&ts->vram_mem, 0x0,
+                                                  memory_region_size(&ts->vram_mem),
+                                                  DIRTY_MEMORY_VGA);
+
     for (y = 0; y < ts->height; page += TARGET_PAGE_SIZE,
             page24 += TARGET_PAGE_SIZE, cpage += TARGET_PAGE_SIZE) {
-        if (tcx24_check_dirty(ts, page, page24, cpage)) {
+        if (tcx24_check_dirty(ts, snap, page, page24, cpage)) {
             if (y_start < 0)
                 y_start = y;
-            if (page < page_min)
-                page_min = page;
-            if (page > page_max)
-                page_max = page;
             tcx24_draw_line32(ts, d, s, ts->width, cptr, s24);
             if (y >= ts->cursy && y < ts->cursy+32 && ts->cursx < ts->width) {
                 tcx_draw_cursor32(ts, d, y, ts->width);
@@ -521,10 +497,7 @@ static void tcx24_update_display(void *opaque)
         dpy_gfx_update(ts->con, 0, y_start,
                        ts->width, y - y_start);
     }
-    /* reset modified pages */
-    if (page_max >= page_min) {
-        tcx24_reset_dirty(ts, page_min, page_max, page24, cpage);
-    }
+    g_free(snap);
 }
 
 static void tcx_invalidate_display(void *opaque)
-- 
2.9.3

  parent reply	other threads:[~2017-04-04 10:23 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-04 10:23 [Qemu-devel] [PATCH 00/10] make display updates thread safe Gerd Hoffmann
2017-04-04 10:23 ` [Qemu-devel] [PATCH 01/10] bitmap: add bitmap_copy_and_clear_atomic Gerd Hoffmann
2017-04-04 10:23 ` [Qemu-devel] [PATCH 02/10] memory: add support getting and using a dirty bitmap copy Gerd Hoffmann
2017-04-04 10:29   ` Paolo Bonzini
2017-04-04 10:23 ` [Qemu-devel] [PATCH 03/10] vga: add vga_scanline_invalidated helper Gerd Hoffmann
2017-04-15 10:39   ` Richard Henderson
2017-04-18  9:23     ` Gerd Hoffmann
2017-04-04 10:23 ` [Qemu-devel] [PATCH 04/10] vga: make display updates thread safe Gerd Hoffmann
2017-04-04 10:23 ` [Qemu-devel] [PATCH 05/10] cg3: remove TARGET_PAGE_SIZE rounding on dirty page detection Gerd Hoffmann
2017-04-04 10:23 ` [Qemu-devel] [PATCH 06/10] cg3: fix up size parameter for memory_region_get_dirty() Gerd Hoffmann
2017-04-04 12:32   ` Mark Cave-Ayland
2017-04-04 10:23 ` [Qemu-devel] [PATCH 07/10] cg3: make display updates thread safe Gerd Hoffmann
2017-04-04 10:23 ` [Qemu-devel] [PATCH 08/10] tcx: introduce tcx_check_dirty() function Gerd Hoffmann
2017-04-04 10:23 ` Gerd Hoffmann [this message]
2017-04-04 12:43   ` [Qemu-devel] [PATCH 09/10] tcx: make display updates thread safe Mark Cave-Ayland
2017-04-04 10:23 ` [Qemu-devel] [PATCH 10/10] [testing] console: remove do_safe_dpy_refresh Gerd Hoffmann
2017-04-04 12:54 ` [Qemu-devel] [PATCH 00/10] make display updates thread safe Mark Cave-Ayland
2017-04-05  8:33   ` Mark Cave-Ayland

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170404102315.24923-10-kraxel@redhat.com \
    --to=kraxel@redhat.com \
    --cc=alex.bennee@linaro.org \
    --cc=mark.cave-ayland@ilande.co.uk \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.