SurfaceFlinger初始化

接着上一节,main_surfaceflinger.cpp main方法中,主要看下三点createSurfaceFlinger(),init(),run()。
一、SurfaceFlinger的继承关系

frameworks/native/services/surfaceflinger/SurfaceFlinger.h

    class SurfaceFlinger:public BnSurfaceComposer,  
        public PriorityDumper,  
        public ClientCache::ErasedRecipient,  
        private IBinder::DeathRecipient,  
        private HWC2::ComposerCallback,  
        private ISchedulerCallback 
   
    class BnSurfaceComposer : public BnInterface<ISurfaceComposer>  
    
template<typename INTERFACE>
class BnInterface : public INTERFACE,public BBinder  

关系图如下:


image.png

SurfaceFlinger继承于BBinder,继承BBinder类的作用是实现Binder机制的服务端,Client请求最终实现的地方,

二、SurfaceFlinger的创建,(Android R SurfaceFlinger对比以前版本变化较大)
在main_surfaceflinger.cpp main方法中,sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
可以知道由SurfaceFlingerFactory.cpp进行创建

frameworks/native/services/surfaceflinger/SurfaceFlingerFactory.cpp

sp<SurfaceFlinger> createSurfaceFlinger(){
static DefaultFactory factory;
return new SurfaceFlinger();
}

看一下它的构造方法

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

 SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
       : mFactory(factory),
         mInterceptor(mFactory.createSurfaceInterceptor(this)),
         mTimeStats(std::make_shared<impl::TimeStats>()),
         mFrameTracer(std::make_unique<FrameTracer>()),
         mEventQueue(mFactory.createMessageQueue()),   //@1
          mCompositionEngine(mFactory.createCompositionEngine()), //@2
          mInternalDisplayDensity(getDensityFromProperty("ro.sf.lcd_density", true)),
          mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)) {}

 SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipInitialization) {
      ALOGI("SurfaceFlinger is starting");
//方法较长主要是属性设置,省略,后面遇到重要的再加上
  ...
}

@1处对MessageQueue进行了初始化,

 frameworks/native/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp 
std::unique_ptr<Message> DefaultFactory::createMessageQueue(){
    return std::make_unique<android::impl::MessageQueue>();
}

创建 MessageQueue对象并返回, make_unique 相当于 new,(能够取代new 而且无需 delete pointer,有助于代码管理)。

@2处对于CompositionEngine进行初始化

frameworks/native/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp 

std::unique_ptr<compositionengine::CompositionEngine> DefaultFactory::createCompositionEngine() {
      return compositionengine::impl::createCompositionEngine();
}
frameworks/native/services/surfaceflinger/compositionengine/src/CompositionEngine.cpp
std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() {
     return std::make_unique<CompositionEngine>();
}

创建了 CompositionEngine对象

由于surfaceFlinger最终会继承RefBase,且创建时强引用sp包装类,会调其用onFirstRef方法

frameworks/native/services/surfaceflinger/surfaceflinger.cpp
void SurfaceFlinger::onFirstRef(){
mEventQueue->init(this);
}
/frameworks/native/services/surfaceflinger/scheduler/MessageQueue.cpp
void MessageQueue::init(const sp<SurfaceFlinger>& flinger){
mFlinger = flinger;
mLooper = new Looper(true);
mHandler = new Handler(*this);
}

创建了looper、Handler对象,很明显 surfaceFlinger处理消息也是looper机制。

