summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <sandmann@redhat.com>2009-07-31 05:19:36 -0400
committerSøren Sandmann Pedersen <sandmann@redhat.com>2009-11-09 17:07:32 -0500
commit768cfee64f8a7d05375b09090e854a3e88652cfe (patch)
treee0f929b8c38730610aadba9d6d7b43881ff0aacc
parentb8898d77d0e7cc1c50321fcb216af3ba6c634959 (diff)
Add some transformed fast paths generated by a preprocessor macro.macro-fast-path
-rw-r--r--pixman/pixman-bits-image.c143
1 files changed, 127 insertions, 16 deletions
diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 5a5a6905..1738d032 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -167,6 +167,8 @@ repeat (pixman_repeat_t repeat, int size, int *coord)
static force_inline uint32_t
bits_image_fetch_pixel_nearest (bits_image_t *image,
+ pixman_format_code_t format,
+ pixman_repeat_t repeat_mode,
pixman_fixed_t x,
pixman_fixed_t y)
{
@@ -278,11 +280,12 @@ bilinear_interpolation (uint32_t tl, uint32_t tr,
#endif
static force_inline uint32_t
-bits_image_fetch_pixel_bilinear (bits_image_t *image,
- pixman_fixed_t x,
- pixman_fixed_t y)
+bits_image_fetch_pixel_bilinear (bits_image_t *image,
+ pixman_format_code_t format,
+ pixman_repeat_t repeat_mode,
+ pixman_fixed_t x,
+ pixman_fixed_t y)
{
- pixman_repeat_t repeat_mode = image->common.repeat;
int width = image->width;
int height = image->height;
int x1, y1, x2, y2;
@@ -535,9 +538,11 @@ bits_image_fetch_bilinear_no_repeat_8888 (pixman_image_t * ima,
}
static force_inline uint32_t
-bits_image_fetch_pixel_convolution (bits_image_t *image,
- pixman_fixed_t x,
- pixman_fixed_t y)
+bits_image_fetch_pixel_convolution (bits_image_t *image,
+ pixman_format_code_t format,
+ pixman_repeat_t repeat_mode,
+ pixman_fixed_t x,
+ pixman_fixed_t y)
{
pixman_fixed_t *params = image->common.filter_params;
int x_off = (params[0] - pixman_fixed_1) >> 1;
@@ -546,7 +551,6 @@ bits_image_fetch_pixel_convolution (bits_image_t *image,
int32_t cheight = pixman_fixed_to_int (params[1]);
int32_t srtot, sgtot, sbtot, satot;
int32_t i, j, x1, x2, y1, y2;
- pixman_repeat_t repeat_mode = image->common.repeat;
int width = image->width;
int height = image->height;
@@ -609,24 +613,27 @@ bits_image_fetch_pixel_convolution (bits_image_t *image,
static force_inline uint32_t
bits_image_fetch_pixel_filtered (bits_image_t *image,
+ pixman_format_code_t format,
+ pixman_filter_t filter,
+ pixman_repeat_t repeat_mode,
pixman_fixed_t x,
pixman_fixed_t y)
{
- switch (image->common.filter)
+ switch (filter)
{
case PIXMAN_FILTER_NEAREST:
case PIXMAN_FILTER_FAST:
- return bits_image_fetch_pixel_nearest (image, x, y);
+ return bits_image_fetch_pixel_nearest (image, format, repeat_mode, x, y);
break;
case PIXMAN_FILTER_BILINEAR:
case PIXMAN_FILTER_GOOD:
case PIXMAN_FILTER_BEST:
- return bits_image_fetch_pixel_bilinear (image, x, y);
+ return bits_image_fetch_pixel_bilinear (image, format, repeat_mode, x, y);
break;
case PIXMAN_FILTER_CONVOLUTION:
- return bits_image_fetch_pixel_convolution (image, x, y);
+ return bits_image_fetch_pixel_convolution (image, format, repeat_mode, x, y);
break;
default:
@@ -683,8 +690,12 @@ bits_image_fetch_transformed (pixman_image_t * image,
{
if (!mask || (mask[i] & mask_bits))
{
- buffer[i] =
- bits_image_fetch_pixel_filtered (&image->bits, x, y);
+ buffer[i] = bits_image_fetch_pixel_filtered (
+ &image->bits,
+ image->bits.format,
+ image->common.filter,
+ image->common.repeat,
+ x, y);
}
x += ux;
@@ -702,8 +713,12 @@ bits_image_fetch_transformed (pixman_image_t * image,
x0 = ((pixman_fixed_48_16_t)x << 16) / w;
y0 = ((pixman_fixed_48_16_t)y << 16) / w;
- buffer[i] =
- bits_image_fetch_pixel_filtered (&image->bits, x0, y0);
+ buffer[i] = bits_image_fetch_pixel_filtered (
+ &image->bits,
+ image->bits.format,
+ image->common.filter,
+ image->common.repeat,
+ x0, y0);
}
x += ux;
@@ -713,6 +728,82 @@ bits_image_fetch_transformed (pixman_image_t * image,
}
}
+#define MAKE_FAST_PATH(name, format, filter, repeat) \
+ static void \
+ bits_image_fetch_ ## name (pixman_image_t * image, \
+ int offset, \
+ int line, \
+ int width, \
+ uint32_t * buffer, \
+ const uint32_t * mask, \
+ uint32_t mask_bits) \
+ { \
+ pixman_fixed_t x, y, w; \
+ pixman_fixed_t ux, uy, uw; \
+ pixman_vector_t v; \
+ int i; \
+ \
+ /* reference point is the center of the pixel */ \
+ v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2; \
+ v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2; \
+ v.vector[2] = pixman_fixed_1; \
+ \
+ /* when using convolution filters or PIXMAN_REPEAT_PAD one \
+ * might get here without a transform */ \
+ if (image->common.transform) \
+ { \
+ if (!pixman_transform_point_3d (image->common.transform, &v)) \
+ return; \
+ \
+ ux = image->common.transform->matrix[0][0]; \
+ uy = image->common.transform->matrix[1][0]; \
+ uw = image->common.transform->matrix[2][0]; \
+ } \
+ else \
+ { \
+ ux = pixman_fixed_1; \
+ uy = 0; \
+ uw = 0; \
+ } \
+ \
+ x = v.vector[0]; \
+ y = v.vector[1]; \
+ w = v.vector[2]; \
+ \
+ for (i = 0; i < width; ++i) \
+ { \
+ if (!mask || (mask[i] & mask_bits)) \
+ { \
+ buffer[i] = \
+ bits_image_fetch_pixel_filtered ( \
+ &image->bits, format, filter, repeat, x, y); \
+ } \
+ \
+ x += ux; \
+ y += uy; \
+ } \
+ }
+
+MAKE_FAST_PATH (
+ a8r8g8b8_bilinear_pad,
+ PIXMAN_a8r8g8b8, PIXMAN_FILTER_BILINEAR, PIXMAN_REPEAT_PAD);
+
+MAKE_FAST_PATH (
+ a8r8g8b8_nearest_pad,
+ PIXMAN_a8r8g8b8, PIXMAN_FILTER_NEAREST, PIXMAN_REPEAT_PAD);
+
+MAKE_FAST_PATH (
+ x8r8g8b8_bilinear_pad,
+ PIXMAN_x8r8g8b8, PIXMAN_FILTER_BILINEAR, PIXMAN_REPEAT_PAD);
+
+MAKE_FAST_PATH (
+ x8r8g8b8_nearest_pad,
+ PIXMAN_x8r8g8b8, PIXMAN_FILTER_NEAREST, PIXMAN_REPEAT_PAD);
+
+MAKE_FAST_PATH (
+ x8r8g8b8_bilinear_none,
+ PIXMAN_x8r8g8b8, PIXMAN_FILTER_BILINEAR, PIXMAN_REPEAT_NONE);
+
static void
bits_image_fetch_solid_32 (pixman_image_t * image,
int x,
@@ -987,6 +1078,26 @@ bits_image_property_changed (pixman_image_t *image)
bits->common.need_workaround =
source_image_needs_out_of_bounds_workaround (bits);
+
+
+ if (bits->format == PIXMAN_a8r8g8b8 &&
+ bits->common.filter == PIXMAN_FILTER_BILINEAR &&
+ bits->common.repeat == PIXMAN_REPEAT_PAD &&
+ !bits->read_func &&
+ !bits->write_func &&
+ !bits->common.alpha_map)
+ {
+ bits->common.get_scanline_32 = bits_image_fetch_a8r8g8b8_bilinear_pad;
+ }
+ else if (bits->format == PIXMAN_x8r8g8b8 &&
+ (bits->common.filter == PIXMAN_FILTER_BILINEAR ||
+ bits->common.filter == PIXMAN_FILTER_GOOD) &&
+ !bits->read_func &&
+ !bits->write_func &&
+ !bits->common.alpha_map)
+ {
+ bits->common.get_scanline_32 = bits_image_fetch_x8r8g8b8_bilinear_none;
+ }
}
static uint32_t *