ui: Render video frame stats

This commit is contained in:
Matt Borgerson 2021-02-11 00:31:55 -07:00 committed by mborgerson
parent 7a08e93085
commit 4b6ee2c923
1 changed files with 123 additions and 0 deletions

View File

@ -39,6 +39,7 @@
#include "imgui/imgui.h"
#include "imgui/backends/imgui_impl_sdl.h"
#include "imgui/backends/imgui_impl_opengl3.h"
#include "implot/implot.h"
extern "C" {
#include "noc_file_dialog.h"
@ -49,6 +50,7 @@ extern "C" {
#include "sysemu/sysemu.h"
#include "sysemu/runstate.h"
#include "hw/xbox/mcpx/apu_debug.h"
#include "hw/xbox/nv2a/debug.h"
#undef typename
#undef atomic_fetch_add
@ -1368,8 +1370,125 @@ public:
};
// utility structure for realtime plot
struct ScrollingBuffer {
int MaxSize;
int Offset;
ImVector<ImVec2> Data;
ScrollingBuffer() {
MaxSize = 2000;
Offset = 0;
Data.reserve(MaxSize);
}
void AddPoint(float x, float y) {
if (Data.size() < MaxSize)
Data.push_back(ImVec2(x,y));
else {
Data[Offset] = ImVec2(x,y);
Offset = (Offset + 1) % MaxSize;
}
}
void Erase() {
if (Data.size() > 0) {
Data.shrink(0);
Offset = 0;
}
}
};
class DebugVideoWindow
{
public:
bool is_open;
DebugVideoWindow()
{
is_open = false;
}
~DebugVideoWindow()
{
}
void Draw()
{
if (!is_open) return;
float window_width = 800.0f*g_ui_scale;
// ImGui::SetNextWindowContentSize(ImVec2(window_width, 0.0f));
if (!ImGui::Begin("Video Debug", &is_open, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::End();
return;
}
double x_start, x_end;
static ImPlotAxisFlags rt_axis = ImPlotAxisFlags_NoTickLabels;
ImPlot::PushStyleVar(ImPlotStyleVar_PlotPadding, ImVec2(5,5));
ImPlot::PushStyleVar(ImPlotStyleVar_FillAlpha, 0.25f);
static ScrollingBuffer fps;
static float t = 0;
if (runstate_is_running()) {
t += ImGui::GetIO().DeltaTime;
fps.AddPoint(t, g_nv2a_stats.increment_fps);
}
x_start = t - 10.0;
x_end = t;
ImPlot::SetNextPlotLimitsX(x_start, x_end, ImGuiCond_Always);
ImPlot::SetNextPlotLimitsY(0, 65, ImGuiCond_Always);
if (ImPlot::BeginPlot("##ScrollingFPS", NULL, NULL, ImVec2(0.5*window_width,75), 0, rt_axis, rt_axis | ImPlotAxisFlags_Lock)) {
ImPlot::PlotShaded("##fps", &fps.Data[0].x, &fps.Data[0].y, fps.Data.size(), 0, fps.Offset, 2 * sizeof(float));
ImPlot::PlotLine("##fps", &fps.Data[0].x, &fps.Data[0].y, fps.Data.size(), fps.Offset, 2 * sizeof(float));
ImPlot::AnnotateClamped(x_start, 65, ImVec2(0,0), ImPlot::GetLastItemColor(), "FPS: %d", g_nv2a_stats.increment_fps);
ImPlot::EndPlot();
}
ImGui::SameLine();
x_end = g_nv2a_stats.frame_count;
x_start = x_end - NV2A_PROF_NUM_FRAMES;
ImPlot::SetNextPlotLimitsX(x_start, x_end, ImGuiCond_Always);
ImPlot::SetNextPlotLimitsY(0, 100, ImGuiCond_Always);
ImPlot::PushStyleColor(ImPlotCol_Line, ImPlot::GetColormapColor(1));
if (ImPlot::BeginPlot("##ScrollingMSPF", NULL, NULL, ImVec2(0.5*window_width,75), 0, rt_axis, rt_axis | ImPlotAxisFlags_Lock)) {
ImPlot::PlotShaded("##mspf", &g_nv2a_stats.frame_history[0].mspf, NV2A_PROF_NUM_FRAMES, 0, 1, x_start, g_nv2a_stats.frame_ptr, sizeof(g_nv2a_stats.frame_working));
ImPlot::PlotLine("##mspf", &g_nv2a_stats.frame_history[0].mspf, NV2A_PROF_NUM_FRAMES, 1, x_start, g_nv2a_stats.frame_ptr, sizeof(g_nv2a_stats.frame_working));
ImPlot::AnnotateClamped(x_start, 100, ImVec2(0,0), ImPlot::GetLastItemColor(), "MSPF: %d", g_nv2a_stats.frame_history[(g_nv2a_stats.frame_ptr - 1) % NV2A_PROF_NUM_FRAMES].mspf);
ImPlot::EndPlot();
}
ImPlot::PopStyleColor();
if (ImGui::TreeNode("Advanced")) {
ImPlot::SetNextPlotLimitsX(x_start, x_end, ImGuiCond_Always);
ImPlot::SetNextPlotLimitsY(0, 1500, ImGuiCond_Always);
if (ImPlot::BeginPlot("##ScrollingDraws", NULL, NULL, ImVec2(-1,500), 0, rt_axis, rt_axis | ImPlotAxisFlags_Lock)) {
for (int i = 0; i < NV2A_PROF__COUNT; i++) {
ImGui::PushID(i);
char title[64];
snprintf(title, sizeof(title), "%s: %d",
nv2a_profile_get_counter_name(i),
nv2a_profile_get_counter_value(i));
ImPlot::PushStyleColor(ImPlotCol_Line, ImPlot::GetColormapColor(i));
ImPlot::PushStyleColor(ImPlotCol_Fill, ImPlot::GetColormapColor(i));
ImPlot::PlotLine(title, &g_nv2a_stats.frame_history[0].counters[i], NV2A_PROF_NUM_FRAMES, 1, x_start, g_nv2a_stats.frame_ptr, sizeof(g_nv2a_stats.frame_working));
ImPlot::PopStyleColor(2);
ImGui::PopID();
}
ImPlot::EndPlot();
}
ImGui::TreePop();
}
ImPlot::PopStyleVar(2);
ImGui::End();
}
};
static MonitorWindow monitor_window;
static DebugApuWindow apu_window;
static DebugVideoWindow video_window;
static InputWindow input_window;
static NetworkWindow network_window;
static AboutWindow about_window;
@ -1601,6 +1720,7 @@ static void ShowMainMenu()
{
ImGui::MenuItem("Monitor", NULL, &monitor_window.is_open);
ImGui::MenuItem("Audio", NULL, &apu_window.is_open);
ImGui::MenuItem("Video", NULL, &video_window.is_open);
ImGui::EndMenu();
}
@ -1729,6 +1849,8 @@ void xemu_hud_init(SDL_Window* window, void* sdl_gl_context)
g_ui_scale = ui_scale_int;
g_sdl_window = window;
ImPlot::CreateContext();
}
void xemu_hud_cleanup(void)
@ -1889,6 +2011,7 @@ void xemu_hud_render(void)
settings_window.Draw();
monitor_window.Draw();
apu_window.Draw();
video_window.Draw();
about_window.Draw();
network_window.Draw();
compatibility_reporter_window.Draw();