Module Name: src Committed By: macallan Date: Thu Aug 9 00:48:07 UTC 2012
Modified Files: src/sys/arch/sparc64/dev: ffb.c ffbreg.h Log Message: split ffb_putchar() into a version for mono fonts and one for anti-aliased ones. While there use the blitter to draw the cursor and remove some waits that are unnecessary now that characters are drawn by hardware. To generate a diff of this commit: cvs rdiff -u -r1.51 -r1.52 src/sys/arch/sparc64/dev/ffb.c cvs rdiff -u -r1.10 -r1.11 src/sys/arch/sparc64/dev/ffbreg.h 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/sparc64/dev/ffb.c diff -u src/sys/arch/sparc64/dev/ffb.c:1.51 src/sys/arch/sparc64/dev/ffb.c:1.52 --- src/sys/arch/sparc64/dev/ffb.c:1.51 Thu Apr 12 19:09:18 2012 +++ src/sys/arch/sparc64/dev/ffb.c Thu Aug 9 00:48:06 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ffb.c,v 1.51 2012/04/12 19:09:18 macallan Exp $ */ +/* $NetBSD: ffb.c,v 1.52 2012/08/09 00:48:06 macallan Exp $ */ /* $OpenBSD: creator.c,v 1.20 2002/07/30 19:48:15 jason Exp $ */ /* @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ffb.c,v 1.51 2012/04/12 19:09:18 macallan Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ffb.c,v 1.52 2012/08/09 00:48:06 macallan Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -127,6 +127,7 @@ void ffb_ras_erasecols(void *, int, int, void ffb_ras_eraserows(void *, int, int, long int); void ffb_ras_do_cursor(struct rasops_info *); void ffb_ras_fill(struct ffb_softc *); +void ffb_ras_invert(struct ffb_softc *); static void ffb_ras_setfg(struct ffb_softc *, int32_t); static void ffb_ras_setbg(struct ffb_softc *, int32_t); @@ -135,7 +136,8 @@ int ffb_load_font(void *, void *, struct void ffb_init_screen(void *, struct vcons_screen *, int, long *); int ffb_allocattr(void *, int, int, int, long *); -void ffb_putchar(void *, int, int, u_int, long); +void ffb_putchar_mono(void *, int, int, u_int, long); +void ffb_putchar_aa(void *, int, int, u_int, long); void ffb_cursor(void *, int, int, int); /* frame buffer generic driver */ @@ -738,6 +740,19 @@ ffb_ras_fill(struct ffb_softc *sc) } void +ffb_ras_invert(struct ffb_softc *sc) +{ + ffb_ras_fifo_wait(sc, 3); + FBC_WRITE(sc, FFB_FBC_PPC, + FBC_PPC_VCE_DIS | FBC_PPC_TBE_OPAQUE | FBC_PPC_ACE_DIS | + FBC_PPC_APE_DIS | FBC_PPC_DCE_DIS | FBC_PPC_CS_CONST | + FBC_PPC_ABE_DIS | FBC_PPC_XS_WID); + FBC_WRITE(sc, FFB_FBC_ROP, FBC_ROP_INVERT); + FBC_WRITE(sc, FFB_FBC_DRAWOP, FBC_DRAWOP_RECTANGLE); + SYNC; +} + +void ffb_ras_copyrows(void *cookie, int src, int dst, int n) { struct rasops_info *ri = cookie; @@ -966,7 +981,7 @@ ffb_cursor(void *cookie, int on, int row struct rasops_info *ri = cookie; struct vcons_screen *scr; struct ffb_softc *sc; - int x, y, wi, he, coffset; + int x, y, wi, he; if (cookie != NULL) { scr = ri->ri_hw; @@ -976,43 +991,36 @@ ffb_cursor(void *cookie, int on, int row he = ri->ri_font->fontheight; if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { - x = ri->ri_ccol * wi + ri->ri_xorigin; - y = ri->ri_crow * he + ri->ri_yorigin; if (ri->ri_flg & RI_CURSOR) { + /* remove cursor */ - coffset = ri->ri_ccol + (ri->ri_crow * - ri->ri_cols); -#ifdef WSDISPLAY_SCROLLSUPPORT - coffset += scr->scr_offset_to_zero; -#endif - ffb_ras_wait(sc); - ffb_putchar(cookie, ri->ri_crow, - ri->ri_ccol, scr->scr_chars[coffset], - scr->scr_attrs[coffset]); + x = ri->ri_ccol * wi + ri->ri_xorigin; + y = ri->ri_crow * he + ri->ri_yorigin; + + ffb_ras_invert(sc); + ffb_ras_fifo_wait(sc, 4); + FBC_WRITE(sc, FFB_FBC_BY, y); + FBC_WRITE(sc, FFB_FBC_BX, x); + FBC_WRITE(sc, FFB_FBC_BH, he); + FBC_WRITE(sc, FFB_FBC_BW, wi); + ri->ri_flg &= ~RI_CURSOR; } ri->ri_crow = row; ri->ri_ccol = col; if (on) { - long attr, revattr; x = ri->ri_ccol * wi + ri->ri_xorigin; y = ri->ri_crow * he + ri->ri_yorigin; - coffset = col + (row * ri->ri_cols); -#ifdef WSDISPLAY_SCROLLSUPPORT - coffset += scr->scr_offset_to_zero; -#endif - attr = scr->scr_attrs[coffset]; -#ifdef FFB_CURSOR_SWAP_COLOURS - revattr=((attr >> 8 ) & 0x000f0000) | ((attr & - 0x000f0000)<<8) | (attr & 0x0000ffff); -#else - revattr = attr ^ 0xffff0000; -#endif - ffb_ras_wait(sc); - ffb_putchar(cookie, ri->ri_crow, ri->ri_ccol, - scr->scr_chars[coffset], revattr); + + ffb_ras_invert(sc); + ffb_ras_fifo_wait(sc, 4); + FBC_WRITE(sc, FFB_FBC_BY, y); + FBC_WRITE(sc, FFB_FBC_BX, x); + FBC_WRITE(sc, FFB_FBC_BH, he); + FBC_WRITE(sc, FFB_FBC_BW, wi); + ri->ri_flg |= RI_CURSOR; } } else { @@ -1023,8 +1031,9 @@ ffb_cursor(void *cookie, int on, int row } } +/* mono bitmap font */ void -ffb_putchar(void *cookie, int row, int col, u_int c, long attr) +ffb_putchar_mono(void *cookie, int row, int col, u_int c, long attr) { struct rasops_info *ri = cookie; struct vcons_screen *scr = ri->ri_hw; @@ -1032,7 +1041,7 @@ ffb_putchar(void *cookie, int row, int c struct ffb_softc *sc = scr->scr_cookie; void *data; uint32_t fg, bg; - int uc, i; + int i; int x, y, wi, he; if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL) @@ -1049,102 +1058,122 @@ ffb_putchar(void *cookie, int row, int c x = ri->ri_xorigin + col * wi; y = ri->ri_yorigin + row * he; - uc = c - font->firstchar; - data = (uint8_t *)font->data + uc * ri->ri_fontscale; + data = WSFONT_GLYPH(c, font); - if (font->stride < wi) { - /* mono bitmap font */ - ffb_ras_setbg(sc, bg); - ffb_ras_setfg(sc, fg); - ffb_ras_fifo_wait(sc, 4); - FBC_WRITE(sc, FFB_FBC_ROP, FBC_ROP_NEW); - FBC_WRITE(sc, FFB_FBC_FONTXY, (y << 16) | x); - FBC_WRITE(sc, FFB_FBC_FONTW, wi); - FBC_WRITE(sc, FFB_FBC_PPC, - FBC_PPC_VCE_DIS | FBC_PPC_TBE_OPAQUE | FBC_PPC_ACE_DIS | - FBC_PPC_APE_DIS | FBC_PPC_DCE_DIS | FBC_PPC_CS_CONST | - FBC_PPC_ABE_DIS | FBC_PPC_XS_WID); - - switch (font->stride) { - case 1: { - uint8_t *data8 = data; - uint32_t reg; - for (i = 0; i < he; i++) { - reg = *data8; - FBC_WRITE(sc, FFB_FBC_FONT, reg << 24); - data8++; - } - break; + ffb_ras_setbg(sc, bg); + ffb_ras_setfg(sc, fg); + ffb_ras_fifo_wait(sc, 4); + FBC_WRITE(sc, FFB_FBC_ROP, FBC_ROP_NEW); + FBC_WRITE(sc, FFB_FBC_FONTXY, (y << 16) | x); + FBC_WRITE(sc, FFB_FBC_FONTW, wi); + FBC_WRITE(sc, FFB_FBC_PPC, + FBC_PPC_VCE_DIS | FBC_PPC_TBE_OPAQUE | FBC_PPC_ACE_DIS | + FBC_PPC_APE_DIS | FBC_PPC_DCE_DIS | FBC_PPC_CS_CONST | + FBC_PPC_ABE_DIS | FBC_PPC_XS_WID); + + switch (font->stride) { + case 1: { + uint8_t *data8 = data; + uint32_t reg; + for (i = 0; i < he; i++) { + reg = *data8; + FBC_WRITE(sc, FFB_FBC_FONT, reg << 24); + data8++; } - case 2: { - uint16_t *data16 = data; - uint32_t reg; - for (i = 0; i < he; i++) { - reg = *data16; - FBC_WRITE(sc, FFB_FBC_FONT, reg << 16); - data16++; - } - break; + break; + } + case 2: { + uint16_t *data16 = data; + uint32_t reg; + for (i = 0; i < he; i++) { + reg = *data16; + FBC_WRITE(sc, FFB_FBC_FONT, reg << 16); + data16++; } + break; } - } else { - /* alpha font */ - volatile uint32_t *dest, *ddest; - uint32_t alpha = 0x80; - uint8_t *data8 = data; - int j; - - /* first we erase the background */ - ffb_ras_fill(sc); - ffb_ras_setfg(sc, bg); - ffb_ras_fifo_wait(sc, 4); - FBC_WRITE(sc, FFB_FBC_BY, y); - FBC_WRITE(sc, FFB_FBC_BX, x); - FBC_WRITE(sc, FFB_FBC_BH, he); - FBC_WRITE(sc, FFB_FBC_BW, wi); - - /* if we draw a space we're done */ - if (c == ' ') return; - - /* now enable alpha blending */ - ffb_ras_setfg(sc, fg); - ffb_ras_fifo_wait(sc, 2); - FBC_WRITE(sc, FFB_FBC_ROP, FBC_ROP_NEW); - - FBC_WRITE(sc, FFB_FBC_PPC, - FBC_PPC_VCE_DIS | FBC_PPC_TBE_OPAQUE | FBC_PPC_ACE_DIS | - FBC_PPC_APE_DIS | FBC_PPC_DCE_DIS | FBC_PPC_CS_CONST | - FBC_PPC_ABE_ENA | FBC_PPC_XS_VAR); - /* - * we have to wait for both the rectangle drawing op above and - * the FFB_FBC_PPC write to finish before mucking around in - * the SFB aperture - */ - ffb_ras_wait(sc); + } +} - /* ... and draw the character */ - dest = sc->sc_sfb32 + 2048 * y + x; - for (i = 0; i < he; i++) { - ddest = dest; - for (j = 0; j < wi; j++) { - alpha = *data8; - /* - * We set the colour source to constant above - * so we only have to write the alpha channel - * here and the colour comes from the FG - * register. It would be nice if we could - * just use the SFB8X aperture and memcpy() - * the alpha map line by line but for some - * strange reason that will take colour info - * from the framebuffer even if we set the - * FBC_PPC_CS_CONST bit above. - */ - *ddest = alpha << 24; - data8++; - ddest++; - } - dest += 2048; +/* alpha font */ +void +ffb_putchar_aa(void *cookie, int row, int col, u_int c, long attr) +{ + struct rasops_info *ri = cookie; + struct vcons_screen *scr = ri->ri_hw; + struct wsdisplay_font *font = PICK_FONT(ri, c); + struct ffb_softc *sc = scr->scr_cookie; + volatile uint32_t *dest, *ddest; + uint8_t *data8; + uint32_t fg, bg; + int i; + int x, y, wi, he; + uint32_t alpha = 0x80; + int j; + + if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL) + return; + + wi = font->fontwidth; + he = font->fontheight; + + if (!CHAR_IN_FONT(c, font)) + return; + + bg = ri->ri_devcmap[(attr >> 16) & 0xf]; + fg = ri->ri_devcmap[(attr >> 24) & 0xf]; + x = ri->ri_xorigin + col * wi; + y = ri->ri_yorigin + row * he; + + data8 = WSFONT_GLYPH(c, font); + + /* first we erase the background */ + ffb_ras_fill(sc); + ffb_ras_setfg(sc, bg); + ffb_ras_fifo_wait(sc, 4); + FBC_WRITE(sc, FFB_FBC_BY, y); + FBC_WRITE(sc, FFB_FBC_BX, x); + FBC_WRITE(sc, FFB_FBC_BH, he); + FBC_WRITE(sc, FFB_FBC_BW, wi); + + /* if we draw a space we're done */ + if (c == ' ') return; + + /* now enable alpha blending */ + ffb_ras_setfg(sc, fg); + ffb_ras_fifo_wait(sc, 2); + FBC_WRITE(sc, FFB_FBC_ROP, FBC_ROP_NEW); + + FBC_WRITE(sc, FFB_FBC_PPC, + FBC_PPC_VCE_DIS | FBC_PPC_TBE_OPAQUE | FBC_PPC_ACE_DIS | + FBC_PPC_APE_DIS | FBC_PPC_DCE_DIS | FBC_PPC_CS_CONST | + FBC_PPC_ABE_ENA | FBC_PPC_XS_VAR); + /* + * we have to wait for both the rectangle drawing op above and the + * FFB_FBC_PPC write to finish before mucking around in the SFB aperture + */ + ffb_ras_wait(sc); + + /* ... and draw the character */ + dest = sc->sc_sfb32 + (y << 11) + x; + for (i = 0; i < he; i++) { + ddest = dest; + for (j = 0; j < wi; j++) { + alpha = *data8; + /* + * We set the colour source to constant above so we only + * have to write the alpha channel here and the colour + * comes from the FG register. It would be nice if we + * could just use the SFB8X aperture and memcpy() the + * alpha map line by line but for some strange reason + * that will take colour info from the framebuffer even + * if we set the FBC_PPC_CS_CONST bit above. + */ + *ddest = alpha << 24; + data8++; + ddest++; } + dest += 2048; } } @@ -1207,7 +1236,10 @@ ffb_init_screen(void *cookie, struct vco ri->ri_ops.erasecols = ffb_ras_erasecols; ri->ri_ops.cursor = ffb_cursor; ri->ri_ops.allocattr = ffb_allocattr; - ri->ri_ops.putchar = ffb_putchar; + if (FONT_IS_ALPHA(ri->ri_font)) { + ri->ri_ops.putchar = ffb_putchar_aa; + } else + ri->ri_ops.putchar = ffb_putchar_mono; } /* I2C bitbanging */ Index: src/sys/arch/sparc64/dev/ffbreg.h diff -u src/sys/arch/sparc64/dev/ffbreg.h:1.10 src/sys/arch/sparc64/dev/ffbreg.h:1.11 --- src/sys/arch/sparc64/dev/ffbreg.h:1.10 Thu Dec 22 05:08:05 2011 +++ src/sys/arch/sparc64/dev/ffbreg.h Thu Aug 9 00:48:06 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ffbreg.h,v 1.10 2011/12/22 05:08:05 macallan Exp $ */ +/* $NetBSD: ffbreg.h,v 1.11 2012/08/09 00:48:06 macallan Exp $ */ /* $OpenBSD: creatorreg.h,v 1.5 2002/07/29 06:21:45 jason Exp $ */ /* @@ -284,6 +284,7 @@ #define FBC_ROP_NEW 0x83 #define FBC_ROP_OLD 0x85 +#define FBC_ROP_INVERT 0x8a #define FBC_UCSR_FIFO_MASK 0x00000fff #define FBC_UCSR_FB_BUSY 0x01000000