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

阿豪讲Framework

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

  • 玩转AOSP篇

  • 学穿Binder篇

  • 基础组件篇

  • 系统启动过程分析

  • Hal开发入门与实践

  • 显示系统

    • 如何调试 SurfaceFlinger
    • HWC 接口分析
      • 1. HWC3 AIDL 接口分析
        • 1.1 IComposer.aidl 接口分析
        • 1.2 IComposerClient.aidl 接口分析
        • 1.3 IComposerCallback.aidl 接口分析
      • 2. HWC3 AIDL 接口的封装
    • SurfaceFlinger 概述
    • 启动过程总览
    • SurfaceFlinger 初始化
    • RenderEnginge 初始化
  • Framework
  • 显示系统
阿豪
2025-10-05
目录

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 接口的封装

ComposerClientWriter:

// /hardware/interfaces/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h

#pragma once

#include <algorithm>
#include <limits>
#include <memory>
#include <vector>

#include <inttypes.h>
#include <string.h>

#include <aidl/android/hardware/graphics/common/BlendMode.h>
#include <aidl/android/hardware/graphics/common/ColorTransform.h>
#include <aidl/android/hardware/graphics/common/FRect.h>
#include <aidl/android/hardware/graphics/common/Rect.h>
#include <aidl/android/hardware/graphics/common/Transform.h>
#include <aidl/android/hardware/graphics/composer3/Color.h>
#include <aidl/android/hardware/graphics/composer3/Composition.h>
#include <aidl/android/hardware/graphics/composer3/DisplayBrightness.h>
#include <aidl/android/hardware/graphics/composer3/DisplayCommand.h>
#include <aidl/android/hardware/graphics/composer3/LayerBrightness.h>
#include <aidl/android/hardware/graphics/composer3/LayerLifecycleBatchCommandType.h>
#include <aidl/android/hardware/graphics/composer3/Luts.h>
#include <aidl/android/hardware/graphics/composer3/PerFrameMetadata.h>
#include <aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h>

#include <log/log.h>
#include <sync/sync.h>

#include <aidlcommonsupport/NativeHandle.h>

using aidl::android::hardware::graphics::common::BlendMode;
using aidl::android::hardware::graphics::common::ColorTransform;
using aidl::android::hardware::graphics::common::Dataspace;
using aidl::android::hardware::graphics::common::FRect;
using aidl::android::hardware::graphics::common::Rect;
using aidl::android::hardware::graphics::common::Transform;

using namespace aidl::android::hardware::graphics::composer3;

using aidl::android::hardware::common::NativeHandle;

namespace aidl::android::hardware::graphics::composer3 {

using PictureProfileId = decltype(LayerCommand().pictureProfileId);

class ComposerClientWriter final {
  public:
    static constexpr std::optional<ClockMonotonicTimestamp> kNoTimestamp = std::nullopt;

    explicit ComposerClientWriter(int64_t display) : mDisplay(display) { reset(); }

    ~ComposerClientWriter() { reset(); }

    ComposerClientWriter(ComposerClientWriter&&) = default;

    ComposerClientWriter(const ComposerClientWriter&) = delete;
    ComposerClientWriter& operator=(const ComposerClientWriter&) = delete;

    void setColorTransform(int64_t display, const float* matrix) {
        std::vector<float> matVec;
        matVec.reserve(16);
        matVec.assign(matrix, matrix + 16);
        getDisplayCommand(display).colorTransformMatrix.emplace(std::move(matVec));
    }

    void setDisplayBrightness(int64_t display, float brightness, float brightnessNits) {
        getDisplayCommand(display).brightness.emplace(
                DisplayBrightness{.brightness = brightness, .brightnessNits = brightnessNits});
    }

    void setDisplayPictureProfileId(int64_t display, PictureProfileId pictureProfileId) {
        getDisplayCommand(display).pictureProfileId = pictureProfileId;
    }

