diff --git a/Makefile b/Makefile index b66a9c9..f2c5b35 100644 --- a/Makefile +++ b/Makefile @@ -36,6 +36,7 @@ SOURCES = \ viddec.cpp \ auddec.cpp \ http.cpp \ + profiling.cpp \ # Build rules generated by macros from common.mk: diff --git a/moonlight.hpp b/moonlight.hpp index 0e69c8d..d29b7ca 100644 --- a/moonlight.hpp +++ b/moonlight.hpp @@ -28,6 +28,9 @@ #include +// Uncomment this line to enable the profiling infrastructure +//#define ENABLE_PROFILING 1 + struct Shader { Shader() : program(0), texcoord_scale_location(0) {} ~Shader() {} @@ -83,7 +86,13 @@ class MoonlightInstance : public pp::Instance, public pp::MouseLock { void OnConnectionStopped(uint32_t unused); void OnConnectionStarted(uint32_t error); void StopConnection(); - + + static uint32_t ProfilerGetPackedMillis(); + static uint64_t ProfilerGetMillis(); + static uint64_t ProfilerUnpackTime(uint32_t packedTime); + static void ProfilerPrintPackedDelta(const char* message, uint32_t packedTimeA, uint32_t packedTimeB); + static void ProfilerPrintDelta(const char* message, uint64_t timeA, uint64_t timeB); + static void* ConnectionThreadFunc(void* context); static void* GamepadThreadFunc(void* context); static void* StopThreadFunc(void* context); diff --git a/profiling.cpp b/profiling.cpp new file mode 100644 index 0000000..a60a91b --- /dev/null +++ b/profiling.cpp @@ -0,0 +1,69 @@ +#include "moonlight.hpp" + +#include + +#include + +#define PACKED_TIME_SECONDS_BITSHIFT 16 +#define PACKED_TIME_MILLIS_MASK 0xFFFF + +uint32_t MoonlightInstance::ProfilerGetPackedMillis() { +#if defined(ENABLE_PROFILING) + struct timeval tv; + uint32_t res; + + gettimeofday(&tv, NULL); + + res = tv.tv_sec << PACKED_TIME_SECONDS_BITSHIFT; + res += (tv.tv_usec / 1000) & PACKED_TIME_MILLIS_MASK; + return res; +#else + return 0; +#endif +} + +uint64_t MoonlightInstance::ProfilerGetMillis() { +#if defined(ENABLE_PROFILING) + struct timeval tv; + uint64_t res; + + gettimeofday(&tv, NULL); + + res = tv.tv_sec * 1000; + res += tv.tv_usec / 1000; + return res; +#else + return 0; +#endif +} + +// The return value of this function is referenced to an +// arbitrary epoch, and as such is only suitable for comparison +// with other unpacked time values. +uint64_t MoonlightInstance::ProfilerUnpackTime(uint32_t packedTime) { +#if defined(ENABLE_PROFILING) + uint64_t res; + res = (packedTime >> PACKED_TIME_SECONDS_BITSHIFT) * 1000; + res += (packedTime & PACKED_TIME_MILLIS_MASK); + return res; +#else + return 0; +#endif +} + +void MoonlightInstance::ProfilerPrintPackedDelta(const char* message, + uint32_t packedTimeA, + uint32_t packedTimeB) { +#if defined(ENABLE_PROFILING) + printf("%s: %d ms\n", message, + (uint32_t)(ProfilerUnpackTime(packedTimeB) - ProfilerUnpackTime(packedTimeA))); +#endif +} + +void MoonlightInstance::ProfilerPrintDelta(const char* message, + uint64_t timeA, + uint64_t timeB) { +#if defined(ENABLE_PROFILING) + printf("%s: %d ms\n", message, (uint32_t)(timeA - timeB)); +#endif +} \ No newline at end of file