[Spice-commits] 2 commits - common/region.c common/region.h server/red_dispatcher.c server/red_worker.c server/vd_interface.h

Izik Eidus izik at kemper.freedesktop.org
Wed Apr 14 09:33:20 PDT 2010


 common/region.c         |   25 +++++++++++++++++++++++++
 common/region.h         |    1 +
 server/red_dispatcher.c |    9 ++++++++-
 server/red_worker.c     |   33 +++++++++++++++++++++++++++------
 server/vd_interface.h   |    6 ++++--
 5 files changed, 65 insertions(+), 9 deletions(-)

New commits:
commit 042bc0f6321f547174b5c89869cce97bdede30d2
Merge: 99341e0... 5a1f8ba...
Author: Izik Eidus <ieidus at redhat.com>
Date:   Wed Apr 14 19:40:03 2010 +0300

    Merge branch 'master' of ssh://git.freedesktop.org/git/spice/spice

commit 99341e058f378c1fbf940a065267802028418969
Author: Izik Eidus <ieidus at redhat.com>
Date:   Wed Apr 14 19:38:49 2010 +0300

    spice: server: change update_area command
    
    The new command return dirty area to be used
    by users that want spice to render localy or
    into some framebuffer (sdl / vnc)
    
    Signed-off-by: Izik Eidus <ieidus at redhat.com>

diff --git a/common/region.c b/common/region.c
index 78d1dbc..f3cf0b2 100644
--- a/common/region.c
+++ b/common/region.c
@@ -363,6 +363,31 @@ SpiceRect *region_dup_rects(const QRegion *rgn, uint32_t *num_rects)
     return rects;
 }
 
+void region_ret_rects(const QRegion *rgn, SpiceRect *rects, uint32_t num_rects)
+{
+    pixman_box32_t *boxes;
+    int n, i;
+
+    boxes = pixman_region32_rectangles((pixman_region32_t *)rgn, &n);
+    for (i = 0; i < n && i < num_rects; i++) {
+        rects[i].left = boxes[i].x1;
+        rects[i].top = boxes[i].y1;
+        rects[i].right = boxes[i].x2;
+        rects[i].bottom = boxes[i].y2;
+    }
+
+    if (i && i != n) {
+        int x;
+
+        for (x = 0; x < (n - num_rects); ++x) {
+            rects[i - 1].left = MIN(rects[i - 1].left, boxes[i + x].x1);
+            rects[i - 1].top = MIN(rects[i - 1].top, boxes[i + x].y1);
+            rects[i - 1].right = MAX(rects[i - 1].right, boxes[i + x].x2);
+            rects[i - 1].bottom = MAX(rects[i - 1].bottom, boxes[i + x].y2);
+        }
+    }
+}
+
 
 int region_is_equal(const QRegion *rgn1, const QRegion *rgn2)
 {
diff --git a/common/region.h b/common/region.h
index 7cc1a3b..223370d 100644
--- a/common/region.h
+++ b/common/region.h
@@ -36,6 +36,7 @@ void region_clear(QRegion *rgn);
 void region_destroy(QRegion *rgn);
 void region_clone(QRegion *dest, const QRegion *src);
 SpiceRect *region_dup_rects(const QRegion *rgn, uint32_t *num_rects);
+void region_ret_rects(const QRegion *rgn, SpiceRect *rects, uint32_t num_rects);
 
 int region_test(const QRegion *rgn, const QRegion *other_rgn, int query);
 int region_is_valid(const QRegion *rgn);
diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c
index 2930dea..5b719bd 100644
--- a/server/red_dispatcher.c
+++ b/server/red_dispatcher.c
@@ -199,12 +199,19 @@ static void update_client_mouse_allowed()
     }
 }
 
-static void qxl_worker_update_area(QXLWorker *qxl_worker)
+static void qxl_worker_update_area(QXLWorker *qxl_worker, uint32_t surface_id,
+                                   SpiceRect *area, SpiceRect *dirty_rects,
+                                   uint32_t num_dirty_rects, uint32_t clear_dirty_region)
 {
     RedDispatcher *dispatcher = (RedDispatcher *)qxl_worker;
     RedWorkeMessage message = RED_WORKER_MESSAGE_UPDATE;
 
     write_message(dispatcher->channel, &message);
+    send_data(dispatcher->channel, &surface_id, sizeof(uint32_t));
+    send_data(dispatcher->channel, &area, sizeof(SpiceRect *));
+    send_data(dispatcher->channel, &dirty_rects, sizeof(SpiceRect *));
+    send_data(dispatcher->channel, &num_dirty_rects, sizeof(uint32_t));
+    send_data(dispatcher->channel, &clear_dirty_region, sizeof(uint32_t));
     read_message(dispatcher->channel, &message);
     ASSERT(message == RED_WORKER_MESSAGE_READY);
 }
