[Spice-commits] 6 commits - server/cursor-channel.c server/dcc-send.c server/display-channel.c server/display-channel.h server/red_memslots.c server/red_memslots.h server/red_parse_qxl.c server/red_record_qxl.c server/red_worker.c server/red_worker.h

Frediano Ziglio fziglio at kemper.freedesktop.org
Thu Dec 3 02:42:37 PST 2015


 server/cursor-channel.c  |    2 
 server/dcc-send.c        |    8 -
 server/display-channel.c |  250 +++++++++++++++++++++++++++++++++++++++
 server/display-channel.h |   20 ---
 server/red_memslots.c    |   34 ++---
 server/red_memslots.h    |   30 ++--
 server/red_parse_qxl.c   |   70 +++++------
 server/red_record_qxl.c  |  102 ++++++++--------
 server/red_worker.c      |  295 +++++------------------------------------------
 server/red_worker.h      |    2 
 10 files changed, 406 insertions(+), 407 deletions(-)

New commits:
commit bf1e139875564d45dbcd04f0f6121991fa0dd8d4
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Tue Dec 1 11:10:26 2015 +0000

    dcc: reduce statement wrapping
    
    Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
    Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
    Acked-by: Fabiano Fidêncio <fidencio at redhat.com>

diff --git a/server/dcc-send.c b/server/dcc-send.c
index 2340252..30303e7 100644
--- a/server/dcc-send.c
+++ b/server/dcc-send.c
@@ -2012,14 +2012,10 @@ static void red_marshall_image(RedChannelClient *rcc, SpiceMarshaller *m, ImageI
                bitmap_fmt_is_rgb(bitmap.format) &&
                red_channel_client_test_remote_cap(&dcc->common.base,
                                                   SPICE_DISPLAY_CAP_LZ4_COMPRESSION)) {
-        comp_succeeded = dcc_compress_image_lz4(dcc, &red_image, &bitmap,
-                                                &comp_send_data,
-                                                groupid);
+        comp_succeeded = dcc_compress_image_lz4(dcc, &red_image, &bitmap, &comp_send_data, groupid);
 #endif
     } else if (comp_mode != SPICE_IMAGE_COMPRESSION_OFF) {
-        comp_succeeded = dcc_compress_image_lz(dcc, &red_image, &bitmap,
-                                               &comp_send_data,
-                                               groupid);
+        comp_succeeded = dcc_compress_image_lz(dcc, &red_image, &bitmap, &comp_send_data, groupid);
     }
 
     surface_lossy_region = &dcc->surface_client_lossy_region[item->surface_id];
commit f31536802a06256ceff5d65b2fa6a01cd76e5b27
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Tue Dec 1 11:08:32 2015 +0000

    worker: change red_worker_new_channel result to CommonChannel*
    
    Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
    Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
    Acked-by: Fabiano Fidêncio <fidencio at redhat.com>

