Module Name:    src
Committed By:   macallan
Date:           Tue Feb 28 20:21:17 UTC 2012

Modified Files:
        src/sys/dev/pci: radeonfb.c radeonfbvar.h

Log Message:
support anti-aliased fonts in 8 bit as well


To generate a diff of this commit:
cvs rdiff -u -r1.54 -r1.55 src/sys/dev/pci/radeonfb.c
cvs rdiff -u -r1.14 -r1.15 src/sys/dev/pci/radeonfbvar.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/dev/pci/radeonfb.c
diff -u src/sys/dev/pci/radeonfb.c:1.54 src/sys/dev/pci/radeonfb.c:1.55
--- src/sys/dev/pci/radeonfb.c:1.54	Thu Feb 16 17:33:28 2012
+++ src/sys/dev/pci/radeonfb.c	Tue Feb 28 20:21:16 2012
@@ -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_copycols(void *, in
 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 @@ radeonfb_put32(struct radeonfb_softc *sc
 }
 
 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 @@ radeonfb_init_screen(void *cookie, struc
 	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 @@ radeonfb_init_screen(void *cookie, struc
 		}
 	} 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 @@ radeonfb_init_palette(struct radeonfb_so
 	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 @@ radeonfb_putchar_aa32(void *cookie, int 
 		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_idle(struct radeonfb_sof
 	radeonfb_engine_flush(sc);
 }
 
-static void
+static inline void
 radeonfb_wait_fifo(struct radeonfb_softc *sc, int n)
 {
 	int	i;

Index: src/sys/dev/pci/radeonfbvar.h
diff -u src/sys/dev/pci/radeonfbvar.h:1.14 src/sys/dev/pci/radeonfbvar.h:1.15
--- src/sys/dev/pci/radeonfbvar.h:1.14	Thu Feb 16 17:33:28 2012
+++ src/sys/dev/pci/radeonfbvar.h	Tue Feb 28 20:21:16 2012
@@ -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 @@ struct radeonfb_softc {
 
 #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 @@ struct radeonfb_softc {
 
 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);

Reply via email to