gfx/cairo/quartz-cache-CGImageRef.patch

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 changeset: 42954:7881873b2b5d
michael@0 2 user: Robert O'Callahan <robert@ocallahan.org>
michael@0 3 date: Tue Jun 01 11:19:45 2010 +1200
michael@0 4 summary: Bug 552537. Cache the CGImageRef that we create for a CGBitmapContext so that we can take advantage of Quartz caching optimizations. r=jrmuizel
michael@0 5
michael@0 6 diff --git a/gfx/cairo/cairo/src/cairo-quartz-private.h b/gfx/cairo/cairo/src/cairo-quartz-private.h
michael@0 7 --- a/gfx/cairo/cairo/src/cairo-quartz-private.h
michael@0 8 +++ b/gfx/cairo/cairo/src/cairo-quartz-private.h
michael@0 9 @@ -49,16 +49,24 @@ typedef struct cairo_quartz_surface {
michael@0 10
michael@0 11 CGContextRef cgContext;
michael@0 12 CGAffineTransform cgContextBaseCTM;
michael@0 13
michael@0 14 void *imageData;
michael@0 15 cairo_surface_t *imageSurfaceEquiv;
michael@0 16
michael@0 17 cairo_surface_clipper_t clipper;
michael@0 18 +
michael@0 19 + /**
michael@0 20 + * If non-null, this is a CGImage representing the contents of the surface.
michael@0 21 + * We clear this out before any painting into the surface, so that we
michael@0 22 + * don't force a copy to be created.
michael@0 23 + */
michael@0 24 + CGImageRef bitmapContextImage;
michael@0 25 +
michael@0 26 cairo_rectangle_int_t extents;
michael@0 27 } cairo_quartz_surface_t;
michael@0 28
michael@0 29 typedef struct cairo_quartz_image_surface {
michael@0 30 cairo_surface_t base;
michael@0 31
michael@0 32 cairo_rectangle_int_t extents;
michael@0 33
michael@0 34 diff --git a/gfx/cairo/cairo/src/cairo-quartz-surface.c b/gfx/cairo/cairo/src/cairo-quartz-surface.c
michael@0 35 --- a/gfx/cairo/cairo/src/cairo-quartz-surface.c
michael@0 36 +++ b/gfx/cairo/cairo/src/cairo-quartz-surface.c
michael@0 37 @@ -1134,19 +1134,24 @@ _cairo_surface_to_cgimage (cairo_surface
michael@0 38 if (stype == CAIRO_SURFACE_TYPE_QUARTZ) {
michael@0 39 cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) source;
michael@0 40 if (IS_EMPTY(surface)) {
michael@0 41 *image_out = NULL;
michael@0 42 return CAIRO_STATUS_SUCCESS;
michael@0 43 }
michael@0 44
michael@0 45 if (_cairo_quartz_is_cgcontext_bitmap_context (surface->cgContext)) {
michael@0 46 - *image_out = CGBitmapContextCreateImage (surface->cgContext);
michael@0 47 - if (*image_out)
michael@0 48 - return CAIRO_STATUS_SUCCESS;
michael@0 49 + if (!surface->bitmapContextImage) {
michael@0 50 + surface->bitmapContextImage =
michael@0 51 + CGBitmapContextCreateImage (surface->cgContext);
michael@0 52 + }
michael@0 53 + if (surface->bitmapContextImage) {
michael@0 54 + *image_out = CGImageRetain (surface->bitmapContextImage);
michael@0 55 + return CAIRO_STATUS_SUCCESS;
michael@0 56 + }
michael@0 57 }
michael@0 58 }
michael@0 59
michael@0 60 if (stype != CAIRO_SURFACE_TYPE_IMAGE) {
michael@0 61 status = _cairo_surface_acquire_source_image (source,
michael@0 62 &isurf, &image_extra);
michael@0 63 if (status)
michael@0 64 return status;
michael@0 65 @@ -1589,16 +1594,29 @@ _cairo_quartz_setup_radial_source (cairo
michael@0 66
michael@0 67 CGColorSpaceRelease(rgb);
michael@0 68 CGFunctionRelease(gradFunc);
michael@0 69
michael@0 70 state->action = DO_SHADING;
michael@0 71 }
michael@0 72
michael@0 73 /**
michael@0 74 + * Call this before any operation that can modify the contents of a
michael@0 75 + * cairo_quartz_surface_t.
michael@0 76 + */
michael@0 77 +static void
michael@0 78 +_cairo_quartz_surface_will_change (cairo_quartz_surface_t *surface)
michael@0 79 +{
michael@0 80 + if (surface->bitmapContextImage) {
michael@0 81 + CGImageRelease (surface->bitmapContextImage);
michael@0 82 + surface->bitmapContextImage = NULL;
michael@0 83 + }
michael@0 84 +}
michael@0 85 +
michael@0 86 +/**
michael@0 87 * Sets up internal state to be used to draw the source mask, stored in
michael@0 88 * cairo_quartz_state_t. Guarantees to call CGContextSaveGState on
michael@0 89 * surface->cgContext.
michael@0 90 */
michael@0 91 static cairo_quartz_drawing_state_t
michael@0 92 _cairo_quartz_setup_state (cairo_quartz_surface_t *surface,
michael@0 93 const cairo_pattern_t *source,
michael@0 94 cairo_operator_t op,
michael@0 95 @@ -1609,16 +1627,18 @@ _cairo_quartz_setup_state (cairo_quartz_
michael@0 96 cairo_status_t status;
michael@0 97
michael@0 98 state.context = context;
michael@0 99 state.image = NULL;
michael@0 100 state.imageSurface = NULL;
michael@0 101 state.shading = NULL;
michael@0 102 state.pattern = NULL;
michael@0 103
michael@0 104 + _cairo_quartz_surface_will_change (surface);
michael@0 105 +
michael@0 106 // Save before we change the pattern, colorspace, etc. so that
michael@0 107 // we can restore and make sure that quartz releases our
michael@0 108 // pattern (which may be stack allocated)
michael@0 109 CGContextSaveGState(context);
michael@0 110
michael@0 111 CGContextSetInterpolationQuality (context, _cairo_quartz_filter_to_quartz (source->filter));
michael@0 112
michael@0 113 status = _cairo_quartz_surface_set_cairo_operator (surface, op);
michael@0 114 @@ -1936,16 +1956,21 @@ _cairo_quartz_surface_finish (void *abst
michael@0 115 /* Restore our saved gstate that we use to reset clipping */
michael@0 116 CGContextRestoreGState (surface->cgContext);
michael@0 117 _cairo_surface_clipper_reset (&surface->clipper);
michael@0 118
michael@0 119 CGContextRelease (surface->cgContext);
michael@0 120
michael@0 121 surface->cgContext = NULL;
michael@0 122
michael@0 123 + if (surface->bitmapContextImage) {
michael@0 124 + CGImageRelease (surface->bitmapContextImage);
michael@0 125 + surface->bitmapContextImage = NULL;
michael@0 126 + }
michael@0 127 +
michael@0 128 if (surface->imageSurfaceEquiv) {
michael@0 129 cairo_surface_destroy (surface->imageSurfaceEquiv);
michael@0 130 surface->imageSurfaceEquiv = NULL;
michael@0 131 }
michael@0 132
michael@0 133 if (surface->imageData) {
michael@0 134 free (surface->imageData);
michael@0 135 surface->imageData = NULL;
michael@0 136 @@ -2006,16 +2031,18 @@ _cairo_quartz_surface_acquire_dest_image
michael@0 137 cairo_rectangle_int_t *image_rect,
michael@0 138 void **image_extra)
michael@0 139 {
michael@0 140 cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
michael@0 141 cairo_int_status_t status;
michael@0 142
michael@0 143 ND((stderr, "%p _cairo_quartz_surface_acquire_dest_image\n", surface));
michael@0 144
michael@0 145 + _cairo_quartz_surface_will_change (surface);
michael@0 146 +
michael@0 147 status = _cairo_quartz_get_image (surface, image_out);
michael@0 148 if (status)
michael@0 149 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
michael@0 150
michael@0 151 *image_rect = surface->extents;
michael@0 152 *image_extra = NULL;
michael@0 153
michael@0 154 return CAIRO_STATUS_SUCCESS;
michael@0 155 @@ -2939,16 +2966,17 @@ _cairo_quartz_surface_create_internal (C
michael@0 156 */
michael@0 157 CGContextSaveGState (cgContext);
michael@0 158
michael@0 159 surface->cgContext = cgContext;
michael@0 160 surface->cgContextBaseCTM = CGContextGetCTM (cgContext);
michael@0 161
michael@0 162 surface->imageData = NULL;
michael@0 163 surface->imageSurfaceEquiv = NULL;
michael@0 164 + surface->bitmapContextImage = NULL;
michael@0 165
michael@0 166 return surface;
michael@0 167 }
michael@0 168
michael@0 169 /**
michael@0 170 * cairo_quartz_surface_create_for_cg_context
michael@0 171 * @cgContext: the existing CGContext for which to create the surface
michael@0 172 * @width: width of the surface, in pixels
michael@0 173

mercurial