[gtk+/wip/blur] Optimize blur rendering by always choosing the smaller surface to blur, since rendering speed is inv
- From: Andrea Cimitan <acimitan src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/blur] Optimize blur rendering by always choosing the smaller surface to blur, since rendering speed is inv
- Date: Wed, 18 Apr 2012 14:43:00 +0000 (UTC)
commit 51b6ce28871d1c7120d9e39f18079f805ede36db
Author: Andrea Cimitan <andrea cimitan canonical com>
Date: Wed Apr 18 15:40:52 2012 +0100
Optimize blur rendering by always choosing the smaller surface to blur, since rendering speed is inversely proportional to the dimension of the surface to blur
gtk/gtkcssshadowsvalue.c | 5 +-
gtk/gtkcssshadowsvalueprivate.h | 4 +-
gtk/gtkcssshadowvalue.c | 118 ++++++++++++++++++++++++++-------------
gtk/gtkcssshadowvalueprivate.h | 4 +-
gtk/gtkthemingengine.c | 13 +++-
5 files changed, 98 insertions(+), 46 deletions(-)
---
diff --git a/gtk/gtkcssshadowsvalue.c b/gtk/gtkcssshadowsvalue.c
index d4f7655..50ebe96 100644
--- a/gtk/gtkcssshadowsvalue.c
+++ b/gtk/gtkcssshadowsvalue.c
@@ -228,7 +228,8 @@ _gtk_css_shadows_value_paint_layout (const GtkCssValue *shadows,
void
_gtk_css_shadows_value_paint_icon (const GtkCssValue *shadows,
- cairo_t *cr)
+ cairo_t *cr,
+ cairo_rectangle_t *rect)
{
guint i;
@@ -236,7 +237,7 @@ _gtk_css_shadows_value_paint_icon (const GtkCssValue *shadows,
for (i = 0; i < shadows->len; i++)
{
- _gtk_css_shadow_value_paint_icon (shadows->values[i], cr);
+ _gtk_css_shadow_value_paint_icon (shadows->values[i], cr, rect);
}
}
diff --git a/gtk/gtkcssshadowsvalueprivate.h b/gtk/gtkcssshadowsvalueprivate.h
index 0918278..34b7db9 100644
--- a/gtk/gtkcssshadowsvalueprivate.h
+++ b/gtk/gtkcssshadowsvalueprivate.h
@@ -41,12 +41,14 @@ void _gtk_css_shadows_value_paint_layout (const GtkCssValue
PangoLayout *layout);
void _gtk_css_shadows_value_paint_icon (const GtkCssValue *shadows,
- cairo_t *cr);
+ cairo_t *cr,
+ cairo_rectangle_t *rect);
void _gtk_css_shadows_value_paint_spinner (const GtkCssValue *shadows,
cairo_t *cr,
gdouble radius,
gdouble progress);
+
void _gtk_css_shadows_value_paint_box (const GtkCssValue *shadows,
cairo_t *cr,
const GtkRoundedBox *padding_box);
diff --git a/gtk/gtkcssshadowvalue.c b/gtk/gtkcssshadowvalue.c
index 7296caf..ef75617 100644
--- a/gtk/gtkcssshadowvalue.c
+++ b/gtk/gtkcssshadowvalue.c
@@ -18,6 +18,7 @@
*/
#include "config.h"
+#include "math.h"
#include "gtkcssshadowvalueprivate.h"
@@ -291,43 +292,41 @@ _gtk_css_shadow_value_compute (GtkCssValue *shadow,
}
static void
-_gtk_css_shadow_value_blur_surface_create (const GtkCssValue *shadow,
- cairo_t *original_cr,
- cairo_t **out_cr,
- cairo_surface_t **out_surface)
+gtk_css_shadow_value_blur_surface_create (const GtkCssValue *shadow,
+ cairo_t *original_cr,
+ cairo_t **out_cr,
+ cairo_surface_t **out_surface,
+ cairo_rectangle_int_t *rect_surface)
{
- cairo_rectangle_int_t clip_rect;
- gdouble radius;
+ gint radius;
- gdk_cairo_get_clip_rectangle (original_cr, &clip_rect);
- radius = _gtk_css_number_value_get (shadow->radius, 0);
+ radius = ceil (_gtk_css_number_value_get (shadow->radius, 0));
/* Create a larger surface to center the blur. */
*out_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
- clip_rect.width + 2 * radius,
- clip_rect.height + 2 * radius);
+ rect_surface->width + 2 * radius,
+ rect_surface->height + 2 * radius);
*out_cr = cairo_create (*out_surface);
cairo_translate (*out_cr, radius, radius);
}
static void
-_gtk_css_shadow_value_blur_surface_paint (const GtkCssValue *shadow,
- cairo_t *cr,
- cairo_surface_t *surface)
+gtk_css_shadow_value_blur_surface_paint (const GtkCssValue *shadow,
+ cairo_t *cr,
+ cairo_surface_t *surface,
+ cairo_rectangle_int_t *rect_surface)
{
- gdouble x, y;
- gdouble radius;
+ gint radius;
- radius = _gtk_css_number_value_get (shadow->radius, 0);
+ radius = ceil (_gtk_css_number_value_get (shadow->radius, 0));
/* Blur the surface. */
_gtk_cairo_blur_surface (surface, radius);
/* Paint the blurred surface to cr. */
- cairo_get_current_point (cr, &x, &y);
cairo_set_source_surface (cr, surface,
- x - radius,
- y - radius);
+ rect_surface->x - radius,
+ rect_surface->y - radius);
cairo_paint (cr);
}
@@ -349,17 +348,35 @@ _gtk_css_shadow_value_paint_layout (const GtkCssValue *shadow,
if (_gtk_css_number_value_get (shadow->radius, 0) > 0)
{
+ PangoRectangle ink_rect;
cairo_t *blur_cr;
cairo_surface_t *surface;
-
- _gtk_css_shadow_value_blur_surface_create (shadow, cr,
- &blur_cr, &surface);
+ cairo_rectangle_int_t rect_surface;
+ gdouble x, y;
+ gint extra_pad;
+
+ /* Calculate blur surface coordinates. */
+ extra_pad = 1; /* Padding seems to help on blur edges, please verify. */
+ pango_layout_get_pixel_extents (layout, &ink_rect, NULL);
+ cairo_get_current_point (cr, &x, &y);
+ rect_surface.x = x + ink_rect.x - extra_pad; /* Loss of precision? */
+ rect_surface.y = y + ink_rect.y - extra_pad; /* Loss of precision? */
+ rect_surface.width = ink_rect.width + 2 * extra_pad;
+ rect_surface.height = ink_rect.height + 2 * extra_pad;
+
+ gtk_css_shadow_value_blur_surface_create (shadow, cr,
+ &blur_cr, &surface,
+ &rect_surface);
/* Create the path on the surface to blur. */
+ cairo_translate (blur_cr,
+ - ink_rect.x + extra_pad,
+ - ink_rect.y + extra_pad);
+
gdk_cairo_set_source_rgba (blur_cr, _gtk_css_rgba_value_get_rgba (shadow->color));
_gtk_pango_fill_layout (blur_cr, layout);
- _gtk_css_shadow_value_blur_surface_paint (shadow, cr, surface);
+ gtk_css_shadow_value_blur_surface_paint (shadow, cr, surface, &rect_surface);
cairo_destroy (blur_cr);
cairo_surface_destroy (surface);
@@ -378,7 +395,8 @@ _gtk_css_shadow_value_paint_layout (const GtkCssValue *shadow,
void
_gtk_css_shadow_value_paint_icon (const GtkCssValue *shadow,
- cairo_t *cr)
+ cairo_t *cr,
+ cairo_rectangle_t *rect)
{
cairo_pattern_t *pattern;
@@ -391,19 +409,23 @@ _gtk_css_shadow_value_paint_icon (const GtkCssValue *shadow,
{
cairo_t *blur_cr;
cairo_surface_t *surface;
+ cairo_rectangle_int_t rect_surface;
- _gtk_css_shadow_value_blur_surface_create (shadow, cr,
- &blur_cr, &surface);
+ /* Calculate blur surface coordinates. */
+ rect_surface.x = rect->x + _gtk_css_number_value_get (shadow->hoffset, 0);
+ rect_surface.y = rect->y + _gtk_css_number_value_get (shadow->voffset, 0);
+ rect_surface.width = rect->width;
+ rect_surface.height = rect->height;
+
+ gtk_css_shadow_value_blur_surface_create (shadow, cr,
+ &blur_cr, &surface,
+ &rect_surface);
/* Create the path on the surface to blur. */
gdk_cairo_set_source_rgba (blur_cr, _gtk_css_rgba_value_get_rgba (shadow->color));
-
- cairo_translate (blur_cr,
- _gtk_css_number_value_get (shadow->hoffset, 0),
- _gtk_css_number_value_get (shadow->voffset, 0));
cairo_mask (blur_cr, pattern);
- _gtk_css_shadow_value_blur_surface_paint (shadow, cr, surface);
+ gtk_css_shadow_value_blur_surface_paint (shadow, cr, surface, &rect_surface);
cairo_destroy (blur_cr);
cairo_surface_destroy (surface);
@@ -436,19 +458,27 @@ _gtk_css_shadow_value_paint_spinner (const GtkCssValue *shadow,
{
cairo_t *blur_cr;
cairo_surface_t *surface;
+ cairo_rectangle_int_t rect_surface;
+
+ /* Calculate blur surface coordinates. */
+ rect_surface.x = _gtk_css_number_value_get (shadow->hoffset, 0) - radius;
+ rect_surface.y = _gtk_css_number_value_get (shadow->voffset, 0) - radius;
+ rect_surface.width = 2 * radius;
+ rect_surface.height = 2 * radius;
- _gtk_css_shadow_value_blur_surface_create (shadow, cr,
- &blur_cr, &surface);
+ gtk_css_shadow_value_blur_surface_create (shadow, cr,
+ &blur_cr, &surface,
+ &rect_surface);
/* Create the path on the surface to blur. */
cairo_translate (blur_cr,
- _gtk_css_number_value_get (shadow->hoffset, 0),
- _gtk_css_number_value_get (shadow->voffset, 0));
+ radius,
+ radius);
_gtk_theming_engine_paint_spinner (blur_cr,
radius, progress,
_gtk_css_rgba_value_get_rgba (shadow->color));
- _gtk_css_shadow_value_blur_surface_paint (shadow, cr, surface);
+ gtk_css_shadow_value_blur_surface_paint (shadow, cr, surface, &rect_surface);
cairo_destroy (blur_cr);
cairo_surface_destroy (surface);
@@ -493,9 +523,19 @@ _gtk_css_shadow_value_paint_box (const GtkCssValue *shadow,
{
cairo_t *blur_cr;
cairo_surface_t *surface;
+ cairo_rectangle_int_t rect_surface;
+ gdouble x, y;
+
+ /* Calculate blur surface coordinates. */
+ cairo_get_current_point (cr, &x, &y);
+ rect_surface.x = x; /* Loss of precision? */
+ rect_surface.x = y; /* Loss of precision? */
+ rect_surface.width = MAX (padding_box->box.width, box.box.width);
+ rect_surface.height = MAX (padding_box->box.height, box.box.height);
- _gtk_css_shadow_value_blur_surface_create (shadow, cr,
- &blur_cr, &surface);
+ gtk_css_shadow_value_blur_surface_create (shadow, cr,
+ &blur_cr, &surface,
+ &rect_surface);
/* Create the path on the surface to blur. */
_gtk_rounded_box_path (padding_box, blur_cr);
@@ -509,7 +549,7 @@ _gtk_css_shadow_value_paint_box (const GtkCssValue *shadow,
gdk_cairo_set_source_rgba (blur_cr, _gtk_css_rgba_value_get_rgba (shadow->color));
cairo_fill (blur_cr);
- _gtk_css_shadow_value_blur_surface_paint (shadow, cr, surface);
+ gtk_css_shadow_value_blur_surface_paint (shadow, cr, surface, &rect_surface);
cairo_destroy (blur_cr);
cairo_surface_destroy (surface);
diff --git a/gtk/gtkcssshadowvalueprivate.h b/gtk/gtkcssshadowvalueprivate.h
index 3683e11..695d863 100644
--- a/gtk/gtkcssshadowvalueprivate.h
+++ b/gtk/gtkcssshadowvalueprivate.h
@@ -42,12 +42,14 @@ void _gtk_css_shadow_value_paint_layout (const GtkCssValue
PangoLayout *layout);
void _gtk_css_shadow_value_paint_icon (const GtkCssValue *shadow,
- cairo_t *cr);
+ cairo_t *cr,
+ cairo_rectangle_t *rect);
void _gtk_css_shadow_value_paint_spinner (const GtkCssValue *shadow,
cairo_t *cr,
gdouble radius,
gdouble progress);
+
void _gtk_css_shadow_value_paint_box (const GtkCssValue *shadow,
cairo_t *cr,
const GtkRoundedBox *padding_box);
diff --git a/gtk/gtkthemingengine.c b/gtk/gtkthemingengine.c
index a085dc4..9de5254 100644
--- a/gtk/gtkthemingengine.c
+++ b/gtk/gtkthemingengine.c
@@ -178,7 +178,7 @@ static GdkPixbuf * gtk_theming_engine_render_icon_pixbuf (GtkThemingEngine *e
GtkIconSize size);
static void gtk_theming_engine_render_icon (GtkThemingEngine *engine,
cairo_t *cr,
- GdkPixbuf *pixbuf,
+ GdkPixbuf *pixbuf,
gdouble x,
gdouble y);
@@ -2928,15 +2928,22 @@ gtk_theming_engine_render_icon_pixbuf (GtkThemingEngine *engine,
static void
gtk_theming_engine_render_icon (GtkThemingEngine *engine,
cairo_t *cr,
- GdkPixbuf *pixbuf,
+ GdkPixbuf *pixbuf,
gdouble x,
gdouble y)
{
+ cairo_rectangle_t rect;
+
cairo_save (cr);
gdk_cairo_set_source_pixbuf (cr, pixbuf, x, y);
- _gtk_css_shadows_value_paint_icon (_gtk_theming_engine_peek_property (engine, GTK_CSS_PROPERTY_ICON_SHADOW), cr);
+ rect.x = x;
+ rect.y = y;
+ rect.width = gdk_pixbuf_get_width (pixbuf);
+ rect.height = gdk_pixbuf_get_height (pixbuf);
+
+ _gtk_css_shadows_value_paint_icon (_gtk_theming_engine_peek_property (engine, GTK_CSS_PROPERTY_ICON_SHADOW), cr, &rect);
cairo_paint (cr);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]