diff --git a/readme.html b/readme.html index b933810a..8a7303e9 100644 --- a/readme.html +++ b/readme.html @@ -309,6 +309,7 @@ version of GLFW.

  • [Cocoa] Bugfix: The loop condition for saving video modes used the wrong index variable
  • [Cocoa] Bugfix: The OpenGL framework was not retrieved, making glfwGetProcAddress crash
  • [X11] Added support for the GLX_EXT_swap_control extension as an alternative to GLX_SGI_swap_control
  • +
  • [X11] Added the POSIX CLOCK_MONOTONIC time source as the preferred method
  • [X11] Bugfix: Calling glXCreateContextAttribsARB with an unavailable OpenGL version caused the application to terminate with a BadMatch Xlib error
  • [Win32] Removed explicit support for versions of Windows older than Windows XP
  • [Win32] Bugfix: Window activation and iconification did not work as expected
  • diff --git a/src/x11_init.c b/src/x11_init.c index 03cc617f..9af7783e 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -639,6 +639,9 @@ const char* _glfwPlatformGetVersionString(void) #else " no-extension-support" #endif +#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) + " clock_gettime" +#endif #if defined(_GLFW_USE_LINUX_JOYSTICKS) " Linux-joystick-API" #else diff --git a/src/x11_platform.h b/src/x11_platform.h index df7cdb15..b3cf642e 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -31,9 +31,9 @@ #ifndef _platform_h_ #define _platform_h_ -#include #include #include +#include #include #include #include @@ -220,8 +220,9 @@ typedef struct _GLFWlibraryX11 // Timer data struct { + GLboolean monotonic; double resolution; - long long t0; + uint64_t t0; } timer; #if defined(_GLFW_DLOPEN_LIBGL) diff --git a/src/x11_time.c b/src/x11_time.c index ab7d0c40..431389c4 100644 --- a/src/x11_time.c +++ b/src/x11_time.c @@ -30,6 +30,33 @@ #include "internal.h" +#include + + +//======================================================================== +// Return raw time +//======================================================================== + +static uint64_t getRawTime(void) +{ +#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) + if (_glfwLibrary.X11.timer.monotonic) + { + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC, &ts); + return (uint64_t) ts.tv_sec * (uint64_t) 1000000000 + (uint64_t) ts.tv_nsec; + } + else +#endif + { + struct timeval tv; + + gettimeofday(&tv, NULL); + return (uint64_t) tv.tv_sec * (uint64_t) 1000000 + (uint64_t) tv.tv_usec; + } +} + //======================================================================== // Initialise timer @@ -37,15 +64,21 @@ void _glfwInitTimer(void) { - struct timeval tv; +#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) + struct timespec ts; - // "Resolution" is 1 us - _glfwLibrary.X11.timer.resolution = 1e-6; + if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) + { + _glfwLibrary.X11.timer.monotonic = GL_TRUE; + _glfwLibrary.X11.timer.resolution = 1e-9; + } + else +#endif + { + _glfwLibrary.X11.timer.resolution = 1e-6; + } - // Set start-time for timer - gettimeofday(&tv, NULL); - _glfwLibrary.X11.timer.t0 = (long long) tv.tv_sec * (long long) 1000000 + - (long long) tv.tv_usec; + _glfwLibrary.X11.timer.t0 = getRawTime(); } @@ -59,14 +92,8 @@ void _glfwInitTimer(void) double _glfwPlatformGetTime(void) { - long long t; - struct timeval tv; - - gettimeofday(&tv, NULL); - t = (long long) tv.tv_sec * (long long) 1000000 + - (long long) tv.tv_usec; - - return (double)(t - _glfwLibrary.X11.timer.t0) * _glfwLibrary.X11.timer.resolution; + return (double) (getRawTime() - _glfwLibrary.X11.timer.t0) * + _glfwLibrary.X11.timer.resolution; } @@ -76,14 +103,7 @@ double _glfwPlatformGetTime(void) void _glfwPlatformSetTime(double t) { - long long t0; - struct timeval tv; - - gettimeofday(&tv, NULL); - t0 = (long long) tv.tv_sec * (long long) 1000000 + - (long long) tv.tv_usec; - - // Calulate new starting time - _glfwLibrary.X11.timer.t0 = t0 - (long long)(t / _glfwLibrary.X11.timer.resolution); + _glfwLibrary.X11.timer.t0 = getRawTime() - + (uint64_t) (t / _glfwLibrary.X11.timer.resolution); }