三、SurfaceFlinger的init方法
在main_surfaceflinger.cpp中创建完surfaceFlinger后会进行 flinger->init();

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::init() {
ALOGI(  "SurfaceFlinger's main thread ready to run. "
              "Initializing graphics H/W...");
     Mutex::Autolock _l(mStateLock);

      // Get a RenderEngine for the given display / config (can't fail)
     // TODO(b/77156734): We need to stop casting and use HAL types when possible.
     // Sending maxFrameBufferAcquiredBuffers as the cache size is tightly tuned to single-display.
      mCompositionEngine->setRenderEngine(renderengine::RenderEngine::create(
              renderengine::RenderEngineCreationArgs::Builder()
                  .setPixelFormat(static_cast<int32_t>(defaultCompositionPixelFormat))
                 .setImageCacheSize(maxFrameBufferAcquiredBuffers)
                  .setUseColorManagerment(useColorManagement)
                 .setEnableProtectedContext(enable_protected_contents(false))
                 .setPrecacheToneMapperShaderOnly(false)
                  .setSupportsBackgroundBlur(mSupportsBlur)
                  .setContextPriority(useContextPriority
                          ? renderengine::RenderEngine::ContextPriority::HIGH
                          : renderengine::RenderEngine::ContextPriority::MEDIUM)
                  .build()));     @1
      mCompositionEngine->setTimeStats(mTimeStats);
  
      LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
              "Starting with vr flinger active is not currently supported.");
      mCompositionEngine->setHwComposer(getFactory().createHWComposer(getBE().mHwcServiceName));  @2
      mCompositionEngine->getHwComposer().setConfiguration(this, getBE().mComposerSequenceId);
      // Process any initial hotplug and resulting display changes.
      processDisplayHotplugEventsLocked();  @3
      const auto display = getDefaultDisplayDeviceLocked();
      LOG_ALWAYS_FATAL_IF(!display, "Missing internal display after registering composer callback.");
      LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(*display->getId()),
                          "Internal display is disconnected.");
  
      if (useVrFlinger) {
          auto vrFlingerRequestDisplayCallback = [this](bool requestDisplay) {
              // This callback is called from the vr flinger dispatch thread. We
              // need to call signalTransaction(), which requires holding
              // mStateLock when we're not on the main thread. Acquiring
              // mStateLock from the vr flinger dispatch thread might trigger a
              // deadlock in surface flinger (see b/66916578), so post a message
              // to be handled on the main thread instead.
              static_cast<void>(schedule([=] {
                  ALOGI("VR request display mode: requestDisplay=%d", requestDisplay);
                  mVrFlingerRequestsDisplay = requestDisplay;
                  signalTransaction();
              }));
          };
          mVrFlinger = dvr::VrFlinger::Create(getHwComposer().getComposer(),
                                              getHwComposer()
                                                      .fromPhysicalDisplayId(*display->getId())
                                                      .value_or(0),
                                              vrFlingerRequestDisplayCallback);
          if (!mVrFlinger) {
              ALOGE("Failed to start vrflinger");
         }
      }
  
      // initialize our drawing state
      mDrawingState = mCurrentState;
  
      // set initial conditions (e.g. unblank default device)
      initializeDisplays();
  
      char primeShaderCache[PROPERTY_VALUE_MAX];
      property_get("service.sf.prime_shader_cache", primeShaderCache, "1");
      if (atoi(primeShaderCache)) {
          getRenderEngine().primeCache();
      }
  
      // Inform native graphics APIs whether the present timestamp is supported:
  
      const bool presentFenceReliable =
              !getHwComposer().hasCapability(hal::Capability::PRESENT_FENCE_IS_NOT_RELIABLE);
      mStartPropertySetThread = getFactory().createStartPropertySetThread(presentFenceReliable);
  
      if (mStartPropertySetThread->Start() != NO_ERROR) {
          ALOGE("Run StartPropertySetThread failed!");
      }
  
      ALOGV("Done initializing");
  }

@1处 对于CompositionEngine 属性进行设置, 创建RenderEngine对象
@2处 创建HWComposer对象并传入一个name属性,再通过mCompositionEngine->setHwComposer设置对象属性。
@3处 processDisplayHotplugEventsLocked(); 处理 任何初始热插拔和显示更改的结果
在此方法中主要有调用 initScheduler(displayId);

void SurfaceFlinger::initScheduler(DisplayId primaryDisplayId) {
      if (mScheduler) {
          // In practice it's not allowed to hotplug in/out the primary display once it's been
          // connected during startup, but some tests do it, so just warn and return.
          ALOGW("Can't re-init scheduler");
         return;
      }
      auto currentConfig = HwcConfigIndexType(getHwComposer().getActiveConfigIndex(primaryDisplayId));
      mRefreshRateConfigs =std::make_unique<scheduler::RefreshRateConfigs>(getHwComposer().getConfigs(
                                                                      primaryDisplayId),currentConfig);
      mRefreshRateStats =
              std::make_unique<scheduler::RefreshRateStats>(*mRefreshRateConfigs, *mTimeStats,
                                                            currentConfig, hal::PowerMode::OFF);
      mRefreshRateStats->setConfigMode(currentConfig);
  
      mPhaseConfiguration = getFactory().createPhaseConfiguration(*mRefreshRateConfigs);
  
      // start the EventThread
      mScheduler =getFactory().createScheduler([this](bool enabled) { setPrimaryVsyncEnabled(enabled); },
                                           *mRefreshRateConfigs, *this);    @4  处创建Scheduler对象
      mAppConnectionHandle =
              mScheduler->createConnection("app", mPhaseConfiguration->getCurrentOffsets().late.app,
                                           impl::EventThread::InterceptVSyncsCallback());   @5  处创建app链接
      mSfConnectionHandle =
              mScheduler->createConnection("sf", mPhaseConfiguration->getCurrentOffsets().late.sf,
                                           [this](nsecs_t timestamp) {
                                               mInterceptor->saveVSyncEvent(timestamp);
                                           });   @6  创建sf链接
  
      mEventQueue->setEventConnection(mScheduler->getEventConnection(mSfConnectionHandle)); @7
      mVSyncModulator.emplace(*mScheduler, mAppConnectionHandle, mSfConnectionHandle,
                              mPhaseConfiguration->getCurrentOffsets());
      mRegionSamplingThread =
              new RegionSamplingThread(*this, *mScheduler,
                                       RegionSamplingThread::EnvironmentTimingTunables());
      // Dispatch a config change request for the primary display on scheduler
      // initialization, so that the EventThreads always contain a reference to a
      // prior configuration.
      // This is a bit hacky, but this avoids a back-pointer into the main SF
      // classes from EventThread, and there should be no run-time binder cost
      // anyway since there are no connected apps at this point.
      const nsecs_t vsyncPeriod =
              mRefreshRateConfigs->getRefreshRateFromConfigId(currentConfig).getVsyncPeriod();
      mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle, primaryDisplayId.value,
                                                currentConfig, vsyncPeriod);
  }

