rasops24.c revision 1.26 1 /* $NetBSD: rasops24.c,v 1.26 2009/03/14 15:36:20 dsl Exp $ */
2
3 /*-
4 * Copyright (c) 1999 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: rasops24.c,v 1.26 2009/03/14 15:36:20 dsl Exp $");
34
35 #include "opt_rasops.h"
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/time.h>
40
41 #include <machine/endian.h>
42 #include <sys/bswap.h>
43
44 #include <dev/wscons/wsdisplayvar.h>
45 #include <dev/wscons/wsconsio.h>
46 #include <dev/rasops/rasops.h>
47
48 static void rasops24_erasecols(void *, int, int, int, long);
49 static void rasops24_eraserows(void *, int, int, long);
50 static void rasops24_putchar(void *, int, int, u_int, long attr);
51 #ifndef RASOPS_SMALL
52 static void rasops24_putchar8(void *, int, int, u_int, long attr);
53 static void rasops24_putchar12(void *, int, int, u_int, long attr);
54 static void rasops24_putchar16(void *, int, int, u_int, long attr);
55 static void rasops24_makestamp(struct rasops_info *, long);
56 #endif
57
58 /*
59 * 4x1 stamp for optimized character blitting
60 */
61 static int32_t stamp[64];
62 static long stamp_attr;
63 static int stamp_mutex; /* XXX see note in readme */
64
65 /*
66 * XXX this confuses the hell out of gcc2 (not egcs) which always insists
67 * that the shift count is negative.
68 *
69 * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK
70 * destination int32_t[0] = STAMP_READ(offset)
71 * destination int32_t[1] = STAMP_READ(offset + 4)
72 * destination int32_t[2] = STAMP_READ(offset + 8)
73 */
74 #define STAMP_SHIFT(fb,n) ((n*4-4) >= 0 ? (fb)>>(n*4-4):(fb)<<-(n*4-4))
75 #define STAMP_MASK (0xf << 4)
76 #define STAMP_READ(o) (*(int32_t *)((char *)stamp + (o)))
77
78 /*
79 * Initialize rasops_info struct for this colordepth.
80 */
81 void
82 rasops24_init(struct rasops_info *ri)
83 {
84
85 switch (ri->ri_font->fontwidth) {
86 #ifndef RASOPS_SMALL
87 case 8:
88 ri->ri_ops.putchar = rasops24_putchar8;
89 break;
90 case 12:
91 ri->ri_ops.putchar = rasops24_putchar12;
92 break;
93 case 16:
94 ri->ri_ops.putchar = rasops24_putchar16;
95 break;
96 #endif
97 default:
98 ri->ri_ops.putchar = rasops24_putchar;
99 break;
100 }
101
102 if (ri->ri_rnum == 0) {
103 ri->ri_rnum = 8;
104 ri->ri_rpos = 0;
105 ri->ri_gnum = 8;
106 ri->ri_gpos = 8;
107 ri->ri_bnum = 8;
108 ri->ri_bpos = 16;
109 }
110
111 ri->ri_ops.erasecols = rasops24_erasecols;
112 ri->ri_ops.eraserows = rasops24_eraserows;
113 }
114
115 /*
116 * Put a single character. This is the generic version.
117 * XXX this bites - we should use masks.
118 */
119 static void
120 rasops24_putchar(cookie, row, col, uc, attr)
121 void *cookie;
122 int row, col;
123 u_int uc;
124 long attr;
125 {
126 int fb, width, height, cnt, clr[2];
127 struct rasops_info *ri;
128 u_char *dp, *rp, *fr;
129
130 ri = (struct rasops_info *)cookie;
131
132 #ifdef RASOPS_CLIPPING
133 /* Catches 'row < 0' case too */
134 if ((unsigned)row >= (unsigned)ri->ri_rows)
135 return;
136
137 if ((unsigned)col >= (unsigned)ri->ri_cols)
138 return;
139 #endif
140
141 rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
142 height = ri->ri_font->fontheight;
143 width = ri->ri_font->fontwidth;
144
145 clr[1] = ri->ri_devcmap[((u_int)attr >> 24) & 0xf];
146 clr[0] = ri->ri_devcmap[((u_int)attr >> 16) & 0xf];
147
148 if (uc == ' ') {
149 u_char c = clr[0];
150 while (height--) {
151 dp = rp;
152 rp += ri->ri_stride;
153
154 for (cnt = width; cnt; cnt--) {
155 *dp++ = c >> 16;
156 *dp++ = c >> 8;
157 *dp++ = c;
158 }
159 }
160 } else {
161 uc -= ri->ri_font->firstchar;
162 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
163
164 while (height--) {
165 dp = rp;
166 fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) |
167 (fr[0] << 24);
168 fr += ri->ri_font->stride;
169 rp += ri->ri_stride;
170
171 for (cnt = width; cnt; cnt--, fb <<= 1) {
172 if ((fb >> 31) & 1) {
173 *dp++ = clr[1] >> 16;
174 *dp++ = clr[1] >> 8;
175 *dp++ = clr[1];
176 } else {
177 *dp++ = clr[0] >> 16;
178 *dp++ = clr[0] >> 8;
179 *dp++ = clr[0];
180 }
181 }
182 }
183 }
184
185 /* Do underline */
186 if ((attr & 1) != 0) {
187 u_char c = clr[1];
188
189 rp -= ri->ri_stride << 1;
190
191 while (width--) {
192 *rp++ = c >> 16;
193 *rp++ = c >> 8;
194 *rp++ = c;
195 }
196 }
197 }
198
199 #ifndef RASOPS_SMALL
200 /*
201 * Recompute the blitting stamp.
202 */
203 static void
204 rasops24_makestamp(struct rasops_info *ri, long attr)
205 {
206 u_int fg, bg, c1, c2, c3, c4;
207 int i;
208
209 fg = ri->ri_devcmap[((u_int)attr >> 24) & 0xf] & 0xffffff;
210 bg = ri->ri_devcmap[((u_int)attr >> 16) & 0xf] & 0xffffff;
211 stamp_attr = attr;
212
213 for (i = 0; i < 64; i += 4) {
214 #if BYTE_ORDER == LITTLE_ENDIAN
215 c1 = (i & 32 ? fg : bg);
216 c2 = (i & 16 ? fg : bg);
217 c3 = (i & 8 ? fg : bg);
218 c4 = (i & 4 ? fg : bg);
219 #else
220 c1 = (i & 8 ? fg : bg);
221 c2 = (i & 4 ? fg : bg);
222 c3 = (i & 16 ? fg : bg);
223 c4 = (i & 32 ? fg : bg);
224 #endif
225 stamp[i+0] = (c1 << 8) | (c2 >> 16);
226 stamp[i+1] = (c2 << 16) | (c3 >> 8);
227 stamp[i+2] = (c3 << 24) | c4;
228
229 #if BYTE_ORDER == LITTLE_ENDIAN
230 if ((ri->ri_flg & RI_BSWAP) == 0) {
231 #else
232 if ((ri->ri_flg & RI_BSWAP) != 0) {
233 #endif
234 stamp[i+0] = bswap32(stamp[i+0]);
235 stamp[i+1] = bswap32(stamp[i+1]);
236 stamp[i+2] = bswap32(stamp[i+2]);
237 }
238 }
239 }
240
241 /*
242 * Put a single character. This is for 8-pixel wide fonts.
243 */
244 static void
245 rasops24_putchar8(cookie, row, col, uc, attr)
246 void *cookie;
247 int row, col;
248 u_int uc;
249 long attr;
250 {
251 struct rasops_info *ri;
252 int height, so, fs;
253 int32_t *rp;
254 u_char *fr;
255
256 /* Can't risk remaking the stamp if it's already in use */
257 if (stamp_mutex++) {
258 stamp_mutex--;
259 rasops24_putchar(cookie, row, col, uc, attr);
260 return;
261 }
262
263 ri = (struct rasops_info *)cookie;
264
265 #ifdef RASOPS_CLIPPING
266 if ((unsigned)row >= (unsigned)ri->ri_rows) {
267 stamp_mutex--;
268 return;
269 }
270
271 if ((unsigned)col >= (unsigned)ri->ri_cols) {
272 stamp_mutex--;
273 return;
274 }
275 #endif
276
277 /* Recompute stamp? */
278 if (attr != stamp_attr)
279 rasops24_makestamp(ri, attr);
280
281 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
282 height = ri->ri_font->fontheight;
283
284 if (uc == (u_int)-1) {
285 int32_t c = stamp[0];
286 while (height--) {
287 rp[0] = rp[1] = rp[2] = rp[3] = rp[4] = rp[5] = c;
288 DELTA(rp, ri->ri_stride, int32_t *);
289 }
290 } else {
291 uc -= ri->ri_font->firstchar;
292 fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
293 fs = ri->ri_font->stride;
294
295 while (height--) {
296 so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
297 rp[0] = STAMP_READ(so);
298 rp[1] = STAMP_READ(so + 4);
299 rp[2] = STAMP_READ(so + 8);
300
301 so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
302 rp[3] = STAMP_READ(so);
303 rp[4] = STAMP_READ(so + 4);
304 rp[5] = STAMP_READ(so + 8);
305
306 fr += fs;
307 DELTA(rp, ri->ri_stride, int32_t *);
308 }
309 }
310
311 /* Do underline */
312 if ((attr & 1) != 0) {
313 int32_t c = STAMP_READ(52);
314
315 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
316 rp[0] = rp[1] = rp[2] = rp[3] = rp[4] = rp[5] = c;
317 }
318
319 stamp_mutex--;
320 }
321
322 /*
323 * Put a single character. This is for 12-pixel wide fonts.
324 */
325 static void
326 rasops24_putchar12(cookie, row, col, uc, attr)
327 void *cookie;
328 int row, col;
329 u_int uc;
330 long attr;
331 {
332 struct rasops_info *ri;
333 int height, so, fs;
334 int32_t *rp;
335 u_char *fr;
336
337 /* Can't risk remaking the stamp if it's already in use */
338 if (stamp_mutex++) {
339 stamp_mutex--;
340 rasops24_putchar(cookie, row, col, uc, attr);
341 return;
342 }
343
344 ri = (struct rasops_info *)cookie;
345
346 #ifdef RASOPS_CLIPPING
347 if ((unsigned)row >= (unsigned)ri->ri_rows) {
348 stamp_mutex--;
349 return;
350 }
351
352 if ((unsigned)col >= (unsigned)ri->ri_cols) {
353 stamp_mutex--;
354 return;
355 }
356 #endif
357
358 /* Recompute stamp? */
359 if (attr != stamp_attr)
360 rasops24_makestamp(ri, attr);
361
362 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
363 height = ri->ri_font->fontheight;
364
365 if (uc == (u_int)-1) {
366 int32_t c = stamp[0];
367 while (height--) {
368 rp[0] = rp[1] = rp[2] = rp[3] =
369 rp[4] = rp[5] = rp[6] = rp[7] = rp[8] = c;
370 DELTA(rp, ri->ri_stride, int32_t *);
371 }
372 } else {
373 uc -= ri->ri_font->firstchar;
374 fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
375 fs = ri->ri_font->stride;
376
377 while (height--) {
378 so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
379 rp[0] = STAMP_READ(so);
380 rp[1] = STAMP_READ(so + 4);
381 rp[2] = STAMP_READ(so + 8);
382
383 so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
384 rp[3] = STAMP_READ(so);
385 rp[4] = STAMP_READ(so + 4);
386 rp[5] = STAMP_READ(so + 8);
387
388 so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
389 rp[6] = STAMP_READ(so);
390 rp[7] = STAMP_READ(so + 4);
391 rp[8] = STAMP_READ(so + 8);
392
393 fr += fs;
394 DELTA(rp, ri->ri_stride, int32_t *);
395 }
396 }
397
398 /* Do underline */
399 if ((attr & 1) != 0) {
400 int32_t c = STAMP_READ(52);
401
402 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
403 rp[0] = rp[1] = rp[2] = rp[3] =
404 rp[4] = rp[5] = rp[6] = rp[7] = rp[8] = c;
405 }
406
407 stamp_mutex--;
408 }
409
410 /*
411 * Put a single character. This is for 16-pixel wide fonts.
412 */
413 static void
414 rasops24_putchar16(cookie, row, col, uc, attr)
415 void *cookie;
416 int row, col;
417 u_int uc;
418 long attr;
419 {
420 struct rasops_info *ri;
421 int height, so, fs;
422 int32_t *rp;
423 u_char *fr;
424
425 /* Can't risk remaking the stamp if it's already in use */
426 if (stamp_mutex++) {
427 stamp_mutex--;
428 rasops24_putchar(cookie, row, col, uc, attr);
429 return;
430 }
431
432 ri = (struct rasops_info *)cookie;
433
434 #ifdef RASOPS_CLIPPING
435 if ((unsigned)row >= (unsigned)ri->ri_rows) {
436 stamp_mutex--;
437 return;
438 }
439
440 if ((unsigned)col >= (unsigned)ri->ri_cols) {
441 stamp_mutex--;
442 return;
443 }
444 #endif
445
446 /* Recompute stamp? */
447 if (attr != stamp_attr)
448 rasops24_makestamp(ri, attr);
449
450 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
451 height = ri->ri_font->fontheight;
452
453 if (uc == (u_int)-1) {
454 int32_t c = stamp[0];
455 while (height--) {
456 rp[0] = rp[1] = rp[2] = rp[3] =
457 rp[4] = rp[5] = rp[6] = rp[7] =
458 rp[8] = rp[9] = rp[10] = rp[11] = c;
459 DELTA(rp, ri->ri_stride, int32_t *);
460 }
461 } else {
462 uc -= ri->ri_font->firstchar;
463 fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
464 fs = ri->ri_font->stride;
465
466 while (height--) {
467 so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
468 rp[0] = STAMP_READ(so);
469 rp[1] = STAMP_READ(so + 4);
470 rp[2] = STAMP_READ(so + 8);
471
472 so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
473 rp[3] = STAMP_READ(so);
474 rp[4] = STAMP_READ(so + 4);
475 rp[5] = STAMP_READ(so + 8);
476
477 so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
478 rp[6] = STAMP_READ(so);
479 rp[7] = STAMP_READ(so + 4);
480 rp[8] = STAMP_READ(so + 8);
481
482 so = STAMP_SHIFT(fr[1], 0) & STAMP_MASK;
483 rp[9] = STAMP_READ(so);
484 rp[10] = STAMP_READ(so + 4);
485 rp[11] = STAMP_READ(so + 8);
486
487 DELTA(rp, ri->ri_stride, int32_t *);
488 fr += fs;
489 }
490 }
491
492 /* Do underline */
493 if ((attr & 1) != 0) {
494 int32_t c = STAMP_READ(52);
495
496 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
497 rp[0] = rp[1] = rp[2] = rp[3] =
498 rp[4] = rp[5] = rp[6] = rp[7] =
499 rp[8] = rp[9] = rp[10] = rp[11] = c;
500 }
501
502 stamp_mutex--;
503 }
504 #endif /* !RASOPS_SMALL */
505
506 /*
507 * Erase rows. This is nice and easy due to alignment.
508 */
509 static void
510 rasops24_eraserows(cookie, row, num, attr)
511 void *cookie;
512 int row, num;
513 long attr;
514 {
515 int n9, n3, n1, cnt, stride, delta;
516 u_int32_t *dp, clr, xstamp[3];
517 struct rasops_info *ri;
518
519 /*
520 * If the color is gray, we can cheat and use the generic routines
521 * (which are faster, hopefully) since the r,g,b values are the same.
522 */
523 if ((attr & 4) != 0) {
524 rasops_eraserows(cookie, row, num, attr);
525 return;
526 }
527
528 ri = (struct rasops_info *)cookie;
529
530 #ifdef RASOPS_CLIPPING
531 if (row < 0) {
532 num += row;
533 row = 0;
534 }
535
536 if ((row + num) > ri->ri_rows)
537 num = ri->ri_rows - row;
538
539 if (num <= 0)
540 return;
541 #endif
542
543 clr = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xffffff;
544 xstamp[0] = (clr << 8) | (clr >> 16);
545 xstamp[1] = (clr << 16) | (clr >> 8);
546 xstamp[2] = (clr << 24) | clr;
547
548 #if BYTE_ORDER == LITTLE_ENDIAN
549 if ((ri->ri_flg & RI_BSWAP) == 0) {
550 #else
551 if ((ri->ri_flg & RI_BSWAP) != 0) {
552 #endif
553 xstamp[0] = bswap32(xstamp[0]);
554 xstamp[1] = bswap32(xstamp[1]);
555 xstamp[2] = bswap32(xstamp[2]);
556 }
557
558 /*
559 * XXX the wsdisplay_emulops interface seems a little deficient in
560 * that there is no way to clear the *entire* screen. We provide a
561 * workaround here: if the entire console area is being cleared, and
562 * the RI_FULLCLEAR flag is set, clear the entire display.
563 */
564 if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR) != 0) {
565 stride = ri->ri_stride;
566 num = ri->ri_height;
567 dp = (int32_t *)ri->ri_origbits;
568 delta = 0;
569 } else {
570 stride = ri->ri_emustride;
571 num *= ri->ri_font->fontheight;
572 dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
573 delta = ri->ri_delta;
574 }
575
576 n9 = stride / 36;
577 cnt = (n9 << 5) + (n9 << 2); /* (32*n9) + (4*n9) */
578 n3 = (stride - cnt) / 12;
579 cnt += (n3 << 3) + (n3 << 2); /* (8*n3) + (4*n3) */
580 n1 = (stride - cnt) >> 2;
581
582 while (num--) {
583 for (cnt = n9; cnt; cnt--) {
584 dp[0] = xstamp[0];
585 dp[1] = xstamp[1];
586 dp[2] = xstamp[2];
587 dp[3] = xstamp[0];
588 dp[4] = xstamp[1];
589 dp[5] = xstamp[2];
590 dp[6] = xstamp[0];
591 dp[7] = xstamp[1];
592 dp[8] = xstamp[2];
593 dp += 9;
594 }
595
596 for (cnt = n3; cnt; cnt--) {
597 dp[0] = xstamp[0];
598 dp[1] = xstamp[1];
599 dp[2] = xstamp[2];
600 dp += 3;
601 }
602
603 for (cnt = 0; cnt < n1; cnt++)
604 *dp++ = xstamp[cnt];
605
606 DELTA(dp, delta, int32_t *);
607 }
608 }
609
610 /*
611 * Erase columns.
612 */
613 static void
614 rasops24_erasecols(cookie, row, col, num, attr)
615 void *cookie;
616 int row, col, num;
617 long attr;
618 {
619 int n12, n4, height, cnt, slop, clr, xstamp[3];
620 struct rasops_info *ri;
621 int32_t *dp, *rp;
622 u_char *dbp;
623
624 /*
625 * If the color is gray, we can cheat and use the generic routines
626 * (which are faster, hopefully) since the r,g,b values are the same.
627 */
628 if ((attr & 4) != 0) {
629 rasops_erasecols(cookie, row, col, num, attr);
630 return;
631 }
632
633 ri = (struct rasops_info *)cookie;
634
635 #ifdef RASOPS_CLIPPING
636 /* Catches 'row < 0' case too */
637 if ((unsigned)row >= (unsigned)ri->ri_rows)
638 return;
639
640 if (col < 0) {
641 num += col;
642 col = 0;
643 }
644
645 if ((col + num) > ri->ri_cols)
646 num = ri->ri_cols - col;
647
648 if (num <= 0)
649 return;
650 #endif
651
652 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
653 num *= ri->ri_font->fontwidth;
654 height = ri->ri_font->fontheight;
655
656 clr = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xffffff;
657 xstamp[0] = (clr << 8) | (clr >> 16);
658 xstamp[1] = (clr << 16) | (clr >> 8);
659 xstamp[2] = (clr << 24) | clr;
660
661 #if BYTE_ORDER == LITTLE_ENDIAN
662 if ((ri->ri_flg & RI_BSWAP) == 0) {
663 #else
664 if ((ri->ri_flg & RI_BSWAP) != 0) {
665 #endif
666 xstamp[0] = bswap32(xstamp[0]);
667 xstamp[1] = bswap32(xstamp[1]);
668 xstamp[2] = bswap32(xstamp[2]);
669 }
670
671 /*
672 * The current byte offset mod 4 tells us the number of 24-bit pels
673 * we need to write for alignment to 32-bits. Once we're aligned on
674 * a 32-bit boundary, we're also aligned on a 4 pixel boundary, so
675 * the stamp does not need to be rotated. The following shows the
676 * layout of 4 pels in a 3 word region and illustrates this:
677 *
678 * aaab bbcc cddd
679 */
680 slop = (int)(long)rp & 3; num -= slop;
681 n12 = num / 12; num -= (n12 << 3) + (n12 << 2);
682 n4 = num >> 2; num &= 3;
683
684 while (height--) {
685 dbp = (u_char *)rp;
686 DELTA(rp, ri->ri_stride, int32_t *);
687
688 /* Align to 4 bytes */
689 /* XXX handle with masks, bring under control of RI_BSWAP */
690 for (cnt = slop; cnt; cnt--) {
691 *dbp++ = (clr >> 16);
692 *dbp++ = (clr >> 8);
693 *dbp++ = clr;
694 }
695
696 dp = (int32_t *)dbp;
697
698 /* 12 pels per loop */
699 for (cnt = n12; cnt; cnt--) {
700 dp[0] = xstamp[0];
701 dp[1] = xstamp[1];
702 dp[2] = xstamp[2];
703 dp[3] = xstamp[0];
704 dp[4] = xstamp[1];
705 dp[5] = xstamp[2];
706 dp[6] = xstamp[0];
707 dp[7] = xstamp[1];
708 dp[8] = xstamp[2];
709 dp += 9;
710 }
711
712 /* 4 pels per loop */
713 for (cnt = n4; cnt; cnt--) {
714 dp[0] = xstamp[0];
715 dp[1] = xstamp[1];
716 dp[2] = xstamp[2];
717 dp += 3;
718 }
719
720 /* Trailing slop */
721 /* XXX handle with masks, bring under control of RI_BSWAP */
722 dbp = (u_char *)dp;
723 for (cnt = num; cnt; cnt--) {
724 *dbp++ = (clr >> 16);
725 *dbp++ = (clr >> 8);
726 *dbp++ = clr;
727 }
728 }
729 }
730