summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2011-09-05 00:19:51 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2011-09-05 00:20:06 -0400
commit3ec5523efeb4d08757778257a8fb0c6106c2ed73 (patch)
tree0c75ef9197f360fad52cd1025d1bdc8350ae607f
parent897f53879efb403344b5d8f0c7ff0e55f9a0317b (diff)
Eliminate compute_sample_extents() functionextents-cleanup
In analyze_extents(), instead of calling compute_sample_extents() twice, just call compute_transformed_extents() once. Instead of calling compute_sample_extents() for the destination rectangle expanded by one, just call compute_transformed_extents() and expand the returned rectangle by adding the absolute values of the 00 and 10 entries in the transformation, then check if the results fit in 16 bits. This is a little bit more conservative than necessary, but only corner cases where we are already close to the limit of the 16 bit coordinate space are affected. The rest of the compute_sample_extents() function can now just be inlined into analyze_extents(), and compute_sample_extents() can be deleted.
-rw-r--r--pixman/pixman.c94
1 files changed, 36 insertions, 58 deletions
diff --git a/pixman/pixman.c b/pixman/pixman.c
index 264a56b2..3ecd3115 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -514,45 +514,9 @@ compute_transformed_extents (pixman_transform_t *transform,
return TRUE;
}
-static pixman_bool_t
-compute_sample_extents (pixman_transform_t *transform,
- pixman_box32_t *extents,
- pixman_fixed_t x_off, pixman_fixed_t y_off,
- pixman_fixed_t width, pixman_fixed_t height)
-{
- box_48_16_t transformed;
-
- if (!compute_transformed_extents (transform, extents, &transformed))
- return FALSE;
-
- /* Expand the source area by a tiny bit so account of different rounding that
- * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
- * 0.5 so this won't cause the area computed to be overly pessimistic.
- */
- transformed.x1 += x_off - 8 * pixman_fixed_e;
- transformed.y1 += y_off - 8 * pixman_fixed_e;
- transformed.x2 += x_off + width + 8 * pixman_fixed_e;
- transformed.y2 += y_off + height + 8 * pixman_fixed_e;
-
- if (transformed.x1 < pixman_min_fixed_48_16 || transformed.x1 > pixman_max_fixed_48_16 ||
- transformed.y1 < pixman_min_fixed_48_16 || transformed.y1 > pixman_max_fixed_48_16 ||
- transformed.x2 < pixman_min_fixed_48_16 || transformed.x2 > pixman_max_fixed_48_16 ||
- transformed.y2 < pixman_min_fixed_48_16 || transformed.y2 > pixman_max_fixed_48_16)
- {
- return FALSE;
- }
- else
- {
- extents->x1 = pixman_fixed_to_int (transformed.x1);
- extents->y1 = pixman_fixed_to_int (transformed.y1);
- extents->x2 = pixman_fixed_to_int (transformed.x2) + 1;
- extents->y2 = pixman_fixed_to_int (transformed.y2) + 1;
-
- return TRUE;
- }
-}
-
#define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
+#define ABS(f) (((f) < 0)? (-(f)) : (f))
+#define IS_16_16(f) (((f) >= pixman_min_fixed_48_16 && ((f) <= pixman_max_fixed_48_16)))
static pixman_bool_t
analyze_extent (pixman_image_t *image,
@@ -563,7 +527,8 @@ analyze_extent (pixman_image_t *image,
pixman_fixed_t *params;
pixman_fixed_t x_off, y_off;
pixman_fixed_t width, height;
- pixman_box32_t ex;
+ pixman_fixed_t m00, m10;
+ box_48_16_t transformed;
if (!image)
return TRUE;
@@ -633,17 +598,6 @@ analyze_extent (pixman_image_t *image,
default:
return FALSE;
}
-
- /* Check whether the non-expanded, transformed extent is entirely within
- * the source image, and set the FAST_PATH_SAMPLES_COVER_CLIP if it is.
- */
- ex = *extents;
- if (compute_sample_extents (transform, &ex, x_off, y_off, width, height) &&
- ex.x1 >= 0 && ex.y1 >= 0 &&
- ex.x2 <= image->bits.width && ex.y2 <= image->bits.height)
- {
- *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
- }
}
else
{
@@ -653,17 +607,41 @@ analyze_extent (pixman_image_t *image,
height = 0;
}
- /* Check that the extents expanded by one don't overflow. This ensures that
- * compositing functions can simply walk the source space using 16.16
- * variables without worrying about overflow.
+ if (!compute_transformed_extents (transform, extents, &transformed))
+ return FALSE;
+
+ /* Expand the source area by a tiny bit so account of different rounding that
+ * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
+ * 0.5 so this won't cause the area computed to be overly pessimistic.
+ */
+ transformed.x1 += x_off - 8 * pixman_fixed_e;
+ transformed.y1 += y_off - 8 * pixman_fixed_e;
+ transformed.x2 += x_off + width + 8 * pixman_fixed_e;
+ transformed.y2 += y_off + height + 8 * pixman_fixed_e;
+
+ /* Check we don't overflow when the destination extents are expanded by one.
+ * This ensures that compositing functions can simply walk the source space
+ * using 16.16 variables without worrying about overflow.
*/
- ex.x1 = extents->x1 - 1;
- ex.y1 = extents->y1 - 1;
- ex.x2 = extents->x2 + 1;
- ex.y2 = extents->y2 + 1;
+ m00 = transform? ABS (transform->matrix[0][0]) : pixman_fixed_1;
+ m10 = transform? ABS (transform->matrix[1][0]) : 0;
- if (!compute_sample_extents (transform, &ex, x_off, y_off, width, height))
+ if (!IS_16_16 (transformed.x1 - m00) ||
+ !IS_16_16 (transformed.y1 - m10) ||
+ !IS_16_16 (transformed.x2 + m00) ||
+ !IS_16_16 (transformed.y2 + m10))
+ {
return FALSE;
+ }
+
+ if (image->common.type == BITS &&
+ pixman_fixed_to_int (transformed.x1) >= 0 &&
+ pixman_fixed_to_int (transformed.y1) >= 0 &&
+ pixman_fixed_to_int (transformed.x2) < image->bits.width &&
+ pixman_fixed_to_int (transformed.y2) < image->bits.height)
+ {
+ *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
+ }
return TRUE;
}