SurfaceFlinger作为Android图形显示系统处理逻辑的核心单元,我们有必要去了解其是如何启动,初始化及进行消息处理的。这篇文章我们就来简单分析SurfaceFlinger这个Binder系统服务的一些基本处理逻辑。接下来分两部分讲解:
>> SurfaceFlinger启动与初始化
>> SurfaceFlinger消息队列处理机制
Tips:
本篇涉及的代码位置:
/frameworks/native/services/surfaceflinger/
SurfaceFlinger是一个Binder系统服务,Android设备开机启动时就会带起SurfaceFlinger服务进程并完成一些初始化动作。
从Android S开始,SurfaceFlinger被编译为一个可执行二进制档案:surfaceflinger(放置于设备/system/bin/下)。
如下这段代码中,可以看到这个可执行档与surfaceflinger.rc这个init rc档相关联,这样开机启动时,init进程就可以解析这个rc档,带起SurfaceFlinger服务进程
cc_binary { name: "surfaceflinger", defaults: ["libsurfaceflinger_binary"], init_rc: ["surfaceflinger.rc"], srcs: [ ":surfaceflinger_binary_sources", // Note: SurfaceFlingerFactory is not in the filegroup so that it // can be easily replaced. "SurfaceFlingerFactory.cpp", ], shared_libs: [ "libSurfaceFlingerProp", ], logtags: ["EventLog/EventLogTags.logtags"],}
再来瞅瞅surfaceflinger.rc这个档案的内容,主要时设置一些SurfaceFlinger服务进程启动属性
service surfaceflinger /system/bin/surfaceflinger class core animation user system group graphics drmrpc readproc capabilities SYS_NICE onrestart restart zygote task_profiles HighPerformance socket pdx/system/vr/display/client stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0 socket pdx/system/vr/display/manager stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0 socket pdx/system/vr/display/vsync stream 0666 system graphics u:object_r:pdx_display_vsync_endpoint_socket:s0
这里我们就简简单单理解为:设备开机启动时,init进程解析surfaceflinger.rc,然后去执行/system/bin/surfaceflinger,从而启动了SurfaceFlinger服务进程。
如果在设备console下执行ps,你就可以看到这个进程PID了
console:/ $ ps -A | grep surfaceflingersystem 210 1 133412 38160 0 0 S surfaceflinger
在此我们仅摘录主要的代码并注释如下:
* /frameworks/native/services/surfaceflinger/main_surfaceflinger.cppint main(int, char**) { ... // When SF is launched in its own process, limit the number of // binder threads to 4. ProcessState::self()->setThreadPoolMaxThreadCount(4); ... // start the thread pool sp<ProcessState> ps(ProcessState::self()); ps->startThreadPool(); ... // 创建SurfaceFlinger对象,由强指针指向。 // SurfaceFlinger继承RefBase类,所以此处一旦new出对象赋给sp指针后,将立刻触发SurfaceFlinger类的onFirstRef方法的调用。 // instantiate surfaceflinger sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger(); ... // SurfaceFlinger类正式初始化 // initialize before clients can connect flinger->init(); // SurfaceFlinger向ServiceManager注册Binder服务, // 这样在其他进程中可以通过getService+SERVICE_NAME来获取SurfaceFlinger服务,继而可以和SurfaceFlinger类进行Binder通信。 // publish surface flinger sp<IServiceManager> sm(defaultServiceManager()); sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false, IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO); ... // SurfaceFlinger类进入主循环(此处注意SurfaceFlinger类未继承Threads类,不遵循Threads类的接口执行顺序) // run surface flinger in this thread flinger->run(); return 0;}
对于main函数,简简单单把握一下几点就可以了:
Tips:
在设备console上执行service list命令就可以看到注册的服务:注册的名称是SurfaceFlinger, 这个服务实现的接口是android.ui.ISurfaceComposer
console:/ $ service list | grep Surface1 SurfaceFlinger: [android.ui.ISurfaceComposer]
* /frameworks/native/services/surfaceflinger/SurfaceFlinger.hclass SurfaceFlinger : public BnSurfaceComposer, public PriorityDumper, private IBinder::DeathRecipient, private HWC2::ComposerCallback, private ISchedulerCallback {
调用surfaceflinger::createSurfaceFlinger()来创建SurfaceFlinger实例,并传递一个factory对象作为参数
* /frameworks/native/services/surfaceflinger/SurfaceFlingerFactory.cppsp<SurfaceFlinger> createSurfaceFlinger() { static DefaultFactory factory; return new SurfaceFlinger(factory);}
来简单看一下Factory的定义:
* /frameworks/native/services/surfaceflinger/SurfaceFlingerFactory.h // The interface that SurfaceFlinger uses to create all of the implementations// of each interface.class Factory {public: virtual std::unique_ptr<HWComposer> createHWComposer(const std::string& serviceName) = 0; virtual std::unique_ptr<MessageQueue> createMessageQueue() = 0; virtual std::unique_ptr<scheduler::VsyncConfiguration> createVsyncConfiguration( Fps currentRefreshRate) = 0; virtual std::unique_ptr<Scheduler> createScheduler(const scheduler::RefreshRateConfigs&, ISchedulerCallback&) = 0; virtual sp<SurfaceInterceptor> createSurfaceInterceptor() = 0; virtual sp<StartPropertySetThread> createStartPropertySetThread( bool timestampPropertyValue) = 0; virtual sp<DisplayDevice> createDisplayDevice(DisplayDeviceCreationArgs&) = 0; virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage, std::string requestorName) = 0; virtual void createBufferQueue(sp<IGraphicBufferProducer>* outProducer, sp<IGraphicBufferConsumer>* outConsumer, bool consumerIsSurfaceFlinger) = 0; virtual sp<IGraphicBufferProducer> createMonitoredProducer(const sp<IGraphicBufferProducer>&, const sp<SurfaceFlinger>&, const wp<Layer>&) = 0; virtual sp<BufferLayerConsumer> createBufferLayerConsumer(const sp<IGraphicBufferConsumer>&, renderengine::RenderEngine&, uint32_t tex, Layer*) = 0; virtual std::unique_ptr<surfaceflinger::NativeWindowSurface> createNativeWindowSurface( const sp<IGraphicBufferProducer>&) = 0; virtual std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() = 0; virtual sp<BufferQueueLayer> createBufferQueueLayer(const LayerCreationArgs& args) = 0; virtual sp<BufferStateLayer> createBufferStateLayer(const LayerCreationArgs& args) = 0; virtual sp<EffectLayer> createEffectLayer(const LayerCreationArgs& args) = 0; virtual sp<ContainerLayer> createContainerLayer(const LayerCreationArgs& args) = 0; virtual std::unique_ptr<FrameTracer> createFrameTracer() = 0; virtual std::unique_ptr<frametimeline::FrameTimeline> createFrameTimeline( std::shared_ptr<TimeStats> timeStats, pid_t surfaceFlingerPid) = 0;protected: ~Factory() = default;};
Factory中定义了各种create方法,其作用如注释中说明:The interface that SurfaceFlinger uses to create all of the implementations of each interface.
SurfaceFlinger用Factory来创建所有实现了对应接口的对象。SurfaceFlinger中默认使用的是DefaultFactory,其中定义各种createXXX()方法的实现。具体可参见:/frameworks/native/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
构造函数的代码就只截取部分贴在这里了,其中主要是读取一些属性值来对一些成员变量进行初始化。其中一些属性值是debug参数。另外就是利用mFactory的createXXX方法去实例化各种对象。
比如 : 创建消息队列 mEventQueue(mFactory.createMessageQueue())
* /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag) : mFactory(factory), mInterceptor(mFactory.createSurfaceInterceptor()), mTimeStats(std::make_shared<impl::TimeStats>()), mFrameTracer(mFactory.createFrameTracer()), mFrameTimeline(mFactory.createFrameTimeline(mTimeStats, getpid())), mEventQueue(mFactory.createMessageQueue()), mCompositionEngine(mFactory.createCompositionEngine()), mHwcServiceName(base::GetProperty("debug.sf.hwc_service_name"s, "default"s)), mTunnelModeEnabledReporter(new TunnelModeEnabledReporter()), mInternalDisplayDensity(getDensityFromProperty("ro.sf.lcd_density", true)), mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)), mPowerAdvisor(*this) { ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str()); mSetInputWindowsListener = new SetInputWindowsListener([&]() { setInputWindowsFinished(); });}SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipInitialization) { ALOGI("SurfaceFlinger is starting"); hasSyncFramework = running_without_sync_framework(true); dispSyncPresentTimeOffset = present_time_offset_from_vsync_ns(0); useHwcForRgbToYuv = force_hwc_copy_for_virtual_displays(false); maxFrameBufferAcquiredBuffers = max_frame_buffer_acquired_buffers(2); maxGraphicsWidth = std::max(max_graphics_width(0), 0); maxGraphicsHeight = std::max(max_graphics_height(0), 0); hasWideColorDisplay = has_wide_color_display(false); ... }
surfaceflinger 会去读取SurfaceFlingerProperties中的系统属性,具体可以参看源码:/frameworks/native/services/surfaceflinger/sysprop/
Tips:
关于系统属性的知识建议可以参见:
https://source.android.google.cn/devices/architecture/sysprops-apis?hl=zh-cn
https://blog.csdn.net/askfgx2010/article/details/112308665
上面创建完SurfaceFlinger对象,立即就会执行到SurfaceFlinger::onFirstRef,这个方法中就做了一件事对消息队列做初始化,如下:
void SurfaceFlinger::onFirstRef() { mEventQueue->init(this);}
消息队列运行的详细分析我们下节在讲,这里先不展开。
再回到可执行档surfaceflinger的main函数中,创建完SurfaceFlinger对象后,紧接着调用了SurfaceFlinger::init()方法:
* /frameworks/native/services/surfaceflinger/SurfaceFlinger.cppvoid SurfaceFlinger::init() { ALOGI( "SurfaceFlinger's main thread ready to run. " "Initializing graphics H/W..."); Mutex::Autolock _l(mStateLock); // 对于CompositionEngine 属性进行设置, 创建 RenderEngine 对象 // 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::REALTIME : renderengine::RenderEngine::ContextPriority::MEDIUM) .build())); // Set SF main policy after initializing RenderEngine which has its own policy. if (!SetTaskProfiles(0, {"SFMainPolicy"})) { ALOGW("Failed to set main task profile"); } // 创建HWComposer对象并传入一个name属性,再通过mCompositionEngine->setHwComposer设置对象属性。 mCompositionEngine->setTimeStats(mTimeStats); mCompositionEngine->setHwComposer(getFactory().createHWComposer(mHwcServiceName)); mCompositionEngine->getHwComposer().setCallback(this); ClientCache::getInstance().setRenderEngine(&getRenderEngine()); if (base::GetBoolProperty("debug.sf.enable_hwc_vds"s, false)) { enableHalVirtualDisplays(true); } // processDisplayHotplugEventsLocked(); 处理 任何初始热插拔和显示更改的结果 // 在此方法中主要有调用 initScheduler(displayId); // Process any initial hotplug and resulting display changes. processDisplayHotplugEventsLocked(); const auto display = getDefaultDisplayDeviceLocked(); LOG_ALWAYS_FATAL_IF(!display, "Missing internal display after registering composer callback."); const auto displayId = display->getPhysicalId(); LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(displayId), "Internal display is disconnected."); // initialize our drawing state mDrawingState = mCurrentState; // 初始化Display信息 // set initial conditions (e.g. unblank default device) initializeDisplays(); mPowerAdvisor.init(); char primeShaderCache[PROPERTY_VALUE_MAX]; property_get("service.sf.prime_shader_cache", primeShaderCache, "1"); if (atoi(primeShaderCache)) { if (setSchedFifo(false) != NO_ERROR) { ALOGW("Can't set SCHED_OTHER for primeCache"); } mRenderEnginePrimeCacheFuture = getRenderEngine().primeCache(); if (setSchedFifo(true) != NO_ERROR) { ALOGW("Can't set SCHED_OTHER for primeCache"); } } getRenderEngine().onPrimaryDisplaySizeChanged(display->getSize()); // 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); // 开启一个设置属性的线程,在这个线程中使用property_set去设置一些属性值 if (mStartPropertySetThread->Start() != NO_ERROR) { ALOGE("Run StartPropertySetThread failed!"); } ALOGV("Done initializing");}
SurfaceFlinger::init方法,完成的工作大概为:
? CompositionEngine的配置,创建RenderEngine对象用于Client合成模式(GPU)合成;
? 初始化HWComposer,注册回调接口mCompositionEngine->getHwComposer().setCallback(this),HAL会回调一些方法;
? 处理Display显示屏幕的热插拔和更改的事件processDisplayHotplugEventsLocked;
? 初始化显示设备initializeDisplays;
? 开启一个设置属性的线程,在这个线程中使用property_set去设置一些属性值mStartPropertySetThread->Start();
可执行档surfaceflinger的main函数中,把SurfaceFinger这个服务注册进ServiceManger中后,后续执行了SurfaceFlinger::run这个方法,代码如下:
* /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp void SurfaceFlinger::run() { while (true) { mEventQueue->waitMessage(); }}
这个方法也很简单,一个while(true)的无限死循环,消息队列等待消息的到来。surfaceflinger主线程中等待消息处理。
讲到这里,大概SurfaceFlinger启动的流程就完成了,当然,很多细节我们没有深入去分析。
* /frameworks/native/services/surfaceflinger/SurfaceFlinger.h//成员变量mEventQueue的声明std::unique_ptr<MessageQueue> mEventQueue;========* /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp// SurfaceFlinger构造函数中创建消息队列mEventQueue(mFactory.createMessageQueue()),
* /frameworks/native/services/surfaceflinger/SurfaceFlingerDefaultFactory.cppstd::unique_ptr<MessageQueue> DefaultFactory::createMessageQueue() { return std::make_unique<android::impl::MessageQueue>();}
* /frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.hnamespace impl {class MessageQueue : public android::MessageQueue { sp<SurfaceFlinger> mFlinger; sp<Looper> mLooper; sp<Handler> mHandler; ...}
* /frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.h void init(const sp<SurfaceFlinger>& flinger) override; void initVsync(scheduler::VSyncDispatch&, frametimeline::TokenManager&, std::chrono::nanoseconds workDuration) override; void setDuration(std::chrono::nanoseconds workDuration) override; void setInjector(sp<EventThreadConnection>) override; void waitMessage() override; void postMessage(sp<MessageHandler>&&) override; // sends INVALIDATE message at next VSYNC void invalidate() override; // sends REFRESH message at next VSYNC void refresh() override;
* /frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cppvoid MessageQueue::init(const sp<SurfaceFlinger>& flinger) { mFlinger = flinger; mLooper = new Looper(true); mHandler = new Handler(*this);}
void MessageQueue::postMessage(sp<MessageHandler>&& handler) { mLooper->sendMessage(handler, Message());}
waitMessage方法中不断去调用mLooper->pollOnce(-1),检查Looper中是否有消息需要处理,如果有,则调用该消息对应的MessageHandler去处理。
void MessageQueue::waitMessage() { do { IPCThreadState::self()->flushCommands(); int32_t ret = mLooper->pollOnce(-1); ... } while (true);}
Handler继承自MessageHandler并实现了handleMessage方法,在这个方法中对消息进行处理
Handler中还有一个成员mQueue指向MessageQueue对象引用
class Handler : public MessageHandler { enum : uint32_t { eventMaskInvalidate = 0x1, eventMaskRefresh = 0x2, eventMaskTransaction = 0x4 }; MessageQueue& mQueue; std::atomic<uint32_t> mEventMask; std::atomic<int64_t> mVsyncId; std::atomic<nsecs_t> mExpectedVSyncTime; public: explicit Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) {} void handleMessage(const Message& message) override; virtual void dispatchRefresh(); virtual void dispatchInvalidate(int64_t vsyncId, nsecs_t expectedVSyncTimestamp); virtual bool invalidatePending(); };
前面讲到的都是一些定义啊,方法呀,他们之间的联系,如何运作似乎还是云里雾里,没有讲到。
其实SurfaceFlinger消息队列主要处理2个重要事件:Refresh 和 Invalidate
某些操作下需要进行refresh动作时,会调用到SurfaceFlinger::signalRefresh()
void SurfaceFlinger::signalRefresh() { mRefreshPending = true; mEventQueue->refresh();}
SurfaceFlinger::signalRefresh()方法中会继续调用mEventQueue->refresh()
void MessageQueue::refresh() { mHandler->dispatchRefresh();}
继而调用到mHandler->dispatchRefresh()
void MessageQueue::Handler::dispatchRefresh() { if ((mEventMask.fetch_or(eventMaskRefresh) & eventMaskRefresh) == 0) { mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH)); }}
Handler::dispatchRefresh()方法中就要准备消息并指定Handler来处理这个消息,然后seedMessage到Looper的消息队列中去,等待后续处理。
对于refresh消息,其what字段为MessageQueue::REFRESH, 处理它就是在MessageQueue::Handler::handleMessage方法中,如下:
void MessageQueue::Handler::handleMessage(const Message& message) { switch (message.what) { case INVALIDATE: mEventMask.fetch_and(~eventMaskInvalidate); mQueue.mFlinger->onMessageReceived(message.what, mVsyncId, mExpectedVSyncTime); break; case REFRESH: mEventMask.fetch_and(~eventMaskRefresh); mQueue.mFlinger->onMessageReceived(message.what, mVsyncId, mExpectedVSyncTime); break; }}
看到这里是不是稍微清晰一点了,当waitMessage --> Looper::pollOnce 检测到这个refresh消息要处理时,就会回调到MessageQueue::Handler::handleMessage方法,进而执行到SurfaceFlinger::onMessageReceived
void SurfaceFlinger::onMessageReceived(int32_t what, int64_t vsyncId, nsecs_t expectedVSyncTime) { switch (what) { case MessageQueue::INVALIDATE: { onMessageInvalidate(vsyncId, expectedVSyncTime); break; } case MessageQueue::REFRESH: { onMessageRefresh(); break; } }}
之后就是具体refresh要完成的具体工作了,此处省略一万字....
讲到这里不知您明白了没,没有图形化的注解确实不太系统,不过只要你理解Android Native Looper/Handler/Message机制应该很容易看懂。
简简单单的理解:
实用技巧
武林中有两招绝学,一阳指和狮吼功,我用了整整三十年的时间,将两招绝学并成了一整招。你过来啊!
Android 11之前的一阳指和狮吼功:
* /frameworks/native/services/surfaceflinger/SurfaceFlinger.h// post an asynchronous message to the main threadstatus_t postMessageAsync(const sp<MessageBase>& msg, nsecs_t reltime = 0, uint32_t flags = 0);// post a synchronous message to the main threadstatus_t postMessageSync(const sp<MessageBase>& msg, nsecs_t reltime = 0, uint32_t flags = 0);
Android 11之后两招绝学并成了一整招
* /frameworks/native/services/surfaceflinger/SurfaceFlinger.h// Schedule an asynchronous or synchronous task on the main thread.template <typename F, typename T = std::invoke_result_t<F>>[[nodiscard]] std::future<T> schedule(F&&);
这些方法的作用就是把指定的任务放到main thread中去执行。
看一下schedule的定义:
template <typename F, typename T>inline std::future<T> SurfaceFlinger::schedule(F&& f) { auto [task, future] = makeTask(std::move(f)); mEventQueue->postMessage(std::move(task)); return std::move(future);}
再看makeTask和Task的定义:
* /frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.htemplate <typename F>class Task : public MessageHandler { template <typename G> friend auto makeTask(G&&); explicit Task(F&& f) : mTask(std::move(f)) {} void handleMessage(const Message&) override { mTask(); } using T = std::invoke_result_t<F>; std::packaged_task<T()> mTask;};template <typename F>inline auto makeTask(F&& f) { sp<Task<F>> task = new Task<F>(std::move(f)); return std::make_pair(task, task->mTask.get_future());}
MessageQueue::postMessage
* /frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cppvoid MessageQueue::postMessage(sp<MessageHandler>&& handler) { mLooper->sendMessage(handler, Message());}
看到这里是不是基本就清楚了,熟悉的字眼:postMessage,MessageHandler,handleMessage本质还是main thread上消息队列处理。
其实换汤不换药,只是利用C++的新特型做了抽象与封装,本质还是向主线程发送一个Message并指定其MessageHandler,主线程收到消息时调用MessageHandler::handleMessage,进而呼叫到我们指定的函数实体代码。
我们已一个例子来说明:
static_cast<void>(schedule([=]() { ALOGD("我在主线程被打印"); }));
我们传递给schedule的函数实体将在主线程执行。
这在我们修改某些逻辑且要保证主线程执行时可能是个不错的技巧。
写到这里 SurfaceFlinger启动与初始化流程和SurfaceFlinger消息队列处理机制就完了,很多内容自己也没有完全吃透,本篇的目的还是着重讲解流程而忽视具体细节,搞懂流程再去按工作需要分析细节,这样感觉会更实用主义。
最后分享一份好心情