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系统》一书
杨长刚著
电子工业出版社出版
相关推荐
vsync 生产、vsync-app 和 vsync-sf 请求、响应; 核心代码、类图、pefetto 图
libgdx FullScreen&vsync
view.onDraw–>canvas.draw–>rasterizer–> view.onDraw–>canvas.draw- openGL...,候时的制绘们我知通统系,件事收接的知通统系是 大太是不知感 对 。顿卡有会以所,调步个这响影会能可程线主是但,定稳隔间前目台平
vsync ) input clock //系统输入时钟 50MHz input [1:0]switch output [2:0]disp_RGB //VGA数据输出 output hsync //VGA行同步信号 output vsync //VGA场同步信号 reg [9:0] hcount //VGA行扫描计数器 reg [9:0]...
vsync_provider VsyncProvider为AnimationController提供vsync。 这适用于。 例子
图文并茂地讲述了图形显示double buffering、vsync信号和triple buffering的机理。
谷歌官方发布视频
SurfaceFlinger 视频教程 显示系统,内部机制,Vsync机制,HDMI系统
适用于Cinder的Vsync / FPS测试应用程序 (提交之日为HEAD) 也可以在获得openFrameworks版本
FPGA控制VGA接口显示屏8种色彩的循环变化实验Verilog逻辑源码Quartus11.0工程文件, FPGA型号为CYCLONE4E系列中的...//分别对RGB的3位数据进行判断 //R,G,B控制液晶屏颜色显示 //最终显示屏显示的颜色是RGB3种颜色的叠加
华为 鸿蒙系统 开发
ffmpeg作为音视频开发和解码的主要工具,其命令格式为应用提供了很大的方便,该工具主要是介绍了ffmpeg的命令参数,非常全面,希望能帮到您。最全的ffmpeg命令参数
camera_vsync, camera_href, camera_pclk, camera_xclk, camera_data, camera_rst_n, camera_pwdn ); input Clk; input Rst_n; output GMII_GTXC; output [7:0]GMII_TXD; output GMII_TXEN; output ...
它决定了引脚 5 上 VSync 信号的频率,并相应地切换引脚 6 的输出电平(50Hz = 0V;60Hz = 5V)。 该程序已发布到公共领域; 作者希望上述原始归属保持不变。 引脚配置: ,---_---. +5V |1 8| GND nc |2 7| nc nc |...
Ov7725_rx模块是一个Ov7725摄像头接收模块,具有通用性,顶层接口如下: parameter RGB_TYPE;输出RGB数据类型; RGB_TYPE=1,输出24bit的RGB888视频; RGB_TYPE=0,输出16bit的RGB565视频; Input rst_n;输入复位...
esp32 通过WiFi联网控制摄像头采集图像并通过oled屏幕显示
编舞Android的Project Butter的Choreographer测试。 一个可运行的示例代码,用于... 而且,每次接收到VSync信号时,它都会使用来自编舞者的信息来估计每秒帧数(FPS)。 您可以在以下链接中找到Project Butter的介绍:
垂直同步 用于FiveM服务器的简单天气和时间同步脚本。 当前版本: 1.3.0作者: Vespura最近更新: 2018年1月13日 特征 每隔10分钟(可以(暂时或永久)禁用)动态变化的天气。天气将仅根据实际情况而变化。...
授予它对整个 Dropbox 的完全访问权限。 您可以随意命名; 它只会被你使用。 在您的应用设置页面上,为您的帐户获取“生成的访问令牌”。 在~/.shadowbox创建一个文件,其中包含: { "token": "YOUR_G
XILINX SPARTAN6 FPGA OV75640摄像头GVA显示实验 VERILOG逻辑例程源码 ISE14.7工程文件 module ov5640_vga( input clk_50M, input reset_n, output [3:0] led, //led灯指示 ... input camera_vsync, //cmos vsync