SDL_systimer.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. Simple DirectMedia Layer
  3. Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
  4. This software is provided 'as-is', without any express or implied
  5. warranty. In no event will the authors be held liable for any damages
  6. arising from the use of this software.
  7. Permission is granted to anyone to use this software for any purpose,
  8. including commercial applications, and to alter it and redistribute it
  9. freely, subject to the following restrictions:
  10. 1. The origin of this software must not be misrepresented; you must not
  11. claim that you wrote the original software. If you use this software
  12. in a product, an acknowledgment in the product documentation would be
  13. appreciated but is not required.
  14. 2. Altered source versions must be plainly marked as such, and must not be
  15. misrepresented as being the original software.
  16. 3. This notice may not be removed or altered from any source distribution.
  17. */
  18. #include "SDL_internal.h"
  19. #ifdef SDL_TIMER_WINDOWS
  20. #include "../../core/windows/SDL_windows.h"
  21. Uint64
  22. SDL_GetPerformanceCounter(void)
  23. {
  24. LARGE_INTEGER counter;
  25. const BOOL rc = QueryPerformanceCounter(&counter);
  26. SDL_assert(rc != 0); /* this should _never_ fail if you're on XP or later. */
  27. return (Uint64)counter.QuadPart;
  28. }
  29. Uint64
  30. SDL_GetPerformanceFrequency(void)
  31. {
  32. LARGE_INTEGER frequency;
  33. const BOOL rc = QueryPerformanceFrequency(&frequency);
  34. SDL_assert(rc != 0); /* this should _never_ fail if you're on XP or later. */
  35. return (Uint64)frequency.QuadPart;
  36. }
  37. void SDL_DelayNS(Uint64 ns)
  38. {
  39. /* CREATE_WAITABLE_TIMER_HIGH_RESOLUTION flag was added in Windows 10 version 1803.
  40. *
  41. * Sleep() is not publicly available to apps in early versions of WinRT.
  42. *
  43. * Visual C++ 2013 Update 4 re-introduced Sleep() for Windows 8.1 and
  44. * Windows Phone 8.1.
  45. *
  46. * Use the compiler version to determine availability.
  47. *
  48. * NOTE #1: _MSC_FULL_VER == 180030723 for Visual C++ 2013 Update 3.
  49. * NOTE #2: Visual C++ 2013, when compiling for Windows 8.0 and
  50. * Windows Phone 8.0, uses the Visual C++ 2012 compiler to build
  51. * apps and libraries.
  52. */
  53. #ifdef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION
  54. HANDLE timer = CreateWaitableTimerExW(NULL, NULL, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
  55. if (timer) {
  56. LARGE_INTEGER due_time;
  57. due_time.QuadPart = -((LONGLONG)ns / 100);
  58. if (SetWaitableTimerEx(timer, &due_time, 0, NULL, NULL, NULL, 0)) {
  59. WaitForSingleObject(timer, INFINITE);
  60. }
  61. CloseHandle(timer);
  62. return;
  63. }
  64. #endif
  65. {
  66. const Uint64 max_delay = 0xffffffffLLU * SDL_NS_PER_MS;
  67. if (ns > max_delay) {
  68. ns = max_delay;
  69. }
  70. #if defined(__WINRT__) && defined(_MSC_FULL_VER) && (_MSC_FULL_VER <= 180030723)
  71. static HANDLE mutex = 0;
  72. if (!mutex) {
  73. mutex = CreateEventEx(0, 0, 0, EVENT_ALL_ACCESS);
  74. }
  75. WaitForSingleObjectEx(mutex, (DWORD)SDL_NS_TO_MS(ns), FALSE);
  76. #else
  77. Sleep((DWORD)SDL_NS_TO_MS(ns));
  78. #endif
  79. }
  80. }
  81. #endif /* SDL_TIMER_WINDOWS */