I have easily pieced together (this library is great!) a UI, and it works just fine both in the SDL desktop simulator and on my board.
The display I have is to be mounted either in landscape or portrait orientation, depending on the individual board. So I need to be able to change the display rotation during runtime, e.g. via an onscreen touch button in a settings menu.
I am however having some Problems with the Rotation feature in LVGL: While the Display Rotation works perfectly well in the SDL desktop simulator (lv_port_pc_eclipse), on my board i get some very weird graphical glitches:
To see it more clearly, I am rendering the display in two steps: First Display a simple list, and then in a 2nd step toggle a checkbox from unchecked to checked.
Per default (not using any rotation), this looks completely fine:
Then I am trying Software Rotation 180deg. In the first step it displays the list upside-down as expected.
HOWEVER, in the 2nd step where it should just update the little checkbox area, it for some reason redraws the rest of the image non-flipped – that is the background area that should not be refreshed at all!
When looking at 90/270 degree rotation, i just get complete garbage. First some checkerboard pattern, then something that vaguely looks like the unrotated list.
I am running this on a Texas Instrument Eval Board with an AM335X Sitara and a custom proprietary RTOS (so I had to implement the display driver myself). The display driver runs uses 2 framebuffers in ping-pong, and they are flushed to the display via DMA by the LCD controller. (I also tried running it in single-framebuffer mode – both single and double buffering seem to work fine, and I get the above problem in both setups).
As for the LVGL display driver, I am using drv_disp.direct=true
, (in double-buffer mode I am manually syncing the dirty display areas – which would just be a tiny rectangle in step 2).
For rotation, I am configuring the driver like
...
drv_disp.full_refresh = false;
drv_disp.direct_mode = true;
drv_disp.sw_rotate = 1;
drv_disp.rotated = LV_DISP_ROT_180;
// drv_disp.rotated = LV_DISP_ROT_90;
...
I also looked into the monitor_cb
, and curiously in all 3 rotation modes the output is the same – a big dirty area in step 1 (first frame rendered), and a small area in step 2. As a side note, weirdly the time
in the CB is always zero, weirdly. But e.g. with the 180deg rotation, although the arg in the monitor_cb
suggests that only a small area was updated, I see that it actually wants me to flush the entire screen in the flush_cb
. Or I am misunderstanding the args in monitor_cb
.
So basically my question is, have I misunderstood the documentation, and setup lvgl incorrectly? Or is this a bug, since the manual warns
Support for software rotation is a new feature, so there may be some glitches/bugs depending on your configuration. If you encounter a problem please open an issue on GitHub.
Since software rotation is giving me problems, I had another look at the manual in Display interface — LVGL documentation and there is a section about hardware rotation that I do not quite understand. How would this look like? Would I have to do a geometric transform of the pixels in the flush_cb
? Does this even have to do with lvgl or is this completely independent of that?
By the way, I am using lvgl branch release/v8.3
. Compiler is IAR iccarm
v7.50.3
Also, here is a screenshot of the Desktop SDL simulator using 90deg rotation.
SDL Desktop, 90deg