Android为了增强界面流畅度引入了VSync机制。VSync信号一般由硬件产生,为了兼容一些老的机器,也可以软件产生。因些,就可以分为硬件VSync和软件VSync。VSync的生成逻辑主要在HWComposer里面。相关文件如下:

frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp

frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.h

HWComposer在SurfaceFlinger的init函数里创建:

void SurfaceFlinger::init() {

ALOGI( "SurfaceFlinger's main thread ready to run. "

"Initializing graphics H/W...");

......

// Initialize the H/W composer object. There may or may not be an

// actual hardware composer underneath.

mHwc = new HWComposer(this,

*static_cast<:eventhandler>(this));

......

}

SurfaceFlinger成员变量保存了HWComposer对象指针

创建HWComposer时,使用SurfaceFlinger作为参数传入

HWComposer::HWComposer(

const sp& flinger,

EventHandler& handler)

: mFlinger(flinger),

mFbDev(0), mHwc(0), mNumDisplays(1),

mCBContext(new cb_context),

mEventHandler(handler),

mDebugForceFakeVSync(false)

{

......

bool needVSyncThread = true;

// Note: some devices may insist that the FB HAL be opened before HWC.

int fberr = loadFbHalModule();

loadHwcModule();

.......

if (mHwc) {

ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER,

(hwcApiVersion(mHwc) >> 24) & 0xff,

(hwcApiVersion(mHwc) >> 16) & 0xff);

if (mHwc->registerProcs) {

mCBContext->hwc = this;

mCBContext->procs.invalidate = &hook_invalidate;

mCBContext->procs.vsync = &hook_vsync;

if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))

mCBContext->procs.hotplug = &hook_hotplug;

else

mCBContext->procs.hotplug = NULL;

memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));

mHwc->registerProcs(mHwc, &mCBContext->procs);

}

// don't need a vsync thread if we have a hardware composer

needVSyncThread = false;

// always turn vsync off when we start

eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);

......

}

......

if (needVSyncThread) {

// we don't have VSYNC support, we need to fake it

mVSyncThread = new VSyncThread(*this);

}

}

在构造函数里把SurfaceFlinger对象指针赋值给成员变量mFlinger和mEventHandler

首先尝试加载HWC模块,如果加载成功就使用硬件vsync,加载失败就使用软件模拟vsync

在加载HWC硬件模块时,会注册vsync回调函数HWComposer::hook_vsync。当硬件vsync到来时会调用些函数。代码如下:

void HWComposer::hook_vsync(const struct hwc_procs* procs, int disp,

int64_t timestamp) {

cb_context* ctx = reinterpret_cast(

const_cast(procs));

ctx->hwc->vsync(disp, timestamp);

}

调用hwc对象的vsync函数

void HWComposer::vsync(int disp, int64_t timestamp) {

if (uint32_t(disp) < HWC_NUM_PHYSICAL_DISPLAY_TYPES) {

{

Mutex::Autolock _l(mLock);

// There have been reports of HWCs that signal several vsync events

// with the same timestamp when turning the display off and on. This

// is a bug in the HWC implementation, but filter the extra events

// out here so they don't cause havoc downstream.

if (timestamp == mLastHwVSync[disp]) {

ALOGW("Ignoring duplicate VSYNC event from HWC (t=%" PRId64 ")",

timestamp);

return;

}

mLastHwVSync[disp] = timestamp;

}

char tag[16];

snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp);

ATRACE_INT(tag, ++mVSyncCounts[disp] & 1);

mEventHandler.onVSyncReceived(disp, timestamp);

}

}

最终调用mEventHandler的onVSyncReceived函数,也既SurfaceFlinger的onVSyncReceived

软件vsync在VSyncThread线程中实现,看看线程循环函数:

bool HWComposer::VSyncThread::threadLoop() {

{ // scope for lock

Mutex::Autolock _l(mLock);

while (!mEnabled) {

mCondition.wait(mLock);

}

}

const nsecs_t period = mRefreshPeriod;

const nsecs_t now = systemTime(CLOCK_MONOTONIC);

nsecs_t next_vsync = mNextFakeVSync;

nsecs_t sleep = next_vsync - now;

if (sleep < 0) {

// we missed, find where the next vsync should be

sleep = (period - ((now - next_vsync) % period));

next_vsync = now + sleep;

}

mNextFakeVSync = next_vsync + period;

struct timespec spec;

spec.tv_sec = next_vsync / 1000000000;

spec.tv_nsec = next_vsync % 1000000000;

int err;

do {

err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);

} while (err<0 && errno == EINTR);

if (err == 0) {

mHwc.mEventHandler.onVSyncReceived(0, next_vsync);

}

return true;

}

以固定的时间间隔发送vsync信号

调用mEventHandler的onVSyncReceived函数,最终调用SurfaceFlinger的onVSyncReceived函数。

这样不管是硬件vsync还是软件vsync都达成了统一。当VSync信号产生时调用SurfaceFlinger的回调函数onVSyncReceived。

android vsync信号间隔,Android SurfaceFlinger服务(五) ----- VSync信号的产生相关推荐

  1. Android系统Surface机制的SurfaceFlinger服务对帧缓冲区(Frame Buffer)的管理分析

    在前文中,我们分析了SurfaceFlinger服务的启动过程.SurfaceFlinger服务在启动的过程中,会对系统的硬件帧缓冲区进行初始化.由于系统的硬件帧缓冲区一般只有一个,并且不是谁都可以随 ...

  2. Android系统Surface机制的SurfaceFlinger服务的线程模型分析

    在前面两篇文章中,我们分析了SurfaceFlinger服务的启动过程以及SurfaceFlinger服务初始化硬件帧缓冲区的过程.从这两个过程可以知道,SurfaceFlinger服务在启动的过程中 ...

  3. Android系统Surface机制的SurfaceFlinger服务渲染应用程序UI的过程分析

    出自:http://blog.csdn.net/luoshengyang/article/details/8079456 在前面的一系列文章中,我们学习了Android应用程序与SurfaceFlin ...

  4. Android系统Surface机制的SurfaceFlinger服务的启动过程分析

    在前面一篇文章中,我们简要介绍了Android系统Surface机制中的SurfaceFlinger服务.SurfaceFlinger服务是在System进程中启动的,并且负责统一管理设备的帧缓冲区. ...

  5. Android系统Surface机制的SurfaceFlinger服务简要介绍和学习计划

    前面我们从Android应用程序与SurfaceFlinger服务的关系出发,从侧面简单学习了SurfaceFlinger服务.有了这些预备知识之后,我们就可以从正面来分析SurfaceFlinger ...

  6. android中按钮间隔,Android布局有2个均匀间隔的按钮

    我有这个布局正常工作,相对布局与文本视图和两个按钮均匀分布在它下面. android:layout_width="fill_parent" android:layout_heigh ...

  7. android edittext字体间隔,android Edittext内容字体大小动态变化

    转自:edittext内容随字体大小动态变化,具体代码如下: package com.yitong.mbank.android.views; import android.content.Contex ...

  8. android timepicker 设置间隔,android – 如何在TimePicker中设置AM / PM?

    我在我的应用程序中使用TimePicker.每当用户使用TimePicker打开屏幕时,我会使用当前时间对其进行初始化.当我这样做时,TimePicker显示AM而不是PM.为什么会这样?我的代码中有 ...

  9. 信号间隔是什么意思_地铁信号里的行车闭塞是啥意思?

    从铁路信号系统角度上说,决定列车行车安全和行车间隔的最主要因素是闭塞分区. 我们日常乘坐地铁的过程中,为何有的线路站台候车时间长,有的线路站台候车时间短?究竟是什么原因?难道像有的人所说和地铁列车的车 ...

最新文章

  1. 设置PLSQ 连接oracle数据库
  2. 病虫害模型算法_基于深度学习的目标检测算法综述
  3. php中的抽象类(abstract class)和接口(interface)
  4. SMOTE 过采样的API使用
  5. Kmeans、Kmeans++和KNN算法比较
  6. java虚拟机通俗_JAVA虚拟机的通俗解释
  7. linux安装x11鼠标主题
  8. LeetCode—210. 课程表 II
  9. 20180601 -1
  10. 虚拟化系列-Windows server 2012 备份管理
  11. android 屏保程序,Android开发中屏保程序
  12. 工业视觉检测—制造过程中的缺陷和异常检测
  13. 预处理器 - 记号传递操作符##
  14. java字符转转长整型_P104 将数字字符串转换成长整型整数 ★★
  15. 4米乘以12米CAD图_身高1米6,却能在12顺位被选中?单场4分19助,他有多强?
  16. [论文写作笔记] C4以小窥大的摘要 C5 讲故事一样的引言
  17. iphone 手机忘记 访问限制密码 处理方法(未越狱版)
  18. Tomcat for win7 搭建集群
  19. 基于 yolov5n6 和tkinker实现的检测模型的可视化界面
  20. 视博云android虚拟机,手游难推广?视博云云游戏解决方案助力游戏厂商破局

热门文章

  1. Dijkstra(单源最短路径)
  2. FindBugs 插件使用
  3. sch i699android4,索尼S39h的手机系统是什么?索尼S39h能升级安卓4.3吗?
  4. 燃气管网监测设备:燃气管网压力在线监测
  5. 关于数学学习的思考(一)为什么牛顿会研究神学
  6. Canvas 示例:4种超炫的网站动画背景效果
  7. macOS如何添加Root用户
  8. 基于netty-socketio的web聊天--发送图片
  9. 公积金贷款将可异地申请 贷款条件放松
  10. 【网红营销】海外网红营销怎么做?及注意事项?