http://blog.manbolo.com/2012/11/20/using-xcode-opengl-es-frame-capture 這里是原文,因為它版本比較老和它demo的限制,所以也想寫一個基於Xcode6上基於3d渲染的分析的教程

Xcode和Visual Studio的一個主要差別,還是再Xcode有一套免費的的性能工具,例如Instruments,不過對於圖形程序員來說,Xcode最強大的功能還是可以捕獲和分析OpenGL ES和最新Metal framewrok的Frame。這個工具叫GPU Frame Capture(Xcode6.x),可以查看OpenGL和Metal的緩沖,以及GLES Shader和Metal shader。這里也是一個如何再你的App上運用它的快速教程。
教程里的例子和代碼來源於UE4的Sun Temple 工程和Apple開發者網站上的MetalDeferredLighting工程
https://developer.apple.com/library/ios/samplecode/MetalDeferredLighting/Introduction/Intro.html
1 設置 GPU Frame Capture
這里是Apple開發文檔上關於GPU Frame Capture的簡介,
https://developer.apple.com/library/ios/documentation/ToolsLanguages/Conceptual/Xcode_Overview/chapters/about.html 如果要使用這個功能,至少要是Xcode4.5以上(Metal的話必須是Xcode6.x),而且必須是在真機上,並連接運行Xcode的Mac,如果渲染api是metal frame的話,必須是ios8的系統,iphone5s,ipad air,級別的設備上。
另外需要把GLKit或OpenGL Framework加入到代碼里,然后在菜單選擇Product > Manage Schemes,雙擊你的app的Scheme,然后進入編輯

點擊Run這個scheme,然后在Options的標簽上設置GPU Frame Capture,默認打開是Automatically Enabled,不過因為GLES和Metal同時存在的緣故,建議強制設置為OpenGL ES或Metal(例如基於UE4的app)。
2 捕獲 Frame
然后你就可以捕獲你要調試的app的Frame了,在Debug模式下運行App (Product > Run or ⌘R),當你的app在真機上完全加載后,就可以進入 Debug Navigator (View > Navigators > Show Debug Navigator,或直接點擊左側代碼欄上的小圖標),再點擊Debug Navigator上的FPS標簽

例如下圖,你可以看到你的App的更新的FPS顯示,以及左側不同的測試項目,而程序員的目標就是讓它達到60FPS,而我們的Sun Temple這個時候只有26FPS左右,需要我們找到性能的瓶頸

在編輯器里,我們可以看到CPU和GPU的消耗時間毫秒數,如果想要達到60 FPS,那么CPU和GPU時間應該只有16毫秒,30FPS的話是32毫秒,而這里例子里,CPU消耗38有些超過限制了。

從這里可以看出,我們的主要瓶頸不在GPU上,而是在我們的代碼調用上,為了獲得更好的信息,我們可以捕獲一個gputrace,來查看每幀渲染內部的具體流程,我們在Debug的輸出窗口上,點擊照相機圖標獲取整個Frame。

點擊Capture Frame圖標后(根據程序的大小捕獲需要等幾~十幾秒),你就可以在Debug Navigator里訪問OpenGL或Metal的Frame了

而在移動設備上,你可以看到程序顯示的事當前捕獲的那幀,並暫停了,在Debug Navigator上,如果你把不同的圖標
展開,也可以看到捕獲Frame內部的OpenGL/Metal調用,Debug Navigator會把與這幀(包括你的代碼調用棧)關聯的每一個Draw Call和State Call都顯示在編輯器面板上,而State的信息,也會顯示在下方的Debug面板上。

如果你沒有看到Object面板的話(藍框部分),可以點擊show assistant Editor,然后選擇想顯示的類型,如果Mac設備不是太好,而游戲又是類似UE4這種大型圖形程序,選擇All需要慎重。

你可以通過在整個buffer面板上右鍵選擇Show/Hide Draw Call Highlight,把當前draw call繪制的三角面用亮綠色高亮出來。

3 查看OpenGL/Metal的對象
在assistant編輯窗口,你可以訪問OpenGL對象,例如Buffer,VAO,以及綁定或未綁定的Texture,還有shader programes:

可以查看Array Buffer里的內容

點擊Shader,會顯示對應的shader源代碼

這樣就可以很簡單的獲得所有的shader代碼了
4 性能的改善
為了方便考慮,這里使用的之前u3d上一個IBL的優化案例,Cpature GPU Frame后,從圖中可以看到,這個app的瓶頸主要在GPU上的某個shader

那么我們需要對這個shader做優化,在這個program上雙擊,可以在輔助編輯器窗口看到shader代碼(可惜的是,UE4和Unity3d的shader都是用glsl-optimizer優化過的,可讀性並不是那么高了)

這里的textureLod是有些消耗的,第3項lod值是用來索引CubeMap的mip,來實現IBL材質的粗糙效果,這個我們把它改為1.0

點擊左下角的刷新圖標。然后就可以看到修改后的效果,下圖中,藍色的修改前的情況,綠色是當前的情況,修改為1.0后效率提高的原因,是如果一開始lod是定值的話,texture就再shader運行前pre fetch,就需要再每個像素的pixelshader里重復加載這個cubemap里,從而起到了優化的作用

然后,你可以回到Unity或UE4里,對shader源代碼再做一次修改,就起到了優化的作用了
5 保存和分享捕獲的Frame
最后,你可以導出和保存你捕獲的GPU Frame,不需要源代碼,就可以把它分享給其他人,例如一個可以電話幫你解決的OpenGL或Metal的專家
只是這種保存方式比較尷尬,目前還沒有更好的方式來保存,特別是在Xcode6.x版里。首先在菜單里選擇Navigator>Open in..

點擊左側的+的符號,然后給UE4Game.gputrace創建一個新的窗口
在新創建的窗口的(*.gputrace)的文字上右鍵 

你可以看到上圖第2個com.apple.dt.xxxxx里保存的就是.gputrace臨時保存的位置了,你可以把它保存到你的其他目錄下,如果你想重新打開或分享給其他人,只需要連接移動設備到你的Mac,並雙擊這個*.gputrace,然后可以在編輯器里看到下圖的對話框:

點擊Replay Trace,然后就會進入這個文件的保存的Frame模式里,非常方便
下篇應該就是UE4 SunTemple的教程了
