pixman: Branch 'master'

Søren Sandmann Pedersen sandmann at kemper.freedesktop.org
Mon Mar 10 20:45:02 PDT 2008


 pixman/pixman-compose.c |   32 ++++++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 8 deletions(-)

New commits:
commit f2d8a5caa63596739b4dc47c00daaaafd9f522e2
Author: Søren Sandmann <sandmann at redhat.com>
Date:   Mon Mar 10 23:41:52 2008 -0400

    Add rounding epsilon for NEAREST filter after transformation, not before.
    
    For nearest filtering, the transformed location must be rounded to the
    nearest sample. For locations that precisely in the middle between two
    samples, we round down by adding -epsilon to the coordinates.
    
    Before, we would do this on untransformed coordinates. This patch
    changes it to happen after transformation. It also clarifies the
    difference between sample locations and rounding.
    
    Reported by Robert O'Callahan.

diff --git a/pixman/pixman-compose.c b/pixman/pixman-compose.c
index 1b2d581..faf2523 100644
--- a/pixman/pixman-compose.c
+++ b/pixman/pixman-compose.c
@@ -4180,6 +4180,19 @@ fbFetchTransformed_Convolution(bits_image_t * pict, int width, uint32_t *buffer,
 }
 
 static void
+adjust (pixman_vector_t *v, pixman_vector_t *u, pixman_fixed_t adjustment)
+{
+    int delta_v = (adjustment * v->vector[2]) >> 16;
+    int delta_u = (adjustment * u->vector[2]) >> 16;
+    
+    v->vector[0] += delta_v;
+    v->vector[1] += delta_v;
+    
+    u->vector[0] += delta_u;
+    u->vector[1] += delta_u;
+}
+
+static void
 fbFetchTransformed(bits_image_t * pict, int x, int y, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
 {
     uint32_t     *bits;
@@ -4192,8 +4205,8 @@ fbFetchTransformed(bits_image_t * pict, int x, int y, int width, uint32_t *buffe
     stride = pict->rowstride;
 
     /* reference point is the center of the pixel */
-    v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1 / 2 - 1;
-    v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1 / 2 - 1;
+    v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1 / 2;
+    v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1 / 2;
     v.vector[2] = pixman_fixed_1;
 
     /* when using convolution filters or PIXMAN_REPEAT_PAD one might get here without a transform */
@@ -4216,8 +4229,14 @@ fbFetchTransformed(bits_image_t * pict, int x, int y, int width, uint32_t *buffe
         unit.vector[2] = 0;
     }
 
+    /* This allows filtering code to pretend that pixels are located at integer coordinates */
+    adjust (&v, &unit, -(pixman_fixed_1 / 2));
+    
     if (pict->common.filter == PIXMAN_FILTER_NEAREST || pict->common.filter == PIXMAN_FILTER_FAST)
     {
+	/* Round down to closest integer, ensuring that 0.5 rounds to 0, not 1 */
+	adjust (&v, &unit, pixman_fixed_1 / 2 - pixman_fixed_e);
+	
         if (pict->common.repeat == PIXMAN_REPEAT_NORMAL)
         {
             fbFetchTransformed_Nearest_Normal(pict, width, buffer, mask, maskBits, affine, v, unit);
@@ -4235,12 +4254,6 @@ fbFetchTransformed(bits_image_t * pict, int x, int y, int width, uint32_t *buffe
 	       pict->common.filter == PIXMAN_FILTER_GOOD	||
 	       pict->common.filter == PIXMAN_FILTER_BEST)
     {
-        /* adjust vector for maximum contribution at 0.5, 0.5 of each texel. */
-        v.vector[0] -= v.vector[2] / 2;
-        v.vector[1] -= v.vector[2] / 2;
-        unit.vector[0] -= unit.vector[2] / 2;
-        unit.vector[1] -= unit.vector[2] / 2;
-
         if (pict->common.repeat == PIXMAN_REPEAT_NORMAL)
         {
             fbFetchTransformed_Bilinear_Normal(pict, width, buffer, mask, maskBits, affine, v, unit);
@@ -4256,6 +4269,9 @@ fbFetchTransformed(bits_image_t * pict, int x, int y, int width, uint32_t *buffe
     }
     else if (pict->common.filter == PIXMAN_FILTER_CONVOLUTION)
     {
+	/* Round to closest integer, ensuring that 0.5 rounds to 0, not 1 */
+	adjust (&v, &unit, pixman_fixed_1 / 2 - pixman_fixed_e);
+	
         fbFetchTransformed_Convolution(pict, width, buffer, mask, maskBits, affine, v, unit);
     }
 


More information about the xorg-commit mailing list