Module Name: src Committed By: rin Date: Mon Jul 29 02:57:41 UTC 2019
Modified Files: src/sys/dev/rasops: rasops1.c Added Files: src/sys/dev/rasops: rasops1_putchar_width.h Log Message: Clean up for rasops1.c: - dedup ugly copy-paste - rewrite to factorize width-optimized putchar functions - misc style To generate a diff of this commit: cvs rdiff -u -r1.28 -r1.29 src/sys/dev/rasops/rasops1.c cvs rdiff -u -r0 -r1.1 src/sys/dev/rasops/rasops1_putchar_width.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/rasops/rasops1.c diff -u src/sys/dev/rasops/rasops1.c:1.28 src/sys/dev/rasops/rasops1.c:1.29 --- src/sys/dev/rasops/rasops1.c:1.28 Thu Jul 25 03:02:44 2019 +++ src/sys/dev/rasops/rasops1.c Mon Jul 29 02:57:41 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rasops1.c,v 1.28 2019/07/25 03:02:44 rin Exp $ */ +/* $NetBSD: rasops1.c,v 1.29 2019/07/29 02:57:41 rin Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rasops1.c,v 1.28 2019/07/25 03:02:44 rin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rasops1.c,v 1.29 2019/07/29 02:57:41 rin Exp $"); #include "opt_rasops.h" @@ -60,6 +60,12 @@ void rasops1_init(struct rasops_info *ri) { + if ((ri->ri_font->fontwidth & 7) != 0) { + ri->ri_ops.erasecols = rasops1_erasecols; + ri->ri_ops.copycols = rasops1_copycols; + ri->ri_do_cursor = rasops1_do_cursor; + } + switch (ri->ri_font->fontwidth) { #ifndef RASOPS_SMALL case 8: @@ -73,12 +79,6 @@ rasops1_init(struct rasops_info *ri) ri->ri_ops.putchar = rasops1_putchar; break; } - - if ((ri->ri_font->fontwidth & 7) != 0) { - ri->ri_ops.erasecols = rasops1_erasecols; - ri->ri_ops.copycols = rasops1_copycols; - ri->ri_do_cursor = rasops1_do_cursor; - } } /* @@ -87,12 +87,15 @@ rasops1_init(struct rasops_info *ri) static void rasops1_putchar(void *cookie, int row, int col, u_int uc, long attr) { - u_int fs, rs, fb, bg, fg, lmask, rmask; - uint32_t height, width; struct rasops_info *ri = (struct rasops_info *)cookie; struct wsdisplay_font *font = PICK_FONT(ri, uc); - uint32_t *rp, *hrp = NULL, tmp, tmp2; + uint32_t fs, rs, fb, bg, fg, lmask, rmask; + uint32_t height, width; + uint32_t *rp, *hrp, tmp, tmp0, tmp1; uint8_t *fr; + bool space; + + hrp = NULL; /* XXX GCC */ #ifdef RASOPS_CLIPPING /* Catches 'row < 0' case too */ @@ -111,30 +114,31 @@ rasops1_putchar(void *cookie, int row, i ((col >> 3) & ~3)); height = font->fontheight; width = font->fontwidth; - col = col & 31; + col &= 31; rs = ri->ri_stride; bg = (attr & 0x000f0000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0]; fg = (attr & 0x0f000000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0]; /* If fg and bg match this becomes a space character */ - if (fg == bg || uc == ' ') { - uc = (u_int)-1; - fr = 0; /* shutup gcc */ - fs = 0; /* shutup gcc */ + if (uc == ' ' || fg == bg) { + space = true; + fr = NULL; /* XXX GCC */ + fs = 0; /* XXX GCC */ } else { + space = false; fr = FONT_GLYPH(uc, font, ri); fs = font->stride; } - /* Single word, one mask */ - if ((col + width) <= 32) { + if (col + width <= 32) { + /* Single word, only one mask */ + rmask = rasops_pmask[col][width]; lmask = ~rmask; - if (uc == (u_int)-1) { + if (space) { bg &= rmask; - while (height--) { tmp = (*rp & lmask) | bg; *rp = tmp; @@ -145,36 +149,19 @@ rasops1_putchar(void *cookie, int row, i } } } else { - /* NOT fontbits if bg is white */ - if (bg) { - while (height--) { - fb = ~(fr[3] | (fr[2] << 8) | - (fr[1] << 16) | (fr[0] << 24)); - tmp = (*rp & lmask) - | (MBE(fb >> col) & rmask); - *rp = tmp; - - fr += fs; - DELTA(rp, rs, uint32_t *); - if (ri->ri_hwbits) { - *hrp = tmp; - DELTA(hrp, rs, uint32_t *); - } - } - } else { - while (height--) { - fb = (fr[3] | (fr[2] << 8) | - (fr[1] << 16) | (fr[0] << 24)); - tmp = (*rp & lmask) - | (MBE(fb >> col) & rmask); - *rp = tmp; - - fr += fs; - DELTA(rp, rs, uint32_t *); - if (ri->ri_hwbits) { - *hrp = tmp; - DELTA(hrp, rs, uint32_t *); - } + while (height--) { + tmp = *rp & lmask; + fb = fr[3] | (fr[2] << 8) | + (fr[1] << 16) | (fr[0] << 24); + fr += fs; + if (bg) + fb = ~fb; + tmp |= (MBE(fb >> col) & rmask); + *rp = tmp; + DELTA(rp, rs, uint32_t *); + if (ri->ri_hwbits) { + *hrp = tmp; + DELTA(hrp, rs, uint32_t *); } } } @@ -190,68 +177,45 @@ rasops1_putchar(void *cookie, int row, i } } } else { + /* Word boundary, two masks needed */ + lmask = ~rasops_lmask[col]; rmask = ~rasops_rmask[(col + width) & 31]; - if (uc == (u_int)-1) { + if (space) { width = bg & ~rmask; bg = bg & ~lmask; - while (height--) { - tmp = (rp[0] & lmask) | bg; - tmp2 = (rp[1] & rmask) | width; - rp[0] = tmp; - rp[1] = tmp2; + tmp0 = (rp[0] & lmask) | bg; + tmp1 = (rp[1] & rmask) | width; + rp[0] = tmp0; + rp[1] = tmp1; DELTA(rp, rs, uint32_t *); if (ri->ri_hwbits) { - hrp[0] = tmp; - hrp[1] = tmp2; + hrp[0] = tmp0; + hrp[1] = tmp1; DELTA(hrp, rs, uint32_t *); } } } else { width = 32 - col; - - /* NOT fontbits if bg is white */ - if (bg) { - while (height--) { - fb = ~(fr[3] | (fr[2] << 8) | - (fr[1] << 16) | (fr[0] << 24)); - - tmp = (rp[0] & lmask) | - MBE((u_int)fb >> col); - - tmp2 = (rp[1] & rmask) | - (MBE((u_int)fb << width) & ~rmask); - rp[0] = tmp; - rp[1] = tmp2; - fr += fs; - DELTA(rp, rs, uint32_t *); - if (ri->ri_hwbits) { - hrp[0] = tmp; - hrp[1] = tmp2; - DELTA(hrp, rs, uint32_t *); - } - } - } else { - while (height--) { - fb = (fr[3] | (fr[2] << 8) | - (fr[1] << 16) | (fr[0] << 24)); - - tmp = (rp[0] & lmask) | - MBE(fb >> col); - - tmp2 = (rp[1] & rmask) | - (MBE(fb << width) & ~rmask); - rp[0] = tmp; - rp[1] = tmp2; - fr += fs; - DELTA(rp, rs, uint32_t *); - if (ri->ri_hwbits) { - hrp[0] = tmp; - hrp[1] = tmp2; - DELTA(hrp, rs, uint32_t *); - } + while (height--) { + tmp0 = rp[0] & lmask; + tmp1 = rp[1] & rmask; + fb = fr[3] | (fr[2] << 8) | + (fr[1] << 16) | (fr[0] << 24); + fr += fs; + if (bg) + fb = ~fb; + tmp0 |= MBE(fb >> col); + tmp1 |= (MBE(fb << width) & ~rmask); + rp[0] = tmp0; + rp[1] = tmp1; + DELTA(rp, rs, uint32_t *); + if (ri->ri_hwbits) { + hrp[0] = tmp0; + hrp[1] = tmp1; + DELTA(hrp, rs, uint32_t *); } } } @@ -259,179 +223,29 @@ rasops1_putchar(void *cookie, int row, i /* Do underline */ if ((attr & WSATTR_UNDERLINE) != 0) { DELTA(rp, -(ri->ri_stride << 1), uint32_t *); - tmp = (rp[0] & lmask) | (fg & ~lmask); - tmp2 = (rp[1] & rmask) | (fg & ~rmask); - rp[0] = tmp; - rp[1] = tmp2; + tmp0 = (rp[0] & lmask) | (fg & ~lmask); + tmp1 = (rp[1] & rmask) | (fg & ~rmask); + rp[0] = tmp0; + rp[1] = tmp1; if (ri->ri_hwbits) { DELTA(hrp, -(ri->ri_stride << 1), uint32_t *); - hrp[0] = tmp; - hrp[1] = tmp2; + hrp[0] = tmp0; + hrp[1] = tmp1; } } } } #ifndef RASOPS_SMALL -/* - * Paint a single character. This is for 8-pixel wide fonts. - */ -static void -rasops1_putchar8(void *cookie, int row, int col, u_int uc, long attr) -{ - int height, fs, rs, bg, fg; - struct rasops_info *ri = (struct rasops_info *)cookie; - struct wsdisplay_font *font = PICK_FONT(ri, uc); - uint8_t *fr, *rp, *hrp = NULL; - -#ifdef RASOPS_CLIPPING - /* Catches 'row < 0' case too */ - if ((unsigned)row >= (unsigned)ri->ri_rows) - return; - - if ((unsigned)col >= (unsigned)ri->ri_cols) - return; -#endif - - rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale; - if (ri->ri_hwbits) - hrp = ri->ri_hwbits + row * ri->ri_yscale + col * ri->ri_xscale; - height = font->fontheight; - rs = ri->ri_stride; - - bg = (attr & 0x000f0000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0]; - fg = (attr & 0x0f000000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0]; - - /* If fg and bg match this becomes a space character */ - if (fg == bg || uc == ' ') { - while (height--) { - *rp = bg; - rp += rs; - if (ri->ri_hwbits) { - *hrp = bg; - hrp += rs; - } - } - } else { - fr = FONT_GLYPH(uc, font, ri); - fs = font->stride; - - /* NOT fontbits if bg is white */ - if (bg) { - while (height--) { - *rp = ~*fr; - rp += rs; - if (ri->ri_hwbits) { - *hrp = ~*fr; - hrp += rs; - } - fr += fs; - - } - } else { - while (height--) { - *rp = *fr; - rp += rs; - if (ri->ri_hwbits) { - *hrp = *fr; - hrp += rs; - } - fr += fs; - } - } - - } - /* Do underline */ - if ((attr & WSATTR_UNDERLINE) != 0) { - rp[-(ri->ri_stride << 1)] = fg; - if (ri->ri_hwbits) { - hrp[-(ri->ri_stride << 1)] = fg; - } - } -} - -/* - * Paint a single character. This is for 16-pixel wide fonts. - */ -static void -rasops1_putchar16(void *cookie, int row, int col, u_int uc, long attr) -{ - int height, fs, rs, bg, fg; - struct rasops_info *ri = (struct rasops_info *)cookie; - struct wsdisplay_font *font = PICK_FONT(ri, uc); - uint8_t *fr, *rp, *hrp = NULL; - -#ifdef RASOPS_CLIPPING - /* Catches 'row < 0' case too */ - if ((unsigned)row >= (unsigned)ri->ri_rows) - return; - - if ((unsigned)col >= (unsigned)ri->ri_cols) - return; -#endif +#define RASOPS_WIDTH 8 +#include "rasops1_putchar_width.h" +#undef RASOPS_WIDTH + +#define RASOPS_WIDTH 16 +#include "rasops1_putchar_width.h" +#undef RASOPS_WIDTH - rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale; - if (ri->ri_hwbits) - hrp = ri->ri_hwbits + row * ri->ri_yscale + col * ri->ri_xscale; - height = font->fontheight; - rs = ri->ri_stride; - - bg = (attr & 0x000f0000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0]; - fg = (attr & 0x0f000000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0]; - - /* If fg and bg match this becomes a space character */ - if (fg == bg || uc == ' ') { - while (height--) { - /* XXX alignment?! */ - *(uint16_t *)rp = bg; - rp += rs; - if (ri->ri_hwbits) { - *(uint16_t *)hrp = bg; - hrp += rs; - } - } - } else { - fr = FONT_GLYPH(uc, font, ri); - fs = font->stride; - - /* NOT fontbits if bg is white */ - if (bg) { - while (height--) { - rp[0] = ~fr[0]; - rp[1] = ~fr[1]; - rp += rs; - if (ri->ri_hwbits) { - hrp[0] = ~fr[0]; - hrp[1] = ~fr[1]; - hrp += rs; - } - fr += fs; - } - } else { - while (height--) { - rp[0] = fr[0]; - rp[1] = fr[1]; - rp += rs; - if (ri->ri_hwbits) { - hrp[0] = fr[0]; - hrp[1] = fr[1]; - hrp += rs; - } - fr += fs; - } - } - } - - /* Do underline */ - if ((attr & WSATTR_UNDERLINE) != 0) { - /* XXX alignment?! */ - *(uint16_t *)(rp - (ri->ri_stride << 1)) = fg; - if (ri->ri_hwbits) { - *(uint16_t *)(hrp - (ri->ri_stride << 1)) = fg; - } - } -} #endif /* !RASOPS_SMALL */ /* Added files: Index: src/sys/dev/rasops/rasops1_putchar_width.h diff -u /dev/null src/sys/dev/rasops/rasops1_putchar_width.h:1.1 --- /dev/null Mon Jul 29 02:57:41 2019 +++ src/sys/dev/rasops/rasops1_putchar_width.h Mon Jul 29 02:57:41 2019 @@ -0,0 +1,137 @@ +/* $NetBSD: rasops1_putchar_width.h,v 1.1 2019/07/29 02:57:41 rin Exp $ */ + +/* NetBSD: rasops1.c,v 1.28 2019/07/25 03:02:44 rin Exp */ +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Andrew Doran. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#if RASOPS_WIDTH != 8 && RASOPS_WIDTH != 16 +#error "Width not supported" +#endif + +#define PUTCHAR_WIDTH1(width) rasops1_putchar ## width +#define PUTCHAR_WIDTH(width) PUTCHAR_WIDTH1(width) + +#if RASOPS_WIDTH == 8 +#define COPY_UNIT uint8_t +#define GET_GLYPH tmp = fr[0] +#endif + +#if RASOPS_WIDTH == 16 +/* + * rp and hrp are always half-word aligned, whereas + * fr may not be aligned in half-word boundary. + */ +#define COPY_UNIT uint16_t +# if BYTE_ORDER == BIG_ENDIAN +#define GET_GLYPH tmp = (fr[0] << 8) | fr[1] +# else +#define GET_GLYPH tmp = fr[0] | (fr[1] << 8) +# endif +#endif /* RASOPS_WIDTH == 16 */ + +/* + * Width-optimized putchar function. + */ +static void +PUTCHAR_WIDTH(RASOPS_WIDTH)(void *cookie, int row, int col, u_int uc, long attr) +{ + struct rasops_info *ri = (struct rasops_info *)cookie; + struct wsdisplay_font *font = PICK_FONT(ri, uc); + int height, fs, rs, bg, fg; + uint8_t *fr; + COPY_UNIT *rp, *hrp, tmp; + + hrp = NULL; /* XXX GCC */ + +#ifdef RASOPS_CLIPPING + /* Catches 'row < 0' case too */ + if ((unsigned)row >= (unsigned)ri->ri_rows) + return; + + if ((unsigned)col >= (unsigned)ri->ri_cols) + return; +#endif + + rp = (COPY_UNIT *)(ri->ri_bits + row * ri->ri_yscale + + col * sizeof(COPY_UNIT)); + if (ri->ri_hwbits) + hrp = (COPY_UNIT *)(ri->ri_hwbits + row * ri->ri_yscale + + col * sizeof(COPY_UNIT)); + height = font->fontheight; + rs = ri->ri_stride; + + bg = (attr & 0x000f0000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0]; + fg = (attr & 0x0f000000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0]; + + /* If fg and bg match this becomes a space character */ + if (uc == ' ' || fg == bg) { + while (height--) { + *rp = bg; + DELTA(rp, rs, COPY_UNIT *); + } + if (ri->ri_hwbits) { + while (height--) { + *hrp = bg; + DELTA(hrp, rs, COPY_UNIT *); + } + } + } else { + fr = FONT_GLYPH(uc, font, ri); + fs = font->stride; + + while (height--) { + GET_GLYPH; + if (bg) + tmp = ~tmp; + *rp = tmp; + DELTA(rp, rs, COPY_UNIT *); + if (ri->ri_hwbits) { + *hrp = tmp; + DELTA(hrp, rs, COPY_UNIT *); + } + fr += fs; + } + } + + /* Do underline */ + if ((attr & WSATTR_UNDERLINE) != 0) { + DELTA(rp, -(ri->ri_stride << 1), COPY_UNIT *); + *rp = fg; + if (ri->ri_hwbits) { + DELTA(hrp, -(ri->ri_stride << 1), COPY_UNIT *); + *hrp = fg; + } + } +} + +#undef PUTCHAR_WIDTH1 +#undef PUTCHAR_WIDTH + +#undef COPY_UNIT +#undef GET_GLYPH