上一篇有提到 Unity 內建的的 Profiler 在繪圖分析方面有所不足之處,但這個可以用 Android 各家 GPU 原廠的工具來補足。因為每一家的工具都只能拿來分析自家的晶片,所以最一開始要先了解自己的機器用的是哪家的 GPU 。

一般來講常見的有

  • Qualcomm: Adreno
  • Intel: HD Graphics
  • Imagination: PowerVR
  • ARM: Mali
  • Nvidia: Tegra

然後這裡只會介紹 Intel 跟 Qualcomm 的工具,因為只有這兩家的工具不需要 root 機器,我自己對 root 完全沒有概念也不太敢用那些工具。Nvidia 有提供不需要 root 的 static library 作為替代方案,但是因為我還沒有辦法把那個特殊的 OpenGL library 跟 Unity 匯出的 Android Studio 專案整合,所以目前也沒有辦法介紹。國外有一篇所有平台的啟動教學在這裡,如果對於 root 比較在行的朋友可以參考那篇。

知道這些 GPU 的名稱也有助於 Android 上面的除錯,因為有些問題是特定的晶片才會有的。像是老一點的 Adreno 用 Unity 的 Stencil 會有裁切不完全的問題,然後 Tegra 在 16-bit back buffer 開啟的狀態下 Color banding 的問題比其他家都還嚴重。知道 GPU 晶片有助於除錯,讀 Unity Release Note 的時候也比較方便知道是不是同一個問題、有沒有被修掉這樣。

OpenGL Extension Viewer

機器用的 GPU 晶片通常可以從 Wiki 上面找到,但是不時還是會有像是 Galaxy S3 那種不同區域或是不同批次使用不同 GPU 的情況。我通常會裝 OpenGL Extension Viewer 這個 App 來看,這樣就連晶片版本都一目了然了。

OpenGL Extensions Viewer

Adreno Profiler

這個我是能讓它執行繪圖分析的工作,但是因為不是我慣用的工具所以就大略介紹到能看到最重要的 GPU clock 這樣,其實這些 GPU 分析工具能做到的功能大多相同,所以概念知道了應該都能應用。

P.S. 有個我還沒有弄很清楚的點是高通官方說要有 libq3dtools_adreno200.so 這個檔案在 /system/lib/egl/ 下面的機器才支援 Profiler ,但是我手邊的 Nexus 7 下了:

adb shell ls -l /system/lib/egl/

沒有找到東西卻還是可以分析,這個可能要很熟 Adreno 的朋友講解了。

如果要試著分析的話首先是到高通的網站申請免費帳號然後下載 Adreno GPU Profiler

https://developer.qualcomm.com/software/adreno-gpu-profiler

安裝工具之後檢查遊戲有沒有在 AndroidManifest 加入網路權限

1
<uses-permission android:name="android.permission.INTERNET"/>

然後 需要 Development Build,Release build 也可以直接 Profile。

把遊戲裝到機器上,從 ADB 介面下啟動指令:

1
adb shell setprop debug.egl.profiler 1

在手機上把遊戲先開起來,如果成功的話進到工具然後點左上角的 Connect 會看到像是下圖有可連線目標的狀態:

Adreno Connect

如果連線成功的話按一下 Scrubber GL 會看到以下的介面

Adreno Scrubber

不過在 Capture 之前要先把最重要的指標 GPU clocks 開出來,Capture 之後才開是不會有資料的,選單如下圖:

Adreno GPU Clock

開好之後就可以按下 Capture frame ,會看到每一個 OpenGL draw call 跟相應的 GPU 使用量,然後我們就可以接下來的繪圖最佳化討論了。

Adreno Capture

Intel Graphics Frame Analyer

這個是我目前慣用的 GPU profiler,不過尷尬的點是因為是 Intel 的工具,所以很自然地只支援 Atom CPU 的 Android 機器。然後要看到 GPU clocks 需要連 GPU 都是 Intel 的,使用 Intel GPU 的 Android 機器非常少見,目前我用的是  Lenovo Yoga Tablet 2,不過我手上這台不知道什麼問題不能 Frame capture ,所以有另一台 Dell Venue 8 作為 Capture 之用。

首先也是到官方網站下載工具

https://software.intel.com/en-us/gpa

然後一樣也是需要網路的權限:

1
<uses-permission android:name="android.permission.INTERNET"/>

Intel Graphics Frame Analyzer 一樣是可以分析 Release build,不過需要有 android:debuggable flag。Unity 在建置 Release build 的時候會自動把 debuggable 拿掉,直接幫 Unity 專案裡的 AndroidManifest 加 flag 沒有用,所以變成要先匯出成 Android Studio 專案然後手動再編輯 AndroidManifest 然後 build。

一開始分析對象會定在電腦模擬器上面,從最上面的選單切換到要做 Frame capture 的機器,然後按下 Add 新增 Frame capture。

Intel Add Frame

跟 Adreno 相反,Intel GFA 是要先把 App 關掉,然後從電腦上下指令啟動 Analyzable app。沒有 android:debuggable 的 App 會被放到 Non-analyzable 的區域裡。

Intel Analyzable List

執行起來後看 Android 機器上的畫面,適合的時候就按下 Capture 按鈕抓取。

Intel Capture

抓取之後的 Frame 資料會一直保留在電腦上,隨時都可以再拿出來分析,同時可以轉移到任何別的 Intel Atom CPU 的機器上重現,如果有注意看的話可以發現下圖接的機器已經從 Dell Venue 8 換成 Lenovo Yoga 了。

直接在 Frame 上面連點就會開始分析。

Intel Captured Frame

分析之後的結果會像是這樣:

(如果不是 Intel 的 GPU 的話 Draw Call 還是能分析,但是最重要的 GPU 使用時間會沒有辦法顯示,上面的長條圖會都一樣長。)

Intel Profiler

點選每個步驟都能看到所有的參數跟所有的輸出,包含 Render target、Depth、Stencil(小抱怨一下,Intel GFA 的 Stencil 還是當 0 ~ 255 的灰階圖顯示,所以 Stencil 值是 0 跟 1 的時候很不明顯,要用滑鼠去指在圖上然後從狀態列看灰階值)

Intel Draw Calls

然後點下上一張圖框起來的箭頭可以進到更詳細的分析:

從模型到 Vertex Shader 到 Rasterization 到 Fragment Shader 再到輸出都可以觀察,這邊停在 Fragment Shader 階段,可以看到右邊有反組譯的 Shader code。

Intel Decompile

有了這些資料終於可以做繪圖的最佳化了。以上是非常粗略的設定介紹,然後感覺知道這些工具好用之處的人不多,所以大概展示了一下功能。接下來會講解一下繪圖的原理,然後就是各種所謂的 Hack 了。

工具設定很多是參考這篇上面有提過的 GPU profiler 教學:

http://blog.toonormal.com/2013/11/14/gpu-debugging-on-android-devices/

Adreno 的說明書找不到線上的版本,在工具開啟的狀態下按下 F1 可以找到離線版的說明書。

Intel 這邊其實官方教學很多,如果英文聽讀不是問題的話其實看原廠的教學會好很多

https://software.intel.com/en-us/videos/android-opengl-es-workflow-intel-graphics-performance-analyzers

還有一篇熱騰騰上個月才出的針對 Unity 的效能調整教學,不只有 Intel GFA、還有 Unity 內的教學

https://software.intel.com/en-us/articles/unity-software-performance-optimizations-for-games-best-practices