[gtk+] rounded rect: cache arcs
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] rounded rect: cache arcs
- Date: Tue, 29 Sep 2015 13:44:11 +0000 (UTC)
commit d9f05aa3f9ecf54ff68295616c92d0f03e3e911c
Author: Matthias Clasen <mclasen redhat com>
Date: Tue Sep 29 09:40:00 2015 -0400
rounded rect: cache arcs
We are only ever drawing axis-aligned quarter arcs here. By caching
these paths, sincos drops from the profiles for drawing-heavy
workloads.
gtk/gtkroundedbox.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 76 insertions(+), 2 deletions(-)
---
diff --git a/gtk/gtkroundedbox.c b/gtk/gtkroundedbox.c
index f95751e..3d2befe 100644
--- a/gtk/gtkroundedbox.c
+++ b/gtk/gtkroundedbox.c
@@ -215,6 +215,80 @@ _gtk_rounded_box_move (GtkRoundedBox *box,
box->box.y += dy;
}
+typedef struct {
+ double angle1;
+ double angle2;
+ gboolean negative;
+} Arc;
+
+static guint
+arc_path_hash (Arc *arc)
+{
+ return g_double_hash (&arc->angle1) ^ g_double_hash (&arc->angle2) ^ arc->negative;
+}
+
+static gboolean
+arc_path_equal (Arc *arc1,
+ Arc *arc2)
+{
+ return arc1->angle1 == arc2->angle1 &&
+ arc1->angle2 == arc2->angle2 &&
+ arc1->negative == arc2->negative;
+}
+
+/* We need the path to start with a line-to */
+static cairo_path_t *
+fixup_path (cairo_path_t *path)
+{
+ cairo_path_data_t *data;
+
+ data = &path->data[0];
+ if (data->header.type == CAIRO_PATH_MOVE_TO)
+ data->header.type = CAIRO_PATH_LINE_TO;
+
+ return path;
+}
+
+static void
+append_arc (cairo_t *cr, double angle1, double angle2, gboolean negative)
+{
+ static GHashTable *arc_path_cache;
+ Arc key;
+ cairo_path_t *arc;
+
+ key.angle1 = angle1;
+ key.angle2 = angle2;
+ key.negative = negative;
+
+ if (arc_path_cache == NULL)
+ arc_path_cache = g_hash_table_new_full ((GHashFunc)arc_path_hash,
+ (GEqualFunc)arc_path_equal,
+ g_free, (GDestroyNotify)cairo_path_destroy);
+
+ arc = g_hash_table_lookup (arc_path_cache, &key);
+ if (arc == NULL)
+ {
+ cairo_surface_t *surface;
+ cairo_t *tmp;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
+ tmp = cairo_create (surface);
+
+ if (negative)
+ cairo_arc_negative (tmp, 0.0, 0.0, 1.0, angle1, angle2);
+ else
+ cairo_arc (tmp, 0.0, 0.0, 1.0, angle1, angle2);
+
+ arc = fixup_path (cairo_copy_path (tmp));
+ g_hash_table_insert (arc_path_cache, g_memdup (&key, sizeof (key)), arc);
+
+ cairo_destroy (tmp);
+ cairo_surface_destroy (surface);
+ }
+
+ cairo_append_path (cr, arc);
+}
+
static void
_cairo_ellipsis (cairo_t *cr,
double xc, double yc,
@@ -232,7 +306,7 @@ _cairo_ellipsis (cairo_t *cr,
cairo_get_matrix (cr, &save);
cairo_translate (cr, xc, yc);
cairo_scale (cr, xradius, yradius);
- cairo_arc (cr, 0, 0, 1.0, angle1, angle2);
+ append_arc (cr, angle1, angle2, FALSE);
cairo_set_matrix (cr, &save);
}
@@ -253,7 +327,7 @@ _cairo_ellipsis_negative (cairo_t *cr,
cairo_get_matrix (cr, &save);
cairo_translate (cr, xc, yc);
cairo_scale (cr, xradius, yradius);
- cairo_arc_negative (cr, 0, 0, 1.0, angle1, angle2);
+ append_arc (cr, angle1, angle2, TRUE);
cairo_set_matrix (cr, &save);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]