[cairo-commit] src/cairo-xlib-source.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Dec 31 03:04:04 PST 2014


 src/cairo-xlib-source.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

New commits:
commit 028d286e611d46755bb3d1e9932805de2ec35765
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Dec 31 10:54:43 2014 +0000

    xlib: Bump reference count for recording surface replays
    
    The snapshot takes a reference to the target recording surface in order
    to enable it for use by multiple treads. In order to balance this, the
    other two sources of recording surface must also take a reference and
    for us to release that reference after the replay.
    
    Otherwise, we end up with a memory leak:
    
    ==1== 1,392 bytes in 3 blocks are definitely lost in loss record 1 of 7
    ==1==    at 0x4A06BCF: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==1==    by 0x4C7042D: _cairo_recording_surface_snapshot (cairo/src/cairo-recording-surface.c:1427)
    ==1==    by 0x4C842BE: _cairo_surface_snapshot_copy_on_write (cairo/src/cairo-surface-snapshot.c:189)
    ==1==    by 0x4C7E7E0: _cairo_surface_detach_snapshot (cairo/src/cairo-surface.c:348)
    ==1==    by 0x4C7E55B: _cairo_surface_detach_snapshots (cairo/src/cairo-surface.c:333)
    ==1==    by 0x4C7E55B: _cairo_surface_flush (cairo/src/cairo-surface.c:1545)
    ==1==    by 0x4C7E6CC: _cairo_surface_finish_snapshots (cairo/src/cairo-surface.c:1017)
    ==1==    by 0x4C7E6CC: cairo_surface_destroy (cairo/src/cairo-surface.c:961)
    ==1==    by 0x4C625A7: cairo_pattern_destroy (cairo/src/cairo-pattern.c:1131)
    ==1==    by 0x4C3FAC6: _cairo_gstate_fini (cairo/src/cairo-gstate.c:225)
    ==1==    by 0x4C3C68C: _cairo_default_context_fini (cairo/src/cairo-default-context.c:75)
    ==1==    by 0x4C3C708: _cairo_default_context_destroy (cairo/src/cairo-default-context.c:93)
    ==1==    by 0x43E576: record_get (cairo/test/record-extend.c:158)
    ==1==    by 0x43E576: record_replay (cairo/test/record-extend.c:173)
    ==1==    by 0x40E22D: cairo_test_for_target (cairo/test/cairo-test.c:929)
    ==1==    by 0x40E22D: _cairo_test_context_run_for_target (cairo/test/cairo-test.c:1532)
    ==1==    by 0x40B6C0: _cairo_test_runner_draw (cairo/test/cairo-test-runner.c:255)
    ==1==    by 0x40B6C0: main (cairo/test/cairo-test-runner.c:937)
    
    Reported-by: Massimo Valentini <mvalentini at src.gnome.org>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=87898
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-xlib-source.c b/src/cairo-xlib-source.c
index 81cc028..1591f58 100644
--- a/src/cairo-xlib-source.c
+++ b/src/cairo-xlib-source.c
@@ -869,11 +869,14 @@ recording_pattern_get_surface (const cairo_pattern_t *pattern)
     cairo_surface_t *surface;
 
     surface = ((const cairo_surface_pattern_t *) pattern)->surface;
+
     if (_cairo_surface_is_paginated (surface))
-	surface = _cairo_paginated_surface_get_recording (surface);
+	return cairo_surface_reference (_cairo_paginated_surface_get_recording (surface));
+
     if (_cairo_surface_is_snapshot (surface))
-	surface = _cairo_surface_snapshot_get_target (surface);
-    return surface;
+	return _cairo_surface_snapshot_get_target (surface);
+
+    return cairo_surface_reference (surface);
 }
 
 static cairo_surface_t *
@@ -885,6 +888,7 @@ record_source (cairo_xlib_surface_t *dst,
 	       int *src_x, int *src_y)
 {
     cairo_xlib_surface_t *src;
+    cairo_surface_t *recording;
     cairo_matrix_t matrix, m;
     cairo_status_t status;
     cairo_rectangle_int_t upload, limit;
@@ -911,9 +915,11 @@ record_source (cairo_xlib_surface_t *dst,
     }
 
     cairo_matrix_init_translate (&matrix, upload.x, upload.y);
-    status = _cairo_recording_surface_replay_with_clip (recording_pattern_get_surface (&pattern->base),
+    recording = recording_pattern_get_surface (&pattern->base),
+    status = _cairo_recording_surface_replay_with_clip (recording,
 							&matrix, &src->base,
 							NULL);
+    cairo_surface_destroy (recording);
     if (unlikely (status)) {
 	cairo_surface_destroy (&src->base);
 	return _cairo_surface_create_in_error (status);


More information about the cairo-commit mailing list