[gtk/wip/chergert/cache-text-render-node] textview: cache paragraph render nodes
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/cache-text-render-node] textview: cache paragraph render nodes
- Date: Tue, 8 Oct 2019 18:44:58 +0000 (UTC)
commit 3b959456ac5335639e9642571f59f17ec8ee97f7
Author: Christian Hergert <chergert redhat com>
Date: Tue Oct 8 11:35:49 2019 -0700
textview: cache paragraph render nodes
We can avoid recreating a number of text nodes from render_para() on
sub-sequent runs if we cache the rendernode instead of just the
PangoLayout.
When used with GtkSourceMap, this can yield a ~7 FPS improvement during
smooth scrolling at the cost of some more memory.
gtk/gtktextlayout.c | 37 ++++++++++++++++++++++++++++++-------
gtk/gtktextlayoutprivate.h | 3 +++
gtk/gtktextlinedisplaycache.c | 1 +
3 files changed, 34 insertions(+), 7 deletions(-)
---
diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c
index f51dd42fcb..d7c270a9dc 100644
--- a/gtk/gtktextlayout.c
+++ b/gtk/gtktextlayout.c
@@ -2643,6 +2643,7 @@ gtk_text_line_display_finalize (GtkTextLineDisplay *display)
g_clear_object (&display->layout);
g_clear_pointer (&display->cursors, g_array_unref);
+ g_clear_pointer (&display->node, gsk_render_node_unref);
}
GtkTextLineDisplay *
@@ -3862,7 +3863,6 @@ render_para (GskPangoRenderer *crenderer,
int screen_width;
GdkRGBA *selection = NULL;
gboolean first = TRUE;
- graphene_point_t point = { 0, offset_y };
g_return_if_fail (GTK_IS_TEXT_VIEW (crenderer->widget));
@@ -3880,8 +3880,12 @@ render_para (GskPangoRenderer *crenderer,
gtk_style_context_restore (context);
}
- gtk_snapshot_save (crenderer->snapshot);
- gtk_snapshot_translate (crenderer->snapshot, &point);
+ if (offset_y)
+ {
+ gtk_snapshot_save (crenderer->snapshot);
+ gtk_snapshot_translate (crenderer->snapshot,
+ &GRAPHENE_POINT_INIT (0, offset_y));
+ }
do
{
@@ -4054,7 +4058,8 @@ render_para (GskPangoRenderer *crenderer,
}
while (pango_layout_iter_next_line (iter));
- gtk_snapshot_restore (crenderer->snapshot);
+ if (offset_y)
+ gtk_snapshot_restore (crenderer->snapshot);
gdk_rgba_free (selection);
pango_layout_iter_free (iter);
@@ -4146,9 +4151,27 @@ gtk_text_layout_snapshot (GtkTextLayout *layout,
}
}
- render_para (crenderer, offset_y, line_display,
- selection_start_index, selection_end_index,
- cursor_alpha);
+ if (line_display->node == NULL)
+ {
+ GtkSnapshot *sub = gtk_snapshot_new ();
+
+ crenderer->snapshot = sub;
+ render_para (crenderer, 0, line_display,
+ selection_start_index, selection_end_index,
+ cursor_alpha);
+ crenderer->snapshot = snapshot;
+
+ line_display->node = gtk_snapshot_free_to_node (sub);
+ }
+
+ if (line_display->node != NULL)
+ {
+ gtk_snapshot_save (crenderer->snapshot);
+ gtk_snapshot_translate (crenderer->snapshot,
+ &GRAPHENE_POINT_INIT (0, offset_y));
+ gtk_snapshot_append_node (crenderer->snapshot, line_display->node);
+ gtk_snapshot_restore (crenderer->snapshot);
+ }
/* We paint the cursors last, because they overlap another chunk
* and need to appear on top.
diff --git a/gtk/gtktextlayoutprivate.h b/gtk/gtktextlayoutprivate.h
index 99d4f812e8..f408d199de 100644
--- a/gtk/gtktextlayoutprivate.h
+++ b/gtk/gtktextlayoutprivate.h
@@ -216,6 +216,9 @@ struct _GtkTextAttrAppearance
struct _GtkTextLineDisplay
{
PangoLayout *layout;
+
+ GskRenderNode *node;
+
GArray *cursors; /* indexes of cursors in the PangoLayout */
/* GSequenceIter backpointer for use within cache */
diff --git a/gtk/gtktextlinedisplaycache.c b/gtk/gtktextlinedisplaycache.c
index 2fe174c0f6..c15d8907d6 100644
--- a/gtk/gtktextlinedisplaycache.c
+++ b/gtk/gtktextlinedisplaycache.c
@@ -234,6 +234,7 @@ gtk_text_line_display_cache_invalidate_display (GtkTextLineDisplayCache *cache,
if (cursors_only)
{
g_clear_pointer (&display->cursors, g_array_unref);
+ g_clear_pointer (&display->node, gsk_render_node_unref);
display->cursors_invalid = TRUE;
display->has_block_cursor = FALSE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]