您的位置:首页 > 产品设计 > UI/UE

Android 7.1 GUI系统-vsync信号的产生和接收(五)

2017-11-25 20:20 417 查看
Vsync信号的产生。以下代码基于高通msm8909芯片,android7.1的源码。Vsync信号的产生有两种来源,一种是硬件,也就是显示模块产生;一中是软件模拟,因为目前基本都是硬件产生的,所以软件模拟的代码就没有分析的必要了。接下来分析由硬件产生的vsync是怎么传到surfaceflinger的。这个硬件源就是HWComposer,它一方面管理这composer的hal模块,composer模块是厂商定制UI合成的接口,我们通常不会直接操作HWComposer模块,而是通过surfaceflinger使用它;另一方面就是产生vsync信号。简单介绍下HWComposer,有很多名字类似的文件,frameworks/native/services/surfaceflinger/displayhardware/目录下的HWComposer.h,HWComposer.cpp这两个文件可以认为是硬件的抽象层,具体的硬件是指:hwcomposer(#defineHWC_HARDWARE_MODULE_ID"hwcomposer"),HWComposer.cpp文件是android提供的标准的api,具体到硬件平台可能会稍微有点区别,比如msm8909android7.1的代码根据宏定义:TARGET_USES_HWC2,实际加载的文件是HWComposer_hwc1.cpp,相应的surfaceflinger对应的文件是SurfaceFlinger_hwc1.cpp。
Hardware/libhardware/include/hardware/Hwcomposer.h;hardware/libhardware/modules/hwcomposer/Hwcomposer.cpp这两个文件是hwc的hal模块。相应的lib库是libhwcomposer.msm8909,库的实现代码在hardware/qcom/display/libhwcompser目录下,主要文件有hwc.cpp,hwc_vsync.cpp,hwc_uevents.cpp,hwc_utils.cpp等。下面先看下hwcomposer这个模块的加载,这个模块是由surfaceflinger来加载的:SurfaceFlinger_hwc1.cpp,如下代码中,只列出与hwcomposer,与vsync有关的代码。HWComposer* mHwc;
void SurfaceFlinger::init() {
//首先是启动EventThread线程, sfVsyncPhaseOffsetNs, vsyncPhaseOffsetNs这两个值都是1000000,在这两个值不等的情况下,会启动两个EventThread,一个是为surfaceflinger服务,一个是为有刷新UI需求的应用程序服务。这里走的是else。
if (vsyncPhaseOffsetNs != sfVsyncPhaseOffsetNs) {
}else{
sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
vsyncPhaseOffsetNs, true, "sf-app");
mEventThread = new EventThread(vsyncSrc, *this);
mEventQueue.setEventThread(mEventThread);
}
//初始化一个HWComposer对象。其中的参数一个是surfaceflinger自身,另一个其实也是surfaceflinger自身,只是其类型转成了HWComposer::EventHandler,可见surfaceflinger一定继承自HWComposer::EventHandler,并实现了其中接口onVSyncReceived等。
mHwc = DisplayUtils::getInstance()->getHWCInstance(this,
*static_cast<HWComposer::EventHandler *>(this));
}
DisplayUtils.cpp
HWComposer* DisplayUtils::getHWCInstance(const sp<SurfaceFlinger>& flinger,
HWComposer::EventHandler& handler) @DisplayUtils.cpp{
//直接new了一个 HWComposer实例,转到其构造函数。
return new HWComposer(flinger,handler);
}

HWComposer_hwc1.cpp
HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger,EventHandler& handler)
: mFlinger(flinger),mEventHandler(handler)...{
//首先加载FB的hal模块,对应设备用framebuffer_device_t*    mFbDev表示;,然后加载Hwc模块,对应的设备用struct hwc_composer_device_1*   mHwc表示。
int fberr = loadFbHalModule();
loadHwcModule();
//这里注册硬件回调事件,这个事件就是vsync信号,先分析传入的参数 mCBContext->procs。
if (mHwc) {
if (mHwc->registerProcs) {
//设置回调事件对应的方法实现,
mCBContext->procs.invalidate = &hook_invalidate;
mCBContext->procs.vsync = &hook_vsync;
//注册硬件回调事件。
mHwc->registerProcs(mHwc, &mCBContext->procs);
}
}
}

