メイン・コンテンツまでスキップ

フレームバッファ

フレームバッファは1まとまりのメモリで、ディスプレイに次に表示する画像を格納するためにグラフィック・エンジンによって更新されます。

フレームバッファは、所定のサイズの連続したRAMの領域です。

フレームバッファ・メモリ

フレームバッファには関連付けられた幅と高さがあります。 このため、通常フレームバッファは、XY座標によってインデックス付け可能な2次元でアクセスするメモリであると考えられます。

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、または4 bppのグレースケール
  • ハイカラーまたはトゥルーカラー: 16、24、または32 bppカラー

使用するbppの値が大きいほど、フレームバッファで表すことのできる色が明瞭になります。さらに、使用するbppの値が大きいほど、フレームバッファに必要なメモリサイズも大きくなります。

ディスプレイ

フレームバッファのコンテンツは最終的には物理ディスプレイに転送され、そこで表示されます。 このため、通常はフレームバッファとディスプレイのピクセルの幅と高さは同じにします。

24 bppフレームバッファのコンテンツとディスプレイ結果

Further reading
さまざまなディスプレイ・タイプの詳細については、「ディスプレイ・テクノロジ」のセクションを参照してください。

フレームバッファの場所

マイクロコントローラ・ベースのグラフィック・システムを非常に簡略化した図を、次に示します。

グラフィック・システムを非常に簡略化した図

フレームバッファはマイクロコントローラ内部、または外部RAMに配置できます。

フレームバッファを配置可能な場所

配置可能な場所それぞれに、利点と欠点があります。

内部RAM

フレームバッファをマイクロコントローラ内部のRAMに配置すると、フレームバッファの読み書きアクセスが最大限に高速化されます。 つまり、TouchGFXアプリケーションが可能な限りスムーズに実行されます。 その反面、内部RAMは非常に少量のリソースで、システムの多くの部分によって使用されるため、フレームバッファがこの大部分を占有することは現実的ではないと考えられます。

フレームバッファを内部RAMに配置するとことが可能であれば、追加のRAMが必要なくなるので、システム全体のコストを削減することができます。

外部RAM

システムに外部RAMがある場合、フレームバッファを内部RAMの代わりにこの外部RAMに配置できます。 一般的に、外部RAMに対する読み書きアクセスは内部RAMより低速ですが、外部RAMの容量の方が通常は非常に大きくなります。 このため、場合によってはこれが唯一の解決策になります。

マイクロコントローラには、外部RAMへのアクセスを高速化させる機能(キャッシュなど)が備わっていることがあります。 詳細については、「マイクロコントローラ」のセクションを参照してください。

Display with GRAM

Depending on the type of display in the system there might be memory embedded on the display (often called GRAM). このメモリには、ディスプレイの「物理的な」ピクセルの内容が保持されます。 ディスプレイにこのピクセル・メモリがあると、マイクロコントローラがアイドル状態でもディスプレイが動作を続けることができます。

TouchGFXのフレームバッファをディスプレイ内のRAMに配置することは不可能です。ディスプレイのメモリはメモリ・マップドではなく、ランダムなピクセルの読み書きに適するようにできていないからです。 代わりに、TouchGFXはフレームバッファを内部または外部RAMに配置し、これを適切なタイミングでディスプレイのRAMに転送します。

メモリ使用量

フレームバッファの色の量やピクセル数によって、フレームバッファが必要とするメモリサイズが決まります。

一般的に、フレームバッファで使用されるメモリの量は、幅x高さx色深度(ビット)/ 8 バイトになります。

解像度(ピクセル)色(bpp)計算メモリ使用量(バイト)
800x48016 bpp800 x 480 x 16 / 8768,000 B
480x27224 bpp480 x 272 x 24 / 8391,680 B
100x1008 bpp100 x 100 x 8 / 810,000 B

複数のフレームバッファを持つと、それに応じてメモリ使用量も大きくなります。 たとえば、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.