Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci support anti-aliased fonts in 8 bit



details:   https://anonhg.NetBSD.org/src/rev/bfa058a0f452
branches:  trunk
changeset: 781516:bfa058a0f452
user:      macallan <macallan%NetBSD.org@localhost>
date:      Wed Sep 12 12:07:04 2012 +0000

description:
support anti-aliased fonts in 8 bit
while there, fix pm2fb_bitblt() packed mode, for real this time
TODO:
- use packed mode when uploading glyphs
- let the hardware do the alpha blending if possible
- mode setting

diffstat:

 sys/dev/pci/pm2fb.c  |  225 +++++++++++++++++++++++++++++++++++++++++++++++---
 sys/dev/pci/pm2reg.h |    4 +-
 2 files changed, 214 insertions(+), 15 deletions(-)

diffs (truncated from 392 to 300 lines):

diff -r 0dd65ee6c2a8 -r bfa058a0f452 sys/dev/pci/pm2fb.c
--- a/sys/dev/pci/pm2fb.c       Wed Sep 12 10:35:10 2012 +0000
+++ b/sys/dev/pci/pm2fb.c       Wed Sep 12 12:07:04 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pm2fb.c,v 1.16 2012/09/05 23:19:13 macallan Exp $      */
+/*     $NetBSD: pm2fb.c,v 1.17 2012/09/12 12:07:04 macallan Exp $      */
 
 /*
  * Copyright (c) 2009 Michael Lorenz
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pm2fb.c,v 1.16 2012/09/05 23:19:13 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pm2fb.c,v 1.17 2012/09/12 12:07:04 macallan Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -55,6 +55,7 @@
 #include <dev/wsfont/wsfont.h>
 #include <dev/rasops/rasops.h>
 #include <dev/wscons/wsdisplay_vconsvar.h>
+#include <dev/wscons/wsdisplay_glyphcachevar.h>
 #include <dev/pci/wsdisplay_pci.h>
 
 #include <dev/i2c/i2cvar.h>
@@ -104,6 +105,7 @@
        uint8_t sc_edid_data[128];
        struct edid_info sc_ei;
        struct videomode *sc_videomode;
+       glyphcache sc_gc;
 };
 
 static int     pm2fb_match(device_t, cfdata_t, void *);
@@ -129,11 +131,11 @@
 static void    pm2fb_flush_engine(struct pm2fb_softc *);
 static void    pm2fb_rectfill(struct pm2fb_softc *, int, int, int, int,
                            uint32_t);
-static void    pm2fb_bitblt(struct pm2fb_softc *, int, int, int, int, int,
-                           int, int);
+static void    pm2fb_bitblt(void *, int, int, int, int, int, int, int);
 
 static void    pm2fb_cursor(void *, int, int, int);
 static void    pm2fb_putchar(void *, int, int, u_int, long);
+static void    pm2fb_putchar_aa(void *, int, int, u_int, long);
 static void    pm2fb_copycols(void *, int, int, int, int);
 static void    pm2fb_erasecols(void *, int, int, int, long);
 static void    pm2fb_copyrows(void *, int, int, int);
@@ -222,7 +224,10 @@
        if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_3DLABS)
                return 0;
 
-       /* only cards tested on so far - likely need a list */
+       /*
+        * only card tested on so far is a TechSource Raptor GFX 8P 
+        * Sun PGX32, which happens to be a Permedia 2v
+        */
        if ((PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_3DLABS_PERMEDIA2) ||
            (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_3DLABS_PERMEDIA2V))
                return 100;
@@ -323,6 +328,18 @@
 
        ri = &sc->sc_console_screen.scr_ri;
 
+       sc->sc_gc.gc_bitblt = pm2fb_bitblt;
+       sc->sc_gc.gc_blitcookie = sc;
+       sc->sc_gc.gc_rop = 3;
+
+#ifdef PM2FB_DEBUG
+       /*
+        * leave some room at the bottom of the screen for various blitter
+        * tests and in order to make the glyph cache visible
+        */
+       sc->sc_height -= 200;
+#endif
+
        if (is_console) {
                vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
                    &defattr);
@@ -334,12 +351,25 @@
                sc->sc_defaultscreen_descr.capabilities = ri->ri_caps;
                sc->sc_defaultscreen_descr.nrows = ri->ri_rows;
                sc->sc_defaultscreen_descr.ncols = ri->ri_cols;
