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