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 as well



details:   https://anonhg.NetBSD.org/src/rev/ddf31b0f31b5
branches:  trunk
changeset: 777665:ddf31b0f31b5
user:      macallan <macallan%NetBSD.org@localhost>
date:      Tue Feb 28 20:21:16 2012 +0000

description:
support anti-aliased fonts in 8 bit as well

diffstat:

 sys/dev/pci/radeonfb.c    |  165 +++++++++++++++++++++++++++++++++++++++++++--
 sys/dev/pci/radeonfbvar.h |    4 +-
 2 files changed, 160 insertions(+), 9 deletions(-)

diffs (255 lines):

diff -r 57c4c3354e37 -r ddf31b0f31b5 sys/dev/pci/radeonfb.c
--- a/sys/dev/pci/radeonfb.c    Tue Feb 28 18:14:47 2012 +0000
+++ b/sys/dev/pci/radeonfb.c    Tue Feb 28 20:21:16 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: radeonfb.c,v 1.54 2012/02/16 17:33:28 macallan Exp $ */
+/*     $NetBSD: radeonfb.c,v 1.55 2012/02/28 20:21:16 macallan Exp $ */
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: radeonfb.c,v 1.54 2012/02/16 17:33:28 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: radeonfb.c,v 1.55 2012/02/28 20:21:16 macallan Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -168,6 +168,7 @@
 static void radeonfb_cursor(void *, int, int, int);
 static void radeonfb_putchar(void *, int, int, unsigned, long);
 static void radeonfb_putchar_aa32(void *, int, int, unsigned, long);
+static void radeonfb_putchar_aa8(void *, int, int, unsigned, long);
 static void radeonfb_putchar_wrapper(void *, int, int, unsigned, long);
 
 static int radeonfb_get_backlight(struct radeonfb_display *);
@@ -1219,6 +1220,13 @@
 }
 
 void
+radeonfb_put32s(struct radeonfb_softc *sc, uint32_t reg, uint32_t val)
+{
+
+       bus_space_write_stream_4(sc->sc_regt, sc->sc_regh, reg, val);
+}
+
+void
 radeonfb_mask32(struct radeonfb_softc *sc, uint32_t reg,
     uint32_t andmask, uint32_t ormask)
 {
@@ -2172,6 +2180,9 @@
        if (ri->ri_depth == 32) {
                ri->ri_flg |= RI_ENABLE_ALPHA;
        }
+       if (ri->ri_depth == 8) {
+               ri->ri_flg |= RI_ENABLE_ALPHA | RI_8BIT_IS_RGB;
+       }
        ri->ri_bits = (void *)dp->rd_fbptr;
 
 #ifdef VCONS_DRAW_INTR
@@ -2227,7 +2238,18 @@
                }
        } else {
                /* got an alpha font */
-               ri->ri_ops.putchar = radeonfb_putchar_aa32;
+               switch(ri->ri_depth) {
+                       case 32:
+                               ri->ri_ops.putchar = radeonfb_putchar_aa32;
+                               break;
+                       case 8:
+                               ri->ri_ops.putchar = radeonfb_putchar_aa8;
+                               break;
+                       default:
+                               /* XXX this should never happen */
+                               panic("%s: depth is not 8 or 32 but we got an alpha font?!",
+                                   __func__);
+               }
        }
        ri->ri_ops.cursor = radeonfb_cursor;
 }
@@ -2360,12 +2382,29 @@
        if (sc->sc_displays[crtc].rd_bpp == 8) {
                /* ANSI palette */
                int j = 0;
+               uint32_t tmp, r, g, b;
 
                 for (i = 0; i <= CLUT_WIDTH; ++i) {
-                       PUT32(sc, RADEON_PALETTE_30_DATA,
-                               (rasops_cmap[j] << 22) |
-                               (rasops_cmap[j + 1] << 12) |
-                               (rasops_cmap[j + 2] << 2));
+                       tmp = i & 0xe0;
+                       /*
+                        * replicate bits so 0xe0 maps to a red value of 0xff
+                        * in order to make white look actually white
+                        */
+                       tmp |= (tmp >> 3) | (tmp >> 6);
+                       r = tmp;
+
+                       tmp = (i & 0x1c) << 3;
+                       tmp |= (tmp >> 3) | (tmp >> 6);
+                       g = tmp;
+
+                       tmp = (i & 0x03) << 6;
+                       tmp |= tmp >> 2;
+                       tmp |= tmp >> 4;
+                       b = tmp;
+               PUT32(sc, RADEON_PALETTE_30_DATA,
+                               (r << 22) |
+                               (g << 12) |
+                               (b << 2));
                        j += 3;
                }
        } else {
@@ -2595,6 +2634,116 @@
                glyphcache_add(&dp->rd_gc, c, xd, yd);
 }
 
