Can LVGL easily work with a paletted display?

Hello!

I am using LVGL in a project that involves the Wii U gamepad. My project is going to be a custom boot menu/loader for the gamepad.

The gamepad itself is a fairly simple platform: ARM9 @ 108MHz, 4MB of RAM, simple LCD controller and DMA blit.

I was going to design the UI part of this project, and have been shown LVGL. I thought, hey, this is going to do what I want. So I grabbed the last release, 9.2.2, and integrated it into my project. So far, all good.

However, I have one concern.

The Wii U gamepad supports 4 display modes: 8-bit paletted, 4-bit paletted, ARGB1555 and RGB565.

For now, I have set up LVGL to use RGB565, and it works fine. However, it’s not ideal. The LCD resolution on the gamepad is 854x480, which means that a 16-bit framebuffer takes up about 800KB of memory, so almost 1/4th of the available memory. Not ideal.

You guess why the gamepad’s stock firmware uses the 8-bit paletted mode instead.

I’d like to use that mode, however, I’ve looked into LVGL’s inner workings and it doesn’t appear very straightforward. LVGL seems to use 24-bit colors internally, and when LV_COLOR_DEPTH is 8, they are converted to a luminance value intended for a greyscale display.

Easiest solution would be to use it like that, and fill the palette with a colored gradient, but that limits my UI to one shade of color.

Alternately, I would need to make a custom theme that uses color indexes instead of raw colors, but even then, I would still need to modify some of LVGL’s internals. For one, I’d need it to use the color indexes as-is instead of trying to calculate a luminance value from them. I’d also need to think of something for color blending and all.

Is there something more obvious that I’m missing? Is there a more straightforward way to make LVGL work with a paletted display mode?

Forget indexed colors and use display with own FB memory for optimize memory in MCU. And 800kB isnt big , for 24 bit double buffering is …

Hello,

Interesting project. This may sound stupid but I don’t think LVGL has indexed colors by default. Could you perhaps modify the lv_flush callback to convert RGB565 values to an index for your framebuffer? May not really fit your purpose but it would amount to a smaller framebuffer.
Only the display buffer used by LVGL cannot really be made any smaller I am afraid.

P.S. @Marian_M using a different display sounds impossible in this case, the Wii U gamepad has a display built in. Would kind of defeat the purpose to use a different display in an existing product.

I guess that would work. I’m already using partial rendering mode, so if the partial buffer is twice as big it won’t be a big concern. Either way, I guess I’ll experiment with it when I’m at the optimization phase.

Thank you.

Edit- thinking back on it, a downside would be that I would need to convert it manually in the lv_flush callback. On the other hand, if I stick to RGB565, I can just use DMA to blit the partial buffer into place. So it’s a tradeoff. I’d have to test it out.

On the flip side, I could also add my own drawing units and leverage DMA for the simpler draw tasks, so there’s that too.

Indexing transcode is possible in flush, but you lost opacity and aliasing plus lvgl dont support it.
And info from wiki “The GamePad’s display contents are streamed as video from the console using a custom protocol and the [H.264] video codec, for which the GamePad contains a hardware decoder.”

Yeah, that’s during normal gameplay. The gamepad has a video decoder, but it also supports an ‘overlay’ framebuffer, which is displayed on top of the video output. Most of the gamepad’s UI is done via this framebuffer.

https://kuribo64.net/wup/doku.php?id=lcd_controller