LVGL Display Tearing: Match Buffering, Flush Completion and Panel Refresh

LVGL display tearing guide: trace the flush completion, DMA, cache and panel scan boundaries, and measure real latency without hiding the tear.

LVGL Display Tearing: Match Buffering, Flush Completion and Panel Refresh
Posted on by CDTech James

LVGL display tearing is usually a timing problem, not a rendering bug. An LVGL interface that tears only when a list scrolls is not usually a rendering bug. The flush path, the DMA transfer and the panel scan are running on different clocks, and the buffer becomes free before the panel has finished reading it. This guide follows the tear through the flush path, separates single and double buffering, and defines the timestamped trace and moving patterns that make the fault reproducible.

Where does LVGL display tearing enter the flush path?

Tearing starts when the scan overlaps the buffer write.

LVGL renders into a draw buffer, the flush callback sends it, and if the panel scans that region while the transfer is active, the frame tears.

LVGL renders into one or more draw buffers and calls a flush callback when a region is ready. The callback hands the pixels to the display interface, often through DMA or a bus write. The panel scans its own GRAM or receives the stream on its own clock. If the panel reads the region while the transfer is still updating it, the top of the region can show the new frame and the bottom the old one.

The tear is therefore a timing relationship, not a rendering error. The image in the buffer may be correct, and a screenshot may look perfect, while the panel shows a seam because the write and the scan overlapped. The fix is either to complete the write before the scan reaches the region or to synchronize the write to a safe window.

Trace the path from the render to the visible pixel. The LVGL 9.2 display porting guide documents draw buffers, render modes, flush callbacks, completion and rotation for that release.

How do single and double buffering change ownership?

Single buffering shares one buffer; double uses two.

With one buffer, drawing and transmission compete for the same memory; with two, LVGL draws into one while the other is displayed, but the swap still needs a scan boundary.

In a single-buffer design, LVGL draws into the buffer and then flushes it. While the flush is active, LVGL cannot safely draw into the same memory. If the flush is asynchronous, LVGL must wait for completion before the next render, or the two operations overlap and corrupt the image.

In a double-buffer design, LVGL draws into one buffer while the other is being displayed or transmitted. When the new buffer is ready, the two are swapped. The swap is the critical point: if it happens while the panel is scanning the old buffer, the panel can show part of each. Double buffering reduces the time the renderer waits, but it does not remove the need for a scan-boundary synchronization.

A swap that is not synchronized can be worse than single buffering, because the panel may see a mix of two full frames. Record the buffer mode, the buffer size and the swap condition. A design that claims double buffering but swaps immediately after the flush callback may still tear.

LCD module with dark front glass resting on a light surface
Module photograph from the industrial LCD display topic page. Interface and performance are not established by the image.

When is a flush-complete callback too early?

A flush callback can signal queued, not completed, transfer.

If flush_ready fires when DMA starts rather than finishes, LVGL reuses the buffer while the panel is still reading it, producing tearing or corruption.

Many display drivers start a DMA transfer in the flush callback and immediately report completion. That is correct only if the callback is defined to mean “the transfer has been queued,” and if LVGL is configured not to reuse the buffer until a later completion signal. If the driver reports completion at the start, LVGL treats the buffer as free and may draw into it while DMA is still reading.

The result can be a tear, a corrupted region or a random pattern that changes with timing. The fault is more likely with large updates, high refresh rates and slow buses, because the transfer takes longer and the overlap is wider.

Signal completion when the transfer has actually finished: the DMA completion interrupt, the bus idle condition or a panel acknowledgement. Record which event is used, because a driver that reports completion too early is a common source of intermittent tearing.

Which panel interfaces can synchronize to a scan boundary?

DSI and RGB panels expose different sync points.

A command-mode panel can use TE to mark a safe write window, while an RGB panel is synchronized by controller timing; the boundary depends on the interface.

A command-mode DSI panel scans its GRAM independently and can expose a tearing-effect signal. The host waits for TE, then writes the region within the safe window. An RGB panel receives a continuous stream from the display controller, and the controller’s frame timing defines the boundary. An SPI panel may accept writes at any time, with no synchronization at all, or may expose a TE pin depending on the controller.

The available synchronization determines the strategy. If the panel has TE, the driver can align updates to it. If the interface is RGB, the display controller’s vertical blanking is the natural boundary. If neither is available, the design has to complete the write faster than the panel can scan the region, or accept some tearing.

The ST AN4861 LTDC application note documents the controller-side timing and synchronization for specific STM32 families.

How should DMA and cache coherency be checked?

Clean the cache before DMA and invalidate after it.

If the CPU writes a buffer DMA reads, clean the cache before transfer; if DMA writes a buffer the CPU reads, invalidate after, or the CPU sees stale data.

On a cached MCU, the CPU may write pixels into a cache line that has not yet reached main memory when DMA starts. The DMA then reads stale data. The reverse happens when DMA writes a buffer and the CPU reads a cached copy that has not been invalidated. The result is a region that looks corrupted or out of date, which can be mistaken for a tearing problem.