Hwc模块的加载、准备的过程:
HWComposer_hwc1.cpp
void HWComposer::loadHwcModule(){
hw_module_t const* module;
//这里会加载相应的lib库, hw_get_module这个方法是上层使用者加载HAL库的通用入口,传入硬件模块的ID,在系统指定的目录加载正确的HAL库,以出参的形式的得到打开的硬件模块 module。
if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) {
return;
}
//调用硬件模块的open方法,打开指定的硬件设备,
int err = hwc_open_1(module, &mHwc);
}
hardware/libhardware/include/hardware/hardware.h//每一个硬件模块都会定义的一个数据结构,

typedef struct hw_module_t {
//每一个HAL库都会提供的一个方法methods,
struct hw_module_methods_t* methods;
}hw_module_t;
typedef struct hw_module_methods_t {
//这个 methods的数据结构中只有一个函数指针变量open,用来打开指定的硬件设备。
int (*open)(const struct hw_module_t* module, const char* id,
struct hw_device_t** device);
} hw_module_methods_t;

针对HWComposer模块,其相应的open函数是hwc_device_open:hwc.cppstatic struct hw_module_methods_t hwc_module_methods = {
.open = hwc_device_open
};
//在打开这个hwc设备时,给很多函数指针赋了值,我们只关注dev->device.registerProcs = hwc_registerProcs;。

static int hwc_device_open(const struct hw_module_t* module, const char* name,
struct hw_device_t** device)
{
int status = -EINVAL;

if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
struct hwc_context_t *dev;
dev = (hwc_context_t*)malloc(sizeof(*dev));
if(dev == NULL)
return status;
memset(dev, 0, sizeof(*dev));

//Initialize hwc context
initContext(dev);

//Setu
1c05f
p HWC methods
dev->device.common.tag = HARDWARE_DEVICE_TAG;
dev->device.common.version = HWC_DEVICE_API_VERSION_1_5;
dev->device.common.module = const_cast<hw_module_t*>(module);
dev->device.common.close = hwc_device_close;
dev->device.prepare = hwc_prepare;
dev->device.set = hwc_set;
dev->device.eventControl = hwc_eventControl;
dev->device.setPowerMode = hwc_setPowerMode;
dev->device.query = hwc_query;
dev->device.registerProcs = hwc_registerProcs;
dev->device.dump = hwc_dump;
dev->device.getDisplayConfigs = hwc_getDisplayConfigs;
dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
dev->device.getActiveConfig = hwc_getActiveConfig;
dev->device.setActiveConfig = hwc_setActiveConfig;
*device = &dev->device.common;
status = 0;
}
return status;
}

然后分析注册硬件的回调的参数,这个参数mCBContext->procs会接收到hwc模块发出的vsync信号。mCBContext的类型是cb_context*,定义如下:

HWComposer_hwc1.cpp
struct HWComposer::cb_context {
//callbacks由继承自 hwc_procs_t,接着看下 hwc_procs_t的定义。
struct callbacks : public hwc_procs_t {
void (*zero[4])(void);
};
callbacks procs;
HWComposer* hwc;
};
hwc_procs_t的定义在hwcomposer.h中,

hwcomposer.h
typedef struct hwc_procs {
//invalidate会触发屏幕刷新,在invalidate被调用不久会调用prepare和set,但是不保证调用了invalidate屏幕就一定会刷新,比如之前屏幕已经刷新过了,就不会在刷新。
void (*invalidate)(const struct hwc_procs* procs);
//vsync是分析这部分代码的目的,在收到一个vsync事件,并且HWC_EVENT_VSYNC是enabled的,这个vsync方法会被hwcomposer hal模块调用,其中的参数disp标示这个vsync事件是属于那个显示设备。
void (*vsync)(const struct hwc_procs* procs, int disp, int64_t timestamp);
//在一个显示设备连接或断开时会调用hotplug,主显示设备一直都是连接的,这个方法不会被调用,主要是针对可热插拔的设备。
void (*hotplug)(const struct hwc_procs* procs, int disp, int connected);
} hwc_procs_t;
分析完了HWComposer这边的参数,接着看下mHwc->registerProcs的实现,hwc.cpp//设置注册到HWC的回调函数。static void hwc_registerProcs(struct hwc_composer_device_1* dev,
hwc_procs_t const* procs)
{
hwc_context_t* ctx = (hwc_context_t*)(dev);
if(!ctx) {
ALOGE("%s: Invalid context", __FUNCTION__);
return;
}
//vsync将通过proc会调到HWComposer的vsync函数。
ctx->proc = procs;

//当有回调函数注册时,会启动uevent,vsync两个线程。uevent线程跟屏幕invalidate有关。
init_uevent_thread(ctx);
init_vsync_thread(ctx);
}
//主要关注vsync线程的开启。

