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