diff --git a/server/red_worker.c b/server/red_worker.c
index 03f3d32..2892728 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -885,6 +885,7 @@ typedef struct RedSurface {
     DrawContext context;
 
     Ring depend_on_me;
+    QRegion draw_dirty_region;
 
     //fix me - better handling here
     QXLReleaseInfo *release_info;
@@ -1505,6 +1506,7 @@ static inline void red_destroy_surface(RedWorker *worker, uint32_t surface_id)
                 worker->qxl->release_resource(worker->qxl, release_info_ext);
             }
 
+            region_destroy(&surface->draw_dirty_region);
             surface->context.canvas = NULL;
             red_destroy_surface_item(worker, surface_id);
         }
@@ -4315,6 +4317,8 @@ static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable)
 
     worker->preload_group_id = drawable->group_id;
 
+    region_add(&surface->draw_dirty_region, &drawable->qxl_drawable->bbox);
+
     localize_clip(worker, &clip, drawable->group_id);
     switch (drawable->qxl_drawable->type) {
     case QXL_DRAW_FILL: {
@@ -7961,6 +7965,7 @@ static inline void red_create_surface(RedWorker *worker, uint32_t surface_id, ui
     ring_init(&surface->current_list);
     ring_init(&surface->depend_on_me);
     ring_init(&surface->glz_drawables);
+    region_init(&surface->draw_dirty_region);
     surface->refs = 1;
     if (worker->renderer != RED_RENDERER_INVALID) {
         surface->context.canvas = create_canvas_for_surface(worker, surface, worker->renderer,
@@ -8890,16 +8895,32 @@ static inline void handle_dev_update(RedWorker *worker)
 {
     RedWorkeMessage message;
     const SpiceRect *rect;
-    uint32_t *surface_id;
-    uint32_t _surface_id;
+    SpiceRect *dirty_rects;
+    RedSurface *surface;
+    uint32_t num_dirty_rects;
+    uint32_t surface_id;
+    uint32_t clear_dirty_region;
+
+    receive_data(worker->channel, &surface_id, sizeof(uint32_t));
+    receive_data(worker->channel, &rect, sizeof(SpiceRect *));
+    receive_data(worker->channel, &dirty_rects, sizeof(SpiceRect *));
+    receive_data(worker->channel, &num_dirty_rects, sizeof(uint32_t));
+    receive_data(worker->channel, &clear_dirty_region, sizeof(uint32_t));
 
     flush_display_commands(worker);
 
-    worker->qxl->get_update_area(worker->qxl, &rect, &surface_id);
     ASSERT(worker->running);
-    _surface_id = *surface_id;
-    validate_surface(worker, _surface_id);
-    red_update_area(worker, rect, _surface_id);
+
+    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);
+    }
+
     message = RED_WORKER_MESSAGE_READY;
     write_message(worker->channel, &message);
 }
diff --git a/server/vd_interface.h b/server/vd_interface.h
index 6d76b9e..25ff007 100644
--- a/server/vd_interface.h
+++ b/server/vd_interface.h
@@ -104,6 +104,7 @@ union QXLReleaseInfo;
 struct QXLReleaseInfoExt;
 struct QXLCommand;
 struct QXLCommandExt;
+struct SpiceRect;
 struct QXLWorker {
     uint32_t minor_version;
     uint32_t major_version;
@@ -113,7 +114,9 @@ struct QXLWorker {
     void (*load)(QXLWorker *worker);
     void (*start)(QXLWorker *worker);
     void (*stop)(QXLWorker *worker);
-    void (*update_area)(QXLWorker *worker);
+    void (*update_area)(QXLWorker *qxl_worker, uint32_t surface_id,
+                       struct SpiceRect *area, struct SpiceRect *dirty_rects,
+                       uint32_t num_dirty_rects, uint32_t clear_dirty_region);
     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);
@@ -199,7 +202,6 @@ struct QXLInterface {
     void (*release_resource)(QXLInterface *qxl, struct QXLReleaseInfoExt release_info);
     int (*get_cursor_command)(QXLInterface *qxl, struct QXLCommandExt *cmd);
     int (*req_cursor_notification)(QXLInterface *qxl);
-    void (*get_update_area)(QXLInterface *qxl, const struct SpiceRect **rect, uint32_t **surface_id);
     void (*notify_update)(QXLInterface *qxl, uint32_t update_id);
     void (*set_save_data)(QXLInterface *qxl, void *data, int size);
     void *(*get_save_data)(QXLInterface *qxl);


More information about the Spice-commits mailing list