Wed Jan 27 22:42:53 2021 UTC ()
add optional glyph cache for genfb
enable with options GENFB_GLYPHCACHE=n
with n being the desired size of the cache in MB. Should be enough to cache
at least 900 glyphs in whatever video mode used in order to be effective
in 32bit per pixel that's about 1MB


(macallan)
diff -r1.11 -r1.12 src/sys/dev/wsfb/files.wsfb
diff -r1.80 -r1.81 src/sys/dev/wsfb/genfb.c
diff -r1.25 -r1.26 src/sys/dev/wsfb/genfbvar.h

cvs diff -r1.11 -r1.12 src/sys/dev/wsfb/files.wsfb (expand / switch to unified diff)

--- src/sys/dev/wsfb/files.wsfb 2019/07/26 10:48:45 1.11
+++ src/sys/dev/wsfb/files.wsfb 2021/01/27 22:42:53 1.12
@@ -1,15 +1,16 @@ @@ -1,15 +1,16 @@
1# $NetBSD: files.wsfb,v 1.11 2019/07/26 10:48:45 rin Exp $ 1# $NetBSD: files.wsfb,v 1.12 2021/01/27 22:42:53 macallan Exp $
2 2
3# 3#
4# wsdisplay framebuffer drivers 4# wsdisplay framebuffer drivers
5# 5#
6 6
7# some generic flags that drivers may or may not honour 7# some generic flags that drivers may or may not honour
8defflag opt_wsfb.h WSFB_FAKE_VGA_FB # allow mmap(0xa0000) 8defflag opt_wsfb.h WSFB_FAKE_VGA_FB # allow mmap(0xa0000)
9defflag opt_wsfb.h WSFB_ALLOW_OTHERS # allow to mmap() foreign ranges 9defflag opt_wsfb.h WSFB_ALLOW_OTHERS # allow to mmap() foreign ranges
10 10
11# a generic framebuffer console 11# a generic framebuffer console
12define genfb: rasops1, rasops2, rasops4, rasops8, rasops15, rasops16, rasops24, rasops32, vcons, edid 12define genfb: rasops1, rasops2, rasops4, rasops8, rasops15, rasops16, rasops24, rasops32, vcons, edid
13device genfb: genfb, wsemuldisplaydev, drm, splash 13device genfb: genfb, wsemuldisplaydev, drm, splash
14file dev/wsfb/genfb.c genfb needs-flag 14file dev/wsfb/genfb.c genfb needs-flag
15defflag opt_genfb.h GENFB_DEBUG GENFB_SHADOWFB 15defflag opt_genfb.h GENFB_DEBUG GENFB_SHADOWFB
 16defparam opt_genfb.h GENFB_GLYPHCACHE=0 # glyphcache size in MB

cvs diff -r1.80 -r1.81 src/sys/dev/wsfb/genfb.c (expand / switch to unified diff)

