[cairo-commit] 6 commits - boilerplate/cairo-boilerplate.c boilerplate/cairo-boilerplate.h perf/cairo-perf-micro.c perf/cairo-perf-trace.c src/cairo-clip.c src/cairo-clip-private.h src/cairo-paginated-surface.c src/cairo-recording-surface.c src/cairo-scaled-font.c src/cairo-script-surface.c src/cairo-surface-wrapper.c test/cairo-test.c

Chris Wilson ickle at kemper.freedesktop.org
Tue Mar 23 13:53:57 PDT 2010


 boilerplate/cairo-boilerplate.c |   13 ++++++
 boilerplate/cairo-boilerplate.h |    3 +
 perf/cairo-perf-micro.c         |    2 
 perf/cairo-perf-trace.c         |    2 
 src/cairo-clip-private.h        |    4 -
 src/cairo-clip.c                |   30 +++++--------
 src/cairo-paginated-surface.c   |   18 ++++----
 src/cairo-recording-surface.c   |   11 ++---
 src/cairo-scaled-font.c         |   11 +++--
 src/cairo-script-surface.c      |   86 ++++++++++++++++++++++++++++++++--------
 src/cairo-surface-wrapper.c     |   14 ++----
 test/cairo-test.c               |    2 
 12 files changed, 130 insertions(+), 66 deletions(-)

New commits:
commit 6da3cea3564bd8c5de37bf2244a2dd656202e4ec
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Mar 23 20:53:11 2010 +0000

    scaled-font: Destroy the old surface when replacing scaled_glyph->recording

diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index b6d0df6..c2ba407 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -198,8 +198,10 @@ _cairo_scaled_glyph_fini (cairo_scaled_font_t *scaled_font,
     if (scaled_glyph->path != NULL)
 	_cairo_path_fixed_destroy (scaled_glyph->path);
 
-    if (scaled_glyph->recording_surface != NULL)
+    if (scaled_glyph->recording_surface != NULL) {
+	cairo_surface_finish (scaled_glyph->recording_surface);
 	cairo_surface_destroy (scaled_glyph->recording_surface);
+    }
 }
 
 #define ZOMBIE 0
@@ -2511,8 +2513,11 @@ _cairo_scaled_glyph_set_recording_surface (cairo_scaled_glyph_t *scaled_glyph,
 					   cairo_scaled_font_t *scaled_font,
 					   cairo_surface_t *recording_surface)
 {
-    if (scaled_glyph->recording_surface != NULL)
-	cairo_surface_destroy (recording_surface);
+    if (scaled_glyph->recording_surface != NULL) {
+	cairo_surface_finish (scaled_glyph->recording_surface);
+	cairo_surface_destroy (scaled_glyph->recording_surface);
+    }
+
     scaled_glyph->recording_surface = recording_surface;
 }
 
commit 548092fe8c9af1423a10e9566cbc4315d2f28efc
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Mar 23 20:08:04 2010 +0000

    script: Free the surface/font bitmaps.

diff --git a/src/cairo-script-surface.c b/src/cairo-script-surface.c
index a4a3f1d..8dc74d3 100644
--- a/src/cairo-script-surface.c
+++ b/src/cairo-script-surface.c
@@ -238,6 +238,16 @@ _bitmap_next_id (struct _bitmap *b,
     return CAIRO_STATUS_SUCCESS;
 }
 
+static void
+_bitmap_fini (struct _bitmap *b)
+{
+    while (b != NULL) {
+	struct _bitmap *next = b->next;
+	free (b);
+	b = next;
+    }
+}
+
 static const char *
 _direction_to_string (cairo_bool_t backward)
 {
@@ -1787,6 +1797,9 @@ _device_destroy (void *abstract_device)
 	assert (status == CAIRO_STATUS_SUCCESS);
     }
 
+    _bitmap_fini (ctx->surface_id.next);
+    _bitmap_fini (ctx->font_id.next);
+
     status = _cairo_output_stream_destroy (ctx->stream);
 
     free (ctx);
commit 83d1bd9f37da93fbdc586788b6891d0eccdb7cee
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Mar 23 20:04:10 2010 +0000

    script: Manually unlink font entries upon destruction
    
    As the device is already finished, we can not lock it without raising an
    error, so we have to open code the destruction of the font entries.
    Fortunately we can make several simplifying assumptions about the
    required cleanup as we know the device is also being destroyed.

diff --git a/src/cairo-script-surface.c b/src/cairo-script-surface.c
index d07ce81..a4a3f1d 100644
--- a/src/cairo-script-surface.c
+++ b/src/cairo-script-surface.c
@@ -1772,7 +1772,9 @@ _device_destroy (void *abstract_device)
 				       cairo_script_surface_font_private_t,
 				       link);
 	cairo_list_del (&font->link);
