Merge commit '51245fc0c5c0dec807af95d442e535aad9d7aa01' into dev

This commit is contained in:
Simone
2025-01-07 15:13:06 +00:00
1409 changed files with 71349 additions and 41303 deletions

View File

@@ -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();
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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