Bug 552537. Cache the CGImageRef that we create for a CGBitmapContext so that we can take advantage of Quartz caching optimizations. r=jrmuizel

This commit is contained in:
Robert O'Callahan 2010-06-01 11:19:45 +12:00
Родитель dbb9e6fc16
Коммит 37a34ca51d
2 изменённых файлов: 39 добавлений и 3 удалений

Просмотреть файл

@ -54,6 +54,14 @@ typedef struct cairo_quartz_surface {
cairo_surface_t *imageSurfaceEquiv;
cairo_surface_clipper_t clipper;
/**
* If non-null, this is a CGImage representing the contents of the surface.
* We clear this out before any painting into the surface, so that we
* don't force a copy to be created.
*/
CGImageRef bitmapContextImage;
cairo_rectangle_int_t extents;
} cairo_quartz_surface_t;

Просмотреть файл

@ -1139,9 +1139,14 @@ _cairo_surface_to_cgimage (cairo_surface_t *target,
}
if (_cairo_quartz_is_cgcontext_bitmap_context (surface->cgContext)) {
*image_out = CGBitmapContextCreateImage (surface->cgContext);
if (*image_out)
return CAIRO_STATUS_SUCCESS;
if (!surface->bitmapContextImage) {
surface->bitmapContextImage =
CGBitmapContextCreateImage (surface->cgContext);
}
if (surface->bitmapContextImage) {
*image_out = CGImageRetain (surface->bitmapContextImage);
return CAIRO_STATUS_SUCCESS;
}
}
}
@ -1593,6 +1598,19 @@ _cairo_quartz_setup_radial_source (cairo_quartz_surface_t *surface,
state->action = DO_SHADING;
}
/**
* Call this before any operation that can modify the contents of a
* cairo_quartz_surface_t.
*/
static void
_cairo_quartz_surface_will_change (cairo_quartz_surface_t *surface)
{
if (surface->bitmapContextImage) {
CGImageRelease (surface->bitmapContextImage);
surface->bitmapContextImage = NULL;
}
}
/**
* Sets up internal state to be used to draw the source mask, stored in
* cairo_quartz_state_t. Guarantees to call CGContextSaveGState on
@ -1614,6 +1632,8 @@ _cairo_quartz_setup_state (cairo_quartz_surface_t *surface,
state.shading = NULL;
state.pattern = NULL;
_cairo_quartz_surface_will_change (surface);
// Save before we change the pattern, colorspace, etc. so that
// we can restore and make sure that quartz releases our
// pattern (which may be stack allocated)
@ -1941,6 +1961,11 @@ _cairo_quartz_surface_finish (void *abstract_surface)
surface->cgContext = NULL;
if (surface->bitmapContextImage) {
CGImageRelease (surface->bitmapContextImage);
surface->bitmapContextImage = NULL;
}
if (surface->imageSurfaceEquiv) {
cairo_surface_destroy (surface->imageSurfaceEquiv);
surface->imageSurfaceEquiv = NULL;
@ -2011,6 +2036,8 @@ _cairo_quartz_surface_acquire_dest_image (void *abstract_surface,
ND((stderr, "%p _cairo_quartz_surface_acquire_dest_image\n", surface));
_cairo_quartz_surface_will_change (surface);
status = _cairo_quartz_get_image (surface, image_out);
if (status)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -2944,6 +2971,7 @@ _cairo_quartz_surface_create_internal (CGContextRef cgContext,
surface->imageData = NULL;
surface->imageSurfaceEquiv = NULL;
surface->bitmapContextImage = NULL;
return surface;
}