On 07/07/2011 07:33 PM, Alon Levy wrote:
used to move dirty rectangle notification from update_area to surface_updated.

This is RfC quality. Specifically where to call surface_updated. Currently I
only call it from stop. This should be good enough for migration, which is
the only use case I think. This means after stop qemu is guranteed to know
the dirty regions of all surfaces.
---
  server/red_dispatcher.c          |   20 +++--------
  server/red_worker.c              |   71 +++++++++++++++++++++++++------------
  server/spice.h                   |    8 ++--
  server/tests/test_display_base.c |    2 +-
  4 files changed, 58 insertions(+), 43 deletions(-)

diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c
index 3dfd4e5..996e1ed 100644
--- a/server/red_dispatcher.c
+++ b/server/red_dispatcher.c
@@ -210,9 +210,7 @@ static void update_client_mouse_allowed(void)
  }

  static void qxl_worker_update_area_helper(QXLWorker *qxl_worker, uint32_t 
surface_id,
-                                   QXLRect *qxl_area, QXLRect *qxl_dirty_rects,
-                                   uint32_t num_dirty_rects, uint32_t 
clear_dirty_region,
-                                   int async, uint64_t cookie)
+                                   QXLRect *qxl_area, int async, uint64_t 
cookie)
  {
      RedDispatcher *dispatcher = (RedDispatcher *)qxl_worker;
      RedWorkerMessage message;
@@ -228,9 +226,6 @@ static void qxl_worker_update_area_helper(QXLWorker 
*qxl_worker, uint32_t surfac
      }
      send_data(dispatcher->channel,&surface_id, sizeof(uint32_t));
      send_data(dispatcher->channel,&qxl_area, sizeof(QXLRect *));
-    send_data(dispatcher->channel,&qxl_dirty_rects, sizeof(QXLRect *));
-    send_data(dispatcher->channel,&num_dirty_rects, sizeof(uint32_t));
-    send_data(dispatcher->channel,&clear_dirty_region, sizeof(uint32_t));
      if (async) {
          return;
      }
@@ -239,22 +234,17 @@ static void qxl_worker_update_area_helper(QXLWorker 
*qxl_worker, uint32_t surfac
  }

  static void qxl_worker_update_area(QXLWorker *qxl_worker, uint32_t surface_id,
-                                   QXLRect *qxl_area, QXLRect *qxl_dirty_rects,
-                                   uint32_t num_dirty_rects, uint32_t 
clear_dirty_region)
+                                   QXLRect *qxl_area)
  {
-    qxl_worker_update_area_helper(qxl_worker, surface_id, qxl_area, 
qxl_dirty_rects, num_dirty_rects,
-        clear_dirty_region, 0, 0);
+    qxl_worker_update_area_helper(qxl_worker, surface_id, qxl_area, 0, 0);
  }

  static void qxl_worker_update_area_async(QXLWorker *qxl_worker, uint32_t 
surface_id,
-                                   QXLRect *qxl_area, QXLRect *qxl_dirty_rects,
-                                   uint32_t num_dirty_rects, uint32_t 
clear_dirty_region, uint64_t cookie)
+                                         QXLRect *qxl_area, uint64_t cookie)
  {
-    qxl_worker_update_area_helper(qxl_worker, surface_id, qxl_area, 
qxl_dirty_rects, num_dirty_rects,
-        clear_dirty_region, 1, cookie);
+    qxl_worker_update_area_helper(qxl_worker, surface_id, qxl_area, 1, cookie);
  }

-
  static void qxl_worker_add_memslot(QXLWorker *qxl_worker, QXLDevMemSlot 
*mem_slot)
  {
      RedDispatcher *dispatcher = (RedDispatcher *)qxl_worker;
diff --git a/server/red_worker.c b/server/red_worker.c
index cb84754..f5b5570 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -9415,25 +9415,56 @@ static void red_wait_pipe_item_sent(RedChannel 
*channel, PipeItem *item)
      red_unref_channel(channel);
  }

+static int surface_updated_available(RedWorker *worker)
+{
+    int minor = worker->qxl->st->qif->base.minor_version;
+    int major = worker->qxl->st->qif->base.major_version;
+
+    return (major>  3 || (major == 3&&  minor>= 1))&&
+            worker->qxl->st->qif->surface_updated != NULL;
+}
Hi,
can qxl < 3.1 be compiled with the interface changes to update_area?

cheers,
Yonit.
+


