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