源码位置位于: /frameworks/native/services/surfaceflinger/DispSync.cpp
先来看下构造方法:
关键是初始化了DispSyncThread线程变量,暂时不看。看下init方法。
0void DispSync::init(bool hasSyncFramework, int64_t dispSyncPresentTimeOffset) {
391 mIgnorePresentFences = !hasSyncFramework;
392 mPresentTimeOffset = dispSyncPresentTimeOffset;
//开始运行线程。
393 mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
394
395 // set DispSync to SCHED_FIFO to minimize jitter
396 struct sched_param param = {0};
397 param.sched_priority = 2;
398 if (sched_setscheduler(mThread->getTid(), SCHED_FIFO, ¶m) != 0) {
399 ALOGE("Couldn't set SCHED_FIFO for DispSyncThread");
400 }
401
402 reset();
403 beginResync();
404
405 if (kTraceDetailedInfo) {
406 // If we're not getting present fences then the ZeroPhaseTracer
407 // would prevent HW vsync event from ever being turned off.
408 // Even if we're just ignoring the fences, the zero-phase tracing is
409 // not needed because any time there is an event registered we will
410 // turn on the HW vsync events.
411 if (!mIgnorePresentFences && kEnableZeroPhaseTracer) {
412 mZeroPhaseTracer = std::make_unique<ZeroPhaseTracer>();
413 addEventListener("ZeroPhaseTracer", 0, mZeroPhaseTracer.get());
414 }
415 }
416}
来看下,其中的reset,就是初始化变量值。
来看下 beginResync()方法。
这里也只是把mModelUpdated 和mNumResyncSamples赋值。貌似没有走业务逻辑。再来看下。主要看下threadLoop() 方法。
virtual bool threadLoop() {
93 status_t err;
94 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
95
96 while (true) {
97 Vector<CallbackInvocation> callbackInvocations;
98
99 nsecs_t targetTime = 0;
100
101 { // Scope for lock
102 Mutex::Autolock lock(mMutex);
103
104 if (kTraceDetailedInfo) {
105 ATRACE_INT64("DispSync:Frame", mFrameNumber);
106 }
107 ALOGV("[%s] Frame %" PRId64, mName, mFrameNumber);
108 ++mFrameNumber;
109
110 if (mStop) {
111 return false;
112 }
113
114 if (mPeriod == 0) {
115 err = mCond.wait(mMutex);
116 if (err != NO_ERROR) {
117 ALOGE("error waiting for new events: %s (%d)", strerror(-err), err);
118 return false;
119 }
120 continue;
121 }
122
123 targetTime = computeNextEventTimeLocked(now);
124
125 bool isWakeup = false;
126
127 if (now < targetTime) {
128 if (kTraceDetailedInfo) ATRACE_NAME("DispSync waiting");
129
130 if (targetTime == INT64_MAX) {
131 ALOGV("[%s] Waiting forever", mName);
132 err = mCond.wait(mMutex);
133 } else {
134 ALOGV("[%s] Waiting until %" PRId64, mName, ns2us(targetTime));
135 err = mCond.waitRelative(mMutex, targetTime - now);
136 }
137
138 if (err == TIMED_OUT) {
139 isWakeup = true;
140 } else if (err != NO_ERROR) {
141 ALOGE("error waiting for next event: %s (%d)", strerror(-err), err);
142 return false;
143 }
144 }
145
146 now = systemTime(SYSTEM_TIME_MONOTONIC);
147
148 // Don't correct by more than 1.5 ms
149 static const nsecs_t kMaxWakeupLatency = us2ns(1500);
150
151 if (isWakeup) {
152 mWakeupLatency = ((mWakeupLatency * 63) + (now - targetTime)) / 64;
153 mWakeupLatency = min(mWakeupLatency, kMaxWakeupLatency);
154 if (kTraceDetailedInfo) {
155 ATRACE_INT64("DispSync:WakeupLat", now - targetTime);
156 ATRACE_INT64("DispSync:AvgWakeupLat", mWakeupLatency);
157 }
158 }
159
160 callbackInvocations = gatherCallbackInvocationsLocked(now);
161 }
162
163 if (callbackInvocations.size() > 0) {
164 fireCallbackInvocations(callbackInvocations);
165 }
166 }
167
168 return false;
169 }
主要来看下gatherCallbackInvocationsLocked()和fireCallbackInvocations()方法。这里面主要是用来收集监听器和发送监听器。 这里的监听器主要是addEventListener来增加的。
这个就是跟sf交互的点。来看下sf是如何把callback加入进去的。sf中监听器是以 DispSyncSource的实现存在的。来看看其中onDispSyncEvent方法。
4private:
575 virtual void onDispSyncEvent(nsecs_t when) {
576 VSyncSource::Callback* callback;
577 {
578 Mutex::Autolock lock(mCallbackMutex);
579 callback = mCallback;
580
581 if (mTraceVsync) {
582 mValue = (mValue + 1) % 2;
583 ATRACE_INT(mVsyncEventLabel.string(), mValue);
584 }
585 }
586
587 if (callback != nullptr) {
588 callback->onVSyncEvent(when);
589 }
590 }
可以看到经过一些逻辑后,又传递给了callback。这里的mCallback是通过
设置的。此篇文章主要是对DispSync有一个直观的认识。