if (image->type == SOLID)
{
code = PIXMAN_solid;
+
+ if (image->solid.color.alpha == 0xffff)
+ flags |= FAST_PATH_IS_OPAQUE;
}
else if (image->common.type == BITS)
{
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;
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;
-}
-
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);
#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 | \
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)