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