mirror of
https://github.com/encounter/SDL.git
synced 2025-12-09 21:47:44 +00:00
timer: Added SDL_GetTicks64(), for a timer that doesn't wrap every ~49 days.
Note that this removes the timeGetTime() fallback on Windows; it is a 32-bit counter and SDL2 should never choose to use it, as it only is needed if QueryPerformanceCounter() isn't available, and QPC is _always_ available on Windows XP and later. OS/2 has a similar situation, but since it isn't clear to me that similar promises can be made about DosTmrQueryTime() even in modern times, I decided to leave the fallback in, with some heroic measures added to try to provide a true 64-bit tick counter despite the 49-day wraparound. That approach can migrate to Windows too, if we discover some truly broken install that doesn't have QPC and still depends on timeGetTime(). Fixes #4870.
This commit is contained in:
@@ -33,12 +33,10 @@
|
||||
static DWORD start = 0;
|
||||
static BOOL ticks_started = FALSE;
|
||||
|
||||
/* Store if a high-resolution performance counter exists on the system */
|
||||
static BOOL hires_timer_available;
|
||||
/* The first high-resolution ticks value of the application */
|
||||
static LARGE_INTEGER hires_start_ticks;
|
||||
static LARGE_INTEGER start_ticks;
|
||||
/* The number of ticks per second of the high-resolution performance counter */
|
||||
static LARGE_INTEGER hires_ticks_per_second;
|
||||
static LARGE_INTEGER ticks_per_second;
|
||||
|
||||
static void
|
||||
SDL_SetSystemTimerResolution(const UINT uPeriod)
|
||||
@@ -79,6 +77,8 @@ SDL_TimerResolutionChanged(void *userdata, const char *name, const char *oldValu
|
||||
void
|
||||
SDL_TicksInit(void)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
if (ticks_started) {
|
||||
return;
|
||||
}
|
||||
@@ -90,18 +90,12 @@ SDL_TicksInit(void)
|
||||
SDL_TimerResolutionChanged, NULL);
|
||||
|
||||
/* Set first ticks value */
|
||||
/* QueryPerformanceCounter has had problems in the past, but lots of games
|
||||
use it, so we'll rely on it here.
|
||||
/* QueryPerformanceCounter allegedly is always available and reliable as of WinXP,
|
||||
so we'll rely on it here.
|
||||
*/
|
||||
if (QueryPerformanceFrequency(&hires_ticks_per_second) == TRUE) {
|
||||
hires_timer_available = TRUE;
|
||||
QueryPerformanceCounter(&hires_start_ticks);
|
||||
} else {
|
||||
hires_timer_available = FALSE;
|
||||
#ifndef __WINRT__
|
||||
start = timeGetTime();
|
||||
#endif /* __WINRT__ */
|
||||
}
|
||||
rc = QueryPerformanceFrequency(&ticks_per_second);
|
||||
SDL_assert(rc != 0); /* this should _never_ fail if you're on XP or later. */
|
||||
QueryPerformanceCounter(&start_ticks);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -116,53 +110,37 @@ SDL_TicksQuit(void)
|
||||
ticks_started = SDL_FALSE;
|
||||
}
|
||||
|
||||
Uint32
|
||||
SDL_GetTicks(void)
|
||||
Uint64
|
||||
SDL_GetTicks64(void)
|
||||
{
|
||||
DWORD now = 0;
|
||||
LARGE_INTEGER hires_now;
|
||||
LARGE_INTEGER now;
|
||||
BOOL rc;
|
||||
|
||||
if (!ticks_started) {
|
||||
SDL_TicksInit();
|
||||
}
|
||||
|
||||
if (hires_timer_available) {
|
||||
QueryPerformanceCounter(&hires_now);
|
||||
|
||||
hires_now.QuadPart -= hires_start_ticks.QuadPart;
|
||||
hires_now.QuadPart *= 1000;
|
||||
hires_now.QuadPart /= hires_ticks_per_second.QuadPart;
|
||||
|
||||
return (DWORD) hires_now.QuadPart;
|
||||
} else {
|
||||
#ifndef __WINRT__
|
||||
now = timeGetTime();
|
||||
#endif /* __WINRT__ */
|
||||
}
|
||||
|
||||
return (now - start);
|
||||
rc = QueryPerformanceCounter(&now);
|
||||
SDL_assert(rc != 0); /* this should _never_ fail if you're on XP or later. */
|
||||
return (Uint64) (((now.QuadPart - start_ticks.QuadPart) * 1000) / ticks_per_second.QuadPart);
|
||||
}
|
||||
|
||||
Uint64
|
||||
SDL_GetPerformanceCounter(void)
|
||||
{
|
||||
LARGE_INTEGER counter;
|
||||
|
||||
if (!QueryPerformanceCounter(&counter)) {
|
||||
return SDL_GetTicks();
|
||||
}
|
||||
return counter.QuadPart;
|
||||
const BOOL rc = QueryPerformanceCounter(&counter);
|
||||
SDL_assert(rc != 0); /* this should _never_ fail if you're on XP or later. */
|
||||
return (Uint64) counter.QuadPart;
|
||||
}
|
||||
|
||||
Uint64
|
||||
SDL_GetPerformanceFrequency(void)
|
||||
{
|
||||
LARGE_INTEGER frequency;
|
||||
|
||||
if (!QueryPerformanceFrequency(&frequency)) {
|
||||
return 1000;
|
||||
}
|
||||
return frequency.QuadPart;
|
||||
const BOOL rc = QueryPerformanceFrequency(&frequency);
|
||||
SDL_assert(rc != 0); /* this should _never_ fail if you're on XP or later. */
|
||||
return (Uint64) frequency.QuadPart;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user