[gtk+/wip/alexl/broadway4: 59/62] broadway: Deserialize node tree in server
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/alexl/broadway4: 59/62] broadway: Deserialize node tree in server
- Date: Thu, 30 Nov 2017 07:35:39 +0000 (UTC)
commit 44f21f86fe9a3d4c0f8d146b0ec8cac3a36c6ed5
Author: Alexander Larsson <alexl redhat com>
Date: Wed Nov 29 19:08:37 2017 +0100
broadway: Deserialize node tree in server
This doesn't really change anything, but it is in preparation for diffing
the trees.
gdk/broadway/broadway-output.c | 35 +++++++++++++---
gdk/broadway/broadway-output.h | 4 +-
gdk/broadway/broadway-server.c | 31 +++++++++----
gdk/broadway/broadway-server.h | 12 ++++-
gdk/broadway/broadwayd.c | 90 +++++++++++++++++++++++++---------------
5 files changed, 118 insertions(+), 54 deletions(-)
---
diff --git a/gdk/broadway/broadway-output.c b/gdk/broadway/broadway-output.c
index 036f71b..e679923 100644
--- a/gdk/broadway/broadway-output.c
+++ b/gdk/broadway/broadway-output.c
@@ -296,19 +296,42 @@ broadway_output_set_transient_for (BroadwayOutput *output,
append_uint16 (output, parent_id);
}
+static void
+append_node (BroadwayOutput *output,
+ BroadwayNode *node)
+{
+ append_uint32 (output, node->type);
+ guint32 i;
+
+ for (i = 0; i < node->n_data; i++)
+ append_uint32 (output, node->data[i]);
+ for (i = 0; i < node->n_children; i++)
+ append_node (output, node->children[i]);
+}
+
+guint32
+get_node_size (BroadwayNode *node)
+{
+ guint32 size = 1 + node->n_data;
+ guint32 i;
+
+ for (i = 0; i < node->n_children; i++)
+ size += get_node_size (node->children[i]);
+
+ return size;
+}
+
+
void
broadway_output_window_set_nodes (BroadwayOutput *output,
int id,
- guint32 *data,
- guint32 data_len)
+ BroadwayNode *root)
{
write_header (output, BROADWAY_OP_SET_NODES);
- guint32 i;
append_uint16 (output, id);
- append_uint32 (output, data_len);
- for (i = 0; i < data_len; i++)
- append_uint32 (output, data[i]);
+ append_uint32 (output, get_node_size (root));
+ append_node (output, root);
}
void
diff --git a/gdk/broadway/broadway-output.h b/gdk/broadway/broadway-output.h
index bf35be2..db1ba94 100644
--- a/gdk/broadway/broadway-output.h
+++ b/gdk/broadway/broadway-output.h
@@ -4,6 +4,7 @@
#include <glib.h>
#include <gio/gio.h>
#include "broadway-protocol.h"
+#include "broadway-server.h"
typedef struct BroadwayOutput BroadwayOutput;
@@ -58,8 +59,7 @@ void broadway_output_set_transient_for (BroadwayOutput *output,
int parent_id);
void broadway_output_window_set_nodes (BroadwayOutput *output,
int id,
- guint32 *data,
- guint32 data_len);
+ BroadwayNode *root);
void broadway_output_upload_texture (BroadwayOutput *output,
guint32 id,
GBytes *texture);
diff --git a/gdk/broadway/broadway-server.c b/gdk/broadway/broadway-server.c
index 3f9dfeb..a6b3114 100644
--- a/gdk/broadway/broadway-server.c
+++ b/gdk/broadway/broadway-server.c
@@ -125,8 +125,7 @@ struct BroadwayWindow {
gboolean visible;
gint32 transient_for;
guint32 texture;
- guint32 *nodes;
- gint nodes_len;
+ BroadwayNode *nodes;
};
static void broadway_server_resync_windows (BroadwayServer *server);
@@ -137,6 +136,17 @@ static GType broadway_server_get_type (void);
G_DEFINE_TYPE (BroadwayServer, broadway_server, G_TYPE_OBJECT)
static void
+broadway_node_free (BroadwayNode *node)
+{
+ int i;
+ for (i = 0; i < node->n_children; i++)
+ broadway_node_free (node->children[i]);
+
+ g_free (node);
+}
+
+
+static void
broadway_server_init (BroadwayServer *server)
{
BroadwayWindow *root;
@@ -187,7 +197,8 @@ broadway_server_class_init (BroadwayServerClass * class)
static void
broadway_window_free (BroadwayWindow *window)
{
- g_free (window->nodes);
+ if (window->nodes)
+ broadway_node_free (window->nodes);
g_free (window);
}
@@ -1612,11 +1623,11 @@ broadway_server_has_client (BroadwayServer *server)
return server->output != NULL;
}
+/* passes ownership of nodes */
void
broadway_server_window_set_nodes (BroadwayServer *server,
gint id,
- gint n_data,
- guint32 *data)
+ BroadwayNode *root)
{
BroadwayWindow *window;
@@ -1624,13 +1635,13 @@ broadway_server_window_set_nodes (BroadwayServer *server,
if (window == NULL)
return;
- g_free (window->nodes);
- window->nodes = g_memdup (data, sizeof (guint32)*n_data);
- window->nodes_len = n_data;
+ if (window->nodes)
+ broadway_node_free (window->nodes);
+ window->nodes = root;
if (server->output != NULL)
broadway_output_window_set_nodes (server->output, window->id,
- window->nodes, window->nodes_len);
+ window->nodes);
}
guint32
@@ -1877,7 +1888,7 @@ broadway_server_resync_windows (BroadwayServer *server)
if (window->nodes)
broadway_output_window_set_nodes (server->output, window->id,
- window->nodes, window->nodes_len);
+ window->nodes);
if (window->visible)
broadway_output_show_surface (server->output, window->id);
diff --git a/gdk/broadway/broadway-server.h b/gdk/broadway/broadway-server.h
index d120261..b24fc5e 100644
--- a/gdk/broadway/broadway-server.h
+++ b/gdk/broadway/broadway-server.h
@@ -18,6 +18,15 @@ typedef struct _BroadwayServerClass BroadwayServerClass;
#define BROADWAY_IS_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), BROADWAY_TYPE_SERVER))
#define BROADWAY_SERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), BROADWAY_TYPE_SERVER,
BroadwayServerClass))
+typedef struct _BroadwayNode BroadwayNode;
+
+struct _BroadwayNode {
+ guint32 type;
+ guint32 n_children;
+ BroadwayNode **children;
+ guint32 n_data;
+ guint32 data[1];
+};
BroadwayServer *broadway_server_new (char *address,
int port,
@@ -87,8 +96,7 @@ cairo_surface_t * broadway_server_create_surface (int
int height);
void broadway_server_window_set_nodes (BroadwayServer *server,
gint id,
- gint n_data,
- guint32 *data);
+ BroadwayNode *root);
gboolean broadway_server_window_move_resize (BroadwayServer *server,
gint id,
gboolean with_move,
diff --git a/gdk/broadway/broadwayd.c b/gdk/broadway/broadwayd.c
index 638b7f9..912a191 100644
--- a/gdk/broadway/broadwayd.c
+++ b/gdk/broadway/broadwayd.c
@@ -224,66 +224,88 @@ get_client_serial (BroadwayClient *client, guint32 daemon_serial)
#define NODE_SIZE_COLOR_STOP (NODE_SIZE_FLOAT + NODE_SIZE_COLOR)
#define NODE_SIZE_SHADOW (NODE_SIZE_COLOR + 3 * NODE_SIZE_FLOAT)
-static int
-rewrite_node_textures (BroadwayClient *client,
- int len, guint32 data[], int pos)
+static BroadwayNode *
+decode_nodes (BroadwayClient *client,
+ int len, guint32 data[], int *pos)
{
+ BroadwayNode *node;
guint32 type;
- guint32 i, n_children, n_stops, n_shadows;
+ guint32 i, n_stops, n_shadows;
+ guint32 size, n_children;
+ gint32 texture_offset;
- g_assert (pos < len);
+ g_assert (*pos < len);
- type = data[pos++];
+ size = 0;
+ n_children = 0;
+ texture_offset = -1;
+
+ type = data[(*pos)++];
switch (type) {
case BROADWAY_NODE_COLOR:
- pos += NODE_SIZE_RECT + NODE_SIZE_COLOR;
+ size = NODE_SIZE_RECT + NODE_SIZE_COLOR;
break;
case BROADWAY_NODE_BORDER:
- pos += NODE_SIZE_RRECT + 4 * NODE_SIZE_FLOAT + 4 * NODE_SIZE_COLOR;
+ size = NODE_SIZE_RRECT + 4 * NODE_SIZE_FLOAT + 4 * NODE_SIZE_COLOR;
break;
case BROADWAY_NODE_INSET_SHADOW:
case BROADWAY_NODE_OUTSET_SHADOW:
- pos += NODE_SIZE_RRECT + NODE_SIZE_COLOR + 4 * NODE_SIZE_FLOAT;
+ size = NODE_SIZE_RRECT + NODE_SIZE_COLOR + 4 * NODE_SIZE_FLOAT;
break;
case BROADWAY_NODE_TEXTURE:
- data[pos+4] = GPOINTER_TO_INT (g_hash_table_lookup (client->textures,
- GINT_TO_POINTER (data[pos+4])));
- pos += 5;
+ texture_offset = 4;
+ size = 5;
break;
case BROADWAY_NODE_CONTAINER:
- n_children = data[pos++];
- for (i = 0; i < n_children; i++)
- pos = rewrite_node_textures (client, len, data, pos);
+ size = 1;
+ n_children = data[*pos];
break;
case BROADWAY_NODE_ROUNDED_CLIP:
- pos += NODE_SIZE_RRECT;
- pos = rewrite_node_textures (client, len, data, pos);
+ size = NODE_SIZE_RRECT;
+ n_children = 1;
break;
case BROADWAY_NODE_CLIP:
- pos += NODE_SIZE_RECT;
- pos = rewrite_node_textures (client, len, data, pos);
+ size = NODE_SIZE_RECT;
+ n_children = 1;
break;
case BROADWAY_NODE_LINEAR_GRADIENT:
- pos += NODE_SIZE_RECT + 2 * NODE_SIZE_POINT;
- n_stops = data[pos++];
- pos += n_stops * NODE_SIZE_COLOR_STOP;
+ size = NODE_SIZE_RECT + 2 * NODE_SIZE_POINT;
+ n_stops = data[*pos + size++];
+ size += n_stops * NODE_SIZE_COLOR_STOP;
break;
case BROADWAY_NODE_SHADOW:
- n_shadows = data[pos++];
- pos += n_shadows * NODE_SIZE_SHADOW;
- pos = rewrite_node_textures (client, len, data, pos);
+ size = 1;
+ n_shadows = data[*pos];
+ size += n_shadows * NODE_SIZE_SHADOW;
+ n_children = 1;
break;
case BROADWAY_NODE_OPACITY:
- pos += NODE_SIZE_FLOAT;
- pos = rewrite_node_textures (client, len, data, pos);
+ size = NODE_SIZE_FLOAT;
+ n_children = 1;
break;
default:
g_assert_not_reached ();
}
- return pos;
-}
+ node = g_malloc (sizeof(BroadwayNode) + (size - 1) * sizeof(guint32) + n_children * sizeof (BroadwayNode
*));
+ node->type = type;
+ node->n_children = n_children;
+ node->children = (BroadwayNode **)((char *)node + sizeof(BroadwayNode) + (size - 1) * sizeof(guint32));
+ node->n_data = size;
+ for (i = 0; i < size; i++)
+ {
+ node->data[i] = data[(*pos)++];
+ if (i == texture_offset)
+ node->data[i] = GPOINTER_TO_INT (g_hash_table_lookup (client->textures,
+ GINT_TO_POINTER (node->data[i])));
+ }
+
+ for (i = 0; i < n_children; i++)
+ node->children[i] = decode_nodes (client, len, data, pos);
+
+ return node;
+}
static void
client_handle_request (BroadwayClient *client,
@@ -360,13 +382,13 @@ client_handle_request (BroadwayClient *client,
{
gsize array_size = request->base.size - sizeof (BroadwayRequestSetNodes) + sizeof(guint32);
int n_data = array_size / sizeof(guint32);
+ int pos = 0;
+ BroadwayNode *node;
- rewrite_node_textures (client, n_data, request->set_nodes.data, 0);
+ node = decode_nodes (client, n_data, request->set_nodes.data, &pos);
- broadway_server_window_set_nodes (server,
- request->set_nodes.id,
- n_data,
- request->set_nodes.data);
+ broadway_server_window_set_nodes (server, request->set_nodes.id,
+ node);
}
break;
case BROADWAY_REQUEST_UPLOAD_TEXTURE:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]