perf(wled): cache per-frame max-pixel for brightness threshold

Cache the np.max(frame) result keyed on frame identity. The
min_brightness_threshold check ran a full reduction over the LED
array on every loop iteration even when the frame reference was
unchanged — at 60 fps with multiple targets this added up to
hundreds of redundant reductions per second.
This commit is contained in:
2026-05-12 15:06:34 +03:00
parent ee4fa81376
commit 6e4c1b6642
@@ -845,6 +845,11 @@ class WledTargetProcessor(TargetProcessor):
prev_frame_ref = None prev_frame_ref = None
has_any_frame = False has_any_frame = False
_prev_brightness = -1 # force first send _prev_brightness = -1 # force first send
# Cache max-pixel per frame ref. ``np.max`` over a 200-300 LED array
# at 60 fps × N targets is non-trivial; we only need to recompute it
# when the frame reference itself changes.
_max_pixel_cached: int = 0
_max_pixel_for_frame: object = None
# Pre-allocate brightness scratch (uint16 intermediate + uint8 output) # Pre-allocate brightness scratch (uint16 intermediate + uint8 output)
_bright_u16: Optional[np.ndarray] = None _bright_u16: Optional[np.ndarray] = None
@@ -1012,7 +1017,12 @@ class WledTargetProcessor(TargetProcessor):
# If below cutoff → snap to 0 (LEDs off). # If below cutoff → snap to 0 (LEDs off).
_thresh = self._min_brightness_threshold _thresh = self._min_brightness_threshold
if _thresh > 0 and cur_brightness > 0: if _thresh > 0 and cur_brightness > 0:
if frame is _max_pixel_for_frame:
max_pixel = _max_pixel_cached
else:
max_pixel = int(np.max(frame)) max_pixel = int(np.max(frame))
_max_pixel_cached = max_pixel
_max_pixel_for_frame = frame
if max_pixel * cur_brightness // 255 < _thresh: if max_pixel * cur_brightness // 255 < _thresh:
cur_brightness = 0 cur_brightness = 0