+               /* XXX use actual memory size instead of assuming 8MB */
+               glyphcache_init(&sc->sc_gc, sc->sc_height + 5,
+                               (0x800000 / sc->sc_stride) - sc->sc_height - 5,
+                               sc->sc_width,
+                               ri->ri_font->fontwidth,
+                               ri->ri_font->fontheight,
+                               defattr);
                wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0,
                    defattr);
                vcons_replay_msgbuf(&sc->sc_console_screen);
        } else {
                if (sc->sc_console_screen.scr_ri.ri_rows == 0) {
                        /* do some minimal setup to avoid weirdnesses later */
+                       glyphcache_init(&sc->sc_gc, sc->sc_height + 5,
+                               (0x800000 / sc->sc_stride) - sc->sc_height - 5,
+                               sc->sc_width,
+                               ri->ri_font->fontwidth,
+                               ri->ri_font->fontheight,
+                               defattr);
                        vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1, 
                           &defattr);
                }
@@ -360,7 +390,25 @@
        aa.accessops = &pm2fb_accessops;
        aa.accesscookie = &sc->vd;
 
-       config_found(sc->sc_dev, &aa, wsemuldisplaydevprint);   
+       config_found(sc->sc_dev, &aa, wsemuldisplaydevprint);
+
+#ifdef PM2FB_DEBUG
+       /*
+        * draw a pattern to check if pm2fb_bitblt() gets the alignment stuff
+        * right
+        */
+       pm2fb_rectfill(sc, 0, sc->sc_height, sc->sc_width, 200, 0xffffffff);
+       pm2fb_rectfill(sc, 0, sc->sc_height, 300, 10, 0);
+       pm2fb_rectfill(sc, 10, sc->sc_height, 200, 10, 0xe0e0e0e0);
+       for (i = 1; i < 20; i++) {
+               pm2fb_bitblt(sc, 0, sc->sc_height, 
+                       i, sc->sc_height + 10 * i,
+                       300, 10, 3);
+               pm2fb_bitblt(sc, i, sc->sc_height, 
+                       400, sc->sc_height + 10 * i,
+                       300, 10, 3);
+       }
+#endif
 }
 
 static int
@@ -414,7 +462,9 @@
                if (new_mode != sc->sc_mode) {
                        sc->sc_mode = new_mode;
                        if(new_mode == WSDISPLAYIO_MODE_EMUL) {
+                               pm2fb_init(sc);
                                pm2fb_restore_palette(sc);
+                               glyphcache_wipe(&sc->sc_gc);
                                vcons_redraw_screen(ms);
                        } else
                                pm2fb_flush_engine(sc);
@@ -497,7 +547,7 @@
        ri->ri_stride = sc->sc_stride;
        ri->ri_flg = RI_CENTER;
        if (sc->sc_depth == 8)
-               ri->ri_flg |= RI_8BIT_IS_RGB /*| RI_ENABLE_ALPHA*/;
+               ri->ri_flg |= RI_8BIT_IS_RGB | RI_ENABLE_ALPHA;
 
        rasops_init(ri, 0, 0);
        ri->ri_caps = WSSCREEN_WSCOLORS;
@@ -511,7 +561,10 @@
        ri->ri_ops.cursor = pm2fb_cursor;
        ri->ri_ops.eraserows = pm2fb_eraserows;
        ri->ri_ops.erasecols = pm2fb_erasecols;
-       ri->ri_ops.putchar = pm2fb_putchar;
+       if (FONT_IS_ALPHA(ri->ri_font)) {
+               ri->ri_ops.putchar = pm2fb_putchar_aa;
+       } else
+               ri->ri_ops.putchar = pm2fb_putchar;
 }
 
 static int
@@ -694,6 +747,13 @@
        bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_SCISSOR_MINYX, 0);
        bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_SCISSOR_MAXYX,
            0x0fff0fff);
