mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-04 06:15:09 +00:00
fix(display): thread-safety for deferred updates, BDF faces and follower image; one refresh default (#652)
- DisplayManager.defer_update()/process_deferred_updates(): one lock around every queue mutation (appends from the update thread were lost to the render thread's filter/slice reassignments); callables run outside it. - FontManager and element_style no longer cache BDF freetype.Face objects process-wide (load_bdf_face caches them per thread); element_style's LRU is locked against get/move_to_end vs eviction races. - limit_refresh_rate_hz default is one constant, DEFAULT_REFRESH_LIMIT_HZ = 100 (the template's), for the library options, refresh_hz, the matrix guard, Vegas and scroll_config. Previously a missing key capped the panel at 90 while pacing assumed 100. - Sync follower: the TCP thread queues the leader's scroll image; the render thread swaps image/array/width in between frames. - update_display() error log rate-limited (traceback first, then once a minute with a count); swallowed DisplayController exceptions log at DEBUG. - Root display_controller.py runs run.py via runpy. - stream_manager: correct the RLock release comments; merge duplicate if. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+7
-1
@@ -498,6 +498,7 @@ class FontManager:
|
||||
self.performance_stats["cache_misses"] += 1
|
||||
|
||||
# Load font
|
||||
shareable = True
|
||||
font_path = self.font_catalog.get(family)
|
||||
if not font_path:
|
||||
logger.warning(f"Font family '{family}' not found")
|
||||
@@ -507,6 +508,7 @@ class FontManager:
|
||||
try:
|
||||
if font_path.endswith('.bdf'):
|
||||
font = self._load_bdf_font(font_path, size_px)
|
||||
shareable = False
|
||||
else:
|
||||
font = load_truetype(font_path, size_px)
|
||||
except Exception as e:
|
||||
@@ -516,7 +518,11 @@ class FontManager:
|
||||
self.performance_stats["failed_loads"] += 1
|
||||
font = ImageFont.load_default()
|
||||
|
||||
self.font_cache[cache_key] = font
|
||||
# A BDF face is not cached here: font_cache is shared by every
|
||||
# thread, and a freetype.Face must never be (see load_bdf_face, which
|
||||
# already caches BDF faces per thread).
|
||||
if shareable:
|
||||
self.font_cache[cache_key] = font
|
||||
return font
|
||||
|
||||
def _load_bdf_font(self, font_path: str, size_px: int) -> freetype.Face:
|
||||
|
||||
Reference in New Issue
Block a user