Add a generic 64 bit fetcher and use it for gradients and transformed images
authorSøren Sandmann Pedersen <sandmann@redhat.com>
Sun, 3 May 2009 03:26:30 +0000 (23:26 -0400)
committerSøren Sandmann Pedersen <sandmann@redhat.com>
Sat, 16 May 2009 19:12:36 +0000 (15:12 -0400)
pixman/pixman-bits-image.c
pixman/pixman-compose.c
pixman/pixman-conical-gradient.c
pixman/pixman-image.c
pixman/pixman-linear-gradient.c
pixman/pixman-private.h
pixman/pixman-radial-gradient.c
pixman/pixman-solid-fill.c
pixman/pixman-source.c
pixman/pixman-transformed.c

index 1437406..2dcf34b 100644 (file)
@@ -90,7 +90,7 @@ bits_image_property_changed (pixman_image_t *image)
     if (bits->common.alpha_map)
     {
        image->common.get_scanline_64 =
-           (scanFetchProc)READ_ACCESS(fbFetchExternalAlpha64);
+           (scanFetchProc)_pixman_image_get_scanline_64_generic;
        image->common.get_scanline_32 =
            (scanFetchProc)READ_ACCESS(fbFetchExternalAlpha);
     }
@@ -112,7 +112,7 @@ bits_image_property_changed (pixman_image_t *image)
     else
     {
        image->common.get_scanline_64 =
-           (scanFetchProc)READ_ACCESS(fbFetchTransformed64);
+           (scanFetchProc)_pixman_image_get_scanline_64_generic;
        image->common.get_scanline_32 =
            (scanFetchProc)READ_ACCESS(fbFetchTransformed);
     }
index d13d87c..23bfe5d 100644 (file)
@@ -216,7 +216,7 @@ pixman_composite_rect_general (const FbComposeData *data)
     const int Bpp = wide ? 8 : 4;
     uint8_t *scanline_buffer = stack_scanline_buffer;
     uint8_t *src_buffer, *mask_buffer, *dest_buffer;
