主頁 > 移動端開發 > 又卡了~從王者榮耀看Android螢屏重繪機制

又卡了~從王者榮耀看Android螢屏重繪機制

2021-06-09 20:14:25 移動端開發

前言

正在帶妹子上分的我,團戰又卡了,我該怎么向妹子解釋?在線等,

“卡”的意思

不管是端游還是手游,我們都會時不時遇到“卡”的時候,一般這個卡有兩種含義:

  • 掉幀

  • 畫面撕裂

那么問題來了,這些情況到底是什么原因導致的?又該怎么解決?

掉幀

首先,要知道是什么,幀率又是什么,

幀,就是影像影片中最小單位的單幅影像畫面,相當于電影膠片上的每一格鏡頭, 一幀就是一幅靜止的畫面,連續的幀就形成影片,如電視圖象等,

幀率(每秒幀數),簡單地說,就是在1秒鐘時間里傳輸的圖片的幀數,也可以理解為圖形處理器每秒鐘能夠重繪幾次,通常用fps(Frames Per Second)表示

這下大家應該知道了,幀就是一個靜止畫面,很多個幀一起就組成了視頻、電影、游戲畫面,

而幀率就是我們游戲常見到的fps,指一秒鐘繪制出現的幀數,單位為“赫茲”(Hz)

這里簡單科普下,一般要求連貫性的話,幀數至少要高于每秒約10至12幀的時候,人眼才會認為是連貫的,此現象叫做“視覺暫留現象”,是由人眼的生物構造決定的,通過這個現象,早期的無聲電影通過手搖驅動,將畫面快速播放,就能讓人感覺在播放完整連續的視頻,

按照我們的認知,這個幀率一般是越大越連貫,就越不卡,但同時,帶來的消耗也就越多,比如電影需要更多的膠卷,電腦需要更好的硬體支持,所以電影一般通用的幀率為24Hz,而電腦、手機一般幀率為60Hz,這樣就能保證正常條件下能讓人舒服得觀看和使用,

掉幀的意思就很明顯了,本來游戲的fps為60,突然降到了20,也就是一秒只有20幀了,那能不卡嗎?

那么,掉幀原因到底是啥呢?

其實原因大家都知道,不信你繼續看...

硬體原因

“我這個手機玩游戲卡死了”

“你那啥破手機啊,趕快換一個~”

這個對話應該時常發生,所以大家也都清楚,硬體的好壞一定程度上決定了玩游戲“卡不卡”,配置高的硬體玩游戲就能保證游戲的流暢,

軟體原因

“你這啥App啊,做的啥游戲啊,這么卡,我這手機配置這么高,就玩你這個卡”

“額,可能是游戲優化沒做好,”

第二個原因,就是因為游戲/軟體自身的優化就沒做好,圖片弄的很大,布局嵌套太深,那么幀 的計算和渲染就更耗時間,就會有可能導致掉幀,

網路原因

“不行了,太卡了,我這ping都快1000了,怎么玩啊”

“快換流量啊,團戰要輸了,少個人怎么打”

對了,第三個原因就是網路原因,這也是最常發生的原因了,網路的波動會影響 畫面 的傳輸,所以就會掉幀,

螢屏重繪機制

上述三個原因,其實都涉及到螢屏重繪的基本機制,

在典型的顯示系統中,不管是手機還是電腦,一般都涉及到三個部分:

  • CPU,中央處理器,用于計算資料,資訊處理,
  • GPU,圖形處理器,用于處理影像圖形,也就是俗稱的顯卡,
  • display,顯示螢屏,用于展示畫面,也就是我們的手機螢屏、電腦顯示幕,

整個顯示程序就是:

  • CPU計算螢屏需要的資料,然后交給GPU,
  • GPU對影像進行處理繪制,然后存到快取區,
  • display再從這個快取區讀取資料,顯示出來,

每一幀都是重復這個作業,也就是1秒中需要60次這樣回圈操作,每次操作需要的時間就約等于16.6ms,也就是我們常說的Android系統中,會每隔16.6ms重繪一次螢屏,

關于螢屏重繪機制,有一張很經典的圖片:

可以看到,16.6ms一到,系統就發送了VSync信號,然后螢屏會從快取區獲取了新的一幀影像并顯示出來,與此同時,CPU也開始了下一幀資料的計算,然后計算好交給GPU,最后放到快取區,等待下一次VSync信號,

