Is LVGL the fastest there is for drawing?

Hi All,

A) I am new to lvgl and to hierarchy of graphics in general in Linux. Here is what I understand the top to down graphics layers are in software - please correct if I am wrong:

LVGL > x11 > Kernel Framebuffer
*Or x11 is not there?

Is LVGL standard use is without x11 and direct to framebuffer using this:

B) Is there a lower level than kernel framebuffer as well for graphics in software? or no rest is hardware and one can not access it using software?

C) I am looking to draw *live streaming charts of financial data (stocks, forex, crypto…) so this will be X/Y axis and not much fancier. I don’t need 3D yet. I may need some interaction to make charts bigger or smaller using mouse scrolling. BUT I need as fast as possible drawing with 100s of 1000s data points coming to LVGL to plot every second. I am ditching all other libraries in favor of speed and going right down to lowest layer. Is my approach for speed correct?

D) Are there any examples of financial data charting with LVGL?

I will have an Ubuntu Server or FreeBSD server which is hosted close to a broker in a data center so it will receive streaming data to it and it does not have a monitor attached to it and I won’t be setting in front of it. The plan is to chart data there using LVGL maybe and then VNC is over to my client-side PC (my home PC) OR to to send all data over network to me and to run LVGL on my client-side PC whichever gives me the fastest response to see on screen. Which approach is correct?

*Yes, I know eyes and brain analysis time is at least 13ms. My questions are just about realistic possible LVGL speeds.

Thank you kindly,

I’ll ask @kisvegabor to take a look at this and also respond with my thoughts here.

LVGL can do both. It can use SDL in order to render within a normal X11 window, or it can render to the framebuffer directly.

[quote=“Bruce_B, post:1, topic:4699”]
Is there a lower level than kernel framebuffer as well for graphics in software? or no rest is hardware and one can not access it using software?[/quote]

In general, for a 2D application, I think the framebuffer is the lowest-level interface.

I should note that the chart widget is not the most optimal for high speed redrawing of large amounts of data, as mentioned by @kisvegabor here. If you are looking for the maximum possible speed, you may have to use a canvas widget and write a line plotting algorithm yourself.

Sending the financial data over the network and plotting it locally is likely to be faster, as the VNC option would require you to send large chunks of the screen for each frame that’s redrawn.

Not that I’m aware of. It’s an interesting use case!

Thanks for the reply. I have some more questions.


LVGL can do both. It can use SDL in order to render within a normal X11 window, or it can render to the framebuffer directly.

It can do both ways without loosing any features? If so, why use SDL or x11?


@kisvegabor here
The person who issue with writing fast to screen says they can write directly to framebuffer with no issues. Why would there be any issues with LVGL? Is LVGL sort of a huge library now that it’s hard to find where the inefficiency is? I am assuming LVGL is just a wrapper and doesn’t add any delays itself to writing process to frame buffer.

The same person was asking for 60Hz (1/60 = 0.16 milliseconds per screen refresh). Does linux kernel framebuffer only support 60Hz and not 120Hz or more? or is this an LVGL limitation?

What makes chart widget not be optimal for this task? Are there delays or it doesn’t have a good queue system for example for receiving data? I see JavaScript libraries that claims to be able to to millions of data points per second so wondering what makes the same job very hard for LVGL?

You suggested to use Canvas. Is that because it is good at taking data points faster? I am assuming write operation speed to framebuffer is same whether it comes from charts widget or canvas widget. I am also assuming canvas widget is more efficient in receiving data points and sorting them before shooting them to framebuffer VS chart widget - is that why I should go for canvas? (my knowledge of canvas, chart graphics is limited as I still see it all as pixels).

If we develop our program on Ubuntu using LVGL for example, is that portable to Android or iOS or parts of it that relate to LVGL? Wondering if we can plan for that ahead of time.

How are these examples displayed? The demo stress test is impressive. Are these actually running on a linux server and then projected as mirror images JavaScript and then to browser? I understand LVGL is just to write to framebuffer and not even to a monitor.


Development is quite inconvenient when LVGL takes over the framebuffer directly. :wink: Linux is not designed to share the framebuffer between different applications, so we use SDL for ease of use. On the real target using the framebuffer would make much more sense.

LVGL is a widget framework, not just a primitives library. As such, there are unavoidable delays which it adds. Lots of things are quite well optimized but direct writing to the framebuffer will always be faster. LVGL’s main advantage is the fact that a lot of the UI handling is done for you.

LVGL can render at any speed if the CPU and hardware support it.

Same answer as above: LVGL is a widgets framework. The chart widget has built-in logic for plotting points, making things look nice, etc., whereas the canvas just renders raw pixels onto the screen. As such, the canvas will be faster than the chart.

LVGL can run on any system that supports C code; there is nothing in the library that depends on a specific OS or hardware setup.

The online demos are actually compiled to JavaScript using Emscripten and run in your browser directly (the server is only used for downloading the JS). It’s amazing how performant browsers have become.

LVGL is designed and optimized for embedded systems, so the benchmarks and anecdotes you read are all given in that context. These JavaScript libraries are all intended to run on a consumer PC, which is many orders of magnitude faster. You will likely not see a major issue with the chart’s performance if you’re running LVGL on a PC-like device.

Thanks for the response again.

Yes, running this on a PC for sure. If using canvas is there a known limit number of data points it can take or that is up to memory?

The canvas is effectively a framebuffer, so the limit is essentially how large you can make the canvas. Although if I were you, I wouldn’t display all the points on a widget at one time. I would keep the majority in memory and only display the visible ones.


I can confirm what @embeddedt said.

