Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/wsfb genfb(4): Make internal parts of struct genfb_s...



details:   https://anonhg.NetBSD.org/src/rev/0bda026e8b90
branches:  trunk
changeset: 368528:0bda026e8b90
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sun Jul 17 13:10:54 2022 +0000

description:
genfb(4): Make internal parts of struct genfb_softc private.

This way the ABI has no ifdefs, so it has a chance to be usable in
modules.  This also makes genfb much easier to maintain without
worrying about ABI breakage.

diffstat:

 sys/dev/wsfb/genfb.c    |  458 ++++++++++++++++++++++++++++-------------------
 sys/dev/wsfb/genfbvar.h |   59 +-----
 2 files changed, 273 insertions(+), 244 deletions(-)

diffs (truncated from 1086 to 300 lines):

diff -r 2763b2fd5a68 -r 0bda026e8b90 sys/dev/wsfb/genfb.c
--- a/sys/dev/wsfb/genfb.c      Sun Jul 17 13:10:04 2022 +0000
+++ b/sys/dev/wsfb/genfb.c      Sun Jul 17 13:10:54 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: genfb.c,v 1.88 2022/07/17 13:10:04 riastradh Exp $ */
+/*     $NetBSD: genfb.c,v 1.89 2022/07/17 13:10:54 riastradh Exp $ */
 
 /*-
  * Copyright (c) 2007 Michael Lorenz
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: genfb.c,v 1.88 2022/07/17 13:10:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: genfb.c,v 1.89 2022/07/17 13:10:54 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -75,6 +75,64 @@
 #define GENFB_BRIGHTNESS_STEP 15
 #define        GENFB_CHAR_WIDTH_MM 3
 
+struct genfb_private {
+       struct genfb_ops sc_ops;
+       struct vcons_screen sc_console_screen;
+       struct wsscreen_descr sc_defaultscreen_descr;
+       const struct wsscreen_descr *sc_screens[1];
+       struct wsscreen_list sc_screenlist;
+       struct genfb_colormap_callback *sc_cmcb;
+       struct genfb_parameter_callback *sc_backlight;
+       struct genfb_parameter_callback *sc_brightness;
+       struct genfb_mode_callback *sc_modecb;
+       int sc_backlight_level, sc_backlight_on;
+       void *sc_shadowfb;
+       bool sc_enable_shadowfb;
+       int sc_mode;
+       u_char sc_cmap_red[256];
+       u_char sc_cmap_green[256];
+       u_char sc_cmap_blue[256];
+       bool sc_want_clear;
+#ifdef SPLASHSCREEN
+       struct splash_info sc_splash;
+#endif
+       struct wsdisplay_accessops sc_accessops;
+#if GENFB_GLYPHCACHE > 0
+       /*
+        * The generic glyphcache code makes a bunch of assumptions that are
+        * true for most graphics hardware with a directly supported blitter.
+        * For example it assume that
+        * - VRAM access from the host is expensive
+        * - copying data around in VRAM is cheap and can happen in parallel
+        *   to the host CPU
+        * -> therefore we draw glyphs normally if we have to, so the ( assumed
+        *    to be hardware assisted ) driver supplied putchar() method doesn't
+        *    need to be glyphcache aware, then copy them away for later use
+        * for genfb things are a bit different. On most hardware:
+        * - VRAM access from the host is still expensive
+        * - copying data around in VRAM is also expensive since we don't have
+        *   a blitter and VRAM is mapped uncached
+        * - VRAM reads are usually slower than writes ( write combining and
+        *   such help writes but not reads, and VRAM might be behind an
+        *   asymmetric bus like AGP ) and must be avoided, both are much
+        *   slower than main memory
+        * -> therefore we cache glyphs in main memory, no reason to map it
+        *    uncached, we draw into the cache first and then copy the glyph
+        *    into video memory to avoid framebuffer reads and to allow more
+        *    efficient write accesses than putchar() would offer
+        * Because of this we can't use the generic code but we can recycle a
+        * few data structures.
+        */
+       uint8_t *sc_cache;
+       struct rasops_info sc_cache_ri;
+       void (*sc_putchar)(void *, int, int, u_int, long);
+       int sc_cache_cells;
+       int sc_nbuckets;        /* buckets allocated */
+       gc_bucket *sc_buckets;  /* we allocate as many as we can get into ram */
+       int sc_attrmap[256];    /* mapping a colour attribute to a bucket */
+#endif
+};
+
 static int     genfb_ioctl(void *, void *, u_long, void *, int, struct lwp *);
 static paddr_t genfb_mmap(void *, void *, off_t, int);
 static void    genfb_pollc(void *, int);