-	_cairo_script_surface_scaled_font_fini (font->parent);
+	if (font->parent->surface_private == font)
+	    font->parent->surface_private = NULL;
+	free (font);
     }
 
     while (! cairo_list_is_empty (&ctx->defines)) {
commit cccf6753ab68b0795351da2626f9e4ecd60c2a2e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Mar 23 19:45:35 2010 +0000

    script: More acquire device fixes.
    
    We also need to acquire the device upon finish, similar surface creation
    and the pagination functions, i.e. the other times outside of the
    drawing ops that must modify the shared context/device.

diff --git a/src/cairo-script-surface.c b/src/cairo-script-surface.c
index 0c77cc3..d07ce81 100644
--- a/src/cairo-script-surface.c
+++ b/src/cairo-script-surface.c
@@ -426,7 +426,6 @@ _get_target (cairo_script_surface_t *surface)
 						 depth);
 		}
 		_cairo_output_stream_puts (ctx->stream, "/target get ");
-		target_push (surface);
 	    }
 	} else {
 	    _cairo_output_stream_puts (ctx->stream, "/target get ");
@@ -1500,6 +1499,7 @@ _emit_source (cairo_script_surface_t *surface,
     if (unlikely (status))
 	return status;
 
+    assert (target_is_active (surface));
     _cairo_output_stream_puts (to_context (surface)->stream,
 			       " set-source\n");
     return CAIRO_STATUS_SUCCESS;
@@ -1700,10 +1700,16 @@ _cairo_script_surface_create_similar (void	       *abstract_surface,
 
     ctx = to_context (other);
 
+    status = cairo_device_acquire (&ctx->base);
+    if (unlikely (status))
+	return _cairo_surface_create_in_error (status);
+
     if (! other->emitted) {
 	status = _emit_surface (other);
-	if (unlikely (status))
+	if (unlikely (status)) {
+	    cairo_device_release (&ctx->base);
 	    return _cairo_surface_create_in_error (status);
+	}
 
 	target_push (other);
     }
@@ -1712,8 +1718,10 @@ _cairo_script_surface_create_similar (void	       *abstract_surface,
 	passthrough =
 	    _cairo_surface_wrapper_create_similar (&other->wrapper,
 						   content, width, height);
-	if (unlikely (passthrough->status))
+	if (unlikely (passthrough->status)) {
+	    cairo_device_release (&ctx->base);
 	    return passthrough;
+	}
     }
 
     surface = _cairo_script_surface_create_internal (ctx,
@@ -1722,8 +1730,10 @@ _cairo_script_surface_create_similar (void	       *abstract_surface,
 						     passthrough);
     cairo_surface_destroy (passthrough);
 
-    if (unlikely (surface->base.status))
+    if (unlikely (surface->base.status)) {
+	cairo_device_release (&ctx->base);
 	return &surface->base;
+    }
 
     _get_target (other);
     _cairo_output_stream_printf (ctx->stream,
@@ -1736,6 +1746,7 @@ _cairo_script_surface_create_similar (void	       *abstract_surface,
     surface->base.is_clear = TRUE;
     target_push (surface);
 
+    cairo_device_release (&ctx->base);
     return &surface->base;
 }
 
@@ -1825,6 +1836,10 @@ _cairo_script_surface_finish (void *abstract_surface)
     _cairo_path_fixed_fini (&surface->cr.current_path);
     _cairo_surface_clipper_reset (&surface->clipper);
 
+    status = cairo_device_acquire (&ctx->base);
+    if (unlikely (status))
+	return status;
+
     if (surface->emitted) {
 	assert (! surface->active);
 
@@ -1871,6 +1886,8 @@ _cairo_script_surface_finish (void *abstract_surface)
     if (status == CAIRO_STATUS_SUCCESS)
 	status = _cairo_output_stream_flush (to_context (surface)->stream);
 
+    cairo_device_release (&ctx->base);
+
     return status;
 }
 
@@ -1880,13 +1897,19 @@ _cairo_script_surface_copy_page (void *abstract_surface)
     cairo_script_surface_t *surface = abstract_surface;
     cairo_status_t status;
 
-    status = _emit_context (surface);
+    status = cairo_device_acquire (surface->base.device);
     if (unlikely (status))
 	return status;
 
+    status = _emit_context (surface);
+    if (unlikely (status))
+	goto BAIL;
+
     _cairo_output_stream_puts (to_context (surface)->stream, "copy-page\n");
 
-    return CAIRO_STATUS_SUCCESS;
+BAIL:
+    cairo_device_release (surface->base.device);
+    return status;
 }
 
 static cairo_int_status_t
@@ -1895,13 +1918,19 @@ _cairo_script_surface_show_page (void *abstract_surface)
     cairo_script_surface_t *surface = abstract_surface;
     cairo_status_t status;
 
-    status = _emit_context (surface);
+    status = cairo_device_acquire (surface->base.device);
     if (unlikely (status))
 	return status;
 
+    status = _emit_context (surface);
+    if (unlikely (status))
+	goto BAIL;
+
     _cairo_output_stream_puts (to_context (surface)->stream, "show-page\n");
 
-    return CAIRO_STATUS_SUCCESS;
+BAIL:
+    cairo_device_release (surface->base.device);
+    return status;
 }
 
 static cairo_status_t
@@ -1994,9 +2023,11 @@ inactive (cairo_script_surface_t *surface)
     cairo_script_context_t *ctx = to_context (surface);
     cairo_list_t sorted;
 
+    assert (surface->active > 0);
     if (--surface->active)
 	goto DONE;
 
+    assert (ctx->active > 0);
     if (--ctx->active)
 	goto DONE;
 
@@ -2459,14 +2490,22 @@ _cairo_script_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font)
 
     font_private = scaled_font->surface_private;
     if (font_private != NULL) {
-	_cairo_output_stream_printf (font_private->ctx->stream,
-				     "/f%lu undef /sf%lu undef\n",
-				     font_private->id,
-				     font_private->id);
+	cairo_status_t status;
+	cairo_device_t *device;
 
-	_bitmap_release_id (&font_private->ctx->font_id, font_private->id);
-	cairo_list_del (&font_private->link);
-	free (font_private);
+	status = cairo_device_acquire (device = &font_private->ctx->base);
+	if (likely (status == CAIRO_STATUS_SUCCESS)) {
+	    _cairo_output_stream_printf (font_private->ctx->stream,
+					 "/f%lu undef /sf%lu undef\n",
+					 font_private->id,
+					 font_private->id);
+
+	    _bitmap_release_id (&font_private->ctx->font_id, font_private->id);
+	    cairo_list_del (&font_private->link);
+	    free (font_private);
+
+	    cairo_device_release (device);
+	}
 
 	scaled_font->surface_private = NULL;
     }
commit 25a77b263d170265a9acf1697793cbbfa07dd852
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Mar 23 16:49:21 2010 +0000

    boilerplate: Cleanup the list of backends upon shutdown.

diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c
index 2a3a354..65e92fa 100644
--- a/boilerplate/cairo-boilerplate.c
+++ b/boilerplate/cairo-boilerplate.c
@@ -836,3 +836,16 @@ cairo_boilerplate_version_string (void)
 {
     return CAIRO_VERSION_STRING;
 }
+
+void
+cairo_boilerplate_fini (void)
+{
+    while (cairo_boilerplate_targets != NULL) {
+	struct cairo_boilerplate_target_list *next;
+
+	next = cairo_boilerplate_targets->next;
+
+	free (cairo_boilerplate_targets);
+	cairo_boilerplate_targets = next;
+    }
+}
diff --git a/boilerplate/cairo-boilerplate.h b/boilerplate/cairo-boilerplate.h
index 91a23fd..6f9afd1 100644
--- a/boilerplate/cairo-boilerplate.h
+++ b/boilerplate/cairo-boilerplate.h
@@ -216,6 +216,9 @@ cairo_boilerplate_version (void);
 const char*
 cairo_boilerplate_version_string (void);
 
+void
+cairo_boilerplate_fini (void);
+
 #include "cairo-boilerplate-system.h"
 
 CAIRO_END_DECLS
diff --git a/perf/cairo-perf-micro.c b/perf/cairo-perf-micro.c
index 44ed209..eec32ef 100644
--- a/perf/cairo-perf-micro.c
+++ b/perf/cairo-perf-micro.c
@@ -476,6 +476,8 @@ static void
 cairo_perf_fini (cairo_perf_t *perf)
 {
     cairo_boilerplate_free_targets (perf->targets);
+    cairo_boilerplate_fini ();
+
     free (perf->times);
     cairo_debug_reset_static_data ();
 #if HAVE_FCFINI
diff --git a/perf/cairo-perf-trace.c b/perf/cairo-perf-trace.c
index cc01158..88c797b 100644
--- a/perf/cairo-perf-trace.c
+++ b/perf/cairo-perf-trace.c
@@ -693,6 +693,8 @@ static void
 cairo_perf_fini (cairo_perf_t *perf)
 {
     cairo_boilerplate_free_targets (perf->targets);
+    cairo_boilerplate_fini ();
+
     free (perf->times);
     cairo_debug_reset_static_data ();
 #if HAVE_FCFINI
diff --git a/test/cairo-test.c b/test/cairo-test.c
index 5d6858c..e2bc687 100644
--- a/test/cairo-test.c
+++ b/test/cairo-test.c
@@ -256,6 +256,8 @@ cairo_test_fini (cairo_test_context_t *ctx)
     if (ctx->own_targets)
 	cairo_boilerplate_free_targets (ctx->targets_to_test);
 
+    cairo_boilerplate_fini ();
+
     cairo_debug_reset_static_data ();
 #if HAVE_FCFINI
     FcFini ();
commit 1ddcd5cf31bb47e9ff18ddf94d0a4648fa70a617
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Mar 23 16:43:39 2010 +0000

    clip: Remove the redundant _cairo_clip_init_rectangle()
    
    As _cairo_clip_init_rectangle() is equivalent and more importantly more
    clearly written as:
      _cairo_clip_init(&clip);
      if (status = _cairo_clip_rectangle(&clip, &rect)) {
         _cairo_clip_fini(&fini);
         return status;
      }
    perform the transformation and in the process catch a few mistakes along
    error paths.

diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h
index b9a39ae..05a10e6 100644
--- a/src/cairo-clip-private.h
+++ b/src/cairo-clip-private.h
@@ -76,10 +76,6 @@ struct _cairo_clip {
 cairo_private void
 _cairo_clip_init (cairo_clip_t *clip);
 
-cairo_private cairo_status_t
-_cairo_clip_init_rectangle (cairo_clip_t *clip,
-			    const cairo_rectangle_int_t *rect);
-
 cairo_private_no_warn cairo_clip_t *
 _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other);
 
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index fdb9470..19be812 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -164,35 +164,25 @@ _cairo_clip_intersect_rectangle (cairo_clip_t *clip,
     status = _cairo_path_fixed_close_path (&clip_path->path);
     assert (status == CAIRO_STATUS_SUCCESS);
 
-    clip_path->extents = *rect;
     clip_path->fill_rule = CAIRO_FILL_RULE_WINDING;
     clip_path->tolerance = 1;
     clip_path->antialias = CAIRO_ANTIALIAS_DEFAULT;
     clip_path->flags |= CAIRO_CLIP_PATH_IS_BOX;
 
+    clip_path->extents = *rect;
+    if (clip_path->prev != NULL) {
+	if (! _cairo_rectangle_intersect (&clip_path->extents,
+					  &clip_path->prev->extents))
+	{
+	    _cairo_clip_set_all_clipped (clip);
+	}
+    }
+
     /* could preallocate the region if it proves worthwhile */
 
     return CAIRO_STATUS_SUCCESS;
 }
 
-/* XXX consider accepting a matrix, no users yet. */
-cairo_status_t
-_cairo_clip_init_rectangle (cairo_clip_t *clip,
-			    const cairo_rectangle_int_t *rect)
-{
-    _cairo_clip_init (clip);
-
-    if (rect == NULL)
-	return CAIRO_STATUS_SUCCESS;
-
-    if (rect->width == 0 || rect->height == 0) {
-	_cairo_clip_set_all_clipped (clip);
-	return CAIRO_STATUS_SUCCESS;
-    }
-
-    return _cairo_clip_intersect_rectangle (clip, rect);
-}
-
 cairo_clip_t *
 _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
 {
@@ -361,6 +351,7 @@ _cairo_clip_path_reapply_clip_path_transform (cairo_clip_t      *clip,
     status = _cairo_path_fixed_init_copy (&clip_path->path,
 					  &other_path->path);
     if (unlikely (status)) {
+	clip->path = clip->path->prev;
 	_cairo_clip_path_destroy (clip_path);
 	return status;
     }
@@ -403,6 +394,7 @@ _cairo_clip_path_reapply_clip_path_translate (cairo_clip_t      *clip,
     status = _cairo_path_fixed_init_copy (&clip_path->path,
 					  &other_path->path);
     if (unlikely (status)) {
+	clip->path = clip->path->prev;
 	_cairo_clip_path_destroy (clip_path);
 	return status;
     }
diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index 4d7dc8f..f8c99f8 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -277,17 +277,17 @@ _paint_fallback_image (cairo_paginated_surface_t *surface,
      * filtering (if possible) to avoid introducing potential artifacts. */
     pattern.base.filter = CAIRO_FILTER_NEAREST;
 
-    status = _cairo_clip_init_rectangle (&clip, rect);
-    if (unlikely (status))
-	goto CLEANUP_IMAGE;
-
-    status = _cairo_surface_paint (surface->target,
-				   CAIRO_OPERATOR_SOURCE,
-				   &pattern.base, &clip);
-
-    _cairo_clip_reset (&clip);
+    _cairo_clip_init (&clip);
+    status = _cairo_clip_rectangle (&clip, rect);
+    if (likely (status == CAIRO_STATUS_SUCCESS)) {
+	status = _cairo_surface_paint (surface->target,
+				       CAIRO_OPERATOR_SOURCE,
+				       &pattern.base, &clip);
+    }
 
+    _cairo_clip_fini (&clip);
     _cairo_pattern_fini (&pattern.base);
+
 CLEANUP_IMAGE:
     cairo_surface_destroy (image);
 
diff --git a/src/cairo-recording-surface.c b/src/cairo-recording-surface.c
index 5f0a298..973b15c 100644
--- a/src/cairo-recording-surface.c
+++ b/src/cairo-recording-surface.c
@@ -130,6 +130,9 @@ cairo_recording_surface_create (cairo_content_t		 content,
 
     recording_surface->content = content;
 
+    recording_surface->unbounded = TRUE;
+    _cairo_clip_init (&recording_surface->clip);
+
     /* unbounded -> 'infinite' extents */
     if (extents != NULL) {
 	recording_surface->extents_pixels = *extents;
@@ -140,16 +143,14 @@ cairo_recording_surface_create (cairo_content_t		 content,
 	recording_surface->extents.width = ceil (extents->x + extents->width) - recording_surface->extents.x;
 	recording_surface->extents.height = ceil (extents->y + extents->height) - recording_surface->extents.y;
 
-	status = _cairo_clip_init_rectangle (&recording_surface->clip, &recording_surface->extents);
+	status = _cairo_clip_rectangle (&recording_surface->clip,
+					&recording_surface->extents);
 	if (unlikely (status)) {
 	    free (recording_surface);
 	    return _cairo_surface_create_in_error (status);
 	}
 
 	recording_surface->unbounded = FALSE;
-    } else {
-	recording_surface->unbounded = TRUE;
-	_cairo_clip_init (&recording_surface->clip);
     }
 
     _cairo_array_init (&recording_surface->commands, sizeof (cairo_command_t *));
@@ -191,8 +192,6 @@ _cairo_recording_surface_finish (void *abstract_surface)
     for (i = 0; i < num_elements; i++) {
 	cairo_command_t *command = elements[i];
 
-	_cairo_clip_reset (&command->header.clip);
-
 	switch (command->header.type) {
 	case CAIRO_COMMAND_PAINT:
 	    _cairo_pattern_fini_snapshot (&command->paint.source.base);
diff --git a/src/cairo-surface-wrapper.c b/src/cairo-surface-wrapper.c
index f970e7d..ae594dc 100644
--- a/src/cairo-surface-wrapper.c
+++ b/src/cairo-surface-wrapper.c
@@ -113,11 +113,9 @@ _cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper,
 							&wrapper->target->device_transform);
 	    if (unlikely (status))
 		goto FINISH;
-	} else {
-	    _cairo_clip_init_copy (&clip_copy, clip);
-	}
 
-	dev_clip = &clip_copy;
+	    dev_clip = &clip_copy;
+	}
 
 	_copy_transformed_pattern (&source_copy.base, source, &wrapper->target->device_transform_inverse);
 	source = &source_copy.base;
@@ -156,12 +154,9 @@ _cairo_surface_wrapper_mask (cairo_surface_wrapper_t *wrapper,
 	    if (unlikely (status))
 		goto FINISH;
 
-	} else {
-	    _cairo_clip_init_copy (&clip_copy, clip);
+	    dev_clip = &clip_copy;
 	}
 
-	dev_clip = &clip_copy;
-
 	_copy_transformed_pattern (&source_copy.base, source, &wrapper->target->device_transform_inverse);
 	source = &source_copy.base;
 
@@ -422,11 +417,12 @@ _cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
 	int i;
 
 	if (clip != NULL) {
-	    dev_clip = &clip_copy;
 	    status = _cairo_clip_init_copy_transformed (&clip_copy, clip,
 							&wrapper->target->device_transform);
 	    if (unlikely (status))
 		goto FINISH;
+
+	    dev_clip = &clip_copy;
 	}
 
 	dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));


More information about the cairo-commit mailing list