summaryrefslogtreecommitdiff
path: root/src/sna/sna_trapezoids.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-09-08 22:54:22 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2011-09-08 22:54:22 +0100
commite9ca05331db9849fba39fbd0583db7052fc80a31 (patch)
treee8965c04849ac5bfa0420a17cdd460fda58d2801 /src/sna/sna_trapezoids.c
parentafdb8aa89a88c62ccd5e26a3ed9adb70fec310a8 (diff)
sna/traps: Use the trapezoid path for AddTraps
Usually this will be to CPU-only pixmap, but just on the off-chance that we are stalling for a GPU pixmap just the faster path developed for Trapezoids. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna/sna_trapezoids.c')
-rw-r--r--src/sna/sna_trapezoids.c155
1 files changed, 144 insertions, 11 deletions
diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c
index 46c1e57c..c7eef037 100644
--- a/src/sna/sna_trapezoids.c
+++ b/src/sna/sna_trapezoids.c
@@ -2103,11 +2103,10 @@ choose_span(PicturePtr dst,
return span;
}
-
static bool
-trap_span_converter(CARD8 op, PicturePtr src, PicturePtr dst,
- PictFormatPtr maskFormat, INT16 src_x, INT16 src_y,
- int ntrap, xTrapezoid *traps)
+trapezoid_span_converter(CARD8 op, PicturePtr src, PicturePtr dst,
+ PictFormatPtr maskFormat, INT16 src_x, INT16 src_y,
+ int ntrap, xTrapezoid *traps)
{
struct sna *sna;
struct sna_composite_spans_op tmp;
@@ -2265,9 +2264,9 @@ tor_blt_mask_mono(struct sna *sna,
}
static bool
-trap_mask_converter(CARD8 op, PicturePtr src, PicturePtr dst,
- PictFormatPtr maskFormat, INT16 src_x, INT16 src_y,
- int ntrap, xTrapezoid *traps)
+trapezoid_mask_converter(CARD8 op, PicturePtr src, PicturePtr dst,
+ PictFormatPtr maskFormat, INT16 src_x, INT16 src_y,
+ int ntrap, xTrapezoid *traps)
{
struct tor tor;
span_func_t span;
@@ -2474,12 +2473,12 @@ sna_composite_trapezoids(CARD8 op,
}
}
- if (trap_span_converter(op, src, dst, maskFormat,
- xSrc, ySrc, ntrap, traps))
+ if (trapezoid_span_converter(op, src, dst, maskFormat,
+ xSrc, ySrc, ntrap, traps))
return;
- if (trap_mask_converter(op, src, dst, maskFormat,
- xSrc, ySrc, ntrap, traps))
+ if (trapezoid_mask_converter(op, src, dst, maskFormat,
+ xSrc, ySrc, ntrap, traps))
return;
fallback:
@@ -2490,6 +2489,140 @@ fallback:
ntrap, traps);
}
+static inline bool
+project_trap_onto_grid(const xTrap *in,
+ int dx, int dy,
+ xTrap *out)
+{
+ out->top.l = dx + pixman_fixed_to_grid(in->top.l);
+ out->top.r = dx + pixman_fixed_to_grid(in->top.r);
+ out->top.y = dy + pixman_fixed_to_grid(in->top.y);
+
+ out->bot.l = dx + pixman_fixed_to_grid(in->bot.l);
+ out->bot.r = dx + pixman_fixed_to_grid(in->bot.r);
+ out->bot.y = dy + pixman_fixed_to_grid(in->bot.y);
+
+ return out->bot.y > out->top.y;
+}
+
+static bool
+trap_span_converter(PicturePtr dst,
+ INT16 src_x, INT16 src_y,
+ int ntrap, xTrap *trap)
+{
+ struct sna *sna;
+ struct sna_composite_spans_op tmp;
+ struct tor tor;
+ BoxRec extents;
+ PicturePtr src;
+ xRenderColor white;
+ pixman_region16_t *clip;
+ int16_t dx, dy;
+ int n, error;
+
+ if (NO_SCAN_CONVERTER)
+ return false;
+
+ /* XXX strict adherence to the Render specification */
+ if (dst->polyMode == PolyModePrecise) {
+ DBG(("%s: fallback -- precise rasterisation requested\n",
+ __FUNCTION__));
+ return false;
+ }
+
+ sna = to_sna_from_drawable(dst->pDrawable);
+ if (!sna->render.composite_spans) {
+ DBG(("%s: fallback -- composite spans not supported\n",
+ __FUNCTION__));
+ return false;
+ }
+
+ DBG(("%s: extents (%d, %d), (%d, %d)\n",
+ __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2));
+
+ clip = dst->pCompositeClip;
+ extents = *RegionExtents(clip);
+ dx = dst->pDrawable->x;
+ dy = dst->pDrawable->y;
+
+ DBG(("%s: after clip -- extents (%d, %d), (%d, %d), delta=(%d, %d)\n",
+ __FUNCTION__,
+ extents.x1, extents.y1,
+ extents.x2, extents.y2,
+ dx, dy));
+
+ white.red = white.green = white.blue = white.alpha = 0xffff;
+ src = CreateSolidPicture(0, &white, &error);
+ if (src == NULL)
+ return true;
+
+ memset(&tmp, 0, sizeof(tmp));
+ if (!sna->render.composite_spans(sna, PictOpAdd, src, dst,
+ 0, 0,
+ extents.x1, extents.y1,
+ extents.x2 - extents.x1,
+ extents.y2 - extents.y1,
+ &tmp)) {
+ DBG(("%s: fallback -- composite spans render op not supported\n",
+ __FUNCTION__));
+ FreePicture(src, 0);
+ return false;
+ }
+
+ dx *= FAST_SAMPLES_X;
+ dy *= FAST_SAMPLES_Y;
+ if (tor_init(&tor, &extents, 2*ntrap))
+ goto skip;
+
+ for (n = 0; n < ntrap; n++) {
+ xTrap t;
+ xPointFixed p1, p2;
+
+ if (!project_trap_onto_grid(&trap[n], dx, dy, &t))
+ continue;
+
+ if (pixman_fixed_to_int(trap[n].top.y) + dst->pDrawable->y >= extents.y2 ||
+ pixman_fixed_to_int(trap[n].bot.y) + dst->pDrawable->y < extents.y1)
+ continue;
+
+ p1.y = t.top.y;
+ p2.y = t.bot.y;
+ p1.x = t.top.l;
+ p2.x = t.bot.l;
+ polygon_add_line(tor.polygon, &p1, &p2);
+
+ p1.y = t.bot.y;
+ p2.y = t.top.y;
+ p1.x = t.top.r;
+ p2.x = t.bot.r;
+ polygon_add_line(tor.polygon, &p1, &p2);
+ }
+
+ tor_render(sna, &tor, &tmp, clip,
+ choose_span(dst, NULL, PictOpAdd, clip), false);
+
+skip:
+ tor_fini(&tor);
+ tmp.done(sna, &tmp);
+ FreePicture(src, 0);
+ return true;
+}
+
+void
+sna_add_traps(PicturePtr picture, INT16 x, INT16 y, int n, xTrap *t)
+{
+ DBG(("%s (%d, %d) x %d\n", __FUNCTION__, x, y, n));
+
+ if (picture_is_gpu (picture)) {
+ if (trap_span_converter(picture, x, y, n, t))
+ return;
+ }
+
+ DBG(("%s -- fallback\n", __FUNCTION__));
+ sna_drawable_move_to_cpu(picture->pDrawable, true);
+ fbAddTraps(picture, x, y, n, t);
+}
+
static inline void
project_point_onto_grid(const xPointFixed *in,
int dx, int dy,