hwc_vsync.cpp//创建一个线程,然后执行其vsync_loop方法。void init_vsync_thread(hwc_context_t* ctx){
int ret;
pthread_t vsync_thread;
ret = pthread_create(&vsync_thread, NULL, vsync_loop, (void*) ctx);
}
static void *vsync_loop(void *param){
//物理显示设备的个数。
int num_displays = HWC_NUM_DISPLAY_TYPES – 1;
//如果系统属性指定使用模拟vsync,把ctx->vstate.fakevsync = true;
if(property_get("debug.hwc.fakevsync", property, NULL) > 0) {
ctx->vstate.fakevsync = true;
}
//非模拟vsync的情况,当有多个显示设备时,对每个显示设备都要执行回调,发出通知。
if (LIKELY(!ctx->vstate.fakevsync)) {
do {
for (int dpy = HWC_DISPLAY_PRIMARY; dpy < num_displays; dpy++) {
event_list[ev].callback(ctx, dpy, vdata);
}
}while(true)
}else{
//使用模拟vsync的情况,通常是明确通过属性设置了或在开机时vsync时间戳节点还没打开,这时候会使用模拟vsync,模拟vsync指发给主显示设备。
do {
usleep(16666);
uint64_t timestamp = systemTime();
//这个回调就是执行的HWComposer的vsync方法。
ctx->proc->vsync(ctx->proc, HWC_DISPLAY_PRIMARY, timestamp);
}while(true)
}
}

HWComposer_hwc1.cppHWComposer这边vsync的接收函数是:hook_vsync,前面贴出的HWComposer的构造函数的代码中:mCBContext->procs.vsync= &hook_vsync; hook_vsync又调用了HWComposer的vsync方法。
void HWComposer::vsync(int disp, int64_t timestamp) {
//HWComposer直接通过mEventHandler把vsync信号传到surfaceflinger。
mEventHandler.onVSyncReceived(disp, timestamp);
}
//接着看surfaceflinger是如何处理vsync信号的。surfaceflinger中事件管理员是mEventQueue,它是MessageQueue类型的对象,所以vsync信号肯定是要送到mEventQueue中的,是怎么送过去的呢?这个过程比想的稍微复杂了点。SurfaceFlinger_hwc1.cpp
void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
bool needsHwVsync = false;

{ // Scope for the lock
Mutex::Autolock _l(mHWVsyncLock);
if (type == 0 && mPrimaryHWVsyncEnabled) {
needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
}
}

if (needsHwVsync) {
enableHardwareVsync();
} else {
disableHardwareVsync(false);
}
}

为了说清楚vsync的接收过程,还要看几个相关的类,从surfaceflinger的初始化开始。void SurfaceFlinger::init() {
sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
vsyncPhaseOffsetNs, true, "sf-app");
mEventThread = new EventThread(vsyncSrc, *this);
mEventQueue.setEventThread(mEventThread);
mHwc = DisplayUtils::getInstance()->getHWCInstance(this,
*static_cast<HWComposer::EventHandler *>(this));
mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
}
在这个初始化函数中,HWComposer前面已经分析过,接着简单介绍下几个类的主要功能。1),mPrimaryDispSync实例的类型是DispSync,这个DispSync的主要作用是模拟软件的vsync源,在收到硬件模块hwc传来的vsync后,可能会disable掉硬件vsync源,不在执行回调HWComposer这边vsync的接收函数是:hook_vsync,控制硬件vsync源开、关的就是EventControlThread.cpp。DispSync在每次接收到硬件的vsync时,都会判断要不要继续使用硬件的vsync,这个判断的其中一个方法是addResyncSample,这个方法也是onVSyncReceived(SurfaceFlinger_hwc1.cpp中的vsync接收函数)中执行判断的依据。还有一个方法是addPresentFence,这个方法在surfaceflinger处理显示合成的后期会调用,判断是否要使用硬件hwc的vsync。
DispSync把sw的vsync信号,传给注册的监听者,是在线程的threadLoop循环中实现的。

