1 /* $NetBSD: raster_op.c,v 1.17 2009/03/18 17:06:50 cegger Exp $ */ 2 3 /*- 4 * Copyright (c) 1991, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to the Computer Systems 8 * Engineering Group at Lawrence Berkeley Laboratory and to the University 9 * of California at Berkeley by Jef Poskanzer. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * @(#)raster_op.c 8.1 (Berkeley) 6/11/93 36 */ 37 38 /* 39 * Bitblit routine for raster library. 40 * 41 * This raster-op is machined to exacting tolerances by skilled native 42 * craftsmen with pride in their work. 43 * 44 * The various cases are broken down like this: 45 * 46 * src required 47 * 1-bit to 1-bit 48 * 1-bit to 2-bits 49 * 1-bit to 4-bits 50 * 1-bit to 8-bits 51 * 1-bit to 16-bits 52 * 2-bits to 2-bits 53 * 2-bits to 4-bits (not implemented) 54 * 2-bits to 8-bits (not implemented) 55 * 2-bits to 16-bits (not implemented) 56 * 4-bits to 4-bits 57 * 4-bits to 8-bits (not implemented) 58 * 4-bits to 16-bits (not implemented) 59 * 8-bits to 8-bits 60 * 8-bits to 16-bits (not implemented) 61 * 16-bits to 16-bits 62 * no src required 63 * 1-bit no-src 64 * 2-bits no-src 65 * 8-bits no-src 66 * 16-bits no-src 67 */ 68 69 #include <sys/cdefs.h> 70 __KERNEL_RCSID(0, "$NetBSD: raster_op.c,v 1.17 2009/03/18 17:06:50 cegger Exp $"); 71 72 #include <sys/types.h> 73 #ifdef _KERNEL 74 #include "opt_rcons.h" 75 #include <dev/rcons/raster.h> 76 #else 77 #include "raster.h" 78 #endif 79 80 /* CONFIGURE: To save on executable size, you can configure out the seldom-used 81 ** logical operations. With this variable set, the only operations implemented 82 ** are: RAS_SRC, RAS_CLEAR, RAS_SET, RAS_INVERT, RAS_XOR, RAS_INVERTSRC. 83 */ 84 #ifdef _KERNEL 85 #define PARTIAL_LOGICAL_OPS 86 #endif 87 88 /* CONFIGURE: bcopy() is supposed to be the ultimately fastest way to move 89 ** bytes, overlapping or not, ignoring the startup cost. Unfortunately 90 ** this is not true on some systems. For example, on a Sun 3 running 91 ** SunOS 3.5, bcopy() is about five times slower than a simple for loop 92 ** on overlapping copies. And on a 4.1.1 SPARC, bcopy() is about 2/3rds 93 ** as fast on backwards overlaps. So, only define this if your bcopy is ok. 94 */ 95 #undef BCOPY_FASTER 96 97 /* End of configurable definitions. */ 98 99 100 /* Definitions. */ 101 102 /* Raster-op macros. These encapsulate the switch statements and so make 103 ** the source code 16 times smaller. The pre and pst args are code 104 ** fragments to put before and after the assignment in each case. They 105 ** can be the beginning and end of a loop. If the pst fragment includes a 106 ** masked assignment, for example to handle the left or right edge cases, 107 ** a good optimizing compiler will simplify the boolean expressions very 108 ** nicely - both cc and gcc on the SPARC will do this. 109 */ 110 111 #ifndef PARTIAL_LOGICAL_OPS 112 113 #define ROP_DST(op,pre,d,pst) \ 114 switch ( op ) \ 115 { \ 116 case RAS_CLEAR: \ 117 pre \ 118 (d) = 0; \ 119 pst \ 120 break; \ 121 case RAS_INVERT: \ 122 pre \ 123 (d) = ~(d); \ 124 pst \ 125 break; \ 126 case RAS_DST: \ 127 /* noop */ \ 128 break; \ 129 case RAS_SET: \ 130 pre \ 131 (d) = ~0; \ 132 pst \ 133 break; \ 134 default: \ 135 return -1; \ 136 } 137 138 #define ROP_DSTCOLOR(op,pre,d,c,pst) \ 139 switch ( op ) \ 140 { \ 141 case RAS_CLEAR: \ 142 pre \ 143 (d) = 0; \ 144 pst \ 145 break; \ 146 case RAS_INVERT: \ 147 pre \ 148 (d) = ~(d); \ 149 pst \ 150 break; \ 151 case RAS_DST: \ 152 /* noop */ \ 153 break; \ 154 case RAS_SET: \ 155 pre \ 156 (d) = (c); \ 157 pst \ 158 break; \ 159 default: \ 160 return -1; \ 161 } 162 163 #define ROP_SRCDST(op,pre,s,d,pst) \ 164 switch ( op ) \ 165 { \ 166 case RAS_NOTOR: \ 167 pre \ 168 (d) = ~( (s) | (d) ); \ 169 pst \ 170 break; \ 171 case RAS_NOTSRC_AND_DST: \ 172 pre \ 173 (d) = ~(s) & (d); \ 174 pst \ 175 break; \ 176 case RAS_INVERTSRC: \ 177 pre \ 178 (d) = ~(s); \ 179 pst \ 180 break; \ 181 case RAS_SRC_AND_NOTDST: \ 182 pre \ 183 (d) = (s) & ~(d); \ 184 pst \ 185 break; \ 186 case RAS_XOR: \ 187 pre \ 188 (d) = (s) ^ (d); \ 189 pst \ 190 break; \ 191 case RAS_NOTAND: \ 192 pre \ 193 (d) = ~( (s) & (d) ); \ 194 pst \ 195 break; \ 196 case RAS_AND: \ 197 pre \ 198 (d) = (s) & (d); \ 199 pst \ 200 break; \ 201 case RAS_NOTXOR: \ 202 pre \ 203 (d) = ~( (s) ^ (d) ); \ 204 pst \ 205 break; \ 206 case RAS_NOTSRC_OR_DST: \ 207 pre \ 208 (d) = ~(s) | (d); \ 209 pst \ 210 break; \ 211 case RAS_SRC: \ 212 pre \ 213 (d) = (s); \ 214 pst \ 215 break; \ 216 case RAS_SRC_OR_NOTDST: \ 217 pre \ 218 (d) = (s) | ~(d); \ 219 pst \ 220 break; \ 221 case RAS_OR: \ 222 pre \ 223 (d) = (s) | (d); \ 224 pst \ 225 break; \ 226 default: \ 227 return -1; \ 228 } 229 230 #define ROP_SRCDSTCOLOR(op,pre,s,d,c,pst) \ 231 switch ( op ) \ 232 { \ 233 case RAS_NOTOR: \ 234 pre \ 235 if ( s ) \ 236 (d) = ~( (c) | (d) ); \ 237 else \ 238 (d) = ~(d); \ 239 pst \ 240 break; \ 241 case RAS_NOTSRC_AND_DST: \ 242 pre \ 243 if ( s ) \ 244 (d) = ~(c) & (d); \ 245 pst \ 246 break; \ 247 case RAS_INVERTSRC: \ 248 pre \ 249 if ( s ) \ 250 (d) = ~(c); \ 251 else \ 252 (d) = ~0; \ 253 pst \ 254 break; \ 255 case RAS_SRC_AND_NOTDST: \ 256 pre \ 257 if ( s ) \ 258 (d) = (c) & ~(d); \ 259 else \ 260 (d) = 0; \ 261 pst \ 262 break; \ 263 case RAS_XOR: \ 264 pre \ 265 if ( s ) \ 266 (d) = (c) ^ (d); \ 267 pst \ 268 break; \ 269 case RAS_NOTAND: \ 270 pre \ 271 if ( s ) \ 272 (d) = ~( (c) & (d) ); \ 273 else \ 274 (d) = ~0; \ 275 pst \ 276 break; \ 277 case RAS_AND: \ 278 pre \ 279 if ( s ) \ 280 (d) = (c) & (d); \ 281 else \ 282 (d) = 0; \ 283 pst \ 284 break; \ 285 case RAS_NOTXOR: \ 286 pre \ 287 if ( s ) \ 288 (d) = ~( (c) ^ (d) ); \ 289 else \ 290 (d) = ~(d); \ 291 pst \ 292 break; \ 293 case RAS_NOTSRC_OR_DST: \ 294 pre \ 295 if ( s ) \ 296 (d) = ~(c) | (d); \ 297 else \ 298 (d) = ~0; \ 299 pst \ 300 break; \ 301 case RAS_SRC: \ 302 pre \ 303 if ( s ) \ 304 (d) = (c); \ 305 else \ 306 (d) = 0; \ 307 pst \ 308 break; \ 309 case RAS_SRC_OR_NOTDST: \ 310 pre \ 311 if ( s ) \ 312 (d) = (c) | ~(d); \ 313 else \ 314 (d) = ~(d); \ 315 pst \ 316 break; \ 317 case RAS_OR: \ 318 pre \ 319 if ( s ) \ 320 (d) = (c) | (d); \ 321 pst \ 322 break; \ 323 default: \ 324 return -1; \ 325 } 326 327 #else /*PARTIAL_LOGICAL_OPS*/ 328 329 #define ROP_DST(op,pre,d,pst) \ 330 switch ( op ) \ 331 { \ 332 case RAS_CLEAR: \ 333 pre \ 334 (d) = 0; \ 335 pst \ 336 break; \ 337 case RAS_INVERT: \ 338 pre \ 339 (d) = ~(d); \ 340 pst \ 341 break; \ 342 case RAS_SET: \ 343 pre \ 344 (d) = ~0; \ 345 pst \ 346 break; \ 347 default: \ 348 return -1; \ 349 } 350 351 #define ROP_DSTCOLOR(op,pre,d,c,pst) \ 352 switch ( op ) \ 353 { \ 354 case RAS_CLEAR: \ 355 pre \ 356 (d) = 0; \ 357 pst \ 358 break; \ 359 case RAS_INVERT: \ 360 pre \ 361 (d) = ~(d); \ 362 pst \ 363 break; \ 364 case RAS_SET: \ 365 pre \ 366 (d) = (c); \ 367 pst \ 368 break; \ 369 default: \ 370 return -1; \ 371 } 372 373 #define ROP_SRCDST(op,pre,s,d,pst) \ 374 switch ( op ) \ 375 { \ 376 case RAS_INVERTSRC: \ 377 pre \ 378 (d) = ~(s); \ 379 pst \ 380 break; \ 381 case RAS_XOR: \ 382 pre \ 383 (d) = (s) ^ (d); \ 384 pst \ 385 break; \ 386 case RAS_SRC: \ 387 pre \ 388 (d) = (s); \ 389 pst \ 390 break; \ 391 default: \ 392 return -1; \ 393 } 394 395 #define ROP_SRCDSTCOLOR(op,pre,s,d,c,pst) \ 396 switch ( op ) \ 397 { \ 398 case RAS_INVERTSRC: \ 399 pre \ 400 if ( s ) \ 401 (d) = ~(c); \ 402 else \ 403 (d) = ~0; \ 404 pst \ 405 break; \ 406 case RAS_XOR: \ 407 pre \ 408 if ( s ) \ 409 (d) = (c) ^ (d); \ 410 pst \ 411 break; \ 412 case RAS_SRC: \ 413 pre \ 414 if ( s ) \ 415 (d) = (c); \ 416 else \ 417 (d) = 0; \ 418 pst \ 419 break; \ 420 default: \ 421 return -1; \ 422 } 423 424 #endif /*PARTIAL_LOGICAL_OPS*/ 425 426 427 /* Variables. */ 428 429 static int needsrc[16] = { 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0 }; 430 /* CLEAR INVERT DST SET */ 431 432 #ifdef MSBIT_FIRST 433 434 u_int32_t raster_bitmask[32] = { 435 0x80000000, 0x40000000, 0x20000000, 0x10000000, 436 0x08000000, 0x04000000, 0x02000000, 0x01000000, 437 0x00800000, 0x00400000, 0x00200000, 0x00100000, 438 0x00080000, 0x00040000, 0x00020000, 0x00010000, 439 0x00008000, 0x00004000, 0x00002000, 0x00001000, 440 0x00000800, 0x00000400, 0x00000200, 0x00000100, 441 0x00000080, 0x00000040, 0x00000020, 0x00000010, 442 0x00000008, 0x00000004, 0x00000002, 0x00000001 }; 443 444 #ifdef MSBYTE_FIRST 445 static u_int32_t leftmask[32] = { 446 0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 447 0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000, 448 0xff000000, 0xff800000, 0xffc00000, 0xffe00000, 449 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 450 0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000, 451 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00, 452 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 453 0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe }; 454 static u_int32_t rightmask[32] = { 455 0x00000000, 0x00000001, 0x00000003, 0x00000007, 456 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 457 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 458 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 459 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, 460 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 461 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, 462 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff }; 463 464 #define LSOP << 465 #define RSOP >> 466 #endif /*MSBYTE_FIRST*/ 467 468 #else /*MSBIT_FIRST*/ 469 470 u_int32_t raster_bitmask[32] = { 471 0x00000001, 0x00000002, 0x00000004, 0x00000008, 472 0x00000010, 0x00000020, 0x00000040, 0x00000080, 473 0x00000100, 0x00000200, 0x00000400, 0x00000800, 474 0x00001000, 0x00002000, 0x00004000, 0x00008000, 475 0x00010000, 0x00020000, 0x00040000, 0x00080000, 476 0x00100000, 0x00200000, 0x00400000, 0x00800000, 477 0x01000000, 0x02000000, 0x04000000, 0x08000000, 478 0x10000000, 0x20000000, 0x40000000, 0x80000000 }; 479 480 #ifndef MSBYTE_FIRST 481 static u_int32_t leftmask[32] = { 482 0x00000000, 0x00000001, 0x00000003, 0x00000007, 483 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 484 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 485 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 486 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, 487 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 488 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, 489 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff }; 490 static u_int32_t rightmask[32] = { 491 0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 492 0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000, 493 0xff000000, 0xff800000, 0xffc00000, 0xffe00000, 494 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 495 0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000, 496 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00, 497 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 498 0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe }; 499 #define LSOP >> 500 #define RSOP << 501 #endif /*not MSBYTE_FIRST*/ 502 503 #endif /*MSBIT_FIRST*/ 504 505 /* (The odd combinations MSBIT+~MSBYTE and ~MSBIT+MSBYTE could be added.) */ 506 507 #ifdef MSBYTE_FIRST 508 static u_int32_t bytemask[4] = { 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff }; 509 #ifdef RCONS_2BPP 510 static u_int32_t twobitmask[16] = { 511 0xc0000000, 0x30000000, 0x0c000000, 0x03000000, 512 0x00c00000, 0x00300000, 0x000c0000, 0x00030000, 513 0x0000c000, 0x00003000, 0x00000c00, 0x00000300, 514 0x000000c0, 0x00000030, 0x0000000c, 0x00000003 }; 515 #endif /* RCONS_2BPP */ 516 #ifdef RCONS_4BPP 517 static u_int32_t fourbitmask[8] = { 518 0xf0000000, 0x0f000000, 519 0x00f00000, 0x000f0000, 520 0x0000f000, 0x00000f00, 521 0x000000f0, 0x0000000f }; 522 #endif /* RCONS_4BPP */ 523 #ifdef RCONS_16BPP 524 static u_int32_t twobytemask[2] = { 0xffff0000, 0x0000ffff }; 525 #endif /* RCONS_16BPP */ 526 #else /*MSBYTE_FIRST*/ 527 static u_int32_t bytemask[4] = { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 }; 528 #ifdef RCONS_2BPP 529 static u_int32_t twobitmask[16] = { 530 0x00000003, 0x0000000c, 0x00000030, 0x000000c0, 531 0x00000300, 0x00000c00, 0x00003000, 0x0000c000, 532 0x00030000, 0x000c0000, 0x00300000, 0x00c00000, 533 0x03000000, 0x0c000000, 0x30000000, 0xc0000000 }; 534 #endif /* RCONS_2BPP */ 535 #ifdef RCONS_4BPP 536 static u_int32_t fourbitmask[16] = { 537 0x0000000f, 0x000000f0, 538 0x00000f00, 0x0000f000, 539 0x000f0000, 0x00f00000, 540 0x0f000000, 0xf0000000 }; 541 #endif /* RCONS_4BPP */ 542 #ifdef RCONS_16BPP 543 static u_int32_t twobytemask[2] = { 0x0000ffff, 0xffff0000 }; 544 #endif /* RCONS_16BPP */ 545 #endif /*MSBYTE_FIRST*/ 546 547 548 /* Forward routines. */ 549 550 static int raster_blit(struct raster *, u_int32_t *, int, int, int, 551 struct raster *, u_int32_t *, int, int, int, 552 int, int); 553 554 /* Raster operations. */ 555 556 /* Performs a bitblit. Returns 0 on success, -1 on failure. */ 557 int 558 raster_op( dst, dx, dy, w, h, rop, src, sx, sy ) 559 struct raster* dst; 560 int dx, dy, w, h, rop; 561 struct raster* src; 562 int sx, sy; 563 { 564 if ( dst == (struct raster*) 0 ) 565 return -1; /* no destination */ 566 567 if ( needsrc[RAS_GETOP( rop )] ) 568 { 569 /* Two-operand blit. */ 570 if ( src == (struct raster*) 0 ) 571 return -1; /* no source */ 572 573 /* Clip against source. */ 574 if ( sx < 0 ) 575 { 576 w += sx; 577 sx = 0; 578 } 579 if ( sy < 0 ) 580 { 581 h += sy; 582 sy = 0; 583 } 584 if ( sx + w > src->width ) 585 w = src->width - sx; 586 if ( sy + h > src->height ) 587 h = src->height - sy; 588 589 /* Clip against dest. */ 590 if ( dx < 0 ) 591 { 592 w += dx; 593 sx -= dx; 594 dx = 0; 595 } 596 if ( dy < 0 ) 597 { 598 h += dy; 599 sy -= dy; 600 dy = 0; 601 } 602 if ( dx + w > dst->width ) 603 w = dst->width - dx; 604 if ( dy + h > dst->height ) 605 h = dst->height - dy; 606 607 if ( w <= 0 || h <= 0 ) 608 return 0; /* nothing to do */ 609 610 return raster_op_noclip( dst, dx, dy, w, h, rop, src, sx, sy ); 611 } 612 613 /* No source necessary - one-operand blit. */ 614 if ( src != (struct raster*) 0 ) 615 return -1; /* unwanted source */ 616 617 /* Clip against dest. */ 618 if ( dx < 0 ) 619 { 620 w += dx; 621 dx = 0; 622 } 623 if ( dy < 0 ) 624 { 625 h += dy; 626 dy = 0; 627 } 628 if ( dx + w > dst->width ) 629 w = dst->width - dx; 630 if ( dy + h > dst->height ) 631 h = dst->height - dy; 632 633 if ( w <= 0 || h <= 0 ) 634 return 0; /* nothing to do */ 635 636 return raster_op_nosrc_noclip( dst, dx, dy, w, h, rop ); 637 } 638 639 /* Semi-public routine to do a bitblit without clipping. Returns 0 on 640 ** success, -1 on failure. 641 */ 642 int 643 raster_op_noclip( dst, dx, dy, w, h, rop, src, sx, sy ) 644 struct raster* dst; 645 int dx, dy, w, h, rop; 646 struct raster* src; 647 int sx, sy; 648 { 649 int op; 650 651 op = RAS_GETOP( rop ); 652 653 if ( src->depth == 1 ) 654 { 655 /* One-bit to ? blit. */ 656 if ( dst->depth == 1 ) 657 { 658 /* One to one blit. */ 659 u_int32_t* srclin1; 660 u_int32_t* dstlin1; 661 int srcleftignore, srcrightignore, srclongs; 662 int dstleftignore, dstrightignore, dstlongs; 663 664 srclin1 = RAS_ADDR( src, sx, sy ); 665 dstlin1 = RAS_ADDR( dst, dx, dy ); 666 667 #ifdef BCOPY_FASTER 668 /* Special-case full-width to full-width copies. */ 669 if ( op == RAS_SRC && src->width == w && dst->width == w && 670 src->linelongs == dst->linelongs && src->linelongs == w >> 5 ) 671 { 672 bcopy( 673 (char*) srclin1, (char*) dstlin1, 674 h * src->linelongs * sizeof(u_int32_t) ); 675 return 0; 676 } 677 #endif /*BCOPY_FASTER*/ 678 679 srcleftignore = ( sx & 31 ); 680 srclongs = ( srcleftignore + w + 31 ) >> 5; 681 srcrightignore = ( srclongs * 32 - w - srcleftignore ) & 31; 682 dstleftignore = ( dx & 31 ); 683 dstlongs = ( dstleftignore + w + 31 ) >> 5; 684 dstrightignore = ( dstlongs * 32 - w - dstleftignore ) & 31; 685 686 return raster_blit( 687 src, srclin1, srcleftignore, srcrightignore, srclongs, 688 dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op ); 689 } 690 691 #ifdef RCONS_2BPP 692 else if ( dst->depth == 2 ) 693 { 694 /* One to two, using the color in the rop. */ 695 u_int32_t* srclin1; 696 u_int32_t* dstlin1; 697 u_int32_t* srclin2; 698 u_int32_t* srclin; 699 u_int32_t* dstlin; 700 u_int32_t* srclong; 701 u_int32_t* dstlong; 702 u_int32_t color, dl; 703 int srcbit, dstbyte, i; 704 705 color = RAS_GETCOLOR( rop ); 706 if ( color == 0 ) 707 color = 3; 708 709 /* Make 32 bits of color so we can do the ROP without shifting. */ 710 color |= (( color << 30 ) | ( color << 28 ) | ( color << 26 ) 711 | ( color << 24 ) | ( color << 22 ) | ( color << 20 ) 712 | ( color << 18 ) | ( color << 16 ) | ( color << 14 ) 713 | ( color << 12 ) | ( color << 10 ) | ( color << 8 ) 714 | ( color << 6 ) | ( color << 4 ) | ( color << 2 )); 715 716 /* Don't have to worry about overlapping blits here. */ 717 srclin1 = RAS_ADDR( src, sx, sy ); 718 srclin2 = srclin1 + h * src->linelongs; 719 dstlin1 = RAS_ADDR( dst, dx, dy ); 720 srclin = srclin1; 721 dstlin = dstlin1; 722 723 while ( srclin != srclin2 ) 724 { 725 srclong = srclin; 726 srcbit = sx & 31; 727 dstlong = dstlin; 728 dstbyte = dx & 15; 729 i = w; 730 731 /* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */ 732 ROP_SRCDSTCOLOR( 733 /*op*/ op, 734 /*pre*/ while ( i > 0 ) 735 { 736 dl = *dstlong;, 737 /*s*/ *srclong & raster_bitmask[srcbit], 738 /*d*/ dl, 739 /*c*/ color, 740 /*pst*/ *dstlong = ( *dstlong & ~twobitmask[dstbyte] ) | 741 ( dl & twobitmask[dstbyte] ); 742 if ( srcbit == 31 ) 743 { 744 srcbit = 0; 745 ++srclong; 746 } 747 else 748 ++srcbit; 749 if ( dstbyte == 15 ) 750 { 751 dstbyte = 0; 752 ++dstlong; 753 } 754 else 755 ++dstbyte; 756 --i; 757 } ) 758 759 srclin += src->linelongs; 760 dstlin += dst->linelongs; 761 } 762 } 763 #endif /* RCONS_2BPP */ 764 #ifdef RCONS_4BPP 765 else if ( dst->depth == 4 ) 766 { 767 /* One to four, using the color in the rop. */ 768 u_int32_t* srclin1; 769 u_int32_t* dstlin1; 770 u_int32_t* srclin2; 771 u_int32_t* srclin; 772 u_int32_t* dstlin; 773 u_int32_t* srclong; 774 u_int32_t* dstlong; 775 u_int32_t color, dl; 776 int srcbit, dstbyte, i; 777 778 color = RAS_GETCOLOR( rop ); 779 if ( color == 0 ) 780 color = 15; 781 782 /* Make 32 bits of color so we can do the ROP without shifting. */ 783 color |= (( color << 28 ) | ( color << 24 ) 784 | ( color << 20 ) | ( color << 16 ) 785 | ( color << 12 ) | ( color << 8 ) 786 | ( color << 4 )); 787 788 /* Don't have to worry about overlapping blits here. */ 789 srclin1 = RAS_ADDR( src, sx, sy ); 790 srclin2 = srclin1 + h * src->linelongs; 791 dstlin1 = RAS_ADDR( dst, dx, dy ); 792 srclin = srclin1; 793 dstlin = dstlin1; 794 795 while ( srclin != srclin2 ) 796 { 797 srclong = srclin; 798 srcbit = sx & 31; 799 dstlong = dstlin; 800 dstbyte = dx & 7; 801 i = w; 802 803 /* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */ 804 ROP_SRCDSTCOLOR( 805 /*op*/ op, 806 /*pre*/ while ( i > 0 ) 807 { 808 dl = *dstlong;, 809 /*s*/ *srclong & raster_bitmask[srcbit], 810 /*d*/ dl, 811 /*c*/ color, 812 /*pst*/ *dstlong = ( *dstlong & ~fourbitmask[dstbyte] ) | 813 ( dl & fourbitmask[dstbyte] ); 814 if ( srcbit == 31 ) 815 { 816 srcbit = 0; 817 ++srclong; 818 } 819 else 820 ++srcbit; 821 if ( dstbyte == 7 ) 822 { 823 dstbyte = 0; 824 ++dstlong; 825 } 826 else 827 ++dstbyte; 828 --i; 829 } ) 830 831 srclin += src->linelongs; 832 dstlin += dst->linelongs; 833 } 834 } 835 #endif /* RCONS_4BPP */ 836 else if ( dst->depth == 8 ) 837 { 838 /* One to eight, using the color in the rop. This could 839 ** probably be sped up by handling each four-bit source nybble 840 ** as a group, indexing into a 16-element runtime-constructed 841 ** table of longwords. 842 */ 843 u_int32_t* srclin1; 844 u_int32_t* dstlin1; 845 u_int32_t* srclin2; 846 u_int32_t* srclin; 847 u_int32_t* dstlin; 848 u_int32_t* srclong; 849 u_int32_t* dstlong; 850 u_int32_t color, dl; 851 int srcbit, dstbyte, i; 852 853 color = RAS_GETCOLOR( rop ); 854 if ( color == 0 ) 855 color = 255; 856 857 /* Make 32 bits of color so we can do the ROP without shifting. */ 858 color |= ( color << 24 ) | ( color << 16 ) | ( color << 8 ); 859 860 /* Don't have to worry about overlapping blits here. */ 861 srclin1 = RAS_ADDR( src, sx, sy ); 862 srclin2 = srclin1 + h * src->linelongs; 863 dstlin1 = RAS_ADDR( dst, dx, dy ); 864 srclin = srclin1; 865 dstlin = dstlin1; 866 while ( srclin != srclin2 ) 867 { 868 srclong = srclin; 869 srcbit = sx & 31; 870 dstlong = dstlin; 871 dstbyte = dx & 3; 872 i = w; 873 874 /* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */ 875 ROP_SRCDSTCOLOR( 876 /*op*/ op, 877 /*pre*/ while ( i > 0 ) 878 { 879 dl = *dstlong;, 880 /*s*/ *srclong & raster_bitmask[srcbit], 881 /*d*/ dl, 882 /*c*/ color, 883 /*pst*/ *dstlong = ( *dstlong & ~bytemask[dstbyte] ) | 884 ( dl & bytemask[dstbyte] ); 885 if ( srcbit == 31 ) 886 { 887 srcbit = 0; 888 ++srclong; 889 } 890 else 891 ++srcbit; 892 if ( dstbyte == 3 ) 893 { 894 dstbyte = 0; 895 ++dstlong; 896 } 897 else 898 ++dstbyte; 899 --i; 900 } ) 901 902 srclin += src->linelongs; 903 dstlin += dst->linelongs; 904 } 905 } 906 #ifdef RCONS_16BPP 907 else 908 { 909 /* One to sixteen, using the color in the rop. This could 910 ** probably be sped up by handling each four-bit source nybble 911 ** as a group, indexing into a 16-element runtime-constructed 912 ** table of longwords. 913 */ 914 u_int32_t* srclin1; 915 u_int32_t* dstlin1; 916 u_int32_t* srclin2; 917 u_int32_t* srclin; 918 u_int32_t* dstlin; 919 u_int32_t* srclong; 920 u_int32_t* dstlong; 921 u_int32_t color, dl; 922 int srcbit, dstbyte, i; 923 924 color = RAS_GETCOLOR( rop ); 925 if ( color == 0 ) 926 color = 0xffff; 927 928 /* Make 32 bits of color so we can do the ROP without shifting. */ 929 color |= ( color << 16 ); 930 931 /* Don't have to worry about overlapping blits here. */ 932 srclin1 = RAS_ADDR( src, sx, sy ); 933 srclin2 = srclin1 + h * src->linelongs; 934 dstlin1 = RAS_ADDR( dst, dx, dy ); 935 srclin = srclin1; 936 dstlin = dstlin1; 937 while ( srclin != srclin2 ) 938 { 939 srclong = srclin; 940 srcbit = sx & 31; 941 dstlong = dstlin; 942 dstbyte = dx & 1; 943 i = w; 944 945 /* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */ 946 ROP_SRCDSTCOLOR( 947 /*op*/ op, 948 /*pre*/ while ( i > 0 ) 949 { 950 dl = *dstlong;, 951 /*s*/ *srclong & raster_bitmask[srcbit], 952 /*d*/ dl, 953 /*c*/ color, 954 /*pst*/ *dstlong = ( *dstlong & ~twobytemask[dstbyte] ) | 955 ( dl & twobytemask[dstbyte] ); 956 if ( srcbit == 31 ) 957 { 958 srcbit = 0; 959 ++srclong; 960 } 961 else 962 ++srcbit; 963 if ( dstbyte == 1 ) 964 { 965 dstbyte = 0; 966 ++dstlong; 967 } 968 else 969 ++dstbyte; 970 --i; 971 } ) 972 973 srclin += src->linelongs; 974 dstlin += dst->linelongs; 975 } 976 } 977 #endif /* RCONS_16BPP */ 978 } 979 #ifdef RCONS_2BPP 980 else if ( src->depth == 2 ) 981 { 982 /* Two to two blit. */ 983 u_int32_t* srclin1; 984 u_int32_t* dstlin1; 985 int srcleftignore, srcrightignore, srclongs; 986 int dstleftignore, dstrightignore, dstlongs; 987 988 srclin1 = RAS_ADDR( src, sx, sy ); 989 dstlin1 = RAS_ADDR( dst, dx, dy ); 990 991 srcleftignore = ( sx & 15 ) * 2; 992 srclongs = ( srcleftignore + w * 2 + 31 ) >> 5; 993 srcrightignore = ( srclongs * 32 - w * 2 - srcleftignore ) & 31; 994 dstleftignore = ( dx & 15 ) * 2; 995 dstlongs = ( dstleftignore + w * 2 + 31 ) >> 5; 996 dstrightignore = ( dstlongs * 32 - w * 2 - dstleftignore ) & 31; 997 998 return raster_blit( 999 src, srclin1, srcleftignore, srcrightignore, srclongs, 1000 dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op ); 1001 } 1002 #endif /* RCONS_2BPP */ 1003 #ifdef RCONS_4BPP 1004 else if ( src->depth == 4 ) 1005 { 1006 /* Four to four blit. */ 1007 u_int32_t* srclin1; 1008 u_int32_t* dstlin1; 1009 int srcleftignore, srcrightignore, srclongs; 1010 int dstleftignore, dstrightignore, dstlongs; 1011 1012 srclin1 = RAS_ADDR( src, sx, sy ); 1013 dstlin1 = RAS_ADDR( dst, dx, dy ); 1014 1015 srcleftignore = ( sx & 7 ) * 4; 1016 srclongs = ( srcleftignore + w * 4 + 31 ) >> 5; 1017 srcrightignore = ( srclongs * 32 - w * 4 - srcleftignore ) & 31; 1018 dstleftignore = ( dx & 7 ) * 4; 1019 dstlongs = ( dstleftignore + w * 4 + 31 ) >> 5; 1020 dstrightignore = ( dstlongs * 32 - w * 4 - dstleftignore ) & 31; 1021 1022 return raster_blit( 1023 src, srclin1, srcleftignore, srcrightignore, srclongs, 1024 dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op ); 1025 } 1026 #endif /* RCONS_4BPP */ 1027 1028 else if ( src->depth == 8 ) 1029 { 1030 /* Eight to eight blit. */ 1031 u_int32_t* srclin1; 1032 u_int32_t* dstlin1; 1033 int srcleftignore, srcrightignore, srclongs; 1034 int dstleftignore, dstrightignore, dstlongs; 1035 1036 if ( dst->depth != 8 ) 1037 return -1; /* depth mismatch */ 1038 1039 srclin1 = RAS_ADDR( src, sx, sy ); 1040 dstlin1 = RAS_ADDR( dst, dx, dy ); 1041 1042 #ifdef BCOPY_FASTER 1043 /* Special-case full-width to full-width copies. */ 1044 if ( op == RAS_SRC && src->width == w && dst->width == w && 1045 src->linelongs == dst->linelongs && src->linelongs == w >> 2 ) 1046 { 1047 memcpy( (char*) dstlin1, (char*) srclin1, 1048 h * src->linelongs * sizeof(u_int32_t) ); 1049 return 0; 1050 } 1051 #endif /*BCOPY_FASTER*/ 1052 1053 srcleftignore = ( sx & 3 ) * 8; 1054 srclongs = ( srcleftignore + w * 8 + 31 ) >> 5; 1055 srcrightignore = ( srclongs * 32 - w * 8 - srcleftignore ) & 31; 1056 dstleftignore = ( dx & 3 ) * 8; 1057 dstlongs = ( dstleftignore + w * 8 + 31 ) >> 5; 1058 dstrightignore = ( dstlongs * 32 - w * 8 - dstleftignore ) & 31; 1059 1060 return raster_blit( 1061 src, srclin1, srcleftignore, srcrightignore, srclongs, 1062 dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op ); 1063 } 1064 #ifdef RCONS_16BPP 1065 else 1066 { 1067 /* Sixteen to sixteen blit. */ 1068 u_int32_t* srclin1; 1069 u_int32_t* dstlin1; 1070 int srcleftignore, srcrightignore, srclongs; 1071 int dstleftignore, dstrightignore, dstlongs; 1072 1073 srclin1 = RAS_ADDR( src, sx, sy ); 1074 dstlin1 = RAS_ADDR( dst, dx, dy ); 1075 1076 srcleftignore = ( sx & 1 ) * 16; 1077 srclongs = ( srcleftignore + w * 16 + 31 ) >> 5; 1078 srcrightignore = ( srclongs * 32 - w * 16 - srcleftignore ) & 31; 1079 dstleftignore = ( dx & 1 ) * 16; 1080 dstlongs = ( dstleftignore + w * 16 + 31 ) >> 5; 1081 dstrightignore = ( dstlongs * 32 - w * 16 - dstleftignore ) & 31; 1082 1083 return raster_blit( 1084 src, srclin1, srcleftignore, srcrightignore, srclongs, 1085 dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op ); 1086 } 1087 #endif /* RCONS_16BPP */ 1088 return 0; 1089 } 1090 1091 /* Semi-public routine to do a no-src bitblit without clipping. Returns 0 1092 ** on success, -1 on failure. 1093 */ 1094 int 1095 raster_op_nosrc_noclip( dst, dx, dy, w, h, rop ) 1096 struct raster* dst; 1097 int dx, dy, w, h, rop; 1098 { 1099 int op; 1100 1101 op = RAS_GETOP( rop ); 1102 1103 if ( dst->depth == 1 ) 1104 { 1105 /* One-bit no-src blit. */ 1106 u_int32_t* dstlin1; 1107 u_int32_t* dstlin2; 1108 u_int32_t* dstlin; 1109 int dstleftignore, dstrightignore, dstlongs; 1110 u_int32_t dl, lm, nlm, rm, nrm; 1111 u_int32_t* dstlong2; 1112 u_int32_t* dstlong; 1113 1114 dstlin1 = RAS_ADDR( dst, dx, dy ); 1115 1116 #ifdef BCOPY_FASTER 1117 /* Special-case full-width clears. */ 1118 if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 5 ) 1119 { 1120 memset( (char*) dstlin1, 0, h * dst->linelongs * sizeof(u_int32_t) ); 1121 return 0; 1122 } 1123 #endif /*BCOPY_FASTER*/ 1124 1125 dstleftignore = ( dx & 31 ); 1126 dstlongs = ( dstleftignore + w + 31 ) >> 5; 1127 dstrightignore = ( dstlongs * 32 - w - dstleftignore ) & 31; 1128 1129 dstlin2 = dstlin1 + h * dst->linelongs; 1130 dstlin = dstlin1; 1131 1132 if ( dstlongs == 1 ) 1133 { 1134 /* It fits into a single longword. */ 1135 lm = leftmask[dstleftignore] | rightmask[dstrightignore]; 1136 nlm = ~lm; 1137 while ( dstlin != dstlin2 ) 1138 { 1139 ROP_DST( 1140 /*op*/ op, 1141 /*pre*/ dl = *dstlin;, 1142 /*d*/ dl, 1143 /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); ) 1144 1145 dstlin += dst->linelongs; 1146 } 1147 } 1148 else 1149 { 1150 lm = leftmask[dstleftignore]; 1151 rm = rightmask[dstrightignore]; 1152 nrm = ~rm; 1153 nlm = ~lm; 1154 1155 while ( dstlin != dstlin2 ) 1156 { 1157 dstlong = dstlin; 1158 dstlong2 = dstlong + dstlongs; 1159 if ( dstrightignore != 0 ) 1160 --dstlong2; 1161 1162 /* Leading edge. */ 1163 if ( dstleftignore != 0 ) 1164 { 1165 ROP_DST( 1166 /*op*/ op, 1167 /*pre*/ dl = *dstlong;, 1168 /*d*/ dl, 1169 /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) 1170 ++dstlong; 1171 } 1172 1173 /* Main rop. */ 1174 ROP_DST( 1175 /*op*/ op, 1176 /*pre*/ while ( dstlong != dstlong2 ) 1177 {, 1178 /*d*/ *dstlong, 1179 /*pst*/ ++dstlong; 1180 } ) 1181 1182 /* Trailing edge. */ 1183 if ( dstrightignore != 0 ) 1184 { 1185 ROP_DST( 1186 /*op*/ op, 1187 /*pre*/ dl = *dstlong;, 1188 /*d*/ dl, 1189 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) 1190 } 1191 1192 dstlin += dst->linelongs; 1193 } 1194 } 1195 } 1196 1197 #ifdef RCONS_2BPP 1198 else if ( dst->depth == 2 ) 1199 { 1200 /* Two-bit no-src blit. */ 1201 u_int32_t color; 1202 u_int32_t* dstlin1; 1203 u_int32_t* dstlin2; 1204 u_int32_t* dstlin; 1205 int dstleftignore, dstrightignore, dstlongs; 1206 u_int32_t dl, lm, nlm, rm, nrm; 1207 u_int32_t* dstlong2; 1208 u_int32_t* dstlong; 1209 1210 dstlin1 = RAS_ADDR( dst, dx, dy ); 1211 1212 #ifdef BCOPY_FASTER 1213 /* Special-case full-width clears. */ 1214 if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 4 ) 1215 { 1216 memset( (char*) dstlin1, 0, h * dst->linelongs * sizeof(u_int32_t) ); 1217 return 0; 1218 } 1219 #endif /*BCOPY_FASTER*/ 1220 1221 color = RAS_GETCOLOR( rop ); 1222 if ( color == 0 ) 1223 color = 3; 1224 1225 /* Make 32 bits of color so we can do the ROP without shifting. */ 1226 color |= (( color << 30 ) | ( color << 28 ) | ( color << 26 ) 1227 | ( color << 24 ) | ( color << 22 ) | ( color << 20 ) 1228 | ( color << 18 ) | ( color << 16 ) | ( color << 14 ) 1229 | ( color << 12 ) | ( color << 10 ) | ( color << 8 ) 1230 | ( color << 6 ) | ( color << 4 ) | ( color << 2 )); 1231 1232 dstleftignore = ( dx & 15 ) * 2; 1233 dstlongs = ( dstleftignore + w * 2 + 31 ) >> 5; 1234 dstrightignore = ( dstlongs * 32 - w * 2 - dstleftignore ) & 31; 1235 1236 dstlin2 = dstlin1 + h * dst->linelongs; 1237 dstlin = dstlin1; 1238 1239 if ( dstlongs == 1 ) 1240 { 1241 /* It fits into a single longword. */ 1242 lm = leftmask[dstleftignore] | rightmask[dstrightignore]; 1243 nlm = ~lm; 1244 while ( dstlin != dstlin2 ) 1245 { 1246 ROP_DST( 1247 /*op*/ op, 1248 /*pre*/ dl = *dstlin;, 1249 /*d*/ dl, 1250 /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); ) 1251 1252 dstlin += dst->linelongs; 1253 } 1254 } 1255 else 1256 { 1257 lm = leftmask[dstleftignore]; 1258 rm = rightmask[dstrightignore]; 1259 nrm = ~rm; 1260 nlm = ~lm; 1261 1262 while ( dstlin != dstlin2 ) 1263 { 1264 dstlong = dstlin; 1265 dstlong2 = dstlong + dstlongs; 1266 if ( dstrightignore != 0 ) 1267 --dstlong2; 1268 1269 /* Leading edge. */ 1270 if ( dstleftignore != 0 ) 1271 { 1272 ROP_DST( 1273 /*op*/ op, 1274 /*pre*/ dl = *dstlong;, 1275 /*d*/ dl, 1276 /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) 1277 ++dstlong; 1278 } 1279 1280 /* Main rop. */ 1281 ROP_DST( 1282 /*op*/ op, 1283 /*pre*/ while ( dstlong != dstlong2 ) 1284 {, 1285 /*d*/ *dstlong, 1286 /*pst*/ ++dstlong; 1287 } ) 1288 1289 /* Trailing edge. */ 1290 if ( dstrightignore != 0 ) 1291 { 1292 ROP_DST( 1293 /*op*/ op, 1294 /*pre*/ dl = *dstlong;, 1295 /*d*/ dl, 1296 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) 1297 } 1298 1299 dstlin += dst->linelongs; 1300 } 1301 } 1302 } 1303 #endif /* RCONS_2BPP */ 1304 #ifdef RCONS_4BPP 1305 else if ( dst->depth == 4 ) 1306 { 1307 /* Two-bit no-src blit. */ 1308 u_int32_t color; 1309 u_int32_t* dstlin1; 1310 u_int32_t* dstlin2; 1311 u_int32_t* dstlin; 1312 int dstleftignore, dstrightignore, dstlongs; 1313 u_int32_t dl, lm, nlm, rm, nrm; 1314 u_int32_t* dstlong2; 1315 u_int32_t* dstlong; 1316 1317 dstlin1 = RAS_ADDR( dst, dx, dy ); 1318 1319 #ifdef BCOPY_FASTER 1320 /* Special-case full-width clears. */ 1321 if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 3 ) 1322 { 1323 memset( (char*) dstlin1, 0, h * dst->linelongs * sizeof(u_int32_t) ); 1324 return 0; 1325 } 1326 #endif /*BCOPY_FASTER*/ 1327 1328 color = RAS_GETCOLOR( rop ); 1329 if ( color == 0 ) 1330 color = 15; 1331 1332 /* Make 32 bits of color so we can do the ROP without shifting. */ 1333 color |= (( color << 28 ) | ( color << 24 ) 1334 | ( color << 20 ) | ( color << 16 ) 1335 | ( color << 12 ) | ( color << 8 ) 1336 | ( color << 4 )); 1337 1338 dstleftignore = ( dx & 7 ) * 4; 1339 dstlongs = ( dstleftignore + w * 4 + 31 ) >> 5; 1340 dstrightignore = ( dstlongs * 32 - w * 4 - dstleftignore ) & 31; 1341 1342 dstlin2 = dstlin1 + h * dst->linelongs; 1343 dstlin = dstlin1; 1344 1345 if ( dstlongs == 1 ) 1346 { 1347 /* It fits into a single longword. */ 1348 lm = leftmask[dstleftignore] | rightmask[dstrightignore]; 1349 nlm = ~lm; 1350 while ( dstlin != dstlin2 ) 1351 { 1352 ROP_DST( 1353 /*op*/ op, 1354 /*pre*/ dl = *dstlin;, 1355 /*d*/ dl, 1356 /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); ) 1357 1358 dstlin += dst->linelongs; 1359 } 1360 } 1361 else 1362 { 1363 lm = leftmask[dstleftignore]; 1364 rm = rightmask[dstrightignore]; 1365 nrm = ~rm; 1366 nlm = ~lm; 1367 1368 while ( dstlin != dstlin2 ) 1369 { 1370 dstlong = dstlin; 1371 dstlong2 = dstlong + dstlongs; 1372 if ( dstrightignore != 0 ) 1373 --dstlong2; 1374 1375 /* Leading edge. */ 1376 if ( dstleftignore != 0 ) 1377 { 1378 ROP_DST( 1379 /*op*/ op, 1380 /*pre*/ dl = *dstlong;, 1381 /*d*/ dl, 1382 /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) 1383 ++dstlong; 1384 } 1385 1386 /* Main rop. */ 1387 ROP_DST( 1388 /*op*/ op, 1389 /*pre*/ while ( dstlong != dstlong2 ) 1390 {, 1391 /*d*/ *dstlong, 1392 /*pst*/ ++dstlong; 1393 } ) 1394 1395 /* Trailing edge. */ 1396 if ( dstrightignore != 0 ) 1397 { 1398 ROP_DST( 1399 /*op*/ op, 1400 /*pre*/ dl = *dstlong;, 1401 /*d*/ dl, 1402 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) 1403 } 1404 1405 dstlin += dst->linelongs; 1406 } 1407 } 1408 } 1409 #endif /* RCONS_4BPP */ 1410 else if ( dst->depth == 8) 1411 { 1412 /* Eight-bit no-src blit. */ 1413 u_int32_t color; 1414 u_int32_t* dstlin1; 1415 u_int32_t* dstlin2; 1416 u_int32_t* dstlin; 1417 int dstleftignore, dstrightignore, dstlongs; 1418 u_int32_t dl, lm, nlm, rm, nrm; 1419 u_int32_t* dstlong2; 1420 u_int32_t* dstlong; 1421 1422 dstlin1 = RAS_ADDR( dst, dx, dy ); 1423 1424 #ifdef BCOPY_FASTER 1425 /* Special-case full-width clears. */ 1426 if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 2 ) 1427 { 1428 memset( (char*) dstlin1, 0, h * dst->linelongs * sizeof(u_int32_t) ); 1429 return 0; 1430 } 1431 #endif /*BCOPY_FASTER*/ 1432 1433 color = RAS_GETCOLOR( rop ); 1434 if ( color == 0 ) 1435 color = 255; 1436 1437 /* Make 32 bits of color so we can do the ROP without shifting. */ 1438 color |= ( color << 24 ) | ( color << 16 ) | ( color << 8 ); 1439 1440 dstleftignore = ( dx & 3 ) * 8; 1441 dstlongs = ( dstleftignore + w * 8 + 31 ) >> 5; 1442 dstrightignore = ( dstlongs * 32 - w * 8 - dstleftignore ) & 31; 1443 1444 dstlin2 = dstlin1 + h * dst->linelongs; 1445 dstlin = dstlin1; 1446 1447 if ( dstlongs == 1 ) 1448 { 1449 /* It fits into a single longword. */ 1450 lm = leftmask[dstleftignore] | rightmask[dstrightignore]; 1451 nlm = ~lm; 1452 while ( dstlin != dstlin2 ) 1453 { 1454 ROP_DSTCOLOR( 1455 /*op*/ op, 1456 /*pre*/ dl = *dstlin;, 1457 /*d*/ dl, 1458 /*c*/ color, 1459 /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); ) 1460 1461 dstlin += dst->linelongs; 1462 } 1463 } 1464 else 1465 { 1466 lm = leftmask[dstleftignore]; 1467 rm = rightmask[dstrightignore]; 1468 nrm = ~rm; 1469 nlm = ~lm; 1470 while ( dstlin != dstlin2 ) 1471 { 1472 dstlong = dstlin; 1473 dstlong2 = dstlong + dstlongs; 1474 if ( dstrightignore != 0 ) 1475 --dstlong2; 1476 1477 /* Leading edge. */ 1478 if ( dstleftignore != 0 ) 1479 { 1480 ROP_DSTCOLOR( 1481 /*op*/ op, 1482 /*pre*/ dl = *dstlong;, 1483 /*d*/ dl, 1484 /*c*/ color, 1485 /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) 1486 ++dstlong; 1487 } 1488 1489 /* Main rop. */ 1490 ROP_DSTCOLOR( 1491 /*op*/ op, 1492 /*pre*/ while ( dstlong != dstlong2 ) 1493 {, 1494 /*d*/ *dstlong, 1495 /*c*/ color, 1496 /*pst*/ ++dstlong; 1497 } ) 1498 1499 /* Trailing edge. */ 1500 if ( dstrightignore != 0 ) 1501 { 1502 ROP_DSTCOLOR( 1503 /*op*/ op, 1504 /*pre*/ dl = *dstlong;, 1505 /*d*/ dl, 1506 /*c*/ color, 1507 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) 1508 } 1509 1510 dstlin += dst->linelongs; 1511 } 1512 } 1513 } 1514 #ifdef RCONS_16BPP 1515 else 1516 { 1517 /* Sixteen-bit no-src blit. */ 1518 u_int32_t color; 1519 u_int32_t* dstlin1; 1520 u_int32_t* dstlin2; 1521 u_int32_t* dstlin; 1522 int dstleftignore, dstrightignore, dstlongs; 1523 u_int32_t dl, lm, nlm, rm, nrm; 1524 u_int32_t* dstlong2; 1525 u_int32_t* dstlong; 1526 1527 dstlin1 = RAS_ADDR( dst, dx, dy ); 1528 1529 #ifdef BCOPY_FASTER 1530 /* Special-case full-width clears. */ 1531 if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 1 ) 1532 { 1533 memset( (char*) dstlin1, 0, h * dst->linelongs * sizeof(u_int32_t) ); 1534 return 0; 1535 } 1536 #endif /*BCOPY_FASTER*/ 1537 1538 color = RAS_GETCOLOR( rop ); 1539 if ( color == 0 ) 1540 color = 0xffff; /* XXX */ 1541 1542 /* Make 32 bits of color so we can do the ROP without shifting. */ 1543 color |= ( color << 16 ); 1544 1545 dstleftignore = ( dx & 1 ) * 16; 1546 dstlongs = ( dstleftignore + w * 16 + 31 ) >> 5; 1547 dstrightignore = ( dstlongs * 32 - w * 8 - dstleftignore ) & 31; 1548 1549 dstlin2 = dstlin1 + h * dst->linelongs; 1550 dstlin = dstlin1; 1551 1552 if ( dstlongs == 1 ) 1553 { 1554 /* It fits into a single longword. */ 1555 lm = leftmask[dstleftignore] | rightmask[dstrightignore]; 1556 nlm = ~lm; 1557 while ( dstlin != dstlin2 ) 1558 { 1559 ROP_DSTCOLOR( 1560 /*op*/ op, 1561 /*pre*/ dl = *dstlin;, 1562 /*d*/ dl, 1563 /*c*/ color, 1564 /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); ) 1565 1566 dstlin += dst->linelongs; 1567 } 1568 } 1569 else 1570 { 1571 lm = leftmask[dstleftignore]; 1572 rm = rightmask[dstrightignore]; 1573 nrm = ~rm; 1574 nlm = ~lm; 1575 while ( dstlin != dstlin2 ) 1576 { 1577 dstlong = dstlin; 1578 dstlong2 = dstlong + dstlongs; 1579 if ( dstrightignore != 0 ) 1580 --dstlong2; 1581 1582 /* Leading edge. */ 1583 if ( dstleftignore != 0 ) 1584 { 1585 ROP_DSTCOLOR( 1586 /*op*/ op, 1587 /*pre*/ dl = *dstlong;, 1588 /*d*/ dl, 1589 /*c*/ color, 1590 /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) 1591 ++dstlong; 1592 } 1593 1594 /* Main rop. */ 1595 ROP_DSTCOLOR( 1596 /*op*/ op, 1597 /*pre*/ while ( dstlong != dstlong2 ) 1598 {, 1599 /*d*/ *dstlong, 1600 /*c*/ color, 1601 /*pst*/ ++dstlong; 1602 } ) 1603 1604 /* Trailing edge. */ 1605 if ( dstrightignore != 0 ) 1606 { 1607 ROP_DSTCOLOR( 1608 /*op*/ op, 1609 /*pre*/ dl = *dstlong;, 1610 /*d*/ dl, 1611 /*c*/ color, 1612 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) 1613 } 1614 1615 dstlin += dst->linelongs; 1616 } 1617 } 1618 } 1619 #endif /* RCONS_16BPP */ 1620 1621 return 0; 1622 } 1623 1624 /* This is a general bitblit routine, handling overlapping source and 1625 ** destination. It's used for both the 1-to-1 and 8-to-8 cases. 1626 */ 1627 static int 1628 raster_blit( src, srclin1, srcleftignore, srcrightignore, srclongs, dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op ) 1629 struct raster* src; 1630 u_int32_t* srclin1; 1631 int srcleftignore, srcrightignore, srclongs; 1632 struct raster* dst; 1633 u_int32_t* dstlin1; 1634 int dstleftignore, dstrightignore, dstlongs; 1635 int h, op; 1636 { 1637 u_int32_t* srclin2; 1638 u_int32_t* dstlin2; 1639 int srclininc, dstlininc; 1640 u_int32_t* srclin; 1641 u_int32_t* dstlin; 1642 int prevleftshift, currrightshift; 1643 int longinc; 1644 u_int32_t* srclong; 1645 u_int32_t* dstlong; 1646 u_int32_t* dstlong2; 1647 u_int32_t dl, lm, nlm, rm, nrm; 1648 1649 prevleftshift = ( srcleftignore - dstleftignore ) & 31; 1650 1651 srclin2 = srclin1 + h * src->linelongs; 1652 dstlin2 = dstlin1 + h * dst->linelongs; 1653 srclininc = src->linelongs; 1654 dstlininc = dst->linelongs; 1655 longinc = 1; 1656 1657 /* Check for overlaps. */ 1658 if ( ( dstlin1 >= srclin1 && dstlin1 < srclin1 + srclongs ) || 1659 ( srclin1 >= dstlin1 && srclin1 < dstlin1 + dstlongs ) ) 1660 { 1661 /* Horizontal overlap. Should we reverse? */ 1662 if ( srclin1 < dstlin1 ) 1663 { 1664 longinc = -1; 1665 srclin1 += srclongs - 1; 1666 srclin2 += srclongs - 1; 1667 dstlin1 += dstlongs - 1; 1668 } 1669 } 1670 else if ( ( dstlin1 >= srclin1 && dstlin1 < srclin2 ) || 1671 ( srclin1 >= dstlin1 && srclin1 < dstlin2 ) ) 1672 { 1673 /* Vertical overlap. Should we reverse? */ 1674 if ( srclin1 < dstlin1 ) 1675 { 1676 srclin2 = srclin1 - srclininc; 1677 srclin1 += ( h - 1 ) * srclininc; 1678 dstlin1 += ( h - 1 ) * dstlininc; 1679 srclininc = -srclininc; 1680 dstlininc = -dstlininc; 1681 } 1682 } 1683 srclin = srclin1; 1684 dstlin = dstlin1; 1685 1686 if ( prevleftshift == 0 ) 1687 { 1688 /* The bits line up, no shifting necessary. */ 1689 if ( dstlongs == 1 ) 1690 { 1691 /* It all fits into a single longword. */ 1692 lm = leftmask[dstleftignore] | rightmask[dstrightignore]; 1693 nlm = ~lm; 1694 while ( srclin != srclin2 ) 1695 { 1696 ROP_SRCDST( 1697 /*op*/ op, 1698 /*pre*/ dl = *dstlin;, 1699 /*s*/ *srclin, 1700 /*d*/ dl, 1701 /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); ) 1702 1703 srclin += srclininc; 1704 dstlin += dstlininc; 1705 } 1706 } 1707 else 1708 { 1709 /* Multiple longwords. */ 1710 lm = leftmask[dstleftignore]; 1711 rm = rightmask[dstrightignore]; 1712 nrm = ~rm; 1713 nlm = ~lm; 1714 if ( longinc == 1 ) 1715 { 1716 /* Left to right. */ 1717 while ( srclin != srclin2 ) 1718 { 1719 srclong = srclin; 1720 dstlong = dstlin; 1721 dstlong2 = dstlong + dstlongs; 1722 if ( dstrightignore != 0 ) 1723 --dstlong2; 1724 1725 /* Leading edge. */ 1726 if ( dstleftignore != 0 ) 1727 { 1728 ROP_SRCDST( 1729 /*op*/ op, 1730 /*pre*/ dl = *dstlong;, 1731 /*s*/ *srclong, 1732 /*d*/ dl, 1733 /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) 1734 ++srclong; 1735 ++dstlong; 1736 } 1737 1738 /* Main rop. */ 1739 ROP_SRCDST( 1740 /*op*/ op, 1741 /*pre*/ while ( dstlong != dstlong2 ) 1742 {, 1743 /*s*/ *srclong, 1744 /*d*/ *dstlong, 1745 /*pst*/ ++srclong; 1746 ++dstlong; 1747 } ) 1748 1749 /* Trailing edge. */ 1750 if ( dstrightignore != 0 ) 1751 { 1752 ROP_SRCDST( 1753 /*op*/ op, 1754 /*pre*/ dl = *dstlong;, 1755 /*s*/ *srclong, 1756 /*d*/ dl, 1757 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) 1758 } 1759 1760 srclin += srclininc; 1761 dstlin += dstlininc; 1762 } 1763 } 1764 else 1765 { 1766 /* Right to left. */ 1767 while ( srclin != srclin2 ) 1768 { 1769 srclong = srclin; 1770 dstlong = dstlin; 1771 dstlong2 = dstlong - dstlongs; 1772 if ( dstleftignore != 0 ) 1773 ++dstlong2; 1774 1775 /* Leading edge. */ 1776 if ( dstrightignore != 0 ) 1777 { 1778 ROP_SRCDST( 1779 /*op*/ op, 1780 /*pre*/ dl = *dstlong;, 1781 /*s*/ *srclong, 1782 /*d*/ dl, 1783 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) 1784 --srclong; 1785 --dstlong; 1786 } 1787 1788 /* Main rop. */ 1789 ROP_SRCDST( 1790 /*op*/ op, 1791 /*pre*/ while ( dstlong != dstlong2 ) 1792 {, 1793 /*s*/ *srclong, 1794 /*d*/ *dstlong, 1795 /*pst*/ --srclong; 1796 --dstlong; 1797 } ) 1798 1799 /* Trailing edge. */ 1800 if ( dstleftignore != 0 ) 1801 { 1802 ROP_SRCDST( 1803 /*op*/ op, 1804 /*pre*/ dl = *dstlong;, 1805 /*s*/ *srclong, 1806 /*d*/ dl, 1807 /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) 1808 } 1809 1810 srclin += srclininc; 1811 dstlin += dstlininc; 1812 } 1813 } 1814 } 1815 } 1816 1817 else 1818 { 1819 /* General case, with shifting and everything. */ 1820 u_int32_t sl, prevsl; 1821 1822 currrightshift = 32 - prevleftshift; 1823 if ( srclongs == 1 && dstlongs == 1 ) 1824 { 1825 /* It fits into a single longword, with a shift. */ 1826 lm = leftmask[dstleftignore] | rightmask[dstrightignore]; 1827 nlm = ~lm; 1828 if ( srcleftignore > dstleftignore ) 1829 { 1830 while ( srclin != srclin2 ) 1831 { 1832 ROP_SRCDST( 1833 /*op*/ op, 1834 /*pre*/ dl = *dstlin;, 1835 /*s*/ *srclin LSOP prevleftshift, 1836 /*d*/ dl, 1837 /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); ) 1838 1839 srclin += srclininc; 1840 dstlin += dstlininc; 1841 } 1842 } 1843 else 1844 { 1845 while ( srclin != srclin2 ) 1846 { 1847 ROP_SRCDST( 1848 /*op*/ op, 1849 /*pre*/ dl = *dstlin;, 1850 /*s*/ *srclin RSOP currrightshift, 1851 /*d*/ dl, 1852 /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); ) 1853 1854 srclin += srclininc; 1855 dstlin += dstlininc; 1856 } 1857 } 1858 } 1859 else 1860 { 1861 /* Multiple longwords. */ 1862 lm = leftmask[dstleftignore]; 1863 rm = rightmask[dstrightignore]; 1864 nrm = ~rm; 1865 nlm = ~lm; 1866 if ( longinc == 1 ) 1867 { 1868 /* Left to right. */ 1869 while ( srclin != srclin2 ) 1870 { 1871 srclong = srclin; 1872 dstlong = dstlin; 1873 dstlong2 = dstlong + dstlongs; 1874 if ( srcleftignore > dstleftignore ) 1875 prevsl = *srclong++ LSOP prevleftshift; 1876 else 1877 prevsl = 0; 1878 if ( dstrightignore != 0 ) 1879 --dstlong2; 1880 1881 /* Leading edge. */ 1882 if ( dstleftignore != 0 ) 1883 { 1884 ROP_SRCDST( 1885 /*op*/ op, 1886 /*pre*/ sl = *srclong; 1887 dl = *dstlong;, 1888 /*s*/ prevsl | ( sl RSOP currrightshift ), 1889 /*d*/ dl, 1890 /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) 1891 prevsl = sl LSOP prevleftshift; 1892 ++srclong; 1893 ++dstlong; 1894 } 1895 1896 /* Main rop. */ 1897 ROP_SRCDST( 1898 /*op*/ op, 1899 /*pre*/ while ( dstlong != dstlong2 ) 1900 { 1901 sl = *srclong;, 1902 /*s*/ prevsl | ( sl RSOP currrightshift ), 1903 /*d*/ *dstlong, 1904 /*pst*/ prevsl = sl LSOP prevleftshift; 1905 ++srclong; 1906 ++dstlong; 1907 } ) 1908 1909 /* Trailing edge. */ 1910 if ( dstrightignore != 0 ) 1911 { 1912 ROP_SRCDST( 1913 /*op*/ op, 1914 /*pre*/ dl = *dstlong;, 1915 /*s*/ prevsl | ( *srclong RSOP currrightshift ), 1916 /*d*/ dl, 1917 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) 1918 } 1919 1920 srclin += srclininc; 1921 dstlin += dstlininc; 1922 } 1923 } 1924 else 1925 { 1926 /* Right to left. */ 1927 while ( srclin != srclin2 ) 1928 { 1929 srclong = srclin; 1930 dstlong = dstlin; 1931 dstlong2 = dstlong - dstlongs; 1932 if ( srcrightignore > dstrightignore ) 1933 prevsl = *srclong-- RSOP currrightshift; 1934 else 1935 prevsl = 0; 1936 if ( dstleftignore != 0 ) 1937 ++dstlong2; 1938 1939 /* Leading edge. */ 1940 if ( dstrightignore != 0 ) 1941 { 1942 ROP_SRCDST( 1943 /*op*/ op, 1944 /*pre*/ sl = *srclong; 1945 dl = *dstlong;, 1946 /*s*/ prevsl | ( sl LSOP prevleftshift ), 1947 /*d*/ dl, 1948 /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) 1949 prevsl = sl RSOP currrightshift; 1950 --srclong; 1951 --dstlong; 1952 } 1953 1954 /* Main rop. */ 1955 ROP_SRCDST( 1956 /*op*/ op, 1957 /*pre*/ while ( dstlong != dstlong2 ) 1958 { 1959 sl = *srclong;, 1960 /*s*/ prevsl | ( sl LSOP prevleftshift ), 1961 /*d*/ *dstlong, 1962 /*pst*/ prevsl = sl RSOP currrightshift; 1963 --srclong; 1964 --dstlong; 1965 } ) 1966 1967 /* Trailing edge. */ 1968 if ( dstleftignore != 0 ) 1969 { 1970 ROP_SRCDST( 1971 /*op*/ op, 1972 /*pre*/ dl = *dstlong;, 1973 /*s*/ prevsl | ( *srclong LSOP prevleftshift ), 1974 /*d*/ dl, 1975 /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) 1976 } 1977 1978 srclin += srclininc; 1979 dstlin += dstlininc; 1980 } 1981 } 1982 } 1983 } 1984 1985 return 0; 1986 } 1987