将来の変更の話
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 件のコメント:
コメントを投稿