diff --git a/blogs/Android/Framework/Interview/UI 体系相关/Vsync 信号机制.md b/blogs/Android/Framework/Interview/UI 体系相关/Vsync 信号机制.md new file mode 100644 index 0000000..8fe3edb --- /dev/null +++ b/blogs/Android/Framework/Interview/UI 体系相关/Vsync 信号机制.md @@ -0,0 +1,103 @@ +--- +Vsync 信号机制 +--- + +1. Vsync 信号的生成机制 +2. Vsync 在 SurfaceFlinger 中的分发流程 +3. Vsync 信号的分发原理 + +![](https://i.loli.net/2020/03/26/XIw6DvOa2MTRKoj.png) + +```c++ +void SurfaceFlinger::init(){ + sp vsyncSrc = new DispSyncSource(&mPrimaryDispSync, vsyncPhaseOffsetNs, true, "app"); + mEventThread = new EventThread(vsyncSrc); + sp sfVsyncSrc = new DisSyncSource(&mPrimaryDispSync, sfVsyncPhaseOffsetNs, true, "sf"); + mSFEventThread = new EventThread(sfVsyncSrc); + mHwc = new HWComposer(this, *static_cast(this)); +} +// 主要用于生成 Vsync 信号 +HWComposer::HWComposer(const sp& flinger, ...){ + bool needVsyncThread = true; + loadHwcModule(); + if(mHwc){ + mCBContext->procs.vsync = &hook_vsync; + needVsyncThread = false; + } + if(needVsyncThread){ + mVsyncThread = new VsyncThread(*this); + } +} +// hook_vsync +void HWComposer::vsync(int disp, int64_t timestamp){ + mEventHandler.onVSyncReceived(disp, timestamp); +} +// 软件分发 +bool HWComposer::VSyncThread::threadLoop(){ + clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL); + mHwc.mEventHandler.onVSyncReceived(0, next_vsync); + return true; +} + +void SurfaceFlinger::onVSyncReceived(int type, nsece_t timestamp){ + mPrimaryDispSync.addResyncSample(timestamp); +} +bool DispSync::addResyncSample(nsecs_t timestamp){ + mResyncSamples[idx] = timestamp; + updateModelLocked(); +} +void DispSync::updateModelLocked(){ + mThread->updateModel(mPeriod, mPhase); +} +DispSync::DispSync():mThread(new DispSyncThread()){ + mThread->run("DispSync", ...); +} +// 工作线程的处理流程 +virtual bool threadLoop(){ + while(true){ + if(mPeriod == 0){ + mCond.wait(mMutex); + continue; + } + now = systemTime(SYSTEM_TIME_MONOTONIC); + callbackInvocations = gatherCallbackInvocationsLocked(now); + fireCallbackInvocations(callbackInvocations); + } + return false; +} +``` + +```c++ +void EventThread::onVSyncEvent(nsecs_t timestamp){ + mVSyncEvent[0].header.timestamp = timestamp; + mCondition.broadcast(); +} +Vector> EventThread::waitForEvent(...){ + do{ + // 检查 mVSyncEvent 数组,看有没有 VSync 触发 + // 如果有就遍历所有注册的 connection + // 如果 count>=0 就加到 signalConnections 里,加的时候重置为 -1 + if(!timestamp){ + if(waitForVSync){ + mCondition.waitRelative(mLock, timeout); + } + } + }while(signalConnections.isEmpty()); + return signalConnections; +} +``` + +```c++ +status_t EventThread::Connection::postEvent(...){ + DisplayEventReceiver::sendEvents(mChannel, &event, 1); +} +ssize_t DisplayEventReceiver::sendEvents(const sp&dataChannel, Event const* events, size_t count){ + return BitTube::sendObjects(dataChannel, events, count); +} +ssize_t BitTube::sendObjects(const sp&tube, void const* events, size_t count, size_t objSize){ + const char* vaddr = reinterpret_cast(events); + sszie_t size = tube->write(vaddr, count*objSize); +} +``` + +![](https://i.loli.net/2020/03/26/gsG1Jlv8cxmCzIE.png) \ No newline at end of file diff --git a/images/Android/Framework/Interview/VSync 分发.png b/images/Android/Framework/Interview/VSync 分发.png new file mode 100644 index 0000000..2c6a8d5 Binary files /dev/null and b/images/Android/Framework/Interview/VSync 分发.png differ diff --git a/images/Android/Framework/Interview/Vsync 分发流程.png b/images/Android/Framework/Interview/Vsync 分发流程.png new file mode 100644 index 0000000..a2151fe Binary files /dev/null and b/images/Android/Framework/Interview/Vsync 分发流程.png differ