我是靠谱客的博主 从容鸡翅,最近开发中收集的这篇文章主要介绍SF中DispSync.cpp源码分析,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

源码位置位于: /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, &param) != 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有一个直观的认识。

最后

以上就是从容鸡翅为你收集整理的SF中DispSync.cpp源码分析的全部内容,希望文章能够帮你解决SF中DispSync.cpp源码分析所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(48)

评论列表共有 0 条评论

立即
投稿
返回
顶部