月別アーカイブ: 2011年10月

Android 3.x 描画 API の比較

Canvas など Android の画面は CPU でレンダリングされています。
画面全体を常に書き換えているアプリは、解像度が上がるほど速度が
落ちていく可能性があります。

SurfaceView を使ったゲームアプリなど、スマートフォンではスムーズに
動いていたのに Tablet では極端に遅くなることがありました。
最近はスマートフォンの解像度も HD 化しており、Tablet と同じくらい
描画が負担になっていると考えられます。

大画面前提の Tablet 向け Android 3.x では 2.x と比べて色々と改良が
施されているようです。
その一つが 2D 描画のハードウェアアクセラレーションです。

使えるコマンドは限られますが Canvas のレンダリングも GPU による描画が
行われます。AndroidManifest.xml に android:hardwareAccelerated=”true”
を追加するだけです。

Optimus Pad L-06C (Tegra 250) Android 3.1

View(SW)         15.0fps      24x24 x  1600個   13.8Mpix/sec
View(HW)         27.8fps      24x24 x  1600個   25.6Mpix/sec
SurfaceView      16.3fps      24x24 x  1600個   15.0Mpix/sec
GLSurfaceView    12.8fps      24x24 x 30000個  221.2Mpix/sec
GLSurfaceView    20.6fps      12x12 x 50000個  148.3Mpix/sec

256×256 pixel のテクスチャ画像から 24×24 pixel を切り出して、
24×24 dot の小さい正方形として描画します。
これを 1600個、ばらばらに動かしています。

SurfaceView ではハードウエアアクセラレーションが有効とならなかったため
速度が逆転しています。HW が有効なら View + onDraw() の方が高速に
描画できています。

それでも OpenGL とは比較になりません。

GLSurfaceView は Java 上で OpenGL ES 2.0 を利用しています。
速すぎて 1600個では測定出来なかったため 30000個に増やしています。
当然かもしれませんがゲームは OpenGL を使った方がよさそうです。

以下 Android 2.3 との比較。

                    View(SW)  View(HW)  SurfaceView  GLSurfaceView
            OS      x1600     x1600     x1600        x30000
------------------------------------------------------------------
OptimusPad  A3.1    15.0fps   27.8fps   16.3fps      12.8fps
HTC EVO 3D  A2.3    20.2fps   --        26.4fps      16.5fps
Galaxy S2   A2.3    31.8fps   --        44.8fps      28.1fps

今後登場する Android 4.0 (Ice Cream Sandwich) では、スマートフォンも
GPU による描画に対応します。
1280×720 など画面解像度が高い機種ほど 2.3→4.0 の差が大きいかもしれません。

Android 3.x には他にも RenderScript があります。
NDK + OpenGL ES の上位ライブラリに近く、機能が限られる代わりに
Java から容易に扱えるようになっています。
こちらも後ほど試してみたいと思っています。

Android エスプガルーダ2/怒首領蜂第復活

iPhone 版やりこんでいたので Android 版も購入しました。
エスプガルーダⅡと怒首領蜂大復活
手持ちで対応していた端末は下記の 3台。

・Galaxy S2 SC-02C (Exynos4210)
・EVO 3D ISW12HT (MSM8660)
・Optimus Pad L-06C (Tegra250) ※2011/10/21現在 エスプガルーダIIのみ

● Galaxy S2 SC-02C

高速です。描画の処理落ちもなくタッチの遅延もなく非常に良好です。
画面はコントラストが高く他機種に比べて濃い発色となります。
気になる場合は設定→画面→スクリーンモード
HDMI アダプタを使って外部モニタでのプレイもあり。

● EVO 3D ISW12HT

推奨端末ですが描画は処理落ちがあります。
Adreno 220 は 3D 性能が高かったのでどこが原因かは不明。
タッチの遅延は少なく追従性は比較的良好です。
Rendering skip off で難易度が下がるので上達した気になる。

● Optimus Pad L-06C

エスプガルーダⅡだけですが、処理落ちもなく描画は高速です。
ただタッチパネルの入力遅延が大きく、操作に対して自機が遅れて
ついてくる動きになっています。

2011/10/26追記 怒首領蜂大復活も L-06C 対応になりました。

対応端末のスペックを調べてみました。

◎推奨端末
Galaxy S SC-02B        S5PC110 Cortex-A8 1GHz      PVR SGX540  512MB
Galaxy S2 SC-02C       S5PC210 Cortex-A9 x2 1.2GHz Mali-400MP    1GB
PHOTON ISW11M          Tegra250 Cortex-A9 x2 1GHz  ULP GeForce   1GB
EVO 3D ISW12HT         MSM8660 Scorpion x2 1.2GHz  Adreno 220    1GB

