連載
» 2009年04月21日 00時00分 公開

インタビュー特集:Google直伝!(1):Androidアプリで高速描画チューニングをするコツ (2/3)

[嶋是一, 中村秀樹, 安生真,日本Androidの会]

T-Mobile G1の仕組みを整理

 高速描画を実現するための仕組みを理解するには、G1のハードウェアの仕組みをある程度理解する必要がある。

 アプリケーションが動作するための計算や演算を行うのは、CPUだ。G1のアプリケーションが動作するCPUにはARM 11(クロック数は528MHz)が搭載されている。通常は、ここで表示する内容を生成して、LCDのバッファへ転送して表示する。

 CPUの演算速度はそれなりに高速なので、すべてソフトウェアで演算する手法もある。しかし、G1は3Dの処理(OpenGL ES)を行う専用ハードウェア(GPU)を持っているため、これを使うことでソフトウェアでの処理に比べて高速かつ、省電力で描画の演算ができる。

 PCで動作するAndroid SDKのエミュレータはソフトウェアレンダリングを使用する。一方、G1では、ソフトウェアの処理を殺して、GPUで高速に処理できるように(Androidのライブラリとドライバの)カスタマイズが行われている(図3)。

図3 Androidのカスタマイズ 図3 Androidのカスタマイズ(GPUとの接続はG1用)

 G1以外の、GPUを持つAndroid端末も、同じようにカスタマイズを行うことでハードウェア上の高速処理が可能だ。ちなみにPCでは、2Dと3DもGPUの機能だが、このG1では3Dだけに限られているようだ。

Androidアプリ描画の基本

 今回の研究報告の前に、いくつか知っておいた方がよい知識を紹介しよう。Androidのアプリケーション上で画像を表示するには、まずアクティビティ(Activity、画面)を生成して、そこに描画する領域を指定する。この描画指定には2つの方法がある。1つはCanvas(キャンバス)、もう1つはSurfaceView(サーフェスビュー)だ。

 Canvasとは、表示する画面を生成するためのソフトウェアレンダリングシステムである。これは、アプリケーションスレッドから用いる場合と、アプリケーションスレッドから独立した描画専用のスレッド「SurfaceView」から用いる場合がある。アプリケーションのスレッドから用いた場合は、表示以外の処理とともに動作するため、描画が遅くなりがちだ。つまり、ゲームの処理に100msec(ミリ秒)かかったら、画面もそのタイミングで100msec止まってしまう。

 一方、SurfaceViewはアプリケーションスレッドから独立して描画専用のスレッドで行われるため、高速かつスムーズに表示ができる。またSurfaceViewではOpenGL ESの処理を利用することもできる。

 SpriteMethodTestでは、Canvasのスレッドに描画するSurfaceViewを使用している。

OpenGLの拡張を用いた高速化

 今回の取材では、2D描画を行う「4つの手法」についてG1上で評価し、おのおののパフォーマンスを報告いただいた。結果からいうと「2D描画で高速表示を行うにはOpenGL ESを用いるのがよく、その中でも『Draw Texture Extension』というOpenGLの拡張を用いるのが最速だ」と分かった。

 主に描画する手法は、前述のCanvasを用いる方法と、OpenGL ESを用いる方法の2つに分類できる。そして、OpenGL ESを用いる方法には、次の3種類がある。

  1. Basic Vert Quads」(Android標準)
  2. Draw Texture Extension」(G1搭載)
  3. VBO Extension」(G1搭載)

 これらの評価を行ったのが図1のSpriteMethodTestアプリケーションだ。詳細の数値は、読者の皆さん自身で実行し、確認していただきたい。

表1 評価アプリケーション「SpriteMethodTest」の参考データ
アンドロイド
ロボットの数 
  
