From 73ca72d9203c04c649b333a767ee3ae6dd41bca5 Mon Sep 17 00:00:00 2001 From: David Gwilliam Date: Mon, 16 Mar 2026 20:03:53 -0700 Subject: [PATCH] fix(display): correct FPS calculation in all display backends MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: FPS display showed incorrect values (e.g., >1000 when actual FPS was ~60) ROOT CAUSE: Display backends were looking for avg_ms at the wrong level in the stats dictionary. The PerformanceMonitor.get_stats() returns: { 'frame_count': N, 'pipeline': {'avg_ms': X, ...}, 'effects': {...} } But the display backends were using: avg_ms = stats.get('avg_ms', 0) # ❌ Returns 0 (not found at top level) FIXED: All display backends now use: avg_ms = stats.get('pipeline', {}).get('avg_ms', 0) # ✅ Correct path Updated backends: - engine/display/backends/terminal.py - engine/display/backends/websocket.py - engine/display/backends/sixel.py - engine/display/backends/pygame.py - engine/display/backends/kitty.py Now FPS displays correctly (e.g., 60 FPS for 16.67ms avg frame time). --- engine/display/backends/kitty.py | 2 +- engine/display/backends/pygame.py | 2 +- engine/display/backends/sixel.py | 2 +- engine/display/backends/terminal.py | 2 +- engine/display/backends/websocket.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/engine/display/backends/kitty.py b/engine/display/backends/kitty.py index 61f1ac7..9174a3d 100644 --- a/engine/display/backends/kitty.py +++ b/engine/display/backends/kitty.py @@ -81,7 +81,7 @@ class KittyDisplay: monitor = get_monitor() if monitor: stats = monitor.get_stats() - avg_ms = stats.get("avg_ms", 0) if stats else 0 + avg_ms = stats.get("pipeline", {}).get("avg_ms", 0) if stats else 0 frame_count = stats.get("frame_count", 0) if stats else 0 if avg_ms and frame_count > 0: fps = 1000.0 / avg_ms diff --git a/engine/display/backends/pygame.py b/engine/display/backends/pygame.py index 0ae9811..2c9a85e 100644 --- a/engine/display/backends/pygame.py +++ b/engine/display/backends/pygame.py @@ -173,7 +173,7 @@ class PygameDisplay: monitor = get_monitor() if monitor: stats = monitor.get_stats() - avg_ms = stats.get("avg_ms", 0) if stats else 0 + avg_ms = stats.get("pipeline", {}).get("avg_ms", 0) if stats else 0 frame_count = stats.get("frame_count", 0) if stats else 0 if avg_ms and frame_count > 0: fps = 1000.0 / avg_ms diff --git a/engine/display/backends/sixel.py b/engine/display/backends/sixel.py index d692895..52dfc2b 100644 --- a/engine/display/backends/sixel.py +++ b/engine/display/backends/sixel.py @@ -135,7 +135,7 @@ class SixelDisplay: monitor = get_monitor() if monitor: stats = monitor.get_stats() - avg_ms = stats.get("avg_ms", 0) if stats else 0 + avg_ms = stats.get("pipeline", {}).get("avg_ms", 0) if stats else 0 frame_count = stats.get("frame_count", 0) if stats else 0 if avg_ms and frame_count > 0: fps = 1000.0 / avg_ms diff --git a/engine/display/backends/terminal.py b/engine/display/backends/terminal.py index 61106c9..e8e89b6 100644 --- a/engine/display/backends/terminal.py +++ b/engine/display/backends/terminal.py @@ -93,7 +93,7 @@ class TerminalDisplay: monitor = get_monitor() if monitor: stats = monitor.get_stats() - avg_ms = stats.get("avg_ms", 0) if stats else 0 + avg_ms = stats.get("pipeline", {}).get("avg_ms", 0) if stats else 0 frame_count = stats.get("frame_count", 0) if stats else 0 if avg_ms and frame_count > 0: fps = 1000.0 / avg_ms diff --git a/engine/display/backends/websocket.py b/engine/display/backends/websocket.py index 5c0c141..d9a2a6d 100644 --- a/engine/display/backends/websocket.py +++ b/engine/display/backends/websocket.py @@ -111,7 +111,7 @@ class WebSocketDisplay: monitor = get_monitor() if monitor: stats = monitor.get_stats() - avg_ms = stats.get("avg_ms", 0) if stats else 0 + avg_ms = stats.get("pipeline", {}).get("avg_ms", 0) if stats else 0 frame_count = stats.get("frame_count", 0) if stats else 0 if avg_ms and frame_count > 0: fps = 1000.0 / avg_ms