005.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();
// ......
}
- 创建 SurfaceFlinger 对象
- 初始化 SurfaceFlinger
2. 创建 SurfaceFlinger 对象
createSurfaceFlinger 函数的实现如下:
// /frameworks/native/services/surfaceflinger/SurfaceFlingerFactory.cpp
sp<SurfaceFlinger> createSurfaceFlinger() {
static DefaultFactory factory;
return sp<SurfaceFlinger>::make(factory);
}
这里通过工厂模式去 new 了一个 SurfaceFlinger 对象。
SurfaceFlinger 类的定义如下:
//
class SurfaceFlinger : public BnSurfaceComposer,
public PriorityDumper,
private IBinder::DeathRecipient,
private HWC2::ComposerCallback,
private ICompositor,
private scheduler::ISchedulerCallback {
// ......
}
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) {
// .......
}
单参构造函数更简单一点,我们先看单参数构造函数的实现,主要是读取各种系统属性值到全局变量中,后续再使用这些值对 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);
}
双参数构造函数先于单参构造函数执行,主要是初始化一些核心组件和状态,为后续的运行做准备。
/*
- 接受一个 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
}
核心组件初始化 :
- 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;
就是简单调用默认构造函数。
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;
};
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");
}
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);
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);
}
}
根据手机中配置的系统属性来确定 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;
}
所以大部分情况下是 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);
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);
}
new 一个 android
// 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)) {}
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
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);
}
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 服务
// .......
}
重要的几个成员:
- 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");
}
- 服务获取: mAidlComposer 作为服务入口,负责连接到 AIDL Composer HAL 服务
- 客户端创建: 通过 mAidlComposer 创建 mAidlComposerClient,建立实际的操作通道
- 回调注册: mAidlComposerCallback,在后续 SurfaceFlinger
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));
这里的 Display 类型来自 ComposerHal.h
:
namespace V2_1 = hardware::graphics::composer::V2_1;
using V2_1::Display;
该类型来自 hal 文件 types.hal
,定义为 uint64_t
,用于表示显示设备的 ID。
// /hardware/interfaces/graphics/composer/2.1/types.hal
typedef uint64_t Display;
translate 函数实现如下:
// frameworks/native/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
template <typename To, typename From>
To translate(From from) {
return static_cast<To>(from);
}
- 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);
}
先看下 ComposerClientReader 的构造函数:
// /hardware\interfaces\graphics\composer\aidl\include\android\hardware\graphics\composer3\ComposerClientReader.h
explicit ComposerClientReader(std::optional<int64_t> display = {}) : mDisplay(display) {}
这里使用了单例 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());
}
}
主要关注以下三个回调函数:
// 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;
//......
}
注释中说明了首次注册回调时,会立即调用 onComposerHalHotplug
回调函数。这点对于后续分析非常重要
4. 总结
- SurfaceFlinger 对象的初始化过程
- SurfaceFlinger::init 部分流程
- RenderEngine 初始化与配置过程
- HWComposer 初始化与配置过程
- 后续容还未分析内