[Spice-commits] 2 commits - server/red_worker.c

Izik Eidus izik at kemper.freedesktop.org
Mon Apr 5 15:58:28 PDT 2010


 server/red_worker.c |  147 +++++++++++++++++++++++++---------------------------
 1 file changed, 73 insertions(+), 74 deletions(-)

New commits:
commit cc943035c94fc6d6e300330f73087ac5bf63897b
Author: Izik Eidus <ieidus at redhat.com>
Date:   Tue Apr 6 02:02:38 2010 +0300

    spice server: try to be less brutal when changing res or when flushing the tree
    
    The idea is that we can try to defer some stuff to be later
    send in the pipe if the pipe is not fulled yet, moreover
    we will then walk on the pipe using:
    red_clear_surface_drawables_from_pipe() and will try to
    remove the uneeded objects of this surface
    
    Still some room to improvment but later...
    
    Signed-off-by: Izik Eidus <ieidus at redhat.com>

diff --git a/server/red_worker.c b/server/red_worker.c
index f996edb..f1de278 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -8143,6 +8143,11 @@ static inline void flush_display_commands(RedWorker *worker)
     for (;;) {
         uint64_t end_time;
 
+        red_process_commands(worker, MAX_PIPE_SIZE);
+        if (!worker->qxl->has_command(worker->qxl)) {
+            break;
+        }
+
         while (red_process_commands(worker, MAX_PIPE_SIZE)) {
             display_channel_push(worker);
         }
commit da2afcff8cf4cda979d1b1a6d12f0a1a01fa245e
Author: Izik Eidus <ieidus at redhat.com>
Date:   Tue Apr 6 01:11:59 2010 +0300

    spice server: remove surface_id and surfaces_dest[3] from guest mem
    
    Validate the surface_ids just once and keep them in safe
    memory area
    
    Make things simpler
    
    Signed-off-by: Izik Eidus <ieidus at redhat.com>

diff --git a/server/red_worker.c b/server/red_worker.c
index 6f91cba..f996edb 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -596,6 +596,7 @@ struct RedGlzDrawable {
     QXLDrawable *qxl_drawable;
     Drawable    *drawable;
     uint32_t     group_id;
+    int32_t      surface_id;
     uint8_t     *self_bitmap;
     GlzDrawableInstanceItem instances_pool[MAX_GLZ_DRAWABLE_INSTANCES];
     Ring instances;
@@ -836,6 +837,9 @@ struct Drawable {
 
     uint8_t *backed_surface_data;
     DependItem pipe_depend_items[3];
+
+    int surface_id;
+    int surfaces_dest[3];
 };
 
 typedef struct _Drawable _Drawable;
@@ -1396,12 +1400,12 @@ static void red_add_surface_image(RedWorker *worker, int surface_id);
 static inline void red_handle_drawable_surfaces_client_synced(RedWorker *worker, Drawable *drawable)
 {
     int x;
-    int surface_id;
 
     for (x = 0; x < 3; ++x) {
-        surface_id = drawable->qxl_drawable->surfaces_dest[x];
+        int surface_id;
+
+        surface_id = drawable->surfaces_dest[x];
         if (surface_id != -1) {
-            validate_surface(worker, surface_id);
             if (worker->display_channel->surface_client_created[surface_id] == TRUE) {
                 continue;
             }
@@ -1410,15 +1414,12 @@ static inline void red_handle_drawable_surfaces_client_synced(RedWorker *worker,
         }
     }
 
-    surface_id = drawable->qxl_drawable->surface_id;
-    validate_surface(worker, surface_id);
-
-    if (worker->display_channel->surface_client_created[surface_id] == TRUE) {
+    if (worker->display_channel->surface_client_created[drawable->surface_id] == TRUE) {
         return;
     }
 
-    red_create_surface_item(worker, surface_id);
-    red_add_surface_image(worker, surface_id);
+    red_create_surface_item(worker, drawable->surface_id);
+    red_add_surface_image(worker, drawable->surface_id);
 }
 
 static inline void red_pipe_add_drawable(RedWorker *worker, Drawable *drawable)
@@ -1630,7 +1631,7 @@ static inline void red_destroy_surface_item(RedWorker *worker, uint32_t surface_
     red_pipe_add(&worker->display_channel->base, &destroy->pipe_item);
 }
 
-static inline void __red_destroy_surface(RedWorker *worker, uint32_t surface_id)
+static inline void red_destroy_surface(RedWorker *worker, uint32_t surface_id)
 {
     RedSurface *surface = &worker->surfaces[surface_id];
 
@@ -1656,18 +1657,11 @@ static inline void __red_destroy_surface(RedWorker *worker, uint32_t surface_id)
     }
 }
 
-static inline void red_destroy_surface(RedWorker *worker, uint32_t surface_id)
-{
-    validate_surface(worker, surface_id);
-    __red_destroy_surface(worker, surface_id);
-}
-
 static inline void set_surface_release_info(RedWorker *worker, uint32_t surface_id,
                                             QXLReleaseInfo *release_info, uint32_t group_id)
 {
     RedSurface *surface;
 
-    validate_surface(worker, surface_id);
     surface = &worker->surfaces[surface_id];
 
     surface->release_info = release_info;
@@ -1675,10 +1669,10 @@ static inline void set_surface_release_info(RedWorker *worker, uint32_t surface_
 }
 
 static inline void free_qxl_drawable(RedWorker *worker, QXLDrawable *drawable, uint32_t group_id,
-                                     uint8_t *self_bitmap)
+                                     uint8_t *self_bitmap, int surface_id)
 {
     QXLReleaseInfoExt release_info_ext;
-    red_destroy_surface(worker, drawable->surface_id);
+    red_destroy_surface(worker, surface_id);
 
     if (self_bitmap) {
         free(self_bitmap);
@@ -1696,7 +1690,7 @@ static void remove_depended_item(DependItem *item)
     ring_remove(&item->ring_item);
 }
 
-static inline void red_dec_surfaces_drawable_dependencies(RedWorker *worker, QXLDrawable *drawable)
+static inline void red_dec_surfaces_drawable_dependencies(RedWorker *worker, Drawable *drawable)
 {
     int x;
     int surface_id;
@@ -1716,7 +1710,7 @@ static void remove_drawable_dependencies(RedWorker *worker, Drawable *drawable)
     int surface_id;
 
     for (x = 0; x < 3; ++x) {
-        surface_id = drawable->qxl_drawable->surfaces_dest[x];
+        surface_id = drawable->surfaces_dest[x];
         if (surface_id != -1 && drawable->depend_items[x].drawable) {
             remove_depended_item(&drawable->depend_items[x]);
         }
@@ -1737,12 +1731,13 @@ static inline void release_drawable(RedWorker *worker, Drawable *item)
         region_destroy(&item->tree_item.base.rgn);
 
         remove_drawable_dependencies(worker, item);
-        red_dec_surfaces_drawable_dependencies(worker, item->qxl_drawable);
+        red_dec_surfaces_drawable_dependencies(worker, item);
 
         if (item->red_glz_drawable) {
             item->red_glz_drawable->drawable = NULL;
         } else { // no refernce to the qxl drawable left
-            free_qxl_drawable(worker, item->qxl_drawable, item->group_id, item->self_bitmap);
+            free_qxl_drawable(worker, item->qxl_drawable, item->group_id, item->self_bitmap,
+                              item->surface_id);
         }
         free_drawable(worker, item);
     }
@@ -1821,7 +1816,7 @@ static void red_flush_source_surfaces(RedWorker *worker, Drawable *drawable)
     int surface_id;
 
     for (x = 0; x < 3; ++x) {
-        surface_id = drawable->qxl_drawable->surfaces_dest[x];
+        surface_id = drawable->surfaces_dest[x];
         if (surface_id != -1 && drawable->depend_items[x].drawable) {
             remove_depended_item(&drawable->depend_items[x]);
             surface_flush(worker, surface_id, &drawable->qxl_drawable->surfaces_rects[x]);
@@ -1978,12 +1973,12 @@ static void red_clear_surface_drawables_from_pipe(RedWorker *worker, int surface
             drawable = SPICE_CONTAINEROF(item, Drawable, pipe_item);
 
             for (x = 0; x < 3; ++x) {
-                if (drawable->qxl_drawable->surfaces_dest[x] == surface_id) {
+                if (drawable->surfaces_dest[x] == surface_id) {
                     return;
                 }
             }
 
-            if (drawable->qxl_drawable->surface_id == surface_id) {
+            if (drawable->surface_id == surface_id) {
                 tmp_item = item;
                 item = (PipeItem *)ring_prev(ring, (RingItem *)item);
                 ring_remove(&tmp_item->link);
@@ -2346,9 +2341,8 @@ static inline int is_opaque_item(TreeItem *item)
 static inline void __current_add_drawable(RedWorker *worker, Drawable *drawable, RingItem *pos)
 {
     RedSurface *surface;
-    uint32_t surface_id = drawable->qxl_drawable->surface_id;
+    uint32_t surface_id = drawable->surface_id;
 
-    validate_surface(worker, surface_id);
     surface = &worker->surfaces[surface_id];
     ring_add_after(&drawable->tree_item.base.siblings_link, pos);
     ring_add(&worker->current_list, &drawable->list_link);
@@ -3819,17 +3813,14 @@ static inline int red_handle_self_bitmap(RedWorker *worker, Drawable *drawable)
     int32_t height;
     uint8_t *dest;
     int dest_stride;
-    uint32_t surface_id;
     RedSurface *surface;
 
     if (!drawable->qxl_drawable->self_bitmap) {
         return TRUE;
     }
 
-    surface_id = drawable->qxl_drawable->surface_id;
-    validate_surface(worker, surface_id);
 
-    surface = &worker->surfaces[surface_id];
+    surface = &worker->surfaces[drawable->surface_id];
 
     width = drawable->qxl_drawable->bbox.right - drawable->qxl_drawable->bbox.left;
     height = drawable->qxl_drawable->bbox.bottom - drawable->qxl_drawable->bbox.top;
@@ -3851,7 +3842,7 @@ static inline int red_handle_self_bitmap(RedWorker *worker, Drawable *drawable)
     image->bitmap.data = (QXLPHYSICAL)dest;
     image->bitmap.palette = 0;
 
-    red_get_area(worker, surface_id,
+    red_get_area(worker, drawable->surface_id,
                  &drawable->qxl_drawable->self_bitmap_area, dest, dest_stride, TRUE);
 
     drawable->self_bitmap = (uint8_t *)image;
@@ -3881,6 +3872,7 @@ static Drawable *get_drawable(RedWorker *worker, uint8_t effect, QXLDrawable *qx
                               uint32_t group_id) {
     Drawable *drawable;
     struct timespec time;
+    int x;
 
     while (!(drawable = alloc_drawable(worker))) {
         free_one_drawable(worker, FALSE);
@@ -3905,6 +3897,15 @@ static Drawable *get_drawable(RedWorker *worker, uint8_t effect, QXLDrawable *qx
     drawable->qxl_drawable = qxl_drawable;
     drawable->group_id = group_id;
 
+    drawable->surface_id = qxl_drawable->surface_id;
+    validate_surface(worker, drawable->surface_id);
+    for (x = 0; x < 3; ++x) {
+        drawable->surfaces_dest[x] = qxl_drawable->surfaces_dest[x];
+        if (drawable->surfaces_dest[x] != -1) {
+            validate_surface(worker, drawable->surfaces_dest[x]);
+        }
+    }
+
     return drawable;
 }
 
@@ -3913,14 +3914,13 @@ static inline int red_handle_depends_on_target_surface(RedWorker *worker, uint32
     RedSurface *surface;
     RingItem *ring_item;
 
-    validate_surface(worker, surface_id);
     surface = &worker->surfaces[surface_id];
 
     while ((ring_item = ring_get_tail(&surface->depend_on_me))) {
         Drawable *drawable;
         DependItem *depended_item = SPICE_CONTAINEROF(ring_item, DependItem, ring_item);
         drawable = depended_item->drawable;
-        surface_flush(worker, drawable->qxl_drawable->surface_id, &drawable->qxl_drawable->bbox);
+        surface_flush(worker, drawable->surface_id, &drawable->qxl_drawable->bbox);
     }
 
     return TRUE;
@@ -3936,7 +3936,6 @@ static inline void add_to_surface_dependency(RedWorker *worker, int depend_on_su
         return;
     }
 
-    validate_surface(worker, depend_on_surface_id);
     surface = &worker->surfaces[depend_on_surface_id];
 
     depend_item->drawable = drawable;
@@ -3948,14 +3947,14 @@ static inline int red_handle_surfaces_dependencies(RedWorker *worker, Drawable *
     int x;
 
     for (x = 0; x < 3; ++x) {
-        add_to_surface_dependency(worker, drawable->qxl_drawable->surfaces_dest[x],
+        add_to_surface_dependency(worker, drawable->surfaces_dest[x],
                                   &drawable->depend_items[x], drawable);
     }
 
     return TRUE;
 }
 
-static inline void red_inc_surfaces_drawable_dependencies(RedWorker *worker, QXLDrawable *drawable)
+static inline void red_inc_surfaces_drawable_dependencies(RedWorker *worker, Drawable *drawable)
 {
     int x;
     int surface_id;
@@ -3966,7 +3965,6 @@ static inline void red_inc_surfaces_drawable_dependencies(RedWorker *worker, QXL
         if (surface_id == -1) {
             continue;
         }
-        validate_surface(worker, surface_id);
         surface = &worker->surfaces[surface_id];
         surface->refs++;
     }
@@ -3979,10 +3977,8 @@ static inline void red_process_drawable(RedWorker *worker, QXLDrawable *drawable
 
     ASSERT(item);
 
-    surface_id = drawable->surface_id;
-    validate_surface(worker, surface_id);
+    surface_id = item->surface_id;
 
-    ASSERT(worker->surfaces[surface_id].refs != 0);
     worker->surfaces[surface_id].refs++;
 
     region_add(&item->tree_item.base.rgn, &drawable->bbox);
@@ -4009,7 +4005,7 @@ static inline void red_process_drawable(RedWorker *worker, QXLDrawable *drawable
 #endif
     }
 
-    red_inc_surfaces_drawable_dependencies(worker, drawable);
+    red_inc_surfaces_drawable_dependencies(worker, item);
 
     if (region_is_empty(&item->tree_item.base.rgn)) {
         release_drawable(worker, item);
@@ -4078,11 +4074,12 @@ static inline void red_process_surface(RedWorker *worker, QXLSurfaceCmd *surface
         break;
     }
     case QXL_SURFACE_CMD_DESTROY:
+        PANIC_ON(!red_surface->context.canvas);
         set_surface_release_info(worker, surface_id, &surface->release_info, group_id);
         red_handle_depends_on_target_surface(worker, surface_id);
         red_current_clear(worker, surface_id);
         red_clear_surface_glz_drawables(worker, surface_id);
-	red_clear_surface_drawables_from_pipe(worker, surface_id);
+        red_clear_surface_drawables_from_pipe(worker, surface_id);
         red_destroy_surface(worker, surface_id);
         break;
     default:
@@ -4549,15 +4546,11 @@ static void unlocalize_attr(SpiceLineAttr *attr)
 
 static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable)
 {
-    uint32_t surface_id;
     RedSurface *surface;
     SpiceCanvas *canvas; 
     SpiceClip clip = drawable->qxl_drawable->clip;
 
-    surface_id = drawable->qxl_drawable->surface_id;
-    validate_surface(worker, surface_id);
-
-    surface = &worker->surfaces[surface_id];
+    surface = &worker->surfaces[drawable->surface_id];
     canvas = surface->context.canvas;
 
     worker->local_images_pos = 0;
@@ -4791,7 +4784,6 @@ static void red_update_area(RedWorker *worker, const SpiceRect *area, int surfac
     Ring items;
     QRegion rgn;
 
-    validate_surface(worker, surface_id);
     surface = &worker->surfaces[surface_id];
     ring = &surface->current;
 
@@ -4832,7 +4824,6 @@ static void red_update_area(RedWorker *worker, const SpiceRect *area, int surfac
     Drawable *now;
     int gn;
 
-    validate_surface(worker, surface_id);
     surface = &worker->surfaces[surface_id];
 
 start_again:
@@ -5061,10 +5052,13 @@ static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size)
             break;
         }
         case QXL_CMD_UPDATE: {
+            int surface_id;
             QXLReleaseInfoExt release_info_ext;
             QXLUpdateCmd *draw_cmd = (QXLUpdateCmd *)get_virt(worker, ext_cmd.cmd.data,
                                                               sizeof(QXLUpdateCmd),
                                                               ext_cmd.group_id);
+            surface_id = draw_cmd->surface_id;
+            validate_surface(worker, surface_id);
             red_update_area(worker, &draw_cmd->area, draw_cmd->surface_id);
             worker->qxl->notify_update(worker->qxl, draw_cmd->update_id);
             release_info_ext.group_id = ext_cmd.group_id;
@@ -5332,7 +5326,6 @@ static void red_display_reset_compress_buf(DisplayChannel *display_channel)
    in the channel (2) to the Drawable*/
 static RedGlzDrawable *red_display_get_glz_drawable(DisplayChannel *channel, Drawable *drawable)
 {
-    int surface_id;
     RedSurface *surface;
     RedGlzDrawable *ret;
 
@@ -5340,9 +5333,7 @@ static RedGlzDrawable *red_display_get_glz_drawable(DisplayChannel *channel, Dra
         return drawable->red_glz_drawable;
     }
 
-    surface_id = drawable->qxl_drawable->surface_id;
-    validate_surface(channel->base.worker, surface_id);
-    surface = &channel->base.worker->surfaces[surface_id];
+    surface = &channel->base.worker->surfaces[drawable->surface_id];
 
     ret = spice_new(RedGlzDrawable, 1);
 
@@ -5350,6 +5341,7 @@ static RedGlzDrawable *red_display_get_glz_drawable(DisplayChannel *channel, Dra
     ret->qxl_drawable = drawable->qxl_drawable;
     ret->drawable = drawable;
     ret->group_id = drawable->group_id;
+    ret->surface_id = drawable->surface_id;
     ret->self_bitmap = drawable->self_bitmap;
     ret->instances_count = 0;
     ring_init(&ret->instances);
@@ -5416,7 +5408,8 @@ static void red_display_free_glz_drawable_instance(DisplayChannel *channel,
             drawable->red_glz_drawable = NULL;
         } else { // no reference to the qxl drawable left
             free_qxl_drawable(channel->base.worker, glz_drawable->qxl_drawable,
-                              glz_drawable->group_id, glz_drawable->self_bitmap);
+                              glz_drawable->group_id, glz_drawable->self_bitmap,
+                              glz_drawable->surface_id);
         }
 
         if (ring_item_is_linked(&glz_drawable->link)) {
@@ -6678,7 +6671,7 @@ static inline void red_send_qxl_drawable(RedWorker *worker, DisplayChannel *disp
     case QXL_DRAW_FILL:
         channel->send_data.header.type = SPICE_MSG_DISPLAY_DRAW_FILL;
         fill_base(display_channel, &display_channel->send_data.u.fill.base, item,
-                  sizeof(SpiceMsgDisplayDrawFill), drawable->surface_id);
+                  sizeof(SpiceMsgDisplayDrawFill), item->surface_id);
         display_channel->send_data.u.fill.data = drawable->u.fill;
         fill_brush(display_channel, &display_channel->send_data.u.fill.data.brush, item);
         fill_mask(display_channel, &display_channel->send_data.u.fill.data.mask, item);
@@ -6686,7 +6679,7 @@ static inline void red_send_qxl_drawable(RedWorker *worker, DisplayChannel *disp
     case QXL_DRAW_OPAQUE:
         channel->send_data.header.type = SPICE_MSG_DISPLAY_DRAW_OPAQUE;
         fill_base(display_channel, &display_channel->send_data.u.opaque.base, item,
-                  sizeof(SpiceMsgDisplayDrawOpaque), drawable->surface_id);
+                  sizeof(SpiceMsgDisplayDrawOpaque), item->surface_id);
         display_channel->send_data.u.opaque.data = drawable->u.opaque;
         fill_bits(display_channel, &display_channel->send_data.u.opaque.data.src_bitmap, item);
         fill_brush(display_channel, &display_channel->send_data.u.opaque.data.brush, item);
@@ -6695,7 +6688,7 @@ static inline void red_send_qxl_drawable(RedWorker *worker, DisplayChannel *disp
     case QXL_DRAW_COPY:
         channel->send_data.header.type = SPICE_MSG_DISPLAY_DRAW_COPY;
         fill_base(display_channel, &display_channel->send_data.u.copy.base, item,
-                  sizeof(SpiceMsgDisplayDrawCopy), drawable->surface_id);
+                  sizeof(SpiceMsgDisplayDrawCopy), item->surface_id);
         display_channel->send_data.u.copy.data = drawable->u.copy;
         fill_bits(display_channel, &display_channel->send_data.u.copy.data.src_bitmap, item);
         fill_mask(display_channel, &display_channel->send_data.u.copy.data.mask, item);
@@ -6703,27 +6696,27 @@ static inline void red_send_qxl_drawable(RedWorker *worker, DisplayChannel *disp
     case QXL_DRAW_TRANSPARENT:
         channel->send_data.header.type = SPICE_MSG_DISPLAY_DRAW_TRANSPARENT;
         fill_base(display_channel, &display_channel->send_data.u.transparent.base, item,
-                  sizeof(SpiceMsgDisplayDrawTransparent), drawable->surface_id);
+                  sizeof(SpiceMsgDisplayDrawTransparent), item->surface_id);
         display_channel->send_data.u.transparent.data = drawable->u.transparent;
         fill_bits(display_channel, &display_channel->send_data.u.transparent.data.src_bitmap, item);
         break;
     case QXL_DRAW_ALPHA_BLEND:
         channel->send_data.header.type = SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND;
         fill_base(display_channel, &display_channel->send_data.u.alpha_blend.base, item,
-                  sizeof(SpiceMsgDisplayDrawAlphaBlend), drawable->surface_id);
+                  sizeof(SpiceMsgDisplayDrawAlphaBlend), item->surface_id);
         display_channel->send_data.u.alpha_blend.data = drawable->u.alpha_blend;
         fill_bits(display_channel, &display_channel->send_data.u.alpha_blend.data.src_bitmap, item);
         break;
     case QXL_COPY_BITS:
         channel->send_data.header.type = SPICE_MSG_DISPLAY_COPY_BITS;
         fill_base(display_channel, &display_channel->send_data.u.copy_bits.base, item,
-                  sizeof(SpiceMsgDisplayCopyBits), drawable->surface_id);
+                  sizeof(SpiceMsgDisplayCopyBits), item->surface_id);
         display_channel->send_data.u.copy_bits.src_pos = drawable->u.copy_bits.src_pos;
         break;
     case QXL_DRAW_BLEND:
         channel->send_data.header.type = SPICE_MSG_DISPLAY_DRAW_BLEND;
         fill_base(display_channel, &display_channel->send_data.u.blend.base, item,
-                  sizeof(SpiceMsgDisplayDrawBlend), drawable->surface_id);
+                  sizeof(SpiceMsgDisplayDrawBlend), item->surface_id);
         display_channel->send_data.u.blend.data = drawable->u.blend;
         fill_bits(display_channel, &display_channel->send_data.u.blend.data.src_bitmap, item);
         fill_mask(display_channel, &display_channel->send_data.u.blend.data.mask, item);
@@ -6731,28 +6724,28 @@ static inline void red_send_qxl_drawable(RedWorker *worker, DisplayChannel *disp
     case QXL_DRAW_BLACKNESS:
         channel->send_data.header.type = SPICE_MSG_DISPLAY_DRAW_BLACKNESS;
         fill_base(display_channel, &display_channel->send_data.u.blackness.base, item,
-                  sizeof(SpiceMsgDisplayDrawBlackness), drawable->surface_id);
+                  sizeof(SpiceMsgDisplayDrawBlackness), item->surface_id);
         display_channel->send_data.u.blackness.data = drawable->u.blackness;
         fill_mask(display_channel, &display_channel->send_data.u.blackness.data.mask, item);
         break;
     case QXL_DRAW_WHITENESS:
         channel->send_data.header.type = SPICE_MSG_DISPLAY_DRAW_WHITENESS;
         fill_base(display_channel, &display_channel->send_data.u.whiteness.base, item,
-                  sizeof(SpiceMsgDisplayDrawWhiteness), drawable->surface_id);
+                  sizeof(SpiceMsgDisplayDrawWhiteness), item->surface_id);
         display_channel->send_data.u.whiteness.data = drawable->u.whiteness;
         fill_mask(display_channel, &display_channel->send_data.u.whiteness.data.mask, item);
         break;
     case QXL_DRAW_INVERS:
         channel->send_data.header.type = SPICE_MSG_DISPLAY_DRAW_INVERS;
         fill_base(display_channel, &display_channel->send_data.u.invers.base, item,
-                  sizeof(SpiceMsgDisplayDrawInvers), drawable->surface_id);
+                  sizeof(SpiceMsgDisplayDrawInvers), item->surface_id);
         display_channel->send_data.u.invers.data = drawable->u.invers;
         fill_mask(display_channel, &display_channel->send_data.u.invers.data.mask, item);
         break;
     case QXL_DRAW_ROP3:
         channel->send_data.header.type = SPICE_MSG_DISPLAY_DRAW_ROP3;
         fill_base(display_channel, &display_channel->send_data.u.rop3.base, item,
-                  sizeof(SpiceMsgDisplayDrawRop3), drawable->surface_id);
+                  sizeof(SpiceMsgDisplayDrawRop3), item->surface_id);
         display_channel->send_data.u.rop3.data = drawable->u.rop3;
         fill_bits(display_channel, &display_channel->send_data.u.rop3.data.src_bitmap, item);
         fill_brush(display_channel, &display_channel->send_data.u.rop3.data.brush, item);
@@ -6761,7 +6754,7 @@ static inline void red_send_qxl_drawable(RedWorker *worker, DisplayChannel *disp
     case QXL_DRAW_STROKE:
         channel->send_data.header.type = SPICE_MSG_DISPLAY_DRAW_STROKE;
         fill_base(display_channel, &display_channel->send_data.u.stroke.base, item,
-                  sizeof(SpiceMsgDisplayDrawStroke), drawable->surface_id);
+                  sizeof(SpiceMsgDisplayDrawStroke), item->surface_id);
         display_channel->send_data.u.stroke.data = drawable->u.stroke;
         fill_path(display_channel, &display_channel->send_data.u.stroke.data.path, item->group_id);
         fill_attr(display_channel, &display_channel->send_data.u.stroke.data.attr, item->group_id);
@@ -6770,7 +6763,7 @@ static inline void red_send_qxl_drawable(RedWorker *worker, DisplayChannel *disp
     case QXL_DRAW_TEXT:
         channel->send_data.header.type = SPICE_MSG_DISPLAY_DRAW_TEXT;
         fill_base(display_channel, &display_channel->send_data.u.text.base, item,
-                  sizeof(SpiceMsgDisplayDrawText), drawable->surface_id);
+                  sizeof(SpiceMsgDisplayDrawText), item->surface_id);
         display_channel->send_data.u.text.data = drawable->u.text;
         fill_brush(display_channel, &display_channel->send_data.u.text.data.fore_brush, item);
         fill_brush(display_channel, &display_channel->send_data.u.text.data.back_brush, item);
@@ -9041,15 +9034,15 @@ static inline void handle_dev_update(RedWorker *worker)
     RedWorkeMessage message;
     const SpiceRect *rect;
     uint32_t *surface_id;
-
-    //ASSERT(worker->surfaces[0].context.canvas && worker->running);
+    uint32_t _surface_id;
 
     flush_display_commands(worker);
 
     worker->qxl->get_update_area(worker->qxl, &rect, &surface_id);
     ASSERT(worker->running);
-    validate_surface(worker, *surface_id);
-    red_update_area(worker, rect, *surface_id);
+    _surface_id = *surface_id;
+    validate_surface(worker, _surface_id);
+    red_update_area(worker, rect, _surface_id);
     message = RED_WORKER_MESSAGE_READY;
     write_message(worker->channel, &message);
 }
@@ -9136,7 +9129,7 @@ static inline void handle_dev_destroy_surfaces(RedWorker *worker)
         if (worker->surfaces[i].context.canvas) {
             destroy_surface_wait(worker, i);
             if (worker->surfaces[i].context.canvas) {
-                __red_destroy_surface(worker, i);
+                red_destroy_surface(worker, i);
             }
         }
     }
@@ -9217,6 +9210,7 @@ static inline void handle_dev_destroy_primary_surface(RedWorker *worker)
     receive_data(worker->channel, &surface_id, sizeof(uint32_t));
 
     PANIC_ON(surface_id != 0);
+    PANIC_ON(!worker->surfaces[surface_id].context.canvas);
 
     if (worker->cursor) {
         red_release_cursor(worker, worker->cursor);


More information about the Spice-commits mailing list