summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-12-31 10:54:43 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2014-12-31 11:01:45 +0000
commit028d286e611d46755bb3d1e9932805de2ec35765 (patch)
treefc4884b009335163e91798e398cb11e8b8742bdd
parent4a225fca5f121c31ddaa0af80a13bf95a7f21a5b (diff)
downloadcairo-028d286e611d46755bb3d1e9932805de2ec35765.tar.gz
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@src.gnome.org> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=87898 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/cairo-xlib-source.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/src/cairo-xlib-source.c b/src/cairo-xlib-source.c
index 81cc028e8..1591f5874 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);