Big UI: More optimization

This commit is contained in:
firestarsdog
2026-07-27 13:27:33 -04:00
parent eaa5a9ad83
commit 515f28fcbd
5 changed files with 53 additions and 8 deletions
@@ -381,14 +381,30 @@ def point_hits(mouse_pos: MousePos, rect: rl.Rectangle, parent_rect: rl.Rectangl
return hit.width > 0 and hit.height > 0 and rl.check_collision_point_rec(mouse_pos, hit)
_WRAP_TEXT_CACHE: dict[tuple[int, str, int, int, int], tuple[str, ...]] = {}
_MAX_WRAP_CACHE_SIZE = 512
def wrap_text(font: rl.Font, text: str, max_width: float, font_size: float, max_lines: int = 2) -> list[str]:
if not text or max_width <= 0:
return []
font_id = getattr(getattr(font, "texture", None), "id", id(font))
w_key = int(round(max_width))
s_key = int(round(font_size))
key = (font_id, text, w_key, s_key, max_lines)
cached = _WRAP_TEXT_CACHE.get(key)
if cached is not None:
return list(cached)
spacing = font_size * 0.15
words = text.split()
lines: list[str] = []
current = ""
for word in words:
candidate = f"{current} {word}".strip() if current else word
if measure_text_cached(font, candidate, int(font_size), spacing=spacing).x <= max_width:
if measure_text_cached(font, candidate, s_key, spacing=spacing).x <= max_width:
current = candidate
else:
if current:
@@ -398,7 +414,12 @@ def wrap_text(font: rl.Font, text: str, max_width: float, font_size: float, max_
break
if current and len(lines) < max_lines:
lines.append(current)
return lines if lines else [text]
result = tuple(lines if lines else [text])
if len(_WRAP_TEXT_CACHE) >= _MAX_WRAP_CACHE_SIZE:
_WRAP_TEXT_CACHE.clear()
_WRAP_TEXT_CACHE[key] = result
return list(result)
def build_list_panel_frame(rect: rl.Rectangle, metrics: AetherListMetrics = AETHER_LIST_METRICS) -> AetherListFrame:
@@ -107,7 +107,7 @@ class StarPilotPanelInfo:
class StarPilotPanel(Widget):
def __init__(self):
super().__init__()
self._params_memory = Params(memory=True)
self._params_memory = ui_state.params_memory
self._params = FrameCachedParams()
self._navigate_callback: Callable | None = None
self._back_callback: Callable | None = None
@@ -111,13 +111,24 @@ def _speed_limit_pulse_color(base: rl.Color, alpha: int) -> rl.Color:
)
# ── State ─────────────────────────────────────────────────────────────
# ── State Cache ──────────────────────────────────────────────────────
_cached_key = None
_cached_slc_state = None
def _get_slc_state():
"""Extract SLC state from SubMaster. Returns dict or None if stale/hidden."""
global _cached_key, _cached_slc_state
sm = ui_state.sm
key = (sm.frame, sm.recv_frame.get("starpilotPlan", 0), ui_state.started_frame)
if key == _cached_key:
return _cached_slc_state
_cached_key = key
if sm.recv_frame["starpilotPlan"] < ui_state.started_frame:
_reset_pulse()
_cached_slc_state = None
return None
plan = sm["starpilotPlan"]
@@ -131,6 +142,7 @@ def _get_slc_state():
if not show_slc and not speed_limit_changed:
_reset_pulse()
_cached_slc_state = None
return None
speed_conversion = CV.MS_TO_KPH if ui_state.is_metric else CV.MS_TO_MPH
@@ -161,7 +173,7 @@ def _get_slc_state():
# and before any sign colors are computed downstream.
_tick_pulse(plan.slcSpeedLimitSource, resolved_ms)
return {
_cached_slc_state = {
'speed_limit': speed_limit,
'speed_limit_str': "\u2013" if speed_limit <= 1 else str(int(round(speed_limit))),
'slc_overridden_speed': slc_overridden_speed,
@@ -182,6 +194,7 @@ def _get_slc_state():
'mapbox_sl': max(0.0, plan.slcMapboxSpeedLimit * speed_conversion),
'next_sl': max(0.0, plan.slcNextSpeedLimit * speed_conversion),
}
return _cached_slc_state
# ── Fonts ─────────────────────────────────────────────────────────────
@@ -10,14 +10,28 @@ class WidgetLayoutManager:
"right": []
}
self.spacing = 15 # Spacing between widgets
self._prev_key = None
def register_widget(self, zone: str, widget: LayoutWidget):
"""Register a widget in a specific zone."""
self.zones[zone].append(widget)
self.zones[zone].sort(key=lambda w: w.priority)
self._prev_key = None
def update_layout(self, content_rect: rl.Rectangle, is_rhd: bool = False):
"""Calculate and apply positions of all active widgets in all zones."""
key = (
content_rect.x, content_rect.y, content_rect.width, content_rect.height,
is_rhd,
tuple(
(zone, tuple((w, w.is_visible, w.get_size() if w.is_visible else None) for w in widgets))
for zone, widgets in self.zones.items()
)
)
if key == self._prev_key:
return
self._prev_key = key
self.content_rect = content_rect
self._layout_left()
self._layout_bottom(is_rhd)
-3
View File
@@ -16,8 +16,6 @@ from openpilot.system.hardware import HARDWARE, PC
BACKLIGHT_OFFROAD = 65 if HARDWARE.get_device_type() == "mici" else 50
USBGPU_POLL_INTERVAL = 1.0
class CachedParams:
def __init__(self, ttl: float = 1.0):
self._params = Params()
@@ -64,7 +62,6 @@ class CachedParams:
return attr
class UIStatus(Enum):
DISENGAGED = "disengaged"
ENGAGED = "engaged"