--- src/sys/dev/wsfb/genfb.c 2021/01/26 18:08:33 1.80
+++ src/sys/dev/wsfb/genfb.c 2021/01/27 22:42:53 1.81
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: genfb.c,v 1.80 2021/01/26 18:08:33 macallan Exp $ */ 1/* $NetBSD: genfb.c,v 1.81 2021/01/27 22:42:53 macallan Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007 Michael Lorenz 4 * Copyright (c) 2007 Michael Lorenz
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -17,27 +17,27 @@ @@ -17,27 +17,27 @@
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: genfb.c,v 1.80 2021/01/26 18:08:33 macallan Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: genfb.c,v 1.81 2021/01/27 22:42:53 macallan Exp $");
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/systm.h> 33#include <sys/systm.h>
34#include <sys/kernel.h> 34#include <sys/kernel.h>
35#include <sys/device.h> 35#include <sys/device.h>
36#include <sys/proc.h> 36#include <sys/proc.h>
37#include <sys/mutex.h> 37#include <sys/mutex.h>
38#include <sys/ioctl.h> 38#include <sys/ioctl.h>
39#include <sys/kernel.h> 39#include <sys/kernel.h>
40#include <sys/systm.h> 40#include <sys/systm.h>
41#include <sys/kmem.h> 41#include <sys/kmem.h>
42#include <sys/reboot.h> 42#include <sys/reboot.h>
43 43
@@ -82,26 +82,31 @@ static void genfb_pollc(void *, int); @@ -82,26 +82,31 @@ static void genfb_pollc(void *, int);
82static void genfb_init_screen(void *, struct vcons_screen *, int, long *); 82static void genfb_init_screen(void *, struct vcons_screen *, int, long *);
83static int genfb_calc_hsize(struct genfb_softc *); 83static int genfb_calc_hsize(struct genfb_softc *);
84static int genfb_calc_cols(struct genfb_softc *); 84static int genfb_calc_cols(struct genfb_softc *);
85 85
86static int genfb_putcmap(struct genfb_softc *, struct wsdisplay_cmap *); 86static int genfb_putcmap(struct genfb_softc *, struct wsdisplay_cmap *);
87static int genfb_getcmap(struct genfb_softc *, struct wsdisplay_cmap *); 87static int genfb_getcmap(struct genfb_softc *, struct wsdisplay_cmap *);
88static int genfb_putpalreg(struct genfb_softc *, uint8_t, uint8_t, 88static int genfb_putpalreg(struct genfb_softc *, uint8_t, uint8_t,
89 uint8_t, uint8_t); 89 uint8_t, uint8_t);
90static void genfb_init_palette(struct genfb_softc *); 90static void genfb_init_palette(struct genfb_softc *);
91 91
92static void genfb_brightness_up(device_t); 92static void genfb_brightness_up(device_t);
93static void genfb_brightness_down(device_t); 93static void genfb_brightness_down(device_t);
94 94
 95#if GENFB_GLYPHCACHE > 0
 96static int genfb_setup_glyphcache(struct genfb_softc *, long);
 97static void genfb_putchar(void *, int, int, u_int, long);
 98#endif
 99
95extern const u_char rasops_cmap[768]; 100extern const u_char rasops_cmap[768];
96 101
97static int genfb_cnattach_called = 0; 102static int genfb_cnattach_called = 0;
98static int genfb_enabled = 1; 103static int genfb_enabled = 1;
99 104
100static struct genfb_softc *genfb_softc = NULL; 105static struct genfb_softc *genfb_softc = NULL;
101 106
102void 107void
103genfb_init(struct genfb_softc *sc) 108genfb_init(struct genfb_softc *sc)
104{ 109{
105 prop_dictionary_t dict; 110 prop_dictionary_t dict;
106 uint64_t cmap_cb, pmf_cb, mode_cb, bl_cb, br_cb, fbaddr; 111 uint64_t cmap_cb, pmf_cb, mode_cb, bl_cb, br_cb, fbaddr;
107 uint64_t fboffset; 112 uint64_t fboffset;
@@ -278,26 +283,30 @@ genfb_attach(struct genfb_softc *sc, str @@ -278,26 +283,30 @@ genfb_attach(struct genfb_softc *sc, str
278 vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr, 283 vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr,
279 &sc->sc_accessops); 284 &sc->sc_accessops);
280 sc->vd.init_screen = genfb_init_screen; 285 sc->vd.init_screen = genfb_init_screen;
281 286
282 /* Do not print anything between this point and the screen 287 /* Do not print anything between this point and the screen
283 * clear operation below. Otherwise it will be lost. */ 288 * clear operation below. Otherwise it will be lost. */
284 289
285 ri = &sc->sc_console_screen.scr_ri; 290 ri = &sc->sc_console_screen.scr_ri;
286 291
287 vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1, 292 vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
288 &defattr); 293 &defattr);
289 sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; 294 sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
290 295
 296#if GENFB_GLYPHCACHE > 0
 297 genfb_setup_glyphcache(sc, defattr);
 298#endif
 299
