Module Name:    src
Committed By:   jmcneill
Date:           Tue Feb  8 12:45:04 UTC 2011

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

Log Message:
add support for command buffering in vcons. still a WIP, same limitations
as async drawing (no ddb, needs interrupts). you can try it with options
VCONS_DRAW_INTR. as with async, there are still occasional glitches.


To generate a diff of this commit:
cvs rdiff -u -r1.42 -r1.43 src/sys/dev/wscons/files.wscons
cvs rdiff -u -r1.19 -r1.20 src/sys/dev/wscons/wsdisplay_vcons.c
cvs rdiff -u -r1.13 -r1.14 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/files.wscons
diff -u src/sys/dev/wscons/files.wscons:1.42 src/sys/dev/wscons/files.wscons:1.43
--- src/sys/dev/wscons/files.wscons:1.42	Tue Jan 25 20:28:21 2011
+++ src/sys/dev/wscons/files.wscons	Tue Feb  8 12:45:04 2011
@@ -1,4 +1,4 @@
-# $NetBSD: files.wscons,v 1.42 2011/01/25 20:28:21 macallan Exp $
+# $NetBSD: files.wscons,v 1.43 2011/02/08 12:45:04 jmcneill Exp $
 
 #
 # "Workstation Console" glue; attaches frame buffer to emulator & keyboard,
@@ -76,3 +76,4 @@
 file	dev/wscons/wsdisplay_vcons.c		vcons
 file	dev/wscons/wsdisplay_vcons_util.c	vcons
 defflag	opt_vcons.h		VCONS_DRAW_ASYNC VCONS_ASYNC_DEBUG
+				VCONS_DRAW_INTR VCONS_INTR_DEBUG

