renderthread是什么_Android 旗舰机标配的高帧屏(120Hz),对各位 App 开发者有什么影响?...
各大手機(jī)廠商發(fā)布的旗艦機(jī),都將 90Hz 甚至 120Hz 高幀率流速屏當(dāng)成了標(biāo)配,那這對我們實(shí)際開發(fā)的 App 會不會有影響?原本在 60Hz 下,每幀只需保證 16ms 內(nèi)繪制完成就可以做到流暢,換到高幀屏中,實(shí)際留給我們繪制時間是縮短了的,是否對我們的代碼質(zhì)量要求更高?
推薦一篇文章,來講講對此的影響,希望對大家有幫助。
以下文內(nèi)的 "我" 為文章原作者。
前言
昨天在 IT 之家留言說,如果應(yīng)用無法滿足 120hz 的繪制會怎樣?假設(shè)如果繪制一幀的時間,如果大于 1/120 秒,哪怕是多了 1 毫秒,就會導(dǎo)致應(yīng)用在 120Hz 的手機(jī)上也就變成了 60Hz。
后來仔細(xì)想想,這句話說的并不是特別嚴(yán)謹(jǐn),為什么這么說呢?
一、證明我的觀點(diǎn)
首先我寫一個 demo 來證明我的觀點(diǎn)。
1.1 滿幀的應(yīng)用
public class MyTextView extends TextView {int i = 0; @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (i < 6) {
this.post(new Runnable() {
@Override
public void run() {
MyTextView.this.setText(i++ + "");
}
});
}
}
}
我寫了一個只繪制 6 幀的一個界面,Activity 中包含這個 MyTextView,通過抓 Trace 可以看到,下面這個 6 幀繪制圖,都是在一個 Vsync 周期(圖中黑白相見的色塊,均是一個 Vsync 周期)繪制一幀。
為什么第一幀會有點(diǎn)延遲,主要是因?yàn)閱訒r,主線程在干了些其他事情,好在繪制花不了太多時間。
大概繪制也就 3 毫秒左右,畢竟界面簡單。
1.2 幀數(shù)減半的應(yīng)用
public class MyTextView extends TextView {int i = 0;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
try {
Thread.sleep(16);
} catch (Exception e) {
}
if (i < 6) {
this.post(new Runnable() {
@Override
public void run() {
MyTextView.this.setText(i++ + "");
}
});
}
}
}
我手動人為在 MyTextView.onDraw() 方法中 sleep 了 16 毫秒,來模擬很多應(yīng)用實(shí)現(xiàn)的不好,導(dǎo)致繪制耗時的情況,例如 View 層級厲害復(fù)雜,甚至在 onDraw() 方法中進(jìn)行文件讀寫。
通過抓 trace 可以看到,原本之前的例子(1.1)中 6 幀由 6 個時間周期繪制完成,現(xiàn)在變成了 6 幀由 12 個時間周期完成了。
1.3 小結(jié)
這就是我一直想說的一個觀點(diǎn),120Hz 的手機(jī)體驗(yàn)不一定有 90Hz 的手機(jī)好的原因,一旦主線程一次 traversal(一次 ViewRootImpl 的 onDraw() 的遍歷)的時間超出了 vsync 的時間周期 1/120s,就會導(dǎo)致幀率直接砍半,降為 60 幀,90Hz 可以讓這個折半降幀率的現(xiàn)象減少。
二、繪制一幀指的是什么
為什么我說我的觀點(diǎn)不準(zhǔn)確?其實(shí)是我太籠統(tǒng)的定義了繪制一幀這個詞。
在硬件加速開啟的情況下:
- 如果我將繪制一幀的時間定義成:主線程一次 traversal,那我說的話是正確的。
- 如果我將繪制一幀的時間定義成:主線程一次 traversal + renderthread 一次渲染,那我說的話是不嚴(yán)謹(jǐn)?shù)摹?/li>
2.1 引發(fā)我思考的 trace
因?yàn)橐屩骶€程一次 traversal + renderthread 超時不是特別好寫 demo,我就用一個昨天引發(fā)我思考的一個 trace 給大家講解一下。
大家從第一個黃色 F 的圓圈開始看。
UI Thread 的 doFrame + RenderThread 的 DrawFrame 的時間超出了一個 Vsync 周期,接下來每一幀的情況,都是按照第一幀繪制的情況一樣的情況運(yùn)行,最好造成的現(xiàn)象就是雖然幀數(shù)是滿幀,但是每一幀其實(shí)都是延遲顯示的。
用一句哲學(xué)的話來概括就是:你眼睛看到任何事物,其實(shí)都是事物過去的樣子。
假如主線程一次 traversal + renderthread 一次渲染時間超出了 vsync 周期不多,這樣子的應(yīng)用大概率是可以滿幀運(yùn)行(滿幀不代表顯示正常)。
我上面一句話中用了不多,大概率這種模糊的文字,因?yàn)檫@個情況下能否滿幀的臨界點(diǎn)比較難定義。
2.2 如何定義這個 120 變成 60 幀的臨界點(diǎn)
繼續(xù)下面這個圖,你會發(fā)現(xiàn) UI Thread 的 doFrame 會非常 happy 的按照 Vsync 信號執(zhí)行,但是下面 renderthread 已經(jīng)忙的不可開交了。
其實(shí)第一幀已經(jīng)延遲了,假如運(yùn)氣不好導(dǎo)致了 drawframe 的時間橫跨了 2 個 Vsync 周期,還是會導(dǎo)致丟幀,這個時候就從 120 幀降為 60 幀。
三、總結(jié)
3.1 理想中的結(jié)論
假設(shè)開啟硬件加速,一幀繪制的時間 = UI 線程(T1)+ RenderThread 線程(T2)。
那么 Vsync 時間的周期是 1/120s,約等于 8.3ms,此時:
- 如果 16.6ms > T1 > 8.3ms,會導(dǎo)致從 120 幀降為 60 幀。
- 如果 T1 <8.3ms,16.6ms> T1 + T2 > 8.3ms,雖然還是滿幀,但是你看到的永遠(yuǎn)是前一幀的畫面。
- 如果 T1 + T2 > 16.6ms,毫無疑問會導(dǎo)致從 120 幀降為 60 幀。
上面理論看起來是很完美的結(jié)論,千萬別把這個當(dāng)做定理去記憶,因?yàn)楝F(xiàn)實(shí)會比這些情況復(fù)雜的多。
3.2 顯示中的結(jié)論
可能會有人說現(xiàn)在 CPU,GPU 那么強(qiáng),怎么可能會超時呢?
舉個微信在 865 的手機(jī)上,滑動消息列表的例子,T1 約等于 6ms,T1 + T2 約等于 8.2ms。
這還并不是太過復(fù)雜的界面,大家會發(fā)現(xiàn),6ms 已經(jīng)很接近 8.3ms 了。
3.3 給開發(fā)者的建議
對于要適配 120hz 手機(jī)的應(yīng)用的工程師,你們要注意以下事情。
四、尾巴
說到這里,如果聽得懂我在說什么的人,應(yīng)該能懂我想表達(dá)的意思。
如果不懂我說的什么的人,希望你去補(bǔ)一下以下知識點(diǎn),再回過頭來看這個文章。
知識點(diǎn) 1:
TextView.setText 到屏幕顯示文字,整個過程發(fā)生了什么。
知識點(diǎn) 2:
硬件加速之后,主線程(UI Thread)和 RenderThread 之間的協(xié)同工作的方式。
知識點(diǎn) 3:
APP 界面和 SurfaceFlinger 之間的關(guān)系
可能會有人說,你揪那么細(xì)致干嘛,對于用戶來說,掉了幾幀的影響也不大,,但是對于性能優(yōu)化工程師來說,有時候就是要糾結(jié)那幾個丟幀的情況,只有做好了每一幀的完美繪制,才能給用戶帶來最完美的用戶體驗(yàn)。
- End -
文章看完了,最后我換個角度補(bǔ)充一些觀點(diǎn)。
手機(jī)硬件雖然增加了高幀屏,確實(shí)看似對每一幀繪制的時間要求更短了,但別忘了,在升級屏幕的同時,對其他硬件(CPU、GPU、ROM等)也做了相應(yīng)的升級。雖然留給我們的刷新時間縮短了,但計(jì)算和渲染繪制的能力,也相應(yīng)的提高了。
那么到具體的代碼上,你在舊手機(jī)上繪制一幀需要 10ms 的代碼,在 120Hz 的旗艦機(jī)上可能只需要 6ms,兩相抵消之下問題不會太大。
所以最后核心還是在日常編碼的過程中,隨時注意性能的問題。管他高幀低幀,領(lǐng)導(dǎo)覺得"不跟手",咱就嘚優(yōu)化。
本文對你有幫助嗎?留言、轉(zhuǎn)發(fā)、點(diǎn)好看是最大的支持,謝謝!
公眾號后臺回復(fù)成長『成長』,將會得到我準(zhǔn)備的學(xué)習(xí)資料。
總結(jié)
以上是生活随笔為你收集整理的renderthread是什么_Android 旗舰机标配的高帧屏(120Hz),对各位 App 开发者有什么影响?...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图像归一化处理 相同像素_图像处理学习笔
- 下一篇: 修改sh文件_修改Android分区大小