WIP: profiling
This commit is contained in:
150
src/gui_2.py
150
src/gui_2.py
@@ -115,6 +115,7 @@ class App:
|
||||
self._last_ui_focus_agent: Optional[str] = None
|
||||
self._log_registry: Optional[log_registry.LogRegistry] = None
|
||||
self.perf_profiling_enabled = False
|
||||
self.perf_show_graphs: dict[str, bool] = {}
|
||||
|
||||
def _handle_approve_tool(self, user_data=None) -> None:
|
||||
"""UI-level wrapper for approving a pending tool execution ask."""
|
||||
@@ -149,7 +150,6 @@ class App:
|
||||
def current_provider(self, value: str) -> None:
|
||||
self.controller.current_provider = value
|
||||
|
||||
@property
|
||||
@property
|
||||
def current_model(self) -> str:
|
||||
return self.controller.current_model
|
||||
@@ -165,6 +165,7 @@ class App:
|
||||
@perf_profiling_enabled.setter
|
||||
def perf_profiling_enabled(self, value: bool) -> None:
|
||||
self.controller.perf_profiling_enabled = value
|
||||
|
||||
def shutdown(self) -> None:
|
||||
"""Cleanly shuts down the app's background tasks and saves state."""
|
||||
try:
|
||||
@@ -491,113 +492,76 @@ class App:
|
||||
exp, opened = imgui.begin("Diagnostics", self.show_windows["Diagnostics"])
|
||||
self.show_windows["Diagnostics"] = bool(opened)
|
||||
if exp:
|
||||
now = time.time()
|
||||
if now - self._perf_last_update >= 0.5:
|
||||
self._perf_last_update = now
|
||||
metrics = self.perf_monitor.get_metrics()
|
||||
self.perf_history["frame_time"].pop(0)
|
||||
self.perf_history["frame_time"].append(metrics.get("last_frame_time_ms", 0.0))
|
||||
self.perf_history["fps"].pop(0)
|
||||
self.perf_history["fps"].append(metrics.get("fps", 0.0))
|
||||
self.perf_history["cpu"].pop(0)
|
||||
self.perf_history["cpu"].append(metrics.get("cpu_percent", 0.0))
|
||||
self.perf_history["input_lag"].pop(0)
|
||||
self.perf_history["input_lag"].append(metrics.get("input_lag_ms", 0.0))
|
||||
metrics = self.perf_monitor.get_metrics()
|
||||
imgui.text("Performance Telemetry")
|
||||
imgui.same_line()
|
||||
_, self.perf_profiling_enabled = imgui.checkbox("Enable Profiling", self.perf_profiling_enabled)
|
||||
imgui.separator()
|
||||
if imgui.begin_table("perf_table", 2, imgui.TableFlags_.borders_inner_h):
|
||||
if imgui.begin_table("perf_table", 3, imgui.TableFlags_.borders_inner_h):
|
||||
imgui.table_setup_column("Metric")
|
||||
imgui.table_setup_column("Value")
|
||||
imgui.table_setup_column("Graph")
|
||||
imgui.table_headers_row()
|
||||
imgui.table_next_row()
|
||||
imgui.table_next_column()
|
||||
imgui.text("FPS")
|
||||
imgui.table_next_column()
|
||||
imgui.text(f"{metrics.get('fps', 0.0):.1f}")
|
||||
imgui.table_next_row()
|
||||
imgui.table_next_column()
|
||||
imgui.text("Frame Time (ms)")
|
||||
imgui.table_next_column()
|
||||
imgui.text(f"{metrics.get('last_frame_time_ms', 0.0):.2f}")
|
||||
imgui.table_next_row()
|
||||
imgui.table_next_column()
|
||||
imgui.text("CPU %")
|
||||
imgui.table_next_column()
|
||||
imgui.text(f"{metrics.get('cpu_percent', 0.0):.1f}")
|
||||
imgui.table_next_row()
|
||||
imgui.table_next_column()
|
||||
imgui.text("Input Lag (ms)")
|
||||
imgui.table_next_column()
|
||||
imgui.text(f"{metrics.get('input_lag_ms', 0.0):.1f}")
|
||||
|
||||
# Core Metrics
|
||||
for label, key, format_str in [
|
||||
("FPS", "fps", "%.1f"),
|
||||
("Frame Time (ms)", "frame_time_ms", "%.2f"),
|
||||
("CPU %", "cpu_percent", "%.1f"),
|
||||
("Input Lag (ms)", "input_lag_ms", "%.1f")
|
||||
]:
|
||||
imgui.table_next_row()
|
||||
imgui.table_next_column()
|
||||
imgui.text(label)
|
||||
imgui.table_next_column()
|
||||
if key == "fps":
|
||||
avg_val = imgui.get_io().framerate
|
||||
else:
|
||||
avg_val = metrics.get(f"{key}_avg", metrics.get(key, 0.0))
|
||||
imgui.text(format_str % avg_val)
|
||||
imgui.table_next_column()
|
||||
self.perf_show_graphs.setdefault(key, False)
|
||||
_, self.perf_show_graphs[key] = imgui.checkbox(f"##g_{key}", self.perf_show_graphs[key])
|
||||
|
||||
imgui.end_table()
|
||||
|
||||
if self.perf_profiling_enabled:
|
||||
imgui.separator()
|
||||
imgui.text("Detailed Component Timings")
|
||||
if imgui.begin_table("comp_timings", 2, imgui.TableFlags_.borders):
|
||||
imgui.text("Detailed Component Timings (Moving Average)")
|
||||
if imgui.begin_table("comp_timings", 3, imgui.TableFlags_.borders):
|
||||
imgui.table_setup_column("Component")
|
||||
imgui.table_setup_column("Time (ms)")
|
||||
imgui.table_setup_column("Avg (ms)")
|
||||
imgui.table_setup_column("Graph")
|
||||
imgui.table_headers_row()
|
||||
# Show all components found in metrics
|
||||
for key, val in metrics.items():
|
||||
if key.startswith("time_") and key.endswith("_ms"):
|
||||
if key.startswith("time_") and key.endswith("_ms") and not key.endswith("_avg"):
|
||||
comp_name = key[5:-3]
|
||||
avg_val = metrics.get(f"{key}_avg", val)
|
||||
imgui.table_next_row()
|
||||
imgui.table_next_column()
|
||||
imgui.text(comp_name)
|
||||
imgui.table_next_column()
|
||||
if val > 10.0:
|
||||
imgui.text_colored(imgui.ImVec4(1.0, 0.2, 0.2, 1.0), f"{val:.2f}")
|
||||
if avg_val > 10.0:
|
||||
imgui.text_colored(imgui.ImVec4(1.0, 0.2, 0.2, 1.0), f"{avg_val:.2f}")
|
||||
else:
|
||||
imgui.text(f"{val:.2f}")
|
||||
imgui.end_table()
|
||||
|
||||
if self.perf_profiling_enabled:
|
||||
imgui.separator()
|
||||
imgui.text("Detailed Component Timings")
|
||||
if imgui.begin_table("comp_timings", 2, imgui.TableFlags_.borders):
|
||||
imgui.table_setup_column("Component")
|
||||
imgui.table_setup_column("Time (ms)")
|
||||
imgui.table_headers_row()
|
||||
for key, val in metrics.items():
|
||||
if key.startswith("time_") and key.endswith("_ms"):
|
||||
comp_name = key[5:-3]
|
||||
imgui.table_next_row()
|
||||
imgui.table_next_column()
|
||||
imgui.text(comp_name)
|
||||
imgui.table_next_column()
|
||||
if val > 10.0:
|
||||
imgui.text_colored(imgui.ImVec4(1.0, 0.2, 0.2, 1.0), f"{val:.2f}")
|
||||
else:
|
||||
imgui.text(f"{val:.2f}")
|
||||
imgui.end_table()
|
||||
|
||||
if self.perf_profiling_enabled:
|
||||
imgui.separator()
|
||||
imgui.text("Detailed Component Timings")
|
||||
if imgui.begin_table("comp_timings", 2, imgui.TableFlags_.borders):
|
||||
imgui.table_setup_column("Component")
|
||||
imgui.table_setup_column("Time (ms)")
|
||||
imgui.table_headers_row()
|
||||
for key, val in metrics.items():
|
||||
if key.startswith("time_") and key.endswith("_ms"):
|
||||
comp_name = key[5:-3]
|
||||
imgui.table_next_row()
|
||||
imgui.table_next_column()
|
||||
imgui.text(comp_name)
|
||||
imgui.table_next_column()
|
||||
if val > 10.0:
|
||||
imgui.text_colored(imgui.ImVec4(1.0, 0.2, 0.2, 1.0), f"{val:.2f}")
|
||||
else:
|
||||
imgui.text(f"{val:.2f}")
|
||||
imgui.text(f"{avg_val:.2f}")
|
||||
imgui.table_next_column()
|
||||
self.perf_show_graphs.setdefault(comp_name, False)
|
||||
_, self.perf_show_graphs[comp_name] = imgui.checkbox(f"##g_{comp_name}", self.perf_show_graphs[comp_name])
|
||||
imgui.end_table()
|
||||
|
||||
# Render all enabled graphs (core + components)
|
||||
imgui.separator()
|
||||
imgui.text("Frame Time (ms)")
|
||||
imgui.plot_lines("##ft_plot", np.array(self.perf_history["frame_time"], dtype=np.float32), overlay_text="frame_time", graph_size=imgui.ImVec2(-1, 60))
|
||||
imgui.text("CPU %")
|
||||
imgui.plot_lines("##cpu_plot", np.array(self.perf_history["cpu"], dtype=np.float32), overlay_text="cpu", graph_size=imgui.ImVec2(-1, 60))
|
||||
imgui.text("Performance Graphs")
|
||||
for key, show in self.perf_show_graphs.items():
|
||||
if show:
|
||||
imgui.text(f"History: {key}")
|
||||
hist_data = self.perf_monitor.get_history(key)
|
||||
if hist_data:
|
||||
imgui.plot_lines(f"##plot_{key}", np.array(hist_data, dtype=np.float32), graph_size=imgui.ImVec2(-1, 60))
|
||||
else:
|
||||
imgui.text_disabled(f"(no history data for {key})")
|
||||
imgui.end()
|
||||
self.perf_monitor.end_frame()
|
||||
# ---- Modals / Popups
|
||||
@@ -2461,7 +2425,21 @@ class App:
|
||||
self.runner_params.app_window_params.window_geometry.size = (1680, 1200)
|
||||
self.runner_params.imgui_window_params.enable_viewports = False
|
||||
self.runner_params.imgui_window_params.default_imgui_window_type = hello_imgui.DefaultImGuiWindowType.provide_full_screen_dock_space
|
||||
self.runner_params.fps_idling.enable_idling = False
|
||||
|
||||
# Detect Monitor Refresh Rate for capping
|
||||
fps_cap = 60.0
|
||||
try:
|
||||
# Use PowerShell to get max refresh rate across all controllers
|
||||
cmd = "powershell -NoProfile -Command \"Get-CimInstance -ClassName Win32_VideoController | Select-Object -ExpandProperty CurrentRefreshRate\""
|
||||
out = subprocess.check_output(cmd, shell=True).decode().splitlines()
|
||||
rates = [float(r.strip()) for r in out if r.strip().isdigit()]
|
||||
if rates: fps_cap = max(rates)
|
||||
except Exception: pass
|
||||
|
||||
# Enable idling with monitor refresh rate to effectively cap FPS
|
||||
self.runner_params.fps_idling.enable_idling = True
|
||||
self.runner_params.fps_idling.fps_idle = fps_cap
|
||||
|
||||
self.runner_params.imgui_window_params.show_menu_bar = True
|
||||
self.runner_params.ini_folder_type = hello_imgui.IniFolderType.current_folder
|
||||
self.runner_params.ini_filename = "manualslop_layout.ini"
|
||||
|
||||
Reference in New Issue
Block a user