syghの新フラグメント置き場

プログラミングTipsやコード断片の保管場所です。お絵描きもときどき載せます。

Android SDKエミュレータでOpenGL ES 2.0

(これは2013-06-01に書いた故OCNブログの記事を移植したものです)

仕事で少しだけ Android(主に OpenGL まわり)に携わることになったんですが、OpenGL ES 2.0 開発環境を構築するのに少々手間取ったのでメモを残しておきます。

最終的には PC 上で OpenGL 4.1/4.3/4.5 の ES 2.0/ES 3.0/ES 3.1 プロファイルを使って途中まで開発を進めたほうが圧倒的に楽なのでは? という結論に至りましたが。

以下、ADT(Android Developer Tools)プラグイン バンドル版の 64bit WindowsAndroid SDK x86_64-20130514 で検証。

一部、Pleiades プラグインによる日本語版の UI 説明もカッコ書きで併記してます。

・OS: Windows 7 x64 SP1
・CPU: Intel Xeon W3520
GPU: NVIDIA Quadro 2000

Intel HAXM

Android SDK では、デフォルトでは ARM プロセッサ対応エミュレータしか使えないのだが、これがすごく重い。正直まったく使い物にならない。そこで Intel x86 プロセッサ対応エミュレータの出番となるわけだが、

[Android SDK Manager (Android SDK マネージャー)] を経由して、
・[Intel x86 Atom System Image]
および
・[Intel x86 Emulator Accelerator (Intel Hardware Accelerated Execution Manager, HAXM)]
をダウンロードし、

<ANDROID_SDK_ROOT>\sdk\extras\intel\Hardware_Accelerated_Execution_Manager\IntelHaxm.exe

にダウンロードされたインストーラーを使って HAXM をインストールすることで、Android 仮想デバイス(AVD)の [CPU/ABI] に [Intel Atom (x86)] を選択することができるようになる。
x86 アクセラレータを使うと、エミュレータの起動も動作もかなり高速化される。

なお、会社などでプロキシ サーバーを経由してる場合、SDK マネージャーでパッケージをダウンロードするときはプロキシ設定も忘れないように。

※ただし、仮想化が可能であるかどうかは開発環境 PC の CPU に依存する。
マイクロソフトが公開している、[ハードウェア支援による仮想化の検出ツール] というのを実行することで、CPU が仮想化(HAV, Hardware-Assisted Virtualization)に対応しているかどうか、また HAV が現在有効になっているかどうかを調べることができる。
あと、たぶん AMD プロセッサでは HAXM の利用は不可能(たぶん今後も未来永劫不可能)。
http://support.microsoft.com/kb/977206/ja

なお、AVD の設定で [Target] に [Android 2.3.3 - API Level 10] などの古い世代を選択し、[Use Host GPU (ホスト GPU を使用する)] を ON にするとエミュレータが起動しない(画面が真っ黒のまま)。
また、GLSurfaceView.setEGLContextClientVersion(2) を使って OpenGL ES 2.0 を有効にすると、[The application ~ has stopped unexpectedly. Please try again.] というエラーメッセージが出て、アプリが起動しない。
エミュレータ環境で OpenGL ES 2.0 を使う場合は、[Target] を [Android 4.2.2 - API Level 17] などの新しい世代にして、[Use Host GPU (ホスト GPU を使用する)] を ON にする必要がある(どうやら OpenGL ES 2.0 をエミュレータで使用するためには、Android 4.0 API Level 14 以降の AVD でないと使用できないらしい?)。
なお、Intel HAXM が使えるならば、起動高速化のために [Snapshot] にチェックを入れる必要は特になさげ。

Android 2.x や 3.x などの古い世代にも対応した OpenGL ES 2.0 アプリを開発・デバッグするときは、新規アプリケーション作成時に古い世代の API レベルを選択した上で、4.x の AVD 上で HAXM を使ってデバッグを進め、最後に実機で動作確認するようにするとよさげ。あと NDK を使う場合、C/C++ でプロセッサ依存のコードを書くのは極力控えましょう(SSE/NEONとか)。

もし AVD の [Target] を変更した後でエミュレータを起動すると [Unfortunately, ~ has stopped.] というエラーメッセージが大量に発生する場合、古いユーザーデータのキャッシュが残っている可能性がある。
この場合、[Launch Option (実行の構成)] 設定で、[Wipe User Data (ユーザー・データを消去する)] にチェックを入れておくとよい。

なお、Mac OS X 上では Intel HAXM を使うと動作がおかしくなったり OS がクラッシュしたりする現象が発生することもあるらしい。
http://dev.classmethod.jp/smartphone/build-fast-android-emulator/

Linux では Intel HAXM は使えないが、逆に KVM(Kernel-based Virtual Machine)経由で Intel だけでなく AMDアクセラレータ(AMD-V)が使えるらしい。

Windows ストア アプリ開発環境との個人的な比較感想

以下は個人的主観に基づく意見なので、興味のある人だけどうぞ。

