pixman: Branch 'master' - 5 commits

Søren Sandmann Pedersen sandmann at kemper.freedesktop.org
Wed Feb 24 18:53:58 PST 2010


 pixman/pixman-edge-imp.h |   12 +++++++----
 pixman/pixman-private.h  |    4 +--
 pixman/pixman-trap.c     |   14 ++++++-------
 test/Makefile.am         |    2 +
 test/a1-trap-test.c      |   50 +++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 69 insertions(+), 13 deletions(-)

New commits:
commit e0f1d8410715083498a35284ea7e5bb71fabe090
Merge: 16ef3ab... 282f5cf...
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Wed Feb 24 21:01:29 2010 -0500

    Merge branch 'trap-fixes'

commit 16ef3ab230047221f813905d390bf762a3d8508a
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Wed Feb 24 20:51:25 2010 -0500

    Add a1-trap-test
    
    When a trapezoid sample point is exactly on a polygon edge, the rule
    is that it is considered inside the trapezoid if the edge is a top or
    left edge, but outside for bottom and right edges.
    
    This program tests that for a1 trapezoids.

diff --git a/test/Makefile.am b/test/Makefile.am
index 3229f96..841ff8d 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -2,6 +2,7 @@ TEST_LDADD = $(top_builddir)/pixman/libpixman-1.la
 INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman
 
 TESTPROGRAMS =			\
+	a1-trap-test		\
 	region-test		\
 	fetch-test		\
 	oob-test		\
@@ -12,6 +13,7 @@ TESTPROGRAMS =			\
 	scaling-test		\
 	composite
 
+a1_trap_test_LDADD = $(TEST_LDADD)
 fetch_test_LDADD = $(TEST_LDADD)
 composite_LDADD = $(TEST_LDADD)
 trap_crasher_LDADD = $(TEST_LDADD)
