Module Name:    src
Committed By:   macallan
Date:           Thu Jan 21 21:45:42 UTC 2021

Modified Files:
        src/sys/dev/wscons: wsdisplay_vcons.c wsdisplay_vconsvar.h

Log Message:
introduce a putchar() based implementation of cursor() in order to avoid
framebuffer reads
quite a speedup on arm64 / genfb


To generate a diff of this commit:
cvs rdiff -u -r1.47 -r1.48 src/sys/dev/wscons/wsdisplay_vcons.c
cvs rdiff -u -r1.30 -r1.31 src/sys/dev/wscons/wsdisplay_vconsvar.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/wscons/wsdisplay_vcons.c
diff -u src/sys/dev/wscons/wsdisplay_vcons.c:1.47 src/sys/dev/wscons/wsdisplay_vcons.c:1.48
--- src/sys/dev/wscons/wsdisplay_vcons.c:1.47	Sun Jan 17 19:03:32 2021
+++ src/sys/dev/wscons/wsdisplay_vcons.c	Thu Jan 21 21:45:42 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: wsdisplay_vcons.c,v 1.47 2021/01/17 19:03:32 jmcneill Exp $ */
+/*	$NetBSD: wsdisplay_vcons.c,v 1.48 2021/01/21 21:45:42 macallan Exp $ */
 
 /*-
  * Copyright (c) 2005, 2006 Michael Lorenz
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wsdisplay_vcons.c,v 1.47 2021/01/17 19:03:32 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wsdisplay_vcons.c,v 1.48 2021/01/21 21:45:42 macallan Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -103,6 +103,7 @@ static void vcons_eraserows_cached(void 
 static void vcons_putchar_cached(void *, int, int, u_int, long);
 #endif
 static void vcons_cursor(void *, int, int, int);
+static void vcons_cursor_noread(void *, int, int, int);
 
 /*
  * methods that avoid framebuffer reads
@@ -352,7 +353,12 @@ vcons_init_screen(struct vcons_data *vd,
 	ri->ri_ops.eraserows = vcons_eraserows;	
 	ri->ri_ops.erasecols = vcons_erasecols;	
 	ri->ri_ops.putchar   = vcons_putchar;
-	ri->ri_ops.cursor    = vcons_cursor;
+	if (scr->scr_flags & VCONS_NO_CURSOR) {
+		ri->ri_ops.cursor    = vcons_cursor_noread;
+	} else {
+		ri->ri_ops.cursor    = vcons_cursor;
+	}
+
 	ri->ri_ops.copycols  = vcons_copycols;
 	ri->ri_ops.copyrows  = vcons_copyrows;
 
@@ -469,7 +475,10 @@ vcons_load_font(void *v, void *cookie, s
 	ri->ri_ops.eraserows = vcons_eraserows;	
 	ri->ri_ops.erasecols = vcons_erasecols;	
 	ri->ri_ops.putchar   = vcons_putchar;
-	ri->ri_ops.cursor    = vcons_cursor;
+	if (scr->scr_flags & VCONS_NO_CURSOR) {
+		ri->ri_ops.cursor    = vcons_cursor_noread;
+	} else
+		ri->ri_ops.cursor    = vcons_cursor;
 	ri->ri_ops.copycols  = vcons_copycols;
 	ri->ri_ops.copyrows  = vcons_copyrows;
 	vcons_unlock(vd->active);
@@ -609,8 +618,8 @@ vcons_redraw_screen(struct vcons_screen 
 				if (c == ' ') {
 					/*
 					 * if we already erased the background
-					 * and this blank uses the same colour
-					 * and flags we don't need to do
+					 * and if this blank uses the same 
+					 * colour and flags we don't need to do
 					 * anything here
 					 */
 					if (acmp == cmp && start == -1)
@@ -1301,6 +1310,60 @@ vcons_cursor(void *cookie, int on, int r
 	vcons_unlock(scr);
 }
 
