Module Name:    src
Committed By:   macallan
Date:           Thu Aug  9 00:48:07 UTC 2012

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

Log Message:
split ffb_putchar() into a version for mono fonts and one for anti-aliased
ones. While there use the blitter to draw the cursor and remove some waits
that are unnecessary now that characters are drawn by hardware.


To generate a diff of this commit:
cvs rdiff -u -r1.51 -r1.52 src/sys/arch/sparc64/dev/ffb.c
cvs rdiff -u -r1.10 -r1.11 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.51 src/sys/arch/sparc64/dev/ffb.c:1.52
--- src/sys/arch/sparc64/dev/ffb.c:1.51	Thu Apr 12 19:09:18 2012
+++ src/sys/arch/sparc64/dev/ffb.c	Thu Aug  9 00:48:06 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: ffb.c,v 1.51 2012/04/12 19:09:18 macallan Exp $	*/
+/*	$NetBSD: ffb.c,v 1.52 2012/08/09 00:48:06 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.51 2012/04/12 19:09:18 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffb.c,v 1.52 2012/08/09 00:48:06 macallan Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -127,6 +127,7 @@ void	ffb_ras_erasecols(void *, int, int,
 void	ffb_ras_eraserows(void *, int, int, long int);
 void	ffb_ras_do_cursor(struct rasops_info *);
 void	ffb_ras_fill(struct ffb_softc *);
+void	ffb_ras_invert(struct ffb_softc *);
 static void	ffb_ras_setfg(struct ffb_softc *, int32_t);
 static void	ffb_ras_setbg(struct ffb_softc *, int32_t);
 
@@ -135,7 +136,8 @@ int	ffb_load_font(void *, void *, struct
 void	ffb_init_screen(void *, struct vcons_screen *, int, 
 	    long *);
 int	ffb_allocattr(void *, int, int, int, long *);
-void	ffb_putchar(void *, int, int, u_int, long);
+void	ffb_putchar_mono(void *, int, int, u_int, long);
+void	ffb_putchar_aa(void *, int, int, u_int, long);
 void	ffb_cursor(void *, int, int, int);
 
 /* frame buffer generic driver */   
@@ -738,6 +740,19 @@ ffb_ras_fill(struct ffb_softc *sc)
 }
 
 void
