Eliminate _pixman_image_is_opaque() in favor of a new FAST_PATH_IS_OPAQUE flag
authorSøren Sandmann Pedersen <sandmann@redhat.com>
Fri, 18 Sep 2009 15:54:21 +0000 (11:54 -0400)
committerSøren Sandmann Pedersen <ssp@redhat.com>
Thu, 25 Feb 2010 04:20:27 +0000 (23:20 -0500)
The new FAST_PATH_IS_OPAQUE flag is computed along with the others in
_pixman_image_validate().

pixman/pixman-image.c
pixman/pixman-private.h
pixman/pixman.c

index ff0fbbb..1014e64 100644 (file)
@@ -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;
-}
-
index 1ad452a..d08440e 100644 (file)
@@ -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            |                               \
index e1bef17..905c7b2 100644 (file)
@@ -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)