svn commit: r270280 - head/sys/dev/vt

Jean-Sebastien Pedron dumbbell at FreeBSD.org
Thu Aug 21 15:55:19 UTC 2014


Author: dumbbell
Date: Thu Aug 21 15:55:18 2014
New Revision: 270280
URL: http://svnweb.freebsd.org/changeset/base/270280

Log:
  vt(4): Pause the flush timer while swithing window
  
  This fixes bad looking refresh when switching window: squares instead
  of text, flashing screen, and so on. In the worst case, vt_flush() came
  at a very inappropriate timing and the screen was not refreshed at all
  (leaving squares all over the place).
  
  This doesn't fix the flickering of the screen with vt_vga, because the
  sync signal is temporarily stopped and the video memory is cleared.
  
  MFC after:	1 week

Modified:
  head/sys/dev/vt/vt.h
  head/sys/dev/vt/vt_core.c

Modified: head/sys/dev/vt/vt.h
==============================================================================
--- head/sys/dev/vt/vt.h	Thu Aug 21 15:32:38 2014	(r270279)
+++ head/sys/dev/vt/vt.h	Thu Aug 21 15:55:18 2014	(r270280)
@@ -133,6 +133,7 @@ struct vt_device {
 	struct mtx		 vd_lock;	/* Per-device lock. */
 	struct cv		 vd_winswitch;	/* (d) Window switch notify. */
 	struct callout		 vd_timer;	/* (d) Display timer. */
+	volatile unsigned int	 vd_timer_armed;/* (?) Display timer started.*/
 	int			 vd_flags;	/* (d) Device flags. */
 #define	VDF_TEXTMODE	0x01	/* Do text mode rendering. */
 #define	VDF_SPLASH	0x02	/* Splash screen active. */

Modified: head/sys/dev/vt/vt_core.c
==============================================================================
--- head/sys/dev/vt/vt_core.c	Thu Aug 21 15:32:38 2014	(r270279)
+++ head/sys/dev/vt/vt_core.c	Thu Aug 21 15:55:18 2014	(r270280)
@@ -228,6 +228,37 @@ vt_update_static(void *dummy)
 }
 
 static void
+vt_schedule_flush(struct vt_device *vd, int ms)
+{
+
+	if (ms <= 0)
+		/* Default to initial value. */
+		ms = 1000 / VT_TIMERFREQ;
+
+	callout_schedule(&vd->vd_timer, hz / (1000 / ms));
+}
+
+static void
+vt_resume_flush_timer(struct vt_device *vd, int ms)
+{
+
+	if (!atomic_cmpset_int(&vd->vd_timer_armed, 0, 1))
+		return;
+
+	vt_schedule_flush(vd, ms);
+}
+
+static void
+vt_suspend_flush_timer(struct vt_device *vd)
+{
+
+	if (!atomic_cmpset_int(&vd->vd_timer_armed, 1, 0))
+		return;
+
+	callout_drain(&vd->vd_timer);
+}
+
+static void
 vt_switch_timer(void *arg)
 {
 
@@ -330,6 +361,8 @@ vt_window_switch(struct vt_window *vw)
 		return (EINVAL);
 	}
 
+	vt_suspend_flush_timer(vd);
+
 	vd->vd_curwindow = vw;
 	vd->vd_flags |= VDF_INVALID;
 	cv_broadcast(&vd->vd_winswitch);
@@ -338,6 +371,8 @@ vt_window_switch(struct vt_window *vw)
 	if (vd->vd_driver->vd_postswitch)
 		vd->vd_driver->vd_postswitch(vd);
 
+	vt_resume_flush_timer(vd, 0);
+
 	/* Restore per-window keyboard mode. */
 	mtx_lock(&Giant);
 	kbd = kbd_get_keyboard(vd->vd_keyboard);
@@ -936,7 +971,7 @@ vt_timer(void *arg)
 	vt_flush(vd);
 
 	/* Schedule for next update. */
-	callout_schedule(&vd->vd_timer, hz / VT_TIMERFREQ);
+	vt_schedule_flush(vd, 0);
 }
 
 static void
@@ -2091,6 +2126,7 @@ vt_upgrade(struct vt_device *vd)
 		/* Start timer when everything ready. */
 		vd->vd_flags |= VDF_ASYNC;
 		callout_reset(&vd->vd_timer, hz / VT_TIMERFREQ, vt_timer, vd);
+		vd->vd_timer_armed = 1;
 	}
 
 	VT_UNLOCK(vd);
@@ -2150,7 +2186,7 @@ vt_allocate(struct vt_driver *drv, void 
 
 	if (vd->vd_flags & VDF_ASYNC) {
 		/* Stop vt_flush periodic task. */
-		callout_drain(&vd->vd_timer);
+		vt_suspend_flush_timer(vd);
 		/*
 		 * Mute current terminal until we done. vt_change_font (called
 		 * from vt_resize) will unmute it.
@@ -2181,7 +2217,7 @@ vt_allocate(struct vt_driver *drv, void 
 		/* Allow to put chars now. */
 		terminal_mute(vd->vd_curwindow->vw_terminal, 0);
 		/* Rerun timer for screen updates. */
-		callout_schedule(&vd->vd_timer, hz / VT_TIMERFREQ);
+		vt_resume_flush_timer(vd, 0);
 	}
 
 	/*


More information about the svn-src-all mailing list