Merge commit '51245fc0c5c0dec807af95d442e535aad9d7aa01' into dev
This commit is contained in:
86
external/SDL/src/timer/SDL_timer.c
vendored
86
external/SDL/src/timer/SDL_timer.c
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -533,7 +533,7 @@ bool SDL_RemoveTimer(SDL_TimerID id)
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !defined(SDL_PLATFORM_EMSCRIPTEN) || !SDL_THREADS_DISABLED
|
||||
#endif // !SDL_PLATFORM_EMSCRIPTEN || !SDL_THREADS_DISABLED
|
||||
|
||||
static Uint64 tick_start;
|
||||
static Uint32 tick_numerator_ns;
|
||||
@@ -658,21 +658,77 @@ void SDL_Delay(Uint32 ms)
|
||||
|
||||
void SDL_DelayNS(Uint64 ns)
|
||||
{
|
||||
Uint64 current_value = SDL_GetTicksNS();
|
||||
Uint64 target_value = current_value + ns;
|
||||
SDL_SYS_DelayNS(ns);
|
||||
}
|
||||
|
||||
// Sleep for a short number of cycles
|
||||
// We'll use 1 ms as a scheduling timeslice, it's a good value for modern operating systems
|
||||
const int SCHEDULING_TIMESLICE_NS = 1 * SDL_NS_PER_MS;
|
||||
while (current_value < target_value) {
|
||||
Uint64 remaining_ns = (target_value - current_value);
|
||||
if (remaining_ns > (SCHEDULING_TIMESLICE_NS + SDL_NS_PER_US)) {
|
||||
// Sleep for a short time, less than the scheduling timeslice
|
||||
SDL_SYS_DelayNS(SCHEDULING_TIMESLICE_NS - SDL_NS_PER_US);
|
||||
} else {
|
||||
// Spin for any remaining time
|
||||
SDL_CPUPauseInstruction();
|
||||
void SDL_DelayPrecise(Uint64 ns)
|
||||
{
|
||||
Uint64 current_value = SDL_GetTicksNS();
|
||||
const Uint64 target_value = current_value + ns;
|
||||
|
||||
// Sleep for a short number of cycles when real sleeps are desired.
|
||||
// We'll use 1 ms, it's the minimum guaranteed to produce real sleeps across
|
||||
// all platforms.
|
||||
const Uint64 SHORT_SLEEP_NS = 1 * SDL_NS_PER_MS;
|
||||
|
||||
// Try to sleep short of target_value. If for some crazy reason
|
||||
// a particular platform sleeps for less than 1 ms when 1 ms was requested,
|
||||
// that's fine, the code below can cope with that, but in practice no
|
||||
// platforms behave that way.
|
||||
Uint64 max_sleep_ns = SHORT_SLEEP_NS;
|
||||
while (current_value + max_sleep_ns < target_value) {
|
||||
// Sleep for a short time
|
||||
SDL_SYS_DelayNS(SHORT_SLEEP_NS);
|
||||
|
||||
const Uint64 now = SDL_GetTicksNS();
|
||||
const Uint64 next_sleep_ns = (now - current_value);
|
||||
if (next_sleep_ns > max_sleep_ns) {
|
||||
max_sleep_ns = next_sleep_ns;
|
||||
}
|
||||
current_value = now;
|
||||
}
|
||||
|
||||
// Do a shorter sleep of the remaining time here, less the max overshoot in
|
||||
// the first loop. Due to maintaining max_sleep_ns as
|
||||
// greater-than-or-equal-to-1 ms, we can always subtract off 1 ms to get
|
||||
// the duration overshot beyond a 1 ms sleep request; if the system never
|
||||
// overshot, great, it's zero duration. By choosing the max overshoot
|
||||
// amount, we're likely to not overshoot here. If the sleep here ends up
|
||||
// functioning like SDL_DelayNS(0) internally, that's fine, we just don't
|
||||
// get to do a more-precise-than-1 ms-resolution sleep to undershoot by a
|
||||
// small amount on the current system, but SDL_DelayNS(0) does at least
|
||||
// introduce a small, yielding delay on many platforms, better than an
|
||||
// unyielding busyloop.
|
||||
//
|
||||
// Note that we'll always do at least one sleep in this function, so the
|
||||
// minimum resolution will be that of SDL_SYS_DelayNS()
|
||||
if (current_value < target_value && (target_value - current_value) > (max_sleep_ns - SHORT_SLEEP_NS)) {
|
||||
const Uint64 delay_ns = (target_value - current_value) - (max_sleep_ns - SHORT_SLEEP_NS);
|
||||
SDL_SYS_DelayNS(delay_ns);
|
||||
current_value = SDL_GetTicksNS();
|
||||
}
|
||||
|
||||
// We've likely undershot target_value at this point by a pretty small
|
||||
// amount, but maybe not. The footgun case if not handled here is where
|
||||
// we've undershot by a large amount, like several ms, but still smaller
|
||||
// than the amount max_sleep_ns overshot by; in such a situation, the above
|
||||
// shorter-sleep block didn't do any delay, the if-block wasn't entered.
|
||||
// Also, maybe the shorter-sleep undershot by several ms, so we still don't
|
||||
// want to spin a lot then. In such a case, we accept the possibility of
|
||||
// overshooting to not spin much, or if overshot here, not at all, keeping
|
||||
// CPU/power usage down in any case. Due to scheduler sloppiness, it's
|
||||
// entirely possible to end up undershooting/overshooting here by much less
|
||||
// than 1 ms even if the current system's sleep function is only 1
|
||||
// ms-resolution, as SDL_GetTicksNS() generally is better resolution than 1
|
||||
// ms on the systems SDL supports.
|
||||
while (current_value + SHORT_SLEEP_NS < target_value) {
|
||||
SDL_SYS_DelayNS(SHORT_SLEEP_NS);
|
||||
current_value = SDL_GetTicksNS();
|
||||
}
|
||||
|
||||
// Spin for any remaining time
|
||||
while (current_value < target_value) {
|
||||
SDL_CPUPauseInstruction();
|
||||
current_value = SDL_GetTicksNS();
|
||||
}
|
||||
}
|
||||
|
||||
2
external/SDL/src/timer/SDL_timer_c.h
vendored
2
external/SDL/src/timer/SDL_timer_c.h
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
2
external/SDL/src/timer/haiku/SDL_systimer.c
vendored
2
external/SDL/src/timer/haiku/SDL_systimer.c
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
2
external/SDL/src/timer/n3ds/SDL_systimer.c
vendored
2
external/SDL/src/timer/n3ds/SDL_systimer.c
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
59
external/SDL/src/timer/ngage/SDL_systimer.cpp
vendored
59
external/SDL/src/timer/ngage/SDL_systimer.cpp
vendored
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef SDL_TIMER_NGAGE
|
||||
|
||||
#include <e32std.h>
|
||||
#include <e32hal.h>
|
||||
|
||||
static TUint start_tick = 0;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
Uint64 SDL_GetPerformanceCounter(void)
|
||||
{
|
||||
// FIXME: Need to account for 32-bit wrapping
|
||||
return (Uint64)User::TickCount();
|
||||
}
|
||||
|
||||
Uint64 SDL_GetPerformanceFrequency(void)
|
||||
{
|
||||
return SDL_US_PER_SECOND;
|
||||
}
|
||||
|
||||
void SDL_SYS_DelayNS(Uint64 ns)
|
||||
{
|
||||
const Uint64 max_delay = 0x7fffffffLL * SDL_NS_PER_US;
|
||||
if (ns > max_delay) {
|
||||
ns = max_delay;
|
||||
}
|
||||
User::After(TTimeIntervalMicroSeconds32((TInt)SDL_NS_TO_US(ns)));
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SDL_TIMER_NGAGE
|
||||
2
external/SDL/src/timer/ps2/SDL_systimer.c
vendored
2
external/SDL/src/timer/ps2/SDL_systimer.c
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
2
external/SDL/src/timer/psp/SDL_systimer.c
vendored
2
external/SDL/src/timer/psp/SDL_systimer.c
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
4
external/SDL/src/timer/unix/SDL_systimer.c
vendored
4
external/SDL/src/timer/unix/SDL_systimer.c
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -73,7 +73,7 @@ static void CheckMonotonicTime(void)
|
||||
struct timespec value;
|
||||
if (clock_gettime(SDL_MONOTONIC_CLOCK, &value) == 0) {
|
||||
has_monotonic_time = true;
|
||||
} else
|
||||
}
|
||||
#elif defined(SDL_PLATFORM_APPLE)
|
||||
if (mach_timebase_info(&mach_base_info) == 0) {
|
||||
has_monotonic_time = true;
|
||||
|
||||
2
external/SDL/src/timer/vita/SDL_systimer.c
vendored
2
external/SDL/src/timer/vita/SDL_systimer.c
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
54
external/SDL/src/timer/windows/SDL_systimer.c
vendored
54
external/SDL/src/timer/windows/SDL_systimer.c
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -25,13 +25,13 @@
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
|
||||
|
||||
#ifdef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION
|
||||
static void SDL_CleanupWaitableTimer(void *timer)
|
||||
static void SDL_CleanupWaitableHandle(void *handle)
|
||||
{
|
||||
CloseHandle(timer);
|
||||
CloseHandle(handle);
|
||||
}
|
||||
|
||||
HANDLE SDL_GetWaitableTimer(void)
|
||||
#ifdef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION
|
||||
static HANDLE SDL_GetWaitableTimer(void)
|
||||
{
|
||||
static SDL_TLSID TLS_timer_handle;
|
||||
HANDLE timer;
|
||||
@@ -40,13 +40,28 @@ HANDLE SDL_GetWaitableTimer(void)
|
||||
if (!timer) {
|
||||
timer = CreateWaitableTimerExW(NULL, NULL, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
|
||||
if (timer) {
|
||||
SDL_SetTLS(&TLS_timer_handle, timer, SDL_CleanupWaitableTimer);
|
||||
SDL_SetTLS(&TLS_timer_handle, timer, SDL_CleanupWaitableHandle);
|
||||
}
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
#endif // CREATE_WAITABLE_TIMER_HIGH_RESOLUTION
|
||||
|
||||
static HANDLE SDL_GetWaitableEvent(void)
|
||||
{
|
||||
static SDL_TLSID TLS_event_handle;
|
||||
HANDLE event;
|
||||
|
||||
event = SDL_GetTLS(&TLS_event_handle);
|
||||
if (!event) {
|
||||
event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if (event) {
|
||||
SDL_SetTLS(&TLS_event_handle, event, SDL_CleanupWaitableHandle);
|
||||
}
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
Uint64 SDL_GetPerformanceCounter(void)
|
||||
{
|
||||
LARGE_INTEGER counter;
|
||||
@@ -81,22 +96,19 @@ void SDL_SYS_DelayNS(Uint64 ns)
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
const Uint64 max_delay = 0xffffffffLL * SDL_NS_PER_MS;
|
||||
if (ns > max_delay) {
|
||||
ns = max_delay;
|
||||
}
|
||||
|
||||
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER <= 180030723)
|
||||
static HANDLE mutex = 0;
|
||||
if (!mutex) {
|
||||
mutex = CreateEventEx(0, 0, 0, EVENT_ALL_ACCESS);
|
||||
}
|
||||
WaitForSingleObjectEx(mutex, (DWORD)SDL_NS_TO_MS(ns), FALSE);
|
||||
#else
|
||||
Sleep((DWORD)SDL_NS_TO_MS(ns));
|
||||
#endif
|
||||
const Uint64 max_delay = 0xffffffffLL * SDL_NS_PER_MS;
|
||||
if (ns > max_delay) {
|
||||
ns = max_delay;
|
||||
}
|
||||
const DWORD delay = (DWORD)SDL_NS_TO_MS(ns);
|
||||
|
||||
HANDLE event = SDL_GetWaitableEvent();
|
||||
if (event) {
|
||||
WaitForSingleObjectEx(event, delay, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
Sleep(delay);
|
||||
}
|
||||
|
||||
#endif // SDL_TIMER_WINDOWS
|
||||
|
||||
Reference in New Issue
Block a user