OpenGL ES チューニングのためのメモ

OpenGL ESを使ったアプリのチューニングについて、
予習としてXcodeやInstrumentsの使い方をメモ。

実際に使ってみた上でのチェックポイントや良かったプラクティス等、随時追記していきます。

## Instrumentsでボトルネックを診断
### OpenGL ES Analyzer を使った自動診断
Instrumentsの"OpenGL ES Analyzer"というテンプレートを使うと、リソースの使われ方や問題になりそうなところを診断してくれます。

はじめに"Xcode" -> "Open Developer Tools" -> "Instruments"か ```cmd + i```でInstrumentsを起動します。

"OpenGL ES Analyzer"を選択して"Choose"をクリック。

この状態で、左上のボタンをクリックするとアプリが起動します。
一通り操作すると、問題になりそうな箇所をリストアップしてくれます。

### OpenGL ES Driverを使った絞り込み
"OpenGL ES Driver" テンプレートを使うと，各フレームごとに分割された以下の情報を取得できます。
* Device Utilization: デバイス（GPU）の使用率
* Renderer Utilization: Rendererの使用率
* Tiler Utilization: Tilerの使用率
* Core Animation Frames Per Sec: FPS

[Measuring Graphics Performance in Your iOS Device](https://developer.apple.com/library/mac/documentation/developertools/conceptual/instrumentsuserguide/MeasuringGraphicsPerformanceinYouriOSDevice/MeasuringGraphicsPerformanceinYouriOSDevice.html)の[Finding Bottlenecks with the OpenGL ES Driver Trace Template](https://developer.apple.com/library/mac/documentation/developertools/conceptual/instrumentsuserguide/MeasuringGraphicsPerformanceinYouriOSDevice/MeasuringGraphicsPerformanceinYouriOSDevice.html#//apple_ref/doc/uid/TP40004652-CH14-SW8)には、簡単なガイドとして以下内容が記載されています。

* Tiler Utilizationが高い場合（Geometry Limited）: 頂点シェーダの処理を確認してみましょう
* Renderer Utlizationが高い場合（Pixel Limited）: フラグメントシェーダの処理を確認してみましょう
* Tiler UtilizationとRenderer Utilizationのどちらも低い場合（CPU Limited）: ボトルネックはOpenGLの処理以外のところにありそう。全体のロジックを見直す方が良い

### Time Profilerを使った絞り込み
システム全体のパフォーマンスを測定するには、"Time Profiler" テンプレートが使えます。

"Time Profiler"テンプレートは，全てのプロセスを監視してバックトレースを取得します。
同じような目的のテンプレートに"Sampler"テンプレートがありますが、こちらは一つのプロセスだけ監視する為に使います。
評価したいアプリが一つのプロセスだけで完結する，という場合には"Sampler"が良いと思いますが……対象アプリ以外のプロセスや非同期な処理等も確認したい、という場合もあるのなら"Time Profiler"テンプレートを使うのが良いでしょう。

Time Profilerを使う場合、ある処理の開始〜終了までの処理を"Inspection Range"で絞り込むことができます。
使い方は簡単で、測定を停止した後
- Instrumentsの"Track"ペインで"プレイヘッド"を対象の処理がスタートした時刻に置く
- ```cmd + <```で開始箇所をマーク
- 対象の処理が終了したところに"プレイヘッド"を置く
- ```cmd + >```で終了箇所をマーク
すると、絞り込むことができます。

![profiler.png](https://qiita-image-store.s3.amazonaws.com/0/30970/2e0b055a-1462-639e-dcb0-5d8ae0a1f96a.png)

対象範囲をクリアしたい場合は```cmd + .```でクリアできます。

### 操作や処理開始等の目印を分かりやすくしたい
長い時間の操作を記録するとき、どのタイミングでどの操作を実行したか、どの処理を開始したかということは把握しづらくなります。
こういうとき、Instruments上でフラグを設定すると整理しやすくなります。
操作を実行するタイミングや処理を開始する、という時刻に"プレイヘッド"を合わせ、```cmd + ↓```でフラグを設定することができます。
フラグには任意の文字列を入力できるので、適当に分かりやすい名前をつけておくと後で整理しやすくなります。

![flag.png](https://qiita-image-store.s3.amazonaws.com/0/30970/0f7a83c9-06d8-e79d-0baf-e97bdf59004a.png)

### OpenGL ESのメモリリークを追いかけたい
OpenGL ES関連の処理でメモリリークの疑いがあるときは、```VM Tracker``` のテンプレートを使いましょう。
リークしていれば、```Dirty Size``` や ```Resident Size``` が徐々に増加していくはずです。

```Leaks``` のテンプレートでは、OpenGL ESで発生したリークを検知できません。
（おそらく仮想メモリに直接アクセスしているから？）

## XcodeのOpenGL ES Frame Debuggerで診断する
デバッガでアプリを起動した後，"Debug" -> "Capture GPU Frame"をクリックします。
この状態で測定したい機能を操作し続けると，自動的に"OpenGL ES Frame Debugger"が起動します。
起動後，レンダリングに使ったコマンド列やリソースの使用状況、パフォーマンスに影響していそうな処理の分析結果が表示されます。
また、iPhone5s等のOpenGL ES 3.0に対応したデバイスであれば、"Program Performance"で、ボトルネックになっている箇所を指し示してくれます。

なお、"Frame Debugger"というだけありフレームを更新する場合しか解析してくれません。
バックグラウンドでOpenGL ESの処理を行って、描画には使わないというケースでは使えないようです。

## 参考URL
[iOS OpenGL ES プログラミングガイド](https://developer.apple.com/jp/devcenter/ios/library/documentation/OpenGLES_ProgrammingGuide.pdf) 「OpenGL ESアプリケーションのチューニング」の辺り

### Instruments関連
[Measuring Graphics Performance in Your iOS Device](https://developer.apple.com/library/mac/documentation/developertools/conceptual/instrumentsuserguide/MeasuringGraphicsPerformanceinYouriOSDevice/MeasuringGraphicsPerformanceinYouriOSDevice.html)
[OpenGL ES Driver Instrument](https://developer.apple.com/library/mac/documentation/AnalysisTools/Reference/Instruments_User_Reference/OpenGLESDriverInstrument/OpenGLESDriverInstrument.html#//apple_ref/doc/uid/TP40011355-CH37)
[VM Tracker Instrument](https://developer.apple.com/library/mac/documentation/AnalysisTools/Reference/Instruments_User_Reference/VMTrackerInstrument/VMTrackerInstrument.html)

### Xcode関連
[Xcode OpenGL ES Tools Overview](https://developer.apple.com/library/ios/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/ToolsOverview/ToolsOverview.html)

### stackoverflowのOpenGL ES関連の質問
[stackoverflow - What does the Tiler Utilization statistic mean in the iPhone OpenGL ES instrument?](http://stackoverflow.com/questions/1287811/what-does-the-tiler-utilization-statistic-mean-in-the-iphone-opengl-es-instrument)
"OpenGL ES Driver Template"のTiler / Renderer Utilizationで取得しているデータの内容、どう見るべきかについて説明。

[stackoverflow - Understanding iPhone OpenGL Profiling](http://stackoverflow.com/questions/5751087/understanding-iphone-opengl-profiling)
"OpenGL ES Driver Template"だけでなく、他のテンプレートも組み合わせると良いよ、との回答あり。

### その他
[OpenGL wiki - Common Mistakes](https://www.opengl.org/wiki/Common_Mistakes)