[Spice-devel] [PATCH 5/5] worker: move surfaces to DisplayChannel
Jonathon Jongsma
jjongsma at redhat.com
Wed Nov 11 08:06:30 PST 2015
On Wed, 2015-11-11 at 13:54 +0100, Fabiano FidĂȘncio wrote:
> On Tue, Nov 10, 2015 at 9:41 PM, Jonathon Jongsma <jjongsma at redhat.com> wrote:
> > From: Marc-André Lureau <marcandre.lureau at gmail.com>
> >
> > Ok. this one was painful.Note that in some cases, DCC_TO_DC should be
> > made safer (there used to be a if !dcc guard in some places, although
> > that looks wrong anyway)...
> > ---
> > server/display-channel.c | 79 ++++
> > server/display-channel.h | 37 +-
> > server/red_worker.c | 1121 ++++++++++++++++++++-----------------------
> > ---
> > server/red_worker.h | 2 +
> > 4 files changed, 593 insertions(+), 646 deletions(-)
> >
> > diff --git a/server/display-channel.c b/server/display-channel.c
> > index b5d8830..5f422c9 100644
> > --- a/server/display-channel.c
> > +++ b/server/display-channel.c
> > @@ -305,3 +305,82 @@ void display_channel_set_stream_video(DisplayChannel
> > *display, int stream_video)
> >
> > display->stream_video = stream_video;
> > }
> > +
> > +static void stop_streams(DisplayChannel *display)
> > +{
> > + Ring *ring = &display->streams;
> > + RingItem *item = ring_get_head(ring);
> > +
> > + while (item) {
> > + Stream *stream = SPICE_CONTAINEROF(item, Stream, link);
> > + item = ring_next(ring, item);
> > + if (!stream->current) {
> > + stream_stop(display, stream);
> > + } else {
> > + spice_info("attached stream");
> > + }
> > + }
> > +
> > + display->next_item_trace = 0;
> > + memset(display->items_trace, 0, sizeof(display->items_trace));
> > +}
> > +
> > +void display_channel_surface_unref(DisplayChannel *display, uint32_t
> > surface_id)
> > +{
> > + RedSurface *surface = &display->surfaces[surface_id];
> > + RedWorker *worker = COMMON_CHANNEL(display)->worker;
> > + QXLInstance *qxl = red_worker_get_qxl(worker);
> > + DisplayChannelClient *dcc;
> > + RingItem *link, *next;
> > +
> > + if (--surface->refs != 0) {
> > + return;
> > + }
> > +
> > + // only primary surface streams are supported
> > + if (is_primary_surface(display, surface_id)) {
> > + stop_streams(display);
> > + }
> > + spice_assert(surface->context.canvas);
> > +
> > + surface->context.canvas->ops->destroy(surface->context.canvas);
> > + if (surface->create.info) {
> > + qxl->st->qif->release_resource(qxl, surface->create);
> > + }
> > + if (surface->destroy.info) {
> > + qxl->st->qif->release_resource(qxl, surface->destroy);
> > + }
> > +
> > + region_destroy(&surface->draw_dirty_region);
> > + surface->context.canvas = NULL;
> > + FOREACH_DCC(display, link, next, dcc) {
> > + dcc_push_destroy_surface(dcc, surface_id);
> > + }
> > +
> > + spice_warn_if(!ring_is_empty(&surface->depend_on_me));
> > +}
> > +
> > +void display_channel_show_tree(DisplayChannel *display)
> > +{
> > + int x;
> > +
> > + for (x = 0; x < NUM_SURFACES; ++x) {
> > + if (!display->surfaces[x].context.canvas)
> > + continue;
> > +
> > + RingItem *it;
> > + Ring *ring = &display->surfaces[x].current;
> > + RING_FOREACH(it, ring) {
> > + TreeItem *now = SPICE_CONTAINEROF(it, TreeItem, siblings_link);
> > + tree_item_dump(now);
> > + }
> > +
> > + }
> > +}
> > +
> > +/* TODO: perhaps rename to "ready" or "realized" ? */
> > +bool display_channel_surface_has_canvas(DisplayChannel *display,
> > + uint32_t surface_id)
> > +{
> > + return display->surfaces[surface_id].context.canvas != NULL;
> > +}
> > diff --git a/server/display-channel.h b/server/display-channel.h
> > index 7bb9c14..c7709ad 100644
> > --- a/server/display-channel.h
> > +++ b/server/display-channel.h
> > @@ -204,8 +204,8 @@ struct DisplayChannelClient {
> >
> > #define DCC_TO_WORKER(dcc) \
> > (SPICE_CONTAINEROF((dcc)->common.base.channel, CommonChannel, base)
> > ->worker)
> > -#define DCC_TO_DC(dcc) SPICE_CONTAINEROF((dcc)->common.base.channel, \
> > - DisplayChannel, common.base)
> > +#define DCC_TO_DC(dcc) \
> > + SPICE_CONTAINEROF((dcc)->common.base.channel, DisplayChannel,
> > common.base)
> > #define RCC_TO_DCC(rcc) SPICE_CONTAINEROF((rcc), DisplayChannelClient,
> > common.base)
> >
> >
> > @@ -272,6 +272,30 @@ void monitors_config_unref
> > (MonitorsCo
> > #define NUM_TRACE_ITEMS (1 << TRACE_ITEMS_SHIFT)
> > #define ITEMS_TRACE_MASK (NUM_TRACE_ITEMS - 1)
> >
> > +typedef struct DrawContext {
> > + SpiceCanvas *canvas;
> > + int canvas_draws_on_surface;
> > + int top_down;
> > + uint32_t width;
> > + uint32_t height;
> > + int32_t stride;
> > + uint32_t format;
> > + void *line_0;
> > +} DrawContext;
> > +
> > +typedef struct RedSurface {
> > + uint32_t refs;
> > + Ring current;
> > + Ring current_list;
> > + DrawContext context;
> > +
> > + Ring depend_on_me;
> > + QRegion draw_dirty_region;
> > +
> > + //fix me - better handling here
> > + QXLReleaseInfoExt create, destroy;
> > +} RedSurface;
> > +
> > #define NUM_DRAWABLES 1000
> > typedef struct _Drawable _Drawable;
> > struct _Drawable {
> > @@ -310,6 +334,10 @@ struct DisplayChannel {
> > uint32_t next_item_trace;
> > uint64_t streams_size_total;
> >
> > + RedSurface surfaces[NUM_SURFACES];
> > + uint32_t n_surfaces;
> > + SpiceImageSurfaces image_surfaces;
> > +
> > ImageCache image_cache;
> > RedCompressBuf *free_compress_bufs;
> >
> > @@ -370,6 +398,11 @@ int
> > display_channel_get_streams_timeout (DisplayCha
> > void display_channel_compress_stats_print (const
> > DisplayChannel *display);
> > void display_channel_compress_stats_reset
> > (DisplayChannel *display);
> > void display_channel_drawable_unref
> > (DisplayChannel *display, Drawable *drawable);
> > +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_show_tree
> > (DisplayChannel *display);
> >
> > static inline int is_equal_path(SpicePath *path1, SpicePath *path2)
> > {
> > diff --git a/server/red_worker.c b/server/red_worker.c
> > index 8a2ff0e..2360866 100644
> > --- a/server/red_worker.c
> > +++ b/server/red_worker.c
> > @@ -111,6 +111,8 @@ static void rendering_incorrect(const char *msg)
> >
> > typedef unsigned long stat_time_t;
> >
> > +static stat_time_t stat_now(RedWorker *worker);
> > +
> > #if defined(RED_WORKER_STAT) || defined(COMPRESS_STAT)
> > double stat_cpu_time_to_sec(stat_time_t time)
> > {
> > @@ -299,30 +301,6 @@ struct RedGlzDrawable {
> > pthread_mutex_t glz_dictionary_list_lock = PTHREAD_MUTEX_INITIALIZER;
> > Ring glz_dictionary_list = {&glz_dictionary_list, &glz_dictionary_list};
> >
> > -typedef struct DrawContext {
> > - SpiceCanvas *canvas;
> > - int canvas_draws_on_surface;
> > - int top_down;
> > - uint32_t width;
> > - uint32_t height;
> > - int32_t stride;
> > - uint32_t format;
> > - void *line_0;
> > -} DrawContext;
> > -
> > -typedef struct RedSurface {
> > - uint32_t refs;
> > - Ring current;
> > - Ring current_list;
> > - DrawContext context;
> > -
> > - Ring depend_on_me;
> > - QRegion draw_dirty_region;
> > -
> > - //fix me - better handling here
> > - QXLReleaseInfoExt create, destroy;
> > -} RedSurface;
> > -
> > typedef struct RedWorker {
> > pthread_t thread;
> > clockid_t clockid;
> > @@ -339,10 +317,6 @@ typedef struct RedWorker {
> > CursorChannel *cursor_channel;
> > uint32_t cursor_poll_tries;
> >
> > - RedSurface surfaces[NUM_SURFACES];
> > - uint32_t n_surfaces;
> > - SpiceImageSurfaces image_surfaces;
> > -
> > uint32_t red_drawable_count;
> > uint32_t glz_drawable_count;
> > uint32_t bits_unique;
> > @@ -403,7 +377,7 @@ typedef struct BitmapData {
> > SpiceRect lossy_rect;
> > } BitmapData;
> >
> > -static inline int validate_surface(RedWorker *worker, uint32_t surface_id);
> > +static inline int validate_surface(DisplayChannel *display, uint32_t
> > surface_id);
> >
> > static stat_time_t stat_now(RedWorker *worker)
> > {
> > @@ -414,11 +388,11 @@ static stat_time_t stat_now(RedWorker *worker)
> > return ts.tv_nsec + ts.tv_sec * 1000 * 1000 * 1000;
> > }
> >
> > -static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable);
> > -static void red_current_flush(RedWorker *worker, int surface_id);
> > -static void red_draw_drawable(RedWorker *worker, Drawable *item);
> > -static void red_update_area(RedWorker *worker, const SpiceRect *area, int
> > surface_id);
> > -static void red_update_area_till(RedWorker *worker, const SpiceRect *area,
> > int surface_id,
> > +static void red_draw_qxl_drawable(DisplayChannel *display, Drawable
> > *drawable);
> > +static void red_current_flush(DisplayChannel *display, int surface_id);
> > +static void red_draw_drawable(DisplayChannel *display, Drawable *item);
> > +static void red_update_area(DisplayChannel *display, const SpiceRect *area,
> > int surface_id);
> > +static void red_update_area_till(DisplayChannel *display, const SpiceRect
> > *area, int surface_id,
> > Drawable *last);
> > static void detach_stream(DisplayChannel *display, Stream *stream, int
> > detach_sized);
> > static inline void display_channel_stream_maintenance(DisplayChannel
> > *display, Drawable *candidate, Drawable *sect);
> > @@ -435,6 +409,9 @@ static void
> > display_channel_client_release_item_before_push(DisplayChannelClient
> > PipeItem
> > *item);
> > static void
> > display_channel_client_release_item_after_push(DisplayChannelClient *dcc,
> > PipeItem *item);
> > +static void red_create_surface(DisplayChannel *display, uint32_t
> > surface_id, uint32_t width,
> > + uint32_t height, int32_t stride, uint32_t
> > format,
> > + void *line_0, int data_is_valid, int
> > send_client);
> >
> > #define LINK_TO_DPI(ptr) SPICE_CONTAINEROF((ptr), DrawablePipeItem, base)
> > #define DRAWABLE_FOREACH_DPI_SAFE(drawable, link, next, dpi) \
> > @@ -570,8 +547,8 @@ static int validate_drawable_bbox(RedWorker *worker,
> > RedDrawable *drawable)
> > /* surface_id must be validated before calling into
> > * validate_drawable_bbox
> > */
> > - VALIDATE_SURFACE_RETVAL(worker, surface_id, FALSE);
> > - context = &worker->surfaces[surface_id].context;
> > + VALIDATE_SURFACE_RETVAL(worker->display_channel, surface_id,
> > FALSE);
> > + context = &worker->display_channel->surfaces[surface_id].context;
> >
> > if (drawable->bbox.top < 0)
> > return FALSE;
> > @@ -589,15 +566,15 @@ static int validate_drawable_bbox(RedWorker *worker,
> > RedDrawable *drawable)
> > return TRUE;
> > }
> >
> > -static inline int validate_surface(RedWorker *worker, uint32_t surface_id)
> > +static inline int validate_surface(DisplayChannel *display, uint32_t
> > surface_id)
> > {
> > - if SPICE_UNLIKELY(surface_id >= worker->n_surfaces) {
> > + if SPICE_UNLIKELY(surface_id >= display->n_surfaces) {
> > spice_warning("invalid surface_id %u", surface_id);
> > return 0;
> > }
> > - if (!worker->surfaces[surface_id].context.canvas) {
> > + if (!display->surfaces[surface_id].context.canvas) {
> > spice_warning("canvas address is %p for %d (and is NULL)\n",
> > - &(worker->surfaces[surface_id].context.canvas),
> > surface_id);
> > + &(display->surfaces[surface_id].context.canvas),
> > surface_id);
> > spice_warning("failed on %d", surface_id);
> > return 0;
> > }
> > @@ -610,7 +587,7 @@ static void red_push_surface_image(DisplayChannelClient
> > *dcc, int surface_id);
> > static inline void red_handle_drawable_surfaces_client_synced(
> > DisplayChannelClient *dcc, Drawable *drawable)
> > {
> > - RedWorker *worker = DCC_TO_WORKER(dcc);
> > + DisplayChannel *display = DCC_TO_DC(dcc);
> > int x;
> >
> > for (x = 0; x < 3; ++x) {
> > @@ -622,7 +599,7 @@ static inline void
> > red_handle_drawable_surfaces_client_synced(
> > continue;
> > }
> > red_create_surface_item(dcc, surface_id);
> > - red_current_flush(worker, surface_id);
> > + red_current_flush(display, surface_id);
> > red_push_surface_image(dcc, surface_id);
> > }
> > }
> > @@ -632,7 +609,7 @@ static inline void
> > red_handle_drawable_surfaces_client_synced(
> > }
> >
> > red_create_surface_item(dcc, drawable->surface_id);
> > - red_current_flush(worker, drawable->surface_id);
> > + red_current_flush(display, drawable->surface_id);
> > red_push_surface_image(dcc, drawable->surface_id);
> > }
> >
> > @@ -657,13 +634,13 @@ static void dcc_add_drawable(DisplayChannelClient
> > *dcc, Drawable *drawable)
> > red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), &dpi
> > ->dpi_pipe_item);
> > }
> >
> > -static void red_pipes_add_drawable(RedWorker *worker, Drawable *drawable)
> > +static void red_pipes_add_drawable(DisplayChannel *display, Drawable
> > *drawable)
> > {
> > DisplayChannelClient *dcc;
> > RingItem *dcc_ring_item, *next;
> >
> > spice_warn_if(!ring_is_empty(&drawable->pipes));
> > - FOREACH_DCC(worker->display_channel, dcc_ring_item, next, dcc) {
> > + FOREACH_DCC(display, dcc_ring_item, next, dcc) {
> > dcc_add_drawable(dcc, drawable);
> > }
> > }
> > @@ -680,7 +657,7 @@ static void
> > dcc_add_drawable_to_tail(DisplayChannelClient *dcc, Drawable *drawab
> > red_channel_client_pipe_add_tail(RED_CHANNEL_CLIENT(dcc), &dpi
> > ->dpi_pipe_item);
> > }
> >
> > -static inline void red_pipes_add_drawable_after(RedWorker *worker,
> > +static inline void red_pipes_add_drawable_after(DisplayChannel *display,
> > Drawable *drawable,
> > Drawable *pos_after)
> > {
> > DrawablePipeItem *dpi, *dpi_pos_after;
> > @@ -697,13 +674,13 @@ static inline void
> > red_pipes_add_drawable_after(RedWorker *worker,
> > &dpi_pos_after->dpi_pipe_item);
> > }
> > if (num_other_linked == 0) {
> > - red_pipes_add_drawable(worker, drawable);
> > + red_pipes_add_drawable(display, drawable);
> > return;
> > }
> > - if (num_other_linked != worker->display_channel
> > ->common.base.clients_num) {
> > - RingItem *worker_item, *next;
> > + if (num_other_linked != display->common.base.clients_num) {
> > + RingItem *item, *next;
> > spice_debug("TODO: not O(n^2)");
> > - FOREACH_DCC(worker->display_channel, worker_item, next, dcc) {
> > + FOREACH_DCC(display, item, next, dcc) {
> > int sent = 0;
> > DRAWABLE_FOREACH_DPI_SAFE(pos_after, dpi_link, dpi_next,
> > dpi_pos_after) {
> > if (dpi_pos_after->dcc == dcc) {
> > @@ -727,8 +704,6 @@ static inline PipeItem
> > *red_pipe_get_tail(DisplayChannelClient *dcc)
> > return (PipeItem*)ring_get_tail(&RED_CHANNEL_CLIENT(dcc)->pipe);
> > }
> >
> > -static void red_surface_unref(RedWorker *worker, uint32_t surface_id);
> > -
> > static inline void red_pipes_remove_drawable(Drawable *drawable)
> > {
> > DrawablePipeItem *dpi;
> > @@ -843,59 +818,6 @@ static void drawables_init(DisplayChannel *display)
> > }
> >
> >
> > -static void stop_streams(DisplayChannel *display)
> > -{
> > - Ring *ring = &display->streams;
> > - RingItem *item = ring_get_head(ring);
> > -
> > - while (item) {
> > - Stream *stream = SPICE_CONTAINEROF(item, Stream, link);
> > - item = ring_next(ring, item);
> > - if (!stream->current) {
> > - stream_stop(display, stream);
> > - } else {
> > - spice_info("attached stream");
> > - }
> > - }
> > -
> > - display->next_item_trace = 0;
> > - memset(display->items_trace, 0, sizeof(display->items_trace));
> > -}
> > -
> > -static void red_surface_unref(RedWorker *worker, uint32_t surface_id)
> > -{
> > - DisplayChannel *display = worker->display_channel;
> > - RedSurface *surface = &worker->surfaces[surface_id];
> > - DisplayChannelClient *dcc;
> > - RingItem *link, *next;
> > -
> > - if (--surface->refs != 0) {
> > - return;
> > - }
> > -
> > - // only primary surface streams are supported
> > - if (is_primary_surface(worker->display_channel, surface_id)) {
> > - stop_streams(display);
> > - }
> > - spice_assert(surface->context.canvas);
> > -
> > - surface->context.canvas->ops->destroy(surface->context.canvas);
> > - if (surface->create.info) {
> > - worker->qxl->st->qif->release_resource(worker->qxl, surface
> > ->create);
> > - }
> > - if (surface->destroy.info) {
> > - worker->qxl->st->qif->release_resource(worker->qxl, surface
> > ->destroy);
> > - }
> > -
> > - region_destroy(&surface->draw_dirty_region);
> > - surface->context.canvas = NULL;
> > - FOREACH_DCC(worker->display_channel, link, next, dcc) {
> > - dcc_push_destroy_surface(dcc, surface_id);
> > - }
> > -
> > - spice_warn_if(!ring_is_empty(&surface->depend_on_me));
> > -}
> > -
> > static inline void set_surface_release_info(QXLReleaseInfoExt
> > *release_info_ext,
> > QXLReleaseInfo *release_info,
> > uint32_t group_id)
> > {
> > @@ -944,7 +866,7 @@ static void drawable_unref_surface_deps(DisplayChannel
> > *display, Drawable *drawa
> > if (surface_id == -1) {
> > continue;
> > }
> > - red_surface_unref(COMMON_CHANNEL(display)->worker, surface_id);
> > + display_channel_surface_unref(display, surface_id);
> > }
> > }
> >
> > @@ -978,7 +900,7 @@ void display_channel_drawable_unref(DisplayChannel
> > *display, Drawable *drawable)
> >
> > drawable_remove_dependencies(display, drawable);
> > drawable_unref_surface_deps(display, drawable);
> > - red_surface_unref(COMMON_CHANNEL(display)->worker, drawable
> > ->surface_id);
> > + display_channel_surface_unref(display, drawable->surface_id);
> >
> > RING_FOREACH_SAFE(item, next, &drawable->glz_ring) {
> > SPICE_CONTAINEROF(item, RedGlzDrawable, drawable_link)->drawable =
> > NULL;
> > @@ -1004,7 +926,7 @@ static inline void remove_shadow(DrawItem *item)
> > free(shadow);
> > }
> >
> > -static inline void current_remove_container(RedWorker *worker, Container
> > *container)
> > +static inline void current_remove_container(DisplayChannel *display,
> > Container *container)
> > {
> > spice_assert(ring_is_empty(&container->items));
> > ring_remove(&container->base.siblings_link);
> > @@ -1012,7 +934,7 @@ static inline void current_remove_container(RedWorker
> > *worker, Container *contai
> > free(container);
> > }
> >
> > -static inline void container_cleanup(RedWorker *worker, Container
> > *container)
> > +static inline void container_cleanup(DisplayChannel *display, Container
> > *container)
> > {
> > while (container && container->items.next == container->items.prev) {
> > Container *next = container->base.container;
> > @@ -1023,7 +945,7 @@ static inline void container_cleanup(RedWorker *worker,
> > Container *container)
> > ring_add_after(&item->siblings_link, &container
> > ->base.siblings_link);
> > item->container = container->base.container;
> > }
> > - current_remove_container(worker, container);
> > + current_remove_container(display, container);
> > container = next;
> > }
> > }
> > @@ -1047,12 +969,12 @@ static void
> > display_stream_trace_add_drawable(DisplayChannel *display, Drawable
> > trace->dest_area = item->red_drawable->bbox;
> > }
> >
> > -static void surface_flush(RedWorker *worker, int surface_id, SpiceRect
> > *rect)
> > +static void surface_flush(DisplayChannel *display, int surface_id,
> > SpiceRect *rect)
> > {
> > - red_update_area(worker, rect, surface_id);
> > + red_update_area(display, rect, surface_id);
> > }
> >
> > -static void red_flush_source_surfaces(RedWorker *worker, Drawable
> > *drawable)
> > +static void red_flush_source_surfaces(DisplayChannel *display, Drawable
> > *drawable)
> > {
> > int x;
> > int surface_id;
> > @@ -1061,15 +983,13 @@ static void red_flush_source_surfaces(RedWorker
> > *worker, Drawable *drawable)
> > surface_id = drawable->surface_deps[x];
> > if (surface_id != -1 && drawable->depend_items[x].drawable) {
> > remove_depended_item(&drawable->depend_items[x]);
> > - surface_flush(worker, surface_id, &drawable->red_drawable
> > ->surfaces_rects[x]);
> > + surface_flush(display, surface_id, &drawable->red_drawable
> > ->surfaces_rects[x]);
> > }
> > }
> > }
> >
> > -static inline void current_remove_drawable(RedWorker *worker, Drawable
> > *item)
> > +static inline void current_remove_drawable(DisplayChannel *display,
> > Drawable *item)
> > {
> > - DisplayChannel *display = worker->display_channel;
> > -
> > display_stream_trace_add_drawable(display, item);
> > remove_shadow(&item->tree_item);
> > ring_remove(&item->tree_item.base.siblings_link);
> > @@ -1079,23 +999,24 @@ static inline void current_remove_drawable(RedWorker
> > *worker, Drawable *item)
> > display->current_size--;
> > }
> >
> > -static void remove_drawable(RedWorker *worker, Drawable *drawable)
> > +static void remove_drawable(DisplayChannel *display, Drawable *drawable)
> > {
> > red_pipes_remove_drawable(drawable);
> > - current_remove_drawable(worker, drawable);
> > + current_remove_drawable(display, drawable);
> > }
> >
> > -static inline void current_remove(RedWorker *worker, TreeItem *item)
> > +static inline void current_remove(DisplayChannel *display, TreeItem *item)
> > {
> > TreeItem *now = item;
> >
> > + /* depth-first tree traversal, todo: do a to tree_foreach()? */
> > for (;;) {
> > Container *container = now->container;
> > RingItem *ring_item;
> >
> > if (now->type == TREE_ITEM_TYPE_DRAWABLE) {
> > ring_item = now->siblings_link.prev;
> > - remove_drawable(worker, SPICE_CONTAINEROF(now, Drawable,
> > tree_item));
> > + remove_drawable(display, SPICE_CONTAINEROF(now, Drawable,
> > tree_item));
> > } else {
> > Container *container = (Container *)now;
> >
> > @@ -1106,7 +1027,7 @@ static inline void current_remove(RedWorker *worker,
> > TreeItem *item)
> > continue;
> > }
> > ring_item = now->siblings_link.prev;
> > - current_remove_container(worker, container);
> > + current_remove_container(display, container);
> > }
> > if (now == item) {
> > return;
> > @@ -1120,13 +1041,14 @@ static inline void current_remove(RedWorker *worker,
> > TreeItem *item)
> > }
> > }
> >
> > -static void red_current_clear(RedWorker *worker, int surface_id)
> > +static void current_clear(DisplayChannel *display, int surface_id)
> > {
> > + Ring *ring = &display->surfaces[surface_id].current;
> > RingItem *ring_item;
> >
> > - while ((ring_item = ring_get_head(&worker
> > ->surfaces[surface_id].current))) {
> > + while ((ring_item = ring_get_head(ring))) {
> > TreeItem *now = SPICE_CONTAINEROF(ring_item, TreeItem,
> > siblings_link);
> > - current_remove(worker, now);
> > + current_remove(display, now);
> > }
> > }
> >
> > @@ -1211,14 +1133,14 @@ static int
> > red_clear_surface_drawables_from_pipe(DisplayChannelClient *dcc, int
> > return TRUE;
> > }
> >
> > -static void red_clear_surface_drawables_from_pipes(RedWorker *worker,
> > +static void red_clear_surface_drawables_from_pipes(DisplayChannel *display,
> > int surface_id,
> > int wait_if_used)
> > {
> > RingItem *item, *next;
> > DisplayChannelClient *dcc;
> >
> > - FOREACH_DCC(worker->display_channel, item, next, dcc) {
> > + FOREACH_DCC(display, item, next, dcc) {
> > if (!red_clear_surface_drawables_from_pipe(dcc, surface_id,
> > wait_if_used)) {
> > red_channel_client_disconnect(RED_CHANNEL_CLIENT(dcc));
> > }
> > @@ -1258,8 +1180,8 @@ static inline int __contained_by(TreeItem *item, Ring
> > *ring)
> > return FALSE;
> > }
> >
> > -static inline void __exclude_region(RedWorker *worker, Ring *ring, TreeItem
> > *item, QRegion *rgn,
> > - Ring **top_ring, Drawable
> > *frame_candidate)
> > +static void __exclude_region(DisplayChannel *display, Ring *ring, TreeItem
> > *item, QRegion *rgn,
> > + Ring **top_ring, Drawable *frame_candidate)
> > {
> > QRegion and_rgn;
> > #ifdef RED_WORKER_STAT
> > @@ -1298,7 +1220,7 @@ static inline void __exclude_region(RedWorker *worker,
> > Ring *ring, TreeItem *ite
> > } else {
> > if (frame_candidate) {
> > Drawable *drawable = SPICE_CONTAINEROF(draw, Drawable,
> > tree_item);
> > - display_channel_stream_maintenance(worker
> > ->display_channel, frame_candidate, drawable);
> > + display_channel_stream_maintenance(display,
> > frame_candidate, drawable);
> > }
> > region_exclude(&draw->base.rgn, &and_rgn);
> > }
> > @@ -1329,8 +1251,8 @@ static inline void __exclude_region(RedWorker *worker,
> > Ring *ring, TreeItem *ite
> > stat_add(&worker->__exclude_stat, start_time);
> > }
> >
> > -static void exclude_region(RedWorker *worker, Ring *ring, RingItem
> > *ring_item, QRegion *rgn,
> > - TreeItem **last, Drawable *frame_candidate)
> > +static void exclude_region(DisplayChannel *display, Ring *ring, RingItem
> > *ring_item,
> > + QRegion *rgn, TreeItem **last, Drawable
> > *frame_candidate)
> > {
> > #ifdef RED_WORKER_STAT
> > stat_time_t start_time = stat_now(worker);
> > @@ -1350,12 +1272,12 @@ static void exclude_region(RedWorker *worker, Ring
> > *ring, RingItem *ring_item, Q
> > spice_assert(!region_is_empty(&now->rgn));
> >
> > if (region_intersects(rgn, &now->rgn)) {
> > - __exclude_region(worker, ring, now, rgn, &top_ring,
> > frame_candidate);
> > + __exclude_region(display, ring, now, rgn, &top_ring,
> > frame_candidate);
> >
> > if (region_is_empty(&now->rgn)) {
> > spice_assert(now->type != TREE_ITEM_TYPE_SHADOW);
> > ring_item = now->siblings_link.prev;
> > - current_remove(worker, now);
> > + current_remove(display, now);
> > if (last && *last == now) {
> > *last = (TreeItem *)ring_next(ring, ring_item);
> > }
> > @@ -1388,13 +1310,13 @@ static void exclude_region(RedWorker *worker, Ring
> > *ring, RingItem *ring_item, Q
> > }
> > }
> >
> > -static inline void __current_add_drawable(RedWorker *worker, Drawable
> > *drawable, RingItem *pos)
> > +static void __current_add_drawable(DisplayChannel *display,
> > + Drawable *drawable, RingItem *pos)
> > {
> > - DisplayChannel *display = worker->display_channel;
> > RedSurface *surface;
> > uint32_t surface_id = drawable->surface_id;
> >
> > - surface = &worker->surfaces[surface_id];
> > + surface = &display->surfaces[surface_id];
> > ring_add_after(&drawable->tree_item.base.siblings_link, pos);
> > ring_add(&display->current_list, &drawable->list_link);
> > ring_add(&surface->current_list, &drawable->surface_list_link);
> > @@ -1490,9 +1412,9 @@ static void
> > dcc_detach_stream_gracefully(DisplayChannelClient *dcc,
> > stream_id, stream->current != NULL);
> > rect_debug(&upgrade_area);
> > if (update_area_limit) {
> > - red_update_area_till(DCC_TO_WORKER(dcc), &upgrade_area, 0,
> > update_area_limit);
> > + red_update_area_till(DCC_TO_DC(dcc), &upgrade_area, 0,
> > update_area_limit);
> > } else {
> > - red_update_area(DCC_TO_WORKER(dcc), &upgrade_area, 0);
> > + red_update_area(DCC_TO_DC(dcc), &upgrade_area, 0);
> > }
> > red_add_surface_area_image(dcc, 0, &upgrade_area, NULL, FALSE);
> > }
> > @@ -2148,9 +2070,8 @@ static inline int
> > is_drawable_independent_from_surfaces(Drawable *drawable)
> > return TRUE;
> > }
> >
> > -static inline int red_current_add_equal(RedWorker *worker, DrawItem *item,
> > TreeItem *other)
> > +static inline int red_current_add_equal(DisplayChannel *display, DrawItem
> > *item, TreeItem *other)
> > {
> > - DisplayChannel *display = worker->display_channel;
> > DrawItem *other_draw_item;
> > Drawable *drawable;
> > Drawable *other_drawable;
> > @@ -2170,14 +2091,14 @@ static inline int red_current_add_equal(RedWorker
> > *worker, DrawItem *item, TreeI
> > if (item->effect == QXL_EFFECT_OPAQUE) {
> > int add_after = !!other_drawable->stream &&
> > is_drawable_independent_from_surfaces(drawable);
> > - display_channel_stream_maintenance(worker->display_channel,
> > drawable, other_drawable);
> > - __current_add_drawable(worker, drawable, &other->siblings_link);
> > + display_channel_stream_maintenance(display, drawable,
> > other_drawable);
> > + __current_add_drawable(display, drawable, &other->siblings_link);
> > other_drawable->refs++;
> > - current_remove_drawable(worker, other_drawable);
> > + current_remove_drawable(display, other_drawable);
> > if (add_after) {
> > - red_pipes_add_drawable_after(worker, drawable, other_drawable);
> > + red_pipes_add_drawable_after(display, drawable,
> > other_drawable);
> > } else {
> > - red_pipes_add_drawable(worker, drawable);
> > + red_pipes_add_drawable(display, drawable);
> > }
> > red_pipes_remove_drawable(other_drawable);
> > display_channel_drawable_unref(display, other_drawable);
> > @@ -2193,11 +2114,11 @@ static inline int red_current_add_equal(RedWorker
> > *worker, DrawItem *item, TreeI
> > RingItem *worker_ring_item, *dpi_ring_item;
> >
> > other_drawable->refs++;
> > - current_remove_drawable(worker, other_drawable);
> > + current_remove_drawable(display, other_drawable);
> >
> > /* sending the drawable to clients that already received
> > * (or will receive) other_drawable */
> > - worker_ring_item = ring_get_head(&RED_CHANNEL(worker
> > ->display_channel)->clients);
> > + worker_ring_item = ring_get_head(&RED_CHANNEL(display)
> > ->clients);
> > dpi_ring_item = ring_get_head(&other_drawable->pipes);
> > /* dpi contains a sublist of dcc's, ordered the same */
> > while (worker_ring_item) {
> > @@ -2206,7 +2127,7 @@ static inline int red_current_add_equal(RedWorker
> > *worker, DrawItem *item, TreeI
> > dpi = SPICE_CONTAINEROF(dpi_ring_item, DrawablePipeItem,
> > base);
> > while (worker_ring_item && (!dpi || dcc != dpi->dcc)) {
> > dcc_add_drawable(dcc, drawable);
> > - worker_ring_item = ring_next(&RED_CHANNEL(worker
> > ->display_channel)->clients,
> > + worker_ring_item = ring_next(&RED_CHANNEL(display)
> > ->clients,
> > worker_ring_item);
> > dcc = SPICE_CONTAINEROF(worker_ring_item,
> > DisplayChannelClient,
> > common.base.channel_link);
> > @@ -2216,7 +2137,7 @@ static inline int red_current_add_equal(RedWorker
> > *worker, DrawItem *item, TreeI
> > dpi_ring_item = ring_next(&other_drawable->pipes,
> > dpi_ring_item);
> > }
> > if (worker_ring_item) {
> > - worker_ring_item = ring_next(&RED_CHANNEL(worker
> > ->display_channel)->clients,
> > + worker_ring_item = ring_next(&RED_CHANNEL(display)
> > ->clients,
> > worker_ring_item);
> > }
> > }
> > @@ -2229,9 +2150,9 @@ static inline int red_current_add_equal(RedWorker
> > *worker, DrawItem *item, TreeI
> > break;
> > case QXL_EFFECT_OPAQUE_BRUSH:
> > if (is_same_geometry(drawable, other_drawable)) {
> > - __current_add_drawable(worker, drawable, &other
> > ->siblings_link);
> > - remove_drawable(worker, other_drawable);
> > - red_pipes_add_drawable(worker, drawable);
> > + __current_add_drawable(display, drawable, &other
> > ->siblings_link);
> > + remove_drawable(display, other_drawable);
> > + red_pipes_add_drawable(display, drawable);
> > return TRUE;
> > }
> > break;
> > @@ -2299,7 +2220,7 @@ static void red_use_stream_trace(DisplayChannel
> > *display, Drawable *drawable)
> > }
> > }
> >
> > -static inline int red_current_add(RedWorker *worker, Ring *ring, Drawable
> > *drawable)
> > +static inline int red_current_add(DisplayChannel *display, Ring *ring,
> > Drawable *drawable)
> > {
> > DrawItem *item = &drawable->tree_item;
> > #ifdef RED_WORKER_STAT
> > @@ -2328,7 +2249,7 @@ static inline int red_current_add(RedWorker *worker,
> > Ring *ring, Drawable *drawa
> > } else if (sibling->type != TREE_ITEM_TYPE_SHADOW) {
> > if (!(test_res & REGION_TEST_RIGHT_EXCLUSIVE) &&
> > !(test_res &
> > REGION_TEST_LEFT_EXCLUSIVE) &&
> > -
> > red_current_add_equal(worker, item, sibling)) {
> > +
> > red_current_add_equal(display, item, sibling)) {
> > stat_add(&worker->add_stat, start_time);
> > return FALSE;
> > }
> > @@ -2340,7 +2261,7 @@ static inline int red_current_add(RedWorker *worker,
> > Ring *ring, Drawable *drawa
> > if ((shadow = __find_shadow(sibling))) {
> > if (exclude_base) {
> > TreeItem *next = sibling;
> > - exclude_region(worker, ring, exclude_base,
> > &exclude_rgn, &next, NULL);
> > + exclude_region(display, ring, exclude_base,
> > &exclude_rgn, &next, NULL);
> > if (next != sibling) {
> > now = next ? &next->siblings_link : NULL;
> > exclude_base = NULL;
> > @@ -2350,7 +2271,7 @@ static inline int red_current_add(RedWorker *worker,
> > Ring *ring, Drawable *drawa
> > region_or(&exclude_rgn, &shadow->on_hold);
> > }
> > now = now->prev;
> > - current_remove(worker, sibling);
> > + current_remove(display, sibling);
> > now = ring_next(ring, now);
> > if (shadow || skip) {
> > exclude_base = now;
> > @@ -2362,7 +2283,7 @@ static inline int red_current_add(RedWorker *worker,
> > Ring *ring, Drawable *drawa
> > Container *container;
> >
> > if (exclude_base) {
> > - exclude_region(worker, ring, exclude_base,
> > &exclude_rgn, NULL, NULL);
> > + exclude_region(display, ring, exclude_base,
> > &exclude_rgn, NULL, NULL);
> > region_clear(&exclude_rgn);
> > exclude_base = NULL;
> > }
> > @@ -2393,24 +2314,24 @@ static inline int red_current_add(RedWorker *worker,
> > Ring *ring, Drawable *drawa
> > }
> > if (item->effect == QXL_EFFECT_OPAQUE) {
> > region_or(&exclude_rgn, &item->base.rgn);
> > - exclude_region(worker, ring, exclude_base, &exclude_rgn, NULL,
> > drawable);
> > - red_use_stream_trace(worker->display_channel, drawable);
> > - streams_update_visible_region(worker->display_channel, drawable);
> > + exclude_region(display, ring, exclude_base, &exclude_rgn, NULL,
> > drawable);
> > + red_use_stream_trace(display, drawable);
> > + streams_update_visible_region(display, drawable);
> > /*
> > * Performing the insertion after exclude_region for
> > * safety (todo: Not sure if exclude_region can affect the drawable
> > * if it is added to the tree before calling exclude_region).
> > */
> > - __current_add_drawable(worker, drawable, ring);
> > + __current_add_drawable(display, drawable, ring);
> > } else {
> > /*
> > * red_detach_streams_behind can affect the current tree since it
> > may
> > * trigger calls to update_area. Thus, the drawable should be added
> > to the tree
> > * before calling red_detach_streams_behind
> > */
> > - __current_add_drawable(worker, drawable, ring);
> > - if (is_primary_surface(worker->display_channel, drawable
> > ->surface_id)) {
> > - detach_streams_behind(worker->display_channel, &drawable
> > ->tree_item.base.rgn, drawable);
> > + __current_add_drawable(display, drawable, ring);
> > + if (is_primary_surface(display, drawable->surface_id)) {
> > + detach_streams_behind(display, &drawable->tree_item.base.rgn,
> > drawable);
> > }
> > }
> > region_destroy(&exclude_rgn);
> > @@ -2427,9 +2348,8 @@ static void add_clip_rects(QRegion *rgn,
> > SpiceClipRects *data)
> > }
> > }
> >
> > -static inline int red_current_add_with_shadow(RedWorker *worker, Ring
> > *ring, Drawable *item)
> > +static int red_current_add_with_shadow(DisplayChannel *display, Ring *ring,
> > Drawable *item)
> > {
> > - DisplayChannel *display = worker->display_channel;
> > #ifdef RED_WORKER_STAT
> > stat_time_t start_time = stat_now(worker);
> > ++worker->add_with_shadow_count;
> > @@ -2455,11 +2375,11 @@ static inline int
> > red_current_add_with_shadow(RedWorker *worker, Ring *ring, Dra
> > }
> >
> > ring_add(ring, &shadow->base.siblings_link);
> > - __current_add_drawable(worker, item, ring);
> > + __current_add_drawable(display, item, ring);
> > if (item->tree_item.effect == QXL_EFFECT_OPAQUE) {
> > QRegion exclude_rgn;
> > region_clone(&exclude_rgn, &item->tree_item.base.rgn);
> > - exclude_region(worker, ring, &shadow->base.siblings_link,
> > &exclude_rgn, NULL, NULL);
> > + exclude_region(display, ring, &shadow->base.siblings_link,
> > &exclude_rgn, NULL, NULL);
> > region_destroy(&exclude_rgn);
> > streams_update_visible_region(display, item);
> > } else {
> > @@ -2515,7 +2435,7 @@ static void drawable_update_streamable(DisplayChannel
> > *display, Drawable *drawab
> > drawable->streamable = TRUE;
> > }
> >
> > -static void red_print_stats(RedWorker *worker)
> > +void red_worker_print_stats(RedWorker *worker)
> > {
> > #ifdef RED_WORKER_STAT
> > if ((++worker->add_count % 100) == 0) {
> > @@ -2543,33 +2463,32 @@ static void red_print_stats(RedWorker *worker)
> > #endif
> > }
> >
> > -static int red_add_drawable(RedWorker *worker, Drawable *drawable)
> > + static int red_add_drawable(DisplayChannel *display, Drawable *drawable)
> > {
> > - DisplayChannel *display = worker->display_channel;
> > int ret = FALSE, surface_id = drawable->surface_id;
> > RedDrawable *red_drawable = drawable->red_drawable;
> > - Ring *ring = &worker->surfaces[surface_id].current;
> > + Ring *ring = &display->surfaces[surface_id].current;
> >
> > if (has_shadow(red_drawable)) {
> > - ret = red_current_add_with_shadow(worker, ring, drawable);
> > + ret = red_current_add_with_shadow(display, ring, drawable);
> > } else {
> > drawable_update_streamable(display, drawable);
> > - ret = red_current_add(worker, ring, drawable);
> > + ret = red_current_add(display, ring, drawable);
> > }
> >
> > - red_print_stats(worker);
> > + red_worker_print_stats(COMMON_CHANNEL(display)->worker);
> > return ret;
> > }
> >
> > -static void red_get_area(RedWorker *worker, int surface_id, const SpiceRect
> > *area, uint8_t *dest,
> > - int dest_stride, int update)
> > +static void red_get_area(DisplayChannel *display, int surface_id, const
> > SpiceRect *area,
> > + uint8_t *dest, int dest_stride, int update)
> > {
> > SpiceCanvas *canvas;
> > RedSurface *surface;
> >
> > - surface = &worker->surfaces[surface_id];
> > + surface = &display->surfaces[surface_id];
> > if (update) {
> > - red_update_area(worker, area, surface_id);
> > + red_update_area(display, area, surface_id);
> > }
> >
> > canvas = surface->context.canvas;
> > @@ -2621,7 +2540,7 @@ static inline int red_handle_self_bitmap(RedWorker
> > *worker, Drawable *drawable)
> > return TRUE;
> > }
> >
> > - surface = &worker->surfaces[drawable->surface_id];
> > + surface = &display->surfaces[drawable->surface_id];
> >
> > bpp = SPICE_SURFACE_FMT_DEPTH(surface->context.format) / 8;
> >
> > @@ -2647,7 +2566,7 @@ static inline int red_handle_self_bitmap(RedWorker
> > *worker, Drawable *drawable)
> > image->u.bitmap.data = spice_chunks_new_linear(dest, height *
> > dest_stride);
> > image->u.bitmap.data->flags |= SPICE_CHUNKS_FLAGS_FREE;
> >
> > - red_get_area(worker, drawable->surface_id,
> > + red_get_area(display, drawable->surface_id,
> > &red_drawable->self_bitmap_area, dest, dest_stride, TRUE);
> >
> > /* For 32bit non-primary surfaces we need to keep any non-zero
> > @@ -2666,9 +2585,8 @@ static inline int red_handle_self_bitmap(RedWorker
> > *worker, Drawable *drawable)
> > return TRUE;
> > }
> >
> > -static bool free_one_drawable(RedWorker *worker, int force_glz_free)
> > +static bool free_one_drawable(DisplayChannel *display, int force_glz_free)
> > {
> > - DisplayChannel *display = worker->display_channel;
> > RingItem *ring_item = ring_get_tail(&display->current_list);
> > Drawable *drawable;
> > Container *container;
> > @@ -2684,12 +2602,11 @@ static bool free_one_drawable(RedWorker *worker, int
> > force_glz_free)
> > red_display_free_glz_drawable(glz->dcc, glz);
> > }
> > }
> > - red_draw_drawable(worker, drawable);
> > + red_draw_drawable(display, drawable);
> > container = drawable->tree_item.base.container;
> >
> > - current_remove_drawable(worker, drawable);
> > - container_cleanup(worker, container);
> > -
> > + current_remove_drawable(display, drawable);
> > + container_cleanup(display, container);
> > return TRUE;
> > }
> >
> > @@ -2700,19 +2617,19 @@ static Drawable *get_drawable(RedWorker *worker,
> > uint8_t effect, RedDrawable *re
> > Drawable *drawable;
> > int x;
> >
> > - VALIDATE_SURFACE_RETVAL(worker, red_drawable->surface_id, NULL)
> > + VALIDATE_SURFACE_RETVAL(display, red_drawable->surface_id, NULL)
> > if (!validate_drawable_bbox(worker, red_drawable)) {
> > rendering_incorrect(__func__);
> > return NULL;
> > }
> > for (x = 0; x < 3; ++x) {
> > if (red_drawable->surface_deps[x] != -1) {
> > - VALIDATE_SURFACE_RETVAL(worker, red_drawable->surface_deps[x],
> > NULL)
> > + VALIDATE_SURFACE_RETVAL(display, red_drawable->surface_deps[x],
> > NULL)
> > }
> > }
> >
> > while (!(drawable = drawable_try_new(display))) {
> > - if (!free_one_drawable(COMMON_CHANNEL(display)->worker, FALSE))
> > + if (!free_one_drawable(display, FALSE))
> > return NULL;
> > }
> >
> > @@ -2737,24 +2654,24 @@ static Drawable *get_drawable(RedWorker *worker,
> > uint8_t effect, RedDrawable *re
> > return drawable;
> > }
> >
> > -static inline int red_handle_depends_on_target_surface(RedWorker *worker,
> > uint32_t surface_id)
> > +static inline int red_handle_depends_on_target_surface(DisplayChannel
> > *display, uint32_t surface_id)
> > {
> > RedSurface *surface;
> > RingItem *ring_item;
> >
> > - surface = &worker->surfaces[surface_id];
> > + surface = &display->surfaces[surface_id];
> >
> > while ((ring_item = ring_get_tail(&surface->depend_on_me))) {
> > Drawable *drawable;
> > DependItem *depended_item = SPICE_CONTAINEROF(ring_item,
> > DependItem, ring_item);
> > drawable = depended_item->drawable;
> > - surface_flush(worker, drawable->surface_id, &drawable->red_drawable
> > ->bbox);
> > + surface_flush(display, drawable->surface_id, &drawable
> > ->red_drawable->bbox);
> > }
> >
> > return TRUE;
> > }
> >
> > -static inline void add_to_surface_dependency(RedWorker *worker, int
> > depend_on_surface_id,
> > +static inline void add_to_surface_dependency(DisplayChannel *display, int
> > depend_on_surface_id,
> > DependItem *depend_item,
> > Drawable *drawable)
> > {
> > RedSurface *surface;
> > @@ -2764,22 +2681,21 @@ static inline void
> > add_to_surface_dependency(RedWorker *worker, int depend_on_su
> > return;
> > }
> >
> > - surface = &worker->surfaces[depend_on_surface_id];
> > + surface = &display->surfaces[depend_on_surface_id];
> >
> > depend_item->drawable = drawable;
> > ring_add(&surface->depend_on_me, &depend_item->ring_item);
> > }
> >
> > -static inline int red_handle_surfaces_dependencies(RedWorker *worker,
> > Drawable *drawable)
> > +static inline int red_handle_surfaces_dependencies(DisplayChannel *display,
> > Drawable *drawable)
> > {
> > - DisplayChannel *display = worker->display_channel;
> > int x;
> >
> > for (x = 0; x < 3; ++x) {
> > // surface self dependency is handled by shadows in "current", or
> > by
> > // handle_self_bitmap
> > if (drawable->surface_deps[x] != drawable->surface_id) {
> > - add_to_surface_dependency(worker, drawable->surface_deps[x],
> > + add_to_surface_dependency(display, drawable->surface_deps[x],
> > &drawable->depend_items[x],
> > drawable);
> >
> > if (drawable->surface_deps[x] == 0) {
> > @@ -2794,7 +2710,7 @@ static inline int
> > red_handle_surfaces_dependencies(RedWorker *worker, Drawable *
> > return TRUE;
> > }
> >
> > -static inline void red_inc_surfaces_drawable_dependencies(RedWorker
> > *worker, Drawable *drawable)
> > +static inline void red_inc_surfaces_drawable_dependencies(DisplayChannel
> > *display, Drawable *drawable)
> > {
> > int x;
> > int surface_id;
> > @@ -2805,7 +2721,7 @@ static inline void
> > red_inc_surfaces_drawable_dependencies(RedWorker *worker, Dra
> > if (surface_id == -1) {
> > continue;
> > }
> > - surface = &worker->surfaces[surface_id];
> > + surface = &display->surfaces[surface_id];
> > surface->refs++;
> > }
> > }
> > @@ -2824,7 +2740,7 @@ static inline void red_process_draw(RedWorker *worker,
> > RedDrawable *red_drawable
> > red_drawable->mm_time = reds_get_mm_time();
> > surface_id = drawable->surface_id;
> >
> > - worker->surfaces[surface_id].refs++;
> > + display->surfaces[surface_id].refs++;
> >
> > region_add(&drawable->tree_item.base.rgn, &red_drawable->bbox);
> >
> > @@ -2836,13 +2752,14 @@ static inline void red_process_draw(RedWorker
> > *worker, RedDrawable *red_drawable
> > region_and(&drawable->tree_item.base.rgn, &rgn);
> > region_destroy(&rgn);
> > }
> > +
> > /*
> > surface->refs is affected by a drawable (that is
> > dependent on the surface) as long as the drawable is alive.
> > However, surface->depend_on_me is affected by a drawable only
> > as long as it is in the current tree (hasn't been rendered yet).
> > */
> > - red_inc_surfaces_drawable_dependencies(worker, drawable);
> > + red_inc_surfaces_drawable_dependencies(worker->display_channel,
> > drawable);
> >
> > if (region_is_empty(&drawable->tree_item.base.rgn)) {
> > goto cleanup;
> > @@ -2852,38 +2769,36 @@ static inline void red_process_draw(RedWorker
> > *worker, RedDrawable *red_drawable
> > goto cleanup;
> > }
> >
> > - if (!red_handle_depends_on_target_surface(worker, surface_id)) {
> > + if (!red_handle_depends_on_target_surface(worker->display_channel,
> > surface_id)) {
> > goto cleanup;
> > }
> >
> > - if (!red_handle_surfaces_dependencies(worker, drawable)) {
> > + if (!red_handle_surfaces_dependencies(worker->display_channel,
> > drawable)) {
> > goto cleanup;
> > }
> >
> > - if (red_add_drawable(worker, drawable)) {
> > - red_pipes_add_drawable(worker, drawable);
> > + if (red_add_drawable(worker->display_channel, drawable)) {
> > + red_pipes_add_drawable(worker->display_channel, drawable);
> > }
> > cleanup:
> > display_channel_drawable_unref(display, drawable);
> > }
> >
> > -static inline void red_create_surface(RedWorker *worker, uint32_t
> > surface_id,uint32_t width,
> > - uint32_t height, int32_t stride,
> > uint32_t format,
> > - void *line_0, int data_is_valid, int
> > send_client);
> >
> > static inline void red_process_surface(RedWorker *worker, RedSurfaceCmd
> > *surface,
> > uint32_t group_id, int loadvm)
> > {
> > + DisplayChannel *display = worker->display_channel;
> > uint32_t surface_id;
> > RedSurface *red_surface;
> > uint8_t *data;
> >
> > surface_id = surface->surface_id;
> > - if SPICE_UNLIKELY(surface_id >= worker->n_surfaces) {
> > + if SPICE_UNLIKELY(surface_id >= display->n_surfaces) {
> > goto exit;
> > }
> >
> > - red_surface = &worker->surfaces[surface_id];
> > + red_surface = &display->surfaces[surface_id];
> >
> > switch (surface->type) {
> > case QXL_SURFACE_CMD_CREATE: {
> > @@ -2899,7 +2814,7 @@ static inline void red_process_surface(RedWorker
> > *worker, RedSurfaceCmd *surface
> > if (stride < 0) {
> > data -= (int32_t)(stride * (height - 1));
> > }
> > - red_create_surface(worker, surface_id, surface
> > ->u.surface_create.width,
> > + red_create_surface(worker->display_channel, surface_id, surface
> > ->u.surface_create.width,
> > height, stride, surface
> > ->u.surface_create.format, data,
> > reloaded_surface,
> > // reloaded surfaces will be sent on demand
> > @@ -2913,13 +2828,13 @@ static inline void red_process_surface(RedWorker
> > *worker, RedSurfaceCmd *surface
> > break;
> > }
> > set_surface_release_info(&red_surface->destroy, surface
> > ->release_info, group_id);
> > - red_handle_depends_on_target_surface(worker, surface_id);
> > - /* note that red_handle_depends_on_target_surface must be called
> > before red_current_clear.
> > + red_handle_depends_on_target_surface(display, surface_id);
> > + /* note that red_handle_depends_on_target_surface must be called
> > before current_clear.
> > otherwise "current" will hold items that other drawables may
> > depend on, and then
> > red_current_clear will remove them from the pipe. */
> > - red_current_clear(worker, surface_id);
> > - red_clear_surface_drawables_from_pipes(worker, surface_id, FALSE);
> > - red_surface_unref(worker, surface_id);
> > + current_clear(display, surface_id);
> > + red_clear_surface_drawables_from_pipes(display, surface_id, FALSE);
> > + display_channel_surface_unref(display, surface_id);
> > break;
> > default:
> > spice_error("unknown surface command");
> > @@ -2932,31 +2847,30 @@ exit:
> > static SpiceCanvas *image_surfaces_get(SpiceImageSurfaces *surfaces,
> > uint32_t surface_id)
> > {
> > - RedWorker *worker;
> > + DisplayChannel *display;
> >
> > - worker = SPICE_CONTAINEROF(surfaces, RedWorker, image_surfaces);
> > - VALIDATE_SURFACE_RETVAL(worker, surface_id, NULL);
> > + display = SPICE_CONTAINEROF(surfaces, DisplayChannel, image_surfaces);
> > + VALIDATE_SURFACE_RETVAL(display, surface_id, NULL);
> >
> > - return worker->surfaces[surface_id].context.canvas;
> > + return display->surfaces[surface_id].context.canvas;
> > }
> >
> > -static void image_surface_init(RedWorker *worker)
> > +static void image_surface_init(DisplayChannel *display)
> > {
> > static SpiceImageSurfacesOps image_surfaces_ops = {
> > image_surfaces_get,
> > };
> >
> > - worker->image_surfaces.ops = &image_surfaces_ops;
> > + display->image_surfaces.ops = &image_surfaces_ops;
> > }
> >
> > -static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable)
> > +static void red_draw_qxl_drawable(DisplayChannel *display, Drawable
> > *drawable)
> > {
> > - DisplayChannel *display = worker->display_channel;
> > RedSurface *surface;
> > SpiceCanvas *canvas;
> > SpiceClip clip = drawable->red_drawable->clip;
> >
> > - surface = &worker->surfaces[drawable->surface_id];
> > + surface = &display->surfaces[drawable->surface_id];
> > canvas = surface->context.canvas;
> >
> > image_cache_aging(&display->image_cache);
> > @@ -3087,17 +3001,17 @@ static void red_draw_qxl_drawable(RedWorker *worker,
> > Drawable *drawable)
> > }
> > }
> >
> > -static void red_draw_drawable(RedWorker *worker, Drawable *drawable)
> > +static void red_draw_drawable(DisplayChannel *display, Drawable *drawable)
> > {
> > - red_flush_source_surfaces(worker, drawable);
> > - red_draw_qxl_drawable(worker, drawable);
> > + red_flush_source_surfaces(display, drawable);
> > + red_draw_qxl_drawable(display, drawable);
> > }
> >
> > -static void validate_area(RedWorker *worker, const SpiceRect *area,
> > uint32_t surface_id)
> > +static void validate_area(DisplayChannel *display, const SpiceRect *area,
> > uint32_t surface_id)
> > {
> > RedSurface *surface;
> >
> > - surface = &worker->surfaces[surface_id];
> > + surface = &display->surfaces[surface_id];
> > if (!surface->context.canvas_draws_on_surface) {
> > SpiceCanvas *canvas = surface->context.canvas;
> > int h;
> > @@ -3119,10 +3033,9 @@ static void validate_area(RedWorker *worker, const
> > SpiceRect *area, uint32_t sur
> > Renders drawables for updating the requested area, but only drawables
> > that are older
> > than 'last' (exclusive).
> > */
> > -static void red_update_area_till(RedWorker *worker, const SpiceRect *area,
> > int surface_id,
> > +static void red_update_area_till(DisplayChannel *display, const SpiceRect
> > *area, int surface_id,
> > Drawable *last)
> > {
> > - DisplayChannel *display = worker->display_channel;
> > RedSurface *surface;
> > Drawable *surface_last = NULL;
> > Ring *ring;
> > @@ -3133,7 +3046,7 @@ static void red_update_area_till(RedWorker *worker,
> > const SpiceRect *area, int s
> > spice_assert(last);
> > spice_assert(ring_item_is_linked(&last->list_link));
> >
> > - surface = &worker->surfaces[surface_id];
> > + surface = &display->surfaces[surface_id];
> >
> > if (surface_id != last->surface_id) {
> > // find the nearest older drawable from the appropriate surface
> > @@ -3185,22 +3098,21 @@ static void red_update_area_till(RedWorker *worker,
> > const SpiceRect *area, int s
> > now = SPICE_CONTAINEROF(ring_item, Drawable, surface_list_link);
> > now->refs++;
> > container = now->tree_item.base.container;
> > - current_remove_drawable(worker, now);
> > - container_cleanup(worker, container);
> > + current_remove_drawable(display, now);
> > + container_cleanup(display, container);
> > /* red_draw_drawable may call red_update_area for the surfaces
> > 'now' depends on. Notice,
> > that it is valid to call red_update_area in this case and not
> > red_update_area_till:
> > It is impossible that there was newer item then 'last' in one of
> > the surfaces
> > that red_update_area is called for, Otherwise, 'now' would have
> > already been rendered.
> > See the call for red_handle_depends_on_target_surface in
> > red_process_draw */
> > - red_draw_drawable(worker, now);
> > + red_draw_drawable(display, now);
> > display_channel_drawable_unref(display, now);
> > } while (now != surface_last);
> > - validate_area(worker, area, surface_id);
> > + validate_area(display, area, surface_id);
> > }
> >
> > -static void red_update_area(RedWorker *worker, const SpiceRect *area, int
> > surface_id)
> > +static void red_update_area(DisplayChannel *display, const SpiceRect *area,
> > int surface_id)
> > {
> > - DisplayChannel *display = worker->display_channel;
> > RedSurface *surface;
> > Ring *ring;
> > RingItem *ring_item;
> > @@ -3215,7 +3127,7 @@ static void red_update_area(RedWorker *worker, const
> > SpiceRect *area, int surfac
> > spice_return_if_fail(area->left >= 0 && area->top >= 0 &&
> > area->left < area->right && area->top < area
> > ->bottom);
> >
> > - surface = &worker->surfaces[surface_id];
> > + surface = &display->surfaces[surface_id];
> >
> > last = NULL;
> > ring = &surface->current_list;
> > @@ -3233,7 +3145,7 @@ static void red_update_area(RedWorker *worker, const
> > SpiceRect *area, int surfac
> > region_destroy(&rgn);
> >
> > if (!last) {
> > - validate_area(worker, area, surface_id);
> > + validate_area(display, area, surface_id);
> > return;
> > }
> >
> > @@ -3244,12 +3156,12 @@ static void red_update_area(RedWorker *worker, const
> > SpiceRect *area, int surfac
> > now = SPICE_CONTAINEROF(ring_item, Drawable, surface_list_link);
> > now->refs++;
> > container = now->tree_item.base.container;
> > - current_remove_drawable(worker, now);
> > - container_cleanup(worker, container);
> > - red_draw_drawable(worker, now);
> > + current_remove_drawable(display, now);
> > + container_cleanup(display, container);
> > + red_draw_drawable(display, now);
> > display_channel_drawable_unref(display, now);
> > } while (now != last);
> > - validate_area(worker, area, surface_id);
> > + validate_area(display, area, surface_id);
> > }
> >
> > static int red_process_cursor(RedWorker *worker, uint32_t max_pipe_size,
> > int *ring_is_empty)
> > @@ -3368,11 +3280,11 @@ static int red_process_commands(RedWorker *worker,
> > uint32_t max_pipe_size, int *
> > &update, ext_cmd.cmd.data)) {
> > break;
> > }
> > - if (!validate_surface(worker, update.surface_id)) {
> > + if (!validate_surface(worker->display_channel,
> > update.surface_id)) {
> > rendering_incorrect("QXL_CMD_UPDATE");
> > break;
> > }
> > - red_update_area(worker, &update.area, update.surface_id);
> > + red_update_area(worker->display_channel, &update.area,
> > update.surface_id);
> > worker->qxl->st->qif->notify_update(worker->qxl,
> > update.update_id);
> > release_info_ext.group_id = ext_cmd.group_id;
> > release_info_ext.info = update.release_info;
> > @@ -3446,7 +3358,7 @@ static void red_free_some(RedWorker *worker)
> > }
> >
> > while (!ring_is_empty(&display->current_list) && n++ <
> > RED_RELEASE_BUNCH_SIZE) {
> > - free_one_drawable(worker, TRUE);
> > + free_one_drawable(display, TRUE);
> > }
> >
> > FOREACH_DCC(worker->display_channel, item, next, dcc) {
> > @@ -3458,12 +3370,12 @@ static void red_free_some(RedWorker *worker)
> > }
> > }
> >
> > -static void red_current_flush(RedWorker *worker, int surface_id)
> > +static void red_current_flush(DisplayChannel *display, int surface_id)
> > {
> > - while (!ring_is_empty(&worker->surfaces[surface_id].current_list)) {
> > - free_one_drawable(worker, FALSE);
> > + while (!ring_is_empty(&display->surfaces[surface_id].current_list)) {
> > + free_one_drawable(display, FALSE);
> > }
> > - red_current_clear(worker, surface_id);
> > + current_clear(display, surface_id);
> > }
> >
> > // adding the pipe item after pos. If pos == NULL, adding to head.
> > @@ -3472,8 +3384,7 @@ static ImageItem
> > *red_add_surface_area_image(DisplayChannelClient *dcc, int surf
> > {
> > DisplayChannel *display = DCC_TO_DC(dcc);
> > RedChannel *channel = RED_CHANNEL(display);
> > - RedWorker *worker = DCC_TO_WORKER(dcc);
> > - RedSurface *surface = &worker->surfaces[surface_id];
> > + RedSurface *surface = &display->surfaces[surface_id];
> > SpiceCanvas *canvas = surface->context.canvas;
> > ImageItem *item;
> > int stride;
> > @@ -3533,15 +3444,11 @@ static ImageItem
> > *red_add_surface_area_image(DisplayChannelClient *dcc, int surf
> >
> > static void red_push_surface_image(DisplayChannelClient *dcc, int
> > surface_id)
> > {
> > + DisplayChannel *display = DCC_TO_DC(dcc);
>
> I would do:
> DisplayChannel *display = dcc ? DCC_TO_DC(dcc) : NULL;
>
> > SpiceRect area;
> > RedSurface *surface;
> > - RedWorker *worker;
> >
> > - if (!dcc) {
> > - return;
> > - }
>
> And here check for a NULL display.
>
> > - worker = DCC_TO_WORKER(dcc);
> > - surface = &worker->surfaces[surface_id];
> > + surface = &display->surfaces[surface_id];
> > if (!surface->context.canvas) {
> > return;
> > }
> > @@ -4968,8 +4875,7 @@ static FillBitsType fill_bits(DisplayChannelClient
> > *dcc, SpiceMarshaller *m,
> > SpiceImage *simage, Drawable *drawable, int
> > can_lossy)
> > {
> > RedChannelClient *rcc = RED_CHANNEL_CLIENT(dcc);
> > - DisplayChannel *display_channel = SPICE_CONTAINEROF(rcc->channel,
> > DisplayChannel, common.base);
> > - RedWorker *worker = DCC_TO_WORKER(dcc);
> > + DisplayChannel *display = DCC_TO_DC(dcc);
> > SpiceImage image;
> > compress_send_data_t comp_send_data = {0};
> > SpiceMarshaller *bitmap_palette_out, *lzplt_palette_out;
> > @@ -4992,7 +4898,7 @@ static FillBitsType fill_bits(DisplayChannelClient
> > *dcc, SpiceMarshaller *m,
> > dcc->send_data.pixmap_cache_items[dcc
> > ->send_data.num_pixmap_cache_items++] =
> >
> > image.descriptor.id;
> > if (can_lossy || !lossy_cache_item) {
> > - if (!display_channel->enable_jpeg || lossy_cache_item) {
> > + if (!display->enable_jpeg || lossy_cache_item) {
> > image.descriptor.type = SPICE_IMAGE_TYPE_FROM_CACHE;
> > } else {
> > // making sure, in multiple monitor scenario, that
> > lossy items that
> > @@ -5004,7 +4910,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(display_channel->cache_hits_counter, 1);
> > + stat_inc_counter(display->cache_hits_counter, 1);
> > pthread_mutex_unlock(&dcc->pixmap_cache->lock);
> > return FILL_BITS_TYPE_CACHE;
> > } else {
> > @@ -5021,13 +4927,13 @@ static FillBitsType fill_bits(DisplayChannelClient
> > *dcc, SpiceMarshaller *m,
> > RedSurface *surface;
> >
> > surface_id = simage->u.surface.surface_id;
> > - if (!validate_surface(worker, surface_id)) {
> > + if (!validate_surface(display, surface_id)) {
> > rendering_incorrect("SPICE_IMAGE_TYPE_SURFACE");
> > pthread_mutex_unlock(&dcc->pixmap_cache->lock);
> > return FILL_BITS_TYPE_SURFACE;
> > }
> >
> > - surface = &worker->surfaces[surface_id];
> > + surface = &display->surfaces[surface_id];
> > image.descriptor.type = SPICE_IMAGE_TYPE_SURFACE;
> > image.descriptor.flags = 0;
> > image.descriptor.width = surface->context.width;
> > @@ -5114,16 +5020,16 @@ static FillBitsType fill_bits(DisplayChannelClient
> > *dcc, SpiceMarshaller *m,
> > static void fill_mask(RedChannelClient *rcc, SpiceMarshaller *m,
> > SpiceImage *mask_bitmap, Drawable *drawable)
> > {
> > - DisplayChannel *display_channel = SPICE_CONTAINEROF(rcc->channel,
> > DisplayChannel, common.base);
> > DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > + DisplayChannel *display = DCC_TO_DC(dcc);
> >
> > if (mask_bitmap && m) {
> > - if (display_channel->common.worker->image_compression !=
> > SPICE_IMAGE_COMPRESSION_OFF) {
> > + if (display->common.worker->image_compression !=
> > SPICE_IMAGE_COMPRESSION_OFF) {
> > SpiceImageCompression save_img_comp =
> > - display_channel->common.worker->image_compression;
> > - display_channel->common.worker->image_compression =
> > SPICE_IMAGE_COMPRESSION_OFF;
> > + display->common.worker->image_compression;
> > + display->common.worker->image_compression =
> > SPICE_IMAGE_COMPRESSION_OFF;
> > fill_bits(dcc, m, mask_bitmap, drawable, FALSE);
> > - display_channel->common.worker->image_compression =
> > save_img_comp;
> > + display->common.worker->image_compression = save_img_comp;
> > } else {
> > fill_bits(dcc, m, mask_bitmap, drawable, FALSE);
> > }
> > @@ -5156,10 +5062,10 @@ static int
> > is_surface_area_lossy(DisplayChannelClient *dcc, uint32_t surface_id,
> > RedSurface *surface;
> > QRegion *surface_lossy_region;
> > QRegion lossy_region;
> > - RedWorker *worker = DCC_TO_WORKER(dcc);
> > + DisplayChannel *display = DCC_TO_DC(dcc);
> >
> > - VALIDATE_SURFACE_RETVAL(worker, surface_id, FALSE);
> > - surface = &worker->surfaces[surface_id];
> > + VALIDATE_SURFACE_RETVAL(display, surface_id, FALSE);
> > + surface = &display->surfaces[surface_id];
> > surface_lossy_region = &dcc->surface_client_lossy_region[surface_id];
> >
> > if (!area) {
> > @@ -5249,7 +5155,7 @@ static int is_brush_lossy(RedChannelClient *rcc,
> > SpiceBrush *brush,
> > }
> > }
> >
> > -static void surface_lossy_region_update(RedWorker *worker,
> > DisplayChannelClient *dcc,
> > +static void surface_lossy_region_update(DisplayChannelClient *dcc,
> > Drawable *item, int has_mask, int
> > lossy)
> > {
> > QRegion *surface_lossy_region;
> > @@ -5360,8 +5266,7 @@ static inline int drawable_depends_on_areas(Drawable
> > *drawable,
> > }
> >
> >
> > -static int pipe_rendered_drawables_intersect_with_areas(RedWorker *worker,
> > -
> > DisplayChannelClient *dcc,
> > +static int
> > pipe_rendered_drawables_intersect_with_areas(DisplayChannelClient *dcc,
> > int surface_ids[],
> > SpiceRect
> > *surface_areas[],
> > int num_surfaces)
> > @@ -5393,8 +5298,7 @@ static int
> > pipe_rendered_drawables_intersect_with_areas(RedWorker *worker,
> > return FALSE;
> > }
> >
> > -static void red_pipe_replace_rendered_drawables_with_images(RedWorker
> > *worker,
> > -
> > DisplayChannelClient *dcc,
> > +static void
> > red_pipe_replace_rendered_drawables_with_images(DisplayChannelClient *dcc,
> > int
> > first_surface_id,
> > SpiceRect
> > *first_area)
> > {
> > @@ -5449,15 +5353,15 @@ static void
> > red_pipe_replace_rendered_drawables_with_images(RedWorker *worker,
> > }
> > }
> >
> > -static void red_add_lossless_drawable_dependencies(RedWorker *worker,
> > - RedChannelClient *rcc,
> > +static void red_add_lossless_drawable_dependencies(RedChannelClient *rcc,
> > Drawable *item,
> > int deps_surfaces_ids[],
> > SpiceRect *deps_areas[],
> > int num_deps)
> > {
> > - RedDrawable *drawable = item->red_drawable;
> > DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > + DisplayChannel *display = DCC_TO_DC(dcc);
> > + RedDrawable *drawable = item->red_drawable;
> > int sync_rendered = FALSE;
> > int i;
> >
> > @@ -5470,7 +5374,7 @@ static void
> > red_add_lossless_drawable_dependencies(RedWorker *worker,
> > // that were rendered, affected the areas that need to be resent
> > if (!drawable_intersects_with_areas(item, deps_surfaces_ids,
> > deps_areas, num_deps)) {
> > - if (pipe_rendered_drawables_intersect_with_areas(worker, dcc,
> > + if (pipe_rendered_drawables_intersect_with_areas(dcc,
> >
> > deps_surfaces_ids,
> > deps_areas,
> > num_deps)) {
> > @@ -5482,7 +5386,7 @@ static void
> > red_add_lossless_drawable_dependencies(RedWorker *worker,
> > } else {
> > sync_rendered = FALSE;
> > for (i = 0; i < num_deps; i++) {
> > - red_update_area_till(worker, deps_areas[i],
> > + red_update_area_till(display, deps_areas[i],
> > deps_surfaces_ids[i], item);
> > }
> > }
> > @@ -5505,11 +5409,11 @@ static void
> > red_add_lossless_drawable_dependencies(RedWorker *worker,
> > drawable_bbox[0] = &drawable->bbox;
> >
> > // check if the other rendered images in the pipe have updated the
> > drawable bbox
> > - if (pipe_rendered_drawables_intersect_with_areas(worker, dcc,
> > + if (pipe_rendered_drawables_intersect_with_areas(dcc,
> >
> > drawable_surface_id,
> > drawable_bbox,
> > 1)) {
> > - red_pipe_replace_rendered_drawables_with_images(worker, dcc,
> > + red_pipe_replace_rendered_drawables_with_images(dcc,
> > drawable
> > ->surface_id,
> > &drawable
> > ->bbox);
> > }
> > @@ -5519,10 +5423,9 @@ static void
> > red_add_lossless_drawable_dependencies(RedWorker *worker,
> > }
> > }
> >
> > -static void red_marshall_qxl_draw_fill(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller *base_marshaller,
> > - DrawablePipeItem *dpi)
> > +static void red_marshall_qxl_draw_fill(RedChannelClient *rcc,
> > + SpiceMarshaller *base_marshaller,
> > + DrawablePipeItem *dpi)
> > {
> > Drawable *item = dpi->drawable;
> > RedDrawable *drawable = item->red_drawable;
> > @@ -5547,13 +5450,12 @@ static void red_marshall_qxl_draw_fill(RedWorker
> > *worker,
> > }
> >
> >
> > -static void red_lossy_marshall_qxl_draw_fill(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller *m,
> > - DrawablePipeItem *dpi)
> > +static void red_lossy_marshall_qxl_draw_fill(RedChannelClient *rcc,
> > + SpiceMarshaller *m,
> > + DrawablePipeItem *dpi)
> > {
> > - Drawable *item = dpi->drawable;
> > DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > + Drawable *item = dpi->drawable;
> > RedDrawable *drawable = item->red_drawable;
> >
> > int dest_allowed_lossy = FALSE;
> > @@ -5580,9 +5482,9 @@ static void red_lossy_marshall_qxl_draw_fill(RedWorker
> > *worker,
> > !(brush_is_lossy && (brush_bitmap_data.type ==
> > BITMAP_DATA_TYPE_SURFACE))) {
> > int has_mask = !!drawable->u.fill.mask.bitmap;
> >
> > - red_marshall_qxl_draw_fill(worker, rcc, m, dpi);
> > + red_marshall_qxl_draw_fill(rcc, m, dpi);
> > // either the brush operation is opaque, or the dest is not lossy
> > - surface_lossy_region_update(worker, dcc, item, has_mask, FALSE);
> > + surface_lossy_region_update(dcc, item, has_mask, FALSE);
> > } else {
> > int resend_surface_ids[2];
> > SpiceRect *resend_areas[2];
> > @@ -5600,18 +5502,17 @@ static void
> > red_lossy_marshall_qxl_draw_fill(RedWorker *worker,
> > num_resend++;
> > }
> >
> > - red_add_lossless_drawable_dependencies(worker, rcc, item,
> > + red_add_lossless_drawable_dependencies(rcc, item,
> > resend_surface_ids,
> > resend_areas, num_resend);
> > }
> > }
> >
> > -static FillBitsType red_marshall_qxl_draw_opaque(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller
> > *base_marshaller,
> > - DrawablePipeItem *dpi, int
> > src_allowed_lossy)
> > +static FillBitsType red_marshall_qxl_draw_opaque(RedChannelClient *rcc,
> > + SpiceMarshaller
> > *base_marshaller,
> > + DrawablePipeItem *dpi, int
> > src_allowed_lossy)
> > {
> > - Drawable *item = dpi->drawable;
> > DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > + Drawable *item = dpi->drawable;
> > RedDrawable *drawable = item->red_drawable;
> > SpiceMarshaller *brush_pat_out;
> > SpiceMarshaller *src_bitmap_out;
> > @@ -5639,13 +5540,12 @@ static FillBitsType
> > red_marshall_qxl_draw_opaque(RedWorker *worker,
> > return src_send_type;
> > }
> >
> > -static void red_lossy_marshall_qxl_draw_opaque(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller *m,
> > - DrawablePipeItem *dpi)
> > +static void red_lossy_marshall_qxl_draw_opaque(RedChannelClient *rcc,
> > + SpiceMarshaller *m,
> > + DrawablePipeItem *dpi)
> > {
> > - Drawable *item = dpi->drawable;
> > DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > + Drawable *item = dpi->drawable;
> > RedDrawable *drawable = item->red_drawable;
> >
> > int src_allowed_lossy;
> > @@ -5675,14 +5575,14 @@ static void
> > red_lossy_marshall_qxl_draw_opaque(RedWorker *worker,
> > FillBitsType src_send_type;
> > int has_mask = !!drawable->u.opaque.mask.bitmap;
> >
> > - src_send_type = red_marshall_qxl_draw_opaque(worker, rcc, m, dpi,
> > src_allowed_lossy);
> > + src_send_type = red_marshall_qxl_draw_opaque(rcc, m, dpi,
> > src_allowed_lossy);
> > if (src_send_type == FILL_BITS_TYPE_COMPRESS_LOSSY) {
> > src_is_lossy = TRUE;
> > } else if (src_send_type == FILL_BITS_TYPE_COMPRESS_LOSSLESS) {
> > src_is_lossy = FALSE;
> > }
> >
> > - surface_lossy_region_update(worker, dcc, item, has_mask,
> > src_is_lossy);
> > + surface_lossy_region_update(dcc, item, has_mask, src_is_lossy);
> > } else {
> > int resend_surface_ids[2];
> > SpiceRect *resend_areas[2];
> > @@ -5700,19 +5600,18 @@ static void
> > red_lossy_marshall_qxl_draw_opaque(RedWorker *worker,
> > num_resend++;
> > }
> >
> > - red_add_lossless_drawable_dependencies(worker, rcc, item,
> > + red_add_lossless_drawable_dependencies(rcc, item,
> > resend_surface_ids,
> > resend_areas, num_resend);
> > }
> > }
> >
> > -static FillBitsType red_marshall_qxl_draw_copy(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller
> > *base_marshaller,
> > - DrawablePipeItem *dpi, int
> > src_allowed_lossy)
> > +static FillBitsType red_marshall_qxl_draw_copy(RedChannelClient *rcc,
> > + SpiceMarshaller
> > *base_marshaller,
> > + DrawablePipeItem *dpi, int
> > src_allowed_lossy)
> > {
> > + DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > Drawable *item = dpi->drawable;
> > RedDrawable *drawable = item->red_drawable;
> > - DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > SpiceMarshaller *src_bitmap_out;
> > SpiceMarshaller *mask_bitmap_out;
> > SpiceCopy copy;
> > @@ -5732,13 +5631,12 @@ static FillBitsType
> > red_marshall_qxl_draw_copy(RedWorker *worker,
> > return src_send_type;
> > }
> >
> > -static void red_lossy_marshall_qxl_draw_copy(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller *base_marshaller,
> > - DrawablePipeItem *dpi)
> > +static void red_lossy_marshall_qxl_draw_copy(RedChannelClient *rcc,
> > + SpiceMarshaller
> > *base_marshaller,
> > + DrawablePipeItem *dpi)
> > {
> > - Drawable *item = dpi->drawable;
> > DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > + Drawable *item = dpi->drawable;
> > RedDrawable *drawable = item->red_drawable;
> > int has_mask = !!drawable->u.copy.mask.bitmap;
> > int src_is_lossy;
> > @@ -5748,23 +5646,22 @@ static void
> > red_lossy_marshall_qxl_draw_copy(RedWorker *worker,
> > src_is_lossy = is_bitmap_lossy(rcc, drawable->u.copy.src_bitmap,
> > &drawable->u.copy.src_area, item,
> > &src_bitmap_data);
> >
> > - src_send_type = red_marshall_qxl_draw_copy(worker, rcc,
> > base_marshaller, dpi, TRUE);
> > + src_send_type = red_marshall_qxl_draw_copy(rcc, base_marshaller, dpi,
> > TRUE);
> > if (src_send_type == FILL_BITS_TYPE_COMPRESS_LOSSY) {
> > src_is_lossy = TRUE;
> > } else if (src_send_type == FILL_BITS_TYPE_COMPRESS_LOSSLESS) {
> > src_is_lossy = FALSE;
> > }
> > - surface_lossy_region_update(worker, dcc, item, has_mask,
> > + surface_lossy_region_update(dcc, item, has_mask,
> > src_is_lossy);
> > }
> >
> > -static void red_marshall_qxl_draw_transparent(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller *base_marshaller,
> > - DrawablePipeItem *dpi)
> > +static void red_marshall_qxl_draw_transparent(RedChannelClient *rcc,
> > + SpiceMarshaller
> > *base_marshaller,
> > + DrawablePipeItem *dpi)
> > {
> > - Drawable *item = dpi->drawable;
> > DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > + Drawable *item = dpi->drawable;
> > RedDrawable *drawable = item->red_drawable;
> > SpiceMarshaller *src_bitmap_out;
> > SpiceTransparent transparent;
> > @@ -5779,10 +5676,9 @@ static void
> > red_marshall_qxl_draw_transparent(RedWorker *worker,
> > fill_bits(dcc, src_bitmap_out, transparent.src_bitmap, item, FALSE);
> > }
> >
> > -static void red_lossy_marshall_qxl_draw_transparent(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller
> > *base_marshaller,
> > - DrawablePipeItem *dpi)
> > +static void red_lossy_marshall_qxl_draw_transparent(RedChannelClient *rcc,
> > + SpiceMarshaller
> > *base_marshaller,
> > + DrawablePipeItem *dpi)
> > {
> > Drawable *item = dpi->drawable;
> > RedDrawable *drawable = item->red_drawable;
> > @@ -5793,7 +5689,7 @@ static void
> > red_lossy_marshall_qxl_draw_transparent(RedWorker *worker,
> > &drawable->u.transparent.src_area, item,
> > &src_bitmap_data);
> >
> > if (!src_is_lossy || (src_bitmap_data.type !=
> > BITMAP_DATA_TYPE_SURFACE)) {
> > - red_marshall_qxl_draw_transparent(worker, rcc, base_marshaller,
> > dpi);
> > + red_marshall_qxl_draw_transparent(rcc, base_marshaller, dpi);
> > // don't update surface lossy region since transperent areas might
> > be lossy
> > } else {
> > int resend_surface_ids[1];
> > @@ -5802,16 +5698,15 @@ static void
> > red_lossy_marshall_qxl_draw_transparent(RedWorker *worker,
> > resend_surface_ids[0] = src_bitmap_data.id;
> > resend_areas[0] = &src_bitmap_data.lossy_rect;
> >
> > - red_add_lossless_drawable_dependencies(worker, rcc, item,
> > + red_add_lossless_drawable_dependencies(rcc, item,
> > resend_surface_ids,
> > resend_areas, 1);
> > }
> > }
> >
> > -static FillBitsType red_marshall_qxl_draw_alpha_blend(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller
> > *base_marshaller,
> > - DrawablePipeItem *dpi,
> > - int src_allowed_lossy)
> > +static FillBitsType red_marshall_qxl_draw_alpha_blend(RedChannelClient
> > *rcc,
> > + SpiceMarshaller
> > *base_marshaller,
> > + DrawablePipeItem
> > *dpi,
> > + int
> > src_allowed_lossy)
> > {
> > Drawable *item = dpi->drawable;
> > DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > @@ -5833,10 +5728,9 @@ static FillBitsType
> > red_marshall_qxl_draw_alpha_blend(RedWorker *worker,
> > return src_send_type;
> > }
> >
> > -static void red_lossy_marshall_qxl_draw_alpha_blend(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller
> > *base_marshaller,
> > - DrawablePipeItem *dpi)
> > +static void red_lossy_marshall_qxl_draw_alpha_blend(RedChannelClient *rcc,
> > + SpiceMarshaller
> > *base_marshaller,
> > + DrawablePipeItem *dpi)
> > {
> > Drawable *item = dpi->drawable;
> > DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > @@ -5848,7 +5742,7 @@ static void
> > red_lossy_marshall_qxl_draw_alpha_blend(RedWorker *worker,
> > src_is_lossy = is_bitmap_lossy(rcc, drawable->u.alpha_blend.src_bitmap,
> > &drawable->u.alpha_blend.src_area, item,
> > &src_bitmap_data);
> >
> > - src_send_type = red_marshall_qxl_draw_alpha_blend(worker, rcc,
> > base_marshaller, dpi, TRUE);
> > + src_send_type = red_marshall_qxl_draw_alpha_blend(rcc, base_marshaller,
> > dpi, TRUE);
> >
> > if (src_send_type == FILL_BITS_TYPE_COMPRESS_LOSSY) {
> > src_is_lossy = TRUE;
> > @@ -5857,14 +5751,13 @@ static void
> > red_lossy_marshall_qxl_draw_alpha_blend(RedWorker *worker,
> > }
> >
> > if (src_is_lossy) {
> > - surface_lossy_region_update(worker, dcc, item, FALSE,
> > src_is_lossy);
> > + surface_lossy_region_update(dcc, item, FALSE, src_is_lossy);
> > } // else, the area stays lossy/lossless as the destination
> > }
> >
> > -static void red_marshall_qxl_copy_bits(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller *base_marshaller,
> > - DrawablePipeItem *dpi)
> > +static void red_marshall_qxl_copy_bits(RedChannelClient *rcc,
> > + SpiceMarshaller *base_marshaller,
> > + DrawablePipeItem *dpi)
> > {
> > Drawable *item = dpi->drawable;
> > RedDrawable *drawable = item->red_drawable;
> > @@ -5877,10 +5770,9 @@ static void red_marshall_qxl_copy_bits(RedWorker
> > *worker,
> > ©_bits);
> > }
> >
> > -static void red_lossy_marshall_qxl_copy_bits(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller *base_marshaller,
> > - DrawablePipeItem *dpi)
> > +static void red_lossy_marshall_qxl_copy_bits(RedChannelClient *rcc,
> > + SpiceMarshaller
> > *base_marshaller,
> > + DrawablePipeItem *dpi)
> > {
> > Drawable *item = dpi->drawable;
> > DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > @@ -5891,7 +5783,7 @@ static void red_lossy_marshall_qxl_copy_bits(RedWorker
> > *worker,
> > int src_is_lossy;
> > SpiceRect src_lossy_area;
> >
> > - red_marshall_qxl_copy_bits(worker, rcc, base_marshaller, dpi);
> > + red_marshall_qxl_copy_bits(rcc, base_marshaller, dpi);
> >
> > horz_offset = drawable->u.copy_bits.src_pos.x - drawable->bbox.left;
> > vert_offset = drawable->u.copy_bits.src_pos.y - drawable->bbox.top;
> > @@ -5904,14 +5796,12 @@ static void
> > red_lossy_marshall_qxl_copy_bits(RedWorker *worker,
> > src_is_lossy = is_surface_area_lossy(dcc, item->surface_id,
> > &src_rect, &src_lossy_area);
> >
> > - surface_lossy_region_update(worker, dcc, item, FALSE,
> > - src_is_lossy);
> > + surface_lossy_region_update(dcc, item, FALSE, src_is_lossy);
> > }
> >
> > -static void red_marshall_qxl_draw_blend(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller *base_marshaller,
> > - DrawablePipeItem *dpi)
> > +static void red_marshall_qxl_draw_blend(RedChannelClient *rcc,
> > + SpiceMarshaller *base_marshaller,
> > + DrawablePipeItem *dpi)
> > {
> > Drawable *item = dpi->drawable;
> > DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > @@ -5933,10 +5823,9 @@ static void red_marshall_qxl_draw_blend(RedWorker
> > *worker,
> > fill_mask(rcc, mask_bitmap_out, blend.mask.bitmap, item);
> > }
> >
> > -static void red_lossy_marshall_qxl_draw_blend(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller *base_marshaller,
> > - DrawablePipeItem *dpi)
> > +static void red_lossy_marshall_qxl_draw_blend(RedChannelClient *rcc,
> > + SpiceMarshaller
> > *base_marshaller,
> > + DrawablePipeItem *dpi)
> > {
> > Drawable *item = dpi->drawable;
> > DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > @@ -5953,7 +5842,7 @@ static void
> > red_lossy_marshall_qxl_draw_blend(RedWorker *worker,
> >
> > if (!dest_is_lossy &&
> > (!src_is_lossy || (src_bitmap_data.type !=
> > BITMAP_DATA_TYPE_SURFACE))) {
> > - red_marshall_qxl_draw_blend(worker, rcc, base_marshaller, dpi);
> > + red_marshall_qxl_draw_blend(rcc, base_marshaller, dpi);
> > } else {
> > int resend_surface_ids[2];
> > SpiceRect *resend_areas[2];
> > @@ -5971,15 +5860,14 @@ static void
> > red_lossy_marshall_qxl_draw_blend(RedWorker *worker,
> > num_resend++;
> > }
> >
> > - red_add_lossless_drawable_dependencies(worker, rcc, item,
> > + red_add_lossless_drawable_dependencies(rcc, item,
> > resend_surface_ids,
> > resend_areas, num_resend);
> > }
> > }
> >
> > -static void red_marshall_qxl_draw_blackness(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller *base_marshaller,
> > - DrawablePipeItem *dpi)
> > +static void red_marshall_qxl_draw_blackness(RedChannelClient *rcc,
> > + SpiceMarshaller
> > *base_marshaller,
> > + DrawablePipeItem *dpi)
> > {
> > Drawable *item = dpi->drawable;
> > RedDrawable *drawable = item->red_drawable;
> > @@ -5997,25 +5885,23 @@ static void
> > red_marshall_qxl_draw_blackness(RedWorker *worker,
> > fill_mask(rcc, mask_bitmap_out, blackness.mask.bitmap, item);
> > }
> >
> > -static void red_lossy_marshall_qxl_draw_blackness(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller
> > *base_marshaller,
> > - DrawablePipeItem *dpi)
> > +static void red_lossy_marshall_qxl_draw_blackness(RedChannelClient *rcc,
> > + SpiceMarshaller
> > *base_marshaller,
> > + DrawablePipeItem *dpi)
> > {
> > Drawable *item = dpi->drawable;
> > DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > RedDrawable *drawable = item->red_drawable;
> > int has_mask = !!drawable->u.blackness.mask.bitmap;
> >
> > - red_marshall_qxl_draw_blackness(worker, rcc, base_marshaller, dpi);
> > + red_marshall_qxl_draw_blackness(rcc, base_marshaller, dpi);
> >
> > - surface_lossy_region_update(worker, dcc, item, has_mask, FALSE);
> > + surface_lossy_region_update(dcc, item, has_mask, FALSE);
> > }
> >
> > -static void red_marshall_qxl_draw_whiteness(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller *base_marshaller,
> > - DrawablePipeItem *dpi)
> > +static void red_marshall_qxl_draw_whiteness(RedChannelClient *rcc,
> > + SpiceMarshaller
> > *base_marshaller,
> > + DrawablePipeItem *dpi)
> > {
> > Drawable *item = dpi->drawable;
> > RedDrawable *drawable = item->red_drawable;
> > @@ -6033,25 +5919,23 @@ static void
> > red_marshall_qxl_draw_whiteness(RedWorker *worker,
> > fill_mask(rcc, mask_bitmap_out, whiteness.mask.bitmap, item);
> > }
> >
> > -static void red_lossy_marshall_qxl_draw_whiteness(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller
> > *base_marshaller,
> > - DrawablePipeItem *dpi)
> > +static void red_lossy_marshall_qxl_draw_whiteness(RedChannelClient *rcc,
> > + SpiceMarshaller
> > *base_marshaller,
> > + DrawablePipeItem *dpi)
> > {
> > Drawable *item = dpi->drawable;
> > DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > RedDrawable *drawable = item->red_drawable;
> > int has_mask = !!drawable->u.whiteness.mask.bitmap;
> >
> > - red_marshall_qxl_draw_whiteness(worker, rcc, base_marshaller, dpi);
> > + red_marshall_qxl_draw_whiteness(rcc, base_marshaller, dpi);
> >
> > - surface_lossy_region_update(worker, dcc, item, has_mask, FALSE);
> > + surface_lossy_region_update(dcc, item, has_mask, FALSE);
> > }
> >
> > -static void red_marshall_qxl_draw_inverse(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller *base_marshaller,
> > - Drawable *item)
> > +static void red_marshall_qxl_draw_inverse(RedChannelClient *rcc,
> > + SpiceMarshaller *base_marshaller,
> > + Drawable *item)
> > {
> > RedDrawable *drawable = item->red_drawable;
> > SpiceMarshaller *mask_bitmap_out;
> > @@ -6068,18 +5952,16 @@ static void red_marshall_qxl_draw_inverse(RedWorker
> > *worker,
> > fill_mask(rcc, mask_bitmap_out, inverse.mask.bitmap, item);
> > }
> >
> > -static void red_lossy_marshall_qxl_draw_inverse(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller
> > *base_marshaller,
> > - Drawable *item)
> > +static void red_lossy_marshall_qxl_draw_inverse(RedChannelClient *rcc,
> > + SpiceMarshaller
> > *base_marshaller,
> > + Drawable *item)
> > {
> > - red_marshall_qxl_draw_inverse(worker, rcc, base_marshaller, item);
> > + red_marshall_qxl_draw_inverse(rcc, base_marshaller, item);
> > }
> >
> > -static void red_marshall_qxl_draw_rop3(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller *base_marshaller,
> > - DrawablePipeItem *dpi)
> > +static void red_marshall_qxl_draw_rop3(RedChannelClient *rcc,
> > + SpiceMarshaller *base_marshaller,
> > + DrawablePipeItem *dpi)
> > {
> > Drawable *item = dpi->drawable;
> > DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > @@ -6106,10 +5988,9 @@ static void red_marshall_qxl_draw_rop3(RedWorker
> > *worker,
> > fill_mask(rcc, mask_bitmap_out, rop3.mask.bitmap, item);
> > }
> >
> > -static void red_lossy_marshall_qxl_draw_rop3(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller *base_marshaller,
> > - DrawablePipeItem *dpi)
> > +static void red_lossy_marshall_qxl_draw_rop3(RedChannelClient *rcc,
> > + SpiceMarshaller
> > *base_marshaller,
> > + DrawablePipeItem *dpi)
> > {
> > Drawable *item = dpi->drawable;
> > DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > @@ -6132,8 +6013,8 @@ static void red_lossy_marshall_qxl_draw_rop3(RedWorker
> > *worker,
> > (!brush_is_lossy || (brush_bitmap_data.type !=
> > BITMAP_DATA_TYPE_SURFACE)) &&
> > !dest_is_lossy) {
> > int has_mask = !!drawable->u.rop3.mask.bitmap;
> > - red_marshall_qxl_draw_rop3(worker, rcc, base_marshaller, dpi);
> > - surface_lossy_region_update(worker, dcc, item, has_mask, FALSE);
> > + red_marshall_qxl_draw_rop3(rcc, base_marshaller, dpi);
> > + surface_lossy_region_update(dcc, item, has_mask, FALSE);
> > } else {
> > int resend_surface_ids[3];
> > SpiceRect *resend_areas[3];
> > @@ -6157,15 +6038,14 @@ static void
> > red_lossy_marshall_qxl_draw_rop3(RedWorker *worker,
> > num_resend++;
> > }
> >
> > - red_add_lossless_drawable_dependencies(worker, rcc, item,
> > + red_add_lossless_drawable_dependencies(rcc, item,
> > resend_surface_ids,
> > resend_areas, num_resend);
> > }
> > }
> >
> > -static void red_marshall_qxl_draw_composite(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller *base_marshaller,
> > - DrawablePipeItem *dpi)
> > +static void red_marshall_qxl_draw_composite(RedChannelClient *rcc,
> > + SpiceMarshaller
> > *base_marshaller,
> > + DrawablePipeItem *dpi)
> > {
> > Drawable *item = dpi->drawable;
> > DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > @@ -6188,8 +6068,7 @@ static void red_marshall_qxl_draw_composite(RedWorker
> > *worker,
> > }
> > }
> >
> > -static void red_lossy_marshall_qxl_draw_composite(RedWorker *worker,
> > - RedChannelClient *rcc,
> > +static void red_lossy_marshall_qxl_draw_composite(RedChannelClient *rcc,
> > SpiceMarshaller
> > *base_marshaller,
> > DrawablePipeItem *dpi)
> > {
> > @@ -6214,8 +6093,8 @@ static void
> > red_lossy_marshall_qxl_draw_composite(RedWorker *worker,
> > if ((!src_is_lossy || (src_bitmap_data.type !=
> > BITMAP_DATA_TYPE_SURFACE)) &&
> > (!mask_is_lossy || (mask_bitmap_data.type !=
> > BITMAP_DATA_TYPE_SURFACE)) &&
> > !dest_is_lossy) {
> > - red_marshall_qxl_draw_composite(worker, rcc, base_marshaller, dpi);
> > - surface_lossy_region_update(worker, dcc, item, FALSE, FALSE);
> > + red_marshall_qxl_draw_composite(rcc, base_marshaller, dpi);
> > + surface_lossy_region_update(dcc, item, FALSE, FALSE);
> > }
> > else {
> > int resend_surface_ids[3];
> > @@ -6240,15 +6119,14 @@ static void
> > red_lossy_marshall_qxl_draw_composite(RedWorker *worker,
> > num_resend++;
> > }
> >
> > - red_add_lossless_drawable_dependencies(worker, rcc, item,
> > + red_add_lossless_drawable_dependencies(rcc, item,
> > resend_surface_ids,
> > resend_areas, num_resend);
> > }
> > }
> >
> > -static void red_marshall_qxl_draw_stroke(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller *base_marshaller,
> > - DrawablePipeItem *dpi)
> > +static void red_marshall_qxl_draw_stroke(RedChannelClient *rcc,
> > + SpiceMarshaller *base_marshaller,
> > + DrawablePipeItem *dpi)
> > {
> > Drawable *item = dpi->drawable;
> > DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > @@ -6271,10 +6149,9 @@ static void red_marshall_qxl_draw_stroke(RedWorker
> > *worker,
> > }
> > }
> >
> > -static void red_lossy_marshall_qxl_draw_stroke(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller
> > *base_marshaller,
> > - DrawablePipeItem *dpi)
> > +static void red_lossy_marshall_qxl_draw_stroke(RedChannelClient *rcc,
> > + SpiceMarshaller
> > *base_marshaller,
> > + DrawablePipeItem *dpi)
> > {
> > Drawable *item = dpi->drawable;
> > DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > @@ -6303,7 +6180,7 @@ static void
> > red_lossy_marshall_qxl_draw_stroke(RedWorker *worker,
> > if (!dest_is_lossy &&
> > (!brush_is_lossy || (brush_bitmap_data.type !=
> > BITMAP_DATA_TYPE_SURFACE)))
> > {
> > - red_marshall_qxl_draw_stroke(worker, rcc, base_marshaller, dpi);
> > + red_marshall_qxl_draw_stroke(rcc, base_marshaller, dpi);
> > } else {
> > int resend_surface_ids[2];
> > SpiceRect *resend_areas[2];
> > @@ -6322,15 +6199,14 @@ static void
> > red_lossy_marshall_qxl_draw_stroke(RedWorker *worker,
> > num_resend++;
> > }
> >
> > - red_add_lossless_drawable_dependencies(worker, rcc, item,
> > + red_add_lossless_drawable_dependencies(rcc, item,
> > resend_surface_ids,
> > resend_areas, num_resend);
> > }
> > }
> >
> > -static void red_marshall_qxl_draw_text(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller *base_marshaller,
> > - DrawablePipeItem *dpi)
> > +static void red_marshall_qxl_draw_text(RedChannelClient *rcc,
> > + SpiceMarshaller *base_marshaller,
> > + DrawablePipeItem *dpi)
> > {
> > Drawable *item = dpi->drawable;
> > DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > @@ -6355,10 +6231,9 @@ static void red_marshall_qxl_draw_text(RedWorker
> > *worker,
> > }
> > }
> >
> > -static void red_lossy_marshall_qxl_draw_text(RedWorker *worker,
> > - RedChannelClient *rcc,
> > - SpiceMarshaller *base_marshaller,
> > - DrawablePipeItem *dpi)
> > +static void red_lossy_marshall_qxl_draw_text(RedChannelClient *rcc,
> > + SpiceMarshaller
> > *base_marshaller,
> > + DrawablePipeItem *dpi)
> > {
> > Drawable *item = dpi->drawable;
> > DisplayChannelClient *dcc = RCC_TO_DCC(rcc);
> > @@ -6395,7 +6270,7 @@ static void red_lossy_marshall_qxl_draw_text(RedWorker
> > *worker,
> > if (!dest_is_lossy &&
> > (!fg_is_lossy || (fg_bitmap_data.type != BITMAP_DATA_TYPE_SURFACE))
> > &&
> > (!bg_is_lossy || (bg_bitmap_data.type !=
> > BITMAP_DATA_TYPE_SURFACE))) {
> > - red_marshall_qxl_draw_text(worker, rcc, base_marshaller, dpi);
> > + red_marshall_qxl_draw_text(rcc, base_marshaller, dpi);
> > } else {
> > int resend_surface_ids[3];
> > SpiceRect *resend_areas[3];
> > @@ -6418,111 +6293,112 @@ static void
> > red_lossy_marshall_qxl_draw_text(RedWorker *worker,
> > resend_areas[num_resend] = &dest_lossy_area;
> > num_resend++;
> > }
> > - red_add_lossless_drawable_dependencies(worker, rcc, item,
> > + red_add_lossless_drawable_dependencies(rcc, item,
> > resend_surface_ids,
> > resend_areas, num_resend);
> > }
> > }
> >
> > -static void red_lossy_marshall_qxl_drawable(RedWorker *worker,
> > RedChannelClient *rcc,
> > - SpiceMarshaller *base_marshaller,
> > DrawablePipeItem *dpi)
> > +static void red_lossy_marshall_qxl_drawable(RedChannelClient *rcc,
> > + SpiceMarshaller
> > *base_marshaller,
> > + DrawablePipeItem *dpi)
> > {
> > Drawable *item = dpi->drawable;
> > switch (item->red_drawable->type) {
> > case QXL_DRAW_FILL:
> > - red_lossy_marshall_qxl_draw_fill(worker, rcc, base_marshaller,
> > dpi);
> > + red_lossy_marshall_qxl_draw_fill(rcc, base_marshaller, dpi);
> > break;
> > case QXL_DRAW_OPAQUE:
> > - red_lossy_marshall_qxl_draw_opaque(worker, rcc, base_marshaller,
> > dpi);
> > + red_lossy_marshall_qxl_draw_opaque(rcc, base_marshaller, dpi);
> > break;
> > case QXL_DRAW_COPY:
> > - red_lossy_marshall_qxl_draw_copy(worker, rcc, base_marshaller,
> > dpi);
> > + red_lossy_marshall_qxl_draw_copy(rcc, base_marshaller, dpi);
> > break;
> > case QXL_DRAW_TRANSPARENT:
> > - red_lossy_marshall_qxl_draw_transparent(worker, rcc,
> > base_marshaller, dpi);
> > + red_lossy_marshall_qxl_draw_transparent(rcc, base_marshaller, dpi);
> > break;
> > case QXL_DRAW_ALPHA_BLEND:
> > - red_lossy_marshall_qxl_draw_alpha_blend(worker, rcc,
> > base_marshaller, dpi);
> > + red_lossy_marshall_qxl_draw_alpha_blend(rcc, base_marshaller, dpi);
> > break;
> > case QXL_COPY_BITS:
> > - red_lossy_marshall_qxl_copy_bits(worker, rcc, base_marshaller,
> > dpi);
> > + red_lossy_marshall_qxl_copy_bits(rcc, base_marshaller, dpi);
> > break;
> > case QXL_DRAW_BLEND:
> > - red_lossy_marshall_qxl_draw_blend(worker, rcc, base_marshaller,
> > dpi);
> > + red_lossy_marshall_qxl_draw_blend(rcc, base_marshaller, dpi);
> > break;
> > case QXL_DRAW_BLACKNESS:
> > - red_lossy_marshall_qxl_draw_blackness(worker, rcc, base_marshaller,
> > dpi);
> > + red_lossy_marshall_qxl_draw_blackness(rcc, base_marshaller, dpi);
> > break;
> > case QXL_DRAW_WHITENESS:
> > - red_lossy_marshall_qxl_draw_whiteness(worker, rcc, base_marshaller,
> > dpi);
> > + red_lossy_marshall_qxl_draw_whiteness(rcc, base_marshaller, dpi);
> > break;
> > case QXL_DRAW_INVERS:
> > - red_lossy_marshall_qxl_draw_inverse(worker, rcc, base_marshaller,
> > item);
> > + red_lossy_marshall_qxl_draw_inverse(rcc, base_marshaller, item);
> > break;
> > case QXL_DRAW_ROP3:
> > - red_lossy_marshall_qxl_draw_rop3(worker, rcc, base_marshaller,
> > dpi);
> > + red_lossy_marshall_qxl_draw_rop3(rcc, base_marshaller, dpi);
> > break;
> > case QXL_DRAW_COMPOSITE:
> > - red_lossy_marshall_qxl_draw_composite(worker, rcc, base_marshaller,
> > dpi);
> > + red_lossy_marshall_qxl_draw_composite(rcc, base_marshaller, dpi);
> > break;
> > case QXL_DRAW_STROKE:
> > - red_lossy_marshall_qxl_draw_stroke(worker, rcc, base_marshaller,
> > dpi);
> > + red_lossy_marshall_qxl_draw_stroke(rcc, base_marshaller, dpi);
> > break;
> > case QXL_DRAW_TEXT:
> > - red_lossy_marshall_qxl_draw_text(worker, rcc, base_marshaller,
> > dpi);
> > + red_lossy_marshall_qxl_draw_text(rcc, base_marshaller, dpi);
> > break;
> > default:
> > spice_error("invalid type");
> > }
> > }
> >
> > -static inline void red_marshall_qxl_drawable(RedWorker *worker,
> > RedChannelClient *rcc,
> > - SpiceMarshaller *m, DrawablePipeItem *dpi)
> > +static inline void red_marshall_qxl_drawable(RedChannelClient *rcc,
> > + SpiceMarshaller *m,
> > DrawablePipeItem *dpi)
> > {
> > Drawable *item = dpi->drawable;
> > RedDrawable *drawable = item->red_drawable;
> >
> > switch (drawable->type) {
> > case QXL_DRAW_FILL:
> > - red_marshall_qxl_draw_fill(worker, rcc, m, dpi);
> > + red_marshall_qxl_draw_fill(rcc, m, dpi);
> > break;
> > case QXL_DRAW_OPAQUE:
> > - red_marshall_qxl_draw_opaque(worker, rcc, m, dpi, FALSE);
> > + red_marshall_qxl_draw_opaque(rcc, m, dpi, FALSE);
> > break;
> > case QXL_DRAW_COPY:
> > - red_marshall_qxl_draw_copy(worker, rcc, m, dpi, FALSE);
> > + red_marshall_qxl_draw_copy(rcc, m, dpi, FALSE);
> > break;
> > case QXL_DRAW_TRANSPARENT:
> > - red_marshall_qxl_draw_transparent(worker, rcc, m, dpi);
> > + red_marshall_qxl_draw_transparent(rcc, m, dpi);
> > break;
> > case QXL_DRAW_ALPHA_BLEND:
> > - red_marshall_qxl_draw_alpha_blend(worker, rcc, m, dpi, FALSE);
> > + red_marshall_qxl_draw_alpha_blend(rcc, m, dpi, FALSE);
> > break;
> > case QXL_COPY_BITS:
> > - red_marshall_qxl_copy_bits(worker, rcc, m, dpi);
> > + red_marshall_qxl_copy_bits(rcc, m, dpi);
> > break;
> > case QXL_DRAW_BLEND:
> > - red_marshall_qxl_draw_blend(worker, rcc, m, dpi);
> > + red_marshall_qxl_draw_blend(rcc, m, dpi);
> > break;
> > case QXL_DRAW_BLACKNESS:
> > - red_marshall_qxl_draw_blackness(worker, rcc, m, dpi);
> > + red_marshall_qxl_draw_blackness(rcc, m, dpi);
> > break;
> > case QXL_DRAW_WHITENESS:
> > - red_marshall_qxl_draw_whiteness(worker, rcc, m, dpi);
> > + red_marshall_qxl_draw_whiteness(rcc, m, dpi);
> > break;
> > case QXL_DRAW_INVERS:
> > - red_marshall_qxl_draw_inverse(worker, rcc, m, item);
> > + red_marshall_qxl_draw_inverse(rcc, m, item);
> > break;
> > case QXL_DRAW_ROP3:
> > - red_marshall_qxl_draw_rop3(worker, rcc, m, dpi);
> > + red_marshall_qxl_draw_rop3(rcc, m, dpi);
> > break;
> > case QXL_DRAW_STROKE:
> > - red_marshall_qxl_draw_stroke(worker, rcc, m, dpi);
> > + red_marshall_qxl_draw_stroke(rcc, m, dpi);
> > break;
> > case QXL_DRAW_COMPOSITE:
> > - red_marshall_qxl_draw_composite(worker, rcc, m, dpi);
> > + red_marshall_qxl_draw_composite(rcc, m, dpi);
> > break;
> > case QXL_DRAW_TEXT:
> > - red_marshall_qxl_draw_text(worker, rcc, m, dpi);
> > + red_marshall_qxl_draw_text(rcc, m, dpi);
> > break;
> > default:
> > spice_error("invalid type");
> > @@ -6821,9 +6697,9 @@ static inline void
> > marshall_qxl_drawable(RedChannelClient *rcc,
> > return;
> > }
> > if (!display_channel->enable_jpeg)
> > - red_marshall_qxl_drawable(display_channel->common.worker, rcc, m,
> > dpi);
> > + red_marshall_qxl_drawable(rcc, m, dpi);
> > else
> > - red_lossy_marshall_qxl_drawable(display_channel->common.worker,
> > rcc, m, dpi);
> > + red_lossy_marshall_qxl_drawable(rcc, m, dpi);
> > }
> >
> > static inline void red_marshall_inval_palette(RedChannelClient *rcc,
> > @@ -7379,24 +7255,6 @@ static inline void red_push(RedWorker *worker)
> > }
> > }
> >
> > -void red_show_tree(RedWorker *worker)
> > -{
> > - int x;
> > -
> > - for (x = 0; x < NUM_SURFACES; ++x) {
> > - if (!worker->surfaces[x].context.canvas)
> > - continue;
> > -
> > - RingItem *it;
> > - Ring *ring = &worker->surfaces[x].current;
> > - RING_FOREACH(it, ring) {
> > - TreeItem *now = SPICE_CONTAINEROF(it, TreeItem, siblings_link);
> > - tree_item_dump(now);
> > - }
> > -
> > - }
> > -}
> > -
> > static void display_channel_client_on_disconnect(RedChannelClient *rcc)
> > {
> > DisplayChannel *display;
> > @@ -7474,15 +7332,15 @@ static void red_migrate_display(DisplayChannel
> > *display, RedChannelClient *rcc)
> > }
> >
> > #ifdef USE_OPENGL
> > -static SpiceCanvas *create_ogl_context_common(RedWorker *worker, OGLCtx
> > *ctx, uint32_t width,
> > - uint32_t height, int32_t
> > stride, uint8_t depth)
> > +static SpiceCanvas *create_ogl_context_common(DisplayChannel *display,
> > OGLCtx *ctx,
> > + uint32_t width, uint32_t
> > height,
> > + int32_t stride, uint8_t
> > depth)
> > {
> > - DisplayChannel *display = worker->display_channel;
> > SpiceCanvas *canvas;
> >
> > oglctx_make_current(ctx);
> > if (!(canvas = gl_canvas_create(width, height, depth, &display
> > ->image_cache.base,
> > - &worker->image_surfaces, NULL, NULL,
> > NULL))) {
> > + &display->image_surfaces, NULL, NULL,
> > NULL))) {
> > return NULL;
> > }
> >
> > @@ -7493,8 +7351,8 @@ static SpiceCanvas
> > *create_ogl_context_common(RedWorker *worker, OGLCtx *ctx, ui
> > return canvas;
> > }
> >
> > -static SpiceCanvas *create_ogl_pbuf_context(RedWorker *worker, uint32_t
> > width, uint32_t height,
> > - int32_t stride, uint8_t depth)
> > +static SpiceCanvas *create_ogl_pbuf_context(DisplayChannel *display,
> > uint32_t width,
> > + uint32_t height, int32_t
> > stride, uint8_t depth)
> > {
> > OGLCtx *ctx;
> > SpiceCanvas *canvas;
> > @@ -7503,7 +7361,7 @@ static SpiceCanvas *create_ogl_pbuf_context(RedWorker
> > *worker, uint32_t width, u
> > return NULL;
> > }
> >
> > - if (!(canvas = create_ogl_context_common(worker, ctx, width, height,
> > stride, depth))) {
> > + if (!(canvas = create_ogl_context_common(display, ctx, width, height,
> > stride, depth))) {
> > oglctx_destroy(ctx);
> > return NULL;
> > }
> > @@ -7511,8 +7369,9 @@ static SpiceCanvas *create_ogl_pbuf_context(RedWorker
> > *worker, uint32_t width, u
> > return canvas;
> > }
> >
> > -static SpiceCanvas *create_ogl_pixmap_context(RedWorker *worker, uint32_t
> > width, uint32_t height,
> > - int32_t stride, uint8_t
> > depth) {
> > +static SpiceCanvas *create_ogl_pixmap_context(DisplayChannel *display,
> > uint32_t width,
> > + uint32_t height, int32_t
> > stride, uint8_t depth)
> > +{
> > OGLCtx *ctx;
> > SpiceCanvas *canvas;
> >
> > @@ -7520,7 +7379,7 @@ static SpiceCanvas
> > *create_ogl_pixmap_context(RedWorker *worker, uint32_t width,
> > return NULL;
> > }
> >
> > - if (!(canvas = create_ogl_context_common(worker, ctx, width, height,
> > stride, depth))) {
> > + if (!(canvas = create_ogl_context_common(display, ctx, width, height,
> > stride, depth))) {
> > oglctx_destroy(ctx);
> > return NULL;
> > }
> > @@ -7529,11 +7388,10 @@ static SpiceCanvas
> > *create_ogl_pixmap_context(RedWorker *worker, uint32_t width,
> > }
> > #endif
> >
> > -static inline void *create_canvas_for_surface(RedWorker *worker, RedSurface
> > *surface,
> > +static inline void *create_canvas_for_surface(DisplayChannel *display,
> > RedSurface *surface,
> > uint32_t renderer, uint32_t
> > width, uint32_t height,
> > int32_t stride, uint32_t
> > format, void *line_0)
> > {
> > - DisplayChannel *display = worker->display_channel;
> > SpiceCanvas *canvas;
> >
> > switch (renderer) {
> > @@ -7541,18 +7399,18 @@ static inline void
> > *create_canvas_for_surface(RedWorker *worker, RedSurface *sur
> > canvas = canvas_create_for_data(width, height, format,
> > line_0, stride,
> > &display->image_cache.base,
> > - &worker->image_surfaces, NULL,
> > NULL, NULL);
> > + &display->image_surfaces, NULL,
> > NULL, NULL);
> > surface->context.top_down = TRUE;
> > surface->context.canvas_draws_on_surface = TRUE;
> > return canvas;
> > #ifdef USE_OPENGL
> > case RED_RENDERER_OGL_PBUF:
> > - canvas = create_ogl_pbuf_context(worker, width, height, stride,
> > + canvas = create_ogl_pbuf_context(display, width, height, stride,
> > SPICE_SURFACE_FMT_DEPTH(format));
> > surface->context.top_down = FALSE;
> > return canvas;
> > case RED_RENDERER_OGL_PIXMAP:
> > - canvas = create_ogl_pixmap_context(worker, width, height, stride,
> > + canvas = create_ogl_pixmap_context(display, width, height, stride,
> >
> > SPICE_SURFACE_FMT_DEPTH(format));
> > surface->context.top_down = FALSE;
> > return canvas;
> > @@ -7586,17 +7444,17 @@ static SurfaceCreateItem *get_surface_create_item(
> >
> > static inline void red_create_surface_item(DisplayChannelClient *dcc, int
> > surface_id)
> > {
> > + DisplayChannel *display = dcc ? DCC_TO_DC(dcc) : NULL;
> > RedSurface *surface;
> > SurfaceCreateItem *create;
> > - RedWorker *worker = dcc ? DCC_TO_WORKER(dcc) : NULL;
> > uint32_t flags = is_primary_surface(DCC_TO_DC(dcc), surface_id) ?
> > SPICE_SURFACE_FLAGS_PRIMARY : 0;
> >
> > /* don't send redundant create surface commands to client */
> > - if (!dcc || worker->display_channel->common.during_target_migrate ||
> > + if (!dcc || display->common.during_target_migrate ||
>
> I would add a check for a NULL display here.
>
> > dcc->surface_client_created[surface_id]) {
> > return;
> > }
> > - surface = &worker->surfaces[surface_id];
> > + surface = &display->surfaces[surface_id];
> > create = get_surface_create_item(RED_CHANNEL_CLIENT(dcc)->channel,
> > surface_id, surface->context.width, surface->context.height,
> > surface->context.format, flags);
> > @@ -7604,33 +7462,32 @@ static inline void
> > red_create_surface_item(DisplayChannelClient *dcc, int surfac
> > red_channel_client_pipe_add(RED_CHANNEL_CLIENT(dcc), &create
> > ->pipe_item);
> > }
> >
> > -static void red_worker_create_surface_item(RedWorker *worker, int
> > surface_id)
> > +static void red_worker_create_surface_item(DisplayChannel *display, int
> > surface_id)
> > {
> > DisplayChannelClient *dcc;
> > RingItem *item, *next;
> >
> > - FOREACH_DCC(worker->display_channel, item, next, dcc) {
> > + FOREACH_DCC(display, item, next, dcc) {
> > red_create_surface_item(dcc, surface_id);
> > }
> > }
> >
> >
> > -static void red_worker_push_surface_image(RedWorker *worker, int
> > surface_id)
> > +static void red_worker_push_surface_image(DisplayChannel *display, int
> > surface_id)
> > {
> > DisplayChannelClient *dcc;
> > RingItem *item, *next;
> >
> > - FOREACH_DCC(worker->display_channel, item, next, dcc) {
> > + FOREACH_DCC(display, item, next, dcc) {
> > red_push_surface_image(dcc, surface_id);
> > }
> > }
> >
> > -static inline void red_create_surface(RedWorker *worker, uint32_t
> > surface_id, uint32_t width,
> > - uint32_t height, int32_t stride,
> > uint32_t format,
> > - void *line_0, int data_is_valid, int
> > send_client)
> > +static void red_create_surface(DisplayChannel *display, uint32_t
> > surface_id, uint32_t width,
> > + uint32_t height, int32_t stride, uint32_t
> > format,
> > + void *line_0, int data_is_valid, int
> > send_client)
> > {
> > - RedSurface *surface = &worker->surfaces[surface_id];
> > - DisplayChannel*display = worker->display_channel;
> > + RedSurface *surface = &display->surfaces[surface_id];
> > uint32_t i;
> >
> > spice_warn_if(surface->context.canvas);
> > @@ -7656,7 +7513,7 @@ static inline void red_create_surface(RedWorker
> > *worker, uint32_t surface_id, ui
> > region_init(&surface->draw_dirty_region);
> > surface->refs = 1;
> > if (display->renderer != RED_RENDERER_INVALID) {
> > - surface->context.canvas = create_canvas_for_surface(worker,
> > surface, display->renderer,
> > + surface->context.canvas = create_canvas_for_surface(display,
> > surface, display->renderer,
> > width, height,
> > stride,
> > surface
> > ->context.format, line_0);
> > if (!surface->context.canvas) {
> > @@ -7664,24 +7521,24 @@ static inline void red_create_surface(RedWorker
> > *worker, uint32_t surface_id, ui
> > }
> >
> > if (send_client) {
> > - red_worker_create_surface_item(worker, surface_id);
> > + red_worker_create_surface_item(display, surface_id);
> > if (data_is_valid) {
> > - red_worker_push_surface_image(worker, surface_id);
> > + red_worker_push_surface_image(display, surface_id);
> > }
> > }
> > return;
> > }
> >
> > for (i = 0; i < display->num_renderers; i++) {
> > - surface->context.canvas = create_canvas_for_surface(worker,
> > surface, display->renderers[i],
> > + surface->context.canvas = create_canvas_for_surface(display,
> > surface, display->renderers[i],
> > width, height,
> > stride,
> > surface
> > ->context.format, line_0);
> > if (surface->context.canvas) { //no need canvas check
> > display->renderer = display->renderers[i];
> > if (send_client) {
> > - red_worker_create_surface_item(worker, surface_id);
> > + red_worker_create_surface_item(display, surface_id);
> > if (data_is_valid) {
> > - red_worker_push_surface_image(worker, surface_id);
> > + red_worker_push_surface_image(display, surface_id);
> > }
> > }
> > return;
> > @@ -7828,8 +7685,7 @@ static int
> > display_channel_client_wait_for_init(DisplayChannelClient *dcc)
> >
> > static void on_new_display_channel_client(DisplayChannelClient *dcc)
> > {
> > - DisplayChannel *display_channel = DCC_TO_DC(dcc);
> > - RedWorker *worker = display_channel->common.worker;
> > + DisplayChannel *display = DCC_TO_DC(dcc);
> > RedChannelClient *rcc = RED_CHANNEL_CLIENT(dcc);
> >
> > red_channel_client_push_set_ack(RED_CHANNEL_CLIENT(dcc));
> > @@ -7842,8 +7698,8 @@ static void
> > on_new_display_channel_client(DisplayChannelClient *dcc)
> > return;
> > }
> > red_channel_client_ack_zero_messages_window(RED_CHANNEL_CLIENT(dcc));
> > - if (worker->surfaces[0].context.canvas) {
> > - red_current_flush(worker, 0);
> > + if (display->surfaces[0].context.canvas) {
> > + red_current_flush(display, 0);
> > push_new_primary_surface(dcc);
> > red_push_surface_image(dcc, 0);
> > dcc_push_monitors_config(dcc);
> > @@ -8577,7 +8433,7 @@ static void
> > display_channel_release_item(RedChannelClient *rcc, PipeItem *item,
> > }
> > }
> >
> > -static void display_channel_create(RedWorker *worker, int migrate)
> > +static void display_channel_create(RedWorker *worker, int migrate, uint32_t
> > n_surfaces)
> > {
> > DisplayChannel *display_channel;
> > ChannelCbs cbs = {
> > @@ -8619,12 +8475,15 @@ static void display_channel_create(RedWorker
> > *worker, int migrate)
> > stat_compress_init(&display_channel->jpeg_alpha_stat,
> > jpeg_alpha_stat_name);
> > stat_compress_init(&display_channel->lz4_stat, lz4_stat_name);
> >
> > + display_channel->n_surfaces = n_surfaces;
> > display_channel->num_renderers = num_renderers;
> > memcpy(display_channel->renderers, renderers, sizeof(display_channel
> > ->renderers));
> > display_channel->renderer = RED_RENDERER_INVALID;
> > - image_cache_init(&display_channel->image_cache);
> > +
> > ring_init(&display_channel->current_list);
> > + image_surface_init(display_channel);
> > drawables_init(display_channel);
> > + image_cache_init(&display_channel->image_cache);
> > stream_init(display_channel);
> > }
> >
> > @@ -8758,14 +8617,13 @@ static void red_connect_cursor(RedWorker *worker,
> > RedClient *client, RedsStream
> >
> > // TODO: why do we check for context.canvas? defer this to after
> > display cc is connected
> > // and test it's canvas? this is just a test to see if there is an
> > active renderer?
> > - if (worker->surfaces[0].context.canvas)
> > + if (display_channel_surface_has_canvas(worker->display_channel, 0))
> > cursor_channel_init(channel, ccc);
> > }
> >
> > static void surface_dirty_region_to_rects(RedSurface *surface,
> > QXLRect *qxl_dirty_rects,
> > - uint32_t num_dirty_rects,
> > - int clear_dirty_region)
> > + uint32_t num_dirty_rects)
> > {
> > QRegion *surface_dirty_region;
> > SpiceRect *dirty_rects;
> > @@ -8774,9 +8632,6 @@ static void surface_dirty_region_to_rects(RedSurface
> > *surface,
> > surface_dirty_region = &surface->draw_dirty_region;
> > dirty_rects = spice_new0(SpiceRect, num_dirty_rects);
> > region_ret_rects(surface_dirty_region, dirty_rects, num_dirty_rects);
> > - if (clear_dirty_region) {
> > - region_clear(surface_dirty_region);
> > - }
> > for (i = 0; i < num_dirty_rects; i++) {
> > qxl_dirty_rects[i].top = dirty_rects[i].top;
> > qxl_dirty_rects[i].left = dirty_rects[i].left;
> > @@ -8786,67 +8641,60 @@ static void surface_dirty_region_to_rects(RedSurface
> > *surface,
> > free(dirty_rects);
> > }
> >
> > -static void handle_dev_update_async(void *opaque, void *payload)
> > +void display_channel_update(DisplayChannel *display,
> > + uint32_t surface_id, const QXLRect *area,
> > uint32_t clear_dirty,
> > + QXLRect **qxl_dirty_rects, uint32_t
> > *num_dirty_rects)
> > {
> > - RedWorker *worker = opaque;
> > - RedWorkerMessageUpdateAsync *msg = payload;
> > SpiceRect rect;
> > - QXLRect *qxl_dirty_rects;
> > - uint32_t num_dirty_rects;
> > RedSurface *surface;
> > - uint32_t surface_id = msg->surface_id;
> > - QXLRect qxl_area = msg->qxl_area;
> > - uint32_t clear_dirty_region = msg->clear_dirty_region;
> >
> > - red_get_rect_ptr(&rect, &qxl_area);
> > - flush_display_commands(worker);
> > + spice_return_if_fail(validate_surface(display, surface_id));
> >
> > - spice_assert(worker->running);
> > + red_get_rect_ptr(&rect, area);
> > + red_update_area(display, &rect, surface_id);
> >
> > - VALIDATE_SURFACE_RET(worker, surface_id);
> > - red_update_area(worker, &rect, surface_id);
> > - if (!worker->qxl->st->qif->update_area_complete) {
> > - return;
> > - }
> > - surface = &worker->surfaces[surface_id];
> > - num_dirty_rects = pixman_region32_n_rects(&surface->draw_dirty_region);
> > - if (num_dirty_rects == 0) {
> > - return;
> > + surface = &display->surfaces[surface_id];
> > + if (!*qxl_dirty_rects) {
> > + *num_dirty_rects = pixman_region32_n_rects(&surface
> > ->draw_dirty_region);
> > + *qxl_dirty_rects = spice_new0(QXLRect, *num_dirty_rects);
> > }
> > - qxl_dirty_rects = spice_new0(QXLRect, num_dirty_rects);
> > - surface_dirty_region_to_rects(surface, qxl_dirty_rects,
> > num_dirty_rects,
> > - clear_dirty_region);
> > - worker->qxl->st->qif->update_area_complete(worker->qxl, surface_id,
> > - qxl_dirty_rects,
> > num_dirty_rects);
> > - free(qxl_dirty_rects);
> > +
> > + surface_dirty_region_to_rects(surface, *qxl_dirty_rects,
> > *num_dirty_rects);
> > + if (clear_dirty)
> > + region_clear(&surface->draw_dirty_region);
> > }
> >
> > -static void handle_dev_update(void *opaque, void *payload)
> > +static void handle_dev_update_async(void *opaque, void *payload)
> > {
> > RedWorker *worker = opaque;
> > - RedWorkerMessageUpdate *msg = payload;
> > - SpiceRect *rect;
> > - RedSurface *surface;
> > - uint32_t surface_id = msg->surface_id;
> > - const QXLRect *qxl_area = msg->qxl_area;
> > - uint32_t num_dirty_rects = msg->num_dirty_rects;
> > - QXLRect *qxl_dirty_rects = msg->qxl_dirty_rects;
> > - uint32_t clear_dirty_region = msg->clear_dirty_region;
> > + RedWorkerMessageUpdateAsync *msg = payload;
> > + QXLRect *qxl_dirty_rects = NULL;
> > + uint32_t num_dirty_rects = 0;
> >
> > - VALIDATE_SURFACE_RET(worker, surface_id);
> > + spice_return_if_fail(worker->running);
> > + spice_return_if_fail(worker->qxl->st->qif->update_area_complete);
> >
> > - rect = spice_new0(SpiceRect, 1);
> > - surface = &worker->surfaces[surface_id];
> > - red_get_rect_ptr(rect, qxl_area);
> > flush_display_commands(worker);
> > + display_channel_update(worker->display_channel,
> > + msg->surface_id, &msg->qxl_area, msg
> > ->clear_dirty_region,
> > + &qxl_dirty_rects, &num_dirty_rects);
> >
> > - spice_assert(worker->running);
> > + worker->qxl->st->qif->update_area_complete(worker->qxl, msg
> > ->surface_id,
> > + qxl_dirty_rects,
> > num_dirty_rects);
> > + free(qxl_dirty_rects);
> > +}
> > +
> > +static void handle_dev_update(void *opaque, void *payload)
> > +{
> > + RedWorker *worker = opaque;
> > + RedWorkerMessageUpdate *msg = payload;
> >
> > - red_update_area(worker, rect, surface_id);
> > - free(rect);
> > + spice_return_if_fail(worker->running);
> >
> > - surface_dirty_region_to_rects(surface, qxl_dirty_rects,
> > num_dirty_rects,
> > - clear_dirty_region);
> > + flush_display_commands(worker);
> > + display_channel_update(worker->display_channel,
> > + msg->surface_id, msg->qxl_area, msg
> > ->clear_dirty_region,
> > + &msg->qxl_dirty_rects, &msg->num_dirty_rects);
> > }
> >
> > static void handle_dev_del_memslot(void *opaque, void *payload)
> > @@ -8859,32 +8707,18 @@ static void handle_dev_del_memslot(void *opaque,
> > void *payload)
> > red_memslot_info_del_slot(&worker->mem_slots, slot_group_id, slot_id);
> > }
> >
> > -/* TODO: destroy_surface_wait, dev_destroy_surface_wait - confusing. one
> > asserts
> > - * surface_id == 0, maybe move the assert upward and merge the two
> > functions? */
> > -static inline void destroy_surface_wait(RedWorker *worker, int surface_id)
> > +void display_channel_destroy_surface_wait(DisplayChannel *display, int
> > surface_id)
> > {
> > - VALIDATE_SURFACE_RET(worker, surface_id);
> > - if (!worker->surfaces[surface_id].context.canvas) {
> > + VALIDATE_SURFACE_RET(display, surface_id);
> > + if (!display->surfaces[surface_id].context.canvas)
> > return;
> > - }
> >
> > - red_handle_depends_on_target_surface(worker, surface_id);
> > - /* note that red_handle_depends_on_target_surface must be called before
> > red_current_clear.
> > + red_handle_depends_on_target_surface(display, surface_id);
> > + /* note that red_handle_depends_on_target_surface must be called before
> > current_clear.
> > otherwise "current" will hold items that other drawables may depend
> > on, and then
> > - red_current_clear will remove them from the pipe. */
> > - red_current_clear(worker, surface_id);
> > - red_clear_surface_drawables_from_pipes(worker, surface_id, TRUE);
> > -}
> > -
> > -static void dev_destroy_surface_wait(RedWorker *worker, uint32_t
> > surface_id)
> > -{
> > - spice_assert(surface_id == 0);
> > -
> > - flush_all_qxl_commands(worker);
> > -
> > - if (worker->surfaces[0].context.canvas) {
> > - destroy_surface_wait(worker, 0);
> > - }
> > + current_clear will remove them from the pipe. */
> > + current_clear(display, surface_id);
> > + red_clear_surface_drawables_from_pipes(display, surface_id, TRUE);
> > }
> >
> > static void handle_dev_destroy_surface_wait(void *opaque, void *payload)
> > @@ -8892,48 +8726,47 @@ static void handle_dev_destroy_surface_wait(void
> > *opaque, void *payload)
> > RedWorkerMessageDestroySurfaceWait *msg = payload;
> > RedWorker *worker = opaque;
> >
> > - dev_destroy_surface_wait(worker, msg->surface_id);
> > + spice_return_if_fail(msg->surface_id == 0);
> > +
> > + flush_all_qxl_commands(worker);
> > + display_channel_destroy_surface_wait(worker->display_channel, msg
> > ->surface_id);
> > }
> >
> > /* called upon device reset */
> >
> > /* TODO: split me*/
> > -static inline void dev_destroy_surfaces(RedWorker *worker)
> > +void display_channel_destroy_surfaces(DisplayChannel *display)
> > {
> > - DisplayChannel *display = worker->display_channel;
> > int i;
> >
> > spice_debug(NULL);
> > - flush_all_qxl_commands(worker);
> > //to handle better
> > for (i = 0; i < NUM_SURFACES; ++i) {
> > - if (worker->surfaces[i].context.canvas) {
> > - destroy_surface_wait(worker, i);
> > - if (worker->surfaces[i].context.canvas) {
> > - red_surface_unref(worker, i);
> > + if (display->surfaces[i].context.canvas) {
> > + display_channel_destroy_surface_wait(display, i);
> > + if (display->surfaces[i].context.canvas) {
> > + display_channel_surface_unref(display, i);
> > }
> > - spice_assert(!worker->surfaces[i].context.canvas);
> > + spice_assert(!display->surfaces[i].context.canvas);
> > }
> > }
> > - spice_assert(ring_is_empty(&display->streams));
> > + spice_warn_if_fail(ring_is_empty(&display->streams));
> >
> > - if (display_is_connected(worker)) {
> > - red_channel_pipes_add_type(RED_CHANNEL(worker->display_channel),
> > - PIPE_ITEM_TYPE_INVAL_PALETTE_CACHE);
> > - red_pipes_add_verb(RED_CHANNEL(worker->display_channel),
> > - SPICE_MSG_DISPLAY_STREAM_DESTROY_ALL);
> > + if (red_channel_is_connected(RED_CHANNEL(display))) {
> > + red_channel_pipes_add_type(RED_CHANNEL(display),
> > PIPE_ITEM_TYPE_INVAL_PALETTE_CACHE);
> > + red_pipes_add_verb(RED_CHANNEL(display),
> > SPICE_MSG_DISPLAY_STREAM_DESTROY_ALL);
> > }
> >
> > - red_display_clear_glz_drawables(worker->display_channel);
> > -
> > - cursor_channel_reset(worker->cursor_channel);
> > + red_display_clear_glz_drawables(display);
> > }
> >
> > static void handle_dev_destroy_surfaces(void *opaque, void *payload)
> > {
> > RedWorker *worker = opaque;
> >
> > - dev_destroy_surfaces(worker);
> > + flush_all_qxl_commands(worker);
> > + display_channel_destroy_surfaces(worker->display_channel);
> > + cursor_channel_reset(worker->cursor_channel);
> > }
> >
> > static void display_update_monitors_config(DisplayChannel *display,
> > @@ -8958,13 +8791,12 @@ static void
> > red_worker_push_monitors_config(RedWorker *worker)
> > }
> > }
> >
> > -static void set_monitors_config_to_primary(RedWorker *worker)
> > +static void set_monitors_config_to_primary(DisplayChannel *display)
> > {
> > - DrawContext *context = &worker->surfaces[0].context;
> > - DisplayChannel *display = worker->display_channel;
> > + DrawContext *context = &display->surfaces[0].context;
> > QXLHead head = { 0, };
> >
> > - spice_return_if_fail(worker->surfaces[0].context.canvas);
> > + spice_return_if_fail(display->surfaces[0].context.canvas);
> >
> > if (display->monitors_config)
> > monitors_config_unref(display->monitors_config);
> > @@ -8977,6 +8809,7 @@ static void set_monitors_config_to_primary(RedWorker
> > *worker)
> > static void dev_create_primary_surface(RedWorker *worker, uint32_t
> > surface_id,
> > QXLDevSurfaceCreate surface)
> > {
> > + DisplayChannel *display = worker->display_channel;
> > uint8_t *line_0;
> > int error;
> >
> > @@ -9001,9 +8834,9 @@ static void dev_create_primary_surface(RedWorker
> > *worker, uint32_t surface_id,
> > line_0 -= (int32_t)(surface.stride * (surface.height -1));
> > }
> >
> > - red_create_surface(worker, 0, surface.width, surface.height,
> > surface.stride, surface.format,
> > + red_create_surface(display, 0, surface.width, surface.height,
> > surface.stride, surface.format,
> > line_0, surface.flags & QXL_SURF_FLAG_KEEP_DATA,
> > TRUE);
> > - set_monitors_config_to_primary(worker);
> > + set_monitors_config_to_primary(display);
> >
> > if (display_is_connected(worker) && !worker->display_channel
> > ->common.during_target_migrate) {
> > /* guest created primary, so it will (hopefully) send a
> > monitors_config
> > @@ -9027,25 +8860,25 @@ static void handle_dev_create_primary_surface(void
> > *opaque, void *payload)
> > dev_create_primary_surface(worker, msg->surface_id, msg->surface);
> > }
> >
> > -static void dev_destroy_primary_surface(RedWorker *worker, uint32_t
> > surface_id)
> > +static void destroy_primary_surface(RedWorker *worker, uint32_t surface_id)
> > {
> > DisplayChannel *display = worker->display_channel;
> >
> > - VALIDATE_SURFACE_RET(worker, surface_id);
> > + VALIDATE_SURFACE_RET(display, surface_id);
> > spice_warn_if(surface_id != 0);
> >
> > spice_debug(NULL);
> > - if (!worker->surfaces[surface_id].context.canvas) {
> > + if (!display->surfaces[surface_id].context.canvas) {
> > spice_warning("double destroy of primary surface");
> > return;
> > }
> >
> > flush_all_qxl_commands(worker);
> > - dev_destroy_surface_wait(worker, 0);
> > - red_surface_unref(worker, 0);
> > - spice_warn_if_fail(ring_is_empty(&display->streams));
> > + display_channel_destroy_surface_wait(display, 0);
> > + display_channel_surface_unref(display, 0);
> >
> > - spice_assert(!worker->surfaces[surface_id].context.canvas);
> > + spice_warn_if_fail(ring_is_empty(&display->streams));
> > + spice_warn_if_fail(!display->surfaces[surface_id].context.canvas);
> >
> > cursor_channel_reset(worker->cursor_channel);
> > }
> > @@ -9056,7 +8889,7 @@ static void handle_dev_destroy_primary_surface(void
> > *opaque, void *payload)
> > RedWorker *worker = opaque;
> > uint32_t surface_id = msg->surface_id;
> >
> > - dev_destroy_primary_surface(worker, surface_id);
> > + destroy_primary_surface(worker, surface_id);
> > }
> >
> > static void handle_dev_destroy_primary_surface_async(void *opaque, void
> > *payload)
> > @@ -9065,16 +8898,16 @@ static void
> > handle_dev_destroy_primary_surface_async(void *opaque, void *payload
> > RedWorker *worker = opaque;
> > uint32_t surface_id = msg->surface_id;
> >
> > - dev_destroy_primary_surface(worker, surface_id);
> > + destroy_primary_surface(worker, surface_id);
> > }
> >
> > -static void flush_all_surfaces(RedWorker *worker)
> > +static void flush_all_surfaces(DisplayChannel *display)
> > {
> > int x;
> >
> > for (x = 0; x < NUM_SURFACES; ++x) {
> > - if (worker->surfaces[x].context.canvas) {
> > - red_current_flush(worker, x);
> > + if (display->surfaces[x].context.canvas) {
> > + red_current_flush(display, x);
> > }
> > }
> > }
> > @@ -9082,7 +8915,7 @@ static void flush_all_surfaces(RedWorker *worker)
> > static void dev_flush_surfaces(RedWorker *worker)
> > {
> > flush_all_qxl_commands(worker);
> > - flush_all_surfaces(worker);
> > + flush_all_surfaces(worker->display_channel);
> > }
> >
> > static void handle_dev_flush_surfaces_async(void *opaque, void *payload)
> > @@ -9100,7 +8933,7 @@ static void handle_dev_stop(void *opaque, void
> > *payload)
> > spice_assert(worker->running);
> > worker->running = FALSE;
> > red_display_clear_glz_drawables(worker->display_channel);
> > - flush_all_surfaces(worker);
> > + flush_all_surfaces(worker->display_channel);
> > /* todo: when the waiting is expected to take long (slow connection and
> > * overloaded pipe), don't wait, and in case of migration,
> > * purge the pipe, send destroy_all_surfaces
> > @@ -9229,14 +9062,16 @@ static void
> > handle_dev_destroy_surface_wait_async(void *opaque, void *payload)
> > RedWorkerMessageDestroySurfaceWaitAsync *msg = payload;
> > RedWorker *worker = opaque;
> >
> > - dev_destroy_surface_wait(worker, msg->surface_id);
> > + display_channel_destroy_surface_wait(worker->display_channel, msg
> > ->surface_id);
> > }
> >
> > static void handle_dev_destroy_surfaces_async(void *opaque, void *payload)
> > {
> > RedWorker *worker = opaque;
> >
> > - dev_destroy_surfaces(worker);
> > + flush_all_qxl_commands(worker);
> > + display_channel_destroy_surfaces(worker->display_channel);
> > + cursor_channel_reset(worker->cursor_channel);
> > }
> >
> > static void handle_dev_create_primary_surface_async(void *opaque, void
> > *payload)
> > @@ -9750,7 +9585,6 @@ RedWorker* red_worker_new(QXLInstance *qxl,
> > RedDispatcher *red_dispatcher)
> > worker->jpeg_state = jpeg_state;
> > worker->zlib_glz_state = zlib_glz_state;
> > worker->driver_cap_monitors_config = 0;
> > - image_surface_init(worker);
> > stat_init(&worker->add_stat, add_stat_name);
> > stat_init(&worker->exclude_stat, exclude_stat_name);
> > stat_init(&worker->__exclude_stat, __exclude_stat_name);
> > @@ -9779,7 +9613,6 @@ RedWorker* red_worker_new(QXLInstance *qxl,
> > RedDispatcher *red_dispatcher)
> > init_info.internal_groupslot_id);
> >
> > spice_warn_if(init_info.n_surfaces > NUM_SURFACES);
> > - worker->n_surfaces = init_info.n_surfaces;
> >
> > red_init_quic(worker);
> > red_init_lz(worker);
> > @@ -9792,7 +9625,7 @@ RedWorker* red_worker_new(QXLInstance *qxl,
> > RedDispatcher *red_dispatcher)
> >
> > worker->cursor_channel = cursor_channel_new(worker);
> > // TODO: handle seemless migration. Temp, setting migrate to FALSE
> > - display_channel_create(worker, FALSE);
> > + display_channel_create(worker, FALSE, init_info.n_surfaces);
> >
> > return worker;
> > }
> > diff --git a/server/red_worker.h b/server/red_worker.h
> > index 2995b8f..3604dfd 100644
> > --- a/server/red_worker.h
> > +++ b/server/red_worker.h
> > @@ -22,6 +22,7 @@
> > #include <errno.h>
> > #include "red_common.h"
> > #include "red_dispatcher.h"
> > +#include "red_parse_qxl.h"
> >
> > typedef struct RedWorker RedWorker;
> >
> > @@ -108,6 +109,7 @@ bool red_worker_run(RedWorker *worker);
> > QXLInstance* red_worker_get_qxl(RedWorker *worker);
> > RedChannel* red_worker_get_cursor_channel(RedWorker *worker);
> > RedChannel* red_worker_get_display_channel(RedWorker *worker);
> > +void red_worker_print_stats(RedWorker *worker);
> >
> > RedChannel *red_worker_new_channel(RedWorker *worker, int size,
> > const char *name,
> > --
> > 2.4.3
> >
> > _______________________________________________
> > Spice-devel mailing list
> > Spice-devel at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/spice-devel
>
> This patch is HUGE!
> I agree with Joanthon about the need of some safety check in
> DCC_TO_DC.
Just for the record, this was Marc-Andre's comment, not mine ;)
> I've suggested to small changes to keep the checks as it
> was before. Removing the checks could come in a different patch (in
> the future).
> Also, there are a few "to do" or "fix me" comments that would be
> better to have them replaced by "TODO" or "FIXME".
> I've done some tests with both Windows and Linux guests and the patch
> seems sane. So, if the comments are addressed and with a better commit
> message, ACK.
More information about the Spice-devel
mailing list