D3D Shader/OpenGL」カテゴリーアーカイブ

Android Wear 3D のアナログ時計 (Watch Face)

OpenGL ES 2.0/3.0 でウオッチフェイスを作ってみました。
3D で動きまわります。

imclock01.jpg
imclock02.jpg

Google Play “3D imclock for Android Wear”
3D imclock

● Install 方法

連動している Smartphone/Tablet (Handheld 端末) にインストールします。
Android Wear (Wearable 端末) にも自動的に転送が行われます。

● 時計の切り替え方

時計画面の長押し、またはメニューから変更できます。
メニューの「設定」から「ウオッチフェイスの変更」

● 描画更新について

Android Wear はスリープ中も時計表示が可能ですが、
バッテリー消費を抑えるために描画の更新速度が大幅に遅くなっているようです。
およそ 1分間隔の更新となっており、それ以外は止まっています。

・通常時 60fps
・スリープ中 0.016fps

内蔵の Watch Face がスリープ中に秒の表示を消している理由がわかりました。

ただし adb で接続している間は別で、画面が暗くなっても完全には停止せずに
描画更新が行われています。
デバッガの通信のために本当の意味でのスリープに移行できないためだと思われます。
USB 接続、Bluetooth 経由の adb 接続どちらでも同じでした。

また作っていて気がついたのですが、
Bluetooth 圏内の場合はスリープへの移行に若干タイムラグがあります。
画面が暗くなったあともしばらくは描画更新が続いており、
連動端末と何らかの通信が行われている可能性があります。

Bluetooth 非接続の場合は特に何もすることがないので、
スリープに入るとすぐに描画更新が停止してしまうようです。

このアプリは平常時 30fps で動作しています。
スリープ中はアニメーションできないので、秒針を消すと同時に
基準の位置に戻す処理を入れています。
ただし Bluetooth 圏外では完全に戻りきる前に画面が止まってしまう場合があるようです。

オリジナルの Windows 版はこちら 3D IM-clock

関連エントリ
Android Wear の 3D 描画 と NDK r10
Android Wear にゲームを移植
Android Wear LG G Watch (LG-W100) の速度(実測)
Android Wear LG G Watch (LG-W100)
Android Wear LG G Watch の GPU

Android Wear の 3D 描画 と NDK r10

Android Wear で flatlib3 の Model data Viewer を起動しています。
OpenGL ES 3.0 を使用。

lgw100_flview1.jpg

lgw100_flview2.jpg

NDK r10 で 64bit と OpenGL ES 3.1 に対応しています。
コンパイルは通りましたがテスト環境がまだありません。
ABI は下記の通り。(こちらにまとめています)

Android
---------------------------------------------------
armeabi            ARMv5TE     32bit --
armeabi-v7a        ARMv7-A     32bit VFPv3-D16
armeabi-v7a-hard   ARMv7-A     32bit VFPv3-D16
arm64-v8a          ARMv8-A     64bit AArch64 NEON
x86                IA32/x86    32bit SSSE3
x86_64             AMD64/x64   64bit SSE4.2
mips               MIPS32 R1   32bit FPU
mips64             MIPS64 R6   64bit
iOS
---------------------------------------------------
armv6              ARMv6       32bit VFPv2
armv7              ARMv7-A     32bit VFPv3-D32 NEON
armv7s             ARMv7-A     32bit VFPv4-D32 NEON
armv64             ARMv8-A     64bit AArch64 NEON
i386               IA32/x86    32bit SSE
x86_64             AMD64/x64   64bit SSE

関連エントリ
Android Wear にゲームを移植
Android Wear LG G Watch (LG-W100) の速度(実測)
Android Wear LG G Watch (LG-W100)
Android Wear LG G Watch の GPU

OpenGL ES 3.1 対応 GPU

Khronos より 2014/07/11 現在、OpenGL ES 3.1 に対応している GPU。

Intel HD Graphics Atom Z3700/N/J
ARM Mali-T760
ARM Mali-T628
ARM Mali-T604
PowerVR Rogue G6230/6200
PowerVR Rogue G6430/6400
Vivante GC7000
NVIDIA Tegra K1
NVIDIA GeForce 600/700/800M
NVIDIA Quadro K

