diff options
author | Matthias Clasen <mclasen@redhat.com> | 2021-03-28 10:18:23 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2021-03-28 10:26:06 -0400 |
commit | 2d5dd7b3d72098a89ff610786a09bb23c3afbf05 (patch) | |
tree | 3710d27d0449ea48cf4f192cf6ffaf15a1d4c909 | |
parent | 0904dd29c20ca8539b9b4261bc595a8f90d19933 (diff) | |
download | gtk+-2d5dd7b3d72098a89ff610786a09bb23c3afbf05.tar.gz |
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.
-rw-r--r-- | gsk/gskrendernode.c | 21 | ||||
-rw-r--r-- | gsk/gskrendernodeimpl.c | 41 | ||||
-rw-r--r-- | 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); |