LVGL Benchmark
A direct port of LVGL's upstream benchmark demo through the oveRTOS LVGL binding. Fifteen rendering scenes exercise widgets, animations, layout, image decoding, and compositing; a summary table reports per-scene FPS / CPU / render / flush time.
Source: apps/{c,cpp,rust,zig}/heap/lvgl_benchmark/ (and matching zeroheap/ variants).
What it does
The app cycles through scenes automatically. Each scene runs for a fixed duration, during which LVGL's built-in profiling records:
| Metric | What it measures |
|---|---|
| FPS | Frames rendered per second |
| CPU | Percentage of CPU time spent in lv_timer_handler |
| Render avg | Mean render time per frame (μs) |
| Flush avg | Mean display flush time per frame (μs) |
After all scenes complete, a summary table replaces the scene area. The summary is the same across every language port — same scenes, same metric layout.
Scenes
- Empty screen — baseline.
- Rectangle — solid fill.
- Rectangle, rounded — anti-aliased corners.
- Rectangle, circle — full circle.
- Rectangle, rounded, shadow — drop shadow compositing.
- Rectangle, rounded, opaque, layer — multi-layer composite.
- Rectangle, rounded, alpha 50, layer — layer with transparency.
- Rectangle, image, RGB recolor — image asset with palette swap.
- Image, ARGB recolor — alpha-blended image.
- Image, ARGB shake — animated alpha image.
- Label, small — short text.
- Label, medium — paragraph text.
- Label, large — full-screen text.
- Substring, small — partial redraw test.
- Substring, medium — partial redraw with longer text.
The scene set tracks the upstream LVGL benchmark verbatim so numbers are directly comparable to other LVGL ports.
Running it
# Host (POSIX) — opens the browser dashboard
make host.posix.lvgl_benchmark
make && make run
# QEMU + FreeRTOS — runs in the QEMU framebuffer
make qemu.freertos.lvgl_benchmark
make && make run
# STM32F7 Discovery board — flashes to hardware
make stm32f746.freertos.lvgl_benchmark
make && make flash
C++, Rust, and Zig ports build the same way — substitute lvgl_benchmark_cpp, lvgl_benchmark_rust, or lvgl_benchmark_zig for the third token.
Per-language walkthroughs
- C — direct LVGL C API through
<ove/lvgl.h> - C++ — RAII wrappers and typed widget builders
- Rust —
no_stdsafe wrappers viaove::lvgl::* - Zig —
comptime-generic widget construction
What to read it for
The benchmark is the easiest place to see:
- How the binding exposes LVGL's draw primitives (rectangles, shadows, animations).
- The pattern for registering a scene — a callback that builds widgets, plus a timer callback that swaps scenes.
- How the binding handles image assets (LVGL's
LV_IMAGE_DECLAREmacro in C;lv_img_dsc_tstatic descriptors in the higher-level languages).
Performance notes
- The same scene on the same board produces near-identical numbers across language ports — the bindings compile down to identical LVGL calls. Spot-checks for any divergence > 5 % usually indicate a binding bug.
- The POSIX backend on a developer laptop yields wildly higher numbers than embedded targets; treat host runs as a regression baseline only.
- For headline numbers on STM32F746G-DISCO, see Benchmarks → per-binding.