[Spice-devel] [PATCH v2 1/9] Add DisplayChannelPrivate struct

Jonathon Jongsma jjongsma at redhat.com
Wed Sep 14 16:53:25 UTC 2016


Move all of the DisplayChannel data memembers into a private struct to
encapsulate things better. This necessitated a few new 'public' methods
and a small bit of refactoring to avoid poking into DisplayChannel
internals from too many places. The DisplayChannel and the
DisplayChannelClient are still far too intertwined to completely avoid
accessing private data, so at the moment the private struct is defined
in display-channel.h and the DisplayChannelClient implementation
still accesses it sometimes.
---
Changes in v2:
 - use priv[1] to avoid memory leak

 server/dcc-send.c        |  32 ++---
 server/dcc.c             |  33 ++---
 server/display-channel.c | 357 +++++++++++++++++++++++++++--------------------
 server/display-channel.h |  51 ++++---
 server/red-worker.c      |  50 ++-----
 server/stream.c          |  71 +++++-----
 6 files changed, 323 insertions(+), 271 deletions(-)

diff --git a/server/dcc-send.c b/server/dcc-send.c
index 521e6a2..0635afa 100644
--- a/server/dcc-send.c
+++ b/server/dcc-send.c
@@ -94,9 +94,9 @@ static int is_surface_area_lossy(DisplayChannelClient *dcc, uint32_t surface_id,
     QRegion lossy_region;
     DisplayChannel *display = DCC_TO_DC(dcc);
 
-    spice_return_val_if_fail(validate_surface(display, surface_id), FALSE);
+    spice_return_val_if_fail(display_channel_validate_surface(display, surface_id), FALSE);
 
-    surface = &display->surfaces[surface_id];
+    surface = &display->priv->surfaces[surface_id];
     surface_lossy_region = &dcc->priv->surface_client_lossy_region[surface_id];
 
     if (!area) {
@@ -208,13 +208,13 @@ static void red_display_add_image_to_pixmap_cache(RedChannelClient *rcc,
                 io_image->descriptor.flags |= SPICE_IMAGE_FLAGS_CACHE_ME;
                 dcc->priv->send_data.pixmap_cache_items[dcc->priv->send_data.num_pixmap_cache_items++] =
                                                                                image->descriptor.id;
-                stat_inc_counter(reds, display_channel->add_to_cache_counter, 1);
+                stat_inc_counter(reds, display_channel->priv->add_to_cache_counter, 1);
             }
         }
     }
 
     if (!(io_image->descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME)) {
-        stat_inc_counter(reds, display_channel->non_cache_counter, 1);
+        stat_inc_counter(reds, display_channel->priv->non_cache_counter, 1);
     }
 }
 
