[Spice-devel] [RFC v4 24/62] server/red_worker: split Surfaces from RedWorker
Marc-André Lureau
marcandre.lureau at gmail.com
Mon May 2 16:52:12 PDT 2011
On Tue, Apr 26, 2011 at 12:54 PM, Alon Levy <alevy at redhat.com> wrote:
> Split the tree (current_list) and the surfaces out from RedWorker.
> This patch is technical, basically a lot of propogation of "Surfaces
> *surfaces" parameter, and otherwise changing s/worker/worker->surfaces/.
>
> Another possible name for Surfaces is RenderingState.
That sounds better. Why did you prefer Surfaces?
> In later patches there will be a multiplicity of surfaces:
> 0 | 1
> n >=1 | n
>
> The first instance is embedded in RedWorker. The later are embdedded
> in the DisplayChannelClient which has not been introduced yet.
ok
> The surfaces backing store needs to be separate for the main Surfaces
> instance and for the rest. For the main it needs to be vram, since
> the guest will read from there after an UPDATE_AREA. For the others
> it will be host memory.
>
> A multiplicity of rendering trees and surfaces makes having a separate
> pipe easy, since we can replace a number of operations in the pipe with
> their equivalent without effecting the other clients. Such a replacement
> may require rendering the operations, so it requires the surfaces to be
> in sync with the tree for that client.
>
> It might be possible to avoid some of this overhead later - in particular,
> possibly having groups of clients associated with the same Surfaces, and
> only create a copy on change. The current implementation is the simplest,
> and it doesn't cost anything extra for a single client.
>
> Many function signatures are changed already to add Surfaces as an
> additional paramater instead of using worker->surfaces, this is in
> preparation for the next patches where Surfaces instances multiply.
Surfaces could reference the worker, that way we can make functions
only take a "Surfaces"
otherwise, ACK, the patch is straightforward.
> ---
> server/red_worker.c | 536 ++++++++++++++++++++++++++++-----------------------
> 1 files changed, 295 insertions(+), 241 deletions(-)
>
> diff --git a/server/red_worker.c b/server/red_worker.c
> index ebeb4af..275bfca 100644
> --- a/server/red_worker.c
> +++ b/server/red_worker.c
> @@ -562,6 +562,7 @@ typedef struct CommonChannel {
> uint8_t recv_buf[RECIVE_BUF_SIZE];
> } CommonChannel;
>
> +typedef struct Surfaces Surfaces;
>
> struct DisplayChannel {
> CommonChannel common; // Must be the first thing
> @@ -806,6 +807,24 @@ typedef struct ItemTrace {
> #define NUM_DRAWABLES 1000
> #define NUM_CURSORS 100
>
> +struct Surfaces {
> + Ring current_list;
> + uint32_t current_size;
> + uint32_t drawable_count;
> + uint32_t transparent_count;
> +
> + uint32_t shadows_count;
> + uint32_t containers_count;
> +
> + RedSurface surfaces[NUM_SURFACES];
> + uint32_t n_surfaces;
> + SpiceImageSurfaces image_surfaces;
> +
> +#ifdef PIPE_DEBUG
> + uint32_t last_id;
> +#endif
> +};
> +
> typedef struct RedWorker {
> EventListener dev_listener;
> DisplayChannel *display_channel;
> @@ -823,17 +842,7 @@ typedef struct RedWorker {
> uint32_t renderers[RED_MAX_RENDERERS];
> uint32_t renderer;
>
> - RedSurface surfaces[NUM_SURFACES];
> - uint32_t n_surfaces;
> - SpiceImageSurfaces image_surfaces;
> -
> - Ring current_list;
> - uint32_t current_size;
> - uint32_t drawable_count;
> - uint32_t transparent_count;
> -
> - uint32_t shadows_count;
> - uint32_t containers_count;
> + Surfaces surfaces;
>
> uint32_t bits_unique;
>
> @@ -880,9 +889,6 @@ typedef struct RedWorker {
> ZlibData zlib_data;
> ZlibEncoder *zlib;
>
> -#ifdef PIPE_DEBUG
> - uint32_t last_id;
> -#endif
> #ifdef RED_WORKER_STAT
> stat_info_t add_stat;
> stat_info_t exclude_stat;
> @@ -911,17 +917,20 @@ typedef struct BitmapData {
> SpiceRect lossy_rect;
> } BitmapData;
>
> -static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable);
> -static void red_current_flush(RedWorker *worker, int surface_id);
> +static void red_draw_qxl_drawable(RedWorker *worker, Surfaces *surfaces, Drawable *drawable);
> +static void red_current_flush(RedWorker *worker, Surfaces *surfaces, int surface_id);
> #ifdef DRAW_ALL
> #define red_update_area(worker, rect, surface_id)
> -#define red_draw_drawable(worker, item)
> +#define red_update_area_surfaces(worker, surfaces, rect, surface_id)
> +#define red_draw_drawable(worker, surfaces, item)
> #else
> -static void red_draw_drawable(RedWorker *worker, Drawable *item);
> +static void red_draw_drawable(RedWorker *worker, Surfaces *surfaces, Drawable *item);
> static void red_update_area(RedWorker *worker, const SpiceRect *area, int surface_id);
> +static void red_update_area_surfaces(RedWorker *worker, Surfaces *surfaces,
> + const SpiceRect *area, int surface_id);
> #endif
> static void red_release_cursor(RedWorker *worker, CursorItem *cursor);
> -static inline void release_drawable(RedWorker *worker, Drawable *item);
> +static inline void release_drawable(RedWorker *worker, Surfaces *surfaces, Drawable *item);
> static void red_display_release_stream(DisplayChannel *display, StreamAgent *agent);
> static inline void red_detach_stream(RedWorker *worker, Stream *stream);
> static void red_stop_stream(RedWorker *worker, Stream *stream);
> @@ -1023,7 +1032,7 @@ static void print_compress_stats(DisplayChannel *display_channel)
>
> #endif
>
> -static inline int is_primary_surface(RedWorker *worker, uint32_t surface_id)
> +static inline int is_primary_surface(uint32_t surface_id)
> {
> if (surface_id == 0) {
> return TRUE;
> @@ -1031,15 +1040,15 @@ static inline int is_primary_surface(RedWorker *worker, uint32_t surface_id)
> return FALSE;
> }
>
> -static inline void __validate_surface(RedWorker *worker, uint32_t surface_id)
> +static inline void __validate_surface(Surfaces *surfaces, uint32_t surface_id)
> {
> - PANIC_ON(surface_id >= worker->n_surfaces);
> + PANIC_ON(surface_id >= surfaces->n_surfaces);
> }
>
> -static inline void validate_surface(RedWorker *worker, uint32_t surface_id)
> +static inline void validate_surface(Surfaces *surfaces, uint32_t surface_id)
> {
> - PANIC_ON(surface_id >= worker->n_surfaces);
> - PANIC_ON(!worker->surfaces[surface_id].context.canvas);
> + PANIC_ON(surface_id >= surfaces->n_surfaces);
> + PANIC_ON(!surfaces->surfaces[surface_id].context.canvas);
> }
>
> char *draw_type_to_str(uint8_t type)
> @@ -1159,7 +1168,7 @@ static inline void red_handle_drawable_surfaces_client_synced(RedWorker *worker,
> continue;
> }
> red_create_surface_item(worker, surface_id);
> - red_current_flush(worker, surface_id);
> + red_current_flush(worker, &worker->surfaces, surface_id);
> red_add_surface_image(worker, surface_id);
> }
> }
> @@ -1169,7 +1178,7 @@ static inline void red_handle_drawable_surfaces_client_synced(RedWorker *worker,
> }
>
> red_create_surface_item(worker, drawable->surface_id);
> - red_current_flush(worker, drawable->surface_id);
> + red_current_flush(worker, &worker->surfaces, drawable->surface_id);
> red_add_surface_image(worker, drawable->surface_id);
> }
>
> @@ -1230,7 +1239,7 @@ static inline PipeItem *red_pipe_get_tail(RedWorker *worker)
> return (PipeItem*)ring_get_tail(&worker->display_channel->common.base.rcc->pipe);
> }
>
> -static inline void red_destroy_surface(RedWorker *worker, uint32_t surface_id);
> +static inline void red_destroy_surface(RedWorker *worker, Surfaces *surfaces, uint32_t surface_id);
>
> static inline void red_pipe_remove_drawable(RedWorker *worker, Drawable *drawable)
> {
> @@ -1266,10 +1275,10 @@ static void release_image_item(ImageItem *item)
> }
> }
>
> -static void release_upgrade_item(RedWorker* worker, UpgradeItem *item)
> +static void release_upgrade_item(RedWorker* worker, Surfaces *surfaces, UpgradeItem *item)
> {
> if (!--item->refs) {
> - release_drawable(worker, item->drawable);
> + release_drawable(worker, surfaces, item->drawable);
> free(item->rects);
> free(item);
> }
> @@ -1337,7 +1346,7 @@ static void drawables_init(RedWorker *worker)
> }
>
>
> -static void red_reset_stream_trace(RedWorker *worker);
> +static void red_reset_stream_trace(RedWorker *worker, Surfaces *surfaces);
>
> static SurfaceDestroyItem *get_surface_destroy_item(RedChannel *channel,
> uint32_t surface_id)
> @@ -1369,14 +1378,15 @@ static inline void red_destroy_surface_item(RedWorker *worker, uint32_t surface_
> red_channel_client_pipe_add(channel->rcc, &destroy->pipe_item);
> }
>
> -static inline void red_destroy_surface(RedWorker *worker, uint32_t surface_id)
> +static inline void red_destroy_surface(RedWorker *worker, Surfaces *surfaces,
> + uint32_t surface_id)
> {
> - RedSurface *surface = &worker->surfaces[surface_id];
> + RedSurface *surface = &surfaces->surfaces[surface_id];
>
> if (!--surface->refs) {
> // only primary surface streams are supported
> if (surface_id == 0) {
> - red_reset_stream_trace(worker);
> + red_reset_stream_trace(worker, surfaces);
> }
> ASSERT(surface->context.canvas);
>
> @@ -1396,12 +1406,12 @@ static inline void red_destroy_surface(RedWorker *worker, uint32_t surface_id)
> }
> }
>
> -static inline void set_surface_release_info(RedWorker *worker, uint32_t surface_id, int is_create,
> +static inline void set_surface_release_info(Surfaces *surfaces, uint32_t surface_id, int is_create,
> QXLReleaseInfo *release_info, uint32_t group_id)
> {
> RedSurface *surface;
>
> - surface = &worker->surfaces[surface_id];
> + surface = &surfaces->surfaces[surface_id];
>
> if (is_create) {
> surface->create.info = release_info;
> @@ -1435,7 +1445,8 @@ static void remove_depended_item(DependItem *item)
> ring_remove(&item->ring_item);
> }
>
> -static inline void red_dec_surfaces_drawable_dependencies(RedWorker *worker, Drawable *drawable)
> +static inline void red_dec_surfaces_drawable_dependencies(RedWorker *worker,
> + Surfaces *surfaces, Drawable *drawable)
> {
> int x;
> int surface_id;
> @@ -1445,7 +1456,7 @@ static inline void red_dec_surfaces_drawable_dependencies(RedWorker *worker, Dra
> if (surface_id == -1) {
> continue;
> }
> - red_destroy_surface(worker, surface_id);
> + red_destroy_surface(worker, surfaces, surface_id);
> }
> }
>
> @@ -1462,7 +1473,7 @@ static void remove_drawable_dependencies(RedWorker *worker, Drawable *drawable)
> }
> }
>
> -static inline void release_drawable(RedWorker *worker, Drawable *item)
> +static inline void release_drawable(RedWorker *worker, Surfaces *surfaces, Drawable *item)
> {
> if (!--item->refs) {
> ASSERT(!item->stream);
> @@ -1470,8 +1481,8 @@ static inline void release_drawable(RedWorker *worker, Drawable *item)
> region_destroy(&item->tree_item.base.rgn);
>
> remove_drawable_dependencies(worker, item);
> - red_dec_surfaces_drawable_dependencies(worker, item);
> - red_destroy_surface(worker, item->surface_id);
> + red_dec_surfaces_drawable_dependencies(worker, surfaces, item);
> + red_destroy_surface(worker, surfaces, item->surface_id);
>
> if (item->red_glz_drawable) {
> item->red_glz_drawable->drawable = NULL;
> @@ -1482,7 +1493,7 @@ static inline void release_drawable(RedWorker *worker, Drawable *item)
> }
> }
>
> -static inline void remove_shadow(RedWorker *worker, DrawItem *item)
> +static inline void remove_shadow(Surfaces *surfaces, DrawItem *item)
> {
> Shadow *shadow;
>
> @@ -1495,19 +1506,19 @@ static inline void remove_shadow(RedWorker *worker, DrawItem *item)
> region_destroy(&shadow->base.rgn);
> region_destroy(&shadow->on_hold);
> free(shadow);
> - worker->shadows_count--;
> + surfaces->shadows_count--;
> }
>
> -static inline void current_remove_container(RedWorker *worker, Container *container)
> +static inline void current_remove_container(Surfaces *surfaces, Container *container)
> {
> ASSERT(ring_is_empty(&container->items));
> - worker->containers_count--;
> + surfaces->containers_count--;
> ring_remove(&container->base.siblings_link);
> region_destroy(&container->base.rgn);
> free(container);
> }
>
> -static inline void container_cleanup(RedWorker *worker, Container *container)
> +static inline void container_cleanup(Surfaces *surfaces, Container *container)
> {
> while (container && container->items.next == container->items.prev) {
> Container *next = container->base.container;
> @@ -1518,7 +1529,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(surfaces, container);
> container = next;
> }
> }
> @@ -1541,12 +1552,12 @@ static inline void red_add_item_trace(RedWorker *worker, Drawable *item)
> trace->dest_area = item->red_drawable->bbox;
> }
>
> -static void surface_flush(RedWorker *worker, int surface_id, SpiceRect *rect)
> +static void surface_flush(RedWorker *worker, Surfaces *surfaces, int surface_id, SpiceRect *rect)
> {
> - red_update_area(worker, rect, surface_id);
> + red_update_area_surfaces(worker, surfaces, rect, surface_id);
> }
>
> -static void red_flush_source_surfaces(RedWorker *worker, Drawable *drawable)
> +static void red_flush_source_surfaces(RedWorker *worker, Surfaces *surfaces, Drawable *drawable)
> {
> int x;
> int surface_id;
> @@ -1555,38 +1566,40 @@ static void red_flush_source_surfaces(RedWorker *worker, Drawable *drawable)
> surface_id = drawable->surfaces_dest[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(worker, surfaces, surface_id,
> + &drawable->red_drawable->surfaces_rects[x]);
> }
> }
> }
>
> -static inline void current_remove_drawable(RedWorker *worker, Drawable *item)
> +static inline void current_remove_drawable(RedWorker *worker, Surfaces *surfaces,
> + Drawable *item)
> {
> - worker->drawable_count--;
> + surfaces->drawable_count--;
>
> if (item->tree_item.effect != QXL_EFFECT_OPAQUE) {
> - worker->transparent_count--;
> + surfaces->transparent_count--;
> }
> if (item->stream) {
> red_detach_stream(worker, item->stream);
> } else {
> red_add_item_trace(worker, item);
> }
> - remove_shadow(worker, &item->tree_item);
> + remove_shadow(surfaces, &item->tree_item);
> ring_remove(&item->tree_item.base.siblings_link);
> ring_remove(&item->list_link);
> ring_remove(&item->surface_list_link);
> - release_drawable(worker, item);
> - worker->current_size--;
> + release_drawable(worker, surfaces, item);
> + surfaces->current_size--;
> }
>
> -static void remove_drawable(RedWorker *worker, Drawable *item)
> +static void remove_drawable(RedWorker *worker, Surfaces *surfaces, Drawable *item)
> {
> red_pipe_remove_drawable(worker, item);
> - current_remove_drawable(worker, item);
> + current_remove_drawable(worker, surfaces, item);
> }
>
> -static inline void current_remove(RedWorker *worker, TreeItem *item)
> +static inline void current_remove(RedWorker *worker, Surfaces *surfaces, TreeItem *item)
> {
> TreeItem *now = item;
>
> @@ -1596,7 +1609,7 @@ static inline void current_remove(RedWorker *worker, TreeItem *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(worker, surfaces, SPICE_CONTAINEROF(now, Drawable, tree_item));
> } else {
> Container *container = (Container *)now;
>
> @@ -1607,7 +1620,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(surfaces, container);
> }
> if (now == item) {
> return;
> @@ -1659,13 +1672,13 @@ static void current_tree_for_each(RedWorker *worker, Ring *ring, void (*f)(TreeI
> }
> }
>
> -static void red_current_clear(RedWorker *worker, int surface_id)
> +static void red_current_clear(RedWorker *worker, Surfaces *surfaces, int surface_id)
> {
> RingItem *ring_item;
>
> - while ((ring_item = ring_get_head(&worker->surfaces[surface_id].current))) {
> + while ((ring_item = ring_get_head(&surfaces->surfaces[surface_id].current))) {
> TreeItem *now = SPICE_CONTAINEROF(ring_item, TreeItem, siblings_link);
> - current_remove(worker, now);
> + current_remove(worker, surfaces, now);
> }
> }
>
> @@ -1923,7 +1936,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,
> +static void exclude_region(RedWorker *worker, Surfaces *surfaces, Ring *ring,
> + RingItem *ring_item, QRegion *rgn,
> TreeItem **last, Drawable *frame_candidate)
> {
> #ifdef RED_WORKER_STAT
> @@ -1952,7 +1966,7 @@ static void exclude_region(RedWorker *worker, Ring *ring, RingItem *ring_item, Q
> ASSERT(now->type != TREE_ITEM_TYPE_SHADOW);
> ring_item = now->siblings_link.prev;
> print_base_item("EXCLUDE_REMOVE", now);
> - current_remove(worker, now);
> + current_remove(worker, surfaces, now);
> if (last && *last == now) {
> *last = (TreeItem *)ring_next(ring, ring_item);
> }
> @@ -1985,12 +1999,12 @@ static void exclude_region(RedWorker *worker, Ring *ring, RingItem *ring_item, Q
> }
> }
>
> -static inline Container *__new_container(RedWorker *worker, DrawItem *item)
> +static inline Container *__new_container(Surfaces *surfaces, DrawItem *item)
> {
> Container *container = spice_new(Container, 1);
> - worker->containers_count++;
> + surfaces->containers_count++;
> #ifdef PIPE_DEBUG
> - container->base.id = ++worker->last_id;
> + container->base.id = ++surfaces->last_id;
> #endif
> container->base.type = TREE_ITEM_TYPE_CONTAINER;
> container->base.container = item->base.container;
> @@ -2012,15 +2026,16 @@ static inline int is_opaque_item(TreeItem *item)
> (IS_DRAW_ITEM(item) && ((DrawItem *)item)->effect == QXL_EFFECT_OPAQUE);
> }
>
> -static inline void __current_add_drawable(RedWorker *worker, Drawable *drawable, RingItem *pos)
> +static inline void __current_add_drawable(RedWorker *worker, Surfaces *surfaces,
> + Drawable *drawable, RingItem *pos)
> {
> RedSurface *surface;
> uint32_t surface_id = drawable->surface_id;
>
> - surface = &worker->surfaces[surface_id];
> + surface = &surfaces->surfaces[surface_id];
> ring_add_after(&drawable->tree_item.base.siblings_link, pos);
> - ring_add(&worker->current_list, &drawable->list_link);
> - worker->drawable_count++;
> + ring_add(&surfaces->current_list, &drawable->list_link);
> + surfaces->drawable_count++;
> ring_add(&surface->current_list, &drawable->surface_list_link);
> drawable->refs++;
> }
> @@ -2709,7 +2724,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(RedWorker *worker, Surfaces *surfaces,
> + DrawItem *item, TreeItem *other)
> {
> DrawItem *other_draw_item;
> Drawable *drawable;
> @@ -2730,13 +2746,13 @@ 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);
> red_stream_maintenance(worker, drawable, other_drawable);
> - __current_add_drawable(worker, drawable, &other->siblings_link);
> + __current_add_drawable(worker, surfaces, drawable, &other->siblings_link);
> if (add_after) {
> red_pipe_add_drawable_after(worker, drawable, other_drawable);
> } else {
> red_pipe_add_drawable(worker, drawable);
> }
> - remove_drawable(worker, other_drawable);
> + remove_drawable(worker, surfaces, other_drawable);
> return TRUE;
> }
>
> @@ -2746,14 +2762,14 @@ static inline int red_current_add_equal(RedWorker *worker, DrawItem *item, TreeI
> if (!ring_item_is_linked(&other_drawable->pipe_item.link)) {
> red_pipe_add_drawable(worker, drawable);
> }
> - remove_drawable(worker, other_drawable);
> + remove_drawable(worker, surfaces, other_drawable);
> return TRUE;
> }
> break;
> case QXL_EFFECT_OPAQUE_BRUSH:
> if (is_same_geometry(worker, drawable, other_drawable)) {
> - __current_add_drawable(worker, drawable, &other->siblings_link);
> - remove_drawable(worker, other_drawable);
> + __current_add_drawable(worker, surfaces, drawable, &other->siblings_link);
> + remove_drawable(worker, surfaces, other_drawable);
> red_pipe_add_drawable(worker, drawable);
> return TRUE;
> }
> @@ -2812,7 +2828,7 @@ static inline void red_use_stream_trace(RedWorker *worker, Drawable *drawable)
> }
> }
>
> -static void red_reset_stream_trace(RedWorker *worker)
> +static void red_reset_stream_trace(RedWorker *worker, Surfaces *surfaces)
> {
> Ring *ring = &worker->streams;
> RingItem *item = ring_get_head(ring);
> @@ -2831,7 +2847,8 @@ static void red_reset_stream_trace(RedWorker *worker)
> memset(worker->items_trace, 0, sizeof(worker->items_trace));
> }
>
> -static inline int red_current_add(RedWorker *worker, Ring *ring, Drawable *drawable)
> +static inline int red_current_add(RedWorker *worker, Surfaces *surfaces,
> + Ring *ring, Drawable *drawable)
> {
> DrawItem *item = &drawable->tree_item;
> #ifdef RED_WORKER_STAT
> @@ -2843,7 +2860,7 @@ static inline int red_current_add(RedWorker *worker, Ring *ring, Drawable *drawa
>
> print_base_item("ADD", &item->base);
> ASSERT(!region_is_empty(&item->base.rgn));
> - worker->current_size++;
> + surfaces->current_size++;
> region_init(&exclude_rgn);
> now = ring_next(ring, ring);
>
> @@ -2863,8 +2880,8 @@ static inline int red_current_add(RedWorker *worker, Ring *ring, Drawable *drawa
> continue;
> } 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)) {
> + !(test_res & REGION_TEST_LEFT_EXCLUSIVE) &&
> + red_current_add_equal(worker, surfaces, item, sibling)) {
> stat_add(&worker->add_stat, start_time);
> return FALSE;
> }
> @@ -2877,7 +2894,8 @@ 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(worker, surfaces, ring, exclude_base,
> + &exclude_rgn, &next, NULL);
> if (next != sibling) {
> now = next ? &next->siblings_link : NULL;
> exclude_base = NULL;
> @@ -2887,7 +2905,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(worker, surfaces, sibling);
> now = ring_next(ring, now);
> if (shadow || skip) {
> exclude_base = now;
> @@ -2899,7 +2917,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(worker, surfaces, ring, exclude_base, &exclude_rgn, NULL, NULL);
> region_clear(&exclude_rgn);
> exclude_base = NULL;
> }
> @@ -2913,7 +2931,7 @@ static inline int red_current_add(RedWorker *worker, Ring *ring, Drawable *drawa
> }
> ASSERT(IS_DRAW_ITEM(sibling));
> if (!((DrawItem *)sibling)->container_root) {
> - container = __new_container(worker, (DrawItem *)sibling);
> + container = __new_container(surfaces, (DrawItem *)sibling);
> if (!container) {
> red_printf("create new container failed");
> region_destroy(&exclude_rgn);
> @@ -2931,7 +2949,7 @@ 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);
> + exclude_region(worker, surfaces, ring, exclude_base, &exclude_rgn, NULL, drawable);
> red_use_stream_trace(worker, drawable);
> red_streams_update_clip(worker, drawable);
> } else {
> @@ -2940,7 +2958,7 @@ static inline int red_current_add(RedWorker *worker, Ring *ring, Drawable *drawa
> }
> }
> region_destroy(&exclude_rgn);
> - __current_add_drawable(worker, drawable, ring);
> + __current_add_drawable(worker, surfaces, drawable, ring);
> stat_add(&worker->add_stat, start_time);
> return TRUE;
> }
> @@ -2954,16 +2972,16 @@ static void add_clip_rects(QRegion *rgn, SpiceClipRects *data)
> }
> }
>
> -static inline Shadow *__new_shadow(RedWorker *worker, Drawable *item, SpicePoint *delta)
> +static inline Shadow *__new_shadow(Surfaces *surfaces, Drawable *item, SpicePoint *delta)
> {
> if (!delta->x && !delta->y) {
> return NULL;
> }
>
> Shadow *shadow = spice_new(Shadow, 1);
> - worker->shadows_count++;
> + surfaces->shadows_count++;
> #ifdef PIPE_DEBUG
> - shadow->base.id = ++worker->last_id;
> + shadow->base.id = ++surfaces->last_id;
> #endif
> shadow->base.type = TREE_ITEM_TYPE_SHADOW;
> shadow->base.container = NULL;
> @@ -2976,19 +2994,20 @@ static inline Shadow *__new_shadow(RedWorker *worker, Drawable *item, SpicePoint
> return shadow;
> }
>
> -static inline int red_current_add_with_shadow(RedWorker *worker, Ring *ring, Drawable *item, SpicePoint *delta)
> +static inline int red_current_add_with_shadow(RedWorker *worker, Surfaces *surfaces,
> + Ring *ring, Drawable *item, SpicePoint *delta)
> {
> #ifdef RED_WORKER_STAT
> stat_time_t start_time = stat_now();
> #endif
>
> - Shadow *shadow = __new_shadow(worker, item, delta);
> + Shadow *shadow = __new_shadow(surfaces, item, delta);
> if (!shadow) {
> stat_add(&worker->add_stat, start_time);
> return FALSE;
> }
> print_base_item("ADDSHADOW", &item->tree_item.base);
> - worker->current_size++;
> + surfaces->current_size++;
> // item and his shadow must initially be placed in the same container.
> // for now putting them on root.
>
> @@ -2997,11 +3016,11 @@ static inline int red_current_add_with_shadow(RedWorker *worker, Ring *ring, Dra
> red_detach_streams_behind(worker, &shadow->base.rgn);
> }
> ring_add(ring, &shadow->base.siblings_link);
> - __current_add_drawable(worker, item, ring);
> + __current_add_drawable(worker, surfaces, 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(worker, surfaces, ring, &shadow->base.siblings_link, &exclude_rgn, NULL, NULL);
> region_destroy(&exclude_rgn);
> red_streams_update_clip(worker, item);
> } else {
> @@ -3058,7 +3077,8 @@ static inline void red_update_streamable(RedWorker *worker, Drawable *drawable,
> drawable->streamable = TRUE;
> }
>
> -static inline int red_current_add_qxl(RedWorker *worker, Ring *ring, Drawable *drawable,
> +static inline int red_current_add_qxl(RedWorker *worker, Surfaces *surfaces,
> + Ring *ring, Drawable *drawable,
> RedDrawable *red_drawable)
> {
> int ret;
> @@ -3071,10 +3091,10 @@ static inline int red_current_add_qxl(RedWorker *worker, Ring *ring, Drawable *d
> #endif
> delta.x = red_drawable->u.copy_bits.src_pos.x - red_drawable->bbox.left;
> delta.y = red_drawable->u.copy_bits.src_pos.y - red_drawable->bbox.top;
> - ret = red_current_add_with_shadow(worker, ring, drawable, &delta);
> + ret = red_current_add_with_shadow(worker, surfaces, ring, drawable, &delta);
> } else {
> red_update_streamable(worker, drawable, red_drawable);
> - ret = red_current_add(worker, ring, drawable);
> + ret = red_current_add(worker, surfaces, ring, drawable);
> }
> #ifdef RED_WORKER_STAT
> if ((++worker->add_count % 100) == 0) {
> @@ -3103,15 +3123,16 @@ static inline int red_current_add_qxl(RedWorker *worker, Ring *ring, Drawable *d
> return ret;
> }
>
> -static void red_get_area(RedWorker *worker, int surface_id, const SpiceRect *area, uint8_t *dest,
> +static void red_get_area(RedWorker *worker, Surfaces *surfaces,
> + int surface_id, const SpiceRect *area, uint8_t *dest,
> int dest_stride, int update)
> {
> SpiceCanvas *canvas;
> RedSurface *surface;
>
> - surface = &worker->surfaces[surface_id];
> + surface = &surfaces->surfaces[surface_id];
> if (update) {
> - red_update_area(worker, area, surface_id);
> + red_update_area_surfaces(worker, surfaces, area, surface_id);
> }
>
> canvas = surface->context.canvas;
> @@ -3161,7 +3182,8 @@ static int rgb32_data_has_alpha(int width, int height, size_t stride,
> return has_alpha;
> }
>
> -static inline int red_handle_self_bitmap(RedWorker *worker, Drawable *drawable)
> +static inline int red_handle_self_bitmap(RedWorker *worker, Surfaces *surfaces,
> + Drawable *drawable)
> {
> SpiceImage *image;
> int32_t width;
> @@ -3176,8 +3198,7 @@ static inline int red_handle_self_bitmap(RedWorker *worker, Drawable *drawable)
> return TRUE;
> }
>
> -
> - surface = &worker->surfaces[drawable->surface_id];
> + surface = &surfaces->surfaces[drawable->surface_id];
>
> bpp = SPICE_SURFACE_FMT_DEPTH(surface->context.format) / 8;
>
> @@ -3201,12 +3222,12 @@ 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(worker, surfaces, drawable->surface_id,
> &drawable->red_drawable->self_bitmap_area, dest, dest_stride, TRUE);
>
> /* For 32bit non-primary surfaces we need to keep any non-zero
> high bytes as the surface may be used as source to an alpha_blend */
> - if (!is_primary_surface(worker, drawable->surface_id) &&
> + if (!is_primary_surface(drawable->surface_id) &&
> image->u.bitmap.format == SPICE_BITMAP_FMT_32BIT &&
> rgb32_data_has_alpha(width, height, dest_stride, dest, &all_set)) {
> if (all_set) {
> @@ -3220,9 +3241,9 @@ static inline int red_handle_self_bitmap(RedWorker *worker, Drawable *drawable)
> return TRUE;
> }
>
> -static void free_one_drawable(RedWorker *worker, int force_glz_free)
> +static void free_one_drawable(RedWorker *worker, Surfaces *surfaces, int force_glz_free)
> {
> - RingItem *ring_item = ring_get_tail(&worker->current_list);
> + RingItem *ring_item = ring_get_tail(&surfaces->current_list);
> Drawable *drawable;
> Container *container;
>
> @@ -3232,28 +3253,28 @@ static void free_one_drawable(RedWorker *worker, int force_glz_free)
> ASSERT(worker->display_channel);
> red_display_free_glz_drawable(worker->display_channel, drawable->red_glz_drawable);
> }
> - red_draw_drawable(worker, drawable);
> + red_draw_drawable(worker, surfaces, drawable);
> container = drawable->tree_item.base.container;
>
> - current_remove_drawable(worker, drawable);
> - container_cleanup(worker, container);
> + current_remove_drawable(worker, surfaces, drawable);
> + container_cleanup(surfaces, container);
> }
>
> -static Drawable *get_drawable(RedWorker *worker, uint8_t effect, RedDrawable *red_drawable,
> +static Drawable *get_drawable(RedWorker *worker, Surfaces *surfaces, uint8_t effect, RedDrawable *red_drawable,
> uint32_t group_id) {
> Drawable *drawable;
> struct timespec time;
> int x;
>
> while (!(drawable = alloc_drawable(worker))) {
> - free_one_drawable(worker, FALSE);
> + free_one_drawable(worker, surfaces, FALSE);
> }
> memset(drawable, 0, sizeof(Drawable));
> drawable->refs = 1;
> clock_gettime(CLOCK_MONOTONIC, &time);
> drawable->creation_time = timespec_to_red_time(&time);
> #ifdef PIPE_DEBUG
> - drawable->tree_item.base.id = ++worker->last_id;
> + drawable->tree_item.base.id = ++surfaces->last_id;
> #endif
> ring_item_init(&drawable->list_link);
> ring_item_init(&drawable->surface_list_link);
> @@ -3270,35 +3291,36 @@ static Drawable *get_drawable(RedWorker *worker, uint8_t effect, RedDrawable *re
> drawable->group_id = group_id;
>
> drawable->surface_id = red_drawable->surface_id;
> - validate_surface(worker, drawable->surface_id);
> + validate_surface(surfaces, drawable->surface_id);
> for (x = 0; x < 3; ++x) {
> drawable->surfaces_dest[x] = red_drawable->surfaces_dest[x];
> if (drawable->surfaces_dest[x] != -1) {
> - validate_surface(worker, drawable->surfaces_dest[x]);
> + validate_surface(surfaces, drawable->surfaces_dest[x]);
> }
> }
>
> 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(RedWorker *worker, Surfaces *surfaces,
> + uint32_t surface_id)
> {
> RedSurface *surface;
> RingItem *ring_item;
>
> - surface = &worker->surfaces[surface_id];
> + surface = &surfaces->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(worker, surfaces, 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(Surfaces *surfaces, int depend_on_surface_id,
> DependItem *depend_item, Drawable *drawable)
> {
> RedSurface *surface;
> @@ -3308,13 +3330,14 @@ static inline void add_to_surface_dependency(RedWorker *worker, int depend_on_su
> return;
> }
>
> - surface = &worker->surfaces[depend_on_surface_id];
> + surface = &surfaces->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(RedWorker *worker,
> + Surfaces *surfaces, Drawable *drawable)
> {
> int x;
>
> @@ -3322,7 +3345,7 @@ static inline int red_handle_surfaces_dependencies(RedWorker *worker, Drawable *
> // surface self dependency is handled by shadows in "current", or by
> // handle_self_bitmap
> if (drawable->surfaces_dest[x] != drawable->surface_id) {
> - add_to_surface_dependency(worker, drawable->surfaces_dest[x],
> + add_to_surface_dependency(surfaces, drawable->surfaces_dest[x],
> &drawable->depend_items[x], drawable);
>
> if (drawable->surfaces_dest[x] == 0) {
> @@ -3337,7 +3360,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(Surfaces *surfaces, Drawable *drawable)
> {
> int x;
> int surface_id;
> @@ -3348,21 +3371,22 @@ static inline void red_inc_surfaces_drawable_dependencies(RedWorker *worker, Dra
> if (surface_id == -1) {
> continue;
> }
> - surface = &worker->surfaces[surface_id];
> + surface = &surfaces->surfaces[surface_id];
> surface->refs++;
> }
> }
>
> -static inline void red_process_drawable(RedWorker *worker, RedDrawable *drawable, uint32_t group_id)
> +static inline void red_process_drawable_surfaces(RedWorker *worker,
> + Surfaces *surfaces, RedDrawable *drawable, uint32_t group_id)
> {
> int surface_id;
> - Drawable *item = get_drawable(worker, drawable->effect, drawable, group_id);
> + Drawable *item = get_drawable(worker, surfaces, drawable->effect, drawable, group_id);
>
> ASSERT(item);
>
> surface_id = item->surface_id;
>
> - worker->surfaces[surface_id].refs++;
> + surfaces->surfaces[surface_id].refs++;
>
> region_add(&item->tree_item.base.rgn, &drawable->bbox);
> #ifdef PIPE_DEBUG
> @@ -3387,42 +3411,49 @@ static inline void red_process_drawable(RedWorker *worker, RedDrawable *drawable
> 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, item);
> + red_inc_surfaces_drawable_dependencies(surfaces, item);
>
> if (region_is_empty(&item->tree_item.base.rgn)) {
> - release_drawable(worker, item);
> + release_drawable(worker, surfaces, item);
> return;
> }
>
> - if (!red_handle_self_bitmap(worker, item)) {
> - release_drawable(worker, item);
> + if (!red_handle_self_bitmap(worker, surfaces, item)) {
> + release_drawable(worker, surfaces, item);
> return;
> }
>
> - if (!red_handle_depends_on_target_surface(worker, surface_id)) {
> - release_drawable(worker, item);
> + if (!red_handle_depends_on_target_surface(worker, surfaces, surface_id)) {
> + release_drawable(worker, surfaces, item);
> return;
> }
>
> - if (!red_handle_surfaces_dependencies(worker, item)) {
> - release_drawable(worker, item);
> + if (!red_handle_surfaces_dependencies(worker, surfaces, item)) {
> + release_drawable(worker, surfaces, item);
> return;
> }
>
> - if (red_current_add_qxl(worker, &worker->surfaces[surface_id].current, item,
> + if (red_current_add_qxl(worker, surfaces,
> + &surfaces->surfaces[surface_id].current, item,
> drawable)) {
> if (item->tree_item.effect != QXL_EFFECT_OPAQUE) {
> - worker->transparent_count++;
> + surfaces->transparent_count++;
> }
> red_pipe_add_drawable(worker, item);
> #ifdef DRAW_ALL
> - red_draw_qxl_drawable(worker, item);
> + red_draw_qxl_drawable(worker, surfaces, item);
> #endif
> }
> - release_drawable(worker, item);
> + release_drawable(worker, surfaces, item);
> }
>
> -static inline void red_create_surface(RedWorker *worker, uint32_t surface_id,uint32_t width,
> +static inline void red_process_drawable(RedWorker *worker, RedDrawable *drawable, uint32_t group_id)
> +{
> + red_process_drawable_surfaces(worker, &worker->surfaces, drawable, group_id);
> +}
> +
> +static inline void red_create_surface(RedWorker *worker, Surfaces *surfaces,
> + uint32_t surface_id, uint32_t width,
> uint32_t height, int32_t stride, uint32_t format,
> void *line_0, int data_is_valid);
>
> @@ -3431,11 +3462,12 @@ static inline void red_process_surface(RedWorker *worker, RedSurfaceCmd *surface
> int surface_id;
> RedSurface *red_surface;
> uint8_t *data;
> + Surfaces *surfaces = &worker->surfaces;
>
> surface_id = surface->surface_id;
> - __validate_surface(worker, surface_id);
> + __validate_surface(surfaces, surface_id);
>
> - red_surface = &worker->surfaces[surface_id];
> + red_surface = &surfaces->surfaces[surface_id];
>
> switch (surface->type) {
> case QXL_SURFACE_CMD_CREATE: {
> @@ -3446,22 +3478,22 @@ 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, surfaces, surface_id, surface->u.surface_create.width,
> height, stride, surface->u.surface_create.format, data,
> data_is_valid);
> - set_surface_release_info(worker, surface_id, 1, surface->release_info, group_id);
> + set_surface_release_info(&worker->surfaces, surface_id, 1, surface->release_info, group_id);
> break;
> }
> case QXL_SURFACE_CMD_DESTROY:
> PANIC_ON(!red_surface->context.canvas);
> - set_surface_release_info(worker, surface_id, 0, surface->release_info, group_id);
> - red_handle_depends_on_target_surface(worker, surface_id);
> + set_surface_release_info(surfaces, surface_id, 0, surface->release_info, group_id);
> + red_handle_depends_on_target_surface(worker, surfaces, surface_id);
> /* note that red_handle_depends_on_target_surface must be called before red_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_current_clear(worker, surfaces, surface_id);
> red_clear_surface_drawables_from_pipe(worker, surface_id, FALSE);
> - red_destroy_surface(worker, surface_id);
> + red_destroy_surface(worker, surfaces, surface_id);
> break;
> default:
> red_error("unknown surface command");
> @@ -3470,24 +3502,24 @@ static inline void red_process_surface(RedWorker *worker, RedSurfaceCmd *surface
> free(surface);
> }
>
> -static SpiceCanvas *image_surfaces_get(SpiceImageSurfaces *surfaces,
> +static SpiceCanvas *image_surfaces_get(SpiceImageSurfaces *image_surfaces,
> uint32_t surface_id)
> {
> - RedWorker *worker;
> + Surfaces *surfaces;
>
> - worker = SPICE_CONTAINEROF(surfaces, RedWorker, image_surfaces);
> - validate_surface(worker, surface_id);
> + surfaces = SPICE_CONTAINEROF(image_surfaces, Surfaces, image_surfaces);
> + validate_surface(surfaces, surface_id);
>
> - return worker->surfaces[surface_id].context.canvas;
> + return surfaces->surfaces[surface_id].context.canvas;
> }
>
> -static void image_surface_init(RedWorker *worker)
> +static void image_surface_init(Surfaces *surfaces)
> {
> static SpiceImageSurfacesOps image_surfaces_ops = {
> image_surfaces_get,
> };
>
> - worker->image_surfaces.ops = &image_surfaces_ops;
> + surfaces->image_surfaces.ops = &image_surfaces_ops;
> }
>
> static ImageCacheItem *image_cache_find(ImageCache *cache, uint64_t id)
> @@ -3680,13 +3712,13 @@ static void localize_mask(RedWorker *worker, SpiceQMask *mask, SpiceImage *image
> }
> }
>
> -static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable)
> +static void red_draw_qxl_drawable(RedWorker *worker, Surfaces *surfaces, Drawable *drawable)
> {
> RedSurface *surface;
> SpiceCanvas *canvas;
> SpiceClip clip = drawable->red_drawable->clip;
>
> - surface = &worker->surfaces[drawable->surface_id];
> + surface = &surfaces->surfaces[drawable->surface_id];
> canvas = surface->context.canvas;
>
> image_cache_eaging(&worker->image_cache);
> @@ -3811,7 +3843,7 @@ static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable)
>
> #ifndef DRAW_ALL
>
> -static void red_draw_drawable(RedWorker *worker, Drawable *drawable)
> +static void red_draw_drawable(RedWorker *worker, Surfaces *surfaces, Drawable *drawable)
> {
> #ifdef UPDATE_AREA_BY_TREE
> SpiceCanvas *canvas;
> @@ -3821,8 +3853,8 @@ static void red_draw_drawable(RedWorker *worker, Drawable *drawable)
> canvas->ops->group_start(canvas,
> &drawable->tree_item.base.rgn);
> #endif
> - red_flush_source_surfaces(worker, drawable);
> - red_draw_qxl_drawable(worker, drawable);
> + red_flush_source_surfaces(worker, surfaces, drawable);
> + red_draw_qxl_drawable(worker, surfaces, drawable);
> #ifdef UPDATE_AREA_BY_TREE
> canvas->ops->group_end(canvas);
> #endif
> @@ -3832,7 +3864,7 @@ static void validate_area(RedWorker *worker, const SpiceRect *area, uint32_t sur
> {
> RedSurface *surface;
>
> - surface = &worker->surfaces[surface_id];
> + surface = &worker->surfaces.surfaces[surface_id];
> if (!surface->context.canvas_draws_on_surface) {
> SpiceCanvas *canvas = surface->context.canvas;
> int h;
> @@ -3899,7 +3931,8 @@ static inline void __red_collect_for_update(RedWorker *worker, Ring *ring, RingI
> }
> }
>
> -static void red_update_area(RedWorker *worker, const SpiceRect *area, int surface_id)
> +static void red_update_area_surfaces(RedWorker *worker, Surfaces *surfaces,
> + const SpiceRect *area, int surface_id)
> {
> RedSurface *surface;
> Ring *ring;
> @@ -3907,7 +3940,7 @@ static void red_update_area(RedWorker *worker, const SpiceRect *area, int surfac
> Ring items;
> QRegion rgn;
>
> - surface = &worker->surfaces[surface_id];
> + surface = &surfaces->surfaces[surface_id];
> ring = &surface->current;
>
> if (!(ring_item = ring_get_head(ring))) {
> @@ -3930,7 +3963,7 @@ static void red_update_area(RedWorker *worker, const SpiceRect *area, int surfac
> red_draw_drawable(worker, drawable);
> container = drawable->tree_item.base.container;
> current_remove_drawable(worker, drawable);
> - container_cleanup(worker, container);
> + container_cleanup(surfaces, container);
> }
> validate_area(worker, area, surface_id);
> }
> @@ -3941,7 +3974,8 @@ static void red_update_area(RedWorker *worker, const SpiceRect *area, int surfac
> 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(RedWorker *worker, Surfaces *surfaces,
> + const SpiceRect *area, int surface_id,
> Drawable *last)
> {
> // TODO: if we use UPDATE_AREA_BY_TREE, a corresponding red_update_area_till
> @@ -3957,11 +3991,11 @@ static void red_update_area_till(RedWorker *worker, const SpiceRect *area, int s
> ASSERT(last);
> ASSERT(ring_item_is_linked(&last->list_link));
>
> - surface = &worker->surfaces[surface_id];
> + surface = &surfaces->surfaces[surface_id];
>
> if (surface_id != last->surface_id) {
> // find the nearest older drawable from the appropriate surface
> - ring = &worker->current_list;
> + ring = &surfaces->current_list;
> ring_item = &last->list_link;
> while ((ring_item = ring_next(ring, ring_item))) {
> now = SPICE_CONTAINEROF(ring_item, Drawable, list_link);
> @@ -3987,7 +4021,7 @@ static void red_update_area_till(RedWorker *worker, const SpiceRect *area, int s
> region_init(&rgn);
> region_add(&rgn, area);
>
> - // find the first older drawable that intersects with the area
> + // find the first older drawable that intersects with the area
> do {
> now = SPICE_CONTAINEROF(ring_item, Drawable, surface_list_link);
> if (region_intersects(&rgn, &now->tree_item.base.rgn)) {
> @@ -3997,7 +4031,7 @@ static void red_update_area_till(RedWorker *worker, const SpiceRect *area, int s
> } while ((ring_item = ring_next(ring, ring_item)));
>
> region_destroy(&rgn);
> -
> +
> if (!surface_last) {
> return;
> }
> @@ -4009,20 +4043,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(worker, surfaces, now);
> + container_cleanup(surfaces, 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_drawable */
> - red_draw_drawable(worker, now);
> - release_drawable(worker, now);
> + red_draw_drawable(worker, surfaces, now);
> + release_drawable(worker, surfaces, now);
> } while (now != surface_last);
> validate_area(worker, area, surface_id);
> }
>
> -static void red_update_area(RedWorker *worker, const SpiceRect *area, int surface_id)
> +static void red_update_area_surfaces(RedWorker *worker, Surfaces *surfaces,
> + const SpiceRect *area, int surface_id)
> {
> RedSurface *surface;
> Ring *ring;
> @@ -4034,7 +4069,7 @@ static void red_update_area(RedWorker *worker, const SpiceRect *area, int surfac
> int gn;
> #endif
>
> - surface = &worker->surfaces[surface_id];
> + surface = &surfaces->surfaces[surface_id];
>
> last = NULL;
> #ifdef ACYCLIC_SURFACE_DEBUG
> @@ -4066,10 +4101,10 @@ 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);
> - release_drawable(worker, now);
> + current_remove_drawable(worker, surfaces, now);
> + container_cleanup(surfaces, container);
> + red_draw_drawable(worker, surfaces, now);
> + release_drawable(worker, surfaces, now);
> #ifdef ACYCLIC_SURFACE_DEBUG
> if (gn != surface->current_gn) {
> red_error("cyclic surface dependencies");
> @@ -4081,6 +4116,11 @@ static void red_update_area(RedWorker *worker, const SpiceRect *area, int surfac
>
> #endif
>
> +static void red_update_area(RedWorker *worker, const SpiceRect *area, int surface_id)
> +{
> + red_update_area_surfaces(worker, &worker->surfaces, area, surface_id);
> +}
> +
> #endif
>
> static inline void free_cursor_item(RedWorker *worker, CursorItem *item);
> @@ -4289,7 +4329,7 @@ static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size, int *
>
> red_get_update_cmd(&worker->mem_slots, ext_cmd.group_id,
> &update, ext_cmd.cmd.data);
> - validate_surface(worker, update.surface_id);
> + validate_surface(&worker->surfaces, update.surface_id);
> red_update_area(worker, &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;
> @@ -4348,8 +4388,8 @@ static void red_free_some(RedWorker *worker)
> n = red_display_free_some_independent_glz_drawables(worker->display_channel);
> }
>
> - while (!ring_is_empty(&worker->current_list) && n++ < RED_RELEASE_BUNCH_SIZE) {
> - free_one_drawable(worker, TRUE);
> + while (!ring_is_empty(&worker->surfaces.current_list) && n++ < RED_RELEASE_BUNCH_SIZE) {
> + free_one_drawable(worker, &worker->surfaces, TRUE);
> }
>
> if (worker->display_channel && worker->display_channel->glz_dict) {
> @@ -4357,12 +4397,12 @@ static void red_free_some(RedWorker *worker)
> }
> }
>
> -static void red_current_flush(RedWorker *worker, int surface_id)
> +static void red_current_flush(RedWorker *worker, Surfaces *surfaces, int surface_id)
> {
> - while (!ring_is_empty(&worker->surfaces[surface_id].current_list)) {
> - free_one_drawable(worker, FALSE);
> + while (!ring_is_empty(&surfaces->surfaces[surface_id].current_list)) {
> + free_one_drawable(worker, surfaces, FALSE);
> }
> - red_current_clear(worker, surface_id);
> + red_current_clear(worker, surfaces, surface_id);
> }
>
> // adding the pipe item after pos. If pos == NULL, adding to head.
> @@ -4373,7 +4413,7 @@ static ImageItem *red_add_surface_area_image(RedWorker *worker, int surface_id,
> int stride;
> int width;
> int height;
> - RedSurface *surface = &worker->surfaces[surface_id];
> + RedSurface *surface = &worker->surfaces.surfaces[surface_id];
> SpiceCanvas *canvas = surface->context.canvas;
> int bpp;
> int all_set;
> @@ -4407,7 +4447,7 @@ static ImageItem *red_add_surface_area_image(RedWorker *worker, int surface_id,
>
> /* For 32bit non-primary surfaces we need to keep any non-zero
> high bytes as the surface may be used as source to an alpha_blend */
> - if (!is_primary_surface(worker, surface_id) &&
> + if (!is_primary_surface(surface_id) &&
> item->image_format == SPICE_BITMAP_FMT_32BIT &&
> rgb32_data_has_alpha(item->width, item->height, item->stride, item->data, &all_set)) {
> if (all_set) {
> @@ -4433,7 +4473,7 @@ static void red_add_surface_image(RedWorker *worker, int surface_id)
> SpiceRect area;
> RedSurface *surface;
>
> - surface = &worker->surfaces[surface_id];
> + surface = &worker->surfaces.surfaces[surface_id];
>
> if (!display_connected(worker) || !surface->context.canvas) {
> return;
> @@ -5813,9 +5853,9 @@ static FillBitsType fill_bits(RedChannelClient *rcc, SpiceMarshaller *m,
> RedSurface *surface;
>
> surface_id = simage->u.surface.surface_id;
> - validate_surface(worker, surface_id);
> + validate_surface(&worker->surfaces, surface_id);
>
> - surface = &worker->surfaces[surface_id];
> + surface = &worker->surfaces.surfaces[surface_id];
> image.descriptor.type = SPICE_IMAGE_TYPE_SURFACE;
> image.descriptor.flags = 0;
> image.descriptor.width = surface->context.width;
> @@ -5977,8 +6017,8 @@ static int is_surface_area_lossy(DisplayChannel *display_channel, uint32_t surfa
> QRegion *surface_lossy_region;
> QRegion lossy_region;
>
> - validate_surface(display_channel->common.worker, surface_id);
> - surface = &display_channel->common.worker->surfaces[surface_id];
> + validate_surface(&display_channel->common.worker->surfaces, surface_id);
> + surface = &display_channel->common.worker->surfaces.surfaces[surface_id];
> surface_lossy_region = &display_channel->surface_client_lossy_region[surface_id];
>
> if (!area) {
> @@ -6298,7 +6338,8 @@ 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], deps_surfaces_ids[i], item);
> + red_update_area_till(worker, &worker->surfaces, deps_areas[i],
> + deps_surfaces_ids[i], item);
> }
> }
>
> @@ -8073,7 +8114,7 @@ static void display_channel_send_item(RedChannelClient *rcc, PipeItem *pipe_item
> case PIPE_ITEM_TYPE_DRAW: {
> Drawable *drawable = SPICE_CONTAINEROF(pipe_item, Drawable, pipe_item);
> marshall_qxl_drawable(rcc, m, drawable);
> - release_drawable(worker, drawable);
> + release_drawable(worker, &worker->surfaces, drawable);
> break;
> }
> case PIPE_ITEM_TYPE_INVAL_ONE:
> @@ -8100,7 +8141,7 @@ static void display_channel_send_item(RedChannelClient *rcc, PipeItem *pipe_item
> }
> case PIPE_ITEM_TYPE_UPGRADE:
> red_display_marshall_upgrade(rcc, m, (UpgradeItem *)pipe_item);
> - release_upgrade_item(worker, (UpgradeItem *)pipe_item);
> + release_upgrade_item(worker, &worker->surfaces, (UpgradeItem *)pipe_item);
> break;
> case PIPE_ITEM_TYPE_VERB:
> red_marshall_verb(rcc, ((VerbItem*)pipe_item)->verb);
> @@ -8269,8 +8310,8 @@ void red_show_tree(RedWorker *worker)
> show_tree_data.level = 0;
> show_tree_data.container = NULL;
> for (x = 0; x < NUM_SURFACES; ++x) {
> - if (worker->surfaces[x].context.canvas) {
> - current_tree_for_each(worker, &worker->surfaces[x].current, __show_tree_call,
> + if (worker->surfaces.surfaces[x].context.canvas) {
> + current_tree_for_each(worker, &worker->surfaces.surfaces[x].current, __show_tree_call,
> &show_tree_data);
> }
> }
> @@ -8283,6 +8324,12 @@ static void red_disconnect_channel(RedChannel *channel)
> red_unref_channel(channel);
> }
>
> +static void init_surfaces(Surfaces *surfaces)
> +{
> + ring_init(&surfaces->current_list);
> + image_surface_init(surfaces);
> +}
> +
> static void red_disconnect_display(RedChannelClient *rcc)
> {
> // TODO: MC: right now we assume single channel
> @@ -8391,7 +8438,8 @@ 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(RedWorker *worker, Surfaces *surfaces,
> + RedSurface *surface,
> uint32_t renderer, uint32_t width, uint32_t height,
> int32_t stride, uint32_t format, void *line_0)
> {
> @@ -8402,7 +8450,7 @@ static inline void *create_canvas_for_surface(RedWorker *worker, RedSurface *sur
> canvas = canvas_create_for_data(width, height, format,
> line_0, stride,
> &worker->image_cache.base,
> - &worker->image_surfaces, NULL, NULL, NULL);
> + &surfaces->image_surfaces, NULL, NULL, NULL);
> surface->context.top_down = TRUE;
> surface->context.canvas_draws_on_surface = TRUE;
> return canvas;
> @@ -8453,7 +8501,7 @@ static inline void __red_create_surface_item(RedWorker *worker, int surface_id,
> return;
> }
>
> - surface = &worker->surfaces[surface_id];
> + surface = &worker->surfaces.surfaces[surface_id];
>
> create = get_surface_create_item(&worker->display_channel->common.base,
> surface_id, surface->context.width, surface->context.height,
> @@ -8466,19 +8514,20 @@ static inline void __red_create_surface_item(RedWorker *worker, int surface_id,
>
> static inline void red_create_surface_item(RedWorker *worker, int surface_id)
> {
> - if (is_primary_surface(worker, surface_id)) {
> + if (is_primary_surface(surface_id)) {
> __red_create_surface_item(worker, surface_id, SPICE_SURFACE_FLAGS_PRIMARY);
> } else {
> __red_create_surface_item(worker, surface_id, 0);
> }
> }
>
> -static inline void red_create_surface(RedWorker *worker, uint32_t surface_id, uint32_t width,
> +static inline void red_create_surface(RedWorker *worker, Surfaces *surfaces,
> + uint32_t surface_id, uint32_t width,
> uint32_t height, int32_t stride, uint32_t format,
> void *line_0, int data_is_valid)
> {
> uint32_t i;
> - RedSurface *surface = &worker->surfaces[surface_id];
> + RedSurface *surface = &surfaces->surfaces[surface_id];
> if (stride >= 0) {
> PANIC("Untested path stride >= 0");
> }
> @@ -8501,7 +8550,8 @@ static inline void red_create_surface(RedWorker *worker, uint32_t surface_id, ui
> region_init(&surface->draw_dirty_region);
> surface->refs = 1;
> if (worker->renderer != RED_RENDERER_INVALID) {
> - surface->context.canvas = create_canvas_for_surface(worker, surface, worker->renderer,
> + surface->context.canvas = create_canvas_for_surface(worker, surfaces,
> + surface, worker->renderer,
> width, height, stride,
> surface->context.format, line_0);
> if (!surface->context.canvas) {
> @@ -8513,7 +8563,8 @@ static inline void red_create_surface(RedWorker *worker, uint32_t surface_id, ui
> }
>
> for (i = 0; i < worker->num_renderers; i++) {
> - surface->context.canvas = create_canvas_for_surface(worker, surface, worker->renderers[i],
> + surface->context.canvas = create_canvas_for_surface(worker, surfaces,
> + surface, worker->renderers[i],
> width, height, stride,
> surface->context.format, line_0);
> if (surface->context.canvas) { //no need canvas check
> @@ -8678,8 +8729,8 @@ static void on_new_display_channel(RedWorker *worker)
> return;
> }
> red_channel_ack_zero_messages_window(&display_channel->common.base);
> - if (worker->surfaces[0].context.canvas) {
> - red_current_flush(worker, 0);
> + if (worker->surfaces.surfaces[0].context.canvas) {
> + red_current_flush(worker, &worker->surfaces, 0);
> push_new_primary_surface(worker);
> red_add_surface_image(worker, 0);
> if (red_channel_is_connected(&display_channel->common.base)) {
> @@ -9167,18 +9218,20 @@ static void display_channel_release_item(RedChannelClient *rcc, PipeItem *item,
> {
> RedChannel *channel = rcc->channel;
> CommonChannel *common = SPICE_CONTAINEROF(channel, CommonChannel, base);
> + RedWorker *worker = common->worker;
>
> ASSERT(item);
> switch (item->type) {
> case PIPE_ITEM_TYPE_DRAW:
> case PIPE_ITEM_TYPE_STREAM_CREATE:
> - release_drawable(common->worker, SPICE_CONTAINEROF(item, Drawable, pipe_item));
> + release_drawable(common->worker, &common->worker->surfaces,
> + SPICE_CONTAINEROF(item, Drawable, pipe_item));
> break;
> case PIPE_ITEM_TYPE_STREAM_CLIP:
> red_display_release_stream_clip((DisplayChannel *)channel, (StreamClipItem *)item);
> break;
> case PIPE_ITEM_TYPE_UPGRADE:
> - release_upgrade_item(common->worker, (UpgradeItem *)item);
> + release_upgrade_item(worker, &worker->surfaces, (UpgradeItem *)item);
> break;
> case PIPE_ITEM_TYPE_IMAGE:
> release_image_item((ImageItem *)item);
> @@ -9351,7 +9404,7 @@ static void on_new_cursor_channel(RedWorker *worker)
> ASSERT(channel);
> red_channel_ack_zero_messages_window(&channel->common.base);
> red_channel_push_set_ack(&channel->common.base);
> - if (worker->surfaces[0].context.canvas && !channel->common.base.migrate) {
> + if (worker->surfaces.surfaces[0].context.canvas && !channel->common.base.migrate) {
> red_channel_client_pipe_add_type(worker->cursor_channel->common.base.rcc, PIPE_ITEM_TYPE_CURSOR_INIT);
> }
> }
> @@ -9559,10 +9612,10 @@ static inline void handle_dev_update(RedWorker *worker)
>
> ASSERT(worker->running);
>
> - validate_surface(worker, surface_id);
> + validate_surface(&worker->surfaces, surface_id);
> red_update_area(worker, rect, surface_id);
>
> - surface = &worker->surfaces[surface_id];
> + surface = &worker->surfaces.surfaces[surface_id];
> region_ret_rects(&surface->draw_dirty_region, dirty_rects, num_dirty_rects);
>
> if (clear_dirty_region) {
> @@ -9600,17 +9653,17 @@ static inline void handle_dev_del_memslot(RedWorker *worker)
> red_memslot_info_del_slot(&worker->mem_slots, slot_group_id, slot_id);
> }
>
> -static inline void destroy_surface_wait(RedWorker *worker, int surface_id)
> +static inline void destroy_surface_wait(RedWorker *worker, Surfaces *surfaces, int surface_id)
> {
> - if (!worker->surfaces[surface_id].context.canvas) {
> + if (!surfaces->surfaces[surface_id].context.canvas) {
> return;
> }
>
> - red_handle_depends_on_target_surface(worker, surface_id);
> + red_handle_depends_on_target_surface(worker, surfaces, surface_id);
> /* note that red_handle_depends_on_target_surface must be called before red_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_current_clear(worker, surfaces, surface_id);
> red_clear_surface_drawables_from_pipe(worker, surface_id, TRUE);
> // in case that the pipe didn't contain any item that is dependent on the surface, but
> // there is one during sending.
> @@ -9631,8 +9684,8 @@ static inline void handle_dev_destroy_surface_wait(RedWorker *worker)
>
> flush_all_qxl_commands(worker);
>
> - if (worker->surfaces[0].context.canvas) {
> - destroy_surface_wait(worker, 0);
> + if (worker->surfaces.surfaces[0].context.canvas) {
> + destroy_surface_wait(worker, &worker->surfaces, 0);
> }
>
> message = RED_WORKER_MESSAGE_READY;
> @@ -9642,18 +9695,20 @@ static inline void handle_dev_destroy_surface_wait(RedWorker *worker)
> /* called upon device reset */
> static inline void handle_dev_destroy_surfaces(RedWorker *worker)
> {
> + Surfaces *surfaces = &worker->surfaces;
> int i;
> RedWorkerMessage message;
> +
> red_printf("");
> 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_destroy_surface(worker, i);
> + if (surfaces->surfaces[i].context.canvas) {
> + destroy_surface_wait(worker, &worker->surfaces, i);
> + if (surfaces->surfaces[i].context.canvas) {
> + red_destroy_surface(worker, surfaces, i);
> }
> - ASSERT(!worker->surfaces[i].context.canvas);
> + ASSERT(!surfaces->surfaces[i].context.canvas);
> }
> }
> ASSERT(ring_is_empty(&worker->streams));
> @@ -9703,7 +9758,8 @@ static inline void handle_dev_create_primary_surface(RedWorker *worker)
> 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(worker, &worker->surfaces, 0, surface.width,
> + surface.height, surface.stride, surface.format,
> line_0, surface.flags & QXL_SURF_FLAG_KEEP_DATA);
>
> if (worker->display_channel) {
> @@ -9727,7 +9783,7 @@ static inline void handle_dev_destroy_primary_surface(RedWorker *worker)
> receive_data(worker->channel, &surface_id, sizeof(uint32_t));
>
> PANIC_ON(surface_id != 0);
> - PANIC_ON(!worker->surfaces[surface_id].context.canvas);
> + PANIC_ON(!worker->surfaces.surfaces[surface_id].context.canvas);
>
> if (worker->cursor) {
> red_release_cursor(worker, worker->cursor);
> @@ -9744,11 +9800,11 @@ static inline void handle_dev_destroy_primary_surface(RedWorker *worker)
> }
>
> flush_all_qxl_commands(worker);
> - destroy_surface_wait(worker, 0);
> - red_destroy_surface(worker, 0);
> + destroy_surface_wait(worker, &worker->surfaces, 0);
> + red_destroy_surface(worker, &worker->surfaces, 0);
> ASSERT(ring_is_empty(&worker->streams));
>
> - ASSERT(!worker->surfaces[surface_id].context.canvas);
> + ASSERT(!worker->surfaces.surfaces[surface_id].context.canvas);
>
> worker->cursor_visible = TRUE;
> worker->cursor_position.x = worker->cursor_position.y = 0;
> @@ -9782,7 +9838,7 @@ static void handle_dev_input(EventListener *listener, uint32_t events)
> red_channel_push(&worker->display_channel->common.base);
> }
> if (worker->qxl->st->qif->flush_resources(worker->qxl) == 0) {
> - red_printf("oom current %u pipe %u", worker->current_size,
> + red_printf("oom current %u pipe %u", worker->surfaces.current_size,
> worker->display_channel ?
> display_red_channel->rcc->pipe_size : 0);
> red_free_some(worker);
> @@ -9864,8 +9920,8 @@ static void handle_dev_input(EventListener *listener, uint32_t events)
> worker->running = FALSE;
> red_display_clear_glz_drawables(worker->display_channel);
> for (x = 0; x < NUM_SURFACES; ++x) {
> - if (worker->surfaces[x].context.canvas) {
> - red_current_flush(worker, x);
> + if (worker->surfaces.surfaces[x].context.canvas) {
> + red_current_flush(worker, &worker->surfaces, x);
> }
> }
> red_cursor_flush(worker);
> @@ -10056,9 +10112,8 @@ static void red_init(RedWorker *worker, WorkerInitData *init_data)
> worker->jpeg_state = init_data->jpeg_state;
> worker->zlib_glz_state = init_data->zlib_glz_state;
> worker->streaming_video = init_data->streaming_video;
> - ring_init(&worker->current_list);
> + init_surfaces(&worker->surfaces);
> image_cache_init(&worker->image_cache);
> - image_surface_init(worker);
> drawables_init(worker);
> cursor_items_init(worker);
> red_init_streams(worker);
> @@ -10092,7 +10147,7 @@ static void red_init(RedWorker *worker, WorkerInitData *init_data)
> init_data->internal_groupslot_id);
>
> PANIC_ON(init_data->n_surfaces > NUM_SURFACES);
> - worker->n_surfaces = init_data->n_surfaces;
> + worker->surfaces.n_surfaces = init_data->n_surfaces;
>
> message = RED_WORKER_MESSAGE_READY;
> write_message(worker->channel, &message);
> @@ -10320,4 +10375,3 @@ static void dump_bitmap(RedWorker *worker, SpiceBitmap *bitmap, uint32_t group_i
> }
>
> #endif
> -
> --
> 1.7.4.4
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
>
--
Marc-André Lureau
More information about the Spice-devel
mailing list