效能優化工具知識梳理(3) 除錯GPU過度繪製 & GPU呈現模式分析

澤毛發表於2017-12-21

一、概述

今天,介紹兩個比較簡單的效能優化工具:

  • 除錯GPU過度繪製
  • GPU呈現模式分析

其實這兩個工具所解決的問題並不相同,之所以把它們放在一起,是因為它們都是Android手機自帶的分析工具,我們只要在設定中對應的開關,就可以實時獲得分析的結果,下面,我們就一起來看一下如何使用它們。

二、除錯GPU過度繪製

2.1 應用場景

這個工具主要是用來檢查佈局中是否存在佈局層次過深的問題。 首先,說明一下什麼叫過度繪製,過度繪製指的是螢幕中同一個畫素點被繪製了多次,舉個例子,我們有一個紅色ViewB,它先被繪製了一次,也就是說它所在區域的每個畫素點都被繪製成了紅色,這時候有一個藍色ViewA,它蓋在ViewB的上面,所以我們需要再把每個畫素點都繪製成藍色,這其實是不必要的,出現這種情況的時候,我們就可以通過這個工具來避免這種情況的發生。

2.2 使用方式

使用方式很簡單,進入設定/輔助功能/開發者選項/,點選除錯GPU過度繪製選項,在彈出框中選擇第二項:

效能優化工具知識梳理(3)   除錯GPU過度繪製 & GPU呈現模式分析
開啟開關之後,可以看到介面當中會出現各種顏色的矩形,這就對應著過度繪製的等級,顏色越深,表明過度繪製越嚴重,也就是說同一個畫素點被重複繪製的次數過多,下面,我們用一個簡單的例子,來看一下過度繪製的等級。 首先看一下我們的佈局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="browser.android.com.repoperformance.OverDrawActivity">
    <FrameLayout
        android:id="@+id/fl_1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="100dp"
        android:background="@android:color/white">
        <FrameLayout
            android:id="@+id/fl_2"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginBottom="100dp"
            android:background="@android:color/white">
            <FrameLayout
                android:id="@+id/fl_3"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginBottom="100dp"
                android:background="@android:color/white">
                <FrameLayout
                    android:id="@+id/fl_4"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_marginBottom="100dp"
                    android:background="@android:color/white">
                    <FrameLayout
                        android:id="@+id/fl_5"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_marginBottom="100dp"
                        android:background="@android:color/white"/>
                </FrameLayout>
            </FrameLayout>
        </FrameLayout>
    </FrameLayout>
</RelativeLayout>
複製程式碼

我們佈局呈現為逐級巢狀的層次,並且從fl_1開始都有一個白色的背景,那麼我們看一下開啟了除錯GPU過度繪製開關之後的結果:

效能優化工具知識梳理(3)   除錯GPU過度繪製 & GPU呈現模式分析

從上面的圖中可以看到,fl_1的白色繪製是正常的,而fl_2fl_1在由於有100dp的重疊區域,因此這部區域被檢測成為了藍色,而fl_3fl_1/fl_2都有重疊,因此這部分割槽域被檢測成為了綠色,fl_4fl_5也是同理。 通過上面的例子,可以看到檢測的結果分為四個等級,從低到高分別是:

  • 藍色
  • 綠色
  • 淺紅
  • 深紅

在開發當中,我們在設計完介面之後,就應當通過這個工具來檢測一下,看能否在保證實現功能的前提下,避免出現過度繪製。

三、GPU呈現模式分析

3.1 應用場景

當開啟這個工具之後,會在螢幕的底端展現當前介面的繪製情況,GPU呈現模式分析有以下幾點作用:

  • 檢視每一幀的渲染是否達到16ms的要求
  • 分析一幀的渲染過程各階段的耗時
  • 因為它是實時展現的,因此我們可以快速到問題產生的原因

這個工具的使用方法和上面類似,同樣是進入開發者選項中,然後點選GPU呈現模式分析,選擇“在螢幕上顯示為條形圖”。