+static void notify_surface_updated(RedWorker *worker, uint32_t surface_id)
+{
+    QXLRect *qxl_dirty_rects;
+    SpiceRect* dirty_rects;
+    uint32_t num_dirty_rects;
+    QRegion *surface_dirty_region;
+    RedSurface *surface;
+    int i;
+
+    if (!surface_updated_available(worker)) {
+        return;
+    }
+
+    surface =&worker->surfaces[surface_id];
+    surface_dirty_region =&surface->draw_dirty_region;
+    num_dirty_rects = pixman_region32_n_rects((pixman_region32_t 
*)&surface_dirty_region);
+    dirty_rects = spice_new0(SpiceRect, num_dirty_rects);
+    region_ret_rects(surface_dirty_region, dirty_rects, num_dirty_rects);
+    region_clear(surface_dirty_region);
+    qxl_dirty_rects = spice_new0(QXLRect, num_dirty_rects);
+    for (i = 0; i<  num_dirty_rects; i++) {
+        qxl_dirty_rects[i].top    = dirty_rects[i].top;
+        qxl_dirty_rects[i].left   = dirty_rects[i].left;
+        qxl_dirty_rects[i].bottom = dirty_rects[i].bottom;
+        qxl_dirty_rects[i].right  = dirty_rects[i].right;
+    }
+    free(dirty_rects);
+    worker->qxl->st->qif->surface_updated(worker->qxl, surface_id,
+                                          qxl_dirty_rects, num_dirty_rects);
+    free(qxl_dirty_rects);
+}
+
  static inline void handle_dev_update(RedWorker *worker)
  {
      const QXLRect *qxl_rect;
      SpiceRect *rect = spice_new0(SpiceRect, 1);
-    QXLRect *qxl_dirty_rects;
-    SpiceRect *dirty_rects;
-    RedSurface *surface;
-    uint32_t num_dirty_rects;
      uint32_t surface_id;
-    uint32_t clear_dirty_region;
-    int i;

      receive_data(worker->channel,&surface_id, sizeof(uint32_t));
      receive_data(worker->channel,&qxl_rect, sizeof(QXLRect *));
-    receive_data(worker->channel,&qxl_dirty_rects, sizeof(QXLRect *));
-    receive_data(worker->channel,&num_dirty_rects, sizeof(uint32_t));
-    receive_data(worker->channel,&clear_dirty_region, sizeof(uint32_t));

-    dirty_rects = spice_new0(SpiceRect, num_dirty_rects);
      red_get_rect_ptr(rect, qxl_rect);
      flush_display_commands(worker);

@@ -9441,19 +9472,6 @@ static inline void handle_dev_update(RedWorker *worker)

      validate_surface(worker, surface_id);
      red_update_area(worker, rect, surface_id);
-
-    surface =&worker->surfaces[surface_id];
-    region_ret_rects(&surface->draw_dirty_region, dirty_rects, 
num_dirty_rects);
-
-    if (clear_dirty_region) {
-        region_clear(&surface->draw_dirty_region);
-    }
-    for (i = 0; i<  num_dirty_rects; i++) {
-        qxl_dirty_rects[i].top    = dirty_rects[i].top;
-        qxl_dirty_rects[i].left   = dirty_rects[i].left;
-        qxl_dirty_rects[i].bottom = dirty_rects[i].bottom;
-        qxl_dirty_rects[i].right  = dirty_rects[i].right;
-    }
  }


@@ -9636,12 +9654,19 @@ static void handle_dev_flush_surfaces(RedWorker *worker)

  static void handle_dev_stop(RedWorker *worker)
  {
+    int x;
+
      ASSERT(worker->running);
      worker->running = FALSE;
      red_display_clear_glz_drawables(worker->display_channel);
      flush_all_surfaces(worker);
      red_wait_outgoing_item((RedChannel *)worker->display_channel);
      red_wait_outgoing_item((RedChannel *)worker->cursor_channel);
+    for (x = 0; x<  NUM_SURFACES; ++x) {
+        if (worker->surfaces[x].context.canvas) {
+            notify_surface_updated(worker, x);
+        }
+    }
  }

  static void handle_dev_start(RedWorker *worker)
diff --git a/server/spice.h b/server/spice.h
index 048462f..4fcc1cf 100644
--- a/server/spice.h
+++ b/server/spice.h
@@ -109,8 +109,7 @@ struct QXLWorker {
      void (*start)(QXLWorker *worker);
      void (*stop)(QXLWorker *worker);
      void (*update_area)(QXLWorker *qxl_worker, uint32_t surface_id,
-                       struct QXLRect *area, struct QXLRect *dirty_rects,
-                       uint32_t num_dirty_rects, uint32_t clear_dirty_region);
+                       struct QXLRect *area);
      void (*add_memslot)(QXLWorker *worker, QXLDevMemSlot *slot);
      void (*del_memslot)(QXLWorker *worker, uint32_t slot_group_id, uint32_t 
slot_id);
      void (*reset_memslots)(QXLWorker *worker);
@@ -124,8 +123,7 @@ struct QXLWorker {
      void (*loadvm_commands)(QXLWorker *worker, struct QXLCommandExt *ext, 
uint32_t count);
      /* async versions of commands. when complete spice calls async_complete */
      void (*update_area_async)(QXLWorker *qxl_worker, uint32_t surface_id,
-                       struct QXLRect *area, struct QXLRect *dirty_rects,
-                       uint32_t num_dirty_rects, uint32_t clear_dirty_region, 
uint64_t cookie);
+                       struct QXLRect *area, uint64_t cookie);
      void (*add_memslot_async)(QXLWorker *worker, QXLDevMemSlot *slot, 
uint64_t cookie);
      void (*destroy_surfaces_async)(QXLWorker *worker, uint64_t cookie);
      void (*destroy_primary_surface_async)(QXLWorker *worker, uint32_t 
surface_id, uint64_t cookie);
@@ -205,6 +203,8 @@ struct QXLInterface {
      void (*notify_update)(QXLInstance *qin, uint32_t update_id);
      int (*flush_resources)(QXLInstance *qin);
      void (*async_complete)(QXLInstance *qin, uint64_t cookie);
+    void (*surface_updated)(QXLInstance *qin, uint32_t surface_id, struct 
QXLRect *updated_rects,
+                       uint32_t num_updated_rects);
  };

  struct QXLInstance {
diff --git a/server/tests/test_display_base.c b/server/tests/test_display_base.c
index 76817d9..57c593a 100644
--- a/server/tests/test_display_base.c
+++ b/server/tests/test_display_base.c
@@ -364,7 +364,7 @@ static void produce_command()
          case SIMPLE_UPDATE: {
              QXLRect rect = {.left = 0, .right = WIDTH,
                              .top = 0, .bottom = HEIGHT};
-            qxl_worker->update_area(qxl_worker, 0,&rect, NULL, 0, 1);
+            qxl_worker->update_area(qxl_worker, 0,&rect);
              break;
          }
          case SIMPLE_COPY_BITS:

_______________________________________________
Spice-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/spice-devel

Reply via email to