diff options
| author | Denys Dmytriyenko <denis@denix.org> | 2009-03-17 14:32:59 -0400 |
|---|---|---|
| committer | Denys Dmytriyenko <denis@denix.org> | 2009-03-17 14:32:59 -0400 |
| commit | 709c4d66e0b107ca606941b988bad717c0b45d9b (patch) | |
| tree | 37ee08b1eb308f3b2b6426d5793545c38396b838 /recipes/cairo | |
| parent | fa6cd5a3b993f16c27de4ff82b42684516d433ba (diff) | |
rename packages/ to recipes/ per earlier agreement
See links below for more details:
http://thread.gmane.org/gmane.comp.handhelds.openembedded/21326
http://thread.gmane.org/gmane.comp.handhelds.openembedded/21816
Signed-off-by: Denys Dmytriyenko <denis@denix.org>
Acked-by: Mike Westerhof <mwester@dls.net>
Acked-by: Philip Balister <philip@balister.org>
Acked-by: Khem Raj <raj.khem@gmail.com>
Acked-by: Marcin Juszkiewicz <hrw@openembedded.org>
Acked-by: Koen Kooi <koen@openembedded.org>
Acked-by: Frans Meulenbroeks <fransmeulenbroeks@gmail.com>
Diffstat (limited to 'recipes/cairo')
34 files changed, 3428 insertions, 0 deletions
diff --git a/recipes/cairo/cairo-1.2.4/0001-Add-autoconf-macro-AX_C_FLOAT_WORDS_BIGENDIAN.diff b/recipes/cairo/cairo-1.2.4/0001-Add-autoconf-macro-AX_C_FLOAT_WORDS_BIGENDIAN.diff new file mode 100644 index 0000000000..90718d4976 --- /dev/null +++ b/recipes/cairo/cairo-1.2.4/0001-Add-autoconf-macro-AX_C_FLOAT_WORDS_BIGENDIAN.diff @@ -0,0 +1,103 @@ +From nobody Mon Sep 17 00:00:00 2001 +From: Dan Amelang <dan@amelang.net> +Date: Sun Oct 29 21:30:08 2006 -0800 +Subject: [PATCH] Add autoconf macro AX_C_FLOAT_WORDS_BIGENDIAN + +The symbol that this macro defines (FLOAT_WORDS_BIGENDIAN) can be used +to make double arithmetic tricks portable. + +--- + + acinclude.m4 | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + configure.in | 1 + + 2 files changed, 66 insertions(+), 0 deletions(-) + +3231d91b59a6c2e1c40bbaa8b143694b6c693662 +diff --git a/acinclude.m4 b/acinclude.m4 +index af73800..a0eb13a 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -51,3 +51,68 @@ ifelse([$1],[],, + AM_CONDITIONAL(ENABLE_GTK_DOC, test x$enable_gtk_doc = xyes) + AM_CONDITIONAL(GTK_DOC_USE_LIBTOOL, test -n "$LIBTOOL") + ]) ++ ++# AX_C_FLOAT_WORDS_BIGENDIAN ([ACTION-IF-TRUE], [ACTION-IF-FALSE], ++# [ACTION-IF-UNKNOWN]) ++# ++# Checks the ordering of words within a multi-word float. This check ++# is necessary because on some systems (e.g. certain ARM systems), the ++# float word ordering can be different from the byte ordering. In a ++# multi-word float context, "big-endian" implies that the word containing ++# the sign bit is found in the memory location with the lowest address. ++# This implemenation was inspired by the AC_C_BIGENDIAN macro in autoconf. ++# ------------------------------------------------------------------------- ++AC_DEFUN([AX_C_FLOAT_WORDS_BIGENDIAN], ++ [AC_CACHE_CHECK(whether float word ordering is bigendian, ++ ax_cv_c_float_words_bigendian, [ ++ ++# The endianess is detected by first compiling C code that contains a special ++# double float value, then grepping the resulting object file for certain ++# strings of ascii values. The double is specially crafted to have a ++# binary representation that corresponds with a simple string. In this ++# implementation, the string "noonsees" was selected because the individual ++# word values ("noon" and "sees") are palindromes, thus making this test ++# byte-order agnostic. If grep finds the string "noonsees" in the object ++# file, the target platform stores float words in big-endian order. If grep ++# finds "seesnoon", float words are in little-endian order. If neither value ++# is found, the user is instructed to specify the ordering. ++ ++ax_cv_c_float_words_bigendian=unknown ++AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ ++ ++double d = 90904234967036810337470478905505011476211692735615632014797120844053488865816695273723469097858056257517020191247487429516932130503560650002327564517570778480236724525140520121371739201496540132640109977779420565776568942592.0; ++ ++]])], [ ++ ++if grep noonsees conftest.$ac_objext >/dev/null ; then ++ ax_cv_c_float_words_bigendian=yes ++fi ++if grep seesnoon conftest.$ac_objext >/dev/null ; then ++ if test "$ax_cv_c_float_words_bigendian" = unknown; then ++ ax_cv_c_float_words_bigendian=no ++ else ++ ax_cv_c_float_words_bigendian=unknown ++ fi ++fi ++ ++])]) ++ ++case $ax_cv_c_float_words_bigendian in ++ yes) ++ m4_default([$1], ++ [AC_DEFINE([FLOAT_WORDS_BIGENDIAN], 1, ++ [Define to 1 if your system stores words within floats ++ with the most significant word first])]) ;; ++ no) ++ $2 ;; ++ *) ++ m4_default([$3], ++ [AC_MSG_ERROR([ ++ ++Unknown float word ordering. You need to manually preset ++ax_cv_c_float_words_bigendian=no (or yes) according to your system. ++ ++ ])]) ;; ++esac ++ ++])# AX_C_FLOAT_WORDS_BIGENDIAN +diff --git a/configure.in b/configure.in +index 2d2bf9f..797c7ce 100644 +--- a/configure.in ++++ b/configure.in +@@ -55,6 +55,7 @@ AC_PROG_CPP + AC_PROG_LIBTOOL dnl required version (1.4) DON'T REMOVE! + AC_STDC_HEADERS + AC_C_BIGENDIAN ++AX_C_FLOAT_WORDS_BIGENDIAN + + dnl =========================================================================== + dnl === Local macros +-- +1.2.6 + diff --git a/recipes/cairo/cairo-1.2.4/0002-Change-_cairo_fixed_from_double-to-use-the-magic-number-technique.diff b/recipes/cairo/cairo-1.2.4/0002-Change-_cairo_fixed_from_double-to-use-the-magic-number-technique.diff new file mode 100644 index 0000000000..56d8b7e99a --- /dev/null +++ b/recipes/cairo/cairo-1.2.4/0002-Change-_cairo_fixed_from_double-to-use-the-magic-number-technique.diff @@ -0,0 +1,79 @@ +From nobody Mon Sep 17 00:00:00 2001 +From: Dan Amelang <dan@amelang.net> +Date: Sun Oct 29 21:31:23 2006 -0800 +Subject: [PATCH] Change _cairo_fixed_from_double to use the "magic number" technique + +See long thread here: +http://lists.freedesktop.org/archives/cairo/2006-October/008285.html + +--- + + src/cairo-fixed.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- + 1 files changed, 47 insertions(+), 1 deletions(-) + +d88acddcabe770e17664b34a2d5f74d3926e1642 +diff --git a/src/cairo-fixed.c b/src/cairo-fixed.c +index 604c9e7..fe6c2dc 100644 +--- a/src/cairo-fixed.c ++++ b/src/cairo-fixed.c +@@ -42,10 +42,56 @@ _cairo_fixed_from_int (int i) + return i << 16; + } + ++/* This is the "magic number" approach to converting a double into fixed ++ * point as described here: ++ * ++ * http://www.stereopsis.com/sree/fpu2006.html (an overview) ++ * http://www.d6.com/users/checker/pdfs/gdmfp.pdf (in detail) ++ * ++ * The basic idea is to add a large enough number to the double that the ++ * literal floating point is moved up to the extent that it forces the ++ * double's value to be shifted down to the bottom of the mantissa (to make ++ * room for the large number being added in). Since the mantissa is, at a ++ * given moment in time, a fixed point integer itself, one can convert a ++ * float to various fixed point representations by moving around the point ++ * of a floating point number through arithmetic operations. This behavior ++ * is reliable on most modern platforms as it is mandated by the IEEE-754 ++ * standard for floating point arithmetic. ++ * ++ * For our purposes, a "magic number" must be carefully selected that is ++ * both large enough to produce the desired point-shifting effect, and also ++ * has no lower bits in its representation that would interfere with our ++ * value at the bottom of the mantissa. The magic number is calculated as ++ * follows: ++ * ++ * (2 ^ (MANTISSA_SIZE - FRACTIONAL_SIZE)) * 1.5 ++ * ++ * where in our case: ++ * - MANTISSA_SIZE for 64-bit doubles is 52 ++ * - FRACTIONAL_SIZE for 16.16 fixed point is 16 ++ * ++ * Although this approach provides a very large speedup of this function ++ * on a wide-array of systems, it does come with two caveats: ++ * ++ * 1) It uses banker's rounding as opposed to arithmetic rounding. ++ * 2) It doesn't function properly if the FPU is in single-precision ++ * mode. ++ */ ++#define CAIRO_MAGIC_NUMBER_FIXED_16_16 (103079215104.0) + cairo_fixed_t + _cairo_fixed_from_double (double d) + { +- return (cairo_fixed_t) floor (d * 65536 + 0.5); ++ union { ++ double d; ++ int32_t i[2]; ++ } u; ++ ++ u.d = d + CAIRO_MAGIC_NUMBER_FIXED_16_16; ++#ifdef FLOAT_WORDS_BIGENDIAN ++ return u.i[1]; ++#else ++ return u.i[0]; ++#endif + } + + cairo_fixed_t +-- +1.2.6 + diff --git a/recipes/cairo/cairo-1.2.4/0003-Add-new-perf-test-pattern_create_radial.diff b/recipes/cairo/cairo-1.2.4/0003-Add-new-perf-test-pattern_create_radial.diff new file mode 100644 index 0000000000..c2b47deb7f --- /dev/null +++ b/recipes/cairo/cairo-1.2.4/0003-Add-new-perf-test-pattern_create_radial.diff @@ -0,0 +1,164 @@ +From nobody Mon Sep 17 00:00:00 2001 +From: Dan Amelang <dan@amelang.net> +Date: Tue Oct 31 23:47:35 2006 -0800 +Subject: [PATCH] Add new perf test "pattern_create_radial" + +This test is really just for hammering the double to fixed-point conversion +(in _cairo_fixed_from_double) that happens as doubles from API calls gets +translated into internal cairo fixed-point numbers. + +Because it's not generally useful, I don't recommend that it become part of +the main cairo performance test. But hey, it might come in handy for someone +else. + +--- + + perf/Makefile.am | 1 + perf/cairo-perf.c | 1 + perf/cairo-perf.h | 1 + perf/pattern_create_radial.c | 98 ++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 101 insertions(+), 0 deletions(-) + create mode 100644 perf/pattern_create_radial.c + +977383b86c68d0523c899efcba3cf8d36e94d2a7 +diff --git a/perf/Makefile.am b/perf/Makefile.am +index 419a998..e1cfdc7 100644 +--- a/perf/Makefile.am ++++ b/perf/Makefile.am +@@ -21,6 +21,7 @@ cairo_perf_SOURCES = \ + stroke.c \ + subimage_copy.c \ + tessellate.c \ ++ pattern_create_radial.c \ + text.c + + if CAIRO_HAS_WIN32_SURFACE +diff --git a/perf/cairo-perf.c b/perf/cairo-perf.c +index d9734c4..0707433 100644 +--- a/perf/cairo-perf.c ++++ b/perf/cairo-perf.c +@@ -256,5 +256,6 @@ cairo_perf_case_t perf_cases[] = { + { text, 64, 256}, + { tessellate, 100, 100}, + { subimage_copy, 16, 512}, ++ { pattern_create_radial, 16, 16}, + { NULL } + }; +diff --git a/perf/cairo-perf.h b/perf/cairo-perf.h +index 560ba64..faacff9 100644 +--- a/perf/cairo-perf.h ++++ b/perf/cairo-perf.h +@@ -88,5 +88,6 @@ CAIRO_PERF_DECL (stroke); + CAIRO_PERF_DECL (subimage_copy); + CAIRO_PERF_DECL (tessellate); + CAIRO_PERF_DECL (text); ++CAIRO_PERF_DECL (pattern_create_radial); + + #endif +diff --git a/perf/pattern_create_radial.c b/perf/pattern_create_radial.c +new file mode 100644 +index 0000000..d793b7d +--- /dev/null ++++ b/perf/pattern_create_radial.c +@@ -0,0 +1,98 @@ ++/* ++ * Copyright © 2006 Dan Amelang ++ * ++ * Permission to use, copy, modify, distribute, and sell this software ++ * and its documentation for any purpose is hereby granted without ++ * fee, provided that the above copyright notice appear in all copies ++ * and that both that copyright notice and this permission notice ++ * appear in supporting documentation, and that the name of ++ * the authors not be used in advertising or publicity pertaining to ++ * distribution of the software without specific, written prior ++ * permission. The authors make no representations about the ++ * suitability of this software for any purpose. It is provided "as ++ * is" without express or implied warranty. ++ * ++ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS ++ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND ++ * FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, ++ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ++ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR ++ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * Authors: Dan Amelang <dan@amelang.net> ++ * ++ * This test was originally created to test _cairo_fixed_from_double. ++ * cairo_pattern_create_radial was selected as the entry point into ++ * cairo as it makes several calls to _cairo_fixed_from_double and ++ * presents a somewhat realistic use-case (although the RADIALS_COUNT ++ * isn't very realistic). ++ */ ++#include <time.h> ++#include "cairo-perf.h" ++ ++#define RADIALS_COUNT (100000) ++ ++static struct ++{ ++ double cx0; ++ double cy0; ++ double radius0; ++ double cx1; ++ double cy1; ++ double radius1; ++} radials[RADIALS_COUNT]; ++ ++static double ++generate_double_in_range (double min, double max) ++{ ++ double d; ++ ++ d = rand () / (double) RAND_MAX; ++ d *= max - min; ++ d += min; ++ ++ return d; ++} ++ ++static cairo_perf_ticks_t ++do_pattern_create_radial (cairo_t *cr, int width, int height) ++{ ++ int i; ++ cairo_pattern_t *pattern; ++ ++ cairo_perf_timer_start (); ++ ++ for (i = 0; i < RADIALS_COUNT; i++) ++ { ++ pattern = cairo_pattern_create_radial (radials[i].cx0, radials[i].cy0, ++ radials[i].radius0, ++ radials[i].cx1, radials[i].cy1, ++ radials[i].radius1); ++ cairo_pattern_destroy (pattern); ++ } ++ ++ cairo_perf_timer_stop (); ++ ++ return cairo_perf_timer_elapsed (); ++} ++ ++void ++pattern_create_radial (cairo_perf_t *perf, cairo_t *cr, int width, int height) ++{ ++ int i; ++ ++ srand (time (0)); ++ for (i = 0; i < RADIALS_COUNT; i++) ++ { ++ radials[i].cx0 = generate_double_in_range (-50000.0, 50000.0); ++ radials[i].cy0 = generate_double_in_range (-50000.0, 50000.0); ++ radials[i].radius0 = generate_double_in_range (0.0, 1000.0); ++ radials[i].cx1 = generate_double_in_range (-50000.0, 50000.0); ++ radials[i].cy1 = generate_double_in_range (-50000.0, 50000.0); ++ radials[i].radius1 = generate_double_in_range (0.0, 1000.0); ++ } ++ ++ cairo_perf_run (perf, "pattern_create_radial", ++ do_pattern_create_radial); ++} +-- +1.2.6 + diff --git a/recipes/cairo/cairo-1.3.4/configure.in_requires_pkg-config-0.15.diff b/recipes/cairo/cairo-1.3.4/configure.in_requires_pkg-config-0.15.diff new file mode 100644 index 0000000000..2bd70a532c --- /dev/null +++ b/recipes/cairo/cairo-1.3.4/configure.in_requires_pkg-config-0.15.diff @@ -0,0 +1,13 @@ +Index: cairo-1.3.2-r0/cairo-1.3.2/configure.in +=================================================================== +--- cairo-1.3.2-r0.orig/cairo-1.3.2/configure.in 2006-11-15 22:31:59.000000000 +0100 ++++ cairo-1.3.2-r0/cairo-1.3.2/configure.in 2006-11-16 23:15:07.000000000 +0100 +@@ -90,7 +90,7 @@ + + dnl =========================================================================== + +-PKGCONFIG_REQUIRED=0.19 ++PKGCONFIG_REQUIRED=0.15 + PKG_PROG_PKG_CONFIG($PKGCONFIG_REQUIRED) + if test "x$PKG_CONFIG" = x; then + AC_MSG_ERROR([pkg-config >= $PKGCONFIG_REQUIRED required but not found (http://pkgconfig.freedesktop.org/)]) diff --git a/recipes/cairo/cairo-1.4.10/stats.patch b/recipes/cairo/cairo-1.4.10/stats.patch new file mode 100644 index 0000000000..63df25c942 --- /dev/null +++ b/recipes/cairo/cairo-1.4.10/stats.patch @@ -0,0 +1,33 @@ +See cairo mailing list 15-10-2007 patch by Soeren Sandmann. +Fixes unreliable results for cairo-perf. + +diff --git a/perf/cairo-perf.c b/perf/cairo-perf.c +index 360f2dd..a8d7abc 100644 +--- a/perf/cairo-perf.c ++++ b/perf/cairo-perf.c +@@ -166,22 +166,11 @@ cairo_perf_run (cairo_perf_t *perf, + cairo_perf_ticks_per_second () / 1000.0); + printf (" %lld", times[i]); + } else { +- if (i > 0) { +- _cairo_stats_compute (&stats, times, i+1); +- +- if (stats.std_dev <= CAIRO_PERF_LOW_STD_DEV && +- ! perf->exact_iterations) +- { +- low_std_dev_count++; +- if (low_std_dev_count >= CAIRO_PERF_STABLE_STD_DEV_COUNT) +- break; +- } else { +- low_std_dev_count = 0; +- } +- } + } + } + ++ _cairo_stats_compute (&stats, times, i+1); ++ + if (perf->raw) { + printf ("\n"); + } else { +diff --git a/perf/cairo-stats.c b/perf/cairo-stats.c diff --git a/recipes/cairo/cairo-1.4.14/0001-Fix-for-a-memory-leak-in-pixman.patch b/recipes/cairo/cairo-1.4.14/0001-Fix-for-a-memory-leak-in-pixman.patch new file mode 100644 index 0000000000..686ab7ceb0 --- /dev/null +++ b/recipes/cairo/cairo-1.4.14/0001-Fix-for-a-memory-leak-in-pixman.patch @@ -0,0 +1,32 @@ +From 7647f29a2a3b69592e38f50890a96d8deeaa2dbb Mon Sep 17 00:00:00 2001
+From: Jan Slupski <jslupski@juljas.net>
+Date: Fri, 15 Feb 2008 00:55:30 +0100
+Subject: [PATCH] Fix for a memory leak in pixman.
+
+Port of a 1.6 fix for a memory leak in pixman_region_init_rects/pixman_rect_alloc
+when the count of boxes is 0.
+---
+ pixman/src/pixregion.c | 9 +++++++++
+ 1 files changed, 9 insertions(+), 0 deletions(-)
+
+diff --git a/pixman/src/pixregion.c b/pixman/src/pixregion.c
+index 1ed3ad7..d6caf6c 100644
+--- a/pixman/src/pixregion.c
++++ b/pixman/src/pixregion.c
+@@ -355,6 +355,15 @@ pixman_region_init_rects(pixman_region16_t *region, pixman_box16_t *boxes, int c
+ }
+
+ pixman_region_init(region);
++
++ /* if it's 0, don't call pixman_rect_alloc -- 0 rectangles is
++ * a special case, and causing pixman_rect_alloc would cause
++ * us to leak memory (because the 0-rect case should be the
++ * static pixman_region_emptyData data).
++ */
++ if (count == 0)
++ return PIXMAN_REGION_STATUS_SUCCESS;
++
+ if (!pixman_rect_alloc(region, count))
+ return PIXMAN_REGION_STATUS_FAILURE;
+
+ diff --git a/recipes/cairo/cairo-1.4.4/cairo-workqueue.patch b/recipes/cairo/cairo-1.4.4/cairo-workqueue.patch new file mode 100644 index 0000000000..4522e99e68 --- /dev/null +++ b/recipes/cairo/cairo-1.4.4/cairo-workqueue.patch @@ -0,0 +1,2148 @@ +From: Chris Wilson <chris@chris-wilson.co.uk> +Date: Wed, 18 Apr 2007 17:34:44 +0000 (+0100) +Subject: Cache freed GCs +X-Git-Url: http://gitweb.freedesktop.org/?p=users/ickle/cairo;a=commitdiff;h=3126c3948691cf7a6c0fc0f9cc6a7eca43c3553b + +Cache freed GCs + +Maintain a cache of freed GCs, one for each used depth. +--- + +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -46,7 +46,11 @@ endif + + if CAIRO_HAS_XLIB_SURFACE + libcairo_xlib_headers = cairo-xlib.h cairo-xlib-xrender.h +-libcairo_xlib_sources = cairo-xlib-surface.c cairo-xlib-screen.c cairo-xlib-private.h cairo-xlib-test.h ++libcairo_xlib_sources = cairo-xlib-surface.c \ ++ cairo-xlib-display.c \ ++ cairo-xlib-screen.c \ ++ cairo-xlib-private.h \ ++ cairo-xlib-test.h + backend_pkgconfigs += cairo-xlib.pc + endif + +--- a/src/cairo-clip.c ++++ b/src/cairo-clip.c +@@ -404,7 +404,8 @@ _cairo_clip_intersect_mask (cairo_clip_t + CAIRO_CONTENT_ALPHA, + surface_rect.width, + surface_rect.height, +- CAIRO_COLOR_WHITE); ++ CAIRO_COLOR_WHITE, ++ NULL); + if (surface->status) + return CAIRO_STATUS_NO_MEMORY; + +--- a/src/cairo-debug.c ++++ b/src/cairo-debug.c +@@ -59,10 +59,6 @@ + void + cairo_debug_reset_static_data (void) + { +-#if CAIRO_HAS_XLIB_SURFACE +- _cairo_xlib_screen_reset_static_data (); +-#endif +- + _cairo_font_reset_static_data (); + + #if CAIRO_HAS_FT_FONT +--- a/src/cairo-directfb-surface.c ++++ b/src/cairo-directfb-surface.c +@@ -1511,6 +1511,16 @@ _cairo_directfb_surface_show_glyphs ( vo + #endif /* DFB_SHOW_GLYPHS */ + + ++static cairo_bool_t ++_cairo_directfb_surface_is_compatible (void *surface_a, ++ void *surface_b) ++{ ++ cairo_directfb_surface_t *a = (cairo_directfb_surface_t *) surface_a; ++ cairo_directfb_surface_t *b = (cairo_directfb_surface_t *) surface_b; ++ ++ return a->dfb == b->dfb; ++} ++ + static cairo_surface_backend_t cairo_directfb_surface_backend = { + CAIRO_SURFACE_TYPE_DIRECTFB, /*type*/ + _cairo_directfb_surface_create_similar,/*create_similar*/ +@@ -1560,7 +1570,8 @@ static cairo_surface_backend_t cairo_dir + #else + NULL, /* show_glyphs */ + #endif +- NULL /* snapshot */ ++ NULL, /* snapshot */ ++ _cairo_directfb_is_compatible + }; + + +--- a/src/cairo-glitz-surface.c ++++ b/src/cairo-glitz-surface.c +@@ -1002,7 +1002,8 @@ _cairo_glitz_surface_fill_rectangles (vo + _cairo_surface_create_similar_solid (&dst->base, + CAIRO_CONTENT_COLOR_ALPHA, + 1, 1, +- (cairo_color_t *) color); ++ (cairo_color_t *) color, ++ NULL); + if (src->base.status) + return CAIRO_STATUS_NO_MEMORY; + +@@ -2171,6 +2172,19 @@ _cairo_glitz_surface_flush (void *abstra + return CAIRO_STATUS_SUCCESS; + } + ++static cairo_bool_t ++_cairo_glitz_surface_is_compatible (void *surface_a, ++ void *surface_b) ++{ ++ cairo_glitz_surface_t *a = (cairo_glitz_surface_t *) surface_a; ++ cairo_glitz_surface_t *b = (cairo_glitz_surface_t *) surface_b; ++ ++ glitz_drawable_t *drawable_a = glitz_surface_get_drawable (a->surface); ++ glitz_drawable_t *drawable_b = glitz_surface_get_drawable (b->surface); ++ ++ return drawable_a == drawable_b; ++} ++ + static const cairo_surface_backend_t cairo_glitz_surface_backend = { + CAIRO_SURFACE_TYPE_GLITZ, + _cairo_glitz_surface_create_similar, +@@ -2193,7 +2207,16 @@ static const cairo_surface_backend_t cai + _cairo_glitz_surface_flush, + NULL, /* mark_dirty_rectangle */ + _cairo_glitz_surface_scaled_font_fini, +- _cairo_glitz_surface_scaled_glyph_fini ++ _cairo_glitz_surface_scaled_glyph_fini, ++ ++ NULL, /* paint */ ++ NULL, /* mask */ ++ NULL, /* stroke */ ++ NULL, /* fill */ ++ NULL, /* show_glyphs */ ++ ++ NULL, /* snapshot */ ++ _cairo_glitz_surface_is_compatible + }; + + static const cairo_surface_backend_t * +--- a/src/cairo-mutex-list-private.h ++++ b/src/cairo-mutex-list-private.h +@@ -34,7 +34,8 @@ + #ifndef CAIRO_MUTEX_LIST_PRIVATE_H + #define CAIRO_MUTEX_LIST_PRIVATE_H + +-CAIRO_MUTEX_DECLARE (_cairo_pattern_solid_cache_lock); ++CAIRO_MUTEX_DECLARE (_cairo_pattern_solid_pattern_cache_lock); ++CAIRO_MUTEX_DECLARE (_cairo_pattern_solid_surface_cache_lock); + + CAIRO_MUTEX_DECLARE (_cairo_font_face_mutex); + CAIRO_MUTEX_DECLARE (_cairo_scaled_font_map_mutex); +@@ -44,7 +45,7 @@ CAIRO_MUTEX_DECLARE (_cairo_ft_unscaled_ + #endif + + #if CAIRO_HAS_XLIB_SURFACE +-CAIRO_MUTEX_DECLARE (_cairo_xlib_screen_mutex); ++CAIRO_MUTEX_DECLARE (_cairo_xlib_display_mutex); + #endif + + #endif +--- a/src/cairo-pattern.c ++++ b/src/cairo-pattern.c +@@ -282,7 +282,7 @@ _cairo_pattern_create_solid (const cairo + { + cairo_solid_pattern_t *pattern = NULL; + +- CAIRO_MUTEX_LOCK (_cairo_pattern_solid_cache_lock); ++ CAIRO_MUTEX_LOCK (_cairo_pattern_solid_pattern_cache_lock); + + if (solid_pattern_cache.size) { + int i = --solid_pattern_cache.size % +@@ -291,7 +291,7 @@ _cairo_pattern_create_solid (const cairo + solid_pattern_cache.patterns[i] = NULL; + } + +- CAIRO_MUTEX_UNLOCK (_cairo_pattern_solid_cache_lock); ++ CAIRO_MUTEX_UNLOCK (_cairo_pattern_solid_pattern_cache_lock); + + if (pattern == NULL) { + /* None cached, need to create a new pattern. */ +@@ -306,12 +306,12 @@ _cairo_pattern_create_solid (const cairo + return &pattern->base; + } + +-void +-_cairo_pattern_reset_static_data (void) ++static void ++_cairo_pattern_reset_solid_pattern_cache (void) + { + int i; + +- CAIRO_MUTEX_LOCK (_cairo_pattern_solid_cache_lock); ++ CAIRO_MUTEX_LOCK (_cairo_pattern_solid_pattern_cache_lock); + + for (i = 0; i < MIN (ARRAY_LENGTH (solid_pattern_cache.patterns), solid_pattern_cache.size); i++) { + free (solid_pattern_cache.patterns[i]); +@@ -319,7 +319,7 @@ _cairo_pattern_reset_static_data (void) + } + solid_pattern_cache.size = 0; + +- CAIRO_MUTEX_UNLOCK (_cairo_pattern_solid_cache_lock); ++ CAIRO_MUTEX_UNLOCK (_cairo_pattern_solid_pattern_cache_lock); + } + + static const cairo_pattern_t * +@@ -630,7 +630,7 @@ cairo_pattern_destroy (cairo_pattern_t * + if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) { + int i; + +- CAIRO_MUTEX_LOCK (_cairo_pattern_solid_cache_lock); ++ CAIRO_MUTEX_LOCK (_cairo_pattern_solid_pattern_cache_lock); + + i = solid_pattern_cache.size++ % + ARRAY_LENGTH (solid_pattern_cache.patterns); +@@ -640,7 +640,7 @@ cairo_pattern_destroy (cairo_pattern_t * + + solid_pattern_cache.patterns[i] = (cairo_solid_pattern_t *) pattern; + +- CAIRO_MUTEX_UNLOCK (_cairo_pattern_solid_cache_lock); ++ CAIRO_MUTEX_UNLOCK (_cairo_pattern_solid_pattern_cache_lock); + } else { + free (pattern); + } +@@ -1235,6 +1235,17 @@ _cairo_pattern_acquire_surface_for_gradi + return status; + } + ++/* We maintain a small cache here, because we don't want to constantly ++ * recreate surfaces for simple solid colors. */ ++#define MAX_SURFACE_CACHE_SIZE 16 ++static struct { ++ struct { ++ cairo_color_t color; ++ cairo_surface_t *surface; ++ } cache[MAX_SURFACE_CACHE_SIZE]; ++ int size; ++} solid_surface_cache; ++ + static cairo_int_status_t + _cairo_pattern_acquire_surface_for_solid (cairo_solid_pattern_t *pattern, + cairo_surface_t *dst, +@@ -1245,12 +1256,54 @@ _cairo_pattern_acquire_surface_for_solid + cairo_surface_t **out, + cairo_surface_attributes_t *attribs) + { +- *out = _cairo_surface_create_similar_solid (dst, +- CAIRO_CONTENT_COLOR_ALPHA, +- 1, 1, +- &pattern->color); +- if ((*out)->status) +- return CAIRO_STATUS_NO_MEMORY; ++ static int i; ++ ++ cairo_surface_t *surface; ++ cairo_status_t status; ++ ++ CAIRO_MUTEX_LOCK (_cairo_pattern_solid_surface_cache_lock); ++ ++ /* Check cache first */ ++ if (i < solid_surface_cache.size && ++ _cairo_color_equal (&solid_surface_cache.cache[i].color, ++ &pattern->color) && ++ _cairo_surface_is_compatible (solid_surface_cache.cache[i].surface, dst)) ++ goto DONE; ++ ++ for (i = 0 ; i < solid_surface_cache.size; i++) { ++ if (_cairo_color_equal (&solid_surface_cache.cache[i].color, ++ &pattern->color) && ++ _cairo_surface_is_compatible (solid_surface_cache.cache[i].surface, dst)) ++ goto DONE; ++ } |
