summaryrefslogtreecommitdiffstats
path: root/gfx/cairo/quartz-cglayers.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/cairo/quartz-cglayers.patch')
-rw-r--r--gfx/cairo/quartz-cglayers.patch715
1 files changed, 0 insertions, 715 deletions
diff --git a/gfx/cairo/quartz-cglayers.patch b/gfx/cairo/quartz-cglayers.patch
deleted file mode 100644
index bb3d44d9e..000000000
--- a/gfx/cairo/quartz-cglayers.patch
+++ /dev/null
@@ -1,715 +0,0 @@
-changeset: 42959:e1964291f8ff
-user: Robert O'Callahan <robert@ocallahan.org>
-date: Tue Jun 01 11:33:23 2010 +1200
-summary: Bug 568189. Implement CGLayer-backed cairo-quartz surfaces. r=jrmuizel
-
-diff --git a/gfx/cairo/cairo/src/cairo-quartz-private.h b/gfx/cairo/cairo/src/cairo-quartz-private.h
---- a/gfx/cairo/cairo/src/cairo-quartz-private.h
-+++ b/gfx/cairo/cairo/src/cairo-quartz-private.h
-@@ -57,16 +57,21 @@ typedef struct cairo_quartz_surface {
-
- /**
- * If non-null, this is a CGImage representing the contents of the surface.
- * We clear this out before any painting into the surface, so that we
- * don't force a copy to be created.
- */
- CGImageRef bitmapContextImage;
-
-+ /**
-+ * If non-null, this is the CGLayer for the surface.
-+ */
-+ CGLayerRef cgLayer;
-+
- cairo_rectangle_int_t extents;
- } cairo_quartz_surface_t;
-
- typedef struct cairo_quartz_image_surface {
- cairo_surface_t base;
-
- cairo_rectangle_int_t extents;
-
-diff --git a/gfx/cairo/cairo/src/cairo-quartz-surface.c b/gfx/cairo/cairo/src/cairo-quartz-surface.c
---- a/gfx/cairo/cairo/src/cairo-quartz-surface.c
-+++ b/gfx/cairo/cairo/src/cairo-quartz-surface.c
-@@ -1110,18 +1110,17 @@ CreateRepeatingRadialGradientFunction (c
- static void
- DataProviderReleaseCallback (void *info, const void *data, size_t size)
- {
- cairo_surface_t *surface = (cairo_surface_t *) info;
- cairo_surface_destroy (surface);
- }
-
- static cairo_status_t
--_cairo_surface_to_cgimage (cairo_surface_t *target,
-- cairo_surface_t *source,
-+_cairo_surface_to_cgimage (cairo_surface_t *source,
- CGImageRef *image_out)
- {
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
- cairo_surface_type_t stype = cairo_surface_get_type (source);
- cairo_image_surface_t *isurf;
- CGImageRef image;
- void *image_extra;
-
-@@ -1267,17 +1266,17 @@ _cairo_quartz_cairo_repeating_surface_pa
- return CAIRO_INT_STATUS_UNSUPPORTED;
-
- spattern = (cairo_surface_pattern_t *) apattern;
- pat_surf = spattern->surface;
-
- is_bounded = _cairo_surface_get_extents (pat_surf, &extents);
- assert (is_bounded);
-
-- status = _cairo_surface_to_cgimage ((cairo_surface_t*) dest, pat_surf, &image);
-+ status = _cairo_surface_to_cgimage (pat_surf, &image);
- if (status)
- return status;
- if (image == NULL)
- return CAIRO_INT_STATUS_NOTHING_TO_DO;
-
- info = malloc(sizeof(SurfacePatternDrawInfo));
- if (!info)
- return CAIRO_STATUS_NO_MEMORY;
-@@ -1339,33 +1338,39 @@ _cairo_quartz_cairo_repeating_surface_pa
- }
-
- typedef enum {
- DO_SOLID,
- DO_SHADING,
- DO_PATTERN,
- DO_IMAGE,
- DO_TILED_IMAGE,
-+ DO_LAYER,
- DO_UNSUPPORTED,
- DO_NOTHING
- } cairo_quartz_action_t;
-
- /* State used during a drawing operation. */
- typedef struct {
- CGContextRef context;
- cairo_quartz_action_t action;
-
-- // Used with DO_SHADING, DO_IMAGE and DO_TILED_IMAGE
-+ // Used with DO_SHADING, DO_IMAGE, DO_TILED_IMAGE and DO_LAYER
- CGAffineTransform transform;
-
- // Used with DO_IMAGE and DO_TILED_IMAGE
- CGImageRef image;
- cairo_surface_t *imageSurface;
-+
-+ // Used with DO_IMAGE, DO_TILED_IMAGE and DO_LAYER
- CGRect imageRect;
-
-+ // Used with DO_LAYER
-+ CGLayerRef layer;
-+
- // Used with DO_SHADING
- CGShadingRef shading;
-
- // Used with DO_PATTERN
- CGPatternRef pattern;
- } cairo_quartz_drawing_state_t;
-
- static void
-@@ -1423,17 +1428,17 @@ _cairo_quartz_setup_fallback_source (cai
- _cairo_pattern_transform (&pattern.base,
- &fallback->device_transform_inverse);
- status = _cairo_surface_paint (fallback,
- CAIRO_OPERATOR_SOURCE,
- &pattern.base, NULL);
- }
- #endif
-
-- status = _cairo_surface_to_cgimage (&surface->base, fallback, &img);
-+ status = _cairo_surface_to_cgimage (fallback, &img);
- if (status) {
- state->action = DO_UNSUPPORTED;
- return;
- }
- if (img == NULL) {
- state->action = DO_NOTHING;
- return;
- }
-@@ -1624,16 +1629,17 @@ _cairo_quartz_setup_state (cairo_quartz_
- {
- CGContextRef context = surface->cgContext;
- cairo_quartz_drawing_state_t state;
- cairo_status_t status;
-
- state.context = context;
- state.image = NULL;
- state.imageSurface = NULL;
-+ state.layer = NULL;
- state.shading = NULL;
- state.pattern = NULL;
-
- _cairo_quartz_surface_will_change (surface);
-
- // Save before we change the pattern, colorspace, etc. so that
- // we can restore and make sure that quartz releases our
- // pattern (which may be stack allocated)
-@@ -1689,33 +1695,43 @@ _cairo_quartz_setup_state (cairo_quartz_
- CGImageRef img;
- cairo_matrix_t m = spat->base.matrix;
- cairo_rectangle_int_t extents;
- CGAffineTransform xform;
- CGRect srcRect;
- cairo_fixed_t fw, fh;
- cairo_bool_t is_bounded;
-
-- status = _cairo_surface_to_cgimage ((cairo_surface_t *) surface, pat_surf, &img);
-+ cairo_matrix_invert(&m);
-+ _cairo_quartz_cairo_matrix_to_quartz (&m, &state.transform);
-+
-+ if (cairo_surface_get_type (pat_surf) == CAIRO_SURFACE_TYPE_QUARTZ) {
-+ cairo_quartz_surface_t *quartz_surf = (cairo_quartz_surface_t *) pat_surf;
-+ if (quartz_surf->cgLayer && source->extend == CAIRO_EXTEND_NONE) {
-+ state.imageRect = CGRectMake (0, 0, quartz_surf->extents.width, quartz_surf->extents.height);
-+ state.layer = quartz_surf->cgLayer;
-+ state.action = DO_LAYER;
-+ return state;
-+ }
-+ }
-+
-+ status = _cairo_surface_to_cgimage (pat_surf, &img);
- if (status) {
- state.action = DO_UNSUPPORTED;
- return state;
- }
- if (img == NULL) {
- state.action = DO_NOTHING;
- return state;
- }
-
- CGContextSetRGBFillColor (surface->cgContext, 0, 0, 0, 1);
-
- state.image = img;
-
-- cairo_matrix_invert(&m);
-- _cairo_quartz_cairo_matrix_to_quartz (&m, &state.transform);
--
- is_bounded = _cairo_surface_get_extents (pat_surf, &extents);
- assert (is_bounded);
-
- if (source->extend == CAIRO_EXTEND_NONE) {
- state.imageRect = CGRectMake (0, 0, extents.width, extents.height);
- state.action = DO_IMAGE;
- return state;
- }
-@@ -1820,33 +1836,48 @@ _cairo_quartz_teardown_state (cairo_quar
-
- CGContextRestoreGState(state->context);
- }
-
-
- static void
- _cairo_quartz_draw_image (cairo_quartz_drawing_state_t *state, cairo_operator_t op)
- {
-- assert (state && state->image && (state->action == DO_IMAGE || state->action == DO_TILED_IMAGE));
-+ assert (state &&
-+ ((state->image && (state->action == DO_IMAGE || state->action == DO_TILED_IMAGE)) ||
-+ (state->layer && state->action == DO_LAYER)));
-
- CGContextConcatCTM (state->context, state->transform);
- CGContextTranslateCTM (state->context, 0, state->imageRect.size.height);
- CGContextScaleCTM (state->context, 1, -1);
-
-- if (state->action == DO_IMAGE) {
-- CGContextDrawImage (state->context, state->imageRect, state->image);
-+ if (state->action == DO_TILED_IMAGE) {
-+ CGContextDrawTiledImagePtr (state->context, state->imageRect, state->image);
-+ /* no need to worry about unbounded operators, since tiled images
-+ fill the entire clip region */
-+ } else {
-+ if (state->action == DO_LAYER) {
-+ /* Note that according to Apple docs it's completely legal
-+ * to draw a CGLayer to any CGContext, even one it wasn't
-+ * created for.
-+ */
-+ CGContextDrawLayerAtPoint (state->context, state->imageRect.origin,
-+ state->layer);
-+ } else {
-+ CGContextDrawImage (state->context, state->imageRect, state->image);
-+ }
-+
- if (!_cairo_operator_bounded_by_source (op)) {
- CGContextBeginPath (state->context);
- CGContextAddRect (state->context, state->imageRect);
- CGContextAddRect (state->context, CGContextGetClipBoundingBox (state->context));
- CGContextSetRGBFillColor (state->context, 0, 0, 0, 0);
- CGContextEOFillPath (state->context);
- }
-- } else
-- CGContextDrawTiledImagePtr (state->context, state->imageRect, state->image);
-+ }
- }
-
-
- /*
- * get source/dest image implementation
- */
-
- /* Read the image from the surface's front buffer */
-@@ -1971,95 +2002,153 @@ _cairo_quartz_surface_finish (void *abst
- surface->imageSurfaceEquiv = NULL;
- }
-
- if (surface->imageData) {
- free (surface->imageData);
- surface->imageData = NULL;
- }
-
-+ if (surface->cgLayer) {
-+ CGLayerRelease (surface->cgLayer);
-+ }
-+
- return CAIRO_STATUS_SUCCESS;
- }
-
- static cairo_status_t
--_cairo_quartz_surface_acquire_source_image (void *abstract_surface,
-- cairo_image_surface_t **image_out,
-- void **image_extra)
-+_cairo_quartz_surface_acquire_image (void *abstract_surface,
-+ cairo_image_surface_t **image_out,
-+ void **image_extra)
- {
- cairo_int_status_t status;
- cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
-
-- //ND((stderr, "%p _cairo_quartz_surface_acquire_source_image\n", surface));
-+ *image_extra = NULL;
-+
-+ /* ND((stderr, "%p _cairo_quartz_surface_acquire_image\n", surface)); */
-
- status = _cairo_quartz_get_image (surface, image_out);
-+
-+ if (status == CAIRO_INT_STATUS_UNSUPPORTED && surface->cgLayer) {
-+ /* copy the layer into a Quartz bitmap context so we can get the data */
-+ cairo_surface_t *tmp =
-+ cairo_quartz_surface_create (CAIRO_CONTENT_COLOR_ALPHA,
-+ surface->extents.width,
-+ surface->extents.height);
-+ cairo_quartz_surface_t *tmp_surface = (cairo_quartz_surface_t *) tmp;
-+
-+ /* if surface creation failed, we won't have a Quartz surface here */
-+ if (cairo_surface_get_type (tmp) == CAIRO_SURFACE_TYPE_QUARTZ &&
-+ tmp_surface->imageSurfaceEquiv) {
-+ CGContextSaveGState (tmp_surface->cgContext);
-+ CGContextTranslateCTM (tmp_surface->cgContext, 0, surface->extents.height);
-+ CGContextScaleCTM (tmp_surface->cgContext, 1, -1);
-+ /* Note that according to Apple docs it's completely legal
-+ * to draw a CGLayer to any CGContext, even one it wasn't
-+ * created for.
-+ */
-+ CGContextDrawLayerAtPoint (tmp_surface->cgContext,
-+ CGPointMake (0.0, 0.0),
-+ surface->cgLayer);
-+ CGContextRestoreGState (tmp_surface->cgContext);
-+
-+ *image_out = (cairo_image_surface_t*)
-+ cairo_surface_reference(tmp_surface->imageSurfaceEquiv);
-+ *image_extra = tmp;
-+ } else {
-+ cairo_surface_destroy (tmp);
-+ }
-+ }
-+
- if (status)
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
-- *image_extra = NULL;
--
- return CAIRO_STATUS_SUCCESS;
- }
-
- static void
- _cairo_quartz_surface_release_source_image (void *abstract_surface,
- cairo_image_surface_t *image,
- void *image_extra)
- {
- cairo_surface_destroy ((cairo_surface_t *) image);
-+
-+ if (image_extra) {
-+ cairo_surface_destroy ((cairo_surface_t *) image_extra);
-+ }
- }
-
-
- static cairo_status_t
- _cairo_quartz_surface_acquire_dest_image (void *abstract_surface,
- cairo_rectangle_int_t *interest_rect,
- cairo_image_surface_t **image_out,
- cairo_rectangle_int_t *image_rect,
- void **image_extra)
- {
- cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
-- cairo_int_status_t status;
-
- ND((stderr, "%p _cairo_quartz_surface_acquire_dest_image\n", surface));
-
-- _cairo_quartz_surface_will_change (surface);
--
-- status = _cairo_quartz_get_image (surface, image_out);
-- if (status)
-- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
--
- *image_rect = surface->extents;
- *image_extra = NULL;
-
-- return CAIRO_STATUS_SUCCESS;
-+ _cairo_quartz_surface_will_change (surface);
-+
-+ return _cairo_quartz_surface_acquire_image (abstract_surface,
-+ image_out, image_extra);
- }
-
- static void
- _cairo_quartz_surface_release_dest_image (void *abstract_surface,
- cairo_rectangle_int_t *interest_rect,
- cairo_image_surface_t *image,
- cairo_rectangle_int_t *image_rect,
- void *image_extra)
- {
-- //cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
--
-- //ND((stderr, "%p _cairo_quartz_surface_release_dest_image\n", surface));
-+ /* ND((stderr, "%p _cairo_quartz_surface_release_dest_image\n", surface)); */
-
- cairo_surface_destroy ((cairo_surface_t *) image);
-+
-+ if (image_extra) {
-+ /* we need to write the data from the temp surface back to the layer */
-+ cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
-+ cairo_quartz_surface_t *tmp_surface = (cairo_quartz_surface_t *) image_extra;
-+ CGImageRef img;
-+ cairo_status_t status = _cairo_surface_to_cgimage (&tmp_surface->base, &img);
-+ if (status) {
-+ cairo_surface_destroy (&tmp_surface->base);
-+ return;
-+ }
-+
-+ CGContextSaveGState (surface->cgContext);
-+ CGContextTranslateCTM (surface->cgContext, 0, surface->extents.height);
-+ CGContextScaleCTM (surface->cgContext, 1, -1);
-+ CGContextDrawImage (surface->cgContext,
-+ CGRectMake (0.0, 0.0, surface->extents.width, surface->extents.height),
-+ img);
-+ CGContextRestoreGState (surface->cgContext);
-+
-+ cairo_surface_destroy (&tmp_surface->base);
-+ }
- }
-
- static cairo_surface_t *
- _cairo_quartz_surface_create_similar (void *abstract_surface,
- cairo_content_t content,
- int width,
- int height)
- {
-- /*cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;*/
--
-+ cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
- cairo_format_t format;
-
-+ if (surface->cgLayer)
-+ return cairo_quartz_surface_create_cg_layer (abstract_surface, width, height);
-+
- if (content == CAIRO_CONTENT_COLOR_ALPHA)
- format = CAIRO_FORMAT_ARGB32;
- else if (content == CAIRO_CONTENT_COLOR)
- format = CAIRO_FORMAT_RGB24;
- else if (content == CAIRO_CONTENT_ALPHA)
- format = CAIRO_FORMAT_A8;
- else
- return NULL;
-@@ -2113,17 +2202,17 @@ _cairo_quartz_surface_clone_similar (voi
- _cairo_quartz_surface_create_internal (NULL, CAIRO_CONTENT_COLOR_ALPHA,
- qsurf->extents.width, qsurf->extents.height);
- *clone_offset_x = 0;
- *clone_offset_y = 0;
- return CAIRO_STATUS_SUCCESS;
- }
- }
-
-- status = _cairo_surface_to_cgimage ((cairo_surface_t*) abstract_surface, src, &quartz_image);
-+ status = _cairo_surface_to_cgimage (src, &quartz_image);
- if (status)
- return CAIRO_INT_STATUS_UNSUPPORTED;
-
- new_format = CAIRO_FORMAT_ARGB32; /* assumed */
- if (_cairo_surface_is_image (src)) {
- new_format = ((cairo_image_surface_t *) src)->format;
- }
-
-@@ -2194,17 +2283,18 @@ _cairo_quartz_surface_paint (void *abstr
- if (state.action == DO_SOLID || state.action == DO_PATTERN) {
- CGContextFillRect (state.context, CGRectMake(surface->extents.x,
- surface->extents.y,
- surface->extents.width,
- surface->extents.height));
- } else if (state.action == DO_SHADING) {
- CGContextConcatCTM (state.context, state.transform);
- CGContextDrawShading (state.context, state.shading);
-- } else if (state.action == DO_IMAGE || state.action == DO_TILED_IMAGE) {
-+ } else if (state.action == DO_IMAGE || state.action == DO_TILED_IMAGE ||
-+ state.action == DO_LAYER) {
- _cairo_quartz_draw_image (&state, op);
- } else if (state.action != DO_NOTHING) {
- rv = CAIRO_INT_STATUS_UNSUPPORTED;
- }
-
- _cairo_quartz_teardown_state (&state);
-
- ND((stderr, "-- paint\n"));
-@@ -2291,17 +2381,18 @@ _cairo_quartz_surface_fill (void *abstra
- // with the shading
- if (fill_rule == CAIRO_FILL_RULE_WINDING)
- CGContextClip (state.context);
- else
- CGContextEOClip (state.context);
-
- CGContextConcatCTM (state.context, state.transform);
- CGContextDrawShading (state.context, state.shading);
-- } else if (state.action == DO_IMAGE || state.action == DO_TILED_IMAGE) {
-+ } else if (state.action == DO_IMAGE || state.action == DO_TILED_IMAGE ||
-+ state.action == DO_LAYER) {
- if (fill_rule == CAIRO_FILL_RULE_WINDING)
- CGContextClip (state.context);
- else
- CGContextEOClip (state.context);
-
- _cairo_quartz_draw_image (&state, op);
- } else if (state.action != DO_NOTHING) {
- rv = CAIRO_INT_STATUS_UNSUPPORTED;
-@@ -2416,17 +2507,18 @@ _cairo_quartz_surface_stroke (void *abst
- if (rv)
- goto BAIL;
-
- if (!_cairo_operator_bounded_by_mask (op) && CGContextCopyPathPtr)
- path_for_unbounded = CGContextCopyPathPtr (state.context);
-
- if (state.action == DO_SOLID || state.action == DO_PATTERN) {
- CGContextStrokePath (state.context);
-- } else if (state.action == DO_IMAGE || state.action == DO_TILED_IMAGE) {
-+ } else if (state.action == DO_IMAGE || state.action == DO_TILED_IMAGE ||
-+ state.action == DO_LAYER) {
- CGContextReplacePathWithStrokedPath (state.context);
- CGContextClip (state.context);
-
- CGContextSetCTM (state.context, origCTM);
- _cairo_quartz_draw_image (&state, op);
- } else if (state.action == DO_SHADING) {
- CGContextReplacePathWithStrokedPath (state.context);
- CGContextClip (state.context);
-@@ -2511,17 +2603,18 @@ _cairo_quartz_surface_show_glyphs (void
- &glyph_extents, NULL);
- state = _cairo_quartz_setup_state (surface, source, op, &glyph_extents);
- } else {
- state = _cairo_quartz_setup_state (surface, source, op, NULL);
- }
-
- if (state.action == DO_SOLID || state.action == DO_PATTERN) {
- CGContextSetTextDrawingMode (state.context, kCGTextFill);
-- } else if (state.action == DO_IMAGE || state.action == DO_TILED_IMAGE || state.action == DO_SHADING) {
-+ } else if (state.action == DO_IMAGE || state.action == DO_TILED_IMAGE ||
-+ state.action == DO_SHADING || state.action == DO_LAYER) {
- CGContextSetTextDrawingMode (state.context, kCGTextClip);
- isClipping = TRUE;
- } else {
- if (state.action != DO_NOTHING)
- rv = CAIRO_INT_STATUS_UNSUPPORTED;
- goto BAIL;
- }
-
-@@ -2622,17 +2715,18 @@ _cairo_quartz_surface_show_glyphs (void
-
- CGContextShowGlyphsWithAdvances (state.context,
- cg_glyphs,
- cg_advances,
- num_glyphs);
-
- CGContextSetCTM (state.context, ctm);
-
-- if (state.action == DO_IMAGE || state.action == DO_TILED_IMAGE) {
-+ if (state.action == DO_IMAGE || state.action == DO_TILED_IMAGE ||
-+ state.action == DO_LAYER) {
- _cairo_quartz_draw_image (&state, op);
- } else if (state.action == DO_SHADING) {
- CGContextConcatCTM (state.context, state.transform);
- CGContextDrawShading (state.context, state.shading);
- }
-
- BAIL:
- if (didForceFontSmoothing)
-@@ -2679,17 +2773,17 @@ _cairo_quartz_surface_mask_with_surface
- cairo_clip_t *clip)
- {
- CGRect rect;
- CGImageRef img;
- cairo_surface_t *pat_surf = mask->surface;
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
- CGAffineTransform ctm, mask_matrix;
-
-- status = _cairo_surface_to_cgimage ((cairo_surface_t *) surface, pat_surf, &img);
-+ status = _cairo_surface_to_cgimage (pat_surf, &img);
- if (status)
- return status;
- if (img == NULL) {
- if (!_cairo_operator_bounded_by_mask (op))
- CGContextClearRect (surface->cgContext, CGContextGetClipBoundingBox (surface->cgContext));
- return CAIRO_STATUS_SUCCESS;
- }
-
-@@ -2869,17 +2963,17 @@ _cairo_quartz_surface_clipper_intersect_
- }
-
- // XXXtodo implement show_page; need to figure out how to handle begin/end
-
- static const struct _cairo_surface_backend cairo_quartz_surface_backend = {
- CAIRO_SURFACE_TYPE_QUARTZ,
- _cairo_quartz_surface_create_similar,
- _cairo_quartz_surface_finish,
-- _cairo_quartz_surface_acquire_source_image,
-+ _cairo_quartz_surface_acquire_image,
- _cairo_quartz_surface_release_source_image,
- _cairo_quartz_surface_acquire_dest_image,
- _cairo_quartz_surface_release_dest_image,
- _cairo_quartz_surface_clone_similar,
- NULL, /* composite */
- NULL, /* fill_rectangles */
- NULL, /* composite_trapezoids */
- NULL, /* create_span_renderer */
-@@ -2950,16 +3044,17 @@ _cairo_quartz_surface_create_internal (C
- CGContextSaveGState (cgContext);
-
- surface->cgContext = cgContext;
- surface->cgContextBaseCTM = CGContextGetCTM (cgContext);
-
- surface->imageData = NULL;
- surface->imageSurfaceEquiv = NULL;
- surface->bitmapContextImage = NULL;
-+ surface->cgLayer = NULL;
-
- return surface;
- }
-
- /**
- * cairo_quartz_surface_create_for_cg_context
- * @cgContext: the existing CGContext for which to create the surface
- * @width: width of the surface, in pixels
-@@ -3002,16 +3097,88 @@ cairo_quartz_surface_create_for_cg_conte
- // create_internal will have set an error
- return (cairo_surface_t*) surf;
- }
-
- return (cairo_surface_t *) surf;
- }
-
- /**
-+ * cairo_quartz_cglayer_surface_create_similar
-+ * @surface: The returned surface can be efficiently drawn into this
-+ * destination surface (if tiling is not used)."
-+ * @width: width of the surface, in pixels
-+ * @height: height of the surface, in pixels
-+ *
-+ * Creates a Quartz surface backed by a CGLayer, if the given surface
-+ * is a Quartz surface; the CGLayer is created to match the surface's
-+ * Quartz context. Otherwise just calls cairo_surface_create_similar
-+ * with CAIRO_CONTENT_COLOR_ALPHA.
-+ * The returned surface can be efficiently blitted to the given surface,
-+ * but tiling and 'extend' modes other than NONE are not so efficient.
-+ *
-+ * Return value: the newly created surface.
-+ *
-+ * Since: 1.10
-+ **/
-+cairo_surface_t *
-+cairo_quartz_surface_create_cg_layer (cairo_surface_t *surface,
-+ unsigned int width,
-+ unsigned int height)
-+{
-+ cairo_quartz_surface_t *surf;
-+ CGLayerRef layer;
-+ CGContextRef ctx;
-+ CGContextRef cgContext;
-+
-+ cgContext = cairo_quartz_surface_get_cg_context (surface);
-+ if (!cgContext)
-+ return cairo_surface_create_similar (surface, CAIRO_CONTENT_COLOR_ALPHA,
-+ width, height);
-+
-+ if (!_cairo_quartz_verify_surface_size(width, height))
-+ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
-+
-+ /* If we pass zero width or height into CGLayerCreateWithContext below,
-+ * it will fail.
-+ */
-+ if (width == 0 || height == 0) {
-+ return (cairo_surface_t*)
-+ _cairo_quartz_surface_create_internal (NULL, CAIRO_CONTENT_COLOR_ALPHA,
-+ width, height);
-+ }
-+
-+ layer = CGLayerCreateWithContext (cgContext,
-+ CGSizeMake (width, height),
-+ NULL);
-+ if (!layer)
-+ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
-+
-+ ctx = CGLayerGetContext (layer);
-+ /* Flip it when we draw into it, so that when we finally composite it
-+ * to a flipped target, the directions match and Quartz will optimize
-+ * the composition properly
-+ */
-+ CGContextTranslateCTM (ctx, 0, height);
-+ CGContextScaleCTM (ctx, 1, -1);
-+
-+ CGContextRetain (ctx);
-+ surf = _cairo_quartz_surface_create_internal (ctx, CAIRO_CONTENT_COLOR_ALPHA,
-+ width, height);
-+ if (surf->base.status) {
-+ CGLayerRelease (layer);
-+ // create_internal will have set an error
-+ return (cairo_surface_t*) surf;
-+ }
-+ surf->cgLayer = layer;
-+
-+ return (cairo_surface_t *) surf;
-+}
-+
-+/**
- * cairo_quartz_surface_create
- * @format: format of pixels in the surface to create
- * @width: width of the surface, in pixels
- * @height: height of the surface, in pixels
- *
- * Creates a Quartz surface backed by a CGBitmap. The surface is
- * created using the Device RGB (or Device Gray, for A8) color space.
- * All Cairo operations, including those that require software
-diff --git a/gfx/cairo/cairo/src/cairo-quartz.h b/gfx/cairo/cairo/src/cairo-quartz.h
---- a/gfx/cairo/cairo/src/cairo-quartz.h
-+++ b/gfx/cairo/cairo/src/cairo-quartz.h
-@@ -45,16 +45,21 @@
- CAIRO_BEGIN_DECLS
-
- cairo_public cairo_surface_t *
- cairo_quartz_surface_create (cairo_format_t format,
- unsigned int width,
- unsigned int height);
-
- cairo_public cairo_surface_t *
-+cairo_quartz_surface_create_cg_layer (cairo_surface_t *surface,
-+ unsigned int width,
-+ unsigned int height);
-+
-+cairo_public cairo_surface_t *
- cairo_quartz_surface_create_for_cg_context (CGContextRef cgContext,
- unsigned int width,
- unsigned int height);
-
- cairo_public CGContextRef
- cairo_quartz_surface_get_cg_context (cairo_surface_t *surface);
-
- cairo_public CGContextRef
-