Windows: Always set the system timer resolution to 1ms by default.
authorRyan C. Gordon <icculus@icculus.org>
Mon, 20 Apr 2015 12:22:44 -0400
changeset 9566 7454bfce9202
parent 9563 537881242756
child 9567 b69cac1cbc8f
Windows: Always set the system timer resolution to 1ms by default. An existing hint lets apps that don't need the timer resolution changed avoid this, to save battery, etc, but this fixes several problems in timing, audio callbacks not firing fast enough, etc. Fixes Bugzilla #2944.
src/timer/windows/SDL_systimer.c
--- a/src/timer/windows/SDL_systimer.c	Thu Apr 16 22:04:35 2015 +0200
+++ b/src/timer/windows/SDL_systimer.c	Mon Apr 20 12:22:44 2015 -0400
@@ -43,7 +43,7 @@
 
 #ifndef __WINRT__
 static void
-timeSetPeriod(UINT uPeriod)
+timeSetPeriod(const UINT uPeriod)
 {
     static UINT timer_period = 0;
 
@@ -87,6 +87,11 @@
     }
     ticks_started = SDL_TRUE;
 
+    /* if we didn't set a precision, set it high. This affects lots of things
+       on Windows besides the SDL timers, like audio callbacks, etc. */
+    SDL_AddHintCallback(SDL_HINT_TIMER_RESOLUTION,
+                        SDL_TimerResolutionChanged, NULL);
+
     /* Set first ticks value */
 #ifdef USE_GETTICKCOUNT
     start = GetTickCount();
@@ -102,11 +107,7 @@
 #ifdef __WINRT__
         start = 0;            /* the timer failed to start! */
 #else
-        timeSetPeriod(1);     /* use 1 ms timer precision */
         start = timeGetTime();
-
-        SDL_AddHintCallback(SDL_HINT_TIMER_RESOLUTION,
-                            SDL_TimerResolutionChanged, NULL);
 #endif /* __WINRT__ */
     }
 #endif /* USE_GETTICKCOUNT */
@@ -120,12 +121,14 @@
 #ifndef __WINRT__
         SDL_DelHintCallback(SDL_HINT_TIMER_RESOLUTION,
                             SDL_TimerResolutionChanged, NULL);
-
-        timeSetPeriod(0);
 #endif /* __WINRT__ */
     }
 #endif /* USE_GETTICKCOUNT */
 
+#ifndef __WINRT__
+    timeSetPeriod(0);  /* always release our timer resolution request. */
+#endif
+
     ticks_started = SDL_FALSE;
 }