[Spice-devel] [PATCH spice 04/10] server/red_worker: support for SpiceDataHeaderNoSub

Yonit Halperin yhalperi at redhat.com
Wed Dec 28 09:15:13 PST 2011


When the display channel's peer uses SpiceDataHeaderNoSub, employ
urgent marshaller and SPICE_MSG_LIST instead of sub_list in the header.
---
 server/red_worker.c |   67 +++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 55 insertions(+), 12 deletions(-)

diff --git a/server/red_worker.c b/server/red_worker.c
index d82c84e..bbcd891 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -593,6 +593,8 @@ typedef struct CommonChannelClient {
     struct RedWorker *worker;
 } CommonChannelClient;
 
+#define MAX_DRAWABLE_PIXMAP_CACHE_ITEMS 3
+
 struct DisplayChannelClient {
     CommonChannelClient common;
 
@@ -616,6 +618,8 @@ struct DisplayChannelClient {
         RedCompressBuf *used_compress_bufs;
 
         FreeList free_list;
+        uint64_t pixmap_cache_items[MAX_DRAWABLE_PIXMAP_CACHE_ITEMS];
+        int num_pixmap_cache_items;
     } send_data;
 
     /* global lz encoding entities */
@@ -986,8 +990,7 @@ static void red_display_release_stream(RedWorker *worker, StreamAgent *agent);
 static inline void red_detach_stream(RedWorker *worker, Stream *stream);
 static void red_stop_stream(RedWorker *worker, Stream *stream);
 static inline void red_stream_maintenance(RedWorker *worker, Drawable *candidate, Drawable *sect);
-static inline void display_begin_send_message(RedChannelClient *rcc,
-                                              SpiceMarshaller *base_marshaller);
+static inline void display_begin_send_message(RedChannelClient *rcc);
 static void red_release_pixmap_cache(DisplayChannelClient *dcc);
 static void red_release_glz(DisplayChannelClient *dcc);
 static void red_freeze_glz(DisplayChannelClient *dcc);
@@ -6248,6 +6251,8 @@ static inline void red_display_add_image_to_pixmap_cache(RedChannelClient *rcc,
                                  image->descriptor.width * image->descriptor.height, is_lossy,
                                  dcc)) {
                 io_image->descriptor.flags |= SPICE_IMAGE_FLAGS_CACHE_ME;
+                dcc->send_data.pixmap_cache_items[dcc->send_data.num_pixmap_cache_items++] =
+                                                                               image->descriptor.id;
                 stat_inc_counter(display_channel->add_to_cache_counter, 1);
             }
         }
