diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-04-27 12:39:40 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-04-27 14:10:50 +0100 |
commit | 7eb33099d34234dcccb8f96caba94b38fa385f16 (patch) | |
tree | 60dc97ad4280107987751a09ca7a85d5eb724ca2 /src/cairo-analysis-surface.c | |
parent | 455b4de1fc6be05f985b43c2f8f83eeed2b2a191 (diff) | |
download | cairo-7eb33099d34234dcccb8f96caba94b38fa385f16.tar.gz |
snapshot: Perform the cow under a mutex
In order to prevent a race between concurrent destroy and use in another
thread, we need to acquire a reference to the snapshot->target under a
mutex. Whilst we hold that reference, it prevents the internal destroy
mechanism from freeing the memory we are using (if we have a pointer to
the original surface) and the client drops their final reference.
Oh boy, talk about opening a can of worms...
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/cairo-analysis-surface.c')
-rw-r--r-- | src/cairo-analysis-surface.c | 12 |
1 files changed, 3 insertions, 9 deletions
diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c index 5583f251e..8516094c2 100644 --- a/src/cairo-analysis-surface.c +++ b/src/cairo-analysis-surface.c @@ -171,11 +171,7 @@ _analyze_recording_surface_pattern (cairo_analysis_surface_t *surface, cairo_matrix_multiply (&tmp->ctm, &p2d, &surface->ctm); tmp->has_ctm = ! _cairo_matrix_is_identity (&tmp->ctm); - if (_cairo_surface_is_snapshot (source)) - source = _cairo_surface_snapshot_get_target (source); - if (_cairo_surface_is_subsurface (source)) - source = _cairo_surface_subsurface_get_target (source); - + source = _cairo_surface_get_source (source, NULL); status = _cairo_recording_surface_replay_and_create_regions (source, &tmp->base); analysis_status = tmp->has_unsupported ? CAIRO_INT_STATUS_IMAGE_FALLBACK : CAIRO_INT_STATUS_SUCCESS; @@ -412,8 +408,7 @@ _cairo_analysis_surface_mask (void *abstract_surface, if (source->type == CAIRO_PATTERN_TYPE_SURFACE) { cairo_surface_t *src_surface = ((cairo_surface_pattern_t *)source)->surface; - if (_cairo_surface_is_snapshot (src_surface)) - src_surface = _cairo_surface_snapshot_get_target (src_surface); + src_surface = _cairo_surface_get_source (src_surface, NULL); if (_cairo_surface_is_recording (src_surface)) { backend_source_status = _analyze_recording_surface_pattern (surface, source); @@ -424,8 +419,7 @@ _cairo_analysis_surface_mask (void *abstract_surface, if (mask->type == CAIRO_PATTERN_TYPE_SURFACE) { cairo_surface_t *mask_surface = ((cairo_surface_pattern_t *)mask)->surface; - if (_cairo_surface_is_snapshot (mask_surface)) - mask_surface = _cairo_surface_snapshot_get_target (mask_surface); + mask_surface = _cairo_surface_get_source (mask_surface, NULL); if (_cairo_surface_is_recording (mask_surface)) { backend_mask_status = _analyze_recording_surface_pattern (surface, mask); |