diff options
-rw-r--r-- | pixman/pixman-image.c | 96 | ||||
-rw-r--r-- | pixman/pixman-private.h | 4 | ||||
-rw-r--r-- | pixman/pixman.c | 7 |
3 files changed, 45 insertions, 62 deletions
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c index ff0fbbb..1014e64 100644 --- a/pixman/pixman-image.c +++ b/pixman/pixman-image.c @@ -298,6 +298,9 @@ compute_image_info (pixman_image_t *image) if (image->type == SOLID) { code = PIXMAN_solid; + + if (image->solid.color.alpha == 0xffff) + flags |= FAST_PATH_IS_OPAQUE; } else if (image->common.type == BITS) { @@ -317,10 +320,48 @@ compute_image_info (pixman_image_t *image) flags |= FAST_PATH_SIMPLE_REPEAT; } } + + if (image->common.repeat != PIXMAN_REPEAT_NONE && + !PIXMAN_FORMAT_A (image->bits.format)) + { + flags |= FAST_PATH_IS_OPAQUE; + } } else { code = PIXMAN_unknown; + + if (image->type == LINEAR || image->type == RADIAL) + { + if (image->common.repeat != PIXMAN_REPEAT_NONE) + { + int i; + + flags |= FAST_PATH_IS_OPAQUE; + + for (i = 0; i < image->gradient.n_stops; ++i) + { + if (image->gradient.stops[i].color.alpha != 0xffff) + { + flags &= ~FAST_PATH_IS_OPAQUE; + break; + } + } + } + } + } + + /* Both alpha maps and convolution filters can introduce + * non-opaqueness in otherwise opaque images. Also + * an image with component alpha turned on is only opaque + * if all channels are opaque, so we simply turn it off + * unconditionally for those images. + */ + if (image->common.alpha_map || + image->common.filter == PIXMAN_FILTER_CONVOLUTION || + image->common.component_alpha) + { + flags &= ~FAST_PATH_IS_OPAQUE; } image->common.flags = flags; @@ -628,58 +669,3 @@ _pixman_image_get_solid (pixman_image_t * image, return result; } - -pixman_bool_t -_pixman_image_is_opaque (pixman_image_t *image) -{ - int i; - - if (image->common.alpha_map) - return FALSE; - - switch (image->type) - { - case BITS: - if (image->common.repeat == PIXMAN_REPEAT_NONE) - return FALSE; - - if (PIXMAN_FORMAT_A (image->bits.format)) - return FALSE; - break; - - case LINEAR: - case RADIAL: - if (image->common.repeat == PIXMAN_REPEAT_NONE) - return FALSE; - - for (i = 0; i < image->gradient.n_stops; ++i) - { - if (image->gradient.stops[i].color.alpha != 0xffff) - return FALSE; - } - break; - - case CONICAL: - /* Conical gradients always have a transparent border */ - return FALSE; - break; - - case SOLID: - if (image->solid.color.alpha != 0xffff) - return FALSE; - break; - - default: - return FALSE; - break; - } - - /* Convolution filters can introduce translucency if the sum of the - * weights is lower than 1. - */ - if (image->common.filter == PIXMAN_FILTER_CONVOLUTION) - return FALSE; - - return TRUE; -} - diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index 1ad452a..d08440e 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -284,9 +284,6 @@ _pixman_image_reset_clip_region (pixman_image_t *image); void _pixman_image_validate (pixman_image_t *image); -pixman_bool_t -_pixman_image_is_opaque (pixman_image_t *image); - uint32_t _pixman_image_get_solid (pixman_image_t * image, pixman_format_code_t format); @@ -579,6 +576,7 @@ _pixman_choose_implementation (void); #define FAST_PATH_SCALE_TRANSFORM (1 << 10) #define FAST_PATH_NEAREST_FILTER (1 << 11) #define FAST_PATH_SIMPLE_REPEAT (1 << 12) +#define FAST_PATH_IS_OPAQUE (1 << 13) #define _FAST_PATH_STANDARD_FLAGS \ (FAST_PATH_ID_TRANSFORM | \ diff --git a/pixman/pixman.c b/pixman/pixman.c index e1bef17..905c7b2 100644 --- a/pixman/pixman.c +++ b/pixman/pixman.c @@ -88,14 +88,13 @@ pixman_optimize_operator (pixman_op_t op, pixman_bool_t is_source_opaque; pixman_bool_t is_dest_opaque; const optimized_operator_info_t *info = pixman_operator_can_be_optimized (op); - if (!info || mask_image) return op; - is_source_opaque = _pixman_image_is_opaque (src_image); - is_dest_opaque = _pixman_image_is_opaque (dst_image); + is_source_opaque = src_image->common.flags & FAST_PATH_IS_OPAQUE; + is_dest_opaque = dst_image->common.flags & FAST_PATH_IS_OPAQUE; - if (is_source_opaque == FALSE && is_dest_opaque == FALSE) + if (!is_source_opaque && !is_dest_opaque) return op; if (is_source_opaque && is_dest_opaque) |