源码位置位于: /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源码分析相关推荐

  1. 【朝花夕拾】Android自定义View篇之(六)Android事件分发机制(中)从源码分析事件分发机制...

    前言 转载请注明,转自[https://www.cnblogs.com/andy-songwei/p/11039252.html]谢谢! 在上一篇文章[[朝花夕拾]Android自定义View篇之(五 ...

  2. 【朝花夕拾】Android自定义View篇之(六)Android事件分发机制(中)从源码分析事件分发逻辑及经常遇到的一些“诡异”现象

    前言 转载请注明,转自[https://www.cnblogs.com/andy-songwei/p/11039252.html]谢谢! 在上一篇文章[[朝花夕拾]Android自定义View篇之(五 ...

  3. zipline中benchmarks.py源码分析

    zipline中benchmarks源码分析 1 benchmark 基准数据 2 get_benchmark_returns_from_file 从文件中获取基准数据 3 BenchmarkSpec ...

  4. 力引导算法深入理解及其在d3.js中实现的源码分析

    中学时最喜欢的学科是物理,大学误打误撞读了计算机.最近在做图计算的相关工作,图的可视化中有一个非常重要的算法:"力引导算法",这个算法的原理居然就是最简单的粒子间的作用力,真是没想 ...

  5. Anchor和RPN的浅薄理解(三)-mmdetection中Anchor生成源码分析

    在 MMDetection 中,RPN 网络使用 AnchorGenerator 类生成 Anchor,在config文件中 AnchorGenerator 的默认设置如下: anchor_gener ...

  6. faster rcnn中RPN网络源码分析(pytorch)

    最近刚入坑检测,初步看了RGB大佬的faster rcnn文章,再看看源码 本次分析的源码是陈云大佬pytorch版本的GITHUB地址 上一张输入输出图 一.forward 主文件./model/r ...

  7. Java 8 中 GZIPInputStream 类源码分析

    这是<水煮 JDK 源码>系列 的第4篇文章,计划撰写100篇关于JDK源码相关的文章 GZIPInputStream 类位于 java.util.zip 包下,继承于 InflaterI ...

  8. ndnSIM学习(十)——apps之ndn-producer.cpp和ndn-consumer.cpp源码分析

    文章目录 前言 ndn-producer.hpp ndn-consumer.hpp ndn-consumer-cbr.hpp 其他消费者 前言 在前面的文章ndnSIM学习(四)--examples之 ...

  9. java.lang中String类源码分析

    一.类 public final class String:final关键字说明String类不能被修改(不能被其他类继承和重写) public final class Stringimplement ...

最新文章

  1. Docker环境配置指南!
  2. CloudStack管理员文档 - 虚拟机
  3. UNIX环境高级编程》笔记--getrlimit和setrlimit函数
  4. 性能测试(02)-HttpSampler
  5. linux ns,Linux Namespace (ns)
  6. 自然语言处理综述_自然语言处理
  7. Calender日历类
  8. goland创建一个不限长度的字节切片_Go语言3 : 切片
  9. Linux中常用的网络命令
  10. python可以和java共存吗_python3 and python2 共存
  11. python判断回文字符串不考虑空格符号大小写_检查带有忽略的标点符号、空格和cas的回文文本...
  12. 六人扑克牌游戏 三先 规则
  13. 天然气阶梯是按年还是按月_天然气阶梯不是明年1月1号开始么?怎么现在充气就限量了...
  14. OLED屏幕还未普及,移动VR没有想象中爆发那么快
  15. 【ML特征工程】第 5 章 :分类变量:机器鸡时代的鸡蛋计数
  16. 浪潮之颠二_读书笔记
  17. SmallTalkEDI程序
  18. Linux磁盘分区工具fdisk和gdisk的区别
  19. 从Devcon5大会看以太坊生态的发展
  20. 【向重复工作说不】c#之模拟鼠标操作

热门文章

  1. 小米嵌入式工程师面试-心得
  2. 各个级别的教师资格证分别可以教什么阶段
  3. 数字图像处理 使用opencv+python识别七段数码显示器的数字
  4. 专访阿里巴巴毕玄:异地多活数据中心项目的来龙去脉
  5. oracle ebs克隆报错,Oracle EBS R12.1.1 应用克隆 - 2
  6. 堡垒主机在信息安全等级保护制度中的探究与应用
  7. 什么是物联网?物联网如何工作?
  8. 腾讯云点播服务端API
  9. 基于matlab的电流滞环控制,电流滞环控制matlab
  10. 粒倍营浅谈如何做好SEO