Flashメモリの使用量に制限のあるGUIの開発
この記事では、TouchGFXを使用して、Flashメモリの使用量を低く抑えたグラフィカル・ユーザ・インタフェースを開発する方法について説明します。
TouchGFXを使用してコードを生成すると、イメージ、テキスト、フォントなどのアセットはC++ファイルに変換され、その後、プログラミング時にTouchGFXアプリケーション・コード、ユーザ・コード、TouchGFXライブラリとともにFlashメモリに格納されます。 これはつまり、多くのアセットを使用する大規模または複雑なプロジェクトでは、Flashメモリの使用量が多くなることを意味します。
ほとんどのアプリケーションではメモリ・リソースに限りがあるため、必要なFlashメモリの量を低減する方法が用意されています。 TouchGFXは、アプリケーションに必要なFlahメモリ量の大幅な低減を可能にする、次の4つの機能を備えております。 L8画像フォーマット、画像圧縮、スケーラブル・ベクタ・グラフィックス(SVG)およびベクタ・フォントの4つの概念です。
この記事では、この4つの概念を利用してアプリケーションでのFlashメモリのフットプリントを制限する方法を紹介します。 測定はSTM32U5G9J-DK2を使用して実行されましたが、Flashメモリの使用量を節約するこれらの概念は、別のハードウェア・プラットフォームにも適用できます。
Further reading
メモリ管理の詳細については、[メモリ使用量](/basic-concepts/memory-usage.mdx)の記事を参照してください。
Flashメモリ使用量が制限されたEバイク・デモ
Flashメモリ使用量が制限されたEバイク・デモは、TouchGFX Designerに用意されており、4つの機能を使用してTouchGFXでFlashメモリ使用量を節約する方法を紹介しています。 このデモは、STM32U5G9J-DK2のボード専用のデモです。 STM32U5G9J-DK2を使用するメリットは、ベクタ・レンダリングのハードウェア・アクセラレーションを可能にするNeoChromVG GPUを搭載していることです。 ただし、L8画像フォーマットと画像圧縮は特に、あらゆるSTM32マイクロコントローラで使用できます。
デモが非圧縮のビットマップのみ(L8、圧縮、SVGおよびベクタ・フォントなし)で実装される場合は、約10.5 MBのFlashメモリが使用されます。 Flashメモリの使用量を節約するこの4つの概念が使用されるデモの実行では、使用されるFlashメモリは約800 KBのみです。 ここからわかるように、Flashメモリの使用量を十分節約できます。 このデモでは、4つの概念を組み合わせて使用した場合、92%というFlashメモリ使用量の節約を達成しています。
いつどの概念を使用するか
4つのFlashメモリを節約する概念を、TouchGFXで使用する方法の技術情報およびガイドについては、以下を参照してください。
この4つの概念はすべて、アプリケーションで必要なFlashメモリ量を低減するのに役立ちます。 いつどの概念を使用するのかはシナリオに応じて異なりますが、いくつかの一般的なルールを適用できます。 これらのルールについて以下に説明します。
L8および画像圧縮
ビットマップでL8画像フォーマットを使用する場合、ビットマップでは最大256色使用できます。 L8フォーマットの画像のレンダリングは、Chrom-ARTによってハードウェア・アクセラレーションされます。つまり、L8ビットマップの描画時間は通常のビットマップとほぼ同じになります。 場合によっては、Flashメモリから読み取るデータ量が少ないため、通常のビットマップと比べてL8フォーマットでのビットマップの描画が速くなることもあります。 色深度が32bitの場合、L8では、通常のビットマップと比べてFlashメモリの使用量を70%以上節約できます。
画像圧縮すれば、L8と比べてさらに多くのFlashメモリを節約できます。 画像圧縮は2つのフォーマット、L8圧縮とRGB圧縮で行われます。 ビットマップでL8圧縮を使用するには、L8圧縮アルゴリズムでカラー・ルックアップ・テーブルが使用されるため、まずビットマップをL8フォーマットにする必要があります。 その結果、L8圧縮されたビットマップは、依然として最大256色に制限されています。 一部のL8圧縮アルゴリズムでは、最大色数がさらに制限されます。 L4は最大16色に、L8 RLEは最大64色に制限されています。 RGB圧縮は、ビットマップをL8フォーマットにする必要がないため、すべてのビットマップで使用できます。 Chrom-ARTでハードウェア・アクセラレーションされるL8ビットマップのレンダリングに対し、圧縮ビットマップ(L8圧縮とRGB圧縮の両方)はソフトウェア・レンダリングされるため、描画時間が長くなります。 圧縮ビットマップのもう1つの制限は、スケーラブルなウィジェットや回転可能なウィジェットで使用できないことです。
PNGフォーマットのアセットがすでにある場合は、L8画像フォーマットと画像圧縮の両方を簡単に使用できます。 通常は、著しいパフォーマンス上のペナルティなしに、最大256色のビットマップでL8画像フォーマットを使用できます。 より多くのFlashメモリを節約する必要があり、必要なパフォーマンスを達成するための描画時間を確保できる場合は、L8画像圧縮も使用できます。 L8フォーマットに対応していないビットマップを圧縮する場合は、代わりにRGB圧縮を使用できます。 ビットマップをスケーラブルまたは回転可能なウィジェットで使用する必要がある場合は、そもそも圧縮ビットマップを使用することはできません。 もちろん、これに対処する方法はいくつかありますが、それについては後ほど説明します。
SVG
アセットでFlashメモリを節約するもう1つのオプションは、アセットをPNGフォーマットではなくSVGフォーマットにすることです。 SVGには、色数の制限はありません。 ただし、SVGは通常、L8や圧縮と比べて描画時間が長くかかります。 したがって、同時使用のSVGの数を制限し、SVGのアニメーションを最小限にしておくことを推奨します。 SVGアセットがシンプルになるほど、その結果、Flashメモリのフットプリントがより小さくなり、パフォーマンスを向上できます。 そのため、1レイヤのSVGのみを使用することを推奨します。
SVGウィジェットでアセットを使用するには、アセットをSVGフォーマットでインポートする必要があります。 その画像はTouchGFXでは変換できません。
ベクタ・フォント
SVGフォーマットのフォント以外のアセットについては、ベクタ・フォントもSVGと同じ方法で描画されるため、描画に時間がかかります。 ベクタ・フォントの使用は、通常、大きなフォント・サイズや同じフォントを複数の異なるサイズで使用する場合に有用です。 異なるサイズの同一フォントをベクタで表現する場合は、フォントを1回格納するだけで済みます。 次に必要なのは、さまざまなサイズで表現するためのスケーリング・ファクタのみです。 ビットマップ・フォントでは、各フォント・サイズをそれぞれ格納する必要があります。 ベクタ・フォントは、画像圧縮やSVGほどFlashメモリを大量に節約できないことがよくあります。 したがって、これは、Flashメモリのフットプリントを絶対的に最小にする必要がある場合に、主に使用します。
例
各種概念の特徴を示す具体的な例を提供するために、通常のビットマップ、L8、L8 RLE圧縮、RGB圧縮およびSVGフォーマットでのEバイク・デモから、2つのアセットで測定を行います。 測定は、内部Flashメモリのアセットを使用してSTM32U5G9J-DK2で実行します。 SVGの描画時間は、NeoChrom GPUを搭載していないマイクロコントローラの場合は長くなります。 ただし、CPUが高速だと、これを補うこともできます。
以下のアセットの色深度は32bitで、上面にアイコンが付いたボタンです。 このボタンは122 x 112ピクセル、アイコンは72 x 72ピクセルです。
このアセットでは次の測定が実行されました。
フォーマット | サイズ | パーセント | 描画時間 | CPU負荷 |
---|---|---|---|---|
ビットマップ: | 75.4 KB | 100% | 0.414 ms | 2.4% |
L8: | 19.3 KB | 25.6% | 0.448 ms | 2.3% |
L8 RLE: | 2.55 KB | 3.4% | 1.51 ms | 9.6% |
RGB: | 4.53 KB | 12.0% | 1.65 ms | 10.5% |
SVG: | 3.01 KB | 4.0% | 1.43 ms | 4.1% |
ここからわかるように、L8 RLEはFlashメモリのフットプリントが最も小さいものの、通常のビットマップ・フォーマットと比べて描画時間が約1 ms長くかかります。
次のアセットは、色深度が32bitで、デモのダッシュボード画面のゲージの一部です。 サイズは150 x 436ピクセルです。
このアセットでは次の測定が実行されました。
フォーマット | サイズ | パーセント | 描画時間 | CPU負荷 |
---|---|---|---|---|
ビットマップ: | 261.6 KB | 100% | 1.15 ms | 1.5% |
L8: | 65.6 KB | 25.1% | 1.24 ms | 1.4% |
L8 RLE: | 4.66 KB | 1.78% | 2.75 ms | 15.0% |
RGB: | 10.5 KB | 4.01% | 3.08 ms | 17.6% |
SVG: | 0.686 KB | 0.27% | 3.40 ms | 2.0% |
SVGフォーマットのアセットでは、Flashメモリのフットプリントは断然少ないですが、描画時間は最長です。
まとめ
上記からわかるように、すべてのアセットに対して最適なフォーマットはありません。 ただし、Flashメモリの節約のみに絞ると、アセットが比較的小さい場合には、通常、L8画像圧縮のFlashメモリのフットプリントが最小になります。また、アセットが大きい場合には、SVGのFlashメモリのフットプリントが最小になります。 SVGアセットで256色を超えて使用できる場合でも、Flashメモリの使用量とパフォーマンスの両方を考慮して、SVGアセットを比較的シンプルにしておくことを推奨します。 L8画像フォーマットの場合、L8、画像圧縮、SVGの中でFlashメモリのフットプリントは最大ですが、描画時間は最短です。
したがって、Flashメモリの使用量が制限されたアプリケーションを開発する場合、ボトルネックを特定し、アプリケーションにとって何が最重要なのかを判断する必要があります。 最も重要なのはパフォーマンスですか、Flashメモリの節約ですか? パフォーマンスが最重要な場合は、L8が最も効率的なアプローチです。 パフォーマンスが許されるなら、一部のアセットに対して圧縮も組み合わせることができます。 Flashメモリのフットプリントを最小にすることが最重要な場合は、画像圧縮とSVGが最適なアプローチになります。
「スマート」アセットの使用
「スマート」アセットを使用すると、Flashメモリの節約とパフォーマンスの両方を改善できます。 ここでは、スマート・アセットとは、アセット自体とその使用の両方を指します。
シンプルなアセット
まず、アセットがシンプルであるほど、より多くの圧縮が可能になり、SVG定義もシンプルになります。 これにより、結果としてFlashメモリのフットプリントがより小さくなります。
参考として、Eバイク・デモでは、すべてのビットマップ・アセットは最大で64色を使用し、またアセットはL8 RLEにも適しているため、すべてのビットマップ・アセットはL8 RLE圧縮されます。 L8 RLEはL8 LZW9と比べて描画時間が短いため、パフォーマンスも最高になります。
さらに、設計もシンプルな場合は、タイル化画像も使用できることがあります。 その場合、画像の一部を格納するだけで済み、その後その画像を繰り返すことができます。
ボックスの使用
スマートな方法でFlashメモリの使用量を節約するもう1つの手法は、ボックス・ウィジェットを使用するものです。 ボックスの使用には、次の2つの主なメリットがあります。
- 1つ目は、ボックスがフレームバッファに直接描画されることです。 その結果、ボックスの格納にFlashメモリは必要ありません。 Flashメモリを必要とするのは、ボックスの定義に必要な少量のコードだけです。
- 2つ目に、ボックスは調整可能で、実行時に色やサイズを変更できます。 Flashメモリの使用量が制限されたEバイク・デモでは、たとえば、ボックスは塗りつぶしのバックグラウンド・カラーに使用され、ボックスの色を変更することでライト / ダークの両モードに対応しています。
再利用可能なアセット
Flashメモリを節約するためのもう1つの方法は、アセットの総数を制限することです。 これはもちろん、設計を非常にシンプルにすることによって実現できますが、同じアセットを複数回再利用することで、既存のアセットの数を制限することでも可能な場合があります。
Flashメモリの使用量が制限されたEバイク・デモでは、たとえば、このアプローチは天候画面に使用されています。 3つのサイズの天気アイコンは、すべて同一のアセットを使用してスケールされています。 スケールされるアセットなので、FlashメモリのフットプリントがRLE圧縮を適用することで小さくすることができる場合でも、SVGフォーマットが圧縮よりも推奨されます。 ただし、アセットが3つのサイズすべてでRLEフォーマットで格納されている場合には、合計のFlashメモリのフットプリントは大きくなります。
さらに、ボタンも再利用可能アセットとして実装されます。 たとえば、ボタンは再利用できるように、アイコンから分離されます。
デモで再利用性を示しているもう1つのケースは、バックグラウンドです。 デモには合計5つの異なるバックグラウンド・デザインがありますが、調整可能なアセット(ボックスと再利用可能アセット)を使用することにより、すべてのバックグラウンドが1つのアセットとボックスだけで作成されています。
パフォーマンスの向上
Flashメモリの使用量が制限されたアプリケーションを開発する場合には、パフォーマンスが阻害されるリスクがあります。 ただし、スペアRAMが利用可能な場合は、アプリケーションのパフォーマンスを向上させる方法があります。 ダイナミック・ビットマップと キャッシュ可能コンテナを使用することにより、アセットまたはコンテナの静的スナップショットをRAMに描画できます。 その後、このアセットやコンテナを使用する場合には常に、キャッシュされたバージョンを代わりに使用できます。 キャッシュされたバージョンは、RAM内の単なるビットマップですが、描画時間が通常のビットマップと同じであることを意味します。
Flashメモリの使用量が制限されたEバイク・デモでは、キャッシュ可能コンテナを使用して、優れたパフォーマンスを維持しながら、SVGアセットやベクタ・フォントのスクロールを可能にしています。
通常、ベクタ・フォントは、実行時に移動した場合または移動可能な場合、常にキャッシュされます。 これにより、ベクタ・フォントのスクロールに関係なく、30 FPS以上が保証されます。
デモで使用されているもう1つの技は、圧縮ビットマップのビットマップ・キャッシュへの解凍です。 ビットマップをRAMに解凍することにより、スケーラブルなウィジェットや回転可能なウィジェットで使用できます。 ビットマップを解凍すると、TouchGFXでは、ビットマップIDを参照する際に、常に解凍したキャッシュ・バージョンが使用されるようになります。 Eバイク・デモでの例を以下に示します。 圧縮ビットマップは単純に解凍され、その後は、このビットマップを通常のビットマップとして使用できるようになります。
StartView.cpp
StartView::StartView()
{
Bitmap::decompress(BITMAP_MAIN_RIPPLE_LEFT_ID); // Decompress compressed image to bitmap cache
Bitmap::decompress(BITMAP_MAIN_RIPPLE_RIGHT_ID); // Decompress compressed image to bitmap cache
}
void StartView::setupScreen()
{
leftMainRippleScale.setBitmap(BITMAP_MAIN_RIPPLE_LEFT_ID); // Set bitmap for Scalable Image
rightMainRippleScale.setBitmap(BITMAP_MAIN_RIPPLE_RIGHT_ID); // Set bitmap for Scalable Image
leftMainRippleScale.setWidthHeight(0, 0); // Set scale of image
rightMainRippleScale.setWidthHeight(0, 0); // Set scale of image
}
ダイナミック・ビットマップを多用した結果、Flashメモリの使用量が制限されたこのEバイク・デモでも、922 KBのビットマップ・キャッシュが必要です。 つまり、大量のスペアRAMが必要です。 ただし、このデモでは、Flashメモリをかなり極端に節約してもいます。 よりシンプルなアプリケーションやパフォーマンス要件がそれほど重要でないアプリケーションでは、はるかに少ないビットマップ・キャッシュで済む可能性があります。
Further reading
[ダイナミック・ビットマップ](/development/ui-development/touchgfx-engine-features/dynamic-bitmaps.mdx)
[キャッシュ可能コンテナによるパフォーマンス向上](/development/ui-development/scenarios/achieving-better-performance-with-cacheable-container.mdx)
[ビットマップ・キャッシュへの画像の解凍](/development/ui-development/touchgfx-engine-features/image-compression.mdx)
まとめ
この記事では、TouchGFXアプリケーションのFlashメモリの使用量を制限する方法について説明してきました。
4つのFlashメモリ使用量節約の概念を、すべてのSTM32ハードウェア・プラットフォームに対して使用できますが、SVGとベクタ・フォントでは描画時間が長くなることに留意してください。 その結果、ベクタ・レンダリングのハードウェア・アクセラレーションや追加の計算能力が利用できない場合には、パフォーマンスが低下する可能性があります。
Flashメモリの使用量が制限されたGUIの開発におけるこの概念は、パフォーマンス上のペナルティにつながる可能性がありますが、ダイナミック・ビットマップやキャッシュ可能コンテナを使用することで、パフォーマンスを向上させることができます。
Flashメモリ節約のこれらの概念を使用することにより、Flashメモリの節約に大きな可能性がもたらされます。 これらの概念が節約できるFlashメモリの正確な量は、個々のアプリケーションに応じて異なりますが、Flashメモリの使用量が制限されたEバイク・デモでは、92%というFlashメモリ使用量の節約を達成しています。