sponsored links

如何用 GPU硬體層加速最佳化Android系統的遊戲流暢度

作為一款VR實時操作遊戲App,我們需要根據重力感應系統,實時監控手機的角度,並渲染出相應位置的VR影象,因此在不同 Android 裝置之間,由於使用的晶片組和不同架構的GPU,遊戲效能會因此受到影響。舉例來說:遊戲在 Galaxy S20+ 上可能以 60fps 的速度渲染,但它在HUAWEI P50 Pro上的表現可能與前者大相徑庭。 由於新版本的手機具有良好的配置,而遊戲需要考慮基於底層硬體的執行情況。

如果玩家遇到幀速率下降或載入時間變慢,他們很快就會對遊戲失去興趣。
如果遊戲耗盡電池電量或裝置過熱,我們也會流失處於長途旅行中的遊戲玩家。
如果提前預渲染不必要的遊戲素材,會大大增加遊戲的啟動時間,導致玩家失去耐心。
如果幀率和手機不能適配,在執行時會由於手機自我保護機制造成閃退,帶來極差的遊戲體驗。

基於此,我們需要對程式碼進行最佳化以適配市場上不同手機的不同幀率執行。

所遇到的挑戰

首先我們使用Streamline 獲取在 Android 裝置上執行的遊戲的配置檔案,在執行測試場景時將 CPU 和 GPU效能計數器活動視覺化,以準確瞭解裝置處理 CPU 和 GPU 工作負載,從而去定位幀速率下降的主要問題。

以下的幀率分析圖表顯示了應用程式如何隨時間執行。

如何用 GPU硬體層加速最佳化Android系統的遊戲流暢度

在下面的圖中,我們可以看到執行引擎週期與 FPS 下降之間的相關性。顯然GPU 正忙於算術運算,並且著色器可能過於複雜。

如何用 GPU硬體層加速最佳化Android系統的遊戲流暢度

為了測試在不同裝置中的幀率情況,使用友盟+U-APM測試不同機型上的卡頓狀況,發現在onSurfaceCreated函式中進行渲染時出現卡頓, 應證了前文的分析,可以確定GPU是在算數運算過程中發生了卡頓:

如何用 GPU硬體層加速最佳化Android系統的遊戲流暢度

因為不同裝置有不同的效能預期,所以需要為每個裝置設定自己的效能預算。例如,已知裝置中 GPU 的最高頻率,並且提供目標幀速率,則可以計算每幀 GPU 成本的絕對限制。

數學公式: $ 每幀 GPU 成本 = GPU 最高頻率 / 目標幀率 $

CPU到 GPU 的排程存在一定的約束,由於排程上存在限制所以我們無法達到目標幀率。
另外,由於 CPU-GPU 介面上的工作負載序列化,渲染過程是非同步進行的。
CPU 將新的渲染工作放入佇列,稍後由 GPU 處理。

資料資源問題

CPU控制渲染過程並且實時提供最新的資料,例如每一幀的變換和燈光位置。然而,GPU 處理是非同步的。這意味著資料資源會被排隊的命令引用,並在命令流中停留一段時間。而程式中的OpenGL ES 需要渲染以反映進行繪製呼叫時資源的狀態,因此在引用它們的 GPU 工作負載完成之前無法修改資源。

如何用 GPU硬體層加速最佳化Android系統的遊戲流暢度

除錯過程

我們曾做出嘗試,對引用資源進行程式碼上的編輯最佳化,然而當我們嘗試修改這部分內容時,會觸發該部分的新副本的建立。這將能夠一定程度上實現我們的目標,但是會產生大量的 CPU 開銷。

於是我們使用Streamline查明高 CPU 負載的例項。在圖形驅動程式內部libGLES_Mali.so路徑函式, 檢視中看到極高的佔用時間。

如何用 GPU硬體層加速最佳化Android系統的遊戲流暢度

