| 112 | } |
| 113 | |
| 114 | void ReportMetrics(Options const& opts, SwapChainData* chain, PresentEvent const& p, PresentEvent const* nextDisplayedPresent) |
| 115 | { |
| 116 | static bool first = true; |
| 117 | static double t0 = 0.0; |
| 118 | static uint64_t q0 = 0; |
| 119 | if (first) { |
| 120 | first = false; |
| 121 | t0 = 1000.0 * p.TimeInSeconds; |
| 122 | q0 = p.QPCTime; |
| 123 | } |
| 124 | |
| 125 | // PB = PresentStartTime |
| 126 | // PE = PresentEndTime |
| 127 | // D = ScreenTime |
| 128 | // F = CPUFrameTime/CPUDuration |
| 129 | // S = CPUFramePacingStall |
| 130 | // D = DisplayDuration |
| 131 | // |
| 132 | // msBetweenDisplayChange: |----------->| |
| 133 | // msUntilDisplayed: | |-------->| |
| 134 | // msBetweenPresents: |----------->| | |
| 135 | // | | | | |
| 136 | // Previous PresentEvent: PB--PE----D | | |
| 137 | // p: | PB--PE----D |
| 138 | // Next PresentEvent(s): | | | PB--PE |
| 139 | // | | | | PB--PE |
| 140 | // nextDisplayedPresent: | | | | PB--PE----D |
| 141 | // | | | | | |
| 142 | // CPUFrameTime/CPUDuration: |------->| | | | |
| 143 | // CPUFramePacingStall: |-->| | | |
| 144 | // DisplayLatency: |----------------->| | |
| 145 | // DisplayDuration: |---------------------->| |
| 146 | |
| 147 | bool displayed = p.Dropped == false && |
| 148 | nextDisplayedPresent != nullptr; |
| 149 | |
| 150 | double metrics_mCPUFrameTime = 0.0; |
| 151 | uint64_t metrics_mCPUFrameQPC = 0; |
| 152 | double metrics_mCPUDuration = 0.0; |
| 153 | double metrics_mCPUFramePacingStall = p.msInPresentAPI; |
| 154 | double metrics_mGPULatency = 0.0; |
| 155 | double metrics_mGPUDuration = p.msUntilRenderComplete - p.msUntilRenderStart; |
| 156 | double metrics_mGPUBusy = p.msGPUActive; |
| 157 | double metrics_mVideoBusy = p.msGPUVideoActive; |
| 158 | double metrics_mDisplayLatency = 0.0; |
| 159 | double metrics_mDisplayDuration = 0.0; |
| 160 | double metrics_mInputLatency = 0.0; |
| 161 | |
| 162 | if (chain->mNextCPUFrameTimeIsValid) { |
| 163 | metrics_mCPUFrameTime = chain->mNextCPUFrameTime; |
| 164 | metrics_mCPUDuration = p.TimeInSeconds * 1000.0 - metrics_mCPUFrameTime; |
| 165 | metrics_mGPULatency = std::max(0.0, p.TimeInSeconds * 1000.0 + p.msUntilRenderStart - metrics_mCPUFrameTime); |
| 166 | |
| 167 | if (displayed) { |
| 168 | metrics_mDisplayLatency = std::max(0.0, nextDisplayedPresent->TimeInSeconds * 1000.0 + |
| 169 | nextDisplayedPresent->msUntilDisplayed - |
| 170 | nextDisplayedPresent->msBetweenDisplayChange - |
| 171 | metrics_mCPUFrameTime); |