summaryrefslogtreecommitdiff
path: root/exa
diff options
context:
space:
mode:
authorEric Anholt <anholt@freebsd.org>2006-04-27 19:17:34 +0000
committerEric Anholt <anholt@freebsd.org>2006-04-27 19:17:34 +0000
commit83b061776a57025076fc26d6d01fe2e049c2243b (patch)
tree5c4fb5d3d3920488e60f49ab59c1006d3dca689d /exa
parent69164ec00c749787dd59d5913ec6b3d159ad74d7 (diff)
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.
Diffstat (limited to 'exa')
-rw-r--r--exa/exa_accel.c50
-rw-r--r--exa/exa_unaccel.c6
2 files changed, 53 insertions, 3 deletions
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);