@@ -79,6 +79,11 @@ typedef struct {
7979static lv_display_t * lvgl_port_add_disp_priv (const lvgl_port_display_cfg_t * disp_cfg , const lvgl_port_disp_priv_cfg_t * priv_cfg );
8080#if LVGL_PORT_HANDLE_FLUSH_READY
8181static bool lvgl_port_flush_io_ready_callback (esp_lcd_panel_io_handle_t panel_io , esp_lcd_panel_io_event_data_t * edata , void * user_ctx );
82+ #if ESP_LVGL_PORT_USE_LCD_BUFFERED
83+ static void lvgl_port_flush_buffered_ready_callback (esp_lcd_panel_handle_t panel ,
84+ esp_lcd_buffered_panel_event_data_t * edata ,
85+ void * user_ctx );
86+ #endif
8287#if CONFIG_IDF_TARGET_ESP32S3 && ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL (5 , 0 , 0 )
8388static bool lvgl_port_flush_rgb_vsync_ready_callback (esp_lcd_panel_handle_t panel_io , const esp_lcd_rgb_panel_event_data_t * edata , void * user_ctx );
8489#endif
@@ -224,6 +229,51 @@ lv_display_t *lvgl_port_add_disp_rgb(const lvgl_port_display_cfg_t *disp_cfg, co
224229 return disp ;
225230}
226231
232+ #if ESP_LVGL_PORT_USE_LCD_BUFFERED
233+ lv_display_t * lvgl_port_add_disp_buffered (const lvgl_port_display_cfg_t * disp_cfg ,
234+ const lvgl_port_display_buffered_cfg_t * buffered_cfg )
235+ {
236+ assert (buffered_cfg != NULL );
237+ const lvgl_port_disp_priv_cfg_t priv_cfg = {
238+ #if LVGL_PORT_HANDLE_FLUSH_READY
239+ .use_flush_smphr = 1 , /* Always use semaphore for now */
240+ #else
241+ .use_flush_smphr = 0 , /* Don't need semaphore if not handling flush ready */
242+ #endif
243+ };
244+ lvgl_port_lock (0 );
245+ lv_disp_t * disp = lvgl_port_add_disp_priv (disp_cfg , & priv_cfg );
246+
247+ if (disp != NULL ) {
248+ lvgl_port_display_ctx_t * disp_ctx = (lvgl_port_display_ctx_t * )lv_display_get_driver_data (disp );
249+ /* Set display type */
250+ disp_ctx -> disp_type = LVGL_PORT_DISP_TYPE_OTHER ;
251+
252+ assert (disp_cfg -> io_handle != NULL );
253+
254+ #if LVGL_PORT_HANDLE_FLUSH_READY
255+ const esp_lcd_buffered_panel_event_callbacks_t cbs = {
256+ .wait_sync = buffered_cfg -> wait_sync ,
257+ .on_color_trans_done = lvgl_port_flush_buffered_ready_callback ,
258+ };
259+ /* Register done callback */
260+ esp_lcd_buffered_panel_register_event_callbacks (disp_ctx -> panel_handle , & cbs , disp );
261+
262+ /* Register wait callback if using semaphore */
263+ if (disp_ctx -> flush_smphr ) {
264+ lv_display_set_flush_wait_cb (disp , lvgl_port_flush_wait_smphr_callback );
265+ }
266+ #endif
267+
268+ /* Apply rotation from initial display configuration */
269+ lvgl_port_disp_rotation_update (disp_ctx );
270+ }
271+ lvgl_port_unlock ();
272+
273+ return disp ;
274+ }
275+ #endif
276+
227277esp_err_t lvgl_port_remove_disp (lv_display_t * disp )
228278{
229279 assert (disp );
@@ -256,6 +306,7 @@ esp_err_t lvgl_port_remove_disp(lv_display_t *disp)
256306 if (disp_ctx -> flush_smphr ) {
257307 vSemaphoreDelete (disp_ctx -> flush_smphr );
258308 }
309+
259310#if LVGL_PORT_PPA
260311 if (disp_ctx -> ppa_handle ) {
261312 lvgl_port_ppa_delete (disp_ctx -> ppa_handle );
@@ -482,13 +533,12 @@ static lv_display_t *lvgl_port_add_disp_priv(const lvgl_port_display_cfg_t *disp
482533}
483534
484535#if LVGL_PORT_HANDLE_FLUSH_READY
485- static bool lvgl_port_flush_io_ready_callback ( esp_lcd_panel_io_handle_t panel_io , esp_lcd_panel_io_event_data_t * edata , void * user_ctx )
536+ static bool lvgl_port_flush_common_ready_callback ( lv_display_t * disp_drv )
486537{
487538 BaseType_t need_yield = pdFALSE ;
488539
489- lv_display_t * disp_drv = (lv_display_t * )user_ctx ;
490540 assert (disp_drv != NULL );
491- lvgl_port_display_ctx_t * disp_ctx = lv_display_get_user_data (disp_drv );
541+ lvgl_port_display_ctx_t * disp_ctx = lv_display_get_driver_data (disp_drv );
492542 assert (disp_ctx != NULL );
493543
494544 if (disp_ctx -> flush_smphr ) {
@@ -504,27 +554,27 @@ static bool lvgl_port_flush_io_ready_callback(esp_lcd_panel_io_handle_t panel_io
504554 return (need_yield == pdTRUE );
505555}
506556
507- #if (CONFIG_IDF_TARGET_ESP32P4 && ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL (5 , 3 , 0 ))
508- static bool lvgl_port_flush_dpi_panel_ready_callback (esp_lcd_panel_handle_t panel_io , esp_lcd_dpi_panel_event_data_t * edata , void * user_ctx )
557+ static bool lvgl_port_flush_io_ready_callback (esp_lcd_panel_io_handle_t panel_io , esp_lcd_panel_io_event_data_t * edata , void * user_ctx )
509558{
510- BaseType_t need_yield = pdFALSE ;
511-
512559 lv_display_t * disp_drv = (lv_display_t * )user_ctx ;
513- assert (disp_drv != NULL );
514- lvgl_port_display_ctx_t * disp_ctx = lv_display_get_user_data (disp_drv );
515- assert (disp_ctx != NULL );
560+ return lvgl_port_flush_common_ready_callback (disp_drv );
561+ }
516562
517- if ( disp_ctx -> flush_smphr ) {
518- if ( xPortInIsrContext () == pdTRUE ) {
519- need_yield = xSemaphoreGiveFromISR ( disp_ctx -> flush_smphr , & need_yield );
520- } else {
521- xSemaphoreGive ( disp_ctx -> flush_smphr );
522- }
523- } else {
524- lv_disp_flush_ready ( disp_drv );
525- }
563+ # if ESP_LVGL_PORT_USE_LCD_BUFFERED
564+ static void lvgl_port_flush_buffered_ready_callback ( esp_lcd_panel_handle_t panel ,
565+ esp_lcd_buffered_panel_event_data_t * edata ,
566+ void * user_ctx )
567+ {
568+ lv_display_t * disp_drv = ( lv_display_t * ) user_ctx ;
569+ lvgl_port_flush_common_ready_callback ( disp_drv );
570+ }
571+ #endif
526572
527- return (need_yield == pdTRUE );
573+ #if (CONFIG_IDF_TARGET_ESP32P4 && ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL (5 , 3 , 0 ))
574+ static bool lvgl_port_flush_dpi_panel_ready_callback (esp_lcd_panel_handle_t panel_io , esp_lcd_dpi_panel_event_data_t * edata , void * user_ctx )
575+ {
576+ lv_display_t * disp_drv = (lv_display_t * )user_ctx ;
577+ return lvgl_port_flush_common_ready_callback (disp_drv );
528578}
529579
530580static bool lvgl_port_flush_dpi_vsync_ready_callback (esp_lcd_panel_handle_t panel_io , esp_lcd_dpi_panel_event_data_t * edata , void * user_ctx )
0 commit comments