[gtk+/wip/alexl/broadway4: 29/39] broadway: Deserialize node tree in server



commit 1820362b2b419a3185f030dcab3a0f90bae06cbb
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]