本投稿はDelphi Advent Calendar 2022 #10 の記事です。
はじめに
Delphiでかなり大きなBitmapを扱うプログラムを書く機会をいただきました。
最新の機能で書きたいと思い,FMXを利用しようとしたら,TBitmapをSetSizeしただけでエラーで落ちてしまいました。
書いたコードは以下のようなものです。
function hoge;
var
Bitmap:TBitmap;
begin
Bitmap:=TBitmap.Create;
Bitmap.SetSize(10000,10000);
・・・・・
Bitmap.Free;
end;
この関数を実行すると,以下のようなエラーが出ます。
そこで,FMXとVCLの32bitおよび64bitのアプリケーションでTBitmapを使用した際のTBitmapのサイズの制限を調べてみることにしました。
VCLのTBitmap
VCLの TBitmap には PixelFormat というプロパティがあります。
TPixelFormat.pf24bit と TPixelFormat.pf32bit について調査しました。
TPixelFormat.pf24bitは1ピクセル当たり3byte,TPixelFormat.pf32bitは4byteで,アルファ情報を持つことができます。
1つのBitmapが利用する画素数(縦の画素 X 横の画素)にこのバイト数をかけたものにBitmapのヘッダサイズを足したものがBitmapが利用するメモリ量になります。
32bit VCLアプリケーション
32bitアプリケーションの最大メモリサイズは2GBですので。一度に使えるメモリはこれ以下になります。Bitmap以外のメモリの使用量が十分小さければ,1GBを超えるBitmapを利用できました。ただし,同時に多くのBitmapを利用する際には,その合計のメモリ量がアプリケーションの使えるメモリ量を超えないようにすることが必要です。
64bit VCLアプリケーション
64bitアプリケーションでは,1つのBitmapが利用できる最大メモリ量は2GBでした。複数のBitmapを同時に使ってもその制限は変わりませんでした。
しかし,今度はパソコンの空きメモリにより制限されます。空きメモリがメモリ全体の20%くらいまでBitmapを作成することができました。
FMXのTBitmap
FMXでDirect2Dはデフォルトでは利用するモードになっています。Direct2Dを使わない場合はGDI+を使います。
これを切り替えるのに,GlobalUseDirect2D を使います。デフォルトではTrueです。FMX.Types で定義されています。
切り替えるときには,プロジェクトソースに以下のように書きます。
program Project1;
uses
System.StartUpCopy,
FMX.Forms,
FMX.Types, // GlobalUseDirect2D が定義されているUnitを追加
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
begin
GlobalUseDirect2D:=False; // Direct2Dを使わない
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Direct2Dを使う場合
Direct2Dを使う場合のBitmapの最大サイズは,ビデオカードにより決まります。
私のビデオカードではBitmapの縦・横の最大は8192pxでした。1つのBitmapの最大サイズは256MBになります。
32Bitアプリケーションだと8個が理論上の最大数になりますが,それ以上のBitmapを生成することができました。
Direct2Dを使うとGPUがその処理をするためかもしれません。64bitも同様です。
Direct2Dを使わない場合(GDI+の場合)
GDI+の場合,Bitmapの縦・横の最大は65535px($FFFF)でした。1つのBitmapの最大サイズは16GBになります。
32Bitアプリケーションの制限を超えていますが,複数のBitmapを生成できました。64Bitも同様です。
まとめ
VCLの場合メモリサイズの制限がある。
- 32bitアプリでは1つ1GBが目安,複数利用の場合には合計で他のプログラムの使うメモリと合わせて2GBを超えないこと。
- 64bitアプリでは1つ2GB。複数同時利用の場合は空きメモリにより変化する。
FMXの場合縦横サイズの制限がある。
- Direct2Dを使う場合,8192px。ただしビデオカードによりこのサイズは変動する。複数同時利用しても変化なし。
- GDI+を使う場合,65535px。複数同時利用しても変化なし。
謝辞(引用元および参考文献)
以下のリンクが参考になりました。
貴重な情報を提供してくださった皆様,ありがとうございます。感謝します。