由於我們希望在不同手機上適配不同幀率執行,所以需要查明libGLES_Mali.so是否在不同機型的裝置上都產生了極高的佔用時間,此處採用了友盟+U-APM來檢測使用者在不同機型上的函式佔用比例。

如何用 GPU硬體層加速最佳化Android系統的遊戲流暢度

經友盟+ U-APM自定義異常測試,下列機型會產生高libGLES_Mali.so佔用的問題,因此我們需要基於底層硬體的執行情況來解決流暢性問題,同時由於存在問題的機型不止一種,我們需要從記憶體層面著手,考慮如何呼叫較少的記憶體快取區並及時釋放記憶體。

如何用 GPU硬體層加速最佳化Android系統的遊戲流暢度

解決方案及最佳化

基於前文的分析,我們首先嚐試從緩衝區入手進行最佳化。
單緩衝區方案
• 使用glMapBufferRange和GL_MAP_UNSYNCHRONIZED.然後使用單個緩衝區內的子區域構建旋轉。這避免了對多個緩衝區的需求,但是這一方案仍然存在一些問題,我們仍需要處理管理子區域依賴項,這一部分的程式碼給我們帶來了額外的工作量。
多緩衝區方案
• 我們嘗試在系統中建立多個緩衝區,並以迴圈方式使用緩衝區。透過計算我們得到了適合的緩衝區的數目,在之後的幀中,程式碼可以去重新使用這些迴圈緩衝區。由於我們使用了大量的迴圈緩衝區,那麼大量的日誌記錄和資料庫寫入是非常有必要的。但是有幾個因素會導致此處的效能不佳:
1. 產生了額外的記憶體使用和GC壓力
2. Android 作業系統實際上是將日誌訊息寫入日誌而並非檔案,這需要額外的時間。
3. 如果只有一次呼叫,那麼這裡的效能消耗微乎其微。但是由於使用了迴圈緩衝區,所以這裡需要用到多次呼叫。
我們會在基於c#中的 Mono 分析器中啟用記憶體分配跟蹤函式用於定位問題:

$ adb shell setprop debug.mono.profile log:calls,alloc

我們可以看到該方法在每次呼叫時都花費時間:

Method call summary Total(ms) Self(ms) Calls Method name 782 5 100 MyApp.MainActivity:Log (string,object[]) 775 3 100 Android.Util.Log:Debug (string,string,object[]) 634 10 100 Android.Util.Log:Debug (string,string)

在這裡定位到我們的日誌記錄花費了大量時間,我們的下一步方向可能需要改進單個呼叫,或者尋求全新的解決方案。

log:alloc還讓我們看到記憶體分配;日誌呼叫直接導致了大量的不合理記憶體分配:

Allocation summary Bytes Count Average Type name 41784 839 49 System.String 4280 144 29 System.Object[]

硬體加速

最後嘗試引入硬體加速,獲得了一個新的繪圖模型來將應用程式渲染到螢幕上。它引入了DisplayList 結構並且記錄檢視的繪圖命令以加快渲染速度。

同時,可以將 View 渲染到螢幕外緩衝區並隨心所欲地修改它而不用擔心被引用的問題。此功能主要適用於動畫,非常適合解決我們的幀率問題,可以更快地為複雜的檢視設定動畫。

如果沒有圖層,在更改動畫屬性後,動畫檢視將使其無效。對於複雜的檢視,這種失效會傳播到所有的子檢視,它們反過來會重繪自己。

在使用由硬體支援的檢視層後,GPU 會為檢視建立紋理。因此我們可以在我們的螢幕上為複雜的檢視設定動畫,並且使動畫更加流暢。

程式碼示例:

// Using the Object animator view.setLayerType(View.LAYER_TYPE_HARDWARE, null); ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, View.TRANSLATION_X, 20f); objectAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { view.setLayerType(View.LAYER_TYPE_NONE, null); } }); objectAnimator.start(); // Using the Property animator view.animate().translationX(20f).withLayer().start();

另外還有幾點在使用硬體層中仍需注意:

(1)在使用之後進行清理:

