mirror of
https://github.com/glfw/glfw.git
synced 2024-11-22 13:04:35 +00:00
Add glfwGetTimerValue and glfwGetTimerFrequency
This adds raw timer access to the public API and builds the floating-point time functions on top. It also makes the GLFWuint64 type public.
This commit is contained in:
parent
8221aadea3
commit
31f67dd3cc
@ -83,6 +83,8 @@ does not find Doxygen, the documentation will not be generated.
|
||||
absolute and relative window size limits
|
||||
- Added `glfwGetKeyName` for querying the layout-specific name of printable
|
||||
keys
|
||||
- Added `glfwGetTimerValue` and `glfwGetTimerFrequency` for raw timer access
|
||||
- Added `GLFWuint64` for platform-independent 64-bit unsigned values
|
||||
- Added `GLFW_NO_API` for creating window without contexts
|
||||
- Added `GLFW_CONTEXT_NO_ERROR` context hint for `GL_KHR_no_error` support
|
||||
- Added `GLFW_INCLUDE_VULKAN` for including the Vulkan header
|
||||
|
@ -554,6 +554,21 @@ glfwSetTime(4.0);
|
||||
|
||||
This sets the timer to the specified time, in seconds.
|
||||
|
||||
You can also access the raw timer value, in 1 / frequency seconds,
|
||||
with @ref glfwGetTimerValue.
|
||||
|
||||
@code
|
||||
GLFWuint64 value = glfwGetTimerValue();
|
||||
@endcode
|
||||
|
||||
The frequency of the raw timer varies depending on what time sources are
|
||||
available on the machine. You can query its frequency, in Hz, with @ref
|
||||
glfwGetTimerFrequency.
|
||||
|
||||
@code
|
||||
GLFWuint64 freqency = glfwGetTimerFrequency();
|
||||
@endcode
|
||||
|
||||
|
||||
@section clipboard Clipboard input and output
|
||||
|
||||
|
@ -37,6 +37,12 @@ GLFW now supports window maximization with @ref glfwMaximizeWindow and the
|
||||
GLFW now supports giving windows input focus with @ref glfwFocusWindow.
|
||||
|
||||
|
||||
@subsection news_32_timer Raw timer access
|
||||
|
||||
GLFW now supports raw timer values with @ref glfwGetTimerValue and @ref
|
||||
glfwGetTimerFrequency.
|
||||
|
||||
|
||||
@section news_31 New features in 3.1
|
||||
|
||||
These are the release highlights. For a full list of changes see the
|
||||
|
@ -728,6 +728,19 @@ extern "C" {
|
||||
* GLFW API types
|
||||
*************************************************************************/
|
||||
|
||||
/*! @brief 64-bit unsigned integer.
|
||||
*
|
||||
* 64-bit unsigned integer.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*/
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1600)
|
||||
typedef unsigned __int64 GLFWuint64;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
typedef uint64_t GLFWuint64;
|
||||
#endif
|
||||
|
||||
/*! @brief Client API function pointer type.
|
||||
*
|
||||
* Generic function pointer used for returning client API function pointers
|
||||
@ -3557,6 +3570,47 @@ GLFWAPI double glfwGetTime(void);
|
||||
*/
|
||||
GLFWAPI void glfwSetTime(double time);
|
||||
|
||||
/*! @brief Returns the current value of the raw timer.
|
||||
*
|
||||
* This function returns the current value of the raw timer. To get its
|
||||
* frequency, call @ref glfwGetTimerFrequency.
|
||||
*
|
||||
* @return The value of the timer, or zero if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_INVALID_VALUE.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread.
|
||||
*
|
||||
* @sa @ref time
|
||||
* @sa glfwGetTimerFrequency
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
GLFWAPI GLFWuint64 glfwGetTimerValue(void);
|
||||
|
||||
/*! @brief Returns the frequency, in Hz, of the raw timer.
|
||||
*
|
||||
* @return The frequency of the timer, in Hz, or zero if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_INVALID_VALUE.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread.
|
||||
*
|
||||
* @sa @ref time
|
||||
* @sa glfwGetTimerValue
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
GLFWAPI GLFWuint64 glfwGetTimerFrequency(void);
|
||||
|
||||
/*! @brief Makes the context of the specified window current for the calling
|
||||
* thread.
|
||||
*
|
||||
|
@ -118,8 +118,7 @@ typedef struct _GLFWcursorNS
|
||||
//
|
||||
typedef struct _GLFWtimeNS
|
||||
{
|
||||
double base;
|
||||
double resolution;
|
||||
GLFWuint64 frequency;
|
||||
|
||||
} _GLFWtimeNS;
|
||||
|
||||
|
@ -29,14 +29,6 @@
|
||||
#include <mach/mach_time.h>
|
||||
|
||||
|
||||
// Return raw time
|
||||
//
|
||||
static uint64_t getRawTime(void)
|
||||
{
|
||||
return mach_absolute_time();
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -48,8 +40,7 @@ void _glfwInitTimerNS(void)
|
||||
mach_timebase_info_data_t info;
|
||||
mach_timebase_info(&info);
|
||||
|
||||
_glfw.ns_time.resolution = (double) info.numer / (info.denom * 1.0e9);
|
||||
_glfw.ns_time.base = getRawTime();
|
||||
_glfw.ns_time.frequency = (info.denom * 1e9) / info.numer;
|
||||
}
|
||||
|
||||
|
||||
@ -57,15 +48,13 @@ void _glfwInitTimerNS(void)
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
double _glfwPlatformGetTime(void)
|
||||
GLFWuint64 _glfwPlatformGetTimerValue(void)
|
||||
{
|
||||
return (double) (getRawTime() - _glfw.ns_time.base) *
|
||||
_glfw.ns_time.resolution;
|
||||
return mach_absolute_time();
|
||||
}
|
||||
|
||||
void _glfwPlatformSetTime(double time)
|
||||
GLFWuint64 _glfwPlatformGetTimerFrequency(void)
|
||||
{
|
||||
_glfw.ns_time.base = getRawTime() -
|
||||
(uint64_t) (time / _glfw.ns_time.resolution);
|
||||
return _glfw.ns_time.frequency;
|
||||
}
|
||||
|
||||
|
@ -135,6 +135,8 @@ GLFWAPI int glfwInit(void)
|
||||
_glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount);
|
||||
_glfwInitialized = GLFW_TRUE;
|
||||
|
||||
_glfw.timerOffset = _glfwPlatformGetTimerValue();
|
||||
|
||||
// Not all window hints have zero as their default value
|
||||
glfwDefaultWindowHints();
|
||||
|
||||
|
18
src/input.c
18
src/input.c
@ -645,7 +645,8 @@ GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle)
|
||||
GLFWAPI double glfwGetTime(void)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(0.0);
|
||||
return _glfwPlatformGetTime();
|
||||
return (double) (_glfwPlatformGetTimerValue() - _glfw.timerOffset) /
|
||||
_glfwPlatformGetTimerFrequency();
|
||||
}
|
||||
|
||||
GLFWAPI void glfwSetTime(double time)
|
||||
@ -658,6 +659,19 @@ GLFWAPI void glfwSetTime(double time)
|
||||
return;
|
||||
}
|
||||
|
||||
_glfwPlatformSetTime(time);
|
||||
_glfw.timerOffset = _glfwPlatformGetTimerValue() -
|
||||
(GLFWuint64) (time * _glfwPlatformGetTimerFrequency());
|
||||
}
|
||||
|
||||
GLFWAPI GLFWuint64 glfwGetTimerValue(void)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(0);
|
||||
return _glfwPlatformGetTimerValue();
|
||||
}
|
||||
|
||||
GLFWAPI GLFWuint64 glfwGetTimerFrequency(void)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(0);
|
||||
return _glfwPlatformGetTimerFrequency();
|
||||
}
|
||||
|
||||
|
@ -47,13 +47,6 @@
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include "../include/GLFW/glfw3.h"
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1600)
|
||||
typedef unsigned __int64 GLFWuint64;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
typedef uint64_t GLFWuint64;
|
||||
#endif
|
||||
|
||||
typedef int GLFWbool;
|
||||
|
||||
typedef struct _GLFWwndconfig _GLFWwndconfig;
|
||||
@ -432,6 +425,8 @@ struct _GLFWlibrary
|
||||
_GLFWmonitor** monitors;
|
||||
int monitorCount;
|
||||
|
||||
GLFWuint64 timerOffset;
|
||||
|
||||
struct {
|
||||
GLFWbool available;
|
||||
void* handle;
|
||||
@ -596,15 +591,15 @@ const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count);
|
||||
*/
|
||||
const char* _glfwPlatformGetJoystickName(int joy);
|
||||
|
||||
/*! @copydoc glfwGetTime
|
||||
/*! @copydoc glfwGetTimerValue
|
||||
* @ingroup platform
|
||||
*/
|
||||
double _glfwPlatformGetTime(void);
|
||||
GLFWuint64 _glfwPlatformGetTimerValue(void);
|
||||
|
||||
/*! @copydoc glfwSetTime
|
||||
/*! @copydoc glfwGetTimerFrequency
|
||||
* @ingroup platform
|
||||
*/
|
||||
void _glfwPlatformSetTime(double time);
|
||||
GLFWuint64 _glfwPlatformGetTimerFrequency(void);
|
||||
|
||||
/*! @ingroup platform
|
||||
*/
|
||||
|
@ -30,28 +30,6 @@
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
// Return raw time
|
||||
//
|
||||
static uint64_t getRawTime(void)
|
||||
{
|
||||
#if defined(CLOCK_MONOTONIC)
|
||||
if (_glfw.posix_time.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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
@ -67,15 +45,14 @@ void _glfwInitTimerPOSIX(void)
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
|
||||
{
|
||||
_glfw.posix_time.monotonic = GLFW_TRUE;
|
||||
_glfw.posix_time.resolution = 1e-9;
|
||||
_glfw.posix_time.frequency = 1000000000;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
_glfw.posix_time.resolution = 1e-6;
|
||||
_glfw.posix_time.monotonic = GLFW_FALSE;
|
||||
_glfw.posix_time.frequency = 1000000;
|
||||
}
|
||||
|
||||
_glfw.posix_time.base = getRawTime();
|
||||
}
|
||||
|
||||
|
||||
@ -83,15 +60,26 @@ void _glfwInitTimerPOSIX(void)
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
double _glfwPlatformGetTime(void)
|
||||
GLFWuint64 _glfwPlatformGetTimerValue(void)
|
||||
{
|
||||
return (double) (getRawTime() - _glfw.posix_time.base) *
|
||||
_glfw.posix_time.resolution;
|
||||
#if defined(CLOCK_MONOTONIC)
|
||||
if (_glfw.posix_time.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;
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformSetTime(double time)
|
||||
GLFWuint64 _glfwPlatformGetTimerFrequency(void)
|
||||
{
|
||||
_glfw.posix_time.base = getRawTime() -
|
||||
(uint64_t) (time / _glfw.posix_time.resolution);
|
||||
return _glfw.posix_time.frequency;
|
||||
}
|
||||
|
||||
|
@ -38,8 +38,7 @@
|
||||
typedef struct _GLFWtimePOSIX
|
||||
{
|
||||
GLFWbool monotonic;
|
||||
double resolution;
|
||||
uint64_t base;
|
||||
GLFWuint64 frequency;
|
||||
|
||||
} _GLFWtimePOSIX;
|
||||
|
||||
|
@ -277,8 +277,7 @@ typedef struct _GLFWcursorWin32
|
||||
typedef struct _GLFWtimeWin32
|
||||
{
|
||||
GLFWbool hasPC;
|
||||
double resolution;
|
||||
unsigned __int64 base;
|
||||
GLFWuint64 frequency;
|
||||
|
||||
} _GLFWtimeWin32;
|
||||
|
||||
|
@ -28,21 +28,6 @@
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
// Return raw time
|
||||
//
|
||||
static unsigned __int64 getRawTime(void)
|
||||
{
|
||||
if (_glfw.win32_time.hasPC)
|
||||
{
|
||||
unsigned __int64 time;
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &time);
|
||||
return time;
|
||||
}
|
||||
else
|
||||
return (unsigned __int64) _glfw_timeGetTime();
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -51,20 +36,18 @@ static unsigned __int64 getRawTime(void)
|
||||
//
|
||||
void _glfwInitTimerWin32(void)
|
||||
{
|
||||
unsigned __int64 frequency;
|
||||
GLFWuint64 frequency;
|
||||
|
||||
if (QueryPerformanceFrequency((LARGE_INTEGER*) &frequency))
|
||||
{
|
||||
_glfw.win32_time.hasPC = GLFW_TRUE;
|
||||
_glfw.win32_time.resolution = 1.0 / (double) frequency;
|
||||
_glfw.win32_time.frequency = frequency;
|
||||
}
|
||||
else
|
||||
{
|
||||
_glfw.win32_time.hasPC = GLFW_FALSE;
|
||||
_glfw.win32_time.resolution = 0.001; // winmm resolution is 1 ms
|
||||
_glfw.win32_time.frequency = 1000;
|
||||
}
|
||||
|
||||
_glfw.win32_time.base = getRawTime();
|
||||
}
|
||||
|
||||
|
||||
@ -72,15 +55,20 @@ void _glfwInitTimerWin32(void)
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
double _glfwPlatformGetTime(void)
|
||||
GLFWuint64 _glfwPlatformGetTimerValue(void)
|
||||
{
|
||||
return (double) (getRawTime() - _glfw.win32_time.base) *
|
||||
_glfw.win32_time.resolution;
|
||||
if (_glfw.win32_time.hasPC)
|
||||
{
|
||||
GLFWuint64 value;
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &value);
|
||||
return value;
|
||||
}
|
||||
else
|
||||
return (GLFWuint64) _glfw_timeGetTime();
|
||||
}
|
||||
|
||||
void _glfwPlatformSetTime(double time)
|
||||
GLFWuint64 _glfwPlatformGetTimerFrequency(void)
|
||||
{
|
||||
_glfw.win32_time.base = getRawTime() -
|
||||
(unsigned __int64) (time / _glfw.win32_time.resolution);
|
||||
return _glfw.win32_time.frequency;
|
||||
}
|
||||
|
||||
|
@ -1688,7 +1688,7 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
||||
if (!_glfwPlatformWindowVisible(window) &&
|
||||
_glfw.x11.NET_REQUEST_FRAME_EXTENTS)
|
||||
{
|
||||
double base;
|
||||
GLFWuint64 base;
|
||||
XEvent event;
|
||||
|
||||
// Ensure _NET_FRAME_EXTENTS is set, allowing glfwGetWindowFrameSize to
|
||||
@ -1696,13 +1696,14 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
||||
sendEventToWM(window, _glfw.x11.NET_REQUEST_FRAME_EXTENTS,
|
||||
0, 0, 0, 0, 0);
|
||||
|
||||
base = _glfwPlatformGetTimerValue();
|
||||
|
||||
// HACK: Poll with timeout for the required reply instead of blocking
|
||||
// This is done because some window managers (at least Unity,
|
||||
// Fluxbox and Xfwm) failed to send the required reply
|
||||
// They have been fixed but broken versions are still in the wild
|
||||
// If you are affected by this and your window manager is NOT
|
||||
// listed above, PLEASE report it to their and our issue trackers
|
||||
base = _glfwPlatformGetTime();
|
||||
while (!XCheckIfEvent(_glfw.x11.display,
|
||||
&event,
|
||||
isFrameExtentsEvent,
|
||||
@ -1711,7 +1712,8 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
||||
double remaining;
|
||||
struct timeval timeout;
|
||||
|
||||
remaining = 0.5 + base - _glfwPlatformGetTime();
|
||||
remaining = 0.5 - (_glfwPlatformGetTimerValue() - base) /
|
||||
(double) _glfwPlatformGetTimerFrequency();
|
||||
if (remaining <= 0.0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
|
Loading…
Reference in New Issue
Block a user