system/ui: improve texture caching (#35222)

improve texture caching
pull/35223/head
Dean Lee 2 weeks ago committed by GitHub
parent c57f576436
commit b1bdab0c90
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 50
      system/ui/lib/application.py
  2. 7
      system/ui/spinner.py

@ -18,6 +18,7 @@ STRICT_MODE = os.getenv("STRICT_MODE") == '1'
DEFAULT_TEXT_SIZE = 60 DEFAULT_TEXT_SIZE = 60
DEFAULT_TEXT_COLOR = rl.Color(200, 200, 200, 255) DEFAULT_TEXT_COLOR = rl.Color(200, 200, 200, 255)
ASSETS_DIR = os.path.join(BASEDIR, "selfdrive/assets")
FONT_DIR = os.path.join(BASEDIR, "selfdrive/assets/fonts") FONT_DIR = os.path.join(BASEDIR, "selfdrive/assets/fonts")
@ -37,7 +38,7 @@ class GuiApplication:
self._fonts: dict[FontWeight, rl.Font] = {} self._fonts: dict[FontWeight, rl.Font] = {}
self._width = width self._width = width
self._height = height self._height = height
self._textures: list[rl.Texture] = [] self._textures: dict[str, rl.Texture] = {}
self._target_fps: int = DEFAULT_FPS self._target_fps: int = DEFAULT_FPS
self._last_fps_log_time: float = time.monotonic() self._last_fps_log_time: float = time.monotonic()
self._window_close_requested = False self._window_close_requested = False
@ -67,28 +68,61 @@ class GuiApplication:
self._set_styles() self._set_styles()
self._load_fonts() self._load_fonts()
def load_texture_from_image(self, file_name: str, width: int, height: int, alpha_premultiply = False):
def texture(self, asset_path: str, width: int, height: int, alpha_premultiply=False, keep_aspect_ratio=True):
cache_key = f"{asset_path}_{width}_{height}_{alpha_premultiply}{keep_aspect_ratio}"
if cache_key in self._textures:
return self._textures[cache_key]
texture_obj = self._load_texture_from_image(os.path.join(ASSETS_DIR, asset_path), width, height, alpha_premultiply, keep_aspect_ratio)
self._textures[cache_key] = texture_obj
return texture_obj
def _load_texture_from_image(self, image_path: str, width: int, height: int, alpha_premultiply = False, keep_aspect_ratio=True):
"""Load and resize a texture, storing it for later automatic unloading.""" """Load and resize a texture, storing it for later automatic unloading."""
image = rl.load_image(file_name) if image_path.endswith('.svg'):
image = self._load_image_from_svg(image_path)
else:
image = rl.load_image(image_path)
if alpha_premultiply: if alpha_premultiply:
rl.image_alpha_premultiply(image) rl.image_alpha_premultiply(image)
rl.image_resize(image, width, height)
# Resize with aspect ratio preservation if requested
if keep_aspect_ratio:
orig_width = image.width
orig_height = image.height
scale_width = width / orig_width
scale_height = height / orig_height
# Calculate new dimensions
scale = min(scale_width, scale_height)
new_width = int(orig_width * scale)
new_height = int(orig_height * scale)
rl.image_resize(image, new_width, new_height)
else:
rl.image_resize(image, width, height)
texture = rl.load_texture_from_image(image) texture = rl.load_texture_from_image(image)
# Set texture filtering to smooth the result # Set texture filtering to smooth the result
rl.set_texture_filter(texture, rl.TextureFilter.TEXTURE_FILTER_BILINEAR) rl.set_texture_filter(texture, rl.TextureFilter.TEXTURE_FILTER_BILINEAR)
rl.unload_image(image) rl.unload_image(image)
self._textures.append(texture)
return texture return texture
def _load_image_from_svg(self, svg_path: str):
# TODO: Implement SVG loading
assert(0)
def close(self): def close(self):
if not rl.is_window_ready(): if not rl.is_window_ready():
return return
for texture in self._textures: for texture in self._textures.values():
rl.unload_texture(texture) rl.unload_texture(texture)
self._textures = [] self._textures = {}
for font in self._fonts.values(): for font in self._fonts.values():
rl.unload_font(font) rl.unload_font(font)

@ -1,10 +1,8 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import pyray as rl import pyray as rl
import os
import threading import threading
import time import time
from openpilot.common.basedir import BASEDIR
from openpilot.system.ui.lib.application import gui_app from openpilot.system.ui.lib.application import gui_app
from openpilot.system.ui.lib.window import BaseWindow from openpilot.system.ui.lib.window import BaseWindow
from openpilot.system.ui.text import wrap_text from openpilot.system.ui.text import wrap_text
@ -26,9 +24,8 @@ def clamp(value, min_value, max_value):
class SpinnerRenderer: class SpinnerRenderer:
def __init__(self): def __init__(self):
self._comma_texture = gui_app.load_texture_from_image(os.path.join(BASEDIR, "selfdrive/assets/img_spinner_comma.png"), TEXTURE_SIZE, TEXTURE_SIZE) self._comma_texture = gui_app.texture("img_spinner_comma.png", TEXTURE_SIZE, TEXTURE_SIZE)
self._spinner_texture = gui_app.load_texture_from_image(os.path.join(BASEDIR, "selfdrive/assets/img_spinner_track.png"), TEXTURE_SIZE, TEXTURE_SIZE, self._spinner_texture = gui_app.texture("img_spinner_track.png", TEXTURE_SIZE, TEXTURE_SIZE, alpha_premultiply=True)
alpha_premultiply=True)
self._rotation = 0.0 self._rotation = 0.0
self._progress: int | None = None self._progress: int | None = None
self._wrapped_lines: list[str] = [] self._wrapped_lines: list[str] = []

Loading…
Cancel
Save