summaryrefslogtreecommitdiff
path: root/gdk
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2019-03-28 20:22:44 +0100
committerAlexander Larsson <alexl@redhat.com>2019-03-29 14:30:13 +0100
commitb58a366dc641b015d5ed50430fa4dfa779ad04fa (patch)
treeb9fdddcadd6416997a3663336fb07dc8b6df4998 /gdk
parentf30ba5632380326f0178d0602522f471492fb9e9 (diff)
downloadgtk+-b58a366dc641b015d5ed50430fa4dfa779ad04fa.tar.gz
broadway: Support patching nodes for textures and transforms
Diffstat (limited to 'gdk')
-rw-r--r--gdk/broadway/broadway-output.c54
-rw-r--r--gdk/broadway/broadway-protocol.h2
-rw-r--r--gdk/broadway/broadway.js76
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);
}