Body:
Hardware: Turing Smart Screen 8.8 inch, HW rev 1.x (USB, PID 0x0088)
OS: CachyOS (Arch), KDE Plasma 6, Wayland, Python 3.14
Revision setting: TUR_USB (LcdCommTuringUSB)
Commit: 262a28a
While trying to display an animation I measured how fast the screen can
accept frames, and found two things that cost a lot of time on every
single frame.
-
read_flush() in library/lcd/lcd_comm_turing_usb.py reads with
timeout=100. In normal use the device has nothing more to send, so this
read always waits the full 100 ms and then gives up. It happens once per
frame.
-
DisplayPILImage sends the whole screen every time, encoded as PNG with
compress_level=9. That is the slowest PNG setting.
Measurements on my machine, full screen 1920x480:
Unchanged code 362 ms per frame 2.76 fps
Same, but region cropped smaller 362 ms per frame 2.76 fps
(size makes no difference, the whole screen is always sent)
PNG encode alone, compress_level 9 104 ms 292 KB
PNG encode alone, compress_level 6 20 ms 309 KB
PNG encode alone, compress_level 1 12 ms 483 KB
JPEG encode alone, quality 85 1 ms 71 KB
Sending JPEG instead of PNG 112 ms per frame 8.9 fps
JPEG, and read_flush timeout 5 ms 20 ms per frame 49.3 fps
At 49 fps I played a 24 fps video with live sensor values drawn on top of
every frame, 240 frames with no errors and nothing garbled on screen.
Important detail: removing read_flush completely does NOT work. It reports
92 fps but that is fake. With real, differing frames the device stops
responding and the endpoint stalls with errno 110. The drain is needed.
Only its timeout is too long.
Suggested fix: keep read_flush but use a short timeout (5 ms worked
reliably for me), and prefer JPEG over compress_level 9 PNG for frame
uploads. I only have the 8.8 inch model, so other models may need a
different value, and it would probably be safest as a configurable option.
Body:
Hardware: Turing Smart Screen 8.8 inch, HW rev 1.x (USB, PID 0x0088)
OS: CachyOS (Arch), KDE Plasma 6, Wayland, Python 3.14
Revision setting: TUR_USB (LcdCommTuringUSB)
Commit: 262a28a
While trying to display an animation I measured how fast the screen can
accept frames, and found two things that cost a lot of time on every
single frame.
read_flush() in library/lcd/lcd_comm_turing_usb.py reads with
timeout=100. In normal use the device has nothing more to send, so this
read always waits the full 100 ms and then gives up. It happens once per
frame.
DisplayPILImage sends the whole screen every time, encoded as PNG with
compress_level=9. That is the slowest PNG setting.
Measurements on my machine, full screen 1920x480:
Unchanged code 362 ms per frame 2.76 fps
Same, but region cropped smaller 362 ms per frame 2.76 fps
(size makes no difference, the whole screen is always sent)
PNG encode alone, compress_level 9 104 ms 292 KB
PNG encode alone, compress_level 6 20 ms 309 KB
PNG encode alone, compress_level 1 12 ms 483 KB
JPEG encode alone, quality 85 1 ms 71 KB
Sending JPEG instead of PNG 112 ms per frame 8.9 fps
JPEG, and read_flush timeout 5 ms 20 ms per frame 49.3 fps
At 49 fps I played a 24 fps video with live sensor values drawn on top of
every frame, 240 frames with no errors and nothing garbled on screen.
Important detail: removing read_flush completely does NOT work. It reports
92 fps but that is fake. With real, differing frames the device stops
responding and the endpoint stalls with errno 110. The drain is needed.
Only its timeout is too long.
Suggested fix: keep read_flush but use a short timeout (5 ms worked
reliably for me), and prefer JPEG over compress_level 9 PNG for frame
uploads. I only have the 8.8 inch model, so other models may need a
different value, and it would probably be safest as a configurable option.