Module Name: src Committed By: macallan Date: Tue Mar 9 22:45:50 UTC 2010
Modified Files: src/sys/dev/pci: wcfb.c Log Message: Use a shadow framebuffer instead of doing every operation twice ( once for each framebuffer ) - this gives quite a dramatic speedup and hides the funky effects previously seen. Almost there, now we need to actually draw a cursor. To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/sys/dev/pci/wcfb.c 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/pci/wcfb.c diff -u src/sys/dev/pci/wcfb.c:1.2 src/sys/dev/pci/wcfb.c:1.3 --- src/sys/dev/pci/wcfb.c:1.2 Thu Feb 25 20:56:20 2010 +++ src/sys/dev/pci/wcfb.c Tue Mar 9 22:45:50 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: wcfb.c,v 1.2 2010/02/25 20:56:20 macallan Exp $ */ +/* $NetBSD: wcfb.c,v 1.3 2010/03/09 22:45:50 macallan Exp $ */ /*- * Copyright (c) 2010 Michael Lorenz @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: wcfb.c,v 1.2 2010/02/25 20:56:20 macallan Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wcfb.c,v 1.3 2010/03/09 22:45:50 macallan Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -39,6 +39,7 @@ #include <sys/kernel.h> #include <sys/systm.h> #include <sys/kauth.h> +#include <sys/kmem.h> #include <dev/pci/pcidevs.h> #include <dev/pci/pcireg.h> @@ -83,7 +84,7 @@ int sc_width, sc_height, sc_stride; int sc_locked; - uint8_t *sc_fbaddr; + uint8_t *sc_fbaddr, *sc_fb0, *sc_fb1, *sc_shadow; struct vcons_screen sc_console_screen; struct wsscreen_descr sc_defaultscreen_descr; const struct wsscreen_descr *sc_screens[1]; @@ -204,10 +205,21 @@ sc->sc_fb0off = bus_space_read_4(sc->sc_regt, sc->sc_regh, 0x8080) - sc->sc_fb; + sc->sc_fb0 = sc->sc_fbaddr + sc->sc_fb0off; + sc->sc_fb1 = sc->sc_fb0 + 0x200000; + sc->sc_stride = 1 << ((bus_space_read_4(sc->sc_regt, sc->sc_regh, 0x8074) & 0x00ff0000) >> 16); printf("%s: %d x %d, %d\n", device_xname(sc->sc_dev), sc->sc_width, sc->sc_height, sc->sc_stride); + + sc->sc_shadow = kmem_alloc(sc->sc_stride * sc->sc_height, KM_SLEEP); + if (sc->sc_shadow == NULL) { + printf("%s: failed to allocate shadow buffer\n", + device_xname(self)); + return; + } + for (i = 0x40; i < 0x100; i += 16) { printf("%04x:", i); for (j = 0; j < 16; j += 4) { @@ -375,7 +387,7 @@ ri->ri_stride = sc->sc_stride; ri->ri_flg = RI_CENTER /*| RI_FULLCLEAR*/; - ri->ri_bits = (char *)sc->sc_fbaddr + sc->sc_fb0off; + ri->ri_bits = sc->sc_shadow; if (existing) { ri->ri_flg |= RI_CLEAR; @@ -408,11 +420,22 @@ struct rasops_info *ri = cookie; struct vcons_screen *scr = ri->ri_hw; struct wcfb_softc *sc = scr->scr_cookie; + int offset = (ri->ri_yorigin + row * ri->ri_font->fontheight) * + sc->sc_stride + ri->ri_xorigin + col * ri->ri_font->fontwidth; + uint8_t *from, *to0, *to1; + int i; sc->putchar(ri, row, col, c, attr); - ri->ri_bits += 0x200000; - sc->putchar(ri, row, col, c, attr); - ri->ri_bits -= 0x200000; + from = sc->sc_shadow + offset; + to0 = sc->sc_fb0 + offset; + to1 = sc->sc_fb1 + offset; + for (i = 0; i < ri->ri_font->fontheight; i++) { + memcpy(to0, from, ri->ri_font->fontwidth); + memcpy(to1, from, ri->ri_font->fontwidth); + to0 += sc->sc_stride; + to1 += sc->sc_stride; + from += sc->sc_stride; + } } static void @@ -441,37 +464,72 @@ struct rasops_info *ri = cookie; struct vcons_screen *scr = ri->ri_hw; struct wcfb_softc *sc = scr->scr_cookie; + int offset = (ri->ri_yorigin + row * ri->ri_font->fontheight) * + sc->sc_stride + ri->ri_xorigin + dstcol * ri->ri_font->fontwidth; + uint8_t *from, *to0, *to1; + int i; sc->copycols(ri, row, srccol, dstcol, ncols); - ri->ri_bits += 0x200000; - sc->copycols(ri, row, srccol, dstcol, ncols); - ri->ri_bits -= 0x200000; + from = sc->sc_shadow + offset; + to0 = sc->sc_fb0 + offset; + to1 = sc->sc_fb1 + offset; + for (i = 0; i < ri->ri_font->fontheight; i++) { + memcpy(to0, from, ri->ri_font->fontwidth * ncols); + memcpy(to1, from, ri->ri_font->fontwidth * ncols); + to0 += sc->sc_stride; + to1 += sc->sc_stride; + from += sc->sc_stride; + } } static void -wcfb_erasecols(void *cookie, int row, int startcol, int ncol, long fillattr) +wcfb_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr) { struct rasops_info *ri = cookie; struct vcons_screen *scr = ri->ri_hw; struct wcfb_softc *sc = scr->scr_cookie; - - sc->erasecols(ri, row, startcol, ncol, fillattr); - ri->ri_bits += 0x200000; - sc->erasecols(ri, row, startcol, ncol, fillattr); - ri->ri_bits -= 0x200000; + int offset = (ri->ri_yorigin + row * ri->ri_font->fontheight) * + sc->sc_stride + ri->ri_xorigin + startcol * ri->ri_font->fontwidth; + uint8_t *to0, *to1; + int i; + + sc->erasecols(ri, row, startcol, ncols, fillattr); + + to0 = sc->sc_fb0 + offset; + to1 = sc->sc_fb1 + offset; + for (i = 0; i < ri->ri_font->fontheight; i++) { + memset(to0, ri->ri_devcmap[(fillattr >> 16) & 0xff], + ri->ri_font->fontwidth * ncols); + memset(to1, ri->ri_devcmap[(fillattr >> 16) & 0xff], + ri->ri_font->fontwidth * ncols); + to0 += sc->sc_stride; + to1 += sc->sc_stride; + } } static void -wcfb_copyrows(void *cookie, int srcrow, int dstrow, int nrow) +wcfb_copyrows(void *cookie, int srcrow, int dstrow, int nrows) { struct rasops_info *ri = cookie; struct vcons_screen *scr = ri->ri_hw; struct wcfb_softc *sc = scr->scr_cookie; - - sc->copyrows(ri, srcrow, dstrow, nrow); - ri->ri_bits += 0x200000; - sc->copyrows(ri, srcrow, dstrow, nrow); - ri->ri_bits -= 0x200000; + int offset = (ri->ri_yorigin + dstrow * ri->ri_font->fontheight) * + sc->sc_stride + ri->ri_xorigin; + uint8_t *from, *to0, *to1; + int i; + + sc->copyrows(ri, srcrow, dstrow, nrows); + + from = sc->sc_shadow + offset; + to0 = sc->sc_fb0 + offset; + to1 = sc->sc_fb1 + offset; + for (i = 0; i < ri->ri_font->fontheight * nrows; i++) { + memcpy(to0, from, ri->ri_emuwidth); + memcpy(to1, from, ri->ri_emuwidth); + to0 += sc->sc_stride; + to1 += sc->sc_stride; + from += sc->sc_stride; + } } static void @@ -480,9 +538,21 @@ struct rasops_info *ri = cookie; struct vcons_screen *scr = ri->ri_hw; struct wcfb_softc *sc = scr->scr_cookie; + int offset = (ri->ri_yorigin + row * ri->ri_font->fontheight) * + sc->sc_stride + ri->ri_xorigin; + uint8_t *to0, *to1; + int i; sc->eraserows(ri, row, nrows, fillattr); - ri->ri_bits += 0x200000; - sc->eraserows(ri, row, nrows, fillattr); - ri->ri_bits -= 0x200000; + + to0 = sc->sc_fb0 + offset; + to1 = sc->sc_fb1 + offset; + for (i = 0; i < ri->ri_font->fontheight * nrows; i++) { + memset(to0, ri->ri_devcmap[(fillattr >> 16) & 0xff], + ri->ri_emuwidth); + memset(to1, ri->ri_devcmap[(fillattr >> 16) & 0xff], + ri->ri_emuwidth); + to0 += sc->sc_stride; + to1 += sc->sc_stride; + } }