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