Module Name:    src
Committed By:   macallan
Date:           Thu Dec 22 05:08:05 UTC 2011

Modified Files:
        src/sys/arch/sparc64/dev: ffb.c ffb_mainbus.c ffbreg.h ffbvar.h

Log Message:
support anti-aliased fonts and let the hardware do the alpha blending


To generate a diff of this commit:
cvs rdiff -u -r1.48 -r1.49 src/sys/arch/sparc64/dev/ffb.c
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/sparc64/dev/ffb_mainbus.c \
    src/sys/arch/sparc64/dev/ffbvar.h
cvs rdiff -u -r1.9 -r1.10 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.48 src/sys/arch/sparc64/dev/ffb.c:1.49
--- src/sys/arch/sparc64/dev/ffb.c:1.48	Mon Oct 31 08:28:46 2011
+++ src/sys/arch/sparc64/dev/ffb.c	Thu Dec 22 05:08:05 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ffb.c,v 1.48 2011/10/31 08:28:46 jdc Exp $	*/
+/*	$NetBSD: ffb.c,v 1.49 2011/12/22 05:08:05 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.48 2011/10/31 08:28:46 jdc Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffb.c,v 1.49 2011/12/22 05:08:05 macallan Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -633,13 +633,13 @@ ffb_ras_init(struct ffb_softc *sc)
 	DPRINTF(("ffb_ras_init: standard resolution.\n"));
 		fbc = FFB_FBC_XE_OFF;
 	}
-	ffb_ras_fifo_wait(sc, 8);
+	ffb_ras_fifo_wait(sc, 11);
 	DPRINTF(("WID: %08x\n", FBC_READ(sc, FFB_FBC_WID)));
 	FBC_WRITE(sc, FFB_FBC_WID, 0x0);
 	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_XS_WID);
+	    FBC_PPC_ABE_DIS | FBC_PPC_XS_WID);
 	    
 	fbc |= FFB_FBC_WB_A | FFB_FBC_RB_A | FFB_FBC_SB_BOTH |
 	       FFB_FBC_RGBE_MASK;
@@ -651,6 +651,11 @@ ffb_ras_init(struct ffb_softc *sc)
 	FBC_WRITE(sc, FFB_FBC_FONTINC, 0x10000);
 	sc->sc_fg_cache = 0;
 	FBC_WRITE(sc, FFB_FBC_FG, sc->sc_fg_cache);
+	FBC_WRITE(sc, FFB_FBC_BLENDC, FFB_BLENDC_FORCE_ONE |
+				      FFB_BLENDC_DF_ONE_M_A |
+				      FFB_BLENDC_SF_A);
+	FBC_WRITE(sc, FFB_FBC_BLENDC1, 0);
+	FBC_WRITE(sc, FFB_FBC_BLENDC2, 0);
 	ffb_ras_wait(sc);
 }
 
@@ -722,7 +727,11 @@ ffb_ras_erasecols(void *cookie, int row,
 void
 ffb_ras_fill(struct ffb_softc *sc)
 {
-	ffb_ras_fifo_wait(sc, 2);
+	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_NEW);
 	FBC_WRITE(sc, FFB_FBC_DRAWOP, FBC_DRAWOP_RECTANGLE);
 	SYNC;
@@ -755,7 +764,11 @@ ffb_ras_copyrows(void *cookie, int src, 
 	src *= ri->ri_font->fontheight;
 	dst *= ri->ri_font->fontheight;
 
-	ffb_ras_fifo_wait(sc, 8);
+	ffb_ras_fifo_wait(sc, 9);
+	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_OLD | (FBC_ROP_OLD << 8));
 	FBC_WRITE(sc, FFB_FBC_DRAWOP, FBC_DRAWOP_VSCROLL);
 	FBC_WRITE(sc, FFB_FBC_BY, ri->ri_yorigin + src);
@@ -1017,34 +1030,42 @@ ffb_putchar(void *cookie, int row, int c
 	struct vcons_screen *scr = ri->ri_hw;
 	struct wsdisplay_font *font = PICK_FONT(ri, c);
 	struct ffb_softc *sc = scr->scr_cookie;
+	void *data;
+	uint32_t fg, bg;
+	int uc, i;
+	int x, y, wi, he;
 	
-	if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
-		void *data;
-		uint32_t fg, bg;
-		int uc, i;
-		int x, y, wi, he;
-
-		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;
+	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;
 
-		uc = c - font->firstchar;
-		data = (uint8_t *)font->data + uc * ri->ri_fontscale;
+	uc = c - font->firstchar;
+	data = (uint8_t *)font->data + uc * ri->ri_fontscale;
 
+	if (font->stride < wi) {
+		/* mono bitmap font */
 		ffb_ras_setbg(sc, bg);
 		ffb_ras_setfg(sc, fg);
