ui: add render loop profiling (#36558)

pull/36555/head^2
Adeeb Shihadeh 4 days ago committed by GitHub
parent cbc8f98682
commit e8a11591a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 32
      system/ui/lib/application.py

@ -31,6 +31,7 @@ SHOW_FPS = os.getenv("SHOW_FPS") == "1"
SHOW_TOUCHES = os.getenv("SHOW_TOUCHES") == "1"
STRICT_MODE = os.getenv("STRICT_MODE") == "1"
SCALE = float(os.getenv("SCALE", "1.0"))
PROFILE_RENDER = int(os.getenv("PROFILE_RENDER", "0"))
DEFAULT_TEXT_SIZE = 60
DEFAULT_TEXT_COLOR = rl.WHITE
@ -172,6 +173,9 @@ class GuiApplication:
self._mouse_history: deque[MousePosWithTime] = deque(maxlen=MOUSE_THREAD_RATE)
self._show_touches = SHOW_TOUCHES
self._show_fps = SHOW_FPS
self._profile_render_frames = PROFILE_RENDER
self._render_profiler = None
self._render_profile_start_time = None
@property
def frame(self):
@ -345,6 +349,12 @@ class GuiApplication:
def render(self):
try:
if self._profile_render_frames > 0:
import cProfile
self._render_profiler = cProfile.Profile()
self._render_profile_start_time = time.monotonic()
self._render_profiler.enable()
while not (self._window_close_requested or rl.window_should_close()):
if PC:
# Thread is not used on PC, need to manually add mouse events
@ -429,6 +439,9 @@ class GuiApplication:
rl.end_drawing()
self._monitor_fps()
self._frame += 1
if self._profile_render_frames > 0 and self._frame >= self._profile_render_frames:
self._output_render_profile()
except KeyboardInterrupt:
pass
@ -526,6 +539,25 @@ class GuiApplication:
cloudlog.error(f"FPS dropped critically below {fps}. Shutting down UI.")
os._exit(1)
def _output_render_profile(self):
import io
import pstats
self._render_profiler.disable()
elapsed_ms = (time.monotonic() - self._render_profile_start_time) * 1e3
avg_frame_time = elapsed_ms / self._frame if self._frame > 0 else 0
stats_stream = io.StringIO()
pstats.Stats(self._render_profiler, stream=stats_stream).sort_stats("cumtime").print_stats(25)
print("\n=== Render loop profile ===")
print(stats_stream.getvalue().rstrip())
green = "\033[92m"
reset = "\033[0m"
print(f"\n{green}Rendered {self._frame} frames in {elapsed_ms:.1f} ms{reset}")
print(f"{green}Average frame time: {avg_frame_time:.2f} ms ({1000/avg_frame_time:.1f} FPS){reset}")
sys.exit(0)
def _calculate_auto_scale(self) -> float:
# Create temporary window to query monitor info
rl.init_window(1, 1, "")

Loading…
Cancel
Save