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