2
* Id: fbblt.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
4
* Copyright � 1998 Keith Packard
6
* Permission to use, copy, modify, distribute, and sell this software and its
7
* documentation for any purpose is hereby granted without fee, provided that
8
* the above copyright notice appear in all copies and that both that
9
* copyright notice and this permission notice appear in supporting
10
* documentation, and that the name of Keith Packard not be used in
11
* advertising or publicity pertaining to distribution of the software without
12
* specific, written prior permission. Keith Packard makes no
13
* representations about the suitability of this software for any purpose. It
14
* is provided "as is" without express or implied warranty.
16
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22
* PERFORMANCE OF THIS SOFTWARE.
24
/* $XFree86: xc/programs/Xserver/fb/fbblt.c,v 1.8 2000/09/28 00:47:22 keithp Exp $ */
28
#define InitializeShifts(sx,dx,ls,rs) { \
41
fbBlt (FbBits *srcLine,
60
int leftShift, rightShift;
61
FbBits startmask, endmask;
65
int startbyte, endbyte;
69
if (bpp == 24 && !FbCheck24Pix (pm))
71
fbBlt24 (srcLine, srcStride, srcX, dstLine, dstStride, dstX,
72
width, height, alu, pm, reverse, upsidedown);
76
FbInitializeMergeRop(alu, pm);
77
destInvarient = FbDestInvarientMergeRop();
80
srcLine += (height - 1) * (srcStride);
81
dstLine += (height - 1) * (dstStride);
82
srcStride = -srcStride;
83
dstStride = -dstStride;
85
FbMaskBitsBytes (dstX, width, destInvarient, startmask, startbyte,
86
nmiddle, endmask, endbyte);
89
srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1;
90
dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1;
91
srcX = (srcX + width - 1) & FB_MASK;
92
dstX = (dstX + width - 1) & FB_MASK;
96
srcLine += srcX >> FB_SHIFT;
97
dstLine += dstX >> FB_SHIFT;
106
srcLine += srcStride;
108
dstLine += dstStride;
115
FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
121
*--dst = FbDoDestInvarientMergeRop(*--src);
129
*dst = FbDoMergeRop (bits, *dst);
136
FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
144
FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
152
* This provides some speedup on screen->screen blts
153
* over the PCI bus, usually about 10%. But fb
154
* isn't usually used for this operation...
156
if (_ca2 + 1 == 0 && _cx2 == 0)
158
FbBits t1, t2, t3, t4;
174
*dst++ = FbDoDestInvarientMergeRop(*src++);
181
*dst = FbDoMergeRop (bits, *dst);
188
FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
197
leftShift = srcX - dstX;
198
rightShift = FB_UNIT - leftShift;
202
rightShift = dstX - srcX;
203
leftShift = FB_UNIT - rightShift;
208
srcLine += srcStride;
210
dstLine += dstStride;
219
bits = FbScrRight(bits1, rightShift);
220
if (FbScrRight(endmask, leftShift))
223
bits |= FbScrLeft(bits1, leftShift);
226
FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
233
bits = FbScrRight(bits1, rightShift);
235
bits |= FbScrLeft(bits1, leftShift);
237
*dst = FbDoDestInvarientMergeRop(bits);
244
bits = FbScrRight(bits1, rightShift);
246
bits |= FbScrLeft(bits1, leftShift);
248
*dst = FbDoMergeRop(bits, *dst);
253
bits = FbScrRight(bits1, rightShift);
254
if (FbScrRight(startmask, leftShift))
257
bits |= FbScrLeft(bits1, leftShift);
260
FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask);
269
bits = FbScrLeft(bits1, leftShift);
271
bits |= FbScrRight(bits1, rightShift);
272
FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask);
280
bits = FbScrLeft(bits1, leftShift);
282
bits |= FbScrRight(bits1, rightShift);
283
*dst = FbDoDestInvarientMergeRop(bits);
291
bits = FbScrLeft(bits1, leftShift);
293
bits |= FbScrRight(bits1, rightShift);
294
*dst = FbDoMergeRop(bits, *dst);
300
bits = FbScrLeft(bits1, leftShift);
301
if (FbScrLeft(endmask, rightShift))
304
bits |= FbScrRight(bits1, rightShift);
306
FbDoRightMaskByteMergeRop (dst, bits, endbyte, endmask);
319
getPixel (char *src, int x)
324
memcpy (&l, src + x * 3, 3);
330
fbBlt24Line (FbBits *src,
344
char *origDst = (char *) dst;
345
FbBits *origLine = dst + ((dstX >> FB_SHIFT) - 1);
346
int origNlw = ((width + FB_MASK) >> FB_SHIFT) + 3;
347
int origX = dstX / 24;
350
int leftShift, rightShift;
351
FbBits startmask, endmask;
358
FbDeclareMergeRop ();
360
FbInitializeMergeRop (alu, FB_ALLONES);
361
FbMaskBits(dstX, width, startmask, n, endmask);
363
ErrorF ("dstX %d width %d reverse %d\n", dstX, width, reverse);
367
src += ((srcX + width - 1) >> FB_SHIFT) + 1;
368
dst += ((dstX + width - 1) >> FB_SHIFT) + 1;
369
rot = FbFirst24Rot (((dstX + width - 8) & FB_MASK));
370
rot = FbPrev24Rot(rot);
372
ErrorF ("dstX + width - 8: %d rot: %d\n", (dstX + width - 8) & FB_MASK, rot);
374
srcX = (srcX + width - 1) & FB_MASK;
375
dstX = (dstX + width - 1) & FB_MASK;
379
src += srcX >> FB_SHIFT;
380
dst += dstX >> FB_SHIFT;
383
rot = FbFirst24Rot (dstX);
385
ErrorF ("dstX: %d rot: %d\n", dstX, rot);
388
mask = FbRot24(pm,rot);
390
ErrorF ("pm 0x%x mask 0x%x\n", pm, mask);
400
*dst = FbDoMaskMergeRop (bits, *dst, mask & endmask);
401
mask = FbPrev24Pix (mask);
407
*dst = FbDoMaskMergeRop (bits, *dst, mask);
408
mask = FbPrev24Pix (mask);
414
*dst = FbDoMaskMergeRop(bits, *dst, mask & startmask);
422
*dst = FbDoMaskMergeRop (bits, *dst, mask & startmask);
424
mask = FbNext24Pix(mask);
429
*dst = FbDoMaskMergeRop (bits, *dst, mask);
431
mask = FbNext24Pix(mask);
436
*dst = FbDoMaskMergeRop(bits, *dst, mask & endmask);
444
leftShift = srcX - dstX;
445
rightShift = FB_UNIT - leftShift;
449
rightShift = dstX - srcX;
450
leftShift = FB_UNIT - rightShift;
460
bits = FbScrRight(bits1, rightShift);
461
if (FbScrRight(endmask, leftShift))
464
bits |= FbScrLeft(bits1, leftShift);
467
*dst = FbDoMaskMergeRop (bits, *dst, mask & endmask);
468
mask = FbPrev24Pix(mask);
472
bits = FbScrRight(bits1, rightShift);
474
bits |= FbScrLeft(bits1, leftShift);
476
*dst = FbDoMaskMergeRop(bits, *dst, mask);
477
mask = FbPrev24Pix(mask);
481
bits = FbScrRight(bits1, rightShift);
482
if (FbScrRight(startmask, leftShift))
485
bits |= FbScrLeft(bits1, leftShift);
488
*dst = FbDoMaskMergeRop (bits, *dst, mask & startmask);
497
bits = FbScrLeft(bits1, leftShift);
499
bits |= FbScrRight(bits1, rightShift);
500
*dst = FbDoMaskMergeRop (bits, *dst, mask & startmask);
502
mask = FbNext24Pix(mask);
506
bits = FbScrLeft(bits1, leftShift);
508
bits |= FbScrRight(bits1, rightShift);
509
*dst = FbDoMaskMergeRop(bits, *dst, mask);
511
mask = FbNext24Pix(mask);
515
bits = FbScrLeft(bits1, leftShift);
516
if (FbScrLeft(endmask, rightShift))
519
bits |= FbScrRight(bits1, rightShift);
521
*dst = FbDoMaskMergeRop (bits, *dst, mask & endmask);
527
int firstx, lastx, x;
532
lastx = origX + width/24 + 1;
533
for (x = firstx; x <= lastx; x++)
534
ErrorF ("%06x ", getPixel (origDst, x));
537
ErrorF ("%08x ", *origLine++);
544
fbBlt24 (FbBits *srcLine,
563
srcLine += (height-1) * srcStride;
564
dstLine += (height-1) * dstStride;
565
srcStride = -srcStride;
566
dstStride = -dstStride;
570
fbBlt24Line (srcLine, srcX, dstLine, dstX, width, alu, pm, reverse);
571
srcLine += srcStride;
572
dstLine += dstStride;
578
#endif /* FB_24BIT */
580
#if FB_SHIFT == FB_STIP_SHIFT + 1
583
* Could be generalized to FB_SHIFT > FB_STIP_SHIFT + 1 by
584
* creating an ring of values stepped through for each line
588
fbBltOdd (FbBits *srcLine,
589
FbStride srcStrideEven,
590
FbStride srcStrideOdd,
595
FbStride dstStrideEven,
596
FbStride dstStrideOdd,
608
int leftShiftEven, rightShiftEven;
609
FbBits startmaskEven, endmaskEven;
613
int leftShiftOdd, rightShiftOdd;
614
FbBits startmaskOdd, endmaskOdd;
617
int leftShift, rightShift;
618
FbBits startmask, endmask;
628
FbDeclareMergeRop ();
630
FbInitializeMergeRop (alu, pm);
631
destInvarient = FbDestInvarientMergeRop();
633
srcLine += srcXEven >> FB_SHIFT;
634
dstLine += dstXEven >> FB_SHIFT;
640
FbMaskBits(dstXEven, width, startmaskEven, nmiddleEven, endmaskEven);
641
FbMaskBits(dstXOdd, width, startmaskOdd, nmiddleOdd, endmaskOdd);
644
InitializeShifts(srcXEven, dstXEven, leftShiftEven, rightShiftEven);
645
InitializeShifts(srcXOdd, dstXOdd, leftShiftOdd, rightShiftOdd);
654
startmask = startmaskEven;
655
endmask = endmaskEven;
656
nmiddle = nmiddleEven;
657
leftShift = leftShiftEven;
658
rightShift = rightShiftEven;
659
srcLine += srcStrideEven;
660
dstLine += dstStrideEven;
667
startmask = startmaskOdd;
668
endmask = endmaskOdd;
669
nmiddle = nmiddleOdd;
670
leftShift = leftShiftOdd;
671
rightShift = rightShiftOdd;
672
srcLine += srcStrideOdd;
673
dstLine += dstStrideOdd;
681
*dst = FbDoMaskMergeRop (bits, *dst, startmask);
690
*dst = FbDoDestInvarientMergeRop(bits);
699
*dst = FbDoMergeRop (bits, *dst);
706
*dst = FbDoMaskMergeRop(bits, *dst, endmask);
716
bits1 = FbScrLeft(bits, leftShift);
718
bits1 |= FbScrRight(bits, rightShift);
719
*dst = FbDoMaskMergeRop (bits1, *dst, startmask);
727
bits1 = FbScrLeft(bits, leftShift);
729
bits1 |= FbScrRight(bits, rightShift);
730
*dst = FbDoDestInvarientMergeRop(bits1);
738
bits1 = FbScrLeft(bits, leftShift);
740
bits1 |= FbScrRight(bits, rightShift);
741
*dst = FbDoMergeRop(bits1, *dst);
747
bits1 = FbScrLeft(bits, leftShift);
748
if (FbScrLeft(endmask, rightShift))
751
bits1 |= FbScrRight(bits, rightShift);
753
*dst = FbDoMaskMergeRop (bits1, *dst, endmask);
761
fbBltOdd24 (FbBits *srcLine,
762
FbStride srcStrideEven,
763
FbStride srcStrideOdd,
768
FbStride dstStrideEven,
769
FbStride dstStrideOdd,
785
fbBlt24Line (srcLine, srcXEven, dstLine, dstXEven,
786
width, alu, pm, FALSE);
787
srcLine += srcStrideEven;
788
dstLine += dstStrideEven;
793
fbBlt24Line (srcLine, srcXOdd, dstLine, dstXOdd,
794
width, alu, pm, FALSE);
795
srcLine += srcStrideOdd;
796
dstLine += dstStrideOdd;
801
fprintf (stderr, "\n");
808
#if FB_STIP_SHIFT != FB_SHIFT
810
fbSetBltOdd (FbStip *stip,
814
FbStride *strideEven,
823
* bytes needed to align source
825
srcAdjust = (((int) stip) & (FB_MASK >> 3));
827
* FbStip units needed to align stride
829
strideAdjust = stipStride & (FB_MASK >> FB_STIP_SHIFT);
831
*bits = (FbBits *) ((char *) stip - srcAdjust);
834
*strideEven = FbStipStrideToBitsStride (stipStride + 1);
835
*strideOdd = FbStipStrideToBitsStride (stipStride);
837
*srcXEven = srcX + (srcAdjust << 3);
838
*srcXOdd = srcX + (srcAdjust << 3) - (strideAdjust << FB_STIP_SHIFT);
842
*strideEven = FbStipStrideToBitsStride (stipStride);
843
*strideOdd = FbStipStrideToBitsStride (stipStride + 1);
846
*srcXOdd = srcX + (strideAdjust << FB_STIP_SHIFT);
852
fbBltStip (FbStip *src,
853
FbStride srcStride, /* in FbStip units, not FbBits units */
857
FbStride dstStride, /* in FbStip units, not FbBits units */
867
#if FB_STIP_SHIFT != FB_SHIFT
868
if (FB_STIP_ODDSTRIDE(srcStride) || FB_STIP_ODDPTR(src) ||
869
FB_STIP_ODDSTRIDE(dstStride) || FB_STIP_ODDPTR(dst))
871
FbStride srcStrideEven, srcStrideOdd;
872
FbStride dstStrideEven, dstStrideOdd;
873
int srcXEven, srcXOdd;
874
int dstXEven, dstXOdd;
878
src += srcX >> FB_STIP_SHIFT;
879
srcX &= FB_STIP_MASK;
880
dst += dstX >> FB_STIP_SHIFT;
881
dstX &= FB_STIP_MASK;
883
fbSetBltOdd (src, srcStride, srcX,
885
&srcStrideEven, &srcStrideOdd,
886
&srcXEven, &srcXOdd);
888
fbSetBltOdd (dst, dstStride, dstX,
890
&dstStrideEven, &dstStrideOdd,
891
&dstXEven, &dstXOdd);
894
if (bpp == 24 && !FbCheck24Pix (pm))
896
fbBltOdd24 (s, srcStrideEven, srcStrideOdd,
899
d, dstStrideEven, dstStrideOdd,
902
width, height, alu, pm);
907
fbBltOdd (s, srcStrideEven, srcStrideOdd,
910
d, dstStrideEven, dstStrideOdd,
913
width, height, alu, pm, bpp);
919
fbBlt ((FbBits *) src, FbStipStrideToBitsStride (srcStride),
921
(FbBits *) dst, FbStipStrideToBitsStride (dstStride),
924
alu, pm, bpp, FALSE, FALSE);