[SOLVED] Problem with Software Rotation in Direct Mode

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:

No Rotation, Frame 1

No Rotation, Frame 2

Then I am trying Software Rotation 180deg. In the first step it displays the list upside-down as expected.

180deg, Frame 1

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!

180deg, Frame 2

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.

90deg, Frame 1

90deg, Frame 2


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

Update: I think the issue is that I am using direct mode, which apparently is not compatible with software rotation.

see the linked github issue comment

and the entire issue

I will have to adjust my flush callback then, bit of a shame since that is very simple in direct mode. Ah well, this can be considered resolved.