EventThread线程对VSync的分发
EventThread线程对VSync的分发
前面提到,EventThread在接收到VSync后再将它们分发给感兴趣的注册者,分发的过程是在其线程循环threadLoop函数中完成的。读者也可以先阅读后面一节内容,先了解感兴趣的注册者如何得到VSync通知以及系统中可能存在哪些感兴趣的注册者后,再回来阅读本小节。
感兴趣的注册者首先需要创建到EventThread的连接,这个到EventThread的连接将保存到EventThread的列表中。创建连接的代码如下(下面的行56,参见文件EventThread.cpp):
由于Connection的父类中有RefBase,所以其重载的onFirstRef函数将被调用,后者又调用registerDisplayEventConnection函数将自己(即“连接”Connection)注册给EventThread(上面的行62);也就是说,每个连接创建时,都要将连接注册到EventThread中,以让EventThread给自己发送VSync事件通知。由于连接可能会失效,所以EventThread中维护的是一个连接的弱指针列表。在有新的连接注册后,需要通知(行63)给threadLoop循环,让其从睡眠中醒来。
EventThread的threadLoop函数的前面的代码如下:
在内嵌的do-while循环(上面的行135~184)中,若注册者指定了需要报告VSync(即行146处的Connection中的count大于0),且VSync时间戳不为0(行153),则跳出该do-while循环,往下执行准备分发VSync事件;若不需要分发,且原来的时间戳不为0,表示VSync还是激活状态,因此去关闭VSync(行157);若时间戳为0,可能VSync原来已经是未激活状态,但若需要分发,则激活VSync(行169);若屏幕关闭(不需刷新输出,VSync关闭)且需分发,那么将睡眠片刻超时后的时间作为VSync时间戳(行178、179),然后在下一个while循环中走到行153和160,跳出while循环,表示是软件模拟的VSync事件;否则,即屏幕打开和屏幕关闭但不需分发的两种情形,这时,将进入睡眠等待状态(行182)。在屏幕打开状态下,VSync很快就会到来(除非主动关闭了VSync),或者有新的感兴趣者进行了注册,或者注册者请求改变了VSync分发频率(见下一小节),这些都将被唤醒行182处的睡眠等待。在屏幕关闭且不需分发VSync的情况下,那么就可以让EventThread线程一直睡眠下去,不需醒来,直到屏幕打开后被唤醒再次开始进行do-while循环的工作。
在跳出第一个内嵌的循环后,表示有VSync需要分发报告,这时将计数器加1(下面的行187),记录下时间戳信息(行188);然后再次在for循环(行192~215)中检查注册者是否已经失效(行196)、报告频率(是否这次该给某个注册者报告,行200、201)等,若需要报告,则将该注册者添加到待报告列表displayEventConnections中(行213)。在行216,若待报告列表为空,则继续while循环,否则就往下执行,准备去分发VSync事件通知。
下面的代码是threadLoop的后面的代码。首先准备好DisplayEvent事件(当前也就只是VSync一种),包括类型和时间戳等信息(行219~221)。再接着,在for循环(行224~246)中,逐个向待处理队列中的连接发送DisplayEvent(VSync)事件(行228)。这就完成了对感兴趣的注册者的分发。
可见,threadLoop首先根据注册者和设备(屏幕是否关闭)等情况判断是否需要分发下一个VSync;在不需要分发(如屏幕关闭并且也没有接收者的情形)或完成任务后等待下一个硬件或软件模拟VSync到来时,则进入睡眠等待状态;当被唤醒(如VSync到来)后,若需要报告分发,则将接收者添加到待处理队列列表中,最后通过连接Connection的postEvent函数分发VSync显示事件给注册的接收者。
本文节选自《深入剖析Android系统》一书
杨长刚著
电子工业出版社出版
EventThread线程对VSync的分发相关推荐
- Swing 的任务线程与 EDT 事件分发队列模型
1 现象及问题 在Swing程序中,经常能看到如下这种代码: 为何用invokeLater,而不直接调用呢? 大多数Swing的API非线程安全,不能在任意地方调用,应该只在EDT中调用. Swing ...
- Android显示系统详解
一.显示系统的分类: 我们来思考一个问题:从普通用户角度来说,某个APP页面(例如购物APP首页)是怎么被显示到屏幕的? 首先看到的是物理屏幕,然后是屏幕中软件工程师编写的APP页面,也就是手机屏幕驱 ...
- vsync信号产生与分发
以下分析基于android 4.4代码 vsync信号的产生.分发涉及到以下几个类,先主要了解下他们各自的功能: HWComposer:产生hardware vsync,post fb VSyncTh ...
- Android SurfaceFlinger vsync信号产生与分发
原址 以下分析基于android 4.4代码 vsync信号的产生.分发涉及到以下几个类,先主要了解下他们各自的功能: HWComposer:产生hardware vsync,post fb VSyn ...
- android vsync,android display之VSync和线程处理关系
目录: 0.mtk平台相关surfaceflinger线程有那些? 1 mtk采用的是:硬件VSYNC线程 2.Mtk通过surfaceflinger注册了3个eventthread 2.1DispS ...
- Android SurfaceFlinger 学习之路(五)----VSync 工作原理
原址 VSync信号的科普我们上一篇已经介绍过了,这篇我们要分析在SurfaceFlinger中的作用.(愈发觉得做笔记对自己记忆模块巩固有很多帮助,整理文章不一定是用来给别人看的,但一定是为加强自己 ...
- Android SurfaceFlinger SW Vsync模型
Android SurfaceFlinger Vsync这块比较复杂,最初在看这块的时候,迟迟不知道从何入手,网上看了各种SurfaceFlinger Vsync相关的博客,个人感觉紧紧是把代码流程给 ...
- vsync 信号处理
Android 系统每隔 16ms 发出 VSYNC 信号,触发对 UI 进行渲染,VSync 是 Vertical Synchronization(垂直同步)的缩写,是一种在PC上很早就广泛使用的技 ...
- Android12 SurfaceFlinger Vsync
Vsync可以控制系统绘图/合成的频率周期,是内容能够在正确的时机完整地显示在屏幕上 在Surfaceflinger中有一套SW-Vsync的机制,能够更灵活的控制app绘图与surfacefling ...
- 07.显示系统:第005课_Vsync机制:第004节_surface使用vsync过程代码分析
前面的小节中,我们讲解了Vsync机制机制的框架,无论SurfaceFlinger还是APP应用程序,对Vsync的使用,都是按需进行的: 比如应用程序把新界面发送给SurfaceFlinger之后, ...
最新文章
- 【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | 查找 DexFile 对应的C代码 | dalvik_system_DexFile.cpp 分析 )
- VB.NET循环体内的局部变量
- 对于analyze table使用
- spring的log4j listener(webAppRootKey)
- 事件冒泡及阻止事件冒泡 事件的触发 事件参数对象 获取用户按下键盘的键
- Error: This command has to be run with superuser privileges (under the root user on most systems).
- java输入月份求天数_java输入年份,月份,输出当月天数
- ftp 上传文件夹_命令行连接FTP服务器
- 孜然网址导航系统源码v1.0
- html提交列表编号自动生成目录,解析 Html 自动生成目录 TOC 的相关代码
- opend和open的区别_open与open up的区别
- python怎么开始_Python自己学习怎么开始?
- android多图片拖动,Android实现图片拖动效果
- Dapper:The member of type SeoTKD cannot be used as a parameter Value
- 人性”的三张图,改变无数人!
- 如何在程序中不用加号实现加法_python不用加号实现加法
- C#数组和list集合的区别
- SpringBoot的C2C水果商城系统
- 东鹏饮料,有点“上头”
- php 发邮件 上传附件,PHPMailer实现PHP的邮件发送,附带附件