EventThread线程对VSync的接收

EventThread被设计用来接收VSync事件通知,并分发VSync通知给系统中的每一个感兴趣的注册者。VSync来源自底层硬件驱动程序的上报,对于Android能看到的接口来说,它是来自HAL层的hwc_composer_device的抽象硬件设备。若硬件不支持,则HWComposer会创建一个线程去模拟产生VSync事件通知。一旦工作起来,VSync将像一个脉搏一样,不断通知到Surfaceflinger中的EventThread线程,由后者再分发给感兴趣的注册者。

先来看一下EventThread何时被创建并开始运行的。

在SurfaceFlinger类被创建时,它的onFirstRef函数将被调用(因为最终继承自RefBase),代码如下:

因为SurfaceFlinger继承自线程类Thread(上面的行130)调用了run函数,意味着创建一个新线程的执行。它的过程是:Thread::run将创建一个新线程,名称为SurfaceFlinger(后面我们将称之为SurfaceFlinger线程),线程的入口函数Thread::_threadLoop又将调用子类重载的threadLoop函数,不过在调用重载的threadLoop之前,先调用子类重载的readyToRun(只是初次时)。也就是说,此处的run函数调用将启动一个新线程SurfaceFlinger,然后SurfaceFlinger的readyToRun函数在其里面被调用,从而做一些初始化工作,如前面提到的从ashm分配一块共享控制块surface_flinger_cblk_t,见前面的11.5.2小节。

在SurfaceFlinger的readyToRun函数的后面,将会创建EventThread线程(下面的行300):

在其EventThread的onFirstRef中被要求开始执行,见行52(参见文件EventThread.cpp):

这样,EventThead在创建后,马上开始了它的线程循环。

再来看一下HAL层是如何向EventThread发送VSync通知的。

在HAL层的文件hardware/libhardware/include/hwcomposer.h中定义了一个供底层向上调用的回调例程hwc_procs结构体,它包含两个例程函数:invalidate和vsync。代码如下(见文件hwcomposer.h):

在Android的HWComposer.h中定义了两个结构体:回调callbacks和回调上下文cb_context。其中callbacks继承自上面的hwc_procs,代码如下:

在HWComposer的构造函数中,先从库中解析符号,然后打开HWComposer硬件模块(下面的行00063),再根据其open函数打开HAL抽象硬件设备mHwc(下面的行00066),然后再判断硬件设备mHwc是否支持registerProcs函数(下面的行00070)。若硬件平台厂商实现了该函数,并在open函数中将其赋值给了HAL抽象硬件设备hwc_composer_device的registerProcs成员,则该成员不为空,表示支持上述的回调例程hwc_procs。HWComposer的构造函数将依据此来判断是否支持VSync,代码如下(参见文件HWComposer.cpp):

在硬件平台支持VSync的情况下,通过上面的行00072~00073的赋值和行00074的注册回调例程,来自底层HAL的调用,将转到调用钩子函数hook_xxx。其中回调例程hwc_procs中的VSync将指向hook_vsync钩子函数,后者代码如下(参见文件HWComposer.cpp):

它又调用到下面的VSync成员函数(参见文件HWComposer.cpp):

上面行00125的mEventHandler实际为DisplayHardware对象。在HWComposer中,定义了一个抽象接口EventHandler,并维护了一个EventHandler类型的对象引用;而DisplayHardware实现了该接口,并在DisplayHardware的init函数初始化时,创建了HWComposer对象,将其指定给了HWComposer维护的EventHandler对象引用(即mEventHandler,见上面HWComposer构造函数的行00048)。因此,对VSync的调用将调用到DisplayHardware的onVSyncReceived函数,后者的代码如下(参见文件DisplayHardware.cpp):

这将继续调用到DisplayHardware中维护的一个handler,而这个handler实际是EventThread的对象(见EventThread::onFirstRef函数,在该函数中指定)。因此,对VSync的调用实际调用到下面的EventThread的onVSyncReceived成员函数(见EventThread.cpp):

这将唤醒EventThread线程的循环函数threadLoop在Condition上的睡眠等待。

EventThread的线程循环函数threadLoop主要用于向系统中对VSync感兴趣的注册者分发VSync事件通知,下节将对其做详细介绍。

对于不支持VSync上报通知的硬件平台来说,则HWComposer会创建一个VSyncThread线程,用于模拟VSync的发送。在HWComposer构造函数的后面,判断出需要模拟一个VSync线程后即创建该线程(下面的行92),代码如下:

VSyncThread的线程循环函数threadLoop后面的部分代码如下(参见文件HWComposer.cpp):

上面的行318睡眠片刻,醒来后即模拟发送VSync事件通知(行322)。睡眠的时间最终由HWComposer中的刷新率变量mRefreshPeriod确定,该值来自framebuffer device或系统设置信息,mRefreshPeriod在HWComposer的构造函数中被赋值,见前面其构造函数的代码行55中。如图11-21所示,VSync起源于①,经过一步步调用,执行到②,唤醒可能正在睡眠的线程,然后由线程循环函数去分发它。图中①到②是本小节讲述的,②后面的将在下一小节讲述。

图11‑21  EventThread接收和分发VSync示意图

本文节选自《深入剖析Android系统》一书

杨长刚著

电子工业出版社出版

EventThread线程对VSync的接收相关推荐

  1. 两个线程同时从服务器接收消息_Linux高性能服务器处理框架

    本文为转载,文中所提到的知识点是每个Linux开发人员都需要考虑的问题.https://www.jianshu.com/p/db15ff4e8359 终于开始学习epoll了,虽然不明白的地方还是很多 ...

  2. 两个线程同时从服务器接收消息_一文看懂I/O多路复用技术(mysql线程池)

    概述 当我们要编写一个echo服务器程序的时候,需要对用户从标准输入键入的交互命令做出响应.在这种情况下,服务器必须响应两个相互独立的I/O事件:1)网络客户端发起网络连接请求,2)用户在键盘上键入命 ...

  3. C语言 线程的回收与子线程返回值的接收

    穿的参数为二级指针 需要用全局变量来返回子线程的返回值 // ..使用内存映射可以拷贝文件 /* 对原始文件进行内存映射 创建一个新文件 把新文件的数据拷贝映射到内存中 通过内存拷贝将第一个文件的内存 ...

  4. C#线程池ThreadPool.QueueUserWorkItem接收线程执行的方法返回值

    最近在项目中需要用到多线程,考虑了一番,选择了ThreadPool,我的需求是要拿到线程执行方法的返回值, 但是ThreadPool.QueueUserWorkItem的回调方法默认是没有返回值的,搜 ...

  5. android vsync,android display之VSync和线程处理关系

    目录: 0.mtk平台相关surfaceflinger线程有那些? 1 mtk采用的是:硬件VSYNC线程 2.Mtk通过surfaceflinger注册了3个eventthread 2.1DispS ...

  6. qt 线程接收线程 moveToThread 特性

    qt 线程槽函数 假定一个线程继承QThread,那么这个线程的槽函数接收信号启动后,是在线程里执行否,答案并不是,只有run 函数才是执行在线程中的,要让槽函数执行在线程中,必须使用qt moveT ...

  7. c# tcpip 通信 Task线程接收信息

    1 c# tcpip通信-用线程实现数据接收与发送 针对用定时器实现数据接收过程出现的界面卡死现象,本次采用线程进行数据接收过程.服务端和客户端如图1所示. 图1 服务端和客户端 2 程序讲解 c# ...

  8. vsync信号产生与分发

    以下分析基于android 4.4代码 vsync信号的产生.分发涉及到以下几个类,先主要了解下他们各自的功能: HWComposer:产生hardware vsync,post fb VSyncTh ...

  9. Android SurfaceFlinger 学习之路(五)----VSync 工作原理

    原址 VSync信号的科普我们上一篇已经介绍过了,这篇我们要分析在SurfaceFlinger中的作用.(愈发觉得做笔记对自己记忆模块巩固有很多帮助,整理文章不一定是用来给别人看的,但一定是为加强自己 ...

  10. Android SurfaceFlinger vsync信号产生与分发

    原址 以下分析基于android 4.4代码 vsync信号的产生.分发涉及到以下几个类,先主要了解下他们各自的功能: HWComposer:产生hardware vsync,post fb VSyn ...

最新文章

  1. 创建新的ros工作空间
  2. laravel使用的模板引擎 blade
  3. MPEG原理分析及MPEG音频编码器的调试
  4. 数据管理 - 每天5分钟玩转 Docker 容器技术(147)
  5. python语言的两种注释方法_python编程时添加中文注释的方法
  6. laravel 5.1 php版本号,发行版本说明 | 序言 | Laravel 5.1 中文文档
  7. 视频会议系统OpenMeetings v5.1.0源码
  8. c++ loadlibrary 初始化对象_C++构造函数和初始化表
  9. 第二:Pycharm设置配置(非常详细)
  10. 程序员面试宝典(一) - 流程概览
  11. Macbook怎么开启三指移动 ForceTouch TrackPad开启三指移动方法
  12. 操作系统期末考试重点知识
  13. 手把手教你Markdown语法
  14. 渐变按钮 css,CSS3 Gradient Buttons
  15. 在Word2007文档中设置页面边框
  16. Linux中根据文件大小排序
  17. 【JavaScript】ES6 数组的扩展
  18. day25/RegexDemo1.java
  19. 浅析计算机网络技术相关论文,计算机网络技术浅析论文 - 经典论文
  20. Mac的brew和brew cask区别

热门文章

  1. 怎么用Excel来批量生成SQL语句
  2. 自定义微信小程序导航(兼容各种手机)
  3. HDU3746 Cyclic Nacklace KMP求循环节
  4. 《最后的狮子》纪录片观后
  5. 有面值为1元、3元和5元的硬币若干枚,如何用最少的硬币凑够11元?
  6. myeclipse注册机,自己生成注册码
  7. PaddlePaddle(7)—— 项目全流程实战:公共场所吸烟检测与EasyEdge部署
  8. (BookxNote Pro)Windows版Marginnote 3 阅读神器 自动生成脑图/思维导图
  9. 题目1120:全排列(回溯法)
  10. HTTP协议及POST与GET操作差异,C#中如何使用POST、GET等