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