diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-10-07 14:06:31 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-10-07 21:39:43 +0100 |
commit | 55cd67485ff34a28ab8eaa7b1b6958b96c072317 (patch) | |
tree | 6512b786625a9ea74949c2df02508e6716c3fac6 /src/sna/sna_trapezoids_precise.c | |
parent | 55e0f4502657078a666761277bbac56a98b3780c (diff) |
sna/trapezoids: Only use a single thread to emit rectilinear spans
If the trapezoids are rectilinear, they should hit a fast path through
the span compositors and so threading them seems pointless. Expect
possibily for inplace pixman operations.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna/sna_trapezoids_precise.c')
-rw-r--r-- | src/sna/sna_trapezoids_precise.c | 83 |
1 files changed, 52 insertions, 31 deletions
diff --git a/src/sna/sna_trapezoids_precise.c b/src/sna/sna_trapezoids_precise.c index bfafca03..b4d7592d 100644 --- a/src/sna/sna_trapezoids_precise.c +++ b/src/sna/sna_trapezoids_precise.c @@ -782,7 +782,7 @@ merge_unsorted_edges(struct edge *head, struct edge *unsorted) /* Test if the edges on the active list can be safely advanced by a * full row without intersections or any edges ending. */ -inline static bool +inline static int can_full_step(struct active_list *active) { const struct edge *e; @@ -790,7 +790,7 @@ can_full_step(struct active_list *active) assert(active->head.next != &active->tail); for (e = active->head.next; &active->tail != e; e = e->next) { - assert(e->height_left >= 0); + assert(e->height_left > 0); if (e->dy != 0) return 0; @@ -848,6 +848,7 @@ nonzero_subrow(struct active_list *active, struct cell_list *coverages) xstart = edge->next->x.quo; } + assert(edge->height_left > 0); if (--edge->height_left) { if (edge->dy) { edge->x.quo += edge->dxdy.quo; @@ -972,6 +973,7 @@ step_edges(struct active_list *active, int count) count *= SAMPLES_Y; for (edge = active->head.next; edge != &active->tail; edge = edge->next) { edge->height_left -= count; + assert(edge->height_left >= 0); if (!edge->height_left) { edge->prev->next = edge->next; edge->next->prev = edge->prev; @@ -1223,6 +1225,7 @@ inplace_row(struct active_list *active, uint8_t *row, int width) int lix, rix; left->height_left -= SAMPLES_Y; + assert(left->height_left >= 0); if (!left->height_left) { left->prev->next = left->next; left->next->prev = left->prev; @@ -1231,6 +1234,7 @@ inplace_row(struct active_list *active, uint8_t *row, int width) right = left->next; do { right->height_left -= SAMPLES_Y; + assert(right->height_left >= 0); if (!right->height_left) { right->prev->next = right->next; right->next->prev = right->prev; @@ -1342,6 +1346,7 @@ inplace_subrow(struct active_list *active, int8_t *row, int width) } else SAMPLES_X_TO_INT_FRAC(edge->x.quo, lix, lfx); + assert(edge->height_left > 0); if (--edge->height_left) { if (edge->dy) { edge->x.quo += edge->dxdy.quo; @@ -1377,6 +1382,7 @@ inplace_subrow(struct active_list *active, int8_t *row, int width) if (0 == winding && edge->x.quo != next->x.quo) break; + assert(edge->height_left > 0); if (--edge->height_left) { if (edge->dy) { edge->x.quo += edge->dxdy.quo; @@ -1416,6 +1422,7 @@ inplace_subrow(struct active_list *active, int8_t *row, int width) } else SAMPLES_X_TO_INT_FRAC(edge->x.quo, rix, rfx); + assert(edge->height_left > 0); if (--edge->height_left) { if (edge->dy) { edge->x.quo += edge->dxdy.quo; @@ -1509,9 +1516,8 @@ tor_inplace(struct tor *converter, PixmapPtr scratch) do_full_step = can_full_step(active); } - __DBG(("%s: y=%d, do_full_step=%d, new edges=%d, min_height=%d, vertical=%d\n", - __FUNCTION__, - i, do_full_step, + __DBG(("%s: y=%d, do_full_step=%d, new edges=%d\n", + __FUNCTION__, i, do_full_step, polygon->y_buckets[i] != NULL)); if (do_full_step) { memset(ptr, 0, width); @@ -1633,8 +1639,8 @@ struct span_thread { #define SPAN_THREAD_MAX_BOXES (8192/sizeof(struct sna_opacity_box)) struct span_thread_boxes { const struct sna_composite_spans_op *op; - struct sna_opacity_box boxes[SPAN_THREAD_MAX_BOXES]; int num_boxes; + struct sna_opacity_box boxes[SPAN_THREAD_MAX_BOXES]; }; static void span_thread_add_boxes(struct sna *sna, void *data, @@ -1792,8 +1798,9 @@ precise_trapezoid_span_converter(struct sna *sna, #if 1 if (((clip.extents.y2 - clip.extents.y1) | (clip.extents.x2 - clip.extents.x1)) < 32) { - DBG(("%s: fallback -- traps extents too small %dx%d\n", - __FUNCTION__, extents.y2 - extents.y1, extents.x2 - extents.x1)); + DBG(("%s: fallback -- traps extents too small %dx%d\n", __FUNCTION__, + clip.extents.y2 - clip.extents.y1, + clip.extents.x2 - clip.extents.x1)); return false; } #endif @@ -1867,7 +1874,9 @@ precise_trapezoid_span_converter(struct sna *sna, dy *= SAMPLES_Y; num_threads = 1; - if (!NO_GPU_THREADS && tmp.thread_boxes && + if (!NO_GPU_THREADS && + (flags & COMPOSITE_SPANS_RECTILINEAR) == 0 && + tmp.thread_boxes && thread_choose_span(&tmp, dst, maskFormat, &clip)) num_threads = sna_use_threads(clip.extents.x2-clip.extents.x1, clip.extents.y2-clip.extents.y1, @@ -2022,7 +2031,8 @@ mask_thread(void *arg) bool precise_trapezoid_mask_converter(CARD8 op, PicturePtr src, PicturePtr dst, - PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, + PictFormatPtr maskFormat, unsigned flags, + INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps) { ScreenPtr screen = dst->pDrawable->pScreen; @@ -2042,7 +2052,7 @@ precise_trapezoid_mask_converter(CARD8 op, PicturePtr src, PicturePtr dst, __FUNCTION__)); do { /* XXX unwind errors? */ - if (!precise_trapezoid_mask_converter(op, src, dst, NULL, + if (!precise_trapezoid_mask_converter(op, src, dst, NULL, flags, src_x, src_y, 1, traps++)) return false; } while (--ntrap); @@ -2088,9 +2098,11 @@ precise_trapezoid_mask_converter(CARD8 op, PicturePtr src, PicturePtr dst, DBG(("%s: created buffer %p, stride %d\n", __FUNCTION__, scratch->devPrivate.ptr, scratch->devKind)); - num_threads = sna_use_threads(extents.x2 - extents.x1, - extents.y2 - extents.y1, - 4); + num_threads = 1; + if ((flags & COMPOSITE_SPANS_RECTILINEAR) == 0) + num_threads = sna_use_threads(extents.x2 - extents.x1, + extents.y2 - extents.y1, + 4); if (num_threads == 1) { struct tor tor; @@ -2180,8 +2192,8 @@ precise_trapezoid_mask_converter(CARD8 op, PicturePtr src, PicturePtr dst, } struct inplace { - uint32_t stride; uint8_t *ptr; + uint32_t stride; union { uint8_t opacity; uint32_t color; @@ -2624,7 +2636,7 @@ static bool trapezoid_span_inplace__x8r8g8b8(CARD8 op, PicturePtr dst, PicturePtr src, int16_t src_x, int16_t src_y, - PictFormatPtr maskFormat, + PictFormatPtr maskFormat, unsigned flags, int ntrap, xTrapezoid *traps) { uint32_t color; @@ -2664,7 +2676,8 @@ trapezoid_span_inplace__x8r8g8b8(CARD8 op, /* XXX unwind errors? */ if (!trapezoid_span_inplace__x8r8g8b8(op, dst, src, src_x, src_y, - NULL, 1, traps++)) + NULL, flags, + 1, traps++)) return false; } while (--ntrap); return true; @@ -2711,9 +2724,11 @@ trapezoid_span_inplace__x8r8g8b8(CARD8 op, dx = dst->pDrawable->x * SAMPLES_X; dy = dst->pDrawable->y * SAMPLES_Y; - num_threads = sna_use_threads(4*(region.extents.x2 - region.extents.x1), - region.extents.y2 - region.extents.y1, - 4); + num_threads = 1; + if ((flags & COMPOSITE_SPANS_RECTILINEAR) == 0 && (lerp || is_solid)) + num_threads = sna_use_threads(4*(region.extents.x2 - region.extents.x1), + region.extents.y2 - region.extents.y1, + 4); DBG(("%s: %dx%d, format=%x, op=%d, lerp?=%d, num_threads=%d\n", __FUNCTION__, @@ -2907,7 +2922,8 @@ static void inplace_thread(void *arg) bool precise_trapezoid_span_inplace(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, - PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, + PictFormatPtr maskFormat, unsigned flags, + INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps, bool fallback) { @@ -2928,7 +2944,7 @@ precise_trapezoid_span_inplace(struct sna *sna, if (dst->format == PICT_a8r8g8b8 || dst->format == PICT_x8r8g8b8) return trapezoid_span_inplace__x8r8g8b8(op, dst, src, src_x, src_y, - maskFormat, + maskFormat, flags, ntrap, traps); if (!sna_picture_is_solid(src, &color)) { @@ -2997,7 +3013,7 @@ precise_trapezoid_span_inplace(struct sna *sna, __FUNCTION__)); do { /* XXX unwind errors? */ - if (!precise_trapezoid_span_inplace(sna, op, src, dst, NULL, + if (!precise_trapezoid_span_inplace(sna, op, src, dst, NULL, flags, src_x, src_y, 1, traps++, fallback)) return false; @@ -3061,9 +3077,11 @@ precise_trapezoid_span_inplace(struct sna *sna, inplace.stride = pixmap->devKind; inplace.opacity = color >> 24; - num_threads = sna_use_threads(region.extents.x2 - region.extents.x1, - region.extents.y2 - region.extents.y1, - 4); + num_threads = 1; + if ((flags & COMPOSITE_SPANS_RECTILINEAR) == 0) + num_threads = sna_use_threads(region.extents.x2 - region.extents.x1, + region.extents.y2 - region.extents.y1, + 4); if (num_threads == 1) { struct tor tor; @@ -3133,7 +3151,8 @@ precise_trapezoid_span_inplace(struct sna *sna, bool precise_trapezoid_span_fallback(CARD8 op, PicturePtr src, PicturePtr dst, - PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, + PictFormatPtr maskFormat, unsigned flags, + INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps) { ScreenPtr screen = dst->pDrawable->pScreen; @@ -3152,7 +3171,7 @@ precise_trapezoid_span_fallback(CARD8 op, PicturePtr src, PicturePtr dst, __FUNCTION__)); do { /* XXX unwind errors? */ - if (!precise_trapezoid_span_fallback(op, src, dst, NULL, + if (!precise_trapezoid_span_fallback(op, src, dst, NULL, flags, src_x, src_y, 1, traps++)) return false; } while (--ntrap); @@ -3197,9 +3216,11 @@ precise_trapezoid_span_fallback(CARD8 op, PicturePtr src, PicturePtr dst, DBG(("%s: created buffer %p, stride %d\n", __FUNCTION__, scratch->devPrivate.ptr, scratch->devKind)); - num_threads = sna_use_threads(extents.x2 - extents.x1, - extents.y2 - extents.y1, - 4); + num_threads = 1; + if ((flags & COMPOSITE_SPANS_RECTILINEAR) == 0) + num_threads = sna_use_threads(extents.x2 - extents.x1, + extents.y2 - extents.y1, + 4); if (num_threads == 1) { struct tor tor; |