pixman: Branch 'master' - 15 commits
Søren Sandmann Pedersen
sandmann at kemper.freedesktop.org
Tue Jan 18 09:45:45 PST 2011
pixman/pixman-arm-common.h | 9 -
pixman/pixman-bits-image.c | 230 ++++++++++++++++++++++++++-----
pixman/pixman-conical-gradient.c | 45 ++++--
pixman/pixman-fast-path.c | 22 +-
pixman/pixman-general.c | 288 +++++++++++++++++++--------------------
pixman/pixman-image.c | 92 +-----------
pixman/pixman-implementation.c | 81 ++++++++++
pixman/pixman-linear-gradient.c | 86 +++++++----
pixman/pixman-mmx.c | 22 +-
pixman/pixman-private.h | 169 ++++++++++++++--------
pixman/pixman-radial-gradient.c | 44 ++++-
pixman/pixman-solid-fill.c | 75 +++-------
pixman/pixman-sse2.c | 30 ++--
pixman/pixman-utils.c | 6
test/alphamap.c | 11 -
15 files changed, 739 insertions(+), 471 deletions(-)
New commits:
commit 7f4eabbeec92e55fd8f812c0e5d8568eacbb633d
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date: Sun Dec 12 07:34:42 2010 -0500
Fix destination fetching
When fetching from destinations, we need to ignore transformations,
repeat and filtering. Currently we don't ignore them, which means all
kinds of bad things can happen.
This bug fixes this problem by directly calling the scanline fetchers
for destinations instead of going through the full
get_scanline_32/64().
diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 8cabfdc..98a2b6d 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -1377,8 +1377,22 @@ _pixman_bits_image_src_iter_init (pixman_image_t *image,
static uint32_t *
dest_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);
+ pixman_image_t *image = iter->image;
+ int x = iter->x;
+ int y = iter->y;
+ int width = iter->width;
+ uint32_t * buffer = iter->buffer;
+
+ image->bits.fetch_scanline_32 (image, x, y, width, buffer, mask);
+ if (image->common.alpha_map)
+ {
+ x -= image->common.alpha_origin_x;
+ y -= image->common.alpha_origin_y;
+
+ image->common.alpha_map->fetch_scanline_32 (
+ (pixman_image_t *)image->common.alpha_map,
+ x, y, width, buffer, mask);
+ }
return iter->buffer;
}
@@ -1386,8 +1400,22 @@ dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
static uint32_t *
dest_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);
+ bits_image_t * image = &iter->image->bits;
+ int x = iter->x;
+ int y = iter->y;
+ int width = iter->width;
+ uint32_t * buffer = iter->buffer;
+
+ image->fetch_scanline_64 (
+ (pixman_image_t *)image, x, y, width, buffer, mask);
+ if (image->common.alpha_map)
+ {
+ x -= image->common.alpha_origin_x;
+ y -= image->common.alpha_origin_y;
+
+ image->common.alpha_map->fetch_scanline_64 (
+ (pixman_image_t *)image->common.alpha_map, x, y, width, buffer, mask);
+ }
return iter->buffer;
}
commit 9489c2e04a5361fe19a89a0da9d7be28436c0a4b
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date: Sun Dec 12 09:19:13 2010 -0500
Turn on testing for destination transformation
diff --git a/test/alphamap.c b/test/alphamap.c
index 9fb8969..554b309 100644
--- a/test/alphamap.c
+++ b/test/alphamap.c
@@ -165,20 +165,17 @@ run_test (int s, int d, int sa, int da, int soff, int doff)
orig_dst = create_image (df, daf, doff, doff);
dst = create_image (df, daf, doff, doff);
- /* Transformations on destinations should be ignored, so just set some
- * random one.
+ /* Transformations, repeats and filters on destinations should be ignored,
+ * so just set some random ones.
*/
pixman_transform_init_identity (&t1);
pixman_transform_scale (&t1, NULL, pixman_int_to_fixed (100), pixman_int_to_fixed (11));
pixman_transform_rotate (&t1, NULL, pixman_double_to_fixed (0.5), pixman_double_to_fixed (0.11));
pixman_transform_translate (&t1, NULL, pixman_int_to_fixed (11), pixman_int_to_fixed (17));
-#if 0
- /* Unfortunately, this is actually broken at the moment, so we can't
- * actually turn it on
- */
pixman_image_set_transform (dst, &t1);
-#endif
+ pixman_image_set_filter (dst, PIXMAN_FILTER_BILINEAR, NULL, 0);
+ pixman_image_set_repeat (dst, PIXMAN_REPEAT_REFLECT);
pixman_image_composite (PIXMAN_OP_SRC, orig_dst, NULL, dst,
0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
commit fffeda703e40ced90ec5ad6d6cd37a44294d3fe4
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date: Sat Dec 11 08:10:04 2010 -0500
Skip fetching pixels when possible
Add two new iterator flags, ITER_IGNORE_ALPHA and ITER_IGNORE_RGB that
are set when the alpha and rgb values are not needed. If both are set,
then we can skip fetching entirely and just use
_pixman_iter_get_scanline_noop.
diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 8d4e4f5..8cabfdc 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -1466,7 +1466,16 @@ _pixman_bits_image_dest_iter_init (pixman_image_t *image,
}
else
{
- iter->get_scanline = dest_get_scanline_narrow;
+ if ((flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) ==
+ (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA))
+ {
+ iter->get_scanline = _pixman_iter_get_scanline_noop;
+ }
+ else
+ {
+ iter->get_scanline = dest_get_scanline_narrow;
+ }
+
iter->write_back = dest_write_back_narrow;
}
}
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index e7a7283..16ea3a4 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -107,6 +107,34 @@ general_dest_iter_init (pixman_implementation_t *imp,
}
}
+typedef struct op_info_t op_info_t;
+struct op_info_t
+{
+ uint8_t src, dst;
+};
+
+#define ITER_IGNORE_BOTH \
+ (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB | ITER_LOCALIZED_ALPHA)
+
+static const op_info_t op_flags[PIXMAN_N_OPERATORS] =
+{
+ /* Src Dst */
+ { ITER_IGNORE_BOTH, ITER_IGNORE_BOTH }, /* CLEAR */
+ { ITER_LOCALIZED_ALPHA, ITER_IGNORE_BOTH }, /* SRC */
+ { ITER_IGNORE_BOTH, ITER_LOCALIZED_ALPHA }, /* DST */
+ { 0, ITER_LOCALIZED_ALPHA }, /* OVER */
+ { ITER_LOCALIZED_ALPHA, 0 }, /* OVER_REVERSE */
+ { ITER_LOCALIZED_ALPHA, ITER_IGNORE_RGB }, /* IN */
+ { ITER_IGNORE_RGB, ITER_LOCALIZED_ALPHA }, /* IN_REVERSE */
+ { ITER_LOCALIZED_ALPHA, ITER_IGNORE_RGB }, /* OUT */
+ { ITER_IGNORE_RGB, ITER_LOCALIZED_ALPHA }, /* OUT_REVERSE */
+ { 0, 0 }, /* ATOP */
+ { 0, 0 }, /* ATOP_REVERSE */
+ { 0, 0 }, /* XOR */
+ { ITER_LOCALIZED_ALPHA, ITER_LOCALIZED_ALPHA }, /* ADD */
+ { 0, 0 }, /* SATURATE */
+};
+
#define SCANLINE_BUFFER_LENGTH 8192
static void
@@ -130,7 +158,7 @@ general_composite_rect (pixman_implementation_t *imp,
pixman_iter_t src_iter, mask_iter, dest_iter;
pixman_combine_32_func_t compose;
pixman_bool_t component_alpha;
- iter_flags_t narrow, dest_flags;
+ iter_flags_t narrow, src_flags;
int Bpp;
int i;
@@ -159,39 +187,39 @@ general_composite_rect (pixman_implementation_t *imp,
mask_buffer = src_buffer + width * Bpp;
dest_buffer = mask_buffer + width * Bpp;
+ /* src iter */
+ src_flags = narrow | op_flags[op].src;
+
_pixman_implementation_src_iter_init (imp->toplevel, &src_iter, src,
src_x, src_y, width, height,
- src_buffer, narrow);
-
- _pixman_implementation_src_iter_init (imp->toplevel, &mask_iter, mask,
- mask_x, mask_y, width, height,
- mask_buffer, narrow);
-
- if (op == PIXMAN_OP_CLEAR ||
- op == PIXMAN_OP_SRC ||
- op == PIXMAN_OP_DST ||
- op == PIXMAN_OP_OVER ||
- op == PIXMAN_OP_IN_REVERSE ||
- op == PIXMAN_OP_OUT_REVERSE ||
- op == PIXMAN_OP_ADD)
- {
- dest_flags = narrow | ITER_LOCALIZED_ALPHA;
- }
- else
+ src_buffer, src_flags);
+
+ /* mask iter */
+ if ((src_flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) ==
+ (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB))
{
- dest_flags = narrow;
+ /* If it doesn't matter what the source is, then it doesn't matter
+ * what the mask is
+ */
+ mask = NULL;
}
- _pixman_implementation_dest_iter_init (imp->toplevel, &dest_iter, dest,
- dest_x, dest_y, width, height,
- dest_buffer, dest_flags);
-
component_alpha =
mask &&
mask->common.type == BITS &&
mask->common.component_alpha &&
PIXMAN_FORMAT_RGB (mask->bits.format);
+ _pixman_implementation_src_iter_init (
+ imp->toplevel, &mask_iter, mask, mask_x, mask_y, width, height,
+ mask_buffer, narrow | (component_alpha? 0 : ITER_IGNORE_RGB));
+
+ /* dest iter */
+ _pixman_implementation_dest_iter_init (imp->toplevel, &dest_iter, dest,
+ dest_x, dest_y, width, height,
+ dest_buffer,
+ narrow | op_flags[op].dst);
+
if (narrow)
{
if (component_alpha)
diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index e633432..adaf9c6 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -278,6 +278,11 @@ _pixman_implementation_src_iter_init (pixman_implementation_t *imp,
{
iter->get_scanline = get_scanline_null;
}
+ else if ((flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) ==
+ (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB))
+ {
+ iter->get_scanline = _pixman_iter_get_scanline_noop;
+ }
else
{
(*imp->src_iter_init) (
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 0aeae2e..1662d2c 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -202,7 +202,9 @@ typedef enum
* we can treat it as if it were ARGB, which means in some cases we can
* avoid copying it to a temporary buffer.
*/
- ITER_LOCALIZED_ALPHA = (1 << 1)
+ ITER_LOCALIZED_ALPHA = (1 << 1),
+ ITER_IGNORE_ALPHA = (1 << 2),
+ ITER_IGNORE_RGB = (1 << 3)
} iter_flags_t;
struct pixman_iter_t
commit 3e635d6491d883304662aff3c72558dc9065f1f1
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date: Fri Dec 10 16:55:55 2010 -0500
Add direct-write optimization back
Introduce a new ITER_LOCALIZED_ALPHA flag that indicates that the
alpha value computed is used only for the alpha channel of the output;
it doesn't affect the RGB channels.
Then in pixman-bits-image.c, if a destination is either a8r8g8b8 or
x8r8g8b8 with localized alpha, the iterator will return a pointer
directly into the image.
diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 983e23c..8d4e4f5 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -1438,6 +1438,12 @@ dest_write_back_wide (pixman_iter_t *iter)
iter->y++;
}
+static void
+dest_write_back_direct (pixman_iter_t *iter)
+{
+ iter->buffer += iter->image->bits.rowstride;
+}
+
void
_pixman_bits_image_dest_iter_init (pixman_image_t *image,
pixman_iter_t *iter,
@@ -1446,8 +1452,23 @@ _pixman_bits_image_dest_iter_init (pixman_image_t *image,
{
if (flags & ITER_NARROW)
{
- iter->get_scanline = dest_get_scanline_narrow;
- iter->write_back = dest_write_back_narrow;
+ if (((image->common.flags &
+ (FAST_PATH_NO_ALPHA_MAP | FAST_PATH_NO_ACCESSORS)) ==
+ (FAST_PATH_NO_ALPHA_MAP | FAST_PATH_NO_ACCESSORS)) &&
+ (image->bits.format == PIXMAN_a8r8g8b8 ||
+ (image->bits.format == PIXMAN_x8r8g8b8 &&
+ (flags & ITER_LOCALIZED_ALPHA))))
+ {
+ iter->buffer = image->bits.bits + y * image->bits.rowstride + x;
+
+ iter->get_scanline = _pixman_iter_get_scanline_noop;
+ iter->write_back = dest_write_back_direct;
+ }
+ else
+ {
+ iter->get_scanline = dest_get_scanline_narrow;
+ iter->write_back = dest_write_back_narrow;
+ }
}
else
{
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index e2f1dc3..e7a7283 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -130,7 +130,7 @@ general_composite_rect (pixman_implementation_t *imp,
pixman_iter_t src_iter, mask_iter, dest_iter;
pixman_combine_32_func_t compose;
pixman_bool_t component_alpha;
- iter_flags_t narrow;
+ iter_flags_t narrow, dest_flags;
int Bpp;
int i;
@@ -167,9 +167,24 @@ general_composite_rect (pixman_implementation_t *imp,
mask_x, mask_y, width, height,
mask_buffer, narrow);
+ if (op == PIXMAN_OP_CLEAR ||
+ op == PIXMAN_OP_SRC ||
+ op == PIXMAN_OP_DST ||
+ op == PIXMAN_OP_OVER ||
+ op == PIXMAN_OP_IN_REVERSE ||
+ op == PIXMAN_OP_OUT_REVERSE ||
+ op == PIXMAN_OP_ADD)
+ {
+ dest_flags = narrow | ITER_LOCALIZED_ALPHA;
+ }
+ else
+ {
+ dest_flags = narrow;
+ }
+
_pixman_implementation_dest_iter_init (imp->toplevel, &dest_iter, dest,
dest_x, dest_y, width, height,
- dest_buffer, narrow);
+ dest_buffer, dest_flags);
component_alpha =
mask &&
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index c3321e1..0aeae2e 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -185,7 +185,24 @@ union pixman_image
typedef struct pixman_iter_t pixman_iter_t;
typedef enum
{
- ITER_NARROW = (1 << 0),
+ ITER_NARROW = (1 << 0),
+
+ /* "Localized alpha" is when the alpha channel is used only to compute
+ * the alpha value of the destination. This means that the computation
+ * of the RGB values of the result is independent of the alpha value.
+ *
+ * For example, the OVER operator has localized alpha for the
+ * destination, because the RGB values of the result can be computed
+ * without knowing the destination alpha. Similarly, ADD has localized
+ * alpha for both source and destination because the RGB values of the
+ * result can be computed without knowing the alpha value of source or
+ * destination.
+ *
+ * When he destination is xRGB, this is useful knowledge, because then
+ * we can treat it as if it were ARGB, which means in some cases we can
+ * avoid copying it to a temporary buffer.
+ */
+ ITER_LOCALIZED_ALPHA = (1 << 1)
} iter_flags_t;
struct pixman_iter_t
commit 0f1a5c4a27d34dcf4525dc38fcb48c14f653e828
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date: Fri Dec 10 15:18:48 2010 -0500
Get rid of the classify methods
They are not used anymore, and the linear gradient is now doing the
optimization in a different way.
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 1aa9de1..a72299b 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -72,7 +72,6 @@ _pixman_image_allocate (void)
common->alpha_map = NULL;
common->component_alpha = FALSE;
common->ref_count = 1;
- common->classify = NULL;
common->property_changed = NULL;
common->client_clip = FALSE;
common->destroy_func = NULL;
@@ -83,19 +82,6 @@ _pixman_image_allocate (void)
return image;
}
-source_image_class_t
-_pixman_image_classify (pixman_image_t *image,
- int x,
- int y,
- int width,
- int height)
-{
- if (image->common.classify)
- return image->common.classify (image, x, y, width, height);
- else
- return SOURCE_IMAGE_CLASS_UNKNOWN;
-}
-
static void
image_property_changed (pixman_image_t *image)
{
diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c
index 66d37ab..07303fc 100644
--- a/pixman/pixman-linear-gradient.c
+++ b/pixman/pixman-linear-gradient.c
@@ -31,21 +31,18 @@
#include <stdlib.h>
#include "pixman-private.h"
-static source_image_class_t
-linear_gradient_classify (pixman_image_t *image,
- int x,
- int y,
- int width,
- int height)
+static pixman_bool_t
+linear_gradient_is_horizontal (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ int height)
{
linear_gradient_t *linear = (linear_gradient_t *)image;
pixman_vector_t v;
pixman_fixed_32_32_t l;
pixman_fixed_48_16_t dx, dy;
double inc;
- source_image_class_t class;
-
- class = SOURCE_IMAGE_CLASS_UNKNOWN;
if (image->common.transform)
{
@@ -54,7 +51,7 @@ linear_gradient_classify (pixman_image_t *image,
image->common.transform->matrix[2][1] != 0 ||
image->common.transform->matrix[2][2] == 0)
{
- return class;
+ return FALSE;
}
v.vector[0] = image->common.transform->matrix[0][1];
@@ -74,7 +71,7 @@ linear_gradient_classify (pixman_image_t *image,
l = dx * dx + dy * dy;
if (l == 0)
- return class;
+ return FALSE;
/*
* compute how much the input of the gradient walked changes
@@ -86,9 +83,9 @@ linear_gradient_classify (pixman_image_t *image,
/* check that casting to integer would result in 0 */
if (-1 < inc && inc < 1)
- class = SOURCE_IMAGE_CLASS_HORIZONTAL;
+ return TRUE;
- return class;
+ return FALSE;
}
static uint32_t *
@@ -245,8 +242,7 @@ _pixman_linear_gradient_iter_init (pixman_image_t *image,
uint8_t *buffer,
iter_flags_t flags)
{
- if (linear_gradient_classify (image, x, y, width, height) ==
- SOURCE_IMAGE_CLASS_HORIZONTAL)
+ if (linear_gradient_is_horizontal (image, x, y, width, height))
{
if (flags & ITER_NARROW)
linear_get_scanline_narrow (iter, NULL);
@@ -290,7 +286,6 @@ pixman_image_create_linear_gradient (pixman_point_fixed_t * p1,
linear->p2 = *p2;
image->type = LINEAR;
- image->common.classify = linear_gradient_classify;
return image;
}
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index d7c7a62..c3321e1 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -60,17 +60,6 @@ typedef enum
SOLID
} image_type_t;
-typedef enum
-{
- SOURCE_IMAGE_CLASS_UNKNOWN,
- SOURCE_IMAGE_CLASS_HORIZONTAL,
-} source_image_class_t;
-
-typedef source_image_class_t (*classify_func_t) (pixman_image_t *image,
- int x,
- int y,
- int width,
- int height);
typedef void (*property_changed_func_t) (pixman_image_t *image);
struct image_common
@@ -95,7 +84,6 @@ struct image_common
int alpha_origin_x;
int alpha_origin_y;
pixman_bool_t component_alpha;
- classify_func_t classify;
property_changed_func_t property_changed;
pixman_image_destroy_func_t destroy_func;
@@ -249,13 +237,6 @@ _pixman_conical_gradient_iter_init (pixman_image_t *image,
int x, int y, int width, int height,
uint8_t *buffer, iter_flags_t flags);
-source_image_class_t
-_pixman_image_classify (pixman_image_t *image,
- int x,
- int y,
- int width,
- int height);
-
pixman_image_t *
_pixman_image_allocate (void);
diff --git a/pixman/pixman-solid-fill.c b/pixman/pixman-solid-fill.c
index a431d74..67681f2 100644
--- a/pixman/pixman-solid-fill.c
+++ b/pixman/pixman-solid-fill.c
@@ -26,16 +26,6 @@
#endif
#include "pixman-private.h"
-static source_image_class_t
-solid_fill_classify (pixman_image_t *image,
- int x,
- int y,
- int width,
- int height)
-{
- return SOURCE_IMAGE_CLASS_HORIZONTAL;
-}
-
void
_pixman_solid_fill_iter_init (pixman_image_t *image,
pixman_iter_t *iter,
@@ -97,8 +87,6 @@ pixman_image_create_solid_fill (pixman_color_t *color)
img->solid.color_32 = color_to_uint32 (color);
img->solid.color_64 = color_to_uint64 (color);
- img->common.classify = solid_fill_classify;
-
return img;
}
commit b66cabb88488413c4787845c7da67901dc988ee6
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date: Fri Dec 10 15:14:24 2010 -0500
Linear: Optimize for horizontal gradients
If the gradient is horizontal, we can reuse the same scanline over and
over. Add support for this optimization to
_pixman_linear_gradient_iter_init().
diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c
index c657243..66d37ab 100644
--- a/pixman/pixman-linear-gradient.c
+++ b/pixman/pixman-linear-gradient.c
@@ -245,10 +245,23 @@ _pixman_linear_gradient_iter_init (pixman_image_t *image,
uint8_t *buffer,
iter_flags_t flags)
{
- if (flags & ITER_NARROW)
- iter->get_scanline = linear_get_scanline_narrow;
+ if (linear_gradient_classify (image, x, y, width, height) ==
+ SOURCE_IMAGE_CLASS_HORIZONTAL)
+ {
+ if (flags & ITER_NARROW)
+ linear_get_scanline_narrow (iter, NULL);
+ else
+ linear_get_scanline_wide (iter, NULL);
+
+ iter->get_scanline = _pixman_iter_get_scanline_noop;
+ }
else
- iter->get_scanline = linear_get_scanline_wide;
+ {
+ if (flags & ITER_NARROW)
+ iter->get_scanline = linear_get_scanline_narrow;
+ else
+ iter->get_scanline = linear_get_scanline_wide;
+ }
}
PIXMAN_EXPORT pixman_image_t *
commit cf14189c6993e42ae71977a4a4061417941ffee8
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date: Fri Dec 10 14:59:20 2010 -0500
Consolidate the various get_scanline_32() into get_scanline_narrow()
The separate get_scanline_32() functions in solid, linear, radial and
conical images are no longer necessary because all access to these
images now go through iterators.
diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c
index d43b454..9d7d2e8 100644
--- a/pixman/pixman-conical-gradient.c
+++ b/pixman/pixman-conical-gradient.c
@@ -50,14 +50,15 @@ coordinates_to_parameter (double x, double y, double angle)
*/
}
-static void
-conical_gradient_get_scanline_32 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
+static uint32_t *
+conical_get_scanline_narrow (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;
+
gradient_t *gradient = (gradient_t *)image;
conical_gradient_t *conical = (conical_gradient_t *)image;
uint32_t *end = buffer + width;
@@ -82,7 +83,7 @@ conical_gradient_get_scanline_32 (pixman_image_t *image,
v.vector[2] = pixman_fixed_1;
if (!pixman_transform_point_3d (image->common.transform, &v))
- return;
+ return iter->buffer;
cx = image->common.transform->matrix[0][0] / 65536.;
cy = image->common.transform->matrix[1][0] / 65536.;
@@ -154,14 +155,6 @@ conical_gradient_get_scanline_32 (pixman_image_t *image,
rz += cz;
}
}
-}
-
-static uint32_t *
-conical_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
-{
- conical_gradient_get_scanline_32 (iter->image, iter->x, iter->y,
- iter->width, iter->buffer,
- mask);
iter->y++;
return iter->buffer;
diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c
index 4c0792c..c657243 100644
--- a/pixman/pixman-linear-gradient.c
+++ b/pixman/pixman-linear-gradient.c
@@ -91,14 +91,16 @@ linear_gradient_classify (pixman_image_t *image,
return class;
}
-static void
-linear_get_scanline_32 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
+static uint32_t *
+linear_get_scanline_narrow (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;
+
pixman_vector_t v, unit;
pixman_fixed_32_32_t l;
pixman_fixed_48_16_t dx, dy;
@@ -117,7 +119,7 @@ linear_get_scanline_32 (pixman_image_t *image,
if (image->common.transform)
{
if (!pixman_transform_point_3d (image->common.transform, &v))
- return;
+ return iter->buffer;
unit.vector[0] = image->common.transform->matrix[0][0];
unit.vector[1] = image->common.transform->matrix[1][0];
@@ -217,19 +219,6 @@ linear_get_scanline_32 (pixman_image_t *image,
v.vector[2] += unit.vector[2];
}
}
-}
-
-static uint32_t *
-linear_get_scanline_narrow (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;
-
- linear_get_scanline_32 (image, x, y, width, buffer, mask);
iter->y++;
diff --git a/pixman/pixman-radial-gradient.c b/pixman/pixman-radial-gradient.c
index d1017d2..6523b82 100644
--- a/pixman/pixman-radial-gradient.c
+++ b/pixman/pixman-radial-gradient.c
@@ -144,13 +144,8 @@ radial_compute_color (double a,
return 0;
}
-static void
-radial_gradient_get_scanline_32 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
+static uint32_t *
+radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
{
/*
* Implementation of radial gradients following the PDF specification.
@@ -233,6 +228,11 @@ radial_gradient_get_scanline_32 (pixman_image_t *image,
* <=> for every p, the radiuses associated with the two t solutions
* have opposite sign
*/
+ pixman_image_t *image = iter->image;
+ int x = iter->x;
+ int y = iter->y;
+ int width = iter->width;
+ uint32_t *buffer = iter->buffer;
gradient_t *gradient = (gradient_t *)image;
radial_gradient_t *radial = (radial_gradient_t *)image;
@@ -250,7 +250,7 @@ radial_gradient_get_scanline_32 (pixman_image_t *image,
if (image->common.transform)
{
if (!pixman_transform_point_3d (image->common.transform, &v))
- return;
+ return iter->buffer;
unit.vector[0] = image->common.transform->matrix[0][0];
unit.vector[1] = image->common.transform->matrix[1][0];
@@ -384,14 +384,6 @@ radial_gradient_get_scanline_32 (pixman_image_t *image,
v.vector[2] += unit.vector[2];
}
}
-}
-
-static uint32_t *
-radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
-{
- radial_gradient_get_scanline_32 (
- iter->image, iter->x, iter->y, iter->width,
- iter->buffer, mask);
iter->y++;
return iter->buffer;
diff --git a/pixman/pixman-solid-fill.c b/pixman/pixman-solid-fill.c
index 2531dbd..a431d74 100644
--- a/pixman/pixman-solid-fill.c
+++ b/pixman/pixman-solid-fill.c
@@ -26,39 +26,6 @@
#endif
#include "pixman-private.h"
-static void
-solid_fill_get_scanline_32 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- uint32_t *end = buffer + width;
- uint32_t color = image->solid.color_32;
-
- while (buffer < end)
- *(buffer++) = color;
-
- return;
-}
-
-static void
-solid_fill_get_scanline_64 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- uint64_t *b = (uint64_t *)buffer;
- uint64_t *e = b + width;
- uint64_t color = image->solid.color_64;
-
- while (b < e)
- *(b++) = color;
-}
-
static source_image_class_t
solid_fill_classify (pixman_image_t *image,
int x,
@@ -77,13 +44,21 @@ _pixman_solid_fill_iter_init (pixman_image_t *image,
{
if (flags & ITER_NARROW)
{
- solid_fill_get_scanline_32 (
- image, x, y, width, (uint32_t *)buffer, NULL);
+ uint32_t *b = (uint32_t *)buffer;
+ uint32_t *e = b + width;
+ uint32_t color = image->solid.color_32;
+
+ while (b < e)
+ *(b++) = color;
}
else
{
- solid_fill_get_scanline_64 (
- image, x, y, width, (uint32_t *)buffer, NULL);
+ uint64_t *b = (uint64_t *)buffer;
+ uint64_t *e = b + width;
+ uint64_t color = image->solid.color_64;
+
+ while (b < e)
+ *(b++) = color;
}
iter->get_scanline = _pixman_iter_get_scanline_noop;
commit 0a6360a7ee0983dd52d368f5352d8c313fb0570b
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date: Fri Dec 10 14:44:22 2010 -0500
Allow NULL property_changed function
Initialize the field to NULL, and then delete the empty functions from
the solid, linear, radial, and conical images.
diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c
index a00170b..d43b454 100644
--- a/pixman/pixman-conical-gradient.c
+++ b/pixman/pixman-conical-gradient.c
@@ -156,11 +156,6 @@ conical_gradient_get_scanline_32 (pixman_image_t *image,
}
}
-static void
-conical_gradient_property_changed (pixman_image_t *image)
-{
-}
-
static uint32_t *
conical_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
{
@@ -221,8 +216,6 @@ pixman_image_create_conical_gradient (pixman_point_fixed_t * center,
conical->center = *center;
conical->angle = (pixman_fixed_to_double (angle) / 180.0) * M_PI;
- image->common.property_changed = conical_gradient_property_changed;
-
return image;
}
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index e059286..1aa9de1 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -73,6 +73,7 @@ _pixman_image_allocate (void)
common->component_alpha = FALSE;
common->ref_count = 1;
common->classify = NULL;
+ common->property_changed = NULL;
common->client_clip = FALSE;
common->destroy_func = NULL;
common->destroy_data = NULL;
@@ -416,7 +417,8 @@ _pixman_image_validate (pixman_image_t *image)
* property_changed() can make use of the flags
* to set up accessors etc.
*/
- image->common.property_changed (image);
+ if (image->common.property_changed)
+ image->common.property_changed (image);
image->common.dirty = FALSE;
}
diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c
index a19d9a8..4c0792c 100644
--- a/pixman/pixman-linear-gradient.c
+++ b/pixman/pixman-linear-gradient.c
@@ -219,11 +219,6 @@ linear_get_scanline_32 (pixman_image_t *image,
}
}
-static void
-linear_gradient_property_changed (pixman_image_t *image)
-{
-}
-
static uint32_t *
linear_get_scanline_narrow (pixman_iter_t *iter,
const uint32_t *mask)
@@ -294,7 +289,6 @@ pixman_image_create_linear_gradient (pixman_point_fixed_t * p1,
image->type = LINEAR;
image->common.classify = linear_gradient_classify;
- image->common.property_changed = linear_gradient_property_changed;
return image;
}
diff --git a/pixman/pixman-radial-gradient.c b/pixman/pixman-radial-gradient.c
index 5121827..d1017d2 100644
--- a/pixman/pixman-radial-gradient.c
+++ b/pixman/pixman-radial-gradient.c
@@ -386,11 +386,6 @@ radial_gradient_get_scanline_32 (pixman_image_t *image,
}
}
-static void
-radial_gradient_property_changed (pixman_image_t *image)
-{
-}
-
static uint32_t *
radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
{
@@ -471,8 +466,6 @@ pixman_image_create_radial_gradient (pixman_point_fixed_t * inner,
radial->mindr = -1. * pixman_fixed_1 * radial->c1.radius;
- image->common.property_changed = radial_gradient_property_changed;
-
return image;
}
diff --git a/pixman/pixman-solid-fill.c b/pixman/pixman-solid-fill.c
index f2df3c7..2531dbd 100644
--- a/pixman/pixman-solid-fill.c
+++ b/pixman/pixman-solid-fill.c
@@ -69,11 +69,6 @@ solid_fill_classify (pixman_image_t *image,
return SOURCE_IMAGE_CLASS_HORIZONTAL;
}
-static void
-solid_fill_property_changed (pixman_image_t *image)
-{
-}
-
void
_pixman_solid_fill_iter_init (pixman_image_t *image,
pixman_iter_t *iter,
@@ -128,7 +123,6 @@ pixman_image_create_solid_fill (pixman_color_t *color)
img->solid.color_64 = color_to_uint64 (color);
img->common.classify = solid_fill_classify;
- img->common.property_changed = solid_fill_property_changed;
return img;
}
commit 34b5633105e5e2838ac8deb32d26e3bbe73a3d1a
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date: Fri Dec 10 14:39:01 2010 -0500
Move get_scanline_32/64 to the bits part of the image struct
At this point these functions are basically a cache that the bits
image uses for its fetchers, so they can be moved to the bits image.
With the scanline getters only being initialized in the bits image,
the _pixman_image_get_scanline_generic_64 can be moved to
pixman-bits-image.c. That gets rid of the final user of
_pixman_image_get_scanline_32/64, so these can be deleted.
diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index bf22dbf..983e23c 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -35,6 +35,43 @@
#include "pixman-private.h"
#include "pixman-combine32.h"
+/*
+ * 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.
+ */
+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)
+{
+ 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, (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);
+
+ /* Expand from 32bpp to 64bpp in place. */
+ pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, width);
+
+ free (mask8);
+}
+
/* Fetch functions */
static force_inline uint32_t
@@ -1298,8 +1335,8 @@ bits_image_property_changed (pixman_image_t *image)
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;
+ image->bits.get_scanline_32 = info->fetch_32;
+ image->bits.get_scanline_64 = info->fetch_64;
break;
}
@@ -1310,7 +1347,7 @@ bits_image_property_changed (pixman_image_t *image)
static uint32_t *
src_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
{
- iter->image->common.get_scanline_32 (
+ iter->image->bits.get_scanline_32 (
iter->image, iter->x, iter->y++, iter->width, iter->buffer, mask);
return iter->buffer;
@@ -1319,7 +1356,7 @@ src_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
static uint32_t *
src_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
{
- iter->image->common.get_scanline_64 (
+ iter->image->bits.get_scanline_64 (
iter->image, iter->x, iter->y++, iter->width, iter->buffer, mask);
return iter->buffer;
@@ -1340,7 +1377,7 @@ _pixman_bits_image_src_iter_init (pixman_image_t *image,
static uint32_t *
dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
{
- iter->image->common.get_scanline_32 (
+ iter->image->bits.get_scanline_32 (
iter->image, iter->x, iter->y, iter->width, iter->buffer, mask);
return iter->buffer;
@@ -1349,7 +1386,7 @@ dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
static uint32_t *
dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
{
- iter->image->common.get_scanline_64 (
+ iter->image->bits.get_scanline_64 (
iter->image, iter->x, iter->y, iter->width, iter->buffer, mask);
return iter->buffer;
diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c
index 35913cb..a00170b 100644
--- a/pixman/pixman-conical-gradient.c
+++ b/pixman/pixman-conical-gradient.c
@@ -159,8 +159,6 @@ conical_gradient_get_scanline_32 (pixman_image_t *image,
static void
conical_gradient_property_changed (pixman_image_t *image)
{
- image->common.get_scanline_32 = conical_gradient_get_scanline_32;
- image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
}
static uint32_t *
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index b487df0..e059286 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -50,43 +50,6 @@ _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_generic_64 (pixman_image_t * image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t * mask)
-{
- 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, (uint64_t *)mask, width);
- }
-
- /* Fetch the source image into the first half of buffer. */
- _pixman_image_get_scanline_32 (image, x, y, width, (uint32_t*)buffer, mask8);
-
- /* Expand from 32bpp to 64bpp in place. */
- pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, width);
-
- free (mask8);
-}
-
pixman_image_t *
_pixman_image_allocate (void)
{
@@ -132,31 +95,6 @@ _pixman_image_classify (pixman_image_t *image,
return SOURCE_IMAGE_CLASS_UNKNOWN;
}
-void
-_pixman_image_get_scanline_32 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- image->common.get_scanline_32 (image, x, y, width, buffer, mask);
-}
-
-/* Even thought the type of buffer is uint32_t *, the function actually expects
- * a uint64_t *buffer.
- */
-void
-_pixman_image_get_scanline_64 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *unused)
-{
- image->common.get_scanline_64 (image, x, y, width, buffer, unused);
-}
-
static void
image_property_changed (pixman_image_t *image)
{
diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c
index 5de3cc8..a19d9a8 100644
--- a/pixman/pixman-linear-gradient.c
+++ b/pixman/pixman-linear-gradient.c
@@ -222,8 +222,6 @@ linear_get_scanline_32 (pixman_image_t *image,
static void
linear_gradient_property_changed (pixman_image_t *image)
{
- image->common.get_scanline_32 = linear_get_scanline_32;
- image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
}
static uint32_t *
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 9028c16..d7c7a62 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -97,8 +97,6 @@ struct image_common
pixman_bool_t component_alpha;
classify_func_t classify;
property_changed_func_t property_changed;
- fetch_scanline_t get_scanline_32;
- fetch_scanline_t get_scanline_64;
pixman_image_destroy_func_t destroy_func;
void * destroy_data;
@@ -168,6 +166,9 @@ 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;
@@ -248,14 +249,6 @@ _pixman_conical_gradient_iter_init (pixman_image_t *image,
int x, int y, int width, int height,
uint8_t *buffer, iter_flags_t flags);
-void
-_pixman_image_get_scanline_generic_64 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask);
-
source_image_class_t
_pixman_image_classify (pixman_image_t *image,
int x,
@@ -263,25 +256,6 @@ _pixman_image_classify (pixman_image_t *image,
int width,
int height);
-void
-_pixman_image_get_scanline_32 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask);
-
-/* Even thought the type of buffer is uint32_t *, the function actually expects
- * a uint64_t *buffer.
- */
-void
-_pixman_image_get_scanline_64 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *unused);
-
pixman_image_t *
_pixman_image_allocate (void);
diff --git a/pixman/pixman-radial-gradient.c b/pixman/pixman-radial-gradient.c
index 161055a..5121827 100644
--- a/pixman/pixman-radial-gradient.c
+++ b/pixman/pixman-radial-gradient.c
@@ -389,8 +389,6 @@ radial_gradient_get_scanline_32 (pixman_image_t *image,
static void
radial_gradient_property_changed (pixman_image_t *image)
{
- image->common.get_scanline_32 = radial_gradient_get_scanline_32;
- image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
}
static uint32_t *
diff --git a/pixman/pixman-solid-fill.c b/pixman/pixman-solid-fill.c
index 0af4df0..f2df3c7 100644
--- a/pixman/pixman-solid-fill.c
+++ b/pixman/pixman-solid-fill.c
@@ -72,8 +72,6 @@ solid_fill_classify (pixman_image_t *image,
static void
solid_fill_property_changed (pixman_image_t *image)
{
- image->common.get_scanline_32 = solid_fill_get_scanline_32;
- image->common.get_scanline_64 = solid_fill_get_scanline_64;
}
void
commit d6b13f99b41eac535d961b89d4b53f616c910c1e
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date: Fri Dec 10 10:53:02 2010 -0500
Use an iterator in pixman_image_get_solid()
This is a step towards getting rid of the
_pixman_image_get_scanline_32/64() functions.
diff --git a/pixman/pixman-arm-common.h b/pixman/pixman-arm-common.h
index 66f448d..372e9f9 100644
--- a/pixman/pixman-arm-common.h
+++ b/pixman/pixman-arm-common.h
@@ -118,7 +118,8 @@ cputype##_composite_##name (pixman_implementation_t *imp, \
int32_t dst_stride; \
uint32_t src; \
\
- src = _pixman_image_get_solid (src_image, dst_image->bits.format); \
+ src = _pixman_image_get_solid ( \
+ imp, src_image, dst_image->bits.format); \
\
if ((flags & SKIP_ZERO_SRC) && src == 0) \
return; \
@@ -164,7 +165,8 @@ cputype##_composite_##name (pixman_implementation_t *imp, \
int32_t dst_stride, mask_stride; \
uint32_t src; \
\
- src = _pixman_image_get_solid (src_image, dst_image->bits.format); \
+ src = _pixman_image_get_solid ( \
+ imp, src_image, dst_image->bits.format); \
\
if ((flags & SKIP_ZERO_SRC) && src == 0) \
return; \
@@ -212,7 +214,8 @@ cputype##_composite_##name (pixman_implementation_t *imp, \
int32_t dst_stride, src_stride; \
uint32_t mask; \
\
- mask = _pixman_image_get_solid (mask_image, dst_image->bits.format);\
+ mask = _pixman_image_get_solid ( \
+ imp, mask_image, dst_image->bits.format); \
\
if ((flags & SKIP_ZERO_MASK) && mask == 0) \
return; \
diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index f103b4c..868175f 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -188,7 +188,7 @@ fast_composite_in_n_8_8 (pixman_implementation_t *imp,
int32_t w;
uint16_t t;
- src = _pixman_image_get_solid (src_image, dest_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format);
srca = src >> 24;
@@ -312,7 +312,7 @@ fast_composite_over_n_8_8888 (pixman_implementation_t *imp,
int dst_stride, mask_stride;
int32_t w;
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
srca = src >> 24;
if (src == 0)
@@ -370,7 +370,7 @@ fast_composite_add_n_8888_8888_ca (pixman_implementation_t *imp,
int dst_stride, mask_stride;
int32_t w;
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
srca = src >> 24;
if (src == 0)
@@ -427,7 +427,7 @@ fast_composite_over_n_8888_8888_ca (pixman_implementation_t *imp,
int dst_stride, mask_stride;
int32_t w;
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
srca = src >> 24;
if (src == 0)
@@ -494,7 +494,7 @@ fast_composite_over_n_8_0888 (pixman_implementation_t *imp,
int dst_stride, mask_stride;
int32_t w;
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
srca = src >> 24;
if (src == 0)
@@ -559,7 +559,7 @@ fast_composite_over_n_8_0565 (pixman_implementation_t *imp,
int dst_stride, mask_stride;
int32_t w;
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
srca = src >> 24;
if (src == 0)
@@ -626,7 +626,7 @@ fast_composite_over_n_8888_0565_ca (pixman_implementation_t *imp,
int dst_stride, mask_stride;
int32_t w;
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
srca = src >> 24;
if (src == 0)
@@ -1034,7 +1034,7 @@ fast_composite_add_n_8_8 (pixman_implementation_t *imp,
PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1);
PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
sa = (src >> 24);
while (height--)
@@ -1146,7 +1146,7 @@ fast_composite_over_n_1_8888 (pixman_implementation_t *imp,
if (width <= 0)
return;
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
srca = src >> 24;
if (src == 0)
return;
@@ -1240,7 +1240,7 @@ fast_composite_over_n_1_0565 (pixman_implementation_t *imp,
if (width <= 0)
return;
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
srca = src >> 24;
if (src == 0)
return;
@@ -1332,7 +1332,7 @@ fast_composite_solid_fill (pixman_implementation_t *imp,
{
uint32_t src;
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
if (dst_image->bits.format == PIXMAN_a1)
{
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 28dc066..b487df0 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -795,12 +795,18 @@ pixman_image_get_format (pixman_image_t *image)
}
uint32_t
-_pixman_image_get_solid (pixman_image_t * image,
- pixman_format_code_t format)
+_pixman_image_get_solid (pixman_implementation_t *imp,
+ pixman_image_t * image,
+ pixman_format_code_t format)
{
uint32_t result;
+ pixman_iter_t iter;
- _pixman_image_get_scanline_32 (image, 0, 0, 1, &result, NULL);
+ _pixman_implementation_src_iter_init (
+ imp, &iter, image, 0, 0, 1, 1,
+ (uint8_t *)&result, ITER_NARROW);
+
+ result = *iter.get_scanline (&iter, NULL);
/* If necessary, convert RGB <--> BGR. */
if (PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB)
diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
index 34637a4..6daa364 100644
--- a/pixman/pixman-mmx.c
+++ b/pixman/pixman-mmx.c
@@ -1108,7 +1108,7 @@ mmx_composite_over_n_8888 (pixman_implementation_t *imp,
CHECKPOINT ();
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
if (src == 0)
return;
@@ -1187,7 +1187,7 @@ mmx_composite_over_n_0565 (pixman_implementation_t *imp,
CHECKPOINT ();
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
if (src == 0)
return;
@@ -1275,7 +1275,7 @@ mmx_composite_over_n_8888_8888_ca (pixman_implementation_t *imp,
CHECKPOINT ();
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
srca = src >> 24;
if (src == 0)
@@ -1384,7 +1384,7 @@ mmx_composite_over_8888_n_8888 (pixman_implementation_t *imp,
PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
- mask = _pixman_image_get_solid (mask_image, dst_image->bits.format);
+ mask = _pixman_image_get_solid (imp, mask_image, dst_image->bits.format);
mask &= 0xff000000;
mask = mask | mask >> 8 | mask >> 16 | mask >> 24;
vmask = load8888 (mask);
@@ -1469,7 +1469,7 @@ mmx_composite_over_x888_n_8888 (pixman_implementation_t *imp,
PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1);
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
- mask = _pixman_image_get_solid (mask_image, dst_image->bits.format);
+ mask = _pixman_image_get_solid (imp, mask_image, dst_image->bits.format);
mask &= 0xff000000;
mask = mask | mask >> 8 | mask >> 16 | mask >> 24;
@@ -1764,7 +1764,7 @@ mmx_composite_over_n_8_8888 (pixman_implementation_t *imp,
CHECKPOINT ();
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
srca = src >> 24;
if (src == 0)
@@ -2038,7 +2038,7 @@ mmx_composite_src_n_8_8888 (pixman_implementation_t *imp,
CHECKPOINT ();
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
srca = src >> 24;
if (src == 0)
@@ -2173,7 +2173,7 @@ mmx_composite_over_n_8_0565 (pixman_implementation_t *imp,
CHECKPOINT ();
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
srca = src >> 24;
if (src == 0)
@@ -2532,7 +2532,7 @@ mmx_composite_over_n_8888_0565_ca (pixman_implementation_t *imp,
CHECKPOINT ();
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
srca = src >> 24;
if (src == 0)
@@ -2643,7 +2643,7 @@ mmx_composite_in_n_8_8 (pixman_implementation_t *imp,
PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1);
PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
sa = src >> 24;
@@ -2790,7 +2790,7 @@ mmx_composite_add_n_8_8 (pixman_implementation_t *imp,
PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1);
PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
sa = src >> 24;
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 158c41d..9028c16 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -295,10 +295,6 @@ _pixman_image_reset_clip_region (pixman_image_t *image);
void
_pixman_image_validate (pixman_image_t *image);
-uint32_t
-_pixman_image_get_solid (pixman_image_t * image,
- pixman_format_code_t format);
-
#define PIXMAN_IMAGE_GET_LINE(image, x, y, type, out_stride, line, mul) \
do \
{ \
@@ -473,6 +469,11 @@ struct pixman_implementation_t
pixman_combine_64_func_t combine_64_ca[PIXMAN_N_OPERATORS];
};
+uint32_t
+_pixman_image_get_solid (pixman_implementation_t *imp,
+ pixman_image_t * image,
+ pixman_format_code_t format);
+
pixman_implementation_t *
_pixman_implementation_create (pixman_implementation_t *delegate,
const pixman_fast_path_t *fast_paths);
diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index 94ba54c..3c0a42f 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -2598,7 +2598,7 @@ sse2_composite_over_n_8888 (pixman_implementation_t *imp,
__m128i xmm_src, xmm_alpha;
__m128i xmm_dst, xmm_dst_lo, xmm_dst_hi;
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
if (src == 0)
return;
@@ -2681,7 +2681,7 @@ sse2_composite_over_n_0565 (pixman_implementation_t *imp,
__m128i xmm_src, xmm_alpha;
__m128i xmm_dst, xmm_dst0, xmm_dst1, xmm_dst2, xmm_dst3;
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
if (src == 0)
return;
@@ -2776,7 +2776,7 @@ sse2_composite_add_n_8888_8888_ca (pixman_implementation_t *imp,
__m64 mmx_src, mmx_alpha, mmx_mask, mmx_dest;
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
srca = src >> 24;
if (src == 0)
@@ -2904,7 +2904,7 @@ sse2_composite_over_n_8888_8888_ca (pixman_implementation_t *imp,
__m64 mmx_src, mmx_alpha, mmx_mask, mmx_dest;
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
if (src == 0)
return;
@@ -3036,7 +3036,7 @@ sse2_composite_over_8888_n_8888 (pixman_implementation_t *imp,
PIXMAN_IMAGE_GET_LINE (
src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
- mask = _pixman_image_get_solid (mask_image, PIXMAN_a8r8g8b8);
+ mask = _pixman_image_get_solid (imp, mask_image, PIXMAN_a8r8g8b8);
xmm_mask = create_mask_16_128 (mask >> 24);
@@ -3226,7 +3226,7 @@ sse2_composite_over_x888_n_8888 (pixman_implementation_t *imp,
PIXMAN_IMAGE_GET_LINE (
src_image, src_x, src_y, uint32_t, src_stride, src_line, 1);
- mask = _pixman_image_get_solid (mask_image, PIXMAN_a8r8g8b8);
+ mask = _pixman_image_get_solid (imp, mask_image, PIXMAN_a8r8g8b8);
xmm_mask = create_mask_16_128 (mask >> 24);
xmm_alpha = mask_00ff;
@@ -3498,7 +3498,7 @@ sse2_composite_over_n_8_8888 (pixman_implementation_t *imp,
__m64 mmx_src, mmx_alpha, mmx_mask, mmx_dest;
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
srca = src >> 24;
if (src == 0)
@@ -3782,7 +3782,7 @@ sse2_composite_src_n_8_8888 (pixman_implementation_t *imp,
__m128i xmm_src, xmm_def;
__m128i xmm_mask, xmm_mask_lo, xmm_mask_hi;
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
srca = src >> 24;
if (src == 0)
@@ -3918,7 +3918,7 @@ sse2_composite_over_n_8_0565 (pixman_implementation_t *imp,
__m128i xmm_mask, xmm_mask_lo, xmm_mask_hi;
__m128i xmm_dst, xmm_dst0, xmm_dst1, xmm_dst2, xmm_dst3;
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
srca = src >> 24;
if (src == 0)
@@ -4318,7 +4318,7 @@ sse2_composite_over_n_8888_0565_ca (pixman_implementation_t *imp,
__m64 mmx_src, mmx_alpha, mmx_mask, mmx_dest;
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
if (src == 0)
return;
@@ -4471,7 +4471,7 @@ sse2_composite_in_n_8_8 (pixman_implementation_t *imp,
PIXMAN_IMAGE_GET_LINE (
mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
sa = src >> 24;
@@ -4570,7 +4570,7 @@ sse2_composite_in_n_8 (pixman_implementation_t *imp,
PIXMAN_IMAGE_GET_LINE (
dst_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1);
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
xmm_alpha = expand_alpha_1x128 (expand_pixel_32_1x128 (src));
@@ -4758,7 +4758,7 @@ sse2_composite_add_n_8_8 (pixman_implementation_t *imp,
PIXMAN_IMAGE_GET_LINE (
mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1);
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
sa = src >> 24;
@@ -4855,7 +4855,7 @@ sse2_composite_add_n_8 (pixman_implementation_t *imp,
PIXMAN_IMAGE_GET_LINE (
dst_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1);
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
src >>= 24;
@@ -5480,7 +5480,7 @@ sse2_composite_over_reverse_n_8888 (pixman_implementation_t *imp,
int dst_stride;
int32_t w;
- src = _pixman_image_get_solid (src_image, dst_image->bits.format);
+ src = _pixman_image_get_solid (imp, src_image, dst_image->bits.format);
if (src == 0)
return;
commit 51a5e949f394560b057911d46aab768f8e07bd54
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date: Fri Dec 10 13:26:53 2010 -0500
Virtualize iterator initialization
Make src_iter_init() and dest_iter_init() virtual methods in the
implementation struct. This allows individual implementations to plug
in their own CPU specific scanline fetchers.
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 4b837fa..e2f1dc3 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -39,18 +39,12 @@
#include "pixman-combine32.h"
#include "pixman-private.h"
-static uint32_t *
-src_get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
-{
- return NULL;
-}
-
static void
-src_iter_init (pixman_implementation_t *imp,
- pixman_iter_t *iter,
- pixman_image_t *image,
- int x, int y, int width, int height,
- uint8_t *buffer, iter_flags_t flags)
+general_src_iter_init (pixman_implementation_t *imp,
+ pixman_iter_t *iter,
+ pixman_image_t *image,
+ int x, int y, int width, int height,
+ uint8_t *buffer, iter_flags_t flags)
{
iter->image = image;
iter->x = x;
@@ -58,11 +52,7 @@ src_iter_init (pixman_implementation_t *imp,
iter->width = width;
iter->buffer = (uint32_t *)buffer;
- if (!image)
- {
- iter->get_scanline = src_get_scanline_null;
- }
- else if (image->type == SOLID)
+ if (image->type == SOLID)
{
_pixman_solid_fill_iter_init (
image, iter, x, y, width, height, buffer, flags);
@@ -94,11 +84,11 @@ src_iter_init (pixman_implementation_t *imp,
}
static void
-dest_iter_init (pixman_implementation_t *imp,
- pixman_iter_t *iter,
- pixman_image_t *image,
- int x, int y, int width, int height,
- uint8_t *buffer, iter_flags_t flags)
+general_dest_iter_init (pixman_implementation_t *imp,
+ pixman_iter_t *iter,
+ pixman_image_t *image,
+ int x, int y, int width, int height,
+ uint8_t *buffer, iter_flags_t flags)
{
iter->image = image;
iter->x = x;
@@ -169,17 +159,17 @@ general_composite_rect (pixman_implementation_t *imp,
mask_buffer = src_buffer + width * Bpp;
dest_buffer = mask_buffer + width * Bpp;
- src_iter_init (imp->toplevel, &src_iter, src,
- src_x, src_y, width, height,
- src_buffer, narrow);
+ _pixman_implementation_src_iter_init (imp->toplevel, &src_iter, src,
+ src_x, src_y, width, height,
+ src_buffer, narrow);
- src_iter_init (imp->toplevel, &mask_iter, mask,
- mask_x, mask_y, width, height,
- mask_buffer, narrow);
+ _pixman_implementation_src_iter_init (imp->toplevel, &mask_iter, mask,
+ mask_x, mask_y, width, height,
+ mask_buffer, narrow);
- dest_iter_init (imp->toplevel, &dest_iter, dest,
- dest_x, dest_y, width, height,
- dest_buffer, narrow);
+ _pixman_implementation_dest_iter_init (imp->toplevel, &dest_iter, dest,
+ dest_x, dest_y, width, height,
+ dest_buffer, narrow);
component_alpha =
mask &&
@@ -272,6 +262,8 @@ _pixman_implementation_create_general (void)
imp->blt = general_blt;
imp->fill = general_fill;
+ imp->src_iter_init = general_src_iter_init;
+ imp->dest_iter_init = general_dest_iter_init;
return imp;
}
diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index bc3749e..e633432 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -111,6 +111,36 @@ delegate_fill (pixman_implementation_t *imp,
imp->delegate, bits, stride, bpp, x, y, width, height, xor);
}
+static void
+delegate_src_iter_init (pixman_implementation_t *imp,
+ pixman_iter_t * iter,
+ pixman_image_t * image,
+ int x,
+ int y,
+ int width,
+ int height,
+ uint8_t * buffer,
+ iter_flags_t flags)
+{
+ _pixman_implementation_src_iter_init (
+ imp->delegate, iter, image, x, y, width, height, buffer, flags);
+}
+
+static void
+delegate_dest_iter_init (pixman_implementation_t *imp,
+ pixman_iter_t * iter,
+ pixman_image_t * image,
+ int x,
+ int y,
+ int width,
+ int height,
+ uint8_t * buffer,
+ iter_flags_t flags)
+{
+ _pixman_implementation_dest_iter_init (
+ imp->delegate, iter, image, x, y, width, height, buffer, flags);
+}
+
pixman_implementation_t *
_pixman_implementation_create (pixman_implementation_t *delegate,
const pixman_fast_path_t *fast_paths)
@@ -133,6 +163,8 @@ _pixman_implementation_create (pixman_implementation_t *delegate,
*/
imp->blt = delegate_blt;
imp->fill = delegate_fill;
+ imp->src_iter_init = delegate_src_iter_init;
+ imp->dest_iter_init = delegate_dest_iter_init;
for (i = 0; i < PIXMAN_N_OPERATORS; ++i)
{
@@ -143,7 +175,7 @@ _pixman_implementation_create (pixman_implementation_t *delegate,
}
imp->fast_paths = fast_paths;
-
+
return imp;
}
@@ -225,3 +257,45 @@ _pixman_implementation_fill (pixman_implementation_t *imp,
return (*imp->fill) (imp, bits, stride, bpp, x, y, width, height, xor);
}
+static uint32_t *
+get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
+{
+ return NULL;
+}
+
+void
+_pixman_implementation_src_iter_init (pixman_implementation_t *imp,
+ pixman_iter_t *iter,
+ pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ int height,
+ uint8_t *buffer,
+ iter_flags_t flags)
+{
+ if (!image)
+ {
+ iter->get_scanline = get_scanline_null;
+ }
+ else
+ {
+ (*imp->src_iter_init) (
+ imp, iter, image, x, y, width, height, buffer, flags);
+ }
+}
+
+void
+_pixman_implementation_dest_iter_init (pixman_implementation_t *imp,
+ pixman_iter_t *iter,
+ pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ int height,
+ uint8_t *buffer,
+ iter_flags_t flags)
+{
+ (*imp->dest_iter_init) (
+ imp, iter, image, x, y, width, height, buffer, flags);
+}
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index d42c114..158c41d 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -431,6 +431,15 @@ typedef pixman_bool_t (*pixman_fill_func_t) (pixman_implementation_t *imp,
int width,
int height,
uint32_t xor);
+typedef void (*pixman_iter_init_func_t) (pixman_implementation_t *imp,
+ pixman_iter_t *iter,
+ pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ int height,
+ uint8_t *buffer,
+ iter_flags_t flags);
void _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp);
void _pixman_setup_combiner_functions_64 (pixman_implementation_t *imp);
@@ -452,9 +461,11 @@ struct pixman_implementation_t
pixman_implementation_t * toplevel;
pixman_implementation_t * delegate;
const pixman_fast_path_t * fast_paths;
-
+
pixman_blt_func_t blt;
pixman_fill_func_t fill;
+ pixman_iter_init_func_t src_iter_init;
+ pixman_iter_init_func_t dest_iter_init;
pixman_combine_32_func_t combine_32[PIXMAN_N_OPERATORS];
pixman_combine_32_func_t combine_32_ca[PIXMAN_N_OPERATORS];
@@ -521,6 +532,28 @@ _pixman_implementation_fill (pixman_implementation_t *imp,
int height,
uint32_t xor);
+void
+_pixman_implementation_src_iter_init (pixman_implementation_t *imp,
+ pixman_iter_t *iter,
+ pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ int height,
+ uint8_t *buffer,
+ iter_flags_t flags);
+
+void
+_pixman_implementation_dest_iter_init (pixman_implementation_t *imp,
+ pixman_iter_t *iter,
+ pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ int height,
+ uint8_t *buffer,
+ iter_flags_t flags);
+
/* Specific implementations */
pixman_implementation_t *
_pixman_implementation_create_general (void);
commit 6503c6edccbc6b08ea8efe398da3265126efa896
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date: Fri Dec 10 12:40:26 2010 -0500
Move iterator initialization to the respective image files
Instead of calling _pixman_image_get_scanline_32/64(), move the
iterator initialization into the respecive image implementations and
call the scanline generators directly.
diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c
index a3685d1..35913cb 100644
--- a/pixman/pixman-conical-gradient.c
+++ b/pixman/pixman-conical-gradient.c
@@ -163,6 +163,39 @@ conical_gradient_property_changed (pixman_image_t *image)
image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
}
+static uint32_t *
+conical_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
+{
+ conical_gradient_get_scanline_32 (iter->image, iter->x, iter->y,
+ iter->width, iter->buffer,
+ mask);
+
+ iter->y++;
+ return iter->buffer;
+}
+
+static uint32_t *
+conical_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
+{
+ uint32_t *buffer = conical_get_scanline_narrow (iter, NULL);
+
+ pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width);
+
+ return buffer;
+}
+
+void
+_pixman_conical_gradient_iter_init (pixman_image_t *image,
+ pixman_iter_t *iter,
+ int x, int y, int width, int height,
+ uint8_t *buffer, iter_flags_t flags)
+{
+ if (flags & ITER_NARROW)
+ iter->get_scanline = conical_get_scanline_narrow;
+ else
+ iter->get_scanline = conical_get_scanline_wide;
+}
+
PIXMAN_EXPORT pixman_image_t *
pixman_image_create_conical_gradient (pixman_point_fixed_t * center,
pixman_fixed_t angle,
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 3b7b59d..4b837fa 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -45,24 +45,6 @@ src_get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
return NULL;
}
-static uint32_t *
-src_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
-{
- _pixman_image_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)
-{
- _pixman_image_get_scanline_64 (
- iter->image, iter->x, iter->y++, iter->width, iter->buffer, mask);
-
- return iter->buffer;
-}
-
static void
src_iter_init (pixman_implementation_t *imp,
pixman_iter_t *iter,
@@ -80,18 +62,34 @@ src_iter_init (pixman_implementation_t *imp,
{
iter->get_scanline = src_get_scanline_null;
}
- else if (image->type == BITS)
+ else if (image->type == SOLID)
{
- _pixman_bits_image_src_iter_init (
+ _pixman_solid_fill_iter_init (
image, iter, x, y, width, height, buffer, flags);
}
- else if (flags & ITER_NARROW)
+ else if (image->type == LINEAR)
{
- iter->get_scanline = src_get_scanline_narrow;
+ _pixman_linear_gradient_iter_init (
+ image, iter, x, y, width, height, buffer, flags);
+ }
+ else if (image->type == RADIAL)
+ {
+ _pixman_radial_gradient_iter_init (
+ image, iter, x, y, width, height, buffer, flags);
+ }
+ else if (image->type == CONICAL)
+ {
+ _pixman_conical_gradient_iter_init (
+ image, iter, x, y, width, height, buffer, flags);
+ }
+ else if (image->type == BITS)
+ {
+ _pixman_bits_image_src_iter_init (
+ image, iter, x, y, width, height, buffer, flags);
}
else
{
- iter->get_scanline = src_get_scanline_wide;
+ _pixman_log_error (FUNC, "Pixman bug: unknown image type\n");
}
}
diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c
index 1547882..5de3cc8 100644
--- a/pixman/pixman-linear-gradient.c
+++ b/pixman/pixman-linear-gradient.c
@@ -92,12 +92,12 @@ linear_gradient_classify (pixman_image_t *image,
}
static void
-linear_gradient_get_scanline_32 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
+linear_get_scanline_32 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
{
pixman_vector_t v, unit;
pixman_fixed_32_32_t l;
@@ -222,10 +222,53 @@ linear_gradient_get_scanline_32 (pixman_image_t *image,
static void
linear_gradient_property_changed (pixman_image_t *image)
{
- image->common.get_scanline_32 = linear_gradient_get_scanline_32;
+ image->common.get_scanline_32 = linear_get_scanline_32;
image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
}
+static uint32_t *
+linear_get_scanline_narrow (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;
+
+ linear_get_scanline_32 (image, x, y, width, buffer, mask);
+
+ iter->y++;
+
+ return iter->buffer;
+}
+
+static uint32_t *
+linear_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
+{
+ uint32_t *buffer = linear_get_scanline_narrow (iter, NULL);
+
+ pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width);
+
+ return buffer;
+}
+
+void
+_pixman_linear_gradient_iter_init (pixman_image_t *image,
+ pixman_iter_t *iter,
+ int x,
+ int y,
+ int width,
+ int height,
+ uint8_t *buffer,
+ iter_flags_t flags)
+{
+ if (flags & ITER_NARROW)
+ iter->get_scanline = linear_get_scanline_narrow;
+ else
+ iter->get_scanline = linear_get_scanline_wide;
+}
+
PIXMAN_EXPORT pixman_image_t *
pixman_image_create_linear_gradient (pixman_point_fixed_t * p1,
pixman_point_fixed_t * p2,
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index d9d19ce..d42c114 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -225,6 +225,30 @@ _pixman_bits_image_dest_iter_init (pixman_image_t *image,
uint8_t *buffer, iter_flags_t flags);
void
+_pixman_solid_fill_iter_init (pixman_image_t *image,
+ pixman_iter_t *iter,
+ int x, int y, int width, int height,
+ uint8_t *buffer, iter_flags_t flags);
+
+void
+_pixman_linear_gradient_iter_init (pixman_image_t *image,
+ pixman_iter_t *iter,
+ int x, int y, int width, int height,
+ uint8_t *buffer, iter_flags_t flags);
+
+void
+_pixman_radial_gradient_iter_init (pixman_image_t *image,
+ pixman_iter_t *iter,
+ int x, int y, int width, int height,
+ uint8_t *buffer, iter_flags_t flags);
+
+void
+_pixman_conical_gradient_iter_init (pixman_image_t *image,
+ pixman_iter_t *iter,
+ int x, int y, int width, int height,
+ uint8_t *buffer, iter_flags_t flags);
+
+void
_pixman_image_get_scanline_generic_64 (pixman_image_t *image,
int x,
int y,
@@ -537,6 +561,8 @@ _pixman_choose_implementation (void);
/*
* Utilities
*/
+uint32_t *
+_pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask);
/* These "formats" all have depth 0, so they
* will never clash with any real ones
diff --git a/pixman/pixman-radial-gradient.c b/pixman/pixman-radial-gradient.c
index 7b92307..161055a 100644
--- a/pixman/pixman-radial-gradient.c
+++ b/pixman/pixman-radial-gradient.c
@@ -393,6 +393,39 @@ radial_gradient_property_changed (pixman_image_t *image)
image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
}
+static uint32_t *
+radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
+{
+ radial_gradient_get_scanline_32 (
+ iter->image, iter->x, iter->y, iter->width,
+ iter->buffer, mask);
+
+ iter->y++;
+ return iter->buffer;
+}
+
+static uint32_t *
+radial_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
+{
+ uint32_t *buffer = radial_get_scanline_narrow (iter, NULL);
+
+ pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width);
+
+ return buffer;
+}
+
+void
+_pixman_radial_gradient_iter_init (pixman_image_t *image,
+ pixman_iter_t *iter,
+ int x, int y, int width, int height,
+ uint8_t *buffer, iter_flags_t flags)
+{
+ if (flags & ITER_NARROW)
+ iter->get_scanline = radial_get_scanline_narrow;
+ else
+ iter->get_scanline = radial_get_scanline_wide;
+}
+
PIXMAN_EXPORT pixman_image_t *
pixman_image_create_radial_gradient (pixman_point_fixed_t * inner,
pixman_point_fixed_t * outer,
diff --git a/pixman/pixman-solid-fill.c b/pixman/pixman-solid-fill.c
index 1d911e9..0af4df0 100644
--- a/pixman/pixman-solid-fill.c
+++ b/pixman/pixman-solid-fill.c
@@ -76,6 +76,26 @@ solid_fill_property_changed (pixman_image_t *image)
image->common.get_scanline_64 = solid_fill_get_scanline_64;
}
+void
+_pixman_solid_fill_iter_init (pixman_image_t *image,
+ pixman_iter_t *iter,
+ int x, int y, int width, int height,
+ uint8_t *buffer, iter_flags_t flags)
+{
+ if (flags & ITER_NARROW)
+ {
+ solid_fill_get_scanline_32 (
+ image, x, y, width, (uint32_t *)buffer, NULL);
+ }
+ else
+ {
+ solid_fill_get_scanline_64 (
+ image, x, y, width, (uint32_t *)buffer, NULL);
+ }
+
+ iter->get_scanline = _pixman_iter_get_scanline_noop;
+}
+
static uint32_t
color_to_uint32 (const pixman_color_t *color)
{
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index 3ef88b7..cb4e621 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -167,6 +167,12 @@ pixman_contract (uint32_t * dst,
}
}
+uint32_t *
+_pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask)
+{
+ return iter->buffer;
+}
+
#define N_TMP_BOXES (16)
pixman_bool_t
commit 23c6e1d2c007cc661b31e1bcdfd84604d7a9a560
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date: Fri Dec 10 12:31:29 2010 -0500
Eliminate the _pixman_image_store_scanline_32/64 functions
They were only called from next_line_write_narrow/wide, so they could
simply be absorbed into those functions.
diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index bcada58..bf22dbf 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -35,45 +35,6 @@
#include "pixman-private.h"
#include "pixman-combine32.h"
-/* Store functions */
-void
-_pixman_image_store_scanline_32 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *buffer)
-{
- image->store_scanline_32 (image, x, y, width, buffer);
-
- if (image->common.alpha_map)
- {
- x -= image->common.alpha_origin_x;
- y -= image->common.alpha_origin_y;
-
- image->common.alpha_map->store_scanline_32 (
- image->common.alpha_map, x, y, width, buffer);
- }
-}
-
-void
-_pixman_image_store_scanline_64 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *buffer)
-{
- image->store_scanline_64 (image, x, y, width, buffer);
-
- if (image->common.alpha_map)
- {
- x -= image->common.alpha_origin_x;
- y -= image->common.alpha_origin_y;
-
- image->common.alpha_map->store_scanline_64 (
- image->common.alpha_map, x, y, width, buffer);
- }
-}
-
/* Fetch functions */
static force_inline uint32_t
@@ -1397,15 +1358,47 @@ dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
static void
dest_write_back_narrow (pixman_iter_t *iter)
{
- _pixman_image_store_scanline_32 (
- &iter->image->bits, iter->x, iter->y++, iter->width, iter->buffer);
+ bits_image_t * image = &iter->image->bits;
+ int x = iter->x;
+ int y = iter->y;
+ int width = iter->width;
+ const uint32_t *buffer = iter->buffer;
+
+ image->store_scanline_32 (image, x, y, width, buffer);
+
+ if (image->common.alpha_map)
+ {
+ x -= image->common.alpha_origin_x;
+ y -= image->common.alpha_origin_y;
+
+ image->common.alpha_map->store_scanline_32 (
+ image->common.alpha_map, x, y, width, buffer);
+ }
+
+ iter->y++;
}
static void
dest_write_back_wide (pixman_iter_t *iter)
{
- _pixman_image_store_scanline_64 (
- &iter->image->bits, iter->x, iter->y++, iter->width, iter->buffer);
+ bits_image_t * image = &iter->image->bits;
+ int x = iter->x;
+ int y = iter->y;
+ int width = iter->width;
+ const uint32_t *buffer = iter->buffer;
+
+ image->store_scanline_64 (image, x, y, width, buffer);
+
+ if (image->common.alpha_map)
+ {
+ x -= image->common.alpha_origin_x;
+ y -= image->common.alpha_origin_y;
+
+ image->common.alpha_map->store_scanline_64 (
+ image->common.alpha_map, x, y, width, buffer);
+ }
+
+ iter->y++;
}
void
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 853fb5a..d9d19ce 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -258,23 +258,6 @@ _pixman_image_get_scanline_64 (pixman_image_t *image,
uint32_t * buffer,
const uint32_t *unused);
-void
-_pixman_image_store_scanline_32 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *buffer);
-
-/* Even though the type of buffer is uint32_t *, the function
- * actually expects a uint64_t *buffer.
- */
-void
-_pixman_image_store_scanline_64 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *buffer);
-
pixman_image_t *
_pixman_image_allocate (void);
commit b2c9eaa5020d08cfaac6c2296895e5a65c971ffd
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date: Fri Dec 10 12:19:50 2010 -0500
Move initialization of iterators for bits images to pixman-bits-image.c
pixman_iter_t is now defined in pixman-private.h, and iterators for
bits images are being initialized in pixman-bits-image.c
diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index c453e0e..bcada58 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -1347,6 +1347,86 @@ bits_image_property_changed (pixman_image_t *image)
}
static uint32_t *
+src_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
+{
+ iter->image->common.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->common.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,
+ int x, int y, int width, int height,
+ uint8_t *buffer, iter_flags_t flags)
+{
+ if (flags & ITER_NARROW)
+ iter->get_scanline = src_get_scanline_narrow;
+ else
+ iter->get_scanline = src_get_scanline_wide;
+}
+
+static uint32_t *
+dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
+{
+ iter->image->common.get_scanline_32 (
+ iter->image, iter->x, iter->y, iter->width, iter->buffer, mask);
+
+ return iter->buffer;
+}
+
+static uint32_t *
+dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
+{
+ iter->image->common.get_scanline_64 (
+ iter->image, iter->x, iter->y, iter->width, iter->buffer, mask);
+
+ return iter->buffer;
+}
+
+static void
+dest_write_back_narrow (pixman_iter_t *iter)
+{
+ _pixman_image_store_scanline_32 (
+ &iter->image->bits, iter->x, iter->y++, iter->width, iter->buffer);
+}
+
+static void
+dest_write_back_wide (pixman_iter_t *iter)
+{
+ _pixman_image_store_scanline_64 (
+ &iter->image->bits, iter->x, iter->y++, iter->width, iter->buffer);
+}
+
+void
+_pixman_bits_image_dest_iter_init (pixman_image_t *image,
+ pixman_iter_t *iter,
+ int x, int y, int width, int height,
+ uint8_t *buffer, iter_flags_t flags)
+{
+ if (flags & ITER_NARROW)
+ {
+ iter->get_scanline = dest_get_scanline_narrow;
+ iter->write_back = dest_write_back_narrow;
+ }
+ else
+ {
+ iter->get_scanline = dest_get_scanline_wide;
+ iter->write_back = dest_write_back_wide;
+ }
+}
+
+static uint32_t *
create_bits (pixman_format_code_t format,
int width,
int height,
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index ea27e80..3b7b59d 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -39,23 +39,6 @@
#include "pixman-combine32.h"
#include "pixman-private.h"
-typedef struct pixman_iter_t pixman_iter_t;
-typedef enum
-{
- ITER_NARROW = (1 << 0)
-} iter_flags_t;
-
-struct pixman_iter_t
-{
- uint32_t *(* get_scanline) (pixman_iter_t *iter, const uint32_t *mask);
- void (* write_back) (pixman_iter_t *iter);
-
- pixman_image_t * image;
- uint32_t * buffer;
- int x, y;
- int width;
-};
-
static uint32_t *
src_get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
{
@@ -94,43 +77,22 @@ src_iter_init (pixman_implementation_t *imp,
iter->buffer = (uint32_t *)buffer;
if (!image)
+ {
iter->get_scanline = src_get_scanline_null;
+ }
+ else if (image->type == BITS)
+ {
+ _pixman_bits_image_src_iter_init (
+ image, iter, x, y, width, height, buffer, flags);
+ }
else if (flags & ITER_NARROW)
+ {
iter->get_scanline = src_get_scanline_narrow;
+ }
else
+ {
iter->get_scanline = src_get_scanline_wide;
-}
-
-static uint32_t *
-dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
-{
- _pixman_image_get_scanline_32 (
- iter->image, iter->x, iter->y, iter->width, iter->buffer, mask);
-
- return iter->buffer;
-}
-
-static uint32_t *
-dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
-{
- _pixman_image_get_scanline_64 (
- iter->image, iter->x, iter->y, iter->width, iter->buffer, mask);
-
- return iter->buffer;
-}
-
-static void
-write_back_narrow (pixman_iter_t *iter)
-{
- _pixman_image_store_scanline_32 (
- &iter->image->bits, iter->x, iter->y++, iter->width, iter->buffer);
-}
-
-static void
-write_back_wide (pixman_iter_t *iter)
-{
- _pixman_image_store_scanline_64 (
- &iter->image->bits, iter->x, iter->y++, iter->width, iter->buffer);
+ }
}
static void
@@ -146,15 +108,14 @@ dest_iter_init (pixman_implementation_t *imp,
iter->width = width;
iter->buffer = (uint32_t *)buffer;
- if (flags & ITER_NARROW)
+ if (image->type == BITS)
{
- iter->get_scanline = dest_get_scanline_narrow;
- iter->write_back = write_back_narrow;
+ _pixman_bits_image_dest_iter_init (
+ image, iter, x, y, width, height, buffer, flags);
}
else
{
- iter->get_scanline = dest_get_scanline_wide;
- iter->write_back = write_back_wide;
+ _pixman_log_error (FUNC, "Trying to write to a non-writable image");
}
}
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 383748a..853fb5a 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -193,10 +193,38 @@ union pixman_image
solid_fill_t solid;
};
+typedef struct pixman_iter_t pixman_iter_t;
+typedef enum
+{
+ ITER_NARROW = (1 << 0),
+} iter_flags_t;
+
+struct pixman_iter_t
+{
+ uint32_t *(* get_scanline) (pixman_iter_t *iter, const uint32_t *mask);
+ void (* write_back) (pixman_iter_t *iter);
+
+ pixman_image_t * image;
+ uint32_t * buffer;
+ int x, y;
+ int width;
+};
+
void
_pixman_bits_image_setup_accessors (bits_image_t *image);
void
+_pixman_bits_image_src_iter_init (pixman_image_t *image,
+ pixman_iter_t *iter,
+ int x, int y, int width, int height,
+ uint8_t *buffer, iter_flags_t flags);
+void
+_pixman_bits_image_dest_iter_init (pixman_image_t *image,
+ pixman_iter_t *iter,
+ int x, int y, int width, int height,
+ uint8_t *buffer, iter_flags_t flags);
+
+void
_pixman_image_get_scanline_generic_64 (pixman_image_t *image,
int x,
int y,
commit 15b1645c7b96498788c9376e3bb7d8a5e7b4e584
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date: Fri Dec 10 11:30:27 2010 -0500
Add iterators in the general implementation
We add a new structure called a pixman_iter_t that encapsulates the
information required to read scanlines from an image. It contains two
functions, get_scanline() and write_back(). The get_scanline()
function will generate pixels for the current scanline. For iterators
for source images, it will also advance to the next scanline. The
write_back() function is only called for destination images. Its
function is to write back the modified pixels to the image and then
advance to the next scanline.
When an iterator is initialized, it is passed this information:
- The image to iterate
- The rectangle to be iterated
- A buffer that the iterator may (but is not required to) use. This
buffer is guaranteed to have space for at least width pixels.
- A flag indicating whether a8r8g8b8 or a16r16g16b16 pixels should
be fetched
There are a number of (eventual) benefits to the iterators:
- The initialization of the iterator can be virtualized such that
implementations can plug in their own CPU specific get_scanline()
and write_back() functions.
- If an image is horizontal, it can simply plug in an appropriate
get_scanline(). This way we can get rid of the annoying
classify() virtual function.
- In general, iterators can remember what they did on the last
scanline, so for example a REPEAT_NONE image might reuse the same
data for all the empty scanlines generated by the zero-extension.
- More detailed information can be passed to iterator, allowing
more specialized fetchers to be used.
- We can fix the bug where destination filters and transformations
are not currently being ignored as they should be.
However, this initial implementation is not optimized at all. We lose
several existing optimizations:
- The ability to composite directly in the destination
- The ability to only fetch one scanline for horizontal images
- The ability to avoid fetching the src and mask for the CLEAR
operator
Later patches will re-introduce these optimizations.
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 8130f16..ea27e80 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -39,6 +39,125 @@
#include "pixman-combine32.h"
#include "pixman-private.h"
+typedef struct pixman_iter_t pixman_iter_t;
+typedef enum
+{
+ ITER_NARROW = (1 << 0)
+} iter_flags_t;
+
+struct pixman_iter_t
+{
+ uint32_t *(* get_scanline) (pixman_iter_t *iter, const uint32_t *mask);
+ void (* write_back) (pixman_iter_t *iter);
+
+ pixman_image_t * image;
+ uint32_t * buffer;
+ int x, y;
+ int width;
+};
+
+static uint32_t *
+src_get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
+{
+ return NULL;
+}
+
+static uint32_t *
+src_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
+{
+ _pixman_image_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)
+{
+ _pixman_image_get_scanline_64 (
+ iter->image, iter->x, iter->y++, iter->width, iter->buffer, mask);
+
+ return iter->buffer;
+}
+
+static void
+src_iter_init (pixman_implementation_t *imp,
+ pixman_iter_t *iter,
+ pixman_image_t *image,
+ int x, int y, int width, int height,
+ uint8_t *buffer, iter_flags_t flags)
+{
+ iter->image = image;
+ iter->x = x;
+ iter->y = y;
+ iter->width = width;
+ iter->buffer = (uint32_t *)buffer;
+
+ if (!image)
+ iter->get_scanline = src_get_scanline_null;
+ else if (flags & ITER_NARROW)
+ iter->get_scanline = src_get_scanline_narrow;
+ else
+ iter->get_scanline = src_get_scanline_wide;
+}
+
+static uint32_t *
+dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
+{
+ _pixman_image_get_scanline_32 (
+ iter->image, iter->x, iter->y, iter->width, iter->buffer, mask);
+
+ return iter->buffer;
+}
+
+static uint32_t *
+dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
+{
+ _pixman_image_get_scanline_64 (
+ iter->image, iter->x, iter->y, iter->width, iter->buffer, mask);
+
+ return iter->buffer;
+}
+
+static void
+write_back_narrow (pixman_iter_t *iter)
+{
+ _pixman_image_store_scanline_32 (
+ &iter->image->bits, iter->x, iter->y++, iter->width, iter->buffer);
+}
+
+static void
+write_back_wide (pixman_iter_t *iter)
+{
+ _pixman_image_store_scanline_64 (
+ &iter->image->bits, iter->x, iter->y++, iter->width, iter->buffer);
+}
+
+static void
+dest_iter_init (pixman_implementation_t *imp,
+ pixman_iter_t *iter,
+ pixman_image_t *image,
+ int x, int y, int width, int height,
+ uint8_t *buffer, iter_flags_t flags)
+{
+ iter->image = image;
+ iter->x = x;
+ iter->y = y;
+ iter->width = width;
+ iter->buffer = (uint32_t *)buffer;
+
+ if (flags & ITER_NARROW)
+ {
+ iter->get_scanline = dest_get_scanline_narrow;
+ iter->write_back = write_back_narrow;
+ }
+ else
+ {
+ iter->get_scanline = dest_get_scanline_wide;
+ iter->write_back = write_back_wide;
+ }
+}
+
#define SCANLINE_BUFFER_LENGTH 8192
static void
@@ -59,21 +178,25 @@ general_composite_rect (pixman_implementation_t *imp,
uint64_t stack_scanline_buffer[(SCANLINE_BUFFER_LENGTH * 3 + 7) / 8];
uint8_t *scanline_buffer = (uint8_t *) stack_scanline_buffer;
uint8_t *src_buffer, *mask_buffer, *dest_buffer;
- fetch_scanline_t fetch_src = NULL, fetch_mask = NULL, fetch_dest = NULL;
+ pixman_iter_t src_iter, mask_iter, dest_iter;
pixman_combine_32_func_t compose;
- store_scanline_t store;
- source_image_class_t src_class, mask_class;
pixman_bool_t component_alpha;
- uint32_t *bits;
- int32_t stride;
- int narrow, Bpp;
+ iter_flags_t narrow;
+ int Bpp;
int i;
- narrow =
- (src->common.flags & FAST_PATH_NARROW_FORMAT) &&
+ if ((src->common.flags & FAST_PATH_NARROW_FORMAT) &&
(!mask || mask->common.flags & FAST_PATH_NARROW_FORMAT) &&
- (dest->common.flags & FAST_PATH_NARROW_FORMAT);
- Bpp = narrow ? 4 : 8;
+ (dest->common.flags & FAST_PATH_NARROW_FORMAT))
+ {
+ narrow = ITER_NARROW;
+ Bpp = 4;
+ }
+ else
+ {
+ narrow = 0;
+ Bpp = 8;
+ }
if (width * Bpp > SCANLINE_BUFFER_LENGTH)
{
@@ -87,85 +210,19 @@ general_composite_rect (pixman_implementation_t *imp,
mask_buffer = src_buffer + width * Bpp;
dest_buffer = mask_buffer + width * Bpp;
- src_class = _pixman_image_classify (src,
- src_x, src_y,
- width, height);
-
- mask_class = SOURCE_IMAGE_CLASS_UNKNOWN;
-
- if (mask)
- {
- mask_class = _pixman_image_classify (mask,
- src_x, src_y,
- width, height);
- }
-
- if (op == PIXMAN_OP_CLEAR)
- fetch_src = NULL;
- else if (narrow)
- fetch_src = _pixman_image_get_scanline_32;
- else
- fetch_src = _pixman_image_get_scanline_64;
+ src_iter_init (imp->toplevel, &src_iter, src,
+ src_x, src_y, width, height,
+ src_buffer, narrow);
- if (!mask || op == PIXMAN_OP_CLEAR)
- fetch_mask = NULL;
- else if (narrow)
- fetch_mask = _pixman_image_get_scanline_32;
- else
- fetch_mask = _pixman_image_get_scanline_64;
+ src_iter_init (imp->toplevel, &mask_iter, mask,
+ mask_x, mask_y, width, height,
+ mask_buffer, narrow);
- if (op == PIXMAN_OP_CLEAR || op == PIXMAN_OP_SRC)
- fetch_dest = NULL;
- else if (narrow)
- fetch_dest = _pixman_image_get_scanline_32;
- else
- fetch_dest = _pixman_image_get_scanline_64;
-
- if (narrow)
- store = _pixman_image_store_scanline_32;
- else
- store = _pixman_image_store_scanline_64;
-
- /* Skip the store step and composite directly into the
- * destination if the output format of the compose func matches
- * the destination format.
- *
- * If the destination format is a8r8g8b8 then we can always do
- * this. If it is x8r8g8b8, then we can only do it if the
- * operator doesn't make use of destination alpha.
- */
- if ((dest->bits.format == PIXMAN_a8r8g8b8) ||
- (dest->bits.format == PIXMAN_x8r8g8b8 &&
- (op == PIXMAN_OP_OVER ||
- op == PIXMAN_OP_ADD ||
- op == PIXMAN_OP_SRC ||
- op == PIXMAN_OP_CLEAR ||
- op == PIXMAN_OP_IN_REVERSE ||
- op == PIXMAN_OP_OUT_REVERSE ||
- op == PIXMAN_OP_DST)))
- {
- if (narrow &&
- !dest->common.alpha_map &&
- !dest->bits.write_func)
- {
- store = NULL;
- }
- }
-
- if (!store)
- {
- bits = dest->bits.bits;
- stride = dest->bits.rowstride;
- }
- else
- {
- bits = NULL;
- stride = 0;
- }
+ dest_iter_init (imp->toplevel, &dest_iter, dest,
+ dest_x, dest_y, width, height,
+ dest_buffer, narrow);
component_alpha =
- fetch_src &&
- fetch_mask &&
mask &&
mask->common.type == BITS &&
mask->common.component_alpha &&
@@ -189,70 +246,17 @@ general_composite_rect (pixman_implementation_t *imp,
if (!compose)
return;
- if (!fetch_mask)
- mask_buffer = NULL;
-
for (i = 0; i < height; ++i)
{
- /* fill first half of scanline with source */
- if (fetch_src)
- {
- if (fetch_mask)
- {
- /* fetch mask before source so that fetching of
- source can be optimized */
- fetch_mask (mask, mask_x, mask_y + i,
- width, (void *)mask_buffer, 0);
-
- if (mask_class == SOURCE_IMAGE_CLASS_HORIZONTAL)
- fetch_mask = NULL;
- }
-
- if (src_class == SOURCE_IMAGE_CLASS_HORIZONTAL)
- {
- fetch_src (src, src_x, src_y + i,
- width, (void *)src_buffer, 0);
- fetch_src = NULL;
- }
- else
- {
- fetch_src (src, src_x, src_y + i,
- width, (void *)src_buffer, (void *)mask_buffer);
- }
- }
- else if (fetch_mask)
- {
- fetch_mask (mask, mask_x, mask_y + i,
- width, (void *)mask_buffer, 0);
- }
-
- if (store)
- {
- /* fill dest into second half of scanline */
- if (fetch_dest)
- {
- fetch_dest (dest, dest_x, dest_y + i,
- width, (void *)dest_buffer, 0);
- }
-
- /* blend */
- compose (imp->toplevel, op,
- (void *)dest_buffer,
- (void *)src_buffer,
- (void *)mask_buffer,
- width);
-
- /* write back */
- store (&(dest->bits), dest_x, dest_y + i, width,
- (void *)dest_buffer);
- }
- else
- {
- /* blend */
- compose (imp->toplevel, op,
- bits + (dest_y + i) * stride + dest_x,
- (void *)src_buffer, (void *)mask_buffer, width);
- }
+ uint32_t *s, *m, *d;
+
+ m = mask_iter.get_scanline (&mask_iter, NULL);
+ s = src_iter.get_scanline (&src_iter, m);
+ d = dest_iter.get_scanline (&dest_iter, NULL);
+
+ compose (imp->toplevel, op, d, s, m, width);
+
+ dest_iter.write_back (&dest_iter);
}
if (scanline_buffer != (uint8_t *) stack_scanline_buffer)
More information about the xorg-commit
mailing list