[gtk/smarter-diff: 4/5] gsk: Make rendernode diffing smarter
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/smarter-diff: 4/5] gsk: Make rendernode diffing smarter
- Date: Sun, 28 Mar 2021 14:46:00 +0000 (UTC)
commit 2d5dd7b3d72098a89ff610786a09bb23c3afbf05
Author: Matthias Clasen <mclasen redhat com>
Date: Sun Mar 28 10:18:23 2021 -0400
gsk: Make rendernode diffing smarter
Allow comparing container nodes to any other
node, by pretending the other node is a single
child container (if it isn't one already).
This fixes a glitch where we redraw the full
entry text when the blinking cursor goes to
opacity 0, since GskSnapshot then optimizes
away first the opacity node, and then the
single-child container.
gsk/gskrendernode.c | 21 +++++++++++++++------
gsk/gskrendernodeimpl.c | 41 +++++++++++++++++++++++++++++++++++------
gsk/gskrendernodeprivate.h | 3 +++
3 files changed, 53 insertions(+), 12 deletions(-)
---
diff --git a/gsk/gskrendernode.c b/gsk/gskrendernode.c
index 00d893be06..fb2ddd3962 100644
--- a/gsk/gskrendernode.c
+++ b/gsk/gskrendernode.c
@@ -489,10 +489,14 @@ gsk_render_node_can_diff (const GskRenderNode *node1,
if (node1 == node2)
return TRUE;
- if (_gsk_render_node_get_node_type (node1) != _gsk_render_node_get_node_type (node2))
- return FALSE;
+ if (_gsk_render_node_get_node_type (node1) == _gsk_render_node_get_node_type (node2))
+ return GSK_RENDER_NODE_GET_CLASS (node1)->can_diff (node1, node2);
- return GSK_RENDER_NODE_GET_CLASS (node1)->can_diff (node1, node2);
+ if (_gsk_render_node_get_node_type (node1) == GSK_CONTAINER_NODE ||
+ _gsk_render_node_get_node_type (node2) == GSK_CONTAINER_NODE)
+ return TRUE;
+
+ return FALSE;
}
static void
@@ -544,10 +548,15 @@ gsk_render_node_diff (GskRenderNode *node1,
if (node1 == node2)
return;
- if (_gsk_render_node_get_node_type (node1) != _gsk_render_node_get_node_type (node2))
- return gsk_render_node_diff_impossible (node1, node2, region);
+ if (_gsk_render_node_get_node_type (node1) == _gsk_render_node_get_node_type (node2))
+ return GSK_RENDER_NODE_GET_CLASS (node1)->diff (node1, node2, region);
+
+ if (_gsk_render_node_get_node_type (node1) == GSK_CONTAINER_NODE)
+ return gsk_container_node_diff_with (node1, node2, region);
+ if (_gsk_render_node_get_node_type (node2) == GSK_CONTAINER_NODE)
+ return gsk_container_node_diff_with (node2, node1, region);
- return GSK_RENDER_NODE_GET_CLASS (node1)->diff (node1, node2, region);
+ return gsk_render_node_diff_impossible (node1, node2, region);
}
/**
diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c
index beeb147fc2..d611977acc 100644
--- a/gsk/gskrendernodeimpl.c
+++ b/gsk/gskrendernodeimpl.c
@@ -2641,6 +2641,36 @@ gsk_container_node_get_diff_settings (void)
return settings;
}
+static gboolean
+gsk_render_node_diff_multiple (GskRenderNode **nodes1,
+ gsize n_nodes1,
+ GskRenderNode **nodes2,
+ gsize n_nodes2,
+ cairo_region_t *region)
+{
+ return gsk_diff ((gconstpointer *) nodes1, n_nodes1,
+ (gconstpointer *) nodes2, n_nodes2,
+ gsk_container_node_get_diff_settings (),
+ region) == GSK_DIFF_OK;
+}
+
+void
+gsk_container_node_diff_with (GskRenderNode *container,
+ GskRenderNode *other,
+ cairo_region_t *region)
+{
+ GskContainerNode *self = (GskContainerNode *) container;
+
+ if (gsk_render_node_diff_multiple (self->children,
+ self->n_children,
+ &other,
+ 1,
+ region))
+ return;
+
+ gsk_render_node_diff_impossible (container, other, region);
+}
+
static void
gsk_container_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
@@ -2649,12 +2679,11 @@ gsk_container_node_diff (GskRenderNode *node1,
GskContainerNode *self1 = (GskContainerNode *) node1;
GskContainerNode *self2 = (GskContainerNode *) node2;
- if (gsk_diff ((gconstpointer *) self1->children,
- self1->n_children,
- (gconstpointer *) self2->children,
- self2->n_children,
- gsk_container_node_get_diff_settings (),
- region) == GSK_DIFF_OK)
+ if (gsk_render_node_diff_multiple (self1->children,
+ self1->n_children,
+ self2->children,
+ self2->n_children,
+ region))
return;
gsk_render_node_diff_impossible (node1, node2, region);
diff --git a/gsk/gskrendernodeprivate.h b/gsk/gskrendernodeprivate.h
index 07ec707c03..a767daa365 100644
--- a/gsk/gskrendernodeprivate.h
+++ b/gsk/gskrendernodeprivate.h
@@ -93,6 +93,9 @@ void gsk_render_node_diff (GskRenderNode
void gsk_render_node_diff_impossible (GskRenderNode *node1,
GskRenderNode *node2,
cairo_region_t *region);
+void gsk_container_node_diff_with (GskRenderNode *container,
+ GskRenderNode *other,
+ cairo_region_t *region);
bool gsk_border_node_get_uniform (const GskRenderNode *self);
bool gsk_border_node_get_uniform_color (const GskRenderNode *self);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]