硬體層會佔用GPU上的空間。在上面的 ObjectAnimator程式碼中,偵聽器會在動畫結束時移除圖層。在 Property animator 示例中,withLayers() 方法會在開始時自動建立圖層並在動畫結束時將其刪除。

(2)需要將硬體層更新視覺化:

使用開發人員選項,可以啟用“顯示硬體層更新”。
如果在應用硬體層後更改檢視,它將使硬體層無效並將檢視重新渲染到該螢幕外緩衝區。

硬體加速最佳化

但是由此帶來了一個問題是,在不需要快速渲染的介面,比如滾動欄, 硬體層也會更快地渲染它們。當將 ViewPager 滾動到兩側時,它的頁面在整個滾動階段會以綠色突出顯示。

因此當我滾動 ViewPager 時,我使用 DDMS 執行 TraceView,按名稱對方法呼叫進行排序,搜尋“android/view/View.setLayerType”,然後跟蹤它的引用:

ViewPager#enableLayers(): private void enableLayers(boolean enable) { final int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { final int layerType = enable ? ViewCompat.LAYER_TYPE_HARDWARE : ViewCompat.LAYER_TYPE_NONE; ViewCompat.setLayerType(getChildAt(i), layerType, null); } }

該方法負責為 ViewPager 的孩子啟用/禁用硬體層。它從 ViewPaper#setScrollState() 呼叫一次:

private void setScrollState(int newState) { if (mScrollState == newState) { return; } mScrollState = newState; if (mPageTransformer != null) { enableLayers(newState != SCROLL_STATE_IDLE); } if (mOnPageChangeListener != null) { mOnPageChangeListener.onPageScrollStateChanged(newState); } }

正如程式碼中所示,當滾動狀態為 IDLE 時硬體被禁用,否則在 DRAGGING 或 SETTLING 時啟用。PageTransformer 旨在“使用動畫屬性將自定義轉換應用於頁面檢視”(Source)。

基於我們的需求,只在渲染動畫的時候啟用硬體層,所以我想覆蓋ViewPager 方法,但由於它們是私有的,我們無法修改這個方法。

所以我採取了另外的解決方案:在 ViewPage#setScrollState() 上,在呼叫enableLayers() 之後,我們還會呼叫OnPageChangeListener#onPageScrollStateChanged()。所以我設定了一個監聽器,當 ViewPager 的滾動狀態不同於 IDLE 時,它將所有 ViewPager 的孩子的圖層型別重置為 NONE:

