Add a few optimizations for solid fills
authorSøren Sandmann Pedersen <sandmann@redhat.com>
Sat, 16 Jun 2007 16:55:59 +0000 (12:55 -0400)
committerSøren Sandmann Pedersen <sandmann@redhat.com>
Sat, 16 Jun 2007 16:55:59 +0000 (12:55 -0400)
TODO
pixman/pixman-compose.c
pixman/pixman-image.c
pixman/pixman-mmx.c
pixman/pixman-mmx.h
pixman/pixman-pict.c
pixman/pixman-private.h
pixman/pixman-utils.c

diff --git a/TODO b/TODO
index 9423dd9..7bbb7d0 100644 (file)
--- a/TODO
+++ b/TODO
@@ -30,6 +30,8 @@
        - done: source clipping happens through an indirection.
          still needs to make the indirection settable.
 
+- Add non-mmx solid fill
+
 done:
 
 - Make sure the endian-ness macros are defined correctly.
index d761e8f..bff67f0 100644 (file)
@@ -4328,6 +4328,9 @@ pixmanCompositeRect (const FbComposeData *data, uint32_t *scanline_buffer)
        if (IS_SOURCE_IMAGE (data->mask))
        {
            fetchMask = (scanFetchProc)pixmanFetchSourcePict;
+           maskClass = SourcePictureClassify ((source_image_t *)data->mask,
+                                              data->xMask, data->yMask,
+                                              data->width, data->height);
        }
        else
        {
@@ -4336,21 +4339,6 @@ pixmanCompositeRect (const FbComposeData *data, uint32_t *scanline_buffer)
            if (bits->common.alpha_map)
            {
                fetchMask = (scanFetchProc)fbFetchExternalAlpha;
-               /* FIXME: this looks highly suspicious. Why would we
-                * expect the mask to be a source picture here? In fact
-                * we _know_ it's not a source picture.
-                *
-                * That's why it's commented out. This will result in
-                * the classification of "unknown" which should be
-                * correct.
-                *
-                * It looks like it belongs in the IS_SOURCE_IMAGE() clause
-                */
-#if 0
-               maskClass = SourcePictureClassify (data->mask,
-                                                  data->xMask, data->yMask,
-                                                  data->width, data->height);
-#endif
            }
            else if (bits->common.repeat == PIXMAN_REPEAT_NORMAL &&
                     bits->width == 1 && bits->height == 1)
index 2211677..d54e438 100644 (file)
@@ -572,10 +572,16 @@ pixman_image_fill_rectangles (pixman_op_t             op,
 {
     pixman_image_t *solid = pixman_image_create_solid_fill (color);
     int i;
-
+    
     if (!solid)
        return FALSE;
 
+    if (color->alpha == 0xffff)
+    {
+       if (op == PIXMAN_OP_OVER)
+           op = PIXMAN_OP_SRC;
+    }
+
     for (i = 0; i < n_rects; ++i)
     {
        const pixman_rectangle16_t *rect = &(rects[i]);
@@ -585,7 +591,7 @@ pixman_image_fill_rectangles (pixman_op_t               op,
                                rect->x, rect->y,
                                rect->width, rect->height);
     }
-
+    
     pixman_image_unref (solid);
 
     return TRUE;
index ba2b873..bda9bf4 100644 (file)
@@ -2850,6 +2850,31 @@ pixman_blt_mmx (uint32_t *src_bits,
 }
 
 void
+fbCompositeSolidFillmmx (pixman_op_t op,
+                        pixman_image_t * pSrc,
+                        pixman_image_t * pMask,
+                        pixman_image_t * pDst,
+                        int16_t      xSrc,
+                        int16_t      ySrc,
+                        int16_t      xMask,
+                        int16_t      yMask,
+                        int16_t      xDst,
+                        int16_t      yDst,
+                        uint16_t     width,
+                        uint16_t     height)
+{
+    uint32_t   src;
+    
+    fbComposeGetSolid(pSrc, src, pDst->bits.format);
+
+    pixman_fill_mmx (pDst->bits.bits, pDst->bits.rowstride,
+                    PIXMAN_FORMAT_BPP (pDst->bits.format),
+                    xDst, yDst,
+                    width, height,
+                    src);
+}
+
+void
 fbCompositeCopyAreammx (pixman_op_t       op,
                        pixman_image_t *        pSrc,
                        pixman_image_t *        pMask,
index 4b9e823..6b86fdc 100644 (file)
@@ -298,5 +298,18 @@ void fbCompositeCopyAreammx (pixman_op_t   op,
                             int16_t      yDst,
                             uint16_t     width,
                             uint16_t     height);
+void
+fbCompositeSolidFillmmx (pixman_op_t op,
+                        pixman_image_t * pSrc,
+                        pixman_image_t * pMask,
+                        pixman_image_t * pDst,
+                        int16_t      xSrc,
+                        int16_t      ySrc,
+                        int16_t      xMask,
+                        int16_t      yMask,
+                        int16_t      xDst,
+                        int16_t      yDst,
+                        uint16_t     width,
+                        uint16_t     height);
 
 #endif /* USE_MMX */
index 741ede6..8b72ffb 100644 (file)
@@ -1037,6 +1037,9 @@ pixman_walk_composite_region (pixman_op_t op,
 static pixman_bool_t
 can_get_solid (pixman_image_t *image)
 {
+    if (image->type == SOLID)
+       return TRUE;
+    
     if (image->type != BITS    ||
        image->bits.width != 1  ||
        image->bits.height != 1)
@@ -1165,7 +1168,7 @@ pixman_image_composite (pixman_op_t      op,
            maskTransform = FALSE;
     }
 
-    if (pSrc->type == BITS && (!pMask || pMask->type == BITS)
+    if ((pSrc->type == BITS || can_get_solid (pSrc)) && (!pMask || pMask->type == BITS)
         && !srcTransform && !maskTransform
         && !maskAlphaMap && !srcAlphaMap && !dstAlphaMap
         && (pSrc->common.filter != PIXMAN_FILTER_CONVOLUTION)
@@ -1180,7 +1183,7 @@ pixman_image_composite (pixman_op_t      op,
            if (can_get_solid(pSrc) &&
                !maskRepeat)
            {
-               if (PIXMAN_FORMAT_COLOR(pSrc->bits.format)) {
+               if (pSrc->type == SOLID || PIXMAN_FORMAT_COLOR(pSrc->bits.format)) {
                    switch (pMask->bits.format) {
                    case PIXMAN_a8:
                        switch (pDst->bits.format) {
@@ -1405,8 +1408,8 @@ pixman_image_composite (pixman_op_t      op,
            if (can_get_solid(pSrc))
            {
                /* no mask and repeating source */
-               switch (pSrc->bits.format) {
-               case PIXMAN_a8r8g8b8:
+               if (pSrc->type == SOLID || pSrc->bits.format == PIXMAN_a8r8g8b8)
+               {
                    switch (pDst->bits.format) {
                    case PIXMAN_a8r8g8b8:
                    case PIXMAN_x8r8g8b8:
@@ -1431,8 +1434,6 @@ pixman_image_composite (pixman_op_t      op,
                        break;
                    }
                    break;
-               default:
-                   break;
                }
            }
            else if (! srcRepeat)
@@ -1602,9 +1603,7 @@ pixman_image_composite (pixman_op_t      op,
        }
        else
        {
-           if ((pSrc->bits.format == PIXMAN_a8r8g8b8   ||
-                pSrc->bits.format == PIXMAN_a8b8g8r8) &&
-               can_get_solid (pSrc)            &&
+           if (can_get_solid (pSrc)            &&
                pMask->bits.format == PIXMAN_a8 &&
                pDst->bits.format == PIXMAN_a8)
            {
@@ -1647,7 +1646,16 @@ pixman_image_composite (pixman_op_t      op,
        }
        else
        {
-           if (pSrc->bits.format == pDst->bits.format)
+           if (can_get_solid (pSrc))
+           {
+               if (PIXMAN_FORMAT_BPP (pDst->bits.format) == 16 ||
+                   PIXMAN_FORMAT_BPP (pDst->bits.format) == 32)
+               {
+                   func = fbCompositeSolidFillmmx;
+                   srcRepeat = FALSE;
+               }
+           }
+           else if (pSrc->bits.format == pDst->bits.format)
            {
 #ifdef USE_MMX
                if (pSrc->bits.bits != pDst->bits.bits && pixman_have_mmx() &&
index db5597b..0dda1a6 100644 (file)
@@ -179,7 +179,7 @@ struct image_common
 struct source_image
 {
     image_common_t     common;
-    unsigned int       class;          /* FIXME: should be an enum */
+    source_pict_class_t class;
 };
 
 struct solid_fill
@@ -643,32 +643,46 @@ void pixmanCompositeRect (const FbComposeData *data,
 
 #define fbFinishAccess(x) 
 
-#define fbComposeGetSolid(img, res, fmt) do {                          \
-       uint32_t               *bits__   = (img)->bits.bits;            \
-       pixman_format_code_t    format__ = (img)->bits.format;          \
-                                                                       \
-       switch (PIXMAN_FORMAT_BPP((img)->bits.format))                  \
+#define fbComposeGetSolid(img, res, fmt)                               \
+    do                                                                 \
+    {                                                                  \
+       pixman_format_code_t format__;                                  \
+       if (img->type == SOLID)                                         \
        {                                                               \
-       case 32:                                                        \
-           (res) = READ((uint32_t *)bits__);                           \
-           break;                                                      \
-       case 24:                                                        \
-           (res) = Fetch24 ((uint8_t *) bits__);                       \
-           break;                                                      \
-       case 16:                                                        \
-           (res) = READ((uint16_t *) bits__);                          \
-           (res) = cvt0565to0888(res);                                 \
-           break;                                                      \
-       case 8:                                                         \
-           (res) = READ((uint8_t *) bits__);                           \
-           (res) = (res) << 24;                                        \
-           break;                                                      \
-       case 1:                                                         \
-           (res) = READ((uint32_t *) bits__);                          \
-           (res) = FbLeftStipBits((res),1) ? 0xff000000 : 0x00000000;  \
-           break;                                                      \
-       default:                                                        \
-           return;                                                     \
+           format__ = PIXMAN_a8r8g8b8;                                 \
+           (res) = img->solid.color;                                   \
+       }                                                               \
+       else                                                            \
+       {                                                               \
+           uint32_t           *bits__   = (img)->bits.bits;            \
+           format__ = (img)->bits.format;                              \
+                                                                       \
+           switch (PIXMAN_FORMAT_BPP((img)->bits.format))              \
+           {                                                           \
+           case 32:                                                    \
+               (res) = READ((uint32_t *)bits__);                       \
+               break;                                                  \
+           case 24:                                                    \
+               (res) = Fetch24 ((uint8_t *) bits__);                   \
+               break;                                                  \
+           case 16:                                                    \
+               (res) = READ((uint16_t *) bits__);                      \
+               (res) = cvt0565to0888(res);                             \
+               break;                                                  \
+           case 8:                                                     \
+               (res) = READ((uint8_t *) bits__);                       \
+               (res) = (res) << 24;                                    \
+               break;                                                  \
+           case 1:                                                     \
+               (res) = READ((uint32_t *) bits__);                      \
+               (res) = FbLeftStipBits((res),1) ? 0xff000000 : 0x00000000; \
+               break;                                                  \
+           default:                                                    \
+               return;                                                 \
+           }                                                           \
+           /* manage missing src alpha */                              \
+           if (!PIXMAN_FORMAT_A((img)->bits.format))                   \
+               (res) |= 0xff000000;                                    \
        }                                                               \
        /* If necessary, convert RGB <--> BGR. */                       \
        if (PIXMAN_FORMAT_TYPE (format__) != PIXMAN_FORMAT_TYPE(fmt))   \
@@ -678,11 +692,8 @@ void pixmanCompositeRect (const FbComposeData *data,
                     (((res) & 0x0000ff00) >>  0) |                     \
                     (((res) & 0x000000ff) << 16));                     \
        }                                                               \
-       /* manage missing src alpha */                                  \
-       if (!PIXMAN_FORMAT_A((img)->bits.format))                       \
-           (res) |= 0xff000000;                                        \
-    } while (0)
-
+    }                                                                  \
+    while (0)
 
 #define fbComposeGetStart(pict,x,y,type,out_stride,line,mul) do {      \
        uint32_t        *__bits__;                                      \
index 4ac30aa..9d611e9 100644 (file)
@@ -82,13 +82,13 @@ pixman_blt (uint32_t *src_bits,
 
 pixman_bool_t
 pixman_fill (uint32_t *bits,
-                int stride,
-                int bpp,
-                int x,
-                int y,
-                int width,
-                int height,
-                uint32_t xor)
+            int stride,
+            int bpp,
+            int x,
+            int y,
+            int width,
+            int height,
+            uint32_t xor)
 {
 #ifdef USE_MMX
     if (pixman_have_mmx())