Browse Source

DebugTools: use steady_clock for FrameProfiler CPU timing.

Otherwise it may happen that the clock gets adjusted mid-frame, leading
to an underflow and an assertion like this:

    Assertion _measurements[i]._movingSum + data >= _measurements[i]._movingSum failed at src/Magnum/DebugTools/FrameProfiler.cpp:233

The clock adjustment is known to be happening rather frequently under
WSL2.
pull/419/merge
Vladimír Vondruš 2 years ago
parent
commit
d536a95f4a
  1. 14
      src/Magnum/DebugTools/FrameProfiler.cpp

14
src/Magnum/DebugTools/FrameProfiler.cpp

@ -476,7 +476,11 @@ void FrameProfilerGL::setup(const Values values, const UnsignedInt maxFrameCount
arrayAppend(measurements, InPlaceInit,
"Frame time"_s, Units::Nanoseconds, UnsignedInt(Containers::arraySize(_state->frameTimeStartFrame)),
[](void* state, UnsignedInt current) {
static_cast<State*>(state)->frameTimeStartFrame[current] = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
/* Using steady_clock even though it might not be as precise as
high_resolution_clock in order to avoid the delta being
negative between frames, causing an underflow and an assert
similar to what used to happen for PrimitiveClipRatio */
static_cast<State*>(state)->frameTimeStartFrame[current] = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
},
[](void*, UnsignedInt) {},
[](void* state, UnsignedInt previous, UnsignedInt current) {
@ -490,11 +494,15 @@ void FrameProfilerGL::setup(const Values values, const UnsignedInt maxFrameCount
arrayAppend(measurements, InPlaceInit,
"CPU duration"_s, Units::Nanoseconds,
[](void* state) {
static_cast<State*>(state)->cpuDurationStartFrame = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
/* Using steady_clock even though it might not be as precise as
high_resolution_clock in order to avoid the delta being
negative between frames, causing an underflow and an assert
similar to what used to happen for PrimitiveClipRatio */
static_cast<State*>(state)->cpuDurationStartFrame = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
},
[](void* state) {
/* libc++ 10 needs an explicit cast to UnsignedLong */
return UnsignedLong(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count() - static_cast<State*>(state)->cpuDurationStartFrame);
return UnsignedLong(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() - static_cast<State*>(state)->cpuDurationStartFrame);
}, _state.get());
_state->cpuDurationIndex = index++;
}

Loading…
Cancel
Save