Permalink
Browse files

Protect against negative Stopwatch values on buggy systems. Fixes iss…

…ue [#2740}: "OpenTK freeze in GameWindow main loop, and possible fix. (Copied from Development forum)".

git-svn-id: https://opentk.svn.sourceforge.net/svnroot/opentk/trunk@3088 ebc5dd9b-fb1d-0410-b6f8-d24c324e9604
  • Loading branch information...
1 parent e4503c0 commit 6f3c919a5e00b1ea18db3524e59ca34b6ab397f3 the_fiddler committed Nov 3, 2011
Showing with 16 additions and 4 deletions.
  1. +16 −4 Source/OpenTK/GameWindow.cs
@@ -441,7 +441,13 @@ void RaiseUpdateFrame(Stopwatch update_watch, ref double next_update, FrameEvent
// Cap the maximum time drift to 1 second (e.g. when the process is suspended).
double time = update_watch.Elapsed.TotalSeconds;
if (time <= 0)
+ {
+ // Protect against negative Stopwatch.Elapsed values.
+ // See http://connect.microsoft.com/VisualStudio/feedback/details/94083/stopwatch-returns-negative-elapsed-time
+ update_watch.Reset();
+ update_watch.Start();
return;
+ }
if (time > 1.0)
time = 1.0;
@@ -451,7 +457,7 @@ void RaiseUpdateFrame(Stopwatch update_watch, ref double next_update, FrameEvent
next_update -= time;
update_args.Time = time;
OnUpdateFrameInternal(update_args);
- time = update_time = update_watch.Elapsed.TotalSeconds - time;
+ time = update_time = Math.Max(update_watch.Elapsed.TotalSeconds, 0) - time;
// Stopwatches are not accurate over long time periods.
// We accumulate the total elapsed time into the time variable
// while reseting the Stopwatch frequently.
@@ -486,13 +492,19 @@ void RaiseRenderFrame(Stopwatch render_watch, ref double next_render, FrameEvent
{
// Cap the maximum time drift to 1 second (e.g. when the process is suspended).
double time = render_watch.Elapsed.TotalSeconds;
- if (time > 1.0)
- time = 1.0;
if (time <= 0)
+ {
+ // Protect against negative Stopwatch.Elapsed values.
+ // See http://connect.microsoft.com/VisualStudio/feedback/details/94083/stopwatch-returns-negative-elapsed-time
+ render_watch.Reset();
+ render_watch.Start();
return;
+ }
+ if (time > 1.0)
+ time = 1.0;
double time_left = next_render - time;
- if (time_left <= 0.0)
+ if (time_left <= 0.0 && time > 0)
{
// Schedule next render event. The 1 second cap ensures
// the process does not appear to hang.

0 comments on commit 6f3c919

Please sign in to comment.