diff --git a/src/hud_elements.cpp b/src/hud_elements.cpp index 6ba6f9733b1..d0266fd529f 100644 --- a/src/hud_elements.cpp +++ b/src/hud_elements.cpp @@ -537,8 +537,31 @@ void HudElements::frame_timing(){ double min_time = 0.0f; double max_time = 50.0f; if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_histogram]){ - ImGui::PlotHistogram(hash, get_time_stat, HUDElements.sw_stats, - ARRAY_SIZE(HUDElements.sw_stats->frames_stats), 0, + uint32_t p50=0, p90=0, p99=0; + // one frame latency between this and update_hud_info_with_frametime. + // That makes p99 only kick in after 100 frames. + uint32_t frame_count = std::min(HUDElements.sw_stats->n_frames, ARRAY_SIZE(HUDElements.sw_stats->frames_stats)); + uint32_t frames_seen = 0; + for(uint32_t i = 0; i < ARRAY_SIZE(HUDElements.sw_stats->frame_times); i++) { + auto ft = HUDElements.sw_stats->frame_times; + frames_seen += ft[i]; + if(p50 == 0 && frames_seen >= frame_count/2) { + p50 = i; + } + if(p90 == 0 && frames_seen >= frame_count - (frame_count/10)) { + p90 = i; + } + if(p99 == 0 && frames_seen >= frame_count - (frame_count/100)) { + p99 = i; + } + } + ImGui::PushFont(HUDElements.sw_stats->font1); + ImGui::TextColored(HUDElements.colors.text, "p50/p90/p99"); + ImGui::TextColored(HUDElements.colors.text, "%3d/%3d/%3d ms", p50, p90, p99); + ImGui::TextColored(HUDElements.colors.text, "s:%d,c:%d", frames_seen, frame_count); + ImGui::PopFont(); + ImGui::PlotHistogram(hash, HUDElements.sw_stats->frame_times, + ARRAY_SIZE(HUDElements.sw_stats->frame_times), 0, NULL, min_time, max_time, ImVec2(ImGui::GetContentRegionAvailWidth() * HUDElements.params->table_columns, 50)); } else { diff --git a/src/overlay.cpp b/src/overlay.cpp index 91ca33dc4d5..7a77b6aee11 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -170,6 +170,17 @@ void update_hud_info_with_frametime(struct swapchain_stats& sw_stats, struct ove if (sw_stats.last_present_time) { sw_stats.frames_stats[f_idx].stats[OVERLAY_PLOTS_frame_timing] = frametime_ns; + uint32_t frametime_ms = frametime_ns/1000000; + if (frametime_ms < 1000) { + sw_stats.frame_times[frametime_ms] += 1.0; + } + // keep the histogram for the same window as the normal frame graph. + int32_t fp_idx = sw_stats.n_frames - ARRAY_SIZE(sw_stats.frames_stats); + if (fp_idx > 0) { + fp_idx = (fp_idx + 1) % ARRAY_SIZE(sw_stats.frames_stats); + uint32_t oldest_frametime_ms = sw_stats.frames_stats[fp_idx].stats[OVERLAY_PLOTS_frame_timing]/1000000; + sw_stats.frame_times[oldest_frametime_ms] -= 1.0; + } } frametime = frametime_ns / 1000; diff --git a/src/overlay.h b/src/overlay.h index 18b839a27aa..3192441180e 100644 --- a/src/overlay.h +++ b/src/overlay.h @@ -51,6 +51,7 @@ struct swapchain_stats { double time_dividor; struct frame_stat stats_min, stats_max; struct frame_stat frames_stats[200]; + float frame_times[1000]; // histogram buckets. ImFont* font1 = nullptr; ImFont* font_text = nullptr; @@ -167,4 +168,4 @@ extern void process_control_socket(struct instance_data *instance_data); void render_mpris_metadata(overlay_params& params, mutexed_metadata& meta, uint64_t frame_timing); #endif -#endif //MANGOHUD_OVERLAY_H \ No newline at end of file +#endif //MANGOHUD_OVERLAY_H