1 /* $NetBSD: raster_op.c,v 1.17 2009/03/18 17:06:50 cegger Exp $ */
4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved.
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.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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
35 * @(#)raster_op.c 8.1 (Berkeley) 6/11/93
39 * Bitblit routine for raster library.
41 * This raster-op is machined to exacting tolerances by skilled native
42 * craftsmen with pride in their work.
44 * The various cases are broken down like this:
53 * 2-bits to 4-bits (not implemented)
54 * 2-bits to 8-bits (not implemented)
55 * 2-bits to 16-bits (not implemented)
57 * 4-bits to 8-bits (not implemented)
58 * 4-bits to 16-bits (not implemented)
60 * 8-bits to 16-bits (not implemented)
69 #include <sys/cdefs.h>
70 __KERNEL_RCSID(0, "$NetBSD: raster_op.c,v 1.17 2009/03/18 17:06:50 cegger Exp $");
72 #include <sys/types.h>
74 #include "opt_rcons.h"
75 #include <dev/rcons/raster.h>
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.
85 #define PARTIAL_LOGICAL_OPS
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.
97 /* End of configurable definitions. */
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.
111 #ifndef PARTIAL_LOGICAL_OPS
113 #define ROP_DST(op,pre,d,pst) \
138 #define ROP_DSTCOLOR(op,pre,d,c,pst) \
163 #define ROP_SRCDST(op,pre,s,d,pst) \
168 (d) = ~( (s) | (d) ); \
171 case RAS_NOTSRC_AND_DST: \
176 case RAS_INVERTSRC: \
181 case RAS_SRC_AND_NOTDST: \
193 (d) = ~( (s) & (d) ); \
203 (d) = ~( (s) ^ (d) ); \
206 case RAS_NOTSRC_OR_DST: \
216 case RAS_SRC_OR_NOTDST: \
230 #define ROP_SRCDSTCOLOR(op,pre,s,d,c,pst) \
236 (d) = ~( (c) | (d) ); \
241 case RAS_NOTSRC_AND_DST: \
247 case RAS_INVERTSRC: \
255 case RAS_SRC_AND_NOTDST: \
272 (d) = ~( (c) & (d) ); \
288 (d) = ~( (c) ^ (d) ); \
293 case RAS_NOTSRC_OR_DST: \
309 case RAS_SRC_OR_NOTDST: \
327 #else /*PARTIAL_LOGICAL_OPS*/
329 #define ROP_DST(op,pre,d,pst) \
351 #define ROP_DSTCOLOR(op,pre,d,c,pst) \
373 #define ROP_SRCDST(op,pre,s,d,pst) \
376 case RAS_INVERTSRC: \
395 #define ROP_SRCDSTCOLOR(op,pre,s,d,c,pst) \
398 case RAS_INVERTSRC: \
424 #endif /*PARTIAL_LOGICAL_OPS*/
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 */
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 };
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 };
466 #endif /*MSBYTE_FIRST*/
468 #else /*MSBIT_FIRST*/
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 };
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 };
501 #endif /*not MSBYTE_FIRST*/
503 #endif /*MSBIT_FIRST*/
505 /* (The odd combinations MSBIT+~MSBYTE and ~MSBIT+MSBYTE could be added.) */
508 static u_int32_t bytemask
[4] = { 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff };
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 */
517 static u_int32_t fourbitmask
[8] = {
518 0xf0000000, 0x0f000000,
519 0x00f00000, 0x000f0000,
520 0x0000f000, 0x00000f00,
521 0x000000f0, 0x0000000f };
522 #endif /* RCONS_4BPP */
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 };
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 */
536 static u_int32_t fourbitmask
[16] = {
537 0x0000000f, 0x000000f0,
538 0x00000f00, 0x0000f000,
539 0x000f0000, 0x00f00000,
540 0x0f000000, 0xf0000000 };
541 #endif /* RCONS_4BPP */
543 static u_int32_t twobytemask
[2] = { 0x0000ffff, 0xffff0000 };
544 #endif /* RCONS_16BPP */
545 #endif /*MSBYTE_FIRST*/
548 /* Forward routines. */
550 static int raster_blit(struct raster
*, u_int32_t
*, int, int, int,
551 struct raster
*, u_int32_t
*, int, int, int,
554 /* Raster operations. */
556 /* Performs a bitblit. Returns 0 on success, -1 on failure. */
558 raster_op( dst
, dx
, dy
, w
, h
, rop
, src
, sx
, sy
)
560 int dx
, dy
, w
, h
, rop
;
564 if ( dst
== (struct raster
*) 0 )
565 return -1; /* no destination */
567 if ( needsrc
[RAS_GETOP( rop
)] )
569 /* Two-operand blit. */
570 if ( src
== (struct raster
*) 0 )
571 return -1; /* no source */
573 /* Clip against source. */
584 if ( sx
+ w
> src
->width
)
586 if ( sy
+ h
> src
->height
)
587 h
= src
->height
- sy
;
589 /* Clip against dest. */
602 if ( dx
+ w
> dst
->width
)
604 if ( dy
+ h
> dst
->height
)
605 h
= dst
->height
- dy
;
607 if ( w
<= 0 || h
<= 0 )
608 return 0; /* nothing to do */
610 return raster_op_noclip( dst
, dx
, dy
, w
, h
, rop
, src
, sx
, sy
);
613 /* No source necessary - one-operand blit. */
614 if ( src
!= (struct raster
*) 0 )
615 return -1; /* unwanted source */
617 /* Clip against dest. */
628 if ( dx
+ w
> dst
->width
)
630 if ( dy
+ h
> dst
->height
)
631 h
= dst
->height
- dy
;
633 if ( w
<= 0 || h
<= 0 )
634 return 0; /* nothing to do */
636 return raster_op_nosrc_noclip( dst
, dx
, dy
, w
, h
, rop
);
639 /* Semi-public routine to do a bitblit without clipping. Returns 0 on
640 ** success, -1 on failure.
643 raster_op_noclip( dst
, dx
, dy
, w
, h
, rop
, src
, sx
, sy
)
645 int dx
, dy
, w
, h
, rop
;
651 op
= RAS_GETOP( rop
);
653 if ( src
->depth
== 1 )
655 /* One-bit to ? blit. */
656 if ( dst
->depth
== 1 )
658 /* One to one blit. */
661 int srcleftignore
, srcrightignore
, srclongs
;
662 int dstleftignore
, dstrightignore
, dstlongs
;
664 srclin1
= RAS_ADDR( src
, sx
, sy
);
665 dstlin1
= RAS_ADDR( dst
, dx
, dy
);
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 )
673 (char*) srclin1
, (char*) dstlin1
,
674 h
* src
->linelongs
* sizeof(u_int32_t
) );
677 #endif /*BCOPY_FASTER*/
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;
687 src
, srclin1
, srcleftignore
, srcrightignore
, srclongs
,
688 dst
, dstlin1
, dstleftignore
, dstrightignore
, dstlongs
, h
, op
);
692 else if ( dst
->depth
== 2 )
694 /* One to two, using the color in the rop. */
703 int srcbit
, dstbyte
, i
;
705 color
= RAS_GETCOLOR( rop
);
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 ));
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
);
723 while ( srclin
!= srclin2
)
731 /* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */
734 /*pre*/ while ( i
> 0 )
737 /*s*/ *srclong
& raster_bitmask
[srcbit
],
740 /*pst*/ *dstlong
= ( *dstlong
& ~twobitmask
[dstbyte
] ) |
741 ( dl
& twobitmask
[dstbyte
] );
759 srclin
+= src
->linelongs
;
760 dstlin
+= dst
->linelongs
;
763 #endif /* RCONS_2BPP */
765 else if ( dst
->depth
== 4 )
767 /* One to four, using the color in the rop. */
776 int srcbit
, dstbyte
, i
;
778 color
= RAS_GETCOLOR( rop
);
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 )
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
);
795 while ( srclin
!= srclin2
)
803 /* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */
806 /*pre*/ while ( i
> 0 )
809 /*s*/ *srclong
& raster_bitmask
[srcbit
],
812 /*pst*/ *dstlong
= ( *dstlong
& ~fourbitmask
[dstbyte
] ) |
813 ( dl
& fourbitmask
[dstbyte
] );
831 srclin
+= src
->linelongs
;
832 dstlin
+= dst
->linelongs
;
835 #endif /* RCONS_4BPP */
836 else if ( dst
->depth
== 8 )
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.
851 int srcbit
, dstbyte
, i
;
853 color
= RAS_GETCOLOR( rop
);
857 /* Make 32 bits of color so we can do the ROP without shifting. */
858 color
|= ( color
<< 24 ) | ( color
<< 16 ) | ( color
<< 8 );
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
);
866 while ( srclin
!= srclin2
)
874 /* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */
877 /*pre*/ while ( i
> 0 )
880 /*s*/ *srclong
& raster_bitmask
[srcbit
],
883 /*pst*/ *dstlong
= ( *dstlong
& ~bytemask
[dstbyte
] ) |
884 ( dl
& bytemask
[dstbyte
] );
902 srclin
+= src
->linelongs
;
903 dstlin
+= dst
->linelongs
;
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.
922 int srcbit
, dstbyte
, i
;
924 color
= RAS_GETCOLOR( rop
);
928 /* Make 32 bits of color so we can do the ROP without shifting. */
929 color
|= ( color
<< 16 );
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
);
937 while ( srclin
!= srclin2
)
945 /* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */
948 /*pre*/ while ( i
> 0 )
951 /*s*/ *srclong
& raster_bitmask
[srcbit
],
954 /*pst*/ *dstlong
= ( *dstlong
& ~twobytemask
[dstbyte
] ) |
955 ( dl
& twobytemask
[dstbyte
] );
973 srclin
+= src
->linelongs
;
974 dstlin
+= dst
->linelongs
;
977 #endif /* RCONS_16BPP */
980 else if ( src
->depth
== 2 )
982 /* Two to two blit. */
985 int srcleftignore
, srcrightignore
, srclongs
;
986 int dstleftignore
, dstrightignore
, dstlongs
;
988 srclin1
= RAS_ADDR( src
, sx
, sy
);
989 dstlin1
= RAS_ADDR( dst
, dx
, dy
);
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;
999 src
, srclin1
, srcleftignore
, srcrightignore
, srclongs
,
1000 dst
, dstlin1
, dstleftignore
, dstrightignore
, dstlongs
, h
, op
);
1002 #endif /* RCONS_2BPP */
1004 else if ( src
->depth
== 4 )
1006 /* Four to four blit. */
1009 int srcleftignore
, srcrightignore
, srclongs
;
1010 int dstleftignore
, dstrightignore
, dstlongs
;
1012 srclin1
= RAS_ADDR( src
, sx
, sy
);
1013 dstlin1
= RAS_ADDR( dst
, dx
, dy
);
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;
1023 src
, srclin1
, srcleftignore
, srcrightignore
, srclongs
,
1024 dst
, dstlin1
, dstleftignore
, dstrightignore
, dstlongs
, h
, op
);
1026 #endif /* RCONS_4BPP */
1028 else if ( src
->depth
== 8 )
1030 /* Eight to eight blit. */
1033 int srcleftignore
, srcrightignore
, srclongs
;
1034 int dstleftignore
, dstrightignore
, dstlongs
;
1036 if ( dst
->depth
!= 8 )
1037 return -1; /* depth mismatch */
1039 srclin1
= RAS_ADDR( src
, sx
, sy
);
1040 dstlin1
= RAS_ADDR( dst
, dx
, dy
);
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 )
1047 bcopy( (char*) srclin1
, (char*) dstlin1
,
1048 h
* src
->linelongs
* sizeof(u_int32_t
) );
1051 #endif /*BCOPY_FASTER*/
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;
1061 src
, srclin1
, srcleftignore
, srcrightignore
, srclongs
,
1062 dst
, dstlin1
, dstleftignore
, dstrightignore
, dstlongs
, h
, op
);
1067 /* Sixteen to sixteen blit. */
1070 int srcleftignore
, srcrightignore
, srclongs
;
1071 int dstleftignore
, dstrightignore
, dstlongs
;
1073 srclin1
= RAS_ADDR( src
, sx
, sy
);
1074 dstlin1
= RAS_ADDR( dst
, dx
, dy
);
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;
1084 src
, srclin1
, srcleftignore
, srcrightignore
, srclongs
,
1085 dst
, dstlin1
, dstleftignore
, dstrightignore
, dstlongs
, h
, op
);
1087 #endif /* RCONS_16BPP */
1091 /* Semi-public routine to do a no-src bitblit without clipping. Returns 0
1092 ** on success, -1 on failure.
1095 raster_op_nosrc_noclip( dst
, dx
, dy
, w
, h
, rop
)
1097 int dx
, dy
, w
, h
, rop
;
1101 op
= RAS_GETOP( rop
);
1103 if ( dst
->depth
== 1 )
1105 /* One-bit no-src blit. */
1109 int dstleftignore
, dstrightignore
, dstlongs
;
1110 u_int32_t dl
, lm
, nlm
, rm
, nrm
;
1111 u_int32_t
* dstlong2
;
1114 dstlin1
= RAS_ADDR( dst
, dx
, dy
);
1117 /* Special-case full-width clears. */
1118 if ( op
== RAS_CLEAR
&& dst
->width
== w
&& dst
->linelongs
== w
>> 5 )
1120 memset( (char*) dstlin1
, 0, h
* dst
->linelongs
* sizeof(u_int32_t
) );
1123 #endif /*BCOPY_FASTER*/
1125 dstleftignore
= ( dx
& 31 );
1126 dstlongs
= ( dstleftignore
+ w
+ 31 ) >> 5;
1127 dstrightignore
= ( dstlongs
* 32 - w
- dstleftignore
) & 31;
1129 dstlin2
= dstlin1
+ h
* dst
->linelongs
;
1132 if ( dstlongs
== 1 )
1134 /* It fits into a single longword. */
1135 lm
= leftmask
[dstleftignore
] | rightmask
[dstrightignore
];
1137 while ( dstlin
!= dstlin2
)
1141 /*pre*/ dl
= *dstlin
;,
1143 /*pst*/ *dstlin
= ( *dstlin
& lm
) | ( dl
& nlm
); )
1145 dstlin
+= dst
->linelongs
;
1150 lm
= leftmask
[dstleftignore
];
1151 rm
= rightmask
[dstrightignore
];
1155 while ( dstlin
!= dstlin2
)
1158 dstlong2
= dstlong
+ dstlongs
;
1159 if ( dstrightignore
!= 0 )
1163 if ( dstleftignore
!= 0 )
1167 /*pre*/ dl
= *dstlong
;,
1169 /*pst*/ *dstlong
= ( *dstlong
& lm
) | ( dl
& nlm
); )
1176 /*pre*/ while ( dstlong
!= dstlong2
)
1182 /* Trailing edge. */
1183 if ( dstrightignore
!= 0 )
1187 /*pre*/ dl
= *dstlong
;,
1189 /*pst*/ *dstlong
= ( dl
& nrm
) | ( *dstlong
& rm
); )
1192 dstlin
+= dst
->linelongs
;
1198 else if ( dst
->depth
== 2 )
1200 /* Two-bit no-src blit. */
1205 int dstleftignore
, dstrightignore
, dstlongs
;
1206 u_int32_t dl
, lm
, nlm
, rm
, nrm
;
1207 u_int32_t
* dstlong2
;
1210 dstlin1
= RAS_ADDR( dst
, dx
, dy
);
1213 /* Special-case full-width clears. */
1214 if ( op
== RAS_CLEAR
&& dst
->width
== w
&& dst
->linelongs
== w
>> 4 )
1216 memset( (char*) dstlin1
, 0, h
* dst
->linelongs
* sizeof(u_int32_t
) );
1219 #endif /*BCOPY_FASTER*/
1221 color
= RAS_GETCOLOR( rop
);
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 ));
1232 dstleftignore
= ( dx
& 15 ) * 2;
1233 dstlongs
= ( dstleftignore
+ w
* 2 + 31 ) >> 5;
1234 dstrightignore
= ( dstlongs
* 32 - w
* 2 - dstleftignore
) & 31;
1236 dstlin2
= dstlin1
+ h
* dst
->linelongs
;
1239 if ( dstlongs
== 1 )
1241 /* It fits into a single longword. */
1242 lm
= leftmask
[dstleftignore
] | rightmask
[dstrightignore
];
1244 while ( dstlin
!= dstlin2
)
1248 /*pre*/ dl
= *dstlin
;,
1250 /*pst*/ *dstlin
= ( *dstlin
& lm
) | ( dl
& nlm
); )
1252 dstlin
+= dst
->linelongs
;
1257 lm
= leftmask
[dstleftignore
];
1258 rm
= rightmask
[dstrightignore
];
1262 while ( dstlin
!= dstlin2
)
1265 dstlong2
= dstlong
+ dstlongs
;
1266 if ( dstrightignore
!= 0 )
1270 if ( dstleftignore
!= 0 )
1274 /*pre*/ dl
= *dstlong
;,
1276 /*pst*/ *dstlong
= ( *dstlong
& lm
) | ( dl
& nlm
); )
1283 /*pre*/ while ( dstlong
!= dstlong2
)
1289 /* Trailing edge. */
1290 if ( dstrightignore
!= 0 )
1294 /*pre*/ dl
= *dstlong
;,
1296 /*pst*/ *dstlong
= ( dl
& nrm
) | ( *dstlong
& rm
); )
1299 dstlin
+= dst
->linelongs
;
1303 #endif /* RCONS_2BPP */
1305 else if ( dst
->depth
== 4 )
1307 /* Two-bit no-src blit. */
1312 int dstleftignore
, dstrightignore
, dstlongs
;
1313 u_int32_t dl
, lm
, nlm
, rm
, nrm
;
1314 u_int32_t
* dstlong2
;
1317 dstlin1
= RAS_ADDR( dst
, dx
, dy
);
1320 /* Special-case full-width clears. */
1321 if ( op
== RAS_CLEAR
&& dst
->width
== w
&& dst
->linelongs
== w
>> 3 )
1323 memset( (char*) dstlin1
, 0, h
* dst
->linelongs
* sizeof(u_int32_t
) );
1326 #endif /*BCOPY_FASTER*/
1328 color
= RAS_GETCOLOR( rop
);
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 )
1338 dstleftignore
= ( dx
& 7 ) * 4;
1339 dstlongs
= ( dstleftignore
+ w
* 4 + 31 ) >> 5;
1340 dstrightignore
= ( dstlongs
* 32 - w
* 4 - dstleftignore
) & 31;
1342 dstlin2
= dstlin1
+ h
* dst
->linelongs
;
1345 if ( dstlongs
== 1 )
1347 /* It fits into a single longword. */
1348 lm
= leftmask
[dstleftignore
] | rightmask
[dstrightignore
];
1350 while ( dstlin
!= dstlin2
)
1354 /*pre*/ dl
= *dstlin
;,
1356 /*pst*/ *dstlin
= ( *dstlin
& lm
) | ( dl
& nlm
); )
1358 dstlin
+= dst
->linelongs
;
1363 lm
= leftmask
[dstleftignore
];
1364 rm
= rightmask
[dstrightignore
];
1368 while ( dstlin
!= dstlin2
)
1371 dstlong2
= dstlong
+ dstlongs
;
1372 if ( dstrightignore
!= 0 )
1376 if ( dstleftignore
!= 0 )
1380 /*pre*/ dl
= *dstlong
;,
1382 /*pst*/ *dstlong
= ( *dstlong
& lm
) | ( dl
& nlm
); )
1389 /*pre*/ while ( dstlong
!= dstlong2
)
1395 /* Trailing edge. */
1396 if ( dstrightignore
!= 0 )
1400 /*pre*/ dl
= *dstlong
;,
1402 /*pst*/ *dstlong
= ( dl
& nrm
) | ( *dstlong
& rm
); )
1405 dstlin
+= dst
->linelongs
;
1409 #endif /* RCONS_4BPP */
1410 else if ( dst
->depth
== 8)
1412 /* Eight-bit no-src blit. */
1417 int dstleftignore
, dstrightignore
, dstlongs
;
1418 u_int32_t dl
, lm
, nlm
, rm
, nrm
;
1419 u_int32_t
* dstlong2
;
1422 dstlin1
= RAS_ADDR( dst
, dx
, dy
);
1425 /* Special-case full-width clears. */
1426 if ( op
== RAS_CLEAR
&& dst
->width
== w
&& dst
->linelongs
== w
>> 2 )
1428 memset( (char*) dstlin1
, 0, h
* dst
->linelongs
* sizeof(u_int32_t
) );
1431 #endif /*BCOPY_FASTER*/
1433 color
= RAS_GETCOLOR( rop
);
1437 /* Make 32 bits of color so we can do the ROP without shifting. */
1438 color
|= ( color
<< 24 ) | ( color
<< 16 ) | ( color
<< 8 );
1440 dstleftignore
= ( dx
& 3 ) * 8;
1441 dstlongs
= ( dstleftignore
+ w
* 8 + 31 ) >> 5;
1442 dstrightignore
= ( dstlongs
* 32 - w
* 8 - dstleftignore
) & 31;
1444 dstlin2
= dstlin1
+ h
* dst
->linelongs
;
1447 if ( dstlongs
== 1 )
1449 /* It fits into a single longword. */
1450 lm
= leftmask
[dstleftignore
] | rightmask
[dstrightignore
];
1452 while ( dstlin
!= dstlin2
)
1456 /*pre*/ dl
= *dstlin
;,
1459 /*pst*/ *dstlin
= ( *dstlin
& lm
) | ( dl
& nlm
); )
1461 dstlin
+= dst
->linelongs
;
1466 lm
= leftmask
[dstleftignore
];
1467 rm
= rightmask
[dstrightignore
];
1470 while ( dstlin
!= dstlin2
)
1473 dstlong2
= dstlong
+ dstlongs
;
1474 if ( dstrightignore
!= 0 )
1478 if ( dstleftignore
!= 0 )
1482 /*pre*/ dl
= *dstlong
;,
1485 /*pst*/ *dstlong
= ( *dstlong
& lm
) | ( dl
& nlm
); )
1492 /*pre*/ while ( dstlong
!= dstlong2
)
1499 /* Trailing edge. */
1500 if ( dstrightignore
!= 0 )
1504 /*pre*/ dl
= *dstlong
;,
1507 /*pst*/ *dstlong
= ( dl
& nrm
) | ( *dstlong
& rm
); )
1510 dstlin
+= dst
->linelongs
;
1517 /* Sixteen-bit no-src blit. */
1522 int dstleftignore
, dstrightignore
, dstlongs
;
1523 u_int32_t dl
, lm
, nlm
, rm
, nrm
;
1524 u_int32_t
* dstlong2
;
1527 dstlin1
= RAS_ADDR( dst
, dx
, dy
);
1530 /* Special-case full-width clears. */
1531 if ( op
== RAS_CLEAR
&& dst
->width
== w
&& dst
->linelongs
== w
>> 1 )
1533 memset( (char*) dstlin1
, 0, h
* dst
->linelongs
* sizeof(u_int32_t
) );
1536 #endif /*BCOPY_FASTER*/
1538 color
= RAS_GETCOLOR( rop
);
1540 color
= 0xffff; /* XXX */
1542 /* Make 32 bits of color so we can do the ROP without shifting. */
1543 color
|= ( color
<< 16 );
1545 dstleftignore
= ( dx
& 1 ) * 16;
1546 dstlongs
= ( dstleftignore
+ w
* 16 + 31 ) >> 5;
1547 dstrightignore
= ( dstlongs
* 32 - w
* 8 - dstleftignore
) & 31;
1549 dstlin2
= dstlin1
+ h
* dst
->linelongs
;
1552 if ( dstlongs
== 1 )
1554 /* It fits into a single longword. */
1555 lm
= leftmask
[dstleftignore
] | rightmask
[dstrightignore
];
1557 while ( dstlin
!= dstlin2
)
1561 /*pre*/ dl
= *dstlin
;,
1564 /*pst*/ *dstlin
= ( *dstlin
& lm
) | ( dl
& nlm
); )
1566 dstlin
+= dst
->linelongs
;
1571 lm
= leftmask
[dstleftignore
];
1572 rm
= rightmask
[dstrightignore
];
1575 while ( dstlin
!= dstlin2
)
1578 dstlong2
= dstlong
+ dstlongs
;
1579 if ( dstrightignore
!= 0 )
1583 if ( dstleftignore
!= 0 )
1587 /*pre*/ dl
= *dstlong
;,
1590 /*pst*/ *dstlong
= ( *dstlong
& lm
) | ( dl
& nlm
); )
1597 /*pre*/ while ( dstlong
!= dstlong2
)
1604 /* Trailing edge. */
1605 if ( dstrightignore
!= 0 )
1609 /*pre*/ dl
= *dstlong
;,
1612 /*pst*/ *dstlong
= ( dl
& nrm
) | ( *dstlong
& rm
); )
1615 dstlin
+= dst
->linelongs
;
1619 #endif /* RCONS_16BPP */
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.
1628 raster_blit( src
, srclin1
, srcleftignore
, srcrightignore
, srclongs
, dst
, dstlin1
, dstleftignore
, dstrightignore
, dstlongs
, h
, op
)
1631 int srcleftignore
, srcrightignore
, srclongs
;
1634 int dstleftignore
, dstrightignore
, dstlongs
;
1639 int srclininc
, dstlininc
;
1642 int prevleftshift
, currrightshift
;
1646 u_int32_t
* dstlong2
;
1647 u_int32_t dl
, lm
, nlm
, rm
, nrm
;
1649 prevleftshift
= ( srcleftignore
- dstleftignore
) & 31;
1651 srclin2
= srclin1
+ h
* src
->linelongs
;
1652 dstlin2
= dstlin1
+ h
* dst
->linelongs
;
1653 srclininc
= src
->linelongs
;
1654 dstlininc
= dst
->linelongs
;
1657 /* Check for overlaps. */
1658 if ( ( dstlin1
>= srclin1
&& dstlin1
< srclin1
+ srclongs
) ||
1659 ( srclin1
>= dstlin1
&& srclin1
< dstlin1
+ dstlongs
) )
1661 /* Horizontal overlap. Should we reverse? */
1662 if ( srclin1
< dstlin1
)
1665 srclin1
+= srclongs
- 1;
1666 srclin2
+= srclongs
- 1;
1667 dstlin1
+= dstlongs
- 1;
1670 else if ( ( dstlin1
>= srclin1
&& dstlin1
< srclin2
) ||
1671 ( srclin1
>= dstlin1
&& srclin1
< dstlin2
) )
1673 /* Vertical overlap. Should we reverse? */
1674 if ( srclin1
< dstlin1
)
1676 srclin2
= srclin1
- srclininc
;
1677 srclin1
+= ( h
- 1 ) * srclininc
;
1678 dstlin1
+= ( h
- 1 ) * dstlininc
;
1679 srclininc
= -srclininc
;
1680 dstlininc
= -dstlininc
;
1686 if ( prevleftshift
== 0 )
1688 /* The bits line up, no shifting necessary. */
1689 if ( dstlongs
== 1 )
1691 /* It all fits into a single longword. */
1692 lm
= leftmask
[dstleftignore
] | rightmask
[dstrightignore
];
1694 while ( srclin
!= srclin2
)
1698 /*pre*/ dl
= *dstlin
;,
1701 /*pst*/ *dstlin
= ( *dstlin
& lm
) | ( dl
& nlm
); )
1703 srclin
+= srclininc
;
1704 dstlin
+= dstlininc
;
1709 /* Multiple longwords. */
1710 lm
= leftmask
[dstleftignore
];
1711 rm
= rightmask
[dstrightignore
];
1716 /* Left to right. */
1717 while ( srclin
!= srclin2
)
1721 dstlong2
= dstlong
+ dstlongs
;
1722 if ( dstrightignore
!= 0 )
1726 if ( dstleftignore
!= 0 )
1730 /*pre*/ dl
= *dstlong
;,
1733 /*pst*/ *dstlong
= ( *dstlong
& lm
) | ( dl
& nlm
); )
1741 /*pre*/ while ( dstlong
!= dstlong2
)
1749 /* Trailing edge. */
1750 if ( dstrightignore
!= 0 )
1754 /*pre*/ dl
= *dstlong
;,
1757 /*pst*/ *dstlong
= ( dl
& nrm
) | ( *dstlong
& rm
); )
1760 srclin
+= srclininc
;
1761 dstlin
+= dstlininc
;
1766 /* Right to left. */
1767 while ( srclin
!= srclin2
)
1771 dstlong2
= dstlong
- dstlongs
;
1772 if ( dstleftignore
!= 0 )
1776 if ( dstrightignore
!= 0 )
1780 /*pre*/ dl
= *dstlong
;,
1783 /*pst*/ *dstlong
= ( dl
& nrm
) | ( *dstlong
& rm
); )
1791 /*pre*/ while ( dstlong
!= dstlong2
)
1799 /* Trailing edge. */
1800 if ( dstleftignore
!= 0 )
1804 /*pre*/ dl
= *dstlong
;,
1807 /*pst*/ *dstlong
= ( *dstlong
& lm
) | ( dl
& nlm
); )
1810 srclin
+= srclininc
;
1811 dstlin
+= dstlininc
;
1819 /* General case, with shifting and everything. */
1820 u_int32_t sl
, prevsl
;
1822 currrightshift
= 32 - prevleftshift
;
1823 if ( srclongs
== 1 && dstlongs
== 1 )
1825 /* It fits into a single longword, with a shift. */
1826 lm
= leftmask
[dstleftignore
] | rightmask
[dstrightignore
];
1828 if ( srcleftignore
> dstleftignore
)
1830 while ( srclin
!= srclin2
)
1834 /*pre*/ dl
= *dstlin
;,
1835 /*s*/ *srclin LSOP prevleftshift
,
1837 /*pst*/ *dstlin
= ( *dstlin
& lm
) | ( dl
& nlm
); )
1839 srclin
+= srclininc
;
1840 dstlin
+= dstlininc
;
1845 while ( srclin
!= srclin2
)
1849 /*pre*/ dl
= *dstlin
;,
1850 /*s*/ *srclin RSOP currrightshift
,
1852 /*pst*/ *dstlin
= ( *dstlin
& lm
) | ( dl
& nlm
); )
1854 srclin
+= srclininc
;
1855 dstlin
+= dstlininc
;
1861 /* Multiple longwords. */
1862 lm
= leftmask
[dstleftignore
];
1863 rm
= rightmask
[dstrightignore
];
1868 /* Left to right. */
1869 while ( srclin
!= srclin2
)
1873 dstlong2
= dstlong
+ dstlongs
;
1874 if ( srcleftignore
> dstleftignore
)
1875 prevsl
= *srclong
++ LSOP prevleftshift
;
1878 if ( dstrightignore
!= 0 )
1882 if ( dstleftignore
!= 0 )
1886 /*pre*/ sl
= *srclong
;
1888 /*s*/ prevsl
| ( sl RSOP currrightshift
),
1890 /*pst*/ *dstlong
= ( *dstlong
& lm
) | ( dl
& nlm
); )
1891 prevsl
= sl LSOP prevleftshift
;
1899 /*pre*/ while ( dstlong
!= dstlong2
)
1902 /*s*/ prevsl
| ( sl RSOP currrightshift
),
1904 /*pst*/ prevsl
= sl LSOP prevleftshift
;
1909 /* Trailing edge. */
1910 if ( dstrightignore
!= 0 )
1914 /*pre*/ dl
= *dstlong
;,
1915 /*s*/ prevsl
| ( *srclong RSOP currrightshift
),
1917 /*pst*/ *dstlong
= ( dl
& nrm
) | ( *dstlong
& rm
); )
1920 srclin
+= srclininc
;
1921 dstlin
+= dstlininc
;
1926 /* Right to left. */
1927 while ( srclin
!= srclin2
)
1931 dstlong2
= dstlong
- dstlongs
;
1932 if ( srcrightignore
> dstrightignore
)
1933 prevsl
= *srclong
-- RSOP currrightshift
;
1936 if ( dstleftignore
!= 0 )
1940 if ( dstrightignore
!= 0 )
1944 /*pre*/ sl
= *srclong
;
1946 /*s*/ prevsl
| ( sl LSOP prevleftshift
),
1948 /*pst*/ *dstlong
= ( dl
& nrm
) | ( *dstlong
& rm
); )
1949 prevsl
= sl RSOP currrightshift
;
1957 /*pre*/ while ( dstlong
!= dstlong2
)
1960 /*s*/ prevsl
| ( sl LSOP prevleftshift
),
1962 /*pst*/ prevsl
= sl RSOP currrightshift
;
1967 /* Trailing edge. */
1968 if ( dstleftignore
!= 0 )
1972 /*pre*/ dl
= *dstlong
;,
1973 /*s*/ prevsl
| ( *srclong LSOP prevleftshift
),
1975 /*pst*/ *dstlong
= ( *dstlong
& lm
) | ( dl
& nlm
); )
1978 srclin
+= srclininc
;
1979 dstlin
+= dstlininc
;