[cairo-commit] 7 commits - boilerplate/cairo-boilerplate.c boilerplate/cairo-boilerplate.h perf/cairo-perf.c src/cairo-arc.c src/cairo.c src/cairo-font-options.c src/cairoint.h src/cairo-surface.c src/cairo-xlib-private.h src/cairo-xlib-screen.c test/cairo-test.c
Chris Wilson
ickle at kemper.freedesktop.org
Fri Apr 11 07:39:18 PDT 2008
boilerplate/cairo-boilerplate.c | 14 ++++++---
boilerplate/cairo-boilerplate.h | 3 ++
perf/cairo-perf.c | 6 ++--
src/cairo-arc.c | 3 ++
src/cairo-font-options.c | 2 -
src/cairo-surface.c | 9 ++----
src/cairo-xlib-private.h | 1
src/cairo-xlib-screen.c | 58 ++++++++++++++++++++++++----------------
src/cairo.c | 16 +++++------
src/cairoint.h | 2 -
test/cairo-test.c | 8 ++---
11 files changed, 71 insertions(+), 51 deletions(-)
New commits:
commit f57100acd4937486bfb69d38dfc72d42427e2851
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Apr 11 11:36:24 2008 +0100
[test] Handle TEST_CONTENT_COLOR_ALPHA_FLATTENED similar surfaces.
Convert the boilerplate specific flattened content value to the ordinary
CAIRO_CONTENT_COLOR_ALPHA for use with cairo_push_group_with_content() -
otherwise cairo rightfully flags an error and the test harness decides
that the similar surface is not available.
diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c
index a4c2114..f563b7a 100644
--- a/boilerplate/cairo-boilerplate.c
+++ b/boilerplate/cairo-boilerplate.c
@@ -68,16 +68,22 @@
#include <ctype.h>
#include <assert.h>
+cairo_content_t
+cairo_boilerplate_content (cairo_content_t content)
+{
+ if (content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED)
+ content = CAIRO_CONTENT_COLOR_ALPHA;
+
+ return content;
+}
+
const char *
cairo_boilerplate_content_name (cairo_content_t content)
{
/* For the purpose of the content name, we don't distinguish the
* flattened content value.
*/
- if (content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED)
- content = CAIRO_CONTENT_COLOR_ALPHA;
-
- switch (content) {
+ switch (cairo_boilerplate_content (content)) {
case CAIRO_CONTENT_COLOR:
return "rgb24";
case CAIRO_CONTENT_COLOR_ALPHA:
diff --git a/boilerplate/cairo-boilerplate.h b/boilerplate/cairo-boilerplate.h
index 7c7aa30..8efc609 100644
--- a/boilerplate/cairo-boilerplate.h
+++ b/boilerplate/cairo-boilerplate.h
@@ -95,6 +95,9 @@
* PDF surfaces. */
#define CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED ((unsigned int) -1)
+cairo_content_t
+cairo_boilerplate_content (cairo_content_t content);
+
const char *
cairo_boilerplate_content_name (cairo_content_t content);
diff --git a/perf/cairo-perf.c b/perf/cairo-perf.c
index be5589f..bfc0240 100644
--- a/perf/cairo-perf.c
+++ b/perf/cairo-perf.c
@@ -176,7 +176,8 @@ cairo_perf_run (cairo_perf_t *perf,
/* We run one iteration in advance to warm caches, etc. */
cairo_perf_yield ();
if (similar)
- cairo_push_group_with_content (perf->cr, perf->target->content);
+ cairo_push_group_with_content (perf->cr,
+ cairo_boilerplate_content (perf->target->content));
(perf_func) (perf->cr, perf->size, perf->size);
if (similar)
cairo_pattern_destroy (cairo_pop_group (perf->cr));
@@ -185,7 +186,8 @@ cairo_perf_run (cairo_perf_t *perf,
for (i =0; i < perf->iterations; i++) {
cairo_perf_yield ();
if (similar)
- cairo_push_group_with_content (perf->cr, perf->target->content);
+ cairo_push_group_with_content (perf->cr,
+ cairo_boilerplate_content (perf->target->content));
times[i] = (perf_func) (perf->cr, perf->size, perf->size);
if (similar)
cairo_pattern_destroy (cairo_pop_group (perf->cr));
diff --git a/test/cairo-test.c b/test/cairo-test.c
index 61cbb31..5608f40 100644
--- a/test/cairo-test.c
+++ b/test/cairo-test.c
@@ -242,7 +242,7 @@ cairo_test_target_has_similar (const cairo_test_t *test, cairo_boilerplate_targe
if (surface != NULL) {
cairo_t * cr = cairo_create (surface);
cairo_surface_t *similar;
- cairo_push_group_with_content (cr, target->content);
+ cairo_push_group_with_content (cr, cairo_boilerplate_content (target->content));
similar = cairo_get_group_target (cr);
has_similar = cairo_surface_get_type (similar) == cairo_surface_get_type (surface);
@@ -342,9 +342,7 @@ cairo_test_for_target (cairo_test_t *test,
* (ignore the articifical
* CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED value).
*/
- expected_content = target->content;
- if (expected_content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED)
- expected_content = CAIRO_CONTENT_COLOR_ALPHA;
+ expected_content = cairo_boilerplate_content (target->content);
if (cairo_surface_get_content (surface) != expected_content) {
cairo_test_log ("Error: Created surface has content %d (expected %d)\n",
@@ -357,7 +355,7 @@ cairo_test_for_target (cairo_test_t *test,
cr = cairo_create (surface);
if (similar)
- cairo_push_group_with_content (cr, target->content);
+ cairo_push_group_with_content (cr, expected_content);
/* Clear to transparent (or black) depending on whether the target
* surface supports alpha. */
commit e4fc5279cc490b8d7c1f611d73601e6782c944a5
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Mar 31 15:48:51 2008 +0100
[cairo-font-options] Eliminate internal use of cairo_font_options_create()
Within the library, we know the precise size of the struct and so can
allocate temporary font options on the stack - eliminating the need
to export an internal alias of cairo_font_options_(create|destory).
diff --git a/src/cairo-font-options.c b/src/cairo-font-options.c
index 1662a6c..dedd337 100644
--- a/src/cairo-font-options.c
+++ b/src/cairo-font-options.c
@@ -95,7 +95,6 @@ cairo_font_options_create (void)
return options;
}
-slim_hidden_def (cairo_font_options_create);
/**
* cairo_font_options_copy:
@@ -144,7 +143,6 @@ cairo_font_options_destroy (cairo_font_options_t *options)
free (options);
}
-slim_hidden_def (cairo_font_options_destroy);
/**
* cairo_font_options_status:
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 12b0885..0d5a3f8 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -2120,19 +2120,16 @@ _cairo_surface_show_glyphs (cairo_surface_t *surface,
if (_cairo_surface_has_device_transform (surface) &&
! _cairo_matrix_is_integer_translation (&surface->device_transform, NULL, NULL))
{
- cairo_font_options_t *font_options;
+ cairo_font_options_t font_options;
cairo_matrix_t dev_ctm;
- font_options = cairo_font_options_create ();
-
cairo_scaled_font_get_ctm (scaled_font, &dev_ctm);
cairo_matrix_multiply (&dev_ctm, &dev_ctm, &surface->device_transform);
- cairo_scaled_font_get_font_options (scaled_font, font_options);
+ cairo_scaled_font_get_font_options (scaled_font, &font_options);
dev_scaled_font = cairo_scaled_font_create (cairo_scaled_font_get_font_face (scaled_font),
&font_matrix,
&dev_ctm,
- font_options);
- cairo_font_options_destroy (font_options);
+ &font_options);
}
status = cairo_scaled_font_status (dev_scaled_font);
if (status) {
diff --git a/src/cairoint.h b/src/cairoint.h
index 0389c26..f843c89 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -2258,8 +2258,6 @@ slim_hidden_proto (cairo_destroy);
slim_hidden_proto (cairo_fill_preserve);
slim_hidden_proto (cairo_font_face_destroy);
slim_hidden_proto_no_warn (cairo_font_face_reference);
-slim_hidden_proto (cairo_font_options_create);
-slim_hidden_proto (cairo_font_options_destroy);
slim_hidden_proto (cairo_font_options_equal);
slim_hidden_proto (cairo_font_options_hash);
slim_hidden_proto (cairo_font_options_merge);
commit b72fe9bb5ff20bfc3d30a8a4bb353e52818b5fb7
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Apr 10 16:48:42 2008 +0100
[cairo-arc] Check that the context is not error before proceeding.
We depend on values stored on the context that become invalid upon an
error, so stop processing as soon as an error occurs. Prior to
adjusting, the values returned from the error context, this would cause
an infinite loop whilst calculating the number of segments required for
a tolerance of 0.
diff --git a/src/cairo-arc.c b/src/cairo-arc.c
index 89e6ce1..5232970 100644
--- a/src/cairo-arc.c
+++ b/src/cairo-arc.c
@@ -181,6 +181,9 @@ _cairo_arc_in_direction (cairo_t *cr,
double angle_max,
cairo_direction_t dir)
{
+ if (cairo_status (cr))
+ return;
+
while (angle_max - angle_min > 4 * M_PI)
angle_max -= 2 * M_PI;
commit f6834dacef3e6f798c54829b9a309c8f96ed39f5
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Apr 10 16:43:10 2008 +0100
[cairo] Return defaults when the context is in error.
Return the default values instead of zero for an error context. This
helps to prevent application logic faults when using the values from
the error context (for an example, see _cairo_arc_in_direction()).
diff --git a/src/cairo.c b/src/cairo.c
index a7073d0..6c73e2c 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -3258,7 +3258,7 @@ cairo_operator_t
cairo_get_operator (cairo_t *cr)
{
if (cr->status)
- return (cairo_operator_t) 0;
+ return CAIRO_GSTATE_OPERATOR_DEFAULT;
return _cairo_gstate_get_operator (cr->gstate);
}
@@ -3275,7 +3275,7 @@ double
cairo_get_tolerance (cairo_t *cr)
{
if (cr->status)
- return 0.;
+ return CAIRO_GSTATE_TOLERANCE_DEFAULT;
return _cairo_gstate_get_tolerance (cr->gstate);
}
@@ -3293,7 +3293,7 @@ cairo_antialias_t
cairo_get_antialias (cairo_t *cr)
{
if (cr->status)
- return (cairo_antialias_t) 0;
+ return CAIRO_ANTIALIAS_DEFAULT;
return _cairo_gstate_get_antialias (cr->gstate);
}
@@ -3386,7 +3386,7 @@ cairo_fill_rule_t
cairo_get_fill_rule (cairo_t *cr)
{
if (cr->status)
- return (cairo_fill_rule_t) 0;
+ return CAIRO_GSTATE_FILL_RULE_DEFAULT;
return _cairo_gstate_get_fill_rule (cr->gstate);
}
@@ -3406,7 +3406,7 @@ double
cairo_get_line_width (cairo_t *cr)
{
if (cr->status)
- return 0.;
+ return CAIRO_GSTATE_LINE_WIDTH_DEFAULT;
return _cairo_gstate_get_line_width (cr->gstate);
}
@@ -3423,7 +3423,7 @@ cairo_line_cap_t
cairo_get_line_cap (cairo_t *cr)
{
if (cr->status)
- return (cairo_line_cap_t) 0;
+ return CAIRO_GSTATE_LINE_CAP_DEFAULT;
return _cairo_gstate_get_line_cap (cr->gstate);
}
@@ -3440,7 +3440,7 @@ cairo_line_join_t
cairo_get_line_join (cairo_t *cr)
{
if (cr->status)
- return (cairo_line_join_t) 0;
+ return CAIRO_GSTATE_LINE_JOIN_DEFAULT;
return _cairo_gstate_get_line_join (cr->gstate);
}
@@ -3457,7 +3457,7 @@ double
cairo_get_miter_limit (cairo_t *cr)
{
if (cr->status)
- return 0.;
+ return CAIRO_GSTATE_MITER_LIMIT_DEFAULT;
return _cairo_gstate_get_miter_limit (cr->gstate);
}
commit 68f53282b9a7ebf1bb2117b5a630237f458b99b0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Apr 10 14:58:30 2008 +0100
[xlib] Clear the Visual cache upon display closure.
Clear the Visual cache, similarly to flushing the GC cache, upon
XCloseDisplay.
diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c
index 73d8bb7..c456b16 100644
--- a/src/cairo-xlib-screen.c
+++ b/src/cairo-xlib-screen.c
@@ -254,6 +254,7 @@ _cairo_xlib_screen_info_reference (cairo_xlib_screen_info_t *info)
void
_cairo_xlib_screen_info_close_display (cairo_xlib_screen_info_t *info)
{
+ cairo_xlib_visual_info_t **visuals;
int i;
CAIRO_MUTEX_LOCK (info->mutex);
@@ -263,6 +264,12 @@ _cairo_xlib_screen_info_close_display (cairo_xlib_screen_info_t *info)
info->gc[i] = NULL;
}
}
+
+ visuals = _cairo_array_index (&info->visuals, 0);
+ for (i = 0; i < _cairo_array_num_elements (&info->visuals); i++)
+ _cairo_xlib_visual_info_destroy (info->display->display, visuals[i]);
+ _cairo_array_truncate (&info->visuals, 0);
+
CAIRO_MUTEX_UNLOCK (info->mutex);
}
@@ -271,8 +278,6 @@ _cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info)
{
cairo_xlib_screen_info_t **prev;
cairo_xlib_screen_info_t *list;
- cairo_xlib_visual_info_t **visuals;
- int i;
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&info->ref_count));
@@ -290,13 +295,10 @@ _cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info)
_cairo_xlib_screen_info_close_display (info);
- visuals = _cairo_array_index (&info->visuals, 0);
- for (i = 0; i < _cairo_array_num_elements (&info->visuals); i++)
- _cairo_xlib_visual_info_destroy (info->display->display, visuals[i]);
- _cairo_array_fini (&info->visuals);
-
_cairo_xlib_display_destroy (info->display);
+ _cairo_array_fini (&info->visuals);
+
CAIRO_MUTEX_FINI (info->mutex);
free (info);
commit a2608cdde54dd677290da83cc9f8b98b139ff774
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Apr 10 14:56:12 2008 +0100
[xlib] Convert the Visual cache to use the screen mutex.
Use the per-screen mutex, introduced for the GC cache, to lock access to
the Visual cache (instead of the per-display mutex).
diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c
index fc07fda..73d8bb7 100644
--- a/src/cairo-xlib-screen.c
+++ b/src/cairo-xlib-screen.c
@@ -286,17 +286,17 @@ _cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info)
break;
}
}
- visuals = _cairo_array_index (&info->visuals, 0);
- for (i = 0; i < _cairo_array_num_elements (&info->visuals); i++)
- _cairo_xlib_visual_info_destroy (info->display->display, visuals[i]);
CAIRO_MUTEX_UNLOCK (info->display->mutex);
_cairo_xlib_screen_info_close_display (info);
- _cairo_xlib_display_destroy (info->display);
-
+ visuals = _cairo_array_index (&info->visuals, 0);
+ for (i = 0; i < _cairo_array_num_elements (&info->visuals); i++)
+ _cairo_xlib_visual_info_destroy (info->display->display, visuals[i]);
_cairo_array_fini (&info->visuals);
+ _cairo_xlib_display_destroy (info->display);
+
CAIRO_MUTEX_FINI (info->mutex);
free (info);
@@ -438,11 +438,12 @@ _cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info,
Visual *visual,
cairo_xlib_visual_info_t **out)
{
+ Display *dpy = info->display->display;
cairo_xlib_visual_info_t **visuals, *ret = NULL;
cairo_status_t status;
int i, n_visuals;
- CAIRO_MUTEX_LOCK (info->display->mutex);
+ CAIRO_MUTEX_LOCK (info->mutex);
visuals = _cairo_array_index (&info->visuals, 0);
n_visuals = _cairo_array_num_elements (&info->visuals);
for (i = 0; i < n_visuals; i++) {
@@ -451,28 +452,28 @@ _cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info,
break;
}
}
- CAIRO_MUTEX_UNLOCK (info->display->mutex);
+ CAIRO_MUTEX_UNLOCK (info->mutex);
if (ret != NULL) {
*out = ret;
return CAIRO_STATUS_SUCCESS;
}
- status = _cairo_xlib_visual_info_create (info->display->display,
+ status = _cairo_xlib_visual_info_create (dpy,
XScreenNumberOfScreen (info->screen),
visual->visualid,
&ret);
if (status)
return status;
- CAIRO_MUTEX_LOCK (info->display->mutex);
+ CAIRO_MUTEX_LOCK (info->mutex);
if (n_visuals != _cairo_array_num_elements (&info->visuals)) {
/* check that another thread has not added our visual */
int new_visuals = _cairo_array_num_elements (&info->visuals);
visuals = _cairo_array_index (&info->visuals, 0);
for (i = n_visuals; i < new_visuals; i++) {
if (visuals[i]->visualid == visual->visualid) {
- _cairo_xlib_visual_info_destroy (info->display->display, ret);
+ _cairo_xlib_visual_info_destroy (dpy, ret);
ret = visuals[i];
break;
}
@@ -481,10 +482,10 @@ _cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info,
status = _cairo_array_append (&info->visuals, &ret);
} else
status = _cairo_array_append (&info->visuals, &ret);
- CAIRO_MUTEX_UNLOCK (info->display->mutex);
+ CAIRO_MUTEX_UNLOCK (info->mutex);
if (status) {
- _cairo_xlib_visual_info_destroy (info->display->display, ret);
+ _cairo_xlib_visual_info_destroy (dpy, ret);
return status;
}
commit dc714106e156cb7901e376c0935922446ae9bcdf
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Apr 10 14:49:47 2008 +0100
[xlib] Add locking around GC cache.
The per-screen cached of most-recently freed GCs lacks suitable locking
for it to be threadsafe.
diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h
index 5bfc2ec..2d9737d 100644
--- a/src/cairo-xlib-private.h
+++ b/src/cairo-xlib-private.h
@@ -79,6 +79,7 @@ typedef struct _cairo_xlib_visual_info {
struct _cairo_xlib_screen_info {
cairo_xlib_screen_info_t *next;
cairo_reference_count_t ref_count;
+ cairo_mutex_t mutex;
cairo_xlib_display_t *display;
Screen *screen;
diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c
index 8a3da66..fc07fda 100644
--- a/src/cairo-xlib-screen.c
+++ b/src/cairo-xlib-screen.c
@@ -256,12 +256,14 @@ _cairo_xlib_screen_info_close_display (cairo_xlib_screen_info_t *info)
{
int i;
+ CAIRO_MUTEX_LOCK (info->mutex);
for (i = 0; i < ARRAY_LENGTH (info->gc); i++) {
if (info->gc[i] != NULL) {
XFreeGC (info->display->display, info->gc[i]);
info->gc[i] = NULL;
}
}
+ CAIRO_MUTEX_UNLOCK (info->mutex);
}
void
@@ -295,6 +297,8 @@ _cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info)
_cairo_array_fini (&info->visuals);
+ CAIRO_MUTEX_FINI (info->mutex);
+
free (info);
}
@@ -335,6 +339,7 @@ _cairo_xlib_screen_info_get (Display *dpy, Screen *screen)
info = malloc (sizeof (cairo_xlib_screen_info_t));
if (info != NULL) {
CAIRO_REFERENCE_COUNT_INIT (&info->ref_count, 2); /* Add one for display cache */
+ CAIRO_MUTEX_INIT (info->mutex);
info->display = _cairo_xlib_display_reference (display);
info->screen = screen;
info->has_render = FALSE;
@@ -385,16 +390,18 @@ GC
_cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info, int depth)
{
GC gc;
+ cairo_bool_t needs_reset;
depth = depth_to_index (depth);
+ CAIRO_MUTEX_LOCK (info->mutex);
gc = info->gc[depth];
info->gc[depth] = NULL;
+ needs_reset = info->gc_needs_clip_reset & (1 << depth);
+ CAIRO_MUTEX_UNLOCK (info->mutex);
- if (info->gc_needs_clip_reset & (1 << depth)) {
+ if (needs_reset)
XSetClipMask(info->display->display, gc, None);
- info->gc_needs_clip_reset &= ~(1 << depth);
- }
return gc;
}
@@ -403,21 +410,25 @@ cairo_status_t
_cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info, int depth, GC gc, cairo_bool_t reset_clip)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
+ GC oldgc;
depth = depth_to_index (depth);
- if (info->gc[depth] != NULL) {
- status = _cairo_xlib_display_queue_work (info->display,
- (cairo_xlib_notify_func) XFreeGC,
- info->gc[depth],
- NULL);
- }
-
+ CAIRO_MUTEX_LOCK (info->mutex);
+ oldgc = info->gc[depth];
info->gc[depth] = gc;
if (reset_clip)
info->gc_needs_clip_reset |= 1 << depth;
else
info->gc_needs_clip_reset &= ~(1 << depth);
+ CAIRO_MUTEX_UNLOCK (info->mutex);
+
+ if (oldgc != NULL) {
+ status = _cairo_xlib_display_queue_work (info->display,
+ (cairo_xlib_notify_func) XFreeGC,
+ oldgc,
+ NULL);
+ }
return status;
}
More information about the cairo-commit
mailing list