trying to improve the timers some
authorDana Jansens <danakj@orodu.net>
Thu, 6 Mar 2008 15:40:19 +0000 (10:40 -0500)
committerDana Jansens <danakj@orodu.net>
Thu, 6 Mar 2008 15:40:19 +0000 (10:40 -0500)
dcompmgr.c
fade.c
screen.c

index 71f3eee..8fa0b28 100644 (file)
@@ -266,18 +266,18 @@ event(d_display_t *dpy)
 }
 
 static void
-timeouts(d_display_t *dpy)
+timeouts(d_display_t *dpy, const struct timeval *now)
 {
     d_list_it_t *it;
-    struct timeval now;
 
-    gettimeofday(&now, NULL);
-    
     for (it = list_top(dpy->screens); it; it = it->next) {
         d_screen_t *sc = it->data;
+        struct timeval tv;
 
-        render_timeout(sc, &now);
-        fade_timeout(sc, &now);
+        if (render_next_timeout(sc, &tv) && time_compare(&tv, now) <= 0)
+            render_timeout(sc, now);
+        if (fade_next_timeout(sc, &tv) && time_compare(&tv, now) <= 0)
+            fade_timeout(sc, now);
     }
 }
 
@@ -285,14 +285,10 @@ static void
 paint(d_display_t *dpy)
 {
     d_list_it_t *it;
-    struct timeval now;
 
-    gettimeofday(&now, NULL);
-    
     for (it = list_top(dpy->screens); it; it = it->next) {
         d_screen_t *sc = it->data;
-
-        if (time_compare(&sc->next_repaint, &now) <= 0)
+        if (sc->need_repaint)
             sc->screen_paint(sc);
     }
 }
