diff --git a/src/sna/fb/fb.h b/src/sna/fb/fb.h index 215aec99..adefaa19 100644 --- a/src/sna/fb/fb.h +++ b/src/sna/fb/fb.h @@ -515,7 +515,9 @@ extern RegionPtr fbBitmapToRegion(PixmapPtr pixmap); extern void -fbPolyPoint(DrawablePtr drawable, GCPtr gc, int mode, int n, xPoint *pt); +fbPolyPoint(DrawablePtr drawable, GCPtr gc, + int mode, int n, xPoint *pt, + unsigned flags); extern void fbPushImage(DrawablePtr drawable, GCPtr gc, diff --git a/src/sna/fb/fbpoint.c b/src/sna/fb/fbpoint.c index e3974fca..3df79a26 100644 --- a/src/sna/fb/fbpoint.c +++ b/src/sna/fb/fbpoint.c @@ -25,21 +25,27 @@ #include #define DOTS fbDots8 +#define DOTS__SIMPLE fbDots8__simple #define BITS BYTE #include "fbpointbits.h" #undef BITS +#undef DOTS__SIMPLE #undef DOTS #define DOTS fbDots16 +#define DOTS__SIMPLE fbDots16__simple #define BITS CARD16 #include "fbpointbits.h" #undef BITS +#undef DOTS__SIMPLE #undef DOTS #define DOTS fbDots32 +#define DOTS__SIMPLE fbDots32__simple #define BITS CARD32 #include "fbpointbits.h" #undef BITS +#undef DOTS__SIMPLE #undef DOTS static void @@ -74,7 +80,7 @@ fbDots(FbBits *dstOrig, FbStride dstStride, int dstBpp, void fbPolyPoint(DrawablePtr drawable, GCPtr gc, - int mode, int n, xPoint *pt) + int mode, int n, xPoint *pt, unsigned flags) { FbBits *dst; FbStride dstStride; @@ -97,16 +103,30 @@ fbPolyPoint(DrawablePtr drawable, GCPtr gc, fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff, dstYoff); dots = fbDots; - switch (dstBpp) { - case 8: - dots = fbDots8; - break; - case 16: - dots = fbDots16; - break; - case 32: - dots = fbDots32; - break; + if ((flags & 2) == 0 && fb_gc(gc)->and == 0) { + switch (dstBpp) { + case 8: + dots = fbDots8__simple; + break; + case 16: + dots = fbDots16__simple; + break; + case 32: + dots = fbDots32__simple; + break; + } + } else { + switch (dstBpp) { + case 8: + dots = fbDots8; + break; + case 16: + dots = fbDots16; + break; + case 32: + dots = fbDots32; + break; + } } dots(dst, dstStride, dstBpp, gc->pCompositeClip, pt, n, drawable->x, drawable->y, dstXoff, dstYoff, diff --git a/src/sna/fb/fbpointbits.h b/src/sna/fb/fbpointbits.h index 2d71c1d2..60bf4881 100644 --- a/src/sna/fb/fbpointbits.h +++ b/src/sna/fb/fbpointbits.h @@ -106,5 +106,43 @@ DOTS(FbBits * dst, } } +static void +DOTS__SIMPLE(FbBits * dst, + FbStride dstStride, + int dstBpp, + RegionPtr region, + xPoint * ptsOrig, + int npt, int xorg, int yorg, int xoff, int yoff, + FbBits and, FbBits xor) +{ + uint32_t *pts = (uint32_t *) ptsOrig; + BITS *bits = (BITS *) dst, *p; + BITS bxor = (BITS) xor; + FbStride bitsStride = dstStride * (sizeof(FbBits) / sizeof(BITS)); + + bits += bitsStride * (yorg + yoff) + (xorg + xoff); + while (npt >= 2) { + union { + uint32_t pt32[2]; + uint64_t pt64; + } pt; + pt.pt64 = *(uint64_t *)pts; + + p = bits + intToY(pt.pt32[0]) * bitsStride + intToX(pt.pt32[0]); + WRITE(p, bxor); + + p = bits + intToY(pt.pt32[1]) * bitsStride + intToX(pt.pt32[1]); + WRITE(p, bxor); + + pts += 2; + npt -= 2; + } + if (npt) { + uint32_t pt = *pts; + p = bits + intToY(pt) * bitsStride + intToX(pt); + WRITE(p, bxor); + } +} + #undef RROP #undef isClipped diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 792d0070..98810502 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -6696,7 +6696,7 @@ fallback: goto out_gc; DBG(("%s: fbPolyPoint\n", __FUNCTION__)); - fbPolyPoint(drawable, gc, mode, n, pt); + fbPolyPoint(drawable, gc, mode, n, pt, flags); FALLBACK_FLUSH(drawable); out_gc: sna_gc_move_to_gpu(gc);