VSync信號是啥呢?我們暫且按下不表,待會再說,可以先理解它為一種同步重繪信號,同步CPU和螢屏,當信號來的時候,螢屏開始切換畫面,CPU開始下一幀計算,

為了方便理解,我做了個小影片:

通過上面的解釋,我們知道了一幀顯示的時間是16.6ms,在這個時間內,CPU和GPU必須把資料處理好并放到快取區(buffer)中,

如果在某次的16.6ms中,CPU和GPU沒有繪制好下一幀資料,那么display就無法更新下一幀資料了,這就是掉幀

所以才有了以上三個原因會導致掉幀,再來回顧下:

  • 1、硬體原因,硬體比較差也就是CPU和GPU計算不給力,導致一幀的資料沒準備好,所以掉幀,
  • 2、軟體原因,在硬體夠用的情況下,App或者游戲的一幀資料計算繁雜,嵌套太多或者圖太大,也會導致下一幀資料不能在16.6ms中被準備好,導致掉幀,
  • 3、網路原因,在硬體軟體都正常情況下,由于網路波動,CPU的計算資料都沒有從網路上獲取到,那么肯定會導致CPU資料的準備延遲,最終導致掉幀,

那么掉幀之后,螢屏重繪機制會怎么處理后續的幀呢?

  • 如果是游戲的話,因為即時性比較重要,所以丟失的幀就不會再去管了,而是直接準備當前時間應該顯示的內容,最終顯示到螢屏,所以這種情況掉的幀就真的掉了,
  • 如果是應用的話,可能對資料的完整性比較重要,所以如果第2幀掉了,那么螢屏就繼續顯示第1幀,而CPU和GPU繼續準備第2幀的資料,如果能在下一個16.6ms內完成第2幀資料,那么螢屏就會接著顯示第二幀了,比如有時候手機卡的時候,我們去操作App,操作會延遲,就是掉幀了,這種情況幀并不是真的掉了,而是延遲了,

畫面撕裂

接下來就看看畫面撕裂,為什么一幀中會出現兩幀的畫面呢?

首先理解一個概念:「逐行掃描」

「逐行掃描」就是說,顯示幕顯示畫面并不是“蹭”一下就打出一張畫面來,而是從上到下一行一行顯示出來的,只不過是顯示得比較快所以肉眼看不出來而已,

之前說了螢屏的資料是從快取區Buffer中取的,如果在螢屏取資料并逐行掃描顯示畫面的程序中,Buffer中的資料變了,那么就有可能導致畫面撕裂,

最明顯的例子就是:顯卡的fps是180,而顯示幕的fps是60,也就是顯卡一秒鐘能產生180張畫面,而顯示幕一秒鐘只能讀取60張畫面,

那么顯示幕從Buffer中讀取資料逐行掃描的程序中,本來需要1/60 秒顯示完一張畫面,但是在1/180的時間點,顯卡就把下一張畫面的資料存到Buffer了,結果顯示幕的下半截就顯示的是第二張畫面的內容了,也就造成了畫面撕裂,

再來個影片解釋下:

所以為了防止這種狀況,一般顯示系統會加入一個雙快取+垂直同步的概念:

  • 首先,開啟垂直同步,就會將GPU的fps限制為和顯示幕的fps一樣,

系統會在顯示幕繪制完一幀之后發送一個垂直同步信號,然后CPU和GPU就準備下一幀的內容,等待顯示幕下一幀繪制完,又會發送一個垂直同步信號,如此反復,就限制了顯卡的fps,按照顯示幕的標準來繪制影像,

這個垂直同步信號就叫做 VSync信號

玩游戲的朋友應該都知道,很多游戲內設定頁都有 垂直同步 的開啟選項,為的就是將顯卡的fps和顯示幕的fps適配,防止畫面撕裂,

  • 其次,通過雙快取保證一幀資料的連貫性,

1、快取區backBuffer用于CPU/GPU圖形處理
2、快取區frameBuffer用于顯示幕顯示

這樣分工明確之后,螢屏只會讀取framebuffer的內容,是一幀完整的畫面,而CPU/GPU計算的新一幀內容會放到backbuffer中,不會影響到framebuffer的內容,

