feat(perf): Implement Input Lag estimation logic

This commit is contained in:
2026-02-23 14:43:07 -05:00
parent e19e9130e4
commit cdd06d4339
3 changed files with 29 additions and 1 deletions

5
gui.py
View File

@@ -1698,6 +1698,11 @@ class App:
) )
def _build_ui(self): def _build_ui(self):
# Performance tracking handlers
with dpg.handler_registry():
dpg.add_mouse_click_handler(callback=lambda: self.perf_monitor.record_input_event())
dpg.add_key_press_handler(callback=lambda: self.perf_monitor.record_input_event())
with dpg.viewport_menu_bar(): with dpg.viewport_menu_bar():
with dpg.menu(label="Windows"): with dpg.menu(label="Windows"):
for label, tag in self.window_info.items(): for label, tag in self.window_info.items():

View File

@@ -13,6 +13,10 @@ class PerformanceMonitor:
self._cpu_usage = 0.0 self._cpu_usage = 0.0
self._cpu_lock = threading.Lock() self._cpu_lock = threading.Lock()
# Input lag tracking
self._last_input_time = None
self._input_lag_ms = 0.0
# Start CPU usage monitoring thread # Start CPU usage monitoring thread
self._stop_event = threading.Event() self._stop_event = threading.Event()
self._cpu_thread = threading.Thread(target=self._monitor_cpu, daemon=True) self._cpu_thread = threading.Thread(target=self._monitor_cpu, daemon=True)
@@ -29,6 +33,9 @@ class PerformanceMonitor:
def start_frame(self): def start_frame(self):
self._start_time = time.time() self._start_time = time.time()
def record_input_event(self):
self._last_input_time = time.time()
def end_frame(self): def end_frame(self):
if self._start_time is None: if self._start_time is None:
return return
@@ -37,6 +44,11 @@ class PerformanceMonitor:
self._last_frame_time = (end_time - self._start_time) * 1000.0 self._last_frame_time = (end_time - self._start_time) * 1000.0
self._frame_count += 1 self._frame_count += 1
# Calculate input lag if an input occurred during this frame
if self._last_input_time is not None:
self._input_lag_ms = (end_time - self._last_input_time) * 1000.0
self._last_input_time = None
elapsed_since_fps = end_time - self._fps_last_time elapsed_since_fps = end_time - self._fps_last_time
if elapsed_since_fps >= 1.0: if elapsed_since_fps >= 1.0:
self._fps = self._frame_count / elapsed_since_fps self._fps = self._frame_count / elapsed_since_fps
@@ -50,7 +62,8 @@ class PerformanceMonitor:
return { return {
'last_frame_time_ms': self._last_frame_time, 'last_frame_time_ms': self._last_frame_time,
'fps': self._fps, 'fps': self._fps,
'cpu_percent': cpu_usage 'cpu_percent': cpu_usage,
'input_lag_ms': self._input_lag_ms
} }
def stop(self): def stop(self):

View File

@@ -23,5 +23,15 @@ class TestPerformanceMonitor(unittest.TestCase):
self.assertIn('cpu_percent', metrics) self.assertIn('cpu_percent', metrics)
self.assertIsInstance(metrics['cpu_percent'], float) self.assertIsInstance(metrics['cpu_percent'], float)
def test_input_lag_collection(self):
self.monitor.start_frame()
self.monitor.record_input_event()
time.sleep(0.02) # 20ms lag
self.monitor.end_frame()
metrics = self.monitor.get_metrics()
self.assertGreaterEqual(metrics['input_lag_ms'], 20)
self.assertLess(metrics['input_lag_ms'], 40)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()