OpenGL ES 3.0 世代の GPU もそのまま 3.1 にも対応しているので、
今後増えていくと思われます。
Intel HD Graphics (BayTrail/IvyBridge 世代) は OpenGL 4.0/4.1 止まりで
ComputeShader に対応していませんでした。
OpenGL から ComputeShader を使えるようになるのは ES 3.1 の方が先かもしれません。

実際に利用するには OS/SDK/Driver 等の対応が必要になります。
Android L 以降で対応予定。
iOS の場合 ES 3.1 ではなく PowerVR G6430 向けに Metal が発表されています。

関連エントリ
CPU 負荷が低い 新しい 3D API
OpenGL ES 3.1 は OpenGL 4.x 相当で ComputeShader に対応

Android Wear LG G Watch の GPU (スペック)

LG G Watch を入手したので CPU/GPU を調べてみました。
プロセッサは Snapdragon 400 MSM8226、1.2GHz で 4 core あります。
GPU は Adreno 305。
Low End ですが 300番台なので OpenGL ES 3.0 に対応しています。

SmartQ ZWatch は Single Core かつ 3D GPU も無かったので、
比較すると LG G Watch がかなり高性能に見えます。
RAM 容量以外はおそらく低価格帯のスマートフォンと同等でしょう。
2014/07/11修正 (実測結果)

Smart Watch スペック一覧

その代わり Z Watch のような Wi-Fi やヘッドホン端子は無く、単独での利用は考えられていません。
通信は Bluetooth だけ。ペアリングした親機 (Android 端末) が必要です。

Android Wear では adb も親機を介した bluetooth 経由で接続できるようになっています。
付属の充電クレードルを使えば、今までどおりの USB 接続もできるようです。

LG G Watch Android 4.4W
Qualcomm Snapdragon 400 MSM8226
Cortex-A7 1.2GHz Quad core, Adreno 305
RAM 512MB

-------------------
CPU
-------------------
processor	: 0
model name	: ARMv7 Processor rev 3 (v7l)
BogoMIPS	: 38.40
Features	: swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt 
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x0
CPU part	: 0xc07
CPU revision	: 3

processor	: 1
model name	: ARMv7 Processor rev 3 (v7l)
BogoMIPS	: 38.40
Features	: swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt 
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x0
CPU part	: 0xc07
CPU revision	: 3

processor	: 2
model name	: ARMv7 Processor rev 3 (v7l)
BogoMIPS	: 38.40
Features	: swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt 
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x0
CPU part	: 0xc07
CPU revision	: 3

processor	: 3
model name	: ARMv7 Processor rev 3 (v7l)
BogoMIPS	: 38.40
Features	: swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt 
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x0
CPU part	: 0xc07
CPU revision	: 3

Hardware	: Qualcomm MSM 8226 DORY (Flattened Device Tree)
Revision	: 0007
Serial		: 0000000000000000



-------------------
GPU
-------------------
GL_VERSION: OpenGL ES 3.0 V@84.0 AU@  (CL@)
GL_RENDERER: Adreno (TM) 305
GL_VENDOR: Qualcomm
GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 3.00

Extension:
GL_AMD_compressed_ATC_texture
GL_AMD_performance_monitor
GL_AMD_program_binary_Z400
GL_EXT_debug_label
GL_EXT_debug_marker
GL_EXT_discard_framebuffer
GL_EXT_robustness
GL_EXT_texture_format_BGRA8888
GL_EXT_texture_type_2_10_10_10_REV
GL_NV_fence
GL_OES_compressed_ETC1_RGB8_texture
GL_OES_depth_texture
GL_OES_depth24
GL_OES_EGL_image
GL_OES_EGL_sync
GL_OES_EGL_image_external
GL_OES_element_index_uint
GL_OES_fbo_render_mipmap
GL_OES_fragment_precision_high
GL_OES_get_program_binary
GL_OES_packed_depth_stencil
GL_OES_depth_texture_cube_map
GL_OES_rgb8_rgba8
GL_OES_standard_derivatives
GL_OES_texture_3D
GL_OES_texture_float
GL_OES_texture_half_float
GL_OES_texture_half_float_linear
GL_OES_texture_npot
GL_OES_vertex_half_float
GL_OES_vertex_type_10_10_10_2
GL_OES_vertex_array_object
GL_QCOM_alpha_test
GL_QCOM_binning_control
GL_QCOM_driver_control
GL_QCOM_perfmon_global_mode
GL_QCOM_extended_get
GL_QCOM_extended_get2
GL_QCOM_tiled_rendering
GL_QCOM_writeonly_rendering
GL_EXT_sRGB
GL_EXT_sRGB_write_control
GL_EXT_texture_sRGB_decode
GL_EXT_texture_filter_anisotropic
GL_EXT_multisampled_render_to_texture
GL_EXT_color_buffer_float
GL_EXT_color_buffer_half_float
GL_EXT_disjoint_timer_query