    void setClientTarget(int64_t display, uint32_t slot, const native_handle_t* target,
                         int acquireFence, Dataspace dataspace, const std::vector<Rect>& damage,
                         float hdrSdrRatio) {
        ClientTarget clientTargetCommand;
        clientTargetCommand.buffer = getBufferCommand(slot, target, acquireFence);
        clientTargetCommand.dataspace = dataspace;
        clientTargetCommand.damage.assign(damage.begin(), damage.end());
        clientTargetCommand.hdrSdrRatio = hdrSdrRatio;
        getDisplayCommand(display).clientTarget.emplace(std::move(clientTargetCommand));
    }

    void setOutputBuffer(int64_t display, uint32_t slot, const native_handle_t* buffer,
                         int releaseFence) {
        getDisplayCommand(display).virtualDisplayOutputBuffer.emplace(
                getBufferCommand(slot, buffer, releaseFence));
    }

    void setLayerLifecycleBatchCommandType(int64_t display, int64_t layer,
                                           LayerLifecycleBatchCommandType cmd) {
        getLayerCommand(display, layer).layerLifecycleBatchCommandType = cmd;
    }

    void setNewBufferSlotCount(int64_t display, int64_t layer, int32_t newBufferSlotToCount) {
        getLayerCommand(display, layer).newBufferSlotCount = newBufferSlotToCount;
    }

    void validateDisplay(int64_t display,
                         std::optional<ClockMonotonicTimestamp> expectedPresentTime,
                         int32_t frameIntervalNs) {
        auto& command = getDisplayCommand(display);
        command.expectedPresentTime = expectedPresentTime;
        command.validateDisplay = true;
        command.frameIntervalNs = frameIntervalNs;
    }

    void presentOrvalidateDisplay(int64_t display,
                                  std::optional<ClockMonotonicTimestamp> expectedPresentTime,
                                  int32_t frameIntervalNs) {
        auto& command = getDisplayCommand(display);
        command.expectedPresentTime = expectedPresentTime;
        command.presentOrValidateDisplay = true;
        command.frameIntervalNs = frameIntervalNs;
    }

    void acceptDisplayChanges(int64_t display) {
        getDisplayCommand(display).acceptDisplayChanges = true;
    }

    void presentDisplay(int64_t display) { getDisplayCommand(display).presentDisplay = true; }

    void setLayerCursorPosition(int64_t display, int64_t layer, int32_t x, int32_t y) {
        common::Point cursorPosition;
        cursorPosition.x = x;
        cursorPosition.y = y;
        getLayerCommand(display, layer).cursorPosition.emplace(std::move(cursorPosition));
    }

    void setLayerBuffer(int64_t display, int64_t layer, uint32_t slot,
                        const native_handle_t* buffer, int acquireFence) {
        getLayerCommand(display, layer).buffer = getBufferCommand(slot, buffer, acquireFence);
    }

    void setLayerBufferWithNewCommand(int64_t display, int64_t layer, uint32_t slot,
                                      const native_handle_t* buffer, int acquireFence) {
        flushLayerCommand();
        getLayerCommand(display, layer).buffer = getBufferCommand(slot, buffer, acquireFence);
        flushLayerCommand();
    }

    void setLayerBufferSlotsToClear(int64_t display, int64_t layer,
                                    const std::vector<uint32_t>& slotsToClear) {
        getLayerCommand(display, layer)
                .bufferSlotsToClear.emplace(slotsToClear.begin(), slotsToClear.end());
    }

    void setLayerSurfaceDamage(int64_t display, int64_t layer, const std::vector<Rect>& damage) {
        getLayerCommand(display, layer).damage.emplace(damage.begin(), damage.end());
    }

    void setLayerBlendMode(int64_t display, int64_t layer, BlendMode mode) {
        ParcelableBlendMode parcelableBlendMode;
        parcelableBlendMode.blendMode = mode;
        getLayerCommand(display, layer).blendMode.emplace(std::move(parcelableBlendMode));
    }

    void setLayerColor(int64_t display, int64_t layer, Color color) {
        getLayerCommand(display, layer).color.emplace(std::move(color));
    }

