[cairo] [PATCH] Implement CGColorSpaceRef support for cairo quartz image

Fred Bca fredbca21 at gmail.com
Mon Aug 26 12:54:35 UTC 2019


Hi,

on recent versions of Mac OS, Core Graphics performs color space
conversions when the source and target are using different color
spaces (which typically happens when drawing an image loaded from file
on screen). The performance hit is not negligible (around 20%).

Here is a patch proposal to let you specify an optional color space
when creating a quartz image surface (instead of using the default RGB
color space). It changes the API, but it could also be implemented as
a separate function if preferred. The patch also ensures that the
appropriate color space is used when creating a similar surface.

Would you please consider incorporating this change to cairo?

Index: cairo-quartz-image.h
===================================================================
--- cairo-quartz-image.h (cairo 14.12)
+++ cairo-quartz-image.h (fix)
@@ -45,7 +45,7 @@
 CAIRO_BEGIN_DECLS

 cairo_public cairo_surface_t *
-cairo_quartz_image_surface_create (cairo_surface_t *image_surface);
+cairo_quartz_image_surface_create (cairo_surface_t
*image_surface,CGColorSpaceRef colorSpace);

 cairo_public cairo_surface_t *
 cairo_quartz_image_surface_get_image (cairo_surface_t *surface);
Index: cairo-quartz-image-surface.c
===================================================================
--- cairo-quartz-image-surface.c (cairo 14.12)
+++ cairo-quartz-image-surface.c (fix)
@@ -56,6 +56,15 @@
     cairo_surface_destroy (surface);
 }

+static CGColorSpaceRef
_cairo_quartz_image_surface_get_color_space(void *asurface)
+{
+    cairo_quartz_image_surface_t *surface =
(cairo_quartz_image_surface_t *) asurface;
+    CGColorSpaceRef colorSpace=NULL;
+    if(surface->image!=NULL)
+        colorSpace=CGImageGetColorSpace(surface->image);
+    return colorSpace;
+}
+
 static cairo_surface_t *
 _cairo_quartz_image_surface_create_similar (void *asurface,
      cairo_content_t content,
@@ -64,7 +73,7 @@
 {
     cairo_surface_t *isurf =
  _cairo_image_surface_create_with_content (content, width, height);
-    cairo_surface_t *result = cairo_quartz_image_surface_create (isurf);
+    cairo_surface_t *result = cairo_quartz_image_surface_create
(isurf,_cairo_quartz_image_surface_get_color_space(asurface));
     cairo_surface_destroy (isurf);

     return result;
@@ -77,7 +86,7 @@
    int height)
 {
     cairo_surface_t *isurf = cairo_image_surface_create (format,
width, height);
-    cairo_surface_t *result = cairo_quartz_image_surface_create (isurf);
+    cairo_surface_t *result = cairo_quartz_image_surface_create
(isurf,_cairo_quartz_image_surface_get_color_space(asurface));
     cairo_surface_destroy (isurf);

     return result;
@@ -147,10 +156,13 @@
     cairo_quartz_image_surface_t *surface =
(cairo_quartz_image_surface_t *) asurface;
     CGImageRef oldImage = surface->image;
     CGImageRef newImage = NULL;
-
+    CGColorSpaceRef colorSpace = NULL;
+
     if (flags)
  return CAIRO_STATUS_SUCCESS;

+    if(oldImage)
+        colorSpace=CGImageGetColorSpace(oldImage);
     /* XXX only flush if the image has been modified. */

     /* To be released by the ReleaseCallback */
@@ -162,7 +174,7 @@
  surface->imageSurface->stride,
  surface->imageSurface->data,
  TRUE,
- NULL,
+ colorSpace,
  DataProviderReleaseCallback,
  surface->imageSurface);

@@ -286,6 +298,7 @@
 /**
  * cairo_quartz_image_surface_create:
  * @image_surface: a cairo image surface to wrap with a quartz image surface
+ * @colorSpace: an optional CGColorSpaceRef to define the color space
used by the CGImageRef
  *
  * Creates a Quartz surface backed by a CGImageRef that references the
  * given image surface. The resulting surface can be rendered quickly
@@ -299,7 +312,7 @@
  * Since: 1.6
  **/
 cairo_surface_t *
-cairo_quartz_image_surface_create (cairo_surface_t *surface)
+cairo_quartz_image_surface_create (cairo_surface_t
*surface,CGColorSpaceRef colorSpace)
 {
     cairo_quartz_image_surface_t *qisurf;

@@ -349,7 +362,7 @@
        stride,
        data,
        TRUE,
-       NULL,
+       colorSpace,
        DataProviderReleaseCallback,
        image_surface);


More information about the cairo mailing list