1 前言

​ surfaceflinger 的作用是合成来自 WMS 的 Surface 数据,并发送到显示设备。

​ SurfaceFlinger 服务不同于 AMS、WMS、IMP、PMS、DMS 等服务,主要区别如下:

  • AMS 等由 SystemServer.java 拉起,SurfaceFlinger 由 main.cpp(init 进程) 拉起;
  • AMS 等运行在 system_server 进程中,SurfaceFlinger 运行在 surface_flinger 进程中;
  • AMS 等启动过程中涉及到的类主要在 Java 层,SurfaceFlinger 启动过程中涉及到的类主要在 Native 层。

2 源码分析

2.1 SurfaceFlinger 创建流程

(1)main

​ /system/core/init/main.cpp

int main(int argc, char** argv) {
...
if (argc > 1) {
...
if (!strcmp(argv[1], "second_stage")) {
return SecondStageMain(argc, argv);
}
}
return FirstStageMain(argc, argv);
}

(2)SecondStageMain

​ /system/core/init/init.cpp

int SecondStageMain(int argc, char** argv) {
...
property_init(); //初始化属性服务
...
LoadBootScripts(am, sm); //加载启动脚本
..
return 0;
}

​ 属性服务类似于 Windows 平台的注册表管理器,属性以键值对的形式呈现,如:ro.xxx.xxx = value。

(3)LoadBootScripts

​ /system/core/init/init.cpp

static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
Parser parser = CreateParser(action_manager, service_list);
std::string bootscript = GetProperty("ro.boot.init_rc", "");
if (bootscript.empty()) {
parser.ParseConfig("/init.rc"); //解析 init.rc 配置文件
...
} else {
parser.ParseConfig(bootscript);
}
}

(4)class_start

​ /system/core/rootdir/init.rc

on boot
...
# Start standard binderized HAL daemons
class_start hal
class_start core //启动 classname 为 core 的 Service

init.rc 是一个配置文件,由 Android 初始化语言(Android Init Language)编写的脚本,主要包含 5 种类型语句:Action、Command、Service、Option 和 Import。

(5)surfaceflinger

​ /frameworks/native/services/surfaceflinger/surfaceflinger.rc

service surfaceflinger /system/bin/surfaceflinger
class core animation
user system
group graphics drmrpc readproc
onrestart restart zygote
writepid /dev/stune/foreground/tasks
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

​ 服务名:surfaceflinger,执行程序路径:/system/bin/surfaceflinger,类名:core(init.rc 文件中 class_start 启动了 core)。

(6)main

​ /frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp

int main(int, char**) {
...
// 初始化 Hal 硬件抽象层的图元生成器服务
startGraphicsAllocatorService();
// 设置最大 binder 线程数
ProcessState::self()->setThreadPoolMaxThreadCount(4);
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
// 实例化 surfaceflinger
sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
...
// 初始化 surfaceflinger
flinger->init();
// 将 flinger 添加到 ServiceManager 进程中
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false, IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
...
//启动 DisplayService
startDisplayService();
// 启动 surfaceflinger
flinger->run();
...
return 0;
}

(7)createSurfaceFlinger

​ /frameworks/native/services/surfaceflinger/SurfaceFlingerFactory.cpp

namespace android::surfaceflinger {

sp<SurfaceFlinger> createSurfaceFlinger() {
class Factory final : public surfaceflinger::Factory {
public:
... std::unique_ptr<EventControlThread> createEventControlThread(
std::function<void(bool)> setVSyncEnabled) override {
return std::make_unique<android::impl::EventControlThread>(setVSyncEnabled);
} std::unique_ptr<HWComposer> createHWComposer(const std::string& serviceName) override {
return std::make_unique<android::impl::HWComposer>(
std::make_unique<Hwc2::impl::Composer>(serviceName));
} std::unique_ptr<MessageQueue> createMessageQueue() override {
return std::make_unique<android::impl::MessageQueue>();
} ...
};
static Factory factory; return new SurfaceFlinger(factory);
} } // namespace android::surfaceflinger

(8)SurfaceFlinger

​ /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
: mFactory(factory),
mPhaseOffsets(mFactory.createPhaseOffsets()),
mInterceptor(mFactory.createSurfaceInterceptor(this)),
mTimeStats(mFactory.createTimeStats()),
mEventQueue(mFactory.createMessageQueue()),
mCompositionEngine(mFactory.createCompositionEngine()) {} SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipInitialization) {
hasSyncFramework = running_without_sync_framework(true);
dispSyncPresentTimeOffset = present_time_offset_from_vsync_ns(0);
useHwcForRgbToYuv = force_hwc_copy_for_virtual_displays(false);
maxVirtualDisplaySize = max_virtual_display_dimension(0); //最大虚拟屏个数
useVrFlinger = use_vr_flinger(false);
maxFrameBufferAcquiredBuffers = max_frame_buffer_acquired_buffers(2);
hasWideColorDisplay = has_wide_color_display(false);
useColorManagement = use_color_management(false);
...
}

