[cairo-commit] 3 commits - src/cairo-recording-surface.c src/cairo-recording-surface-private.h test/subsurface-modify-parent.c

Chris Wilson ickle at kemper.freedesktop.org
Wed May 5 01:25:37 PDT 2010


 src/cairo-recording-surface-private.h |    1 -
 src/cairo-recording-surface.c         |   29 ++++++++++++++++++-----------
 test/subsurface-modify-parent.c       |    1 +
 3 files changed, 19 insertions(+), 12 deletions(-)

New commits:
commit fba4cf1d94b3ab676e0b62ae3574bf1ee4e69de0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed May 5 09:22:03 2010 +0100

    recording: Mark an empty recording surface as clear.

diff --git a/src/cairo-recording-surface.c b/src/cairo-recording-surface.c
index d3866ed..ab78dca 100644
--- a/src/cairo-recording-surface.c
+++ b/src/cairo-recording-surface.c
@@ -156,6 +156,7 @@ cairo_recording_surface_create (cairo_content_t		 content,
     _cairo_array_init (&recording_surface->commands, sizeof (cairo_command_t *));
 
     recording_surface->replay_start_idx = 0;
+    recording_surface->base.is_clear = TRUE;
 
     return &recording_surface->base;
 }
@@ -628,6 +629,8 @@ _cairo_recording_surface_snapshot (void *abstract_other)
      * need to handle reference cycles during subsurface and self-copy.
      */
     recording_surface->replay_start_idx = 0;
+    recording_surface->base.is_clear = TRUE;
+
     _cairo_array_init (&recording_surface->commands, sizeof (cairo_command_t *));
     status = _cairo_recording_surface_replay (&other->base, &recording_surface->base);
     if (unlikely (status)) {
@@ -807,6 +810,9 @@ _cairo_recording_surface_replay_internal (cairo_surface_t	     *surface,
     if (unlikely (surface->finished))
 	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
 
+    if (surface->is_clear)
+	return CAIRO_STATUS_SUCCESS;
+
     assert (_cairo_surface_is_recording (surface));
 
     _cairo_surface_wrapper_init (&wrapper, target);
commit e5329805394c94c915e43a0040b51d5019b4a90e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed May 5 09:17:51 2010 +0100

    recording: Avoid refcycles by always copying the command array.
    
    Short-term solution to avoid the refleaks and to make the test suite
    happy. A more elegant solution would be to track the references and
    avoid the substantial memory overhead of copying the recording surfaces.
    
    Thanks to Benjamin Otte for pointing out the solution to avoiding
    refcycles.

diff --git a/src/cairo-recording-surface-private.h b/src/cairo-recording-surface-private.h
index 4a5c9db..4ec5f88 100644
--- a/src/cairo-recording-surface-private.h
+++ b/src/cairo-recording-surface-private.h
@@ -132,7 +132,6 @@ typedef struct _cairo_recording_surface {
     cairo_clip_t clip;
 
     cairo_array_t commands;
-    cairo_surface_t *commands_owner;
 
     int replay_start_idx;
 } cairo_recording_surface_t;
diff --git a/src/cairo-recording-surface.c b/src/cairo-recording-surface.c
index 5a2f804..d3866ed 100644
--- a/src/cairo-recording-surface.c
+++ b/src/cairo-recording-surface.c
@@ -154,7 +154,6 @@ cairo_recording_surface_create (cairo_content_t		 content,
     }
 
     _cairo_array_init (&recording_surface->commands, sizeof (cairo_command_t *));
-    recording_surface->commands_owner = NULL;
 
     recording_surface->replay_start_idx = 0;
 
@@ -182,12 +181,6 @@ _cairo_recording_surface_finish (void *abstract_surface)
     cairo_command_t **elements;
     int i, num_elements;
 
-    if (recording_surface->commands_owner) {
-	cairo_surface_destroy (recording_surface->commands_owner);
-	_cairo_clip_fini (&recording_surface->clip);
-	return CAIRO_STATUS_SUCCESS;
-    }
-
     num_elements = recording_surface->commands.num_elements;
     elements = _cairo_array_index (&recording_surface->commands, 0);
     for (i = 0; i < num_elements; i++) {
@@ -613,6 +606,7 @@ _cairo_recording_surface_snapshot (void *abstract_other)
 {
     cairo_recording_surface_t *other = abstract_other;
     cairo_recording_surface_t *recording_surface;
+    cairo_status_t status;
 
     recording_surface = malloc (sizeof (cairo_recording_surface_t));
     if (unlikely (recording_surface == NULL))
@@ -626,14 +620,21 @@ _cairo_recording_surface_snapshot (void *abstract_other)
     recording_surface->extents_pixels = other->extents_pixels;
     recording_surface->extents = other->extents;
     recording_surface->unbounded = other->unbounded;
-    recording_surface->replay_start_idx = other->replay_start_idx;
     recording_surface->content = other->content;
 
-    _cairo_array_init_snapshot (&recording_surface->commands, &other->commands);
-    recording_surface->commands_owner = cairo_surface_reference (&other->base);
-
     _cairo_clip_init_copy (&recording_surface->clip, &other->clip);
 
+    /* XXX We should in theory be able to reuse the original array, but we
+     * need to handle reference cycles during subsurface and self-copy.
+     */
+    recording_surface->replay_start_idx = 0;
+    _cairo_array_init (&recording_surface->commands, sizeof (cairo_command_t *));
+    status = _cairo_recording_surface_replay (&other->base, &recording_surface->base);
+    if (unlikely (status)) {
+	cairo_surface_destroy (&recording_surface->base);
+	return _cairo_surface_create_in_error (status);
+    }
+
     return &recording_surface->base;
 }
 
commit 6a06e0ef7b534355d0f3b4885159ffc37dbc3867
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed May 5 09:17:33 2010 +0100

    test/subsurface-modify-parent: Free region.
    
    Minor refleak.

diff --git a/test/subsurface-modify-parent.c b/test/subsurface-modify-parent.c
index 3dab2dd..3d542d5 100644
--- a/test/subsurface-modify-parent.c
+++ b/test/subsurface-modify-parent.c
@@ -59,6 +59,7 @@ draw (cairo_t *cr, int width, int height)
     cairo_fill (cr);
 
     cairo_set_source_surface (cr, region, 20, 20);
+    cairo_surface_destroy (region);
 
     /* repeat the pattern around the outside, but do not overwrite...*/
     cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);


More information about the cairo-commit mailing list