Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/rasops Add width-optimized putchar functions for 32-...



details:   https://anonhg.NetBSD.org/src/rev/4c0f3d25f56a
branches:  trunk
changeset: 457970:4c0f3d25f56a
user:      rin <rin%NetBSD.org@localhost>
date:      Thu Jul 25 15:12:47 2019 +0000

description:
Add width-optimized putchar functions for 32-bpp, that work fine on
both little- and big-endian machines.

WIP genfb(4) driver for mac68k becomes 1.5 times faster!

diffstat:

 sys/dev/rasops/rasops32.c |  477 +++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 474 insertions(+), 3 deletions(-)

diffs (truncated from 510 to 300 lines):

diff -r 0c8ac708d1ad -r 4c0f3d25f56a sys/dev/rasops/rasops32.c
--- a/sys/dev/rasops/rasops32.c Thu Jul 25 15:06:07 2019 +0000
+++ b/sys/dev/rasops/rasops32.c Thu Jul 25 15:12:47 2019 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: rasops32.c,v 1.35 2019/07/25 03:02:44 rin Exp $       */
+/*      $NetBSD: rasops32.c,v 1.36 2019/07/25 15:12:47 rin Exp $       */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rasops32.c,v 1.35 2019/07/25 03:02:44 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rasops32.c,v 1.36 2019/07/25 15:12:47 rin Exp $");
 
 #include "opt_rasops.h"
 
@@ -44,6 +44,30 @@
 
 static void    rasops32_putchar(void *, int, int, u_int, long attr);
 static void    rasops32_putchar_aa(void *, int, int, u_int, long attr);
