forked from AuroraMiddleware/gtk
textview: optimize linedisplay cache based on number of visible rows
This tries to estimate the number of visible rows in a textview based on the default text size and then tunes the GtkTextLineDisplayCache to keep 3*n_rows entries in the cache. This was found imperically to be near the right cache size. In most cases, this is less than the number of items we cache now. However, in some cases, such as the "overview map" from GtkSourceView, it allows us to reach a higher value such as 1000+. This is needed to keep scrolling smooth on the larger view sizes. With this patch, a HiDPI system with a GtkSourceView and GtkSourceMap from the GTK 4 port can perform smooth scrolling simultaneously.
This commit is contained in:
parent
a29853f53b
commit
5e49da1d73
@ -4210,3 +4210,12 @@ gtk_text_line_display_compare (const GtkTextLineDisplay *display1,
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_text_layout_set_mru_size (GtkTextLayout *layout,
|
||||
guint mru_size)
|
||||
{
|
||||
GtkTextLayoutPrivate *priv = GTK_TEXT_LAYOUT_GET_PRIVATE (layout);
|
||||
|
||||
gtk_text_line_display_cache_set_mru_size (priv->cache, mru_size);
|
||||
}
|
||||
|
@ -414,6 +414,9 @@ void gtk_text_layout_snapshot (GtkTextLayout *layout,
|
||||
const GdkRectangle *clip,
|
||||
float cursor_alpha);
|
||||
|
||||
void gtk_text_layout_set_mru_size (GtkTextLayout *layout,
|
||||
guint mru_size);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_TEXT_LAYOUT_PRIVATE_H__ */
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include "gtktextiterprivate.h"
|
||||
#include "gtktextlinedisplaycacheprivate.h"
|
||||
|
||||
#define MRU_MAX_SIZE 250
|
||||
#define DEFAULT_MRU_SIZE 250
|
||||
#define BLOW_CACHE_TIMEOUT_SEC 20
|
||||
#define DEBUG_LINE_DISPLAY_CACHE 0
|
||||
|
||||
@ -35,6 +35,7 @@ struct _GtkTextLineDisplayCache
|
||||
GtkTextLine *cursor_line;
|
||||
GQueue mru;
|
||||
GSource *evict_source;
|
||||
guint mru_size;
|
||||
|
||||
#if DEBUG_LINE_DISPLAY_CACHE
|
||||
guint log_source;
|
||||
@ -78,6 +79,7 @@ gtk_text_line_display_cache_new (void)
|
||||
ret = g_slice_new0 (GtkTextLineDisplayCache);
|
||||
ret->sorted_by_line = g_sequence_new ((GDestroyNotify)gtk_text_line_display_unref);
|
||||
ret->line_to_display = g_hash_table_new (NULL, NULL);
|
||||
ret->mru_size = DEFAULT_MRU_SIZE;
|
||||
|
||||
#if DEBUG_LINE_DISPLAY_CACHE
|
||||
ret->log_source = g_timeout_add_seconds (1, dump_stats, ret);
|
||||
@ -200,7 +202,7 @@ gtk_text_line_display_cache_take_display (GtkTextLineDisplayCache *cache,
|
||||
g_queue_push_head_link (&cache->mru, &display->mru_link);
|
||||
|
||||
/* Cull the cache if we're at capacity */
|
||||
while (cache->mru.length > MRU_MAX_SIZE)
|
||||
while (cache->mru.length > cache->mru_size)
|
||||
{
|
||||
display = g_queue_peek_tail (&cache->mru);
|
||||
|
||||
@ -716,3 +718,27 @@ gtk_text_line_display_cache_set_cursor_line (GtkTextLineDisplayCache *cache,
|
||||
if (display != NULL)
|
||||
gtk_text_line_display_cache_invalidate_display (cache, display, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_text_line_display_cache_set_mru_size (GtkTextLineDisplayCache *cache,
|
||||
guint mru_size)
|
||||
{
|
||||
GtkTextLineDisplay *display;
|
||||
|
||||
g_assert (cache != NULL);
|
||||
|
||||
if (mru_size == 0)
|
||||
mru_size = DEFAULT_MRU_SIZE;
|
||||
|
||||
if (mru_size != cache->mru_size)
|
||||
{
|
||||
cache->mru_size = mru_size;
|
||||
|
||||
while (cache->mru.length > cache->mru_size)
|
||||
{
|
||||
display = g_queue_peek_tail (&cache->mru);
|
||||
|
||||
gtk_text_line_display_cache_invalidate_display (cache, display, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,6 +53,8 @@ void gtk_text_line_display_cache_invalidate_y_range (GtkText
|
||||
gint y,
|
||||
gint height,
|
||||
gboolean cursors_only);
|
||||
void gtk_text_line_display_cache_set_mru_size (GtkTextLineDisplayCache *cache,
|
||||
guint mru_size);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -4109,6 +4109,8 @@ gtk_text_view_size_allocate (GtkWidget *widget,
|
||||
GdkRectangle top_rect;
|
||||
GdkRectangle bottom_rect;
|
||||
GtkWidget *chooser;
|
||||
PangoLayout *layout;
|
||||
guint mru_size;
|
||||
|
||||
text_view = GTK_TEXT_VIEW (widget);
|
||||
priv = text_view->priv;
|
||||
@ -4178,6 +4180,16 @@ gtk_text_view_size_allocate (GtkWidget *widget,
|
||||
if (!gtk_adjustment_is_animating (priv->vadjustment))
|
||||
gtk_text_view_set_vadjustment_values (text_view);
|
||||
|
||||
/* Optimize display cache size */
|
||||
layout = gtk_widget_create_pango_layout (widget, "X");
|
||||
pango_layout_get_pixel_size (layout, &width, &height);
|
||||
if (height > 0)
|
||||
{
|
||||
mru_size = SCREEN_HEIGHT (widget) / height * 3;
|
||||
gtk_text_layout_set_mru_size (priv->layout, mru_size);
|
||||
}
|
||||
g_object_unref (layout);
|
||||
|
||||
/* The GTK resize loop processes all the pending exposes right
|
||||
* after doing the resize stuff, so the idle sizer won't have a
|
||||
* chance to run. So we do the work here.
|
||||
|
Loading…
Reference in New Issue
Block a user