fix(i1): fix compiler and runtime issues with I1 rendering (#6714)

Co-authored-by: Liam <30486941+liamHowatt@users.noreply.github.com>
This commit is contained in:
Gabor Kiss-Vamosi
2024-08-26 12:30:40 +02:00
committed by GitHub
parent 6b8d420170
commit 3147fc2f52
6 changed files with 57 additions and 10 deletions

View File

@@ -136,7 +136,6 @@ or anything else to optimize while the waiting for flush.
If ``flush_wait_cb`` is not set, LVGL assume that `lv_display_flush_ready`
is used.
Rotation
--------
@@ -173,7 +172,7 @@ The default color format of the display is set according to :c:macro:`LV_COLOR_D
- :c:macro:`LV_COLOR_DEPTH` ``24``: RGB888 (3 bytes/pixel)
- :c:macro:`LV_COLOR_DEPTH` ``16``: RGB565 (2 bytes/pixel)
- :c:macro:`LV_COLOR_DEPTH` ``8``: L8 (1 bytes/pixel)
- :c:macro:`LV_COLOR_DEPTH` ``1``: I1 (1 bit/pixel) Only support for horizontal mapped buffers.
- :c:macro:`LV_COLOR_DEPTH` ``1``: I1 (1 bit/pixel) Only support for horizontal mapped buffers. See :refr:`monochrome` for more details:
The ``color_format`` can be changed with
:cpp:expr:`lv_display_set_color_depth(display, LV_COLOR_FORMAT_...)`.
@@ -205,6 +204,40 @@ to
``GGG BBBBB | RRRRR GGG``.
.. _monochrome:
Monochrome Displays
-------------------
LVGL supports rendering directly in a 1-bit format for monochrome displays.
To enable it, set ``LV_COLOR_DEPTH 1`` or use :cpp:expr:`lv_display_set_color_format(display, LV_COLOR_FORMAT_I1)`.
The :cpp:expr:`LV_COLOR_FORMAT_I1` format assumes that bytes are mapped to rows (i.e., the bits of a byte are written next to each other).
The order of bits is MSB first, which means:
.. code::
MSB LSB
bits 7 6 5 4 3 2 1 0
pixels 0 1 2 3 4 5 6 7
Left Right
Ensure that the LCD controller is configured accordingly.
Internally, LVGL rounds the redrawn areas to byte boundaries. Therefore, updated areas will:
- Start on an ``Nx8`` coordinate.
- End on an ``Nx8 - 1`` coordinate.
When setting up the buffers for rendering (:cpp:func:`lv_display_set_buffers`), make the buffer 8 bytes larger.
This is necessary because LVGL reserves 2 x 4 bytes in the buffer, as these are assumed to be used as a palette.
To skip the palette, include the following line in your ``flush_cb`` function: ``px_map += 8``.
As usual, monochrome displays support partial, full, and direct rendering modes as well.
In full and direct modes, the buffer size should be large enough for the whole screen, meaning ``(horizontal_resolution x vertical_resolution / 8) + 8`` bytes.
As LVGL can not handle fractional width make sure to round the horizontal resolution to 8-
(For example 90 to 96)
User data
---------

View File

@@ -26,7 +26,7 @@
COLOR SETTINGS
*====================*/
/*Color depth: 8 (A8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/
/*Color depth: 1 (I1), 8 (L8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/
#define LV_COLOR_DEPTH 16
/*=========================

View File

@@ -291,6 +291,13 @@ void lv_inv_area(lv_display_t * disp, const lv_area_t * area_p)
suc = lv_area_intersect(&com_area, area_p, &scr_area);
if(suc == false) return; /*Out of the screen*/
if(disp->color_format == LV_COLOR_FORMAT_I1) {
/*Make sure that the X coordinates start and end on byte boundary.
*E.g. convert 11;27 to 8;31*/
com_area.x1 &= ~0x7; /*Round down: Nx8*/
com_area.x2 |= 0x7; /*Round up: Nx8 - 1*/
}
/*If there were at least 1 invalid area in full refresh mode, redraw the whole screen*/
if(disp->render_mode == LV_DISPLAY_RENDER_MODE_FULL) {
disp->inv_areas[0] = scr_area;
@@ -1101,10 +1108,11 @@ static void refr_obj(lv_layer_t * layer, lv_obj_t * obj)
static uint32_t get_max_row(lv_display_t * disp, int32_t area_w, int32_t area_h)
{
bool has_alpha = lv_color_format_has_alpha(disp->color_format);
lv_color_format_t cf = has_alpha ? LV_COLOR_FORMAT_ARGB8888 : disp->color_format;
lv_color_format_t cf = disp->color_format;
uint32_t stride = lv_draw_buf_width_to_stride(area_w, cf);
int32_t max_row = (uint32_t)disp->buf_act->data_size / stride;
uint32_t overhead = LV_COLOR_INDEXED_PALETTE_SIZE(cf) * sizeof(lv_color32_t);
int32_t max_row = (uint32_t)(disp->buf_act->data_size - overhead) / stride;
if(max_row > area_h) max_row = area_h;

View File

@@ -168,9 +168,9 @@ void lv_draw_buf_clear(lv_draw_buf_t * draw_buf, const lv_area_t * a)
if(lv_area_get_width(&a_clipped) <= 0) return;
if(lv_area_get_height(&a_clipped) <= 0) return;
uint8_t px_size = lv_color_format_get_size(header->cf);
uint8_t * buf = lv_draw_buf_goto_xy(draw_buf, a_clipped.x1, a_clipped.y1);
uint32_t line_length = lv_area_get_width(&a_clipped) * px_size;
uint8_t bpp = lv_color_format_get_bpp(header->cf);
uint32_t line_length = (lv_area_get_width(&a_clipped) * bpp + 7) >> 3;
int32_t y;
for(y = a_clipped.y1; y <= a_clipped.y2; y++) {
lv_memzero(buf, line_length);

View File

@@ -83,7 +83,7 @@
COLOR SETTINGS
*====================*/
/*Color depth: 8 (A8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/
/*Color depth: 1 (I1), 8 (L8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/
#ifndef LV_COLOR_DEPTH
#ifdef CONFIG_LV_COLOR_DEPTH
#define LV_COLOR_DEPTH CONFIG_LV_COLOR_DEPTH

View File

@@ -171,7 +171,10 @@ typedef enum {
LV_COLOR_FORMAT_YUV_END = LV_COLOR_FORMAT_UYVY,
/*Color formats in which LVGL can render*/
#if LV_COLOR_DEPTH == 8
#if LV_COLOR_DEPTH == 1
LV_COLOR_FORMAT_NATIVE = LV_COLOR_FORMAT_I1,
LV_COLOR_FORMAT_NATIVE_WITH_ALPHA = LV_COLOR_FORMAT_I1,
#elif LV_COLOR_DEPTH == 8
LV_COLOR_FORMAT_NATIVE = LV_COLOR_FORMAT_L8,
LV_COLOR_FORMAT_NATIVE_WITH_ALPHA = LV_COLOR_FORMAT_AL88,
#elif LV_COLOR_DEPTH == 16
@@ -183,7 +186,10 @@ typedef enum {
#elif LV_COLOR_DEPTH == 32
LV_COLOR_FORMAT_NATIVE = LV_COLOR_FORMAT_XRGB8888,
LV_COLOR_FORMAT_NATIVE_WITH_ALPHA = LV_COLOR_FORMAT_ARGB8888,
#else
#error "LV_COLOR_DEPTH should be 1, 8, 16, 24 or 32"
#endif
} lv_color_format_t;
#define LV_COLOR_FORMAT_IS_ALPHA_ONLY(cf) ((cf) >= LV_COLOR_FORMAT_A1 && (cf) <= LV_COLOR_FORMAT_A8)