[2/4] Introduce FAST_PATH_SAMPLES_COVER_CLIP_TIGHT_BILINEAR flag

Submitted by Ben Avison on Sept. 4, 2015, 2:09 a.m.

Details

Message ID 1441332563-23521-2-git-send-email-bavison@riscosopen.org
State Under Review
Headers show

Not browsing as part of any series.

Commit Message

Ben Avison Sept. 4, 2015, 2:09 a.m.
This flag is similar to FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR, except that
it requires and permits corresponding fast paths and iterators to handle
operations where both of the following hold:

* the lower destination coordinate, transformed into source space, matches
  or is higher than the centre of the first pixel/row (0.5)
* the upper destination coordinate, transformed into source space, matches
  or is lower than the centre of the last pixel/row (width-0.5 or height-0.5)

Because the first thing that a bilinear fast path does with coordinates is
typically to subtract pixman_fixed_1/2, this may also be conveniently
expressed as the adjusted coordinate falling into the interval
[0, (width-1)*pixman_fixed_1] or [0, (height-1)*pixman_fixed_1].

The old flag was inclusive at the lower end and exclusive at the upper end.
The new flag is inclusive at both ends.

The new flag permits those fast path implementations that filter out loads
of zero-weighted pixels beyond the limits of both transformed coordinates to
be utilised in the maximum number of cases.

The next series of patches adapt each fast path that uses the old flag to
follow the rules of the new flag, using a variety of different techniques.
The eventual aim is to retire the old flag entirely, at which point the new
flag can be renamed to match the old one.
---
 pixman/pixman-private.h |    1 +
 pixman/pixman.c         |    8 ++++++++
 2 files changed, 9 insertions(+), 0 deletions(-)

Patch hide | download patch | download mbox

diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 73108a0..dff42c8 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -701,6 +701,7 @@  _pixman_iter_init_bits_stride (pixman_iter_t *iter, const pixman_iter_info_t *in
 #define FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR	(1 << 24)
 #define FAST_PATH_BITS_IMAGE			(1 << 25)
 #define FAST_PATH_SEPARABLE_CONVOLUTION_FILTER  (1 << 26)
+#define FAST_PATH_SAMPLES_COVER_CLIP_TIGHT_BILINEAR (1 << 27)
 
 #define FAST_PATH_PAD_REPEAT						\
     (FAST_PATH_NO_NONE_REPEAT		|				\
diff --git a/pixman/pixman.c b/pixman/pixman.c
index f932eac..61bc3bd 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -514,6 +514,14 @@  analyze_extent (pixman_image_t       *image,
 	{
 	    *flags |= FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR;
 	}
+
+        if (pixman_fixed_to_int (transformed.x1 - pixman_fixed_1 / 2) >= 0                                 &&
+            pixman_fixed_to_int (transformed.y1 - pixman_fixed_1 / 2) >= 0                                 &&
+            pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2 - pixman_fixed_e) < image->bits.width &&
+            pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2 - pixman_fixed_e) < image->bits.height)
+        {
+            *flags |= FAST_PATH_SAMPLES_COVER_CLIP_TIGHT_BILINEAR;
+        }
     }
 
     /* Check we don't overflow when the destination extents are expanded by one.