Index: src/sys/dev/wscons/wsdisplay_vcons.c
diff -u src/sys/dev/wscons/wsdisplay_vcons.c:1.19 src/sys/dev/wscons/wsdisplay_vcons.c:1.20
--- src/sys/dev/wscons/wsdisplay_vcons.c:1.19	Tue Jan 25 20:28:21 2011
+++ src/sys/dev/wscons/wsdisplay_vcons.c	Tue Feb  8 12:45:04 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: wsdisplay_vcons.c,v 1.19 2011/01/25 20:28:21 macallan Exp $ */
+/*	$NetBSD: wsdisplay_vcons.c,v 1.20 2011/02/08 12:45:04 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2005, 2006 Michael Lorenz
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wsdisplay_vcons.c,v 1.19 2011/01/25 20:28:21 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wsdisplay_vcons.c,v 1.20 2011/02/08 12:45:04 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -55,6 +55,10 @@
 #include "opt_wsdisplay_compat.h"
 #include "opt_vcons.h"
 
+#if defined(VCONS_DRAW_ASYNC) && defined(VCONS_DRAW_INTR)
+#error VCONS_DRAW_ASYNC and VCONS_DRAW_INTR cannot be defined together
+#endif
+
 static void vcons_dummy_init_screen(void *, struct vcons_screen *, int, 
 	    long *);
 
@@ -117,6 +121,10 @@
 #ifdef VCONS_DRAW_ASYNC
 static void vcons_kthread(void *);
 #endif
+#ifdef VCONS_DRAW_INTR
+static void vcons_intr(void *);
+static void vcons_intr_work(struct work *, void *);
+#endif
 
 int
 vcons_init(struct vcons_data *vd, void *cookie, struct wsscreen_descr *def,
@@ -163,6 +171,13 @@
 	kthread_create(PRI_NONE, 0, NULL, vcons_kthread, vd,
 	    &vd->drawing_thread, "vcons_draw");
 #endif
+#ifdef VCONS_DRAW_INTR
+	workqueue_create(&vd->intr_wq, "vcons_draw",
+	    vcons_intr_work, vd, PRI_KTHREAD, IPL_TTY, WQ_MPSAFE);
+	callout_init(&vd->intr, 0);
+	callout_setfunc(&vd->intr, vcons_intr, vd);
+	callout_schedule(&vd->intr, mstohz(33));
+#endif
 	return 0;
 }
 
@@ -562,16 +577,23 @@
 	memmove(&scr->scr_chars[to], &scr->scr_chars[from],
 	    ncols * sizeof(uint16_t));
 #endif
+
+#ifdef VCONS_DRAW_INTR
+	scr->scr_dirty++;
+#endif
 }
 
 static void
 vcons_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
 {
+#if !defined(VCONS_DRAW_INTR) || defined(VCONS_INTR_DEBUG)
 	struct rasops_info *ri = cookie;
 	struct vcons_screen *scr = ri->ri_hw;
+#endif
 
 	vcons_copycols_buffer(cookie, row, srccol, dstcol, ncols);
 
+#if !defined(VCONS_DRAW_INTR) || defined(VCONS_INTR_DEBUG)
 	vcons_lock(scr);
 	if (SCREEN_IS_VISIBLE(scr) && SCREEN_CAN_DRAW(scr)) {
 #ifdef VCONS_DRAW_ASYNC
@@ -583,6 +605,7 @@
 			scr->scr_vd->copycols(cookie, row, srccol, dstcol, ncols);
 	}
 	vcons_unlock(scr);
+#endif
 }
 
 static void
@@ -630,16 +653,23 @@
 		scr->scr_chars[i] = 0x20;
 	}
 #endif
+
+#ifdef VCONS_DRAW_INTR
+	scr->scr_dirty++;
+#endif
 }
 
 static void
 vcons_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr)
 {
+#if !defined(VCONS_DRAW_INTR) || defined(VCONS_INTR_DEBUG)
 	struct rasops_info *ri = cookie;
 	struct vcons_screen *scr = ri->ri_hw;
+#endif
 
 	vcons_erasecols_buffer(cookie, row, startcol, ncols, fillattr);
 
+#if !defined(VCONS_DRAW_INTR) || defined(VCONS_INTR_DEBUG)
 	vcons_lock(scr);
 	if (SCREEN_IS_VISIBLE(scr) && SCREEN_CAN_DRAW(scr)) {
 #ifdef VCONS_DRAW_ASYNC
@@ -653,6 +683,7 @@
 			    fillattr);
 	}
 	vcons_unlock(scr);
+#endif
 }
 
 static void
@@ -689,16 +720,23 @@
 	    len * sizeof(long));
 	memmove(&scr->scr_chars[to], &scr->scr_chars[from],
 	    len * sizeof(uint16_t));
+
+#ifdef VCONS_DRAW_INTR
+	scr->scr_dirty++;
+#endif
 }
 
 static void
 vcons_copyrows(void *cookie, int srcrow, int dstrow, int nrows)
 {
+#if !defined(VCONS_DRAW_INTR) || defined(VCONS_INTR_DEBUG)
 	struct rasops_info *ri = cookie;
 	struct vcons_screen *scr = ri->ri_hw;
+#endif
 
 	vcons_copyrows_buffer(cookie, srcrow, dstrow, nrows);
 
+#if !defined(VCONS_DRAW_INTR) || defined(VCONS_INTR_DEBUG)
 	vcons_lock(scr);
 	if (SCREEN_IS_VISIBLE(scr) && SCREEN_CAN_DRAW(scr)) {
 #ifdef VCONS_DRAW_ASYNC
@@ -710,6 +748,7 @@
 			scr->scr_vd->copyrows(cookie, srcrow, dstrow, nrows);
 	}
 	vcons_unlock(scr);
+#endif
 }
 
 static void
@@ -759,16 +798,23 @@
 		scr->scr_attrs[i] = fillattr;
 		scr->scr_chars[i] = 0x20;
 	}
+
+#ifdef VCONS_DRAW_INTR
+	scr->scr_dirty++;
+#endif
 }
 
 static void
 vcons_eraserows(void *cookie, int row, int nrows, long fillattr)
 {
+#if !defined(VCONS_DRAW_INTR) || defined(VCONS_INTR_DEBUG)
 	struct rasops_info *ri = cookie;
 	struct vcons_screen *scr = ri->ri_hw;
+#endif
 
 	vcons_eraserows_buffer(cookie, row, nrows, fillattr);
 
+#if !defined(VCONS_DRAW_INTR) || defined(VCONS_INTR_DEBUG)
 	vcons_lock(scr);
 	if (SCREEN_IS_VISIBLE(scr) && SCREEN_CAN_DRAW(scr)) {
 #ifdef VCONS_DRAW_ASYNC
@@ -780,6 +826,7 @@
 			scr->scr_vd->eraserows(cookie, row, nrows, fillattr);
 	}
 	vcons_unlock(scr);
+#endif
 }
 
 static void
@@ -807,16 +854,23 @@
 		scr->scr_chars[pos] = c;
 	}
 #endif
+
+#ifdef VCONS_DRAW_INTR
+	scr->scr_dirty++;
+#endif
 }
 
 static void
 vcons_putchar(void *cookie, int row, int col, u_int c, long attr)
 {
+#if !defined(VCONS_DRAW_INTR) || defined(VCONS_INTR_DEBUG)
 	struct rasops_info *ri = cookie;
 	struct vcons_screen *scr = ri->ri_hw;
+#endif
 	
 	vcons_putchar_buffer(cookie, row, col, c, attr);
 	
+#if !defined(VCONS_DRAW_INTR) || defined(VCONS_INTR_DEBUG)
 	vcons_lock(scr);
 	if (SCREEN_IS_VISIBLE(scr) && SCREEN_CAN_DRAW(scr)) {
 #ifdef VCONS_DRAW_ASYNC
@@ -828,6 +882,7 @@
 			scr->scr_vd->putchar(cookie, row, col, c, attr);
 	}
 	vcons_unlock(scr);
+#endif
 }
 
 static void
@@ -836,7 +891,15 @@
 	struct rasops_info *ri = cookie;
 	struct vcons_screen *scr = ri->ri_hw;
 
+
 	vcons_lock(scr);
+#if defined(VCONS_DRAW_INTR)
+	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;
+		scr->scr_dirty++;
+	}
+#else
 	if (SCREEN_IS_VISIBLE(scr) && SCREEN_CAN_DRAW(scr)) {
 #ifdef VCONS_DRAW_ASYNC
 		struct vcons_data *vd = scr->scr_vd;
@@ -849,6 +912,7 @@
 		scr->scr_ri.ri_crow = row;
 		scr->scr_ri.ri_ccol = col;
 	}
+#endif
 	vcons_unlock(scr);
 }
 
@@ -1331,3 +1395,30 @@
 	}
 }
 #endif /* VCONS_DRAW_ASYNC */
