lvgl / lvgl

Embedded graphics library to create beautiful UIs for any MCU, MPU and display type.
https://lvgl.io
MIT License
16.13k stars 3.16k forks source link

Recolor question #538

Closed chenshijianworkgit closed 5 years ago

chenshijianworkgit commented 5 years ago

Hi, I don't know if this is a problem. After clicking the recolor wallpaper, the brushing time increases a lot.

I am driving the 800*480 screen of the mpu interface under STM32H743, the normal loading screen is 9.2ms, the screen with wallpaper is 12.6ms, and the wallpaper recolor is 62.4ms.

I am running the official benchmark_create routine

20181108103859

20181108103907

20181108103918

AloyseTech commented 5 years ago

I think this is normal since the recolor takes time. It is a per pixel process IFAIK handled by the CPU. So it should take around 800*480*[instructions per pixel recolor]/[instruction per seconds] seconds to recolor the screen. Which is around 45ms for the STMH7 with 856DMIPS at 400MHz if we estimate 100 instruction for recoloring a pixel: 800*480*100/856000000 = 45ms.

See here the recolor code section : https://github.com/littlevgl/lvgl/blob/master/lv_draw/lv_draw_vbasic.c#L473

embeddedt commented 5 years ago

I agree with @AloyseTech. Recoloring is a CPU-bound process so it will definitely consume extra time. If we divide 1000 milliseconds by your benchmark time we get 1000/62.5 = 15 fps which is probably more than necessary for a static application. Running a video might not work well though.

chenshijianworkgit commented 5 years ago

@AloyseTech @embeddedt Can also be calculated like this, thank you very much。

Also want to ask if re-coloring a point requires 100 instruction?

chenshijianworkgit commented 5 years ago

Look at the code seems to be a bit more, do not know how many actual assembly instructions

AloyseTech commented 5 years ago

This was a rough estimation. The actual instruction count could be analyzed with a disassembly of the function.

embeddedt commented 5 years ago

STM32F746G-DISCO with Cortex-M7, compiled with GCC 7.3.1 and full optimization.

Haven't actually done any performance testing but those are the stats from my disassembly.

kisvegabor commented 5 years ago

The target of the image recolor features is the small icons. For example, if you have a green pipe icon, you can add a little black to it when it pressed. The drawing of small icons should be fast. So it's not a real-life scenario to recolor the whole background.

Anyway, I can imagine 100 instructions. If recolor is not used then the image's pixels are copied with memcpy line by line. It is very fast. In the case of recolor, every pixel needs to check one-by-one. If the image has:

We could achieve a minor speed up to check only what is really required but it would result in 8 algorithms. For example, we would need a separate algorithm for:

And it would break the simplicity, clearance and maintainability for a minor speed up.

embeddedt commented 5 years ago

@kisvegabor I don't think it's worth it to split the algorithm in this way. I doubt the overhead is very much especially with all the optimization GCC can do.

kisvegabor commented 5 years ago

@embeddedt I agree.

chenshijianworkgit commented 5 years ago

@kisvegabor @embeddedt @AloyseTech

Thank you very much for answering my questions

There are 136 instructions for re-coloring, so it is very close according to AloyseTech said. 136*800*480/856000000 = 61ms.

embeddedt commented 5 years ago

@chenshijianworkgit Glad to help! If this issue is solved please close it.

chenshijianworkgit commented 5 years ago

@embeddedt The questions are let to kissvegabor to close, forming a closed loop. Or let him see if there is any possibility of optimization.

kisvegabor commented 5 years ago

IMO the current implementation has a good balance between complexity and optimization. Anyway, this examination was interesting to see what is really happening in assembly level.