
Tearing and double buffering
Tearing is the display reading a picture while a program is changing it. A faster refresh makes each frame shorter and does not remove the conflict. Two buffers swapped at the frame boundary, or a wait for the controller's TE signal, do.
A display scans from the top of the picture to the bottom. At 60 Hz a frame takes about 16.7 ms, so the bottom line is drawn 16.7 ms after the top. If the program changes the memory being scanned, the scan reaches the changed pixels part way down and shows a new moment under an old one. The seam is a horizontal tear.
The tear sits where the scan was when the write landed, and moves with it.
Why refresh rate does not fix it
At 120 Hz a frame is about 8.3 ms. The tear can get harder to see, but the timing conflict is unchanged. The same buffer is still being read and written at the same time.
Two buffers, swapped at the right time
Double buffering gives the scan one complete frame to read while the next is built elsewhere. That removes the half-written frame. It does not remove the tear if the program switches buffers in the middle of a scan, because the display then reads the top of one frame and the bottom of another.
The fix is timing. On an RGB display the swap is made at the VSYNC boundary, so the next scan starts on a complete new frame. The cost is memory: a second 1024 × 600 RGB565 frame is another 1.2288 MB.
A controller with its own memory
A GRAM display has a different version of the problem. The controller stores the picture, but the host can still write to that memory while the panel is scanning it. The ILI9341's Tearing Effect output exists to fix this. Its datasheet describes it as a pin that synchronises the MPU to frame writing, switched on by a software command. The host waits for TE and then starts the update.
On the ESP32
ESP-IDF's RGB panel configuration accepts up to three frame buffers, which is what makes a swap at the frame boundary possible. For a GRAM panel, TE is a pin you wire to a GPIO, turn on with a command, and wait on in your own code.
Common mistakes
- Raising the refresh rate. It shortens the frame and leaves the unsynchronised write. Tearing is a synchronisation problem.
- Swapping buffers immediately. Two buffers are not enough on their own. A swap in the middle of a scan brings the tear back.
- Leaving TE unconnected. On a GRAM panel, an update that does not wait for it can land in the middle of the panel's own scan. That is one possible cause of a tear on such a screen.
Edit this page — content/fundamentals/screens/tearing-and-double-buffering.mdx
Discuss this article
Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.