The main reasons why JS is much faster than LVGL:

  • LVGL has no interface to “PC-level” GPUs (e.g. OpenGL) only to embedded GPUs
  • LVGL renders everything real-time and doesn’t buffer the rendered image. That is all anti-aliased lines of the chart are drawn every time the chart needs to be redrawn. It’s on our roadmap to add this kind of caching to LVGL.

Thanks for the input.

In a trading chart what is the “visible” parts and what is the “non-visible” parts? All data streaming to me should be visible to make a rael-time full chart. I am not sure I understood what you mean there

JS = JavaScript?

My trading charts application is like this:

  • C++ program in Ubuntu Server (in data center) receives streaming price data which it hands off to my charts C++ program which incorporates LVGL and writes to buffer frame.
  • There are no monitors. I don’t know what graphic cards these servers use (probably just embedded ones anyway). I use xvfb and VNC to connect to server to look at these charts.


  • C++ program in Ubuntu Server (in data center) receives streaming price data which it sends over UDP socket to remote (my home ubuntu server) and then I have my charts C++ program which incorporates LVGL and writes to buffer frame and shows on a monitor for me.

True; in your case there isn’t going to be any history as you care about real-time data only.

Streaming the price data and rendering it locally is a better approach as it should mean less data being sent.

Thanks @embeddedt.

If I want to use Chart widget or Canvas widget are to draw trading charts are the following available?

  • Is there a Minimize/Maximize?
  • Is there a horizontal / vertical scroll available?
  • Can the window resize?
  • Can I have multiple windows on screen and open/close more?

Below is imagur link for picture sample of what I want to recreate for example. This is candle sticks but it can be regular bars too or a line. I have circled some Window features that I may need as well in LVGL.


All of these should be easy to implement. Note that the specific windowing functionality you are asking about is not built-in to LVGL, as it’s not designed around windowed interfaces.

In v8 I improved the chart widget to effectively handle a large number of points.

Take a look at this example:

Thanks for update. That sounds great.

I copied the lv_conf.h example to right place already without any changes. Is there a guide for compiling examples for x86? I get some errors like:

/lvgl/lvgl/examples/widgets/chart# gcc lv_example_chart_5.c /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/…/…/…/x86_64-linux-gnu/Scrt1.o: in function _start': (.text+0x24): undefined reference to main’
/usr/bin/ld: /tmp/ccj9Ly04.o: in function lv_obj_set_style_size': lv_example_chart_5.c:(.text+0xaf): undefined reference to lv_obj_set_local_style_prop’
/usr/bin/ld: /tmp/ccj9Ly04.o: in function lv_scr_act': lv_example_chart_5.c:(.text+0xbb): undefined reference to lv_disp_get_default’
/usr/bin/ld: lv_example_chart_5.c:(.text+0xc3): undefined reference to lv_disp_get_scr_act' /usr/bin/ld: /tmp/ccj9Ly04.o: in function lv_slider_set_range’:
lv_example_chart_5.c:(.text+0xf5): undefined reference to lv_bar_set_range' /usr/bin/ld: /tmp/ccj9Ly04.o: in function lv_slider_get_value’:
lv_example_chart_5.c:(.text+0x110): undefined reference to lv_bar_get_value' /usr/bin/ld: /tmp/ccj9Ly04.o: in function slider_x_event_cb’:
lv_example_chart_5.c:(.text+0x152): undefined reference to lv_chart_set_zoom_x' /usr/bin/ld: /tmp/ccj9Ly04.o: in function slider_y_event_cb’:
lv_example_chart_5.c:(.text+0x18e): undefined reference to lv_chart_set_zoom_y' /usr/bin/ld: /tmp/ccj9Ly04.o: in function lv_example_chart_5’:
lv_example_chart_5.c:(.text+0x1af): undefined reference to lv_chart_create' /usr/bin/ld: lv_example_chart_5.c:(.text+0x1cf): undefined reference to lv_obj_set_size’
/usr/bin/ld: lv_example_chart_5.c:(.text+0x1f3): undefined reference to lv_obj_align' /usr/bin/ld: lv_example_chart_5.c:(.text+0x211): undefined reference to lv_chart_set_range’
/usr/bin/ld: lv_example_chart_5.c:(.text+0x24c): undefined reference to lv_chart_add_series' /usr/bin/ld: lv_example_chart_5.c:(.text+0x26e): undefined reference to lv_chart_set_point_count’
/usr/bin/ld: lv_example_chart_5.c:(.text+0x28b): undefined reference to lv_chart_set_ext_array' /usr/bin/ld: lv_example_chart_5.c:(.text+0x29d): undefined reference to lv_slider_create’
/usr/bin/ld: lv_example_chart_5.c:(.text+0x2cf): undefined reference to lv_obj_add_event_cb' /usr/bin/ld: lv_example_chart_5.c:(.text+0x2de): undefined reference to lv_obj_get_width’
/usr/bin/ld: lv_example_chart_5.c:(.text+0x2f4): undefined reference to lv_obj_set_size' /usr/bin/ld: lv_example_chart_5.c:(.text+0x317): undefined reference to lv_obj_align’
/usr/bin/ld: lv_example_chart_5.c:(.text+0x329): undefined reference to lv_slider_create' /usr/bin/ld: lv_example_chart_5.c:(.text+0x35b): undefined reference to lv_obj_add_event_cb’
/usr/bin/ld: lv_example_chart_5.c:(.text+0x36a): undefined reference to lv_obj_get_height' /usr/bin/ld: lv_example_chart_5.c:(.text+0x37e): undefined reference to lv_obj_set_size’
/usr/bin/ld: lv_example_chart_5.c:(.text+0x3a1): undefined reference to `lv_obj_align’
collect2: error: ld returned 1 exit status

You will probably want to use one of the preconfigured simulator projects to experiment with examples. Since v8 is still in the prerelease stage, most of them haven’t been updated yet. I know that has v8 in the dev branch.