[Pixman] [PATCH 1/3] 'pixman_transform_bounds' fixed to match the rest of transform code

Siarhei Siamashka siarhei.siamashka at gmail.com
Mon Jul 19 13:41:07 PDT 2010


From: Siarhei Siamashka <siarhei.siamashka at nokia.com>

This fixes the discrepancy between how FAST_PATH_SAMPLES_COVER_CLIP
flag is calculated and the code in fast_composite_scaled_nearest_*
functions.

Function 'pixman_transform_bounds' which is used for deciding whether
to set FAST_PATH_SAMPLES_COVER_CLIP flag, was doing 'pixman_transform_point'
call. While 'fast_composite_scaled_nearest_*' functions do initial addition
of 'pixman_fixed_1 / 2' constant, then call 'pixman_transform_point_3d' and
finally subtract 'pixman_fixed_e'.

As a result, two problems were possible:
1. Invalid memory accesses when fast_composite_scaled_nearest_* functions try
to fetch pixels outside the source image.
2. Missing FAST_PATH_SAMPLES_COVER_CLIP flag for the cases, when there is
actually no need to access pixels outside the source image. Causing fast
path functions not to be used and impacting performance.

As an additional note, function 'pixman_transform_point_3d' is truncating low
order bits in intermediate calculations losing some precision. But this
can't affect non-rotated nearest neighbor scaling.
---
 pixman/pixman-matrix.c |   21 ++++++++++++---------
 1 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/pixman/pixman-matrix.c b/pixman/pixman-matrix.c
index abdfa05..0ace321 100644
--- a/pixman/pixman-matrix.c
+++ b/pixman/pixman-matrix.c
@@ -287,27 +287,30 @@ pixman_transform_bounds (const struct pixman_transform *matrix,
     int i;
     int x1, y1, x2, y2;
 
-    v[0].vector[0] = F (b->x1);
-    v[0].vector[1] = F (b->y1);
+    v[0].vector[0] = F (b->x1) + pixman_fixed_1 / 2;
+    v[0].vector[1] = F (b->y1) + pixman_fixed_1 / 2;
     v[0].vector[2] = F (1);
 
-    v[1].vector[0] = F (b->x2);
-    v[1].vector[1] = F (b->y1);
+    v[1].vector[0] = F (b->x2) + pixman_fixed_1 / 2;
+    v[1].vector[1] = F (b->y1) + pixman_fixed_1 / 2;
     v[1].vector[2] = F (1);
 
-    v[2].vector[0] = F (b->x2);
-    v[2].vector[1] = F (b->y2);
+    v[2].vector[0] = F (b->x2) + pixman_fixed_1 / 2;
+    v[2].vector[1] = F (b->y2) + pixman_fixed_1 / 2;
     v[2].vector[2] = F (1);
 
-    v[3].vector[0] = F (b->x1);
-    v[3].vector[1] = F (b->y2);
+    v[3].vector[0] = F (b->x1) + pixman_fixed_1 / 2;
+    v[3].vector[1] = F (b->y2) + pixman_fixed_1 / 2;
     v[3].vector[2] = F (1);
 
     for (i = 0; i < 4; i++)
     {
-	if (!pixman_transform_point (matrix, &v[i]))
+	if (!pixman_transform_point_3d (matrix, &v[i]))
 	    return FALSE;
 
+	v[i].vector[0] -= pixman_fixed_e;
+	v[i].vector[1] -= pixman_fixed_e;
+
 	x1 = pixman_fixed_to_int (v[i].vector[0]);
 	y1 = pixman_fixed_to_int (v[i].vector[1]);
 	x2 = pixman_fixed_to_int (pixman_fixed_ceil (v[i].vector[0]));
-- 
1.6.4.4



More information about the Pixman mailing list