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

パフォーマンス

このセクションでは、組込みグラフィカル・ユーザ・インタフェースのパフォーマンスについて説明します。

ここでの高パフォーマンスとは、必要なグラフィカル効果とアニメーションも実現しながら、高いフレーム・レートを達成できている状態として定義されます。

前のセクションで説明した、ユーザ・インタフェースのフレーム・レートがメイン・ループから受ける影響について思い出してみましょう。今回も、パラレルRGBディスプレイがLTDCおよび2つのフレームバッファと接続されていると仮定します。基本的な状況は以下のとおりです。

ダブル・フレームバッファ

ディスプレイは、毎秒60回リフレッシュされると想定されるので、各リフレッシュ間隔はおよそ16 msです。 The calculation is this:

1 s / 60 = 0.01667 s = 16.67 ms.

TouchGFXは、フレームバッファ1の転送が開始した時点で、フレーム1をフレームバッファ2に描画することを開始します。次の転送が開始される前に、フレーム1の描画が終了すれば、フレームバッファ2を転送することができます。 16.67 ms以内に描画が終了しない場合、フレームバッファ1が再度転送されるので、ディスプレイの表示は変わりません。

メイン・ループの時間が16.67 msを超える場合

この状況はロスト・フレームと呼ばれます。

The time for the collect and update phases are typically minuscule, e.g. less than 1 ms, and therefore more or less negligible when considering the overall time taken of the main loop. したがって、以下の説明でも一般的にも、描画時間を考える際、そこには収集および更新フェーズを含めます。

多くのフレームの描画時間が16.67 msの制限を超える場合、ディスプレイのフレーム・レートは毎秒30フレーム(30 fps)になります。

描画時間が全般的に16.67 msを下回るものの、一部のフレームで16.67 msよりも長くかかる場合は、平均フレーム・レートは60 fpsに近づくことになりますが、アニメーションがユーザに滑らかに表示されない可能性があります。アプリケーションによっては、アニメーションのステップの一部が速く表示されたり、遅く表示されたりする可能性もあります。 This is not desirable.

描画時間が長くなる可能性もあります。 If it is just above 33 ms, the frame rate will drop to 20 fps as we only have a new frame ready on every third transfer.

FPS最大描画時間
6016.67 ms
3033.34 ms
2050.00 ms
1566.67 ms

The table shows the maximum rendering time (including the collect and update phases) that is available for a given frame rate.

ユーザ・インタフェースの最適なパフォーマンスを実現するには、フレーム・レートを定期的にチェックして監視することが非常に有益であると思われます。次の2つのアプローチを利用できます。

  • 描画時間の測定
  • ロスト・フレームのカウント

描画時間の測定​

描画時間を測定するという最初のアプローチは、最も詳細な情報をもたらします。基本的な考え方は、フレーム転送から描画フェーズ終了までの時間を測定することです。グラフィック・エンジンは収集フェーズの開始時にGPIOクラスの関数を呼び出し、描画フェーズの終了時に別の関数を呼び出すようにします。 The application defines these functions and can hook into them to perform measurements.

測定は以下の2つの方法で実行できます。

  • Use an external timing device like an oscilloscope: To measure using an oscilloscope, the application should implement the set(GPIO_ID) and clear(GPIO_ID) methods from the GPIO interface. これでオシロスコープは、描画時間を出力がハイのときの経過時間として測定できます。
  • 内部タイマを使用: もう1つのアプローチでは、sysTickタイマなどの内部タイマを使用します。 GPIO::set(RENDER_TIME)が呼び出されると、アプリケーションはタイマの値をある変数に保存できます。クリア・コールが行われると、アプリケーションは再度タイマを読み取り、前の値を差し引いて描画時間を取得できます。タイマの速度によって測定の解像度が決まります。アプリケーションは、何らかの方法で描画時間を表示する必要があります。 1つの方法として、値をグローバル変数に保存し、その値をスクリーン上のテキスト・エリアに表示することが考えられます。この値はデバッガでチェックすることもできます。

