[gtk+/wip/pango-shadow-cache: 9/9] cssshadowvalue: Add a cache for blurred Pango layouts
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/pango-shadow-cache: 9/9] cssshadowvalue: Add a cache for blurred Pango layouts
- Date: Sat, 30 Aug 2014 00:45:04 +0000 (UTC)
commit a74cf529a801da75f58c738c44581cda82b58b13
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Fri Aug 29 13:51:30 2014 -0700
cssshadowvalue: Add a cache for blurred Pango layouts
Drawing text with Pango is quite expensive, and drawing text and also
blurring it is *really* expensive. To prevent us from drawing a lot of
text and then blurring it a lot is *really* expensive.
To detect changes
gtk/gtkcssshadowvalue.c | 83 +++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 74 insertions(+), 9 deletions(-)
---
diff --git a/gtk/gtkcssshadowvalue.c b/gtk/gtkcssshadowvalue.c
index 90b7848..2a5707a 100644
--- a/gtk/gtkcssshadowvalue.c
+++ b/gtk/gtkcssshadowvalue.c
@@ -321,6 +321,17 @@ needs_blur (const GtkCssValue *shadow)
return TRUE;
}
+static void
+setup_cairo_for_shadow_apply (const GtkCssValue *shadow,
+ cairo_t *cr)
+{
+ gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
+
+ cairo_translate (cr,
+ _gtk_css_number_value_get (shadow->hoffset, 0),
+ _gtk_css_number_value_get (shadow->voffset, 0));
+}
+
static const cairo_user_data_key_t original_cr_key;
static cairo_t *
@@ -332,11 +343,7 @@ gtk_css_shadow_value_start_drawing (const GtkCssValue *shadow,
cairo_t *blur_cr;
gdouble radius, clip_radius;
- gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
-
- cairo_translate (cr,
- _gtk_css_number_value_get (shadow->hoffset, 0),
- _gtk_css_number_value_get (shadow->voffset, 0));
+ setup_cairo_for_shadow_apply (shadow, cr);
if (!needs_blur (shadow))
return cr;
@@ -390,6 +397,35 @@ gtk_css_shadow_value_finish_drawing (const GtkCssValue *shadow,
return original_cr;
}
+static const cairo_user_data_key_t radius_key;
+static const cairo_user_data_key_t layout_serial_key;
+
+G_DEFINE_QUARK (GtkCssShadowValue pango_cached_blurred_surface, pango_cached_blurred_surface)
+
+static cairo_surface_t *
+get_cached_surface (PangoLayout *layout,
+ const GtkCssValue *shadow)
+{
+ cairo_surface_t *cached_surface = g_object_get_qdata (G_OBJECT (layout),
pango_cached_blurred_surface_quark ());
+ guint cached_radius, cached_serial;
+ guint radius, serial;
+
+ if (!cached_surface)
+ return NULL;
+
+ radius = _gtk_css_number_value_get (shadow->radius, 0);
+ cached_radius = GPOINTER_TO_UINT (cairo_surface_get_user_data (cached_surface, &radius_key));
+ if (radius != cached_radius)
+ return NULL;
+
+ serial = pango_layout_get_serial (layout);
+ cached_serial = GPOINTER_TO_UINT (cairo_surface_get_user_data (cached_surface, &layout_serial_key));
+ if (serial != cached_serial)
+ return NULL;
+
+ return cached_surface;
+}
+
void
_gtk_css_shadow_value_paint_layout (const GtkCssValue *shadow,
cairo_t *cr,
@@ -402,10 +438,39 @@ _gtk_css_shadow_value_paint_layout (const GtkCssValue *shadow,
cairo_save (cr);
- cr = gtk_css_shadow_value_start_drawing (shadow, cr);
- _gtk_pango_fill_layout (cr, layout);
- cr = gtk_css_shadow_value_finish_drawing (shadow, cr);
+ if (needs_blur (shadow))
+ {
+ cairo_surface_t *cached_surface = get_cached_surface (layout, shadow);
+ if (cached_surface)
+ {
+ setup_cairo_for_shadow_apply (shadow, cr);
+ cairo_mask_surface (cr, cached_surface, 0, 0);
+ }
+ else
+ {
+ guint radius, serial;
+
+ cr = gtk_css_shadow_value_start_drawing (shadow, cr);
+ _gtk_pango_fill_layout (cr, layout);
+ cached_surface = cairo_get_target (cr);
+ g_object_set_qdata_full (G_OBJECT (layout), pango_cached_blurred_surface_quark (),
+ cairo_surface_reference (cached_surface),
+ (GDestroyNotify) cairo_surface_destroy);
+ cr = gtk_css_shadow_value_finish_drawing (shadow, cr);
+
+ radius = _gtk_css_number_value_get (shadow->radius, 0);
+ cairo_surface_set_user_data (cached_surface, &radius_key, GUINT_TO_POINTER (radius), NULL);
+ serial = pango_layout_get_serial (layout);
+ cairo_surface_set_user_data (cached_surface, &layout_serial_key, GUINT_TO_POINTER (serial), NULL);
+ }
+ }
+ else
+ {
+ cr = gtk_css_shadow_value_start_drawing (shadow, cr);
+ _gtk_pango_fill_layout (cr, layout);
+ cr = gtk_css_shadow_value_finish_drawing (shadow, cr);
+ }
cairo_restore (cr);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]