帧缓冲区
帧缓冲是存储器的一部分,图形引擎通过更新帧缓冲,将需要显示的下一帧图像包含进来。
帧缓冲是RAM的一个连续部分,可以根据需要设定合适的大小。
帧缓冲具有相应的宽度和高度。 因此,我们通常将帧缓冲视为存储器的一个二维部分,可通过x、y坐标检索。
帧缓冲具有相应的色彩格式。 帧缓冲中的每个条目都是该色彩格式下的色彩。 我们将帧缓冲中的每一个这样的条目称为像素。
通过计算帧缓冲中像素的存储地址和更新存储的色彩,可以更新帧缓冲中位置 x,y 处的像素色彩。
uint32_t pixelAddress = x + y * WIDTH;
framebuffer[ pixelAddress ] = newColor;
同样地,我们可以获取帧缓冲中像素的色彩并用在计算中。 例如,暗化帧缓冲中像素的色彩(假设有暗化
函数可用)。
uint32_t pixelAddress = x + y * WIDTH;
framebuffer[ pixelAddress ] = darken( framebuffer[ pixelAddress ] );
对于帧缓冲存储器,通常不会如前文所述逐一读写像素,而是利用系统的底层硬件功能(如Chrom-ART DMA)进行读写。
色彩
在TouchGFX中,帧缓冲的像素色彩格式可以是:
- 灰度1、2或4位每像素(bpp)灰度,或者
- 高或真彩16、24或32 bpp色彩
每个像素使用的位数越多,帧缓冲能够呈现的颜色就越清晰,此外,每个像素使用的位数越多,帧缓冲消耗的存储空间就越多。
显示屏
帧缓冲的内容最终会被传输到并显示在物理显示屏上。 因此,帧缓冲与显示屏的像素宽度和高度相同是十分常见的。
Further reading
帧缓冲的位置
下面是一个基于微控制器的绘图系统的极简图。
帧缓冲可以位于MCU内部或外部RAM中。
每个可能位置都具有潜在的优势和不足。
内部RAM
如果帧缓冲位于MCU内部的RAM中,对帧缓冲的读和写访问会尽可能快地完成。 这意味着TouchGFX应用的运行会非常流畅。 反过来,内部RAM是十分稀少的资源,被系统的许多部件使用,因此,帧缓冲大量占用内部RAM也许不可行。
如果可行,由于无需额外的RAM,在内部RAM中提供帧缓冲可以降低系统的总体成本。
外部RAM
如果系统有外部RAM,可以选择在外部RAM而不是内部RAM中提供帧缓冲。 对外部RAM的读和写访问通常会比内部RAM慢,但外部RAM的空间量通常大得多。 因此,有时候这是唯一可行的解决方案。
MCU可能具有一些功能(如缓存),可加快外部RAM的访问速度。 参见关于MCU的部分了解详细信息。
Display with GRAM
Depending on the type of display in the system there might be memory embedded on the display (often called GRAM). 这段存储空间用来保存显示屏“实际”像素的内容。 显示屏中保存像素的存储空间,意味着在显示屏仍活动时,MCU可能处于空闲状态。
由于显示屏存储器并非存储器映射,既不打算也不适合用于像素的随机读取或写入,因此不可能将TouchGFX帧缓冲放在在显示屏自带的RAM中。 相反,TouchGFX将帧缓冲置于内部或外部RAM中,并在适当的时候将其传输到显示屏RAM。
存储空间消耗
帧缓冲中的色彩数量和像素数量决定了帧缓冲消耗的存储空间。
帧缓冲使用的存储空间通常为 宽 * 高 * 以位数计的色深 / 8 字节数。
分辨率(像素) | 色彩(bpp) | 计算 | 消耗的存储空间(字节) |
---|---|---|---|
800x480 | 16 bpp | 800 * 480 * 16 / 8 | 768,000 B |
480x272 | 24 bpp | 480 * 272 * 24 / 8 | 391,680 B |
100x100 | 8 bpp | 100 * 100 * 8 / 8 | 10,000 B |
当具有一个以上的帧缓冲时,消耗的存储空间相应地较大。 例如,当使用双重缓冲方案时,使用两个帧缓冲会消耗两倍的存储空间。
当帧缓冲不足一个时,由应用明确地分配和控制存储空间的量。 因此,存储空间的消耗量是完全可定制的,但应注意的是,使用量过少会影响整体图形性能。
Framebuffer Strategies
Framebuffer strategy is a core feature, that enables you to make the most optimal match between TouchGFX rendering and your existing hardware (MCU, RAM and Display). In case you are selecting new hardware, it is recommended to get familiar with the available framebuffer strategies in relation to your use case. The right choice can help optimize your hardware cost, i.e. assist you in selecting the minimum required hardware in terms of the amount of RAM for framebuffer(s) and the suitable display interface.
A framebuffer strategy defines how much RAM is used for framebuffers and controls how TouchGFX renders to the RAM. The strategy must match the available RAM and the type of display in the system. TouchGFX offers three different strategies, applicable on display systems with and without GRAM. Below is an overview of the strategies, highlighting their advantages and drawbacks in relation to display systems.
Displays without GRAM
Strategy | Advantages | Drawbacks | Use Cases |
---|---|---|---|
Double | No risk of tearing, optimal time for rendering | RAM for 2 framebuffers | High performance UIs |
Single | Only RAM for 1 framebuffer | Risk of tearing, suboptimal time for rendering | High - Moderate performance UIs |
Partial | Only RAM for less than a framebuffer | Higher risk of tearing, higher CPU load | Moderate - Low performance UIs |
Displays with GRAM
Strategy | Advantages | Drawbacks | Use Cases |
---|---|---|---|
Double | No risk of tearing, optimal time for rendering | RAM for 2 framebuffers | High performance UIs |
Single | Only RAM for 1 framebuffer, no risk of tearing | Suboptimal time for rendering | High - Moderate performance UIs |
Partial | Only RAM for less than a framebuffer | Risk of tearing | Moderate - Low performance UIs |
Tearing
Tearing is a visual artifact on the display where pixel data from two frames are shown in one screen draw, e.g. the screen has half of an old frame and half of a current one, with a clean horizontal split across (the tear). The location of the tear varies according to timing, it usually jumps all over the place, which can be distracting.
UI Performance
In the general Performance article, you will be introduced to aspects of UI performance, which covers how the individual UI components and there structure impacts performance. In the context of framebuffer strategy we think of:
- High performance, as UIs that uses multiple complex UI components/animations, e.g. Texture Mappers, SVGs, screen transitions
- Moderate performance, as UIs that uses few complex UI components/animations
- Low performance, as UIs that uses no complex UI components/animations
Note
Glossary
The following terms are used to describe the different framebuffer strategies.
- Display Controller (DC) - The hardware that reads pixels from memory. Is continuously reading the memory containing pixels. Sometimes referred to as the scanline.
- Display Transfer (DT) - The hardware responsible of transferring pixels from framebuffer memory to GRAM. Is only initiated by the MCU when required. Sometimes referred to as the transferline.
- Framebuffer Write (W) - The rendering of pixels to the framebuffer.
Displays without GRAM
The following demonstrates the working concept of framebuffer strategies on displays without GRAM. Common for all strategies are the use of a Display Controller which continuously reads pixel data directly from a framebuffer.
Double Buffering Strategy
Having two framebuffers allows rendering of the next frame into one framebuffer while the Display Controller scans the other framebuffer. Render time of the next frame is unrestricted by the Display Controller. Swapping framebuffers is blocked until the next frame is ready, meaning no risk of tearing because the Display Controller just scans the current framebuffer once again. The framebuffers are swapped after the Display Controller has scanned the entire framebuffer and the rendering is complete.
Single Buffering Strategy
Having one framebuffer allows rendering of the next frame into the same framebuffer as the Display Controller scans from. Render time of the next frame is restricted by the Display Controller. The Display Controller scans continuously, so if writing to the framebuffer takes too long, the Display Controller will collide (catch up) with the writing area and tearing will occur. This is caused by rendering complex UI components.
Partial Buffering Strategy
A single partial framebuffer block is used to emulate a full size framebuffer through a Memory Management Unit (MMU). Therefore this strategy is also known as Emulated Framebuffer Strategy.
The partial block acts as a sliding window moving down through the emulated framebuffer, with the phase and speed of the Display Controller.
Having a partial framebuffer block only allows rendering of a small portion of the next frame, because the block is reused multiple times to render the current frame. The reuse of the partial block results in a large number of small rendering operations, which result in higher CPU load. Render time of the next frame is restricted by the Display Controller and the partial block size. The Display Controller scans continuously, so if writing to the partial framebuffer block takes too long for any given region of the emulated framebuffer, the Display Controller will collide (catch up) with the writing area and tearing will occur. This is caused by rendering complex UI components. Compared to the Single Buffering Strategy the risk of tearing is higher because the working area of the Display Controller and framebuffer rendering is much smaller.
Note
Displays with GRAM
The following demonstrates the working concept of framebuffer strategies on GRAM displays. Common for all strategies are the use of a Display Interface used for transferring pixel data from a framebuffer to the GRAM on the display.
Double Buffering Strategy
Having two framebuffers allows rendering of the next frame into one framebuffer while the pixels are transferred to GRAM from the other. Render time of the next frame is unrestricted by the Display Transfer. Display transfers are only initiated when the next frame is ready, meaning no risk of tearing because the Display Controller just scans what is already in GRAM. The framebuffers are swapped after the display transfer and the rendering is complete.
Single Buffering Strategy
Having one framebuffer allows rendering of the next frame into the same framebuffer where pixels are transferred to GRAM. Render time of the next frame is restricted by the Display Transfer bandwidth. Display transfers are only initiated when the next frame is ready, meaning no risk of tearing because the Display Controller just scans what is already in GRAM. Rendering of the next frame cannot complete before the corresponding area to update has been transferred to GRAM.
Partial Buffering Strategy
One or more partial framebuffer blocks are used to emulate a full size framebuffer.
The partial blocks are reused to render all parts of the current frame that needs to be updated. When a block is rendered it can be transferred to GRAM and used for subsequent rendering.
To minimize the risk of tearing we strive to have the largest margin between GRAM being updated by the Display Transfer and the Display Controller scanline. This is done be having the transferline behind the scanline, which means that we can only render the current frame and not begin rendering the next frame. Render time of the current frame depends on the number of partial blocks defined and the time it takes to transfer each block. This means that we are allowed to render a block that is ahead of the Display Controller scanline if a block is available. If rendering and transferring of all the dirty areas of the current frame takes longer than the Display Controller its scanline can wrap around and catch the transferline, resulting in tearing. This is caused by rendering complex UI components and/or transferring too many pixels.
Getting Started with Framebuffer Strategies
In the following section we will show common hardware setups and point to scenarios on how to use framebuffer strategies on various hardware setups.
Further reading
Displays with GRAM
This display type has a dedicated RAM buffer with the same size as the display, i.e. a full size framebuffer.
The interfaces for this type of display are:
- FMC
- SPI
- DSI (Command Mode)
Scenarios demonstrating the use of these interfaces can be found here:
Displays without GRAM
This display type doesn't have a dedicated RAM buffer.
The interfaces for this type of display are:
- LTDC
- DSI (Video Mode)
Scenarios demonstrating the use of these interfaces can be found here: