summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <sandmann@redhat.com>2009-09-13 05:29:48 -0400
committerSøren Sandmann Pedersen <sandmann@redhat.com>2010-02-14 11:10:15 -0500
commit87430cfc35c6e51bb1a947795e0ddb198c460253 (patch)
treebf50a2ae6cc6c6802ba5d887cc2edfbf668550dd
parentd7e281e0a1f7b1aecd245070736e03d2953b0911 (diff)
Make general_composite_rect() just another fast path.
We introduce a new PIXMAN_OP_any fake operator and a PIXMAN_any fake format that match anything. Then general_composite_rect() can be used as another fast path. Because general_composite_rect() does not require the sources to cover the clip region, we add a new flag FAST_PATH_COVERS_CLIP which is part of the set of standard flags for fast paths. Because this flag cannot be computed until after the clip region is available, we have to call pixman_compute_composite_region32() before checking for fast paths. This will resolve itself when we get to the point where _pixman_run_fast_path() is only called once per composite operation.
-rw-r--r--pixman/pixman-general.c25
-rw-r--r--pixman/pixman-private.h8
-rw-r--r--pixman/pixman-utils.c107
3 files changed, 85 insertions, 55 deletions
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index c96a3f9..83500b9 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -264,6 +264,17 @@ general_composite_rect (pixman_implementation_t *imp,
free (scanline_buffer);
}
+static const pixman_fast_path_t general_fast_path[] =
+{
+ { PIXMAN_OP_any,
+ PIXMAN_any, 0,
+ PIXMAN_any, 0,
+ PIXMAN_any, 0,
+ general_composite_rect,
+ },
+ { PIXMAN_OP_NONE }
+};
+
static void
general_composite (pixman_implementation_t * imp,
pixman_op_t op,
@@ -279,10 +290,16 @@ general_composite (pixman_implementation_t * imp,
int32_t width,
int32_t height)
{
- _pixman_walk_composite_region (imp, op, src, mask, dest, src_x, src_y,
- mask_x, mask_y, dest_x, dest_y,
- width, height,
- general_composite_rect);
+ pixman_bool_t result;
+
+ result = _pixman_run_fast_path (general_fast_path, imp,
+ op, src, mask, dest,
+ src_x, src_y,
+ mask_x, mask_y,
+ dest_x, dest_y,
+ width, height);
+
+ assert (result);
}
static pixman_bool_t
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index c99b101..0ed3662 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -564,6 +564,9 @@ _pixman_choose_implementation (void);
#define PIXMAN_pixbuf PIXMAN_FORMAT (0, 2, 0, 0, 0, 0)
#define PIXMAN_rpixbuf PIXMAN_FORMAT (0, 3, 0, 0, 0, 0)
#define PIXMAN_unknown PIXMAN_FORMAT (0, 4, 0, 0, 0, 0)
+#define PIXMAN_any PIXMAN_FORMAT (0, 5, 0, 0, 0, 0)
+
+#define PIXMAN_OP_any (PIXMAN_N_OPERATORS + 1)
#define FAST_PATH_ID_TRANSFORM (1 << 0)
#define FAST_PATH_NO_ALPHA_MAP (1 << 1)
@@ -572,7 +575,7 @@ _pixman_choose_implementation (void);
#define FAST_PATH_NO_REFLECT_REPEAT (1 << 4)
#define FAST_PATH_NO_ACCESSORS (1 << 5)
#define FAST_PATH_NO_WIDE_FORMAT (1 << 6)
-#define FAST_PATH_reserved (1 << 7)
+#define FAST_PATH_COVERS_CLIP (1 << 7)
#define FAST_PATH_COMPONENT_ALPHA (1 << 8)
#define FAST_PATH_UNIFIED_ALPHA (1 << 9)
@@ -583,7 +586,8 @@ _pixman_choose_implementation (void);
FAST_PATH_NO_PAD_REPEAT | \
FAST_PATH_NO_REFLECT_REPEAT | \
FAST_PATH_NO_ACCESSORS | \
- FAST_PATH_NO_WIDE_FORMAT)
+ FAST_PATH_NO_WIDE_FORMAT | \
+ FAST_PATH_COVERS_CLIP)
#define FAST_PATH_STD_SRC_FLAGS \
_FAST_PATH_STANDARD_FLAGS
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index 5441b6b..66bdb30 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -614,7 +614,9 @@ _pixman_run_fast_path (const pixman_fast_path_t *paths,
pixman_composite_func_t func;
const pixman_fast_path_t *info;
pixman_bool_t result;
-
+ pixman_region32_t region;
+ pixman_box32_t *extents;
+
get_image_info (src, &src_format, &src_flags);
get_image_info (mask, &mask_format, &mask_flags);
get_image_info (dest, &dest_format, &dest_flags);
@@ -631,15 +633,40 @@ _pixman_run_fast_path (const pixman_fast_path_t *paths,
src_format = mask_format = PIXMAN_rpixbuf;
}
+ pixman_region32_init (&region);
+
+ if (!pixman_compute_composite_region32 (
+ &region, src, mask, dest,
+ src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
+ {
+ return TRUE;
+ }
+
+ result = FALSE;
+
+ extents = pixman_region32_extents (&region);
+
+ if (image_covers (src, extents, dest_x - src_x, dest_y - src_y))
+ src_flags |= FAST_PATH_COVERS_CLIP;
+
+ if (mask && image_covers (mask, extents, dest_x - mask_x, dest_y - mask_y))
+ mask_flags |= FAST_PATH_COVERS_CLIP;
+
func = NULL;
for (info = paths; info->op != PIXMAN_OP_NONE; ++info)
{
- if (info->op == op &&
- (info->src_format == src_format) &&
+ if ((info->op == op || info->op == PIXMAN_OP_any) &&
+ /* src */
+ ((info->src_format == src_format) ||
+ (info->src_format == PIXMAN_any)) &&
(info->src_flags & src_flags) == info->src_flags &&
- (info->mask_format == mask_format) &&
+ /* mask */
+ ((info->mask_format == mask_format) ||
+ (info->mask_format == PIXMAN_any)) &&
(info->mask_flags & mask_flags) == info->mask_flags &&
- (info->dest_format == dest_format) &&
+ /* dest */
+ ((info->dest_format == dest_format) ||
+ (info->dest_format == PIXMAN_any)) &&
(info->dest_flags & dest_flags) == info->dest_flags)
{
func = info->func;
@@ -647,54 +674,36 @@ _pixman_run_fast_path (const pixman_fast_path_t *paths,
}
}
- result = FALSE;
-
if (func)
{
- pixman_region32_t region;
- pixman_region32_init (&region);
-
- if (pixman_compute_composite_region32 (
- &region, src, mask, dest,
- src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
- {
- pixman_box32_t *extents = pixman_region32_extents (&region);
-
- if (sources_cover (
- src, mask, extents,
- src_x, src_y, mask_x, mask_y, dest_x, dest_y))
- {
- pixman_bool_t src_repeat, mask_repeat;
-
- src_repeat =
- src->type == BITS &&
- src_flags & FAST_PATH_ID_TRANSFORM &&
- src->common.repeat == PIXMAN_REPEAT_NORMAL &&
- src_format != PIXMAN_solid;
-
- mask_repeat =
- mask &&
- mask->type == BITS &&
- mask_flags & FAST_PATH_ID_TRANSFORM &&
- mask->common.repeat == PIXMAN_REPEAT_NORMAL &&
- mask_format != PIXMAN_solid;
-
- walk_region_internal (imp, op,
- src, mask, dest,
- src_x, src_y, mask_x, mask_y,
- dest_x, dest_y,
- width, height,
- src_repeat, mask_repeat,
- &region,
- func);
-
- result = TRUE;
- }
-
- pixman_region32_fini (&region);
- }
+ pixman_bool_t src_repeat, mask_repeat;
+
+ src_repeat =
+ src->type == BITS &&
+ src_flags & FAST_PATH_ID_TRANSFORM &&
+ src->common.repeat == PIXMAN_REPEAT_NORMAL &&
+ src_format != PIXMAN_solid;
+
+ mask_repeat =
+ mask &&
+ mask->type == BITS &&
+ mask_flags & FAST_PATH_ID_TRANSFORM &&
+ mask->common.repeat == PIXMAN_REPEAT_NORMAL &&
+ mask_format != PIXMAN_solid;
+
+ walk_region_internal (imp, op,
+ src, mask, dest,
+ src_x, src_y, mask_x, mask_y,
+ dest_x, dest_y,
+ width, height,
+ src_repeat, mask_repeat,
+ &region,
+ func);
+
+ result = TRUE;
}
+ pixman_region32_fini (&region);
return result;
}