291#ifdef SPLASHSCREEN 300#ifdef SPLASHSCREEN
292/* 301/*
293 * If system isn't going to go multiuser, or user has requested to see 302 * If system isn't going to go multiuser, or user has requested to see
294 * boot text, don't render splash screen immediately 303 * boot text, don't render splash screen immediately
295 */ 304 */
296 if (DISABLESPLASH) 305 if (DISABLESPLASH)
297#endif 306#endif
298 vcons_redraw_screen(&sc->sc_console_screen); 307 vcons_redraw_screen(&sc->sc_console_screen);
299 308
300 sc->sc_defaultscreen_descr.textops = &ri->ri_ops; 309 sc->sc_defaultscreen_descr.textops = &ri->ri_ops;
301 sc->sc_defaultscreen_descr.capabilities = ri->ri_caps; 310 sc->sc_defaultscreen_descr.capabilities = ri->ri_caps;
302 sc->sc_defaultscreen_descr.nrows = ri->ri_rows; 311 sc->sc_defaultscreen_descr.nrows = ri->ri_rows;
303 sc->sc_defaultscreen_descr.ncols = ri->ri_cols; 312 sc->sc_defaultscreen_descr.ncols = ri->ri_cols;
@@ -622,27 +631,30 @@ genfb_init_screen(void *cookie, struct v @@ -622,27 +631,30 @@ genfb_init_screen(void *cookie, struct v
622 default: 631 default:
623 break; 632 break;
624 } 633 }
625 634
626 wantcols = genfb_calc_cols(sc); 635 wantcols = genfb_calc_cols(sc);
627 636
628 rasops_init(ri, 0, wantcols); 637 rasops_init(ri, 0, wantcols);
629 ri->ri_caps = WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_UNDERLINE | 638 ri->ri_caps = WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_UNDERLINE |
630 WSSCREEN_RESIZE; 639 WSSCREEN_RESIZE;
631 rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight, 640 rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight,
632 sc->sc_width / ri->ri_font->fontwidth); 641 sc->sc_width / ri->ri_font->fontwidth);
633 642
634 ri->ri_hw = scr; 643 ri->ri_hw = scr;
635 644#if GENFB_GLYPHCACHE > 0
 645 sc->sc_putchar = ri->ri_ops.putchar;
 646 ri->ri_ops.putchar = genfb_putchar;
 647#endif