@@ -107,11 +165,14 @@
 void
 genfb_init(struct genfb_softc *sc)
 {
+       struct genfb_private *scp;
        prop_dictionary_t dict;
        uint64_t cmap_cb, pmf_cb, mode_cb, bl_cb, br_cb, fbaddr;
        uint64_t fboffset;
        bool console;
 
+       scp = sc->sc_private = kmem_zalloc(sizeof(*sc->sc_private), KM_SLEEP);
+
        dict = device_properties(sc->sc_dev);
 #ifdef GENFB_DEBUG
        printf("%s", prop_dictionary_externalize(dict));
@@ -120,20 +181,20 @@
 
        if (!prop_dictionary_get_uint32(dict, "width", &sc->sc_width)) {
                GPRINTF("no width property\n");
-               return;
+               goto bad;
        }
        if (!prop_dictionary_get_uint32(dict, "height", &sc->sc_height)) {
                GPRINTF("no height property\n");
-               return;
+               goto bad;
        }
        if (!prop_dictionary_get_uint32(dict, "depth", &sc->sc_depth)) {
                GPRINTF("no depth property\n");
-               return;
+               goto bad;
        }
 
        if (!prop_dictionary_get_uint64(dict, "address", &fboffset)) {
                GPRINTF("no address property\n");
-               return;
+               goto bad;
        }
 
        sc->sc_fboffset = (bus_addr_t)fboffset;
@@ -143,13 +204,13 @@
                sc->sc_fbaddr = (void *)(uintptr_t)fbaddr;
        }
 
-       sc->sc_shadowfb = NULL;
+       scp->sc_shadowfb = NULL;
        if (!prop_dictionary_get_bool(dict, "enable_shadowfb",
-           &sc->sc_enable_shadowfb))
+           &scp->sc_enable_shadowfb))
 #ifdef GENFB_SHADOWFB
-               sc->sc_enable_shadowfb = true;
+               scp->sc_enable_shadowfb = true;
 #else
-               sc->sc_enable_shadowfb = false;
+               scp->sc_enable_shadowfb = false;
 #endif
 
        if (!prop_dictionary_get_uint32(dict, "linebytes", &sc->sc_stride))
@@ -165,10 +226,10 @@
        sc->sc_fbsize = sc->sc_height * sc->sc_stride;
 
        /* optional colour map callback */
-       sc->sc_cmcb = NULL;
+       scp->sc_cmcb = NULL;
        if (prop_dictionary_get_uint64(dict, "cmap_callback", &cmap_cb)) {
                if (cmap_cb != 0)
-                       sc->sc_cmcb = (void *)(vaddr_t)cmap_cb;
+                       scp->sc_cmcb = (void *)(vaddr_t)cmap_cb;
        }
 
        /* optional pmf callback */
@@ -179,31 +240,31 @@
        }
 
        /* optional mode callback */
-       sc->sc_modecb = NULL;
+       scp->sc_modecb = NULL;
        if (prop_dictionary_get_uint64(dict, "mode_callback", &mode_cb)) {
                if (mode_cb != 0)
-                       sc->sc_modecb = (void *)(vaddr_t)mode_cb;
+                       scp->sc_modecb = (void *)(vaddr_t)mode_cb;
        }
 
        /* optional backlight control callback */
-       sc->sc_backlight = NULL;
+       scp->sc_backlight = NULL;
        if (prop_dictionary_get_uint64(dict, "backlight_callback", &bl_cb)) {
                if (bl_cb != 0) {
-                       sc->sc_backlight = (void *)(vaddr_t)bl_cb;
+                       scp->sc_backlight = (void *)(vaddr_t)bl_cb;
                        aprint_naive_dev(sc->sc_dev,
                            "enabling backlight control\n");
                }
        }
 
        /* optional brightness control callback */
-       sc->sc_brightness = NULL;
+       scp->sc_brightness = NULL;
        if (prop_dictionary_get_uint64(dict, "brightness_callback", &br_cb)) {
                if (br_cb != 0) {
-                       sc->sc_brightness = (void *)(vaddr_t)br_cb;
+                       scp->sc_brightness = (void *)(vaddr_t)br_cb;
                        aprint_naive_dev(sc->sc_dev,
                            "enabling brightness control\n");
                        if (console &&
-                           sc->sc_brightness->gpc_upd_parameter != NULL) {
+                           scp->sc_brightness->gpc_upd_parameter != NULL) {
                                pmf_event_register(sc->sc_dev,
                                    PMFE_DISPLAY_BRIGHTNESS_UP,
                                    genfb_brightness_up, TRUE);
@@ -213,11 +274,17 @@
                        }
                }
        }
