[gtk/wip/chergert/gtk3-speedup-char_is_invisible: 3/3] textbtree: short-circuit visibility check when possible
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/gtk3-speedup-char_is_invisible: 3/3] textbtree: short-circuit visibility check when possible
- Date: Wed, 18 Mar 2020 20:02:51 +0000 (UTC)
commit 9fc7c3b1b36265813a778445d97f89faef53a669
Author: Christian Hergert <chergert redhat com>
Date: Wed Mar 18 12:56:19 2020 -0700
textbtree: short-circuit visibility check when possible
If we have never seen a GtkTextTag in the GtkTextTagTable with the
invisible bit set, then we do not need to go through the process of
checking the accumulated tags.
Not using invisible tags is overwhelmingly the common case.
gtk/gtktextbtree.c | 9 ++++++++-
gtk/gtktexttagtable.c | 27 +++++++++++++++++++++++++++
gtk/gtktexttagtableprivate.h | 15 ++++++++-------
3 files changed, 43 insertions(+), 8 deletions(-)
---
diff --git a/gtk/gtktextbtree.c b/gtk/gtktextbtree.c
index 1931e46a40..b2475e8aa1 100644
--- a/gtk/gtktextbtree.c
+++ b/gtk/gtktextbtree.c
@@ -61,7 +61,7 @@
#include "gtktextbufferprivate.h"
#include "gtktexttag.h"
#include "gtktexttagprivate.h"
-#include "gtktexttagtable.h"
+#include "gtktexttagtableprivate.h"
#include "gtktextlayout.h"
#include "gtktextiterprivate.h"
#include "gtkdebug.h"
@@ -2492,6 +2492,13 @@ _gtk_text_btree_char_is_invisible (const GtkTextIter *iter)
line = _gtk_text_iter_get_text_line (iter);
tree = _gtk_text_iter_get_btree (iter);
+
+ /* Short-circuit if we've never seen a visibility tag within the
+ * tag table (meaning everything must be visible).
+ */
+ if G_LIKELY (!_gtk_text_tag_table_affects_visibility (tree->table))
+ return FALSE;
+
byte_index = gtk_text_iter_get_line_index (iter);
numTags = gtk_text_tag_table_get_size (tree->table);
diff --git a/gtk/gtktexttagtable.c b/gtk/gtktexttagtable.c
index d2c4b5154d..3b0de892b0 100644
--- a/gtk/gtktexttagtable.c
+++ b/gtk/gtktexttagtable.c
@@ -68,6 +68,8 @@ struct _GtkTextTagTablePrivate
GSList *buffers;
gint anon_count;
+
+ guint seen_invisible : 1;
};
enum {
@@ -160,6 +162,22 @@ gtk_text_tag_table_init (GtkTextTagTable *table)
table->priv->hash = g_hash_table_new (g_str_hash, g_str_equal);
}
+static void
+check_visible (GtkTextTagTable *table,
+ GtkTextTag *tag)
+{
+ if (table->priv->seen_invisible)
+ return;
+
+ if (tag->priv->invisible_set)
+ {
+ gboolean invisible;
+
+ g_object_get (tag, "invisible", &invisible, NULL);
+ table->priv->seen_invisible = invisible;
+ }
+}
+
/**
* gtk_text_tag_table_new:
*
@@ -281,6 +299,8 @@ gtk_text_tag_table_add (GtkTextTagTable *table,
g_assert (size > 0);
tag->priv->priority = size - 1;
+ check_visible (table, tag);
+
g_signal_emit (table, signals[TAG_ADDED], 0, tag);
return TRUE;
}
@@ -470,5 +490,12 @@ _gtk_text_tag_table_tag_changed (GtkTextTagTable *table,
GtkTextTag *tag,
gboolean size_changed)
{
+ check_visible (table, tag);
g_signal_emit (table, signals[TAG_CHANGED], 0, tag, size_changed);
}
+
+gboolean
+_gtk_text_tag_table_affects_visibility (GtkTextTagTable *table)
+{
+ return table->priv->seen_invisible;
+}
diff --git a/gtk/gtktexttagtableprivate.h b/gtk/gtktexttagtableprivate.h
index 0a8401e695..4bf0d5773c 100644
--- a/gtk/gtktexttagtableprivate.h
+++ b/gtk/gtktexttagtableprivate.h
@@ -29,13 +29,14 @@
G_BEGIN_DECLS
-void _gtk_text_tag_table_add_buffer (GtkTextTagTable *table,
- gpointer buffer);
-void _gtk_text_tag_table_remove_buffer (GtkTextTagTable *table,
- gpointer buffer);
-void _gtk_text_tag_table_tag_changed (GtkTextTagTable *table,
- GtkTextTag *tag,
- gboolean size_changed);
+void _gtk_text_tag_table_add_buffer (GtkTextTagTable *table,
+ gpointer buffer);
+void _gtk_text_tag_table_remove_buffer (GtkTextTagTable *table,
+ gpointer buffer);
+void _gtk_text_tag_table_tag_changed (GtkTextTagTable *table,
+ GtkTextTag *tag,
+ gboolean size_changed);
+gboolean _gtk_text_tag_table_affects_visibility (GtkTextTagTable *table);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]