summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Johnson <ajohnson@redneon.com>2016-06-19 14:08:55 +0930
committerAdrian Johnson <ajohnson@redneon.com>2016-06-19 14:08:55 +0930
commiteb808aa6250f1a44a2f5efff5c9ad3df44cb4d1d (patch)
treebfeffed4301623b55c84e85d232133b8dd188435
parent113ba5f3fa48f9f826b86ff9198ce0d35144eea4 (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.c86
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 *