    void setLayerCompositionType(int64_t display, int64_t layer, Composition type) {
        ParcelableComposition compositionPayload;
        compositionPayload.composition = type;
        getLayerCommand(display, layer).composition.emplace(std::move(compositionPayload));
    }

    void setLayerDataspace(int64_t display, int64_t layer, Dataspace dataspace) {
        ParcelableDataspace dataspacePayload;
        dataspacePayload.dataspace = dataspace;
        getLayerCommand(display, layer).dataspace.emplace(std::move(dataspacePayload));
    }

    void setLayerDisplayFrame(int64_t display, int64_t layer, const Rect& frame) {
        getLayerCommand(display, layer).displayFrame.emplace(frame);
    }

    void setLayerPlaneAlpha(int64_t display, int64_t layer, float alpha) {
        PlaneAlpha planeAlpha;
        planeAlpha.alpha = alpha;
        getLayerCommand(display, layer).planeAlpha.emplace(std::move(planeAlpha));
    }

    void setLayerSidebandStream(int64_t display, int64_t layer, const native_handle_t* stream) {
        NativeHandle handle;
        if (stream) handle = ::android::dupToAidl(stream);
        getLayerCommand(display, layer).sidebandStream.emplace(std::move(handle));
    }

    void setLayerSourceCrop(int64_t display, int64_t layer, const FRect& crop) {
        getLayerCommand(display, layer).sourceCrop.emplace(crop);
    }

    void setLayerTransform(int64_t display, int64_t layer, Transform transform) {
        ParcelableTransform transformPayload;
        transformPayload.transform = transform;
        getLayerCommand(display, layer).transform.emplace(std::move(transformPayload));
    }

    void setLayerVisibleRegion(int64_t display, int64_t layer, const std::vector<Rect>& visible) {
        getLayerCommand(display, layer).visibleRegion.emplace(visible.begin(), visible.end());
    }

    void setLayerZOrder(int64_t display, int64_t layer, uint32_t z) {
        ZOrder zorder;
        zorder.z = static_cast<int32_t>(z);
        getLayerCommand(display, layer).z.emplace(std::move(zorder));
    }

    void setLayerPerFrameMetadata(int64_t display, int64_t layer,
                                  const std::vector<PerFrameMetadata>& metadataVec) {
        getLayerCommand(display, layer)
                .perFrameMetadata.emplace(metadataVec.begin(), metadataVec.end());
    }

    void setLayerColorTransform(int64_t display, int64_t layer, const float* matrix) {
        getLayerCommand(display, layer).colorTransform.emplace(matrix, matrix + 16);
    }

    void setLayerPerFrameMetadataBlobs(int64_t display, int64_t layer,
                                       const std::vector<PerFrameMetadataBlob>& metadata) {
        getLayerCommand(display, layer)
                .perFrameMetadataBlob.emplace(metadata.begin(), metadata.end());
    }

    void setLayerBrightness(int64_t display, int64_t layer, float brightness) {
        getLayerCommand(display, layer)
                .brightness.emplace(LayerBrightness{.brightness = brightness});
    }

    void setLayerBlockingRegion(int64_t display, int64_t layer, const std::vector<Rect>& blocking) {
        getLayerCommand(display, layer).blockingRegion.emplace(blocking.begin(), blocking.end());
    }

    void setLayerLuts(int64_t display, int64_t layer, Luts& luts) {
        getLayerCommand(display, layer).luts.emplace(std::move(luts));
    }

    void setLayerPictureProfileId(int64_t display, int64_t layer,
                                  PictureProfileId pictureProfileId) {
        getLayerCommand(display, layer).pictureProfileId = pictureProfileId;
    }

    std::vector<DisplayCommand> takePendingCommands() {
        flushLayerCommand();
        flushDisplayCommand();
        std::vector<DisplayCommand> moved = std::move(mCommands);
        mCommands.clear();
        return moved;
    }

  private:
    std::optional<DisplayCommand> mDisplayCommand;
    std::optional<LayerCommand> mLayerCommand;
    std::vector<DisplayCommand> mCommands;
    const int64_t mDisplay;

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

