Important: unclear posts may not receive useful answers.
Before posting
- Get familiar with Markdown to format and structure your post
- Be sure to update lvgl from the latest version from the
master
branch.
- Read the
Delete this section if you read and applied the mentioned points.
Description
My display controller accepts 8bits each of R, G and B… but the LVGL image converter has only one entry for RGB888 with a 4th byte 0f 0xFF (#if LV_COLOR_DEPTH == 32
/*Pixel format: Blue: 8 bit, Green: 8 bit, Red: 8 bit, Fix 0xFF: 8 bit, */)… Unfortunately my display controller doesn’t deal with this very well and obviously renders some messy stuff…
- I am noob and hence might be a stupid question is LV_COLOR_DEPTH of 24 possible at all ? I know it’s not defined anywhere(I only see 1, 8,16 and 32 defined though I noticed lvgl_flush_cb_24bit function).
- Is there a way to create an array with just a simple 3 byte RGB instead of 4 bytes ? Or should I write a script to do that ? is there a reason why you only have 32 bit color depth for RGB888 ?
What MCU/Processor/Board and compiler are you using?
Nrf5340 MCU, Custom board, RM69090 Display controller (QSPI), 320%360 AMOLED display. Zephyr RTOS with Nordic NCS (SDK) with built-in gcc tools)
NCS version: 1.5.1
LVGL version: ## v7.6.1 (06.10.2020)
Zephyr RTOS version: 2.4.99
What do you want to achieve?
display a image on my display screen
What have you tried so far?
displayed button and text… so i know basic stuff is up and running
Code to reproduce
Add the relevant code snippets here.
The code block(s) should be between ```c
and ```
tags:
/*You code here*/
Screenshot and/or video
If possible, add screenshots and/or videos about the current state.
Hi,
It’s planned to support RGB888 but it’s really not supported now. We have only ARGB888 because addressing and array of 4 bytes is trivial but with 3 byte elements there can be issues. E.g. lv_color24_t
can be 4 bytes on some systems.
What you can do is converting the rendered ARGB8888 image to RGB888 in your flush_cb
. You can do the conversation in place, e.g.:
uint8_t * color24 = (uint8_t *) color_p;
uint8_t * color32 = (uint8_t *) color_p;
uint32_t size = lv_area_get_size(area);
for(init i; i < size; i++) {
color24[0] = color32[0];
color24[1] = color32[1];
color24[2] = color32[2];
color24+=3;
color32+=4;
}
thanks… tried that… here’s how my cb looks like
void lvgl_flush_cb_24bit(struct _disp_drv_t *disp_drv,
const lv_area_t *area, lv_color_t *color_p)
{
#if 1
uint8_t * color24 = (uint8_t *) color_p;
uint8_t * color32 = (uint8_t *) color_p;
uint32_t size = lv_area_get_size(area);
printk("\n first converting 32 bit to 24 bit");
for(int i; i < size; i++) {
color24[0] = color32[0];
color24[1] = color32[1];
color24[2] = color32[2];
color24+=3;
color32+=4;
}
#endif
const struct device *display_dev = (const struct device *)disp_drv->user_data;
uint16_t w = area->x2 - area->x1 + 1;
uint16_t h = area->y2 - area->y1 + 1;
struct display_buffer_descriptor desc;
desc.buf_size = w * 3U * h;
desc.width = w;
desc.pitch = w;
desc.height = h;
display_write(display_dev, area->x1, area->y1, &desc, (void *) color_p);
lv_disp_flush_ready(disp_drv);
}
That didn’t make too much of difference when it comes to displaying the image… but I can not display a button or text if i use this change (if I remove the change, then button and text rendering works)…
Zephyr has another callback that points to this function… and this one works one way another depending on CONFIG_LVGL_COLOR_DEPTH_32… does tis need to change too ?
void lvgl_set_px_cb_24bit(struct _disp_drv_t *disp_drv,
uint8_t *buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
lv_color_t color, lv_opa_t opa)
{
uint8_t *buf_xy = buf + x * 3U + y * 3U * buf_w;
lv_color32_t converted_color;
#ifdef CONFIG_LVGL_COLOR_DEPTH_32
if (opa != LV_OPA_COVER) {
lv_color_t mix_color;
mix_color.ch.red = *buf_xy;
mix_color.ch.green = *(buf_xy+1);
mix_color.ch.blue = *(buf_xy+2);
color = lv_color_mix(color, mix_color, opa);
}
#endif
the actual call back is setup by zephyr as follows: (just code snip)
case PIXEL_FORMAT_RGB_888:
disp_drv->flush_cb = lvgl_flush_cb_24bit;
disp_drv->rounder_cb = NULL;
disp_drv->set_px_cb = lvgl_set_px_cb_24bit;
break;
If lvgl_set_px_cb_24bit
is set then the rendered image is already in RGB888 format. But note that it can be much faster to convert only the result image than every pixel.
I don’t know the details of the Zephyr driver, but if set px callback is set it might assume a disp_draw_buf suitable for 3 byte/px. So if you remove the set px callback be sure to use 4byte/px sized draw buffer.
thanks… looks like copying 32 bit image map to 24 bit is not needed… things seem to work right now and I am able to render images now…
thank you
1 Like