ロスト・フレームのカウント​

グラフィック・エンジンは、直前の収集-更新-描画フェーズで発生した転送の回数をカウントします。アプリケーションはこの値をチェックして、フレームが失われてフレーム・レートが低下していないかどうか、簡単に確認することができます。

カウントはHALクラスで利用できます。

void handleTickEvent() {
tickCounter += 1;
if (HAL::getInstance()->getLCDRefreshCount() > 1) {
//Alert programmer somehow
...
}
}

ロスト・フレームの補正​

When frames are lost and the frame rate of one of our animations therefore lowered we can compensate to a certain degree. 以下のいずれかを実行します。

  • 待ち続ける - アニメーションをそのまま続けます。アニメーションの時間が長引き、スムーズでなくなる可能性もあります。
  • skip some frames - make sure that the overall animation does not take more time than intended by skipping frames.

TouchGFX can be instructed to automatically skip some frames, when frames are lost. このためには、実際のフレームあたり複数回アニメーションをティックします。これにより、描画時間が不均等な場合でも、アニメーションをより滑らかにできます。

HAL.hpp
void setFrameRateCompensation(bool enabled)

描画時間への影響要因​

描画時間には多様な要因が影響します。更新部分のサイズ、レイヤ化の利用、ウィジェットの複雑さ、描画をサポートするハードウェアなどです。

更新されるスクリーンの量​

描画時間は一般に、更新の必要があるピクセル数に比例します。つまり、アニメーションの描画に時間がかかりすぎている場合、考えられる修正はアニメーションの領域を減らすことです。たとえば、回転する画像があり、パフォーマンスが十分でない場合、その画像のサイズを小さくすることでパフォーマンスを向上させることができます。

画像サイズを小さくすることで描画時間を短縮

グラフィック・エンジンは、アプリケーションが無効化した領域を再描画することを思い出してください。 This means that it is important to only invalidate the areas that actually require a refresh.

無効化領域が大きいほど、描画時間が長くなります。

グラフィックス内のレイヤ数​

一般的なアプリケーションでは、グラフィックスは互いに積み重なるさまざまな要素で構成されます。要素のいずれかが更新されると、通常はすべての要素を再描画する必要があります。

この代表的な例がバックグラウンド画像、フレーム、いくつかのテキストです。

グラフィック要素のレイヤ化

このユーザ・インタフェースは、透明なフレームを表示するImageウィジェットの上にTextAreaウィジェットを配置しています。どちらもバックグラウンド画像上にあります。

TouchGFX Designerでのグラフィック要素のレイヤ化

This solution is used very often in applications. これは実は柔軟性の高い非常に容易なソリューションで、たとえば、実行時にフレームを変更したり、バックグラウンド上でフレームやテキストを移動したりできます。

描画時間に関する問題は、実行時にテキストが更新され、再描画の必要が生じた場合、グラフィック・エンジンはバックグラウンドとフレームも再描画し、それから新しいテキストを再描画する必要があることです。このためにテキストの描画時間が大幅に増大します。

無効化領域内のレイヤが多いほど、描画時間が長くなります。

ピクセル描画の複雑さ​

フレームバッファへの描画の難しさは、すべてのピクセルで同じわけではありません。どのタイプの描画でも、グラフィック・エンジンは計算結果のピクセルをフレームバッファに書き込む必要があります。しかし、書き込むピクセルの計算時間はさまざまです。

Boxウィジェットなどで使用される固定の色の計算時間は低くなります。ピクセルの計算は一度だけ行われ、すべてのピクセルに再利用されるからです。つまり、多数のボックスを使用すると、パフォーマンスは非常に高くなります。ただし、高品質のユーザ・インタフェースにならないので、この方法は推奨されません。

ピクセルの計算時間が次に低いのは画像です。ピクセルがすぐに使用可能なフォーマットでビットマップに保存されているからです。フレームバッファに書き込むピクセルの計算で問題になるのは、色の値をビットマップ内の正しい位置から読み込むことです。

