summaryrefslogtreecommitdiff
path: root/src/sna/fb/fblinebits.h
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-07-06 15:22:26 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2012-07-08 21:34:21 +0100
commite3e58123d36924c760ab6f58a7155a040422e91d (patch)
tree683b2db2d53d8abe790d34e431ddc7747d5639ff /src/sna/fb/fblinebits.h
parent5d2f88fd9972c62c87098ddc7fee7b6f0cea0fdb (diff)
sna: Fixup fb wrapper
To accommodate changes in the Xserver and avoid breakage; would have been much easier had the fb been exported in the first place.
Diffstat (limited to 'src/sna/fb/fblinebits.h')
-rw-r--r--src/sna/fb/fblinebits.h284
1 files changed, 284 insertions, 0 deletions
diff --git a/src/sna/fb/fblinebits.h b/src/sna/fb/fblinebits.h
new file mode 100644
index 00000000..db315d81
--- /dev/null
+++ b/src/sna/fb/fblinebits.h
@@ -0,0 +1,284 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * 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.
+ */
+
+#define isClipped(c,ul,lr) (((c) | ((c) - (ul)) | ((lr) - (c))) & 0x80008000)
+#define RROP(b,a,x) WRITE((b), FbDoRRop (READ(b), (a), (x)))
+
+static void
+POLYLINE(DrawablePtr drawable, GCPtr gc, int mode, int n_0, DDXPointPtr pt_0)
+{
+ int xoff = drawable->x;
+ int yoff = drawable->y;
+ unsigned int bias = miGetZeroLineBias(drawable->pScreen);
+ const BoxRec *clip = RegionRects(gc->pCompositeClip);
+ const BoxRec *const last_clip = clip + RegionNumRects(gc->pCompositeClip);
+
+ FbBits *dst;
+ int dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+
+ BITS *bits, *bitsBase;
+ FbStride bitsStride;
+ BITS xor = fb_gc(gc)->xor;
+ BITS and = fb_gc(gc)->and;
+
+
+ int e, e1, e3, len;
+ int stepmajor, stepminor;
+ int octant;
+
+ if (mode == CoordModePrevious)
+ fbFixCoordModePrevious(n_0, pt_0);
+
+ fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ bitsStride = dstStride * (sizeof(FbBits) / sizeof(BITS));
+ bitsBase =
+ ((BITS *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff);
+ do {
+ INT32 *pt = (INT32 *)pt_0;
+ int n = n_0;
+ INT32 pt1, pt2;
+
+ INT32 ul = coordToInt(clip->x1 - xoff, clip->y1 - yoff);
+ INT32 lr = coordToInt(clip->x2 - xoff - 1, clip->y2 - yoff - 1);
+
+ pt1 = *pt++; n--;
+ pt2 = *pt++; n--;
+ for (;;) {
+ if (isClipped(pt1, ul, lr) | isClipped(pt2, ul, lr)) {
+ int dashoffset = 0;
+ fbSegment1(drawable, gc, clip,
+ intToX(pt1) + xoff, intToY(pt1) + yoff,
+ intToX(pt2) + xoff, intToY(pt2) + yoff,
+ n == 0 && gc->capStyle != CapNotLast, &dashoffset);
+ if (!n)
+ return;
+
+ pt1 = pt2;
+ pt2 = *pt++;
+ n--;
+ } else {
+ bits = bitsBase + intToY(pt1) * bitsStride + intToX(pt1);
+ for (;;) {
+ CalcLineDeltas(intToX(pt1), intToY(pt1),
+ intToX(pt2), intToY(pt2),
+ len, e1, stepmajor, stepminor, 1, bitsStride,
+ octant);
+ if (len < e1) {
+ e3 = len;
+ len = e1;
+ e1 = e3;
+
+ e3 = stepminor;
+ stepminor = stepmajor;
+ stepmajor = e3;
+ SetYMajorOctant(octant);
+ }
+ e = -len;
+ e1 <<= 1;
+ e3 = e << 1;
+ FIXUP_ERROR(e, octant, bias);
+ if (and == 0) {
+ while (len--) {
+ WRITE(bits, xor);
+ bits += stepmajor;
+ e += e1;
+ if (e >= 0) {
+ bits += stepminor;
+ e += e3;
+ }
+ }
+ } else {
+ while (len--) {
+ RROP(bits, and, xor);
+ bits += stepmajor;
+ e += e1;
+ if (e >= 0) {
+ bits += stepminor;
+ e += e3;
+ }
+ }
+ }
+ if (!n) {
+ if (gc->capStyle != CapNotLast &&
+ pt2 != *((INT32 *)pt_0)) {
+ RROP(bits, and, xor);
+ }
+ return;
+ }
+ pt1 = pt2;
+ pt2 = *pt++;
+ --n;
+ if (isClipped(pt2, ul, lr))
+ break;
+ }
+ }
+ }
+ } while (++clip != last_clip);
+}
+
+static void
+POLYSEGMENT(DrawablePtr drawable, GCPtr gc, int n_0, xSegment *seg_0)
+{
+ int xoff = drawable->x;
+ int yoff = drawable->y;
+ unsigned int bias = miGetZeroLineBias(drawable->pScreen);
+ const BoxRec *clip = RegionRects(gc->pCompositeClip);
+ const BoxRec *const last_clip = clip + RegionNumRects(gc->pCompositeClip);
+
+ FbBits *dst;
+ int dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+
+ BITS *bits, *bitsBase;
+ FbStride bitsStride;
+ FbBits xor = fb_gc(gc)->xor;
+ FbBits and = fb_gc(gc)->and;
+
+ int e, e1, e3, len;
+ int stepmajor, stepminor;
+ int octant;
+ bool capNotLast = gc->capStyle == CapNotLast;
+
+ fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ bitsStride = dstStride * (sizeof(FbBits) / sizeof(BITS));
+ bitsBase =
+ ((BITS *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff);
+
+ do {
+ INT32 ul = coordToInt(clip->x1 - xoff, clip->y1 - yoff);
+ INT32 lr = coordToInt(clip->x2 - xoff - 1, clip->y2 - yoff - 1);
+ uint64_t *pt = (uint64_t *)seg_0;
+ int n = n_0;
+
+ while (n--) {
+ union {
+ int32_t pt32[2];
+ uint64_t pt64;
+ } u;
+
+ u.pt64 = *pt++;
+ if (isClipped(u.pt32[0], ul, lr) | isClipped(u.pt32[1], ul, lr)) {
+ int dashoffset = 0;
+ fbSegment1(drawable, gc, clip,
+ intToX(u.pt32[0]) + xoff, intToY(u.pt32[0]) + yoff,
+ intToX(u.pt32[1]) + xoff, intToY(u.pt32[1]) + yoff,
+ !capNotLast, &dashoffset);
+ } else {
+ CalcLineDeltas(intToX(u.pt32[0]), intToY(u.pt32[0]),
+ intToX(u.pt32[1]), intToY(u.pt32[1]),
+ len, e1, stepmajor, stepminor, 1, bitsStride,
+ octant);
+ if (e1 == 0 && len > 3) {
+ int x1, x2;
+ FbBits *dstLine;
+ int dstX, width;
+ FbBits startmask, endmask;
+ int nmiddle;
+
+ if (stepmajor < 0) {
+ x1 = intToX(u.pt32[1]);
+ x2 = intToX(u.pt32[0]) + 1;
+ if (capNotLast)
+ x1++;
+ } else {
+ x1 = intToX(u.pt32[0]);
+ x2 = intToX(u.pt32[1]);
+ if (!capNotLast)
+ x2++;
+ }
+ dstX = (x1 + xoff + dstXoff) * (sizeof(BITS) * 8);
+ width = (x2 - x1) * (sizeof(BITS) * 8);
+
+ dstLine = dst + (intToY(u.pt32[0]) + yoff + dstYoff) * dstStride;
+ dstLine += dstX >> FB_SHIFT;
+ dstX &= FB_MASK;
+ FbMaskBits(dstX, width, startmask, nmiddle, endmask);
+ if (startmask) {
+ WRITE(dstLine,
+ FbDoMaskRRop(READ(dstLine), and, xor,
+ startmask));
+ dstLine++;
+ }
+ if (!and)
+ while (nmiddle--)
+ WRITE(dstLine++, xor);
+ else
+ while (nmiddle--) {
+ WRITE(dstLine,
+ FbDoRRop(READ(dstLine), and, xor));
+ dstLine++;
+ }
+ if (endmask)
+ WRITE(dstLine,
+ FbDoMaskRRop(READ(dstLine), and, xor,
+ endmask));
+ } else {
+ bits = bitsBase + intToY(u.pt32[0]) * bitsStride + intToX(u.pt32[0]);
+ if (len < e1) {
+ e3 = len;
+ len = e1;
+ e1 = e3;
+
+ e3 = stepminor;
+ stepminor = stepmajor;
+ stepmajor = e3;
+ SetYMajorOctant(octant);
+ }
+ e = -len;
+ e1 <<= 1;
+ e3 = e << 1;
+ FIXUP_ERROR(e, octant, bias);
+ if (!capNotLast)
+ len++;
+ if (and == 0) {
+ while (len--) {
+ WRITE(bits, xor);
+ bits += stepmajor;
+ e += e1;
+ if (e >= 0) {
+ bits += stepminor;
+ e += e3;
+ }
+ }
+ } else {
+ while (len--) {
+ RROP(bits, and, xor);
+ bits += stepmajor;
+ e += e1;
+ if (e >= 0) {
+ bits += stepminor;
+ e += e3;
+ }
+ }
+ }
+ }
+ }
+ }
+ } while (++clip != last_clip);
+}
+
+#undef RROP
+#undef isClipped