昨日、Starling2.0がついにリリースされました。
ベータ公開からたくさんのフィードバックを得て、バグフィックとさらなるパフォーマンスチューニングが行われ、その流れで1つ大きな新機能が追加されたので、これをレポートしてみます。
無駄な描画更新を行わない
AIR+Starling1.xで作成されたコンテンツは電力消費が大きいという短所がありました。これはStage3Dレイヤーでは毎フレーム画面全体を書き直す事からなのですが、全く画面更新のない際も再描画が行われていて無駄な電力消費となっていました。
2.0の正式リリースとともに追加されたStarlng.skipUnchangedFramesというプロパティをtrueにする事でこの無駄な描画更新停止させる事ができるようになりました。デフォルトではfalse設定ですが(理由は後述)積極的にtrueにして使う事が公式に推奨されています。
公式ブログにある描画負荷の比較図
Starling1.xではflattenという命令で大きさ・回転・位置などで変更がないディスプレイリストの描画更新を行わない機能がありましたが、変更があるかないかはユーザ側で判断し、手動でflattenを呼び出したり、unflattenでそれを解除する事が必要で、一定の効果はあるもののイマイチつ使いずらい機能となっていました。Starling2.0ではこの機能が進化し、全ディスプレイリスト対象で自動でflatten処理が必要時だけかかるようになりました。これがさらに正式公開前のブラッシュアップで進化して、 ディスプレイリスト全体で全く更新がない場合は、画面更新処理自体をスキップするという事ができるようになりました。他のフレームワークではよくある機能のようですが、状況によってはかなりの電力消費の低下が期待できます。
いくつかの注意点
上記で述べたようにデフォルトでこの機能はoffになっています。これは描画更新スキップを行っているとレンダーテクスチャ機能とビデオテクスチャ機能がただしく機能しなくなるからとの事です。これらの機能と描画更新スキップを合わせて使う場合は画面を更新したい際にStaling.setRequiresRedraw()を呼び出し、強制更新を行えば良いようです。また、ブログポストではまだ触れられていませんがソースコードを読む限り、描画更新スキップ機能が働かない状況がいくつかありました。
- 別のStage3Dライブラリ(Away3Dなど)と同時にStarling2.0が動いている時
- Flashネイティブの(昔からあるStage3Dでない)ディスプレイリストがstage3Dレイヤー外に表示されている時
前者はまれなケースかと思いますが、後者はそこそこ該当する使い方をする方も多いのではないでしょうか。。というか、まさに自分がそうなのですが、ネイティブ側のディスプレイリストを更新しない場合、スマホ上での動作であってもCPU負荷はほとんど増加しないため、自分の作成したアプリでは、Stage3D側では実装しずらいUIや演出をネイティブ側でおとなし目に表示する事をしばしばしていました。(ネイティブ側ディスプレイリストが画面上に存在しても、更新がかからなければスマホ上で60fpsの実現は可能です。)この描画更新スキップに関する制限は、スマホや一部のPCではstage3D側の描画更新入って初めてネイティブのディスプレイリスト描画更新が入る仕様である事から来ているようです。
とはいえ、描画更新スキップが行われない状況でも、Starling2.0では上述した自動flatten(のような)処理は働きます。こちらだけでもパフォーマンスアップや電力消費を抑える効果もあるはずですね。
なお、デスクトップPC(Win/Mac)上では(あまり古いビデオカードを用いている場合などを除いて)描画スキップはたいていの場合動作させる事が可能なようです。
Statsの表示
手軽にパフォーマンス測定を行え便利なのでStarlingのStats機能はみな使っているかと思いますが、こちらにも関連した新機能が入りました。描画更新スキップ機能が働いている時は表示色が緑になるというものです。わかりやすくて良いですね。
なお、ビルトインのStatsViewはdrawコールを追加で2回確実に使ってしまいます。(draw回数が1の表示の時は、実は合計で3回drawコールが発生している。)描画スキップ情報がStarlingクラス外部から取得できると、使い勝手が良いのですが、現状のコードを見る限り、外から値を得るのは難しそうでした。残念。
終わりに
とりあえず、最新の日本語情報としてまとめましたが、まだ自分はスマホ実機ではStarling2.0を動かしておりません。動かしてみて何か記載内容がおかしかった際は、できるかぎり記事内容を修正しようと思います。
さて、ネイティブのディスプレイリストに関してですが、setRequiresRedraw命令にて強制描画更新する方式をとれば、ネイティブのディスプレイリストが表示されたまま描画更新スキップできる仕様にできるのではないかな、と疑問に思っています。時間があればStaling自体に手を入れて実験してみたい所です。
情報元:下記ブログポストと最新ソースコード
http://gamua.com/blog/2016/04/starling-20/?utm_content=buffer0d604&utm_medium=social&utm_source=facebook.com&utm_campaign=buffer