[gtk/wip/chergert/refcount-line-display: 1/2] textlayout: make GtkTextLineDisplay reference counted
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/refcount-line-display: 1/2] textlayout: make GtkTextLineDisplay reference counted
- Date: Tue, 23 Jul 2019 22:02:06 +0000 (UTC)
commit e0b9b51e9f2f744c3ab517083579b567ac1d3fca
Author: Christian Hergert <chergert redhat com>
Date: Tue Jul 23 14:52:14 2019 -0700
textlayout: make GtkTextLineDisplay reference counted
This makes GtkTextLineDisplay use GRcBox instead of g_slice_*
directly. By using reference counting for this structure, we
can ensure that we hold an extra ref for one_display_cache as
well as caching additional GtkTextLineDisplay for the visible
range in the future.
gtk/gtktextlayout.c | 62 ++++++++++++++++++++++++----------------------
gtk/gtktextlayoutprivate.h | 2 ++
2 files changed, 35 insertions(+), 29 deletions(-)
---
diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c
index 6974353b7c..f150c927fa 100644
--- a/gtk/gtktextlayout.c
+++ b/gtk/gtktextlayout.c
@@ -197,12 +197,7 @@ gtk_text_layout_dispose (GObject *object)
g_clear_object (&layout->ltr_context);
g_clear_object (&layout->rtl_context);
- if (layout->one_display_cache)
- {
- GtkTextLineDisplay *tmp_display = layout->one_display_cache;
- layout->one_display_cache = NULL;
- gtk_text_layout_free_line_display (layout, tmp_display);
- }
+ g_clear_pointer (&layout->one_display_cache, gtk_text_line_display_unref);
if (layout->preedit_attrs != NULL)
{
@@ -826,20 +821,17 @@ gtk_text_layout_invalidate_cache (GtkTextLayout *layout,
{
if (layout->one_display_cache && line == layout->one_display_cache->line)
{
- GtkTextLineDisplay *display = layout->one_display_cache;
-
if (cursors_only)
{
- if (display->cursors)
- g_array_free (display->cursors, TRUE);
- display->cursors = NULL;
+ GtkTextLineDisplay *display = layout->one_display_cache;
+
+ g_clear_pointer (&display->cursors, g_array_unref);
display->cursors_invalid = TRUE;
display->has_block_cursor = FALSE;
}
else
{
- layout->one_display_cache = NULL;
- gtk_text_layout_free_line_display (layout, display);
+ g_clear_pointer (&layout->one_display_cache, gtk_text_line_display_unref);
}
}
}
@@ -2287,19 +2279,17 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
{
if (!size_only)
update_text_display_cursors (layout, line, layout->one_display_cache);
- return layout->one_display_cache;
+ return gtk_text_line_display_ref (layout->one_display_cache);
}
else
{
- GtkTextLineDisplay *tmp_display = layout->one_display_cache;
- layout->one_display_cache = NULL;
- gtk_text_layout_free_line_display (layout, tmp_display);
+ g_clear_pointer (&layout->one_display_cache, gtk_text_line_display_unref);
}
}
DV (g_print ("creating one line display cache (%s)\n", G_STRLOC));
- display = g_slice_new0 (GtkTextLineDisplay);
+ display = g_rc_box_new0 (GtkTextLineDisplay);
display->size_only = size_only;
display->line = line;
@@ -2619,7 +2609,9 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
if (tags != NULL)
g_ptr_array_free (tags, TRUE);
- layout->one_display_cache = display;
+ g_assert (layout->one_display_cache == NULL);
+
+ layout->one_display_cache = gtk_text_line_display_ref (display);
if (saw_widget)
allocate_child_widgets (layout, display);
@@ -2627,20 +2619,32 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
return display;
}
+static void
+gtk_text_line_display_finalize (GtkTextLineDisplay *display)
+{
+ g_clear_object (&display->layout);
+ g_clear_pointer (&display->cursors, g_array_unref);
+}
+
+GtkTextLineDisplay *
+gtk_text_line_display_ref (GtkTextLineDisplay *display)
+{
+ return g_rc_box_acquire (display);
+}
+
+void
+gtk_text_line_display_unref (GtkTextLineDisplay *display)
+{
+ g_rc_box_release_full (display, (GDestroyNotify)gtk_text_line_display_finalize);
+}
+
+/* For compat until we switch away from this */
void
gtk_text_layout_free_line_display (GtkTextLayout *layout,
GtkTextLineDisplay *display)
{
- if (display != layout->one_display_cache)
- {
- if (display->layout)
- g_object_unref (display->layout);
-
- if (display->cursors)
- g_array_free (display->cursors, TRUE);
-
- g_slice_free (GtkTextLineDisplay, display);
- }
+ if (display != NULL)
+ gtk_text_line_display_unref (display);
}
/* Functions to convert iter <=> index for the line of a GtkTextLineDisplay
diff --git a/gtk/gtktextlayoutprivate.h b/gtk/gtktextlayoutprivate.h
index 7aff2074ff..366fbb86c8 100644
--- a/gtk/gtktextlayoutprivate.h
+++ b/gtk/gtktextlayoutprivate.h
@@ -300,6 +300,8 @@ GtkTextLineDisplay* gtk_text_layout_get_line_display (GtkTextLayout *layou
gboolean size_only);
void gtk_text_layout_free_line_display (GtkTextLayout *layout,
GtkTextLineDisplay *display);
+GtkTextLineDisplay *gtk_text_line_display_ref (GtkTextLineDisplay *display);
+void gtk_text_line_display_unref (GtkTextLineDisplay *display);
void gtk_text_layout_get_line_at_y (GtkTextLayout *layout,
GtkTextIter *target_iter,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]