summaryrefslogtreecommitdiff
path: root/gsk/gskrenderer.c
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2018-03-28 15:43:43 +0200
committerBenjamin Otte <otte@redhat.com>2018-04-05 14:56:38 +0200
commit925cbeaadffddbb42dbedc1a61230a4db97c8a44 (patch)
tree5f4fe41d27f3b648f6685888b4c73c21a04f0808 /gsk/gskrenderer.c
parent7c313c7b254da37929cff8bd45c41921f257a376 (diff)
downloadgtk+-925cbeaadffddbb42dbedc1a61230a4db97c8a44.tar.gz
renderer: Track the previous node
... and diff the previous node with the current one to determine the clip region. This doubles the work necessary to track clip regions, but the following commits will clean that up.
Diffstat (limited to 'gsk/gskrenderer.c')
-rw-r--r--gsk/gskrenderer.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/gsk/gskrenderer.c b/gsk/gskrenderer.c
index c011fb6cf2..e4945feb5e 100644
--- a/gsk/gskrenderer.c
+++ b/gsk/gskrenderer.c
@@ -66,6 +66,7 @@ typedef struct
GObject parent_instance;
GdkSurface *surface;
+ GskRenderNode *prev_node;
GskRenderNode *root_node;
GdkDisplay *display;
@@ -375,6 +376,8 @@ gsk_renderer_unrealize (GskRenderer *renderer)
GSK_RENDERER_GET_CLASS (renderer)->unrealize (renderer);
+ g_clear_pointer (&priv->prev_node, gsk_render_node_unref);
+
priv->is_realized = FALSE;
}
@@ -465,32 +468,37 @@ gsk_renderer_render (GskRenderer *renderer,
const cairo_region_t *region)
{
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
- cairo_region_t *real_region;
+ cairo_region_t *clip;
g_return_if_fail (GSK_IS_RENDERER (renderer));
g_return_if_fail (priv->is_realized);
g_return_if_fail (GSK_IS_RENDER_NODE (root));
g_return_if_fail (priv->root_node == NULL);
- priv->root_node = gsk_render_node_ref (root);
-
- if (region == NULL || GSK_RENDERER_DEBUG_CHECK (renderer, FULL_REDRAW))
+ if (region == NULL || priv->prev_node == NULL || GSK_RENDERER_DEBUG_CHECK (renderer, FULL_REDRAW))
{
- real_region = cairo_region_create_rectangle (&(GdkRectangle) {
- 0, 0,
- gdk_surface_get_width (priv->surface),
- gdk_surface_get_height (priv->surface)
- });
-
- GSK_RENDERER_GET_CLASS (renderer)->render (renderer, root, real_region);
-
- cairo_region_destroy (real_region);
+ clip = cairo_region_create_rectangle (&(GdkRectangle) {
+ 0, 0,
+ gdk_surface_get_width (priv->surface),
+ gdk_surface_get_height (priv->surface)
+ });
}
else
{
- GSK_RENDERER_GET_CLASS (renderer)->render (renderer, root, region);
+ clip = cairo_region_copy (region);
+ gsk_render_node_diff (priv->prev_node, root, clip);
+
+ if (cairo_region_is_empty (clip))
+ {
+ cairo_region_destroy (clip);
+ return;
+ }
}
+ priv->root_node = gsk_render_node_ref (root);
+
+ GSK_RENDERER_GET_CLASS (renderer)->render (renderer, root, clip);
+
#ifdef G_ENABLE_DEBUG
if (GSK_RENDERER_DEBUG_CHECK (renderer, RENDERER))
{
@@ -508,7 +516,9 @@ gsk_renderer_render (GskRenderer *renderer,
}
#endif
- g_clear_pointer (&priv->root_node, gsk_render_node_unref);
+ g_clear_pointer (&priv->prev_node, gsk_render_node_unref);
+ priv->prev_node = priv->root_node;
+ priv->root_node = NULL;
}
/*< private >