Ahao's Technical Blog Ahao's Technical Blog
首页
  • 001.基础篇
  • 002.玩转AOSP篇
  • 003.学穿Binder篇
  • 004.基础组件篇
  • 005.系统启动过程分析
  • 006.Hal开发入门与实践
  • 007.显示系统
  • 008.核心系统服务
  • 009.输入系统
  • 010.开发工具
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

阿豪讲Framework

不积跬步无以至千里
首页
  • 001.基础篇
  • 002.玩转AOSP篇
  • 003.学穿Binder篇
  • 004.基础组件篇
  • 005.系统启动过程分析
  • 006.Hal开发入门与实践
  • 007.显示系统
  • 008.核心系统服务
  • 009.输入系统
  • 010.开发工具
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 基础篇

  • 玩转AOSP篇

  • 学穿Binder篇

  • 基础组件篇

  • 系统启动过程分析

  • Hal开发入门与实践

  • 显示系统

    • 如何调试SurfaceFlinger
    • SurfaceFlinger概述
    • HWC 接口分析
      • 1. HWC3 AIDL 接口分析
        • 1.1 IComposer.aidl 接口分析
        • 1.2 IComposerClient.aidl 接口分析
        • 1.3 IComposerCallback.aidl 接口分析
      • 2. HWC3 AIDL 接口的封装
        • 2.1 AidlComposer 类结构分析
        • 2.1.1 成员变量
        • 2.1.2 成员方法
        • 2.1.3 mReaders 与 mWriters 作用分析
    • 启动过程总览
    • SurfaceFlinger 初始化
    • RenderEnginge 初始化
    • 显示设备初始化
    • 显示疑难问题分析基础
  • 核心系统服务

  • 输入系统

  • 开发工具

  • Framework
  • 显示系统
阿豪
2025-10-07
目录

HWC 接口分析

# HWC 接口分析

# 1. HWC3 AIDL 接口分析

HWC HAL 作为一个 HAL 模块,通过 Binder 服务向 SurfaceFlinger 提供了使用接口。这些接口通过 AIDL 文件定义:

  • IComposer.aidl:HWC 直接提供的 Binder 服务
  • IComposerClient.aidl:HWC 通过匿名 Binder 提供的 Binder 服务

SurfaceFlinger 向 HWC 注册了一个 Binder 回调,用于接收 HWC 事件通知,该回调协议通过 AIDL 文件定义:

  • IComposerCallback.aidl:HWC 事件通知回调接口

# 1.1 IComposer.aidl 接口分析

// /hardware/interfaces/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposer.aidl
package android.hardware.graphics.composer3;
@VintfStability
interface IComposer {
  android.hardware.graphics.composer3.IComposerClient createClient();
  android.hardware.graphics.composer3.Capability[] getCapabilities();
  const int EX_NO_RESOURCES = 6;
}
1
2
3
4
5
6
7
8

getCapabilities 用于获取 HWC 支持的能力, 返回的 Capability 是一个枚举类型,枚举值定义在 Capability.aidl 中。

