将来の変更の話
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;
- }
$ 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);
- }
- <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();
- }
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));
・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 件のコメント:
コメントを投稿