实现SurfaceFlinger的主动刷新

本文深入探讨SurfaceFlinger如何处理Vsync事件,从SurfaceFlinger.cpp的init()开始,详细解析EventThread的工作流程,通过修改EventThread::Connection的count实现每个Vsync事件都调用handleMessageInvalidate()。

实现SurfaceFlinger的主动刷新

Abstract

SurfaceFlinger在收到来自硬件层的Vsync事件之后,不是每次都会调用SurfaceFlinger::handleMessageInvalidate()的。而SurfaceFlinger中处理Vsync事件涉及到的类有:DispSyncThread, DispSync, SurfaceFlinger::DispSyncSource, EventThread, EventThread::Connection, MessageQueue.

本文首先研究这些类之间的关系,以及自Vysnc事件发生后这些类的处理流程。最终,通过修改EventThread::Connection中的成员count实现了每个Vsync事件都会调用SurfaceFlinger::handleMessageInvalidate()的功能。

Process

从SurfaceFlinger.cpp的init()开始

在SurfaceFlinger.cpp的init()方法中,通过如下的代码初始化了DispSyncSource和EventThread,并将mSFEventThread关联到成员变量MessageQueue mEventQueue中:

sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
      vsyncPhaseOffsetNs, true, "app");
mEventThread = new EventThread(vsyncSrc, *this, false);
sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
      sfVsyncPhaseOffsetNs, true, "sf");
mSFEventThread = new EventThread(sfVsyncSrc, *this, true);
mEventQueue.setEventThread(mSFEventThread);

在EventThread.cpp中可以看到当EventThread的实例创建时,在其onFirstRef()中会开启线程:

void EventThread::onFirstRef() {
    run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
}

而在MessageQueue::setEventThread()中,会创建EventThread::Connection:

void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
{
   if (mEventThread == eventThread) {
      return;
   }

   if (mEventTube.getFd() >= 0) {
      mLooper->removeFd(mEventTube.getFd());
   }

   mEventThread = eventThread;
   mEvents = eventThread->createEventConnection();
   mEvents->stealReceiveChannel(&mEventTube);
   mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT,
         MessageQueue::cb_eventReceiver, this);
}
sp<EventThread::Connection> EventThread::createEventConnection() const {
    return new Connection(const_cast<EventThread*>(this));
}

EventThread::Connection::Connection(
      const sp<EventThread>& eventThread)
   : count(-1), mEventThread(eventThread), mChannel(gui::BitTube::DefaultSize) {}

注意 count的初始值是-1
EventThread::ConnectiononFirstConnection中,会将Connection的实例传给EventThread,并加到其成员变量mDisplayEventConnections:

void EventThread::Connection::onFirstRef() {
   mEventThread->registerDisplayEventConnection(this);
}

status_t EventThread::registerDisplayEventConnection(
      const sp<EventThread::Connection>& connection) {
   Mutex::Autolock _l(mLock);
   mDisplayEventConnections.add(connection);

   if (!mFirstConnectionInited) {
      // additional external displays can't be enumerated by default,
      // need to report additional hotplug to listeners
      for (int32_t type = DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES;
            type < (int32_t)mHotplugEvent.size(); type++) {
         if (mHotplugEvent[type].hotplug.connected) {
               connection->postEvent(mHotplugEvent[type]);
         }
      }
      mFirstConnectionInited = true;
   }

   mCondition.broadcast();
   return NO_ERROR;
}

第一次执行EventThread::waitForEvent()

EventThread::threadLoop()运行起来后,首先会执行EventThread::waitForEvent()方法:

Vector< sp<EventThread::Connection> > EventThread::waitForEvent(
      DisplayEventReceiver::Event* event)
{
   Mutex::Autolock _l(mLock);
   Vector< sp<EventThread::Connection> > signalConnections;

   do {
      bool 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值