テキストは画像よりも時間がかかります。個々の文字が実際には小さな画像として表現されているからです。実際のところ、時間がかかるようになるのは、多数の小さな画像があるために「開始-停止」の時間が大幅に増えるためです。たとえば、個々の文字位置の計算があります。テキストの見栄えをできる限りよくするために、テキストは透明性のある小さな画像で表現されます。透明度に関する下の注を参照してください。

回転画像や拡大画像は上記よりも時間がかかります。ここでのタスクはビットマップからピクセル値を再び読み込むことですが、こちらの計算の方が時間がかかります。グラフィック・エンジンが画像のスケーリングや回転を組み込む必要があるからです。

円などの幾何学的要素はさらに時間がかかります。今度はピクセルの色をビットマップから読み込むことができず、円の形状と、円の中の個々のピクセルの色を計算する必要があるからです。

透明度は要素の描画時間を増やします。一部のピクセルが塗りつぶされていない場合、要素は透明になります。このことが描画時間を増大させます。グラフィック・エンジンは最初に、透明な要素の背後にある要素を描画する必要があるからです(「フレーム内のテキスト」に関するセクションを参照)。次にグラフィック・エンジンは、バックグラウンドのピクセルと透明な要素のピクセルを結合させ、結果をフレームバッファに書き込む必要があります。計算済みのピクセルをただ書き込むよりも、この計算にははるかに時間がかかります。

ボックス、画像、回転画像、円。上の行は塗りつぶしの要素。下の行は透明な要素。

透明度を持たせると、常に余分なレイヤが必要になります。ただし、塗りつぶしのピクセルを他の塗りつぶしピクセルの上に配置しても、必ずしもレイヤの数が増えるわけではありません。 The graphical engine tries not to draw pixels that are covered by other solid pixels, as this would be a waste of precious time.

無効化領域内に時間がかかる要素が多いほど、描画時間が長くなります。

Remember that it is only the elements that are part of the invalidated area that add to the rendering time. 無効化領域以外にある要素は、描画時間に影響を及ぼしません。

UIコンポーネントとパフォーマンスの詳細については、こちらを参照してください。

描画をサポートするハードウェア​

Some STM32 microcontrollers contain graphical accelerators. These accelerators can reduce rendering time, as the accelerators can run in parallel with the microcontroller core. The core will then be able to run other tasks, while the accelerators render graphics.

The accelerators are automatically used by TouchGFX when available.

描画時間を考慮する必要がある場合​

描画時間は、いつも同じように重要なわけではありません。低速なフレーム・レートがユーザの目に触れるようになった場合には、描画時間に注意を払う必要があります。通常これは、スクリーンの一部でアニメーション(回転アイコンなど)を実行している場合や、スクリーン上で何かを移動またはスライドさせている場合などです。更新頻度が低くなると、ユーザへの表示が滑らかでなくなり、段階的に表示されます。こうした場合には、描画時間をチェックする必要があります。

一方で、スクリーン全体を新しいスクリーンに置き換える場合、変更中にフレーム・レートが大幅に低下しても、通常そのことはユーザにはわかりません。ユーザは描画の開始時がわからず、終了時のみがわかるからです。

上記の2つのルールは、(移動などの)アニメーション化する要素には、わずかなレイヤを使用して、複雑な要素や多数のレイヤの使用を控える必要があることを意味しています。スクリーンの他のパーツでは、このことは問題ではないと思われます。

アナログ・クロックとスクロール・リスト

この例では、左側にアナログ・クロックがあります。時計の3本の針は、回転する小さく細長い画像によって描画されています。針は常に動いているわけではないので、通常はこれで大丈夫です。しかし、スクリーン上でクロックが動き回るようにする場合は、すべてのフレームで再描画することになり、問題が生じる可能性があります。回転画像の描画は、典型的に時間がかかるからです。

