mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-04 22:35:08 +00:00
fix(display): end the scroll state at scroller-to-static handovers (#716)
A static plugin screen that follows a scroller no longer starts with the ticker's lagging rows on scan-compensated panels, and the 1 Hz loop's second frame is no longer recorded as a ~1 s mid-scroll freeze / Render stall. The display controller calls DisplayManager.end_scroll_for_static_screen() before a static screen's first display() (clears the scan history; _scan_segments passes its frames through in one swap) and set_scrolling_state(False) after it; the scroller's hold stays until then, so late-frame counts are unchanged. A screen's first frame is tagged 'handover': gaps of 250 ms or more before it go to the additive handover_freezes (frame_soak prints 'Handover gaps'), not freezes. The display thread is named display-<plugin id>. The WiFi notice and the schedule-off blank are not covered yet (docs list them as a follow-up). ledpi A B B A soak (20 min each, --preview): main 0.118% / 0.113% late with 6 / 3 freezes; with this and #717 0.107% / 0.104% late, 0 freezes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -141,6 +141,27 @@ class TestPluginExecutor:
|
||||
assert result is True
|
||||
mock_plugin.display.assert_called_once()
|
||||
|
||||
def test_execute_display_runs_on_a_thread_named_for_the_plugin(self):
|
||||
"""A screen's first frame is presented from this thread, so stack
|
||||
dumps (the frame-timing stall watchdog's) should name the plugin."""
|
||||
import threading
|
||||
from src.plugin_system.plugin_executor import PluginExecutor
|
||||
executor = PluginExecutor()
|
||||
seen = []
|
||||
|
||||
class Plugin:
|
||||
def display(self, display_mode=None, force_clear=False):
|
||||
seen.append((threading.current_thread().name, display_mode))
|
||||
return True
|
||||
|
||||
# Both ways display() is called: without a mode, and with one (most
|
||||
# multi-mode plugins, the scoreboards among them).
|
||||
assert executor.execute_display(Plugin(), "clock-simple") is True
|
||||
assert executor.execute_display(Plugin(), "clock-simple",
|
||||
display_mode="clock") is True
|
||||
assert seen == [("display-clock-simple", None),
|
||||
("display-clock-simple", "clock")]
|
||||
|
||||
def test_execute_display_exception(self):
|
||||
"""Test display execution with exception."""
|
||||
from src.plugin_system.plugin_executor import PluginExecutor
|
||||
|
||||
Reference in New Issue
Block a user