Tue, 06 Jan 2015 21:39:09 +0100
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 |