2.2 SurfaceFlinger 初始化流程

(1)init

​ /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

void SurfaceFlinger::init() {
...
mScheduler = getFactory().createScheduler([this](bool enabled) { setPrimaryVsyncEnabled(enabled); }, mRefreshRateConfigs);
auto resyncCallback = mScheduler->makeResyncCallback(std::bind(&SurfaceFlinger::getVsyncPeriod, this));
// 初始化 App 的 ConnectionHandle
mAppConnectionHandle = mScheduler->createConnection("app", mPhaseOffsets->getCurrentAppOffset(), resyncCallback, impl::EventThread::InterceptVSyncsCallback());
// 初始化 SF 的 ConnectionHandle
mSfConnectionHandle = mScheduler->createConnection("sf", mPhaseOffsets->getCurrentSfOffset(), resyncCallback, [this](nsecs_t timestamp) {
mInterceptor->saveVSyncEvent(timestamp);
});
// 将 mSfConnectionHandle 对应的 EventThreadConnection 注入 mEventQueue
mEventQueue->setEventConnection(mScheduler->getEventConnection(mSfConnectionHandle));
...
mRegionSamplingThread = new RegionSamplingThread(*this, *mScheduler, RegionSamplingThread::EnvironmentTimingTunables());
...
// 创建 GLESRenderEngine 渲染引擎
mCompositionEngine->setRenderEngine(renderengine::RenderEngine::create(static_cast<int32_t>(defaultCompositionPixelFormat), renderEngineFeature, maxFrameBufferAcquiredBuffers));
...
mCompositionEngine->setHwComposer(getFactory().createHWComposer(getBE().mHwcServiceName));
// 将 this 封装到 ComposerCallbackBridge,再注入到 IComposerClient 的实现类中
mCompositionEngine->getHwComposer().registerCallback(this, getBE().mComposerSequenceId);
// 处理初始热插拔事件和由此导致的 Display 的改变
processDisplayHotplugEventsLocked();
const auto display = getDefaultDisplayDeviceLocked();
...
if (useVrFlinger) {
...
mVrFlinger = dvr::VrFlinger::Create(getHwComposer().getComposer(), getHwComposer().fromPhysicalDisplayId(*display->getId()).value_or(0),
vrFlingerRequestDisplayCallback);
...
}
// 初始化绘制状态
mDrawingState = mCurrentState;
// 调用 onInitializeDisplays,初始化 Display 的宽高等信息
initializeDisplays();
getRenderEngine().primeCache();
...
mStartPropertySetThread = getFactory().createStartPropertySetThread(presentFenceReliable);
...
mScheduler->setChangeRefreshRateCallback([this](RefreshRateType type, Scheduler::ConfigEvent event) {
Mutex::Autolock lock(mStateLock);
setRefreshRateTo(type, event);
});
mScheduler->setGetVsyncPeriodCallback([this] {
Mutex::Autolock lock(mStateLock);
return getVsyncPeriod();
});
mRefreshRateConfigs.populate(getHwComposer().getConfigs(*display->getId()));
mRefreshRateStats.setConfigMode(getHwComposer().getActiveConfigIndex(*display->getId()));
...
}

​ 说明:

​ 1)每个 ConnectionHandle 对象里有个 id,作为 Scheduler 对象中 mConnections 属性(map<id, Connection>)的键值,Connection 对象中又包含 ConnectionHandle、EventThreadConnection、EventThread 3个属性。

​ 2)mScheduler->getEventConnection(mSfConnectionHandle) 中,以 mSfConnectionHandle 的 id 为键值,在 Scheduler 的 mConnections(unordered_map<int64_t, Connection>)中找到对应的Connection,并返回其 EventThreadConnection 成员属性。

​ 3)getHwComposer().registerCallback() 中,依次调用 HwComposer、Device 的 registerCallback() 方法,并在 Device 中 将 SurfaceFlinger 对象封装到 ComposerCallbackBridge 中;对于封装后的对象,依次调用 Composer、IComposerClient 的 registerCallback() 方法,注入到 IComposerClient 的实现类中。

(2)startDisplayService

​ /frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp

static status_t startDisplayService() {
...
sp<IDisplayService> displayservice = new DisplayService();
status_t err = displayservice->registerAsService();
...
return err;
}

(3)run

​ /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

void SurfaceFlinger::run() {
do {
waitForEvent();
} while (true);
}

(4)waitForEvent

​ /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

void SurfaceFlinger::waitForEvent() {
mEventQueue->waitMessage();
}

​ 声明:本文转自【framework】surfaceflinger启动流程