自分は Windows デスクトップ アプリ開発歴がそれなりに長いのだが、Windows 8.x ストア アプリは使用可能な API の制限がきついだけで、あとはデスクトップ アプリと大して変わらない感覚で開発できるので非常に楽。むしろゲームとかは DirectX Graphics と XAML との連携・合成ができるし、システム標準で XAudio2 が使えるので、(Windows ストア アプリ専用であれば)Direct3D/OpenGLIME 対応エディットボックスなどの UI 部品を自前で作ったり、オーディオまわりの外部ランタイムを用意したりしなくて済む分、かえってストア アプリのほうが楽になると思う。Direct3D/OpenGL の苦手な文字列描画まわりだって、Direct2D/DirectWrite 連携もしくは XAML 連携を行なえばあっさり解決するし(ただしカツカツのチューニングしてフルパフォーマンスを引き出したい場合、毎フレームDirectWrite使ってたらさすがにアウトなので、従来通りフォント スプライトを実装するかDirectX Tool Kitを使いましょう)。

Windows ストア アプリの開発環境である Visual Studio には ARM エミュレータは存在しないが、基本的に最初から x86/x64 Windows 8.x で開発して、最後に(必要に応じて)ARM デバイスでリモート デバッグするスタンスなので、Windows Phone アプリを XNA で開発していた頃と同じく、ほとんどストレスなくスムーズに開発できる。
Windows ストア アプリでは OpenGL/OpenGL ES は使えないが、Direct3D 11.1 の Feature Level 9_x は OpenGL ES 2.0 よりも多くの GPU Feature が使えるようになっている。
ハードウェアさえ対応していれば、Feature Level 10 のジオメトリ シェーダー・コンピュート シェーダーや Feature Level 11 のハル シェーダー・ドメイン シェーダー・コンピュート シェーダーを使うこともできる。

OpenGL ES のほうは 3.0 時点でもいまだジオメトリ シェーダーすら対応してないが、Direct3D 11.1 はハードウェアとアプリさえ対応すれば、API セットの変更は一切要らない。ハードウェア側の Feature Level 9~11 に応じて、必要とあればより高度な機能を使ってグラフィックス品質や性能を向上させることができる。まぁ ES 規格自体はそのうち PC 向けの本家 OpenGL 規格と完全統合されて、モバイルとかの組み込みでも OpenGL 4.x や 5.x のダウンレベル プロファイルを使うようになると思うけど。
また、ARM 版 SSE である NEON 拡張命令に関しても、Windows SDK 8.x にはそのラッパー API である DirectX Math が存在し、x86/x64 では SSE2、また ARM では NEON を使うようにすることが簡単にできる。
あと、Android の Dalvik + Java + C/C++ (NDK) よりも、Windows .NET + C# + C++/CX のほうがずっとスマートで連携しやすい(JNI よりも WinRT のほうがオブジェクト指向コンポーネント指向的)。
.NET の VMJIT コンパイラが生成したネイティブ コードを実行するので、C#VB.NET だけでもたいていの場合十分な速度が出る。

あと、GLSL しか使ったことがない人には分からないと思うが、現時点でのシェーダー言語およびシェーダー開発環境としての完成度は

HLSL>>NVIDIA Cg>>>>>>>>GLSL

だと思う。特に GLSL のオフライン コンパイラが存在しないこと(共通のバイトコード規格が存在しないこと)は HLSL に比べて大きく遅れをとっている。ちなみになぜNV Cgを低評価しているかというと、一般公開されてる最終版のVer.3.1 (April 2012) ではCompute Shaderのサポートがないから。

最後に、現行の Android エミュレータではスクリーンのマルチタッチ ジェスチャーをマウスでエミュレートできないんだが、これはどう考えても怠慢としか言いようがない。ちなみに Visual Studio 2012/2013 を Windows 8.x にインストールし、アプリを Simulator モードでデバッグ開始すると、Microsoft.Windows.Simulator.exe という OS 自身をシミュレートするシミュレータ上でアプリをデバッグ実行できるようになる。こいつはかなり優秀なシミュレータで、実行中の解像度の変更や、マウスによるマルチタッチ操作のエミュレーションも可能となっている。概要は下記を参照。
シミュレーターでの Windows ストア アプリの実行

Android アプリは快適なクロス開発環境を構築するのはかなり骨が折れるが、Windows ストア アプリは素人でも Windows 8.x に Visual Studio 2012/2013 をインストールするだけで快適に開発可能となる。
やはり有償 OS には開発元による開発者向けの手厚いサポートという非常に大きなメリットがある。

しかし Eclipse(と Java)は使いづらいな……
あとなんでデフォルトで BOM 付き UTF-8 エンコードを使わないのか……

みんなよくこんな貧弱な開発環境で Android 開発できるよな……どう見てもマゾすぎだろ……

ちなみに自分は iPhone ユーザーですが、Mac/iPhone 開発に関しては知りません。あまり興味ないし。実は Apple 嫌いだし。というか Apple 信者が嫌いだし。Objective-C とかいうおぞましい言語なんぞ見たくもないし。iPhone を選んだのも、Windows Phone の日本展開があまりに遅いのと、Android は(今のところ個人では)絶対に使いたくなかったから仕方なく iPhone 選んだだけです。