@4处创建Scheduler对象
@5、@6处分别创建app 链接和 sf链接
@7 请看下面第五大点

四、详细看下app、sf的链接

frameworks/native/services/surfaceflinger/scheduler/Scheduler.cpp
Scheduler::ConnectionHandle Scheduler::createConnection(
         const char* connectionName, nsecs_t phaseOffsetNs,
         impl::EventThread::InterceptVSyncsCallback interceptCallback) {
     auto vsyncSource = makePrimaryDispSyncSource(connectionName, phaseOffsetNs);   
     auto eventThread = std::make_unique<impl::EventThread>(std::move(vsyncSource),                                                           std::move(interceptCallback));  
      return createConnection(std::move(eventThread));
}

1、 调用makePrimaryDispSyncSource方法

  std::unique_ptr<VSyncSource> Scheduler::makePrimaryDispSyncSource(const char* name,
                                                                    nsecs_t phaseOffsetNs) {
      return std::make_unique<DispSyncSource>(mPrimaryDispSync.get(), phaseOffsetNs,
                                              true /* traceVsync */, name);
  }

可以看到创建了DispSyncSource对象,且构造方法传入了四个值,dispSync对象,phaseOffset偏移量,traceVsync为true,name就是 app或 sf

  DispSyncSource::DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,
                                 const char* name)
        : mName(name),
          mValue(base::StringPrintf("VSYNC-%s", name), 0),    @1
          mTraceVsync(traceVsync),   @2
          mVsyncOnLabel(base::StringPrintf("VsyncOn-%s", name)),
          mDispSync(dispSync),
          mPhaseOffset(base::StringPrintf("VsyncOffset-%s", name), phaseOffset)   @3
{}

@1处 对mValue进行了赋值,systrace上我们看到的 VSYNC-app VSYNC-sf 标签就是它
@2处 mTraceVsync为true,在onDispSyncEvent方法中

  void DispSyncSource::onDispSyncEvent(nsecs_t when, nsecs_t expectedVSyncTimestamp) {
    ...
      if (mTraceVsync) {
          mValue = (mValue + 1) % 2;
      }
     ...
  }
17.png

所以我们在systrace上面看到的 VSYNC-app/VSYNC-sf 驼峰 0 1变化,来源于这个。
@3处 对mPhaseOffset进行初始化 vsync信号到来时候,sf、app的偏移量

2、创建EventThread对象,传入sf 或 app 相关联的vsyncSource对象

auto eventThread = std::make_unique<impl::EventThread>(std::move(vsyncSource),                                                           std::move(interceptCallback));

3、 执行createConnection(std::move(eventThread));

Scheduler::ConnectionHandle Scheduler::createConnection(std::unique_ptr<EventThread> eventThread) {
      const ConnectionHandle handle = ConnectionHandle{mNextConnectionHandleId++};
      ALOGV("Creating a connection handle with ID %" PRIuPTR, handle.id);
  
      auto connection =
              createConnectionInternal(eventThread.get(), ISurfaceComposer::eConfigChangedSuppress);
  
      mConnections.emplace(handle, Connection{connection, std::move(eventThread)});
      return handle;
  }

  sp<EventThreadConnection> Scheduler::createConnectionInternal(
          EventThread* eventThread, ISurfaceComposer::ConfigChanged configChanged) {
      return eventThread->createEventConnection([&] { resync(); }, configChanged);
  }

