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;

Reply via email to