    void flushLayerCommand() {
        if (mLayerCommand.has_value()) {
            mDisplayCommand->layers.emplace_back(std::move(*mLayerCommand));
            mLayerCommand.reset();
        }
    }

    void flushDisplayCommand() {
        if (mDisplayCommand.has_value()) {
            mCommands.emplace_back(std::move(*mDisplayCommand));
            mDisplayCommand.reset();
        }
    }

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

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

    void reset() {
        mDisplayCommand.reset();
        mLayerCommand.reset();
        mCommands.clear();
    }
};

}  // namespace aidl::android::hardware::graphics::composer3
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
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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
// /hardware/interfaces/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl
package android.hardware.graphics.composer3;
@VintfStability
parcelable DisplayCommand {
  long display;
  android.hardware.graphics.composer3.LayerCommand[] layers;
  @nullable float[] colorTransformMatrix;
  @nullable android.hardware.graphics.composer3.DisplayBrightness brightness;
  @nullable android.hardware.graphics.composer3.ClientTarget clientTarget;
  @nullable android.hardware.graphics.composer3.Buffer virtualDisplayOutputBuffer;
  @nullable android.hardware.graphics.composer3.ClockMonotonicTimestamp expectedPresentTime;
  boolean validateDisplay;
  boolean acceptDisplayChanges;
  boolean presentDisplay;
  boolean presentOrValidateDisplay;
}

