[Spice-devel] [RFC v4 24/62] server/red_worker: split Surfaces from RedWorker
Alon Levy
alevy at redhat.com
Thu May 5 01:31:38 PDT 2011
On Tue, May 03, 2011 at 01:52:12AM +0200, Marc-André Lureau wrote:
> 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?
Because it appeared to contain that mainly at first. Bad name, I'll rename to
RenderingState. And the variables to render_state. Unless you have a shorter idea?
>
> > 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"
Well, it does already ''slightly'' indirectly (the compiler will boil this down to two
dereferences, the rest are just offsets):
((CommonChannel*)surfaces->dcc->common.base.channel)->worker
and if dcc is NULL, then this is the embedded surfaces (render_state?)
>
>
> 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