目錄:
0.mtk平臺相關surfaceflinger線程有那些?
1 mtk採用的是:硬件VSYNC 線程
2.Mtk 通過surfaceflinger註冊了3個eventthread
2.1 DispSyncThread如何區分和執行vssyncsrc和sfVsyncSrc的vs?
2.2 vssyncsrc和sfVsyncSrc的事件接受者什麼創建
2.3 EventControl線程
//////////////////////////////////////////////////////////////////////////////////////
0.mtk平臺相關surfaceflinger線程有:
1 mtk採用的是:硬件VSYNC 線程:
2.Mtk 通過surfaceflinger註冊了3個eventthread:
每個event線程都註冊:
voidEventThread::Connection::onFirstRef() {
// NOTE: mEventThread doesn't hold a strongreference on us
mEventThread->registerDisplayEventConnection(this);
}
線程 |
VS信號源 |
功能 |
eventthread: |
vssyncsrc硬件VS |
用於控制App UI的同步,產生sfVsyncSrc的週期:sfVsyncPhaseOffsetNs。在setVSyncEnabled()的時候mDispSync->addEventListener()來設置週期 |
Eventthread |
sfVsyncSrc |
與surfaceflinger的渲染同步,產生vssyncsrc的週期是:vsyncPhaseOffsetNs。在setVSyncEnabled()的時候mDispSync->addEventListener()來設置週期 |
EventControl |
無 |
用來向VSync硬件發命令,只是使能和關閉硬件vs信號 |
DispSync線程 |
vssyncsrc硬件VS |
統一處理硬件產生的vs信號,以及計算幀時間 |
理論上來說:vssyncsrc和sfVsyncSrc都是虛擬的vs。兩者都是通過DispSync線程來計算髮出vs的時間。
2.1 DispSyncThread如何區分和執行vssyncsrc和sfVsyncSrc的VsyncSrc?
答案:
1)首先VSyncSource對象的創建如下
// start the EventThread
sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,返回一個DispSyncSource對象給vsyncSrc
vsyncPhaseOffsetNs, true);
mEventThread = new EventThread(vsyncSrc);
sp<VSyncSource>sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,----返回一個DispSyncSource對象給sfVsyncSrc
sfVsyncPhaseOffsetNs, false);
mSFEventThread = newEventThread(sfVsyncSrc);
mEventQueue.setEventThread(mSFEventThread);
-------也就是每個EventThread都是有管理自己的對象vsyncSrc或者sfVsyncSrc;
---------EventThread::threadLoop-------
{
……...
-waitForEvent()
…...
}
//增加監聽者以及設置接收到vsync的時候callbakc
waitForEvent(){
…..
// Here we figure outif we need to enable or disable vsyncs
if (timestamp && !waitForVSync){
// we received a VSYNC but we haveno clients
// don't report it, and disableVSYNC events
disableVSyncLocked();
} else if (!timestamp &&waitForVSync) {
// we have at least one client, sowe want vsync enabled
// (TODO: this function is calledright after we finish
// notifying clients of a vsync, sothis call will be made
// at the vsync rate, e.g.60fps. If we can accurately
// track the current state we couldavoid making this call
// so often.)
enableVSyncLocked();
}
………
}
void EventThread::enableVSyncLocked() {
if (!mUseSoftwareVSync) {
// never enable h/w VSYNC when screenis off
if (!mVsyncEnabled) {
mVsyncEnabled = true;
/*設置回調VSyncSource::Callback 的onVSyncEvent是純虛函數:EventThread繼承自VSyncSource::Callback。實現了onVSyncEvent()回調函數。
//classEventThread : public Thread, private VSyncSource::Callback
最終:mCallback = callback;
virtual voidsetCallback(const sp<VSyncSource::Callback>& callback) {
Mutex::Autolock lock(mMutex);
mCallback = callback;
}
*/
mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));
mVSyncSource->setVSyncEnabled(true);-----》這側監聽者到mEventListeners
mPowerHAL.vsyncHint(true);
}
}
mDebugVsyncEnabled = true;
}
2)其次硬件常常一個VS--->通知到SurfaceFlinger::onVSyncReceived(inttype, nsecs_t timestamp)//timestamp就是用來計算這次vs的週期:mPeriod ;而mPeriod 就是DispSync線程的執行週期。
virtual bool threadLoop() {
status_t err;
nsecs_t now =systemTime(SYSTEM_TIME_MONOTONIC);
nsecs_t nextEventTime = 0;
while (true) {
Vector<CallbackInvocation>callbackInvocations;
………...
if (mPeriod == 0) {
err = mCond.wait(mMutex);//週期超時 ,則wait,直到下一次HW VS產生
if (err != NO_ERROR) {
ALOGE("errorwaiting for new events: %s (%d)",
strerror(-err),err);
return false;
}
continue;
}
。。。。。。。。。
if (isWakeup) {
mWakeupLatency =((mWakeupLatency * 63) +
(now - targetTime))/ 64;
if (mWakeupLatency >500000) {
// Don't correct bymore than 500 us
mWakeupLatency =500000;
}
if (traceDetailedInfo) {
ATRACE_INT64("DispSync:WakeupLat", now - nextEventTime);
ATRACE_INT64("DispSync:AvgWakeupLat", mWakeupLatency);
}
}
//gatherCallbackInvocationsLocked() 計算出虛擬VSync信號 要多久產生。
callbackInvocations= gatherCallbackInvocationsLocked(now);
}
if (callbackInvocations.size() >0) {
fireCallbackInvocations(callbackInvocations);
//調起監聽者的回調函數DispSyncSource::onDispSyncEvent()-----》callback->onVSyncEvent(when);
}
}
return false;
}
voidfireCallbackInvocations(const Vector<CallbackInvocation>& callbacks){
for (size_t i = 0; i <callbacks.size(); i++) {
callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime);
}
}
“DispSyncThread就像樂隊鼓手一樣控制着大家的節奏。它在主循環中會先通過已經向DispSync註冊的listener計算下一個要產生的虛擬VSync信號還要多久,等待相應時間後就會調用相應listener的callback函數。這樣,對於那些註冊了listener的監聽者來說,就好像被真實的VSync信號控制着一樣。”
小結:相對DispSyncThread而言,vssyncsrc線程和sfVsyncSrc線程是vsync監聽者。
而vssyncsrc和sfVsyncSrc收到vsync之後,應用程序和surfaceflinger(兩線程循環 獲取Event)是vsync事件的接收者。
所以vsynv的路徑就是:DispSyncThread--->vssyncsrc和sfVsyncSrc---->vsync事件的接收者:應用程序和surfaceflinger.
2.2 vssyncsrc線程和sfVsyncSrc線程的vsync事件接受者什麼創建?
1)sfVsyncSrc的vsync事件接收者創建:通過mSFEventThread對象 ;
mSFEventThread= new EventThread(sfVsyncSrc);
mEventQueue.setEventThread(mSFEventThread);
voidMessageQueue::setEventThread(constsp<EventThread>& eventThread)
{
mEventThread = eventThread;
mEvents =eventThread->createEventConnection();
mEventTube = mEvents->getDataChannel();
mLooper->addFd(mEventTube->getFd(),0, ALOOPER_EVENT_INPUT,
MessageQueue::cb_eventReceiver,this);
}
2)vssyncsrc的vsync事件接收者創建:
應用層通過DisplayEventReceiver.java
--->android_view_DisplayEventReceiver.cpp
--->DisplayEventReceiver.cpp
---->EventThread.cpp
一直到mEventThread對象:
sp<IDisplayEventConnection>SurfaceFlinger::createDisplayEventConnection() {
return mEventThread->createEventConnection();
}
2.3 EventControl線程
EventControlThread::threadLoop()
---->
mFlinger->eventControl(HWC_DISPLAY_PRIMARY,
SurfaceFlinger::EVENT_VSYNC, mVsyncEnabled);
----->getHwComposer().eventControl(disp, event, enabled);----->HWComposer::eventControl()
---- mHwc->eventControl() hal層