Repository navigation
feat(m5stack-tab5): multiple DPI frame buffers (rotate at full FPS, optional zero-copy rendering) - #847
Draft
Alaining wants to merge 3 commits into
Conversation
… the panel's frame buffers The DPI panel was always created with one frame buffer, private to the BSP, so LVGL had to render into separate PSRAM draw buffers and every flush copied the area into the frame buffer the panel scans out. - Kconfig M5STACK_TAB5_DPI_NUM_FBS (1..3, default 1) sets num_fbs for all three panel variants (ILI9881, ST7123, ST7121). - frame_buffers() returns the panel's frame buffers (cached by initialize_lcd()), frame_buffer_size() their size, so an application can render straight into them; esp_lcd_panel_draw_bitmap() on a frame buffer switches the panel to it instead of copying. - initialize_display(const DisplayConfig &): with render_to_frame_buffers the BSP sets LVGL up in DIRECT mode on two of the frame buffers and its flush switches buffers once the frame's last area is rendered. No draw buffers and no rotation scratch buffer are allocated. initialize_display(size_t) is unchanged. - The example gains an opt-in menuconfig option for that mode; README and example README document it, with the render time measured on a Tab5 (full screen 75.6 -> 48.6 ms) and the PSRAM it saves. Defaults are unchanged: one frame buffer, draw buffers, copying flush. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…_flush_ready() itself The DPI transfer-done interrupt (notify_lvgl_flush_ready) only gives draw_done_sem_ now; the BSP's own flush() calls lv_display_flush_ready(). An application that installs its own flush callback on the frame buffers (frame_buffers(), DisplayConfig::render_to_frame_buffers) and relies on the interrupt to finish the flush hangs on its first frame. Say so in both doc comments. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…, or use a flush wait callback Make the custom-flush-callback note precise: LVGL waits for lv_display_flush_ready() after every flush-callback call (per area), and lv_display_set_flush_wait_cb() is the alternative that needs no call. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Author
|
@finger563 could you take a look when you have a moment? This adds multiple DPI frame buffers to the Tab5 BSP and is stacked on #738 (details in my comment there: #738 (comment)). It's a draft until #738 lands; the default config behaves exactly as #738 alone. Thanks! |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Tab5 screen rotation. With 2 frame buffers it rotates at 45 FPS instead of 15-27, and it can render with no copy and no tearing.
Stacked on #738. Merge order:
cfdbd8d9.main. Because fix(m5stack-tab5): rotation audit, experimental opt-in ST7121 panel rotation (default off), and DSI underrun fixes #738 is squash-merged, we rebase this branch ontomain(leaving only its own 3 commits) and retarget it tomain.Alternatively, this PR can be merged into #738's branch first, so #738 brings it to
main.CONFIG_M5STACK_TAB5_DPI_NUM_FBS(1-3, default 1) sets the number of DPI frame buffers for allthree panel variants. The default behaves as today.
frame_buffers()/frame_buffer_size()give access to the panel's frame buffers.initialize_display({.render_to_frame_buffers = true}): LVGL renders straight into the framebuffers (DIRECT mode) and the panel switches buffers. There are no draw buffers and no copy.
Rotation is not available in this mode.
into the single buffer.
which turns a buffer switch into a copy; fixed in v6.0.1.
lv_display_flush_ready()once perflush call (since fix(m5stack-tab5): rotation audit, experimental opt-in ST7121 panel rotation (default off), and DSI underrun fixes #738). Why: fix(m5stack-tab5): rotation audit, experimental opt-in ST7121 panel rotation (default off), and DSI underrun fixes #738's transfer-done interrupt no longer calls it, so LVGL would
wait forever for the next area.
Motivation and Context
With one frame buffer, every flush of a rotated UI has to rotate and copy into the buffer the
panel is scanning out. That costs most of the frame time and tears. With two buffers, rotated
drawing keeps the full frame rate, and a non-rotated UI can render into the hidden buffer with no
copy and no tearing, using less PSRAM.
Measured with the
m5stack-tab5example on a Tab5 (ST7123, ESP-IDF v6.0.0) while drawing on thetouch screen. "Rotated" means 90/180/270°, which all measured the same:
main, 1 bufferrender_to_frame_buffersHow has this been tested?
option on), with no new warnings. clang-format (pre-commit) is clean.
test and our hardware bench suite pass.
Types of changes
Checklist:
Software
.github/workflows/build.ymlfile to add my new test to the automated cloud build github action. (Not needed: the example is already built.)🤖 Generated with Claude Code