+       /*
+        * another scissor we need to disable in order to blit into off-screen
+        * memory
+        */
+       bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_SCREENSIZE,
+           0x0fff0fff);
+
        switch(sc->sc_depth) {
                case 8:
                        bus_space_write_4(sc->sc_memt, sc->sc_regh,
@@ -709,7 +769,8 @@
                        break;
        }
        pm2fb_flush_engine(sc);
-       DPRINTF("pixel size: %08x\n", bus_space_read_4(sc->sc_memt, sc->sc_regh, PM2_RE_PIXEL_SIZE));
+       DPRINTF("pixel size: %08x\n", 
+           bus_space_read_4(sc->sc_memt, sc->sc_regh, PM2_RE_PIXEL_SIZE));
 }
 
 static void
@@ -733,11 +794,12 @@
 }
 
 static void
-pm2fb_bitblt(struct pm2fb_softc *sc, int xs, int ys, int xd, int yd,
+pm2fb_bitblt(void *cookie, int xs, int ys, int xd, int yd,
     int wi, int he, int rop)
 {
+       struct pm2fb_softc *sc = cookie;
        uint32_t dir = 0;
-       int rxs, rxd, rwi;
+       int rxs, rxd, rwi, rxdelta;
 
        if (yd <= ys) {
                dir |= PM2RE_INC_Y;
@@ -771,12 +833,14 @@
                }
                rxs = xs >> 2;
                rxd = xd >> 2;
-               rwi = wi >> 2;
+               rwi = (wi + 7) >> 2;
+               rxdelta = (xs & 0xffc) - (xd & 0xffc);
                /* adjust for non-aligned x */
-               adjust = (xs & 3) - (xd & 3);
+               adjust = ((xd & 3) - (xs & 3));
                bus_space_write_4(sc->sc_memt, sc->sc_regh,
                    PM2_RE_PACKEDDATA_LIMIT,
                    (xd << 16) | (xd + wi) | (adjust << 29));
+               
        } else {
                /* we're in 16 or 32bit mode */
                if (rop == 3) {
@@ -794,13 +858,14 @@
                rxs = xs;
                rxd = xd;
                rwi = wi;
+               rxdelta = xs - xd;
        }               
        bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_RECT_START,
            (yd << 16) | rxd);
        bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_RECT_SIZE,
            (he << 16) | rwi);
        bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_SOURCE_DELTA,
-           (((ys - yd) & 0xfff) << 16) | ((rxs - rxd) & 0xfff));
+           (((ys - yd) & 0xfff) << 16) | (rxdelta & 0xfff));
        bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_RENDER,
            PM2RE_RECTANGLE | dir);
 }
@@ -934,6 +999,138 @@
 }
 
 static void
+pm2fb_putchar_aa(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 pm2fb_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 = GC_NOPE, cnt = 0;
+
+       if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL) 
+               return;
+
+       if (!CHAR_IN_FONT(c, font))
+               return;
+
+       wi = font->fontwidth;
+       he = font->fontheight;
+
+       bg = ri->ri_devcmap[(attr >> 16) & 0xf];
+       x = ri->ri_xorigin + col * wi;
+       y = ri->ri_yorigin + row * he;
+       if (c == 0x20) {
+               pm2fb_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);
+
+       pm2fb_wait(sc, 5);
+#if 0
+       /*
+        * TODO:
+        * - use packed mode here as well, instead of writing each pixel separately
+        * - support 32bit colour
+        * - see if we can trick the chip into doing the alpha blending for us
+        */
+       x = x >> 2;
+       wi = (wi + 3) >> 2;
+#endif
+       bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_MODE, 0);
+       bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_CONFIG,
+                           PM2RECFG_WRITE_EN /*| PM2RECFG_PACKED*/);
+       bus_space_write_4(sc->sc_memt, sc->sc_regh, 
+                           PM2_RE_RECT_START, (y << 16) | x);
+       bus_space_write_4(sc->sc_memt, sc->sc_regh, 
+                           PM2_RE_RECT_SIZE, (he << 16) | wi);
+       bus_space_write_4(sc->sc_memt, sc->sc_regh, 
+                           PM2_RE_RENDER,
+                           PM2RE_RECTANGLE | PM2RE_SYNC_ON_HOST |
+                           PM2RE_INC_X | PM2RE_INC_Y);
+       /*
+        * we need the RGB colours here, so get offsets into rasops_cmap
+        */
+       fgo = ((attr >> 24) & 0xf) * 3;



Home | Main Index | Thread Index | Old Index