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