下記のページを更新しました
CPU/GPU OpenGL ES Extension (Mobile GPU)
SmartWatch スペック一覧

2014/07/11訂正: 実測結果より cpu0 しか使われておらず実質 single core 700MHz 相当でした(詳細はこちら)

関連エントリ
Android SmartWatch ZWatch で 3Dゲーム (ChiRaKS)
Android SmartWatch スマートウオッチのスペック比較表
Android SmartWatch SmartQ ZWatch (4) アプリの管理
Android SmartWatch SmartQ ZWatch (3) 腕に関数電卓
Android SmartWatch SmartQ ZWatch (2)
Android 4.1 SmartWatch SmartQ Z Watch

CPU 負荷が低い 新しい 3D API

昨年の AMD Mantle を皮切りに DirectX 12 が発表され、
つい先日 Apple から Metal も登場しました。
DirectX 11 以降停滞かつ安定していた状態から一変、
新しい GPU 向け API への流れが加速しつつあります。
どれも DirectX11, OpenGL とは互換性がない全く新しい API セットです。

これまでと趣が大きく異なっているのは CPU のための刷新だということ。
新しい描画機能への対応はなく GPU へのハードウエア追加も特に求められていません。
目的は CPU 負荷の軽減です。

API           Platform   Beta SDK   GPUs
-------------------------------------------------------------
Mantle        Windows    2014/5     RADEON GCN
Direct3D 12   Windows    ?          GCN,Fermi,Kepler,Maxwell
Metal         iOS 8      2014/6     PowerVR G6430

それだけ CPU の負荷の高さが問題になっていたことになります。

これまでは共通 API の互換性の代償として厚いドライバのレイヤーが存在し、
さらに性能向上により CPU が転送するコマンドの規模も大きくなりました。
Multi Core CPU が当たり前となっているにもかかわらず、
旧態依然とした OpenGL はスレッドによる最適化を阻んでいます。

ドライバのオーバーヘッドは、ゲーム専用機 (Game Console) と汎用機
PC/Smartphone の大きな違いの一つとなっていました。

●シンプルに

固定機能は段階的に減っていき、3D 描画に必要なアルゴリズムのほとんどが
アプリケーション側のソフトウエアで実装されるようになりました。
汎用化が進んで GPU の用途が広がると、既存の高度な機能やドライバの手厚い保護が
かえってプログラミングの自由を妨げることがあります。

GPU はもともと進化が早く、機能も性能も使われ方も短期間で変化してきました。
Desktop から Mobile に移っても同様です。
高度なレベルで統合された API は大きな変化についていくのが困難になります。
何でもやってくれる命令は便利ですが、ある程度使われ方が決まっていないと
仕様を決められないからです。
変更が頻繁に行われるほど設計はよりシンプルになり、依存を減らす方向に進みます。

Direct3D 10 では Shader の統合やリソースの Buffer 化といった改革が行われました。
実際に使ってみるとリソース管理は思ったより簡単ではない事に気が付きます。
Resource View には細かなフラグ設定が必要で、
慣れるまでは組み合わせの制限に悩まされました。
本当に自由に感じたのは Direct3D 11 の ComputeShader からです。
用途もデータの仕様もすべてプログラマが決められます。

Texture Atlas は複数のテクスチャを巨大なテクスチャに統合します。
中の配置をプログラマが自分で管理しなければなりませんが、
その代わりシェーダーは uv だけで好きなテクスチャを読み出すことが可能です。
もし仮に GPU のメモリ全部を巨大な 1 枚のテクスチャとみなすことができたら
uv はポインタとほとんど同じものになるでしょう。
現状リソース管理はプログラマに開放されていませんが、
Texture Atlas は制限を超えるための手法の一つとみなすことが出来ます。

