cancel
Showing results for 
Search instead for 
Did you mean: 

Support for padding in frame buffer

SZano
Associate III

Referring to application note AN4861

https://www.st.com/resource/en/application_note/dm00287603-lcdtft-display-controller-ltdc-on-stm32-mcus-stmicroelectronics.pdf

section 4.5.2 "Optimizing the LTDC framebuffer fetching from external memories" (page 43 on)

Performances are improved by not having a frame buffer that is "packed" (i.e. after the last pixel of a row there's the first pixel of the next row), and having instead a frame buffer with appropriate padding between rows.

This is because the LTDC reads the SDRAM in bursts of 64 bytes, but SDRAM burst reads cannot cross a 1KiB boundary. If this happens, the LTDC read is slowed down significantly (and it causes artifacts to appear when a significant portion of the screen is being redrawn, because during that time the LTDC is also slowed down by the DMA accessing the SDRAM, and the bandwidth is no longer sufficient to have a smooth, continuous display refresh).

To guarantee that this will never happen, each row in the frame buffer must be a multiple of 64bytes (row_width_bytes = active_width_pixels * bpp/8 + padding_bytes).

Also, the padding should be an integer number of pixels (the LTDC accepts an arbitrary number of bytes, but DMA2D requires an integer number of pixels).

For example: 800x480 display in RGB888 mode: each row is 800*3 = 2400 bytes

This must be rounded up to a multiple of both 64 and 3, which is 2496 bytes (813 pixels).

I have properly configured LTDC and DMA2D to work with this setting, but the TouchGFX library doesn't seem to support it.

I think the padding could be accounted for by changing the "stride" reported by the LCD classes (e.g. LCD24bpp::getFrameBufferStride()).

Right now, the stride is already used to work on a region smaller than the full width; the LCD class could just report the total width (display width + padding).

The padding could be passed to the LCD during TouchGFX initialization.

I don't know how this interacts with various features:

* rotating the display 90 degrees

* standard widgets that draw images / graphics

* drawing using DMA / NoDMA

I tried setting the padding to 13 pixels and the image is completely scrambled.

I then tried setting it to 1 pixel and here is what I see:

* artifacts appear when there is a lot of DMA activity (this is expected, since a padding of 1 is not appropriate to solve the alignment issue, it's just for debugging)

* the LCD24bpp::getFrameBufferStride() is completely ignored; nobody calls it

* images drawn by DMA are wrong, but if I tweak the STM32DMA class to account for the padding, they are ok

* actually, images drawn by DMA are piece-wise correct: sometimes an image is transferred in multiple chunks (depending on the occlusion algorithm), and all the chunks not starting at (0,0) are off

* vertical lines are slanted by 1 pixel (which is expected)

* texts are wrong: their position is always off; some of them are slanted, some are ok (I guess the ones that are ok are the ones that are being copied in a single DMA operation, with the DMA tweak that I tried)

From this, I guess that all the library code implicitly assumes that width==stride.

All that code is part of the precompiled library, so I don't think I can work around it.

Is there any plan to support arbitrary padding in the frame buffer(s)? Is there any other way for me to work around the problem?

3 REPLIES 3
Alexandre RENOUX
Principal

Hello,

Thank you for your detailed post. We will see what we can do to support arbitrary padding in the framebuffer. I don't know any work around right now but I will update you if something comes up.

/Alexandre

Do you know if support for this has been added to the framework?

We have a 480*480 screen, and would like to optimise the memory access.

4.18.0 will feature an XRGB framebuffer format, e.g. a 32-bit format without alpha. There's no immediate plan to support arbitrary padding.