执行EventThread对象的 createEventConnection方法

 /frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp
  sp<EventThreadConnection> EventThread::createEventConnection(
          ResyncCallback resyncCallback, ISurfaceComposer::ConfigChanged configChanged) const {
      return new EventThreadConnection(const_cast<EventThread*>(this), std::move(resyncCallback),
                                       configChanged);
  }

在EventThreadConnection第一次引用时候,会执行onFirstRef方法

 void EventThreadConnection::onFirstRef() {
      // NOTE: mEventThread doesn't hold a strong reference on us
      mEventThread->registerDisplayEventConnection(this);
  }

这个this是什么呢,就是app 和 sf关联的eventThread, 进行注册,

  status_t EventThread::registerDisplayEventConnection(const sp<EventThreadConnection>& connection) {
      std::lock_guard<std::mutex> lock(mMutex);
  
      // this should never happen
      auto it = std::find(mDisplayEventConnections.cbegin(),
              mDisplayEventConnections.cend(), connection);
      if (it != mDisplayEventConnections.cend()) {
          ALOGW("DisplayEventConnection %p already exists", connection.get());
          mCondition.notify_all();
          return ALREADY_EXISTS;
      }
  
      mDisplayEventConnections.push_back(connection);
      mCondition.notify_all();
      return NO_ERROR;
  }

五、继续看下initScheduler 中的 @7

mEventQueue->setEventConnection(mScheduler->getEventConnection(mSfConnectionHandle));
/frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp
void MessageQueue::setEventConnection(const sp<EventThreadConnection>& connection) {
      if (mEventTube.getFd() >= 0) {
          mLooper->removeFd(mEventTube.getFd());
      }
  
      mEvents = connection;
      mEvents->stealReceiveChannel(&mEventTube);   
      mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver,
                     this);     
  }

1、

/frameworks/native/services/surfaceflinger/scheduler/EventThread.cpp
  status_t EventThreadConnection::stealReceiveChannel(gui::BitTube* outChannel) {
      outChannel->setReceiveFd(mChannel.moveReceiveFd());
      outChannel->setSendFd(base::unique_fd(dup(mChannel.getSendFd())));
      return NO_ERROR;
  }

将mEventTube和EventConnection关联

2、 addFd函数,将fd添加到MessageQueue的Looper中。Looper的callback为MessageQueue::cb_eventReceiver,data为MessageQueue本身

首先看下参数 MessageQueue::cb_eventReceiver,函数指针其实引用的是

/frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp
  int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
      MessageQueue* queue = reinterpret_cast<MessageQueue*>(data);
      return queue->eventReceiver(fd, events);
  }
  
  int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) {
      ssize_t n;
      DisplayEventReceiver::Event buffer[8];
      while ((n = DisplayEventReceiver::getEvents(&mEventTube, buffer, 8)) > 0) {
          for (int i = 0; i < n; i++) {
              if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
                  mHandler->dispatchInvalidate(buffer[i].vsync.expectedVSyncTimestamp);
                  break;
              }
          }
      }
      return 1;
  }

循环等待消息的到来,进行mhandler->dispatchInvalidate 消息分发

system/core/libutils/Looper.cpp
  int Looper::addFd(int fd, int ident, int events, Looper_callbackFunc callback, void* data) {
      return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : nullptr, data);
  }

  int Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data) {
.....
epollResult = epoll_ctl(mEpollFd.get(),EPOLL_CTL_ADD,fd,&eventItem);
......
}

addFd 里面主要用了epoll_ctl 注册新的fd到epfd中。 messageQueue里面有消息会通过fd唤醒epoll_wait,looper从中拿取消息,messageQueue没有消息时候就会睡眠等待唤醒。

六、surfaceFlinger的run方法

/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
  void SurfaceFlinger::run() {
      while (true) {
          mEventQueue->waitMessage();
      }
  }
/frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp
 void MessageQueue::waitMessage() {
      do {
          IPCThreadState::self()->flushCommands();
          int32_t ret = mLooper->pollOnce(-1);
          switch (ret) {
              case Looper::POLL_WAKE:
             case Looper::POLL_CALLBACK:
                  continue;
              case Looper::POLL_ERROR:
                  ALOGE("Looper::POLL_ERROR");
                  continue;
              case Looper::POLL_TIMEOUT:
                  // timeout (should not happen)
                  continue;
              default:
                  // should not happen
                  ALOGE("Looper::pollOnce() returned unknown status %d", ret);
                  continue;
          }
      } while (true);
  }

可以看到熟悉的mLooper->pollOnce(-1), 接着会调用pollInner方法,其中epoll_wait 进行消息的等待唤醒,

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容