2013年5月23日木曜日

Google I/O 2013 - Android : Android Graphics Performance

1. Architecture

将来の変更の話

reordering & merging

■ reordering

GPU の性能をより引き出すために、描画の順番を変える
Checkbox → Checkbox → Button → Text → Button → Text

Checkbox の画像 → Checkbox の画像 → Button → Button → Checkbox のテキスト → Checkbox のテキスト → Text → Text

GPU のステータスを変えなくていいので効果的


■ merging

Checkbox の画像 → Checkbox の画像 → Button → Button → Checkbox のテキスト → Checkbox のテキスト → Text → Text

Checkbox の画像 x2 → Button x2 → Text x4

# draw call が 88 から 38 に減ったサンプルを実際にデモ


Multi-threading

マルチコアの性能を引き出すため

例えば4コアあるとすると、描画時に shadows を4コアで描画した後、何個かのコアで Path を描画するなど

non-rectangular clipping

今までは hardware accelerated pipeline でサポートされていなかった 3D rotation でフリップさせたとき、レイヤーを使わないでアニメーションを走らせると、現状の Android(4.1 とか 4.2)では clipping breaks が起こる 回転させたときの rect はもはや四角にならないはずだから



2. Developer Tools

"Show GPU overdraw" オプション(Developer options)

何回描画されたかに応じてオーバーレイされる色が変わる
1x Blue
2x Green
3x Red
4x Deep Red


"Profile GPU rendering"(Developer options) オプション

時間毎のフレームレートを表示するオプション

ADB を介してデータをダンプしてチャートを作る機能はあったが、画面上に直接チャートを表示できるようになった
緑の横線は 60FPS を表していて、常にこれを超えないようにするべき


Systrace

次のアップデートでは systrace の使い方がより簡単になる

$ cd sdk/platform-tools
$ ./systrace.py gfx view freq sched

"Enable OpenGL traces" の systrace


android.os.Trace

新しい API import android.os.Trace; @Override public View getView(int pos, View view, ViewGroup parent) { Trace.beginSection("getView"); if(view == null) { view = createView(); } // Trace time spent binding dta Trace.beginSection("bind"); bindView(pos, view); Trace.endSection(); Trace.endSection(); return view; } この新しい API を使うときは -a オプションで systrace を使う

$ cd sdk/platform-tools
$ ./systrace.py -a com.example.myapp

アプリのどこが遅くなっているのか調べるのにいい



3. Tips and Tricks

"Show GPU overdraw" オプションを使ったデモ

ListView の android:background で指定していた背景色をテーマの android:windowBackground に移したら Deep red が blue になった


9patch のコンテンツエリアの透明化

コンテンツによって完全に隠されるエリアを透明にしてしまう


MIP mapping

コードから MIP map を有効にする private void loadData() { // Load bitmap Bitmap b = getBitmap(); // Enable trilinear filtering b.setHasMipMap(true); } XML で MIP map を有効にする <bitmap android:mipMap="true" android:src="@drawable/my_drawable" />


Canvas Layers

Clip layer @Override protected void onDraw(Canvas canvas) { //Create a clipped layer canvas.save(); canvas.saveLayer(x, y, width, height, Canvas.CLIP_TO_LAYER_SAVE_FLAG); // Draw stuff canvas.drawBitmap(bugDroid, 0.0f, 0.0f, null); canvas.restore(); } Canvas.CLIP_TO_LAYER_DAVE_FLAG を付けないとパフォーマンスにすごい悪いので気をつける


Using alpha with case

View に alpha を設定する方法はいくつかあるが、これらはいずれも canvas.saveLayerAlpha(l, t, r, b, 127, Canvas.CLIP_TO_LAYER_SAVE_FLAG); をしていることになる

View 上のコンテンツを透明にしたいのか、View 自身を透明にしたいのか(View の後ろにあるものが見えてほしいのか)はっきりさせる

・TextView

TextView 上のコンテンツを透明にしたいだけの場合は View の setAlpha() を使うのではなく int newTextColor = (int) (0xFF * alpha) << 24 | baseTextColor & 0xFFFFFF; textView.setTextColor(newTextColor); にする

・ImageView

ImageView 上のコンテンツを透明にしたいだけの場合は View の setAlpha() を使うのではなく imageView.setImageAlpha((int) (alpha * 255)); にする(setImageAlpha は Jelly Bean で追加された API)

・CustomView

CustomView 上のコンテンツを透明にしたいだけの場合は View の setAlpha() を使うのではなく int alpha = (int) (255 * slider.getProgress() / 100.0f); paint.setAlpha(alpha); canvas.draw*(..., paint); にする

・レイヤーを使う(特にアニメーション) view.setLayerType(View.LAYER_TYPE_HARDWARE, null); // Transient layer view.animate().alpha(0).withLayer(); ・その他の関連すること // API level 16+ @Override public boolean hasOverlappingRendering() { // Don't lie to us! return false; }


Canvas の注意点

canvas の getWidth() と getHeight() は hardware rendering と software rendering で異なる
with Hardware rendering : View のサイズ
with Software rendering : Window のサイズ

canvas のサイズを View のサイズとして使ってはいけない!


Clipping の注意点 @Override protected void onDraw(Canvas canvas) { // Keep the jellybeans canvas.clipRect(l, t, r, b); // Rotate the jar canvas.rotate(-30.0f, pX, pY); // Draw the jar canvas.drawBitmap(mJellyBeans, x, y, null); } 命令の順番に注意する
ここでは最初にクリップしてから回転している
これだと最終的なクリップエリアは四角になっている
もし、回転してからクリップすると、最終的なクリップエリアはダイアモンド型になるのでパフォーマンスによくない


clip bounds の注意点

getClipBounds の Rect は hardware rendering と software rendering で異なる
with Hardware rendering : View の bounds
with Software rendering : invalidate の dirty rect の bounds



0 件のコメント:

コメントを投稿