PNG images pre-caching

What do you want to achieve?

LVGL with enabled PNG decoder and i use in setup

lv_img_set_src(ui_ImageFlt, filtriky[lv_roller_get_selected(ui_Roller1)-1]);

i hope is preloaded into cache, but seems not, or only actual png.
Howto preload multiple decoded images for one object?

What have you tried so far?

In conf i setup #define LV_MEM_BUF_MAX_NUM 16 cached images and mem custom.
I see one workaround create all object over and hide unhide, but this isnt good.

Screenshot or video

Others

  • SquareLine Studio version: latest/8.3.7
  • Operating system:
  • Target hardware: ESP32 SPIRAM 4M

@kisvegabor can you help ?

You can set LV_IMG_CACHE_DEF_SIZE to > 1 to set number of images kept open in the memory.

FYI, in LVGL v9 we will allow setting the max size to be used for image cache instead of the number of images.

1 Like

sorry i miss copy here ofcourse i have set LV_IMG_CACHE_DEF_SIZE 16

The image caching mechanism will cache the images when they are opened (used) for the first time.

If you would like to preload the image you can do this:

    lv_img_decoder_dsc_t decoder;
    lv_img_decoder_open(&decoder, &img_wink_png, lv_color_hex(0x000000), 0);
    //Image header info is in decoder.header;
    //The decompressed image is in decoder.img_data;
    //Create an lv_img_dsc_t manually from decoder.header and decoder.img_data
    lv_img_decoder_close(&decoder);

can i check if when set img1 then 2 and back 1 on this command is last back without decode procesed over cache?

I debug 8.3.7 and my result is caching works, but is cleared by start any animation.
My 5 pngs is precached properly and next try showing is without decode.
But call this Tpan1_Animation(ui_TopPanel1, 0); or any other
and next show decode repeat plus i check free mem and after call anim mem go back to free state.
LOG first num is free mem cached all 5 pngs

