summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@gmail.com>2013-09-10 22:59:31 +0200
committerFrediano Ziglio <fziglio@redhat.com>2015-11-02 12:12:14 +0000
commit372eb0072aca0051867b5b9496d5376c685567af (patch)
tree59407c7ade6f21faf6d1df7a5aa9b720542ef4a4
parent9e42647101ef3683a3318ba2baaae7e4edd58baf (diff)
downloadspice-372eb0072aca0051867b5b9496d5376c685567af.tar.gz
spice-372eb0072aca0051867b5b9496d5376c685567af.tar.xz
spice-372eb0072aca0051867b5b9496d5376c685567af.zip
tree: move that to a separate unit
Acked-by: Frediano Ziglio <fziglio@redhat.com>
-rw-r--r--server/Makefile.am2
-rw-r--r--server/display-channel.h6
-rw-r--r--server/red_worker.c265
-rw-r--r--server/tree.c182
-rw-r--r--server/tree.h111
5 files changed, 311 insertions, 255 deletions
diff --git a/server/Makefile.am b/server/Makefile.am
index 87288ccb..c15a7014 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -130,6 +130,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/display-channel.h b/server/display-channel.h
index e1ddc117..7f3ab7c2 100644
--- a/server/display-channel.h
+++ b/server/display-channel.h
@@ -18,9 +18,15 @@
#ifndef RED_WORKER_CLIENT_H_
# define RED_WORKER_CLIENT_H_
+#include <setjmp.h>
+
#include "red_worker.h"
#include "cache-item.h"
#include "pixmap-cache.h"
+#include "reds_sw_canvas.h"
+#include "glz_encoder_dictionary.h"
+#include "glz_encoder.h"
+#include "mjpeg_encoder.h"
#include "utils.h"
typedef struct Drawable Drawable;
diff --git a/server/red_worker.c b/server/red_worker.c
index 68cb153c..c1eff6d9 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -94,6 +94,7 @@
#include "pixmap-cache.h"
#include "display-channel.h"
#include "cursor-channel.h"
+#include "tree.h"
//#define COMPRESS_STAT
//#define DUMP_BITMAP
@@ -424,52 +425,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 */
@@ -478,35 +433,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 {
@@ -927,91 +853,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);
@@ -1575,43 +1416,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;
@@ -8393,70 +8197,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 00000000..ed7d39ad
--- /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 00000000..8cd7b05f
--- /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_ */