[cairo-commit] src/cairo-image-surface.c

Adrian Johnson ajohnson at kemper.freedesktop.org
Sun Jun 19 04:46:51 UTC 2016


 src/cairo-image-surface.c |   86 ++++++++++++++++++++++++++++------------------
 1 file changed, 54 insertions(+), 32 deletions(-)

New commits:
commit eb808aa6250f1a44a2f5efff5c9ad3df44cb4d1d
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sun Jun 19 14:08:55 2016 +0930

    image: only cache analyzed transparency/color for snapshot surfaces
    
    https://lists.cairographics.org/archives/cairo/2016-June/027429.html

diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 13d6272..1571c54 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 *


More information about the cairo-commit mailing list