右側にはスクロール・リストがあります。 The user can move this list of numbers up and down, so we need a high frame rate for the user interface to appear responsive. このため、スクロール・リスト内の要素の描画時間を考慮するか、スクロール・リストのサイズを小さくすることが重要になります。

コンテンツの無効化によるパフォーマンスの最適化​

通常はウィジェット全体が無効化されますが、グラフィック・エンジンには、ウィジェット全体ではなく、ウィジェットのコンテンツのみを無効化する機能があります。無効化する領域を減らすことで、描画時間が明らかに短縮されることがよくあります。描画時間の改善は以下によって異なります。

  • ウィジェット全体のサイズに対して、そのウィジェットのコンテンツがカバーする領域のサイズの割合
  • そのウィジェットがバックグラウンドのウィジェットを一部カバーするのか、完全にカバーするのか

The following figures illustrate the concept of invalidating content, by using the TextArea widget as an example. 図1は、ウィジェット全体の領域を示しています。図2は、TextArea::invalidate()を使用したときに無効化される領域を示しています。図3は、TextArea::invalidateContent()を使用したときに無効化される領域を示しています。

図1: スクリーンの幅全体に広がるTextArea

図2: TextArea::invalidate()を使用したときの無効化領域(赤色)

図3: TextArea::invalidateContent()を使用したときの無効化領域(緑色)

TextArea::invalidateContent()を使用する例​

ウィジェットが他のウィジェットにオーバーラップしている場合、TextArea::invalidate()を使用してTextArea全体を無効化すると、こうした他のウィジェットを再描画する必要があります。代わりにTextArea::invalidateContent()を使用することで、ウィジェットの不要な無効化や再描画のリスクを最小限に抑えることができます。これは、CircleやGaugeなど、描画コストのかかるウィジェットの場合は特に当てはまります。

次の図は、TextArea::invalidateContent()を使用して、バックグラウンドのウィジェット(画像- STロゴ)の無効化を避ける方法を示しています。 TextArea::invalidate()を使用していれば、バックグラウンドのウィジェットは無効化され再描画の必要がありました。

TextArea::invalidateContent()を使用する例

最適なパフォーマンスを得るためのヒント​

このセクションの最後に、最適なパフォーマンスを得るためのヒントをまとめます。

  • 変更ないものを再描画しない: ディスプレイの不必要なパーツを誤って無効化しないようにしてください。パフォーマンスが低下し、何もいいことはありません。
  • 品質と速度のバランスを見いだす: 要素の複雑さを軽減することで、パフォーマンスを向上できます。複雑さとパフォーマンスとの適切なバランスが、鍵となることは多くあります。
  • Utilize hardware capabilities The capability of a microcontroller with hardware acceleration is often higher than a microcontroller without. Consider using a microcontroller with hardware acceleration.
  • 計算されたグラフィックスを画像に置き換える: 円を計算して描くことは、円の画像を使用するよりも低速です。一般に、画像は多くの静的要素と置換できます。
  • ディスプレイのリフレッシュ・レートを調整する: このセクションの最初で説明したように、リフレッシュ・レートは描画時間に対して厳しい制限になります。描画時間がリフレッシュ・レートを超えると、フレーム・レートが低下します。描画時間がリフレッシュ・レートを少しだけ上回る場合は、ディスプレイのリフレッシュ・レートを、たとえば55 Hz(18.2 msに対応)まで下げて、高いフレーム・レートを維持することができるかもしれません。

Framebuffer strategies​

The Partial Framebuffer, Emulated Framebuffer, and Hybrid Double Buffer strategies render updated graphics in small slices. To keep rendering time low, reduce the use of widgets that are expensive to draw in multiple small areas, such as TextArea with automatic line wrapping, Circle, Video, and SVGs.
Widgets such as Box, image based Widgets, and TextureMapper have very little overhead in this rendering pattern.

For the Emulated framebuffer strategy it is important to have an even load. It is adviced to separate expensive elements.

グラフィック・アクセラレータ​

