diff --git a/src/display/lv_display.c b/src/display/lv_display.c index df4bb9b27..8b1eaad11 100644 --- a/src/display/lv_display.c +++ b/src/display/lv_display.c @@ -444,6 +444,31 @@ void lv_display_set_buffers(lv_display_t * disp, void * buf1, void * buf2, uint3 lv_display_set_render_mode(disp, render_mode); } +void lv_display_set_buffers_with_stride(lv_display_t * disp, void * buf1, void * buf2, uint32_t buf_size, + uint32_t stride, lv_display_render_mode_t render_mode) +{ + LV_ASSERT_MSG(buf1 != NULL, "Null buffer"); + lv_color_format_t cf = lv_display_get_color_format(disp); + uint32_t w = lv_display_get_horizontal_resolution(disp); + uint32_t h = lv_display_get_vertical_resolution(disp); + LV_ASSERT_MSG(w != 0 && h != 0, "display resolution is 0"); + + if(render_mode == LV_DISPLAY_RENDER_MODE_PARTIAL) { + /* for partial mode, we calculate the height based on the buf_size and stride */ + h = buf_size / stride; + LV_ASSERT_MSG(h != 0, "the buffer is too small"); + } + else { + LV_ASSERT_FORMAT_MSG(stride * h <= buf_size, "%s mode requires screen sized buffer(s)", + render_mode == LV_DISPLAY_RENDER_MODE_FULL ? "FULL" : "DIRECT"); + } + + lv_draw_buf_init(&disp->_static_buf1, w, h, cf, stride, buf1, buf_size); + lv_draw_buf_init(&disp->_static_buf2, w, h, cf, stride, buf2, buf_size); + lv_display_set_draw_buffers(disp, &disp->_static_buf1, buf2 ? &disp->_static_buf2 : NULL); + lv_display_set_render_mode(disp, render_mode); +} + void lv_display_set_render_mode(lv_display_t * disp, lv_display_render_mode_t render_mode) { if(disp == NULL) disp = lv_display_get_default(); diff --git a/src/display/lv_display.h b/src/display/lv_display.h index e3e7c49f2..102a5325f 100644 --- a/src/display/lv_display.h +++ b/src/display/lv_display.h @@ -239,6 +239,21 @@ int32_t lv_display_get_dpi(const lv_display_t * disp); void lv_display_set_buffers(lv_display_t * disp, void * buf1, void * buf2, uint32_t buf_size, lv_display_render_mode_t render_mode); +/** + * Set the frame buffers for a display, similarly to `lv_display_set_buffers`, but allow + * for a custom stride as required by a display controller. + * This allows the frame buffers to have a stride alignment different from the rest of + * the buffers` + * @param disp pointer to a display + * @param buf1 first buffer + * @param buf2 second buffer (can be `NULL`) + * @param buf_size buffer size in byte + * @param stride buffer stride in bytes + * @param render_mode LV_DISPLAY_RENDER_MODE_PARTIAL/DIRECT/FULL + */ +void lv_display_set_buffers_with_stride(lv_display_t * disp, void * buf1, void * buf2, uint32_t buf_size, + uint32_t stride, lv_display_render_mode_t render_mode); + /** * Set the buffers for a display, accept a draw buffer pointer. * Normally use `lv_display_set_buffers` is enough for most cases.