2686964 loop … 36852
2686964 loop … 36852
Handled Headphone anim
4128756 loop … 36852
Handled Headphone
4128756 loop … 36852
[Error] (412.738, +368195) decoder_open: PNG decoded
(in lv_png.c line #178)
[Error] (412.845, +107) decoder_open: PNG decoded
(in lv_png.c line #178)
[Error] (413.238, +393) decoder_open: PNG decoded
(in lv_png.c line #178)
3342324 loop … 36852
3342324 loop … 36852
cached ok 3 images to next anim

I need solve this bug.
Error isnt error i only use LV_LOG_ERROR("

EDIT FYI used mem custom 1 in conf

Can you send a very simple code snippet to reproduce it? How do you pre-cache the images?

1 Like

This is in SQS + VSCode little complicated then basic info :
ESP32 VSCode Arduino LCD 320x480

  • upper half screen roller , bottom half IMG with changing src by roller possition
  • IMG is png src var type, and lvgl conf enabled png and mem custom
  • event roller change call this
void roller1_tpan2(lv_event_t * e)
{

lv_img_dsc_t * filtriky[8]={&filter1,&filter2,&filter3,&filter4,&filter5,&filter1,&filter1,&filter1};

	// Your code here
	
	//evnt key on moving
	if(lv_roller_get_selected(ui_Roller1)>0)	//and filters show filter no screen R
	{
		if(lv_obj_get_parent(ui_PanelR2) != ui_Screen2) lv_obj_set_parent(ui_PanelR2, ui_Screen2);
		lv_img_set_src(ui_ImageFlt, filtriky[lv_roller_get_selected(ui_Roller1)-1]);
	}
}

where

LV_IMG_DECLARE(filter1);
LV_IMG_DECLARE(filter2);
LV_IMG_DECLARE(filter3);
LV_IMG_DECLARE(filter4);
LV_IMG_DECLARE(filter5);

is png img src declarations.

On other button is assigned animation start for testing. Any animation created in SQS, but maybe not all , i test normal image with fade rotation and zoom.

First use roller all images is decoded and after this only show ok. But use anim start decode logged as in previous log info…

For meminfo in loop every 10s

if(1 && (looper5%2000)==0)   {
  Serial.print(heap_caps_get_largest_free_block(MALLOC_CAP_8BIT));
  Serial.print(" loop ... ");
  Serial.println(heap_caps_get_largest_free_block(MALLOC_CAP_DMA));
}

Where is the “pre-cache” part?

Pre-cache i test, but now check only cache system in lvgl. First use in roller log png decoding (precache) and after this it must never ocur. Actualy this work, but animation break it.
We need locate why break and how block images stay in cache.

//Create an lv_img_dsc_t manually from decoder.header and decoder.img_data

I dont understand , how this help. I test your code and decoding png is logged , but if i use source img in my code , decoding repeat and dont use predecoded. And i mean if i assign imgdsc as in comment this helps, but still will erased by next animation.

Sorry, I don’t get it. Let’s start from the beginning. What you wan’t is always keep some PNGs cached, right?

yes decode and dont trash and perfect is command for predecode, without this first show is slow and block GUI
plus define memory size free limit for no trash.
For example here i have 4M RAM and trash can start is less as an define 2M free

In LVGL v8 there is no size based limit on caching. (It will be in v9 though).

This dont help me, start begin, why animation erase all cached images?
How workaround decode to my malloc area and leave?

And special question can be C:\Program Files\SquareLine Studio 1.3.2\lvgl\lv_font_conv-win.exe used for cmdline convert png to c file with raw mode or other exe? Now is very annoy use online convert for every required image…

Wakeup Squareline company, you sell license …

There is nothing special in animations. Probably you have more images than LV_IMG_CACHE_DEF_SIZE and some images are removed from the cache.

You can do something like this to manually decode and store an image:

LV_IMG_DECLARE(my_raw_png);
lv_img_decoder_dsc_t decoder_dsc;
lv_img_decoder_open(&decoder_dsc, &my_raw_png, lv_color_black(), 0);

static lv_img_dsc_t img_dsc;
uint32_t decoded_img_size = decoder_dsc.header.w * decoder_dsc.header.h * LV_IMG_PX_SIZE_ALPHA_BYTE;
img_dsc.data = malloc(decoded_img_size);
memcpy(img_dsc.data, decoder_dsc.img_data, decoded_img_size);
img_dsc.header = decoder_dsc.header;
img_dsc.header.cf = LV_IMG_CF_TRUE_COLOR_ALPHA;
lv_img_decoder_close(&decoder_dsc);

lv_obj_t * img_widget = lv_img_create(lv_scr_act());
lv_img_set_src(img_widget, &img_dsc);

You can use GitHub - lvgl/lv_img_conv: Image converter for LVGL, written in JS as an offline converter.

My def is 16 and images png 6. Still you dont reply why erased.
And animations invoke this 100% as showed in log. When animation is disabled/not used images stay in cache.

Plus @kisvegabor your code create memory chaos. Example idea first image decoded 300x200 second 301x201 third 302x203. After this memory is …

I don’t understand why is it a memory chaos.

because 4M free mem:
1.image decoder reserve space and decode 300x200x4 … you copy 300x200x4 and leave it static. Mark area free
2.image cant use area and place decoding after static and repeat
3…
after this we have in RAM space image space image space image …
Areas with space is unusable for cache or decode next images bigger as 1.

Ok i use simple trick precache bigest image as first. Then memory storing images is filled continuosly and i see one interesant joke. LVGL Cached images fill bigger space as my stored. Seems because png decoder always reserve WxHx4 bytes , but for lvgl in 16 bit mode reconvert to WxHx3 . But in cache space leave reserved . In my precache memcpy is less space used and images stay in memory…

@kisvegabor and i still dont have info why little simple animation erase all lvgl cached images at once