-
+    
     if (data->width * Bpp > SCANLINE_BUFFER_LENGTH)
     {
        scanline_buffer = pixman_malloc_abc (data->width, 3, Bpp);
index cd8d36c..d5c4e23 100644 (file)
@@ -27,8 +27,8 @@
 static void
 conical_gradient_property_changed (pixman_image_t *image)
 {
-    image->common.get_scanline_64 = (scanFetchProc)pixmanFetchSourcePict64;
     image->common.get_scanline_32 = (scanFetchProc)pixmanFetchSourcePict;
+    image->common.get_scanline_64 = (scanFetchProc)_pixman_image_get_scanline_64_generic;
 }
 
 PIXMAN_EXPORT pixman_image_t *
index 0553a5a..9d62f4a 100644 (file)
@@ -56,6 +56,38 @@ _pixman_init_gradient (gradient_t     *gradient,
     return TRUE;
 }
 
+/*
+ * By default, just evaluate the image at 32bpp and expand.  Individual image
+ * types can plug in a better scanline getter if they want to. For example
+ * we  could produce smoother gradients by evaluating them at higher color depth, but
+ * that's a project for the future.
+ */
+void
+_pixman_image_get_scanline_64_generic (pixman_image_t * pict, int x, int y, int width,
+                                      uint64_t *buffer, uint64_t *mask, uint32_t maskBits)
+{
+    uint32_t *mask8 = NULL;
+
+    // Contract the mask image, if one exists, so that the 32-bit fetch function
+    // can use it.
+    if (mask) {
+        mask8 = pixman_malloc_ab(width, sizeof(uint32_t));
+       if (!mask8)
+           return;
+       
+        pixman_contract(mask8, mask, width);
+    }
+
+    // Fetch the source image into the first half of buffer.
+    _pixman_image_get_scanline_32 (pict, x, y, width, (uint32_t*)buffer, mask8,
+                                  maskBits);
+
+    // Expand from 32bpp to 64bpp in place.
+    pixman_expand(buffer, (uint32_t*)buffer, PIXMAN_a8r8g8b8, width);
+
+    free(mask8);
+}
+
 pixman_image_t *
 _pixman_image_allocate (void)
 {
index 46217a0..c6c662a 100644 (file)
@@ -86,8 +86,8 @@ linear_gradient_classify (pixman_image_t *image,
 static void
 linear_gradient_property_changed (pixman_image_t *image)
 {
-    image->common.get_scanline_64 = (scanFetchProc)pixmanFetchSourcePict64;
     image->common.get_scanline_32 = (scanFetchProc)pixmanFetchSourcePict;
+    image->common.get_scanline_64 = (scanFetchProc)_pixman_image_get_scanline_64_generic;
 }
 
 PIXMAN_EXPORT pixman_image_t *
index fedbbb3..ff1bfa6 100644 (file)
@@ -222,9 +222,8 @@ void pixman_contract(uint32_t *dst, const uint64_t *src, int width);
 
 void pixmanFetchSourcePict(source_image_t *, int x, int y, int width,
                            uint32_t *buffer, uint32_t *mask, uint32_t maskBits);
-void pixmanFetchSourcePict64(source_image_t *, int x, int y, int width,
-                             uint64_t *buffer, uint64_t *mask, uint32_t maskBits);
-
+void _pixman_image_get_scanline_64_generic (pixman_image_t * pict, int x, int y, int width,
+                                           uint64_t *buffer, uint64_t *mask, uint32_t maskBits);
 void fbFetchTransformed(bits_image_t *, int x, int y, int width,
                         uint32_t *buffer, uint32_t *mask, uint32_t maskBits);
 void fbStoreExternalAlpha(bits_image_t *, int x, int y, int width,
@@ -241,21 +240,11 @@ void fbFetchExternalAlpha_accessors(bits_image_t *, int x, int y, int width,
                                     uint32_t *buffer, uint32_t *mask,
                                     uint32_t maskBits);
 
-void fbFetchTransformed64(bits_image_t *, int x, int y, int width,
-                          uint64_t *buffer, uint64_t *mask, uint32_t maskBits);
 void fbStoreExternalAlpha64(bits_image_t *, int x, int y, int width,
                             uint64_t *buffer);
-void fbFetchExternalAlpha64(bits_image_t *, int x, int y, int width,
-                            uint64_t *buffer, uint64_t *mask, uint32_t maskBits);
 
-void fbFetchTransformed64_accessors(bits_image_t *, int x, int y, int width,
-                                    uint64_t *buffer, uint64_t *mask,
-                                    uint32_t maskBits);
 void fbStoreExternalAlpha64_accessors(bits_image_t *, int x, int y, int width,
                                       uint64_t *buffer);
-void fbFetchExternalAlpha64_accessors(bits_image_t *, int x, int y, int width,
-                                      uint64_t *buffer, uint64_t *mask,
-                                      uint32_t maskBits);
 
 /* end */
 
index 62f8f27..e05299c 100644 (file)
@@ -27,8 +27,8 @@
 static void
 radial_gradient_property_changed (pixman_image_t *image)
 {
-    image->common.get_scanline_64 = (scanFetchProc)pixmanFetchSourcePict64;
     image->common.get_scanline_32 = (scanFetchProc)pixmanFetchSourcePict;
+    image->common.get_scanline_64 = (scanFetchProc)_pixman_image_get_scanline_64_generic;
 }
 
 PIXMAN_EXPORT pixman_image_t *
index b6e8ebb..af383b5 100644 (file)
@@ -37,8 +37,8 @@ solid_fill_classify (pixman_image_t *image,
 static void
 solid_fill_property_changed (pixman_image_t *image)
 {
-    image->common.get_scanline_64 = (scanFetchProc)pixmanFetchSourcePict64;
     image->common.get_scanline_32 = (scanFetchProc)pixmanFetchSourcePict;
+    image->common.get_scanline_64 = (scanFetchProc)_pixman_image_get_scanline_64_generic;
 }
 
 static uint32_t
index c405f49..0b2569e 100644 (file)
@@ -458,30 +458,3 @@ void pixmanFetchSourcePict(source_image_t * pict, int x, int y, int width,
         }
     }
 }
-
-/*
- * For now, just evaluate the source picture at 32bpp and expand.  We could
- * produce smoother gradients by evaluating them at higher color depth, but
- * that's a project for the future.
- */
-void pixmanFetchSourcePict64(source_image_t * pict, int x, int y, int width,
-                             uint64_t *buffer, uint64_t *mask, uint32_t maskBits)
-{
-    uint32_t *mask8 = NULL;
-
-    // Contract the mask image, if one exists, so that the 32-bit fetch function
-    // can use it.
-    if (mask) {
-        mask8 = pixman_malloc_ab(width, sizeof(uint32_t));
-        pixman_contract(mask8, mask, width);
-    }
-
-    // Fetch the source image into the first half of buffer.
-    pixmanFetchSourcePict(pict, x, y, width, (uint32_t*)buffer, mask8,
-                          maskBits);
-
-    // Expand from 32bpp to 64bpp in place.
-    pixman_expand(buffer, (uint32_t*)buffer, PIXMAN_a8r8g8b8, width);
-
-    free(mask8);
-}
index 6d695c5..997d24e 100644 (file)
@@ -472,30 +472,6 @@ ACCESS(fbFetchTransformed)(bits_image_t * pict, int x, int y, int width,
     }
 }
 
-void
-ACCESS(fbFetchTransformed64)(bits_image_t * pict, int x, int y, int width,
-                             uint64_t *buffer, uint64_t *mask, uint32_t maskBits)
-{
-    // TODO: Don't lose precision for wide pictures!
-    uint32_t *mask8 = NULL;
-
-    // Contract the mask image, if one exists, so that the 32-bit fetch function
-    // can use it.
-    if (mask) {
-        mask8 = pixman_malloc_ab(width, sizeof(uint32_t));
-        pixman_contract(mask8, mask, width);
-    }
-
-    // Fetch the image into the first half of buffer.
-    ACCESS(fbFetchTransformed)(pict, x, y, width, (uint32_t*)buffer, mask8,
-                               maskBits);
-
-    // Expand from 32bpp to 64bpp in place.
-    pixman_expand(buffer, (uint32_t*)buffer, PIXMAN_a8r8g8b8, width);
-
-    free(mask8);
-}
-
 #define SCANLINE_BUFFER_LENGTH 2048
 
 void
@@ -534,45 +510,6 @@ ACCESS(fbFetchExternalAlpha)(bits_image_t * pict, int x, int y, int width,
 }
 
 void
-ACCESS(fbFetchExternalAlpha64)(bits_image_t * pict, int x, int y, int width,
-                               uint64_t *buffer, uint64_t *mask,
-                               uint32_t maskBits)
-{
-    int i;
-    uint64_t _alpha_buffer[SCANLINE_BUFFER_LENGTH];
-    uint64_t *alpha_buffer = _alpha_buffer;
-    uint64_t maskBits64;
-
-    if (!pict->common.alpha_map) {
-        ACCESS(fbFetchTransformed64) (pict, x, y, width, buffer, mask, maskBits);
-       return;
-    }
-    if (width > SCANLINE_BUFFER_LENGTH)
-        alpha_buffer = (uint64_t *) pixman_malloc_ab (width, sizeof(uint64_t));
-
-    ACCESS(fbFetchTransformed64)(pict, x, y, width, buffer, mask, maskBits);
-    ACCESS(fbFetchTransformed64)((bits_image_t *)pict->common.alpha_map, x - pict->common.alpha_origin.x,
-                                 y - pict->common.alpha_origin.y, width,
-                                 alpha_buffer, mask, maskBits);
-
-    pixman_expand(&maskBits64, &maskBits, PIXMAN_a8r8g8b8, 1);
-
-    for (i = 0; i < width; ++i) {
-        if (!mask || mask[i] & maskBits64)
-       {
-           int64_t a = alpha_buffer[i]>>48;
-           *(buffer + i) = (a << 48)
-               | (div_65535(Red64(*(buffer + i)) * a) << 32)
-               | (div_65535(Green64(*(buffer + i)) * a) << 16)
-               | (div_65535(Blue64(*(buffer + i)) * a));
-       }
-    }
-
-    if (alpha_buffer != _alpha_buffer)
-        free(alpha_buffer);
-}
-
-void
 ACCESS(fbStoreExternalAlpha)(bits_image_t * pict, int x, int y, int width,
                              uint32_t *buffer)
 {