高いパフォーマンスを実現するための一般的な方法として、グラフィック・アクセラレータを搭載したSTM32マイクロコントローラを使用します。 The STM32 MCU family mainly uses two graphics accelerators: Chrom-ART and NeoChrom GPU. Chrom-ART is also called DMA2D, and NeoChrom GPU is also called GPU2D.

The Chrom-ART accelerator is capable of copying and blending images between the image storage and the frame buffer. NeoChrom GPU can do the same, but is also capable of texture mapping and vector graphics.

Chrom-ART comes in three versions. The first version of Chrom-ART is capable of copying and blending. The second version is also capable of converting YCbCr data to RGB. これによりJPEGデコーディングのパフォーマンスが向上します。 The third version is called Chrom-ART2 (DMA2D3) and is command-list based, supports more image formats, and is capable of down-scaling with nearest-neighbor.

Compared to Chrom-ART, NeoChrom GPU is capable of accelerating more graphical operations and has a richer feature set.

NeoChrom GPU comes in two versions: NeoChrom GPU and NeoChromVG GPU. NeoChromVG GPU has the same feature set as NeoChrom GPU, but also has full hardware acceleration of vector rendering.

グラフィック機能Chrom-ARTChrom-ART2NeoChrom GPUNeoChromVG GPU
サポート対象フォーマット(TouchGFX使用時)ARGB8888、RGB888、RGB565、A8、A4、L8-888、L8-8888ARGB8888、RGB888、RGB565、A8、A4、A2、A1、L8-565、L8-888、L8-8888ARGB8888、RGB888、RGB565、A8、A4、A2、A1ARGB8888、RGB888、RGB565、A8、A4、A2、A1
コマンドリスト・ベースNoYesYesYes
描画長方形長方形マルチサンプリング・アンチエイリアシング(MSAA)を使用した長方形、ピクセル、ライン、三角形、四辺形マルチサンプリング・アンチエイリアシング(MSAA)を使用した長方形、ピクセル、ライン、三角形、四辺形
ビットマップ転送コピー、アルファブレンディング、ピクセル・フォーマット変換コピー、アルファブレンディング、ピクセル・フォーマット変換コピー、アルファブレンディング、ピクセル・フォーマット変換、カラー・キーイングコピー、アルファブレンディング、ピクセル・フォーマット変換、カラー・キーイング
スケーリングNoYes (down-scaling with nearest neighbor)YesYes
テクスチャ・マッピングNoNoYesYes
ベクタ・グラフィックスNoNoNo*Yes

* Vector Graphics are partially hardware-accelerated with NeoChrom GPU when using TouchGFX. Full hardware acceleration for Vector Graphics is available with NeoChromVG GPU.

利用可能なこれらの機能により、多くのTouchGFXウィジェットが高速化されます。

ウィジェットChrom-ARTChrom-ART2NeoChrom GPUNeoChromVG GPU
Box、BoxWithBorderYesYesYesYes
Image、AnimatedImage、TiledImage、SnapshotWidgetYesYesYesYes
Button、ButtonWithIcon、ButtonWithLabel、ToggleButtonYesYesYesYes
RadioButton、RepeatButtonYesYesYesYes
PixelDataWidgetYesYesYesYes
TextArea、TextAreaWithWildcard、Keyboard一部YesYesYes
ScalableImageNo一部YesYes
TextureMapper、AnimatedTextureMapperNoNoYesYes
Circle, Line, GraphNo*No*No*No*
SVGNo*No*No**Yes

* The drawing/blending of pixels to the framebuffer is done by Chrom-ART or NeoChrom GPU, but the shape calculations are done in software.
** SVG rendering is partially hardware accelerated with NeoChrom GPU and fully accelerated with NeoChromVG GPU.

The operations that are not hardware-accelerated are software-rendered (implying a higher CPU load, and lower performance). As the table above shows, NeoChrom GPU can accelerate widgets like ScalableImage and TextureMapper. つまり、高い性能を維持しながら、これらのウィジェットをより一層使用できるようになります。

NeoChrom使用時のTouchGFXの詳細については、こちらを参照してください。