OpenGL の Shader 命令は DirectX よりもかなり後にデザインされたものなので、
Uniform の配置やシェーダー同士のバインドも自動化されています。
OpenGL 3.x 以降はメモリ配置をプログラマが決められるようになり、
4.x 以降はシンボルのバインドも単純な番号指定に置き換わりつつあります。
Direct3D の低レベル命令に近づいています。

GPU は汎用性を増していますが、互換性を維持した積み重ねは
必要以上に複雑になってしまうことがあります。
新しい API では、CPU 負荷の低減と同時に
よりシンプルで使いやすい API への回帰も期待できます。

● Command Buffer

描画時に CPU が行っているのは Command Buffer の構築です。
いわば GPU (Command Processor) が実行するプログラムそのもので、
アプリケーションは毎フレーム動的にプログラムを生成していることになります。

ドライバはできるだけ GPU の性能を引き出すように作られているので、
無駄な Command を省くなどの最適化が行われます。
ハードウエア毎に構造が異なるので、GPU Native な形式への変換も必要になります。
GPU Command の生成と発行はそれなりにコストがかかります。

ステートの値が必要になるのは Draw のタイミングなので、
Command の生成は描画命令まで遅延します。
Draw 命令に負荷が集中して見えるのはそのためです。

各種 Buffer 化は Command 負荷軽減手段の一つとなります。
パイプラインステートだと描画のたびに Command Buffer に書き込まれますが、
Buffer なら予め転送しておいたリソースをアサインするだけで済むからです。

●ゲーム専用機 (Console)

ゲーム専用機では PC と事情が大きく異なります。

 ・互換性の枷がない
  ・ハードウエア互換性が不要 (ハードは単一)
  ・ソフトウエア互換性を持たない (SDK の上位互換性を持たない)
 ・必要に応じてより低レベルな最適化手段が用意されている
 ・ハード内部の情報がある程度公開されている

ゲーム専用機は数年サイクルでリフレッシュされ、互換性の確保には
専用ハードウエアまたはソフトウエアエミュレーションが用いられます。
そのためソフトウエア (SDK) 互換性があまり重要ではありません。

最初から GPU Native な形式を使用できることもあり、
CPU のオーバーヘッドも PC と比べるとかなり低くなっています。

必要に応じてより低レベルな最適化が可能なことも専用機の特徴です。

最近は少ないと思いますが、例えば GPU Command を直接操作できるなら
事前にモデルデータを GPU Native な Command 形式に変換しておくことが出来ます。
メモリに Buffer Data と Command Buffer をロードするだけで描画が可能となります。
動的な Command 生成と比べて CPU 負荷はほとんど生じません。
(ただしいくつかのトレードオフが発生するので必ずしも最善とはいえない)

ハードの内部構造がある程度公開されている点もプログラマの負担を減らしてくれます。
描画アルゴリズムの設計時に内部の仕組みがわかっていれば、
どの方法が効率が良いのかある程度判断できるからです。
あまり迷わなく済みます。

●互換性とこれから

・ゲーム専用機との差が小さくなる
・API の分裂

新しい API は今の CPU/GPU 性能と使われ方に合わせた再設計が行われます。
全体的な動作効率があがり、CPU オーバーヘッドの低減などパフォーマンス特性は
よりゲーム専用機に近づいていくものと考えられます。
その反面、現状ではプラットフォームごとに仕様が分断されており、
互換性においては新たな課題が残ります。

OpenGL ES 2.0 はモバイルからブラウザまでプラットフォームの枠を超えて
用いられており、統一された API として大きな意味を持っていました。
今後同じように OpenGL ES 3.0/3.1 が広く用いられるようになるのかといえば
必ずしもそうではないようです。
特に iOS の場合は Metal 対応デバイスと一致しているため、
性能や機能のために OpenGL ES 3.0 を選ぶメリットが無くなりました。

                                      ES2.0  ES3.0  Metal
----------------------------------------------------------
Apple A5/A6    PowerVR SGX543/554       Y      -      -
Apple A7       PowreVR G6430            Y      Y      Y

Android の ES 3.0 や Desktop の OpenGL 4.x と互換性を保つためには必要ですが、
性能や使いやすさを優先するなら Metal が選ばれる可能性が高まります。
用途に応じた使い分けが行われるでしょう。

とはいえ各種プラットフォームへの個別対応は大変です。
OpenGL なら Low Overhead Profile や Multi thread Extension のような、
プラットフォームを超えた新しい仕様が登場することを期待します。

関連ページ
3D Low overhead API