summaryrefslogtreecommitdiff
path: root/src/cairo-quartz-surface.c
diff options
context:
space:
mode:
authorJohn Ralls <jralls@ceridwen.us>2020-11-30 15:13:41 -0800
committerJohn Ralls <jralls@ceridwen.us>2020-12-03 10:59:04 -0800
commitb5e84a97833e8e1d082f4409383b09f9827ada09 (patch)
tree0724f46ef256a14e91b3defb92f0fda932810c71 /src/cairo-quartz-surface.c
parent32c12c617a2551e1238e52c570bd5c42a6c0cbef (diff)
downloadcairo-b5e84a97833e8e1d082f4409383b09f9827ada09.tar.gz
Quartz: Ensure that image data and surface are available to draw.
Snapshot the cairo_surface_t and copy the image data to provide to the CGDataProvider so that it is independent of the cairo_surface_t's lifetime. Closes https://gitlab.freedesktop.org/cairo/cairo/-/issues/420
Diffstat (limited to 'src/cairo-quartz-surface.c')
-rw-r--r--src/cairo-quartz-surface.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index f697d157e..2fa376bb8 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -784,6 +784,7 @@ typedef struct {
cairo_surface_t *surface;
cairo_image_surface_t *image_out;
void *image_extra;
+ void *image_data;
} quartz_source_image_t;
static void
@@ -791,6 +792,8 @@ DataProviderReleaseCallback (void *info, const void *data, size_t size)
{
quartz_source_image_t *source_img = info;
_cairo_surface_release_source_image (source_img->surface, source_img->image_out, source_img->image_extra);
+ cairo_surface_destroy (source_img->surface);
+ free (source_img->image_data);
free (source_img);
}
@@ -830,7 +833,7 @@ _cairo_surface_to_cgimage (cairo_surface_t *source,
if (unlikely (source_img == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
- source_img->surface = source;
+ source_img->surface = _cairo_surface_snapshot (source);
if (source->type == CAIRO_SURFACE_TYPE_RECORDING) {
image_surface = (cairo_image_surface_t *)
@@ -853,7 +856,7 @@ _cairo_surface_to_cgimage (cairo_surface_t *source,
}
source_img->image_out = image_surface;
- source_img->image_extra = NULL;
+ source_img->image_data = NULL;
cairo_matrix_init_identity (matrix);
}
@@ -867,6 +870,12 @@ _cairo_surface_to_cgimage (cairo_surface_t *source,
}
}
+ source_img->image_data = malloc (source_img->image_out->height * source_img->image_out->stride);
+ if (unlikely (!source_img->image_data))
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+ memcpy (source_img->image_data, source_img->image_out->data,
+ source_img->image_out->height * source_img->image_out->stride);
if (source_img->image_out->width == 0 || source_img->image_out->height == 0) {
*image_out = NULL;
DataProviderReleaseCallback (source_img,
@@ -877,7 +886,7 @@ _cairo_surface_to_cgimage (cairo_surface_t *source,
source_img->image_out->width,
source_img->image_out->height,
source_img->image_out->stride,
- source_img->image_out->data,
+ source_img->image_data,
TRUE,
NULL,
DataProviderReleaseCallback,