無効領域と遮蔽

Posted 2013.05.03 in 吉里吉里

めざせ60FPS!の記事で、Foooの無効領域処理と遮蔽処理による最適化を紹介したが
この二つの最適化は、実は吉里吉里でも行われている。

無効領域処理

無効領域処理は常に自動的に行われている。
吉里吉里のウィンドウをアクティブにして「Shift+F11キー」を押すと
更新矩形の発生の様子を確認できる。
複数の矩形で管理されているため、期待通り効率的に動作する。

無効領域は描画関数を使ったり、レイヤーの見た目が変化する操作をすると自動的に発生する。
Layer クラスの update 関数で明示的に無効領域を発生させることもできる。
プラグインで新たに描画関数を作る時は、
描画を行った範囲を update 関数を使って無効領域にする必要がある点に注意が必要だ。
そうしないと描画が画面に反映されない。

ちなみに update 関数には少し癖がある。
詳しくは onPaintが二度呼ばれる問題 の記事を参照のこと。

遮蔽処理

吉里吉里が遮蔽処理を行うことはあまり知られていないかもしれない。
遮蔽処理は無効領域処理と違って、常に行われるわけではない。
遮蔽処理が行われるのは、レイヤーが不透明であることが保証される場合だけである。
言い変えるとレイヤーが

type==ltOpaque && opacity==255

の時に遮蔽処理が行われるということだ。
(厳密に言うともうちょっと複雑だが)

遮蔽処理をいつの間にか使っているケース

描画処理を少しでも軽くしようと思案した時まず思いつくのが
背景レイヤーの type を不透明度を考慮するデフォルトのltAlphaではなく、
不透明度を無視する ltOpaque にすることだろう。
背景は常に不透明であり、不透明度が必要ないからだ。

背景レイヤーの face を書き込み先の不透明度を保証しない dfOpaque にすると、
さらに描画の効率化が期待できる。
もっとも face はデフォルトで dfAuto なので、type を ltOpaque にすると
いちいち face を設定しなくても dfOpaque が設定された状態と同じになる。

face が dfOpaque だと ltAdditive のような不透明度を考慮しない高速なレイヤ表示タイプを
子レイヤーに対して使うことができるというメリットもある。

そうこうしてレイヤーの type を ltOpaque にすると…そう
「type==ltOpaque かつ opacity==255」の条件を満たすことで
遮蔽処理が行われるようになる。
遮蔽処理のことを知らなくても自動的にさらに描画が効率化されるというわけだ!

とは言え…視覚的には何も変わらないので、
遮蔽処理が行われている事実はわかりにくいかもしれない。

まとめ

無効領域処理と遮蔽処理の効果は、Foooの動作サンプルを見てもわかる通り絶大である。
その存在を意識することで、より効率的な動作をさせることが可能となるだろう。
積極的に活用していきたいところだ。

が!
………遮蔽処理には大きな問題がいくつか潜んでいる。
そのお話はまた次回~


Leave a Reply

*