3.2 使用詳解

Android 6.0之前和之後,GPU呈現的模式會有所不同,區別在於6.0之後,它將整個繪製的階段更加細分,讓開發者能夠更方便的定位問題。

  • 基礎 無論是在6.0之前還是之後,這個工具的原理都是相同的。因為系統每隔16ms就會發出一次VSYNC訊號,通知重新整理UI,如果在16ms之內沒有完成繪製,那麼就必須等到下一次,這就會導致在很長一段時間內,看到的都是同一個畫面,也就是我們所說的”卡頓”,介面的展示就是基於這個原理:

  • 柱狀圖:柱狀圖的每一根的高度就表示渲染這一幀的耗時,當渲染的時間越長,則柱狀圖的高度越高。

  • 基準線:我們在介面上並不能看到柱狀圖對應的時間,而是通過在柱狀圖上方的基準線來判斷是否超過了標準的時間,基準線對應的就是16ms,如果柱狀圖的高度在基準線的下方,那麼就表示這一幀繪製的時間小於16ms

  • Android 6.0之前 在這個6.0版本之前,我們將柱狀圖分為以下幾個部分:

    效能優化工具知識梳理(3)   除錯GPU過度繪製 & GPU呈現模式分析

  • 藍色Update 這部分代表View建立和更新DisplayList的時間,如果這部分很高,那麼表示我們有很多自定義的View,或者在onDraw當中進行了過於複雜的操作。

  • 紫色XFer 這部分在Android 4.0之後才有,表示將資源傳遞到渲染執行緒所花的時間。

  • 紅色Execute 這部分代表Android 2D渲染器向OpenGL傳送命令來繪製和重繪的時間,這些命令就是來自於前面生成的Display List,如果這部分很高,那麼說明執行Display Lists中的命令花費了很多的時間。

  • 黃色Process 這部分代表了CPU等待GPU完成操作所花的時間,如果這部分很高,那麼說明GPU當前很忙碌。

從上面的解釋當中,我們可以發現,雖然說這個工具的名字叫做GPU呈現模式分析,但是我們獲得的所有資訊都是來自CPU的,也就是說,我們是從CPU的角度來間接地分析出當前渲染需要處理的資訊。

整個渲染的過程是通過CPUGPU發出命令,再由GPU去非同步地渲染螢幕。在某些情況下,由於GPU有太多的工作要做,那麼就會導致CPU需要一直等待才能發出新的命令,而當這種情況發生的時候,我們就會看到橙色和紅色的部分特別長。

關於6.0之前各顏色的解釋來自於官方文件:

http://android.xsoftlab.net/tools/performance/profile-gpu-rendering/index.html

  • Android 6.0之後 在Android 6.0 之後,變為了現在的八個部分:
    效能優化工具知識梳理(3)   除錯GPU過度繪製 & GPU呈現模式分析
    其中,如果新增部分的圖形高度較高,那麼表示:
    • Misc/Vsync Delay 我們在主執行緒當中執行了過多的操作,導致跟不上VSYNC訊號。
    • InputHandling 我們在處理使用者輸入的地方做了過多的操作。
    • Animation 我們在執行動畫的過程中進行了耗時的操作。
    • Measure & Layout: 我們的佈局過於複雜,以至於在測量和佈局的過程中耗費了過多的時間。
    • Sync & Upload: 準備當前介面中有待繪製的圖片所耗費的時間過長。

6.0之前所保留下來的對應關係為:

效能優化工具知識梳理(3)   除錯GPU過度繪製 & GPU呈現模式分析

關於6.0之後各顏色的解釋來源於:

http://hukai.me/android-performance-patterns-season-5/

四、小結

這篇文章,主要還是著重於介紹如何使用這兩個工具,因此,關於整個渲染的原理也只是一筆帶過,之後會專門詳細的分析。


更多文章,歡迎訪問我的 Android 知識梳理系列:

相關文章