summaryrefslogtreecommitdiff
path: root/src/cairo-analysis-surface.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-04-27 12:39:40 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2012-04-27 14:10:50 +0100
commit7eb33099d34234dcccb8f96caba94b38fa385f16 (patch)
tree60dc97ad4280107987751a09ca7a85d5eb724ca2 /src/cairo-analysis-surface.c
parent455b4de1fc6be05f985b43c2f8f83eeed2b2a191 (diff)
downloadcairo-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.c12
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);