summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-09-03 14:46:57 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2011-09-04 11:20:07 +0100
commit2cda0aaf397de1a0ca049508c6fa76f2dd4e61e8 (patch)
treea91eea857f03ed2431b3afb05511578ea46dc5ff
parentdb0fb368c135d4fef4ae993df67ed4610a80fd52 (diff)
sna/trapezoids: Check for alignment after projection
If after projection onto the Imprecise fast sample grid, the trapezoid becomes a pixel-aligned box, treat it as such and send it down the fast paths. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/sna_trapezoids.c105
1 files changed, 69 insertions, 36 deletions
diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c
index cb228e83..46c1e57c 100644
--- a/src/sna/sna_trapezoids.c
+++ b/src/sna/sna_trapezoids.c
@@ -63,11 +63,10 @@
#define SAMPLES_X 17
#define SAMPLES_Y 15
-#define FAST_SAMPLES_X_shift 2
-#define FAST_SAMPLES_Y_shift 2
-
-#define FAST_SAMPLES_X (1<<FAST_SAMPLES_X_shift)
-#define FAST_SAMPLES_Y (1<<FAST_SAMPLES_Y_shift)
+#define FAST_SAMPLES_shift 2
+#define FAST_SAMPLES_X (1<<FAST_SAMPLES_shift)
+#define FAST_SAMPLES_Y (1<<FAST_SAMPLES_shift)
+#define FAST_SAMPLES_mask ((1<<FAST_SAMPLES_shift)-1)
typedef void (*span_func_t)(struct sna *sna,
struct sna_composite_spans_op *op,
@@ -129,11 +128,14 @@ typedef int grid_scaled_x_t;
typedef int grid_scaled_y_t;
#define FAST_SAMPLES_X_TO_INT_FRAC(x, i, f) \
- _GRID_TO_INT_FRAC_shift(x, i, f, FAST_SAMPLES_X_shift)
+ _GRID_TO_INT_FRAC_shift(x, i, f, FAST_SAMPLES_shift)
+
+#define FAST_SAMPLES_INT(x) ((x) >> (FAST_SAMPLES_shift))
+#define FAST_SAMPLES_FRAC(x) ((x) & (FAST_SAMPLES_mask))
#define _GRID_TO_INT_FRAC_shift(t, i, f, b) do { \
- (f) = (t) & ((1 << (b)) - 1); \
- (i) = (t) >> (b); \
+ (f) = FAST_SAMPLES_FRAC(t); \
+ (i) = FAST_SAMPLES_INT(t); \
} while (0)
/* A grid area is a real in [0,1] scaled by 2*SAMPLES_X*SAMPLES_Y. We want
@@ -673,8 +675,15 @@ polygon_add_edge(struct polygon *polygon,
grid_scaled_y_t ymin = polygon->ymin;
grid_scaled_y_t ymax = polygon->ymax;
- DBG(("%s: edge=(%d, %d), (%d, %d), top=%d, bottom=%d, dir=%d\n",
- __FUNCTION__, x1, y1, x2, y2, top, bottom, dir));
+ DBG(("%s: edge=(%d [%d.%d], %d [%d.%d]), (%d [%d.%d], %d [%d.%d]), top=%d [%d.%d], bottom=%d [%d.%d], dir=%d\n",
+ __FUNCTION__,
+ x1, FAST_SAMPLES_INT(x1), FAST_SAMPLES_FRAC(x1),
+ y1, FAST_SAMPLES_INT(y1), FAST_SAMPLES_FRAC(y1),
+ x2, FAST_SAMPLES_INT(x2), FAST_SAMPLES_FRAC(x2),
+ y2, FAST_SAMPLES_INT(y2), FAST_SAMPLES_FRAC(y2),
+ top, FAST_SAMPLES_INT(top), FAST_SAMPLES_FRAC(top),
+ bottom, FAST_SAMPLES_INT(bottom), FAST_SAMPLES_FRAC(bottom),
+ dir));
assert (dy > 0);
e->dy = dy;
@@ -2040,23 +2049,28 @@ composite_unaligned_boxes(CARD8 op,
return true;
}
+static inline int pixman_fixed_to_grid (pixman_fixed_t v)
+{
+ return (v + FAST_SAMPLES_mask/2) >> (16 - FAST_SAMPLES_shift);
+}
+
static inline bool
project_trapezoid_onto_grid(const xTrapezoid *in,
int dx, int dy,
xTrapezoid *out)
{
- out->left.p1.x = dx + (in->left.p1.x >> (16 - FAST_SAMPLES_X_shift));
- out->left.p1.y = dy + (in->left.p1.y >> (16 - FAST_SAMPLES_Y_shift));
- out->left.p2.x = dx + (in->left.p2.x >> (16 - FAST_SAMPLES_X_shift));
- out->left.p2.y = dy + (in->left.p2.y >> (16 - FAST_SAMPLES_Y_shift));
+ out->left.p1.x = dx + pixman_fixed_to_grid(in->left.p1.x);
+ out->left.p1.y = dy + pixman_fixed_to_grid(in->left.p1.y);
+ out->left.p2.x = dx + pixman_fixed_to_grid(in->left.p2.x);
+ out->left.p2.y = dy + pixman_fixed_to_grid(in->left.p2.y);
- out->right.p1.x = dx + (in->right.p1.x >> (16 - FAST_SAMPLES_X_shift));
- out->right.p1.y = dy + (in->right.p1.y >> (16 - FAST_SAMPLES_Y_shift));
- out->right.p2.x = dx + (in->right.p2.x >> (16 - FAST_SAMPLES_X_shift));
- out->right.p2.y = dy + (in->right.p2.y >> (16 - FAST_SAMPLES_Y_shift));
+ out->right.p1.x = dx + pixman_fixed_to_grid(in->right.p1.x);
+ out->right.p1.y = dy + pixman_fixed_to_grid(in->right.p1.y);
+ out->right.p2.x = dx + pixman_fixed_to_grid(in->right.p2.x);
+ out->right.p2.y = dy + pixman_fixed_to_grid(in->right.p2.y);
- out->top = dy + (in->top >> (16 - FAST_SAMPLES_Y_shift));
- out->bottom = dy + (in->bottom >> (16 - FAST_SAMPLES_Y_shift));
+ out->top = dy + pixman_fixed_to_grid(in->top);
+ out->bottom = dy + pixman_fixed_to_grid(in->bottom);
return xTrapezoidValid(out);
}
@@ -2375,8 +2389,7 @@ sna_composite_trapezoids(CARD8 op,
int ntrap, xTrapezoid *traps)
{
struct sna *sna = to_sna_from_drawable(dst->pDrawable);
- bool rectilinear = true;
- bool pixel_aligned = true;
+ bool rectilinear, pixel_aligned;
int n;
DBG(("%s(op=%d, src=(%d, %d), mask=%08x, ntrap=%d)\n", __FUNCTION__,
@@ -2411,21 +2424,41 @@ sna_composite_trapezoids(CARD8 op,
}
/* scan through for fast rectangles */
- for (n = 0; n < ntrap && rectilinear; n++) {
- rectilinear &=
- traps[n].left.p1.x == traps[n].left.p2.x &&
- traps[n].right.p1.x == traps[n].right.p2.x;
- pixel_aligned &=
- ((traps[n].top | traps[n].bottom |
- traps[n].left.p1.x | traps[n].left.p2.x |
- traps[n].right.p1.x | traps[n].right.p2.x)
- & pixman_fixed_1_minus_e) == 0;
+ rectilinear = pixel_aligned = true;
+ if (maskFormat ? maskFormat->depth == 1 : dst->polyEdge == PolyEdgeSharp) {
+ for (n = 0; n < ntrap && rectilinear; n++) {
+ int lx1 = pixman_fixed_to_int(traps[n].left.p1.x + pixman_fixed_1_minus_e/2);
+ int lx2 = pixman_fixed_to_int(traps[n].left.p2.x + pixman_fixed_1_minus_e/2);
+ int rx1 = pixman_fixed_to_int(traps[n].left.p1.x + pixman_fixed_1_minus_e/2);
+ int rx2 = pixman_fixed_to_int(traps[n].left.p2.x + pixman_fixed_1_minus_e/2);
+ rectilinear &= lx1 == lx2 && rx1 == rx2;
+ }
+ } else if (dst->polyMode != PolyModePrecise) {
+ for (n = 0; n < ntrap && rectilinear; n++) {
+ int lx1 = pixman_fixed_to_grid(traps[n].left.p1.x);
+ int lx2 = pixman_fixed_to_grid(traps[n].right.p2.x);
+ int rx1 = pixman_fixed_to_grid(traps[n].left.p1.x);
+ int rx2 = pixman_fixed_to_grid(traps[n].right.p2.x);
+ int top = pixman_fixed_to_grid(traps[n].top);
+ int bot = pixman_fixed_to_grid(traps[n].bottom);
+
+ rectilinear &= lx1 == lx2 && rx1 == rx2;
+ pixel_aligned &= ((top | bot | lx1 | lx2 | rx1 | rx2) & FAST_SAMPLES_mask) == 0;
+ }
+ } else {
+ for (n = 0; n < ntrap && rectilinear; n++) {
+ rectilinear &=
+ traps[n].left.p1.x == traps[n].left.p2.x &&
+ traps[n].right.p1.x == traps[n].right.p2.x;
+ pixel_aligned &=
+ ((traps[n].top | traps[n].bottom |
+ traps[n].left.p1.x | traps[n].left.p2.x |
+ traps[n].right.p1.x | traps[n].right.p2.x)
+ & pixman_fixed_1_minus_e) == 0;
+ }
}
if (rectilinear) {
- pixel_aligned |= maskFormat ?
- maskFormat->depth == 1 :
- dst->polyEdge == PolyEdgeSharp;
if (pixel_aligned) {
if (composite_aligned_boxes(op, src, dst,
maskFormat,
@@ -2462,8 +2495,8 @@ project_point_onto_grid(const xPointFixed *in,
int dx, int dy,
xPointFixed *out)
{
- out->x = dx + (in->x >> (16 - FAST_SAMPLES_X_shift));
- out->y = dy + (in->y >> (16 - FAST_SAMPLES_Y_shift));
+ out->x = dx + pixman_fixed_to_grid(in->x);
+ out->y = dy + pixman_fixed_to_grid(in->y);
}
static inline bool