diff --git a/hal/src/main/native/sim/HAL.cpp b/hal/src/main/native/sim/HAL.cpp index a319ef7a9d..c0fecfbd04 100644 --- a/hal/src/main/native/sim/HAL.cpp +++ b/hal/src/main/native/sim/HAL.cpp @@ -13,6 +13,7 @@ #ifdef _WIN32 #include +#pragma comment(lib, "Winmm.lib") #pragma comment(lib, "ntdll.lib") extern "C" NTSYSAPI NTSTATUS NTAPI NtSetTimerResolution( ULONG DesiredResolution, BOOLEAN SetResolution, PULONG CurrentResolution); @@ -371,6 +372,19 @@ HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode) { // Set Timer Precision to 0.5ms on Windows #ifdef _WIN32 + // Use timeGetDevCaps as well to prevent Java from interfering + TIMECAPS tc; + if (timeGetDevCaps(&tc, sizeof(tc)) == TIMERR_NOERROR) { + UINT target = (std::max)(static_cast(1), tc.wPeriodMin); + timeBeginPeriod(target); + std::atexit([]() { + TIMECAPS tc; + if (timeGetDevCaps(&tc, sizeof(tc)) == TIMERR_NOERROR) { + UINT target = (std::max)(static_cast(1), tc.wPeriodMin); + timeEndPeriod(target); + } + }); + } // https://stackoverflow.com/questions/3141556/how-to-setup-timer-resolution-to-0-5-ms ULONG min, max, current; if (NtQueryTimerResolution(&min, &max, ¤t) == 0) { @@ -385,31 +399,33 @@ HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode) { // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setprocessinformation // Enable HighQoS to achieve maximum performance, and turn off power saving. - { - PROCESS_POWER_THROTTLING_STATE PowerThrottling{}; - PowerThrottling.Version = PROCESS_POWER_THROTTLING_CURRENT_VERSION; - PowerThrottling.ControlMask = PROCESS_POWER_THROTTLING_EXECUTION_SPEED; - PowerThrottling.StateMask = 0; - - SetProcessInformation(GetCurrentProcess(), ProcessPowerThrottling, - &PowerThrottling, sizeof(PowerThrottling)); - } // https://forums.oculusvr.com/t5/General/SteamVR-has-fixed-the-problems-with-Windows-11/td-p/956413 // Always honor Timer Resolution Requests. This is to ensure that the timer // resolution set-up above sticks through transitions of the main window (eg: // minimization). - { - // This setting was introduced in Windows 11 and the definition is not - // available in older headers. + // This setting was introduced in Windows 11 and the definition is not + // available in older headers. #ifndef PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION - const auto PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION = 0x4U; + const auto PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION = 0x4U; #endif - PROCESS_POWER_THROTTLING_STATE PowerThrottling{}; + // Try both at once, and if that doesn't succeed, only set HighQoS + PROCESS_POWER_THROTTLING_STATE PowerThrottling{}; + PowerThrottling.Version = PROCESS_POWER_THROTTLING_CURRENT_VERSION; + PowerThrottling.ControlMask = + PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION | + PROCESS_POWER_THROTTLING_EXECUTION_SPEED; + PowerThrottling.StateMask = 0; + + auto status = + SetProcessInformation(GetCurrentProcess(), ProcessPowerThrottling, + &PowerThrottling, sizeof(PowerThrottling)); + + // setting both failed, fall back to HighQoS only + if (status == 0) { PowerThrottling.Version = PROCESS_POWER_THROTTLING_CURRENT_VERSION; - PowerThrottling.ControlMask = - PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION; + PowerThrottling.ControlMask = PROCESS_POWER_THROTTLING_EXECUTION_SPEED; PowerThrottling.StateMask = 0; SetProcessInformation(GetCurrentProcess(), ProcessPowerThrottling,