diff options
author | Adrian Johnson <ajohnson@redneon.com> | 2016-06-19 14:08:55 +0930 |
---|---|---|
committer | Adrian Johnson <ajohnson@redneon.com> | 2016-06-19 14:08:55 +0930 |
commit | eb808aa6250f1a44a2f5efff5c9ad3df44cb4d1d (patch) | |
tree | bfeffed4301623b55c84e85d232133b8dd188435 | |
parent | 113ba5f3fa48f9f826b86ff9198ce0d35144eea4 (diff) |
image: only cache analyzed transparency/color for snapshot surfaces
https://lists.cairographics.org/archives/cairo/2016-June/027429.html
-rw-r--r-- | src/cairo-image-surface.c | 86 |
1 files changed, 54 insertions, 32 deletions
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c index 13d6272a8..1571c549a 100644 --- a/src/cairo-image-surface.c +++ b/src/cairo-image-surface.c @@ -52,6 +52,7 @@ #include "cairo-recording-surface-private.h" #include "cairo-region-private.h" #include "cairo-scaled-font-private.h" +#include "cairo-surface-snapshot-inline.h" #include "cairo-surface-snapshot-private.h" #include "cairo-surface-subsurface-private.h" @@ -1153,79 +1154,87 @@ cleanup: return (cairo_image_surface_t *) _cairo_surface_create_in_error (status); } -cairo_image_transparency_t -_cairo_image_analyze_transparency (cairo_image_surface_t *image) +static cairo_image_transparency_t +_cairo_image_compute_transparency (cairo_image_surface_t *image) { int x, y; - - if (image->transparency != CAIRO_IMAGE_UNKNOWN) - return image->transparency; + cairo_image_transparency_t transparency; if ((image->base.content & CAIRO_CONTENT_ALPHA) == 0) - return image->transparency = CAIRO_IMAGE_IS_OPAQUE; + return CAIRO_IMAGE_IS_OPAQUE; if (image->base.is_clear) - return image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA; + return CAIRO_IMAGE_HAS_BILEVEL_ALPHA; if ((image->base.content & CAIRO_CONTENT_COLOR) == 0) { if (image->format == CAIRO_FORMAT_A1) { - return image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA; + return CAIRO_IMAGE_HAS_BILEVEL_ALPHA; } else if (image->format == CAIRO_FORMAT_A8) { for (y = 0; y < image->height; y++) { uint8_t *alpha = (uint8_t *) (image->data + y * image->stride); for (x = 0; x < image->width; x++, alpha++) { if (*alpha > 0 && *alpha < 255) - return image->transparency = CAIRO_IMAGE_HAS_ALPHA; + return CAIRO_IMAGE_HAS_ALPHA; } } - return image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA; + return CAIRO_IMAGE_HAS_BILEVEL_ALPHA; } else { - return image->transparency = CAIRO_IMAGE_HAS_ALPHA; + return CAIRO_IMAGE_HAS_ALPHA; } } if (image->format == CAIRO_FORMAT_RGB16_565) { - image->transparency = CAIRO_IMAGE_IS_OPAQUE; return CAIRO_IMAGE_IS_OPAQUE; } if (image->format != CAIRO_FORMAT_ARGB32) - return image->transparency = CAIRO_IMAGE_HAS_ALPHA; + return CAIRO_IMAGE_HAS_ALPHA; - image->transparency = CAIRO_IMAGE_IS_OPAQUE; + transparency = CAIRO_IMAGE_IS_OPAQUE; for (y = 0; y < image->height; y++) { uint32_t *pixel = (uint32_t *) (image->data + y * image->stride); for (x = 0; x < image->width; x++, pixel++) { int a = (*pixel & 0xff000000) >> 24; if (a > 0 && a < 255) { - return image->transparency = CAIRO_IMAGE_HAS_ALPHA; + return CAIRO_IMAGE_HAS_ALPHA; } else if (a == 0) { - image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA; + transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA; } } } - return image->transparency; + return transparency; } -cairo_image_color_t -_cairo_image_analyze_color (cairo_image_surface_t *image) +cairo_image_transparency_t +_cairo_image_analyze_transparency (cairo_image_surface_t *image) { - int x, y; + if (_cairo_surface_is_snapshot (&image->base)) { + if (image->transparency == CAIRO_IMAGE_UNKNOWN) + image->transparency = _cairo_image_compute_transparency (image); - if (image->color != CAIRO_IMAGE_UNKNOWN_COLOR) - return image->color; + return image->transparency; + } + + return _cairo_image_compute_transparency (image); +} + +static cairo_image_color_t +_cairo_image_compute_color (cairo_image_surface_t *image) +{ + int x, y; + cairo_image_color_t color; if (image->format == CAIRO_FORMAT_A1) - return image->color = CAIRO_IMAGE_IS_MONOCHROME; + return CAIRO_IMAGE_IS_MONOCHROME; if (image->format == CAIRO_FORMAT_A8) - return image->color = CAIRO_IMAGE_IS_GRAYSCALE; + return CAIRO_IMAGE_IS_GRAYSCALE; if (image->format == CAIRO_FORMAT_ARGB32) { - image->color = CAIRO_IMAGE_IS_MONOCHROME; + color = CAIRO_IMAGE_IS_MONOCHROME; for (y = 0; y < image->height; y++) { uint32_t *pixel = (uint32_t *) (image->data + y * image->stride); @@ -1242,16 +1251,16 @@ _cairo_image_analyze_color (cairo_image_surface_t *image) b = (b * 255 + a / 2) / a; } if (!(r == g && g == b)) - return image->color = CAIRO_IMAGE_IS_COLOR; + return CAIRO_IMAGE_IS_COLOR; else if (r > 0 && r < 255) - image->color = CAIRO_IMAGE_IS_GRAYSCALE; + color = CAIRO_IMAGE_IS_GRAYSCALE; } } - return image->color; + return color; } if (image->format == CAIRO_FORMAT_RGB24) { - image->color = CAIRO_IMAGE_IS_MONOCHROME; + color = CAIRO_IMAGE_IS_MONOCHROME; for (y = 0; y < image->height; y++) { uint32_t *pixel = (uint32_t *) (image->data + y * image->stride); @@ -1260,15 +1269,28 @@ _cairo_image_analyze_color (cairo_image_surface_t *image) int g = (*pixel & 0x0000ff00) >> 8; int b = (*pixel & 0x000000ff); if (!(r == g && g == b)) - return image->color = CAIRO_IMAGE_IS_COLOR; + return CAIRO_IMAGE_IS_COLOR; else if (r > 0 && r < 255) - image->color = CAIRO_IMAGE_IS_GRAYSCALE; + color = CAIRO_IMAGE_IS_GRAYSCALE; } } + return color; + } + + return CAIRO_IMAGE_IS_COLOR; +} + +cairo_image_color_t +_cairo_image_analyze_color (cairo_image_surface_t *image) +{ + if (_cairo_surface_is_snapshot (&image->base)) { + if (image->color == CAIRO_IMAGE_UNKNOWN_COLOR) + image->color = _cairo_image_compute_color (image); + return image->color; } - return image->color = CAIRO_IMAGE_IS_COLOR; + return _cairo_image_compute_color (image); } cairo_image_surface_t * |