+ffb_ras_invert(struct ffb_softc *sc)
+{
+	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_INVERT);
+	FBC_WRITE(sc, FFB_FBC_DRAWOP, FBC_DRAWOP_RECTANGLE);
+	SYNC;
+}
+
+void
 ffb_ras_copyrows(void *cookie, int src, int dst, int n)
 {
 	struct rasops_info *ri = cookie;
@@ -966,7 +981,7 @@ ffb_cursor(void *cookie, int on, int row
 	struct rasops_info *ri = cookie;
 	struct vcons_screen *scr;
 	struct ffb_softc *sc;
-	int x, y, wi, he, coffset;
+	int x, y, wi, he;
 	
 	if (cookie != NULL) {
 		scr = ri->ri_hw;
@@ -976,43 +991,36 @@ ffb_cursor(void *cookie, int on, int row
 		he = ri->ri_font->fontheight;
 
 		if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
-			x = ri->ri_ccol * wi + ri->ri_xorigin;
-			y = ri->ri_crow * he + ri->ri_yorigin;
 	
 			if (ri->ri_flg & RI_CURSOR) {
+
 				/* remove cursor */
-				coffset = ri->ri_ccol + (ri->ri_crow *
-				    ri->ri_cols);
-#ifdef WSDISPLAY_SCROLLSUPPORT
-				coffset += scr->scr_offset_to_zero;
-#endif
-				ffb_ras_wait(sc);
-				ffb_putchar(cookie, ri->ri_crow, 
-				    ri->ri_ccol, scr->scr_chars[coffset], 
-				    scr->scr_attrs[coffset]);
+				x = ri->ri_ccol * wi + ri->ri_xorigin;
+				y = ri->ri_crow * he + ri->ri_yorigin;
+
+				ffb_ras_invert(sc);
+				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);
+
 				ri->ri_flg &= ~RI_CURSOR;
 			}
 			ri->ri_crow = row;
 			ri->ri_ccol = col;
 			if (on)
 			{
-				long attr, revattr;
 				x = ri->ri_ccol * wi + ri->ri_xorigin;
 				y = ri->ri_crow * he + ri->ri_yorigin;
-				coffset = col + (row * ri->ri_cols);
-#ifdef WSDISPLAY_SCROLLSUPPORT
-				coffset += scr->scr_offset_to_zero;
-#endif
-				attr = scr->scr_attrs[coffset];
-#ifdef FFB_CURSOR_SWAP_COLOURS
-				revattr=((attr >> 8 ) & 0x000f0000) | ((attr & 
-				    0x000f0000)<<8) | (attr & 0x0000ffff);
-#else
-				revattr = attr ^ 0xffff0000;
-#endif
-				ffb_ras_wait(sc);
-				ffb_putchar(cookie, ri->ri_crow, ri->ri_ccol,
-				    scr->scr_chars[coffset], revattr);
+
+				ffb_ras_invert(sc);
+				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);
+
 				ri->ri_flg |= RI_CURSOR;
 			}
 		} else {
@@ -1023,8 +1031,9 @@ ffb_cursor(void *cookie, int on, int row
 	}
 }
 
+/* mono bitmap font */
 void
-ffb_putchar(void *cookie, int row, int col, u_int c, long attr)
+ffb_putchar_mono(void *cookie, int row, int col, u_int c, long attr)
 {
 	struct rasops_info *ri = cookie;
 	struct vcons_screen *scr = ri->ri_hw;
@@ -1032,7 +1041,7 @@ ffb_putchar(void *cookie, int row, int c
 	struct ffb_softc *sc = scr->scr_cookie;
 	void *data;
 	uint32_t fg, bg;
-	int uc, i;
+	int i;
 	int x, y, wi, he;
 	
 	if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL)
@@ -1049,102 +1058,122 @@ ffb_putchar(void *cookie, int row, int c
 	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;
+	data = WSFONT_GLYPH(c, font);
 
-	if (font->stride < wi) {
-		/* mono bitmap font */
-		ffb_ras_setbg(sc, bg);
-		ffb_ras_setfg(sc, fg);
-		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 (font->stride) {
-			case 1: {
-				uint8_t *data8 = data;
-				uint32_t reg;
-				for (i = 0; i < he; i++) {
-					reg = *data8;
-					FBC_WRITE(sc, FFB_FBC_FONT, reg << 24);
-					data8++;
-				}
-				break;
+	ffb_ras_setbg(sc, bg);
+	ffb_ras_setfg(sc, fg);
+	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 (font->stride) {
+		case 1: {
+			uint8_t *data8 = data;
+			uint32_t reg;
+			for (i = 0; i < he; i++) {
+				reg = *data8;
+				FBC_WRITE(sc, FFB_FBC_FONT, reg << 24);
+				data8++;
 			}
-			case 2: {
-				uint16_t *data16 = data;
-				uint32_t reg;
-				for (i = 0; i < he; i++) {
-					reg = *data16;
-					FBC_WRITE(sc, FFB_FBC_FONT, reg << 16);
-					data16++;
-				}
-				break;
+			break;
+		}
+		case 2: {
+			uint16_t *data16 = data;
+			uint32_t reg;
+			for (i = 0; i < he; i++) {
+				reg = *data16;
+				FBC_WRITE(sc, FFB_FBC_FONT, reg << 16);
+				data16++;
 			}
+			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;
+/* alpha font */
+void
+ffb_putchar_aa(void *cookie, int row, int col, u_int c, long attr)
+{
+	struct rasops_info *ri = cookie;
+	struct vcons_screen *scr = ri->ri_hw;
+	struct wsdisplay_font *font = PICK_FONT(ri, c);
+	struct ffb_softc *sc = scr->scr_cookie;
+	volatile uint32_t *dest, *ddest;
+	uint8_t *data8;
+	uint32_t fg, bg;
+	int i;
+	int x, y, wi, he;
+	uint32_t alpha = 0x80;
+	int j;
+	
+	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;
+
+	data8 = WSFONT_GLYPH(c, font);
+
+	/* 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 + (y << 11) + 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;
 	} 
 }
 
@@ -1207,7 +1236,10 @@ ffb_init_screen(void *cookie, struct vco
 	ri->ri_ops.erasecols = ffb_ras_erasecols;
 	ri->ri_ops.cursor = ffb_cursor;
 	ri->ri_ops.allocattr = ffb_allocattr;
-	ri->ri_ops.putchar = ffb_putchar;
+	if (FONT_IS_ALPHA(ri->ri_font)) {
+		ri->ri_ops.putchar = ffb_putchar_aa;
+	} else
+		ri->ri_ops.putchar = ffb_putchar_mono;
 }
 
 /* I2C bitbanging */

Index: src/sys/arch/sparc64/dev/ffbreg.h
diff -u src/sys/arch/sparc64/dev/ffbreg.h:1.10 src/sys/arch/sparc64/dev/ffbreg.h:1.11
--- src/sys/arch/sparc64/dev/ffbreg.h:1.10	Thu Dec 22 05:08:05 2011
+++ src/sys/arch/sparc64/dev/ffbreg.h	Thu Aug  9 00:48:06 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: ffbreg.h,v 1.10 2011/12/22 05:08:05 macallan Exp $	*/
+/*	$NetBSD: ffbreg.h,v 1.11 2012/08/09 00:48:06 macallan Exp $	*/
 /*	$OpenBSD: creatorreg.h,v 1.5 2002/07/29 06:21:45 jason Exp $	*/
 
 /*
@@ -284,6 +284,7 @@
 
 #define	FBC_ROP_NEW		0x83
 #define	FBC_ROP_OLD		0x85
+#define	FBC_ROP_INVERT		0x8a
 
 #define	FBC_UCSR_FIFO_MASK	0x00000fff
 #define	FBC_UCSR_FB_BUSY	0x01000000

Reply via email to