From 83b061776a57025076fc26d6d01fe2e049c2243b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 27 Apr 2006 19:17:34 +0000 Subject: [PATCH] Add trivial PolySegment acceleration for 0-width horizontal/vertical lines, which still happen somewhat frequently and were cluttering up my fallback debugging output. x11perf says it's a major performance win in those cases (though probably irrelevant), and it passes Xlib9. --- ChangeLog | 9 +++++++++ exa/exa_accel.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++- exa/exa_unaccel.c | 6 ++++-- 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8e985bd50..2a1e78e9e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2006-04-27 Eric Anholt + + * exa/exa_accel.c: (exaPolySegment): + * exa/exa_unaccel.c: (ExaCheckPolylines), (ExaCheckPolySegment): + Add trivial PolySegment acceleration for 0-width horizontal/vertical + lines, which still happen somewhat frequently and were cluttering up my + fallback debugging output. x11perf says it's a major performance win + in those cases (though probably irrelevant), and it passes Xlib9. + 2006-04-26 Eric Anholt * exa/exa_render.c: (exaGlyphs): diff --git a/exa/exa_accel.c b/exa/exa_accel.c index 57355e673..e910bc92b 100644 --- a/exa/exa_accel.c +++ b/exa/exa_accel.c @@ -459,6 +459,54 @@ exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, dstx, dsty, exaCopyNtoN, 0, NULL); } +/** + * exaPolySegment() checks if it can accelerate the lines as a group of + * horizontal or vertical lines (rectangles), and uses existing rectangle fill + * acceleration if so. + */ +static void +exaPolySegment (DrawablePtr pDrawable, GCPtr pGC, int nseg, + xSegment *pSeg) +{ + xRectangle *prect; + int i; + + /* Don't try to do wide lines or non-solid fill style. */ + if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid) + { + ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg); + return; + } + + /* If we have any non-horizontal/vertical, fall back. */ + for (i = 0; i < nseg; i++) { + if (pSeg[i].x1 != pSeg[i].x2 && pSeg[i].y1 != pSeg[i].y2) { + ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg); + return; + } + } + + prect = ALLOCATE_LOCAL(sizeof(xRectangle) * nseg); + for (i = 0; i < nseg; i++) { + if (pSeg[i].x1 < pSeg[i].x2) { + prect[i].x = pSeg[i].x1; + prect[i].width = pSeg[i].x2 - pSeg[i].x1 + 1; + } else { + prect[i].x = pSeg[i].x2; + prect[i].width = pSeg[i].x1 - pSeg[i].x2 + 1; + } + if (pSeg[i].y1 < pSeg[i].y2) { + prect[i].y = pSeg[i].y1; + prect[i].height = pSeg[i].y2 - pSeg[i].y1 + 1; + } else { + prect[i].y = pSeg[i].y2; + prect[i].height = pSeg[i].y1 - pSeg[i].y2 + 1; + } + } + pGC->ops->PolyFillRect(pDrawable, pGC, nseg, prect); + DEALLOCATE_LOCAL(prect); +} + static void exaPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, @@ -802,7 +850,7 @@ const GCOps exaOps = { ExaCheckCopyPlane, ExaCheckPolyPoint, ExaCheckPolylines, - ExaCheckPolySegment, + exaPolySegment, miPolyRectangle, ExaCheckPolyArc, miFillPolygon, diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c index cc5c61a38..283fdc433 100644 --- a/exa/exa_unaccel.c +++ b/exa/exa_unaccel.c @@ -134,7 +134,8 @@ void ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt) { - EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable)); + EXA_FALLBACK(("to 0x%lx, width %d, mode %d, count %d\n", (long)pDrawable, + pGC->lineWidth, mode, npt)); if (pGC->lineWidth == 0) { exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); @@ -152,7 +153,8 @@ void ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC, int nsegInit, xSegment *pSegInit) { - EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable)); + EXA_FALLBACK(("to 0x%lx width %d, count %d\n", (long)pDrawable, + pGC->lineWidth, nsegInit)); if (pGC->lineWidth == 0) { exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); exaPrepareAccessGC (pGC);