◎対応端末
Xperia arc  SO-01C     MSM8255 Scorpion 1GHz       Adreno 205  512MB
Xperia acro SO-02C     MSM8255 Scorpion 1GHz       Adreno 205  512MB
Xperia ray  SO-03C     MSM8255 Scorpion 1GHz       Adreno 205  512MB
Xperia play SO-01D     MSM8255 Scorpion 1GHz       Adreno 205  512MB
Optimus bright L-07C   OMAP3630 Cortex-A8 1GHz     PVR SGX530  512MB
Optimus Pad L-06C      Tegra250 Cortex-A9 x2 1GHz  ULP GeForce   1GB
AQUOS PHONE SH-12C     MSM8255 Scorpion 1.4GHz     Adreno 205  512MB
AQUOS PHONE SH-13C     MSM8255 Scorpion 1GHz       Adreno 205  512MB
MEDIAS WP N-06C        MSM8255 Scorpion 1GHz       Adreno 205  512MB
Panasonic P-07C        OMAP3630 Cortex-A8 1GHz     PVR SGX530  512MB
FUjitsu F-12C          MSM8255 Scorpion 1GHz       Adreno 205  512MB
Galaxy Tab SC-01C      S5PC110 Cortex-A8 1GHz      PVR SGX540  512MB

SHARP IS05             MSM8655 Scorpion 1GHz       Adreno 205  512MB
Xperia acro IS11S      MSM8655 Scorpoin 1GHz       Adreno 205  512MB
AQUOS PHONE IS11SH     MSM8655 Scorpion 1.4GHz     Adreno 205  512MB
AQUOS PHONE IS12SH     MSM8655 Scorpion 1.4GHz     Adreno 205  512MB
INFOBAR A01            MSM8655 Scorpion 1.4GHz     Adreno 205  512MB
G'zOne IS11CA          MSM8655 Scorpion 1GHz       Adreno 205  512MB
REGZA Phone IS11T      MSM8655 Scorpion 1.4GHz     Adreno 205  512MB
MIRACH IS11PT          MSM8655 Scorpion 1.0GHz     Adreno 205  512MB

Desire HD 001HT        MSM8255 Scorpion 1GHz       Adreno 205  768MB
GALAPAGOS 003SH        MSM8255 Scorpion 1GHz       Adreno 205  512MB
GALAPAGOS 005SH        MSM8255 Scorpion 1GHz       Adreno 205  512MB
AQUOS PHONE 006SH      MSM8255 Scorpion 1.4GHz     Adreno 205  512MB
AQUOS HYBRID 007SH     MSM8255 Scorpion 1GHz       Adreno 205  512MB
Sweety 003P            OMAP3630 Cortex-A8 1GHz     PVR SGX530  512MB
ZTE 008Z               MSM8255 Scorpion 1GHz       Adreno 205  512MB
Vision 007HW           MSM8255 Scorpion 1GHz       Adreno 205  512MB
AQUOS PHONE 009SH      MSM8255 Scorpion 1GHz       Adreno 205  512MB
DM009SH                MSM8255 Scorpion 1GHz       Adreno 205  512MB

端末一覧と比べてみると、ちょうど Adreno 205/PVR SGX530 以上の端末が
動作対象となっています。
CPU/GPU 等の搭載プロセッサで線引きが行われているようです。

GPU 性能で下記のようにグループ分けしてみました。
Group 2 以上が今回の動作対象となっています。

GPU別
G3   | Adreno 220, PVRSGX543MP2, Mali-400MP
G2   | Adreno 205, PVRSGX530/535/540, ULP GeForce(Tegra250)
G1   | Adreno 200, Z430
G0   | ARMv6 (ARM11)

Chip (CPU)
G3   | MSM8260/8660, Exynos4210, A5
G2.5 | Tegra250
-------- ↑ Dual core CPU ------------------------
G2   | MSM8255/8655, S5PC110, OMAP3630, A4
G1   | QSD8250/8650, i.MX515
-------- ↑ ARMv7 --------------------------------
G0   | MSM7227, MSM7225

関連エントリ
iPhone 3GS エスプガルーダII ESPGALUDA2

OpenGL ES 2.0 Mobile GPU の比較、重いテクスチャ

テクスチャ負荷が高いケースでのテスト

GPU             fps       display pix/sec
--------------------------------------------------
Adreno 220      28.88fps  960x540  15.0M
Mali-400MP      20.08fps  800x480   7.7M  
ULP GeForce(8)   4.37fps 1280x752   4.2M  (Tegra250)
PVR SGX543MP2   20.65fps 1024x768  16.2M
PVR SGX535       8.70fps  480x320   1.3M