diff --git a/server/cursor-channel.c b/server/cursor-channel.c
index 9d72299..840ff30 100644
--- a/server/cursor-channel.c
+++ b/server/cursor-channel.c
@@ -427,7 +427,7 @@ static void cursor_channel_release_item(RedChannelClient *rcc, PipeItem *item, i
 CursorChannel* cursor_channel_new(RedWorker *worker)
 {
     CursorChannel *cursor_channel;
-    RedChannel *channel = NULL;
+    CommonChannel *channel = NULL;
     ChannelCbs cbs = {
         .on_disconnect =  cursor_channel_client_on_disconnect,
         .send_item = cursor_channel_send_item,
diff --git a/server/red_worker.c b/server/red_worker.c
index d501e2e..fd72992 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -638,7 +638,7 @@ CommonChannelClient *common_channel_new_client(CommonChannel *common,
 }
 
 
-RedChannel *red_worker_new_channel(RedWorker *worker, int size,
+CommonChannel *red_worker_new_channel(RedWorker *worker, int size,
                                    const char *name,
                                    uint32_t channel_type, int migration_flags,
                                    ChannelCbs *channel_cbs,
@@ -669,7 +669,7 @@ RedChannel *red_worker_new_channel(RedWorker *worker, int size,
 
     common = (CommonChannel *)channel;
     common->worker = worker;
-    return channel;
+    return common;
 }
 
 static void guest_set_client_capabilities(RedWorker *worker)
diff --git a/server/red_worker.h b/server/red_worker.h
index a76c805..755f0c3 100644
--- a/server/red_worker.h
+++ b/server/red_worker.h
@@ -106,7 +106,7 @@ RedMemSlotInfo* red_worker_get_memslot(RedWorker *worker);
 void red_drawable_unref(RedWorker *worker, RedDrawable *red_drawable,
                         uint32_t group_id);
 
-RedChannel *red_worker_new_channel(RedWorker *worker, int size,
+CommonChannel *red_worker_new_channel(RedWorker *worker, int size,
                                    const char *name,
                                    uint32_t channel_type, int migration_flags,
                                    ChannelCbs *channel_cbs,
commit 7280460b780236a71649a0c9e39198c668d8d461
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Tue Dec 1 16:33:07 2015 +0000

    memslot: prefix memslot functions with memslot_
    
    Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
    Acked-by: Fabiano Fidêncio <fidencio at redhat.com>

diff --git a/server/red_memslots.c b/server/red_memslots.c
index 1b3ec62..2fd939e 100644
--- a/server/red_memslots.c
+++ b/server/red_memslots.c
@@ -49,8 +49,8 @@ static void print_memslots(RedMemSlotInfo *info)
 }
 
 /* return 1 if validation successfull, 0 otherwise */
-int validate_virt(RedMemSlotInfo *info, unsigned long virt, int slot_id,
-                  uint32_t add_size, uint32_t group_id)
+int memslot_validate_virt(RedMemSlotInfo *info, unsigned long virt, int slot_id,
+                          uint32_t add_size, uint32_t group_id)
 {
     MemSlot *slot;
 
@@ -76,8 +76,8 @@ int validate_virt(RedMemSlotInfo *info, unsigned long virt, int slot_id,
  * return virtual address if successful, which may be 0.
  * returns 0 and sets error to 1 if an error condition occurs.
  */
-unsigned long get_virt(RedMemSlotInfo *info, QXLPHYSICAL addr, uint32_t add_size,
-                       int group_id, int *error)
+unsigned long memslot_get_virt(RedMemSlotInfo *info, QXLPHYSICAL addr, uint32_t add_size,
+                               int group_id, int *error)
 {
     int slot_id;
     int generation;
@@ -92,7 +92,7 @@ unsigned long get_virt(RedMemSlotInfo *info, QXLPHYSICAL addr, uint32_t add_size
         return 0;
     }
 
-    slot_id = get_memslot_id(info, addr);
+    slot_id = memslot_get_id(info, addr);
     if (slot_id > info->num_memslots) {
         print_memslots(info);
         spice_critical("slot_id %d too big, addr=%" PRIx64, slot_id, addr);
@@ -102,7 +102,7 @@ unsigned long get_virt(RedMemSlotInfo *info, QXLPHYSICAL addr, uint32_t add_size
 
     slot = &info->mem_slots[group_id][slot_id];
 
-    generation = get_generation(info, addr);
+    generation = memslot_get_generation(info, addr);
     if (generation != slot->generation) {
         print_memslots(info);
         spice_critical("address generation is not valid, group_id %d, slot_id %d, gen %d, slot_gen %d\n",
@@ -114,7 +114,7 @@ unsigned long get_virt(RedMemSlotInfo *info, QXLPHYSICAL addr, uint32_t add_size
     h_virt = __get_clean_virt(info, addr);
     h_virt += slot->address_delta;
 
-    if (!validate_virt(info, h_virt, slot_id, add_size, group_id)) {
+    if (!memslot_validate_virt(info, h_virt, slot_id, add_size, group_id)) {
         *error = 1;
         return 0;
     }
@@ -122,11 +122,11 @@ unsigned long get_virt(RedMemSlotInfo *info, QXLPHYSICAL addr, uint32_t add_size
     return h_virt;
 }
 
-void red_memslot_info_init(RedMemSlotInfo *info,
-                           uint32_t num_groups, uint32_t num_slots,
-                           uint8_t generation_bits,
-                           uint8_t id_bits,
-                           uint8_t internal_groupslot_id)
+void memslot_info_init(RedMemSlotInfo *info,
+                       uint32_t num_groups, uint32_t num_slots,
+                       uint8_t generation_bits,
+                       uint8_t id_bits,
+                       uint8_t internal_groupslot_id)
 {
     uint32_t i;
 
@@ -153,9 +153,9 @@ void red_memslot_info_init(RedMemSlotInfo *info,
                                        (info->mem_slot_bits + info->generation_bits));
 }
 
-void red_memslot_info_add_slot(RedMemSlotInfo *info, uint32_t slot_group_id, uint32_t slot_id,
-                               uint64_t addr_delta, unsigned long virt_start, unsigned long virt_end,
-                               uint32_t generation)
+void memslot_info_add_slot(RedMemSlotInfo *info, uint32_t slot_group_id, uint32_t slot_id,
+                           uint64_t addr_delta, unsigned long virt_start, unsigned long virt_end,
+                           uint32_t generation)
 {
     spice_assert(info->num_memslots_groups > slot_group_id);
     spice_assert(info->num_memslots > slot_id);
@@ -166,7 +166,7 @@ void red_memslot_info_add_slot(RedMemSlotInfo *info, uint32_t slot_group_id, uin
     info->mem_slots[slot_group_id][slot_id].generation = generation;
 }
 
-void red_memslot_info_del_slot(RedMemSlotInfo *info, uint32_t slot_group_id, uint32_t slot_id)
+void memslot_info_del_slot(RedMemSlotInfo *info, uint32_t slot_group_id, uint32_t slot_id)
 {
     spice_assert(info->num_memslots_groups > slot_group_id);
     spice_assert(info->num_memslots > slot_id);
@@ -175,7 +175,7 @@ void red_memslot_info_del_slot(RedMemSlotInfo *info, uint32_t slot_group_id, uin
     info->mem_slots[slot_group_id][slot_id].virt_end_addr = 0;
 }
 
-void red_memslot_info_reset(RedMemSlotInfo *info)
+void memslot_info_reset(RedMemSlotInfo *info)
 {
         uint32_t i;
         for (i = 0; i < info->num_memslots_groups; ++i) {
diff --git a/server/red_memslots.h b/server/red_memslots.h
index 27443a6..a40050c 100644
--- a/server/red_memslots.h
+++ b/server/red_memslots.h
@@ -43,30 +43,30 @@ typedef struct RedMemSlotInfo {
     unsigned long memslot_clean_virt_mask;
 } RedMemSlotInfo;
 
-static inline int get_memslot_id(RedMemSlotInfo *info, uint64_t addr)
+static inline int memslot_get_id(RedMemSlotInfo *info, uint64_t addr)
 {
     return addr >> info->memslot_id_shift;
 }
 
-static inline int get_generation(RedMemSlotInfo *info, uint64_t addr)
+static inline int memslot_get_generation(RedMemSlotInfo *info, uint64_t addr)
 {
     return (addr >> info->memslot_gen_shift) & info->memslot_gen_mask;
 }
 
-int validate_virt(RedMemSlotInfo *info, unsigned long virt, int slot_id,
-                  uint32_t add_size, uint32_t group_id);
-unsigned long get_virt(RedMemSlotInfo *info, QXLPHYSICAL addr, uint32_t add_size,
+int memslot_validate_virt(RedMemSlotInfo *info, unsigned long virt, int slot_id,
+                          uint32_t add_size, uint32_t group_id);
+unsigned long memslot_get_virt(RedMemSlotInfo *info, QXLPHYSICAL addr, uint32_t add_size,
                        int group_id, int *error);
 
-void red_memslot_info_init(RedMemSlotInfo *info,
-                           uint32_t num_groups, uint32_t num_slots,
-                           uint8_t generation_bits,
-                           uint8_t id_bits,
-                           uint8_t internal_groupslot_id);
-void red_memslot_info_add_slot(RedMemSlotInfo *info, uint32_t slot_group_id, uint32_t slot_id,
-                               uint64_t addr_delta, unsigned long virt_start, unsigned long virt_end,
-                               uint32_t generation);
-void red_memslot_info_del_slot(RedMemSlotInfo *info, uint32_t slot_group_id, uint32_t slot_id);
-void red_memslot_info_reset(RedMemSlotInfo *info);
+void memslot_info_init(RedMemSlotInfo *info,
+                       uint32_t num_groups, uint32_t num_slots,
+                       uint8_t generation_bits,
+                       uint8_t id_bits,
+                       uint8_t internal_groupslot_id);
+void memslot_info_add_slot(RedMemSlotInfo *info, uint32_t slot_group_id, uint32_t slot_id,
+                           uint64_t addr_delta, unsigned long virt_start, unsigned long virt_end,
+                           uint32_t generation);
+void memslot_info_del_slot(RedMemSlotInfo *info, uint32_t slot_group_id, uint32_t slot_id);
+void memslot_info_reset(RedMemSlotInfo *info);
 
 #endif
diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
index 2cfd5ea..6e2ca99 100644
--- a/server/red_parse_qxl.c
+++ b/server/red_parse_qxl.c
@@ -52,7 +52,7 @@ static void hexdump_qxl(RedMemSlotInfo *slots, int group_id,
     uint8_t *hex;
     int i;
 
-    hex = (uint8_t*)get_virt(slots, addr, bytes, group_id);
+    hex = (uint8_t*)memslot_get_virt(slots, addr, bytes, group_id);
     for (i = 0; i < bytes; i++) {
         if (0 == i % 16) {
             fprintf(stderr, "%lx: ", addr+i);
@@ -118,7 +118,7 @@ static size_t red_get_data_chunks_ptr(RedMemSlotInfo *slots, int group_id,
     data_size += red->data_size;
     red->data = qxl->data;
     red->prev_chunk = red->next_chunk = NULL;
-    if (!validate_virt(slots, (intptr_t)red->data, memslot_id, red->data_size, group_id)) {
+    if (!memslot_validate_virt(slots, (intptr_t)red->data, memslot_id, red->data_size, group_id)) {
         red->data = NULL;
         return 0;
     }
@@ -132,9 +132,9 @@ static size_t red_get_data_chunks_ptr(RedMemSlotInfo *slots, int group_id,
             goto error;
         }
 
-        memslot_id = get_memslot_id(slots, next_chunk);
-        qxl = (QXLDataChunk *)get_virt(slots, next_chunk, sizeof(*qxl),
-                                       group_id, &error);
+        memslot_id = memslot_get_id(slots, next_chunk);
+        qxl = (QXLDataChunk *)memslot_get_virt(slots, next_chunk, sizeof(*qxl),
+                                               group_id, &error);
         if (error)
             goto error;
 
@@ -161,7 +161,7 @@ static size_t red_get_data_chunks_ptr(RedMemSlotInfo *slots, int group_id,
             spice_warning("too much data inside chunks, avoiding DoS\n");
             goto error;
         }
-        if (!validate_virt(slots, (intptr_t)red->data, memslot_id, red->data_size, group_id))
+        if (!memslot_validate_virt(slots, (intptr_t)red->data, memslot_id, red->data_size, group_id))
             goto error;
     }
 
@@ -185,9 +185,9 @@ static size_t red_get_data_chunks(RedMemSlotInfo *slots, int group_id,
 {
     QXLDataChunk *qxl;
     int error;
-    int memslot_id = get_memslot_id(slots, addr);
+    int memslot_id = memslot_get_id(slots, addr);
 
-    qxl = (QXLDataChunk *)get_virt(slots, addr, sizeof(*qxl), group_id, &error);
+    qxl = (QXLDataChunk *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id, &error);
     if (error) {
         return 0;
     }
@@ -242,12 +242,12 @@ static SpicePath *red_get_path(RedMemSlotInfo *slots, int group_id,
     uint32_t count;
     int error;
 
-    qxl = (QXLPath *)get_virt(slots, addr, sizeof(*qxl), group_id, &error);
+    qxl = (QXLPath *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id, &error);
     if (error) {
         return NULL;
     }
     size = red_get_data_chunks_ptr(slots, group_id,
-                                   get_memslot_id(slots, addr),
+                                   memslot_get_id(slots, addr),
                                    &chunks, &qxl->chunk);
     data = red_linearize_chunk(&chunks, size, &free_data);
     red_put_data_chunks(&chunks);
@@ -321,12 +321,12 @@ static SpiceClipRects *red_get_clip_rects(RedMemSlotInfo *slots, int group_id,
     int error;
     uint32_t num_rects;
 
-    qxl = (QXLClipRects *)get_virt(slots, addr, sizeof(*qxl), group_id, &error);
+    qxl = (QXLClipRects *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id, &error);
     if (error) {
         return NULL;
     }
     size = red_get_data_chunks_ptr(slots, group_id,
-                                   get_memslot_id(slots, addr),
+                                   memslot_get_id(slots, addr),
                                    &chunks, &qxl->chunk);
     data = red_linearize_chunk(&chunks, size, &free_data);
     red_put_data_chunks(&chunks);
@@ -355,7 +355,7 @@ static SpiceChunks *red_get_image_data_flat(RedMemSlotInfo *slots, int group_id,
 
     data = spice_chunks_new(1);
     data->data_size      = size;
-    data->chunk[0].data  = (void*)get_virt(slots, addr, size, group_id, &error);
+    data->chunk[0].data  = (void*)memslot_get_virt(slots, addr, size, group_id, &error);
     if (error) {
         return 0;
     }
@@ -445,7 +445,7 @@ static SpiceImage *red_get_image(RedMemSlotInfo *slots, int group_id,
         return NULL;
     }
 
-    qxl = (QXLImage *)get_virt(slots, addr, sizeof(*qxl), group_id, &error);
+    qxl = (QXLImage *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id, &error);
     if (error) {
         return NULL;
     }
@@ -488,15 +488,15 @@ static SpiceImage *red_get_image(RedMemSlotInfo *slots, int group_id,
         if (palette) {
             QXLPalette *qp;
             int i, num_ents;
-            qp = (QXLPalette *)get_virt(slots, palette,
-                                        sizeof(*qp), group_id, &error);
+            qp = (QXLPalette *)memslot_get_virt(slots, palette,
+                                                sizeof(*qp), group_id, &error);
             if (error) {
                 goto error;
             }
             num_ents = qp->num_ents;
-            if (!validate_virt(slots, (intptr_t)qp->ents,
-                               get_memslot_id(slots, palette),
-                               num_ents * sizeof(qp->ents[0]), group_id)) {
+            if (!memslot_validate_virt(slots, (intptr_t)qp->ents,
+                                       memslot_get_id(slots, palette),
+                                       num_ents * sizeof(qp->ents[0]), group_id)) {
                 goto error;
             }
             rp = spice_malloc_n_m(num_ents, sizeof(rp->ents[0]), sizeof(*rp));
@@ -544,7 +544,7 @@ static SpiceImage *red_get_image(RedMemSlotInfo *slots, int group_id,
     case SPICE_IMAGE_TYPE_QUIC:
         red->u.quic.data_size = qxl->quic.data_size;
         size = red_get_data_chunks_ptr(slots, group_id,
-                                       get_memslot_id(slots, addr),
+                                       memslot_get_id(slots, addr),
                                        &chunks, (QXLDataChunk *)qxl->quic.data);
         spice_assert(size == red->u.quic.data_size);
         if (size != red->u.quic.data_size) {
@@ -741,7 +741,7 @@ static bool get_transform(RedMemSlotInfo *slots,
     if (qxl_transform == 0)
         return FALSE;
 
-    t = (uint32_t *)get_virt(slots, qxl_transform, sizeof(*dst_transform), group_id, &error);
+    t = (uint32_t *)memslot_get_virt(slots, qxl_transform, sizeof(*dst_transform), group_id, &error);
 
     if (!t || error)
         return FALSE;
@@ -816,8 +816,8 @@ static int red_get_stroke_ptr(RedMemSlotInfo *slots, int group_id,
         red->attr.style = spice_malloc_n(style_nseg, sizeof(SPICE_FIXED28_4));
         red->attr.style_nseg  = style_nseg;
         spice_assert(qxl->attr.style);
-        buf = (uint8_t *)get_virt(slots, qxl->attr.style,
-                                  style_nseg * sizeof(QXLFIXED), group_id, &error);
+        buf = (uint8_t *)memslot_get_virt(slots, qxl->attr.style,
+                                          style_nseg * sizeof(QXLFIXED), group_id, &error);
         if (error) {
             return error;
         }
@@ -858,12 +858,12 @@ static SpiceString *red_get_string(RedMemSlotInfo *slots, int group_id,
     int error;
     uint16_t qxl_flags, qxl_length;
 
-    qxl = (QXLString *)get_virt(slots, addr, sizeof(*qxl), group_id, &error);
+    qxl = (QXLString *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id, &error);
     if (error) {
         return NULL;
     }
     chunk_size = red_get_data_chunks_ptr(slots, group_id,
-                                         get_memslot_id(slots, addr),
+                                         memslot_get_id(slots, addr),
                                          &chunks, &qxl->chunk);
     if (!chunk_size) {
         /* XXX could be a zero sized string.. */
@@ -1013,7 +1013,7 @@ static int red_get_native_drawable(RedMemSlotInfo *slots, int group_id,
     int i;
     int error = 0;
 
-    qxl = (QXLDrawable *)get_virt(slots, addr, sizeof(*qxl), group_id, &error);
+    qxl = (QXLDrawable *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id, &error);
     if (error) {
         return error;
     }
@@ -1096,7 +1096,7 @@ static int red_get_compat_drawable(RedMemSlotInfo *slots, int group_id,
     QXLCompatDrawable *qxl;
     int error;
 
-    qxl = (QXLCompatDrawable *)get_virt(slots, addr, sizeof(*qxl), group_id, &error);
+    qxl = (QXLCompatDrawable *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id, &error);
     if (error) {
         return error;
     }
@@ -1244,7 +1244,7 @@ int red_get_update_cmd(RedMemSlotInfo *slots, int group_id,
     QXLUpdateCmd *qxl;
     int error;
 
-    qxl = (QXLUpdateCmd *)get_virt(slots, addr, sizeof(*qxl), group_id, &error);
+    qxl = (QXLUpdateCmd *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id, &error);
     if (error) {
         return 1;
     }
@@ -1273,7 +1273,7 @@ int red_get_message(RedMemSlotInfo *slots, int group_id,
      *   luckily this is for debug logging only,
      *   so we can just ignore it by default.
      */
-    qxl = (QXLMessage *)get_virt(slots, addr, sizeof(*qxl), group_id, &error);
+    qxl = (QXLMessage *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id, &error);
     if (error) {
         return 1;
     }
@@ -1312,8 +1312,8 @@ int red_get_surface_cmd(RedMemSlotInfo *slots, int group_id,
     int error;
     unsigned int bpp;
 
-    qxl = (QXLSurfaceCmd *)get_virt(slots, addr, sizeof(*qxl), group_id,
-                                    &error);
+    qxl = (QXLSurfaceCmd *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id,
+                                            &error);
     if (error) {
         return 1;
     }
@@ -1350,7 +1350,7 @@ int red_get_surface_cmd(RedMemSlotInfo *slots, int group_id,
             return 1;
         }
         red->u.surface_create.data =
-            (uint8_t*)get_virt(slots, qxl->u.surface_create.data, size, group_id, &error);
+            (uint8_t*)memslot_get_virt(slots, qxl->u.surface_create.data, size, group_id, &error);
         if (error) {
             return 1;
         }
@@ -1374,7 +1374,7 @@ static int red_get_cursor(RedMemSlotInfo *slots, int group_id,
     bool free_data;
     int error;
 
-    qxl = (QXLCursor *)get_virt(slots, addr, sizeof(*qxl), group_id, &error);
+    qxl = (QXLCursor *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id, &error);
     if (error) {
         return 1;
     }
@@ -1389,7 +1389,7 @@ static int red_get_cursor(RedMemSlotInfo *slots, int group_id,
     red->flags = 0;
     red->data_size = qxl->data_size;
     size = red_get_data_chunks_ptr(slots, group_id,
-                                   get_memslot_id(slots, addr),
+                                   memslot_get_id(slots, addr),
                                    &chunks, &qxl->chunk);
     red->data_size = MIN(red->data_size, size);
     data = red_linearize_chunk(&chunks, size, &free_data);
@@ -1414,7 +1414,7 @@ int red_get_cursor_cmd(RedMemSlotInfo *slots, int group_id,
     QXLCursorCmd *qxl;
     int error;
 
-    qxl = (QXLCursorCmd *)get_virt(slots, addr, sizeof(*qxl), group_id, &error);
+    qxl = (QXLCursorCmd *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id, &error);
     if (error) {
         return error;
     }
diff --git a/server/red_record_qxl.c b/server/red_record_qxl.c
index b35b462..17f17bd 100644
--- a/server/red_record_qxl.c
+++ b/server/red_record_qxl.c
@@ -35,8 +35,8 @@ static void hexdump_qxl(RedMemSlotInfo *slots, int group_id,
     int i;
     int error;
 
-    hex = (uint8_t*)get_virt(slots, addr, bytes, group_id,
-                             &error);
+    hex = (uint8_t*)memslot_get_virt(slots, addr, bytes, group_id,
+                                     &error);
     for (i = 0; i < bytes; i++) {
         if (0 == i % 16) {
             fprintf(stderr, "%lx: ", addr+i);
@@ -139,21 +139,21 @@ static size_t red_record_data_chunks_ptr(FILE *fd, const char *prefix,
 
     while (cur->next_chunk) {
         cur =
-            (QXLDataChunk*)get_virt(slots, cur->next_chunk, sizeof(*cur), group_id,
-                                    &error);
+            (QXLDataChunk*)memslot_get_virt(slots, cur->next_chunk, sizeof(*cur), group_id,
+                                            &error);
         data_size += cur->data_size;
         count_chunks++;
     }
     fprintf(fd, "data_chunks %d %ld\n", count_chunks, data_size);
-    validate_virt(slots, (intptr_t)qxl->data, memslot_id, qxl->data_size, group_id);
+    memslot_validate_virt(slots, (intptr_t)qxl->data, memslot_id, qxl->data_size, group_id);
     write_binary(fd, prefix, qxl->data_size, qxl->data);
 
     while (qxl->next_chunk) {
-        memslot_id = get_memslot_id(slots, qxl->next_chunk);
-        qxl = (QXLDataChunk*)get_virt(slots, qxl->next_chunk, sizeof(*qxl), group_id,
-                                      &error);
+        memslot_id = memslot_get_id(slots, qxl->next_chunk);
+        qxl = (QXLDataChunk*)memslot_get_virt(slots, qxl->next_chunk, sizeof(*qxl), group_id,
+                                              &error);
 
-        validate_virt(slots, (intptr_t)qxl->data, memslot_id, qxl->data_size, group_id);
+        memslot_validate_virt(slots, (intptr_t)qxl->data, memslot_id, qxl->data_size, group_id);
         write_binary(fd, prefix, qxl->data_size, qxl->data);
     }
 
@@ -165,11 +165,11 @@ static size_t red_record_data_chunks(FILE *fd, const char *prefix,
                                      QXLPHYSICAL addr)
 {
     QXLDataChunk *qxl;
-    int memslot_id = get_memslot_id(slots, addr);
+    int memslot_id = memslot_get_id(slots, addr);
     int error;
 
-    qxl = (QXLDataChunk*)get_virt(slots, addr, sizeof(*qxl), group_id,
-                                  &error);
+    qxl = (QXLDataChunk*)memslot_get_virt(slots, addr, sizeof(*qxl), group_id,
+                                          &error);
     return red_record_data_chunks_ptr(fd, prefix, slots, group_id, memslot_id, qxl);
 }
 
@@ -195,10 +195,10 @@ static void red_record_path(FILE *fd, RedMemSlotInfo *slots, int group_id,
     QXLPath *qxl;
     int error;
 
-    qxl = (QXLPath *)get_virt(slots, addr, sizeof(*qxl), group_id,
-                              &error);
+    qxl = (QXLPath *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id,
+                                      &error);
     red_record_data_chunks_ptr(fd, "path", slots, group_id,
-                                   get_memslot_id(slots, addr),
+                                   memslot_get_id(slots, addr),
                                    &qxl->chunk);
 }
 
@@ -208,11 +208,11 @@ static void red_record_clip_rects(FILE *fd, RedMemSlotInfo *slots, int group_id,
     QXLClipRects *qxl;
     int error;
 
-    qxl = (QXLClipRects *)get_virt(slots, addr, sizeof(*qxl), group_id,
-                                   &error);
+    qxl = (QXLClipRects *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id,
+                                           &error);
     fprintf(fd, "num_rects %d\n", qxl->num_rects);
     red_record_data_chunks_ptr(fd, "clip_rects", slots, group_id,
-                                   get_memslot_id(slots, addr),
+                                   memslot_get_id(slots, addr),
                                    &qxl->chunk);
 }
 
@@ -223,8 +223,8 @@ static void red_record_virt_data_flat(FILE *fd, const char *prefix,
     int error;
 
     write_binary(fd, prefix,
-                 size, (uint8_t*)get_virt(slots, addr, size, group_id,
-                                          &error));
+                 size, (uint8_t*)memslot_get_virt(slots, addr, size, group_id,
+                                                  &error));
 }
 
 static void red_record_image_data_flat(FILE *fd, RedMemSlotInfo *slots, int group_id,
@@ -253,8 +253,8 @@ static void red_record_image(FILE *fd, RedMemSlotInfo *slots, int group_id,
         return;
     }
 
-    qxl = (QXLImage *)get_virt(slots, addr, sizeof(*qxl), group_id,
-                               &error);
+    qxl = (QXLImage *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id,
+                                       &error);
     fprintf(fd, "descriptor.id %ld\n", qxl->descriptor.id);
     fprintf(fd, "descriptor.type %d\n", qxl->descriptor.type);
     fprintf(fd, "descriptor.flags %d\n", qxl->descriptor.flags);
@@ -273,12 +273,12 @@ static void red_record_image(FILE *fd, RedMemSlotInfo *slots, int group_id,
         if (qxl->bitmap.palette) {
             QXLPalette *qp;
             int i, num_ents;
-            qp = (QXLPalette *)get_virt(slots, qxl->bitmap.palette,
-                                        sizeof(*qp), group_id, &error);
+            qp = (QXLPalette *)memslot_get_virt(slots, qxl->bitmap.palette,
+                                                sizeof(*qp), group_id, &error);
             num_ents = qp->num_ents;
             fprintf(fd, "qp.num_ents %d\n", qp->num_ents);
-            validate_virt(slots, (intptr_t)qp->ents,
-                          get_memslot_id(slots, qxl->bitmap.palette),
+            memslot_validate_virt(slots, (intptr_t)qp->ents,
+                          memslot_get_id(slots, qxl->bitmap.palette),
                           num_ents * sizeof(qp->ents[0]), group_id);
             fprintf(fd, "unique %ld\n", qp->unique);
             for (i = 0; i < num_ents; i++) {
@@ -302,7 +302,7 @@ static void red_record_image(FILE *fd, RedMemSlotInfo *slots, int group_id,
     case SPICE_IMAGE_TYPE_QUIC:
         fprintf(fd, "quic.data_size %d\n", qxl->quic.data_size);
         size = red_record_data_chunks_ptr(fd, "quic.data", slots, group_id,
-                                       get_memslot_id(slots, addr),
+                                       memslot_get_id(slots, addr),
                                        (QXLDataChunk *)qxl->quic.data);
         spice_assert(size == qxl->quic.data_size);
         break;
@@ -426,9 +426,9 @@ static void red_record_stroke_ptr(FILE *fd, RedMemSlotInfo *slots, int group_id,
 
         fprintf(fd, "attr.style_nseg %d\n", qxl->attr.style_nseg);
         spice_assert(qxl->attr.style);
-        buf = (uint8_t *)get_virt(slots, qxl->attr.style,
-                                  style_nseg * sizeof(QXLFIXED), group_id,
-                                  &error);
+        buf = (uint8_t *)memslot_get_virt(slots, qxl->attr.style,
+                                          style_nseg * sizeof(QXLFIXED), group_id,
+                                          &error);
         write_binary(fd, "style", style_nseg * sizeof(QXLFIXED), buf);
     }
     red_record_brush_ptr(fd, slots, group_id, &qxl->brush, flags);
@@ -443,14 +443,14 @@ static void red_record_string(FILE *fd, RedMemSlotInfo *slots, int group_id,
     size_t chunk_size;
     int error;
 
-    qxl = (QXLString *)get_virt(slots, addr, sizeof(*qxl), group_id,
-                                &error);
+    qxl = (QXLString *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id,
+                                        &error);
     fprintf(fd, "data_size %d\n", qxl->data_size);
     fprintf(fd, "length %d\n", qxl->length);
     fprintf(fd, "flags %d\n", qxl->flags);
     chunk_size = red_record_data_chunks_ptr(fd, "string", slots, group_id,
-                                         get_memslot_id(slots, addr),
-                                         &qxl->chunk);
+                                            memslot_get_id(slots, addr),
+                                            &qxl->chunk);
     spice_assert(chunk_size == qxl->data_size);
 }
 
@@ -521,8 +521,8 @@ static void red_record_native_drawable(FILE *fd, RedMemSlotInfo *slots, int grou
     int i;
     int error;
 
-    qxl = (QXLDrawable *)get_virt(slots, addr, sizeof(*qxl), group_id,
-                                  &error);
+    qxl = (QXLDrawable *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id,
+                                          &error);
 
     red_record_rect_ptr(fd, "bbox", &qxl->bbox);
     red_record_clip_ptr(fd, slots, group_id, &qxl->clip);
@@ -597,8 +597,8 @@ static void red_record_compat_drawable(FILE *fd, RedMemSlotInfo *slots, int grou
     QXLCompatDrawable *qxl;
     int error;
 
-    qxl = (QXLCompatDrawable *)get_virt(slots, addr, sizeof(*qxl), group_id,
-                                        &error);
+    qxl = (QXLCompatDrawable *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id,
+                                                &error);
 
     red_record_rect_ptr(fd, "bbox", &qxl->bbox);
     red_record_clip_ptr(fd, slots, group_id, &qxl->clip);
@@ -676,8 +676,8 @@ static void red_record_update_cmd(FILE *fd, RedMemSlotInfo *slots, int group_id,
     QXLUpdateCmd *qxl;
     int error;
 
-    qxl = (QXLUpdateCmd *)get_virt(slots, addr, sizeof(*qxl), group_id,
-                                   &error);
+    qxl = (QXLUpdateCmd *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id,
+                                           &error);
 
     fprintf(fd, "update\n");
     red_record_rect_ptr(fd, "area", &qxl->area);
@@ -697,8 +697,8 @@ static void red_record_message(FILE *fd, RedMemSlotInfo *slots, int group_id,
      *   luckily this is for debug logging only,
      *   so we can just ignore it by default.
      */
-    qxl = (QXLMessage *)get_virt(slots, addr, sizeof(*qxl), group_id,
-                                 &error);
+    qxl = (QXLMessage *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id,
+                                         &error);
     write_binary(fd, "message", strlen((char*)qxl->data), (uint8_t*)qxl->data);
 }
 
@@ -709,8 +709,8 @@ static void red_record_surface_cmd(FILE *fd, RedMemSlotInfo *slots, int group_id
     size_t size;
     int error;
 
-    qxl = (QXLSurfaceCmd *)get_virt(slots, addr, sizeof(*qxl), group_id,
-                                    &error);
+    qxl = (QXLSurfaceCmd *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id,
+                                            &error);
 
     fprintf(fd, "surface_cmd\n");
     fprintf(fd, "surface_id %d\n", qxl->surface_id);
@@ -726,8 +726,8 @@ static void red_record_surface_cmd(FILE *fd, RedMemSlotInfo *slots, int group_id
         size = qxl->u.surface_create.height * abs(qxl->u.surface_create.stride);
         if ((qxl->flags & QXL_SURF_FLAG_KEEP_DATA) != 0) {
             write_binary(fd, "data", size,
-                (uint8_t*)get_virt(slots, qxl->u.surface_create.data, size, group_id,
-                                   &error));
+                (uint8_t*)memslot_get_virt(slots, qxl->u.surface_create.data, size, group_id,
+                                           &error));
         }
         break;
     }
@@ -739,8 +739,8 @@ static void red_record_cursor(FILE *fd, RedMemSlotInfo *slots, int group_id,
     QXLCursor *qxl;
     int error;
 
-    qxl = (QXLCursor *)get_virt(slots, addr, sizeof(*qxl), group_id,
-                                &error);
+    qxl = (QXLCursor *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id,
+                                        &error);
 
     fprintf(fd, "header.unique %ld\n", qxl->header.unique);
     fprintf(fd, "header.type %d\n", qxl->header.type);
@@ -751,7 +751,7 @@ static void red_record_cursor(FILE *fd, RedMemSlotInfo *slots, int group_id,
 
     fprintf(fd, "data_size %d\n", qxl->data_size);
     red_record_data_chunks_ptr(fd, "cursor", slots, group_id,
-                                   get_memslot_id(slots, addr),
+                                   memslot_get_id(slots, addr),
                                    &qxl->chunk);
 }
 
@@ -761,8 +761,8 @@ void red_record_cursor_cmd(FILE *fd, RedMemSlotInfo *slots, int group_id,
     QXLCursorCmd *qxl;
     int error;
 
-    qxl = (QXLCursorCmd *)get_virt(slots, addr, sizeof(*qxl), group_id,
-                                   &error);
+    qxl = (QXLCursorCmd *)memslot_get_virt(slots, addr, sizeof(*qxl), group_id,
+                                           &error);
 
     fprintf(fd, "cursor_cmd\n");
     fprintf(fd, "type %d\n", qxl->type);
diff --git a/server/red_worker.c b/server/red_worker.c
index b10b52e..d501e2e 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -787,7 +787,7 @@ static void handle_dev_del_memslot(void *opaque, void *payload)
     uint32_t slot_id = msg->slot_id;
     uint32_t slot_group_id = msg->slot_group_id;
 
-    red_memslot_info_del_slot(&worker->mem_slots, slot_group_id, slot_id);
+    memslot_info_del_slot(&worker->mem_slots, slot_group_id, slot_id);
 }
 
 static void handle_dev_destroy_surface_wait(void *opaque, void *payload)
@@ -860,9 +860,9 @@ static void dev_create_primary_surface(RedWorker *worker, uint32_t surface_id,
     spice_warn_if(((uint64_t)abs(surface.stride) * (uint64_t)surface.height) !=
              abs(surface.stride) * surface.height);
 
-    line_0 = (uint8_t*)get_virt(&worker->mem_slots, surface.mem,
-                                surface.height * abs(surface.stride),
-                                surface.group_id, &error);
+    line_0 = (uint8_t*)memslot_get_virt(&worker->mem_slots, surface.mem,
+                                        surface.height * abs(surface.stride),
+                                        surface.group_id, &error);
     if (error) {
         return;
     }
@@ -1139,9 +1139,9 @@ static void handle_dev_monitors_config_async(void *opaque, void *payload)
     int error;
     uint16_t count, max_allowed;
     QXLMonitorsConfig *dev_monitors_config =
-        (QXLMonitorsConfig*)get_virt(&worker->mem_slots, msg->monitors_config,
-                                     qxl_monitors_config_size(1),
-                                     msg->group_id, &error);
+        (QXLMonitorsConfig*)memslot_get_virt(&worker->mem_slots, msg->monitors_config,
+                                             qxl_monitors_config_size(1),
+                                             msg->group_id, &error);
 
     if (error) {
         /* TODO: raise guest bug (requires added QXL interface) */
@@ -1163,9 +1163,9 @@ static void handle_dev_monitors_config_async(void *opaque, void *payload)
     }
     /* get pointer again to check virtual size */
     dev_monitors_config =
-        (QXLMonitorsConfig*)get_virt(&worker->mem_slots, msg->monitors_config,
-                                     qxl_monitors_config_size(count),
-                                     msg->group_id, &error);
+        (QXLMonitorsConfig*)memslot_get_virt(&worker->mem_slots, msg->monitors_config,
+                                             qxl_monitors_config_size(count),
+                                             msg->group_id, &error);
     if (error) {
         /* TODO: raise guest bug (requires added QXL interface) */
         return;
@@ -1267,9 +1267,9 @@ static void handle_dev_set_mouse_mode(void *opaque, void *payload)
 
 static void dev_add_memslot(RedWorker *worker, QXLDevMemSlot mem_slot)
 {
-    red_memslot_info_add_slot(&worker->mem_slots, mem_slot.slot_group_id, mem_slot.slot_id,
-                              mem_slot.addr_delta, mem_slot.virt_start, mem_slot.virt_end,
-                              mem_slot.generation);
+    memslot_info_add_slot(&worker->mem_slots, mem_slot.slot_group_id, mem_slot.slot_id,
+                          mem_slot.addr_delta, mem_slot.virt_start, mem_slot.virt_end,
+                          mem_slot.generation);
 }
 
 static void handle_dev_add_memslot(void *opaque, void *payload)
@@ -1278,9 +1278,9 @@ static void handle_dev_add_memslot(void *opaque, void *payload)
     RedWorkerMessageAddMemslot *msg = payload;
     QXLDevMemSlot mem_slot = msg->mem_slot;
 
-    red_memslot_info_add_slot(&worker->mem_slots, mem_slot.slot_group_id, mem_slot.slot_id,
-                              mem_slot.addr_delta, mem_slot.virt_start, mem_slot.virt_end,
-                              mem_slot.generation);
+    memslot_info_add_slot(&worker->mem_slots, mem_slot.slot_group_id, mem_slot.slot_id,
+                          mem_slot.addr_delta, mem_slot.virt_start, mem_slot.virt_end,
+                          mem_slot.generation);
 }
 
 static void handle_dev_add_memslot_async(void *opaque, void *payload)
@@ -1295,7 +1295,7 @@ static void handle_dev_reset_memslots(void *opaque, void *payload)
 {
     RedWorker *worker = opaque;
 
-    red_memslot_info_reset(&worker->mem_slots);
+    memslot_info_reset(&worker->mem_slots);
 }
 
 static void handle_dev_driver_unload(void *opaque, void *payload)
@@ -1607,12 +1607,12 @@ RedWorker* red_worker_new(QXLInstance *qxl, RedDispatcher *red_dispatcher)
     worker->watches[0].watch_func = handle_dev_input;
     worker->watches[0].watch_func_opaque = worker;
 
-    red_memslot_info_init(&worker->mem_slots,
-                          init_info.num_memslots_groups,
-                          init_info.num_memslots,
-                          init_info.memslot_gen_bits,
-                          init_info.memslot_id_bits,
-                          init_info.internal_groupslot_id);
+    memslot_info_init(&worker->mem_slots,
+                      init_info.num_memslots_groups,
+                      init_info.num_memslots,
+                      init_info.memslot_gen_bits,
+                      init_info.memslot_id_bits,
+                      init_info.internal_groupslot_id);
 
     spice_warn_if(init_info.n_surfaces > NUM_SURFACES);
 
commit 768dfa2139f9959daffcd4cac5128c13bff461ad
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Mon Nov 30 18:06:34 2015 +0000

    worker: do not use dynamic memory for RedSurfaceCmd
    
    Allocation on stack is sufficient and code is more similar to
    QXL_CMD_MESSAGE and QXL_CMD_UPDATE cases.
    
    Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
    Acked-by: Fabiano Fidêncio <fidencio at redhat.com>

diff --git a/server/display-channel.c b/server/display-channel.c
index ba39174..e9e3770 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -2078,7 +2078,7 @@ void display_channel_process_surface_cmd(DisplayChannel *display, RedSurfaceCmd
 
     surface_id = surface->surface_id;
     if SPICE_UNLIKELY(surface_id >= display->n_surfaces) {
-        goto exit;
+        return;
     }
 
     red_surface = &display->surfaces[surface_id];
@@ -2116,9 +2116,6 @@ void display_channel_process_surface_cmd(DisplayChannel *display, RedSurfaceCmd
     default:
         spice_warn_if_reached();
     };
-exit:
-    red_put_surface_cmd(surface);
-    free(surface);
 }
 
 void display_channel_update_compression(DisplayChannel *display, DisplayChannelClient *dcc)
diff --git a/server/red_worker.c b/server/red_worker.c
index 81b7fdc..b10b52e 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -329,15 +329,16 @@ static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size, int *
             break;
         }
         case QXL_CMD_SURFACE: {
-            RedSurfaceCmd *surface = spice_new0(RedSurfaceCmd, 1);
+            RedSurfaceCmd surface;
 
             if (red_get_surface_cmd(&worker->mem_slots, ext_cmd.group_id,
-                                    surface, ext_cmd.cmd.data)) {
-                free(surface);
+                                    &surface, ext_cmd.cmd.data)) {
                 break;
             }
-            display_channel_process_surface_cmd(worker->display_channel, surface,
+            display_channel_process_surface_cmd(worker->display_channel, &surface,
                                                 ext_cmd.group_id, FALSE);
+            // do not release resource as is released inside red_process_surface
+            red_put_surface_cmd(&surface);
             break;
         }
         default:
commit c1ecbaf7b1faa7fee4328e76607f3ea638381756
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Fri Nov 27 12:49:40 2015 +0000

    display: move more logic in display_channel_get_drawable()
    
    Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
    Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
    Acked-by: Fabiano Fidêncio <fidencio at redhat.com>

diff --git a/server/display-channel.c b/server/display-channel.c
index 27f0d34..ba39174 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -916,6 +916,152 @@ void display_channel_print_stats(DisplayChannel *display)
 #endif
 }
 
+static inline void red_inc_surfaces_drawable_dependencies(DisplayChannel *display, Drawable *drawable)
+{
+    int x;
+    int surface_id;
+    RedSurface *surface;
+
+    for (x = 0; x < 3; ++x) {
+        surface_id = drawable->surface_deps[x];
+        if (surface_id == -1) {
+            continue;
+        }
+        surface = &display->surfaces[surface_id];
+        surface->refs++;
+    }
+}
+
+static void red_get_area(DisplayChannel *display, int surface_id, const SpiceRect *area,
+                         uint8_t *dest, int dest_stride, int update)
+{
+    SpiceCanvas *canvas;
+    RedSurface *surface;
+
+    surface = &display->surfaces[surface_id];
+    if (update) {
+        display_channel_draw(display, area, surface_id);
+    }
+
+    canvas = surface->context.canvas;
+    canvas->ops->read_bits(canvas, dest, dest_stride, area);
+}
+
+static int display_channel_handle_self_bitmap(DisplayChannel *display, Drawable *drawable)
+{
+    SpiceImage *image;
+    int32_t width;
+    int32_t height;
+    uint8_t *dest;
+    int dest_stride;
+    RedSurface *surface;
+    int bpp;
+    int all_set;
+    RedDrawable *red_drawable = drawable->red_drawable;
+
+    if (!red_drawable->self_bitmap) {
+        return TRUE;
+    }
+
+    surface = &display->surfaces[drawable->surface_id];
+
+    bpp = SPICE_SURFACE_FMT_DEPTH(surface->context.format) / 8;
+
+    width = red_drawable->self_bitmap_area.right
+            - red_drawable->self_bitmap_area.left;
+    height = red_drawable->self_bitmap_area.bottom
+            - red_drawable->self_bitmap_area.top;
+    dest_stride = SPICE_ALIGN(width * bpp, 4);
+
+    image = spice_new0(SpiceImage, 1);
+    image->descriptor.type = SPICE_IMAGE_TYPE_BITMAP;
+    image->descriptor.flags = 0;
+
+    QXL_SET_IMAGE_ID(image, QXL_IMAGE_GROUP_RED, display_channel_generate_uid(display));
+    image->u.bitmap.flags = surface->context.top_down ? SPICE_BITMAP_FLAGS_TOP_DOWN : 0;
+    image->u.bitmap.format = spice_bitmap_from_surface_type(surface->context.format);
+    image->u.bitmap.stride = dest_stride;
+    image->descriptor.width = image->u.bitmap.x = width;
+    image->descriptor.height = image->u.bitmap.y = height;
+    image->u.bitmap.palette = NULL;
+
+    dest = (uint8_t *)spice_malloc_n(height, dest_stride);
+    image->u.bitmap.data = spice_chunks_new_linear(dest, height * dest_stride);
+    image->u.bitmap.data->flags |= SPICE_CHUNKS_FLAGS_FREE;
+
+    red_get_area(display, drawable->surface_id,
+                 &red_drawable->self_bitmap_area, dest, dest_stride, TRUE);
+
+    /* For 32bit non-primary surfaces we need to keep any non-zero
+       high bytes as the surface may be used as source to an alpha_blend */
+    if (!is_primary_surface(display, drawable->surface_id) &&
+        image->u.bitmap.format == SPICE_BITMAP_FMT_32BIT &&
+        rgb32_data_has_alpha(width, height, dest_stride, dest, &all_set)) {
+        if (all_set) {
+            image->descriptor.flags |= SPICE_IMAGE_FLAGS_HIGH_BITS_SET;
+        } else {
+            image->u.bitmap.format = SPICE_BITMAP_FMT_RGBA;
+        }
+    }
+
+    red_drawable->self_bitmap_image = image;
+    return TRUE;
+}
+
+static inline void add_to_surface_dependency(DisplayChannel *display, int depend_on_surface_id,
+                                             DependItem *depend_item, Drawable *drawable)
+{
+    RedSurface *surface;
+
+    if (depend_on_surface_id == -1) {
+        depend_item->drawable = NULL;
+        return;
+    }
+
+    surface = &display->surfaces[depend_on_surface_id];
+
+    depend_item->drawable = drawable;
+    ring_add(&surface->depend_on_me, &depend_item->ring_item);
+}
+
+static inline int red_handle_surfaces_dependencies(DisplayChannel *display, Drawable *drawable)
+{
+    int x;
+
+    for (x = 0; x < 3; ++x) {
+        // surface self dependency is handled by shadows in "current", or by
+        // handle_self_bitmap
+        if (drawable->surface_deps[x] != drawable->surface_id) {
+            add_to_surface_dependency(display, drawable->surface_deps[x],
+                                      &drawable->depend_items[x], drawable);
+
+            if (drawable->surface_deps[x] == 0) {
+                QRegion depend_region;
+                region_init(&depend_region);
+                region_add(&depend_region, &drawable->red_drawable->surfaces_rects[x]);
+                stream_detach_behind(display, &depend_region, NULL);
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+static void draw_depend_on_me(DisplayChannel *display, uint32_t surface_id)
+{
+    RedSurface *surface;
+    RingItem *ring_item;
+
+    surface = &display->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;
+        display_channel_draw(display, &drawable->red_drawable->bbox, drawable->surface_id);
+    }
+}
+
 static int validate_drawable_bbox(DisplayChannel *display, RedDrawable *drawable)
 {
         DrawContext *context;
@@ -980,6 +1126,45 @@ void display_channel_add_drawable(DisplayChannel *display, Drawable *drawable)
 {
     int success = FALSE, surface_id = drawable->surface_id;
     RedDrawable *red_drawable = drawable->red_drawable;
+
+    red_drawable->mm_time = reds_get_mm_time();
+    surface_id = drawable->surface_id;
+
+    display->surfaces[surface_id].refs++;
+
+    region_add(&drawable->tree_item.base.rgn, &red_drawable->bbox);
+
+    if (red_drawable->clip.type == SPICE_CLIP_TYPE_RECTS) {
+        QRegion rgn;
+
+        region_init(&rgn);
+        region_add_clip_rects(&rgn, red_drawable->clip.rects);
+        region_and(&drawable->tree_item.base.rgn, &rgn);
+        region_destroy(&rgn);
+    }
+
+    /*
+        surface->refs is affected by a drawable (that is
+        dependent on the surface) as long as the drawable is alive.
+        However, surface->depend_on_me is affected by a drawable only
+        as long as it is in the current tree (hasn't been rendered yet).
+    */
+    red_inc_surfaces_drawable_dependencies(display, drawable);
+
+    if (region_is_empty(&drawable->tree_item.base.rgn)) {
+        return;
+    }
+
+    if (!display_channel_handle_self_bitmap(display, drawable)) {
+        return;
+    }
+
+    draw_depend_on_me(display, surface_id);
+
+    if (!red_handle_surfaces_dependencies(display, drawable)) {
+        return;
+    }
+
     Ring *ring = &display->surfaces[surface_id].current;
 
     if (has_shadow(red_drawable)) {
diff --git a/server/display-channel.h b/server/display-channel.h
index 6c0862c..83b50ca 100644
--- a/server/display-channel.h
+++ b/server/display-channel.h
@@ -442,19 +442,4 @@ static inline void region_add_clip_rects(QRegion *rgn, SpiceClipRects *data)
     }
 }
 
-static inline void draw_depend_on_me(DisplayChannel *display, uint32_t surface_id)
-{
-    RedSurface *surface;
-    RingItem *ring_item;
-
-    surface = &display->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;
-        display_channel_draw(display, &drawable->red_drawable->bbox, drawable->surface_id);
-    }
-}
-
 #endif /* DISPLAY_CHANNEL_H_ */
diff --git a/server/red_worker.c b/server/red_worker.c
index 8dafcbd..81b7fdc 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -165,143 +165,10 @@ void red_drawable_unref(RedWorker *worker, RedDrawable *red_drawable,
     free(red_drawable);
 }
 
-static void red_get_area(DisplayChannel *display, int surface_id, const SpiceRect *area,
-                         uint8_t *dest, int dest_stride, int update)
-{
-    SpiceCanvas *canvas;
-    RedSurface *surface;
-
-    surface = &display->surfaces[surface_id];
-    if (update) {
-        display_channel_draw(display, area, surface_id);
-    }
-
-    canvas = surface->context.canvas;
-    canvas->ops->read_bits(canvas, dest, dest_stride, area);
-}
-
-static inline int red_handle_self_bitmap(RedWorker *worker, Drawable *drawable)
-{
-    DisplayChannel *display = worker->display_channel;
-    SpiceImage *image;
-    int32_t width;
-    int32_t height;
-    uint8_t *dest;
-    int dest_stride;
-    RedSurface *surface;
-    int bpp;
-    int all_set;
-    RedDrawable *red_drawable = drawable->red_drawable;
-
-    if (!red_drawable->self_bitmap) {
-        return TRUE;
-    }
-
-    surface = &display->surfaces[drawable->surface_id];
-
-    bpp = SPICE_SURFACE_FMT_DEPTH(surface->context.format) / 8;
-
-    width = red_drawable->self_bitmap_area.right
-            - red_drawable->self_bitmap_area.left;
-    height = red_drawable->self_bitmap_area.bottom
-            - red_drawable->self_bitmap_area.top;
-    dest_stride = SPICE_ALIGN(width * bpp, 4);
-
-    image = spice_new0(SpiceImage, 1);
-    image->descriptor.type = SPICE_IMAGE_TYPE_BITMAP;
-    image->descriptor.flags = 0;
-
-    QXL_SET_IMAGE_ID(image, QXL_IMAGE_GROUP_RED, display_channel_generate_uid(display));
-    image->u.bitmap.flags = surface->context.top_down ? SPICE_BITMAP_FLAGS_TOP_DOWN : 0;
-    image->u.bitmap.format = spice_bitmap_from_surface_type(surface->context.format);
-    image->u.bitmap.stride = dest_stride;
-    image->descriptor.width = image->u.bitmap.x = width;
-    image->descriptor.height = image->u.bitmap.y = height;
-    image->u.bitmap.palette = NULL;
-
-    dest = (uint8_t *)spice_malloc_n(height, dest_stride);
-    image->u.bitmap.data = spice_chunks_new_linear(dest, height * dest_stride);
-    image->u.bitmap.data->flags |= SPICE_CHUNKS_FLAGS_FREE;
-
-    red_get_area(display, drawable->surface_id,
-                 &red_drawable->self_bitmap_area, dest, dest_stride, TRUE);
-
-    /* For 32bit non-primary surfaces we need to keep any non-zero
-       high bytes as the surface may be used as source to an alpha_blend */
-    if (!is_primary_surface(display, drawable->surface_id) &&
-        image->u.bitmap.format == SPICE_BITMAP_FMT_32BIT &&
-        rgb32_data_has_alpha(width, height, dest_stride, dest, &all_set)) {
-        if (all_set) {
-            image->descriptor.flags |= SPICE_IMAGE_FLAGS_HIGH_BITS_SET;
-        } else {
-            image->u.bitmap.format = SPICE_BITMAP_FMT_RGBA;
-        }
-    }
-
-    red_drawable->self_bitmap_image = image;
-    return TRUE;
-}
-
-static inline void add_to_surface_dependency(DisplayChannel *display, int depend_on_surface_id,
-                                             DependItem *depend_item, Drawable *drawable)
-{
-    RedSurface *surface;
-
-    if (depend_on_surface_id == -1) {
-        depend_item->drawable = NULL;
-        return;
-    }
-
-    surface = &display->surfaces[depend_on_surface_id];
-
-    depend_item->drawable = drawable;
-    ring_add(&surface->depend_on_me, &depend_item->ring_item);
-}
-
-static inline int red_handle_surfaces_dependencies(DisplayChannel *display, Drawable *drawable)
-{
-    int x;
-
-    for (x = 0; x < 3; ++x) {
-        // surface self dependency is handled by shadows in "current", or by
-        // handle_self_bitmap
-        if (drawable->surface_deps[x] != drawable->surface_id) {
-            add_to_surface_dependency(display, drawable->surface_deps[x],
-                                      &drawable->depend_items[x], drawable);
-
-            if (drawable->surface_deps[x] == 0) {
-                QRegion depend_region;
-                region_init(&depend_region);
-                region_add(&depend_region, &drawable->red_drawable->surfaces_rects[x]);
-                stream_detach_behind(display, &depend_region, NULL);
-            }
-        }
-    }
-
-    return TRUE;
-}
-
-static inline void red_inc_surfaces_drawable_dependencies(DisplayChannel *display, Drawable *drawable)
-{
-    int x;
-    int surface_id;
-    RedSurface *surface;
-
-    for (x = 0; x < 3; ++x) {
-        surface_id = drawable->surface_deps[x];
-        if (surface_id == -1) {
-            continue;
-        }
-        surface = &display->surfaces[surface_id];
-        surface->refs++;
-    }
-}
-
 static inline void red_process_draw(RedWorker *worker, RedDrawable *red_drawable,
                                     uint32_t group_id)
 {
     DisplayChannel *display = worker->display_channel;
-    int surface_id;
     Drawable *drawable =
         display_channel_get_drawable(display, red_drawable->effect, red_drawable, group_id,
                                      worker->process_commands_generation);
@@ -310,47 +177,8 @@ static inline void red_process_draw(RedWorker *worker, RedDrawable *red_drawable
         return;
     }
 
-    red_drawable->mm_time = reds_get_mm_time();
-    surface_id = drawable->surface_id;
-
-    display->surfaces[surface_id].refs++;
-
-    region_add(&drawable->tree_item.base.rgn, &red_drawable->bbox);
-
-    if (red_drawable->clip.type == SPICE_CLIP_TYPE_RECTS) {
-        QRegion rgn;
-
-        region_init(&rgn);
-        region_add_clip_rects(&rgn, red_drawable->clip.rects);
-        region_and(&drawable->tree_item.base.rgn, &rgn);
-        region_destroy(&rgn);
-    }
-
-    /*
-        surface->refs is affected by a drawable (that is
-        dependent on the surface) as long as the drawable is alive.
-        However, surface->depend_on_me is affected by a drawable only
-        as long as it is in the current tree (hasn't been rendered yet).
-    */
-    red_inc_surfaces_drawable_dependencies(worker->display_channel, drawable);
-
-    if (region_is_empty(&drawable->tree_item.base.rgn)) {
-        goto cleanup;
-    }
-
-    if (!red_handle_self_bitmap(worker, drawable)) {
-        goto cleanup;
-    }
-
-    draw_depend_on_me(display, surface_id);
-
-    if (!red_handle_surfaces_dependencies(worker->display_channel, drawable)) {
-        goto cleanup;
-    }
-
     display_channel_add_drawable(worker->display_channel, drawable);
 
-cleanup:
     display_channel_drawable_unref(display, drawable);
 }
 
commit c26e6de0ee5492a3c944d98422885bd468768a56
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Fri Nov 27 12:15:56 2015 +0000

    worker: move get_drawable to display-channel.c
    
    Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
    Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
    Acked-by: Fabiano Fidêncio <fidencio at redhat.com>

diff --git a/server/display-channel.c b/server/display-channel.c
index a37e651..27f0d34 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -916,6 +916,66 @@ void display_channel_print_stats(DisplayChannel *display)
 #endif
 }
 
+static int validate_drawable_bbox(DisplayChannel *display, RedDrawable *drawable)
+{
+        DrawContext *context;
+        uint32_t surface_id = drawable->surface_id;
+
+        /* surface_id must be validated before calling into
+         * validate_drawable_bbox
+         */
+        if (!validate_surface(display, drawable->surface_id)) {
+            return FALSE;
+        }
+        context = &display->surfaces[surface_id].context;
+
+        if (drawable->bbox.top < 0)
+                return FALSE;
+        if (drawable->bbox.left < 0)
+                return FALSE;
+        if (drawable->bbox.bottom < 0)
+                return FALSE;
+        if (drawable->bbox.right < 0)
+                return FALSE;
+        if (drawable->bbox.bottom > context->height)
+                return FALSE;
+        if (drawable->bbox.right > context->width)
+                return FALSE;
+
+        return TRUE;
+}
+
+Drawable *display_channel_get_drawable(DisplayChannel *display, uint8_t effect,
+                                       RedDrawable *red_drawable, uint32_t group_id,
+                                       uint32_t process_commands_generation)
+{
+    Drawable *drawable;
+    int x;
+
+    if (!validate_drawable_bbox(display, red_drawable)) {
+        return NULL;
+    }
+    for (x = 0; x < 3; ++x) {
+        if (red_drawable->surface_deps[x] != -1
+            && !validate_surface(display, red_drawable->surface_deps[x])) {
+            return NULL;
+        }
+    }
+
+    drawable = display_channel_drawable_try_new(display, group_id, process_commands_generation);
+    if (!drawable) {
+        return NULL;
+    }
+
+    drawable->tree_item.effect = effect;
+    drawable->red_drawable = red_drawable_ref(red_drawable);
+
+    drawable->surface_id = red_drawable->surface_id;
+    memcpy(drawable->surface_deps, red_drawable->surface_deps, sizeof(drawable->surface_deps));
+
+    return drawable;
+}
+
 void display_channel_add_drawable(DisplayChannel *display, Drawable *drawable)
 {
     int success = FALSE, surface_id = drawable->surface_id;
diff --git a/server/display-channel.h b/server/display-channel.h
index 7187600..6c0862c 100644
--- a/server/display-channel.h
+++ b/server/display-channel.h
@@ -300,6 +300,11 @@ void                       display_channel_destroy_surfaces          (DisplayCha
 void                       display_channel_destroy_surface           (DisplayChannel *display,
                                                                       uint32_t surface_id);
 uint32_t                   display_channel_generate_uid              (DisplayChannel *display);
+Drawable *                 display_channel_get_drawable              (DisplayChannel *display,
+                                                                      uint8_t effect,
+                                                                      RedDrawable *red_drawable,
+                                                                      uint32_t group_id,
+                                                                      uint32_t process_commands_generation);
 void                       display_channel_process_surface_cmd       (DisplayChannel *display,
                                                                       RedSurfaceCmd *surface,
                                                                       uint32_t group_id,
diff --git a/server/red_worker.c b/server/red_worker.c
index ffd1508..8dafcbd 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -119,35 +119,6 @@ static int display_is_connected(RedWorker *worker)
         &worker->display_channel->common.base));
 }
 
-static int validate_drawable_bbox(DisplayChannel *display, RedDrawable *drawable)
-{
-        DrawContext *context;
-        uint32_t surface_id = drawable->surface_id;
-
-        /* surface_id must be validated before calling into
-         * validate_drawable_bbox
-         */
-        if (!validate_surface(display, drawable->surface_id)) {
-            return FALSE;
-        }
-        context = &display->surfaces[surface_id].context;
-
-        if (drawable->bbox.top < 0)
-                return FALSE;
-        if (drawable->bbox.left < 0)
-                return FALSE;
-        if (drawable->bbox.bottom < 0)
-                return FALSE;
-        if (drawable->bbox.right < 0)
-                return FALSE;
-        if (drawable->bbox.bottom > context->height)
-                return FALSE;
-        if (drawable->bbox.right > context->width)
-                return FALSE;
-
-        return TRUE;
-}
-
 static int cursor_is_connected(RedWorker *worker)
 {
     return worker->cursor_channel &&
@@ -271,37 +242,6 @@ static inline int red_handle_self_bitmap(RedWorker *worker, Drawable *drawable)
     return TRUE;
 }
 
-static Drawable *get_drawable(RedWorker *worker, uint8_t effect, RedDrawable *red_drawable,
-                              uint32_t group_id)
-{
-    DisplayChannel *display = worker->display_channel;
-    Drawable *drawable;
-    int x;
-
-    if (!validate_drawable_bbox(display, red_drawable)) {
-        return NULL;
-    }
-    for (x = 0; x < 3; ++x) {
-        if (red_drawable->surface_deps[x] != -1
-            && !validate_surface(display, red_drawable->surface_deps[x])) {
-            return NULL;
-        }
-    }
-
-    drawable = display_channel_drawable_try_new(display, group_id, worker->process_commands_generation);
-    if (!drawable) {
-        return NULL;
-    }
-
-    drawable->tree_item.effect = effect;
-    drawable->red_drawable = red_drawable_ref(red_drawable);
-
-    drawable->surface_id = red_drawable->surface_id;
-    memcpy(drawable->surface_deps, red_drawable->surface_deps, sizeof(drawable->surface_deps));
-
-    return drawable;
-}
-
 static inline void add_to_surface_dependency(DisplayChannel *display, int depend_on_surface_id,
                                              DependItem *depend_item, Drawable *drawable)
 {
@@ -362,7 +302,9 @@ static inline void red_process_draw(RedWorker *worker, RedDrawable *red_drawable
 {
     DisplayChannel *display = worker->display_channel;
     int surface_id;
-    Drawable *drawable = get_drawable(worker, red_drawable->effect, red_drawable, group_id);
+    Drawable *drawable =
+        display_channel_get_drawable(display, red_drawable->effect, red_drawable, group_id,
+                                     worker->process_commands_generation);
 
     if (!drawable) {
         return;


More information about the Spice-commits mailing list