@Override public void onPageScrollStateChanged(int scrollState) { // A small hack to remove the HW layer that the viewpager add to each page when scrolling. if (scrollState != ViewPager.SCROLL_STATE_IDLE) { final int childCount = <your_viewpager>.getChildCount(); for (int i = 0; i < childCount; i++) <your_viewpager>.getChildAt(i).setLayerType(View.LAYER_TYPE_NONE, null); } }

這樣,在 ViewPager#setScrollState() 為頁面設定了一個硬體層之後——我將它們重新設定為 NONE,這將禁用硬體層,因此而導致的幀率區別主要顯示在 Nexus上。

作者:陳可心

原文連結:http://click.aliyun.com/m/1000306394/

本文為阿里雲原創內容,未經允許不得轉載。

分類: 遊戲
時間: 2021-11-16

相關文章

蘋果釋出會登上多個熱搜,官方展示新技術,原神又成測試遊戲

蘋果釋出會登上多個熱搜,官方展示新技術,原神又成測試遊戲
近日,一年一度的蘋果秋季釋出會正式落幕,iPhone13系列新品亮相,在大眾的討論下相繼登上熱搜,而這其中,iPhone13 Pro以上所搭載的全新ProMotion技術,成為不少人熱議的焦點. 有意 ...

2021年25款好玩的離線單機手機遊戲推薦(Android和iOS)

2021年25款好玩的離線單機手機遊戲推薦(Android和iOS)
1.很多朋友讓我推薦些單機遊戲,所以經過兩天時間的整理和準備今天他來了! 2.很多朋友問我遊戲怎麼下?為什麼搜不到. Android:首選應用商店,其次Google play,最後百度搜索,很多國外優 ...

2021年外媒評選10臺最佳手機,僅有一款是國產機型

2021年外媒評選10臺最佳手機,僅有一款是國產機型
隨著2021年iPhone13系列手機的發售,2021年所有高階手機品牌均已交出了自己的答卷.各大國內外評測機構及媒體都開始評選了各自認為的2021年手機排行榜單.來自外媒的知名數碼科技媒體ZDNet ...

原神新增120幀模式選項 iPhone 13 Pro率先支援

原神新增120幀模式選項 iPhone 13 Pro率先支援
[PChome手機頻道報道]熱門手遊<原神>在今天正式更新了2.2版本,除了遊戲內容的更新之外,<原神>還開放了120幀極限幀率模式,不過目前該模式僅支援iPhone 13 P ...

2021年度C-NCAP熱門車豐田卡羅拉完成AEB測試

2021年度C-NCAP熱門車豐田卡羅拉完成AEB測試
[太平洋汽車網 行業頻道]2021年9月14日至9月18日,2021年度C-NCAP熱門車豐田卡羅拉,在中國汽車技術研究中心有限公司的試驗場內,按照<C-NCAP管理規則(2018年版)> ...

中部戰區組織2021年度面向社會公開招考文職人員網路面試

中部戰區組織2021年度面向社會公開招考文職人員網路面試
9月14日至16日,中部戰區組織2021年度面向社會公開招考文職人員面試工作,首次採用網路視訊會議的方式進行. 此次網路面試依託騰訊會議進行,每個考場安排有1名考場管理員隨機抽取1套考題,由主考官進行 ...

做好2021年度高階審計師和正高階審計師任職資格評審工作的通知
黑龍江省審計廳 黑審文[2021]6號 關於做好2021年度高階審計師和正高階審計師 任職資格評審工作的通知 各行署.市.縣審計局,省直各單位: 按照黑龍江省人力資源和社會保障廳<關於做好202 ...

原神雷鳴仙在哪釣 雷鳴仙魚餌配方分享

原神雷鳴仙在哪釣 雷鳴仙魚餌配方分享
原神2.1版本更新了釣魚系統,玩家可以透過釣魚獲得很多材料,釣魚也是一個非常休閒的玩法,很多玩家不知道雷鳴仙在哪裡釣,小編整理和收集了有關內容,下面就來跟隨蠶豆網小編一起來看看詳細的攻略內容. 原神雷 ...

鐵騎力士入選2021年度全國農業農村資訊化示範基地

鐵騎力士入選2021年度全國農業農村資訊化示範基地
2021年9月19日,從農業農村部市場與資訊化司獲悉鐵騎力士成功入選2021年度全國農業農村資訊化示範基地,成為全國15個經營型示範單位之一,也是四川省唯一入選的經營型示範單位! 據悉,<202 ...

國內漫展遇到假原神,這玩意還能有假的?這些人圖什麼啊?

國內漫展遇到假原神,這玩意還能有假的?這些人圖什麼啊?
不知道朋友們去漫展溜達閒逛的時候,喜不喜歡去逛各個廠商.出品方啥的官方展臺? 我之前在上海工作的時候,因為工作原因經常去逛漫展,像是啥CP啊CCG啊CJ啊WF啊螢火蟲啊一類的動漫展.遊戲展.手辦展我都 ...

2021年度J.D. Power汽車魅力指數榜,道奇竟然排在榜首

2021年度J.D. Power汽車魅力指數榜,道奇竟然排在榜首
近日,J.D. Power公佈了2021年度汽車魅力指數,在汽車效能.設計等方面進行調研,從而釋出的排行榜. 排行榜中,我們能夠看出,道奇品牌蟬聯了指數榜的榜首,而大眾集團旗下的保時捷同樣也是並列榜首 ...

原神:心海上線不久,國外玩家就開始“整活”,真人COS很搶鏡

原神:心海上線不久,國外玩家就開始“整活”,真人COS很搶鏡
哈羅大家好,我是盟盟,本期和大家聊聊原神的話題. 在珊瑚宮心海PV中,稻妻地處最西部的海祇島,她給我們講述了一個關於魔神奧羅巴斯的故事.心海是海祇島名義上的指揮官,外表看上去柔和,但是卻機敏過人,在眼 ...

黑龍江唯一!這個醫院獲批2021年度中醫全科規培重點專業基地
來源:黑龍江日報 近日,中國醫師協會公佈2021年度中醫全科規培重點專業基地名單,黑龍江中醫藥大學附屬第一醫院成功入選,成為黑龍江省內唯一獲批該基地的單位. 為鞏固完善中醫全科住院醫師規範化培訓制度, ...

從口誅筆伐到年入百億,上線才一年的原神,怎麼就鹹魚大翻身了?

從口誅筆伐到年入百億,上線才一年的原神,怎麼就鹹魚大翻身了?
不知不覺,<原神>已經上線整整一年了,回想起當時的"抄襲"風波,幾乎所有人都在對它口誅筆伐,鮮少有人看好它的未來. 然而就是這樣一款自誕生前就充滿爭議的產品,在所有玩家 ...

別搓鋼化膜了!花百元買了遊戲手柄,玩王者原神LOL手遊真爽

別搓鋼化膜了!花百元買了遊戲手柄,玩王者原神LOL手遊真爽
作為一名遊戲玩家,尤其是賽車遊戲玩家,藍芽遊戲手柄一直是我的必備.相信我,用手搓螢幕開車和用手柄開車完全是兩個遊戲!奈何之前用的其他品牌遊戲手柄太老了,無法適配新系統了,所以準備入手一個新款.剛好我最 ...

2021年度全國審計專業技術資格考試舉行
原標題:2021年度全國審計專業技術資格考試舉行 10月10日,2021年度審計專業技術資格考試在全國統一舉行.審計署黨組成員.副審計長陳健到北京市部分考點巡考.據悉,今年全國共有84061名考生報名 ...

原神為iPhone 13 Pro系列新增120幀選項,最高可實現120幀重新整理率

原神為iPhone 13 Pro系列新增120幀選項,最高可實現120幀重新整理率
<原神>由於對手機效能配置要求過高,導致許多手機在玩此款遊戲時,遊戲幀率發揮並不穩定,無法達到滿幀執行,遊戲體驗的流暢度也有所欠缺.但是在近日<原神>大版本更新中,卻為部分機型 ...

《原神》迎大更新:新增120Hz高幀率模式,iPhone 13 Pro系列嚐鮮

《原神》迎大更新:新增120Hz高幀率模式,iPhone 13 Pro系列嚐鮮
作為當前最熱門的手遊之一,<原神>一直備受玩家們的關注,但由於該手遊對於效能的要求極高,驍龍888.麒麟9000.A15等一眾旗艦處理器都不敢說完全hold住它,需要解決散熱背夾等外設才能 ...

眾望所歸:2021年度諾貝爾獎各獎項先後揭曉

眾望所歸:2021年度諾貝爾獎各獎項先後揭曉
兩名美國科學家分享生理學或醫學獎 瑞典卡羅琳醫學院10月4日宣佈,將2021年諾貝爾生理學或醫學獎授予戴維·朱利葉斯和阿德姆·帕塔普蒂安兩名科學家,以表彰他們在發現溫度與觸覺"感受器&quo ...

原神更新2.2版本!蘋果率先適配120幀模式

原神更新2.2版本!蘋果率先適配120幀模式
10月13日,<原神>更新了「霧海懸謎境」2.2版本,新增了新地圖.新角色.新玩法--以及120幀遊戲模式.值得注意的是,目前120幀選項僅適配了蘋果部分裝置,安卓裝置最高依然為60幀. ...