Author: toshok
Date: 2007-10-02 23:03:21 -0400 (Tue, 02 Oct 2007)
New Revision: 86794
Modified:
trunk/moon/src/ChangeLog
trunk/moon/src/clock.cpp
trunk/moon/src/clock.h
Log:
2007-10-02 Chris Toshok <[EMAIL PROTECTED]>
* clock.h, clock.cpp: rip out the old stupid throttling code and
replace it with an exponential moving average of the delays.
Modified: trunk/moon/src/ChangeLog
===================================================================
--- trunk/moon/src/ChangeLog 2007-10-03 02:48:36 UTC (rev 86793)
+++ trunk/moon/src/ChangeLog 2007-10-03 03:03:21 UTC (rev 86794)
@@ -1,5 +1,10 @@
2007-10-02 Chris Toshok <[EMAIL PROTECTED]>
+ * clock.h, clock.cpp: rip out the old stupid throttling code and
+ replace it with an exponential moving average of the delays.
+
+2007-10-02 Chris Toshok <[EMAIL PROTECTED]>
+
* clock.h, clock.cpp: add Timeline::Get/SetSpeedRatio methods, and
use them to make test/xaml/clock8.xaml work.
Modified: trunk/moon/src/clock.cpp
===================================================================
--- trunk/moon/src/clock.cpp 2007-10-03 02:48:36 UTC (rev 86793)
+++ trunk/moon/src/clock.cpp 2007-10-03 03:03:21 UTC (rev 86794)
@@ -39,7 +39,7 @@
#define MINIMUM_FPS 5
-#define DEFAULT_FPS 20
+#define DEFAULT_FPS 60
#define MAXIMUM_FPS 60
#define FPS_TO_DELAY(fps) (int)(((double)1/(fps)) * 1000)
@@ -76,13 +76,13 @@
current_fps (DEFAULT_FPS),
current_timeout (FPS_TO_DELAY (DEFAULT_FPS)), /* something suitably small
*/
max_fps (MAXIMUM_FPS),
- strikes (0),
flags (TimeManagerOp (TIME_MANAGER_UPDATE_CLOCKS | TIME_MANAGER_RENDER |
TIME_MANAGER_TICK_CALL /*| TIME_MANAGER_UPDATE_INPUT*/)),
tick_calls (NULL)
{
start_time = get_now ();
tick_call_mutex = g_mutex_new ();
+ first_tick = true;
}
void
@@ -214,54 +214,45 @@
ENDTICKTIMER (tick, "TimeManager::Tick");
TimeSpan post_tick = get_now();
- /* we only count strikes for higher/lower fps if the frame
- took more than 50ms over our timeour, or less than 50ms
- under our timeout. */
- if (post_tick - pre_tick > (TimeSpan)(current_timeout * 10000))
- strikes ++;
- else if (post_tick - pre_tick < (TimeSpan)(current_timeout * 10000) -
100000)
- strikes --;
- else {
-// if (strikes < 0) strikes++;
-// else if (strikes > 0) strikes--;
- }
+ /* implement an exponential moving average by way of simple
+ exponential smoothing:
-#define STRIKE_COUNT 10
-#define FPS_ADJUSTMENT 3
+ s(0) = x(0)
+ s(t) = alpha * x(t) + (1 - alpha) * s(t-1)
- if (strikes > STRIKE_COUNT || strikes < -STRIKE_COUNT) {
- int new_timeout = current_timeout;
-
- if (strikes > STRIKE_COUNT) {
- /* it took us longer than our current_timeout to run
through
- the clock update/render loop. we need to scale back
our
- timeout (lower fps) */
- current_fps -= FPS_ADJUSTMENT;
- }
- else if (strikes < -STRIKE_COUNT) {
- /* it took us less time than our
- current_timeout to run through the clock
- update/render loop. let's make the timeout
- less (higher fps). */
- current_fps += FPS_ADJUSTMENT;
- }
+ where 0 < alpha < 1.
- if (current_fps < MINIMUM_FPS)
- current_fps = MINIMUM_FPS;
- else if (current_fps > max_fps)
- current_fps = max_fps;
+ see http://en.wikipedia.org/wiki/Exponential_smoothing.
+ */
- new_timeout = FPS_TO_DELAY (current_fps);
- strikes = 0;
+#define SMOOTHING_ALPHA 0.60 /* we probably want to play with this value
some.. - toshok */
- if (new_timeout != current_timeout) {
-// printf ("current_fps = %2.3ffps\n", current_fps);
- current_timeout = new_timeout;
- RemoveTimeout();
- AddTimeout();
-// printf ("new timeout is %dms (%.2ffps)\n",
current_timeout, DELAY_TO_FPS (current_timeout));
- }
+
+ TimeSpan xt = post_tick - pre_tick;
+
+ /* the s(0) case */
+ if (first_tick) {
+ first_tick = false;
+ previous_smoothed = xt;
+ return;
}
+
+ /* the s(t) case */
+ TimeSpan current_smoothed = SMOOTHING_ALPHA * xt + (1 -
SMOOTHING_ALPHA) * previous_smoothed;
+
+ /* current_smoothed now contains the prediction for what our next delay
should be */
+
+ current_timeout = current_smoothed / 10000;
+ if (current_timeout < FPS_TO_DELAY (max_fps))
+ current_timeout = FPS_TO_DELAY (max_fps);
+ else if (current_timeout > FPS_TO_DELAY (MINIMUM_FPS))
+ current_timeout = FPS_TO_DELAY (MINIMUM_FPS);
+
+ // printf ("new timeout is %dms (%.2ffps)\n", current_timeout,
DELAY_TO_FPS (current_timeout));
+ RemoveTimeout();
+ AddTimeout();
+
+ previous_smoothed = current_smoothed;
}
void
Modified: trunk/moon/src/clock.h
===================================================================
--- trunk/moon/src/clock.h 2007-10-03 02:48:36 UTC (rev 86793)
+++ trunk/moon/src/clock.h 2007-10-03 03:03:21 UTC (rev 86794)
@@ -221,8 +221,10 @@
double current_fps;
int current_timeout;
int max_fps;
- int strikes; /* used by our lame fps tuning code */
+ bool first_tick;
+ TimeSpan previous_smoothed;
+
enum TimeManagerOp {
TIME_MANAGER_UPDATE_CLOCKS = 0x01,
TIME_MANAGER_RENDER = 0x02,
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches