Google I/Oの”Accelerated Android Rendering”のメモ
このページの動画を見てメモしました。
accelerated-android-rendering.html
GPUによる描画の高速化はすでにゲームアプリやLive Wallpaperで使われているが、Basic UIはまだGPUを利用していない。
しかしながら、HoneycombのタブレットからはBasic UIもGPUで高速化している。
ピクセルの数とメモリバンド幅のグラフ
タブレットでピクセルの数は増えたが、メモリバンド幅はのびていない。
UI on the GPU -> GPUI (グプイ)
Software rendering の流れ
新しいモデルではOpenGL RendererからGPUを使って描画する。
ListView は全てメッシュ(三角形の集まり)としてGPUで処理される。
9パッチのボタンもテキスチャ付きのメッシュとして処理される。
HW アクセラレーションを有効にするには指定が必要。(opt-in)
Application, Activity, Window, Viewのそれぞれのレベルで指定することができる。
Application, Activity
android:hardwareAccelerated="true" を manufest.xmlに書く。
<application android:hardwareAccelerated="true"> <activity ... /> <activity android:hardwareAccelerated="false" /> </application>
Windowではruntimeにコードで指定する。
getWindow().setFlags( WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
制限事項
Canvasの一部はGPUで効率的に実装できない。そのため機能が限定されたり、サポートされていないものもある。
ビットマップを扱うものはダメ。
New drawing model
デバッグのためには理解しておく必要がある。
変更のないものはredrawしない。
DisplayList: OpenGLのコマンドの列。条件分岐なし。
invalidate()で対応するDisplayListにdirtyの印をつける。
rebuild DisplayListを作り直す。dirtyの印がついているものだけ。
例
ListItem: 旧モデルでは全て再描画が必要。結局全てのUI部品のdrawが呼ばれる。
新モデルでは、変更箇所のdisplayListを作り直して、displayListを再実行する。
Layer
SOFTWARE ビットマップが作られてテキスチャに変換される。
HARDWARE GPUのメモリの中で処理される。
Hardware layer速い!1000倍以上速い。
Hardware layerを使ってグレイスケールのvisual effectをつける例。
Layerと相性のいいproperty。 rotationの指定はDisplayListに一行追加するだけですむ。これを使ったアニメーションはGPUで非常に高速。
Tips & Tricks
Viewをたくさん使いすぎるな。階層化は浅く。
setAlpha()はHardware layerなしでは2倍のfill-rateがかかる。
rendering obujectは再利用しろ。
ビットマップは変更するな。変更するとそのたびにGPU側に転送が必要になる。
マップアプリケーションで1フレームの描画に300msecもかかるという問題があった。何度もバグレポートをやりとりしたが、結局96回xmlファイルを読み込んでいたことがわかった。プロファイル重要。
今の世代のGPUはfill-rateはスクリーンのピクセル数の2.5倍程度しかない。
そのためスクリーンサイズと同じバックグランドイメージとテキスチャを転送したら、それでほとんどの帯域を食いつぶしてしまう。
Profile!
遅いと思ったらまずプロファイルをとって何が起きているか調べる。
HTML5のCanvasはAndroid3.0でもまだGPUで高速化していない。ブラウザチームがとりくんでいる。
HardwareアクセラレーションはデフォルトではONになっていない。これは今までとの互換性のため。アプリケーションが十分対応したら将来デフォルトでONにするかも。