+
+       return;
+
+bad:   kmem_free(sc->sc_private, sizeof(*sc->sc_private));
+       sc->sc_private = NULL;
 }
 
 int
 genfb_attach(struct genfb_softc *sc, struct genfb_ops *ops)
 {
+       struct genfb_private *scp = sc->sc_private;
        struct wsemuldisplaydev_attach_args aa;
        prop_dictionary_t dict;
        struct rasops_info *ri;
@@ -230,14 +297,16 @@
        int error = ENXIO;
 #endif
 
+       KASSERTMSG(scp != NULL, "missing genfb_init");
+
        dict = device_properties(sc->sc_dev);
        prop_dictionary_get_bool(dict, "is_console", &console);
 
        if (prop_dictionary_get_uint16(dict, "cursor-row", &crow) == false)
                crow = 0;
-       if (prop_dictionary_get_bool(dict, "clear-screen", &sc->sc_want_clear)
+       if (prop_dictionary_get_bool(dict, "clear-screen", &scp->sc_want_clear)
            == false)
-               sc->sc_want_clear = true;
+               scp->sc_want_clear = true;
 
        fb_phys = (paddr_t)sc->sc_fboffset;
        if (fb_phys == 0) {
@@ -251,7 +320,7 @@
            fb_phys ? (void *)(intptr_t)fb_phys : sc->sc_fbaddr,
            sc->sc_width, sc->sc_height, sc->sc_depth, sc->sc_stride);
 
-       sc->sc_defaultscreen_descr = (struct wsscreen_descr){
+       scp->sc_defaultscreen_descr = (struct wsscreen_descr){
                "default",
                0, 0,
                NULL,
@@ -260,38 +329,39 @@
                  WSSCREEN_RESIZE,
                NULL
        };
-       sc->sc_screens[0] = &sc->sc_defaultscreen_descr;
-       sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens};
-       memcpy(&sc->sc_ops, ops, sizeof(struct genfb_ops));
-       sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
-       if (sc->sc_modecb != NULL)
-               sc->sc_modecb->gmc_setmode(sc, sc->sc_mode);
+       scp->sc_screens[0] = &scp->sc_defaultscreen_descr;
+       scp->sc_screenlist = (struct wsscreen_list){1, scp->sc_screens};
+       memcpy(&scp->sc_ops, ops, sizeof(struct genfb_ops));
+       scp->sc_mode = WSDISPLAYIO_MODE_EMUL;
+       if (scp->sc_modecb != NULL)
+               scp->sc_modecb->gmc_setmode(sc, scp->sc_mode);
 
-       sc->sc_accessops.ioctl = genfb_ioctl;
-       sc->sc_accessops.mmap = genfb_mmap;
-       sc->sc_accessops.pollc = genfb_pollc;
+       scp->sc_accessops.ioctl = genfb_ioctl;
+       scp->sc_accessops.mmap = genfb_mmap;
+       scp->sc_accessops.pollc = genfb_pollc;
 
-       if (sc->sc_enable_shadowfb) {
-               sc->sc_shadowfb = kmem_alloc(sc->sc_fbsize, KM_SLEEP);
-               if (sc->sc_want_clear == false)
-                       memcpy(sc->sc_shadowfb, sc->sc_fbaddr, sc->sc_fbsize);
+       if (scp->sc_enable_shadowfb) {
+               scp->sc_shadowfb = kmem_alloc(sc->sc_fbsize, KM_SLEEP);
+               if (scp->sc_want_clear == false) {
+                       memcpy(scp->sc_shadowfb, sc->sc_fbaddr, sc->sc_fbsize);
+               }
                aprint_verbose_dev(sc->sc_dev,
                    "shadow framebuffer enabled, size %zu KB\n",
                    sc->sc_fbsize >> 10);
        }
 
-       vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr,
-           &sc->sc_accessops);
+       vcons_init(&sc->vd, sc, &scp->sc_defaultscreen_descr,
+           &scp->sc_accessops);
        sc->vd.init_screen = genfb_init_screen;
 
        /* Do not print anything between this point and the screen
         * clear operation below.  Otherwise it will be lost. */
 
-       ri = &sc->sc_console_screen.scr_ri;
+       ri = &scp->sc_console_screen.scr_ri;
 
-       vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
+       vcons_init_screen(&sc->vd, &scp->sc_console_screen, 1,
            &defattr);
-       sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
+       scp->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
 
 #if GENFB_GLYPHCACHE > 0
        genfb_setup_glyphcache(sc, defattr);
@@ -304,24 +374,24 @@
  */
        if (DISABLESPLASH)



Home | Main Index | Thread Index | Old Index