virtual bool threadLoop() {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
while (true) {
//计算下一次的vsync时间,如果这个时间还没到,就wait一段时间差,
targetTime = computeNextEventTimeLocked(now);
if (now < targetTime) {
err = mCond.waitRelative(mMutex, targetTime - now);
}
//获取都有那些监听,然后调用其回调onDispSyncEvent。
callbackInvocations = gatherCallbackInvocationsLocked(now);
fireCallbackInvocations(callbackInvocations);
}
}
2),接着EventControlThread怎样控制硬件vsync的开关。

bool EventControlThread::threadLoop() {
// mVsyncEnabled这个值在初始化 EventControlThread时赋值为false,
bool vsyncEnabled = mVsyncEnabled;
//这里会去调用HWComposer的实现。
mFlinger->eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC,
mVsyncEnabled);
//在线程启动后,这个while循环会进入wait,直到调用它的setVsyncEnabled的方法把这个唤醒。初始化时mVsyncEnabled是false,那就是说线程刚启动时是把vsync关闭的,是后面初始化显示设备时通过 setVsyncEnabled打开了。
while (true) {
status_t err = mCond.wait(mMutex);
if (err != NO_ERROR) {
ALOGE("error waiting for new events: %s (%d)",
strerror(-err), err);
return false;
}
//唤醒后,判断要不要重新设置vsync的开、关。
if (vsyncEnabled != mVsyncEnabled) {
mFlinger->eventControl(HWC_DISPLAY_PRIMARY,
SurfaceFlinger::EVENT_VSYNC, mVsyncEnabled);
vsyncEnabled = mVsyncEnabled;
}
}
//这里返回值是false,就是说这个线程的threadloop不会在被系统调用,换句话它他是一个单次循环,只是通过内部的while实现循环执行。
return false;
}

接着看EventControlThread线程被唤醒的条件:

void EventControlThread::setVsyncEnabled(bool enabled) {
Mutex::Autolock lock(mMutex);
mVsyncEnabled = enabled;
mCond.signal();
}
只要有人调用setVsyncEnabled,通过mCond.signal();都会唤醒这个线程。第一次启动时谁会调用这个方法打开硬件的vsync呢?
大致列出调用逻辑以下方法都在SurfaceFlinger_hwc1.cpp中。void SurfaceFlinger::init() {
//显示相关的初始化,这个调用在EventControlThread线程运行起来之后。
initializeDisplays();
}
通过异步消息,调用了onInitializeDisplays();

void SurfaceFlinger::initializeDisplays() {
class MessageScreenInitialized : public MessageBase {
virtual bool handler() {
flinger->onInitializeDisplays();
}
};
sp<MessageBase> msg = new MessageScreenInitialized(this);
postMessageAsync(msg);
}
void SurfaceFlinger::onInitializeDisplays() {
//这个方法在每次点亮屏幕时都会被调用,针对主显示屏来说,应该是每次点两屏,都会重新打开硬件模块hwc的vsync。
setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL);
}
既然点亮屏时会enable硬件hwc的vsync,息屏时也会disable硬件hwc的vsync。void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,
int mode) {
mEventThread->onScreenAcquired();
resyncToHardwareVsync(true);
}
void SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
//这里调用了EventControlThread中的 setVsyncEnabled,参数true,会enable硬件的vsync。同时注意这里的变量 mPrimaryHWVsyncEnabled = true,这个变量是 SurfaceFlinger::onVSyncReceived的中一个判断条件,在收到硬件hwc的vsync回调时,判断要不要disable硬件vsync。
mEventControlThread->setVsyncEnabled(true);
mPrimaryHWVsyncEnabled = true;
}

最后看看mFlinger->eventControl()是如何控制vsync的。void SurfaceFlinger::eventControl(int disp, int event, int enabled) {
ATRACE_CALL();
//直接调用了HWComposer_hwc1.cpp中的实现。
getHwComposer().eventControl(disp, event, enabled);
}
void HWComposer::eventControl(int disp, int event, int enabled) @HWComposer_hwc1.cpp{
err = mHwc->eventControl(mHwc, disp, event, enabled);
//根据enabled,让HWComposer::VSyncThread::VSyncThread线程wait或者唤醒。
mVSyncThread->setEnabled(enabled);
}

mHwc->eventControl()最终的实现在hwc_vsync.cpp,通过IO命令控制硬件vsync。int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable)@hwc_vsync.cpp{
ioctl(ctx->dpyAttr[dpy].fd, MSMFB_OVERLAY_VSYNC_CTRL, &enable);
}
3),DispSyncSource,这个类是SurfaceFlinger_hwc1.cpp的内部类,他的构造函数中持有DispSync的引用,即mDispSync,这个类的主要功能是通过mDispSync添加、删除对vsync(DispSync中的)的监听,并接收vsync(来自DispSync)回调。这个函数虽然也叫vsyncenabled,实际只是向DispSync添加、删除对vsync的监听。

virtual void setVSyncEnabled(bool enable) @SurfaceFlinger_hwc1.cpp$DispSyncSource{
if (enable) {
status_t err = mDispSync->addEventListener(mName, mPhaseOffset,
static_cast<DispSync::Callback*>(this));
}else{
status_t err = mDispSync→removeEventListener(
static_cast<DispSync::Callback*>(this));
}
}
向DispSync注册的监听vsync的回调类型是DispSync::Callback,DispSyncSource继承了这个类,并实现了其中的方法onDispSyncEvent。DispSync会把软件vsync信号通过注册的监听,回调其onDispSyncEvent函数。virtual void onDispSyncEvent(nsecs_t when) @SurfaceFlinger_hwc1.cpp$DispSyncSource{
sp<VSyncSource::Callback> callback;
callback = mCallback;
callback->onVSyncEvent(when);
}
这里出现了VSyncSource::Callback的回调,vsync信号会传到VSyncSource::Callback类中的onVSyncEvent函数。这个VSyncSource::Callback的实现具体是什么?在surfaceflinger的初始化(init()函数)中,有这么一句代码:

mEventThread = new EventThread(vsyncSrc, *this);
其中参数vsyncSrc就是DispSyncSource,所以接着看EventThread线程的实现。这个线程在他第一次被引用时,由其强指针的特性执行其onFirstRef方法,让这个线程运行起来,第一次被引用的地方就是紧接着实例化其对象的代码:mEventQueue.setEventThread(mSFEventThread);
这里让surfaceflinger的消息管理员mEventQueue(MessageQueue)跟EventThread线程绑定,现在越来越接近目标了,还记得分析这段的目的是想弄明白vsync信号是怎么传到surfaceflinger的mEventQueue的。bool EventThread::threadLoop() @EventThread.cpp{
signalConnections = waitForEvent(&event);
}
waitForEvent会调用下面的enableVSyncLocked函数,然后通过DispSyncSource的setCallback函数,设置一个类型是VSyncSource::Callback的回调,这个回调的实现端就是EventThread自身。

void EventThread::enableVSyncLocked() @EventThread.cpp{
mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));
}
所以前面DispSync会先把vsync信号通过回调传到DispSyncSource的onDispSyncEvent,最后在传到EventThread的onVSyncEvent函数。

4),EventThread是如何处理vsync信号的。void EventThread::onVSyncEvent(nsecs_t timestamp) @EventThread.cpp{
Mutex::Autolock _l(mLock);
mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
mVSyncEvent[0].header.id = 0;
mVSyncEvent[0].header.timestamp = timestamp;
mVSyncEvent[0].vsync.count++;
mCondition.broadcast();
}
上面的函数做了两件事情,一是填充了DisplayEventReceiver::Event类型的事件对象mVSyncEvent,主要包括事件的类型DisplayEventReceiver::DISPLAY_EVENT_VSYNC,还有事件戳timestamp。另外一个事情是mCondition.broadcast(),唤醒等待的EventThread线程。EventThread线程什么情况下wait的呢?一种情况是没有对vsync感兴趣的客户端,另一种情况是正在等待vsync信号的产生,还有一种情况是当前屏幕是off,不需要vsync,这是会进入一个16ms的超时等待。唤醒之后,线程继续循环。bool EventThread::threadLoop() @EventThread.cpp{
DisplayEventReceiver::Event event;
Vector< sp<EventThread::Connection> > signalConnections;
//线程就是在waitForEvent中进入等待的。
signalConnections = waitForEvent(&event);
//开始分发vsync给所有的监听者,eventthread处理的事件不是只有vsync,还有DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG;
const size_t count = signalConnections.size();
for (size_t i=0 ; i<count ; i++) {
const sp<Connection>& conn(signalConnections[i]);
status_t err = conn->postEvent(event);
}
//返回值true,系统会再次调用这个线程的threadloop,从而形成一个循环。
return true;
}
waitForEvent除了会让线程进入wait,还有一个作用是找出等待事件的connections,也即是对vsync感兴趣的监听者,找出来后保存在signalConnections中。所有对vsync感兴趣的监听者都会被保存在mDisplayEventConnections中。通常有两类监听者,
一类是surfaceflinger,它负责UI数据的合成,肯定要受vsync信号的触发。负责vsync接收的是surfaceflinger的事件管理员MessageQueue,相应的实例对象是mEventQueue,前面提到当实例化EventThread对象后,mEventQueue就跟EventThread执行了绑定,具体代码:
void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
{
mEventThread = eventThread;
mEvents = eventThread->createEventConnection();
mEventTube = mEvents->getDataChannel();
mLooper->addFd(mEventTube->getFd(), 0, Looper::EVENT_INPUT,
MessageQueue::cb_eventReceiver, this);
}
首先通过eventThread的接口createEventConnection创建了一个Connection,赋值给mEvents,并且当这个Connection实例被引用时,会执行其onFirstRef方法,将这个Connection注册到EventThread中,把这个connection保存到EventThread中的变量mDisplayEventConnections中。

void EventThread::Connection::onFirstRef() {
mEventThread->registerDisplayEventConnection(this);
}
mEvents的类型是sp<IDisplayEventConnection>,也即是Connection的客户端,对应的服务端的实现是EventThread的内部类Connection,这个可以从它的继承关系看出:

class Connection : public BnDisplayEventConnection {}
Connection继承了BnDisplayEventConnection。然后,通过mEvents获取一个mEventTube,这个BitTube的实质是socketpair,它有一个发送端,一个接收端。最后通过mEventTube->getFd()获取了socketpair的接收端,并且给这个接收设置了回调MessageQueue::cb_eventReceiver,通过Looper接口addFd把他们加入到Looper中的监视请求列表mRequests,我们知道主线程循环从消息队列中取消息时,会调用Looper的pollOnce,然后是pollInner,在这个pollInner中,只要有事件需要处理,就会执行其callback函数,在这个场景中,就会执行MessageQueue::cb_eventReceiver。弄清楚了事件的接收端,那事件的发送端在哪里呢?负责发送的服务端就是EventThread,具体实现就是下面的postEvent:

bool EventThread::threadLoop() {
status_t err = conn->postEvent(event);
}
//mChannel就是前面说的BitTube,会通过其mSendFd把event数据写入。status_t EventThread::Connection::postEvent(
const DisplayEventReceiver::Event& event) {
ssize_t size = DisplayEventReceiver::sendEvents(mChannel, &event, 1);
return size < 0 ? status_t(size) : status_t(NO_ERROR);
}
第二类对vsync感兴趣的监听者是应用程序,不在详细分析,只把它创建connection的过程列一下。每一个有窗口的应用进程,都会有一个渲染线程RenderThread,frameworks/base/libs/hwui/renderthread/
bool RenderThread::threadLoop() @RenderThread.cpp{
initThreadLocals();
}
void RenderThread::initThreadLocals() {
initializeDisplayEventReceiver();
}

//接收vsync的回调RenderThread::displayEventReceiverCallback,

void RenderThread::initializeDisplayEventReceiver() {
mDisplayEventReceiver = new DisplayEventReceiver();
mLooper->addFd(mDisplayEventReceiver->getFd(), 0,
Looper::EVENT_INPUT, RenderThread::displayEventReceiverCallback, this);
}
//先获取surfaceflinger的句柄ISurfaceComposer。
DisplayEventReceiver::DisplayEventReceiver() {
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
if (sf != NULL) {
mEventConnection = sf->createDisplayEventConnection();
if (mEventConnection != NULL) {
mDataChannel = mEventConnection->getDataChannel();
}
}
}

//调用eventthread中接口createEventConnection。sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
return mEventThread->createEventConnection();
}
sp<EventThread::Connection> EventThread::createEventConnection() const {
return new Connection(const_cast<EventThread*>(this));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: