summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-01-06 02:26:39 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-01-06 02:47:45 +0000
commit5c2e9a98715eeddd8dfdff9fe3871bde659484cc (patch)
tree1456aa38a4e3972b264f4aaf84a2913eb1dba567
parent75f61678249018c84872c61b4609ba9d3d0d73dc (diff)
sna/trapezoids: Use a slightly faster miTrapezoidBounds()
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/sna_trapezoids.c97
1 files changed, 88 insertions, 9 deletions
diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c
index 42cebb9d..903bc42d 100644
--- a/src/sna/sna_trapezoids.c
+++ b/src/sna/sna_trapezoids.c
@@ -1872,6 +1872,88 @@ static int operator_is_bounded(uint8_t op)
}
}
+inline static xFixed
+line_x_for_y(const xLineFixed *l, xFixed y, bool ceil)
+{
+ xFixed_32_32 ex = (xFixed_32_32)(y - l->p1.y) * (l->p2.x - l->p1.x);
+ xFixed d = l->p2.y - l->p1.y;
+
+ if (ceil)
+ ex += (d - 1);
+
+ return l->p1.x + (xFixed) (ex / d);
+}
+
+#define pixman_fixed_integer_floor(V) pixman_fixed_to_int(V)
+#define pixman_fixed_integer_ceil(V) pixman_fixed_to_int(pixman_fixed_ceil(V))
+
+static void
+trapezoids_bounds(int n, const xTrapezoid *t, BoxPtr box)
+{
+ xFixed x1, y1, x2, y2;
+
+ /* XXX need 33 bits... */
+ x1 = y1 = INT_MAX / 2;
+ x2 = y2 = INT_MIN / 2;
+
+ do {
+ xFixed fx1, fx2, v;
+
+ if (!xTrapezoidValid(t))
+ continue;
+
+ if (t->top < y1)
+ y1 = t->top;
+ if (t->bottom > y2)
+ y2 = t->bottom;
+
+ if (((t->left.p1.x - x1) | (t->left.p2.x - x1)) < 0) {
+ if (pixman_fixed_floor(t->left.p1.x) == pixman_fixed_floor(t->left.p2.x)) {
+ x1 = pixman_fixed_floor(t->left.p1.x);
+ } else {
+ if (t->left.p1.y == t->top)
+ fx1 = t->left.p1.x;
+ else
+ fx1 = line_x_for_y(&t->left, t->top, false);
+
+ if (t->left.p2.y == t->bottom)
+ fx2 = t->left.p2.x;
+ else
+ fx2 = line_x_for_y(&t->left, t->bottom, false);
+
+ v = min(fx1, fx2);
+ if (v < x1)
+ x1 = pixman_fixed_floor(v);
+ }
+ }
+
+ if (((x2 - t->right.p1.x) | (x2 - t->right.p2.x)) < 0) {
+ if (pixman_fixed_floor(t->right.p1.x) == pixman_fixed_floor(t->right.p2.x)) {
+ x2 = pixman_fixed_ceil(t->right.p1.x);
+ } else {
+ if (t->right.p1.y == t->top)
+ fx1 = t->right.p1.x;
+ else
+ fx1 = line_x_for_y(&t->right, t->top, true);
+
+ if (t->right.p2.y == t->bottom)
+ fx2 = t->right.p2.x;
+ else
+ fx2 = line_x_for_y(&t->right, t->bottom, true);
+
+ v = max(fx1, fx2);
+ if (v > x2)
+ x2 = pixman_fixed_ceil(v);
+ }
+ }
+ } while (t++, --n);
+
+ box->x1 = pixman_fixed_to_int(x1);
+ box->x2 = pixman_fixed_to_int(x2);
+ box->y1 = pixman_fixed_integer_floor(y1);
+ box->y2 = pixman_fixed_integer_ceil(y2);
+}
+
static void
trapezoids_fallback(CARD8 op, PicturePtr src, PicturePtr dst,
PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
@@ -1892,7 +1974,7 @@ trapezoids_fallback(CARD8 op, PicturePtr src, PicturePtr dst,
dst_x = pixman_fixed_to_int(traps[0].left.p1.x);
dst_y = pixman_fixed_to_int(traps[0].left.p1.y);
- miTrapezoidBounds(ntrap, traps, &bounds);
+ trapezoids_bounds(ntrap, traps, &bounds);
if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
return;
@@ -2585,7 +2667,7 @@ mono_trapezoids_span_converter(CARD8 op, PicturePtr src, PicturePtr dst,
dst_x = pixman_fixed_to_int(traps[0].left.p1.x);
dst_y = pixman_fixed_to_int(traps[0].left.p1.y);
- miTrapezoidBounds(ntrap, traps, &extents);
+ trapezoids_bounds(ntrap, traps, &extents);
if (extents.y1 >= extents.y2 || extents.x1 >= extents.x2)
return true;
@@ -2742,7 +2824,7 @@ trapezoid_span_converter(CARD8 op, PicturePtr src, PicturePtr dst,
dst_x = pixman_fixed_to_int(traps[0].left.p1.x);
dst_y = pixman_fixed_to_int(traps[0].left.p1.y);
- miTrapezoidBounds(ntrap, traps, &extents);
+ trapezoids_bounds(ntrap, traps, &extents);
if (extents.y1 >= extents.y2 || extents.x1 >= extents.x2)
return true;
@@ -2905,7 +2987,7 @@ trapezoid_mask_converter(CARD8 op, PicturePtr src, PicturePtr dst,
return true;
}
- miTrapezoidBounds(ntrap, traps, &extents);
+ trapezoids_bounds(ntrap, traps, &extents);
if (extents.y1 >= extents.y2 || extents.x1 >= extents.x2)
return true;
@@ -3275,7 +3357,7 @@ trapezoid_span_inplace(CARD8 op, PicturePtr src, PicturePtr dst,
return true;
}
- miTrapezoidBounds(ntrap, traps, &region.extents);
+ trapezoids_bounds(ntrap, traps, &region.extents);
if (region.extents.y1 >= region.extents.y2 ||
region.extents.x1 >= region.extents.x2)
return true;
@@ -3414,7 +3496,7 @@ trapezoid_span_fallback(CARD8 op, PicturePtr src, PicturePtr dst,
return true;
}
- miTrapezoidBounds(ntrap, traps, &extents);
+ trapezoids_bounds(ntrap, traps, &extents);
if (extents.y1 >= extents.y2 || extents.x1 >= extents.x2)
return true;
@@ -3841,9 +3923,6 @@ skip:
return true;
}
-#define pixman_fixed_integer_floor(V) pixman_fixed_to_int(pixman_fixed_floor(V))
-#define pixman_fixed_integer_ceil(V) pixman_fixed_to_int(pixman_fixed_ceil(V))
-
static void mark_damaged(PixmapPtr pixmap, struct sna_pixmap *priv,
BoxPtr box, int16_t x, int16_t y)
{