diff options
author | Alexander Larsson <alexl@redhat.com> | 2010-03-12 15:41:01 +0100 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2010-03-17 11:03:05 -0400 |
commit | 5750408e48259f42373a5233231104d9bd3eb35a (patch) | |
tree | 91c34072dfdc3736fee726731fb378c0dda9af16 /pixman | |
parent | cba6fbbddce5edfd8e28ef570c493b044761f870 (diff) |
Add FAST_PATH_SAMPLES_COVER_CLIP and FAST_PATH_16BIT_SAFE
FAST_PATH_SAMPLES_COVER_CLIP:
This is set of the source sample grid, unrepeated but transformed
completely completely covers the clip destination. If this is set
you can use a simple scaled that doesn't have to care about the repeat
mode.
FAST_PATH_16BIT_SAFE:
This signifies two things:
1) The size of the src/mask fits in a 16.16 fixed point, so something like:
max_vx = src_image->bits.width << 16;
Is allowed and is guaranteed to not overflow max_vx
2) When stepping the source space we're guaranteed to never overflow
a 16.16 bit fix point variable, even if we step one extra step
in the destination space. This means that a loop doing:
x = vx >> 16;
vx += unit_x; d = src_row[x];
will never overflow vx causing x to be negative.
And additionally, if you track vx like above and apply NORMAL repeat
after the vx addition with something like:
while (vx >= max_vx) vx -= max_vx;
This will never overflow the vx even on the final increment that
takes vx one past the end of where we will read, which makes the
repeat loop safe.
Diffstat (limited to 'pixman')
-rw-r--r-- | pixman/pixman-private.h | 2 | ||||
-rw-r--r-- | pixman/pixman.c | 84 |
2 files changed, 69 insertions, 17 deletions
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index 65314b9..0cf9113 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -580,6 +580,8 @@ _pixman_choose_implementation (void); #define FAST_PATH_IS_OPAQUE (1 << 13) #define FAST_PATH_NEEDS_WORKAROUND (1 << 14) #define FAST_PATH_NO_NONE_REPEAT (1 << 15) +#define FAST_PATH_SAMPLES_COVER_CLIP (1 << 16) +#define FAST_PATH_16BIT_SAFE (1 << 17) #define _FAST_PATH_STANDARD_FLAGS \ (FAST_PATH_ID_TRANSFORM | \ diff --git a/pixman/pixman.c b/pixman/pixman.c index 68483a0..56c9536 100644 --- a/pixman/pixman.c +++ b/pixman/pixman.c @@ -479,24 +479,75 @@ walk_region_internal (pixman_implementation_t *imp, } } -static force_inline pixman_bool_t -image_covers (pixman_image_t *image, - pixman_box32_t *extents, - int x, - int y) +#define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX)) + +static force_inline uint32_t +compute_src_extents_flags (pixman_image_t *image, + pixman_box32_t *extents, + int x, + int y) { - if (image->common.type == BITS && - image->common.repeat == PIXMAN_REPEAT_NONE) + pixman_box16_t extents16; + uint32_t flags; + + flags = FAST_PATH_COVERS_CLIP; + + if (image->common.type != BITS) + return flags; + + if (image->common.repeat == PIXMAN_REPEAT_NONE && + (x > extents->x1 || y > extents->y1 || + x + image->bits.width < extents->x2 || + y + image->bits.height < extents->y2)) + { + flags &= ~FAST_PATH_COVERS_CLIP; + } + + if (IS_16BIT (extents->x1 - x) && + IS_16BIT (extents->y1 - y) && + IS_16BIT (extents->x2 - x) && + IS_16BIT (extents->y2 - y)) { - if (x > extents->x1 || y > extents->y1 || - x + image->bits.width < extents->x2 || - y + image->bits.height < extents->y2) + extents16.x1 = extents->x1 - x; + extents16.y1 = extents->y1 - y; + extents16.x2 = extents->x2 - x; + extents16.y2 = extents->y2 - y; + + if (!image->common.transform || + pixman_transform_bounds (image->common.transform, &extents16)) { - return FALSE; + if (extents16.x1 >= 0 && extents16.y1 >= 0 && + extents16.x2 <= image->bits.width && + extents16.y2 <= image->bits.height) + { + flags |= FAST_PATH_SAMPLES_COVER_CLIP; + } } } - return TRUE; + if (IS_16BIT (extents->x1 - x - 1) && + IS_16BIT (extents->y1 - y - 1) && + IS_16BIT (extents->x2 - x + 1) && + IS_16BIT (extents->y2 - y + 1)) + { + extents16.x1 = extents->x1 - x - 1; + extents16.y1 = extents->y1 - y - 1; + extents16.x2 = extents->x2 - x + 1; + extents16.y2 = extents->y2 - y + 1; + + if (/* src space expanded by one in dest space fits in 16 bit */ + (!image->common.transform || + pixman_transform_bounds (image->common.transform, &extents16)) && + /* And src image size can be used as 16.16 fixed point */ + image->bits.width < 0x7fff && + image->bits.height < 0x7fff) + { + /* Then we're "16bit safe" */ + flags |= FAST_PATH_16BIT_SAFE; + } + } + + return flags; } #define N_CACHED_FAST_PATHS 8 @@ -588,11 +639,10 @@ do_composite (pixman_implementation_t *imp, extents = pixman_region32_extents (®ion); - 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; + src_flags |= compute_src_extents_flags (src, extents, dest_x - src_x, dest_y - src_y); + + if (mask) + mask_flags |= compute_src_extents_flags (mask, extents, dest_x - mask_x, dest_y - mask_y); /* * Check if we can replace our operator by a simpler one |