+static void
+vcons_cursor_noread(void *cookie, int on, int row, int col)
+{
+	struct rasops_info *ri = cookie;
+	struct vcons_screen *scr = ri->ri_hw;
+	int offset = 0;	
+
+#if defined(VCONS_DRAW_INTR)
+	if (scr->scr_vd->use_intr) {
+		vcons_lock(scr);
+		if (scr->scr_ri.ri_crow != row || scr->scr_ri.ri_ccol != col) {
+			scr->scr_ri.ri_crow = row;
+			scr->scr_ri.ri_ccol = col;
+			atomic_inc_uint(&scr->scr_dirty);
+		}
+		vcons_unlock(scr);
+		return;
+	}
+#endif
+
+	vcons_lock(scr);
+
+#ifdef WSDISPLAY_SCROLLSUPPORT
+	offset = scr->scr_current_offset;
+#endif
+	if (SCREEN_IS_VISIBLE(scr) && SCREEN_CAN_DRAW(scr)) {
+		int ofs = offset + ri->ri_crow * ri->ri_cols + ri->ri_ccol;
+		if (ri->ri_flg & RI_CURSOR) {
+			scr->putchar(cookie, ri->ri_crow, ri->ri_ccol,
+			    scr->scr_chars[ofs], scr->scr_attrs[ofs]);
+			ri->ri_flg &= ~RI_CURSOR;
+		}
+		ri->ri_crow = row;
+		ri->ri_ccol = col;
+		ofs = offset + ri->ri_crow * ri->ri_cols + ri->ri_ccol;
+		if (on) {
+			scr->putchar(cookie, row, col, scr->scr_chars[ofs],
+#ifdef VCONS_DEBUG_CURSOR_NOREAD
+			/* draw a red cursor so we can tell which cursor() 
+			 * implementation is being used */
+			    ((scr->scr_attrs[ofs] & 0xff00ffff) ^ 0x0f000000) |
+			      0x00010000);
+#else
+			    scr->scr_attrs[ofs] ^ 0x0f0f0000);
+#endif
+			ri->ri_flg |= RI_CURSOR;
+		}
+	} else {
+		scr->scr_ri.ri_crow = row;
+		scr->scr_ri.ri_ccol = col;
+	}
+	vcons_unlock(scr);
+}
+
 /* methods to read/write characters via ioctl() */
 
 static int

Index: src/sys/dev/wscons/wsdisplay_vconsvar.h
diff -u src/sys/dev/wscons/wsdisplay_vconsvar.h:1.30 src/sys/dev/wscons/wsdisplay_vconsvar.h:1.31
--- src/sys/dev/wscons/wsdisplay_vconsvar.h:1.30	Sun Jan 17 19:03:32 2021
+++ src/sys/dev/wscons/wsdisplay_vconsvar.h	Thu Jan 21 21:45:42 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: wsdisplay_vconsvar.h,v 1.30 2021/01/17 19:03:32 jmcneill Exp $ */
+/*	$NetBSD: wsdisplay_vconsvar.h,v 1.31 2021/01/21 21:45:42 macallan Exp $ */
 
 /*-
  * Copyright (c) 2005, 2006 Michael Lorenz
@@ -65,9 +65,11 @@ struct vcons_screen {
  */
 #define VCONS_NO_COPYCOLS	0x10	/* use putchar() based copycols() */
 #define VCONS_NO_COPYROWS	0x20	/* use putchar() based copyrows() */
-#define VCONS_DONT_READ		(VCONS_NO_COPYCOLS|VCONS_NO_COPYROWS)
+#define VCONS_DONT_READ		(VCONS_NO_COPYCOLS|VCONS_NO_COPYROWS|VCONS_NO_CURSOR)
 					/* avoid framebuffer reads */
 #define VCONS_LOADFONT		0x40	/* driver can load_font() */
+#define VCONS_NO_CURSOR		0x80	/* use putchar() based cursor(), to
+					 * avoid fb reads */
 	/* status flags used by vcons */
 	uint32_t scr_status;
 #define VCONS_IS_VISIBLE	1	/* this screen is currently visible */

Reply via email to