Fix load-dependent DSI flicker: TRIPLE_PARTIAL -> TRIPLE_FULL tear-avoid
Root cause (investigation): the BSP default tear-avoid mode is TRIPLE_PARTIAL. On ESP-IDF 5.5 the MIPI-DSI driver has no on_frame_buf_complete callback (added in IDF 6.0 -> the boot warning "buffer-switch...may not function on MIPI DSI"), so the adapter falls back to on_refresh_done, which fires every refresh (~60Hz) as a fake vsync. In PARTIAL mode that release path is NOT submit-gated, so when one LVGL frame takes >1 refresh to render it over-releases the buffer that is still being scanned out -> LVGL draws into the live front buffer -> tearing/flicker. Why it only started with the wake word, and only under load: at idle (sparse rain) a frame renders in <16.6ms so exactly one submit per refresh -> harmless. The always-on WakeNet added constant CPU/PSRAM load that pushed the heavy-rain frames (listening=16, thinking=40 streams) past one refresh -> triggered the over-release. User correctly identified it as a resource starve exposing the latent bug. Fix: switch to TRIPLE_FULL, which IS submit-gated even without the callback (one release per actual submit). Same 3 framebuffers, zero memory cost, app-side one-liner via bsp_display_start_with_config so the managed component is untouched. Trade-off: full-screen redraw per frame; if the rain gets choppy under load, cheaper rain rendering (canvas / half-rate tick) is the follow-up. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -142,7 +142,18 @@ void app_main(void)
|
||||
|
||||
s_events = xQueueCreate(8, sizeof(app_event_t));
|
||||
|
||||
bsp_display_start();
|
||||
/* TRIPLE_FULL, not the BSP default TRIPLE_PARTIAL: on IDF 5.5 the DSI driver
|
||||
* lacks the on_frame_buf_complete callback, so PARTIAL mode falls back to a
|
||||
* per-refresh "fake vsync" that over-releases the scanout buffer when a frame
|
||||
* takes >1 refresh to draw (heavy rain + always-on WakeNet) -> tearing/flicker.
|
||||
* TRIPLE_FULL is submit-gated even without that callback. Same 3 framebuffers. */
|
||||
bsp_display_cfg_t disp_cfg = {
|
||||
.lv_adapter_cfg = ESP_LV_ADAPTER_DEFAULT_CONFIG(),
|
||||
.rotation = ESP_LV_ADAPTER_ROTATE_0,
|
||||
.tear_avoid_mode = ESP_LV_ADAPTER_TEAR_AVOID_MODE_TRIPLE_FULL,
|
||||
.touch_flags = { .swap_xy = 0, .mirror_x = 0, .mirror_y = 0 },
|
||||
};
|
||||
bsp_display_start_with_config(&disp_cfg);
|
||||
bsp_display_backlight_on();
|
||||
face_init();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user