> > From: Marc-André Lureau <marcandre.lureau@xxxxxxxxx> > > --- > server/Makefile.am | 2 + > server/red_worker.c | 266 > +++------------------------------------------------- > server/tree.c | 182 +++++++++++++++++++++++++++++++++++ > server/tree.h | 111 ++++++++++++++++++++++ > 4 files changed, 306 insertions(+), 255 deletions(-) > create mode 100644 server/tree.c > create mode 100644 server/tree.h > > diff --git a/server/Makefile.am b/server/Makefile.am > index 428417b..d2a7343 100644 > --- a/server/Makefile.am > +++ b/server/Makefile.am > @@ -131,6 +131,8 @@ libspice_server_la_SOURCES = \ > spice_image_cache.c \ > pixmap-cache.h \ > pixmap-cache.c \ > + tree.h \ > + tree.c \ > utils.h \ > $(NULL) > > diff --git a/server/red_worker.c b/server/red_worker.c > index 601805e..0049cca 100644 > --- a/server/red_worker.c > +++ b/server/red_worker.c > @@ -63,6 +63,8 @@ > #include "red_worker.h" > #include "spice_timer_queue.h" > #include "cursor-channel.h" > +#include "tree.h" > +#include "utils.h" > > //#define COMPRESS_STAT > //#define DUMP_BITMAP > @@ -405,52 +407,6 @@ struct DisplayChannel { > #endif > }; > > -enum { > - TREE_ITEM_TYPE_DRAWABLE, > - TREE_ITEM_TYPE_CONTAINER, > - TREE_ITEM_TYPE_SHADOW, > -}; > - > -typedef struct TreeItem { > - RingItem siblings_link; > - uint32_t type; > - struct Container *container; > - QRegion rgn; > -} TreeItem; > - > -#define IS_DRAW_ITEM(item) ((item)->type == TREE_ITEM_TYPE_DRAWABLE) > - > -typedef struct Shadow { > - TreeItem base; > - QRegion on_hold; > - struct DrawItem* owner; > -} Shadow; > - > -typedef struct Container { > - TreeItem base; > - Ring items; > -} Container; > - > -typedef struct DrawItem { > - TreeItem base; > - uint8_t effect; > - uint8_t container_root; > - Shadow *shadow; > -} DrawItem; > - > -typedef enum { > - BITMAP_GRADUAL_INVALID, > - BITMAP_GRADUAL_NOT_AVAIL, > - BITMAP_GRADUAL_LOW, > - BITMAP_GRADUAL_MEDIUM, > - BITMAP_GRADUAL_HIGH, > -} BitmapGradualType; > - > -typedef struct DependItem { > - Drawable *drawable; > - RingItem ring_item; > -} DependItem; > - > typedef struct DrawablePipeItem { > RingItem base; /* link for a list of pipe items held by Drawable */ > PipeItem dpi_pipe_item; /* link for the client's pipe itself */ > @@ -459,35 +415,6 @@ typedef struct DrawablePipeItem { > uint8_t refs; > } DrawablePipeItem; > > -struct Drawable { > - uint8_t refs; > - RingItem surface_list_link; > - RingItem list_link; > - DrawItem tree_item; > - Ring pipes; > - PipeItem *pipe_item_rest; > - uint32_t size_pipe_item_rest; > - RedDrawable *red_drawable; > - > - Ring glz_ring; > - > - red_time_t creation_time; > - int frames_count; > - int gradual_frames_count; > - int last_gradual_frame; > - Stream *stream; > - Stream *sized_stream; > - int streamable; > - BitmapGradualType copy_bitmap_graduality; > - uint32_t group_id; > - DependItem depend_items[3]; > - > - int surface_id; > - int surfaces_dest[3]; > - > - uint32_t process_commands_generation; > -}; > - > typedef struct _Drawable _Drawable; > struct _Drawable { > union { > @@ -908,91 +835,6 @@ static inline int validate_surface(RedWorker *worker, > uint32_t surface_id) > return 1; > } > > -static const char *draw_type_to_str(uint8_t type) > -{ > - switch (type) { > - case QXL_DRAW_FILL: > - return "QXL_DRAW_FILL"; > - case QXL_DRAW_OPAQUE: > - return "QXL_DRAW_OPAQUE"; > - case QXL_DRAW_COPY: > - return "QXL_DRAW_COPY"; > - case QXL_DRAW_TRANSPARENT: > - return "QXL_DRAW_TRANSPARENT"; > - case QXL_DRAW_ALPHA_BLEND: > - return "QXL_DRAW_ALPHA_BLEND"; > - case QXL_COPY_BITS: > - return "QXL_COPY_BITS"; > - case QXL_DRAW_BLEND: > - return "QXL_DRAW_BLEND"; > - case QXL_DRAW_BLACKNESS: > - return "QXL_DRAW_BLACKNESS"; > - case QXL_DRAW_WHITENESS: > - return "QXL_DRAW_WHITENESS"; > - case QXL_DRAW_INVERS: > - return "QXL_DRAW_INVERS"; > - case QXL_DRAW_ROP3: > - return "QXL_DRAW_ROP3"; > - case QXL_DRAW_COMPOSITE: > - return "QXL_DRAW_COMPOSITE"; > - case QXL_DRAW_STROKE: > - return "QXL_DRAW_STROKE"; > - case QXL_DRAW_TEXT: > - return "QXL_DRAW_TEXT"; > - default: > - return "?"; > - } > -} > - > -static void show_red_drawable(RedWorker *worker, RedDrawable *drawable, > const char *prefix) > -{ > - if (prefix) { > - printf("%s: ", prefix); > - } > - > - printf("%s effect %d bbox(%d %d %d %d)", > - draw_type_to_str(drawable->type), > - drawable->effect, > - drawable->bbox.top, > - drawable->bbox.left, > - drawable->bbox.bottom, > - drawable->bbox.right); > - > - switch (drawable->type) { > - case QXL_DRAW_FILL: > - case QXL_DRAW_OPAQUE: > - case QXL_DRAW_COPY: > - case QXL_DRAW_TRANSPARENT: > - case QXL_DRAW_ALPHA_BLEND: > - case QXL_COPY_BITS: > - case QXL_DRAW_BLEND: > - case QXL_DRAW_BLACKNESS: > - case QXL_DRAW_WHITENESS: > - case QXL_DRAW_INVERS: > - case QXL_DRAW_ROP3: > - case QXL_DRAW_COMPOSITE: > - case QXL_DRAW_STROKE: > - case QXL_DRAW_TEXT: > - break; > - default: > - spice_error("bad drawable type"); > - } > - printf("\n"); > -} > - > -static void show_draw_item(RedWorker *worker, DrawItem *draw_item, const > char *prefix) > -{ > - if (prefix) { > - printf("%s: ", prefix); > - } > - printf("effect %d bbox(%d %d %d %d)\n", > - draw_item->effect, > - draw_item->base.rgn.extents.x1, > - draw_item->base.rgn.extents.y1, > - draw_item->base.rgn.extents.x2, > - draw_item->base.rgn.extents.y2); > -} > - > static inline void red_create_surface_item(DisplayChannelClient *dcc, int > surface_id); > static void red_push_surface_image(DisplayChannelClient *dcc, int > surface_id); > > @@ -1556,43 +1398,6 @@ static inline void current_remove(RedWorker *worker, > TreeItem *item) > } > } > > -static void current_tree_for_each(Ring *ring, void (*f)(TreeItem *, void *), > void * data) > -{ > - RingItem *ring_item; > - Ring *top_ring; > - > - if (!(ring_item = ring_get_head(ring))) { > - return; > - } > - top_ring = ring; > - > - for (;;) { > - TreeItem *now = SPICE_CONTAINEROF(ring_item, TreeItem, > siblings_link); > - > - f(now, data); > - > - if (now->type == TREE_ITEM_TYPE_CONTAINER) { > - Container *container = (Container *)now; > - > - if ((ring_item = ring_get_head(&container->items))) { > - ring = &container->items; > - continue; > - } > - } > - for (;;) { > - ring_item = ring_next(ring, &now->siblings_link); > - if (ring_item) { > - break; > - } > - if (ring == top_ring) { > - return; > - } > - now = (TreeItem *)now->container; > - ring = (now->container) ? &now->container->items : top_ring; > - } > - } > -} > - > static void red_current_clear(RedWorker *worker, int surface_id) > { > RingItem *ring_item; > @@ -8365,70 +8170,21 @@ static inline void red_push(RedWorker *worker) > } > } > > -typedef struct ShowTreeData { > - RedWorker *worker; > - int level; > - Container *container; > -} ShowTreeData; > - > -static void __show_tree_call(TreeItem *item, void *data) > -{ > - ShowTreeData *tree_data = data; > - const char *item_prefix = "|--"; > - int i; > - > - while (tree_data->container != item->container) { > - spice_assert(tree_data->container); > - tree_data->level--; > - tree_data->container = tree_data->container->base.container; > - } > - > - switch (item->type) { > - case TREE_ITEM_TYPE_DRAWABLE: { > - Drawable *drawable = SPICE_CONTAINEROF(item, Drawable, tree_item); > - const int max_indent = 200; > - char indent_str[max_indent + 1]; > - int indent_str_len; > - > - for (i = 0; i < tree_data->level; i++) { > - printf(" "); > - } > - printf(item_prefix, 0); > - show_red_drawable(tree_data->worker, drawable->red_drawable, NULL); > - for (i = 0; i < tree_data->level; i++) { > - printf(" "); > - } > - printf("| "); > - show_draw_item(tree_data->worker, &drawable->tree_item, NULL); > - indent_str_len = MIN(max_indent, strlen(item_prefix) + > tree_data->level * 2); > - memset(indent_str, ' ', indent_str_len); > - indent_str[indent_str_len] = 0; > - region_dump(&item->rgn, indent_str); > - printf("\n"); > - break; > - } > - case TREE_ITEM_TYPE_CONTAINER: > - tree_data->level++; > - tree_data->container = (Container *)item; > - break; > - case TREE_ITEM_TYPE_SHADOW: > - break; > - } > -} > - > void red_show_tree(RedWorker *worker) > { > int x; > > - ShowTreeData show_tree_data; > - show_tree_data.worker = 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->surfaces[x].current, > __show_tree_call, > - &show_tree_data); > + if (!worker->surfaces[x].context.canvas) > + continue; > + > + RingItem *it; > + Ring *ring = &worker->surfaces[x].current; > + RING_FOREACH(it, ring) { > + TreeItem *now = SPICE_CONTAINEROF(it, TreeItem, siblings_link); > + tree_item_dump(now); > } > + > } > } > > diff --git a/server/tree.c b/server/tree.c > new file mode 100644 > index 0000000..ed7d39a > --- /dev/null > +++ b/server/tree.c > @@ -0,0 +1,182 @@ > +/* > + Copyright (C) 2009-2015 Red Hat, Inc. > + > + This library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + This library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with this library; if not, see > <http://www.gnu.org/licenses/>. > +*/ > +#include <spice/qxl_dev.h> > +#include "red_parse_qxl.h" > +#include "display-channel.h" > + > +#include "tree.h" > + > +static const char *draw_type_to_str(uint8_t type) > +{ > + switch (type) { > + case QXL_DRAW_FILL: > + return "QXL_DRAW_FILL"; > + case QXL_DRAW_OPAQUE: > + return "QXL_DRAW_OPAQUE"; > + case QXL_DRAW_COPY: > + return "QXL_DRAW_COPY"; > + case QXL_DRAW_TRANSPARENT: > + return "QXL_DRAW_TRANSPARENT"; > + case QXL_DRAW_ALPHA_BLEND: > + return "QXL_DRAW_ALPHA_BLEND"; > + case QXL_COPY_BITS: > + return "QXL_COPY_BITS"; > + case QXL_DRAW_BLEND: > + return "QXL_DRAW_BLEND"; > + case QXL_DRAW_BLACKNESS: > + return "QXL_DRAW_BLACKNESS"; > + case QXL_DRAW_WHITENESS: > + return "QXL_DRAW_WHITENESS"; > + case QXL_DRAW_INVERS: > + return "QXL_DRAW_INVERS"; > + case QXL_DRAW_ROP3: > + return "QXL_DRAW_ROP3"; > + case QXL_DRAW_COMPOSITE: > + return "QXL_DRAW_COMPOSITE"; > + case QXL_DRAW_STROKE: > + return "QXL_DRAW_STROKE"; > + case QXL_DRAW_TEXT: > + return "QXL_DRAW_TEXT"; > + default: > + return "?"; > + } > +} > + > +static void show_red_drawable(RedDrawable *drawable, const char *prefix) > +{ > + if (prefix) { > + printf("%s: ", prefix); > + } > + > + printf("%s effect %d bbox(%d %d %d %d)", > + draw_type_to_str(drawable->type), > + drawable->effect, > + drawable->bbox.top, > + drawable->bbox.left, > + drawable->bbox.bottom, > + drawable->bbox.right); > + > + switch (drawable->type) { > + case QXL_DRAW_FILL: > + case QXL_DRAW_OPAQUE: > + case QXL_DRAW_COPY: > + case QXL_DRAW_TRANSPARENT: > + case QXL_DRAW_ALPHA_BLEND: > + case QXL_COPY_BITS: > + case QXL_DRAW_BLEND: > + case QXL_DRAW_BLACKNESS: > + case QXL_DRAW_WHITENESS: > + case QXL_DRAW_INVERS: > + case QXL_DRAW_ROP3: > + case QXL_DRAW_COMPOSITE: > + case QXL_DRAW_STROKE: > + case QXL_DRAW_TEXT: > + break; > + default: > + spice_error("bad drawable type"); > + } > + printf("\n"); > +} > + > +static void show_draw_item(DrawItem *draw_item, const char *prefix) > +{ > + if (prefix) { > + printf("%s: ", prefix); > + } > + printf("effect %d bbox(%d %d %d %d)\n", > + draw_item->effect, > + draw_item->base.rgn.extents.x1, > + draw_item->base.rgn.extents.y1, > + draw_item->base.rgn.extents.x2, > + draw_item->base.rgn.extents.y2); > +} > + > +typedef struct DumpItem { > + int level; > + Container *container; > +} DumpItem; > + > +static void dump_item(TreeItem *item, void *data) > +{ > + DumpItem *di = data; > + const char *item_prefix = "|--"; > + int i; > + > + if (di->container) { > + while (di->container != item->container) { > + di->level--; > + di->container = di->container->base.container; > + } > + } > + > + switch (item->type) { > + case TREE_ITEM_TYPE_DRAWABLE: { > + Drawable *drawable = SPICE_CONTAINEROF(item, Drawable, tree_item); > + const int max_indent = 200; > + char indent_str[max_indent + 1]; > + int indent_str_len; > + > + for (i = 0; i < di->level; i++) { > + printf(" "); > + } > + printf(item_prefix, 0); > + show_red_drawable(drawable->red_drawable, NULL); > + for (i = 0; i < di->level; i++) { > + printf(" "); > + } > + printf("| "); > + show_draw_item(&drawable->tree_item, NULL); > + indent_str_len = MIN(max_indent, strlen(item_prefix) + di->level * > 2); > + memset(indent_str, ' ', indent_str_len); > + indent_str[indent_str_len] = 0; > + region_dump(&item->rgn, indent_str); > + printf("\n"); > + break; > + } > + case TREE_ITEM_TYPE_CONTAINER: > + di->level++; > + di->container = (Container *)item; > + break; > + case TREE_ITEM_TYPE_SHADOW: > + break; > + } > +} > + > +static void tree_foreach(TreeItem *item, void (*f)(TreeItem *, void *), void > * data) > +{ > + if (!item) > + return; > + > + f(item, data); > + > + if (item->type == TREE_ITEM_TYPE_CONTAINER) { > + Container *container = (Container*)item; > + RingItem *it; > + > + RING_FOREACH(it, &container->items) { > + tree_foreach(SPICE_CONTAINEROF(it, TreeItem, siblings_link), f, > data); > + } > + } > +} > + > +void tree_item_dump(TreeItem *item) > +{ > + DumpItem di = { 0, }; > + > + spice_return_if_fail(item != NULL); > + tree_foreach(item, dump_item, &di); > +} > diff --git a/server/tree.h b/server/tree.h > new file mode 100644 > index 0000000..8cd7b05 > --- /dev/null > +++ b/server/tree.h > @@ -0,0 +1,111 @@ > +/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ > +/* > + Copyright (C) 2009-2015 Red Hat, Inc. > + > + This library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + This library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with this library; if not, see > <http://www.gnu.org/licenses/>. > +*/ > +#ifndef TREE_H_ > +# define TREE_H_ > + > +#include <stdint.h> > +#include "common/region.h" > +#include "common/ring.h" > + > +enum { > + TREE_ITEM_TYPE_NONE, > + TREE_ITEM_TYPE_DRAWABLE, > + TREE_ITEM_TYPE_CONTAINER, > + TREE_ITEM_TYPE_SHADOW, > + > + TREE_ITEM_TYPE_LAST, > +}; > + > +typedef struct TreeItem TreeItem; > +typedef struct Shadow Shadow; > +typedef struct Container Container; > +typedef struct DrawItem DrawItem; > + > +/* TODO consider GNode instead */ > +struct TreeItem { > + RingItem siblings_link; > + uint32_t type; > + Container *container; > + QRegion rgn; > +}; > + > +struct Shadow { > + TreeItem base; > + QRegion on_hold; > + DrawItem* owner; > +}; > + > +struct Container { > + TreeItem base; > + Ring items; > +}; > + > +struct DrawItem { > + TreeItem base; > + uint8_t effect; > + uint8_t container_root; > + Shadow *shadow; > +}; > + > +#define IS_DRAW_ITEM(item) ((item)->type == TREE_ITEM_TYPE_DRAWABLE) > + > +typedef enum { > + BITMAP_GRADUAL_INVALID, > + BITMAP_GRADUAL_NOT_AVAIL, > + BITMAP_GRADUAL_LOW, > + BITMAP_GRADUAL_MEDIUM, > + BITMAP_GRADUAL_HIGH, > +} BitmapGradualType; > + > +typedef struct DependItem { > + Drawable *drawable; > + RingItem ring_item; > +} DependItem; > + > +struct Drawable { > + uint8_t refs; > + RingItem surface_list_link; > + RingItem list_link; > + DrawItem tree_item; > + Ring pipes; > + PipeItem *pipe_item_rest; > + uint32_t size_pipe_item_rest; > + RedDrawable *red_drawable; > + > + Ring glz_ring; > + > + red_time_t creation_time; > + int frames_count; > + int gradual_frames_count; > + int last_gradual_frame; > + Stream *stream; > + Stream *sized_stream; > + int streamable; > + BitmapGradualType copy_bitmap_graduality; > + uint32_t group_id; > + DependItem depend_items[3]; > + > + int surface_id; > + int surfaces_dest[3]; > + > + uint32_t process_commands_generation; > +}; > + > +void tree_item_dump (TreeItem *item); > + > +#endif /* TREE_H_ */ Acked and pushed. (no comments beside this in more than a week). Frediano _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel