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, ¶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有一个直观的认识。
SF中DispSync.cpp源码分析相关推荐
- 【朝花夕拾】Android自定义View篇之(六)Android事件分发机制(中)从源码分析事件分发机制...
前言 转载请注明,转自[https://www.cnblogs.com/andy-songwei/p/11039252.html]谢谢! 在上一篇文章[[朝花夕拾]Android自定义View篇之(五 ...
- 【朝花夕拾】Android自定义View篇之(六)Android事件分发机制(中)从源码分析事件分发逻辑及经常遇到的一些“诡异”现象
前言 转载请注明,转自[https://www.cnblogs.com/andy-songwei/p/11039252.html]谢谢! 在上一篇文章[[朝花夕拾]Android自定义View篇之(五 ...
- zipline中benchmarks.py源码分析
zipline中benchmarks源码分析 1 benchmark 基准数据 2 get_benchmark_returns_from_file 从文件中获取基准数据 3 BenchmarkSpec ...
- 力引导算法深入理解及其在d3.js中实现的源码分析
中学时最喜欢的学科是物理,大学误打误撞读了计算机.最近在做图计算的相关工作,图的可视化中有一个非常重要的算法:"力引导算法",这个算法的原理居然就是最简单的粒子间的作用力,真是没想 ...
- Anchor和RPN的浅薄理解(三)-mmdetection中Anchor生成源码分析
在 MMDetection 中,RPN 网络使用 AnchorGenerator 类生成 Anchor,在config文件中 AnchorGenerator 的默认设置如下: anchor_gener ...
- faster rcnn中RPN网络源码分析(pytorch)
最近刚入坑检测,初步看了RGB大佬的faster rcnn文章,再看看源码 本次分析的源码是陈云大佬pytorch版本的GITHUB地址 上一张输入输出图 一.forward 主文件./model/r ...
- Java 8 中 GZIPInputStream 类源码分析
这是<水煮 JDK 源码>系列 的第4篇文章,计划撰写100篇关于JDK源码相关的文章 GZIPInputStream 类位于 java.util.zip 包下,继承于 InflaterI ...
- ndnSIM学习(十)——apps之ndn-producer.cpp和ndn-consumer.cpp源码分析
文章目录 前言 ndn-producer.hpp ndn-consumer.hpp ndn-consumer-cbr.hpp 其他消费者 前言 在前面的文章ndnSIM学习(四)--examples之 ...
- java.lang中String类源码分析
一.类 public final class String:final关键字说明String类不能被修改(不能被其他类继承和重写) public final class Stringimplement ...
最新文章
- Docker环境配置指南!
- CloudStack管理员文档 - 虚拟机
- UNIX环境高级编程》笔记--getrlimit和setrlimit函数
- 性能测试(02)-HttpSampler
- linux ns,Linux Namespace (ns)
- 自然语言处理综述_自然语言处理
- Calender日历类
- goland创建一个不限长度的字节切片_Go语言3 : 切片
- Linux中常用的网络命令
- python可以和java共存吗_python3 and python2 共存
- python判断回文字符串不考虑空格符号大小写_检查带有忽略的标点符号、空格和cas的回文文本...
- 六人扑克牌游戏 三先 规则
- 天然气阶梯是按年还是按月_天然气阶梯不是明年1月1号开始么?怎么现在充气就限量了...
- OLED屏幕还未普及,移动VR没有想象中爆发那么快
- 【ML特征工程】第 5 章 :分类变量:机器鸡时代的鸡蛋计数
- 浪潮之颠二_读书笔记
- SmallTalkEDI程序
- Linux磁盘分区工具fdisk和gdisk的区别
- 从Devcon5大会看以太坊生态的发展
- 【向重复工作说不】c#之模拟鼠标操作