주요 내용으로 건너뛰기

프레임버퍼

프레임버퍼란 그래픽 엔진에서 디스플레이에 표시할 다음 이미지를 준비할 목적으로 업데이트되는 메모리를 말합니다.

프레임버퍼는 일정 크기의 RAM에 인접한 부분입니다.

프레임버퍼 메모리

프레임버퍼에는 연관된 가로와 세로가 있습니다. 이러한 이유로 프레임버퍼는 x,y 좌표로 인덱싱이 가능한 2D 메모리라는 인식이 있습니다.

2D 프레임버퍼 메모리

프레임버퍼에는 연관된 색상 형식이 있습니다. 프레임버퍼의 시작 부분은 이러한 색상 형식에 따른 색상을 나타냅니다. 따라서 프레임버퍼의 이러한 각 시작 부분을 픽셀이라고 칭하겠습니다.

프레임버퍼의 픽셀 메모리 주소를 계산하여 저장된 색상을 업데이트하면 프레임버퍼에서 x, y 위치의 픽셀 색상을 업데이트할 수 있습니다.

uint32_t pixelAddress = x + y * WIDTH;
framebuffer[ pixelAddress ] = newColor;

마찬가지로 프레임버퍼의 픽셀 색상을 가져와서 계산에 사용할 수도 있습니다. 예를 들어 프레임버퍼의 픽셀 색상을 어둡게 할 수 있습니다(darken 함수를 사용할 수 있는 경우).

uint32_t pixelAddress = x + y * WIDTH;
framebuffer[ pixelAddress ] = darken( framebuffer[ pixelAddress ] );

프레임버퍼 메모리는 위와 같이 픽셀 단위로 쓰거나 읽는 경우가 많지 않고, Chrom-ART DMA와 같은 시스템 기반 하드웨어 기능을 주로 이용해 쓰거나 읽습니다.

색상

TouchGFX에서 프레임버퍼의 픽셀 색상 형식은 다음 중 한 가지입니다.

  • 그레이스케일 1, 2 또는 4bpp(Bits per Pixel) 그레이스케일
  • 하이 또는 트루 컬러 16, 24 또는 32bpp 색상

bpp를 많이 사용할수록 프레임버퍼에서 나타낼 수 있는 고유 색상도 늘어납니다. 나아가, bpp를 많이 사용할수록 프레임버퍼의 메모리 소비량도 증가합니다.

디스플레이

프레임버퍼의 내용은 최종적으로 물리적 디스플레이에 전송되어 표시됩니다. 따라서 프레임버퍼와 디스플레이의 픽셀 가로 및 세로가 서로 동일한 경우가 많습니다.

24bpp 프레임버퍼 내용과 그에 따른 디스플레이 결과

Further reading
여러 가지 디스플레이 유형에 대한 자세한 내용은 디스플레이 기술 섹션을 참조하십시오.

프레임버퍼 위치

마이크로컨트롤러 기반의 그래픽 시스템을 크게 단순화하면 다음과 같습니다.

그래픽 시스템 개략도

프레임버퍼는 MCU 내부 또는 외부 RAM에 저장됩니다.

가능한 프레임버퍼 위치

각 위치는 잠재적 장점과 단점이 있습니다.

내부 RAM

프레임버퍼를 MCU 내부 RAM에 저장하면 프레임버퍼에 대한 읽기/쓰기 액세스 속도를 극대화할 수 있습니다. 따라서 TouchGFX 애플리케이션도 최대한 원활하게 실행됩니다. 반대로 내부 RAM은 다수의 시스템 구성요소에서 사용하여 매우 부족한 리소스이기 때문에 프레임버퍼가 많은 용량을 차지하기는 어려울 수 있습니다.

하지만 만약 가능하다면 프레임버퍼를 내부 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)계산메모리 사용량(바이트)
800 x 48016bpp800 480 16 / 8768,000B
480 x 27224bpp480 272 24 / 8391,680B
100 x 1008bpp100 100 8 / 810,000B

프레임버퍼가 다수일 경우에는 사용되는 메모리의 크기도 그만큼 커집니다. 예를 들어 프레임버퍼를 2개 사용하는 이중 버퍼링 기법을 적용하면 사용되는 메모리 크기도 2배로 늘어납니다.

반대로 프레임버퍼를 1개 미만으로 사용하는 경우에는 애플리케이션에서 메모리 크기를 명시적으로 할당하고 제어합니다. 따라서 메모리 사용량을 전적으로 맞춤 설정할 수 있지만 너무 적게 사용하면 그래픽의 전반적인 성능이 느려질 수 있습니다.

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

StrategyAdvantagesDrawbacksUse Cases
DoubleNo risk of tearing, optimal time for renderingRAM for 2 framebuffersHigh performance UIs
SingleOnly RAM for 1 framebufferRisk of tearing, suboptimal time for renderingHigh - Moderate performance UIs
PartialOnly RAM for less than a framebufferHigher risk of tearing, higher CPU loadModerate - Low performance UIs

Displays with GRAM

StrategyAdvantagesDrawbacksUse Cases
DoubleNo risk of tearing, optimal time for renderingRAM for 2 framebuffersHigh performance UIs
SingleOnly RAM for 1 framebuffer, no risk of tearingSuboptimal time for renderingHigh - Moderate performance UIs
PartialOnly RAM for less than a framebufferRisk of tearingModerate - 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
The above examples are not definitive. Keep in mind that the UI performance depend on your hardware and UI design.

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.

Double Buffering Strategy Concept

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.

Single Buffering Strategy Concept

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.

Partial Buffering Strategy Concept

Note
This strategy is only available on MCUs with a STM32 Chrom-GRC (GFXMMU)

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.

Double Buffering Strategy Concept

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.

Single Buffering Strategy Concept

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.

Partial Buffering Strategy Concept

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
See article Buffering Strategies & Location on how to configure a framebuffer strategy through the TouchGFX Generator.

Displays with GRAM

This display type has a dedicated RAM buffer with the same size as the display, i.e. a full size framebuffer.

Display with GRAM

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.

Display without GRAM

The interfaces for this type of display are:

  • LTDC
  • DSI (Video Mode)

Scenarios demonstrating the use of these interfaces can be found here:

Further reading
The STM32 LTDC display controller document has further details on framebuffers.