[Pixman] [PATCH 7/7] Store the various bits image fetchers in a table with formats and flags.

Søren Sandmann sandmann at daimi.au.dk
Thu Jul 29 07:12:48 PDT 2010


From: Søren Sandmann Pedersen <ssp at redhat.com>

Similarly to how the fast paths are done, put the various bits_image
fetchers in a table, so that we can quickly find the best one based on
the image's flags and format.
---
 pixman/pixman-bits-image.c |  126 ++++++++++++++++++++++++++-----------------
 1 files changed, 76 insertions(+), 50 deletions(-)

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 7129e86..a32ebcc 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -906,62 +906,88 @@ bits_image_fetch_untransformed_64 (pixman_image_t * image,
     }
 }
 
+typedef struct
+{
+    pixman_format_code_t	format;
+    uint32_t			flags;
+    fetch_scanline_t		fetch_32;
+    fetch_scanline_t		fetch_64;
+} fetcher_info_t;
+
+static const fetcher_info_t fetcher_info[] =
+{
+    { PIXMAN_solid,
+      FAST_PATH_NO_ALPHA_MAP,
+      bits_image_fetch_solid_32,
+      bits_image_fetch_solid_64
+    },
+
+    { PIXMAN_any,
+      (FAST_PATH_NO_ALPHA_MAP			|
+       FAST_PATH_ID_TRANSFORM			|
+       FAST_PATH_NO_CONVOLUTION_FILTER		|
+       FAST_PATH_NO_PAD_REPEAT			|
+       FAST_PATH_NO_REFLECT_REPEAT),
+      bits_image_fetch_untransformed_32,
+      bits_image_fetch_untransformed_64
+    },
+
+#define FAST_BILINEAR_FLAGS						\
+    (FAST_PATH_NO_ALPHA_MAP		|				\
+     FAST_PATH_NO_ACCESSORS		|				\
+     FAST_PATH_HAS_TRANSFORM		|				\
+     FAST_PATH_AFFINE_TRANSFORM		|				\
+     FAST_PATH_X_UNIT_POSITIVE		|				\
+     FAST_PATH_Y_UNIT_ZERO		|				\
+     FAST_PATH_NONE_REPEAT		|				\
+     FAST_PATH_BILINEAR_FILTER)
+
+    { PIXMAN_a8r8g8b8,
+      FAST_BILINEAR_FLAGS,
+      bits_image_fetch_bilinear_no_repeat_8888,
+      _pixman_image_get_scanline_generic_64
+    },
+
+    { PIXMAN_x8r8g8b8,
+      FAST_BILINEAR_FLAGS,
+      bits_image_fetch_bilinear_no_repeat_8888,
+      _pixman_image_get_scanline_generic_64
+    },
+
+    { PIXMAN_any,
+      (FAST_PATH_NO_ALPHA_MAP |
+       FAST_PATH_HAS_TRANSFORM |
+       FAST_PATH_AFFINE_TRANSFORM),
+      bits_image_fetch_affine_no_alpha,
+      _pixman_image_get_scanline_generic_64
+    },
+
+    { PIXMAN_any, 0, bits_image_fetch_general, _pixman_image_get_scanline_generic_64 },
+
+    { PIXMAN_null },
+};
+
 static void
 bits_image_property_changed (pixman_image_t *image)
 {
-    bits_image_t *bits = (bits_image_t *)image;
+    uint32_t flags = image->common.flags;
+    pixman_format_code_t format = image->common.extended_format_code;
+    const fetcher_info_t *info;
 
-    _pixman_bits_image_setup_accessors (bits);
+    _pixman_bits_image_setup_accessors (&image->bits);
 
-    if (bits->common.alpha_map)
-    {
-	image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
-	image->common.get_scanline_32 = bits_image_fetch_general;
-    }
-    else if ((bits->common.repeat != PIXMAN_REPEAT_NONE) &&
-             bits->width == 1 &&
-             bits->height == 1)
-    {
-	image->common.get_scanline_64 = bits_image_fetch_solid_64;
-	image->common.get_scanline_32 = bits_image_fetch_solid_32;
-    }
-    else if (!bits->common.transform &&
-             bits->common.filter != PIXMAN_FILTER_CONVOLUTION &&
-             (bits->common.repeat == PIXMAN_REPEAT_NONE ||
-              bits->common.repeat == PIXMAN_REPEAT_NORMAL))
-    {
-	image->common.get_scanline_64 = bits_image_fetch_untransformed_64;
-	image->common.get_scanline_32 = bits_image_fetch_untransformed_32;
-    }
-    else if (bits->common.transform					&&
-	     bits->common.transform->matrix[2][0] == 0			&&
-	     bits->common.transform->matrix[2][1] == 0			&&
-	     bits->common.transform->matrix[2][2] == pixman_fixed_1	&&
-	     bits->common.transform->matrix[0][0] > 0			&&
-	     bits->common.transform->matrix[1][0] == 0			&&
-	     !bits->read_func						&&
-	     (bits->common.filter == PIXMAN_FILTER_BILINEAR ||
-	      bits->common.filter == PIXMAN_FILTER_GOOD	    ||
-	      bits->common.filter == PIXMAN_FILTER_BEST)		&&
-	     bits->common.repeat == PIXMAN_REPEAT_NONE			&&
-	     (bits->format == PIXMAN_a8r8g8b8	||
-	      bits->format == PIXMAN_x8r8g8b8))
-    {
-	image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
-	image->common.get_scanline_32 = bits_image_fetch_bilinear_no_repeat_8888;
-    }
-    else if (bits->common.transform					&&
-	     bits->common.transform->matrix[2][0] == 0			&&
-	     bits->common.transform->matrix[2][1] == 0			&&
-	     bits->common.transform->matrix[2][2] == pixman_fixed_1)
+    info = fetcher_info;
+    while (info->format != PIXMAN_null)
     {
-	image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
-	image->common.get_scanline_32 = bits_image_fetch_affine_no_alpha;
-    }
-    else
-    {
-	image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
-	image->common.get_scanline_32 = bits_image_fetch_general;
+	if ((info->format == format || info->format == PIXMAN_any)	&&
+	    (info->flags & flags) == info->flags)
+	{
+	    image->common.get_scanline_32 = info->fetch_32;
+	    image->common.get_scanline_64 = info->fetch_64;
+	    break;
+	}
+
+	info++;
     }
 }
 
-- 
1.7.1.1



More information about the Pixman mailing list