// /hardware/interfaces/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
@VintfStability
parcelable LayerCommand {
    /**
     * The layer which this commands refers to.
     * @see IComposer.createLayer
     */
    long layer;

    /**
     * Sets the position of a cursor layer.
     *
     * The position of a cursor layer can be updated without a validate/present display
     * sequence if that layer was marked as Composition.CURSOR and validation previously succeeded
     * (i.e., the device didn't request a composition).
     */
    @nullable Point cursorPosition;

    /**
     * Sets the buffer handle to be displayed for this layer. If the buffer
     * properties set at allocation time (width, height, format, and usage)
     * have not changed since the previous frame, it is not necessary to call
     * validateDisplay before calling presentDisplay unless new state needs to
     * be validated in the interim.
     *
     * Also provides a file descriptor referring to an acquire sync fence
     * object, which must be signaled when it is safe to read from the given
     * buffer. If it is already safe to read from the buffer, an empty handle
     * may be passed instead.
     *
     * This function must return NONE and have no other effect if called for a
     * layer with a composition type of Composition.SOLID_COLOR (because it
     * has no buffer) or Composition.SIDEBAND or Composition.CLIENT (because
     * synchronization and buffer updates for these layers are handled
     * elsewhere).
     */
    @nullable Buffer buffer;

    /**
     * Provides the region of the source buffer which has been modified since
     * the last frame. This region does not need to be validated before
     * calling presentDisplay.
     *
     * Once set through this function, the damage region remains the same
     * until a subsequent call to this function.
     *
     * If damage is non-empty, then it may be assumed that any portion of the
     * source buffer not covered by one of the rects has not been modified
     * this frame. If damage is empty, then the whole source buffer must be
     * treated as if it has been modified.
     *
     * If the layer's contents are not modified relative to the prior frame,
     * damage must contain exactly one empty rect([0, 0, 0, 0]).
     *
     * The damage rects are relative to the pre-transformed buffer, and their
     * origin is the top-left corner. They must not exceed the dimensions of
     * the latched buffer.
     */
    @nullable Rect[] damage;

    /**
     * Sets the blend mode of the given layer.
     */
    @nullable ParcelableBlendMode blendMode;

    /**
     * Sets the color of the given layer. If the composition type of the layer
     * is not Composition.SOLID_COLOR, this call must succeed and have no
     * other effect.
     */
    @nullable Color color;

    /**
     * Sets the desired composition type of the given layer. During
     * validateDisplay, the device may request changes to the composition
     * types of any of the layers as described in the definition of
     * Composition above.
     */
    @nullable ParcelableComposition composition;

    /**
     * Sets the dataspace of the layer.
     *
     * The dataspace provides more information about how to interpret the buffer
     * or solid color, such as the encoding standard and color transform.
     *
     * See the values of ParcelableDataspace for more information.
     */
    @nullable ParcelableDataspace dataspace;

    /**
     * Sets the display frame (the portion of the display covered by a layer)
     * of the given layer. This frame must not exceed the display dimensions.
     */
    @nullable Rect displayFrame;

    /**
     * Sets an alpha value (a floating point value in the range [0.0, 1.0])
     * which will be applied to the whole layer. It can be conceptualized as a
     * preprocessing step which applies the following function:
     *   if (blendMode == BlendMode.PREMULTIPLIED)
     *       out.rgb = in.rgb * planeAlpha
     *   out.a = in.a * planeAlpha
     *
     * If the device does not support this operation on a layer which is
     * marked Composition.DEVICE, it must request a composition type change
     * to Composition.CLIENT upon the next validateDisplay call.
     *
     */
    @nullable PlaneAlpha planeAlpha;

    /**
     * Sets the sideband stream for this layer. If the composition type of the
     * given layer is not Composition.SIDEBAND, this call must succeed and
     * have no other effect.
     */
    @nullable NativeHandle sidebandStream;

    /**
     * Sets the source crop (the portion of the source buffer which will fill
     * the display frame) of the given layer. This crop rectangle must not
     * exceed the dimensions of the latched buffer.
     *
     * If the device is not capable of supporting a true float source crop
     * (i.e., it will truncate or round the floats to integers), it must set
     * this layer to Composition.CLIENT when crop is non-integral for the
     * most accurate rendering.
     *
     * If the device cannot support float source crops, but still wants to
     * handle the layer, it must use the following code (or similar) to
     * convert to an integer crop:
     *   intCrop.left = (int) ceilf(crop.left);
     *   intCrop.top = (int) ceilf(crop.top);
     *   intCrop.right = (int) floorf(crop.right);
     *   intCrop.bottom = (int) floorf(crop.bottom);
     */
    @nullable FRect sourceCrop;

    /**
     * Sets the transform (rotation/flip) of the given layer.
     */
    @nullable ParcelableTransform transform;

    /**
     * Specifies the portion of the layer that is visible, including portions
     * under translucent areas of other layers. The region is in screen space,
     * and must not exceed the dimensions of the screen.
     */
    @nullable Rect[] visibleRegion;

    /**
     * Sets the desired Z order (height) of the given layer. A layer with a
     * greater Z value occludes a layer with a lesser Z value.
     */
    @nullable ZOrder z;

    /**
     * Sets a matrix for color transform which will be applied on this layer
     * before composition.
     *
     * If the device is not capable of apply the matrix on this layer, it must force
     * this layer to client composition during VALIDATE_DISPLAY.
     *
     * The matrix provided is an affine color transformation of the following
     * form:
     *
     * |r.r r.g r.b 0|
     * |g.r g.g g.b 0|
     * |b.r b.g b.b 0|
     * |Tr  Tg  Tb  1|
     *
     * This matrix must be provided in row-major form:
     *
     * {r.r, r.g, r.b, 0, g.r, ...}.
     *
     * Given a matrix of this form and an input color [R_in, G_in, B_in],
     * the input color must first be converted to linear space
     * [R_linear, G_linear, B_linear], then the output linear color
     * [R_out_linear, G_out_linear, B_out_linear] will be:
     *
     * R_out_linear = R_linear * r.r + G_linear * g.r + B_linear * b.r + Tr
     * G_out_linear = R_linear * r.g + G_linear * g.g + B_linear * b.g + Tg
     * B_out_linear = R_linear * r.b + G_linear * g.b + B_linear * b.b + Tb
     *
     * [R_out_linear, G_out_linear, B_out_linear] must then be converted to
     * gamma space: [R_out, G_out, B_out] before blending.
     */
    @nullable float[] colorTransform;

    /**
     * Sets the desired brightness for the layer. This is intended to be used for instance when
     * presenting an SDR layer alongside HDR content. The HDR content will be presented at the
     * display brightness in nits, and accordingly SDR content shall be dimmed according to the
     * provided brightness ratio.
     */
    @nullable LayerBrightness brightness;

    /**
     * Sets the PerFrameMetadata for the display. This metadata must be used
     * by the implementation to better tone map content to that display.
     *
     * This is a command that may be called every frame.
     */
    @nullable PerFrameMetadata[] perFrameMetadata;

    /**
     * This command sends metadata that may be used for tone-mapping the
     * associated layer.  The metadata structure follows a {key, blob}
     * format (see the PerFrameMetadataBlob struct).  All keys must be
     * returned by a prior call to getPerFrameMetadataKeys and must
     * be part of the list of keys associated with blob-type metadata
     * (see PerFrameMetadataKey).
     *
     * This command may be called every frame.
     */
    @nullable PerFrameMetadataBlob[] perFrameMetadataBlob;

    /**
     * Specifies a region of the layer that is transparent and may be skipped
     * by the DPU, e.g. using a blocking region, in order to save power. This
     * is only a hint, so the composition of the layer must look the same
     * whether or not this region is skipped.
     *
     * The region is in screen space and must not exceed the dimensions of
     * the screen.
     */
    @nullable Rect[] blockingRegion;

    /**
     * Specifies which buffer slots should be cleared of buffer references
     * because these buffers will no longer be used and the memory should
     * be freed.
     */
    @nullable int[] bufferSlotsToClear;

    /**
     * Specifies if this layer command is on type modify, create or destroy.
     * This command is replacing the older IComposerClient.createLayer and destroyLayer
     * and making it more efficient with reduced aidls to the HAL.
     * The HAL will report the errors by setting CommandResultPayload::CommandError.
     */
    LayerLifecycleBatchCommandType layerLifecycleBatchCommandType;

    /**
     * Specifies the number of buffer slot to be reserved.
     */
    int newBufferSlotCount;

    /**
     * Sets the lut(s) for the layer.
     */
    @nullable Luts luts;

    /**
     * If the display has multiple per-layer picture processing pipelines, then this value is used
     * to look up a picture profile which defines the parameters used when configuring a
     * picture-processing pipeline for this layer, enhancing the quality of the buffer contents. If
     * the server doesn't recognize this profile, it must continue with composition and ignore
     * this value. If the value is zero, then the no picture processing must be applied.
     *
     * Note that the client will never send a DisplayCommand.pictureProfileId if
     * IComposerClient.getMaxLayerPictureProfiles is non-zero. Picture profiles will only be
     * specified on a per-layer basis.
     *
     * @see IComposerClient.getMaxLayerPictureProfiles
     * @see DisplayCommand.pictureProfileId
     */
    long pictureProfileId;
}

// /hardware/interfaces/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTarget.aidl
@VintfStability
parcelable ClientTarget {
    /**
     * Client target Buffer
     */
    Buffer buffer;

    /**
     * The dataspace of the buffer, as described in LayerCommand.dataspace.
     */
    Dataspace dataspace;

    /**
     * The surface damage regions.
     */
    Rect[] damage;

    /**
     * The HDR/SDR ratio.
     * Only meaningful for extended_range client targets to communicate the amount of HDR heaedroom
     * inside the client target. For floating point client targets, this means that for each color
     * channel the maximum SDR luminance is 1.0, and the maximum display relative luminance is
     * the hdrSdrRatio.
     * Note that this ratio is meant to be >= 1.0.
     */
    float hdrSdrRatio = 1.0f;
}

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
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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
#显示系统
如何调试 SurfaceFlinger
SurfaceFlinger 概述

← 如何调试 SurfaceFlinger SurfaceFlinger 概述→

最近更新
01
如何调试 SurfaceFlinger
10-05
02
SurfaceFlinger 概述
10-05
03
启动过程总览
10-05
更多文章>
Theme by Vdoing | Copyright © 2020-2025 AHao Framework | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式