// /hardware/interfaces/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Capability.aidl
enum Capability {
  // 作为默认值或错误状态的标识
  INVALID = 0,
  // 支持侧带流(Sideband Stream)处理能力,允许硬件直接处理视频流,无需通过 SurfaceFlinger
  SIDEBAND_STREAM = 1,
  // 跳过客户端颜色变换处理,HWC 可以直接在硬件层面处理颜色空间转换
  SKIP_CLIENT_COLOR_TRANSFORM = 2,
  // 当硬件无法提供可靠的同步信号时设置此标志
  PRESENT_FENCE_IS_NOT_RELIABLE = 3,
  // - 原本用于跳过 HWC 的验证阶段以提升性能,现在默认启用,不再需要显式设置
  /**
   * @deprecated - enabled by default.
   */
  SKIP_VALIDATE = 4,
  //支持启动时显示配置
  BOOT_DISPLAY_CONFIG = 5,
  // HDR 输出转换配置支持
  HDR_OUTPUT_CONVERSION_CONFIG = 6,
  // 刷新率变化回调调试支持
  REFRESH_RATE_CHANGED_CALLBACK_DEBUG = 7,
  // 图层生命周期批处理命令支持
  LAYER_LIFECYCLE_BATCH_COMMAND = 8,
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

createClient 用于获取 HWC 的匿名 Binder 服务 IComposerClient,该服务是一个匿名 Binder 服务,其能力定义在 IComposerClient.aidl 文件中。

# 1.2 IComposerClient.aidl 接口分析

IComposerClient.aidl 定义了 HWC 进程中匿名 Binder 服务 IComposerClient 向 SurfaceFlinger 提供的主要的功能,其定义如下:

// /hardware/interfaces/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
package android.hardware.graphics.composer3;
@VintfStability
interface IComposerClient {
  long createLayer(long display, int bufferSlotCount);
  android.hardware.graphics.composer3.VirtualDisplay createVirtualDisplay(int width, int height, android.hardware.graphics.common.PixelFormat formatHint, int outputBufferSlotCount);
  void destroyLayer(long display, long layer);
  void destroyVirtualDisplay(long display);
  android.hardware.graphics.composer3.CommandResultPayload[] execut eCommands(in android.hardware.graphics.composer3.DisplayCommand[] commands);
  int getActiveConfig(long display);
  android.hardware.graphics.composer3.ColorMode[] getColorModes(long display);
  float[] getDataspaceSaturationMatrix(android.hardware.graphics.common.Dataspace dataspace);
  /**
   * @deprecated use getDisplayConfigurations instead. Returns a display attribute value for a particular display configuration. For legacy support getDisplayAttribute should return valid values for any requested DisplayAttribute, and for all of the configs obtained either through getDisplayConfigs or getDisplayConfigurations.
   */
  int getDisplayAttribute(long display, int config, android.hardware.graphics.composer3.DisplayAttribute attribute);
  android.hardware.graphics.composer3.DisplayCapability[] getDisplayCapabilities(long display);
  /**
   * @deprecated use getDisplayConfigurations instead. For legacy support getDisplayConfigs should return at least one valid config. All the configs returned from the getDisplayConfigs should also be returned from getDisplayConfigurations.
   */
  int[] getDisplayConfigs(long display);
  android.hardware.graphics.composer3.DisplayConnectionType getDisplayConnectionType(long display);
  android.hardware.graphics.composer3.DisplayIdentification getDisplayIdentificationData(long display);
  String getDisplayName(long display);
  int getDisplayVsyncPeriod(long display);
  android.hardware.graphics.composer3.DisplayContentSample getDisplayedContentSample(long display, long maxFrames, long timestamp);
  android.hardware.graphics.composer3.DisplayContentSamplingAttributes getDisplayedContentSamplingAttributes(long display);
  android.hardware.graphics.common.Transform getDisplayPhysicalOrientation(long display);
  android.hardware.graphics.composer3.HdrCapabilities getHdrCapabilities(long display);
  int getMaxVirtualDisplayCount();
  android.hardware.graphics.composer3.PerFrameMetadataKey[] getPerFrameMetadataKeys(long display);
  android.hardware.graphics.composer3.ReadbackBufferAttributes getReadbackBufferAttributes(long display);
  @nullable ParcelFileDescriptor getReadbackBufferFence(long display);
  android.hardware.graphics.composer3.RenderIntent[] getRenderIntents(long display, android.hardware.graphics.composer3.ColorMode mode);
  android.hardware.graphics.composer3.ContentType[] getSupportedContentTypes(long display);
  @nullable android.hardware.graphics.common.DisplayDecorationSupport getDisplayDecorationSupport(long display);
  void registerCallback(in android.hardware.graphics.composer3.IComposerCallback callback);
  void setActiveConfig(long display, int config);
  android.hardware.graphics.composer3.VsyncPeriodChangeTimeline setActiveConfigWithConstraints(long display, int config, in android.hardware.graphics.composer3.VsyncPeriodChangeConstraints vsyncPeriodChangeConstraints);
  void setBootDisplayConfig(long display, int config);
  void clearBootDisplayConfig(long display);
  int getPreferredBootDisplayConfig(long display);
  void setAutoLowLatencyMode(long display, boolean on);
  void setClientTargetSlotCount(long display, int clientTargetSlotCount);
  void setColorMode(long display, android.hardware.graphics.composer3.ColorMode mode, android.hardware.graphics.composer3.RenderIntent intent);
  void setContentType(long display, android.hardware.graphics.composer3.ContentType type);
  void setDisplayedContentSamplingEnabled(long display, boolean enable, android.hardware.graphics.composer3.FormatColorComponent componentMask, long maxFrames);
  void setPowerMode(long display, android.hardware.graphics.composer3.PowerMode mode);
  void setReadbackBuffer(long display, in android.hardware.common.NativeHandle buffer, in @nullable ParcelFileDescriptor releaseFence);
  void setVsyncEnabled(long display, boolean enabled);
  void setIdleTimerEnabled(long display, int timeoutMs);
  android.hardware.graphics.composer3.OverlayProperties getOverlaySupport();
  android.hardware.graphics.common.HdrConversionCapability[] getHdrConversionCapabilities();
  android.hardware.graphics.common.Hdr setHdrConversionStrategy(in android.hardware.graphics.common.HdrConversionStrategy conversionStrategy);
  void setRefreshRateChangedCallbackDebugEnabled(long display, boolean enabled);
  android.hardware.graphics.composer3.DisplayConfiguration[] getDisplayConfigurations(long display, int maxFrameIntervalNs);
  oneway void notifyExpectedPresent(long display, in android.hardware.graphics.composer3.ClockMonotonicTimestamp expectedPresentTime, int frameIntervalNs);
  int getMaxLayerPictureProfiles(long display);
  oneway void startHdcpNegotiation(long display, in android.hardware.drm.HdcpLevels levels);
  android.hardware.graphics.composer3.Luts[] getLuts(long display, in android.hardware.graphics.composer3.Buffer[] buffers);
  const int EX_BAD_CONFIG = 1;
  const int EX_BAD_DISPLAY = 2;
  const int EX_BAD_LAYER = 3;
  const int EX_BAD_PARAMETER = 4;
  const int EX_RESERVED = 5;
  const int EX_NO_RESOURCES = 6;
  const int EX_NOT_VALIDATED = 7;
  const int EX_UNSUPPORTED = 8;
  const int EX_SEAMLESS_NOT_ALLOWED = 9;
  const int EX_SEAMLESS_NOT_POSSIBLE = 10;
  const int EX_CONFIG_FAILED = 11;
  const int EX_PICTURE_PROFILE_MAX_EXCEEDED = 12;
  const int INVALID_CONFIGURATION = 0x7fffffff;
}
1
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

内部定义的接口可分为以下几类:

