Delphi 13 で TBitmap.Map の取り扱いが変わりました
Delphi 12 までは、TBitmap.Canvas.BeginScene のブロック内で TBitmap.Map を呼び出しても問題ありませんでした。
しかし Delphi 13 の iOS では仕様が変わり、BeginScene の中で Map を呼ぶとクラッシュしてしまいます。
Windows / macOS/ Android では、今まで通り BeginScene ブロック内で Map を呼んでも問題ありません。
実際にアプリを作っていて気づいた変更点を整理しておきます。
Delphi12
Bitmap.Canvas.BeginScene;
try
var Data: TBitmapData;
// ↓↓↓ ここ
Bitmap.Map(TMapAccess.ReadWrite, Data);
try
// Data の読み書き
// Canvas に対する描画命令も両立できた
finally
Bitmap.Unmap(Data);
end;
finally
Bitmap.Canvas.EndScene;
end;
Canvas 描画と BitmapData アクセスを、1 つの BeginScene ブロックにまとめられました。
Delphi 13
Delphi 13 の iOS では、Canvas のロック (BeginScene) と BitmapData のロック (Map) を 同時に保持することが禁止 されたようです。
そのため、以下のように 処理を分離 する必要があります。
// Canvas の操作は BeginScene 内
Bitmap.Canvas.BeginScene;
try
// DrawLine / DrawRect / FillRect など
finally
Bitmap.Canvas.EndScene;
end;
// BitmapData の操作は BeginScene の外で
var Data: TBitmapData;
Bitmap.Map(TMapAccess.ReadWrite, Data);
try
// Data の読み書きはこちら
finally
Bitmap.Unmap(Data);
end;
Canvas と BitmapData の並行作業ができなくなったため、
「描画しつつ、同じタイミングで Data を直接いじる」というコードは書けません。
TBitmap.Clear に注意!!
TBitmap.Clear は内部で Map を呼ぶため、BeginScene の外で呼ばないとクラッシュします!
サンプルコードで BeginScene 内に Clear が書かれているケースがあり、移行時の落とし穴になりそうです。
なお、この仕様変更はこちらの記事のアプリ作成中に遭遇しました。
さいごに
Display Link に対応したことで、内部が色々変わっている感じがします。
コミュニティ紹介
Delphi のコミュニティを紹介します。
Delphi Discord Server(最も活発)
Delphi に関する質問・最新情報・雑談など、とにかく情報が早いコミュニティです。
お気軽に参加できます。
Delphi Discord Server 紹介ページ
※こちらは招待リンクそのものではありません。招待リンクは遷移先ページにあります。
その他のコミュニティ
Qiita のこちらの記事に、日本語圏で参加しやすいコミュニティをまとめています。