[gtk/smooth-cursor: 1/3] text: cache the content and cursor nodes
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/smooth-cursor: 1/3] text: cache the content and cursor nodes
- Date: Tue, 23 Jul 2019 06:02:23 +0000 (UTC)
commit 70013161b332d744cf6baf928b6fa1f744cee137
Author: Matthias Clasen <mclasen redhat com>
Date: Mon Jul 22 16:50:29 2019 -0700
text: cache the content and cursor nodes
We don't want to redraw the unchanged text every frame
while we blink the cursor, so cache the pieces and just
combine them with the current opacity.
gtk/gtktext.c | 63 ++++++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 47 insertions(+), 16 deletions(-)
---
diff --git a/gtk/gtktext.c b/gtk/gtktext.c
index af9cf73e1d..9b3a7a014c 100644
--- a/gtk/gtktext.c
+++ b/gtk/gtktext.c
@@ -199,6 +199,9 @@ struct _GtkTextPrivate
guint blink_tick;
float cursor_alpha;
+ GskRenderNode *content_node;
+ GskRenderNode *cursor_node;
+
guint16 preedit_length; /* length of preedit string, in bytes */
guint16 preedit_cursor; /* offset of cursor within preedit string, in chars */
@@ -2245,6 +2248,18 @@ gtk_text_draw_undershoot (GtkText *self,
}
}
+static void
+gtk_text_queue_draw (GtkWidget *widget)
+{
+ GtkText *self = GTK_TEXT (widget);
+ GtkTextPrivate *priv = gtk_text_get_instance_private (self);
+
+ gtk_widget_queue_draw (widget);
+
+ g_clear_pointer (&priv->content_node, gsk_render_node_unref);
+ g_clear_pointer (&priv->cursor_node, gsk_render_node_unref);
+}
+
static void
gtk_text_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
@@ -2252,26 +2267,42 @@ gtk_text_snapshot (GtkWidget *widget,
GtkText *self = GTK_TEXT (widget);
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
- /* Draw text and cursor */
- if (priv->dnd_position != -1)
- gtk_text_draw_cursor (self, snapshot, CURSOR_DND);
+ if (!priv->content_node)
+ {
+ GtkSnapshot *s = gtk_snapshot_new ();
- if (priv->placeholder)
- gtk_widget_snapshot_child (widget, priv->placeholder, snapshot);
+ if (priv->dnd_position != -1)
+ gtk_text_draw_cursor (self, s, CURSOR_DND);
+
+ if (priv->placeholder)
+ gtk_widget_snapshot_child (widget, priv->placeholder, s);
- gtk_text_draw_text (self, snapshot);
+ gtk_text_draw_text (self, s);
+ gtk_text_draw_undershoot (self, s);
+
+ priv->content_node = gtk_snapshot_free_to_node (s);
+ }
+
+ gtk_snapshot_append_node (snapshot, priv->content_node);
/* When no text is being displayed at all, don't show the cursor */
if (gtk_text_get_display_mode (self) != DISPLAY_BLANK &&
gtk_widget_has_focus (widget) &&
priv->selection_bound == priv->current_pos)
{
+ if (!priv->cursor_node)
+ {
+ GtkSnapshot *s = gtk_snapshot_new ();
+
+ gtk_text_draw_cursor (self, s, CURSOR_STANDARD);
+
+ priv->cursor_node = gtk_snapshot_free_to_node (s);
+ }
+
gtk_snapshot_push_opacity (snapshot, priv->cursor_alpha);
- gtk_text_draw_cursor (self, snapshot, CURSOR_STANDARD);
+ gtk_snapshot_append_node (snapshot, priv->cursor_node);
gtk_snapshot_pop (snapshot);
}
-
- gtk_text_draw_undershoot (self, snapshot);
}
static void
@@ -2974,7 +3005,7 @@ gtk_text_focus_in (GtkWidget *widget)
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
GdkKeymap *keymap;
- gtk_widget_queue_draw (widget);
+ gtk_text_queue_draw (widget);
keymap = gdk_display_get_keymap (gtk_widget_get_display (widget));
@@ -3004,7 +3035,7 @@ gtk_text_focus_out (GtkWidget *widget)
_gtk_text_handle_set_mode (priv->text_handle,
GTK_TEXT_HANDLE_MODE_NONE);
- gtk_widget_queue_draw (widget);
+ gtk_text_queue_draw (widget);
keymap = gdk_display_get_keymap (gtk_widget_get_display (widget));
@@ -3894,7 +3925,7 @@ gtk_text_toggle_overwrite (GtkText *self)
}
gtk_text_pend_cursor_blink (self);
- gtk_widget_queue_draw (GTK_WIDGET (self));
+ gtk_text_queue_draw (GTK_WIDGET (self));
}
static void
@@ -4150,7 +4181,7 @@ gtk_text_recompute (GtkText *self)
gtk_text_update_handles (self, handle_mode);
}
- gtk_widget_queue_draw (GTK_WIDGET (self));
+ gtk_text_queue_draw (GTK_WIDGET (self));
}
static PangoLayout *
@@ -5241,7 +5272,7 @@ gtk_text_set_editable (GtkText *self,
is_editable ? priv->im_context : NULL);
g_object_notify (G_OBJECT (self), "editable");
- gtk_widget_queue_draw (widget);
+ gtk_text_queue_draw (widget);
}
}
@@ -6050,7 +6081,7 @@ gtk_text_drag_leave (GtkWidget *widget,
gtk_drag_unhighlight (widget);
priv->dnd_position = -1;
- gtk_widget_queue_draw (widget);
+ gtk_text_queue_draw (widget);
}
static gboolean
@@ -6121,7 +6152,7 @@ gtk_text_drag_motion (GtkWidget *widget,
gtk_drag_highlight (widget);
if (priv->dnd_position != old_position)
- gtk_widget_queue_draw (widget);
+ gtk_text_queue_draw (widget);
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]