Canvas Basic Vert Quads Draw Texture VBO Extension
msec fps msec fps msec fps msec fps
10体 Frame 16 62.5 16 62.5 16 62.5 16 62.5
Draw 7 3 0 1
PageFlip 0 13 16 14
Sim 0 0 0 0
100体 Frame 42 23 37 27 16 62.5 21 47.6
Draw 38 27 2 11
PageFlip 1 9 13 9
Sim 0 0 0 0
1000体 Frame 341 2.9 322 3.1 102 9 210 4.7
Draw 326 259 20 106
PageFlip 1 52 73 56
Sim 12 9 7 8
数値は、筆者が保持しているG1で評価した参考値。パフォーマンスは環境や携帯端末の状況により異なるため、数値は読者で評価してもらいたい

 このアプリケーションで表示される結果のパラメータの意味は表2のとおりだ。

表2 パラメータの意味
Frame 描画を開始してから完了するまでの時間。これを秒で割るとフレームレート(fps)になる
Draw 描画系の関数だけでかかった時間
PageFlip レンダリングスレッドが「wait()」(待ち)を行った時間
Sim 表示オブジェクトのシミュレーションにかかった時間

 描画速度であるフレームレートは、次の結果のとおりとなった。

Canvas Basic Vert Quads VBO Extension Draw Texture Extension

 画面を見ていると、アンドロイドロボットが少ない場合はよいのだが、100〜1000体を超える表示をさせたときは、その描画速度の差が明らかになる。ほとんど“コマ落ち”でしか表示できなかった画面でも、高速な描画で行うことで、アンドロイドロボットが移動しているのが見えるようになる。

Androidで2D描画を行う4つの方法

Canvasを用いる

 Canvasを用いた場合は、アプリケーション本体のスレッドで表示する画像を作っている。そのため、描画以外の処理でCPUパワーが足りなくなると画面が動かなくなってしまう。

 また、その逆に描画データが大きくなり、時間がかかるようになると、それだけアプリケーションの処理時間も遅くなる。その結果、描画速度が低下してしまう。しかし、プログラミングの面でCanvasは、最も簡単な表示方法でもある。速度を必要としないときは問題ない。ゲームのようなリアルタイムに高速描画を要求される場合には向いていない。利用シーンに応じて使い分けることが望ましいだろう。

Basic Vert Quads

 Basic Vert Quadsは、OpenGL ESの最もオーソドックスな利用方法で、4つの頂点を面に正射投影させる方法だ。しかし、これだけだとCanvasの速度と大きく変わらなかった。

Draw Texture Extension

 Draw Texture Extensionの手法は、プログラミング上では「glDrawTexfOES()」メソッドを利用して実装している。これは完全な3Dの処理に比べて、平面(テクスチャ)を前提にVertexの処理を簡素化し高速を図る手法だ。簡素化のため回転(Rotate)ができないなどの制約がある。この結果、今回評価したいずれの方法よりも、最高の速度向上が見られた。

VBO Extension

 VBO Extensionの手法は、基本的にBasic Vert Quadsと同じだ。一番の違いは、4つの頂点をメインメモリ上でなく、GPU内部のメモリで管理している点である。そのため、メモリデータをGPUから移動させる必要がなく、この分の速度が向上していると考えられる。

デザインにより評価するべき

 今回の評価アプリのデザインだと、VBO ExtensionはDraw Texture Extensionほど高速でない。例えば図4のように、一画面を多数の分割されたブロックとして扱い、それを並べて描画するタイル形式に限定してチューニングを行えば、VBO Extensionでも高速にできる可能性があると語った。

図4 タイルで画面を管理する(複数の領域に分割し、その単位で描画を行う手法) 図4 タイルで画面を管理する(複数の領域に分割し、その単位で描画を行う手法)

 このタイル形式はロールプレイングゲームなどの2Dゲームアプリケーションでは一般的に用いられている手法だ。デザインにより、どちらを利用すると速くなるか評価して用いるのがよいだろう。

 次ページでは、どの手法を採用するべきか判断するための3つのポイントを紹介したい。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。