-		ffb_ras_fifo_wait(sc, 3);
+		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 (ri->ri_font->stride) {
+		switch (font->stride) {
 			case 1: {
 				uint8_t *data8 = data;
 				uint32_t reg;
@@ -1066,7 +1087,65 @@ ffb_putchar(void *cookie, int row, int c
 				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;
+		}
+	} 
 }
 
 int
@@ -1097,7 +1176,7 @@ ffb_init_screen(void *cookie, struct vco
 	ri->ri_width = sc->sc_width;
 	ri->ri_height = sc->sc_height;
 	ri->ri_stride = sc->sc_linebytes;
-	ri->ri_flg = RI_CENTER;
+	ri->ri_flg = RI_CENTER | RI_ENABLE_ALPHA;
 
 	/*
 	 * we can't accelerate copycols() so instead of falling back to

Index: src/sys/arch/sparc64/dev/ffb_mainbus.c
diff -u src/sys/arch/sparc64/dev/ffb_mainbus.c:1.12 src/sys/arch/sparc64/dev/ffb_mainbus.c:1.13
--- src/sys/arch/sparc64/dev/ffb_mainbus.c:1.12	Mon Oct 31 08:28:46 2011
+++ src/sys/arch/sparc64/dev/ffb_mainbus.c	Thu Dec 22 05:08:05 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ffb_mainbus.c,v 1.12 2011/10/31 08:28:46 jdc Exp $	*/
+/*	$NetBSD: ffb_mainbus.c,v 1.13 2011/12/22 05:08:05 macallan Exp $	*/
 /*	$OpenBSD: creator_mainbus.c,v 1.4 2002/07/26 16:39:04 jason Exp $	*/
 
 /*
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ffb_mainbus.c,v 1.12 2011/10/31 08:28:46 jdc Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffb_mainbus.c,v 1.13 2011/12/22 05:08:05 macallan Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -102,6 +102,14 @@ ffb_mainbus_attach(device_t parent, devi
 		goto unmap_fbc;
 	}
 
+	if (bus_space_map(sc->sc_bt, ma->ma_reg[FFB_REG_SFB32].ur_paddr,
+	    ma->ma_reg[FFB_REG_SFB32].ur_len, BUS_SPACE_MAP_LINEAR,
+	    &sc->sc_sfb32_h)) {
+		panic(": failed to map SFB32\n");
+		goto unmap_dac;
+	}
+	sc->sc_sfb32 = bus_space_vaddr(sc->sc_bt, sc->sc_sfb32_h);
+
 	for (i = 0; i < nregs; i++) {
 		sc->sc_addrs[i] = ma->ma_reg[i].ur_paddr;
 		sc->sc_sizes[i] = ma->ma_reg[i].ur_len;
@@ -118,11 +126,10 @@ ffb_mainbus_attach(device_t parent, devi
 
 	return;
 
-#if notyet
 unmap_dac:
 	bus_space_unmap(sc->sc_bt, sc->sc_dac_h,
 		    ma->ma_reg[FFB_REG_DAC].ur_len);
-#endif
+
 unmap_fbc:
 	bus_space_unmap(sc->sc_bt, sc->sc_fbc_h,
 		    ma->ma_reg[FFB_REG_FBC].ur_len);
Index: src/sys/arch/sparc64/dev/ffbvar.h
diff -u src/sys/arch/sparc64/dev/ffbvar.h:1.12 src/sys/arch/sparc64/dev/ffbvar.h:1.13
--- src/sys/arch/sparc64/dev/ffbvar.h:1.12	Mon Oct 31 08:28:46 2011
+++ src/sys/arch/sparc64/dev/ffbvar.h	Thu Dec 22 05:08:05 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ffbvar.h,v 1.12 2011/10/31 08:28:46 jdc Exp $	*/
+/*	$NetBSD: ffbvar.h,v 1.13 2011/12/22 05:08:05 macallan Exp $	*/
 /*	$OpenBSD: creatorvar.h,v 1.6 2002/07/30 19:48:15 jason Exp $	*/
 
 /*
@@ -54,6 +54,8 @@ struct ffb_softc {
 	bus_space_tag_t sc_bt;
 	bus_space_handle_t sc_dac_h;
 	bus_space_handle_t sc_fbc_h;
+	bus_space_handle_t sc_sfb32_h;
+	uint32_t *sc_sfb32;
 	bus_addr_t sc_addrs[FFB_NREGS];
 	bus_size_t sc_sizes[FFB_NREGS];
 	int sc_height, sc_width, sc_linebytes, sc_depth;

Index: src/sys/arch/sparc64/dev/ffbreg.h
diff -u src/sys/arch/sparc64/dev/ffbreg.h:1.9 src/sys/arch/sparc64/dev/ffbreg.h:1.10
--- src/sys/arch/sparc64/dev/ffbreg.h:1.9	Sun Oct 23 06:06:24 2011
+++ src/sys/arch/sparc64/dev/ffbreg.h	Thu Dec 22 05:08:05 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ffbreg.h,v 1.9 2011/10/23 06:06:24 jdc Exp $	*/
+/*	$NetBSD: ffbreg.h,v 1.10 2011/12/22 05:08:05 macallan Exp $	*/
 /*	$OpenBSD: creatorreg.h,v 1.5 2002/07/29 06:21:45 jason Exp $	*/
 
 /*
@@ -309,4 +309,18 @@
 #define FBC_CFG0_SINGLE_BUF	0x20	/* Single buffer */
 #define FBC_CFG0_DOUBLE_BUF	0x30	/* Double buffer */
 
+/* Alpha Blend Control */
+#define FFB_BLENDC_FORCE_ONE	0x00000010 /* Defines 0xff as 1.0 */
+#define FFB_BLENDC_DF_MASK	0x0000000c /* Destination Frac Mask */
+#define FFB_BLENDC_DF_ZERO	0x00000000 /* Destination Frac: 0.00 */
+#define FFB_BLENDC_DF_ONE	0x00000004 /* Destination Frac: 1.00 */
+#define FFB_BLENDC_DF_ONE_M_A	0x00000008 /* Destination Frac: 1.00 - Xsrc */
+#define FFB_BLENDC_DF_A		0x0000000c /* Destination Frac: Xsrc */
+#define FFB_BLENDC_SF_MASK	0x00000003 /* Source Frac Mask */
+#define FFB_BLENDC_SF_ZERO	0x00000000 /* Source Frac: 0.00 */
+#define FFB_BLENDC_SF_ONE	0x00000001 /* Source Frac: 1.00 */
+#define FFB_BLENDC_SF_ONE_M_A	0x00000002 /* Source Frac: 1.00 - Xsrc */
+#define FFB_BLENDC_SF_A		0x00000003 /* Source Frac: Xsrc */
+
+
 #endif /* FFB_REG_H */

Reply via email to