[PATCH 13/23] fb: Remove even/odd stipple slow-pathing
Adam Jackson
ajax at redhat.com
Mon Oct 27 12:52:01 PDT 2014
This is clearly meant to be a fast path, but it appears to be a net
loss at this point.
If you really wanted to ricer-tune here, note that the inner loop of
fbBltOne is a bit too complicated for gcc (at least 4.8.2), it doesn't
specialize the loop for the handful of legal values of bitsPerDst, which
means computing at runtime what could have been const-propped.
Reviewed-by: Keith Packard <keithp at keithp.com>
Signed-off-by: Adam Jackson <ajax at redhat.com>
---
fb/Makefile.am | 1 -
fb/fb.h | 58 --------------
fb/fbbltone.c | 85 ++++----------------
fb/fbfill.c | 46 ++++++++++-
fb/fbgc.c | 83 --------------------
fb/fbstipple.c | 243 ---------------------------------------------------------
fb/wfbrename.h | 4 -
7 files changed, 60 insertions(+), 460 deletions(-)
delete mode 100644 fb/fbstipple.c
diff --git a/fb/Makefile.am b/fb/Makefile.am
index 752eabe..ff6dc3a 100644
--- a/fb/Makefile.am
+++ b/fb/Makefile.am
@@ -44,7 +44,6 @@ libfb_la_SOURCES = \
fbseg.c \
fbsetsp.c \
fbsolid.c \
- fbstipple.c \
fbtile.c \
fbtrap.c \
fbutil.c \
diff --git a/fb/fb.h b/fb/fb.h
index 6db5803..f7cbaf9 100644
--- a/fb/fb.h
+++ b/fb/fb.h
@@ -452,7 +452,6 @@ typedef struct {
FbBits bgand, bgxor; /* for stipples */
FbBits fg, bg, pm; /* expanded and filled */
unsigned int dashLength; /* total of all dash elements */
- unsigned char evenStipple; /* stipple is even */
unsigned char bpp; /* current drawable bpp */
} FbGCPrivRec, *FbGCPrivPtr;
@@ -545,11 +544,6 @@ typedef struct {
* Accelerated tiles are power of 2 width <= FB_UNIT
*/
#define FbEvenTile(w) ((w) <= FB_UNIT && FbPowerOfTwo(w))
-/*
- * Accelerated stipples are power of 2 width and <= FB_UNIT/dstBpp
- * with dstBpp a power of 2 as well
- */
-#define FbEvenStip(w,bpp) ((w) * (bpp) <= FB_UNIT && FbPowerOfTwo(w) && FbPowerOfTwo(bpp))
/*
* fb24_32.c
@@ -1338,58 +1332,6 @@ fbSolid24(FbBits * dst,
int dstX, int width, int height, FbBits and, FbBits xor);
/*
- * fbstipple.c
- */
-
-extern _X_EXPORT void
- fbTransparentSpan(FbBits * dst, FbBits stip, FbBits fgxor, int n);
-
-extern _X_EXPORT void
-
-fbEvenStipple(FbBits * dst,
- FbStride dstStride,
- int dstX,
- int dstBpp,
- int width,
- int height,
- FbStip * stip,
- FbStride stipStride,
- int stipHeight,
- FbBits fgand,
- FbBits fgxor, FbBits bgand, FbBits bgxor, int xRot, int yRot);
-
-extern _X_EXPORT void
-
-fbOddStipple(FbBits * dst,
- FbStride dstStride,
- int dstX,
- int dstBpp,
- int width,
- int height,
- FbStip * stip,
- FbStride stipStride,
- int stipWidth,
- int stipHeight,
- FbBits fgand,
- FbBits fgxor, FbBits bgand, FbBits bgxor, int xRot, int yRot);
-
-extern _X_EXPORT void
-
-fbStipple(FbBits * dst,
- FbStride dstStride,
- int dstX,
- int dstBpp,
- int width,
- int height,
- FbStip * stip,
- FbStride stipStride,
- int stipWidth,
- int stipHeight,
- Bool even,
- FbBits fgand,
- FbBits fgxor, FbBits bgand, FbBits bgxor, int xRot, int yRot);
-
-/*
* fbtile.c
*/
diff --git a/fb/fbbltone.c b/fb/fbbltone.c
index 3042c4b..bd3229a 100644
--- a/fb/fbbltone.c
+++ b/fb/fbbltone.c
@@ -62,26 +62,6 @@
bits = (src < srcEnd ? READ(src++) : 0); \
}
-#define LaneCases1(n,a) case n: FbLaneCase(n,a); break
-#define LaneCases2(n,a) LaneCases1(n,a); LaneCases1(n+1,a)
-#define LaneCases4(n,a) LaneCases2(n,a); LaneCases2(n+2,a)
-#define LaneCases8(n,a) LaneCases4(n,a); LaneCases4(n+4,a)
-#define LaneCases16(n,a) LaneCases8(n,a); LaneCases8(n+8,a)
-
-#define LaneCases(a) LaneCases16(0,a)
-
-static const CARD8 fb8Lane[16] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
-};
-
-static const CARD8 fb16Lane[16] = {
- 0, 3, 12, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-
-static const CARD8 fb32Lane[16] = {
- 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-
void
fbBltOne(FbStip * src, FbStride srcStride, /* FbStip units per scanline */
int srcX, /* bit position of source */
@@ -110,7 +90,6 @@ fbBltOne(FbStip * src, FbStride srcStride, /* FbStip units per scanline */
Bool transparent; /* accelerate 0 nop */
int srcinc; /* source units consumed */
Bool endNeedsLoad = FALSE; /* need load for endmask */
- const CARD8 *fbLane;
int startbyte, endbyte;
if (dstBpp == 24) {
@@ -176,15 +155,6 @@ fbBltOne(FbStip * src, FbStride srcStride, /* FbStip units per scanline */
fbBits = 0; /* unused */
if (pixelsPerDst <= 8)
fbBits = fbStippleTable[pixelsPerDst];
- fbLane = 0;
- if (transparent && fgand == 0) {
- if (dstBpp == 8)
- fbLane = fb8Lane;
- if (dstBpp == 16)
- fbLane = fb16Lane;
- if (dstBpp == 32)
- fbLane = fb32Lane;
- }
/*
* Compute total number of destination words written, but
@@ -235,15 +205,10 @@ fbBltOne(FbStip * src, FbStride srcStride, /* FbStip units per scanline */
*/
if (startmask) {
mask = fbBits[FbLeftStipBits(bits, pixelsPerDst)];
- if (fbLane) {
- fbTransparentSpan(dst, mask & startmask, fgxor, 1);
- }
- else {
- if (mask || !transparent)
- FbDoLeftMaskByteStippleRRop(dst, mask,
- fgand, fgxor, bgand, bgxor,
- startbyte, startmask);
- }
+ if (mask || !transparent)
+ FbDoLeftMaskByteStippleRRop(dst, mask,
+ fgand, fgxor, bgand, bgxor,
+ startbyte, startmask);
bits = FbStipLeft(bits, pixelsPerDst);
dst++;
n--;
@@ -263,29 +228,15 @@ fbBltOne(FbStip * src, FbStride srcStride, /* FbStip units per scanline */
}
}
else {
- if (fbLane) {
- while (bits && n) {
- switch (fbLane[FbLeftStipBits(bits, pixelsPerDst)]) {
- LaneCases((CARD8 *) dst);
- }
- bits = FbStipLeft(bits, pixelsPerDst);
- dst++;
- n--;
- }
- dst += n;
- }
- else {
- while (n--) {
- left = FbLeftStipBits(bits, pixelsPerDst);
- if (left || !transparent) {
- mask = fbBits[left];
- WRITE(dst, FbStippleRRop(READ(dst), mask,
- fgand, fgxor, bgand,
- bgxor));
- }
- dst++;
- bits = FbStipLeft(bits, pixelsPerDst);
+ while (n--) {
+ left = FbLeftStipBits(bits, pixelsPerDst);
+ if (left || !transparent) {
+ mask = fbBits[left];
+ WRITE(dst, FbStippleRRop(READ(dst), mask, fgand,
+ fgxor, bgand, bgxor));
}
+ dst++;
+ bits = FbStipLeft(bits, pixelsPerDst);
}
}
if (!w)
@@ -307,15 +258,9 @@ fbBltOne(FbStip * src, FbStride srcStride, /* FbStip units per scanline */
LoadBits;
}
mask = fbBits[FbLeftStipBits(bits, pixelsPerDst)];
- if (fbLane) {
- fbTransparentSpan(dst, mask & endmask, fgxor, 1);
- }
- else {
- if (mask || !transparent)
- FbDoRightMaskByteStippleRRop(dst, mask,
- fgand, fgxor, bgand, bgxor,
- endbyte, endmask);
- }
+ if (mask || !transparent)
+ FbDoRightMaskByteStippleRRop(dst, mask, fgand, fgxor,
+ bgand, bgxor, endbyte, endmask);
}
dst += dstStride;
src += srcStride;
diff --git a/fb/fbfill.c b/fb/fbfill.c
index de9d6b3..ad09671 100644
--- a/fb/fbfill.c
+++ b/fb/fbfill.c
@@ -26,6 +26,50 @@
#include "fb.h"
+static void
+fbStipple(FbBits * dst, FbStride dstStride,
+ int dstX, int dstBpp,
+ int width, int height,
+ FbStip * stip, FbStride stipStride,
+ int stipWidth, int stipHeight,
+ FbBits fgand, FbBits fgxor,
+ FbBits bgand, FbBits bgxor,
+ int xRot, int yRot)
+{
+ int stipX, stipY, sx;
+ int widthTmp;
+ int h, w;
+ int x, y;
+
+ modulus(-yRot, stipHeight, stipY);
+ modulus(dstX / dstBpp - xRot, stipWidth, stipX);
+ y = 0;
+ while (height) {
+ h = stipHeight - stipY;
+ if (h > height)
+ h = height;
+ height -= h;
+ widthTmp = width;
+ x = dstX;
+ sx = stipX;
+ while (widthTmp) {
+ w = (stipWidth - sx) * dstBpp;
+ if (w > widthTmp)
+ w = widthTmp;
+ widthTmp -= w;
+ fbBltOne(stip + stipY * stipStride,
+ stipStride,
+ sx,
+ dst + y * dstStride,
+ dstStride, x, dstBpp, w, h, fgand, fgxor, bgand, bgxor);
+ x += w;
+ sx = 0;
+ }
+ y += h;
+ stipY = 0;
+ }
+}
+
void
fbFill(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int width, int height)
{
@@ -97,7 +141,7 @@ fbFill(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int width, int height)
fbStipple(dst + (y + dstYoff) * dstStride, dstStride,
(x + dstXoff) * dstBpp, dstBpp, width * dstBpp, height,
stip, stipStride, stipWidth, stipHeight,
- pPriv->evenStipple, fgand, fgxor, bgand, bgxor,
+ fgand, fgxor, bgand, bgxor,
pGC->patOrg.x + pDrawable->x + dstXoff,
pGC->patOrg.y + pDrawable->y - y);
fbFinishAccess(&pStip->drawable);
diff --git a/fb/fbgc.c b/fb/fbgc.c
index f4d7f3a..21c9b03 100644
--- a/fb/fbgc.c
+++ b/fb/fbgc.c
@@ -110,80 +110,6 @@ fbPadPixmap(PixmapPtr pPixmap)
fbFinishAccess(&pPixmap->drawable);
}
-/*
- * Verify that 'bits' repeats every 'len' bits
- */
-static Bool
-fbBitsRepeat(FbBits bits, int len, int width)
-{
- FbBits mask = FbBitsMask(0, len);
- FbBits orig = bits & mask;
- int i;
-
- if (width > FB_UNIT)
- width = FB_UNIT;
- for (i = 0; i < width / len; i++) {
- if ((bits & mask) != orig)
- return FALSE;
- bits = FbScrLeft(bits, len);
- }
- return TRUE;
-}
-
-/*
- * Check whether an entire bitmap line is a repetition of
- * the first 'len' bits
- */
-static Bool
-fbLineRepeat(FbBits * bits, int len, int width)
-{
- FbBits first = bits[0];
-
- if (!fbBitsRepeat(first, len, width))
- return FALSE;
- width = (width + FB_UNIT - 1) >> FB_SHIFT;
- bits++;
- while (--width)
- if (READ(bits) != first)
- return FALSE;
- return TRUE;
-}
-
-/*
- * The even stipple code wants the first FB_UNIT/bpp bits on
- * each scanline to represent the entire stipple
- */
-static Bool
-fbCanEvenStipple(PixmapPtr pStipple, int bpp)
-{
- int len = FB_UNIT / bpp;
- FbBits *bits;
- int stride;
- int stip_bpp;
- _X_UNUSED int stipXoff, stipYoff;
- int h;
-
- /* can't even stipple 24bpp drawables */
- if ((bpp & (bpp - 1)) != 0)
- return FALSE;
- /* make sure the stipple width is a multiple of the even stipple width */
- if (pStipple->drawable.width % len != 0)
- return FALSE;
- fbGetDrawable(&pStipple->drawable, bits, stride, stip_bpp, stipXoff,
- stipYoff);
- h = pStipple->drawable.height;
- /* check to see that the stipple repeats horizontally */
- while (h--) {
- if (!fbLineRepeat(bits, len, pStipple->drawable.width)) {
- fbFinishAccess(&pStipple->drawable);
- return FALSE;
- }
- bits += stride;
- }
- fbFinishAccess(&pStipple->drawable);
- return TRUE;
-}
-
void
fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
{
@@ -239,16 +165,7 @@ fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
fbPadPixmap(pGC->tile.pixmap);
}
if (changes & GCStipple) {
- pPriv->evenStipple = FALSE;
-
if (pGC->stipple) {
-
- /* can we do an even stipple ?? */
- if (FbEvenStip(pGC->stipple->drawable.width,
- pDrawable->bitsPerPixel) &&
- (fbCanEvenStipple(pGC->stipple, pDrawable->bitsPerPixel)))
- pPriv->evenStipple = TRUE;
-
if (pGC->stipple->drawable.width * pDrawable->bitsPerPixel <
FB_UNIT)
fbPadPixmap(pGC->stipple);
diff --git a/fb/fbstipple.c b/fb/fbstipple.c
deleted file mode 100644
index 9a877c1..0000000
--- a/fb/fbstipple.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright © 1998 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "fb.h"
-
-/*
- * This is a slight abuse of the preprocessor to generate repetitive
- * code, the idea is to generate code for each case of a copy-mode
- * transparent stipple
- */
-#define LaneCases1(c,a) case c: \
- while (n--) { FbLaneCase(c,a); a++; } \
- break
-#define LaneCases2(c,a) LaneCases1(c,a); LaneCases1(c+1,a)
-#define LaneCases4(c,a) LaneCases2(c,a); LaneCases2(c+2,a)
-#define LaneCases8(c,a) LaneCases4(c,a); LaneCases4(c+4,a)
-#define LaneCases16(c,a) LaneCases8(c,a); LaneCases8(c+8,a)
-
-#define LaneCases(a) LaneCases16(0,a)
-
-/*
- * Repeat a transparent stipple across a scanline n times
- */
-
-void
-fbTransparentSpan(FbBits * dst, FbBits stip, FbBits fgxor, int n)
-{
- FbStip s;
-
- s = ((FbStip) (stip) & 0x01);
- s |= ((FbStip) (stip >> 8) & 0x02);
- s |= ((FbStip) (stip >> 16) & 0x04);
- s |= ((FbStip) (stip >> 24) & 0x08);
- switch (s) {
- LaneCases(dst);
- }
-}
-
-void
-fbEvenStipple(FbBits * dst,
- FbStride dstStride,
- int dstX,
- int dstBpp,
- int width,
- int height,
- FbStip * stip,
- FbStride stipStride,
- int stipHeight,
- FbBits fgand,
- FbBits fgxor, FbBits bgand, FbBits bgxor, int xRot, int yRot)
-{
- FbBits startmask, endmask;
- FbBits mask, and, xor;
- int nmiddle, n;
- FbStip *s, *stipEnd, bits;
- int rot, stipX, stipY;
- int pixelsPerDst;
- const FbBits *fbBits;
- Bool transparent;
- int startbyte, endbyte;
-
- /*
- * Check for a transparent stipple (stencil)
- */
- transparent = FALSE;
- if (dstBpp >= 8 && fgand == 0 && bgand == FB_ALLONES && bgxor == 0)
- transparent = TRUE;
-
- pixelsPerDst = FB_UNIT / dstBpp;
- /*
- * Adjust dest pointers
- */
- dst += dstX >> FB_SHIFT;
- dstX &= FB_MASK;
- FbMaskBitsBytes(dstX, width, fgand == 0 && bgand == 0,
- startmask, startbyte, nmiddle, endmask, endbyte);
-
- if (startmask)
- dstStride--;
- dstStride -= nmiddle;
-
- xRot *= dstBpp;
- /*
- * Compute stip start scanline and rotation parameters
- */
- stipEnd = stip + stipStride * stipHeight;
- modulus(-yRot, stipHeight, stipY);
- s = stip + stipStride * stipY;
- modulus(-xRot, FB_UNIT, stipX);
- rot = stipX;
-
- /*
- * Get pointer to stipple mask array for this depth
- */
- /* fbStippleTable covers all valid bpp (4,8,16,32) */
- fbBits = fbStippleTable[pixelsPerDst];
-
- while (height--) {
- /*
- * Extract stipple bits for this scanline;
- */
- bits = READ(s);
- s += stipStride;
- if (s == stipEnd)
- s = stip;
- mask = fbBits[FbLeftStipBits(bits, pixelsPerDst)];
- /*
- * Rotate into position and compute reduced rop values
- */
- mask = FbRotLeft(mask, rot);
- and = (fgand & mask) | (bgand & ~mask);
- xor = (fgxor & mask) | (bgxor & ~mask);
-
- if (transparent) {
- if (startmask) {
- fbTransparentSpan(dst, mask & startmask, fgxor, 1);
- dst++;
- }
- fbTransparentSpan(dst, mask, fgxor, nmiddle);
- dst += nmiddle;
- if (endmask)
- fbTransparentSpan(dst, mask & endmask, fgxor, 1);
- }
- else {
- /*
- * Fill scanline
- */
- if (startmask) {
- FbDoLeftMaskByteRRop(dst, startbyte, startmask, and, xor);
- dst++;
- }
- n = nmiddle;
- if (!and)
- while (n--)
- WRITE(dst++, xor);
- else {
- while (n--) {
- WRITE(dst, FbDoRRop(READ(dst), and, xor));
- dst++;
- }
- }
- if (endmask)
- FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor);
- }
- dst += dstStride;
- }
-}
-
-void
-fbOddStipple(FbBits * dst,
- FbStride dstStride,
- int dstX,
- int dstBpp,
- int width,
- int height,
- FbStip * stip,
- FbStride stipStride,
- int stipWidth,
- int stipHeight,
- FbBits fgand,
- FbBits fgxor, FbBits bgand, FbBits bgxor, int xRot, int yRot)
-{
- int stipX, stipY, sx;
- int widthTmp;
- int h, w;
- int x, y;
-
- modulus(-yRot, stipHeight, stipY);
- modulus(dstX / dstBpp - xRot, stipWidth, stipX);
- y = 0;
- while (height) {
- h = stipHeight - stipY;
- if (h > height)
- h = height;
- height -= h;
- widthTmp = width;
- x = dstX;
- sx = stipX;
- while (widthTmp) {
- w = (stipWidth - sx) * dstBpp;
- if (w > widthTmp)
- w = widthTmp;
- widthTmp -= w;
- fbBltOne(stip + stipY * stipStride,
- stipStride,
- sx,
- dst + y * dstStride,
- dstStride, x, dstBpp, w, h, fgand, fgxor, bgand, bgxor);
- x += w;
- sx = 0;
- }
- y += h;
- stipY = 0;
- }
-}
-
-void
-fbStipple(FbBits * dst,
- FbStride dstStride,
- int dstX,
- int dstBpp,
- int width,
- int height,
- FbStip * stip,
- FbStride stipStride,
- int stipWidth,
- int stipHeight,
- Bool even,
- FbBits fgand,
- FbBits fgxor, FbBits bgand, FbBits bgxor, int xRot, int yRot)
-{
- if (even)
- fbEvenStipple(dst, dstStride, dstX, dstBpp, width, height,
- stip, stipStride, stipHeight,
- fgand, fgxor, bgand, bgxor, xRot, yRot);
- else
- fbOddStipple(dst, dstStride, dstX, dstBpp, width, height,
- stip, stipStride, stipWidth, stipHeight,
- fgand, fgxor, bgand, bgxor, xRot, yRot);
-}
diff --git a/fb/wfbrename.h b/fb/wfbrename.h
index a80858a..0bd233e 100644
--- a/fb/wfbrename.h
+++ b/fb/wfbrename.h
@@ -58,7 +58,6 @@
#define fbDots24 wfbDots24
#define fbDots32 wfbDots32
#define fbDots8 wfbDots8
-#define fbEvenStipple wfbEvenStipple
#define fbEvenTile wfbEvenTile
#define fbExpandDirectColors wfbExpandDirectColors
#define fbFill wfbFill
@@ -84,7 +83,6 @@
#define fbInitVisuals wfbInitVisuals
#define fbListInstalledColormaps wfbListInstalledColormaps
#define FbMergeRopBits wFbMergeRopBits
-#define fbOddStipple wfbOddStipple
#define fbOddTile wfbOddTile
#define fbOver wfbOver
#define fbOver24 wfbOver24
@@ -143,7 +141,6 @@
#define fbSolid wfbSolid
#define fbSolid24 wfbSolid24
#define fbSolidBoxClipped wfbSolidBoxClipped
-#define fbStipple wfbStipple
#define fbStipple1Bits wfbStipple1Bits
#define fbStipple24Bits wfbStipple24Bits
#define fbStipple2Bits wfbStipple2Bits
@@ -151,7 +148,6 @@
#define fbStipple8Bits wfbStipple8Bits
#define fbStippleTable wfbStippleTable
#define fbTile wfbTile
-#define fbTransparentSpan wfbTransparentSpan
#define fbTrapezoids wfbTrapezoids
#define fbTriangles wfbTriangles
#define fbUninstallColormap wfbUninstallColormap
--
1.9.3
More information about the xorg-devel
mailing list