diff --git a/test/a1-trap-test.c b/test/a1-trap-test.c
new file mode 100644
index 0000000..6163e7c
--- /dev/null
+++ b/test/a1-trap-test.c
@@ -0,0 +1,50 @@
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "pixman.h"
+
+int
+main (int argc, char **argv)
+{
+#define WIDTH 20
+#define HEIGHT 20
+
+    pixman_image_t *src_img;
+    pixman_image_t *mask_img;
+    pixman_image_t *dest_img;
+    pixman_trap_t trap;
+    pixman_color_t red = { 0xffff, 0x0000, 0x0000, 0xffff };
+    uint32_t *bits = malloc (WIDTH * HEIGHT * 4);
+    uint32_t *mbits = malloc (WIDTH * HEIGHT);
+
+    memset (mbits, 0, WIDTH * HEIGHT);
+    memset (bits, 0xff, WIDTH * HEIGHT * 4);
+    
+    trap.top.l = pixman_double_to_fixed (0.5);
+    trap.top.r = pixman_double_to_fixed (1.5);
+    trap.top.y = pixman_double_to_fixed (0.5);
+
+    trap.bot.l = pixman_double_to_fixed (0.5);
+    trap.bot.r = pixman_double_to_fixed (1.5);
+    trap.bot.y = pixman_double_to_fixed (1.5);
+
+    mask_img = pixman_image_create_bits (
+	PIXMAN_a1, WIDTH, HEIGHT, mbits, WIDTH);
+    src_img = pixman_image_create_solid_fill (&red);
+    dest_img = pixman_image_create_bits (
+	PIXMAN_a8r8g8b8, WIDTH, HEIGHT, bits, WIDTH * 4);
+    
+    pixman_add_traps (mask_img, 0, 0, 1, &trap);
+
+    pixman_image_composite (PIXMAN_OP_OVER,
+			    src_img, mask_img, dest_img,
+			    0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
+
+    assert (bits[0] == 0xffff0000);
+    assert (bits[1] == 0xffffffff);
+    assert (bits[1 * WIDTH + 0] == 0xffffffff);
+    assert (bits[1 * WIDTH + 1] == 0xffffffff);
+    
+    return 0;
+}
commit 282f5cf8b821a34bab1e32957913ef8d9f9ee43c
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Thu Nov 12 17:54:40 2009 -0500

    Round horizontal sampling points towards northwest.
    
    This is a similar change as the top/bottom one, but in this case the
    rounding is simpler because it's just always rounding down.
    
    Based on a patch by M Joonas Pihlaja.

diff --git a/pixman/pixman-edge-imp.h b/pixman/pixman-edge-imp.h
index a30f821..d786ea7 100644
--- a/pixman/pixman-edge-imp.h
+++ b/pixman/pixman-edge-imp.h
@@ -49,10 +49,14 @@ RASTERIZE_EDGES (pixman_image_t  *image,
 	rx = r->x;
 #if N_BITS == 1
 	/* For the non-antialiased case, round the coordinates up, in effect
-	 * sampling the center of the pixel. (The AA case does a similar 
-	 * adjustment in RENDER_SAMPLES_X) */
-	lx += X_FRAC_FIRST(1);
-	rx += X_FRAC_FIRST(1);
+	 * sampling just slightly to the left of the pixel. This is so that
+	 * when the sample point lies exactly on the line, we round towards
+	 * north-west.
+	 *
+	 * (The AA case does a similar  adjustment in RENDER_SAMPLES_X)
+	 */
+	lx += X_FRAC_FIRST(1) - pixman_fixed_e;
+	rx += X_FRAC_FIRST(1) - pixman_fixed_e;
 #endif
 	/* clip X */
 	if (lx < 0)
commit f44431986f667eb49571e9365960524361f833c5
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Thu Nov 12 17:20:32 2009 -0500

    Fix rounding of top and bottom coordinates.
    
    The rules for trap rasterization is that coordinates are rounded
    towards north-west.
    
    The pixman_sample_ceil() function is used to compute the first
    (top-most) sample row included in the trap, so when the input
    coordinate is already exactly on a sample row, no rounding should take
    place.
    
    On the other hand, pixman_sample_floor() is used to compute the final
    (bottom-most) sample row, so if the input is precisely on a sample
    row, it needs to be rounded down to the previous row.
    
    This commit fixes the rounding computation. The idea of the
    computation is like this:
    
    Floor operation that rounds exact matches down: First subtract
    pixman_fixed_e to make sure input already on a sample row gets rounded
    down. Then find out how many small steps are between the input and the
    first fraction. Then add those small steps to the first fraction.
    
    The ceil operation first adds (small_step + pixman_e), then runs a
    floor. This ensures that exact matches are not rounded off.
    
    Based on a patch by M Joonas Pihlaja.

diff --git a/pixman/pixman-trap.c b/pixman/pixman-trap.c
index 962cbb3..8353992 100644
--- a/pixman/pixman-trap.c
+++ b/pixman/pixman-trap.c
@@ -28,8 +28,8 @@
 #include "pixman-private.h"
 
 /*
- * Compute the smallest value no less than y which is on a
- * grid row
+ * Compute the smallest value greater than or equal to y which is on a
+ * grid row.
  */
 
 PIXMAN_EXPORT pixman_fixed_t
@@ -38,7 +38,7 @@ pixman_sample_ceil_y (pixman_fixed_t y, int n)
     pixman_fixed_t f = pixman_fixed_frac (y);
     pixman_fixed_t i = pixman_fixed_floor (y);
 
-    f = ((f + Y_FRAC_FIRST (n)) / STEP_Y_SMALL (n)) * STEP_Y_SMALL (n) +
+    f = DIV (f - Y_FRAC_FIRST (n) + (STEP_Y_SMALL (n) - pixman_fixed_e), STEP_Y_SMALL (n)) * STEP_Y_SMALL (n) +
 	Y_FRAC_FIRST (n);
     
     if (f > Y_FRAC_LAST (n))
@@ -57,8 +57,8 @@ pixman_sample_ceil_y (pixman_fixed_t y, int n)
 }
 
 /*
- * Compute the largest value no greater than y which is on a
- * grid row
+ * Compute the largest value strictly less than y which is on a
+ * grid row.
  */
 PIXMAN_EXPORT pixman_fixed_t
 pixman_sample_floor_y (pixman_fixed_t y,
@@ -67,7 +67,7 @@ pixman_sample_floor_y (pixman_fixed_t y,
     pixman_fixed_t f = pixman_fixed_frac (y);
     pixman_fixed_t i = pixman_fixed_floor (y);
 
-    f = DIV (f - Y_FRAC_FIRST (n), STEP_Y_SMALL (n)) * STEP_Y_SMALL (n) +
+    f = DIV (f - pixman_fixed_e - Y_FRAC_FIRST (n), STEP_Y_SMALL (n)) * STEP_Y_SMALL (n) +
 	Y_FRAC_FIRST (n);
 
     if (f < Y_FRAC_FIRST (n))
@@ -380,7 +380,7 @@ pixman_rasterize_trapezoid (pixman_image_t *          image,
     if (pixman_fixed_to_int (b) >= height)
 	b = pixman_int_to_fixed (height) - 1;
     b = pixman_sample_floor_y (b, bpp);
-
+    
     if (b >= t)
     {
 	/* initialize edge walkers */
commit 3bea18e3ea587c84423e9f7bafff21150c37d287
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Thu Nov 12 17:03:53 2009 -0500

    Fix slightly skewed sampling grid for antialiased traps
    
    The sampling grid is slightly skewed in the antialiased case. Consider
    the case where we have n = 8 bits of alpha.
    
    The small step is
    
         small_step = fixed_1 / 15 = 65536 / 15 = 4369
    
    The first fraction is then
    
         frac_first = (small_step / 2) = (65536 - 15) / 2 = 2184
    
    and the last fraction becomes
    
         frac_last
              = frac_first + (15 - 1) * small_step = 2184 + 14 * 4369 = 63350
    
    which means the size of the last bit of the pixel is
    
         65536 - 63350 = 2186
    
    which is 2 bigger than the first fraction. This is not the end of the
    world, but it would be more correct to have 2185 and 2185, and we can
    accomplish that simply by making the first fraction half the *big*
    step instead of half the small step.
    
    If we ever move to coordinates with 8 fractional bits, the
    corresponding values become 8 and 10 out of 256, where 9 and 9 would
    be better.
    
    Similarly in the X direction.

diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 5000f91..0745149 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -350,13 +350,13 @@ _pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker,
 #define STEP_Y_SMALL(n) (pixman_fixed_1 / N_Y_FRAC (n))
 #define STEP_Y_BIG(n)   (pixman_fixed_1 - (N_Y_FRAC (n) - 1) * STEP_Y_SMALL (n))
 
-#define Y_FRAC_FIRST(n) (STEP_Y_SMALL (n) / 2)
+#define Y_FRAC_FIRST(n) (STEP_Y_BIG (n) / 2)
 #define Y_FRAC_LAST(n)  (Y_FRAC_FIRST (n) + (N_Y_FRAC (n) - 1) * STEP_Y_SMALL (n))
 
 #define STEP_X_SMALL(n) (pixman_fixed_1 / N_X_FRAC (n))
 #define STEP_X_BIG(n)   (pixman_fixed_1 - (N_X_FRAC (n) - 1) * STEP_X_SMALL (n))
 
-#define X_FRAC_FIRST(n) (STEP_X_SMALL (n) / 2)
+#define X_FRAC_FIRST(n) (STEP_X_BIG (n) / 2)
 #define X_FRAC_LAST(n)  (X_FRAC_FIRST (n) + (N_X_FRAC (n) - 1) * STEP_X_SMALL (n))
 
 #define RENDER_SAMPLES_X(x, n)						\


More information about the xorg-commit mailing list