[Spice-devel] [PATCH v2 2/2] Add DisplayChannelPrivate struct

Jonathon Jongsma jjongsma at redhat.com
Thu Sep 15 20:06:15 UTC 2016


On Thu, 2016-09-15 at 11:22 -0500, Jonathon Jongsma wrote:
> 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.
> ---
>  server/dcc-send.c        |  16 +--
>  server/dcc.c             |  33 ++---
>  server/display-channel.c | 314 ++++++++++++++++++++++++-------------
> ----------
>  server/display-channel.h |  13 +-
>  server/red-worker.c      |   6 +
>  server/stream.c          |  53 ++++----
>  6 files changed, 227 insertions(+), 208 deletions(-)
> 
> diff --git a/server/dcc-send.c b/server/dcc-send.c
> index 0afa25c..0635afa 100644
> --- a/server/dcc-send.c
> +++ b/server/dcc-send.c
> @@ -96,7 +96,7 @@ static int
> is_surface_area_lossy(DisplayChannelClient *dcc, uint32_t surface_id,
>  
>      spice_return_val_if_fail(display_channel_validate_surface(displa
> y, 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 {
> @@ -420,7 +420,7 @@ static FillBitsType
> fill_bits(DisplayChannelClient *dcc, SpiceMarshaller *m,
>              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;
> @@ -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);
> 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"

Forgot to remove this change before sending out the patch, but I've
removed it locally.


>  #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(d
> cc));
> -    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_CHANN
> EL_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 56bb029..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;
> @@ -207,7 +207,7 @@ void display_channel_surface_unref(DisplayChannel
> *display, uint32_t surface_id)
>  bool display_channel_surface_has_canvas(DisplayChannel *display,
>                                          uint32_t surface_id)
>  {
> -    return display->surfaces[surface_id].context.canvas != NULL;
> +    return display->priv->surfaces[surface_id].context.canvas !=
> NULL;
>  }
>  
>  static void streams_update_visible_region(DisplayChannel *display,
> Drawable *drawable)
> @@ -225,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) {
> @@ -301,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++;
>  }
>  
> @@ -318,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)
> @@ -375,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))) {
> @@ -470,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);
> @@ -532,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;
> @@ -575,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;
>              }
>          }
> @@ -584,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;
> @@ -596,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;
> @@ -609,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.
> @@ -633,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;
>  }
>  
> @@ -643,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);
> @@ -665,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;
>              }
>  
> @@ -751,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;
>  }
>  
> @@ -760,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;
>      }
>  
> @@ -780,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;
>  
> @@ -797,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
>  
> @@ -831,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++;
>      }
>  }
> @@ -840,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);
> @@ -858,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;
> @@ -910,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);
> @@ -944,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;
> @@ -965,7 +965,7 @@ static int validate_drawable_bbox(DisplayChannel
> *display, RedDrawable *drawable
>          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;
> @@ -1019,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));
>      /*
> @@ -1069,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);
> @@ -1082,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
>  }
> @@ -1146,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);
>          }
>      }
> @@ -1178,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;
>  
> @@ -1200,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);
> @@ -1212,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);
>  
> @@ -1224,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);
>      }
>  
> @@ -1239,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);
>      }
>  }
>  
> @@ -1360,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)
> @@ -1385,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);
>  
> @@ -1397,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;
> @@ -1406,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;
> @@ -1424,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;
> @@ -1432,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;
> @@ -1445,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;
> @@ -1454,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;
> @@ -1462,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;
> @@ -1470,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;
> @@ -1478,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;
> @@ -1488,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;
> @@ -1498,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;
> @@ -1506,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;
> @@ -1599,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);
> @@ -1644,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)
> @@ -1681,7 +1681,7 @@ void display_channel_update(DisplayChannel
> *display,
>      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);
> @@ -1721,7 +1721,7 @@ void
> display_channel_destroy_surface_wait(DisplayChannel *display,
> uint32_t surf
>  {
>      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);
> @@ -1741,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);
> @@ -1780,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;
> @@ -1796,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);
>  
> @@ -1821,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);
> @@ -1830,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);
> @@ -1859,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)
> @@ -1887,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(display_channel_validate_surface(displa
> y, 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, 
> @@ -1919,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_c
> ache", 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;
> @@ -1957,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: {
> @@ -2001,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)
> @@ -2024,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);
> @@ -2035,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);
> @@ -2043,23 +2045,23 @@ 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->streams_buf);
> +    return (int)(stream - display->priv->streams_buf);
>  }
>  
>  gboolean display_channel_validate_surface(DisplayChannel *display,
> uint32_t surface_id)
>  {
> -    if SPICE_UNLIKELY(surface_id >= display->n_surfaces) {
> +    if SPICE_UNLIKELY(surface_id >= display->priv->n_surfaces) {
>          spice_warning("invalid surface_id %u", surface_id);
>          return 0;
>      }
> -    if (!display->surfaces[surface_id].context.canvas) {
> +    if (!display->priv->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);
> +                   &(display->priv-
> >surfaces[surface_id].context.canvas), surface_id);
>          spice_warning("failed on %d", surface_id);
>          return 0;
>      }
> @@ -2071,29 +2073,29 @@ void
> display_channel_update_monitors_config(DisplayChannel *display,
>                                              uint16_t count, uint16_t
> max_allowed)
>  {
>  
> -    if (display->monitors_config)
> -        monitors_config_unref(display->monitors_config);
> +    if (display->priv->monitors_config)
> +        monitors_config_unref(display->priv->monitors_config);
>  
> -    display->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->surfaces[0].context;
> +    DrawContext *context = &display->priv->surfaces[0].context;
>      QXLHead head = { 0, };
>  
> -    spice_return_if_fail(display->surfaces[0].context.canvas);
> +    spice_return_if_fail(display->priv->surfaces[0].context.canvas);
>  
> -    if (display->monitors_config)
> -        monitors_config_unref(display->monitors_config);
> +    if (display->priv->monitors_config)
> +        monitors_config_unref(display->priv->monitors_config);
>  
>      head.width = context->width;
>      head.height = context->height;
> -    display->monitors_config = monitors_config_new(&head, 1, 1);
> +    display->priv->monitors_config = monitors_config_new(&head, 1,
> 1);
>  }
>  
>  void display_channel_reset_image_cache(DisplayChannel *self)
>  {
> -    image_cache_reset(&self->image_cache);
> +    image_cache_reset(&self->priv->image_cache);
>  }
> diff --git a/server/display-channel.h b/server/display-channel.h
> index 022cd93..ce5d419 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,6 +212,11 @@ struct DisplayChannel {
>      ImageEncoderSharedData encoder_shared_data;
>  };
>  
> +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), \
> diff --git a/server/red-worker.c b/server/red-worker.c
> index 6df6420..92ab59c 100644
> --- a/server/red-worker.c
> +++ b/server/red-worker.c
> @@ -676,7 +676,9 @@ 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_channel_surface_has_canvas(display,
> surface_id));
>  
>      cursor_channel_reset(worker->cursor_channel);
> @@ -771,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);
>      }
> @@ -783,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);
>  }
>  
> diff --git a/server/stream.c b/server/stream.c
> index 8997c10..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)
>  {
> @@ -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;
>      }
> @@ -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) {
> @@ -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;
> @@ -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;


More information about the Spice-devel mailing list