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.
This commit is contained in:
parent
f8aba72830
commit
5a795c59e3
|
@ -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 self, void *aux)
|
|||
|
||||
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, uint32_t slots)
|
|||
}
|
||||
|
||||
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, int x, int y, int wi, int he,
|
|||
|
||||
}
|
||||
|
||||
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 col, u_int c, long attr)
|
|||
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 col, u_int c, long attr)
|
|||
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue