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 47 FbBits *dstLine, 48 FbStride dstStride, 49 int dstX, 50 51 int width, 52 int height, 53 54 int alu, 55 FbBits pm, 56 int bpp, 57 58 Bool reverse, 59 Bool upsidedown) 60{ 61 FbBits *src, *dst; 62 int leftShift, rightShift; 63 FbBits startmask, endmask; 64 FbBits bits, bits1; 65 int n, nmiddle; 66 Bool destInvarient; 67 int startbyte, endbyte; 68 int careful; 69 FbDeclareMergeRop (); 70 71#ifdef FB_24BIT 72 if (bpp == 24 && !FbCheck24Pix (pm)) 73 { 74 fbBlt24 (srcLine, srcStride, srcX, dstLine, dstStride, dstX, 75 width, height, alu, pm, reverse, upsidedown); 76 return; 77 } 78#endif 79 80 careful = !((srcLine < dstLine && srcLine + width * (bpp>>3) > dstLine) || 81 (dstLine < srcLine && dstLine + width * (bpp>>3) > srcLine)) || 82 (bpp & 7); 83 84 if (alu == GXcopy && pm == FB_ALLONES && !careful && 85 !(srcX & 7) && !(dstX & 7) && !(width & 7)) { 86 int i; 87 CARD8 *src = (CARD8 *) srcLine; 88 CARD8 *dst = (CARD8 *) dstLine; 89 90 srcStride *= sizeof(FbBits); 91 dstStride *= sizeof(FbBits); 92 width >>= 3; 93 src += (srcX >> 3); 94 dst += (dstX >> 3); 95 96 if (!upsidedown) 97 for (i = 0; i < height; i++) 98 MEMCPY_WRAPPED(dst + i * dstStride, src + i * srcStride, width); 99 else 100 for (i = height - 1; i >= 0; i--) 101 MEMCPY_WRAPPED(dst + i * dstStride, src + i * srcStride, width); 102 103 return; 104 } 105 106 FbInitializeMergeRop(alu, pm); 107 destInvarient = FbDestInvarientMergeRop(); 108 if (upsidedown) 109 { 110 srcLine += (height - 1) * (srcStride); 111 dstLine += (height - 1) * (dstStride); 112 srcStride = -srcStride; 113 dstStride = -dstStride; 114 } 115 FbMaskBitsBytes (dstX, width, destInvarient, startmask, startbyte, 116 nmiddle, endmask, endbyte); 117 if (reverse) 118 { 119 srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1; 120 dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1; 121 srcX = (srcX + width - 1) & FB_MASK; 122 dstX = (dstX + width - 1) & FB_MASK; 123 } 124 else 125 { 126 srcLine += srcX >> FB_SHIFT; 127 dstLine += dstX >> FB_SHIFT; 128 srcX &= FB_MASK; 129 dstX &= FB_MASK; 130 } 131 if (srcX == dstX) 132 { 133 while (height--) 134 { 135 src = srcLine; 136 srcLine += srcStride; 137 dst = dstLine; 138 dstLine += dstStride; 139 if (reverse) 140 { 141 if (endmask) 142 { 143 bits = READ(--src); 144 --dst; 145 FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); 146 } 147 n = nmiddle; 148 if (destInvarient) 149 { 150 while (n--) 151 WRITE(--dst, FbDoDestInvarientMergeRop(READ(--src))); 152 } 153 else 154 { 155 while (n--) 156 { 157 bits = READ(--src); 158 --dst; 159 WRITE(dst, FbDoMergeRop (bits, READ(dst))); 160 } 161 } 162 if (startmask) 163 { 164 bits = READ(--src); 165 --dst; 166 FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask); 167 } 168 } 169 else 170 { 171 if (startmask) 172 { 173 bits = READ(src++); 174 FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask); 175 dst++; 176 } 177 n = nmiddle; 178 if (destInvarient) 179 { 180#if 0 181 /* 182 * This provides some speedup on screen->screen blts 183 * over the PCI bus, usually about 10%. But fb 184 * isn't usually used for this operation... 185 */ 186 if (_ca2 + 1 == 0 && _cx2 == 0) 187 { 188 FbBits t1, t2, t3, t4; 189 while (n >= 4) 190 { 191 t1 = *src++; 192 t2 = *src++; 193 t3 = *src++; 194 t4 = *src++; 195 *dst++ = t1; 196 *dst++ = t2; 197 *dst++ = t3; 198 *dst++ = t4; 199 n -= 4; 200 } 201 } 202#endif 203 while (n--) 204 WRITE(dst++, FbDoDestInvarientMergeRop(READ(src++))); 205 } 206 else 207 { 208 while (n--) 209 { 210 bits = READ(src++); 211 WRITE(dst, FbDoMergeRop (bits, READ(dst))); 212 dst++; 213 } 214 } 215 if (endmask) 216 { 217 bits = READ(src); 218 FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); 219 } 220 } 221 } 222 } 223 else 224 { 225 if (srcX > dstX) 226 { 227 leftShift = srcX - dstX; 228 rightShift = FB_UNIT - leftShift; 229 } 230 else 231 { 232 rightShift = dstX - srcX; 233 leftShift = FB_UNIT - rightShift; 234 } 235 while (height--) 236 { 237 src = srcLine; 238 srcLine += srcStride; 239 dst = dstLine; 240 dstLine += dstStride; 241 242 bits1 = 0; 243 if (reverse) 244 { 245 if (srcX < dstX) 246 bits1 = READ(--src); 247 if (endmask) 248 { 249 bits = FbScrRight(bits1, rightShift); 250 if (FbScrRight(endmask, leftShift)) 251 { 252 bits1 = READ(--src); 253 bits |= FbScrLeft(bits1, leftShift); 254 } 255 --dst; 256 FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); 257 } 258 n = nmiddle; 259 if (destInvarient) 260 { 261 while (n--) 262 { 263 bits = FbScrRight(bits1, rightShift); 264 bits1 = READ(--src); 265 bits |= FbScrLeft(bits1, leftShift); 266 --dst; 267 WRITE(dst, FbDoDestInvarientMergeRop(bits)); 268 } 269 } 270 else 271 { 272 while (n--) 273 { 274 bits = FbScrRight(bits1, rightShift); 275 bits1 = READ(--src); 276 bits |= FbScrLeft(bits1, leftShift); 277 --dst; 278 WRITE(dst, FbDoMergeRop(bits, READ(dst))); 279 } 280 } 281 if (startmask) 282 { 283 bits = FbScrRight(bits1, rightShift); 284 if (FbScrRight(startmask, leftShift)) 285 { 286 bits1 = READ(--src); 287 bits |= FbScrLeft(bits1, leftShift); 288 } 289 --dst; 290 FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask); 291 } 292 } 293 else 294 { 295 if (srcX > dstX) 296 bits1 = READ(src++); 297 if (startmask) 298 { 299 bits = FbScrLeft(bits1, leftShift); 300 if (FbScrLeft(startmask, rightShift)) 301 { 302 bits1 = READ(src++); 303 bits |= FbScrRight(bits1, rightShift); 304 } 305 FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask); 306 dst++; 307 } 308 n = nmiddle; 309 if (destInvarient) 310 { 311 while (n--) 312 { 313 bits = FbScrLeft(bits1, leftShift); 314 bits1 = READ(src++); 315 bits |= FbScrRight(bits1, rightShift); 316 WRITE(dst, FbDoDestInvarientMergeRop(bits)); 317 dst++; 318 } 319 } 320 else 321 { 322 while (n--) 323 { 324 bits = FbScrLeft(bits1, leftShift); 325 bits1 = READ(src++); 326 bits |= FbScrRight(bits1, rightShift); 327 WRITE(dst, FbDoMergeRop(bits, READ(dst))); 328 dst++; 329 } 330 } 331 if (endmask) 332 { 333 bits = FbScrLeft(bits1, leftShift); 334 if (FbScrLeft(endmask, rightShift)) 335 { 336 bits1 = READ(src); 337 bits |= FbScrRight(bits1, rightShift); 338 } 339 FbDoRightMaskByteMergeRop (dst, bits, endbyte, endmask); 340 } 341 } 342 } 343 } 344} 345 346#ifdef FB_24BIT 347 348#undef DEBUG_BLT24 349#ifdef DEBUG_BLT24 350 351static unsigned long 352getPixel (char *src, int x) 353{ 354 unsigned long l; 355 356 l = 0; 357 memcpy (&l, src + x * 3, 3); 358 return l; 359} 360#endif 361 362static void 363fbBlt24Line (FbBits *src, 364 int srcX, 365 366 FbBits *dst, 367 int dstX, 368 369 int width, 370 371 int alu, 372 FbBits pm, 373 374 Bool reverse) 375{ 376#ifdef DEBUG_BLT24 377 char *origDst = (char *) dst; 378 FbBits *origLine = dst + ((dstX >> FB_SHIFT) - 1); 379 int origNlw = ((width + FB_MASK) >> FB_SHIFT) + 3; 380 int origX = dstX / 24; 381#endif 382 383 int leftShift, rightShift; 384 FbBits startmask, endmask; 385 int n; 386 387 FbBits bits, bits1; 388 FbBits mask; 389 390 int rot; 391 FbDeclareMergeRop (); 392 393 FbInitializeMergeRop (alu, FB_ALLONES); 394 FbMaskBits(dstX, width, startmask, n, endmask); 395#ifdef DEBUG_BLT24 396 ErrorF ("dstX %d width %d reverse %d\n", dstX, width, reverse); 397#endif 398 if (reverse) 399 { 400 src += ((srcX + width - 1) >> FB_SHIFT) + 1; 401 dst += ((dstX + width - 1) >> FB_SHIFT) + 1; 402 rot = FbFirst24Rot (((dstX + width - 8) & FB_MASK)); 403 rot = FbPrev24Rot(rot); 404#ifdef DEBUG_BLT24 405 ErrorF ("dstX + width - 8: %d rot: %d\n", (dstX + width - 8) & FB_MASK, rot); 406#endif 407 srcX = (srcX + width - 1) & FB_MASK; 408 dstX = (dstX + width - 1) & FB_MASK; 409 } 410 else 411 { 412 src += srcX >> FB_SHIFT; 413 dst += dstX >> FB_SHIFT; 414 srcX &= FB_MASK; 415 dstX &= FB_MASK; 416 rot = FbFirst24Rot (dstX); 417#ifdef DEBUG_BLT24 418 ErrorF ("dstX: %d rot: %d\n", dstX, rot); 419#endif 420 } 421 mask = FbRot24(pm,rot); 422#ifdef DEBUG_BLT24 423 ErrorF ("pm 0x%x mask 0x%x\n", pm, mask); 424#endif 425 if (srcX == dstX) 426 { 427 if (reverse) 428 { 429 if (endmask) 430 { 431 bits = READ(--src); 432 --dst; 433 WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & endmask)); 434 mask = FbPrev24Pix (mask); 435 } 436 while (n--) 437 { 438 bits = READ(--src); 439 --dst; 440 WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask)); 441 mask = FbPrev24Pix (mask); 442 } 443 if (startmask) 444 { 445 bits = READ(--src); 446 --dst; 447 WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & startmask)); 448 } 449 } 450 else 451 { 452 if (startmask) 453 { 454 bits = READ(src++); 455 WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & startmask)); 456 dst++; 457 mask = FbNext24Pix(mask); 458 } 459 while (n--) 460 { 461 bits = READ(src++); 462 WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask)); 463 dst++; 464 mask = FbNext24Pix(mask); 465 } 466 if (endmask) 467 { 468 bits = READ(src); 469 WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & endmask)); 470 } 471 } 472 } 473 else 474 { 475 if (srcX > dstX) 476 { 477 leftShift = srcX - dstX; 478 rightShift = FB_UNIT - leftShift; 479 } 480 else 481 { 482 rightShift = dstX - srcX; 483 leftShift = FB_UNIT - rightShift; 484 } 485 486 bits1 = 0; 487 if (reverse) 488 { 489 if (srcX < dstX) 490 bits1 = READ(--src); 491 if (endmask) 492 { 493 bits = FbScrRight(bits1, rightShift); 494 if (FbScrRight(endmask, leftShift)) 495 { 496 bits1 = READ(--src); 497 bits |= FbScrLeft(bits1, leftShift); 498 } 499 --dst; 500 WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & endmask)); 501 mask = FbPrev24Pix(mask); 502 } 503 while (n--) 504 { 505 bits = FbScrRight(bits1, rightShift); 506 bits1 = READ(--src); 507 bits |= FbScrLeft(bits1, leftShift); 508 --dst; 509 WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask)); 510 mask = FbPrev24Pix(mask); 511 } 512 if (startmask) 513 { 514 bits = FbScrRight(bits1, rightShift); 515 if (FbScrRight(startmask, leftShift)) 516 { 517 bits1 = READ(--src); 518 bits |= FbScrLeft(bits1, leftShift); 519 } 520 --dst; 521 WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & startmask)); 522 } 523 } 524 else 525 { 526 if (srcX > dstX) 527 bits1 = READ(src++); 528 if (startmask) 529 { 530 bits = FbScrLeft(bits1, leftShift); 531 bits1 = READ(src++); 532 bits |= FbScrRight(bits1, rightShift); 533 WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & startmask)); 534 dst++; 535 mask = FbNext24Pix(mask); 536 } 537 while (n--) 538 { 539 bits = FbScrLeft(bits1, leftShift); 540 bits1 = READ(src++); 541 bits |= FbScrRight(bits1, rightShift); 542 WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask)); 543 dst++; 544 mask = FbNext24Pix(mask); 545 } 546 if (endmask) 547 { 548 bits = FbScrLeft(bits1, leftShift); 549 if (FbScrLeft(endmask, rightShift)) 550 { 551 bits1 = READ(src); 552 bits |= FbScrRight(bits1, rightShift); 553 } 554 WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & endmask)); 555 } 556 } 557 } 558#ifdef DEBUG_BLT24 559 { 560 int firstx, lastx, x; 561 562 firstx = origX; 563 if (firstx) 564 firstx--; 565 lastx = origX + width/24 + 1; 566 for (x = firstx; x <= lastx; x++) 567 ErrorF ("%06x ", getPixel (origDst, x)); 568 ErrorF ("\n"); 569 while (origNlw--) 570 ErrorF ("%08x ", *origLine++); 571 ErrorF ("\n"); 572 } 573#endif 574} 575 576void 577fbBlt24 (FbBits *srcLine, 578 FbStride srcStride, 579 int srcX, 580 581 FbBits *dstLine, 582 FbStride dstStride, 583 int dstX, 584 585 int width, 586 int height, 587 588 int alu, 589 FbBits pm, 590 591 Bool reverse, 592 Bool upsidedown) 593{ 594 if (upsidedown) 595 { 596 srcLine += (height-1) * srcStride; 597 dstLine += (height-1) * dstStride; 598 srcStride = -srcStride; 599 dstStride = -dstStride; 600 } 601 while (height--) 602 { 603 fbBlt24Line (srcLine, srcX, dstLine, dstX, width, alu, pm, reverse); 604 srcLine += srcStride; 605 dstLine += dstStride; 606 } 607#ifdef DEBUG_BLT24 608 ErrorF ("\n"); 609#endif 610} 611#endif /* FB_24BIT */ 612 613#if FB_SHIFT == FB_STIP_SHIFT + 1 614 615/* 616 * Could be generalized to FB_SHIFT > FB_STIP_SHIFT + 1 by 617 * creating an ring of values stepped through for each line 618 */ 619 620void 621fbBltOdd (FbBits *srcLine, 622 FbStride srcStrideEven, 623 FbStride srcStrideOdd, 624 int srcXEven, 625 int srcXOdd, 626 627 FbBits *dstLine, 628 FbStride dstStrideEven, 629 FbStride dstStrideOdd, 630 int dstXEven, 631 int dstXOdd, 632 633 int width, 634 int height, 635 636 int alu, 637 FbBits pm, 638 int bpp) 639{ 640 FbBits *src; 641 int leftShiftEven, rightShiftEven; 642 FbBits startmaskEven, endmaskEven; 643 int nmiddleEven; 644 645 FbBits *dst; 646 int leftShiftOdd, rightShiftOdd; 647 FbBits startmaskOdd, endmaskOdd; 648 int nmiddleOdd; 649 650 int leftShift, rightShift; 651 FbBits startmask, endmask; 652 int nmiddle; 653 654 int srcX, dstX; 655 656 FbBits bits, bits1; 657 int n; 658 659 Bool destInvarient; 660 Bool even; 661 FbDeclareMergeRop (); 662 663 FbInitializeMergeRop (alu, pm); 664 destInvarient = FbDestInvarientMergeRop(); 665 666 srcLine += srcXEven >> FB_SHIFT; 667 dstLine += dstXEven >> FB_SHIFT; 668 srcXEven &= FB_MASK; 669 dstXEven &= FB_MASK; 670 srcXOdd &= FB_MASK; 671 dstXOdd &= FB_MASK; 672 673 FbMaskBits(dstXEven, width, startmaskEven, nmiddleEven, endmaskEven); 674 FbMaskBits(dstXOdd, width, startmaskOdd, nmiddleOdd, endmaskOdd); 675 676 even = TRUE; 677 InitializeShifts(srcXEven, dstXEven, leftShiftEven, rightShiftEven); 678 InitializeShifts(srcXOdd, dstXOdd, leftShiftOdd, rightShiftOdd); 679 while (height--) 680 { 681 src = srcLine; 682 dst = dstLine; 683 if (even) 684 { 685 srcX = srcXEven; 686 dstX = dstXEven; 687 startmask = startmaskEven; 688 endmask = endmaskEven; 689 nmiddle = nmiddleEven; 690 leftShift = leftShiftEven; 691 rightShift = rightShiftEven; 692 srcLine += srcStrideEven; 693 dstLine += dstStrideEven; 694 even = FALSE; 695 } 696 else 697 { 698 srcX = srcXOdd; 699 dstX = dstXOdd; 700 startmask = startmaskOdd; 701 endmask = endmaskOdd; 702 nmiddle = nmiddleOdd; 703 leftShift = leftShiftOdd; 704 rightShift = rightShiftOdd; 705 srcLine += srcStrideOdd; 706 dstLine += dstStrideOdd; 707 even = TRUE; 708 } 709 if (srcX == dstX) 710 { 711 if (startmask) 712 { 713 bits = READ(src++); 714 WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), startmask)); 715 dst++; 716 } 717 n = nmiddle; 718 if (destInvarient) 719 { 720 while (n--) 721 { 722 bits = READ(src++); 723 WRITE(dst, FbDoDestInvarientMergeRop(bits)); 724 dst++; 725 } 726 } 727 else 728 { 729 while (n--) 730 { 731 bits = READ(src++); 732 WRITE(dst, FbDoMergeRop (bits, READ(dst))); 733 dst++; 734 } 735 } 736 if (endmask) 737 { 738 bits = READ(src); 739 WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), endmask)); 740 } 741 } 742 else 743 { 744 bits = 0; 745 if (srcX > dstX) 746 bits = READ(src++); 747 if (startmask) 748 { 749 bits1 = FbScrLeft(bits, leftShift); 750 bits = READ(src++); 751 bits1 |= FbScrRight(bits, rightShift); 752 WRITE(dst, FbDoMaskMergeRop (bits1, READ(dst), startmask)); 753 dst++; 754 } 755 n = nmiddle; 756 if (destInvarient) 757 { 758 while (n--) 759 { 760 bits1 = FbScrLeft(bits, leftShift); 761 bits = READ(src++); 762 bits1 |= FbScrRight(bits, rightShift); 763 WRITE(dst, FbDoDestInvarientMergeRop(bits1)); 764 dst++; 765 } 766 } 767 else 768 { 769 while (n--) 770 { 771 bits1 = FbScrLeft(bits, leftShift); 772 bits = READ(src++); 773 bits1 |= FbScrRight(bits, rightShift); 774 WRITE(dst, FbDoMergeRop(bits1, READ(dst))); 775 dst++; 776 } 777 } 778 if (endmask) 779 { 780 bits1 = FbScrLeft(bits, leftShift); 781 if (FbScrLeft(endmask, rightShift)) 782 { 783 bits = READ(src); 784 bits1 |= FbScrRight(bits, rightShift); 785 } 786 WRITE(dst, FbDoMaskMergeRop (bits1, READ(dst), endmask)); 787 } 788 } 789 } 790} 791 792#ifdef FB_24BIT 793void 794fbBltOdd24 (FbBits *srcLine, 795 FbStride srcStrideEven, 796 FbStride srcStrideOdd, 797 int srcXEven, 798 int srcXOdd, 799 800 FbBits *dstLine, 801 FbStride dstStrideEven, 802 FbStride dstStrideOdd, 803 int dstXEven, 804 int dstXOdd, 805 806 int width, 807 int height, 808 809 int alu, 810 FbBits pm) 811{ 812 Bool even = TRUE; 813 814 while (height--) 815 { 816 if (even) 817 { 818 fbBlt24Line (srcLine, srcXEven, dstLine, dstXEven, 819 width, alu, pm, FALSE); 820 srcLine += srcStrideEven; 821 dstLine += dstStrideEven; 822 even = FALSE; 823 } 824 else 825 { 826 fbBlt24Line (srcLine, srcXOdd, dstLine, dstXOdd, 827 width, alu, pm, FALSE); 828 srcLine += srcStrideOdd; 829 dstLine += dstStrideOdd; 830 even = TRUE; 831 } 832 } 833} 834#endif 835 836#endif 837 838#if FB_STIP_SHIFT != FB_SHIFT 839void 840fbSetBltOdd (FbStip *stip, 841 FbStride stipStride, 842 int srcX, 843 FbBits **bits, 844 FbStride *strideEven, 845 FbStride *strideOdd, 846 int *srcXEven, 847 int *srcXOdd) 848{ 849 int srcAdjust; 850 int strideAdjust; 851 852 /* 853 * bytes needed to align source 854 */ 855 srcAdjust = (((int) stip) & (FB_MASK >> 3)); 856 /* 857 * FbStip units needed to align stride 858 */ 859 strideAdjust = stipStride & (FB_MASK >> FB_STIP_SHIFT); 860 861 *bits = (FbBits *) ((char *) stip - srcAdjust); 862 if (srcAdjust) 863 { 864 *strideEven = FbStipStrideToBitsStride (stipStride + 1); 865 *strideOdd = FbStipStrideToBitsStride (stipStride); 866 867 *srcXEven = srcX + (srcAdjust << 3); 868 *srcXOdd = srcX + (srcAdjust << 3) - (strideAdjust << FB_STIP_SHIFT); 869 } 870 else 871 { 872 *strideEven = FbStipStrideToBitsStride (stipStride); 873 *strideOdd = FbStipStrideToBitsStride (stipStride + 1); 874 875 *srcXEven = srcX; 876 *srcXOdd = srcX + (strideAdjust << FB_STIP_SHIFT); 877 } 878} 879#endif 880 881void 882fbBltStip (FbStip *src, 883 FbStride srcStride, /* in FbStip units, not FbBits units */ 884 int srcX, 885 886 FbStip *dst, 887 FbStride dstStride, /* in FbStip units, not FbBits units */ 888 int dstX, 889 890 int width, 891 int height, 892 893 int alu, 894 FbBits pm, 895 int bpp) 896{ 897#if FB_STIP_SHIFT != FB_SHIFT 898 if (FB_STIP_ODDSTRIDE(srcStride) || FB_STIP_ODDPTR(src) || 899 FB_STIP_ODDSTRIDE(dstStride) || FB_STIP_ODDPTR(dst)) 900 { 901 FbStride srcStrideEven, srcStrideOdd; 902 FbStride dstStrideEven, dstStrideOdd; 903 int srcXEven, srcXOdd; 904 int dstXEven, dstXOdd; 905 FbBits *s, *d; 906 int sx, dx; 907 908 src += srcX >> FB_STIP_SHIFT; 909 srcX &= FB_STIP_MASK; 910 dst += dstX >> FB_STIP_SHIFT; 911 dstX &= FB_STIP_MASK; 912 913 fbSetBltOdd (src, srcStride, srcX, 914 &s, 915 &srcStrideEven, &srcStrideOdd, 916 &srcXEven, &srcXOdd); 917 918 fbSetBltOdd (dst, dstStride, dstX, 919 &d, 920 &dstStrideEven, &dstStrideOdd, 921 &dstXEven, &dstXOdd); 922 923#ifdef FB_24BIT 924 if (bpp == 24 && !FbCheck24Pix (pm)) 925 { 926 fbBltOdd24 (s, srcStrideEven, srcStrideOdd, 927 srcXEven, srcXOdd, 928 929 d, dstStrideEven, dstStrideOdd, 930 dstXEven, dstXOdd, 931 932 width, height, alu, pm); 933 } 934 else 935#endif 936 { 937 fbBltOdd (s, srcStrideEven, srcStrideOdd, 938 srcXEven, srcXOdd, 939 940 d, dstStrideEven, dstStrideOdd, 941 dstXEven, dstXOdd, 942 943 width, height, alu, pm, bpp); 944 } 945 } 946 else 947#endif 948 { 949 fbBlt ((FbBits *) src, FbStipStrideToBitsStride (srcStride), 950 srcX, 951 (FbBits *) dst, FbStipStrideToBitsStride (dstStride), 952 dstX, 953 width, height, 954 alu, pm, bpp, FALSE, FALSE); 955 } 956} 957