只有當螢屏繪制完一幀內容之后,才會將CPU/GPU計算好的新一幀內容也就是backbuffer內容和framebuffer進行交換,

這樣就保證了一幀資料的完整連貫,

這里的交換其實就是交換記憶體地址,兩塊快取區A和B,A在第一次充當framebuffer的角色,B充當backbuffer的角色,螢屏完成一幀繪制之后,將AB記憶體地址置換,
當新的一輪VSync信號來的時候,A就充當了backbuffer的角色,而B就變成了framebuffer的角色,

小結:當螢屏掃描完第1幀畫面之后,系統發送VSync信號,這時會發生三件事:

  • 1、交換兩個快取區(framebuffer、backbuffer)內容,
  • 2、顯示幕開始顯示第2幀內容,也就是交換后的framebuffer內容,
  • 3、CPU/GPU開始計算處理第三幀的內容,并在處理好內容后放到backbuffer中,

再來個影片:

Android Project Butter(黃油計劃)

問題都解決了嗎?并沒有,

加入VSync信號之后,掉幀問題變得更嚴重了:

可以發現,加入了VSync信號后,雖然統一了CPU處理的時間點,但是掉幀問題可能會被再一次放大,從掉一幀直接變成掉兩幀,因為中間的16.6ms被浪費了,

怎么辦呢?在保留VSync信號的同時有可能最大利用上CPU/GPU嗎?

三快取來了:

1、快取區backBuffer用于CPU/GPU圖形處理
2、快取區TripleBuffer用于CPU/GPU圖形處理
3、快取區frameBuffer用于顯示幕顯示

剛才說的情況導致的原因就是因為在第二個VSync信號來的時候,因為backBuffer被GPU占用,所以CPU無法去開始新一幀的計算,
加入了第三個快取區,那么在第二個VSync信號來的時候,CPU就可以利用TripleBuffer開始新一幀的計算,而無視正在被GPU占用的backBuffer

你可以理解為 CPU、GPU、Display每個人都有一個快取區,這樣三個就能同時做自己的事而互不影響,最大化利用每個模塊,

三快取和上面說到的Vsync同步信號都是 Android 4.1 發布的一個Project Butter(黃油計劃)中提出的,為的是就是讓Android能讓黃油/奶油般順滑,

最后貼個三快取機制下的重繪機制圖:

小結

今天了解了Android系統的重繪機制,雖然沒有代碼,但是面試中也是常常被問到的,再次總結下:

1、為了解決畫面撕裂問題,引入了垂直同步信號VSync信號雙快取

  • 每次VSync信號到達的時候,螢屏進行畫面切換,CPU/GPU開始準備下一幀內容,
  • CPU/GPU每次準備好資料后,放到一個單獨的快取區backBuffer,當螢屏準備好之后,將backBuffer資料和frameBuffer資料交換,螢屏只讀取frameBuffer快取區的資料,保證了資料的完整連續性,

2、為了解決VSync信號下CPU/GPU無法最大化利用的問題,引入了三快取,

VSync信號來的時候,即使GPU還沒處理好上一幀資料,backBuffer還不空閑,但是CPU也可以利用第三個快取區正常開始處理下一幀的資料,最大化利用CPU/GPU,保證垂直同步機制的同時不浪費資源,

3、掉幀的根本原因是因為在一幀時間內(一般為16.6ms),CPU/GPU無法把下一幀的資料準備好,

即使參考了三快取和垂直同步,但是掉幀的情況該發生還是會發生,我們作為App軟體開發者,能做的就是盡可能優化布局,減少嵌套,減少CPU/GPU計算畫面資料的時間,讓每一幀時間內正常準備好下一幀影像資料,

至于重繪機制在Android原始碼中到底是怎么實作的呢?這就涉及到Choreographer類的決議,

參考

螢屏重繪機制
為什么【垂直同步】技術往往不被玩家推崇
Android Project Butter分析
FrameBuffer初探

拜拜

感謝大家的閱讀,有一起學習的小伙伴可以關注下我的公眾號——碼上積木????
每日一個知識點,積少成多,建立知識體系架構,
這里有一群很好的Android小伙伴,歡迎大家加入~

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/286135.html

標籤:Android

上一篇:在 Android 使用 QuickJS JavaScript 引擎教程

下一篇:寫給Android開發的Nginx入門

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more