[Pixman] [PATCH 16/18] Skip fetching pixels when possible
Søren Sandmann
sandmann at cs.au.dk
Wed Jan 5 18:28:00 PST 2011
From: Søren Sandmann Pedersen <ssp at redhat.com>
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.
---
pixman/pixman-bits-image.c | 11 +++++-
pixman/pixman-general.c | 74 +++++++++++++++++++++++++++------------
pixman/pixman-implementation.c | 7 ++++
pixman/pixman-private.h | 4 ++-
4 files changed, 71 insertions(+), 25 deletions(-)
diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index df8d56e..7d588a9 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -1444,7 +1444,16 @@ _pixman_bits_image_iter_init (pixman_image_t *image,
}
else
{
- iter->get_scanline = 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 = get_scanline_narrow;
+ }
+
iter->next_line = next_line_write_narrow;
}
}
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 84b52c2..25d1fe4 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -83,6 +83,34 @@ general_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
@@ -106,7 +134,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;
@@ -135,39 +163,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_iter_init (imp->toplevel, &src_iter, src,
src_x, src_y, width, height,
- src_buffer, narrow);
-
- _pixman_implementation_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_WRITE | 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 | ITER_WRITE;
+ /* If it doesn't matter what the source is, then it doesn't matter
+ * what the mask is
+ */
+ mask = NULL;
}
- _pixman_implementation_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_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_iter_init (imp->toplevel, &dest_iter, dest,
+ dest_x, dest_y, width, height,
+ dest_buffer,
+ narrow | ITER_WRITE | op_flags[op].dst);
+
if (narrow)
{
if (component_alpha)
diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index 1aa28d1..57134cb 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -258,11 +258,18 @@ _pixman_implementation_iter_init (pixman_implementation_t *imp,
uint8_t *buffer,
iter_flags_t flags)
{
+#define NOOP (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)
+
if (!image)
{
iter->get_scanline = get_scanline_null;
iter->next_line = _pixman_iter_next_line_noop;
}
+ else if ((flags & (NOOP | ITER_WRITE)) == NOOP)
+ {
+ iter->get_scanline = _pixman_iter_get_scanline_noop;
+ iter->next_line = _pixman_iter_next_line_noop;
+ }
else
{
(*imp->iter_init) (
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 8532b98..2a00dc4 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -201,7 +201,9 @@ typedef enum
* we can treat it as ARGB, which means in some cases we can avoid copying
* it to a temporary buffer.
*/
- ITER_LOCALIZED_ALPHA = (1 << 2)
+ ITER_LOCALIZED_ALPHA = (1 << 2),
+ ITER_IGNORE_ALPHA = (1 << 3),
+ ITER_IGNORE_RGB = (1 << 4)
} iter_flags_t;
struct pixman_iter_t
--
1.6.0.6
More information about the Pixman
mailing list