+
+#ifdef VCONS_DRAW_INTR
+static void
+vcons_intr(void *cookie)
+{
+	struct vcons_data *vd = cookie;
+
+	workqueue_enqueue(vd->intr_wq, &vd->wk, NULL);
+}
+
+static void
+vcons_intr_work(struct work *wk, void *cookie)
+{
+	struct vcons_data *vd = cookie;
+	struct vcons_screen *scr = vd->active;
+
+	if (scr) {
+		if (!SCREEN_IS_BUSY(scr) && scr->scr_dirty > 0) {
+			if ((scr->scr_flags & VCONS_NO_REDRAW) == 0)
+				vcons_redraw_screen(scr);
+			scr->scr_dirty = 0;
+		}
+	}
+
+	callout_schedule(&vd->intr, mstohz(33));
+}
+#endif /* VCONS_DRAW_INTR */

Index: src/sys/dev/wscons/wsdisplay_vconsvar.h
diff -u src/sys/dev/wscons/wsdisplay_vconsvar.h:1.13 src/sys/dev/wscons/wsdisplay_vconsvar.h:1.14
--- src/sys/dev/wscons/wsdisplay_vconsvar.h:1.13	Tue Jan 25 20:28:21 2011
+++ src/sys/dev/wscons/wsdisplay_vconsvar.h	Tue Feb  8 12:45:04 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: wsdisplay_vconsvar.h,v 1.13 2011/01/25 20:28:21 macallan Exp $ */
+/*	$NetBSD: wsdisplay_vconsvar.h,v 1.14 2011/02/08 12:45:04 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2005, 2006 Michael Lorenz
@@ -32,6 +32,8 @@
 #include "opt_wsdisplay_compat.h"
 #include "opt_vcons.h"
 
+#include <sys/workqueue.h>
+
 struct vcons_data;
 
 struct vcons_screen {
@@ -73,6 +75,9 @@
 	int scr_offset_to_zero;
 	int scr_current_offset;
 #endif
+#ifdef VCONS_DRAW_INTR
+	int scr_dirty;
+#endif
 };
 
 #define SCREEN_IS_VISIBLE(scr) (((scr)->scr_status & VCONS_IS_VISIBLE) != 0)
@@ -132,6 +137,11 @@
 				 * drawing_mutex held */
 	uint32_t rb_buffer[VCONS_RING_BUFFER_LENGTH];
 #endif
+#ifdef VCONS_DRAW_INTR
+	callout_t intr;
+	struct workqueue *intr_wq;
+	struct work wk;
+#endif
 };
 
 /*

Reply via email to