636#ifdef GENFB_DISABLE_TEXT 648#ifdef GENFB_DISABLE_TEXT
637 if (scr == &sc->sc_console_screen && !DISABLESPLASH) 649 if (scr == &sc->sc_console_screen && !DISABLESPLASH)
638 SCREEN_DISABLE_DRAWING(&sc->sc_console_screen); 650 SCREEN_DISABLE_DRAWING(&sc->sc_console_screen);
639#endif 651#endif
640} 652}
641 653
642/* Returns the width of the display in millimeters, or 0 if not known. */ 654/* Returns the width of the display in millimeters, or 0 if not known. */
643static int 655static int
644genfb_calc_hsize(struct genfb_softc *sc) 656genfb_calc_hsize(struct genfb_softc *sc)
645{ 657{
646 device_t dev = sc->sc_dev; 658 device_t dev = sc->sc_dev;
647 prop_dictionary_t dict = device_properties(dev); 659 prop_dictionary_t dict = device_properties(dev);
648 prop_data_t edid_data; 660 prop_data_t edid_data;
@@ -880,13 +892,181 @@ genfb_enable_polling(device_t dev) @@ -880,13 +892,181 @@ genfb_enable_polling(device_t dev)
880} 892}
881 893
882void 894void
883genfb_disable_polling(device_t dev) 895genfb_disable_polling(device_t dev)
884{ 896{
885 struct genfb_softc *sc = device_private(dev); 897 struct genfb_softc *sc = device_private(dev);
886 898
887 if (sc->sc_console_screen.scr_vd) { 899 if (sc->sc_console_screen.scr_vd) {
888 if (sc->sc_ops.genfb_disable_polling) 900 if (sc->sc_ops.genfb_disable_polling)
889 (*sc->sc_ops.genfb_disable_polling)(sc); 901 (*sc->sc_ops.genfb_disable_polling)(sc);
890 vcons_disable_polling(&sc->vd); 902 vcons_disable_polling(&sc->vd);
891 } 903 }
892} 904}
 905
 906#if GENFB_GLYPHCACHE > 0
 907#define GLYPHCACHESIZE ((GENFB_GLYPHCACHE) * 1024 * 1024)
 908
 909static inline int
 910attr2idx(long attr)
 911{
 912 if ((attr & 0xf0f00ff8) != 0)
 913 return -1;
 914
 915 return (((attr >> 16) & 0x0f) | ((attr >> 20) & 0xf0));
 916}
 917
 918static int
 919genfb_setup_glyphcache(struct genfb_softc *sc, long defattr)
 920{
 921 struct rasops_info *ri = &sc->sc_console_screen.scr_ri,
 922 *cri = &sc->sc_cache_ri;
 923 gc_bucket *b;
 924 int i, usedcells = 0, idx, j;
 925
 926 sc->sc_cache = kmem_alloc(GLYPHCACHESIZE, KM_SLEEP);
 927
 928 /*
 929 * now we build a mutant rasops_info for the cache - same pixel type
 930 * and such as the real fb, but only one character per line for
 931 * simplicity and locality
 932 */
 933 memcpy(cri, ri, sizeof(struct rasops_info));
 934 cri->ri_ops.putchar = sc->sc_putchar;
 935 cri->ri_width = ri->ri_font->fontwidth;
 936 cri->ri_stride = ri->ri_xscale;
 937 cri->ri_bits = sc->sc_cache;
 938 cri->ri_hwbits = NULL;
 939 cri->ri_origbits = sc->sc_cache;
 940 cri->ri_cols = 1;
 941 cri->ri_rows = GLYPHCACHESIZE /
 942 (cri->ri_stride * cri->ri_font->fontheight);
 943 cri->ri_xorigin = 0;
 944 cri->ri_yorigin = 0;
 945 cri->ri_xscale = ri->ri_xscale;
 946 cri->ri_yscale = ri->ri_font->fontheight * ri->ri_xscale;
 947
 948 printf("size %d %d %d\n", GLYPHCACHESIZE, ri->ri_width, ri->ri_stride);
 949 printf("cells: %d\n", cri->ri_rows);
 950 sc->sc_nbuckets = uimin(256, cri->ri_rows / 223);
 951 sc->sc_buckets = kmem_alloc(sizeof(gc_bucket) * sc->sc_nbuckets, KM_SLEEP);
 952 printf("buckets: %d\n", sc->sc_nbuckets);
 953 for (i = 0; i < sc->sc_nbuckets; i++) {
 954 b = &sc->sc_buckets[i];
 955 b->gb_firstcell = usedcells;
 956 b->gb_numcells = uimin(223, cri->ri_rows - usedcells);
 957 usedcells += 223;
 958 b->gb_usedcells = 0;
 959 b->gb_index = -1;
 960 for (j = 0; j < 223; j++) b->gb_map[j] = -1;
 961 }
 962
 963 /* initialize the attribute map... */
 964 for (i = 0; i < 256; i++) {
 965 sc->sc_attrmap[i] = -1;
 966 }
 967
 968 /* first bucket goes to default attr */
 969 idx = attr2idx(defattr);
 970 printf("defattr %08lx idx %x\n", defattr, idx);
 971
 972 if (idx >= 0) {
 973 sc->sc_attrmap[idx] = 0;
 974 sc->sc_buckets[0].gb_index = idx;
 975 }
 976
 977 return 0;
 978}
 979
 980static void
 981genfb_putchar(void *cookie, int row, int col, u_int c, long attr)
 982{
 983 struct rasops_info *ri = cookie;
 984 struct vcons_screen *scr = ri->ri_hw;
 985 struct genfb_softc *sc = scr->scr_cookie;
 986 uint8_t *src, *dst;
 987 gc_bucket *b;
 988 int i, idx, bi, cell;
 989
 990 attr &= ~WSATTR_USERMASK;
 991
 992 idx = attr2idx(attr);
 993 if (c < 33 || c > 255 || idx < 0) goto nope;
 994
 995 /* look for a bucket with the right attribute */
 996 bi = sc->sc_attrmap[idx];
 997 if (bi == -1) {
 998 /* nope, see if there's an empty one left */
 999 bi = 1;
 1000 while ((bi < sc->sc_nbuckets) &&
 1001 (sc->sc_buckets[bi].gb_index != -1)) {
 1002 bi++;
 1003 }
 1004 if (bi < sc->sc_nbuckets) {
 1005 /* found one -> grab it */
 1006 sc->sc_attrmap[idx] = bi;
 1007 b = &sc->sc_buckets[bi];
 1008 b->gb_index = idx;
 1009 b->gb_usedcells = 0;
 1010 /* make sure this doesn't get evicted right away */
 1011 b->gb_lastread = time_uptime;
 1012 } else {
 1013 /*
 1014 * still nothing
 1015 * steal the least recently read bucket
 1016 */
 1017 time_t moo = time_uptime;
 1018 int oldest = 1;
 1019
 1020 for (i = 1; i < sc->sc_nbuckets; i++) {
 1021 if (sc->sc_buckets[i].gb_lastread < moo) {
 1022 oldest = i;
 1023 moo = sc->sc_buckets[i].gb_lastread;
 1024 }
 1025 }
 1026
 1027 /* if we end up here all buckets must be in use */
 1028 b = &sc->sc_buckets[oldest];
 1029 sc->sc_attrmap[b->gb_index] = -1;
 1030 b->gb_index = idx;
 1031 b->gb_usedcells = 0;
 1032 sc->sc_attrmap[idx] = oldest;
 1033 /* now scrub it */
 1034 for (i = 0; i < 223; i++)
 1035 b->gb_map[i] = -1;
 1036 /* and set the time stamp */
 1037 b->gb_lastread = time_uptime;
 1038 }
 1039 } else {
 1040 /* found one */
 1041 b = &sc->sc_buckets[bi];
 1042 }
 1043
 1044 /* see if there's room in the bucket */
 1045 if (b->gb_usedcells >= b->gb_numcells) goto nope;
 1046
 1047 cell = b->gb_map[c - 33];
 1048 if (cell == -1) {
 1049 if (b->gb_usedcells >= b->gb_numcells)
 1050 goto nope;
 1051 cell = atomic_add_int_nv(&b->gb_usedcells, 1) - 1;
 1052 b->gb_map[c - 33] = cell;
 1053 cell += b->gb_firstcell;
 1054 sc->sc_putchar(&sc->sc_cache_ri, cell, 0, c, attr);
 1055
 1056 } else
 1057 cell += b->gb_firstcell;
 1058
 1059 src = sc->sc_cache + cell * sc->sc_cache_ri.ri_yscale;
 1060 dst = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
 1061 for (i = 0; i < ri->ri_font->fontheight; i++) {
 1062 memcpy(dst, src, ri->ri_xscale);
 1063 src += ri->ri_xscale;
 1064 dst += ri->ri_stride;
 1065 }
 1066 b->gb_lastread = time_uptime;
 1067 return;
 1068nope:
 1069 sc->sc_putchar(cookie, row, col, c, attr);
 1070}
 1071
 1072#endif

