[Spice-devel] [PATCH 09/10] tree: move that to a seperate unit

Frediano Ziglio fziglio at redhat.com
Mon Nov 2 04:43:49 PST 2015


> 
> From: Marc-André Lureau <marcandre.lureau at gmail.com>
> 
> ---
>  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


More information about the Spice-devel mailing list