Add patch that contain Mali fixes.
[deb_xorg-server.git] / fb / fbblt.c
CommitLineData
a09e091a
JB
1/*
2 * Copyright © 1998 Keith Packard
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Keith Packard not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Keith Packard makes no
11 * representations about the suitability of this software for any purpose. It
12 * is provided "as is" without express or implied warranty.
13 *
14 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22
23#ifdef HAVE_DIX_CONFIG_H
24#include <dix-config.h>
25#endif
26
27#include <string.h>
28#include "fb.h"
29
30#define InitializeShifts(sx,dx,ls,rs) { \
31 if (sx != dx) { \
32 if (sx > dx) { \
33 ls = sx - dx; \
34 rs = FB_UNIT - ls; \
35 } else { \
36 rs = dx - sx; \
37 ls = FB_UNIT - rs; \
38 } \
39 } \
40}
41
42void
43fbBlt(FbBits * srcLine,
44 FbStride srcStride,
45 int srcX,
46 FbBits * dstLine,
47 FbStride dstStride,
48 int dstX,
49 int width,
50 int height, int alu, FbBits pm, int bpp, Bool reverse, Bool upsidedown)
51{
52 FbBits *src, *dst;
53 int leftShift, rightShift;
54 FbBits startmask, endmask;
55 FbBits bits, bits1;
56 int n, nmiddle;
57 Bool destInvarient;
58 int startbyte, endbyte;
59 int careful;
60
61 FbDeclareMergeRop();
62
63 if (bpp == 24 && !FbCheck24Pix(pm)) {
64 fbBlt24(srcLine, srcStride, srcX, dstLine, dstStride, dstX,
65 width, height, alu, pm, reverse, upsidedown);
66 return;
67 }
68
69 careful = !((srcLine < dstLine && srcLine + width * (bpp >> 3) > dstLine) ||
70 (dstLine < srcLine && dstLine + width * (bpp >> 3) > srcLine))
71 || (bpp & 7);
72
73 if (alu == GXcopy && pm == FB_ALLONES && !careful &&
74 !(srcX & 7) && !(dstX & 7) && !(width & 7)) {
75 int i;
76 CARD8 *tmpsrc = (CARD8 *) srcLine;
77 CARD8 *tmpdst = (CARD8 *) dstLine;
78
79 srcStride *= sizeof(FbBits);
80 dstStride *= sizeof(FbBits);
81 width >>= 3;
82 tmpsrc += (srcX >> 3);
83 tmpdst += (dstX >> 3);
84
85 if (!upsidedown)
86 for (i = 0; i < height; i++)
87 MEMCPY_WRAPPED(tmpdst + i * dstStride, tmpsrc + i * srcStride, width);
88 else
89 for (i = height - 1; i >= 0; i--)
90 MEMCPY_WRAPPED(tmpdst + i * dstStride, tmpsrc + i * srcStride, width);
91
92 return;
93 }
94
95 FbInitializeMergeRop(alu, pm);
96 destInvarient = FbDestInvarientMergeRop();
97 if (upsidedown) {
98 srcLine += (height - 1) * (srcStride);
99 dstLine += (height - 1) * (dstStride);
100 srcStride = -srcStride;
101 dstStride = -dstStride;
102 }
103 FbMaskBitsBytes(dstX, width, destInvarient, startmask, startbyte,
104 nmiddle, endmask, endbyte);
105 if (reverse) {
106 srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1;
107 dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1;
108 srcX = (srcX + width - 1) & FB_MASK;
109 dstX = (dstX + width - 1) & FB_MASK;
110 }
111 else {
112 srcLine += srcX >> FB_SHIFT;
113 dstLine += dstX >> FB_SHIFT;
114 srcX &= FB_MASK;
115 dstX &= FB_MASK;
116 }
117 if (srcX == dstX) {
118 while (height--) {
119 src = srcLine;
120 srcLine += srcStride;
121 dst = dstLine;
122 dstLine += dstStride;
123 if (reverse) {
124 if (endmask) {
125 bits = READ(--src);
126 --dst;
127 FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
128 }
129 n = nmiddle;
130 if (destInvarient) {
131 while (n--)
132 WRITE(--dst, FbDoDestInvarientMergeRop(READ(--src)));
133 }
134 else {
135 while (n--) {
136 bits = READ(--src);
137 --dst;
138 WRITE(dst, FbDoMergeRop(bits, READ(dst)));
139 }
140 }
141 if (startmask) {
142 bits = READ(--src);
143 --dst;
144 FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
145 }
146 }
147 else {
148 if (startmask) {
149 bits = READ(src++);
150 FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
151 dst++;
152 }
153 n = nmiddle;
154 if (destInvarient) {
155#if 0
156 /*
157 * This provides some speedup on screen->screen blts
158 * over the PCI bus, usually about 10%. But fb
159 * isn't usually used for this operation...
160 */
161 if (_ca2 + 1 == 0 && _cx2 == 0) {
162 FbBits t1, t2, t3, t4;
163
164 while (n >= 4) {
165 t1 = *src++;
166 t2 = *src++;
167 t3 = *src++;
168 t4 = *src++;
169 *dst++ = t1;
170 *dst++ = t2;
171 *dst++ = t3;
172 *dst++ = t4;
173 n -= 4;
174 }
175 }
176#endif
177 while (n--)
178 WRITE(dst++, FbDoDestInvarientMergeRop(READ(src++)));
179 }
180 else {
181 while (n--) {
182 bits = READ(src++);
183 WRITE(dst, FbDoMergeRop(bits, READ(dst)));
184 dst++;
185 }
186 }
187 if (endmask) {
188 bits = READ(src);
189 FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
190 }
191 }
192 }
193 }
194 else {
195 if (srcX > dstX) {
196 leftShift = srcX - dstX;
197 rightShift = FB_UNIT - leftShift;
198 }
199 else {
200 rightShift = dstX - srcX;
201 leftShift = FB_UNIT - rightShift;
202 }
203 while (height--) {
204 src = srcLine;
205 srcLine += srcStride;
206 dst = dstLine;
207 dstLine += dstStride;
208
209 bits1 = 0;
210 if (reverse) {
211 if (srcX < dstX)
212 bits1 = READ(--src);
213 if (endmask) {
214 bits = FbScrRight(bits1, rightShift);
215 if (FbScrRight(endmask, leftShift)) {
216 bits1 = READ(--src);
217 bits |= FbScrLeft(bits1, leftShift);
218 }
219 --dst;
220 FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
221 }
222 n = nmiddle;
223 if (destInvarient) {
224 while (n--) {
225 bits = FbScrRight(bits1, rightShift);
226 bits1 = READ(--src);
227 bits |= FbScrLeft(bits1, leftShift);
228 --dst;
229 WRITE(dst, FbDoDestInvarientMergeRop(bits));
230 }
231 }
232 else {
233 while (n--) {
234 bits = FbScrRight(bits1, rightShift);
235 bits1 = READ(--src);
236 bits |= FbScrLeft(bits1, leftShift);
237 --dst;
238 WRITE(dst, FbDoMergeRop(bits, READ(dst)));
239 }
240 }
241 if (startmask) {
242 bits = FbScrRight(bits1, rightShift);
243 if (FbScrRight(startmask, leftShift)) {
244 bits1 = READ(--src);
245 bits |= FbScrLeft(bits1, leftShift);
246 }
247 --dst;
248 FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
249 }
250 }
251 else {
252 if (srcX > dstX)
253 bits1 = READ(src++);
254 if (startmask) {
255 bits = FbScrLeft(bits1, leftShift);
256 if (FbScrLeft(startmask, rightShift)) {
257 bits1 = READ(src++);
258 bits |= FbScrRight(bits1, rightShift);
259 }
260 FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
261 dst++;
262 }
263 n = nmiddle;
264 if (destInvarient) {
265 while (n--) {
266 bits = FbScrLeft(bits1, leftShift);
267 bits1 = READ(src++);
268 bits |= FbScrRight(bits1, rightShift);
269 WRITE(dst, FbDoDestInvarientMergeRop(bits));
270 dst++;
271 }
272 }
273 else {
274 while (n--) {
275 bits = FbScrLeft(bits1, leftShift);
276 bits1 = READ(src++);
277 bits |= FbScrRight(bits1, rightShift);
278 WRITE(dst, FbDoMergeRop(bits, READ(dst)));
279 dst++;
280 }
281 }
282 if (endmask) {
283 bits = FbScrLeft(bits1, leftShift);
284 if (FbScrLeft(endmask, rightShift)) {
285 bits1 = READ(src);
286 bits |= FbScrRight(bits1, rightShift);
287 }
288 FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
289 }
290 }
291 }
292 }
293}
294
295#undef DEBUG_BLT24
296#ifdef DEBUG_BLT24
297
298static unsigned long
299getPixel(char *src, int x)
300{
301 unsigned long l;
302
303 l = 0;
304 memcpy(&l, src + x * 3, 3);
305 return l;
306}
307#endif
308
309static void
310fbBlt24Line(FbBits * src,
311 int srcX,
312 FbBits * dst, int dstX, int width, int alu, FbBits pm, Bool reverse)
313{
314#ifdef DEBUG_BLT24
315 char *origDst = (char *) dst;
316 FbBits *origLine = dst + ((dstX >> FB_SHIFT) - 1);
317 int origNlw = ((width + FB_MASK) >> FB_SHIFT) + 3;
318 int origX = dstX / 24;
319#endif
320
321 int leftShift, rightShift;
322 FbBits startmask, endmask;
323 int n;
324
325 FbBits bits, bits1;
326 FbBits mask;
327
328 int rot;
329
330 FbDeclareMergeRop();
331
332 FbInitializeMergeRop(alu, FB_ALLONES);
333 FbMaskBits(dstX, width, startmask, n, endmask);
334#ifdef DEBUG_BLT24
335 ErrorF("dstX %d width %d reverse %d\n", dstX, width, reverse);
336#endif
337 if (reverse) {
338 src += ((srcX + width - 1) >> FB_SHIFT) + 1;
339 dst += ((dstX + width - 1) >> FB_SHIFT) + 1;
340 rot = FbFirst24Rot(((dstX + width - 8) & FB_MASK));
341 rot = FbPrev24Rot(rot);
342#ifdef DEBUG_BLT24
343 ErrorF("dstX + width - 8: %d rot: %d\n", (dstX + width - 8) & FB_MASK,
344 rot);
345#endif
346 srcX = (srcX + width - 1) & FB_MASK;
347 dstX = (dstX + width - 1) & FB_MASK;
348 }
349 else {
350 src += srcX >> FB_SHIFT;
351 dst += dstX >> FB_SHIFT;
352 srcX &= FB_MASK;
353 dstX &= FB_MASK;
354 rot = FbFirst24Rot(dstX);
355#ifdef DEBUG_BLT24
356 ErrorF("dstX: %d rot: %d\n", dstX, rot);
357#endif
358 }
359 mask = FbRot24(pm, rot);
360#ifdef DEBUG_BLT24
361 ErrorF("pm 0x%x mask 0x%x\n", pm, mask);
362#endif
363 if (srcX == dstX) {
364 if (reverse) {
365 if (endmask) {
366 bits = READ(--src);
367 --dst;
368 WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & endmask));
369 mask = FbPrev24Pix(mask);
370 }
371 while (n--) {
372 bits = READ(--src);
373 --dst;
374 WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask));
375 mask = FbPrev24Pix(mask);
376 }
377 if (startmask) {
378 bits = READ(--src);
379 --dst;
380 WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & startmask));
381 }
382 }
383 else {
384 if (startmask) {
385 bits = READ(src++);
386 WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & startmask));
387 dst++;
388 mask = FbNext24Pix(mask);
389 }
390 while (n--) {
391 bits = READ(src++);
392 WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask));
393 dst++;
394 mask = FbNext24Pix(mask);
395 }
396 if (endmask) {
397 bits = READ(src);
398 WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & endmask));
399 }
400 }
401 }
402 else {
403 if (srcX > dstX) {
404 leftShift = srcX - dstX;
405 rightShift = FB_UNIT - leftShift;
406 }
407 else {
408 rightShift = dstX - srcX;
409 leftShift = FB_UNIT - rightShift;
410 }
411
412 bits1 = 0;
413 if (reverse) {
414 if (srcX < dstX)
415 bits1 = READ(--src);
416 if (endmask) {
417 bits = FbScrRight(bits1, rightShift);
418 if (FbScrRight(endmask, leftShift)) {
419 bits1 = READ(--src);
420 bits |= FbScrLeft(bits1, leftShift);
421 }
422 --dst;
423 WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & endmask));
424 mask = FbPrev24Pix(mask);
425 }
426 while (n--) {
427 bits = FbScrRight(bits1, rightShift);
428 bits1 = READ(--src);
429 bits |= FbScrLeft(bits1, leftShift);
430 --dst;
431 WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask));
432 mask = FbPrev24Pix(mask);
433 }
434 if (startmask) {
435 bits = FbScrRight(bits1, rightShift);
436 if (FbScrRight(startmask, leftShift)) {
437 bits1 = READ(--src);
438 bits |= FbScrLeft(bits1, leftShift);
439 }
440 --dst;
441 WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & startmask));
442 }
443 }
444 else {
445 if (srcX > dstX)
446 bits1 = READ(src++);
447 if (startmask) {
448 bits = FbScrLeft(bits1, leftShift);
449 bits1 = READ(src++);
450 bits |= FbScrRight(bits1, rightShift);
451 WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & startmask));
452 dst++;
453 mask = FbNext24Pix(mask);
454 }
455 while (n--) {
456 bits = FbScrLeft(bits1, leftShift);
457 bits1 = READ(src++);
458 bits |= FbScrRight(bits1, rightShift);
459 WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask));
460 dst++;
461 mask = FbNext24Pix(mask);
462 }
463 if (endmask) {
464 bits = FbScrLeft(bits1, leftShift);
465 if (FbScrLeft(endmask, rightShift)) {
466 bits1 = READ(src);
467 bits |= FbScrRight(bits1, rightShift);
468 }
469 WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & endmask));
470 }
471 }
472 }
473#ifdef DEBUG_BLT24
474 {
475 int firstx, lastx, x;
476
477 firstx = origX;
478 if (firstx)
479 firstx--;
480 lastx = origX + width / 24 + 1;
481 for (x = firstx; x <= lastx; x++)
482 ErrorF("%06x ", getPixel(origDst, x));
483 ErrorF("\n");
484 while (origNlw--)
485 ErrorF("%08x ", *origLine++);
486 ErrorF("\n");
487 }
488#endif
489}
490
491void
492fbBlt24(FbBits * srcLine,
493 FbStride srcStride,
494 int srcX,
495 FbBits * dstLine,
496 FbStride dstStride,
497 int dstX,
498 int width,
499 int height, int alu, FbBits pm, Bool reverse, Bool upsidedown)
500{
501 if (upsidedown) {
502 srcLine += (height - 1) * srcStride;
503 dstLine += (height - 1) * dstStride;
504 srcStride = -srcStride;
505 dstStride = -dstStride;
506 }
507 while (height--) {
508 fbBlt24Line(srcLine, srcX, dstLine, dstX, width, alu, pm, reverse);
509 srcLine += srcStride;
510 dstLine += dstStride;
511 }
512#ifdef DEBUG_BLT24
513 ErrorF("\n");
514#endif
515}
516
517#if FB_SHIFT == FB_STIP_SHIFT + 1
518
519/*
520 * Could be generalized to FB_SHIFT > FB_STIP_SHIFT + 1 by
521 * creating an ring of values stepped through for each line
522 */
523
524void
525fbBltOdd(FbBits * srcLine,
526 FbStride srcStrideEven,
527 FbStride srcStrideOdd,
528 int srcXEven,
529 int srcXOdd,
530 FbBits * dstLine,
531 FbStride dstStrideEven,
532 FbStride dstStrideOdd,
533 int dstXEven,
534 int dstXOdd, int width, int height, int alu, FbBits pm, int bpp)
535{
536 FbBits *src;
537 int leftShiftEven, rightShiftEven;
538 FbBits startmaskEven, endmaskEven;
539 int nmiddleEven;
540
541 FbBits *dst;
542 int leftShiftOdd, rightShiftOdd;
543 FbBits startmaskOdd, endmaskOdd;
544 int nmiddleOdd;
545
546 int leftShift, rightShift;
547 FbBits startmask, endmask;
548 int nmiddle;
549
550 int srcX, dstX;
551
552 FbBits bits, bits1;
553 int n;
554
555 Bool destInvarient;
556 Bool even;
557
558 FbDeclareMergeRop();
559
560 FbInitializeMergeRop(alu, pm);
561 destInvarient = FbDestInvarientMergeRop();
562
563 srcLine += srcXEven >> FB_SHIFT;
564 dstLine += dstXEven >> FB_SHIFT;
565 srcXEven &= FB_MASK;
566 dstXEven &= FB_MASK;
567 srcXOdd &= FB_MASK;
568 dstXOdd &= FB_MASK;
569
570 FbMaskBits(dstXEven, width, startmaskEven, nmiddleEven, endmaskEven);
571 FbMaskBits(dstXOdd, width, startmaskOdd, nmiddleOdd, endmaskOdd);
572
573 even = TRUE;
574 InitializeShifts(srcXEven, dstXEven, leftShiftEven, rightShiftEven);
575 InitializeShifts(srcXOdd, dstXOdd, leftShiftOdd, rightShiftOdd);
576 while (height--) {
577 src = srcLine;
578 dst = dstLine;
579 if (even) {
580 srcX = srcXEven;
581 dstX = dstXEven;
582 startmask = startmaskEven;
583 endmask = endmaskEven;
584 nmiddle = nmiddleEven;
585 leftShift = leftShiftEven;
586 rightShift = rightShiftEven;
587 srcLine += srcStrideEven;
588 dstLine += dstStrideEven;
589 even = FALSE;
590 }
591 else {
592 srcX = srcXOdd;
593 dstX = dstXOdd;
594 startmask = startmaskOdd;
595 endmask = endmaskOdd;
596 nmiddle = nmiddleOdd;
597 leftShift = leftShiftOdd;
598 rightShift = rightShiftOdd;
599 srcLine += srcStrideOdd;
600 dstLine += dstStrideOdd;
601 even = TRUE;
602 }
603 if (srcX == dstX) {
604 if (startmask) {
605 bits = READ(src++);
606 WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), startmask));
607 dst++;
608 }
609 n = nmiddle;
610 if (destInvarient) {
611 while (n--) {
612 bits = READ(src++);
613 WRITE(dst, FbDoDestInvarientMergeRop(bits));
614 dst++;
615 }
616 }
617 else {
618 while (n--) {
619 bits = READ(src++);
620 WRITE(dst, FbDoMergeRop(bits, READ(dst)));
621 dst++;
622 }
623 }
624 if (endmask) {
625 bits = READ(src);
626 WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), endmask));
627 }
628 }
629 else {
630 bits = 0;
631 if (srcX > dstX)
632 bits = READ(src++);
633 if (startmask) {
634 bits1 = FbScrLeft(bits, leftShift);
635 bits = READ(src++);
636 bits1 |= FbScrRight(bits, rightShift);
637 WRITE(dst, FbDoMaskMergeRop(bits1, READ(dst), startmask));
638 dst++;
639 }
640 n = nmiddle;
641 if (destInvarient) {
642 while (n--) {
643 bits1 = FbScrLeft(bits, leftShift);
644 bits = READ(src++);
645 bits1 |= FbScrRight(bits, rightShift);
646 WRITE(dst, FbDoDestInvarientMergeRop(bits1));
647 dst++;
648 }
649 }
650 else {
651 while (n--) {
652 bits1 = FbScrLeft(bits, leftShift);
653 bits = READ(src++);
654 bits1 |= FbScrRight(bits, rightShift);
655 WRITE(dst, FbDoMergeRop(bits1, READ(dst)));
656 dst++;
657 }
658 }
659 if (endmask) {
660 bits1 = FbScrLeft(bits, leftShift);
661 if (FbScrLeft(endmask, rightShift)) {
662 bits = READ(src);
663 bits1 |= FbScrRight(bits, rightShift);
664 }
665 WRITE(dst, FbDoMaskMergeRop(bits1, READ(dst), endmask));
666 }
667 }
668 }
669}
670
671void
672fbBltOdd24(FbBits * srcLine,
673 FbStride srcStrideEven,
674 FbStride srcStrideOdd,
675 int srcXEven,
676 int srcXOdd,
677 FbBits * dstLine,
678 FbStride dstStrideEven,
679 FbStride dstStrideOdd,
680 int dstXEven, int dstXOdd, int width, int height, int alu, FbBits pm)
681{
682 Bool even = TRUE;
683
684 while (height--) {
685 if (even) {
686 fbBlt24Line(srcLine, srcXEven, dstLine, dstXEven,
687 width, alu, pm, FALSE);
688 srcLine += srcStrideEven;
689 dstLine += dstStrideEven;
690 even = FALSE;
691 }
692 else {
693 fbBlt24Line(srcLine, srcXOdd, dstLine, dstXOdd,
694 width, alu, pm, FALSE);
695 srcLine += srcStrideOdd;
696 dstLine += dstStrideOdd;
697 even = TRUE;
698 }
699 }
700}
701
702#endif
703
704#if FB_STIP_SHIFT != FB_SHIFT
705void
706fbSetBltOdd(FbStip * stip,
707 FbStride stipStride,
708 int srcX,
709 FbBits ** bits,
710 FbStride * strideEven,
711 FbStride * strideOdd, int *srcXEven, int *srcXOdd)
712{
713 int srcAdjust;
714 int strideAdjust;
715
716 /*
717 * bytes needed to align source
718 */
719 srcAdjust = (((int) stip) & (FB_MASK >> 3));
720 /*
721 * FbStip units needed to align stride
722 */
723 strideAdjust = stipStride & (FB_MASK >> FB_STIP_SHIFT);
724
725 *bits = (FbBits *) ((char *) stip - srcAdjust);
726 if (srcAdjust) {
727 *strideEven = FbStipStrideToBitsStride(stipStride + 1);
728 *strideOdd = FbStipStrideToBitsStride(stipStride);
729
730 *srcXEven = srcX + (srcAdjust << 3);
731 *srcXOdd = srcX + (srcAdjust << 3) - (strideAdjust << FB_STIP_SHIFT);
732 }
733 else {
734 *strideEven = FbStipStrideToBitsStride(stipStride);
735 *strideOdd = FbStipStrideToBitsStride(stipStride + 1);
736
737 *srcXEven = srcX;
738 *srcXOdd = srcX + (strideAdjust << FB_STIP_SHIFT);
739 }
740}
741#endif
742
743void
744fbBltStip(FbStip * src, FbStride srcStride, /* in FbStip units, not FbBits units */
745 int srcX, FbStip * dst, FbStride dstStride, /* in FbStip units, not FbBits units */
746 int dstX, int width, int height, int alu, FbBits pm, int bpp)
747{
748#if FB_STIP_SHIFT != FB_SHIFT
749 if (FB_STIP_ODDSTRIDE(srcStride) || FB_STIP_ODDPTR(src) ||
750 FB_STIP_ODDSTRIDE(dstStride) || FB_STIP_ODDPTR(dst)) {
751 FbStride srcStrideEven, srcStrideOdd;
752 FbStride dstStrideEven, dstStrideOdd;
753 int srcXEven, srcXOdd;
754 int dstXEven, dstXOdd;
755 FbBits *s, *d;
756 int sx, dx;
757
758 src += srcX >> FB_STIP_SHIFT;
759 srcX &= FB_STIP_MASK;
760 dst += dstX >> FB_STIP_SHIFT;
761 dstX &= FB_STIP_MASK;
762
763 fbSetBltOdd(src, srcStride, srcX,
764 &s, &srcStrideEven, &srcStrideOdd, &srcXEven, &srcXOdd);
765
766 fbSetBltOdd(dst, dstStride, dstX,
767 &d, &dstStrideEven, &dstStrideOdd, &dstXEven, &dstXOdd);
768
769 if (bpp == 24 && !FbCheck24Pix(pm)) {
770 fbBltOdd24(s, srcStrideEven, srcStrideOdd,
771 srcXEven, srcXOdd,
772 d, dstStrideEven, dstStrideOdd,
773 dstXEven, dstXOdd, width, height, alu, pm);
774 }
775 else {
776 fbBltOdd(s, srcStrideEven, srcStrideOdd,
777 srcXEven, srcXOdd,
778 d, dstStrideEven, dstStrideOdd,
779 dstXEven, dstXOdd, width, height, alu, pm, bpp);
780 }
781 }
782 else
783#endif
784 {
785 fbBlt((FbBits *) src, FbStipStrideToBitsStride(srcStride),
786 srcX,
787 (FbBits *) dst, FbStipStrideToBitsStride(dstStride),
788 dstX, width, height, alu, pm, bpp, FALSE, FALSE);
789 }
790}