@@ -300,8 +296,13 @@ paint(d_display_t *dpy)
 static void
 run(d_display_t *dpy)
 {
+    struct timeval now, next_repaint;
+
+    gettimeofday(&now, NULL);
+    next_repaint = now;
+
     while (!quit) {
-        struct timeval next, now, *wait;
+        struct timeval next, *wait;
         int            r, npaint, ntime;
         d_list_it_t   *it;
         fd_set         fds;
@@ -315,32 +316,27 @@ run(d_display_t *dpy)
             struct timeval next_timeout;
 
             if (render_next_timeout(sc, &next_timeout)) {
-                if ((!npaint && !ntime) ||
-                    time_compare(&next_timeout, &next) < 0)
-                {
+                if (!ntime || time_compare(&next_timeout, &next) < 0) {
                     next = next_timeout;
                     ++ntime;
                 }
             }
             if (fade_next_timeout(sc, &next_timeout)) {
-                if ((!npaint && !ntime) ||
-                    time_compare(&next_timeout, &next) < 0)
-                {
+                if (!ntime || time_compare(&next_timeout, &next) < 0) {
                     next = next_timeout;
                     ++ntime;
                 }
             }
 
-            if (sc->need_repaint &&
-                ((!npaint && !ntime) ||
-                 time_compare(&sc->next_repaint, &next) < 0))
-            {
-                next = sc->next_repaint;
+            if (sc->need_repaint)
                 ++npaint;
-            }
         }
 
-        gettimeofday(&now, 0);
+        if (npaint) {
+            if (!ntime || time_compare(&next_repaint, &next) < 0) {
+                next = next_repaint;
+            }
+        }
 
         if (!npaint && !ntime)
             /* wait forever, there is nothing that needs drawing */
@@ -353,7 +349,7 @@ run(d_display_t *dpy)
         else {
             /* don't wait cuz a timer is due now already */
             next.tv_sec = 0;
-            next.tv_usec = 0;
+            next.tv_usec = 1;
             wait = &next;
         }
 
@@ -363,10 +359,16 @@ run(d_display_t *dpy)
         //printf("select %d\n", npaint);
 
         r = select(dpy->fd+1, &fds, NULL, NULL, wait);
+
+        gettimeofday(&now, NULL);
         if (r == 0) {
             //printf("select timeout\n");
-            timeouts(dpy);
-            paint(dpy);
+            timeouts(dpy, &now);
+            if (time_compare(&next_repaint, &now) <= 0) {
+                paint(dpy);
+                next_repaint = now;
+                time_add(&next_repaint, 1000000/90); /* 60hz */
+            }
             xcb_flush(dpy->conn);
         }
 
diff --git a/fade.c b/fade.c
index 8244333..eb59ec6 100644 (file)
--- a/fade.c
+++ b/fade.c
@@ -52,8 +52,8 @@ fade_init(d_screen_t *sc, int id)
     sc->window_hide = fade_window_hide;
 
     d->fades = list_new();
-    d->fade_step_time = 5000;     /* 5 milliseconds */
-    d->fade_total_time = 150000;  /* 0.15 seconds */
+    d->fade_step_time = 10000;     /* 5 milliseconds */
+    d->fade_total_time = 200000;  /* 0.15 seconds */
 }
 
 void
@@ -82,7 +82,7 @@ fade_window_show(d_window_t *w)
     data_t *d;
 
     if (!window_is_input_only(w))
-        start_fade(w, 0, 0xffff);
+        start_fade(w, 0x0000, 0xffff);
 
     d = screen_find_plugin_data(w->sc, plugin_id);
     d->window_show(w);    
@@ -94,7 +94,7 @@ fade_window_hide(d_window_t *w)
     data_t *d;
 
     if (!window_is_input_only(w))
-        start_fade(w, 0xffff, 0);
+        start_fade(w, 0xffff, 0x0000);
 
     d = screen_find_plugin_data(w->sc, plugin_id);
     d->window_hide(w);
@@ -192,30 +192,38 @@ fade_timeout(struct d_screen *sc, const struct timeval *now)
 
     for (it = list_top(d->fades); it; it = next) {
         fade_t *fade = it->data;
-        struct timeval time_done, total_time;
-        unsigned long done, total;
-        double percent;
 
         next = it->next;
 
-        time_difference(now, &fade->start_time, &time_done);
-        time_difference(&fade->end_time, &fade->start_time, &total_time);
-
-        /* count milliseconds */
-        done = time_done.tv_sec * 1000 + time_done.tv_usec / 1000;
-        total = total_time.tv_sec * 1000 + total_time.tv_usec / 1000;
-        percent = (double)done / total;
-
-        //printf("done %lu total %lu percent %f\n", done, total, percent);
-
-        if (percent >= 1)
+        if (time_compare(&fade->end_time, now) <= 0) {
+            /* done */
             fade->current_alpha = fade->end_alpha;
-        else if (fade->end_alpha > fade->start_alpha)
-            fade->current_alpha = fade->start_alpha +
-                (fade->end_alpha - fade->start_alpha) * percent;
-        else
-            fade->current_alpha = fade->start_alpha -
-                (fade->start_alpha - fade->end_alpha) * percent;
+        }
+        else {
+            struct timeval total_time, time_left;
+            unsigned long remain, total;
+            double percent;
+
+            time_difference(&fade->end_time, now, &time_left);
+            time_difference(&fade->end_time, &fade->start_time, &total_time);
+
+
+            /* count milliseconds */
+            remain = time_left.tv_sec * 1000 + time_left.tv_usec / 1000;
+            total = total_time.tv_sec * 1000 + total_time.tv_usec / 1000;
+            percent = (double)remain / total;
+
+            //printf("done %lu total %lu percent %f\n", done, total, percent);
+
+            if (fade->end_alpha > fade->start_alpha)
+                /* increasing */
+                fade->current_alpha = fade->end_alpha -
+                    (fade->end_alpha - fade->start_alpha) * percent;
+            else
+                /* decreasing */
+                fade->current_alpha = fade->end_alpha +
+                    (fade->start_alpha - fade->end_alpha) * percent;
+        }
 
         window_set_opacity(fade->w, fade->current_alpha);
 
@@ -227,5 +235,6 @@ fade_timeout(struct d_screen *sc, const struct timeval *now)
             g_free(fade);
         }
     }
+    d->next_timeout = *now;
     time_add(&d->next_timeout, d->fade_step_time);
 }
index af7772d..7a68c80 100644 (file)
--- a/screen.c
+++ b/screen.c
@@ -23,7 +23,6 @@
 static gboolean screen_init(d_screen_t *sc);
 static xcb_timestamp_t screen_timestamp(d_screen_t *sc);
 static void screen_add_existing_windows(d_screen_t *sc);
-static void screen_set_next_repaint(d_screen_t *sc);
 
 static guint
 xcb_window_hash(xcb_window_t *w) { return *w; }
@@ -43,7 +42,6 @@ screen_new(struct d_display *dpy, int num, xcb_screen_t *xcb)
     sc->dpy = dpy;
     sc->num = num;
 
-    gettimeofday(&sc->next_repaint, NULL);
     sc->need_repaint = TRUE;
 
     sc->winhash = g_hash_table_new((GHashFunc)xcb_window_hash,
@@ -365,18 +363,15 @@ void screen_stacking_move_to_bottom(d_screen_t *sc, struct d_window *w)
 }
 
 static void
-screen_set_next_repaint(d_screen_t *sc)
+screen_set_need_repaint(d_screen_t *sc)
 {
-    gettimeofday(&sc->next_repaint, NULL);
-    /* add time for the refresh rate (60 hz) */
-    time_add(&sc->next_repaint, 1000000/60);
     sc->need_repaint = FALSE;
 }
 
 void
 screen_setup_default_functions(d_screen_t *sc)
 {
-    sc->screen_paint = screen_set_next_repaint;
+    sc->screen_paint = screen_set_need_repaint;
     sc->window_show = window_show;
     sc->window_hide = window_hide;
     sc->window_become_zombie = window_become_zombie;