@@ -6290,6 +6295,8 @@ static FillBitsType fill_bits(DisplayChannelClient *dcc, SpiceMarshaller *m,
         int lossy_cache_item;
         if (pixmap_cache_hit(dcc->pixmap_cache, image.descriptor.id,
                              &lossy_cache_item, dcc)) {
+            dcc->send_data.pixmap_cache_items[dcc->send_data.num_pixmap_cache_items++] =
+                                                                               image.descriptor.id;
             if (can_lossy || !lossy_cache_item) {
                 if (!display_channel->enable_jpeg || lossy_cache_item) {
                     image.descriptor.type = SPICE_IMAGE_TYPE_FROM_CACHE;
@@ -6463,6 +6470,7 @@ static inline void red_display_reset_send_data(DisplayChannelClient *dcc)
 {
     red_display_reset_compress_buf(dcc);
     dcc->send_data.free_list.res->count = 0;
+    dcc->send_data.num_pixmap_cache_items = 0;
     memset(dcc->send_data.free_list.sync, 0, sizeof(dcc->send_data.free_list.sync));
 }
 
@@ -7780,21 +7788,30 @@ static void display_channel_push_release(DisplayChannelClient *dcc, uint8_t type
     free_list->res->resources[free_list->res->count++].id = id;
 }
 
-static inline void display_begin_send_message(RedChannelClient *rcc,
-                                              SpiceMarshaller *base_marshaller)
+static inline void display_begin_send_message(RedChannelClient *rcc)
 {
     DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
     FreeList *free_list = &dcc->send_data.free_list;
-    SpiceDataHeader *header = red_channel_client_get_header(rcc);
 
     if (free_list->res->count) {
         int sub_list_len = 1;
+        SpiceMarshaller *urgent_marshaller;
         SpiceMarshaller *wait_m = NULL;
         SpiceMarshaller *inval_m;
+        SpiceMarshaller *sub_list_m;
+        uint32_t sub_arr_offset;
+        uint32_t wait_offset = 0;
+        uint32_t inval_offset = 0;
         int sync_count = 0;
         int i;
 
-        inval_m = spice_marshaller_get_submarshaller(base_marshaller);
+        if (rcc->is_header_with_sub) {
+            urgent_marshaller = red_channel_client_get_marshaller(rcc);
+        } else {
+            urgent_marshaller = red_channel_client_switch_to_urgent_sender(rcc);
+            red_channel_client_init_send_data(rcc, SPICE_MSG_LIST, NULL);
+        }
+        inval_m = spice_marshaller_get_submarshaller(urgent_marshaller);
 
         /* type + size + submessage */
         spice_marshaller_add_uint16(inval_m, SPICE_MSG_DISPLAY_INVAL_LIST);
@@ -7812,7 +7829,9 @@ static inline void display_begin_send_message(RedChannelClient *rcc,
         free_list->wait.header.wait_count = sync_count;
 
         if (sync_count) {
-            wait_m = spice_marshaller_get_submarshaller(base_marshaller);
+            int j;
+
+            wait_m = spice_marshaller_get_submarshaller(urgent_marshaller);
 
             /* type + size + submessage */
             spice_marshaller_add_uint16(wait_m, SPICE_MSG_WAIT_FOR_CHANNELS);
@@ -7820,15 +7839,39 @@ static inline void display_begin_send_message(RedChannelClient *rcc,
                                                 sync_count * sizeof(free_list->wait.buf[0]));
             spice_marshall_msg_wait_for_channels(wait_m, &free_list->wait.header);
             sub_list_len++;
+
+            if (!rcc->is_header_with_sub) {
+                for (j = 0; j < dcc->send_data.num_pixmap_cache_items; j++) {
+                    int dummy;
+                    // refresshing the serial value
+                    pixmap_cache_hit(dcc->pixmap_cache, dcc->send_data.pixmap_cache_items[j],
+                                    &dummy, dcc);
+                }
+            }
+        }
+
+        if (rcc->is_header_with_sub) {
+            sub_list_m = spice_marshaller_get_submarshaller(urgent_marshaller);
+            sub_arr_offset = 0;
+        } else {
+            sub_list_m = urgent_marshaller;
+            sub_arr_offset = sub_list_len * sizeof(uint32_t);
         }
 
-        SpiceMarshaller *sub_list_m = spice_marshaller_get_submarshaller(base_marshaller);
         spice_marshaller_add_uint16(sub_list_m, sub_list_len);
+        inval_offset = spice_marshaller_get_offset(inval_m); // calc the offset before
+                                                             // adding the sub list
+                                                             // offsets array to the marshaller
         if (wait_m) {
-            spice_marshaller_add_uint32(sub_list_m, spice_marshaller_get_offset(wait_m));
+            wait_offset = spice_marshaller_get_offset(wait_m);
+            spice_marshaller_add_uint32(sub_list_m, wait_offset + sub_arr_offset);
+        }
+        spice_marshaller_add_uint32(sub_list_m, inval_offset + sub_arr_offset);
+
+        if (rcc->is_header_with_sub) {
+            SpiceDataHeader* header = red_channel_client_get_header(rcc);
+            header->sub_list = spice_marshaller_get_offset(sub_list_m);
         }
-        spice_marshaller_add_uint32(sub_list_m, spice_marshaller_get_offset(inval_m));
-        header->sub_list = spice_marshaller_get_offset(sub_list_m);
     }
     red_channel_client_begin_send_message(rcc);
 }
@@ -8496,7 +8539,7 @@ static void display_channel_send_item(RedChannelClient *rcc, PipeItem *pipe_item
 
     // a message is pending
     if (red_channel_client_send_message_pending(rcc)) {
-        display_begin_send_message(rcc, m);
+        display_begin_send_message(rcc);
     }
 }
 
-- 
1.7.6.4



More information about the Spice-devel mailing list