summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2012-01-08 13:21:11 -0500
committerSøren Sandmann Pedersen <ssp@redhat.com>2012-06-11 07:15:00 -0400
commitf80e7ad3cbf46218bb3b4247e7b9e5d448670ad8 (patch)
treee0f98b4d3e22662c85e557fba7f2d5a271b9e1fe
parentfd175f9d02f36b1e91973e4264519228547f5dc7 (diff)
bits-image: Turn all the fetchers into iterator getters
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.
-rw-r--r--pixman/pixman-bits-image.c214
-rw-r--r--pixman/pixman-private.h4
2 files changed, 114 insertions, 104 deletions
diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 3ba6739d..05eab963 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 873f3218..72e3b4f6 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -155,9 +155,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;
@@ -227,6 +224,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;
};