diff --git a/docs/src/details/main-modules/display/rotation.rst b/docs/src/details/main-modules/display/rotation.rst index a2889cb81d..38930cbd2d 100644 --- a/docs/src/details/main-modules/display/rotation.rst +++ b/docs/src/details/main-modules/display/rotation.rst @@ -21,11 +21,14 @@ according to the current rotation settings of the display. Note that in :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_DIRECT` the small changed areas are rendered directly in the frame buffer so they cannot be rotated later. Therefore in direct mode only the whole frame buffer can be rotated. -The same is true for :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_FULL`. In the case of :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_PARTIAL` the small rendered areas can be rotated on their own before flushing to the frame buffer. +:cpp:enumerator:`LV_DISPLAY_RENDER_MODE_FULL` can work with rotation if the buffer(s) +being rendered to are different than the buffer(s) being rotated to in the flush callback +and the buffers being rendered to do not have a stride requirement. + Below is an example for rotating when the rendering mode is :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_PARTIAL` and the rotated image should be sent to a **display controller**. diff --git a/src/core/lv_refr.c b/src/core/lv_refr.c index 5ddfecb518..9897698319 100644 --- a/src/core/lv_refr.c +++ b/src/core/lv_refr.c @@ -696,9 +696,15 @@ static void refr_area(const lv_area_t * area_p, int32_t y_offset) /*In direct mode and full mode the the buffer area is always the whole screen, not considering rotation*/ layer->buf_area.x1 = 0; layer->buf_area.y1 = 0; - layer->buf_area.x2 = lv_display_get_original_horizontal_resolution(disp_refr) - 1; - layer->buf_area.y2 = lv_display_get_original_vertical_resolution(disp_refr) - 1; - layer_reshape_draw_buf(layer, layer->draw_buf->header.stride); + if(lv_display_get_matrix_rotation(disp_refr)) { + layer->buf_area.x2 = lv_display_get_original_horizontal_resolution(disp_refr) - 1; + layer->buf_area.y2 = lv_display_get_original_vertical_resolution(disp_refr) - 1; + } + else { + layer->buf_area.x2 = lv_display_get_horizontal_resolution(disp_refr) - 1; + layer->buf_area.y2 = lv_display_get_vertical_resolution(disp_refr) - 1; + } + layer_reshape_draw_buf(layer, disp_refr->stride_is_auto ? LV_STRIDE_AUTO : layer->draw_buf->header.stride); } /*Try to divide the area to smaller tiles*/ diff --git a/src/display/lv_display.c b/src/display/lv_display.c index 01ca536425..8d47dfca42 100644 --- a/src/display/lv_display.c +++ b/src/display/lv_display.c @@ -439,6 +439,8 @@ void lv_display_set_draw_buffers(lv_display_t * disp, lv_draw_buf_t * buf1, lv_d disp->buf_1 = buf1; disp->buf_2 = buf2; disp->buf_act = disp->buf_1; + + disp->stride_is_auto = 0; } void lv_display_set_3rd_draw_buffer(lv_display_t * disp, lv_draw_buf_t * buf3) @@ -480,11 +482,19 @@ void lv_display_set_buffers(lv_display_t * disp, void * buf1, void * buf2, uint3 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); + + /* the stride was not set explicitly */ + disp->stride_is_auto = 1; } 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) { + if(stride == LV_STRIDE_AUTO) { + lv_display_set_buffers(disp, buf1, buf2, buf_size, render_mode); + return; + } + LV_ASSERT_MSG(buf1 != NULL, "Null buffer"); lv_color_format_t cf = lv_display_get_color_format(disp); uint32_t w = lv_display_get_original_horizontal_resolution(disp); @@ -505,6 +515,8 @@ void lv_display_set_buffers_with_stride(lv_display_t * disp, void * buf1, void * 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); + + disp->stride_is_auto = 0; } void lv_display_set_render_mode(lv_display_t * disp, lv_display_render_mode_t render_mode) diff --git a/src/display/lv_display_private.h b/src/display/lv_display_private.h index 8417d061cb..6545b0c161 100644 --- a/src/display/lv_display_private.h +++ b/src/display/lv_display_private.h @@ -93,6 +93,7 @@ struct _lv_display_t { lv_display_render_mode_t render_mode; uint32_t antialiasing : 1; /**< 1: anti-aliasing is enabled on this display.*/ uint32_t tile_cnt : 8; /**< Divide the display buffer into these number of tiles */ + uint32_t stride_is_auto : 1; /**< 1: The stride of the buffers was not set explicitly. */ /** 1: The current screen rendering is in progress*/