A buffer allocated in non-cacheable memory avoids the clean and invalidate steps, but it may be slower to access from the CPU. The ST AN4839 cache application note describes clean and invalidate operations for the named STM32 families. The exact sequence depends on whether the buffer is in cacheable memory and whether the DMA is coherent with the CPU.

Record the cache operations and their order relative to the transfer. A cache bug can look exactly like a timing bug, and the trace will show the corruption without showing why.

LCD module with exposed flexible printed-circuit tails below the screen
Module photograph from the custom LCD display topic page. The picture shows the module only; its interface and performance are not established here.

What moving patterns reveal partial-frame updates?

Moving bars and scrolling text expose partial-frame updates.

A vertical bar, scrolling text and a full-screen colour change make the boundary between old and new content visible; a static image hides it.

A vertical bar moving across the screen crosses the update seam and shows a horizontal offset where the old and new frames meet. Scrolling text produces the same effect along the direction of motion. A full-screen colour change exercises the largest update and the shortest window. A small rectangle moving over a static background exposes a stale region that was not redrawn.

A moving bar at the panel’s refresh rate is the minimum test; a slower bar can hide a seam that appears only when the update rate matches the scan. Run the patterns at the product’s refresh rate and at the fastest update rate the application can produce. A slow update may fit easily; a fast update may overrun. Run them with the real widget set and the real font, because the update area and the number of flushes depend on the content.

Record the pattern, the update area, the refresh rate and the observed result. A test that only shows a static logo cannot reveal a partial-update fault.

How can latency be measured without hiding tearing?

Timestamp render, flush, DMA and scan on one time base.

Measure from render start to the first changed pixel on the panel; timing only the flush callback misses when the panel actually updates.

Latency has several stages: the render, the flush call, the DMA transfer, the panel’s scan and the visible change. If the measurement stops at the flush callback, it describes only the software path. If it stops at the DMA completion, it still misses the panel’s scan.

Use a GPIO toggle at the render start and another at the first visible change, or a camera/photodiode at the panel. Put both on the same time base. The difference is the end-to-end latency. Record the latency in the same run as the visual check; a fast result that tears is not a pass. Do not change the synchronization to reduce the measured latency, because that can hide the tear.

The Linux device power management documentation is relevant if the display is suspended and resumed; a resume path can change the buffer state and the first frame after resume.

What belongs in the graphics regression checklist?

The checklist pins buffer mode, sync source and completion.

Record buffer mode, flush completion condition, sync source, cache operations, test patterns and measured latency, so a later change can be compared.

The checklist should state whether the design uses single or double buffering, how the buffer is swapped, which event signals completion and which scan boundary is used. It should record the cache operations and their order, the panel interface and refresh rate, the test patterns and the measured latency.

Add the failure modes that were observed: tearing at a particular update size, a stale region after a rotation, or a corrupted frame after resume. A regression run should reproduce those cases, not only a healthy animation.

The table below is a template for the graphics record. It is not a set of limits; the values come from the panel and controller documents.

LVGL flush and tear evidence record
Workload or state Pixel or buffer format Measured traffic or energy Constraint Evidence source
Static screen Single buffer One flush per change No scan overlap Trace and screenshot
Scrolling list Double buffer Flush rate and DMA time Blank window or TE Camera and timing trace
Full-screen animation Double buffer Frame period and bus load Refresh and latency Frame capture
Rotation change Buffer reallocation Redraw traffic Buffer size and alignment Trace and visual check
Resume from sleep Restored buffer First-frame traffic Panel ready time State log and camera

The LVGL rotation documentation covers the buffer consequences of rotating a display, and the ST AN4861 LTDC application note note covers the controller-side interaction. A display such as the industrial TFT module shown above is only the final stage; the tear is decided before the pixels reach it.

FAQ

Can a faster frame rate make tearing more visible?

It can. A higher refresh means the panel scans the framebuffer more often, so a write that overlaps the scan has more opportunities to be caught. It also shortens the blanking window, leaving less time to complete the transfer. The result is more frequent or more visible tears, not fewer.

Should a flush callback signal completion when DMA starts?

No. Signalling completion when DMA starts tells LVGL that the buffer is free while the transfer is still reading it. LVGL may then draw into the buffer, and the panel sees a mixture of old and new data. Signal completion when the transfer has actually finished and the buffer is safe to reuse.

Can tearing disappear in a screenshot while remaining visible on the panel?

Yes. A screenshot captures the framebuffer or the rendered image, not the panel’s scan. The tear exists in the timing relationship between the write and the scan, so a captured frame can look perfect while the panel shows a seam. Diagnose tearing with a camera or with timing traces, not with a screenshot alone.

If an LVGL interface tears only during motion, send the buffer mode, flush completion event and timing trace to the CDTech engineering team for a display-path review.

Request a graphics tearing review

Copyright Shenzhen CDTech Electronics Co., Ltd. All Rights Reserved