1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/cairo/quartz-cache-CGImageRef.patch Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,173 @@ 1.4 +changeset: 42954:7881873b2b5d 1.5 +user: Robert O'Callahan <robert@ocallahan.org> 1.6 +date: Tue Jun 01 11:19:45 2010 +1200 1.7 +summary: Bug 552537. Cache the CGImageRef that we create for a CGBitmapContext so that we can take advantage of Quartz caching optimizations. r=jrmuizel 1.8 + 1.9 +diff --git a/gfx/cairo/cairo/src/cairo-quartz-private.h b/gfx/cairo/cairo/src/cairo-quartz-private.h 1.10 +--- a/gfx/cairo/cairo/src/cairo-quartz-private.h 1.11 ++++ b/gfx/cairo/cairo/src/cairo-quartz-private.h 1.12 +@@ -49,16 +49,24 @@ typedef struct cairo_quartz_surface { 1.13 + 1.14 + CGContextRef cgContext; 1.15 + CGAffineTransform cgContextBaseCTM; 1.16 + 1.17 + void *imageData; 1.18 + cairo_surface_t *imageSurfaceEquiv; 1.19 + 1.20 + cairo_surface_clipper_t clipper; 1.21 ++ 1.22 ++ /** 1.23 ++ * If non-null, this is a CGImage representing the contents of the surface. 1.24 ++ * We clear this out before any painting into the surface, so that we 1.25 ++ * don't force a copy to be created. 1.26 ++ */ 1.27 ++ CGImageRef bitmapContextImage; 1.28 ++ 1.29 + cairo_rectangle_int_t extents; 1.30 + } cairo_quartz_surface_t; 1.31 + 1.32 + typedef struct cairo_quartz_image_surface { 1.33 + cairo_surface_t base; 1.34 + 1.35 + cairo_rectangle_int_t extents; 1.36 + 1.37 +diff --git a/gfx/cairo/cairo/src/cairo-quartz-surface.c b/gfx/cairo/cairo/src/cairo-quartz-surface.c 1.38 +--- a/gfx/cairo/cairo/src/cairo-quartz-surface.c 1.39 ++++ b/gfx/cairo/cairo/src/cairo-quartz-surface.c 1.40 +@@ -1134,19 +1134,24 @@ _cairo_surface_to_cgimage (cairo_surface 1.41 + if (stype == CAIRO_SURFACE_TYPE_QUARTZ) { 1.42 + cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) source; 1.43 + if (IS_EMPTY(surface)) { 1.44 + *image_out = NULL; 1.45 + return CAIRO_STATUS_SUCCESS; 1.46 + } 1.47 + 1.48 + if (_cairo_quartz_is_cgcontext_bitmap_context (surface->cgContext)) { 1.49 +- *image_out = CGBitmapContextCreateImage (surface->cgContext); 1.50 +- if (*image_out) 1.51 +- return CAIRO_STATUS_SUCCESS; 1.52 ++ if (!surface->bitmapContextImage) { 1.53 ++ surface->bitmapContextImage = 1.54 ++ CGBitmapContextCreateImage (surface->cgContext); 1.55 ++ } 1.56 ++ if (surface->bitmapContextImage) { 1.57 ++ *image_out = CGImageRetain (surface->bitmapContextImage); 1.58 ++ return CAIRO_STATUS_SUCCESS; 1.59 ++ } 1.60 + } 1.61 + } 1.62 + 1.63 + if (stype != CAIRO_SURFACE_TYPE_IMAGE) { 1.64 + status = _cairo_surface_acquire_source_image (source, 1.65 + &isurf, &image_extra); 1.66 + if (status) 1.67 + return status; 1.68 +@@ -1589,16 +1594,29 @@ _cairo_quartz_setup_radial_source (cairo 1.69 + 1.70 + CGColorSpaceRelease(rgb); 1.71 + CGFunctionRelease(gradFunc); 1.72 + 1.73 + state->action = DO_SHADING; 1.74 + } 1.75 + 1.76 + /** 1.77 ++ * Call this before any operation that can modify the contents of a 1.78 ++ * cairo_quartz_surface_t. 1.79 ++ */ 1.80 ++static void 1.81 ++_cairo_quartz_surface_will_change (cairo_quartz_surface_t *surface) 1.82 ++{ 1.83 ++ if (surface->bitmapContextImage) { 1.84 ++ CGImageRelease (surface->bitmapContextImage); 1.85 ++ surface->bitmapContextImage = NULL; 1.86 ++ } 1.87 ++} 1.88 ++ 1.89 ++/** 1.90 + * Sets up internal state to be used to draw the source mask, stored in 1.91 + * cairo_quartz_state_t. Guarantees to call CGContextSaveGState on 1.92 + * surface->cgContext. 1.93 + */ 1.94 + static cairo_quartz_drawing_state_t 1.95 + _cairo_quartz_setup_state (cairo_quartz_surface_t *surface, 1.96 + const cairo_pattern_t *source, 1.97 + cairo_operator_t op, 1.98 +@@ -1609,16 +1627,18 @@ _cairo_quartz_setup_state (cairo_quartz_ 1.99 + cairo_status_t status; 1.100 + 1.101 + state.context = context; 1.102 + state.image = NULL; 1.103 + state.imageSurface = NULL; 1.104 + state.shading = NULL; 1.105 + state.pattern = NULL; 1.106 + 1.107 ++ _cairo_quartz_surface_will_change (surface); 1.108 ++ 1.109 + // Save before we change the pattern, colorspace, etc. so that 1.110 + // we can restore and make sure that quartz releases our 1.111 + // pattern (which may be stack allocated) 1.112 + CGContextSaveGState(context); 1.113 + 1.114 + CGContextSetInterpolationQuality (context, _cairo_quartz_filter_to_quartz (source->filter)); 1.115 + 1.116 + status = _cairo_quartz_surface_set_cairo_operator (surface, op); 1.117 +@@ -1936,16 +1956,21 @@ _cairo_quartz_surface_finish (void *abst 1.118 + /* Restore our saved gstate that we use to reset clipping */ 1.119 + CGContextRestoreGState (surface->cgContext); 1.120 + _cairo_surface_clipper_reset (&surface->clipper); 1.121 + 1.122 + CGContextRelease (surface->cgContext); 1.123 + 1.124 + surface->cgContext = NULL; 1.125 + 1.126 ++ if (surface->bitmapContextImage) { 1.127 ++ CGImageRelease (surface->bitmapContextImage); 1.128 ++ surface->bitmapContextImage = NULL; 1.129 ++ } 1.130 ++ 1.131 + if (surface->imageSurfaceEquiv) { 1.132 + cairo_surface_destroy (surface->imageSurfaceEquiv); 1.133 + surface->imageSurfaceEquiv = NULL; 1.134 + } 1.135 + 1.136 + if (surface->imageData) { 1.137 + free (surface->imageData); 1.138 + surface->imageData = NULL; 1.139 +@@ -2006,16 +2031,18 @@ _cairo_quartz_surface_acquire_dest_image 1.140 + cairo_rectangle_int_t *image_rect, 1.141 + void **image_extra) 1.142 + { 1.143 + cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; 1.144 + cairo_int_status_t status; 1.145 + 1.146 + ND((stderr, "%p _cairo_quartz_surface_acquire_dest_image\n", surface)); 1.147 + 1.148 ++ _cairo_quartz_surface_will_change (surface); 1.149 ++ 1.150 + status = _cairo_quartz_get_image (surface, image_out); 1.151 + if (status) 1.152 + return _cairo_error (CAIRO_STATUS_NO_MEMORY); 1.153 + 1.154 + *image_rect = surface->extents; 1.155 + *image_extra = NULL; 1.156 + 1.157 + return CAIRO_STATUS_SUCCESS; 1.158 +@@ -2939,16 +2966,17 @@ _cairo_quartz_surface_create_internal (C 1.159 + */ 1.160 + CGContextSaveGState (cgContext); 1.161 + 1.162 + surface->cgContext = cgContext; 1.163 + surface->cgContextBaseCTM = CGContextGetCTM (cgContext); 1.164 + 1.165 + surface->imageData = NULL; 1.166 + surface->imageSurfaceEquiv = NULL; 1.167 ++ surface->bitmapContextImage = NULL; 1.168 + 1.169 + return surface; 1.170 + } 1.171 + 1.172 + /** 1.173 + * cairo_quartz_surface_create_for_cg_context 1.174 + * @cgContext: the existing CGContext for which to create the surface 1.175 + * @width: width of the surface, in pixels 1.176 +