SurfaceFlinger 初始化
SurfaceFlinger 系列文章持续更新中(公众号:阿豪讲Framework):
- 如何调试 SurfaceFlinger
- SurfaceFlinger 概述
- 启动过程总览
- SurfaceFlinger 初始化
- ........
# 1. 整体流程
// frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
int main(int, char**) {
// ......
// 创建 SurfaceFlinger 对象
sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
// ......
// 初始化 SurfaceFlinger
flinger->init();
// ......
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- 创建 SurfaceFlinger 对象
- 初始化 SurfaceFlinger
# 2. 创建 SurfaceFlinger 对象
createSurfaceFlinger 函数的实现如下:
// /frameworks/native/services/surfaceflinger/SurfaceFlingerFactory.cpp
sp<SurfaceFlinger> createSurfaceFlinger() {
static DefaultFactory factory;
return sp<SurfaceFlinger>::make(factory);
}
2
3
4
5
6
这里通过工厂模式去 new 了一个 SurfaceFlinger 对象。
SurfaceFlinger 类的定义如下:
//
class SurfaceFlinger : public BnSurfaceComposer,
public PriorityDumper,
private IBinder::DeathRecipient,
private HWC2::ComposerCallback,
private ICompositor,
private scheduler::ISchedulerCallback {
// ......
}
2
3
4
5
6
7
8
9
SurfaceFlinger 继承了多个父类,目前主要关注 BnSurfaceComposer(ISurfaceComposer)、ComposerCallback 和 ISchedulerCallback:
ISurfaceComposer 是一个接口,定义了 SurfaceFlinger 作为一个 Binder 服务对外提供的服务
ComposerCallback 是 HWC 模块的回调,该回调在初始化过程中会注册给 HWC HAL,包含了三个很关键的回调函数,当 HWC HAL 中相关状态变化时,就会调用到这三个函数
- onComposerHotplug 函数表示显示屏热插拔事件
- onComposerHalRefresh 函数表示 Refresh 事件
- onComposerHalVsync 表示 Vsync 信号事件。
ISchedulerCallback 接口,是一个 Scheduler 回调接口,该回调在初始化过程中会注册给 Scheduler,它定义了 SurfaceFlinger 与 Scheduler 之间的通信协议:
- requestHardwareVsync :启用或禁用硬件 VSYNC
- requestDisplayModes :处理显示模式请求
- kernelTimerChanged :处理内核定时器变化
- onChoreographerAttached :处理编舞者附加事件
- onExpectedPresentTimePosted :处理预期呈现时间发布
- onCommitNotComposited :处理未合成的提交
- vrrDisplayIdle :处理可变刷新率显示空闲状态
接着看 SurfaceFlinger 的构造函数:
// /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
// C++11 引入了委托构造函数,允许一个构造函数调用同一个类中的其他构造函数
// 先调用双参数的构造函数,再调用单参数构造函数
SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipInitialization) {
// .......
}
2
3
4
5
6
单参构造函数更简单一点,我们先看单参数构造函数的实现,主要是读取各种系统属性值到全局变量中,后续再使用这些值对 SF 进行相应的配置。
// /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
int64_t SurfaceFlinger::dispSyncPresentTimeOffset;
bool SurfaceFlinger::useHwcForRgbToYuv;
bool SurfaceFlinger::hasSyncFramework;
int64_t SurfaceFlinger::maxFrameBufferAcquiredBuffers;
int64_t SurfaceFlinger::minAcquiredBuffers = 1;
std::optional<int64_t> SurfaceFlinger::maxAcquiredBuffersOpt;
uint32_t SurfaceFlinger::maxGraphicsWidth;
uint32_t SurfaceFlinger::maxGraphicsHeight;
bool SurfaceFlinger::useContextPriority;
Dataspace SurfaceFlinger::defaultCompositionDataspace = Dataspace::V0_SRGB;
ui::PixelFormat SurfaceFlinger::defaultCompositionPixelFormat = ui::PixelFormat::RGBA_8888;
Dataspace SurfaceFlinger::wideColorGamutCompositionDataspace = Dataspace::V0_SRGB;
ui::PixelFormat SurfaceFlinger::wideColorGamutCompositionPixelFormat = ui::PixelFormat::RGBA_8888;
LatchUnsignaledConfig SurfaceFlinger::enableLatchUnsignaledConfig;
SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipInitialization) {
SFTRACE_CALL();
ALOGI("SurfaceFlinger is starting");
/*
- 作用 : 检测设备是否支持同步框架(fence机制)
- 影响 : 在 `onCompositionPresented` 中,当没有同步框架时会主动启用硬件VSync
- 重要性 : 确保在老设备上的向后兼容性
*/
hasSyncFramework = running_without_sync_framework(true);
/*
- 作用 : 设置显示呈现时间相对于VSync的偏移量
- 影响 : 用于VSync时序调整和显示同步优化
*/
dispSyncPresentTimeOffset = present_time_offset_from_vsync_ns(0);
/*
- 作用 : 控制虚拟显示是否强制使用 HWC 进行 RGB 到 YUV 转换
- 影响 : 影响虚拟显示的合成策略和性能
*/
useHwcForRgbToYuv = force_hwc_copy_for_virtual_displays(false);
/*
- 作用 : 控制FramebufferSurface可获取的最大缓冲区数量
- 影响 : 影响缓冲区分配策略和内存使用
*/
maxFrameBufferAcquiredBuffers = max_frame_buffer_acquired_buffers(2);
/*
- 作用 : 设置SurfaceFlinger建议的最小获取缓冲区数量
- 影响 : 通过ISurfaceComposer.getMaxAcquiredBufferCount()影响客户端缓冲区策略
*/
minAcquiredBuffers =
SurfaceFlingerProperties::min_acquired_buffers().value_or(minAcquiredBuffers);
/*
- 作用 : 设置GPU回退合成支持的最大宽度和高度
- 影响 : 用于8K设备配4K GPU或4K设备配2K GPU的场景
*/
maxGraphicsWidth = std::max(max_graphics_width(0), 0);
maxGraphicsHeight = std::max(max_graphics_height(0), 0);
/*
- 作用 : 指示设备是否支持广色域显示
- 影响 : 决定色彩空间选择和HDR支持能力
*/
mSupportsWideColor = has_wide_color_display(false);
/*
- 作用 : 设置HWC期望的高效合成数据空间和像素格式
- 影响 : 优化硬件合成器的性能和色彩空间支持
*/
mDefaultCompositionDataspace =
static_cast<ui::Dataspace>(default_composition_dataspace(Dataspace::V0_SRGB));
mWideColorGamutCompositionDataspace = static_cast<ui::Dataspace>(wcg_composition_dataspace(
mSupportsWideColor ? Dataspace::DISPLAY_P3 : Dataspace::V0_SRGB));
defaultCompositionDataspace = mDefaultCompositionDataspace;
wideColorGamutCompositionDataspace = mWideColorGamutCompositionDataspace;
defaultCompositionPixelFormat = static_cast<ui::PixelFormat>(
default_composition_pixel_format(ui::PixelFormat::RGBA_8888));
wideColorGamutCompositionPixelFormat =
static_cast<ui::PixelFormat>(wcg_composition_pixel_format(ui::PixelFormat::RGBA_8888));
/*
- 作用 : 控制是否启用图层缓存功能
- 影响 : 可通过debug.sf.enable_layer_caching动态覆盖
*/
mLayerCachingEnabled =
base::GetBoolProperty("debug.sf.enable_layer_caching"s,
sysprop::SurfaceFlingerProperties::enable_layer_caching()
.value_or(false));
/*
- 作用 : 指示RenderEngine是否使用EGL_IMG_context_priority提示
- 影响 : 优化GPU上下文优先级
*/
useContextPriority = use_context_priority(true);
mInternalDisplayPrimaries = sysprop::getDisplayNativePrimaries();
// debugging stuff...
char value[PROPERTY_VALUE_MAX];
/*
- 作用 : 区分用户版本和开发版本
- 影响 : 控制调试功能和事务跟踪的启用
*/
property_get("ro.build.type", value, "user");
mIsUserBuild = strcmp(value, "user") == 0;
// mDebugFlashDelay : 控制更新闪烁延迟
mDebugFlashDelay = base::GetUintProperty("debug.sf.showupdates"s, 0u);
//GPU合成背压控制
mBackpressureGpuComposition = base::GetBoolProperty("debug.sf.enable_gl_backpressure"s, true);
ALOGI_IF(mBackpressureGpuComposition, "Enabling backpressure for GPU composition");
// 背景模糊支持
property_get("ro.surface_flinger.supports_background_blur", value, "0");
bool supportsBlurs = atoi(value);
mSupportsBlur = supportsBlurs;
ALOGI_IF(!mSupportsBlur, "Disabling blur effects, they are not supported.");
// 亮度采样控制
property_get("debug.sf.luma_sampling", value, "1");
mLumaSampling = atoi(value);
// 客户端合成缓存控制
property_get("debug.sf.disable_client_composition_cache", value, "0");
mDisableClientCompositionCache = atoi(value);
// HWC合成策略预测
property_get("debug.sf.predict_hwc_composition_strategy", value, "1");
mPredictCompositionStrategy = atoi(value);
// 170M色彩空间处理
property_get("debug.sf.treat_170m_as_sRGB", value, "0");
mTreat170mAsSrgb = atoi(value);
// 增强截图中的伽马空间调光
property_get("debug.sf.dim_in_gamma_in_enhanced_screenshots", value, "0");
mDimInGammaSpaceForEnhancedScreenshots = atoi(value);
// 控制是否忽略HWC物理显示方向
mIgnoreHwcPhysicalDisplayOrientation =
base::GetBoolProperty("debug.sf.ignore_hwc_physical_display_orientation"s, false);
// We should be reading 'persist.sys.sf.color_saturation' here
// but since /data may be encrypted, we need to wait until after vold
// comes online to attempt to read the property. The property is
// instead read after the boot animation
// Treble测试覆盖
if (base::GetBoolProperty("debug.sf.treble_testing_override"s, false)) {
// Without the override SurfaceFlinger cannot connect to HIDL
// services that are not listed in the manifests. Considered
// deriving the setting from the set service name, but it
// would be brittle if the name that's not 'default' is used
// for production purposes later on.
ALOGI("Enabling Treble testing override");
android::hardware::details::setTrebleTestingOverride(true);
}
// TODO (b/270966065) Update the HWC based refresh rate overlay to support spinner
// 刷新率覆盖属性
mRefreshRateOverlaySpinner = property_get_bool("debug.sf.show_refresh_rate_overlay_spinner", 0);
mRefreshRateOverlayRenderRate =
property_get_bool("debug.sf.show_refresh_rate_overlay_render_rate", 0);
mRefreshRateOverlayShowInMiddle =
property_get_bool("debug.sf.show_refresh_rate_overlay_in_middle", 0);
// 事务跟踪(仅非用户版本)
if (!mIsUserBuild && base::GetBoolProperty("debug.sf.enable_transaction_tracing"s, true)) {
mTransactionTracing.emplace();
mLayerTracing.setTransactionTracing(*mTransactionTracing);
}
// HDR相机图层处理
mIgnoreHdrCameraLayers = ignore_hdr_camera_layers(false);
// HDCP 通过负 VSync 的解决方案
// These are set by the HWC implementation to indicate that they will use the workarounds.
mIsHdcpViaNegVsync = base::GetBoolProperty("debug.sf.hwc_hdcp_via_neg_vsync"s, false);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
双参数构造函数先于单参构造函数执行,主要是初始化一些核心组件和状态,为后续的运行做准备。
/*
- 接受一个 Factory 引用和 SkipInitializationTag 标签参数
- SkipInitializationTag 是一个标记类型,用于区分不同的构造函数重载
*/
SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
: mFactory(factory),
mPid(getpid()),
mTimeStats(std::make_shared<impl::TimeStats>()), // 统计时间信息
mFrameTracer(mFactory.createFrameTracer()), // 用 Perfetto 追踪框架记录详细的帧渲染时间线
mFrameTimeline(mFactory.createFrameTimeline(mTimeStats, mPid)), // 用于 Perfetto 跟踪和管理显示帧的时间线信息
mCompositionEngine(mFactory.createCompositionEngine()), // 关注点
// HWC HAL 进程名字各家都不一样
mHwcServiceName(base::GetProperty("debug.sf.hwc_service_name"s, "default"s)),
mTunnelModeEnabledReporter(sp<TunnelModeEnabledReporter>::make()), // 视频播放相关,还不太懂 https://blog.csdn.net/Damon_X/article/details/147044147
mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)),
mInternalDisplayDensity(
getDensityFromProperty("ro.sf.lcd_density", !mEmulatedDisplayDensity)),
// 功耗管理和性能优化组件,属于 Android Dynamic Performance Framework (ADPF) 的一部分
mPowerAdvisor(std::make_unique<
adpf::impl::PowerAdvisor>([this] { disableExpensiveRendering(); },
std::chrono::milliseconds(
sysprop::display_update_imminent_timeout_ms(
80)))),
mWindowInfosListenerInvoker(sp<WindowInfosListenerInvoker>::make()), // ?
mSkipPowerOnForQuiescent(base::GetBoolProperty("ro.boot.quiescent"s, false)) {
ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str());
#ifdef MTK_SF_CPU_POLICY
if (SfCpuPolicyAdapter::isEnabled())
mSfCpuPolicy = &SfCpuPolicyAdapter::getInstance(*mFrameTimeline);
#endif
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
核心组件初始化 :
- mFactory(factory) :保存工厂引用,用于创建各种组件
- mPid(getpid()) :获取当前进程ID
- mTimeStats :创建时间统计组件
- mFrameTracer :通过工厂创建帧追踪器
- mFrameTimeline :创建帧时间线管理器
- mCompositionEngine :创建合成引擎
系统属性读取 :
- mHwcServiceName :从系统属性 "debug.sf.hwc_service_name"s 读取HWC服务名称,默认为 "default"s
- mSkipPowerOnForQuiescent :从 "ro.boot.quiescent"s 属性读取是否跳过电源开启
显示密度配置 :
- mEmulatedDisplayDensity :从 "qemu.sf.lcd_density" 获取模拟显示密度
- mInternalDisplayDensity :从 "ro.sf.lcd_density" 获取内部显示密度
其他组件 :
- mTunnelModeEnabledReporter :隧道模式报告器,视频播放相关,还不太懂 https://blog.csdn.net/Damon_X/article/details/147044147
- mPowerAdvisor :电源顾问,用于性能优化
- mWindowInfosListenerInvoker :窗口信息监听器调用器
目前,我们主要关注最核心的 mCompositionEngine 成员,这里通过 mFactory.createCompositionEngine()
函数创建 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::CompositionEngine() = default;
2
3
4
5
6
7
8
9
10
就是简单调用默认构造函数。
CompositionEngine 的定义如下:
// /frameworks/native/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h
class CompositionEngine : public compositionengine::CompositionEngine {
public:
// ......
private:
//两个核心成员
std::unique_ptr<HWComposer> mHwComposer;
renderengine::RenderEngine* mRenderEngine;
std::shared_ptr<TimeStats> mTimeStats;
bool mNeedsAnotherUpdate = false;
nsecs_t mRefreshStartTime = 0;
};
2
3
4
5
6
7
8
9
10
11
12
13
14
CompositionEngine 持有了 HWComposer 和 RenderEngine 两个核心成员,这两个核心成员均在后续的 SurfaceFlinger::init
函数中初始化。
HWComposer(硬件合成器,Device 合成) 是Android图形系统中的核心组件,主要负责:
- 硬件加速合成 :利用显示硬件(如GPU或专用显示处理器)来合成多个图层
- 显示输出管理 :管理与物理显示设备的交互,包括显示模式设置、刷新率控制等
- 图层优化 :决定哪些图层可以通过硬件直接合成,哪些需要通过软件渲染
- 电源效率 :通过硬件合成减少CPU和GPU的负载,提高电源效率
- 显示同步 :与显示硬件的垂直同步(VSync)信号协调,确保流畅的显示效果
RenderEngine(渲染引擎,Client 合成) 是软件渲染的核心组件,主要负责:
- 软件渲染 :当硬件合成器无法处理某些复杂效果时,使用 GPU 进行软件渲染
- 特效处理 :处理复杂的视觉效果,如模糊、阴影、变换等
- 纹理管理 :管理图形纹理的创建、更新和销毁
- 着色器执行 :执行自定义的图形着色器程序
- 离屏渲染 :将某些图层渲染到离屏缓冲区,然后再合成到最终画面
这两个组件在 CompositionEngine 中协同工作:
- 混合渲染策略 :CompositionEngine 根据图层的复杂度和硬件能力,决定使用 HWComposer 进行硬件合成还是使用 RenderEngine 进行软件渲染
- 性能优化 :优先使用 HWComposer 以获得更好的性能和电源效率,在需要复杂效果时回退到RenderEngine
- 显示管道 :两者共同构成了 Android SurfaceFlinger 的显示合成管道,确保所有应用界面能够正确、高效地显示在屏幕上
# 3. SurfaceFlinger init 过程分析
flinger->init();
这里调用 init 函数初始化 SurfaceFlinger,具体实现如下:
void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) {
SFTRACE_CALL();
ALOGI( "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W...");
// ?
addTransactionReadyFilters();
Mutex::Autolock lock(mStateLock);
// 关注点1,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.
auto builder = renderengine::RenderEngineCreationArgs::Builder()
// 默认值 RGBA_8888
.setPixelFormat(static_cast<int32_t>(defaultCompositionPixelFormat))
// 默认值 2
.setImageCacheSize(maxFrameBufferAcquiredBuffers)
.setEnableProtectedContext(enable_protected_contents(false))
.setPrecacheToneMapperShaderOnly(false)
.setBlurAlgorithm(chooseBlurAlgorithm(mSupportsBlur))
.setContextPriority(
useContextPriority
? renderengine::RenderEngine::ContextPriority::REALTIME
: renderengine::RenderEngine::ContextPriority::MEDIUM);
chooseRenderEngineType(builder);
mRenderEngine = renderengine::RenderEngine::create(builder.build());
mCompositionEngine->setRenderEngine(mRenderEngine.get());
mMaxRenderTargetSize =
std::min(getRenderEngine().getMaxTextureSize(), getRenderEngine().getMaxViewportDims());
// Set SF main policy after initializing RenderEngine which has its own policy.
if (!SetTaskProfiles(0, {"SFMainPolicy"})) {
ALOGW("Failed to set main task profile");
}
mCompositionEngine->setTimeStats(mTimeStats);
// 关注点2, HWComposer 初始化
mCompositionEngine->setHwComposer(getFactory().createHWComposer(mHwcServiceName));
auto& composer = mCompositionEngine->getHwComposer();
composer.setCallback(*this);
// mDisplayModeController 成员的初始化与配置
mDisplayModeController.setHwComposer(&composer);
// ClientCache 配置
ClientCache::getInstance().setRenderEngine(&getRenderEngine());
mHasReliablePresentFences =
!getHwComposer().hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE);
// 用于控制 SurfaceFlinger 是否允许锁定(latch)未信号的缓冲区
enableLatchUnsignaledConfig = getLatchUnsignaledConfig();
if (base::GetBoolProperty("debug.sf.enable_hwc_vds"s, false)) {
enableHalVirtualDisplays(true);
}
// Process hotplug for displays connected at boot.
LOG_ALWAYS_FATAL_IF(!configureLocked(),
"Initial display configuration failed: HWC did not hotplug");
mActiveDisplayId = getPrimaryDisplayIdLocked();
// 关注点3 显示设备配置
// Commit primary display.
sp<const DisplayDevice> display;
if (const auto indexOpt = mCurrentState.getDisplayIndex(mActiveDisplayId)) {
const auto& displays = mCurrentState.displays;
const auto& token = displays.keyAt(*indexOpt);
const auto& state = displays.valueAt(*indexOpt);
// 关注点 DisplayDevice 初始化
processDisplayAdded(token, state);
mDrawingState.displays.add(token, state);
display = getDefaultDisplayDeviceLocked();
}
LOG_ALWAYS_FATAL_IF(!display, "Failed to configure the primary display");
LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(display->getPhysicalId()),
"Primary display is disconnected");
// TODO(b/241285876): The Scheduler needlessly depends on creating the CompositionEngine part of
// the DisplayDevice, hence the above commit of the primary display. Remove that special case by
// initializing the Scheduler after configureLocked, once decoupled from DisplayDevice.
// 关注点4, Scheduler 初始化
initScheduler(display);
// Start listening after creating the Scheduler, since the listener calls into it.
mDisplayModeController.setActiveModeListener(
display::DisplayModeController::ActiveModeListener::make(
[this](PhysicalDisplayId displayId, Fps vsyncRate, Fps renderRate) {
// This callback cannot lock mStateLock, as some callers already lock it.
// Instead, switch context to the main thread.
static_cast<void>(mScheduler->schedule([=,
this]() FTL_FAKE_GUARD(mStateLock) {
if (const auto display = getDisplayDeviceLocked(displayId)) {
display->updateRefreshRateOverlayRate(vsyncRate, renderRate);
}
}));
}));
mLayerTracing.setTakeLayersSnapshotProtoFunction(
[&](uint32_t traceFlags,
const LayerTracing::OnLayersSnapshotCallback& onLayersSnapshot) {
// Do not wait the future to avoid deadlocks
// between main and Perfetto threads (b/313130597)
static_cast<void>(mScheduler->schedule(
[&, traceFlags, onLayersSnapshot]() FTL_FAKE_GUARD(mStateLock)
FTL_FAKE_GUARD(kMainThreadContext) {
auto snapshot =
takeLayersSnapshotProto(traceFlags, TimePoint::now(),
mLastCommittedVsyncId, true);
onLayersSnapshot(std::move(snapshot));
}));
});
// Commit secondary display(s).
// 处理显示设备状态变化
processDisplayChangesLocked();
// initialize our drawing state
mDrawingState = mCurrentState;
// ?
onActiveDisplayChangedLocked(nullptr, *display);
// 关注一下下
static_cast<void>(mScheduler->schedule(
[this]() FTL_FAKE_GUARD(kMainThreadContext) { initializeDisplays(); }));
// 电源管理
mPowerAdvisor->init();
// 关注点,着色器缓存预热
if (base::GetBoolProperty("service.sf.prime_shader_cache"s, true)) {
if (setSchedFifo(false) != NO_ERROR) {
ALOGW("Can't set SCHED_OTHER for primeCache");
}
mRenderEnginePrimeCacheFuture.callOnce([this] {
renderengine::PrimeCacheConfig config;
config.cacheHolePunchLayer =
base::GetBoolProperty("debug.sf.prime_shader_cache.hole_punch"s, true);
config.cacheSolidLayers =
base::GetBoolProperty("debug.sf.prime_shader_cache.solid_layers"s, true);
config.cacheSolidDimmedLayers =
base::GetBoolProperty("debug.sf.prime_shader_cache.solid_dimmed_layers"s, true);
config.cacheImageLayers =
base::GetBoolProperty("debug.sf.prime_shader_cache.image_layers"s, true);
config.cacheImageDimmedLayers =
base::GetBoolProperty("debug.sf.prime_shader_cache.image_dimmed_layers"s, true);
config.cacheClippedLayers =
base::GetBoolProperty("debug.sf.prime_shader_cache.clipped_layers"s, true);
config.cacheShadowLayers =
base::GetBoolProperty("debug.sf.prime_shader_cache.shadow_layers"s, true);
config.cachePIPImageLayers =
base::GetBoolProperty("debug.sf.prime_shader_cache.pip_image_layers"s, true);
config.cacheTransparentImageDimmedLayers = base::
GetBoolProperty("debug.sf.prime_shader_cache.transparent_image_dimmed_layers"s,
true);
config.cacheClippedDimmedImageLayers = base::
GetBoolProperty("debug.sf.prime_shader_cache.clipped_dimmed_image_layers"s,
true);
// ro.surface_flinger.prime_chader_cache.ultrahdr exists as a previous ro property
// which we maintain for backwards compatibility.
config.cacheUltraHDR =
base::GetBoolProperty("ro.surface_flinger.prime_shader_cache.ultrahdr"s, false);
config.cacheEdgeExtension =
base::GetBoolProperty("debug.sf.prime_shader_cache.edge_extension_shader"s,
true);
return getRenderEngine().primeCache(config);
});
if (setSchedFifo(true) != NO_ERROR) {
ALOGW("Can't set SCHED_FIFO after primeCache");
}
}
// Avoid blocking the main thread on `init` to set properties.
// ?
mInitBootPropsFuture.callOnce([this] {
return std::async(std::launch::async, &SurfaceFlinger::initBootProperties, this);
});
// ?
initTransactionTraceWriter();
ALOGV("Done initializing");
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
SurfaceFlinger::init() 主要执行了以下初始化任务:
- RenderEngine 初始化
- 创建渲染引擎配置参数,包括像素格式、图像缓存大小、保护内容支持等
- 设置模糊算法和上下文优先级
- 创建RenderEngine实例并设置到CompositionEngine中
- 获取最大渲染目标尺寸限制
- HWComposer 初始化
- 创建硬件合成器实例
- 设置HWComposer到CompositionEngine中
- 配置回调函数和显示模式控制器
- 检查Present Fence的可靠性
- 显示设备配置
- 处理启动时连接的显示设备热插拔
- 配置主显示设备
- 设置活动显示ID
- 处理显示设备添加和状态更新
- 提交主显示和次要显示的配置
- 调度器 Scheduler 初始化
- 基于主显示设备初始化调度器
- 设置活动模式监听器,用于更新刷新率覆盖
- 配置VSync和渲染率回调
- 图层追踪设置
- 配置图层快照获取函数
- 设置Perfetto追踪回调,避免主线程和Perfetto线程间的死锁
- 着色器缓存预热
- 根据系统属性决定是否启用着色器缓存预热
- 配置各种图层类型的缓存选项(实心图层、图像图层、阴影图层等)
- 异步执行缓存预热以避免阻塞主线程
- 电源管理
- 初始化PowerAdvisor
- 设置调度优先级
本文主要分析 RenderEngine 和 HWComposer 初始化,剩下的在后续章节分析。
# 3.1 RenderEngine 初始化
- 首先通过 RenderEngineCreationArgs::Builder 构建初始化参数:
// frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
auto builder = renderengine::RenderEngineCreationArgs::Builder()
.setPixelFormat(static_cast<int32_t>(defaultCompositionPixelFormat))
.setImageCacheSize(maxFrameBufferAcquiredBuffers)
.setEnableProtectedContext(enable_protected_contents(false))
.setPrecacheToneMapperShaderOnly(false)
.setBlurAlgorithm(chooseBlurAlgorithm(mSupportsBlur))
.setContextPriority(useContextPriority ?
renderengine::RenderEngine::ContextPriority::REALTIME :
renderengine::RenderEngine::ContextPriority::MEDIUM);
2
3
4
5
6
7
8
9
10
setPixelFormat(static_cast<int32_t>(defaultCompositionPixelFormat))
- 作用 :设置渲染引擎使用的像素格式
- 默认值 :1 (对应 RGBA_8888)
- 说明 :决定了渲染缓冲区的颜色格式,影响颜色精度和内存使用
- setImageCacheSize(maxFrameBufferAcquiredBuffers)
- 作用 :设置 Buffer 的个数,对应 Builder 的 imageCacheSize 成员
- 默认值 :2
- 说明 :控制 RenderEngine Buffer 数量
- setEnableProtectedContext(enable_protected_contents(false))
- 作用 :启用受保护内容上下文
- 默认值 :false
- 说明 :用于支持 DRM 保护内容的渲染,如受版权保护的视频内容
- setPrecacheToneMapperShaderOnly(false)
- 作用 :是否仅预缓存色调映射着色器
- 默认值 :false
- 说明 :控制是否只预编译色调映射相关的着色器,用于优化启动性能
- setBlurAlgorithm(chooseBlurAlgorithm(mSupportsBlur))
- 作用 :设置模糊算法类型
- 可选值 :
- NONE :无模糊
- GAUSSIAN :高斯模糊
- KAWASE :Kawase 模糊(默认)
- KAWASE_DUAL_FILTER :Kawase 双重过滤模糊
- 说明 :
chooseBlurAlgorithm
函数会根据设备是否支持模糊和系统属性选择合适的算法
- setContextPriority(...)
- 作用 :设置渲染上下文优先级
- 可选值 :
- LOW :低优先级
- MEDIUM :中等优先级
- HIGH :高优先级
- REALTIME :实时优先级(默认)
- 说明 :根据 useContextPriority 变量(默认是true)决定使用 REALTIME 还是 MEDIUM 优先级,影响 GPU 调度
- 其他默认参数(未在此代码段中设置):
- threaded :默认为 YES ,启用线程化渲染
- graphicsApi :默认为 GL ,使用 OpenGL ES
- skiaBackend :默认为 GANESH ,使用 Ganesh 后端
- 渲染引擎类型选择阶段
通过 chooseRenderEngineType
函数确定使用的渲染后端:
void chooseRenderEngineType(renderengine::RenderEngineCreationArgs::Builder& builder) {
char prop[PROPERTY_VALUE_MAX];
// debug.renderengine.backend
// pixel 上为空
property_get(PROPERTY_DEBUG_RENDERENGINE_BACKEND, prop, "");
// TODO: b/293371537 - Once GraphiteVk is deemed relatively stable, log a warning that
// PROPERTY_DEBUG_RENDERENGINE_BACKEND is deprecated
if (strcmp(prop, "skiagl") == 0) {
builder.setThreaded(renderengine::RenderEngine::Threaded::NO)
.setGraphicsApi(renderengine::RenderEngine::GraphicsApi::GL);
} else if (strcmp(prop, "skiaglthreaded") == 0) {
builder.setThreaded(renderengine::RenderEngine::Threaded::YES)
.setGraphicsApi(renderengine::RenderEngine::GraphicsApi::GL);
} else if (strcmp(prop, "skiavk") == 0) {
builder.setThreaded(renderengine::RenderEngine::Threaded::NO)
.setGraphicsApi(renderengine::RenderEngine::GraphicsApi::VK);
} else if (strcmp(prop, "skiavkthreaded") == 0) {
builder.setThreaded(renderengine::RenderEngine::Threaded::YES)
.setGraphicsApi(renderengine::RenderEngine::GraphicsApi::VK);
} else { // 默认 prop 为空,走这个分支
const auto kVulkan = renderengine::RenderEngine::GraphicsApi::VK;
// TODO: b/341728634 - Clean up conditional compilation.
// Note: this guard in particular must check e.g.
// COM_ANDROID_GRAPHICS_SURFACEFLINGER_FLAGS_GRAPHITE_RENDERENGINE directly (instead of calling e.g.
// COM_ANDROID_GRAPHICS_SURFACEFLINGER_FLAGS(GRAPHITE_RENDERENGINE)) because that macro is undefined
// in the libsurfaceflingerflags_test variant of com_android_graphics_surfaceflinger_flags.h, which
// is used by layertracegenerator (which also needs SurfaceFlinger.cpp). :)
#if COM_ANDROID_GRAPHICS_SURFACEFLINGER_FLAGS_GRAPHITE_RENDERENGINE || \
COM_ANDROID_GRAPHICS_SURFACEFLINGER_FLAGS_FORCE_COMPILE_GRAPHITE_RENDERENGINE
const bool useGraphite = shouldUseGraphiteIfCompiledAndSupported() &&
renderengine::RenderEngine::canSupport(kVulkan);
#else
const bool useGraphite = false;
if (shouldUseGraphiteIfCompiledAndSupported()) {
ALOGE("RenderEngine's Graphite Skia backend was requested, but it is not compiled in "
"this build! Falling back to Ganesh backend selection logic.");
}
#endif
const bool useVulkan = useGraphite ||
(FlagManager::getInstance().vulkan_renderengine() &&
renderengine::RenderEngine::canSupport(kVulkan));
// 大部分手机都是 OpenGL ES + Ganesh 类型
builder.setSkiaBackend(useGraphite ? renderengine::RenderEngine::SkiaBackend::GRAPHITE
: renderengine::RenderEngine::SkiaBackend::GANESH);
builder.setGraphicsApi(useVulkan ? kVulkan : renderengine::RenderEngine::GraphicsApi::GL);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
根据手机中配置的系统属性来确定 RenderEngine 类型。RenderEngine 类型主要包含了以下三个维度:
- 图形 API 类型 (GraphicsApi)
- GL : 基于 OpenGL ES 的渲染
- VK : 基于 Vulkan 的渲染
- Skia 后端类型 (SkiaBackend)
- GANESH : Skia 的传统 GPU 后端,基于 OpenGL/Vulkan
- GRAPHITE : Skia 的新一代 GPU 后端,专为现代 GPU API 设计
- 线程模式 (Threaded)
- NO : 非线程化渲染
- YES : 线程化渲染 (默认)
可以通过 adb shell dumpsys SurfaceFlinger | grep -A 10 "RE "
命令查看 RenderEngine 类型:
- ------------RE GLES (Ganesh)------------: (OpenGL ES + Ganesh)
- ------------RE Vulkan (Ganesh)----------: (Vulkan + Ganesh)
- ------------RE Vulkan (Graphite)----------: (Vulkan + Graphite)
目前主流仍然是 OpenGL ES + Ganesh 类型(稳如老狗)。
builder 中的 RenderEngine::Threaded threaded
线程化参数,默认是 YES:
// frameworks/native/libs/renderengine/include/renderengine/RenderEngine.h
struct RenderEngineCreationArgs::Builder {
private:
// 1 means RGBA_8888
int pixelFormat = 1;
uint32_t imageCacheSize = 0;
bool enableProtectedContext = false;
bool precacheToneMapperShaderOnly = false;
RenderEngine::BlurAlgorithm blurAlgorithm = RenderEngine::BlurAlgorithm::NONE;
RenderEngine::ContextPriority contextPriority = RenderEngine::ContextPriority::MEDIUM;
// 线程化,默认是 YES
RenderEngine::Threaded threaded = RenderEngine::Threaded::YES;
RenderEngine::GraphicsApi graphicsApi = RenderEngine::GraphicsApi::GL;
RenderEngine::SkiaBackend skiaBackend = RenderEngine::SkiaBackend::GANESH;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
所以大部分情况下是 OpenGL ES + Ganesh + Threaded
类型,
- RenderEngine 实例创建阶段
在 create
方法中执行具体的创建逻辑:
mRenderEngine = renderengine::RenderEngine::create(builder.build());
create 过程会涉及到 opengles 相关的内容,这个会在下一章来详细介绍,这里知道创建一个 RenderEngine 实例即可
# 3.2 HWComposer 初始化
HWComposer 初始化过程:
// HWC Client 初始化
mCompositionEngine->setHwComposer(getFactory().createHWComposer(mHwcServiceName));
auto& composer = mCompositionEngine->getHwComposer();
composer.setCallback(*this);
2
3
4
# 3.2.1 HWComposer 初始化过程
getFactory().createHWComposer(mHwcServiceName)
构建一个 HWComposer 对象,
// frameworks/native/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
// serviceName 通常是空字符串
std::unique_ptr<HWComposer> DefaultFactory::createHWComposer(const std::string& serviceName) {
return std::make_unique<android::impl::HWComposer>(serviceName);
}
2
3
4
5
new 一个 android::impl::HWComposer 对象:
// frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp
HWComposer::HWComposer(const std::string& composerServiceName)
: HWComposer(Hwc2::Composer::create(composerServiceName)) {}
HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer)
: mComposer(std::move(composer)),
mMaxVirtualDisplayDimension(static_cast<size_t>(sysprop::max_virtual_display_dimension(0))),
mUpdateDeviceProductInfoOnHotplugReconnect(
sysprop::update_device_product_info_on_hotplug_reconnect(false)),
mEnableVrrTimeout(base::GetBoolProperty("debug.sf.vrr_timeout_hint_enabled"s, true)) {}
2
3
4
5
6
7
8
9
10
HWComposer 类的构造函数初始化了以下关键成员变量:
1.mComposer - 硬件合成器接口
- 通过依赖注入接收
std::unique_ptr<Hwc2::Composer>
实例 - 作为与底层 HAL 层交互的核心接口
2.mMaxVirtualDisplayDimension - 最大虚拟显示尺寸
- 通过系统属性
sysprop::max_virtual_display_dimension()
初始化 - 控制虚拟显示器的最大分辨率限制
3.mUpdateDeviceProductInfoOnHotplugReconnect - 热插拔重连更新标志
- 通过系统属性
sysprop::update_device_product_info_on_hotplug_reconnect()
初始化 - 决定在显示设备热插拔重连时是否更新设备产品信息
4.mEnableVrrTimeout - VRR 超时提示启用标志
- 通过系统属性 android::base::GetBoolProperty("debug.sf.vrr_timeout_hint_enabled", false) 初始化
- 控制是否启用可变刷新率(VRR)的超时提示功能
其中 mComposer 通过 Composer::create 函数构建和初始化:
// frameworks/native/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
std::unique_ptr<Composer> Composer::create(const std::string& serviceName) {
if (AidlComposer::namesAnAidlComposerService(serviceName)) {
return std::make_unique<AidlComposer>(serviceName); // 一般是这个
}
return std::make_unique<HidlComposer>(serviceName);
}
2
3
4
5
6
7
8
new 一个 AidlComposer 对象,AidlComposer 继承自 Hwc2::Composer,是 SF 中与 HWC HAL 通信的辅助类,用于简化 SF 中与 HWC HAL 通信的代码。
// frameworks/native/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
class AidlComposer final : public Hwc2::Composer {
// .......
ui::PhysicalDisplayMap<Display, ComposerClientWriter> mWriters GUARDED_BY(mMutex);
ui::PhysicalDisplayMap<Display, ComposerClientReader> mReaders GUARDED_BY(mMutex);
// Aidl interface
using AidlIComposer = aidl::android::hardware::graphics::composer3::IComposer;
using AidlIComposerClient = aidl::android::hardware::graphics::composer3::IComposerClient;
std::shared_ptr<AidlIComposer> mAidlComposer; // Composer HAL 系统服务客户端
std::shared_ptr<AidlIComposerClient> mAidlComposerClient; // Composer HAL 提供的匿名 Binder 服务对应的客户端,远程调用 Composer HAL 功能的主要接口
std::shared_ptr<AidlIComposerCallbackWrapper> mAidlComposerCallback; // SF 这边的 Binder 远程 Callback 回调,是 SF 中的一个匿名 Binder 服务
// .......
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
重要的几个成员:
- mWriters: 负责收集和缓存要发送给硬件合成器的命令
- mReaders: 负责解析硬件合成器返回的执行结果
- mAidlComposer: Composer HAL 系统服务客户端
- mAidlComposerClient: Composer HAL 提供的匿名 Binder 服务对应的客户端,远程调用 Composer HAL 功能的主要接口
- mAidlComposerCallback: SF 这边的 Binder 远程 Callback 回调,是 SF 中的一个匿名 Binder 服务
// frameworks/native/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
AidlComposer::AidlComposer(const std::string& serviceName) {
// This only waits if the service is actually declared
// 关注点1
mAidlComposer = AidlIComposer::fromBinder(ndk::SpAIBinder( // 获取 Composer HAL 系统服务客户端
AServiceManager_waitForService(ensureFullyQualifiedName(serviceName).c_str())));
if (!mAidlComposer) {
LOG_ALWAYS_FATAL("Failed to get AIDL composer service");
return;
}
// 关注点2
if (!mAidlComposer->createClient(&mAidlComposerClient).isOk()) { // 获取 Composer HAL client 匿名 Binder系统服务客户端
LOG_ALWAYS_FATAL("Can't create AidlComposerClient");
return;
}
// 关注点 3
// 给 mReaders 添加一个成员
addReader(translate<Display>(kSingleReaderKey));
// If unable to read interface version, then become backwards compatible.
const auto status = mAidlComposerClient->getInterfaceVersion(&mComposerInterfaceVersion);
if (!status.isOk()) {
ALOGE("getInterfaceVersion for AidlComposer constructor failed %s",
status.getDescription().c_str());
}
if (mComposerInterfaceVersion <= 1) {
if (sysprop::clear_slots_with_set_layer_buffer(false)) {
mClearSlotBuffer = sp<GraphicBuffer>::make(1, 1, PIXEL_FORMAT_RGBX_8888,
GraphicBuffer::USAGE_HW_COMPOSER |
GraphicBuffer::USAGE_SW_READ_OFTEN |
GraphicBuffer::USAGE_SW_WRITE_OFTEN,
"AidlComposer");
if (!mClearSlotBuffer || mClearSlotBuffer->initCheck() != ::android::OK) {
LOG_ALWAYS_FATAL("Failed to allocate a buffer for clearing layer buffer slots");
return;
}
}
}
if (getLayerLifecycleBatchCommand()) {
mEnableLayerCommandBatchingFlag =
FlagManager::getInstance().enable_layer_command_batching();
}
ALOGI("Loaded AIDL composer3 HAL service");
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
- 服务获取: mAidlComposer 作为服务入口,负责连接到 AIDL Composer HAL 服务
- 客户端创建: 通过 mAidlComposer 创建 mAidlComposerClient,建立实际的操作通道
- 回调注册: mAidlComposerCallback,在后续 SurfaceFlinger::init 中调用 registerCallback 函数,该函数会调用 AidlComposer::registerCallback 将 mAidlComposerCallback 注册到 Composer HAL 服务中,实现 HAL 到 SurfaceFlinger 的异步通信。
构造函数中 addReader 过程:
// frameworks/native/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
bool mSingleReader = true;
static constexpr int64_t kSingleReaderKey = 0;
ui::PhysicalDisplayMap<Display, ComposerClientReader> mReaders GUARDED_BY(mMutex);
// frameworks/native/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
addReader(translate<Display>(kSingleReaderKey));
2
3
4
5
6
7
这里的 Display 类型来自 ComposerHal.h
:
namespace V2_1 = hardware::graphics::composer::V2_1;
using V2_1::Display;
2
该类型来自 hal 文件 types.hal
,定义为 uint64_t
,用于表示显示设备的 ID。
// /hardware/interfaces/graphics/composer/2.1/types.hal
typedef uint64_t Display;
2
3
translate 函数实现如下:
// frameworks/native/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
template <typename To, typename From>
To translate(From from) {
return static_cast<To>(from);
}
2
3
4
5
- kSingleReaderKey 是 static constexpr int64_t 类型,值为 0
- Display 是 int64_t 的类型别名(在
AidlComposerHal.h
中定义) translate<Display>(kSingleReaderKey)
将 int64_t 类型的 kSingleReaderKey 转换为 Display 类型
- Display 是 int64_t 的类型别名(在
- 实际效果 :
- 由于 Display 本身就是 int64_t 的别名,这个转换在运行时是无操作的
- 但在编译时提供了类型安全性,确保传递给 addReader 的参数是正确的 Display 类型
void AidlComposer::addReader(Display display) {
const auto displayId = translate<int64_t>(display);
std::optional<int64_t> displayOpt;
if (displayId != kSingleReaderKey) {
displayOpt.emplace(displayId);
}
auto [it, added] = mReaders.try_emplace(display, std::move(displayOpt));
ALOGW_IF(!added, "Attempting to add writer for display %" PRId64 " which is already connected",
displayId);
}
2
3
4
5
6
7
8
9
10
先看下 ComposerClientReader 的构造函数:
// /hardware\interfaces\graphics\composer\aidl\include\android\hardware\graphics\composer3\ComposerClientReader.h
explicit ComposerClientReader(std::optional<int64_t> display = {}) : mDisplay(display) {}
2
这里使用了单例 Reader 机制:
- 默认模式 : mSingleReader = true
- 所有显示器共享一个 ComposerClientReader 实例
- 使用 kSingleReaderKey (值为0)作为这个共享 Reader 的键值
- 这是一个无效的显示器ID,专门用作单例模式的标识
- 多线程模式 :当检测到硬件支持 MULTI_THREADED_PRESENT 能力时 (AidlComposer::addDisplay 中执行该逻辑)
- mSingleReader 变为 false
- 移除单例 Reader
- 为每个显示器创建独立的 Reader
到目前为止,相关的类关系如下:
# 3.2.2 HWComposer 注册回调
SurfaceFlinger::init 中完成 HWComposer 初始化过程以后,通过 setCallback(*this);
将当前 SurfaceFlinger 对象设置为 HWComposer 的回调。
// frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp
void HWComposer::setCallback(HWC2::ComposerCallback& callback) {
// 通过 mComposer 向 HWC HAl 获取一些配置参数
loadCapabilities();
loadLayerMetadataSupport();
loadOverlayProperties();
loadHdrConversionCapabilities();
if (mRegisteredCallback) {
ALOGW("Callback already registered. Ignored extra registration attempt.");
return;
}
mRegisteredCallback = true;
// 关注点:通过 mComposer 向 HWC HAL 注册回调
mComposer->registerCallback(callback);
}
// frameworks/native/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
void AidlComposer::registerCallback(HWC2::ComposerCallback& callback) {
if (mAidlComposerCallback) {
ALOGE("Callback already registered");
}
// 将 callback 包装成 AidlIComposerCallbackWrapper 匿名 Binder
mAidlComposerCallback = ndk::SharedRefBase::make<AidlIComposerCallbackWrapper>(callback);
ndk::SpAIBinder binder = mAidlComposerCallback->asBinder();
if (!FlagManager::getInstance().disable_sched_fifo_composer_callback()) {
AIBinder_setMinSchedulerPolicy(binder.get(), SCHED_FIFO, 2);
}
// 向 HWC Hal 注册回调
const auto status = mAidlComposerClient->registerCallback(mAidlComposerCallback);
if (!status.isOk()) {
ALOGE("registerCallback failed %s", status.getDescription().c_str());
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
主要关注以下三个回调函数:
// Implement this interface to receive hardware composer events.
//
// These callback functions will generally be called on a hwbinder thread, but
// when first registering the callback the onComposerHalHotplugEvent() function
// will immediately be called on the thread calling registerCallback().
struct ComposerCallback {
// 热插拔,首次注册回调会调用一次
virtual void onComposerHalHotplug(hal::HWDisplayId, hal::Connection) = 0;
// 刷新
virtual void onComposerHalRefresh(hal::HWDisplayId) = 0;
// 硬件 Vysnc 信号
virtual void onComposerHalVsync(hal::HWDisplayId, nsecs_t timestamp,
std::optional<hal::VsyncPeriodNanos>) = 0;
//......
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
注释中说明了首次注册回调时,会立即调用 onComposerHalHotplug
回调函数。这点对于后续分析非常重要
# 4. 总结
- SurfaceFlinger 对象的初始化过程
- SurfaceFlinger::init 部分流程
- RenderEngine 初始化与配置过程
- HWComposer 初始化与配置过程
- 后续容还未分析内