  1. 命令执行,绝大部分显示相关操作都是通过 android.hardware.graphics.composer3.CommandResultPayload[] executeCommands(in android.hardware.graphics.composer3.DisplayCommand[] commands); 函数执行
  2. 图层管理函数
    • long createLayer(long display, int bufferSlotCount)
    • void destroyLayer(long display, long layer);
  3. 虚拟显示管理
    • createVirtualDisplay
    • destroyVirtualDisplay
  4. 显示配置管理
  • getActiveConfig / setActiveConfigWithConstraints
  • getDisplayConfigurations
  • setActiveConfigWithConstraints
  1. 颜色和显示质量管理
    • getColorModes / setColorMode
    • getHdrCapabilities
    • getDataspaceSaturationMatrix
  2. 电源管理
    • setPowerMode
  3. 同步和时序控制
    • setVsyncEnabled
    • getDisplayVsyncPeriod
    • notifyExpectedPresent
  4. 回调注册
    • registerCallback
  5. 高级功能
    • getOverlaySupport
    • setAutoLowLatencyMode
    • getHdrConversionCapabilities() / setHdrConversionStrategy
  6. 调试和诊断
* setRefreshRateChangedCallbackDebugEnabled
* getDisplayedContentSample

口还定义了一系列错误码常量:

  • EX_BAD_CONFIG - 配置错误
  • EX_BAD_DISPLAY - 显示设备错误
  • EX_BAD_LAYER - 图层错误
  • EX_NO_RESOURCES - 资源不足
  • EX_UNSUPPORTED - 不支持的操作

IComposerClient 接口是 Android 图形系统的核心组件,它提供了完整的显示设备管理、图层合成、颜色管理、电源控制等功能。通过这个接口,Android系统能够高效地管理各种显示设备,支持多显示器、HDR、高刷新率等现代显示技术,同时保证良好的性能和用户体验。

# 1.3 IComposerCallback.aidl 接口分析

ComposerCallback.aidl 定义了 HWC HAL 层向 SurfaceFlinger 回调的接口。该接口包含 8 个回调方法,用于通知显示设备状态变化、垂直同步事件和其他重要的图形系统事件。

// /hardware/interfaces/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerCallback.aidl
package android.hardware.graphics.composer3;
@VintfStability
interface IComposerCallback {
  /**
   *  已弃用,建议使用 onHotplugEvent 替代
   */
  void onHotplug(long display, boolean connected);

/**
参数说明:
    - display : 显示设备 ID
    - connected : 布尔值,表示设备是连接 (true) 还是断开 (false)
触发场景: 当外部显示设备(如 HDMI 显示器、USB-C 显示器)物理连接或断开时触发
作用:HAL 层检测到硬件连接状态变化时主动调用此回调,通知 SurfaceFlinger 显示设备的热插拔状态变化
*/
  oneway void onRefresh(long display);
/**
参数说明:
    - display : 显示设备 ID
触发场景: 当显示设备支持无缝模式切换(如刷新率变化、分辨率变化)时触发
作用: 当 HWC 检测到某个显示设备(由 display参数标识)能够支持​​无缝切换​​到一种新的显示模式(例如分辨率、刷新率的改变)时,通过此回调函数主动通知上层的 SurfaceFlinger,无需黑屏或闪烁
 */
  oneway void onSeamlessPossible(long display);
/**
参数说明:
- display : 产生垂直同步信号的显示设备 ID
- timestamp : 垂直同步信号的时间戳(纳秒)
- vsyncPeriodNanos : 垂直同步周期(纳秒)
触发场景: 每当显示设备产生垂直同步信号时触发,通常以固定频率(如 60Hz、90Hz、120Hz)
作用: 为 SurfaceFlinger 提供精确的显示时序信息,用于同步渲染和合成操作,确保流畅的动画和视频播放
 */
  oneway void onVsync(long display, long timestamp, int vsyncPeriodNanos);

/**
参数说明:
- display : 显示设备 ID
- updatedTimeline : `VsyncPeriodChangeTimeline.aidl` 结构,包含:
  - newVsyncAppliedTimeNanos : 新垂直同步周期生效的时间
  - refreshRequired : 是否需要刷新
  - refreshTimeNanos : 刷新时间
触发场景: 当显示设备的垂直同步周期发生变化时触发,如动态刷新率切换
 */
  oneway void onVsyncPeriodTimingChanged(long display, in android.hardware.graphics.composer3.VsyncPeriodChangeTimeline updatedTimeline);

/**
参数说明:
- display : 进入空闲状态的显示设备 ID
触发场景: 当显示设备进入空闲状态,不再需要频繁的垂直同步信号时触发,HAL 层检测到显示内容静止或系统进入省电模式时调用
 */
  oneway void onVsyncIdle(long display);

/**
参数说明:
- data : `RefreshRateChangedDebugData.aidl` 结构,包含:
  - display : 显示设备 ID
  - vsyncPeriodNanos : 垂直同步周期(纳秒)
  - refreshPeriodNanos : 刷新周期(纳秒)
触发场景: 当刷新率发生变化时触发,主要用于调试和性能分析
 */
  oneway void onRefreshRateChangedDebug(in android.hardware.graphics.composer3.RefreshRateChangedDebugData data);

/*
参数说明:
- display : 显示设备 ID
- event : `DisplayHotplugEvent.aidl` 枚举,包含:
  - CONNECTED : 设备连接
  - DISCONNECTED : 设备断开
  - ERROR_UNKNOWN : 未知错误
  - ERROR_INCOMPATIBLE_CABLE : 不兼容的线缆
  - ERROR_TOO_MANY_DISPLAYS : 显示设备过多
  - ERROR_LINK_UNSTABLE : 连接不稳定
触发场景:当显示设备热插拔事件发生时触发,替代已弃用的 onHotplug 方法
*/
  void onHotplugEvent(long display, android.hardware.graphics.common.DisplayHotplugEvent event);
/*
参数说明:
- display : 显示设备 ID
- levels : HDCP(高带宽数字内容保护)级别信息
触发场景: 当显示设备的 HDCP 保护级别发生变化时触发,用于数字版权管理和内容保护
*/
  oneway void onHdcpLevelsChanged(long display, in android.hardware.drm.HdcpLevels levels);
}
1
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

# 2. HWC3 AIDL 接口的封装

上述的 aidl 中定义的接口,通常不直接使用代理端对象操作,一般会通过一个管理类来封装这些接口。AidlComposer 类就是这样一个管理类,它封装了 IComposer 接口的所有方法,提供了更方便的调用接口。

# 2.1 AidlComposer 类结构分析

// /frameworks/native/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
class AidlComposer final : public Hwc2::Composer
1
2

AidlComposer 继承自 Hwc2::Composer,Hwc2::Composer 内部基本都是虚函数,定义了 HWC3 AIDL 接口代理端管理类应该具有的能力。

# 2.1.1 成员变量

AIDL 接口相关成员:

// AIDL 接口实例
std::shared_ptr<AidlIComposer> mAidlComposer;           // AIDL Composer 客户端接口
std::shared_ptr<AidlIComposerClient> mAidlComposerClient; // AIDL Composer 客户端接口  
std::shared_ptr<AidlIComposerCallbackWrapper> mAidlComposerCallback; // 回调接口包装器
1
2
3
4

命令缓冲区管理成员:

// 每个显示设备的命令写入器和读取器
ui::PhysicalDisplayMap<Display, ComposerClientWriter> mWriters GUARDED_BY(mMutex);
ui::PhysicalDisplayMap<Display, ComposerClientReader> mReaders GUARDED_BY(mMutex);
1
2
3

配置和状态管理成员:

// 接口版本和功能标志
int32_t mComposerInterfaceVersion = 1;           // Composer 接口版本
bool mEnableLayerCommandBatchingFlag = false;   // 图层命令批处理标志
std::atomic<int64_t> mLayerID = 1;              // 原子性图层ID计数器

// 多线程支持配置
bool mSingleReader = true;                       // 单读取器模式标志
static constexpr int64_t kSingleReaderKey = 0;  // 单读取器模式的键值
1
2
3
4
5
6
7
8

缓冲区管理成员:

sp<GraphicBuffer> mClearSlotBuffer;  // 提供一个专用缓冲区用于清理图层的缓冲区槽位
1

# 2.1.2 成员方法

生命周期管理:

static bool isDeclared(const std::string& serviceName);  // 检查服务是否声明
explicit AidlComposer(const std::string& serviceName);   // 构造函数
~AidlComposer() override;                                 // 析构函数
1
2
3

能力查询接口:

bool isSupported(OptionalFeature) const;                 // 检查可选功能支持
bool isVrrSupported() const;                             // 检查可变刷新率支持
std::vector<Capability> getCapabilities() override;      // 获取硬件能力
1
2
3

显示设备管理:

Error createVirtualDisplay(...);     // 创建虚拟显示设备
Error destroyVirtualDisplay(...);    // 销毁虚拟显示设备
Error getDisplayConfigs(...);        // 获取显示配置
Error setActiveConfig(...);          // 显示配置
Error setActiveConfigWithConstraints(...) // 显示配置
1
2
3
4
5

图层操作接口:

Error createLayer(...);              // 创建图层
Error destroyLayer(...);             // 销毁图层
Error setLayerBuffer(...);           // 设置图层缓冲区
Error setLayerCompositionType(...);  // 设置图层合成类型
Error setClientTarget(...)
// ......
1
2
3
4
5
6

# 2.1.3 mReaders 与 mWriters 作用分析

