@@ -22,7 +22,7 @@ struct EspPlatform : public slint::platform::Platform
2222{
2323 EspPlatform (slint::PhysicalSize size, esp_lcd_panel_handle_t panel,
2424 std::optional<esp_lcd_touch_handle_t > touch,
25- std::span<slint::platform::Rgb565Pixel> buffer1,
25+ std::optional<std:: span<slint::platform::Rgb565Pixel> > buffer1,
2626 std::optional<std::span<slint::platform::Rgb565Pixel>> buffer2 = {}
2727#ifdef SLINT_FEATURE_EXPERIMENTAL
2828 ,
@@ -52,7 +52,7 @@ struct EspPlatform : public slint::platform::Platform
5252 slint::PhysicalSize size;
5353 esp_lcd_panel_handle_t panel_handle;
5454 std::optional<esp_lcd_touch_handle_t > touch_handle;
55- std::span<slint::platform::Rgb565Pixel> buffer1;
55+ std::optional<std:: span<slint::platform::Rgb565Pixel> > buffer1;
5656 std::optional<std::span<slint::platform::Rgb565Pixel>> buffer2;
5757#ifdef SLINT_FEATURE_EXPERIMENTAL
5858 slint::platform::SoftwareRenderer::RenderingRotation rotation;
@@ -214,43 +214,71 @@ void EspPlatform::run_event_loop()
214214 }
215215
216216 if (std::exchange (m_window->needs_redraw , false )) {
217- auto rotated = false
217+ if (buffer1) {
218+ auto buffer1 = *this ->buffer1 ;
219+ auto rotated = false
218220#ifdef SLINT_FEATURE_EXPERIMENTAL
219- || rotation
220- == slint::platform::SoftwareRenderer::RenderingRotation::Rotate90
221- || rotation
222- == slint::platform::SoftwareRenderer::RenderingRotation::Rotate270
221+ || rotation
222+ == slint::platform::SoftwareRenderer::RenderingRotation::
223+ Rotate90
224+ || rotation
225+ == slint::platform::SoftwareRenderer::RenderingRotation::
226+ Rotate270
223227#endif
224- ;
225- auto region =
226- m_window-> m_renderer . render (buffer1, rotated ? size.height : size.width );
227- auto o = region.bounding_box_origin ();
228- auto s = region.bounding_box_size ();
229- if (s.width > 0 && s.height > 0 ) {
230- if (buffer2) {
228+ ;
229+ auto region = m_window-> m_renderer . render (buffer1,
230+ rotated ? size.height : size.width );
231+ auto o = region.bounding_box_origin ();
232+ auto s = region.bounding_box_size ();
233+ if (s.width > 0 && s.height > 0 ) {
234+ if (buffer2) {
231235#if SOC_LCD_RGB_SUPPORTED && ESP_IDF_VERSION_MAJOR >= 5
232- xSemaphoreGive (sem_gui_ready);
233- xSemaphoreTake (sem_vsync_end, portMAX_DELAY);
236+ xSemaphoreGive (sem_gui_ready);
237+ xSemaphoreTake (sem_vsync_end, portMAX_DELAY);
234238#endif
235239
236- // Assuming that using double buffer means that the buffer comes from the
237- // driver and we need to pass the exact pointer.
238- // https://github.com/espressif/esp-idf/blob/53ff7d43dbff642d831a937b066ea0735a6aca24/components/esp_lcd/src/esp_lcd_panel_rgb.c#L681
239- esp_lcd_panel_draw_bitmap (panel_handle, 0 , 0 , size.width , size.height ,
240- buffer1.data ());
241- std::swap (buffer1, buffer2.value ());
242- } else {
243- for (int y = o.y ; y < o.y + s.height ; y++) {
244- for (int x = o.x ; x < o.x + s.width ; x++) {
245- // Swap endianess to big endian
246- auto px =
247- reinterpret_cast <uint16_t *>(&buffer1[y * size.width + x]);
248- *px = (*px << 8 ) | (*px >> 8 );
240+ // Assuming that using double buffer means that the buffer comes from
241+ // the driver and we need to pass the exact pointer.
242+ // https://github.com/espressif/esp-idf/blob/53ff7d43dbff642d831a937b066ea0735a6aca24/components/esp_lcd/src/esp_lcd_panel_rgb.c#L681
243+ esp_lcd_panel_draw_bitmap (panel_handle, 0 , 0 , size.width , size.height ,
244+ buffer1.data ());
245+
246+ std::swap (buffer1, buffer2.value ());
247+ } else {
248+ for (int y = o.y ; y < o.y + s.height ; y++) {
249+ for (int x = o.x ; x < o.x + s.width ; x++) {
250+ // Swap endianess to big endian
251+ auto px = reinterpret_cast <uint16_t *>(
252+ &buffer1[y * size.width + x]);
253+ *px = (*px << 8 ) | (*px >> 8 );
254+ }
255+ esp_lcd_panel_draw_bitmap (panel_handle, o.x , y, o.x + s.width ,
256+ y + 1 ,
257+ buffer1.data () + y * size.width + o.x );
249258 }
250- esp_lcd_panel_draw_bitmap (panel_handle, o.x , y, o.x + s.width , y + 1 ,
251- buffer1.data () + y * size.width + o.x );
252259 }
253260 }
261+ } else {
262+ slint::platform::Rgb565Pixel *lb =
263+ (slint::platform::Rgb565Pixel *)heap_caps_malloc (
264+ size.width * 2 , MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
265+
266+ m_window->m_renderer .render_by_line ([this ,
267+ &lb](std::size_t line_y,
268+ std::size_t line_start,
269+ std::size_t line_end,
270+ void (*render_fn)(
271+ void *,
272+ std::span<slint::platform::
273+ Rgb565Pixel>
274+ &),
275+ void *render_fn_data) {
276+ std::span<slint::platform::Rgb565Pixel> view { lb, line_end - line_start };
277+ render_fn (render_fn_data, view);
278+ esp_lcd_panel_draw_bitmap (panel_handle, line_start, line_y, line_end,
279+ line_y + 1 , lb);
280+ });
281+ free (lb);
254282 }
255283 }
256284
@@ -292,7 +320,7 @@ TaskHandle_t EspPlatform::task = {};
292320
293321void slint_esp_init (slint::PhysicalSize size, esp_lcd_panel_handle_t panel,
294322 std::optional<esp_lcd_touch_handle_t > touch,
295- std::span<slint::platform::Rgb565Pixel> buffer1,
323+ std::optional<std:: span<slint::platform::Rgb565Pixel> > buffer1,
296324 std::optional<std::span<slint::platform::Rgb565Pixel>> buffer2
297325#ifdef SLINT_FEATURE_EXPERIMENTAL
298326 ,
0 commit comments