Skip to content

Commit 6d8ae6a

Browse files
committed
Enable LVGL double buffering and improve border redraw
Introduces a second LVGL buffer for double buffering to reduce display tearing. Updates critical border flashing logic to invalidate and immediately refresh the border area, ensuring cleaner redraws and minimizing visual artifacts.
1 parent 0238748 commit 6d8ae6a

File tree

3 files changed

+18
-4
lines changed

3 files changed

+18
-4
lines changed

inc/sp140/lvgl/lvgl_core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ extern int8_t displayCS; // Display chip select pin
2424
extern lv_disp_drv_t disp_drv;
2525
extern lv_disp_draw_buf_t draw_buf;
2626
extern lv_color_t buf[LVGL_BUFFER_SIZE];
27+
extern lv_color_t buf2[LVGL_BUFFER_SIZE]; // Second buffer for double buffering
2728
extern Adafruit_ST7735* tft_driver;
2829
extern uint32_t lvgl_last_update;
2930
// Shared SPI bus mutex (guards TFT + MCP2515 access)

src/sp140/lvgl/lvgl_core.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
lv_disp_drv_t disp_drv;
88
lv_disp_draw_buf_t draw_buf;
99
lv_color_t buf[LVGL_BUFFER_SIZE];
10+
lv_color_t buf2[LVGL_BUFFER_SIZE]; // Second buffer for double buffering
1011
Adafruit_ST7735* tft_driver = nullptr;
1112
uint32_t lvgl_last_update = 0;
1213
// Define the shared SPI bus mutex
@@ -18,10 +19,10 @@ void setupLvglBuffer() {
1819
lv_init();
1920
USBSerial.println("LVGL initialized");
2021

21-
// Setup buffer for LVGL
22-
USBSerial.println("Setting up LVGL buffer");
23-
lv_disp_draw_buf_init(&draw_buf, buf, NULL, LVGL_BUFFER_SIZE);
24-
USBSerial.println("LVGL buffer initialized");
22+
// Setup double buffer for LVGL to reduce tearing
23+
USBSerial.println("Setting up LVGL double buffer");
24+
lv_disp_draw_buf_init(&draw_buf, buf, buf2, LVGL_BUFFER_SIZE);
25+
USBSerial.println("LVGL double buffer initialized");
2526
}
2627

2728
void setupLvglDisplay(

src/sp140/lvgl/lvgl_updates.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,16 +183,22 @@ static void critical_border_flash_timer_cb(lv_timer_t* timer) {
183183
bool is_on = !lv_obj_has_flag(critical_border, LV_OBJ_FLAG_HIDDEN);
184184
if (is_on) {
185185
lv_obj_add_flag(critical_border, LV_OBJ_FLAG_HIDDEN);
186+
// Invalidate the border area to ensure clean redraw
187+
lv_obj_invalidate(critical_border);
186188
lv_timer_set_period(timer, 700); // Off duration
187189
} else {
188190
lv_obj_clear_flag(critical_border, LV_OBJ_FLAG_HIDDEN);
191+
// Invalidate the border area to ensure clean redraw
192+
lv_obj_invalidate(critical_border);
189193
lv_timer_set_period(timer, 300); // On duration
190194

191195
// Trigger vibration pulse in sync with border "on"
192196
if (ENABLE_VIBE) {
193197
pulseVibration(300, 200); // 300ms pulse, intensity 200
194198
}
195199
}
200+
// Force immediate refresh to minimize tearing
201+
lv_refr_now(lv_disp_get_default());
196202
}
197203
}
198204

@@ -230,7 +236,10 @@ void startCriticalBorderFlashDirect() {
230236
if (critical_border != NULL && !isFlashingCriticalBorder) {
231237
isFlashingCriticalBorder = true;
232238
lv_obj_clear_flag(critical_border, LV_OBJ_FLAG_HIDDEN); // Start visible
239+
lv_obj_invalidate(critical_border); // Ensure clean initial draw
233240
critical_border_flash_timer = lv_timer_create(critical_border_flash_timer_cb, 300, NULL);
241+
// Force immediate refresh for clean start
242+
lv_refr_now(lv_disp_get_default());
234243
}
235244
}
236245

@@ -241,6 +250,9 @@ void stopCriticalBorderFlashDirect() {
241250
}
242251
if (critical_border != NULL) {
243252
lv_obj_add_flag(critical_border, LV_OBJ_FLAG_HIDDEN);
253+
lv_obj_invalidate(critical_border); // Ensure clean removal
254+
// Force immediate refresh for clean stop
255+
lv_refr_now(lv_disp_get_default());
244256
}
245257
isFlashingCriticalBorder = false;
246258
}

0 commit comments

Comments
 (0)