    ui::PhysicalDisplayMap<Display, ComposerClientWriter> mWriters GUARDED_BY(mMutex);
    ui::PhysicalDisplayMap<Display, ComposerClientReader> mReaders GUARDED_BY(mMutex);
1
2

mWriters 的主要功能是为每个物理显示设备维护一个独立的命令写入器 ComposerClientWriter,用于:

1.命令缓冲管理:为每个显示设备缓存待发送给硬件合成器(HWC)的命令 2.显示设备隔离:确保不同显示设备的命令操作相互独立 3.批量命令处理:支持将多个图层操作命令批量发送,提高性能

mReaders 负责解析和处理来自 Composer 服务的命令执行结果。

ComposerClientWriter 添加过程与移除过程:

void AidlComposer::addDisplay(Display display) {
    const auto displayId = translate<int64_t>(display);
    mMutex.lock();
    auto [it, added] = mWriters.try_emplace(display, displayId);
    // ...
}

void AidlComposer::removeDisplay(Display display) {
    mMutex.lock();
    bool wasErased = mWriters.erase(display);
    // ...
}
1
2
3
4
5
6
7
8
9
10
11
12

ComposerClientReader 的添加与移除过程:

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);
}

void AidlComposer::removeReader(Display display) {
    bool wasErased = mReaders.erase(display);
    ALOGW_IF(!wasErased,
             "Attempting to remove reader for display %" PRId64 " which is not connected",
             translate<int64_t>(display));
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

ComposerClientWriter 的核心成员如下:

    std::optional<DisplayCommand> mDisplayCommand;
    std::optional<LayerCommand> mLayerCommand;
    std::vector<DisplayCommand> mCommands;
    const int64_t mDisplay;
1
2
3
4

AidlComposer 中定义了很多显示设备与图层配置的函数,当执行这些函数时,显示相关的参数插入 mDisplayCommand 中,Layer相关的参数插入 mLayerCommand 中。当配置完成,需要完成一帧的显示时,会调用 composerClientWriter 的 takePendingCommands 函数获取配置好的 Command 集合:

    // /hardware/interfaces/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
    std::vector<DisplayCommand> takePendingCommands() {
        flushLayerCommand();
        flushDisplayCommand();
        std::vector<DisplayCommand> moved = std::move(mCommands);
        mCommands.clear();
        return moved;
    }
1
2
3
4
5
6
7
8

flushLayerCommand 和 flushDisplayCommand 函数会将 mDisplayCommand 和 mLayerCommand 中保存的指令汇总到 mCommands 成员中,接着将 mCommands 中的成员通过 Binder 远程调用传递给 HWC 执行。

接着我们以 layer 的 buffer 配置为例分析整个过程:

  1. AidlComposer::setLayerBuffer 配置 layer 的buffer 过程:
// /frameworks/native/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
Error AidlComposer::setLayerBuffer(Display display, Layer layer, uint32_t slot,
                                   const sp<GraphicBuffer>& buffer, int acquireFence) {
    Error error = Error::NONE;
    mMutex.lock_shared();
    if (auto writer = getWriter(display)) {
        writer->get().setLayerBuffer(translate<int64_t>(display), translate<int64_t>(layer),
                                     slot, handle, acquireFence);
    } else {
        error = Error::BAD_DISPLAY;
    }
    mMutex.unlock_shared();
    return error;
}

    // /hardware/interfaces/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
    void setLayerBuffer(int64_t display, int64_t layer, uint32_t slot,
                        const native_handle_t* buffer, int acquireFence) {
        // 图层相关配置保存到 mLayerCommand 中
        getLayerCommand(display, layer).buffer = getBufferCommand(slot, buffer, acquireFence);
    }

    LayerCommand& getLayerCommand(int64_t display, int64_t layer) {
        getDisplayCommand(display);
        if (!mLayerCommand.has_value() || mLayerCommand->layer != layer) {
            flushLayerCommand();
            mLayerCommand.emplace();
            mLayerCommand->layer = layer;
        }
        return *mLayerCommand;
    }

    DisplayCommand& getDisplayCommand(int64_t display) {
        if (!mDisplayCommand.has_value() || mDisplayCommand->display != display) {
            LOG_ALWAYS_FATAL_IF(display != mDisplay);
            flushLayerCommand();
            flushDisplayCommand();
            mDisplayCommand.emplace();
            mDisplayCommand->display = display;
        }
        return *mDisplayCommand;
    }

    Buffer getBufferCommand(uint32_t slot, const native_handle_t* bufferHandle, int fence) {
        Buffer bufferCommand;
        bufferCommand.slot = static_cast<int32_t>(slot);
        if (bufferHandle) bufferCommand.handle.emplace(::android::dupToAidl(bufferHandle));
        if (fence > 0) bufferCommand.fence = ::ndk::ScopedFileDescriptor(fence);
        return bufferCommand;
    }
1
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
  1. 当 setLayerBuffer 配置命令执行完成后,调用 executeCommands 方法将缓存的命令批量发送给 HWC 执行。
// /frameworks/native/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
Error AidlComposer::executeCommands(Display display) {
    mMutex.lock_shared();
    auto error = execute(display);
    mMutex.unlock_shared();
    return error;
}

Error AidlComposer::execute(Display display) {
    auto writer = getWriter(display);
    auto reader = getReader(display);
    if (!writer || !reader) {
        return Error::BAD_DISPLAY;
    }

    // takePendingCommands 函数将 mDisplayCommand 和 mLayerCommand 中保存的指令汇总到 mCommands 成员中并返回
    auto commands = writer->get().takePendingCommands();
    if (commands.empty()) {
        return Error::NONE;
    }

    { // scope for results
        std::vector<CommandResultPayload> results;
        // 远程调用到 HWC,批量执行命令
        auto status = mAidlComposerClient->executeCommands(commands, &results);
        if (!status.isOk()) {
            ALOGE("executeCommands failed %s", status.getDescription().c_str());
            return static_cast<Error>(status.getServiceSpecificError());
        }

        // 解析 HWC 的返回值
        reader->get().parse(std::move(results));
    }

    // 异常处理
    const auto commandErrors = reader->get().takeErrors();
    Error error = Error::NONE;
    for (const auto& cmdErr : commandErrors) {
        const auto index = static_cast<size_t>(cmdErr.commandIndex);
        if (index < 0 || index >= commands.size()) {
            ALOGE("invalid command index %zu", index);
            return Error::BAD_PARAMETER;
        }

        const auto& command = commands[index];
        if (command.validateDisplay || command.presentDisplay || command.presentOrValidateDisplay) {
            error = translate<Error>(cmdErr.errorCode);
        } else {
            ALOGW("command '%s' generated error %" PRId32, command.toString().c_str(),
                  cmdErr.errorCode);
        }
    }

    return error;
}
1
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

最后来看 ComposerClientReader 如何解析 HWC 返回的数据。ComposerClientReader 解析出的数据保存在 mReturnData 成员中:

std::unordered_map<int64_t, ReturnData> mReturnData
1

mReturnData 是一个 map 数据,key 是显示器ID,value 是解析出的数据。

struct ReturnData {
    DisplayRequest displayRequests;                              // 显示请求
    std::vector<ChangedCompositionLayer> changedLayers;         // 合成类型变更的图层
    ndk::ScopedFileDescriptor presentFence;                     // 呈现栅栏
    std::vector<PresentFence::LayerPresentFence> layerPresentFences; // 图层呈现栅栏
    std::vector<ReleaseFences::Layer> releasedLayers;           // 释放栅栏的图层
    PresentOrValidate::Result presentOrValidateState;           // 呈现或验证状态
    ClientTargetPropertyWithBrightness clientTargetProperty;    // 客户端目标属性
    std::vector<DisplayLuts::LayerLut> layerLuts;              // 图层查找表
};
1
2
3
4
5
6
7
8
9
10

parse 传入的数据类型是 CommandResultPayload:

union CommandResultPayload {
    /**
     * Indicates an error generated by a command.
     *
     * If there is an error from a command, the composer should only respond
     * with the CommandError, and not with other results
     * (e.g. ChangedCompositionTypes).
     */
    CommandError error;

    /**
     * Sets the layers for which the device requires a different composition
     * type than had been set prior to the last call to VALIDATE_DISPLAY. The
     * client must either update its state with these types and call
     * ACCEPT_DISPLAY_CHANGES, or must set new types and attempt to validate
     * the display again.
     */
    ChangedCompositionTypes changedCompositionTypes;

    /**
     * Sets the display requests and the layer requests required for the last
     * validated configuration.
     *
     * Display requests provide information about how the client must handle
     * the client target. Layer requests provide information about how the
     * client must handle an individual layer.
     */
    DisplayRequest displayRequest;

    /**
     * Sets the present fence as a result of PRESENT_DISPLAY. For physical
     * displays, this fence must be signaled at the vsync when the result
     * of composition of this frame starts to appear (for video-mode panels)
     * or starts to transfer to panel memory (for command-mode panels). For
     * virtual displays, this fence must be signaled when writes to the output
     * buffer have completed and it is safe to read from it.
     */
    PresentFence presentFence;

    /**
     * Sets the release fences for device layers on this display which will
     * receive new buffer contents this frame.
     *
     * A release fence is a file descriptor referring to a sync fence object
     * which must be signaled after the device has finished reading from the
     * buffer presented in the prior frame. This indicates that it is safe to
     * start writing to the buffer again. If a given layer's fence is not
     * returned from this function, it must be assumed that the buffer
     * presented on the previous frame is ready to be written.
     *
     * The fences returned by this function must be unique for each layer
     * (even if they point to the same underlying sync object).
     *
     */
    ReleaseFences releaseFences;

    /**
     * Sets the state of PRESENT_OR_VALIDATE_DISPLAY command.
     */
    PresentOrValidate presentOrValidateResult;

    /**
     * The brightness parameter describes the intended brightness space of the client target buffer.
     * The brightness is in the range [0, 1], where 1 is the current brightness of the display.
     * When client composition blends both HDR and SDR content, the client must composite to the
     * brightness space as specified by the hardware composer. This is so that adjusting the real
     * display brightness may be applied atomically with compensating the client target output. For
     * instance, client-compositing a list of SDR layers requires dimming the brightness space of
     * the SDR buffers when an HDR layer is simultaneously device-composited.
     */
    ClientTargetPropertyWithBrightness clientTargetProperty;

    /**
     * Sets the Lut(s) for the layers.
     *
     * HWC should only request Lut(s) if SurfaceFlinger does not send the Lut(s) to the HWC.
     * The main use-case is like HDR10+ or Dolby Vision where there is no Lut to send from
     * SurfaceFlinger.
     */
    DisplayLuts displayLuts;
}

1
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

解析过程如下:

// /hardware/interfaces/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
    void parse(std::vector<CommandResultPayload>&& results) {
        resetData();

        for (auto& result : results) {
            switch (result.getTag()) { // 根据 tag 区分不同的类型,具体解析函数就不看了
                case CommandResultPayload::Tag::error:
                    parseSetError(std::move(result.get<CommandResultPayload::Tag::error>()));
                    break;
                case CommandResultPayload::Tag::changedCompositionTypes:
                    parseSetChangedCompositionTypes(std::move(
                            result.get<CommandResultPayload::Tag::changedCompositionTypes>()));
                    break;
                case CommandResultPayload::Tag::displayRequest:
                    parseSetDisplayRequests(
                            std::move(result.get<CommandResultPayload::Tag::displayRequest>()));
                    break;
                case CommandResultPayload::Tag::presentFence:
                    parseSetPresentFence(
                            std::move(result.get<CommandResultPayload::Tag::presentFence>()));
                    break;
                case CommandResultPayload::Tag::releaseFences:
                    parseSetReleaseFences(
                            std::move(result.get<CommandResultPayload::Tag::releaseFences>()));
                    break;
                case CommandResultPayload::Tag::presentOrValidateResult:
                    parseSetPresentOrValidateDisplayResult(std::move(
                            result.get<CommandResultPayload::Tag::presentOrValidateResult>()));
                    break;
                case CommandResultPayload::Tag::clientTargetProperty:
                    parseSetClientTargetProperty(std::move(
                            result.get<CommandResultPayload::Tag::clientTargetProperty>()));
                    break;
                case CommandResultPayload::Tag::displayLuts:
                    parseSetDisplayLuts(
                            std::move(result.get<CommandResultPayload::Tag::displayLuts>()));
                    break;
            }
        }
    }
1
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
#显示系统
上次更新: 2025/10/08, 17:04:37
SurfaceFlinger概述
启动过程总览

← SurfaceFlinger概述 启动过程总览→

最近更新
01
显示设备初始化
10-17
02
显示疑难问题分析基础
10-08
03
Perfetto 上手指南1 —— Trace 的抓取
10-08
更多文章>
Theme by Vdoing | Copyright © 2020-2025 AHao Framework | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式