[gtk/wip/alexl/broadway7: 6/16] broadway: Support patching nodes for textures and transforms



commit e71c90bf7016d4e880fe259daf516adfd1458b76
Author: Alexander Larsson <alexl redhat com>
Date:   Thu Mar 28 20:22:44 2019 +0100

    broadway: Support patching nodes for textures and transforms

 gdk/broadway/broadway-output.c   | 54 +++++++++++++++++++++++++++-
 gdk/broadway/broadway-protocol.h |  2 ++
 gdk/broadway/broadway.js         | 76 +++++++++++++++++++++++++++++-----------
 3 files changed, 111 insertions(+), 21 deletions(-)
---
diff --git a/gdk/broadway/broadway-output.c b/gdk/broadway/broadway-output.c
index 853a66eb85..4666acb61f 100644
--- a/gdk/broadway/broadway-output.c
+++ b/gdk/broadway/broadway-output.c
@@ -387,6 +387,58 @@ append_node (BroadwayOutput *output,
   append_node_depth--;
 }
 
+static gboolean
+should_reuse_node (BroadwayOutput *output,
+                   BroadwayNode   *node,
+                   BroadwayNode   *old_node)
+{
+  int i;
+  guint32 new_texture;
+
+  if (old_node->reused)
+    return FALSE;
+
+  if (node->type != old_node->type)
+    return FALSE;
+
+  if (broadway_node_equal (node, old_node))
+    return TRUE;
+
+  switch (node->type) {
+  case BROADWAY_NODE_TRANSFORM:
+#ifdef DEBUG_NODE_SENDING
+   g_print ("Patching transform node %d/%d\n",
+            old_node->id, old_node->output_id);
+#endif
+    append_uint32 (output, BROADWAY_NODE_OP_PATCH_TRANSFORM);
+    append_uint32 (output, old_node->output_id);
+    for (i = 0; i < node->n_data; i++)
+      append_uint32 (output, node->data[i]);
+    return TRUE;
+
+  case BROADWAY_NODE_TEXTURE:
+    /* Check that the size, etc is the same */
+    for (i = 0; i < 4; i++)
+      if (node->data[i] != old_node->data[i])
+        return FALSE;
+
+    new_texture = node->data[4];
+
+#ifdef DEBUG_NODE_SENDING
+   g_print ("Patching texture node %d/%d to tx=%d\n",
+            old_node->id, old_node->output_id,
+            new_texture);
+#endif
+    append_uint32 (output, BROADWAY_NODE_OP_PATCH_TEXTURE);
+    append_uint32 (output, old_node->output_id);
+    append_uint32 (output, new_texture);
+    return TRUE;
+    break;
+  default:
+    return FALSE;
+  }
+}
+
 
 static BroadwayNode *
 append_node_ops (BroadwayOutput *output,
@@ -441,7 +493,7 @@ append_node_ops (BroadwayOutput *output,
    * Except we avoid this for reused node as those make more sense to reuse deeply.
    */
 
-  if (old_node && broadway_node_equal (node, old_node) && !old_node->reused)
+  if (old_node && should_reuse_node (output, node, old_node))
     {
       int old_i = 0;
       BroadwayNode *last_child = NULL;
diff --git a/gdk/broadway/broadway-protocol.h b/gdk/broadway/broadway-protocol.h
index b642e342bc..9d1c2c03d4 100644
--- a/gdk/broadway/broadway-protocol.h
+++ b/gdk/broadway/broadway-protocol.h
@@ -29,6 +29,8 @@ typedef enum { /* Sync changes with broadway.js */
   BROADWAY_NODE_OP_INSERT_NODE = 0,
   BROADWAY_NODE_OP_REMOVE_NODE = 1,
   BROADWAY_NODE_OP_MOVE_AFTER_CHILD = 2,
+  BROADWAY_NODE_OP_PATCH_TEXTURE = 3,
+  BROADWAY_NODE_OP_PATCH_TRANSFORM = 4,
 } BroadwayNodeOpType;
 
 static const char *broadway_node_type_names[] G_GNUC_UNUSED =  {
diff --git a/gdk/broadway/broadway.js b/gdk/broadway/broadway.js
index 2cef2c1e7d..4ab39c9627 100644
--- a/gdk/broadway/broadway.js
+++ b/gdk/broadway/broadway.js
@@ -18,6 +18,8 @@ const BROADWAY_NODE_REUSE = 13;
 const BROADWAY_NODE_OP_INSERT_NODE = 0;
 const BROADWAY_NODE_OP_REMOVE_NODE = 1;
 const BROADWAY_NODE_OP_MOVE_AFTER_CHILD = 2;
+const BROADWAY_NODE_OP_PATCH_TEXTURE = 3;
+const BROADWAY_NODE_OP_PATCH_TRANSFORM = 4;
 
 const BROADWAY_OP_GRAB_POINTER = 'g';
 const BROADWAY_OP_UNGRAB_POINTER = 'u';
@@ -67,6 +69,8 @@ const DISPLAY_OP_MOVE_NODE = 7;
 const DISPLAY_OP_RESIZE_NODE = 8;
 const DISPLAY_OP_RESTACK_SURFACES = 9;
 const DISPLAY_OP_DELETE_SURFACE = 10;
+const DISPLAY_OP_CHANGE_TEXTURE = 11;
+const DISPLAY_OP_CHANGE_TRANSFORM = 12;
 
 // GdkCrossingMode
 const GDK_CROSSING_NORMAL = 0;
@@ -446,6 +450,28 @@ TransformNodes.prototype.decode_string = function() {
     return utf8_to_string (utf8);
 }
 
+TransformNodes.prototype.decode_transform = function() {
+    var transform_type = this.decode_uint32();
+
+    if (transform_type == 0) {
+        var point = this.decode_point();
+        return "translate(" + px(point.x) + "," + px(point.y) + ")";
+    } else if (transform_type == 1) {
+        var m = new Array();
+        for (var i = 0; i < 16; i++) {
+            m[i] = this.decode_float ();
+        }
+
+        return "matrix3d(" +
+            m[0] + "," + m[1] + "," + m[2] + "," + m[3]+ "," +
+            m[4] + "," + m[5] + "," + m[6] + "," + m[7] + "," +
+            m[8] + "," + m[9] + "," + m[10] + "," + m[11] + "," +
+            m[12] + "," + m[13] + "," + m[14] + "," + m[15] + ")";
+    } else {
+        alert("Unexpected transform type " + transform_type);
+    }
+}
+
 function args() {
     var argsLength = arguments.length;
     var strings = [];
@@ -654,25 +680,7 @@ TransformNodes.prototype.insertNode = function(parent, previousSibling, is_tople
 
     case BROADWAY_NODE_TRANSFORM:
         {
-            var transform_type = this.decode_uint32();
-            var transform_string;
-
-            if (transform_type == 0) {
-                var point = this.decode_point();
-                transform_string = "translate(" + px(point.x) + "," + px(point.y) + ")";
-            } else if (transform_type == 1) {
-                var m = new Array();
-                for (var i = 0; i < 16; i++) {
-                    m[i] = this.decode_float ();
-                }
-
-                transform_string =
-                    "matrix3d(" +
-                    m[0] + "," + m[1] + "," + m[2] + "," + m[3]+ "," +
-                    m[4] + "," + m[5] + "," + m[6] + "," + m[7] + "," +
-                    m[8] + "," + m[9] + "," + m[10] + "," + m[11] + "," +
-                    m[12] + "," + m[13] + "," + m[14] + "," + m[15] + ")";
-            }
+            var transform_string = this.decode_transform();
 
             var div = this.createDiv(id);
             div.style["transform"] = transform_string;
@@ -832,7 +840,21 @@ TransformNodes.prototype.execute = function(display_commands)
             var toMove = this.nodes[toMoveId];
             this.display_commands.push([DISPLAY_OP_INSERT_AFTER_CHILD, parent, previousChild, toMove]);
             break;
+        case BROADWAY_NODE_OP_PATCH_TEXTURE:
+            var textureNodeId = this.decode_uint32();
+            var textureNode = this.nodes[textureNodeId];
+            var textureId = this.decode_uint32();
+            var texture = textures[textureId].ref();
+            this.display_commands.push([DISPLAY_OP_CHANGE_TEXTURE, textureNode, texture]);
+            break;
+        case BROADWAY_NODE_OP_PATCH_TRANSFORM:
+            var transformNodeId = this.decode_uint32();
+            var transformNode = this.nodes[transformNodeId];
+            var transformString = this.decode_transform();
+            this.display_commands.push([DISPLAY_OP_CHANGE_TRANSFORM, transformNode, transformString]);
+            break;
         }
+
     }
 }
 
@@ -909,7 +931,21 @@ function handleDisplayCommands(display_commands)
             var id = cmd[1];
             delete surfaces[id];
             break;
-
+        case DISPLAY_OP_CHANGE_TEXTURE:
+            var image = cmd[1];
+            var texture = cmd[2];
+            // We need a new closure here to have a separate copy of "template" for each iteration...
+            function a_block(t) {
+                image.src = t.url;
+                // Unref blob url when loaded
+                image.onload = function() { t.unref(); };
+            }(texture);
+            break;
+        case DISPLAY_OP_CHANGE_TRANSFORM:
+            var div = cmd[1];
+            var transform_string = cmd[2];
+            div.style["transform"] = transform_string;
+            break;
         default:
             alert("Unknown display op " + command);
         }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]