個(gè)人博客網(wǎng)站總結(jié)漯河seo推廣
背景:
hi,粉絲朋友們:
大家好!近期分享了surfaceflinger相關(guān)的一些blog,有同學(xué)就對(duì)相關(guān)的一些內(nèi)容產(chǎn)生了一些疑問。
比如:vsync查看問題,即怎么才可以說是vsync到來了。
比如perfetto中surfaceflinger的VSYNC脈沖經(jīng)典圖如上圖所示的,看到一個(gè)的小方塊,上升下降的方波形,那么通過看這些方塊了解真實(shí)的vsync信號(hào)到來呢?
大部分同學(xué)常規(guī)方法:
第一種方法:
方波方塊確定vsync,這個(gè)很多同學(xué)不了解原理的或者屬于自己看trace同學(xué),看到一個(gè)方塊的脈沖,然后測(cè)量一下方塊剛好耗時(shí)是16ms左右,任務(wù)一個(gè)方塊就代表一個(gè)vsync周期
哈哈,這種想法其實(shí)一開始很多新手自己看vsync都是這樣的,屬于自己想當(dāng)然情況,隨便一個(gè)脈沖就可以反駁比如如下:
所以這種方式其實(shí)不準(zhǔn)確哈,很多時(shí)候不便于理解
第二種方式:
判斷變脈沖方波變化的上升下降的瞬間代表vsync來臨方式。
這種思路和觀點(diǎn)其實(shí)已經(jīng)基本上已經(jīng)算正確了,因?yàn)関sync本身是一個(gè)信號(hào),屬于瞬時(shí)的動(dòng)作,上升和下降代表這個(gè)時(shí)候的vsync是有變化的。但是有一些場(chǎng)景有問題比如如下這種:
上面問題是課程學(xué)員提出的,相關(guān)framework干貨課程看這里:
更多framework干貨課程優(yōu)惠獲取相關(guān)可以+V(androidframework007)
視頻:https://www.bilibili.com/video/BV1ah411d7Y3
真實(shí)的vsync理解方法:
這個(gè)情況就可以看到如果按照上升下降理論確實(shí)這個(gè)同學(xué)說的是對(duì)的。但其實(shí)這個(gè)上升下降理解也還是缺少點(diǎn)理論支持,最好可以結(jié)合代碼來驗(yàn)證一下。首先看看這個(gè)VSYNC-app信號(hào)是在哪里:
打印這個(gè)VSYNC-app信號(hào)的代碼如下:
frameworks/native/services/surfaceflinger/Scheduler/DispSyncSource.cpp
void DispSyncSource::onVsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime,nsecs_t readyTime) {VSyncSource::Callback* callback;{std::lock_guard lock(mCallbackMutex);callback = mCallback;}if (mTraceVsync) {//正常都進(jìn)行tracevsyncmValue = (mValue + 1) % 2;//這里就是trace的值,所以只有0和1}if (callback != nullptr) {callback->onVSyncEvent(targetWakeupTime, {vsyncTime, readyTime});}
}
上面大家可能有疑問,這里
mValue = (mValue + 1) % 2
明明就是對(duì) mValue只是個(gè)簡(jiǎn)單賦值,哪來的TRACE打印。哈哈,這里你得知道c++的符號(hào)重載,可以看看mValue的源碼就了解了
class TracedOrdinal {
public:static_assert(std::is_same<bool, T>() || (std::is_signed<T>() && std::is_integral<T>()) ||std::is_same<std::chrono::nanoseconds, T>(),"Type is not supported. Please test it with systrace before adding ""it to the list.");TracedOrdinal(std::string name, T initialValue): mName(std::move(name)),mHasGoneNegative(std::signbit(initialValue)),mData(initialValue) {trace();}T get() const { return mData; }operator T() const { return get(); }TracedOrdinal& operator=(T other) { //對(duì)賦值進(jìn)行重載mData = other;mHasGoneNegative = mHasGoneNegative || std::signbit(mData);trace();//打印TRACEreturn *this;}private:void trace() {if (CC_LIKELY(!ATRACE_ENABLED())) {return;}if (mNameNegative.empty()) {mNameNegative = mName + "Negative";}if (!std::signbit(mData)) {ATRACE_INT64(mName.c_str(), to_int64(mData));if (mHasGoneNegative) {ATRACE_INT64(mNameNegative.c_str(), 0);}} else {ATRACE_INT64(mNameNegative.c_str(), -to_int64(mData));ATRACE_INT64(mName.c_str(), 0);}}const std::string mName;std::string mNameNegative;bool mHasGoneNegative;T mData;
};
所以說mValue = (mValue + 1) % 2的這個(gè)賦值操作就是打印trace了,也就是說系統(tǒng)執(zhí)行到了 DispSyncSource::onVsyncCallback就代表有vsync到來,上升和下降那種理論就說的過去了,因?yàn)樯仙陆荡韒Value確實(shí)有變化了。但是上面方法二那個(gè)同學(xué)疑問怎么解釋呢?
這里大家要注意看這個(gè)信號(hào)圖:
關(guān)注VSYNC-appSf這一欄信號(hào),是不是發(fā)現(xiàn)第一個(gè)繪制第一個(gè)信號(hào)value為0,在這個(gè)第一個(gè)信號(hào)繪制以前圖形中其實(shí)并沒有看到有任何的value。
相當(dāng)于這個(gè)信號(hào)在我們這個(gè)trace中屬于第一次有value情況。
那么結(jié)合我們上面的代碼結(jié)論我們知道,第一次有value的trace打印了,說明肯定是有vsync的回調(diào)了,至于之前脈沖圖沒有打印,那一般是因?yàn)樽トr(shí)候就沒有觸發(fā)這個(gè)onVsyncCallback回調(diào),所以自然不會(huì)打印出來啦。這樣理解了代碼再去看這個(gè)vsync脈沖圖是不是好理解多了。