Add direct-write optimization back
authorSøren Sandmann Pedersen <ssp@redhat.com>
Fri, 10 Dec 2010 21:55:55 +0000 (16:55 -0500)
committerSøren Sandmann Pedersen <ssp@redhat.com>
Tue, 18 Jan 2011 17:42:26 +0000 (12:42 -0500)
Introduce a new ITER_LOCALIZED_ALPHA flag that indicates that the
alpha value computed is used only for the alpha channel of the output;
it doesn't affect the RGB channels.

Then in pixman-bits-image.c, if a destination is either a8r8g8b8 or
x8r8g8b8 with localized alpha, the iterator will return a pointer
directly into the image.

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

index 983e23c..8d4e4f5 100644 (file)
@@ -1438,6 +1438,12 @@ dest_write_back_wide (pixman_iter_t *iter)
     iter->y++;
 }
 
+static void
+dest_write_back_direct (pixman_iter_t *iter)
+{
+    iter->buffer += iter->image->bits.rowstride;
+}
+
 void
 _pixman_bits_image_dest_iter_init (pixman_image_t *image,
                                   pixman_iter_t *iter,
@@ -1446,8 +1452,23 @@ _pixman_bits_image_dest_iter_init (pixman_image_t *image,
 {
     if (flags & ITER_NARROW)
     {
-       iter->get_scanline = dest_get_scanline_narrow;
-       iter->write_back = dest_write_back_narrow;
+       if (((image->common.flags &
+             (FAST_PATH_NO_ALPHA_MAP | FAST_PATH_NO_ACCESSORS)) ==
+            (FAST_PATH_NO_ALPHA_MAP | FAST_PATH_NO_ACCESSORS)) &&
+           (image->bits.format == PIXMAN_a8r8g8b8      ||
+            (image->bits.format == PIXMAN_x8r8g8b8     &&
+             (flags & ITER_LOCALIZED_ALPHA))))
+       {
+           iter->buffer = image->bits.bits + y * image->bits.rowstride + x;
+
+           iter->get_scanline = _pixman_iter_get_scanline_noop;
+           iter->write_back = dest_write_back_direct;
+       }
+       else
+       {
+           iter->get_scanline = dest_get_scanline_narrow;
+           iter->write_back = dest_write_back_narrow;
+       }
     }
     else
     {
index e2f1dc3..e7a7283 100644 (file)
@@ -130,7 +130,7 @@ general_composite_rect  (pixman_implementation_t *imp,
     pixman_iter_t src_iter, mask_iter, dest_iter;
     pixman_combine_32_func_t compose;
     pixman_bool_t component_alpha;
-    iter_flags_t narrow;
+    iter_flags_t narrow, dest_flags;
     int Bpp;
     int i;
 
@@ -167,9 +167,24 @@ general_composite_rect  (pixman_implementation_t *imp,
                                          mask_x, mask_y, width, height,
                                          mask_buffer, narrow);
 
+    if (op == PIXMAN_OP_CLEAR          ||
+       op == PIXMAN_OP_SRC             ||
+       op == PIXMAN_OP_DST             ||
+       op == PIXMAN_OP_OVER            ||
+       op == PIXMAN_OP_IN_REVERSE      ||
+       op == PIXMAN_OP_OUT_REVERSE     ||
+       op == PIXMAN_OP_ADD)
+    {
+       dest_flags = narrow | ITER_LOCALIZED_ALPHA;
+    }
+    else
+    {
+       dest_flags = narrow;
+    }
+
     _pixman_implementation_dest_iter_init (imp->toplevel, &dest_iter, dest,
                                           dest_x, dest_y, width, height,
-                                          dest_buffer, narrow);
+                                          dest_buffer, dest_flags);
 
     component_alpha =
         mask                            &&
index c3321e1..0aeae2e 100644 (file)
@@ -185,7 +185,24 @@ union pixman_image
 typedef struct pixman_iter_t pixman_iter_t;
 typedef enum
 {
-    ITER_NARROW        = (1 << 0),
+    ITER_NARROW =              (1 << 0),
+
+    /* "Localized alpha" is when the alpha channel is used only to compute
+     * the alpha value of the destination. This means that the computation
+     * of the RGB values of the result is independent of the alpha value.
+     *
+     * For example, the OVER operator has localized alpha for the
+     * destination, because the RGB values of the result can be computed
+     * without knowing the destination alpha. Similarly, ADD has localized
+     * alpha for both source and destination because the RGB values of the
+     * result can be computed without knowing the alpha value of source or
+     * destination.
+     *
+     * When he destination is xRGB, this is useful knowledge, because then
+     * we can treat it as if it were ARGB, which means in some cases we can
+     * avoid copying it to a temporary buffer.
+     */
+    ITER_LOCALIZED_ALPHA =     (1 << 1)
 } iter_flags_t;
 
 struct pixman_iter_t