[cairo-commit] 3 commits - src/cairo-pattern.c test/Makefile.am test/solid-pattern-cache-stress.c test/solid-pattern-cache-stress-ref.png test/xlib-surface-source.c
Chris Wilson
ickle at kemper.freedesktop.org
Thu Jun 19 04:30:52 PDT 2008
src/cairo-pattern.c | 9 +
test/Makefile.am | 1
test/solid-pattern-cache-stress-ref.png |binary
test/solid-pattern-cache-stress.c | 148 +++++++++++++++++++++++++-------
test/xlib-surface-source.c | 4
5 files changed, 129 insertions(+), 33 deletions(-)
New commits:
commit 565644e616ea64f97769d8939beb155f4031da2f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Jun 19 11:42:43 2008 +0100
[cairo-pattern] Band-aid for the solid surface cache.
Behdad noticed that the mixing of dissimilar surfaces within the cache
was fubar
(http://lists.cairographics.org/archives/cairo/2008-June/014348.html).
This corrects the dereferencing of the evicted surface, but leaves open
the question of the future of the cache.
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 89e92ca..b9f068a 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -1453,9 +1453,10 @@ _cairo_pattern_acquire_surface_for_solid (cairo_solid_pattern_t *pattern,
&pattern->base);
if (status)
goto UNLOCK;
+
+ cairo_surface_reference (surface);
} else {
/* Unable to reuse, evict */
- cairo_surface_destroy (surface);
surface = NULL;
}
}
@@ -1485,6 +1486,7 @@ _cairo_pattern_acquire_surface_for_solid (cairo_solid_pattern_t *pattern,
i = solid_surface_cache.size++;
solid_surface_cache.cache[i].color = pattern->color;
+ cairo_surface_destroy (solid_surface_cache.cache[i].surface);
solid_surface_cache.cache[i].surface = surface;
DONE:
@@ -1513,8 +1515,11 @@ _cairo_pattern_reset_solid_surface_cache (void)
/* remove surfaces starting from the end so that solid_surface_cache.cache
* is always in a consistent state when we release the mutex. */
while (solid_surface_cache.size) {
- cairo_surface_t *surface = solid_surface_cache.cache[solid_surface_cache.size-1].surface;
+ cairo_surface_t *surface;
+
solid_surface_cache.size--;
+ surface = solid_surface_cache.cache[solid_surface_cache.size].surface;
+ solid_surface_cache.cache[solid_surface_cache.size].surface = NULL;
/* release the lock to avoid the possibility of a recursive
* deadlock when the scaled font destroy closure gets called */
commit 47d8739ea198510919b2611c34a44aa3c63f3f59
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Jun 19 11:38:38 2008 +0100
[test/xlib-surface-source] Build under --disable-xlib-xrender.
Add an ifdef to support compiling without XRender.
diff --git a/test/xlib-surface-source.c b/test/xlib-surface-source.c
index 3a70a4d..192dadc 100644
--- a/test/xlib-surface-source.c
+++ b/test/xlib-surface-source.c
@@ -53,6 +53,7 @@ cleanup (void *data)
static cairo_surface_t *
create_source_surface (int size)
{
+#if CAIRO_HAS_XLIB_XRENDER_SURFACE
XRenderPictFormat *xrender_format;
struct closure *data;
cairo_surface_t *surface;
@@ -73,4 +74,7 @@ create_source_surface (int size)
cairo_surface_set_user_data (surface, &closure_key, data, cleanup);
return surface;
+#else
+ return NULL;
+#endif
}
commit 38c4bcc2da225b36455ee3da396305a7d93d4c1d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Jun 19 09:44:58 2008 +0100
[test/solid-pattern-cache-stress] Do what it says on the tin.
Actually draw to the surface after setting the source in order to
trigger use of the solid surface cache.
diff --git a/test/Makefile.am b/test/Makefile.am
index 7dba516..c7c265f 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -638,6 +638,7 @@ REFERENCE_IMAGES = \
stroke-image-pdf-ref.png \
stroke-image-ps-ref.png \
stroke-image-quartz-ref.png \
+ solid-pattern-cache-stress-ref.png \
source-clip-ref.png \
source-clip-scale-quartz-ref.png \
source-clip-scale-ps-argb32-ref.png \
diff --git a/test/solid-pattern-cache-stress-ref.png b/test/solid-pattern-cache-stress-ref.png
new file mode 100644
index 0000000..e0e8498
Binary files /dev/null and b/test/solid-pattern-cache-stress-ref.png differ
diff --git a/test/solid-pattern-cache-stress.c b/test/solid-pattern-cache-stress.c
index 957b204..39c6454 100644
--- a/test/solid-pattern-cache-stress.c
+++ b/test/solid-pattern-cache-stress.c
@@ -28,24 +28,118 @@
#endif
#include "cairo-test.h"
+#include <stdlib.h> /* drand48() */
+
+#define LOOPS 10
+#define NRAND 100
+
+#ifndef HAVE_DRAND48
+#define drand48() (rand () / (double) RAND_MAX)
+#endif
static cairo_test_draw_function_t draw;
cairo_test_t test = {
"solid-pattern-cache-stress",
"Stress the solid pattern cache and ensure it behaves",
- 0, 0,
+ 1, 1,
draw
};
-#include <cairo.h>
-#include <stdlib.h>
-#define LOOPS 10
-#define NRAND 100
+static cairo_t *
+_cairo_create_similar (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *similar;
-#ifndef HAVE_DRAND48
-#define drand48() (rand () / (double) RAND_MAX)
-#endif
+ similar = cairo_surface_create_similar (cairo_get_target (cr),
+ cairo_surface_get_content (cairo_get_target (cr)),
+ width, height);
+ cr = cairo_create (similar);
+ cairo_surface_destroy (similar);
+
+ return cr;
+}
+
+static cairo_t *
+_cairo_create_image (cairo_t *cr, cairo_format_t format, int width, int height)
+{
+ cairo_surface_t *image;
+
+ image = cairo_image_surface_create (format, width, height);
+ cr = cairo_create (image);
+ cairo_surface_destroy (image);
+
+ return cr;
+}
+
+static void
+_draw (cairo_t *cr,
+ double red,
+ double green,
+ double blue)
+{
+ cairo_text_extents_t extents;
+
+ cairo_set_source_rgb (cr, red, green, blue);
+ cairo_paint (cr);
+
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, 1, 1);
+ cairo_stroke (cr);
+
+ cairo_mask (cr, cairo_get_source (cr));
+
+ cairo_text_extents (cr, "cairo", &extents);
+ cairo_move_to (cr,
+ -extents.x_bearing - .5 * extents.width,
+ -extents.y_bearing - .5 * extents.height);
+ cairo_show_text (cr, "cairo");
+
+}
+
+static void
+use_similar (cairo_t *cr,
+ double red,
+ double green,
+ double blue)
+{
+ cr = _cairo_create_similar (cr, 1, 1);
+
+ _draw (cr, red, green, blue);
+
+ cairo_destroy (cr);
+}
+
+static void
+use_image (cairo_t *cr,
+ cairo_format_t format,
+ double red,
+ double green,
+ double blue)
+{
+ cr = _cairo_create_image (cr, format, 1, 1);
+
+ _draw (cr, red, green, blue);
+
+ cairo_destroy (cr);
+}
+
+static void
+use_solid (cairo_t *cr,
+ double red,
+ double green,
+ double blue)
+{
+ /* mix in dissimilar solids */
+ use_image (cr, CAIRO_FORMAT_A1, red, green, blue);
+ use_image (cr, CAIRO_FORMAT_A8, red, green, blue);
+ use_image (cr, CAIRO_FORMAT_RGB24, red, green, blue);
+ use_image (cr, CAIRO_FORMAT_ARGB32, red, green, blue);
+
+ use_similar (cr, red, green, blue);
+
+ _draw (cr, red, green, blue);
+}
static cairo_test_status_t
draw (cairo_t *cr, int width, int height)
@@ -54,32 +148,25 @@ draw (cairo_t *cr, int width, int height)
int i;
for (loop = 0; loop < LOOPS; loop++) {
- cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */
- cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); /* red */
- cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); /* green */
- cairo_set_source_rgb (cr, 1.0, 1.0, 0.0); /* yellow */
- cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); /* blue */
- cairo_set_source_rgb (cr, 1.0, 0.0, 1.0); /* magenta */
- cairo_set_source_rgb (cr, 0.0, 1.0, 1.0); /* cyan */
- cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
-
- cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0); /* black */
- cairo_set_source_rgba (cr, 1.0, 0.0, 0.0, 1.0); /* red */
- cairo_set_source_rgba (cr, 0.0, 1.0, 0.0, 1.0); /* green */
- cairo_set_source_rgba (cr, 1.0, 1.0, 0.0, 1.0); /* yellow */
- cairo_set_source_rgba (cr, 0.0, 0.0, 1.0, 1.0); /* blue */
- cairo_set_source_rgba (cr, 1.0, 0.0, 1.0, 1.0); /* magenta */
- cairo_set_source_rgba (cr, 0.0, 1.0, 1.0, 1.0); /* cyan */
- cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0); /* white */
+ for (i = 0; i < LOOPS; i++) {
+ use_solid (cr, 0.0, 0.0, 0.0); /* black */
+ use_solid (cr, 1.0, 0.0, 0.0); /* red */
+ use_solid (cr, 0.0, 1.0, 0.0); /* green */
+ use_solid (cr, 1.0, 1.0, 0.0); /* yellow */
+ use_solid (cr, 0.0, 0.0, 1.0); /* blue */
+ use_solid (cr, 1.0, 0.0, 1.0); /* magenta */
+ use_solid (cr, 0.0, 1.0, 1.0); /* cyan */
+ use_solid (cr, 1.0, 1.0, 1.0); /* white */
+ }
for (i = 0; i < NRAND; i++)
- cairo_set_source_rgba (cr,
- drand48 (),
- drand48 (),
- drand48 (),
- drand48 ());
+ use_solid (cr, drand48 (), drand48 (), drand48 ());
}
+ /* stress test only, so clear the surface before comparing */
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_paint (cr);
+
return CAIRO_TEST_SUCCESS;
}
@@ -88,4 +175,3 @@ main (void)
{
return cairo_test (&test);
}
-
More information about the cairo-commit
mailing list