cvs diff -r1.25 -r1.26 src/sys/dev/wsfb/genfbvar.h (expand / switch to unified diff)

--- src/sys/dev/wsfb/genfbvar.h 2017/02/25 01:11:55 1.25
+++ src/sys/dev/wsfb/genfbvar.h 2021/01/27 22:42:53 1.26
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: genfbvar.h,v 1.25 2017/02/25 01:11:55 nonaka Exp $ */ 1/* $NetBSD: genfbvar.h,v 1.26 2021/01/27 22:42:53 macallan Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007 Michael Lorenz 4 * Copyright (c) 2007 Michael Lorenz
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -44,26 +44,30 @@ @@ -44,26 +44,30 @@
44#include <dev/wscons/wsdisplayvar.h> 44#include <dev/wscons/wsdisplayvar.h>
45#include <dev/rasops/rasops.h> 45#include <dev/rasops/rasops.h>
46 46
47#include <dev/wscons/wsdisplay_vconsvar.h> 47#include <dev/wscons/wsdisplay_vconsvar.h>
48#ifdef _KERNEL_OPT 48#ifdef _KERNEL_OPT
49#include "opt_genfb.h" 49#include "opt_genfb.h"
50#endif 50#endif
51 51
52#ifdef SPLASHSCREEN 52#ifdef SPLASHSCREEN
53#define GENFB_DISABLE_TEXT 53#define GENFB_DISABLE_TEXT
54#include <dev/splash/splash.h> 54#include <dev/splash/splash.h>
55#endif 55#endif
56 56
 57#if GENFB_GLYPHCACHE > 0
 58#include <dev/wscons/wsdisplay_glyphcachevar.h>
 59#endif
 60
57struct genfb_softc; 61struct genfb_softc;
58 62
59struct genfb_ops { 63struct genfb_ops {
60 int (*genfb_ioctl)(void *, void *, u_long, void *, int, struct lwp *); 64 int (*genfb_ioctl)(void *, void *, u_long, void *, int, struct lwp *);
61 paddr_t (*genfb_mmap)(void *, void *, off_t, int); 65 paddr_t (*genfb_mmap)(void *, void *, off_t, int);
62 int (*genfb_borrow)(void *, bus_addr_t, bus_space_handle_t *); 66 int (*genfb_borrow)(void *, bus_addr_t, bus_space_handle_t *);
63 int (*genfb_enable_polling)(void *); 67 int (*genfb_enable_polling)(void *);
64 int (*genfb_disable_polling)(void *); 68 int (*genfb_disable_polling)(void *);
65}; 69};
66 70
67struct genfb_colormap_callback { 71struct genfb_colormap_callback {
68 void *gcc_cookie; 72 void *gcc_cookie;
69 void (*gcc_set_mapreg)(void *, int, int, int, int); 73 void (*gcc_set_mapreg)(void *, int, int, int, int);
@@ -115,26 +119,61 @@ struct genfb_softc { @@ -115,26 +119,61 @@ struct genfb_softc {
115 bool sc_enable_shadowfb; 119 bool sc_enable_shadowfb;
116 bus_addr_t sc_fboffset; /* bus address */ 120 bus_addr_t sc_fboffset; /* bus address */
117 int sc_width, sc_height, sc_stride, sc_depth; 121 int sc_width, sc_height, sc_stride, sc_depth;
118 size_t sc_fbsize; 122 size_t sc_fbsize;
119 int sc_mode; 123 int sc_mode;
120 u_char sc_cmap_red[256]; 124 u_char sc_cmap_red[256];
121 u_char sc_cmap_green[256]; 125 u_char sc_cmap_green[256];
122 u_char sc_cmap_blue[256]; 126 u_char sc_cmap_blue[256];
123 bool sc_want_clear; 127 bool sc_want_clear;
124#ifdef SPLASHSCREEN 128#ifdef SPLASHSCREEN
125 struct splash_info sc_splash; 129 struct splash_info sc_splash;
126#endif 130#endif
127 struct wsdisplay_accessops sc_accessops; 131 struct wsdisplay_accessops sc_accessops;
 132#if GENFB_GLYPHCACHE > 0
 133 /*
 134 * The generic glyphcache code makes a bunch of assumptions that are
 135 * true for most graphics hardware with a directly supported blitter.
 136 * For example it assume that
 137 * - VRAM access from the host is expensive
 138 * - copying data around in VRAM is cheap and can happen in parallel
 139 * to the host CPU
 140 * -> therefore we draw glyphs normally if we have to, so the ( assumed
 141 * to be hardware assisted ) driver supplied putchar() method doesn't
 142 * need to be glyphcache aware, then copy them away for later use
 143 * for genfb things are a bit different. On most hardware:
 144 * - VRAM access from the host is still expensive
 145 * - copying data around in VRAM is also expensive since we don't have
 146 * a blitter and VRAM is mapped uncached
 147 * - VRAM reads are usually slower than writes ( write combining and
 148 * such help writes but not reads, and VRAM might be behind an
 149 * asymmetric bus like AGP ) and must be avoided, both are much
 150 * slower than main memory
 151 * -> therefore we cache glyphs in main memory, no reason to map it
 152 * uncached, we draw into the cache first and then copy the glyph
 153 * into video memory to avoid framebuffer reads and to allow more
 154 * efficient write accesses than putchar() would offer
 155 * Because of this we can't use the generic code but we can recycle a
 156 * few data structures.
 157 */
 158 uint8_t *sc_cache;
 159 struct rasops_info sc_cache_ri;
 160 void (*sc_putchar)(void *, int, int, u_int, long);
 161 int sc_cache_cells;
 162 int sc_nbuckets; /* buckets allocated */
 163 gc_bucket *sc_buckets; /* we allocate as many as we can get into ram */
 164 int sc_attrmap[256]; /* mapping a colour attribute to a bucket */
 165#endif
 166
128}; 167};
129 168
130void genfb_cnattach(void); 169void genfb_cnattach(void);
131void genfb_disable(void); 170void genfb_disable(void);
132int genfb_is_console(void); 171int genfb_is_console(void);
133int genfb_is_enabled(void); 172int genfb_is_enabled(void);
134void genfb_init(struct genfb_softc *); 173void genfb_init(struct genfb_softc *);
135int genfb_attach(struct genfb_softc *, struct genfb_ops *); 174int genfb_attach(struct genfb_softc *, struct genfb_ops *);
136int genfb_borrow(bus_addr_t, bus_space_handle_t *); 175int genfb_borrow(bus_addr_t, bus_space_handle_t *);
137void genfb_restore_palette(struct genfb_softc *); 176void genfb_restore_palette(struct genfb_softc *);
138void genfb_enable_polling(device_t); 177void genfb_enable_polling(device_t);
139void genfb_disable_polling(device_t); 178void genfb_disable_polling(device_t);
140 179