Module Name: src Committed By: macallan Date: Thu Aug 2 00:17:45 UTC 2012
Modified Files: src/sys/dev/pci: files.pci machfb.c Log Message: add support for anti-aliased fonts To generate a diff of this commit: cvs rdiff -u -r1.359 -r1.360 src/sys/dev/pci/files.pci cvs rdiff -u -r1.78 -r1.79 src/sys/dev/pci/machfb.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/files.pci diff -u src/sys/dev/pci/files.pci:1.359 src/sys/dev/pci/files.pci:1.360 --- src/sys/dev/pci/files.pci:1.359 Mon Jul 30 18:57:19 2012 +++ src/sys/dev/pci/files.pci Thu Aug 2 00:17:44 2012 @@ -1,4 +1,4 @@ -# $NetBSD: files.pci,v 1.359 2012/07/30 18:57:19 degroote Exp $ +# $NetBSD: files.pci,v 1.360 2012/08/02 00:17:44 macallan Exp $ # # Config file and device description for machine-independent PCI code. # Included by ports that need it. Requires that the SCSI files be @@ -830,7 +830,7 @@ file dev/pci/joy_pci.c joy_pci # ATI Mach64 framebuffer console driver defflag opt_machfb.h MACHFB_DEBUG -device machfb: wsemuldisplaydev, rasops8, fb, vcons, videomode, edid, drm +device machfb: wsemuldisplaydev, rasops8, fb, vcons, videomode, edid, drm, glyphcache attach machfb at pci file dev/pci/machfb.c machfb Index: src/sys/dev/pci/machfb.c diff -u src/sys/dev/pci/machfb.c:1.78 src/sys/dev/pci/machfb.c:1.79 --- src/sys/dev/pci/machfb.c:1.78 Thu Jun 14 00:56:37 2012 +++ src/sys/dev/pci/machfb.c Thu Aug 2 00:17:44 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: machfb.c,v 1.78 2012/06/14 00:56:37 macallan Exp $ */ +/* $NetBSD: machfb.c,v 1.79 2012/08/02 00:17:44 macallan Exp $ */ /* * Copyright (c) 2002 Bang Jun-Young @@ -34,7 +34,7 @@ #include <sys/cdefs.h> __KERNEL_RCSID(0, - "$NetBSD: machfb.c,v 1.78 2012/06/14 00:56:37 macallan Exp $"); + "$NetBSD: machfb.c,v 1.79 2012/08/02 00:17:44 macallan Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -68,6 +68,7 @@ __KERNEL_RCSID(0, #include <dev/pci/wsdisplay_pci.h> #include <dev/wscons/wsdisplay_vconsvar.h> +#include <dev/wscons/wsdisplay_glyphcachevar.h> #include "opt_wsemul.h" #include "opt_machfb.h" @@ -153,6 +154,7 @@ struct mach64_softc { int sc_dacw, sc_blanked, sc_console; struct vcons_data vd; struct wsdisplay_accessops sc_accessops; + glyphcache sc_gc; }; struct mach64_crtcregs { @@ -272,7 +274,8 @@ static void mach64_cursor(void *, int, i #if 0 static int mach64_mapchar(void *, int, u_int *); #endif -static void mach64_putchar(void *, int, int, u_int, long); +static void mach64_putchar_mono(void *, int, int, u_int, long); +static void mach64_putchar_aa8(void *, int, int, u_int, long); static void mach64_copycols(void *, int, int, int, int); static void mach64_erasecols(void *, int, int, int, long); static void mach64_copyrows(void *, int, int, int); @@ -283,8 +286,7 @@ static int mach64_putcmap(struct mach64_ static int mach64_getcmap(struct mach64_softc *, struct wsdisplay_cmap *); static int mach64_putpalreg(struct mach64_softc *, uint8_t, uint8_t, uint8_t, uint8_t); -static void mach64_bitblt(struct mach64_softc *, int, int, int, int, int, - int, int, int) ; +static void mach64_bitblt(void *, int, int, int, int, int, int, int); static void mach64_rectfill(struct mach64_softc *, int, int, int, int, int); static void mach64_setup_mono(struct mach64_softc *, int, int, int, int, uint32_t, uint32_t); @@ -428,6 +430,14 @@ regw(struct mach64_softc *sc, uint32_t i } static inline void +regws(struct mach64_softc *sc, uint32_t index, uint32_t data) +{ + bus_space_write_stream_4(sc->sc_regt, sc->sc_regh, index, data); + bus_space_barrier(sc->sc_regt, sc->sc_regh, index, 4, + BUS_SPACE_BARRIER_WRITE); +} + +static inline void regwb(struct mach64_softc *sc, uint32_t index, uint8_t data) { bus_space_write_1(sc->sc_regt, sc->sc_regh, index, data); @@ -748,17 +758,28 @@ mach64_attach(device_t parent, device_t vcons_init(&sc->vd, sc, &mach64_defaultscreen, &sc->sc_accessops); sc->vd.init_screen = mach64_init_screen; + sc->sc_gc.gc_bitblt = mach64_bitblt; + sc->sc_gc.gc_blitcookie = sc; + sc->sc_gc.gc_rop = MIX_SRC; + + ri = &mach64_console_screen.scr_ri; if (sc->sc_console) { vcons_init_screen(&sc->vd, &mach64_console_screen, 1, &defattr); mach64_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; - ri = &mach64_console_screen.scr_ri; mach64_defaultscreen.textops = &ri->ri_ops; mach64_defaultscreen.capabilities = ri->ri_caps; mach64_defaultscreen.nrows = ri->ri_rows; mach64_defaultscreen.ncols = ri->ri_cols; + glyphcache_init(&sc->sc_gc, sc->sc_my_mode->vdisplay + 5, + (sc->memsize / sc->sc_my_mode->hdisplay) - + sc->sc_my_mode->vdisplay - 5, + sc->sc_my_mode->hdisplay, + ri->ri_font->fontwidth, + ri->ri_font->fontheight, + defattr); wsdisplay_cnattach(&mach64_defaultscreen, ri, 0, 0, defattr); } else { @@ -772,7 +793,16 @@ mach64_attach(device_t parent, device_t vcons_init_screen(&sc->vd, &mach64_console_screen, 1, &defattr); } + + glyphcache_init(&sc->sc_gc, sc->sc_my_mode->vdisplay + 5, + (sc->memsize / sc->sc_my_mode->hdisplay) - + sc->sc_my_mode->vdisplay - 5, + sc->sc_my_mode->hdisplay, + ri->ri_font->fontwidth, + ri->ri_font->fontheight, + defattr); } + sc->sc_bg = mach64_console_screen.scr_ri.ri_devcmap[WS_DEFAULT_BG]; mach64_clearscreen(sc); mach64_init_lut(sc); @@ -816,7 +846,7 @@ mach64_init_screen(void *cookie, struct ri->ri_stride = ri->ri_width; ri->ri_flg = RI_CENTER; if (ri->ri_depth == 8) - ri->ri_flg |= RI_8BIT_IS_RGB/* | RI_ENABLE_ALPHA*/; + ri->ri_flg |= RI_8BIT_IS_RGB | RI_ENABLE_ALPHA; set_address(ri, sc->sc_aperture); #ifdef VCONS_DRAW_INTR @@ -842,7 +872,12 @@ mach64_init_screen(void *cookie, struct ri->ri_ops.eraserows = mach64_eraserows; ri->ri_ops.erasecols = mach64_erasecols; ri->ri_ops.cursor = mach64_cursor; - ri->ri_ops.putchar = mach64_putchar; + if (FONT_IS_ALPHA(ri->ri_font)) { + ri->ri_ops.putchar = mach64_putchar_aa8; + ri->ri_ops.allocattr(ri, WS_DEFAULT_FG, WS_DEFAULT_BG, + 0, &sc->sc_gc.gc_attr); + } else + ri->ri_ops.putchar = mach64_putchar_mono; } static void @@ -1123,7 +1158,7 @@ mach64_init_engine(struct mach64_softc * regw(sc, CLR_CMP_MASK, 0xffffffff); regw(sc, CLR_CMP_CNTL, 0); - wait_for_fifo(sc, 2); + wait_for_fifo(sc, 3); switch (sc->bits_per_pixel) { case 8: regw(sc, DP_PIX_WIDTH, HOST_1BPP | SRC_8BPP | DST_8BPP); @@ -1137,6 +1172,7 @@ mach64_init_engine(struct mach64_softc * regw(sc, DAC_CNTL, regr(sc, DAC_CNTL) | DAC_8BIT_EN); break; } + regw(sc, DP_WRITE_MASK, 0xff); wait_for_fifo(sc, 5); regw(sc, CRTC_INT_CNTL, regr(sc, CRTC_INT_CNTL) & ~0x20); @@ -1447,8 +1483,7 @@ mach64_cursor(void *cookie, int on, int x = ri->ri_ccol * wi + ri->ri_xorigin; y = ri->ri_crow * he + ri->ri_yorigin; if (ri->ri_flg & RI_CURSOR) { - mach64_bitblt(sc, x, y, x, y, wi, he, MIX_NOT_SRC, - 0xff); + mach64_bitblt(sc, x, y, x, y, wi, he, MIX_NOT_SRC); ri->ri_flg &= ~RI_CURSOR; } ri->ri_crow = row; @@ -1456,8 +1491,7 @@ mach64_cursor(void *cookie, int on, int if (on) { x = ri->ri_ccol * wi + ri->ri_xorigin; y = ri->ri_crow * he + ri->ri_yorigin; - mach64_bitblt(sc, x, y, x, y, wi, he, MIX_NOT_SRC, - 0xff); + mach64_bitblt(sc, x, y, x, y, wi, he, MIX_NOT_SRC); ri->ri_flg |= RI_CURSOR; } } else { @@ -1476,7 +1510,7 @@ mach64_mapchar(void *cookie, int uni, u_ #endif static void -mach64_putchar(void *cookie, int row, int col, u_int c, long attr) +mach64_putchar_mono(void *cookie, int row, int col, u_int c, long attr) { struct rasops_info *ri = cookie; struct wsdisplay_font *font = PICK_FONT(ri, c); @@ -1509,6 +1543,114 @@ mach64_putchar(void *cookie, int row, in } } +static void +mach64_putchar_aa8(void *cookie, int row, int col, u_int c, long attr) +{ + struct rasops_info *ri = cookie; + struct wsdisplay_font *font = PICK_FONT(ri, c); + struct vcons_screen *scr = ri->ri_hw; + struct mach64_softc *sc = scr->scr_cookie; + uint32_t bg, latch = 0, bg8, fg8, pixel; + int i, x, y, wi, he, r, g, b, aval; + int r1, g1, b1, r0, g0, b0, fgo, bgo; + uint8_t *data8; + int rv = 0, cnt = 0; + + if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL) + return; + + if (!CHAR_IN_FONT(c, font)) + return; + + wi = font->fontwidth; + he = font->fontheight; + bg = (u_char)ri->ri_devcmap[(attr >> 16) & 0x0f]; + x = ri->ri_xorigin + col * wi; + y = ri->ri_yorigin + row * he; + + if (c == 0x20) { + mach64_rectfill(sc, x, y, wi, he, bg); + return; + } + + rv = glyphcache_try(&sc->sc_gc, c, x, y, attr); + if (rv == GC_OK) + return; + + data8 = WSFONT_GLYPH(c, font); + + wait_for_fifo(sc, 11); + regw(sc, DP_PIX_WIDTH, DST_8BPP | SRC_8BPP | HOST_8BPP); + regw(sc, DP_SRC, MONO_SRC_ONE | BKGD_SRC_HOST | FRGD_SRC_HOST); + regw(sc, DP_MIX, ((MIX_SRC & 0xffff) << 16) | MIX_SRC); + regw(sc, CLR_CMP_CNTL ,0); /* no transparency */ + regw(sc, SRC_CNTL, SRC_LINE_X_LEFT_TO_RIGHT); + regw(sc, DST_CNTL, DST_Y_TOP_TO_BOTTOM | DST_X_LEFT_TO_RIGHT); + regw(sc, HOST_CNTL, HOST_BYTE_ALIGN); + regw(sc, SRC_Y_X, 0); + regw(sc, SRC_WIDTH1, wi); + regw(sc, DST_Y_X, (x << 16) | y); + regw(sc, DST_HEIGHT_WIDTH, (wi << 16) | he); + + /* + * we need the RGB colours here, so get offsets into rasops_cmap + */ + fgo = ((attr >> 24) & 0xf) * 3; + bgo = ((attr >> 16) & 0xf) * 3; + + r0 = rasops_cmap[bgo]; + r1 = rasops_cmap[fgo]; + g0 = rasops_cmap[bgo + 1]; + g1 = rasops_cmap[fgo + 1]; + b0 = rasops_cmap[bgo + 2]; + b1 = rasops_cmap[fgo + 2]; +#define R3G3B2(r, g, b) ((r & 0xe0) | ((g >> 3) & 0x1c) | (b >> 6)) + bg8 = R3G3B2(r0, g0, b0); + fg8 = R3G3B2(r1, g1, b1); + + wait_for_fifo(sc, 10); + + for (i = 0; i < ri->ri_fontscale; i++) { + aval = *data8; + if (aval == 0) { + pixel = bg8; + } else if (aval == 255) { + pixel = fg8; + } else { + r = aval * r1 + (255 - aval) * r0; + g = aval * g1 + (255 - aval) * g0; + b = aval * b1 + (255 - aval) * b0; + pixel = ((r & 0xe000) >> 8) | + ((g & 0xe000) >> 11) | + ((b & 0xc000) >> 14); + } + latch = (latch << 8) | pixel; + /* write in 32bit chunks */ + if ((i & 3) == 3) { + regws(sc, HOST_DATA0, latch); + /* + * not strictly necessary, old data should be shifted + * out + */ + latch = 0; + cnt++; + if (cnt > 8) { + wait_for_fifo(sc, 10); + cnt = 0; + } + } + data8++; + } + /* if we have pixels left in latch write them out */ + if ((i & 3) != 0) { + latch = latch << ((4 - (i & 3)) << 3); + regws(sc, HOST_DATA0, latch); + } + + if (rv == GC_ADD) { + glyphcache_add(&sc->sc_gc, c, x, y); + } +} static void mach64_copycols(void *cookie, int row, int srccol, int dstcol, int ncols) @@ -1524,7 +1666,7 @@ mach64_copycols(void *cookie, int row, i y = ri->ri_yorigin + ri->ri_font->fontheight * row; width = ri->ri_font->fontwidth * ncols; height = ri->ri_font->fontheight; - mach64_bitblt(sc, xs, y, xd, y, width, height, MIX_SRC, 0xff); + mach64_bitblt(sc, xs, y, xd, y, width, height, MIX_SRC); } } @@ -1561,7 +1703,7 @@ mach64_copyrows(void *cookie, int srcrow yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow; width = ri->ri_emuwidth; height = ri->ri_font->fontheight*nrows; - mach64_bitblt(sc, x, ys, x, yd, width, height, MIX_SRC, 0xff); + mach64_bitblt(sc, x, ys, x, yd, width, height, MIX_SRC); } } @@ -1585,12 +1727,12 @@ mach64_eraserows(void *cookie, int row, } static void -mach64_bitblt(struct mach64_softc *sc, int xs, int ys, int xd, int yd, int width, int height, int rop, int mask) +mach64_bitblt(void *cookie, int xs, int ys, int xd, int yd, int width, int height, int rop) { + struct mach64_softc *sc = cookie; uint32_t dest_ctl = 0; - wait_for_idle(sc); - regw(sc, DP_WRITE_MASK, mask); /* XXX only good for 8 bit */ + wait_for_fifo(sc, 10); regw(sc, DP_PIX_WIDTH, DST_8BPP | SRC_8BPP | HOST_8BPP); regw(sc, DP_SRC, FRGD_SRC_BLIT); regw(sc, DP_MIX, (rop & 0xffff) << 16); @@ -1669,8 +1811,7 @@ static void mach64_rectfill(struct mach64_softc *sc, int x, int y, int width, int height, int colour) { - wait_for_idle(sc); - regw(sc, DP_WRITE_MASK, 0xff); + wait_for_fifo(sc, 11); regw(sc, DP_FRGD_CLR, colour); regw(sc, DP_PIX_WIDTH, DST_8BPP | SRC_8BPP | HOST_8BPP); regw(sc, DP_SRC, FRGD_SRC_FRGD_CLR);