@@ -385,7 +385,7 @@ static FillBitsType fill_bits(DisplayChannelClient *dcc, SpiceMarshaller *m,
             dcc->priv->send_data.pixmap_cache_items[dcc->priv->send_data.num_pixmap_cache_items++] =
                 image.descriptor.id;
             if (can_lossy || !lossy_cache_item) {
-                if (!display->enable_jpeg || lossy_cache_item) {
+                if (!display->priv->enable_jpeg || lossy_cache_item) {
                     image.descriptor.type = SPICE_IMAGE_TYPE_FROM_CACHE;
                 } else {
                     // making sure, in multiple monitor scenario, that lossy items that
@@ -397,7 +397,7 @@ static FillBitsType fill_bits(DisplayChannelClient *dcc, SpiceMarshaller *m,
                                      &bitmap_palette_out, &lzplt_palette_out);
                 spice_assert(bitmap_palette_out == NULL);
                 spice_assert(lzplt_palette_out == NULL);
-                stat_inc_counter(reds, display->cache_hits_counter, 1);
+                stat_inc_counter(reds, display->priv->cache_hits_counter, 1);
                 pthread_mutex_unlock(&dcc->priv->pixmap_cache->lock);
                 return FILL_BITS_TYPE_CACHE;
             } else {
@@ -414,13 +414,13 @@ static FillBitsType fill_bits(DisplayChannelClient *dcc, SpiceMarshaller *m,
         RedSurface *surface;
 
         surface_id = simage->u.surface.surface_id;
-        if (!validate_surface(display, surface_id)) {
+        if (!display_channel_validate_surface(display, surface_id)) {
             spice_warning("Invalid surface in SPICE_IMAGE_TYPE_SURFACE");
             pthread_mutex_unlock(&dcc->priv->pixmap_cache->lock);
             return FILL_BITS_TYPE_SURFACE;
         }
 
-        surface = &display->surfaces[surface_id];
+        surface = &display->priv->surfaces[surface_id];
         image.descriptor.type = SPICE_IMAGE_TYPE_SURFACE;
         image.descriptor.flags = 0;
         image.descriptor.width = surface->context.width;
@@ -1706,7 +1706,7 @@ static int red_marshall_stream_data(RedChannelClient *rcc,
         return FALSE;
     }
 
-    StreamAgent *agent = &dcc->priv->stream_agents[get_stream_id(display, stream)];
+    StreamAgent *agent = &dcc->priv->stream_agents[display_channel_get_stream_id(display, stream)];
     uint64_t time_now = spice_get_monotonic_time_ns();
 
     if (!dcc->priv->use_video_encoder_rate_control) {
@@ -1752,7 +1752,7 @@ static int red_marshall_stream_data(RedChannelClient *rcc,
 
         red_channel_client_init_send_data(rcc, SPICE_MSG_DISPLAY_STREAM_DATA, NULL);
 
-        stream_data.base.id = get_stream_id(display, stream);
+        stream_data.base.id = display_channel_get_stream_id(display, stream);
         stream_data.base.multi_media_time = frame_mm_time;
         stream_data.data_size = outbuf->size;
 
@@ -1762,7 +1762,7 @@ static int red_marshall_stream_data(RedChannelClient *rcc,
 
         red_channel_client_init_send_data(rcc, SPICE_MSG_DISPLAY_STREAM_DATA_SIZED, NULL);
 
-        stream_data.base.id = get_stream_id(display, stream);
+        stream_data.base.id = display_channel_get_stream_id(display, stream);
         stream_data.base.multi_media_time = frame_mm_time;
         stream_data.data_size = outbuf->size;
         stream_data.width = copy->src_area.right - copy->src_area.left;
@@ -1862,7 +1862,7 @@ static void display_channel_marshall_migrate_data(RedChannelClient *rcc,
     spice_marshaller_add(base_marshaller,
                          (uint8_t *)&display_data, sizeof(display_data) - sizeof(uint32_t));
     display_channel_marshall_migrate_data_surfaces(dcc, base_marshaller,
-                                                   display_channel->enable_jpeg);
+                                                   display_channel->priv->enable_jpeg);
 }
 
 static void display_channel_marshall_pixmap_sync(RedChannelClient *rcc,
@@ -2148,7 +2148,7 @@ static void marshall_qxl_drawable(RedChannelClient *rcc,
     if (item->stream && red_marshall_stream_data(rcc, m, item)) {
         return;
     }
-    if (display->enable_jpeg)
+    if (display->priv->enable_jpeg)
         marshall_lossy_qxl_drawable(rcc, m, dpi);
     else
         marshall_lossless_qxl_drawable(rcc, m, dpi);
@@ -2171,7 +2171,7 @@ static void marshall_stream_start(RedChannelClient *rcc,
     SpiceClipRects clip_rects;
 
     stream_create.surface_id = 0;
-    stream_create.id = get_stream_id(DCC_TO_DC(dcc), stream);
+    stream_create.id = display_channel_get_stream_id(DCC_TO_DC(dcc), stream);
     stream_create.flags = stream->top_down ? SPICE_STREAM_FLAGS_TOP_DOWN : 0;
     stream_create.codec_type = agent->video_encoder->codec_type;
 
@@ -2207,7 +2207,7 @@ static void marshall_stream_clip(RedChannelClient *rcc,
     red_channel_client_init_send_data(rcc, SPICE_MSG_DISPLAY_STREAM_CLIP, &item->base);
     SpiceMsgDisplayStreamClip stream_clip;
 
-    stream_clip.id = get_stream_id(DCC_TO_DC(dcc), agent->stream);
+    stream_clip.id = display_channel_get_stream_id(DCC_TO_DC(dcc), agent->stream);
     stream_clip.clip.type = item->clip_type;
     stream_clip.clip.rects = item->rects;
 
@@ -2221,7 +2221,7 @@ static void marshall_stream_end(RedChannelClient *rcc,
     SpiceMsgDisplayStreamDestroy destroy;
 
     red_channel_client_init_send_data(rcc, SPICE_MSG_DISPLAY_STREAM_DESTROY, NULL);
-    destroy.id = get_stream_id(DCC_TO_DC(dcc), agent->stream);
+    destroy.id = display_channel_get_stream_id(DCC_TO_DC(dcc), agent->stream);
     stream_agent_stop(agent);
     spice_marshall_msg_display_stream_destroy(base_marshaller, &destroy);
 }
diff --git a/server/dcc.c b/server/dcc.c
index 36c9c1d..62e32c4 100644
--- a/server/dcc.c
+++ b/server/dcc.c
@@ -21,6 +21,7 @@
 
 #include "dcc-private.h"
 #include "display-channel.h"
+#include "dcc.h"
 #include "red-channel-client-private.h"
 
 #define DISPLAY_CLIENT_SHORT_TIMEOUT 15000000000ULL //nano
@@ -157,7 +158,7 @@ void dcc_create_surface(DisplayChannelClient *dcc, int surface_id)
         dcc->priv->surface_client_created[surface_id]) {
         return;
     }
-    surface = &display->surfaces[surface_id];
+    surface = &display->priv->surfaces[surface_id];
     create = red_surface_create_item_new(RED_CHANNEL(display),
                                          surface_id, surface->context.width,
                                          surface->context.height,
@@ -174,7 +175,7 @@ RedImageItem *dcc_add_surface_area_image(DisplayChannelClient *dcc,
                                          int can_lossy)
 {
     DisplayChannel *display = DCC_TO_DC(dcc);
-    RedSurface *surface = &display->surfaces[surface_id];
+    RedSurface *surface = &display->priv->surfaces[surface_id];
     SpiceCanvas *canvas = surface->context.canvas;
     RedImageItem *item;
     int stride;
@@ -240,7 +241,7 @@ void dcc_push_surface_image(DisplayChannelClient *dcc, int surface_id)
     }
 
     display = DCC_TO_DC(dcc);
-    surface = &display->surfaces[surface_id];
+    surface = &display->priv->surfaces[surface_id];
     if (!surface->context.canvas) {
         return;
     }
@@ -343,7 +344,7 @@ static void dcc_init_stream_agents(DisplayChannelClient *dcc)
 
     for (i = 0; i < NUM_STREAMS; i++) {
         StreamAgent *agent = &dcc->priv->stream_agents[i];
-        agent->stream = &display->streams_buf[i];
+        agent->stream = &display->priv->streams_buf[i];
         region_init(&agent->vis_region);
         region_init(&agent->clip);
     }
@@ -392,14 +393,14 @@ DisplayChannelClient *dcc_new(DisplayChannel *display,
 
     dcc_init_stream_agents(dcc);
 
-    image_encoders_init(&dcc->priv->encoders, &display->encoder_shared_data);
+    image_encoders_init(&dcc->priv->encoders, &display->priv->encoder_shared_data);
 
     return dcc;
 }
 
 static void dcc_create_all_streams(DisplayChannelClient *dcc)
 {
-    Ring *ring = &DCC_TO_DC(dcc)->streams;
+    Ring *ring = &DCC_TO_DC(dcc)->priv->streams;
     RingItem *item = ring;
 
     while ((item = ring_next(ring, item))) {
@@ -451,7 +452,7 @@ void dcc_start(DisplayChannelClient *dcc)
         return;
 
     red_channel_client_ack_zero_messages_window(RED_CHANNEL_CLIENT(dcc));
-    if (display->surfaces[0].context.canvas) {
+    if (display->priv->surfaces[0].context.canvas) {
         display_channel_current_flush(display, 0);
         red_channel_client_pipe_add_type(rcc, RED_PIPE_ITEM_TYPE_INVAL_PALETTE_CACHE);
         dcc_create_surface(dcc, 0);
@@ -538,7 +539,7 @@ static RedMonitorsConfigItem *red_monitors_config_item_new(RedChannel* channel,
 void dcc_push_monitors_config(DisplayChannelClient *dcc)
 {
     DisplayChannel *dc = DCC_TO_DC(dcc);
-    MonitorsConfig *monitors_config = dc->monitors_config;
+    MonitorsConfig *monitors_config = dc->priv->monitors_config;
     RedMonitorsConfigItem *mci;
 
     if (monitors_config == NULL) {
@@ -552,7 +553,7 @@ void dcc_push_monitors_config(DisplayChannelClient *dcc)
     }
 
     mci = red_monitors_config_item_new(red_channel_client_get_channel(RED_CHANNEL_CLIENT(dcc)),
-                                       monitors_config_ref(dc->monitors_config));
+                                       monitors_config_ref(dc->priv->monitors_config));
     red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), &mci->pipe_item);
     red_channel_client_push(RED_CHANNEL_CLIENT(dcc));
 }
@@ -724,14 +725,14 @@ int dcc_compress_image(DisplayChannelClient *dcc,
     stat_start_time_t start_time;
     int success = FALSE;
 
-    stat_start_time_init(&start_time, &display_channel->encoder_shared_data.off_stat);
+    stat_start_time_init(&start_time, &display_channel->priv->encoder_shared_data.off_stat);
 
     image_compression = get_compression_for_bitmap(src, dcc->priv->image_compression, drawable);
     switch (image_compression) {
     case SPICE_IMAGE_COMPRESSION_OFF:
         break;
     case SPICE_IMAGE_COMPRESSION_QUIC:
-        if (can_lossy && display_channel->enable_jpeg &&
+        if (can_lossy && display_channel->priv->enable_jpeg &&
             (src->format != SPICE_BITMAP_FMT_RGBA || !bitmap_has_extra_stride(src))) {
             success = image_encoders_compress_jpeg(&dcc->priv->encoders, dest, src, o_comp_data);
             break;
@@ -742,7 +743,7 @@ int dcc_compress_image(DisplayChannelClient *dcc,
         success = image_encoders_compress_glz(&dcc->priv->encoders, dest, src,
                                               drawable->red_drawable, &drawable->glz_retention,
                                               o_comp_data,
-                                              display_channel->enable_zlib_glz_wrap);
+                                              display_channel->priv->enable_zlib_glz_wrap);
         if (success) {
             break;
         }
@@ -768,7 +769,7 @@ lz_compress:
 
     if (!success) {
         uint64_t image_size = src->stride * src->y;
-        stat_compress_add(&display_channel->encoder_shared_data.off_stat, start_time, image_size, image_size);
+        stat_compress_add(&display_channel->priv->encoder_shared_data.off_stat, start_time, image_size, image_size);
     }
 
     return success;
@@ -1115,15 +1116,15 @@ int dcc_handle_migrate_data(DisplayChannelClient *dcc, uint32_t size, void *mess
     if (migrate_data->low_bandwidth_setting) {
         red_channel_client_ack_set_client_window(RED_CHANNEL_CLIENT(dcc), WIDE_CLIENT_ACK_WINDOW);
         if (dcc->priv->jpeg_state == SPICE_WAN_COMPRESSION_AUTO) {
-            display->enable_jpeg = TRUE;
+            display->priv->enable_jpeg = TRUE;
         }
         if (dcc->priv->zlib_glz_state == SPICE_WAN_COMPRESSION_AUTO) {
-            display->enable_zlib_glz_wrap = TRUE;
+            display->priv->enable_zlib_glz_wrap = TRUE;
         }
     }
 
     surfaces = (uint8_t *)message + migrate_data->surfaces_at_client_ptr;
-    surfaces_restored = display->enable_jpeg ?
+    surfaces_restored = display->priv->enable_jpeg ?
         restore_surfaces_lossy(dcc, (MigrateDisplaySurfacesAtClientLossy *)surfaces) :
         restore_surfaces_lossless(dcc, (MigrateDisplaySurfacesAtClientLossless*)surfaces);
 
diff --git a/server/display-channel.c b/server/display-channel.c
index 108e69b..d193925 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -30,7 +30,7 @@ uint32_t display_channel_generate_uid(DisplayChannel *display)
 {
     spice_return_val_if_fail(display != NULL, 0);
 
-    return ++display->bits_unique;
+    return ++display->priv->bits_unique;
 }
 
 #define stat_start(stat, var)                                        \
@@ -40,7 +40,7 @@ void display_channel_compress_stats_reset(DisplayChannel *display)
 {
     spice_return_if_fail(display);
 
-    image_encoder_shared_stat_reset(&display->encoder_shared_data);
+    image_encoder_shared_stat_reset(&display->priv->encoder_shared_data);
 }
 
 void display_channel_compress_stats_print(const DisplayChannel *display_channel)
@@ -49,7 +49,7 @@ void display_channel_compress_stats_print(const DisplayChannel *display_channel)
     spice_return_if_fail(display_channel);
 
     spice_info("==> Compression stats for display %u", display_channel->common.base.id);
-    image_encoder_shared_stat_print(&display_channel->encoder_shared_data);
+    image_encoder_shared_stat_print(&display_channel->priv->encoder_shared_data);
 #endif
 }
 
@@ -101,7 +101,7 @@ MonitorsConfig* monitors_config_new(QXLHead *heads, ssize_t nheads, ssize_t max)
 int display_channel_get_streams_timeout(DisplayChannel *display)
 {
     int timeout = INT_MAX;
-    Ring *ring = &display->streams;
+    Ring *ring = &display->priv->streams;
     RingItem *item = ring;
 
     red_time_t now = spice_get_monotonic_time_ns();
@@ -139,20 +139,20 @@ void display_channel_set_stream_video(DisplayChannel *display, int stream_video)
         return;
     }
 
-    display->stream_video = stream_video;
+    display->priv->stream_video = stream_video;
 }
 
 void display_channel_set_video_codecs(DisplayChannel *display, GArray *video_codecs)
 {
     spice_return_if_fail(display);
 
-    g_array_unref(display->video_codecs);
-    display->video_codecs = g_array_ref(video_codecs);
+    g_array_unref(display->priv->video_codecs);
+    display->priv->video_codecs = g_array_ref(video_codecs);
 }
 
 static void stop_streams(DisplayChannel *display)
 {
-    Ring *ring = &display->streams;
+    Ring *ring = &display->priv->streams;
     RingItem *item = ring_get_head(ring);
 
     while (item) {
@@ -165,13 +165,13 @@ static void stop_streams(DisplayChannel *display)
         }
     }
 
-    display->next_item_trace = 0;
-    memset(display->items_trace, 0, sizeof(display->items_trace));
+    display->priv->next_item_trace = 0;
+    memset(display->priv->items_trace, 0, sizeof(display->priv->items_trace));
 }
 
 void display_channel_surface_unref(DisplayChannel *display, uint32_t surface_id)
 {
-    RedSurface *surface = &display->surfaces[surface_id];
+    RedSurface *surface = &display->priv->surfaces[surface_id];
     QXLInstance *qxl = display->common.qxl;
     DisplayChannelClient *dcc;
     GList *link, *next;
@@ -203,6 +203,13 @@ void display_channel_surface_unref(DisplayChannel *display, uint32_t surface_id)
     spice_warn_if_fail(ring_is_empty(&surface->depend_on_me));
 }
 
+/* TODO: perhaps rename to "ready" or "realized" ? */
+bool display_channel_surface_has_canvas(DisplayChannel *display,
+                                        uint32_t surface_id)
+{
+    return display->priv->surfaces[surface_id].context.canvas != NULL;
+}
+
 static void streams_update_visible_region(DisplayChannel *display, Drawable *drawable)
 {
     Ring *ring;
@@ -218,7 +225,7 @@ static void streams_update_visible_region(DisplayChannel *display, Drawable *dra
         return;
     }
 
-    ring = &display->streams;
+    ring = &display->priv->streams;
     item = ring_get_head(ring);
 
     while (item) {
@@ -232,7 +239,7 @@ static void streams_update_visible_region(DisplayChannel *display, Drawable *dra
         }
 
         FOREACH_CLIENT(display, link, next, dcc) {
-            agent = dcc_get_stream_agent(dcc, get_stream_id(display, stream));
+            agent = dcc_get_stream_agent(dcc, display_channel_get_stream_id(display, stream));
 
             if (region_intersects(&agent->vis_region, &drawable->tree_item.base.rgn)) {
                 region_exclude(&agent->vis_region, &drawable->tree_item.base.rgn);
@@ -294,11 +301,11 @@ static void current_add_drawable(DisplayChannel *display,
     RedSurface *surface;
     uint32_t surface_id = drawable->surface_id;
 
-    surface = &display->surfaces[surface_id];
+    surface = &display->priv->surfaces[surface_id];
     ring_add_after(&drawable->tree_item.base.siblings_link, pos);
-    ring_add(&display->current_list, &drawable->list_link);
+    ring_add(&display->priv->current_list, &drawable->list_link);
     ring_add(&surface->current_list, &drawable->surface_list_link);
-    display->current_size++;
+    display->priv->current_size++;
     drawable->refs++;
 }
 
@@ -311,7 +318,7 @@ static void current_remove_drawable(DisplayChannel *display, Drawable *item)
     ring_remove(&item->list_link);
     ring_remove(&item->surface_list_link);
     drawable_unref(item);
-    display->current_size--;
+    display->priv->current_size--;
 }
 
 static void drawable_remove_from_pipes(Drawable *drawable)
@@ -368,7 +375,7 @@ static void current_remove(DisplayChannel *display, TreeItem *item)
 
 static void current_remove_all(DisplayChannel *display, int surface_id)
 {
-    Ring *ring = &display->surfaces[surface_id].current;
+    Ring *ring = &display->priv->surfaces[surface_id].current;
     RingItem *ring_item;
 
     while ((ring_item = ring_get_head(ring))) {
@@ -463,7 +470,7 @@ static void __exclude_region(DisplayChannel *display, Ring *ring, TreeItem *item
                              Ring **top_ring, Drawable *frame_candidate)
 {
     QRegion and_rgn;
-    stat_start(&display->__exclude_stat, start_time);
+    stat_start(&display->priv->__exclude_stat, start_time);
 
     region_clone(&and_rgn, rgn);
     region_and(&and_rgn, &item->rgn);
@@ -525,14 +532,14 @@ static void __exclude_region(DisplayChannel *display, Ring *ring, TreeItem *item
         }
     }
     region_destroy(&and_rgn);
-    stat_add(&display->__exclude_stat, start_time);
+    stat_add(&display->priv->__exclude_stat, start_time);
 }
 
 static void exclude_region(DisplayChannel *display, Ring *ring, RingItem *ring_item,
                            QRegion *rgn, TreeItem **last, Drawable *frame_candidate)
 {
     Ring *top_ring;
-    stat_start(&display->exclude_stat, start_time);
+    stat_start(&display->priv->exclude_stat, start_time);
 
     if (!ring_item) {
         return;
@@ -568,7 +575,7 @@ static void exclude_region(DisplayChannel *display, Ring *ring, RingItem *ring_i
             }
 
             if (region_is_empty(rgn)) {
-                stat_add(&display->exclude_stat, start_time);
+                stat_add(&display->priv->exclude_stat, start_time);
                 return;
             }
         }
@@ -577,7 +584,7 @@ static void exclude_region(DisplayChannel *display, Ring *ring, RingItem *ring_i
         while ((last && *last == (TreeItem *)ring_item) ||
                !(ring_item = ring_next(ring, ring_item))) {
             if (ring == top_ring) {
-                stat_add(&display->exclude_stat, start_time);
+                stat_add(&display->priv->exclude_stat, start_time);
                 return;
             }
             ring_item = &container->base.siblings_link;
@@ -589,9 +596,9 @@ static void exclude_region(DisplayChannel *display, Ring *ring, RingItem *ring_i
 
 static int current_add_with_shadow(DisplayChannel *display, Ring *ring, Drawable *item)
 {
-    stat_start(&display->add_stat, start_time);
+    stat_start(&display->priv->add_stat, start_time);
 #ifdef RED_WORKER_STAT
-    ++display->add_with_shadow_count;
+    ++display->priv->add_with_shadow_count;
 #endif
 
     RedDrawable *red_drawable = item->red_drawable;
@@ -602,7 +609,7 @@ static int current_add_with_shadow(DisplayChannel *display, Ring *ring, Drawable
 
     Shadow *shadow = shadow_new(&item->tree_item, &delta);
     if (!shadow) {
-        stat_add(&display->add_stat, start_time);
+        stat_add(&display->priv->add_stat, start_time);
         return FALSE;
     }
     // item and his shadow must initially be placed in the same container.
@@ -626,7 +633,7 @@ static int current_add_with_shadow(DisplayChannel *display, Ring *ring, Drawable
             stream_detach_behind(display, &item->tree_item.base.rgn, item);
         }
     }
-    stat_add(&display->add_stat, start_time);
+    stat_add(&display->priv->add_stat, start_time);
     return TRUE;
 }
 
@@ -636,7 +643,7 @@ static int current_add(DisplayChannel *display, Ring *ring, Drawable *drawable)
     RingItem *now;
     QRegion exclude_rgn;
     RingItem *exclude_base = NULL;
-    stat_start(&display->add_stat, start_time);
+    stat_start(&display->priv->add_stat, start_time);
 
     spice_assert(!region_is_empty(&item->base.rgn));
     region_init(&exclude_rgn);
@@ -658,7 +665,7 @@ static int current_add(DisplayChannel *display, Ring *ring, Drawable *drawable)
             if (!(test_res & REGION_TEST_RIGHT_EXCLUSIVE) &&
                                                    !(test_res & REGION_TEST_LEFT_EXCLUSIVE) &&
                                                    current_add_equal(display, item, sibling)) {
-                stat_add(&display->add_stat, start_time);
+                stat_add(&display->priv->add_stat, start_time);
                 return FALSE;
             }
 
@@ -744,7 +751,7 @@ static int current_add(DisplayChannel *display, Ring *ring, Drawable *drawable)
         }
     }
     region_destroy(&exclude_rgn);
-    stat_add(&display->add_stat, start_time);
+    stat_add(&display->priv->add_stat, start_time);
     return TRUE;
 }
 
@@ -753,7 +760,7 @@ static bool drawable_can_stream(DisplayChannel *display, Drawable *drawable)
     RedDrawable *red_drawable = drawable->red_drawable;
     SpiceImage *image;
 
-    if (display->stream_video == SPICE_STREAM_VIDEO_OFF) {
+    if (display->priv->stream_video == SPICE_STREAM_VIDEO_OFF) {
         return FALSE;
     }
 
@@ -773,7 +780,7 @@ static bool drawable_can_stream(DisplayChannel *display, Drawable *drawable)
         return FALSE;
     }
 
-    if (display->stream_video == SPICE_STREAM_VIDEO_FILTER) {
+    if (display->priv->stream_video == SPICE_STREAM_VIDEO_FILTER) {
         SpiceRect* rect;
         int size;
 
@@ -790,26 +797,26 @@ static bool drawable_can_stream(DisplayChannel *display, Drawable *drawable)
 #ifdef RED_WORKER_STAT
 static void display_channel_print_stats(DisplayChannel *display)
 {
-    stat_time_t total = display->add_stat.total;
+    stat_time_t total = display->priv->add_stat.total;
     spice_info("add with shadow count %u",
-               display->add_with_shadow_count);
-    display->add_with_shadow_count = 0;
+               display->priv->add_with_shadow_count);
+    display->priv->add_with_shadow_count = 0;
     spice_info("add[%u] %f exclude[%u] %f __exclude[%u] %f",
-               display->add_stat.count,
+               display->priv->add_stat.count,
                stat_cpu_time_to_sec(total),
-               display->exclude_stat.count,
-               stat_cpu_time_to_sec(display->exclude_stat.total),
-               display->__exclude_stat.count,
-               stat_cpu_time_to_sec(display->__exclude_stat.total));
+               display->priv->exclude_stat.count,
+               stat_cpu_time_to_sec(display->priv->exclude_stat.total),
+               display->priv->__exclude_stat.count,
+               stat_cpu_time_to_sec(display->priv->__exclude_stat.total));
     spice_info("add %f%% exclude %f%% exclude2 %f%% __exclude %f%%",
-               (double)(total - display->exclude_stat.total) / total * 100,
-               (double)(display->exclude_stat.total) / total * 100,
-               (double)(display->exclude_stat.total -
-                        display->__exclude_stat.total) / display->exclude_stat.total * 100,
-               (double)(display->__exclude_stat.total) / display->exclude_stat.total * 100);
-    stat_reset(&display->add_stat);
-    stat_reset(&display->exclude_stat);
-    stat_reset(&display->__exclude_stat);
+               (double)(total - display->priv->exclude_stat.total) / total * 100,
+               (double)(display->priv->exclude_stat.total) / total * 100,
+               (double)(display->priv->exclude_stat.total -
+                        display->priv->__exclude_stat.total) / display->priv->exclude_stat.total * 100,
+               (double)(display->priv->__exclude_stat.total) / display->priv->exclude_stat.total * 100);
+    stat_reset(&display->priv->add_stat);
+    stat_reset(&display->priv->exclude_stat);
+    stat_reset(&display->priv->__exclude_stat);
 }
 #endif
 
@@ -824,7 +831,7 @@ static void drawable_ref_surface_deps(DisplayChannel *display, Drawable *drawabl
         if (surface_id == -1) {
             continue;
         }
-        surface = &display->surfaces[surface_id];
+        surface = &display->priv->surfaces[surface_id];
         surface->refs++;
     }
 }
@@ -833,7 +840,7 @@ static void surface_read_bits(DisplayChannel *display, int surface_id,
                               const SpiceRect *area, uint8_t *dest, int dest_stride)
 {
     SpiceCanvas *canvas;
-    RedSurface *surface = &display->surfaces[surface_id];
+    RedSurface *surface = &display->priv->surfaces[surface_id];
 
     canvas = surface->context.canvas;
     canvas->ops->read_bits(canvas, dest, dest_stride, area);
@@ -851,7 +858,7 @@ static void handle_self_bitmap(DisplayChannel *display, Drawable *drawable)
     int bpp;
     int all_set;
 
-    surface = &display->surfaces[drawable->surface_id];
+    surface = &display->priv->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;
@@ -903,7 +910,7 @@ static void surface_add_reverse_dependency(DisplayChannel *display, int surface_
         return;
     }
 
-    surface = &display->surfaces[surface_id];
+    surface = &display->priv->surfaces[surface_id];
 
     depend_item->drawable = drawable;
     ring_add(&surface->depend_on_me, &depend_item->ring_item);
@@ -937,7 +944,7 @@ static void draw_depend_on_me(DisplayChannel *display, uint32_t surface_id)
     RedSurface *surface;
     RingItem *ring_item;
 
-    surface = &display->surfaces[surface_id];
+    surface = &display->priv->surfaces[surface_id];
 
     while ((ring_item = ring_get_tail(&surface->depend_on_me))) {
         Drawable *drawable;
@@ -955,10 +962,10 @@ static int validate_drawable_bbox(DisplayChannel *display, RedDrawable *drawable
         /* surface_id must be validated before calling into
          * validate_drawable_bbox
          */
-        if (!validate_surface(display, drawable->surface_id)) {
+        if (!display_channel_validate_surface(display, drawable->surface_id)) {
             return FALSE;
         }
-        context = &display->surfaces[surface_id].context;
+        context = &display->priv->surfaces[surface_id].context;
 
         if (drawable->bbox.top < 0)
                 return FALSE;
@@ -998,7 +1005,7 @@ static Drawable *display_channel_get_drawable(DisplayChannel *display, uint8_t e
     }
     for (x = 0; x < 3; ++x) {
         if (red_drawable->surface_deps[x] != -1
-            && !validate_surface(display, red_drawable->surface_deps[x])) {
+            && !display_channel_validate_surface(display, red_drawable->surface_deps[x])) {
             return NULL;
         }
     }
@@ -1012,7 +1019,7 @@ static Drawable *display_channel_get_drawable(DisplayChannel *display, uint8_t e
     drawable->red_drawable = red_drawable_ref(red_drawable);
 
     drawable->surface_id = red_drawable->surface_id;
-    display->surfaces[drawable->surface_id].refs++;
+    display->priv->surfaces[drawable->surface_id].refs++;
 
     memcpy(drawable->surface_deps, red_drawable->surface_deps, sizeof(drawable->surface_deps));
     /*
@@ -1062,7 +1069,7 @@ static void display_channel_add_drawable(DisplayChannel *display, Drawable *draw
         return;
     }
 
-    Ring *ring = &display->surfaces[surface_id].current;
+    Ring *ring = &display->priv->surfaces[surface_id].current;
     int add_to_pipe;
     if (has_shadow(red_drawable)) {
         add_to_pipe = current_add_with_shadow(display, ring, drawable);
@@ -1075,7 +1082,7 @@ static void display_channel_add_drawable(DisplayChannel *display, Drawable *draw
         pipes_add_drawable(display, drawable);
 
 #ifdef RED_WORKER_STAT
-    if ((++display->add_count % 100) == 0)
+    if ((++display->priv->add_count % 100) == 0)
         display_channel_print_stats(display);
 #endif
 }
@@ -1139,7 +1146,7 @@ void display_channel_flush_all_surfaces(DisplayChannel *display)
     int x;
 
     for (x = 0; x < NUM_SURFACES; ++x) {
-        if (display->surfaces[x].context.canvas) {
+        if (display->priv->surfaces[x].context.canvas) {
             display_channel_current_flush(display, x);
         }
     }
@@ -1171,7 +1178,7 @@ void display_channel_free_glz_drawables(DisplayChannel *display)
 
 static bool free_one_drawable(DisplayChannel *display, int force_glz_free)
 {
-    RingItem *ring_item = ring_get_tail(&display->current_list);
+    RingItem *ring_item = ring_get_tail(&display->priv->current_list);
     Drawable *drawable;
     Container *container;
 
@@ -1193,7 +1200,7 @@ static bool free_one_drawable(DisplayChannel *display, int force_glz_free)
 
 void display_channel_current_flush(DisplayChannel *display, int surface_id)
 {
-    while (!ring_is_empty(&display->surfaces[surface_id].current_list)) {
+    while (!ring_is_empty(&display->priv->surfaces[surface_id].current_list)) {
         free_one_drawable(display, FALSE);
     }
     current_remove_all(display, surface_id);
@@ -1205,8 +1212,8 @@ void display_channel_free_some(DisplayChannel *display)
     DisplayChannelClient *dcc;
     GList *link, *next;
 
-    spice_debug("#draw=%d, #glz_draw=%d", display->drawable_count,
-                display->encoder_shared_data.glz_drawable_count);
+    spice_debug("#draw=%d, #glz_draw=%d", display->priv->drawable_count,
+                display->priv->encoder_shared_data.glz_drawable_count);
     FOREACH_CLIENT(display, link, next, dcc) {
         ImageEncoders *encoders = dcc_get_encoders(dcc);
 
@@ -1217,7 +1224,7 @@ void display_channel_free_some(DisplayChannel *display)
         }
     }
 
-    while (!ring_is_empty(&display->current_list) && n++ < RED_RELEASE_BUNCH_SIZE) {
+    while (!ring_is_empty(&display->priv->current_list) && n++ < RED_RELEASE_BUNCH_SIZE) {
         free_one_drawable(display, TRUE);
     }
 
@@ -1232,29 +1239,29 @@ static Drawable* drawable_try_new(DisplayChannel *display)
 {
     Drawable *drawable;
 
-    if (!display->free_drawables)
+    if (!display->priv->free_drawables)
         return NULL;
 
-    drawable = &display->free_drawables->u.drawable;
-    display->free_drawables = display->free_drawables->u.next;
-    display->drawable_count++;
+    drawable = &display->priv->free_drawables->u.drawable;
+    display->priv->free_drawables = display->priv->free_drawables->u.next;
+    display->priv->drawable_count++;
 
     return drawable;
 }
 
 static void drawable_free(DisplayChannel *display, Drawable *drawable)
 {
-    ((_Drawable *)drawable)->u.next = display->free_drawables;
-    display->free_drawables = (_Drawable *)drawable;
+    ((_Drawable *)drawable)->u.next = display->priv->free_drawables;
+    display->priv->free_drawables = (_Drawable *)drawable;
 }
 
 static void drawables_init(DisplayChannel *display)
 {
     int i;
 
-    display->free_drawables = NULL;
+    display->priv->free_drawables = NULL;
     for (i = 0; i < NUM_DRAWABLES; i++) {
-        drawable_free(display, &display->drawables[i].u.drawable);
+        drawable_free(display, &display->priv->drawables[i].u.drawable);
     }
 }
 
@@ -1353,7 +1360,7 @@ void drawable_unref(Drawable *drawable)
         red_drawable_unref(drawable->red_drawable);
     }
     drawable_free(display, drawable);
-    display->drawable_count--;
+    display->priv->drawable_count--;
 }
 
 static void drawable_deps_draw(DisplayChannel *display, Drawable *drawable)
@@ -1378,11 +1385,11 @@ static void drawable_draw(DisplayChannel *display, Drawable *drawable)
 
     drawable_deps_draw(display, drawable);
 
-    surface = &display->surfaces[drawable->surface_id];
+    surface = &display->priv->surfaces[drawable->surface_id];
     canvas = surface->context.canvas;
     spice_return_if_fail(canvas);
 
-    image_cache_aging(&display->image_cache);
+    image_cache_aging(&display->priv->image_cache);
 
     region_add(&surface->draw_dirty_region, &drawable->red_drawable->bbox);
 
@@ -1390,8 +1397,8 @@ static void drawable_draw(DisplayChannel *display, Drawable *drawable)
     case QXL_DRAW_FILL: {
         SpiceFill fill = drawable->red_drawable->u.fill;
         SpiceImage img1, img2;
-        image_cache_localize_brush(&display->image_cache, &fill.brush, &img1);
-        image_cache_localize_mask(&display->image_cache, &fill.mask, &img2);
+        image_cache_localize_brush(&display->priv->image_cache, &fill.brush, &img1);
+        image_cache_localize_mask(&display->priv->image_cache, &fill.mask, &img2);
         canvas->ops->draw_fill(canvas, &drawable->red_drawable->bbox,
                                &clip, &fill);
         break;
@@ -1399,17 +1406,17 @@ static void drawable_draw(DisplayChannel *display, Drawable *drawable)
     case QXL_DRAW_OPAQUE: {
         SpiceOpaque opaque = drawable->red_drawable->u.opaque;
         SpiceImage img1, img2, img3;
-        image_cache_localize_brush(&display->image_cache, &opaque.brush, &img1);
-        image_cache_localize(&display->image_cache, &opaque.src_bitmap, &img2, drawable);
-        image_cache_localize_mask(&display->image_cache, &opaque.mask, &img3);
+        image_cache_localize_brush(&display->priv->image_cache, &opaque.brush, &img1);
+        image_cache_localize(&display->priv->image_cache, &opaque.src_bitmap, &img2, drawable);
+        image_cache_localize_mask(&display->priv->image_cache, &opaque.mask, &img3);
         canvas->ops->draw_opaque(canvas, &drawable->red_drawable->bbox, &clip, &opaque);
         break;
     }
     case QXL_DRAW_COPY: {
         SpiceCopy copy = drawable->red_drawable->u.copy;
         SpiceImage img1, img2;
-        image_cache_localize(&display->image_cache, &copy.src_bitmap, &img1, drawable);
-        image_cache_localize_mask(&display->image_cache, &copy.mask, &img2);
+        image_cache_localize(&display->priv->image_cache, &copy.src_bitmap, &img1, drawable);
+        image_cache_localize_mask(&display->priv->image_cache, &copy.mask, &img2);
         canvas->ops->draw_copy(canvas, &drawable->red_drawable->bbox,
                                &clip, &copy);
         break;
@@ -1417,7 +1424,7 @@ static void drawable_draw(DisplayChannel *display, Drawable *drawable)
     case QXL_DRAW_TRANSPARENT: {
         SpiceTransparent transparent = drawable->red_drawable->u.transparent;
         SpiceImage img1;
-        image_cache_localize(&display->image_cache, &transparent.src_bitmap, &img1, drawable);
+        image_cache_localize(&display->priv->image_cache, &transparent.src_bitmap, &img1, drawable);
         canvas->ops->draw_transparent(canvas,
                                       &drawable->red_drawable->bbox, &clip, &transparent);
         break;
@@ -1425,7 +1432,7 @@ static void drawable_draw(DisplayChannel *display, Drawable *drawable)
     case QXL_DRAW_ALPHA_BLEND: {
         SpiceAlphaBlend alpha_blend = drawable->red_drawable->u.alpha_blend;
         SpiceImage img1;
-        image_cache_localize(&display->image_cache, &alpha_blend.src_bitmap, &img1, drawable);
+        image_cache_localize(&display->priv->image_cache, &alpha_blend.src_bitmap, &img1, drawable);
         canvas->ops->draw_alpha_blend(canvas,
                                       &drawable->red_drawable->bbox, &clip, &alpha_blend);
         break;
@@ -1438,8 +1445,8 @@ static void drawable_draw(DisplayChannel *display, Drawable *drawable)
     case QXL_DRAW_BLEND: {
         SpiceBlend blend = drawable->red_drawable->u.blend;
         SpiceImage img1, img2;
-        image_cache_localize(&display->image_cache, &blend.src_bitmap, &img1, drawable);
-        image_cache_localize_mask(&display->image_cache, &blend.mask, &img2);
+        image_cache_localize(&display->priv->image_cache, &blend.src_bitmap, &img1, drawable);
+        image_cache_localize_mask(&display->priv->image_cache, &blend.mask, &img2);
         canvas->ops->draw_blend(canvas, &drawable->red_drawable->bbox,
                                 &clip, &blend);
         break;
@@ -1447,7 +1454,7 @@ static void drawable_draw(DisplayChannel *display, Drawable *drawable)
     case QXL_DRAW_BLACKNESS: {
         SpiceBlackness blackness = drawable->red_drawable->u.blackness;
         SpiceImage img1;
-        image_cache_localize_mask(&display->image_cache, &blackness.mask, &img1);
+        image_cache_localize_mask(&display->priv->image_cache, &blackness.mask, &img1);
         canvas->ops->draw_blackness(canvas,
                                     &drawable->red_drawable->bbox, &clip, &blackness);
         break;
@@ -1455,7 +1462,7 @@ static void drawable_draw(DisplayChannel *display, Drawable *drawable)
     case QXL_DRAW_WHITENESS: {
         SpiceWhiteness whiteness = drawable->red_drawable->u.whiteness;
         SpiceImage img1;
-        image_cache_localize_mask(&display->image_cache, &whiteness.mask, &img1);
+        image_cache_localize_mask(&display->priv->image_cache, &whiteness.mask, &img1);
         canvas->ops->draw_whiteness(canvas,
                                     &drawable->red_drawable->bbox, &clip, &whiteness);
         break;
@@ -1463,7 +1470,7 @@ static void drawable_draw(DisplayChannel *display, Drawable *drawable)
     case QXL_DRAW_INVERS: {
         SpiceInvers invers = drawable->red_drawable->u.invers;
         SpiceImage img1;
-        image_cache_localize_mask(&display->image_cache, &invers.mask, &img1);
+        image_cache_localize_mask(&display->priv->image_cache, &invers.mask, &img1);
         canvas->ops->draw_invers(canvas,
                                  &drawable->red_drawable->bbox, &clip, &invers);
         break;
@@ -1471,9 +1478,9 @@ static void drawable_draw(DisplayChannel *display, Drawable *drawable)
     case QXL_DRAW_ROP3: {
         SpiceRop3 rop3 = drawable->red_drawable->u.rop3;
         SpiceImage img1, img2, img3;
-        image_cache_localize_brush(&display->image_cache, &rop3.brush, &img1);
-        image_cache_localize(&display->image_cache, &rop3.src_bitmap, &img2, drawable);
-        image_cache_localize_mask(&display->image_cache, &rop3.mask, &img3);
+        image_cache_localize_brush(&display->priv->image_cache, &rop3.brush, &img1);
+        image_cache_localize(&display->priv->image_cache, &rop3.src_bitmap, &img2, drawable);
+        image_cache_localize_mask(&display->priv->image_cache, &rop3.mask, &img3);
         canvas->ops->draw_rop3(canvas, &drawable->red_drawable->bbox,
                                &clip, &rop3);
         break;
@@ -1481,9 +1488,9 @@ static void drawable_draw(DisplayChannel *display, Drawable *drawable)
     case QXL_DRAW_COMPOSITE: {
         SpiceComposite composite = drawable->red_drawable->u.composite;
         SpiceImage src, mask;
-        image_cache_localize(&display->image_cache, &composite.src_bitmap, &src, drawable);
+        image_cache_localize(&display->priv->image_cache, &composite.src_bitmap, &src, drawable);
         if (composite.mask_bitmap)
-            image_cache_localize(&display->image_cache, &composite.mask_bitmap, &mask, drawable);
+            image_cache_localize(&display->priv->image_cache, &composite.mask_bitmap, &mask, drawable);
         canvas->ops->draw_composite(canvas, &drawable->red_drawable->bbox,
                                     &clip, &composite);
         break;
@@ -1491,7 +1498,7 @@ static void drawable_draw(DisplayChannel *display, Drawable *drawable)
     case QXL_DRAW_STROKE: {
         SpiceStroke stroke = drawable->red_drawable->u.stroke;
         SpiceImage img1;
-        image_cache_localize_brush(&display->image_cache, &stroke.brush, &img1);
+        image_cache_localize_brush(&display->priv->image_cache, &stroke.brush, &img1);
         canvas->ops->draw_stroke(canvas,
                                  &drawable->red_drawable->bbox, &clip, &stroke);
         break;
@@ -1499,8 +1506,8 @@ static void drawable_draw(DisplayChannel *display, Drawable *drawable)
     case QXL_DRAW_TEXT: {
         SpiceText text = drawable->red_drawable->u.text;
         SpiceImage img1, img2;
-        image_cache_localize_brush(&display->image_cache, &text.fore_brush, &img1);
-        image_cache_localize_brush(&display->image_cache, &text.back_brush, &img2);
+        image_cache_localize_brush(&display->priv->image_cache, &text.fore_brush, &img1);
+        image_cache_localize_brush(&display->priv->image_cache, &text.back_brush, &img2);
         canvas->ops->draw_text(canvas, &drawable->red_drawable->bbox,
                                &clip, &text);
         break;
@@ -1592,11 +1599,11 @@ void display_channel_draw_until(DisplayChannel *display, const SpiceRect *area,
     spice_return_if_fail(last);
     spice_return_if_fail(ring_item_is_linked(&last->list_link));
 
-    surface = &display->surfaces[surface_id];
+    surface = &display->priv->surfaces[surface_id];
 
     if (surface_id != last->surface_id) {
         // find the nearest older drawable from the appropriate surface
-        ring = &display->current_list;
+        ring = &display->priv->current_list;
         ring_item = &last->list_link;
         while ((ring_item = ring_next(ring, ring_item))) {
             now = SPICE_CONTAINEROF(ring_item, Drawable, list_link);
@@ -1637,7 +1644,7 @@ void display_channel_draw(DisplayChannel *display, const SpiceRect *area, int su
     spice_return_if_fail(area->left >= 0 && area->top >= 0 &&
                          area->left < area->right && area->top < area->bottom);
 
-    surface = &display->surfaces[surface_id];
+    surface = &display->priv->surfaces[surface_id];
 
     last = current_find_intersects_rect(&surface->current_list, NULL, area);
     if (last)
@@ -1669,12 +1676,12 @@ void display_channel_update(DisplayChannel *display,
     SpiceRect rect;
     RedSurface *surface;
 
-    spice_return_if_fail(validate_surface(display, surface_id));
+    spice_return_if_fail(display_channel_validate_surface(display, surface_id));
 
     red_get_rect_ptr(&rect, area);
     display_channel_draw(display, &rect, surface_id);
 
-    surface = &display->surfaces[surface_id];
+    surface = &display->priv->surfaces[surface_id];
     if (*qxl_dirty_rects == NULL) {
         *num_dirty_rects = pixman_region32_n_rects(&surface->draw_dirty_region);
         *qxl_dirty_rects = spice_new0(QXLRect, *num_dirty_rects);
@@ -1712,9 +1719,9 @@ static void display_channel_destroy_surface(DisplayChannel *display, uint32_t su
 
 void display_channel_destroy_surface_wait(DisplayChannel *display, uint32_t surface_id)
 {
-    if (!validate_surface(display, surface_id))
+    if (!display_channel_validate_surface(display, surface_id))
         return;
-    if (!display->surfaces[surface_id].context.canvas)
+    if (!display->priv->surfaces[surface_id].context.canvas)
         return;
 
     draw_depend_on_me(display, surface_id);
@@ -1734,15 +1741,15 @@ void display_channel_destroy_surfaces(DisplayChannel *display)
     spice_debug(NULL);
     //to handle better
     for (i = 0; i < NUM_SURFACES; ++i) {
-        if (display->surfaces[i].context.canvas) {
+        if (display->priv->surfaces[i].context.canvas) {
             display_channel_destroy_surface_wait(display, i);
-            if (display->surfaces[i].context.canvas) {
+            if (display->priv->surfaces[i].context.canvas) {
                 display_channel_surface_unref(display, i);
             }
-            spice_assert(!display->surfaces[i].context.canvas);
+            spice_assert(!display->priv->surfaces[i].context.canvas);
         }
     }
-    spice_warn_if_fail(ring_is_empty(&display->streams));
+    spice_warn_if_fail(ring_is_empty(&display->priv->streams));
 
     if (red_channel_is_connected(RED_CHANNEL(display))) {
         red_channel_pipes_add_type(RED_CHANNEL(display), RED_PIPE_ITEM_TYPE_INVAL_PALETTE_CACHE);
@@ -1773,8 +1780,8 @@ create_canvas_for_surface(DisplayChannel *display, RedSurface *surface, uint32_t
     case RED_RENDERER_SW:
         canvas = canvas_create_for_data(surface->context.width, surface->context.height, surface->context.format,
                                         surface->context.line_0, surface->context.stride,
-                                        &display->image_cache.base,
-                                        &display->image_surfaces, NULL, NULL, NULL);
+                                        &display->priv->image_cache.base,
+                                        &display->priv->image_surfaces, NULL, NULL, NULL);
         surface->context.top_down = TRUE;
         surface->context.canvas_draws_on_surface = TRUE;
         return canvas;
@@ -1789,7 +1796,7 @@ void display_channel_create_surface(DisplayChannel *display, uint32_t surface_id
                                     uint32_t height, int32_t stride, uint32_t format,
                                     void *line_0, int data_is_valid, int send_client)
 {
-    RedSurface *surface = &display->surfaces[surface_id];
+    RedSurface *surface = &display->priv->surfaces[surface_id];
 
     spice_warn_if_fail(!surface->context.canvas);
 
@@ -1814,7 +1821,7 @@ void display_channel_create_surface(DisplayChannel *display, uint32_t surface_id
     region_init(&surface->draw_dirty_region);
     surface->refs = 1;
 
-    if (display->renderer == RED_RENDERER_INVALID) {
+    if (display->priv->renderer == RED_RENDERER_INVALID) {
         int i;
         QXLInstance *qxl = display->common.qxl;
         RedsState *reds = red_qxl_get_server(qxl->st);
@@ -1823,12 +1830,12 @@ void display_channel_create_surface(DisplayChannel *display, uint32_t surface_id
             uint32_t renderer = g_array_index(renderers, uint32_t, i);
             surface->context.canvas = create_canvas_for_surface(display, surface, renderer);
             if (surface->context.canvas) {
-                display->renderer = renderer;
+                display->priv->renderer = renderer;
                 break;
             }
         }
     } else {
-        surface->context.canvas = create_canvas_for_surface(display, surface, display->renderer);
+        surface->context.canvas = create_canvas_for_surface(display, surface, display->priv->renderer);
     }
 
     spice_return_if_fail(surface->context.canvas);
@@ -1852,8 +1859,8 @@ static void on_disconnect(RedChannelClient *rcc)
 
     // this was the last channel client
     spice_debug("#draw=%d, #glz_draw=%d",
-                display->drawable_count,
-                display->encoder_shared_data.glz_drawable_count);
+                display->priv->drawable_count,
+                display->priv->encoder_shared_data.glz_drawable_count);
 }
 
 static int handle_migrate_flush_mark(RedChannelClient *rcc)
@@ -1880,11 +1887,12 @@ static int handle_migrate_data(RedChannelClient *rcc, uint32_t size, void *messa
 
 static SpiceCanvas *image_surfaces_get(SpiceImageSurfaces *surfaces, uint32_t surface_id)
 {
-    DisplayChannel *display = SPICE_CONTAINEROF(surfaces, DisplayChannel, image_surfaces);
+    DisplayChannelPrivate *p = SPICE_CONTAINEROF(surfaces, DisplayChannelPrivate, image_surfaces);
+    DisplayChannel *display = p->pub;
 
-    spice_return_val_if_fail(validate_surface(display, surface_id), NULL);
+    spice_return_val_if_fail(display_channel_validate_surface(display, surface_id), NULL);
 
-    return display->surfaces[surface_id].context.canvas;
+    return display->priv->surfaces[surface_id].context.canvas;
 }
 
 DisplayChannel* display_channel_new(SpiceServer *reds, RedWorker *worker, 
@@ -1912,31 +1920,32 @@ DisplayChannel* display_channel_new(SpiceServer *reds, RedWorker *worker,
         SPICE_MIGRATE_NEED_FLUSH | SPICE_MIGRATE_NEED_DATA_TRANSFER,
         &cbs, dcc_handle_message);
     spice_return_val_if_fail(display, NULL);
+    display->priv->pub = display;
 
     clockid_t stat_clock = CLOCK_THREAD_CPUTIME_ID;
-    stat_init(&display->add_stat, "add", stat_clock);
-    stat_init(&display->exclude_stat, "exclude", stat_clock);
-    stat_init(&display->__exclude_stat, "__exclude", stat_clock);
+    stat_init(&display->priv->add_stat, "add", stat_clock);
+    stat_init(&display->priv->exclude_stat, "exclude", stat_clock);
+    stat_init(&display->priv->__exclude_stat, "__exclude", stat_clock);
 #ifdef RED_STATISTICS
     RedChannel *channel = RED_CHANNEL(display);
-    display->cache_hits_counter = stat_add_counter(reds, channel->stat,
-                                                   "cache_hits", TRUE);
-    display->add_to_cache_counter = stat_add_counter(reds, channel->stat,
-                                                     "add_to_cache", TRUE);
-    display->non_cache_counter = stat_add_counter(reds, channel->stat,
-                                                  "non_cache", TRUE);
+    display->priv->cache_hits_counter = stat_add_counter(reds, channel->stat,
+                                                         "cache_hits", TRUE);
+    display->priv->add_to_cache_counter = stat_add_counter(reds, channel->stat,
+                                                           "add_to_cache", TRUE);
+    display->priv->non_cache_counter = stat_add_counter(reds, channel->stat,
+                                                        "non_cache", TRUE);
 #endif
-    image_encoder_shared_init(&display->encoder_shared_data);
+    image_encoder_shared_init(&display->priv->encoder_shared_data);
 
-    display->n_surfaces = n_surfaces;
-    display->renderer = RED_RENDERER_INVALID;
+    display->priv->n_surfaces = n_surfaces;
+    display->priv->renderer = RED_RENDERER_INVALID;
 
-    ring_init(&display->current_list);
-    display->image_surfaces.ops = &image_surfaces_ops;
+    ring_init(&display->priv->current_list);
+    display->priv->image_surfaces.ops = &image_surfaces_ops;
     drawables_init(display);
-    image_cache_init(&display->image_cache);
-    display->stream_video = stream_video;
-    display->video_codecs = g_array_ref(video_codecs);
+    image_cache_init(&display->priv->image_cache);
+    display->priv->stream_video = stream_video;
+    display->priv->video_codecs = g_array_ref(video_codecs);
     display_channel_init_streams(display);
 
     return display;
@@ -1950,11 +1959,11 @@ void display_channel_process_surface_cmd(DisplayChannel *display, RedSurfaceCmd
     uint8_t *data;
 
     surface_id = surface->surface_id;
-    if SPICE_UNLIKELY(surface_id >= display->n_surfaces) {
+    if SPICE_UNLIKELY(surface_id >= display->priv->n_surfaces) {
         return;
     }
 
-    red_surface = &display->surfaces[surface_id];
+    red_surface = &display->priv->surfaces[surface_id];
 
     switch (surface->type) {
     case QXL_SURFACE_CMD_CREATE: {
@@ -1994,18 +2003,18 @@ void display_channel_process_surface_cmd(DisplayChannel *display, RedSurfaceCmd
 void display_channel_update_compression(DisplayChannel *display, DisplayChannelClient *dcc)
 {
     if (dcc_get_jpeg_state(dcc) == SPICE_WAN_COMPRESSION_AUTO) {
-        display->enable_jpeg = dcc_is_low_bandwidth(dcc);
+        display->priv->enable_jpeg = dcc_is_low_bandwidth(dcc);
     } else {
-        display->enable_jpeg = (dcc_get_jpeg_state(dcc) == SPICE_WAN_COMPRESSION_ALWAYS);
+        display->priv->enable_jpeg = (dcc_get_jpeg_state(dcc) == SPICE_WAN_COMPRESSION_ALWAYS);
     }
 
     if (dcc_get_zlib_glz_state(dcc) == SPICE_WAN_COMPRESSION_AUTO) {
-        display->enable_zlib_glz_wrap = dcc_is_low_bandwidth(dcc);
+        display->priv->enable_zlib_glz_wrap = dcc_is_low_bandwidth(dcc);
     } else {
-        display->enable_zlib_glz_wrap = (dcc_get_zlib_glz_state(dcc) == SPICE_WAN_COMPRESSION_ALWAYS);
+        display->priv->enable_zlib_glz_wrap = (dcc_get_zlib_glz_state(dcc) == SPICE_WAN_COMPRESSION_ALWAYS);
     }
-    spice_info("jpeg %s", display->enable_jpeg ? "enabled" : "disabled");
-    spice_info("zlib-over-glz %s", display->enable_zlib_glz_wrap ? "enabled" : "disabled");
+    spice_info("jpeg %s", display->priv->enable_jpeg ? "enabled" : "disabled");
+    spice_info("zlib-over-glz %s", display->priv->enable_zlib_glz_wrap ? "enabled" : "disabled");
 }
 
 void display_channel_gl_scanout(DisplayChannel *display)
@@ -2017,7 +2026,7 @@ static void set_gl_draw_async_count(DisplayChannel *display, int num)
 {
     QXLInstance *qxl = display->common.qxl;
 
-    display->gl_draw_async_count = num;
+    display->priv->gl_draw_async_count = num;
 
     if (num == 0) {
         red_qxl_gl_draw_async_complete(qxl);
@@ -2028,7 +2037,7 @@ void display_channel_gl_draw(DisplayChannel *display, SpiceMsgDisplayGlDraw *dra
 {
     int num;
 
-    spice_return_if_fail(display->gl_draw_async_count == 0);
+    spice_return_if_fail(display->priv->gl_draw_async_count == 0);
 
     num = red_channel_pipes_new_add_push(RED_CHANNEL(display), dcc_gl_draw_item_new, draw);
     set_gl_draw_async_count(display, num);
@@ -2036,5 +2045,57 @@ void display_channel_gl_draw(DisplayChannel *display, SpiceMsgDisplayGlDraw *dra
 
 void display_channel_gl_draw_done(DisplayChannel *display)
 {
-    set_gl_draw_async_count(display, display->gl_draw_async_count - 1);
+    set_gl_draw_async_count(display, display->priv->gl_draw_async_count - 1);
+}
+
+int display_channel_get_stream_id(DisplayChannel *display, Stream *stream)
+{
+    return (int)(stream - display->priv->streams_buf);
+}
+
+gboolean display_channel_validate_surface(DisplayChannel *display, uint32_t surface_id)
+{
+    if SPICE_UNLIKELY(surface_id >= display->priv->n_surfaces) {
+        spice_warning("invalid surface_id %u", surface_id);
+        return 0;
+    }
+    if (!display->priv->surfaces[surface_id].context.canvas) {
+        spice_warning("canvas address is %p for %d (and is NULL)\n",
+                   &(display->priv->surfaces[surface_id].context.canvas), surface_id);
+        spice_warning("failed on %d", surface_id);
+        return 0;
+    }
+    return 1;
+}
+
+void display_channel_update_monitors_config(DisplayChannel *display,
+                                            QXLMonitorsConfig *config,
+                                            uint16_t count, uint16_t max_allowed)
+{
+
+    if (display->priv->monitors_config)
+        monitors_config_unref(display->priv->monitors_config);
+
+    display->priv->monitors_config =
+        monitors_config_new(config->heads, count, max_allowed);
+}
+
+void set_monitors_config_to_primary(DisplayChannel *display)
+{
+    DrawContext *context = &display->priv->surfaces[0].context;
+    QXLHead head = { 0, };
+
+    spice_return_if_fail(display->priv->surfaces[0].context.canvas);
+
+    if (display->priv->monitors_config)
+        monitors_config_unref(display->priv->monitors_config);
+
+    head.width = context->width;
+    head.height = context->height;
+    display->priv->monitors_config = monitors_config_new(&head, 1, 1);
+}
+
+void display_channel_reset_image_cache(DisplayChannel *self)
+{
+    image_cache_reset(&self->priv->image_cache);
 }
diff --git a/server/display-channel.h b/server/display-channel.h
index 7b71480..561dc46 100644
--- a/server/display-channel.h
+++ b/server/display-channel.h
@@ -157,8 +157,12 @@ struct _Drawable {
     } u;
 };
 
-struct DisplayChannel {
-    CommonGraphicsChannel common; // Must be the first thing
+typedef struct DisplayChannelPrivate DisplayChannelPrivate;
+/* FIXME: move to separate file */
+struct DisplayChannelPrivate
+{
+    DisplayChannel *pub;
+
     uint32_t bits_unique;
 
     MonitorsConfig *monitors_config;
@@ -208,10 +212,23 @@ struct DisplayChannel {
     ImageEncoderSharedData encoder_shared_data;
 };
 
-static inline int get_stream_id(DisplayChannel *display, Stream *stream)
-{
-    return (int)(stream - display->streams_buf);
-}
+
+struct DisplayChannel {
+    CommonGraphicsChannel common; // Must be the first thing
+
+    DisplayChannelPrivate priv[1];
+};
+
+#define FOREACH_DCC(channel, _link, _next, _data)                   \
+    for (_link = (channel ? RED_CHANNEL(channel)->clients : NULL), \
+         _next = (_link ? _link->next : NULL), \
+         _data = (_link ? _link->data : NULL); \
+         _link; \
+         _link = _next, \
+         _next = (_link ? _link->next : NULL), \
+         _data = (_link ? _link->data : NULL))
+
+int display_channel_get_stream_id(DisplayChannel *display, Stream *stream);
 
 typedef struct RedSurfaceDestroyItem {
     RedPipeItem pipe_item;
@@ -258,6 +275,8 @@ void                       display_channel_compress_stats_print      (const Disp
 void                       display_channel_compress_stats_reset      (DisplayChannel *display);
 void                       display_channel_surface_unref             (DisplayChannel *display,
                                                                       uint32_t surface_id);
+bool                       display_channel_surface_has_canvas        (DisplayChannel *display,
+                                                                      uint32_t surface_id);
 void                       display_channel_current_flush             (DisplayChannel *display,
                                                                       int surface_id);
 int                        display_channel_wait_for_migrate_data     (DisplayChannel *display);
@@ -281,20 +300,12 @@ void                       display_channel_gl_draw                   (DisplayCha
                                                                       SpiceMsgDisplayGlDraw *draw);
 void                       display_channel_gl_draw_done              (DisplayChannel *display);
 
-static inline int validate_surface(DisplayChannel *display, uint32_t surface_id)
-{
-    if SPICE_UNLIKELY(surface_id >= display->n_surfaces) {
-        spice_warning("invalid surface_id %u", surface_id);
-        return 0;
-    }
-    if (!display->surfaces[surface_id].context.canvas) {
-        spice_warning("canvas address is %p for %d (and is NULL)\n",
-                   &(display->surfaces[surface_id].context.canvas), surface_id);
-        spice_warning("failed on %d", surface_id);
-        return 0;
-    }
-    return 1;
-}
+void display_channel_update_monitors_config(DisplayChannel *display, QXLMonitorsConfig *config,
+                                            uint16_t count, uint16_t max_allowed);
+void set_monitors_config_to_primary(DisplayChannel *display);
+
+gboolean display_channel_validate_surface(DisplayChannel *display, uint32_t surface_id);
+void display_channel_reset_image_cache(DisplayChannel *self);
 
 static inline int is_equal_path(SpicePath *path1, SpicePath *path2)
 {
diff --git a/server/red-worker.c b/server/red-worker.c
index 590412b..92ab59c 100644
--- a/server/red-worker.c
+++ b/server/red-worker.c
@@ -247,7 +247,7 @@ static int red_process_display(RedWorker *worker, int *ring_is_empty)
                                    &update, ext_cmd.cmd.data)) {
                 break;
             }
-            if (!validate_surface(worker->display_channel, update.surface_id)) {
+            if (!display_channel_validate_surface(worker->display_channel, update.surface_id)) {
                 spice_warning("Invalid surface in QXL_CMD_UPDATE");
             } else {
                 display_channel_draw(worker->display_channel, &update.area, update.surface_id);
@@ -587,18 +587,6 @@ static void handle_dev_destroy_surfaces(void *opaque, void *payload)
     cursor_channel_reset(worker->cursor_channel);
 }
 
-static void display_update_monitors_config(DisplayChannel *display,
-                                           QXLMonitorsConfig *config,
-                                           uint16_t count, uint16_t max_allowed)
-{
-
-    if (display->monitors_config)
-        monitors_config_unref(display->monitors_config);
-
-    display->monitors_config =
-        monitors_config_new(config->heads, count, max_allowed);
-}
-
 static void red_worker_push_monitors_config(RedWorker *worker)
 {
     DisplayChannelClient *dcc;
@@ -609,21 +597,6 @@ static void red_worker_push_monitors_config(RedWorker *worker)
     }
 }
 
-static void set_monitors_config_to_primary(DisplayChannel *display)
-{
-    DrawContext *context = &display->surfaces[0].context;
-    QXLHead head = { 0, };
-
-    spice_return_if_fail(display->surfaces[0].context.canvas);
-
-    if (display->monitors_config)
-        monitors_config_unref(display->monitors_config);
-
-    head.width = context->width;
-    head.height = context->height;
-    display->monitors_config = monitors_config_new(&head, 1, 1);
-}
-
 static void dev_create_primary_surface(RedWorker *worker, uint32_t surface_id,
                                        QXLDevSurfaceCreate surface)
 {
@@ -689,12 +662,12 @@ static void destroy_primary_surface(RedWorker *worker, uint32_t surface_id)
 {
     DisplayChannel *display = worker->display_channel;
 
-    if (!validate_surface(display, surface_id))
+    if (!display_channel_validate_surface(display, surface_id))
         return;
     spice_warn_if_fail(surface_id == 0);
 
     spice_debug(NULL);
-    if (!display->surfaces[surface_id].context.canvas) {
+    if (!display_channel_surface_has_canvas(display, surface_id)) {
         spice_warning("double destroy of primary surface");
         return;
     }
@@ -703,8 +676,10 @@ static void destroy_primary_surface(RedWorker *worker, uint32_t surface_id)
     display_channel_destroy_surface_wait(display, 0);
     display_channel_surface_unref(display, 0);
 
+    /* FIXME: accessing private data only for warning purposes...
     spice_warn_if_fail(ring_is_empty(&display->streams));
-    spice_warn_if_fail(!display->surfaces[surface_id].context.canvas);
+    */
+    spice_warn_if_fail(!display_channel_surface_has_canvas(display, surface_id));
 
     cursor_channel_reset(worker->cursor_channel);
 }
@@ -798,11 +773,13 @@ static void handle_dev_oom(void *opaque, void *payload)
 
     spice_return_if_fail(worker->running);
     // streams? but without streams also leak
+#if FIXME
     spice_debug("OOM1 #draw=%u, #glz_draw=%u current %u pipes %u",
                 display->drawable_count,
                 display->encoder_shared_data.glz_drawable_count,
                 display->current_size,
                 red_channel_sum_pipes_size(display_red_channel));
+#endif
     while (red_process_display(worker, &ring_is_empty)) {
         red_channel_push(display_red_channel);
     }
@@ -810,11 +787,13 @@ static void handle_dev_oom(void *opaque, void *payload)
         display_channel_free_some(worker->display_channel);
         red_qxl_flush_resources(worker->qxl);
     }
+#if FIXME
     spice_debug("OOM2 #draw=%u, #glz_draw=%u current %u pipes %u",
                 display->drawable_count,
                 display->encoder_shared_data.glz_drawable_count,
                 display->current_size,
                 red_channel_sum_pipes_size(display_red_channel));
+#endif
     red_qxl_clear_pending(worker->qxl->st, RED_DISPATCHER_PENDING_OOM);
 }
 
@@ -828,9 +807,8 @@ static void handle_dev_reset_cursor(void *opaque, void *payload)
 static void handle_dev_reset_image_cache(void *opaque, void *payload)
 {
     RedWorker *worker = opaque;
-    DisplayChannel *display = worker->display_channel;
 
-    image_cache_reset(&display->image_cache);
+    display_channel_reset_image_cache(worker->display_channel);
 }
 
 static void handle_dev_destroy_surface_wait_async(void *opaque, void *payload)
@@ -950,9 +928,9 @@ static void handle_dev_monitors_config_async(void *opaque, void *payload)
         /* TODO: raise guest bug (requires added QXL interface) */
         return;
     }
-    display_update_monitors_config(worker->display_channel, dev_monitors_config,
-                                   MIN(count, msg->max_monitors),
-                                   MIN(max_allowed, msg->max_monitors));
+    display_channel_update_monitors_config(worker->display_channel, dev_monitors_config,
+                                           MIN(count, msg->max_monitors),
+                                           MIN(max_allowed, msg->max_monitors));
     red_worker_push_monitors_config(worker);
 }
 
diff --git a/server/stream.c b/server/stream.c
index 4819723..c3877c7 100644
--- a/server/stream.c
+++ b/server/stream.c
@@ -20,12 +20,13 @@
 
 #include "stream.h"
 #include "display-channel.h"
+#include "main-channel-client.h"
 
 #define FPS_TEST_INTERVAL 1
 #define FOREACH_STREAMS(display, item)                  \
-    for (item = ring_get_head(&(display)->streams);     \
+    for (item = ring_get_head(&(display)->priv->streams);     \
          item != NULL;                                  \
-         item = ring_next(&(display)->streams, item))
+         item = ring_next(&(display)->priv->streams, item))
 
 static void stream_agent_stats_print(StreamAgent *agent)
 {
@@ -101,11 +102,11 @@ void stream_stop(DisplayChannel *display, Stream *stream)
     spice_return_if_fail(ring_item_is_linked(&stream->link));
     spice_return_if_fail(!stream->current);
 
-    spice_debug("stream %d", get_stream_id(display, stream));
+    spice_debug("stream %d", display_channel_get_stream_id(display, stream));
     FOREACH_CLIENT(display, link, next, dcc) {
         StreamAgent *stream_agent;
 
-        stream_agent = dcc_get_stream_agent(dcc, get_stream_id(display, stream));
+        stream_agent = dcc_get_stream_agent(dcc, display_channel_get_stream_id(display, stream));
         region_clear(&stream_agent->vis_region);
         region_clear(&stream_agent->clip);
         if (stream_agent->video_encoder && dcc_use_video_encoder_rate_control(dcc)) {
@@ -121,25 +122,25 @@ void stream_stop(DisplayChannel *display, Stream *stream)
         red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), stream_destroy_item_new(stream_agent));
         stream_agent_stats_print(stream_agent);
     }
-    display->streams_size_total -= stream->width * stream->height;
+    display->priv->streams_size_total -= stream->width * stream->height;
     ring_remove(&stream->link);
     stream_unref(display, stream);
 }
 
 static void stream_free(DisplayChannel *display, Stream *stream)
 {
-    stream->next = display->free_streams;
-    display->free_streams = stream;
+    stream->next = display->priv->free_streams;
+    display->priv->free_streams = stream;
 }
 
 void display_channel_init_streams(DisplayChannel *display)
 {
     int i;
 
-    ring_init(&display->streams);
-    display->free_streams = NULL;
+    ring_init(&display->priv->streams);
+    display->priv->free_streams = NULL;
     for (i = 0; i < NUM_STREAMS; i++) {
-        Stream *stream = &display->streams_buf[i];
+        Stream *stream = &display->priv->streams_buf[i];
         ring_item_init(&stream->link);
         stream_free(display, stream);
     }
@@ -153,7 +154,7 @@ void stream_unref(DisplayChannel *display, Stream *stream)
     spice_warn_if_fail(!ring_item_is_linked(&stream->link));
 
     stream_free(display, stream);
-    display->stream_count--;
+    display->priv->stream_count--;
 }
 
 void stream_agent_unref(DisplayChannel *display, StreamAgent *agent)
@@ -197,7 +198,7 @@ static void update_copy_graduality(DisplayChannel *display, Drawable *drawable)
     SpiceBitmap *bitmap;
     spice_return_if_fail(drawable->red_drawable->type == QXL_DRAW_COPY);
 
-    if (display->stream_video != SPICE_STREAM_VIDEO_FILTER) {
+    if (display->priv->stream_video != SPICE_STREAM_VIDEO_FILTER) {
         drawable->copy_bitmap_graduality = BITMAP_GRADUAL_INVALID;
         return;
     }
@@ -302,7 +303,7 @@ static void attach_stream(DisplayChannel *display, Drawable *drawable, Stream *s
         StreamAgent *agent;
         QRegion clip_in_draw_dest;
 
-        agent = dcc_get_stream_agent(dcc, get_stream_id(display, stream));
+        agent = dcc_get_stream_agent(dcc, display_channel_get_stream_id(display, stream));
         region_or(&agent->vis_region, &drawable->tree_item.base.rgn);
 
         region_init(&clip_in_draw_dest);
@@ -349,7 +350,7 @@ static void before_reattach_stream(DisplayChannel *display,
         return;
     }
 
-    index = get_stream_id(display, stream);
+    index = display_channel_get_stream_id(display, stream);
     DRAWABLE_FOREACH_DPI_SAFE(stream->current, ring_item, next, dpi) {
         dcc = dpi->dcc;
         agent = dcc_get_stream_agent(dcc, index);
@@ -406,11 +407,11 @@ static void before_reattach_stream(DisplayChannel *display,
 static Stream *display_channel_stream_try_new(DisplayChannel *display)
 {
     Stream *stream;
-    if (!display->free_streams) {
+    if (!display->priv->free_streams) {
         return NULL;
     }
-    stream = display->free_streams;
-    display->free_streams = display->free_streams->next;
+    stream = display->priv->free_streams;
+    display->priv->free_streams = display->priv->free_streams->next;
     return stream;
 }
 
@@ -430,7 +431,7 @@ static void display_channel_create_stream(DisplayChannel *display, Drawable *dra
     spice_assert(drawable->red_drawable->type == QXL_DRAW_COPY);
     src_rect = &drawable->red_drawable->u.copy.src_area;
 
-    ring_add(&display->streams, &stream->link);
+    ring_add(&display->priv->streams, &stream->link);
     stream->current = drawable;
     stream->last_time = drawable->creation_time;
     stream->width = src_rect->right - src_rect->left;
@@ -452,13 +453,13 @@ static void display_channel_create_stream(DisplayChannel *display, Drawable *dra
     }
     stream->num_input_frames = 0;
     stream->input_fps_start_time = drawable->creation_time;
-    display->streams_size_total += stream->width * stream->height;
-    display->stream_count++;
+    display->priv->streams_size_total += stream->width * stream->height;
+    display->priv->stream_count++;
     FOREACH_CLIENT(display, link, next, dcc) {
         dcc_create_stream(dcc, stream);
     }
     spice_debug("stream %d %dx%d (%d, %d) (%d, %d) %u fps",
-                (int)(stream - display->streams_buf), stream->width,
+                (int)(stream - display->priv->streams_buf), stream->width,
                 stream->height, stream->dest_area.left, stream->dest_area.top,
                 stream->dest_area.right, stream->dest_area.bottom,
                 stream->input_fps);
@@ -530,7 +531,7 @@ void stream_trace_update(DisplayChannel *display, Drawable *drawable)
         }
     }
 
-    trace = display->items_trace;
+    trace = display->priv->items_trace;
     trace_end = trace + NUM_TRACE_ITEMS;
     for (; trace < trace_end; trace++) {
         if (is_next_stream_frame(display, drawable, trace->width, trace->height,
@@ -597,7 +598,7 @@ static void dcc_update_streams_max_latency(DisplayChannelClient *dcc, StreamAgen
     }
 
     dcc_set_max_stream_latency(dcc, 0);
-    if (DCC_TO_DC(dcc)->stream_count == 1) {
+    if (DCC_TO_DC(dcc)->priv->stream_count == 1) {
         return;
     }
     for (i = 0; i < NUM_STREAMS; i++) {
@@ -656,7 +657,7 @@ static uint64_t get_initial_bit_rate(DisplayChannelClient *dcc, Stream *stream)
     /* dividing the available bandwidth among the active streams, and saving
      * (1-RED_STREAM_CHANNEL_CAPACITY) of it for other messages */
     return (RED_STREAM_CHANNEL_CAPACITY * bit_rate *
-            stream->width * stream->height) / DCC_TO_DC(dcc)->streams_size_total;
+            stream->width * stream->height) / DCC_TO_DC(dcc)->priv->streams_size_total;
 }
 
 static uint32_t get_roundtrip_ms(void *opaque)
@@ -729,8 +730,8 @@ static VideoEncoder* dcc_create_video_encoder(DisplayChannelClient *dcc,
     int client_has_multi_codec = red_channel_client_test_remote_cap(rcc, SPICE_DISPLAY_CAP_MULTI_CODEC);
     int i;
 
-    for (i = 0; i < display->video_codecs->len; i++) {
-        RedVideoCodec* video_codec = &g_array_index (display->video_codecs, RedVideoCodec, i);
+    for (i = 0; i < display->priv->video_codecs->len; i++) {
+        RedVideoCodec* video_codec = &g_array_index (display->priv->video_codecs, RedVideoCodec, i);
 
         if (!client_has_multi_codec &&
             video_codec->type != SPICE_VIDEO_CODEC_TYPE_MJPEG) {
@@ -759,7 +760,7 @@ static VideoEncoder* dcc_create_video_encoder(DisplayChannelClient *dcc,
 
 void dcc_create_stream(DisplayChannelClient *dcc, Stream *stream)
 {
-    StreamAgent *agent = dcc_get_stream_agent(dcc, get_stream_id(DCC_TO_DC(dcc), stream));
+    StreamAgent *agent = dcc_get_stream_agent(dcc, display_channel_get_stream_id(DCC_TO_DC(dcc), stream));
 
     spice_return_if_fail(region_is_empty(&agent->vis_region));
 
@@ -796,7 +797,7 @@ void dcc_create_stream(DisplayChannelClient *dcc, Stream *stream)
         agent->report_id = rand();
         red_pipe_item_init(&report_pipe_item->pipe_item,
                            RED_PIPE_ITEM_TYPE_STREAM_ACTIVATE_REPORT);
-        report_pipe_item->stream_id = get_stream_id(DCC_TO_DC(dcc), stream);
+        report_pipe_item->stream_id = display_channel_get_stream_id(DCC_TO_DC(dcc), stream);
         red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), &report_pipe_item->pipe_item);
     }
 #ifdef STREAM_STATS
@@ -839,7 +840,7 @@ static void dcc_detach_stream_gracefully(DisplayChannelClient *dcc,
                                          Drawable *update_area_limit)
 {
     DisplayChannel *display = DCC_TO_DC(dcc);
-    int stream_id = get_stream_id(display, stream);
+    int stream_id = display_channel_get_stream_id(display, stream);
     StreamAgent *agent = dcc_get_stream_agent(dcc, stream_id);
 
     /* stopping the client from playing older frames at once*/
@@ -924,7 +925,7 @@ static void detach_stream_gracefully(DisplayChannel *display, Stream *stream,
  */
 void stream_detach_behind(DisplayChannel *display, QRegion *region, Drawable *drawable)
 {
-    Ring *ring = &display->streams;
+    Ring *ring = &display->priv->streams;
     RingItem *item = ring_get_head(ring);
     GList *link, *next;
     DisplayChannelClient *dcc;
@@ -936,12 +937,12 @@ void stream_detach_behind(DisplayChannel *display, QRegion *region, Drawable *dr
         item = ring_next(ring, item);
 
         FOREACH_CLIENT(display, link, next, dcc) {
-            StreamAgent *agent = dcc_get_stream_agent(dcc, get_stream_id(display, stream));
+            StreamAgent *agent = dcc_get_stream_agent(dcc, display_channel_get_stream_id(display, stream));
 
             if (region_intersects(&agent->vis_region, region)) {
                 dcc_detach_stream_gracefully(dcc, stream, drawable);
                 detach = 1;
-                spice_debug("stream %d", get_stream_id(display, stream));
+                spice_debug("stream %d", display_channel_get_stream_id(display, stream));
             }
         }
         if (detach && stream->current) {
@@ -960,7 +961,7 @@ void stream_detach_and_stop(DisplayChannel *display)
     RingItem *stream_item;
 
     spice_debug(NULL);
-    while ((stream_item = ring_get_head(&display->streams))) {
+    while ((stream_item = ring_get_head(&display->priv->streams))) {
         Stream *stream = SPICE_CONTAINEROF(stream_item, Stream, link);
 
         detach_stream_gracefully(display, stream, NULL);
@@ -970,7 +971,7 @@ void stream_detach_and_stop(DisplayChannel *display)
 
 void stream_timeout(DisplayChannel *display)
 {
-    Ring *ring = &display->streams;
+    Ring *ring = &display->priv->streams;
     RingItem *item;
 
     red_time_t now = spice_get_monotonic_time_ns();
@@ -993,7 +994,7 @@ void stream_trace_add_drawable(DisplayChannel *display, Drawable *item)
         return;
     }
 
-    trace = &display->items_trace[display->next_item_trace++ & ITEMS_TRACE_MASK];
+    trace = &display->priv->items_trace[display->priv->next_item_trace++ & ITEMS_TRACE_MASK];
     trace->time = item->creation_time;
     trace->first_frame_time = item->first_frame_time;
     trace->frames_count = item->frames_count;
-- 
2.7.4



More information about the Spice-devel mailing list