mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2026-07-24 07:40:45 +00:00
Improve support for high-resolution stats
* This patch adds a new microsecond-resolution function call, LiGetMicroseconds(), to complement the existing LiGetMillis(). Many variables used by stats have been updated to work at this higher resolution and now provide better results when displaying e.g. sub-millisecond frametime stats. To try and avoid confusion, variables that now contain microseconds have been renamed with a suffix of 'Us', and those ending in 'Ms' contain milliseconds. I originally experimented with nanoseconds but it felt like overkill for our needs. Public API in Limelight.h: uint64_t LiGetMicroseconds(void); uint64_t LiGetMillis(void); const RTP_AUDIO_STATS* LiGetRTPAudioStats(void); // provides access to RTP data for the overlay stats const RTP_VIDEO_STATS* LiGetRTPVideoStats(void); Note: Users of this library may need to make changes. If using LiGetMillis() to track the duration of something that is shown to the user, consider switching to LiGetMicroseconds(). Remember to divide by 1000 at time of display to show in milliseconds.
This commit is contained in:
committed by
Cameron Gutman
parent
5f2280183c
commit
82ee2d6590
+148
-13
@@ -419,24 +419,157 @@ void PltWaitForConditionVariable(PLT_COND* cond, PLT_MUTEX* mutex) {
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t PltGetMillis(void) {
|
||||
//// Begin timing functions
|
||||
|
||||
// These functions return a number of microseconds or milliseconds since an opaque start time.
|
||||
|
||||
static bool has_monotonic_time = false;
|
||||
static bool ticks_started = false;
|
||||
|
||||
#if defined(LC_WINDOWS)
|
||||
return GetTickCount64();
|
||||
#elif defined(CLOCK_MONOTONIC) && !defined(NO_CLOCK_GETTIME)
|
||||
struct timespec tv;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &tv);
|
||||
static LARGE_INTEGER start_ticks;
|
||||
static LARGE_INTEGER ticks_per_second;
|
||||
|
||||
return ((uint64_t)tv.tv_sec * 1000) + (tv.tv_nsec / 1000000);
|
||||
#else
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
return ((uint64_t)tv.tv_sec * 1000) + (tv.tv_usec / 1000);
|
||||
#endif
|
||||
void PltTicksInit(void) {
|
||||
if (ticks_started) {
|
||||
return;
|
||||
}
|
||||
ticks_started = true;
|
||||
QueryPerformanceFrequency(&ticks_per_second);
|
||||
QueryPerformanceCounter(&start_ticks);
|
||||
}
|
||||
|
||||
uint64_t PltGetMicroseconds(void) {
|
||||
if (!ticks_started) {
|
||||
PltTicksInit();
|
||||
}
|
||||
LARGE_INTEGER now;
|
||||
QueryPerformanceCounter(&now);
|
||||
return (uint64_t)(((now.QuadPart - start_ticks.QuadPart) * 1000000) / ticks_per_second.QuadPart);
|
||||
}
|
||||
|
||||
#elif defined(LC_DARWIN)
|
||||
|
||||
static mach_timebase_info_data_t mach_base_info;
|
||||
static uint64_t start;
|
||||
|
||||
void PltTicksInit(void) {
|
||||
if (ticks_started) {
|
||||
return;
|
||||
}
|
||||
ticks_started = true;
|
||||
mach_timebase_info(&mach_base_info);
|
||||
has_monotonic_time = true;
|
||||
start = mach_absolute_time();
|
||||
}
|
||||
|
||||
uint64_t PltGetMicroseconds(void) {
|
||||
if (!ticks_started) {
|
||||
PltTicksInit();
|
||||
}
|
||||
const uint64_t now = mach_absolute_time();
|
||||
return (((now - start) * mach_base_info.numer) / mach_base_info.denom) / 1000;
|
||||
}
|
||||
|
||||
#elif defined(__vita__)
|
||||
|
||||
static uint64_t start;
|
||||
|
||||
void PltTicksInit(void) {
|
||||
if (ticks_started) {
|
||||
return;
|
||||
}
|
||||
ticks_started = true;
|
||||
start = sceKernelGetProcessTimeWide();
|
||||
}
|
||||
|
||||
uint64_t PltGetMicroseconds(void) {
|
||||
if (!ticks_started) {
|
||||
PltTicksInit();
|
||||
}
|
||||
uint64_t now = sceKernelGetProcessTimeWide();
|
||||
return (uint64_t)(now - start);
|
||||
}
|
||||
|
||||
#elif defined(__3DS__)
|
||||
|
||||
static uint64_t start;
|
||||
|
||||
void PltTicksInit(void) {
|
||||
if (ticks_started) {
|
||||
return;
|
||||
}
|
||||
ticks_started = true;
|
||||
start = svcGetSystemTick();
|
||||
}
|
||||
|
||||
uint64_t PltGetMicroseconds(void) {
|
||||
if (!ticks_started) {
|
||||
PltTicksInit();
|
||||
}
|
||||
uint64_t elapsed = svcGetSystemTick() - start;
|
||||
return elapsed * 1000 / CPU_TICKS_PER_MSEC;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Use CLOCK_MONOTONIC_RAW, if available, which is not subject to adjustment by NTP */
|
||||
#ifdef HAVE_CLOCK_GETTIME
|
||||
static struct timespec start_ts;
|
||||
# ifdef CLOCK_MONOTONIC_RAW
|
||||
# define PLT_MONOTONIC_CLOCK CLOCK_MONOTONIC_RAW
|
||||
# else
|
||||
# define PLT_MONOTONIC_CLOCK CLOCK_MONOTONIC
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static struct timeval start_tv;
|
||||
|
||||
void PltTicksInit(void) {
|
||||
if (ticks_started) {
|
||||
return;
|
||||
}
|
||||
ticks_started = true;
|
||||
#ifdef HAVE_CLOCK_GETTIME
|
||||
if (clock_gettime(PLT_MONOTONIC_CLOCK, &start_ts) == 0) {
|
||||
has_monotonic_time = true;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
gettimeofday(&start_tv, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t PltGetMicroseconds(void) {
|
||||
if (!ticks_started) {
|
||||
PltTicksInit();
|
||||
}
|
||||
|
||||
if (has_monotonic_time) {
|
||||
#ifdef HAVE_CLOCK_GETTIME
|
||||
struct timespec now;
|
||||
clock_gettime(PLT_MONOTONIC_CLOCK, &now);
|
||||
return (uint64_t)(((int64_t)(now.tv_sec - start_ts.tv_sec) * 1000000) + ((now.tv_nsec - start_ts.tv_nsec) / 1000));
|
||||
#else
|
||||
LC_ASSERT(false);
|
||||
return 0;
|
||||
#endif
|
||||
} else {
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
return (uint64_t)(((int64_t)(now.tv_sec - start_tv.tv_sec) * 1000000) + (now.tv_usec - start_tv.tv_usec));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
uint64_t PltGetMillis(void) {
|
||||
return PltGetMicroseconds() / 1000;
|
||||
}
|
||||
|
||||
//// End timing functions
|
||||
|
||||
bool PltSafeStrcpy(char* dest, size_t dest_size, const char* src) {
|
||||
LC_ASSERT(dest_size > 0);
|
||||
|
||||
@@ -474,6 +607,8 @@ bool PltSafeStrcpy(char* dest, size_t dest_size, const char* src) {
|
||||
int initializePlatform(void) {
|
||||
int err;
|
||||
|
||||
PltTicksInit();
|
||||
|
||||
err = initializePlatformSockets();
|
||||
if (err != 0) {
|
||||
return err;
|
||||
|
||||
Reference in New Issue
Block a user