[Pixman] [PATCH] bits-image: Turn all the fetchers into iterator getters
Søren Sandmann
sandmann at cs.au.dk
Mon Jun 4 02:19:58 PDT 2012
From: Søren Sandmann Pedersen <ssp at redhat.com>
Instead of caching these fetchers in the image structure, and then
have the iterator getter call them from there, simply change them to
be iterator getters themselves.
This avoids an extra indirect function call and lets us get rid of the
get_scanline_32/64 fields in pixman_image_t.
---
pixman/pixman-bits-image.c | 214 +++++++++++++++++++++++---------------------
pixman/pixman-private.h | 4 +-
2 files changed, 114 insertions(+), 104 deletions(-)
diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 3ba6739..05eab96 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -42,14 +42,14 @@
* we could produce smoother gradients by evaluating them at higher color
* depth, but that's a project for the future.
*/
-static void
-_pixman_image_get_scanline_generic_64 (pixman_image_t * image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t * mask)
+static uint32_t *
+_pixman_image_get_scanline_generic_64 (pixman_iter_t * iter,
+ const uint32_t *mask)
{
+ int width = iter->width;
+ uint32_t * buffer = iter->buffer;
+
+ pixman_iter_get_scanline_t fetch_32 = iter->data;
uint32_t *mask8 = NULL;
/* Contract the mask image, if one exists, so that the 32-bit fetch
@@ -59,18 +59,20 @@ _pixman_image_get_scanline_generic_64 (pixman_image_t * image,
{
mask8 = pixman_malloc_ab (width, sizeof(uint32_t));
if (!mask8)
- return;
+ return buffer;
pixman_contract (mask8, (uint64_t *)mask, width);
}
/* Fetch the source image into the first half of buffer. */
- image->bits.get_scanline_32 (image, x, y, width, (uint32_t*)buffer, mask8);
+ fetch_32 (iter, mask8);
/* Expand from 32bpp to 64bpp in place. */
pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, width);
free (mask8);
+
+ return buffer;
}
/* Fetch functions */
@@ -160,14 +162,17 @@ bits_image_fetch_pixel_bilinear (bits_image_t *image,
return bilinear_interpolation (tl, tr, bl, br, distx, disty);
}
-static void
-bits_image_fetch_bilinear_no_repeat_8888 (pixman_image_t * ima,
- int offset,
- int line,
- int width,
- uint32_t * buffer,
- const uint32_t * mask)
+static uint32_t *
+bits_image_fetch_bilinear_no_repeat_8888 (pixman_iter_t *iter,
+ const uint32_t *mask)
{
+
+ pixman_image_t * ima = iter->image;
+ int offset = iter->x;
+ int line = iter->y++;
+ int width = iter->width;
+ uint32_t * buffer = iter->buffer;
+
bits_image_t *bits = &ima->bits;
pixman_fixed_t x_top, x_bottom, x;
pixman_fixed_t ux_top, ux_bottom, ux;
@@ -189,7 +194,7 @@ bits_image_fetch_bilinear_no_repeat_8888 (pixman_image_t * ima,
v.vector[2] = pixman_fixed_1;
if (!pixman_transform_point_3d (bits->common.transform, &v))
- return;
+ return iter->buffer;
ux = ux_top = ux_bottom = bits->common.transform->matrix[0][0];
x = x_top = x_bottom = v.vector[0] - pixman_fixed_1/2;
@@ -256,7 +261,7 @@ bits_image_fetch_bilinear_no_repeat_8888 (pixman_image_t * ima,
if (top_row == zero && bottom_row == zero)
{
memset (buffer, 0, width * sizeof (uint32_t));
- return;
+ return iter->buffer;
}
else if (bits->format == PIXMAN_x8r8g8b8)
{
@@ -368,6 +373,8 @@ bits_image_fetch_bilinear_no_repeat_8888 (pixman_image_t * ima,
/* Zero fill to the left of the image */
while (buffer < end)
*buffer++ = 0;
+
+ return iter->buffer;
}
static force_inline uint32_t
@@ -474,14 +481,16 @@ bits_image_fetch_pixel_filtered (bits_image_t *image,
return 0;
}
-static void
-bits_image_fetch_affine_no_alpha (pixman_image_t * image,
- int offset,
- int line,
- int width,
- uint32_t * buffer,
+static uint32_t *
+bits_image_fetch_affine_no_alpha (pixman_iter_t * iter,
const uint32_t * mask)
{
+ pixman_image_t *image = iter->image;
+ int offset = iter->x;
+ int line = iter->y++;
+ int width = iter->width;
+ uint32_t * buffer = iter->buffer;
+
pixman_fixed_t x, y;
pixman_fixed_t ux, uy;
pixman_vector_t v;
@@ -495,7 +504,7 @@ bits_image_fetch_affine_no_alpha (pixman_image_t * image,
if (image->common.transform)
{
if (!pixman_transform_point_3d (image->common.transform, &v))
- return;
+ return iter->buffer;
ux = image->common.transform->matrix[0][0];
uy = image->common.transform->matrix[1][0];
@@ -520,6 +529,8 @@ bits_image_fetch_affine_no_alpha (pixman_image_t * image,
x += ux;
y += uy;
}
+
+ return buffer;
}
/* General fetcher */
@@ -563,14 +574,16 @@ fetch_pixel_general (bits_image_t *image, int x, int y, pixman_bool_t check_boun
return pixel;
}
-static void
-bits_image_fetch_general (pixman_image_t * image,
- int offset,
- int line,
- int width,
- uint32_t * buffer,
- const uint32_t * mask)
+static uint32_t *
+bits_image_fetch_general (pixman_iter_t *iter,
+ const uint32_t *mask)
{
+ pixman_image_t *image = iter->image;
+ int offset = iter->x;
+ int line = iter->y++;
+ int width = iter->width;
+ uint32_t * buffer = iter->buffer;
+
pixman_fixed_t x, y, w;
pixman_fixed_t ux, uy, uw;
pixman_vector_t v;
@@ -584,7 +597,7 @@ bits_image_fetch_general (pixman_image_t * image,
if (image->common.transform)
{
if (!pixman_transform_point_3d (image->common.transform, &v))
- return;
+ return buffer;
ux = image->common.transform->matrix[0][0];
uy = image->common.transform->matrix[1][0];
@@ -626,6 +639,8 @@ bits_image_fetch_general (pixman_image_t * image,
y += uy;
w += uw;
}
+
+ return buffer;
}
static const uint8_t zero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
@@ -882,35 +897,33 @@ convert_r5g6b5 (const uint8_t *row, int x)
}
#define MAKE_BILINEAR_FETCHER(name, format, repeat_mode) \
- static void \
- bits_image_fetch_bilinear_affine_ ## name (pixman_image_t *image, \
- int offset, \
- int line, \
- int width, \
- uint32_t * buffer, \
+ static uint32_t * \
+ bits_image_fetch_bilinear_affine_ ## name (pixman_iter_t *iter, \
const uint32_t * mask) \
{ \
- bits_image_fetch_bilinear_affine (image, offset, line, \
- width, buffer, mask, \
+ bits_image_fetch_bilinear_affine (iter->image, \
+ iter->x, iter->y++, \
+ iter->width, \
+ iter->buffer, mask, \
convert_ ## format, \
PIXMAN_ ## format, \
repeat_mode); \
+ return iter->buffer; \
}
#define MAKE_NEAREST_FETCHER(name, format, repeat_mode) \
- static void \
- bits_image_fetch_nearest_affine_ ## name (pixman_image_t *image, \
- int offset, \
- int line, \
- int width, \
- uint32_t * buffer, \
+ static uint32_t * \
+ bits_image_fetch_nearest_affine_ ## name (pixman_iter_t *iter, \
const uint32_t * mask) \
{ \
- bits_image_fetch_nearest_affine (image, offset, line, \
- width, buffer, mask, \
+ bits_image_fetch_nearest_affine (iter->image, \
+ iter->x, iter->y++, \
+ iter->width, \
+ iter->buffer, mask, \
convert_ ## format, \
PIXMAN_ ## format, \
repeat_mode); \
+ return iter->buffer; \
}
#define MAKE_FETCHERS(name, format, repeat_mode) \
@@ -1059,14 +1072,16 @@ bits_image_fetch_untransformed_repeat_normal (bits_image_t *image,
}
}
-static void
-bits_image_fetch_untransformed_32 (pixman_image_t * image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t * mask)
+static uint32_t *
+bits_image_fetch_untransformed_32 (pixman_iter_t * iter,
+ const uint32_t *mask)
{
+ pixman_image_t *image = iter->image;
+ int x = iter->x;
+ int y = iter->y;
+ int width = iter->width;
+ uint32_t * buffer = iter->buffer;
+
if (image->common.repeat == PIXMAN_REPEAT_NONE)
{
bits_image_fetch_untransformed_repeat_none (
@@ -1077,16 +1092,22 @@ bits_image_fetch_untransformed_32 (pixman_image_t * image,
bits_image_fetch_untransformed_repeat_normal (
&image->bits, FALSE, x, y, width, buffer);
}
+
+ iter->y++;
+ return buffer;
}
-static void
-bits_image_fetch_untransformed_64 (pixman_image_t * image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t * unused)
+static uint32_t *
+bits_image_fetch_untransformed_64 (pixman_iter_t * iter,
+ const uint32_t *mask)
+
{
+ pixman_image_t *image = iter->image;
+ int x = iter->x;
+ int y = iter->y;
+ int width = iter->width;
+ uint32_t * buffer = iter->buffer;
+
if (image->common.repeat == PIXMAN_REPEAT_NONE)
{
bits_image_fetch_untransformed_repeat_none (
@@ -1097,14 +1118,21 @@ bits_image_fetch_untransformed_64 (pixman_image_t * image,
bits_image_fetch_untransformed_repeat_normal (
&image->bits, TRUE, x, y, width, buffer);
}
+
+ iter->y++;
+ return buffer;
}
+static uint32_t *
+_pixman_image_get_scanline_generic_64 (pixman_iter_t *iter,
+ const uint32_t * mask);
+
typedef struct
{
pixman_format_code_t format;
uint32_t flags;
- fetch_scanline_t fetch_32;
- fetch_scanline_t fetch_64;
+ pixman_iter_get_scanline_t get_scanline_32;
+ pixman_iter_get_scanline_t get_scanline_64;
} fetcher_info_t;
static const fetcher_info_t fetcher_info[] =
@@ -1206,52 +1234,36 @@ static const fetcher_info_t fetcher_info[] =
static void
bits_image_property_changed (pixman_image_t *image)
{
- uint32_t flags = image->common.flags;
+ _pixman_bits_image_setup_accessors (&image->bits);
+}
+
+void
+_pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter)
+{
pixman_format_code_t format = image->common.extended_format_code;
+ uint32_t flags = image->common.flags;
const fetcher_info_t *info;
- _pixman_bits_image_setup_accessors (&image->bits);
-
- info = fetcher_info;
- while (info->format != PIXMAN_null)
+ for (info = fetcher_info; info->format != PIXMAN_null; ++info)
{
if ((info->format == format || info->format == PIXMAN_any) &&
(info->flags & flags) == info->flags)
{
- image->bits.get_scanline_32 = info->fetch_32;
- image->bits.get_scanline_64 = info->fetch_64;
- break;
+ if (iter->iter_flags & ITER_NARROW)
+ {
+ iter->get_scanline = info->get_scanline_32;
+ }
+ else
+ {
+ iter->data = info->get_scanline_32;
+ iter->get_scanline = info->get_scanline_64;
+ }
+ return;
}
-
- info++;
}
-}
-static uint32_t *
-src_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
-{
- iter->image->bits.get_scanline_32 (
- iter->image, iter->x, iter->y++, iter->width, iter->buffer, mask);
-
- return iter->buffer;
-}
-
-static uint32_t *
-src_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
-{
- iter->image->bits.get_scanline_64 (
- iter->image, iter->x, iter->y++, iter->width, iter->buffer, mask);
-
- return iter->buffer;
-}
-
-void
-_pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter)
-{
- if (iter->iter_flags & ITER_NARROW)
- iter->get_scanline = src_get_scanline_narrow;
- else
- iter->get_scanline = src_get_scanline_wide;
+ /* Just in case we somehow didn't find a scanline function */
+ iter->get_scanline = _pixman_iter_get_scanline_noop;
}
static uint32_t *
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index f4ca632..7922773 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -154,9 +154,6 @@ struct bits_image
uint32_t * free_me;
int rowstride; /* in number of uint32_t's */
- fetch_scanline_t get_scanline_32;
- fetch_scanline_t get_scanline_64;
-
fetch_scanline_t fetch_scanline_32;
fetch_pixel_32_t fetch_pixel_32;
store_scanline_t store_scanline_32;
@@ -226,6 +223,7 @@ struct pixman_iter_t
pixman_iter_write_back_t write_back;
/* These fields are scratch data that implementations can use */
+ void * data;
uint8_t * bits;
int stride;
};
--
1.7.4
More information about the Pixman
mailing list