SurfaceFlinger初始化

作者: 欣兄 | 来源:发表于2021-03-08 17:29 被阅读0次

    接着上一节,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 进行消息的等待唤醒,

    相关文章

      网友评论

        本文标题:SurfaceFlinger初始化

        本文链接:https://www.haomeiwen.com/subject/zazpqltx.html