+#ifndef RASOPS_SMALL
+static void    rasops32_putchar8(void *, int, int, u_int, long);
+static void    rasops32_putchar12(void *, int, int, u_int, long);
+static void    rasops32_putchar16(void *, int, int, u_int, long);
+static void    rasops32_makestamp(struct rasops_info *, long);
+
+/*
+ * 4x1 stamp for optimized character blitting
+ */
+static uint32_t        stamp[64];
+static long    stamp_attr;
+static int     stamp_mutex;    /* XXX see note in readme */
+#endif
+
+/*
+ * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK
+ * destination uint32_t[0] = STAMP_READ(offset)
+ * destination uint32_t[1] = STAMP_READ(offset +  4)
+ * destination uint32_t[2] = STAMP_READ(offset +  8)
+ * destination uint32_t[3] = STAMP_READ(offset + 12)
+ */
+#define        STAMP_SHIFT(fb, n)      ((n) ? (fb) : (fb) << 4)
+#define        STAMP_MASK              (0xf << 4)
+#define        STAMP_READ(o)           (*(uint32_t *)((char *)stamp + (o)))
 
 /*
  * Initialize a 'rasops_info' descriptor for this depth.
@@ -63,8 +87,25 @@
 
        if (FONT_IS_ALPHA(ri->ri_font)) {
                ri->ri_ops.putchar = rasops32_putchar_aa;
-       } else
+               return;
+       }
+
+       switch (ri->ri_font->fontwidth) {
+#ifndef RASOPS_SMALL
+       case 8:
+               ri->ri_ops.putchar = rasops32_putchar8;
+               break;
+       case 12:
+               ri->ri_ops.putchar = rasops32_putchar12;
+               break;
+       case 16:
+               ri->ri_ops.putchar = rasops32_putchar16;
+               break;
+#endif
+       default:
                ri->ri_ops.putchar = rasops32_putchar;
+               break;
+       }
 }
 
 /*
@@ -243,3 +284,433 @@
                        *rp++ = clr[1];
        }
 }
+
+#ifndef RASOPS_SMALL
+/*
+ * Recompute the blitting stamp.
+ */
+static void
+rasops32_makestamp(struct rasops_info *ri, long attr)
+{
+       uint32_t fg, bg;
+       int i;
+
+       fg = ri->ri_devcmap[((uint32_t)attr >> 24) & 0xf];
+       bg = ri->ri_devcmap[((uint32_t)attr >> 16) & 0xf];
+       stamp_attr = attr;
+
+       for (i = 0; i < 64; i += 4) {
+               stamp[i + 0] = (i & 32 ? fg : bg);
+               stamp[i + 1] = (i & 16 ? fg : bg);
+               stamp[i + 2] = (i & 8 ? fg : bg);
+               stamp[i + 3] = (i & 4 ? fg : bg);
+       }
+}
+
+/*
+ * Put a single character. This is for 8-pixel wide fonts.
+ */
+static void
+rasops32_putchar8(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, so, fs;
+       uint32_t *rp, *hrp = NULL;
+       uint8_t *fr;
+
+       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
+
+       /* check if character fits into font limits */
+       if (!CHAR_IN_FONT(uc, font))
+               return;
+
+       /* Can't risk remaking the stamp if it's already in use */
+       if (stamp_mutex++) {
+               stamp_mutex--;
+               rasops32_putchar(cookie, row, col, uc, attr);
+               return;
+       }
+
+       /* Recompute stamp? */
+       if (attr != stamp_attr)
+               rasops32_makestamp(ri, attr);
+
+       rp = (uint32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
+       if (ri->ri_hwbits)
+               hrp = (uint32_t *)(ri->ri_hwbits + row*ri->ri_yscale +
+                   col*ri->ri_xscale);
+
+       height = font->fontheight;
+
+       if (uc == ' ') {
+               while (height--) {
+                       rp[0] = rp[1] = rp[2] = rp[3] =
+                       rp[4] = rp[5] = rp[6] = rp[7] = stamp[0];
+                       DELTA(rp, ri->ri_stride, uint32_t *);
+                       if (ri->ri_hwbits) {
+                               hrp[0] = hrp[1] = hrp[2] = hrp[3] =
+                               hrp[4] = hrp[5] = hrp[6] = hrp[7] = stamp[0];
+                               DELTA(hrp, ri->ri_stride, uint32_t *);
+                       }
+               }
+       } else {
+               fr = FONT_GLYPH(uc, font, ri);
+               fs = font->stride;
+
+               while (height--) {
+                       uint32_t tmp0, tmp1, tmp2, tmp3;
+
+                       so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
+                       tmp0 = STAMP_READ(so);
+                       tmp1 = STAMP_READ(so +  4);
+                       tmp2 = STAMP_READ(so +  8);
+                       tmp3 = STAMP_READ(so + 12);
+                       rp[0] = tmp0;
+                       rp[1] = tmp1;
+                       rp[2] = tmp2;
+                       rp[3] = tmp3;
+                       if (ri->ri_hwbits) {
+                               hrp[0] = tmp0;
+                               hrp[1] = tmp1;
+                               hrp[2] = tmp2;
+                               hrp[3] = tmp3;
+                       }
+
+                       so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
+                       tmp0 = STAMP_READ(so);
+                       tmp1 = STAMP_READ(so +  4);
+                       tmp2 = STAMP_READ(so +  8);
+                       tmp3 = STAMP_READ(so + 12);
+                       rp[4] = tmp0;
+                       rp[5] = tmp1;
+                       rp[6] = tmp2;
+                       rp[7] = tmp3;
+                       if (ri->ri_hwbits) {
+                               hrp[4] = tmp0;
+                               hrp[5] = tmp1;
+                               hrp[6] = tmp2;
+                               hrp[7] = tmp3;
+                       }
+
+                       fr += fs;
+                       DELTA(rp, ri->ri_stride, uint32_t *);
+                       if (ri->ri_hwbits)
+                               DELTA(hrp, ri->ri_stride, uint32_t *);
+               }
+       }
+
+       /* Do underline */
+       if ((attr & WSATTR_UNDERLINE) != 0) {
+               DELTA(rp, -(ri->ri_stride << 1), uint32_t *);
+               rp[0] = rp[1] = rp[2] = rp[3] =
+               rp[4] = rp[5] = rp[6] = rp[7] = stamp[60];
+               if (ri->ri_hwbits)
+                       hrp[0] = hrp[1] = hrp[2] = hrp[3] =
+                       hrp[4] = hrp[5] = hrp[6] = hrp[7] = stamp[60];
+       }
+
+       stamp_mutex--;
+}
+
+/*
+ * Put a single character. This is for 12-pixel wide fonts.
+ */
+static void
+rasops32_putchar12(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, so, fs;
+       uint32_t *rp, *hrp = NULL;
+       uint8_t *fr;
+
+       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
+
+       /* check if character fits into font limits */
+       if (!CHAR_IN_FONT(uc, font))
+               return;
+
+       /* Can't risk remaking the stamp if it's already in use */
+       if (stamp_mutex++) {
+               stamp_mutex--;
+               rasops32_putchar(cookie, row, col, uc, attr);
+               return;
+       }
+
+       /* Recompute stamp? */
+       if (attr != stamp_attr)
+               rasops32_makestamp(ri, attr);
+
+       rp = (uint32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
+       if (ri->ri_hwbits)
+               hrp = (uint32_t *)(ri->ri_hwbits + row*ri->ri_yscale +
+                   col*ri->ri_xscale);
+
+       height = font->fontheight;
+
+       if (uc == ' ') {
+               while (height--) {
+                       rp[0]  = rp[1]  = rp[2]  = rp[3]  =
+                       rp[4]  = rp[5]  = rp[6]  = rp[7]  =
+                       rp[8]  = rp[9]  = rp[10] = rp[11] = stamp[0];
+                       DELTA(rp, ri->ri_stride, uint32_t *);
+                       if (ri->ri_hwbits) {
+                               hrp[0]  = hrp[1]  = hrp[2]  = hrp[3]  =
+                               hrp[4]  = hrp[5]  = hrp[6]  = hrp[7]  =
+                               hrp[8]  = hrp[9]  = hrp[10] = hrp[11] =
+                                   stamp[0];
+                               DELTA(hrp, ri->ri_stride, uint32_t *);
+                       }
+               }
+       } else {
+               fr = FONT_GLYPH(uc, font, ri);
+               fs = font->stride;
+
+               while (height--) {
+                       uint32_t tmp0, tmp1, tmp2, tmp3;
+
+                       so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
+                       tmp0 = STAMP_READ(so);
+                       tmp1 = STAMP_READ(so +  4);
+                       tmp2 = STAMP_READ(so +  8);
+                       tmp3 = STAMP_READ(so + 12);
+                       rp[0] = tmp0;
+                       rp[1] = tmp1;
+                       rp[2] = tmp2;
+                       rp[3] = tmp3;
+                       if (ri->ri_hwbits) {
+                               hrp[0] = tmp0;
+                               hrp[1] = tmp1;
+                               hrp[2] = tmp2;
+                               hrp[3] = tmp3;
+                       }
+



Home | Main Index | Thread Index | Old Index