背景データ
 ・170000 ポリゴン
 ・1024×1024 カラーテクスチャ 5枚
 ・2048×2048 非圧縮ノーマルマップ 2枚
 ・ライティングあり(directional x2 + point x1)

キャラクタ
 ・10000ポリゴン前後 x5 (animation あり)
 ・ColorMap + NormalMap + SpecularMap
 ・ライティングあり(directional x2 + point x1)

背景の normal map は非圧縮 mip 無しで 1枚 12MByte もあります。
それでも Adreno 220/PVR SGX543MP2 はよくこの速度で動いています。

Color Texture の一部は alpha が入っており、
ETC1 しか使えない Mali-400MP では圧縮できませんでした。
このあたりが速度に影響しているかもしれません。

                alpha無し      alpha 1bit     alpha
---------------------------------------------------------
Mali-400MP      ETC1  4bpp     非圧縮         非圧縮
Adreno 220      ATC   4bpp     ATCA  8bpp     ATCI  8bpp
ULP GeForce     DXT1  4bpp     DXT1  4bpp     DXT5  8bpp
PVR SGX543MP2   PVRTC 4bpp     PVRTC 4bpp     PVRTC 4bpp

圧縮テクスチャ対応表

高負荷で長時間走らせていると端末も結構熱を持ちます。
Tablet は大丈夫ですが、うっかり雑誌の上においた EVO 3D が熱くなり
LED が点滅してました。

関連エントリ
頂点性能の比較 その2 (OpenGL ES 2.0 Mobile GPU)
OpenGL ES 2.0 Mobile GPU の頂点性能を比較する
A5 PowerVR SGX543MP2 は iOS 5 だと速い
さらに OpenGL ES 2.0 Mobile GPU の速度比較
OpenGL ES 2.0 Mobile GPU の速度比較 (dual core世代) 更新

Android 4.0 Ice Cream Sandwich SDK と AVD

Emulator (AVD) が ARMv7 になっているようです。
neon ありでデフォルトの RAM 容量も 512MB。
(以前は ARMv5TE)

Processor	: ARMv7 Processor rev 0 (v7l)
BogoMIPS	: 405.50
Features	: swp half thumb fastmult vfp edsp neon vfpv3 
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x0
CPU part	: 0xc08
CPU revision	: 0

ndk も armeabi-v7a のまま走らせられるようになります。

SDK Manager 周りの UI が変更されているようです。
下記インストール手順のページを修正しました。

Android SDK/NDK install 方法

Android Java で OpenGL ES 2.0 を使う

Android の OpenGL ES 2.0 対応は OS 2.0 Eclair からです。
まず NDK で使えるようになり、2.2 Froyo (API Level 8) では Java からも
呼び出せるようになっています。
実際に使ってみました。

2.0 への切り替えは GLSurfaceView の setEGLContextClientVersion( 2 ) です。

public class MarkerView extends GLSurfaceView {
    public MarkerView( Context context ) {
        super( context );
        setEGLContextClientVersion( 2 );    // GLES 2.0
        setRenderer( new MarkerRenderer( context ) );
    }
}

GLSurfaceView.Renderer には GL10 の interface が引数で渡されますが使いません。
android.opengl.GLES20 の static メソッドをそのまま呼び出します。

public class MarkerRenderer implements GLSurfaceView.Renderer {

  ~

    public void onSurfaceChanged( GL10 ugl, int w, int h ) {
        GLES20.glViewport( 0, 0, w, h );
    }

    public void onDrawFrame( GL10 ugl ) {
        GLES20.glClearColor( 0.0f, 0.0f, 0.5f, 0.0f );
        GLES20.glClear( GLES20.GL_COLOR_BUFFER_BIT|GLES20.GL_DEPTH_BUFFER_BIT );

        GLES20.glEnable( GLES20.GL_CULL_FACE );
        GLES20.glFrontFace( GLES20.GL_CW );
        GLES20.glCullFace( GLES20.GL_BACK );

        ~
        GLES20.glBindBuffer( GLES20.GL_ELEMENT_ARRAY_BUFFER, ibuffer );
        GLES20.glDrawElements( GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, 0 ); // ← できない
    }
}

試してみて気がついたのですが、Android 2.2 の Java からは
VertexBuffer/IndexBuffer (VBO) が使えないようです。

glVertexAttribPointer() や glDrawElements() の最後の引数に、
NULL やアドレスのオフセットを与えることができないからです。

Android 2.3 (API Level 9) では修正されており、足りない命令が追加
されていました。

↓また下のスライドに説明があります。

io2011-opengl-for-android

Android 2.2 の場合は、glVertexAttribPointer() / glDrawElements()
の 2命令を jni (NDK) を使って自分で作ればこの問題を回避できるそうです。