Module Name: src Committed By: macallan Date: Thu Mar 28 12:50:31 UTC 2024
Modified Files: src/sys/arch/hppa/dev: gftfb.c Log Message: For some reason the drawing engine occasionally scribbles past the right boundary when filling rectangles, especially annoying when we draw whitespaces As a workaround we draw all rectangles less than 50 pixels wide by drawing a 50 pixel rectangle into off-screen memory to the right of the visible fb and then copy the portion we want. Keeps track of the colour and size of the off-screen rectangle so we can avoid redrawing it whenever possible. To generate a diff of this commit: cvs rdiff -u -r1.11 -r1.12 src/sys/arch/hppa/dev/gftfb.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/arch/hppa/dev/gftfb.c diff -u src/sys/arch/hppa/dev/gftfb.c:1.11 src/sys/arch/hppa/dev/gftfb.c:1.12 --- src/sys/arch/hppa/dev/gftfb.c:1.11 Wed Mar 27 09:08:38 2024 +++ src/sys/arch/hppa/dev/gftfb.c Thu Mar 28 12:50:31 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: gftfb.c,v 1.11 2024/03/27 09:08:38 macallan Exp $ */ +/* $NetBSD: gftfb.c,v 1.12 2024/03/28 12:50:31 macallan Exp $ */ /* $OpenBSD: sti_pci.c,v 1.7 2009/02/06 22:51:04 miod Exp $ */ @@ -88,6 +88,7 @@ struct gftfb_softc { #define HW_FB 0 #define HW_FILL 1 #define HW_BLIT 2 + uint32_t sc_rect_colour, sc_rect_height; /* cursor stuff */ int sc_cursor_x, sc_cursor_y; int sc_hot_x, sc_hot_y, sc_enabled; @@ -250,7 +251,9 @@ gftfb_attach(device_t parent, device_t s sc->sc_width = sc->sc_scr.scr_cfg.scr_width; sc->sc_height = sc->sc_scr.scr_cfg.scr_height; - + sc->sc_rect_colour = 0xf0000000; + sc->sc_rect_height = 0; + aprint_normal_dev(sc->sc_dev, "%s at %dx%d\n", sc->sc_scr.name, sc->sc_width, sc->sc_height); gftfb_setup(sc); @@ -687,6 +690,9 @@ gftfb_setup(struct gftfb_softc *sc) sc->sc_enabled = 0; sc->sc_video_on = 1; + sc->sc_rect_colour = 0xf0000000; + sc->sc_rect_height = 0; + /* set Bt458 read mask register to all planes */ gftfb_wait(sc); ngle_bt458_write(memt, memh, 0x08, 0x04); @@ -1051,7 +1057,7 @@ gftfb_wait_fifo(struct gftfb_softc *sc, } static void -gftfb_rectfill(struct gftfb_softc *sc, int x, int y, int wi, int he, +gftfb_real_rectfill(struct gftfb_softc *sc, int x, int y, int wi, int he, uint32_t bg) { struct sti_rom *rom = sc->sc_base.sc_rom; @@ -1081,6 +1087,30 @@ gftfb_rectfill(struct gftfb_softc *sc, i } +static void +gftfb_rectfill(struct gftfb_softc *sc, int x, int y, int wi, int he, + uint32_t bg) +{ + /* + * For some reason my 4MB VisEG always draws rectangles at least 32 + * pixels wide - no idea why, the bitblt command doesn't have this + * problem. + * So, as a workaround, we draw a 50xFontHeight rectangle to the right + * of the visible fb, keep track of the colour so we don't need to + * redraw every time, and bitblt the portion we need + */ + if (wi < 50) { + if ((bg != sc->sc_rect_colour) || + (he > sc->sc_rect_height)) { + gftfb_real_rectfill(sc, sc->sc_width + 10, 0, 50, + he, bg); + sc->sc_rect_colour = bg; + sc->sc_rect_height = he; + } + gftfb_bitblt(sc, sc->sc_width + 10, 0, x, y, wi, he, RopSrc); + } else + gftfb_real_rectfill(sc, x, y, wi, he, bg); +} static void gftfb_bitblt(void *cookie, int xs, int ys, int xd, int yd, int wi, @@ -1161,9 +1191,8 @@ gftfb_putchar(void *cookie, int row, int struct vcons_screen *scr = ri->ri_hw; struct gftfb_softc *sc = scr->scr_cookie; int x, y, wi, he, rv = GC_NOPE; -#if 0 uint32_t bg; -#endif + if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL) return; @@ -1179,20 +1208,14 @@ gftfb_putchar(void *cookie, int row, int x = ri->ri_xorigin + col * wi; y = ri->ri_yorigin + row * he; -#if 0 + bg = ri->ri_devcmap[(attr >> 16) & 0xf]; - /* XXX - * rectfill currently draws rectangles less than 32 pixels wide as - * 32 pixels wide, no idea why. So until I figure that one out we - * draw blanks by software - * bitblt doesn't seem to have this problem - */ if (c == 0x20) { gftfb_rectfill(sc, x, y, wi, he, bg); return; } -#endif + rv = glyphcache_try(&sc->sc_gc, c, x, y, attr); if (rv == GC_OK) return;