Author: emaste
Date: Wed Sep  3 14:00:37 2014
New Revision: 271023
URL: http://svnweb.freebsd.org/changeset/base/271023

Log:
  MFC r270280 by dumbbell: 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.
  
  Sponsored by: The FreeBSD Foundation

Modified:
  stable/10/sys/dev/vt/vt.h
  stable/10/sys/dev/vt/vt_core.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/vt/vt.h
==============================================================================
--- stable/10/sys/dev/vt/vt.h   Wed Sep  3 13:40:02 2014        (r271022)
+++ stable/10/sys/dev/vt/vt.h   Wed Sep  3 14:00:37 2014        (r271023)
@@ -128,6 +128,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: stable/10/sys/dev/vt/vt_core.c
==============================================================================
--- stable/10/sys/dev/vt/vt_core.c      Wed Sep  3 13:40:02 2014        
(r271022)
+++ stable/10/sys/dev/vt/vt_core.c      Wed Sep  3 14:00:37 2014        
(r271023)
@@ -225,6 +225,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)
 {
 
@@ -327,6 +358,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);
@@ -335,6 +368,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);
@@ -929,7 +964,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
@@ -2084,6 +2119,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);
@@ -2145,7 +2181,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.
@@ -2176,7 +2212,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);
        }
 
        /*
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to