diff --git a/selfdrive/ui/layouts/settings/starpilot/aethergrid.py b/selfdrive/ui/layouts/settings/starpilot/aethergrid.py index f8ede9bb0..5d3f33c76 100644 --- a/selfdrive/ui/layouts/settings/starpilot/aethergrid.py +++ b/selfdrive/ui/layouts/settings/starpilot/aethergrid.py @@ -381,30 +381,14 @@ 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, s_key, spacing=spacing).x <= max_width: + if measure_text_cached(font, candidate, int(font_size), spacing=spacing).x <= max_width: current = candidate else: if current: @@ -414,12 +398,7 @@ 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) - - 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) + return lines if lines else [text] def build_list_panel_frame(rect: rl.Rectangle, metrics: AetherListMetrics = AETHER_LIST_METRICS) -> AetherListFrame: diff --git a/selfdrive/ui/layouts/settings/starpilot/panel.py b/selfdrive/ui/layouts/settings/starpilot/panel.py index 6a7728ea8..1e1c6a18d 100644 --- a/selfdrive/ui/layouts/settings/starpilot/panel.py +++ b/selfdrive/ui/layouts/settings/starpilot/panel.py @@ -107,7 +107,7 @@ class StarPilotPanelInfo: class StarPilotPanel(Widget): def __init__(self): super().__init__() - self._params_memory = ui_state.params_memory + self._params_memory = Params(memory=True) self._params = FrameCachedParams() self._navigate_callback: Callable | None = None self._back_callback: Callable | None = None diff --git a/selfdrive/ui/onroad/starpilot/slc_speed_limit.py b/selfdrive/ui/onroad/starpilot/slc_speed_limit.py index 2bea66953..cf363f15a 100644 --- a/selfdrive/ui/onroad/starpilot/slc_speed_limit.py +++ b/selfdrive/ui/onroad/starpilot/slc_speed_limit.py @@ -111,24 +111,13 @@ def _speed_limit_pulse_color(base: rl.Color, alpha: int) -> rl.Color: ) -# ── State Cache ────────────────────────────────────────────────────── -_cached_key = None -_cached_slc_state = None - +# ── State ───────────────────────────────────────────────────────────── 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"] @@ -142,7 +131,6 @@ 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 @@ -173,7 +161,7 @@ def _get_slc_state(): # and before any sign colors are computed downstream. _tick_pulse(plan.slcSpeedLimitSource, resolved_ms) - _cached_slc_state = { + return { 'speed_limit': speed_limit, 'speed_limit_str': "\u2013" if speed_limit <= 1 else str(int(round(speed_limit))), 'slc_overridden_speed': slc_overridden_speed, @@ -194,7 +182,6 @@ 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 ───────────────────────────────────────────────────────────── diff --git a/selfdrive/ui/onroad/starpilot/widget_layout_manager.py b/selfdrive/ui/onroad/starpilot/widget_layout_manager.py index a4dfe1d63..7d1513fde 100644 --- a/selfdrive/ui/onroad/starpilot/widget_layout_manager.py +++ b/selfdrive/ui/onroad/starpilot/widget_layout_manager.py @@ -10,28 +10,14 @@ 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) diff --git a/selfdrive/ui/ui_state.py b/selfdrive/ui/ui_state.py index e7098c67c..76ef3d756 100644 --- a/selfdrive/ui/ui_state.py +++ b/selfdrive/ui/ui_state.py @@ -16,6 +16,8 @@ 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() @@ -62,6 +64,7 @@ class CachedParams: return attr + class UIStatus(Enum): DISENGAGED = "disengaged" ENGAGED = "engaged"