+static void
+radeonfb_putchar_aa8(void *cookie, int row, int col, u_int c, long attr)
+{
+       struct rasops_info      *ri = cookie;
+       struct vcons_screen     *scr = ri->ri_hw;
+       struct radeonfb_display *dp = scr->scr_cookie;
+       struct radeonfb_softc   *sc = dp->rd_softc;
+       struct wsdisplay_font   *font = PICK_FONT(ri, c);
+       uint32_t bg, latch = 0, bg8, fg8, pixel, gmc;
+       int i, x, y, wi, he, r, g, b, aval;
+       int r1, g1, b1, r0, g0, b0, fgo, bgo;
+       uint8_t *data8;
+       int rv;
+
+       if (dp->rd_wsmode != 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) {
+               radeonfb_rectfill(dp, x, y, wi, he, bg);
+               return;
+       }
+       rv = glyphcache_try(&dp->rd_gc, c, x, y, attr);
+       if (rv == GC_OK)
+               return;
+
+       data8 = WSFONT_GLYPH(c, font);
+
+       gmc = dp->rd_format << RADEON_GMC_DST_DATATYPE_SHIFT;
+
+       radeonfb_wait_fifo(sc, 5);
+       
+       PUT32(sc, RADEON_DP_GUI_MASTER_CNTL,
+           RADEON_GMC_BRUSH_NONE |
+           RADEON_GMC_SRC_DATATYPE_COLOR |
+           RADEON_ROP3_S |
+           RADEON_DP_SRC_SOURCE_HOST_DATA |
+           RADEON_GMC_CLR_CMP_CNTL_DIS |
+           RADEON_GMC_WR_MSK_DIS |
+           gmc);
+
+       PUT32(sc, RADEON_DP_CNTL,
+           RADEON_DST_X_LEFT_TO_RIGHT |
+           RADEON_DST_Y_TOP_TO_BOTTOM);
+
+       PUT32(sc, RADEON_SRC_X_Y, 0);
+       PUT32(sc, RADEON_DST_X_Y, (x << 16) | y);
+       PUT32(sc, RADEON_DST_WIDTH_HEIGHT, (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);
+       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) {
+                       PUT32S(sc, RADEON_HOST_DATA0, latch);
+                       /*
+                        * not strictly necessary, old data should be shifted 
+                        * out 
+                        */
+                       latch = 0;
+               }
+               data8++;
+       }
+       /* if we have pixels left in latch write them out */
+       if ((i & 3) != 0) {
+               latch = latch << ((4 - (i & 3)) << 3);  
+               PUT32(sc, RADEON_HOST_DATA0, latch);
+       }
+
+       if (rv == GC_ADD)
+               glyphcache_add(&dp->rd_gc, c, x, y);
+}
+
 /*
  * wrapper for software character drawing
  * just sync the engine and call rasops*_putchar()
@@ -2808,7 +2957,7 @@
        radeonfb_engine_flush(sc);
 }
 
-static void
+static inline void
 radeonfb_wait_fifo(struct radeonfb_softc *sc, int n)
 {
        int     i;
diff -r 57c4c3354e37 -r ddf31b0f31b5 sys/dev/pci/radeonfbvar.h
--- a/sys/dev/pci/radeonfbvar.h Tue Feb 28 18:14:47 2012 +0000
+++ b/sys/dev/pci/radeonfbvar.h Tue Feb 28 20:21:16 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: radeonfbvar.h,v 1.14 2012/02/16 17:33:28 macallan Exp $ */
+/* $NetBSD: radeonfbvar.h,v 1.15 2012/02/28 20:21:16 macallan Exp $ */
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -317,6 +317,7 @@
 
 #define        GET32(sc, r)    radeonfb_get32(sc, r)
 #define        PUT32(sc, r, v) radeonfb_put32(sc, r, v)
+#define        PUT32S(sc, r, v)        radeonfb_put32s(sc, r, v)
 #define        SET32(sc, r, v) PUT32(sc, r, GET32(sc, r) | (v))
 #define        CLR32(sc, r, v) PUT32(sc, r, GET32(sc, r) & ~(v))
 #define        PATCH32(sc, r, v, m)    PUT32(sc, r, (GET32(sc, r) & (m)) | (v))
@@ -349,6 +350,7 @@
 
 uint32_t radeonfb_get32(struct radeonfb_softc *, uint32_t);
 void radeonfb_put32(struct radeonfb_softc *, uint32_t, uint32_t);
+void radeonfb_put32s(struct radeonfb_softc *, uint32_t, uint32_t);
 void radeonfb_mask32(struct radeonfb_softc *, uint32_t, uint32_t, uint32_t);
 
 uint32_t radeonfb_getindex(struct radeonfb_softc *, uint32_t);



Home | Main Index | Thread Index | Old Index