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.

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

mercurial