【framework】surfaceflinger启动流程的更多相关文章

  1. go web framework gin 启动流程分析

    最主要的package : gin 最主要的struct: Engine Engine 是整个framework的实例,它包含了muxer, middleware, configuration set ...

  2. Phalcon Framework的MVC结构及启动流程分析

    目前的项目中选择了Phalcon Framework作为未来一段时间的核心框架.技术选型的原因会单开一篇Blog另说,本次优先对Phalcon的MVC架构与启动流程进行分析说明,如有遗漏还望指出. P ...

  3. Phalcon Framework的Mvc结构及启动流程(部分源码分析)

    创建项目 Phalcon环境配置安装后,可以通过命令行生成一个标准的Phalcon多模块应用 phalcon project eva --type modules入口文件为public/index.p ...

  4. Android进阶系列之源码分析Activity的启动流程

    美女镇楼,辟邪! 源码,是一个程序猿前进路上一个大的而又不得不去翻越障碍,我讨厌源码,看着一大堆.5000多行,要看完得啥时候去了啊.不过做安卓的总有这一天,自从踏上这条不归路,我就认命了.好吧,我慢 ...

  5. u-boot启动流程分析(2)_板级(board)部分

    转自:http://www.wowotech.net/u-boot/boot_flow_2.html 目录: 1. 前言 2. Generic Board 3. _main 4. global dat ...

  6. Android开机动画启动流程

    android开机动画启动流程   从android的Surface Flinger服务启动分析知道,开机动画是在SurfaceFlinger实例通过调用startBootAnim()启动的. 下面我 ...

  7. 老李推荐:第5章2节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 启动流程概览

    老李推荐:第5章2节<MonkeyRunner源码剖析>Monkey原理分析-启动运行: 启动流程概览   每个应用都会有一个入口方法来供操作系统调用执行,Monkey这个应用的入口方法就 ...

  8. Android系统开机启动流程及init进程浅析

    Android系统启动概述 Android系统开机流程基于Linux系统,总体可分为三个阶段: Boot Loader引导程序启动Linux内核启动Android系统启动,Launcher/app启动 ...

  9. 海思uboot启动流程详细分析(三)【转】

    1. 前言 书接上文(u-boot启动流程分析(二)_平台相关部分),本文介绍u-boot启动流程中和具体版型(board)有关的部分,也即board_init_f/board_init_r所代表的. ...

  10. Android N 的开机启动流程概述

    原地址:https://blog.csdn.net/h655370/article/details/77727554 图片展示了Android的五层架构,从上到下依次是:应用层,应用框架层,库层,运行 ...

随机推荐

  1. [STM32H7] 实战技能分享,如何让工程代码各种优化等级通吃,含MDK AC5,AC6,IAR和GCC

    引出问题:    一个好的工程项目代码,特别是开源类的,如果能做到各种优化等级通吃,是一种非常好的工程案例,这样别人借鉴的时候,可以方便的适配到自己工程里.但实际项目中,针对一款产品代码,我们一般不会 ...

  2. 【TouchGFX】Callback

    回调函数模板定义 单参数回调函数模板 实现回调函数接口: 实现合法性检查接口: 实现执行接口: 按键触发回调实现 定义回调数据结构对象 使用回调数据结构构造函数 执行接口实现 整个切换机制的管理主体对 ...

  3. 搭建 github 报错 Permission denied (publickey)

    将 key 加入 github 出现如下问题 这是本地仓 user.name user.email 与 github 注册信息不一致造成 将本地仓 user 信息与 github 修改一致,出现如下问 ...

  4. [转帖]History of Unicode Release and Publication Dates

    www.unicode.org For ease of reference, this page collects together information about the dates for v ...

  5. SQLServer解决deadlock问题的一个场景

    SQLServer解决deadlock问题的一个场景 背景 公司产品出现过很多次dead lock 跟研发讨论了很久, 都没有具体的解决思路 但是这边知道了一个SQLServer数据库上面计划100% ...

  6. [转帖]SQL Server中查询CPU占用高的SQL语句

    本文导读:触发器造成死锁.作业多且频繁.中间表的大量使用.游标的大量使用.索引的设计不合理.事务操作频繁.SQL语句设计不合理,都会造成查询效率低下.影响服务器性能的发挥.我们可以使用sql serv ...

  7. [转帖]7.5 TiKV 磁盘空间占用与回收常见问题

    https://book.tidb.io/session4/chapter7/compact.html TiKV 作为 TiDB 的存储节点,用户通过 SQL 导入或更改的所有数据都存储在 TiKV. ...

  8. [转帖]使用 EXISTS 代替 IN 和 inner join

      在使用Exists时,如果能正确使用,有时会提高查询速度: 1,使用Exists代替inner join 2,使用Exists代替 in 1,使用Exists代替inner join例子: 在一般 ...

  9. [转帖]SQL标准

    SQL 的标准 1986 年 10 月,美国国家标准协会 ANSI 采用 SQL 作为关系数据库管理系统的标准语言,并命名为 ANSI X3. 135-1986,后来国际标准化组织(ISO)也采纳 S ...

  10. 如何减缓vm中慢插入的次数

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 偶然发现vm-storage的监控里有这样一个指标:vm_ ...