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

Frediano Ziglio fziglio at redhat.com
Tue Oct 27 12:19:15 PDT 2015


From: Marc-André Lureau <marcandre.lureau at gmail.com>

---
 server/Makefile.am  |   2 +
 server/red_worker.c | 265 ++--------------------------------------------------
 server/tree.c       | 182 ++++++++++++++++++++++++++++++++++++
 server/tree.h       | 111 ++++++++++++++++++++++
 4 files changed, 305 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 164c986..9c731b8 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -133,6 +133,8 @@ libspice_server_la_SOURCES =			\
 	spice_image_cache.c			\
 	pixmap-cache.h				\
 	pixmap-cache.c				\
+	tree.h				\
+	tree.c				\
 	$(NULL)
 
 if HAVE_GL
diff --git a/server/red_worker.c b/server/red_worker.c
index 036bbd8..fa74ec6 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -64,6 +64,7 @@
 #include "red_worker.h"
 #include "spice_timer_queue.h"
 #include "cursor-channel.h"
+#include "tree.h"
 
 //#define COMPRESS_STAT
 //#define DUMP_BITMAP
@@ -411,52 +412,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 */
@@ -465,35 +420,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 {
@@ -912,91 +838,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);
 
@@ -1560,43 +1401,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;
@@ -8439,70 +8243,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..58aeb57
--- /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_ */
-- 
2.4.3



More information about the Spice-devel mailing list