SurfaceFlinger 调用 libdrm 的详细代码流程分析

news2026/5/22 1:42:19
1. 整体架构图┌─────────────────────────────────────────────────────────────────┐ │ 应用层框架 │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ App应用 │ │ Activity │ │ View系统 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ └─────────────────────┬───────────────────────────────────────────┘ │ Binder IPC ▼ ┌─────────────────────────────────────────────────────────────────┐ │ SurfaceFlinger服务 │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ SurfaceFlinger.cpp │ │ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ │ │ - mHwc (std::unique_ptrHWComposer) │ │ │ │ │ │ - mDisplays (显示设备集合) │ │ │ │ │ │ - commit() - 合成提交 │ │ │ │ │ │ - postComposition() - 后处理 │ │ │ │ │ └─────────────────────────────────────────────────┘ │ │ │ └──────────────────────────────────────────────────────────┘ │ └─────────────────────┬───────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ HWComposer硬件组合器 │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ DisplayHardware/HWComposer.h/.cpp │ │ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ │ │ std::unique_ptrHwc2::Composer mComposer │ │ │ │ │ │ mDisplayData (显示数据结构) │ │ │ │ │ │ │ │ │ │ │ │ 关键方法 │ │ │ │ │ │ - setCallback() - 设置回调 │ │ │ │ │ │ - getDeviceCompositionChanges() - 获取合成变更 │ │ │ │ │ │ - setClientTarget() - 设置客户端目标 │ │ │ │ │ │ - presentAndGetReleaseFences() - 显示和获取栅栏 │ │ │ │ │ └─────────────────────────────────────────────────┘ │ │ │ └──────────────────────────────────────────────────────────┘ │ └─────────────────────┬───────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ Composer HAL抽象层 │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ DisplayHardware/ComposerHal.h │ │ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ │ │ class Composer { │ │ │ │ │ │ public: │ │ │ │ │ │ virtual Error presentDisplay() 0; │ │ │ │ │ │ virtual Error setClientTarget() 0; │ │ │ │ │ │ virtual Error validateDisplay() 0; │ │ │ │ │ │ virtual Error createLayer() 0; │ │ │ │ │ │ // ... 更多接口 │ │ │ │ │ │ }; │ │ │ │ │ └─────────────────────────────────────────────────┘ │ │ │ └──────────────────────────────────────────────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ 具体实现AidlComposerHal/HidlComposerHal │ │ │ └──────────────────────────────────────────────────────────┘ │ └─────────────────────┬───────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 硬件组合器HAL服务 (厂商实现) │ │ (位于vendor分区实现具体的显示输出逻辑) │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ 厂商实现的核心代码 │ │ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ │ │ DrmDisplay.cpp (DRM显示管理) │ │ │ │ │ │ DrmConnector.cpp (连接器管理) │ │ │ │ │ │ DrmCrtc.cpp (CRTC管理) │ │ │ │ │ │ DrmPlane.cpp (平面管理) │ │ │ │ │ │ DrmDevice.cpp (DRM设备管理) │ │ │ │ │ └─────────────────────────────────────────────────┘ │ │ │ └──────────────────────────────────────────────────────────┘ │ └─────────────────────┬───────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ libdrm │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ libdrm核心接口 │ │ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ │ │ 设备管理 (xf86drm.h) │ │ │ │ │ │ - drmOpen() - 打开DRM设备 │ │ │ │ │ │ - drmClose() - 关闭DRM设备 │ │ │ │ │ │ - drmGetVersion() - 获取驱动版本 │ │ │ │ │ │ - drmIoctl() - ioctl封装 │ │ │ │ │ └─────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ │ │ KMS模式设置 (xf86drmMode.h) │ │ │ │ │ │ - drmModeGetResources() - 获取资源 │ │ │ │ │ │ - drmModeGetConnector() - 获取连接器 │ │ │ │ │ │ - drmModeSetCrtc() - 设置CRTC │ │ │ │ │ │ - drmModeAddFB() - 添加帧缓冲区 │ │ │ │ │ │ - drmModePageFlip() - 页面翻转 │ │ │ │ │ └─────────────────────────────────────────────────┘ │ │ │ └──────────────────────────────────────────────────────────┘ │ └─────────────────────┬───────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ Linux Kernel DRM子系统 │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ DRM Core (drivers/gpu/drm/) │ │ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ │ │ drm_dev.c - 设备管理 │ │ │ │ │ │ drm_mode_config.c - 模式配置 │ │ │ │ │ │ drm_connector.c - 连接器管理 │ │ │ │ │ │ drm_crtc.c - CRTC管理 │ │ │ │ │ │ drm_encoder.c - 编码器管理 │ │ │ │ │ │ drm_plane.c - 平面管理 │ │ │ │ │ │ drm_gem.c - GEM内存管理 │ │ │ │ │ │ drm_fb_helper.c - 帧缓冲区助手 │ │ │ │ │ └─────────────────────────────────────────────────┘ │ │ │ └──────────────────────────────────────────────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ GPU驱动实现 │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ │ │ i915 │ │ amdgpu │ │ 其他驱动 │ │ │ │ │ │ Intel GPU │ │ AMD GPU │ │ │ │ │ │ │ │ 驱动实现 │ │ 驱动实现 │ │ │ │ │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ │ └──────────────────────────────────────────────────────────┘ │ └─────────────────────┬───────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ GPU硬件 / 显示控制器 │ │ ├─► GPU核心 (计算单元、着色器等) │ │ ├─► 显示控制器 (时序控制、信号输出) │ │ ├─► 显存 (VRAM/系统内存共享) │ │ ├─► 输出接口 (HDMI/DP/eDP/DSI/Mipi等) │ │ └─► 显示器 (实际显示设备) │ └─────────────────────────────────────────────────────────────────┘2. 初始化阶段详细代码流程SurfaceFlinger::init() │ │ 代码位置: native/services/surfaceflinger/SurfaceFlinger.cpp │ ├─► HWComposer构造函数 │ │ │ ├─► HWComposer::HWComposer(composerServiceName) │ │ │ │ │ └─► HWComposer::HWComposer(Hwc2::Composer::create(composerServiceName)) │ │ │ │ │ ├─► Hwc2::Composer::create() │ │ │ │ │ │ │ └─► 检查并连接到硬件服务 │ │ │ │ │ │ │ ├─► 检查AIDL服务 │ │ │ │ │ │ │ │ │ └─► AServiceManager_checkService( │ │ │ │ android.hardware.graphics.composer3) │ │ │ │ │ │ │ ├─► 检查HIDL服务 │ │ │ │ │ │ │ │ │ └─► IComposer::getService() │ │ │ │ │ │ │ └─► 创建Composer实例 │ │ │ │ │ │ │ └─► std::make_uniqueAidlComposerHal(halService) │ │ │ │ │ │ │ └─► 初始化AIDL连接 │ │ │ │ │ │ │ └─► 连接到硬件Composer服务 │ │ │ │ │ │ │ └─► 厂商HAL服务初始化 │ │ │ │ │ │ │ └─► libdrm初始化调用 │ │ │ │ │ │ │ ├─► drmOpen(/dev/dri/card0) │ │ │ │ │ │ │ │ │ └─► libdrm/xf86drm.c │ │ │ │ │ │ │ │ │ ├─► drmOpenDevice() │ │ │ │ │ ├─► 确定设备节点路径 │ │ │ │ │ ├─► open(/dev/dri/card0, O_RDWR) │ │ │ │ │ └─► 返回文件描述符 │ │ │ │ │ │ │ ├─► drmGetVersion(fd, version) │ │ │ │ │ │ │ │ │ └─► drmIoctl(fd, DRM_IOCTL_VERSION, version) │ │ │ │ │ │ │ │ │ └─► 内核处理并返回驱动版本 │ │ │ │ │ │ │ └─► drmModeGetResources(fd) │ │ │ │ │ │ │ └─► libdrm/xf86drmMode.c │ │ │ │ │ │ │ ├─► drmModeGetResources() │ │ │ │ │ │ │ │ │ ├─► 准备drm_mode_card_res结构 │ │ │ │ │ │ │ │ │ ├─► 第一次ioctl调用 │ │ │ │ │ └─► drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, res) │ │ │ │ │ ├─► 内核DRM处理 │ │ │ │ │ ├─► 返回资源数量 │ │ │ │ │ └─► res.count_crtcs, res.count_connectors等 │ │ │ │ │ │ │ │ │ ├─► 分配内存 │ │ │ │ │ ├─► res.fb_id_ptr malloc(count_fbs * sizeof(uint32_t)) │ │ │ │ │ ├─► res.crtc_id_ptr malloc(count_crtcs * sizeof(uint32_t)) │ │ │ │ │ └─► ... 分配其他资源数组 │ │ │ │ │ │ │ │ │ └─► 第二次ioctl调用 │ │ │ │ └─► drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, res) │ │ │ │ ├─► 内核填充资源ID数组 │ │ │ │ └─│ 返回完整的资源信息 │ │ │ │ │ │ │ └─► 构建drmModeRes结构返回 │ │ │ ├─► fbs: 帧缓冲区ID数组 │ │ │ ├─► crtcs: CRTC ID数组 │ │ │ ├─► connectors: 连接器ID数组 │ │ │ └─► encoders: 编码器ID数组 │ │ │ │ │ └─► 初始化HWComposer成员变量 │ │ ├─► mComposer std::move(composer) │ │ ├─► mRegisteredCallback false │ │ └─► mCapabilities 初始化能力集合 │ │ │ └─► 返回HWComposer实例 │ ├─► 设置回调函数 │ │ │ ├─► HWComposer::setCallback(callback) │ │ │ │ │ ├─► loadCapabilities() │ │ │ │ │ │ │ └─► mComposer-getCapabilities() │ │ │ │ │ │ │ └─► AidlComposerHal::getCapabilities() │ │ │ │ │ │ │ └─► mHal-getCapabilities(capabilities) │ │ │ │ │ │ │ └─► 硬件服务返回能力列表 │ │ │ ├─► SKIP_CLIENT_COLOR_TRANSFORM │ │ │ ├─► DOZE │ │ │ ├─► REFRESH_RATE_SWITCHING │ │ │ └─► 其他能力 │ │ │ │ │ ├─► loadLayerMetadataSupport() │ │ │ │ │ ├─► loadOverlayProperties() │ │ │ │ │ ├─► loadHdrConversionCapabilities() │ │ │ │ │ └─► 注册回调 │ │ │ │ │ └─► mComposer-registerCallback(callback) │ │ │ │ │ └─► AidlComposerHal::registerCallback() │ │ │ │ │ └─► mHal-registerCallback(callbackWrapper) │ │ │ │ │ └─► 硬件服务注册回调 │ │ │ │ │ └─► 启用热插拔、VSync等事件通知 │ │ ├─► onHotplug - 显示器热插拔 │ │ ├─► onVsync - 垂直同步信号 │ │ └─► onRefresh - 刷新请求 │ │ └─► 初始化显示设备 │ └─► SurfaceFlinger::initializeDisplays() │ ├─► 处理热插拔事件 │ │ │ └─► HWComposer::onHotplug(hwcDisplayId, connection) │ │ │ └─► onHotplugConnect(hwcDisplayId) │ │ │ ├─► 获取显示标识信息 │ │ │ │ │ └─► getDisplayIdentificationData(hwcDisplayId) │ │ │ │ │ └─► mComposer-getDisplayIdentificationData() │ │ │ │ │ └─► 硬件服务返回显示标识 │ │ ├─► EDID数据 │ │ ├─► 厂商信息 │ │ └─│ 设备ID │ │ │ ├─► 创建物理显示设备 │ │ │ │ │ └─► allocatePhysicalDisplay(hwcDisplayId, displayId) │ │ │ │ │ └─► 创建HWC2::Display实例 │ │ │ │ │ └─► std::make_uniqueHWC2::impl::Display( │ │ *mComposer.get(), │ │ mCapabilities, │ │ hwcDisplayId, │ │ hal::DisplayType::PHYSICAL) │ │ │ └─► 返回显示设备信息 │ ├─► 显示ID │ ├─► 分辨率 │ └─► 显示名称 │ └─► 创建DisplayDevice实例 │ └─► 创建DisplayDevice并添加到显示设备列表3. 帧显示和合成详细流程SurfaceFlinger::commit() │ │ 代码位置: native/services/surfaceflinger/SurfaceFlinger.cpp │ ├─► 准备合成 │ │ │ ├─► validateLayers() │ │ │ │ │ └─► 检查所有Layer的状态 │ │ ├─► 图层可见性 │ │ ├─│ 缓冲区状态 │ │ └─│ 合成类型 │ │ │ └─► buildLayerStacks() │ │ │ └─► 构建图层栈 │ ├─► 按Z顺序排序 │ ├─► 确定合成策略 │ └─► 准备合成参数 │ ├─► 获取硬件合成器建议 │ │ │ ├─► HWComposer::getDeviceCompositionChanges(displayId, frameUsesClientComposition, │ │ earliestPresentTime, expectedPresentTime, │ │ frameInterval, outChanges) │ │ │ │ │ └─► DeviceRequestedChanges获取流程 │ │ │ │ │ ├─► 检查显示有效性 │ │ │ │ │ │ │ └─► RETURN_IF_INVALID_DISPLAY(displayId, error) │ │ │ │ │ ├─► 获取显示数据 │ │ │ │ │ │ │ └─► auto displayData mDisplayData[displayId] │ │ │ │ │ │ │ └─► 获取HWC2::Display实例 │ │ │ │ │ │ │ └─► displayData.hwcDisplay │ │ │ │ │ ├─► 准备客户端目标 │ │ │ │ │ │ │ └─► prepareClientTarget(displayData, frameUsesClientComposition, │ │ │ earliestPresentTime, expectedPresentTime, │ │ │ frameInterval) │ │ │ │ │ ├─► 验证显示 │ │ │ │ │ │ │ └─► validateDisplay(displayData, earliestPresentTime, │ │ │ expectedPresentTime, frameInterval) │ │ │ │ │ │ │ ├─► HWC2::Display::validate() │ │ │ │ │ │ │ └─► ComposerHal::validateDisplay(display, expectedPresentTime, │ │ │ frameIntervalNs, outNumTypes, │ │ │ outNumRequests) │ │ │ │ │ │ │ └─► AidlComposerHal::validateDisplay() │ │ │ │ │ │ │ └─► mHal-validateDisplay(display, expectedPresentTime, │ │ │ frameIntervalNs, numTypes, │ │ │ numRequests) │ │ │ │ │ │ │ └─► 硬件服务验证 │ │ │ │ │ │ │ └─► 厂商实现调用libdrm │ │ │ │ │ │ │ ├─► drmModeGetConnector() │ │ │ │ │ │ │ │ │ └─► ioctl(DRM_IOCTL_MODE_GETCONNECTOR) │ │ │ │ ├─► 内核DRM处理 │ │ │ │ ├─► 检查连接状态 │ │ │ │ ├─► 获取支持的显示模式 │ │ │ │ └─│ 返回连接器信息 │ │ │ │ │ │ │ ├─► drmModeGetEncoder() │ │ │ │ │ │ │ │ │ └─► ioctl(DRM_IOCTL_MODE_GETENCODER) │ │ │ │ └─► 获取编码器信息 │ │ │ │ │ │ │ └─► drmModeGetCrtc() │ │ │ │ │ │ │ └─► ioctl(DRM_IOCTL_MODE_GETCRTC) │ │ │ ├─► 获取CRTC状态 │ │ │ └─│ 返回当前配置 │ │ │ │ │ ├─► 获取合成类型变更 │ │ │ │ │ │ │ └─► getChangedCompositionTypes() │ │ │ │ │ │ │ └─► ComposerHal::getChangedCompositionTypes(display, outLayers, │ │ │ outTypes) │ │ │ │ │ │ │ └─► 硬件服务返回合成类型建议 │ │ │ ├─► DEVICE - 硬件合成 │ │ │ ├─► CLIENT - 客户端合成 │ │ │ └─► CURSOR - 光标合成 │ │ │ │ │ ├─► 获取显示请求 │ │ │ │ │ │ │ └─► getDisplayRequests(display, outDisplayRequestMask, │ │ │ outLayers, outLayerRequestMasks) │ │ │ │ │ │ │ └─► 获取显示相关的合成请求 │ │ │ ├─► FLIP_CLIENT_TARGET - 翻转客户端目标 │ │ │ ├─► WRITE_CLIENT_TARGET_TO_OUTPUT - 写入客户端目标 │ │ │ └─► 其他显示请求 │ │ │ │ │ └─► 构建返回结果 │ │ │ │ │ └─► DeviceRequestedChanges │ │ ├─► changedTypes - 图层合成类型变更 │ │ ├─► displayRequests - 显示器请求 │ │ └─► layerRequests - 图层请求 │ │ └─► 执行合成操作 │ ├─► 根据合成类型选择合成方式 │ │ │ ├─► DEVICE合成 (硬件加速) │ │ │ │ │ └─► 直接由硬件合成器处理 │ │ │ │ │ └─► 设置图层层属性 │ │ │ │ │ ├─► setLayerBuffer() │ │ │ │ │ │ │ └─► ComposerHal::setLayerBuffer(display, layer, slot, │ │ │ buffer, acquireFence) │ │ │ │ │ │ │ └─► 硬件服务设置图层缓冲区 │ │ │ │ │ │ │ └─► 关联GEM句柄到图层 │ │ │ │ │ ├─► setLayerCompositionType() │ │ │ │ │ │ │ └─► 设置为DEVICE合成类型 │ │ │ │ │ └─► 其他图层属性设置 │ │ ├─► setLayerDisplayFrame() │ │ ├─► setLayerSourceCrop() │ │ ├─► setLayerBlendMode() │ │ └─► setLayerTransform() │ │ │ └─► CLIENT合成 (软件渲染) │ │ │ └─► GPU渲染流程 │ │ │ └─► RenderEngine::renderLayers() │ │ │ ├─► OpenGL ES渲染 │ │ │ │ │ └─► 使用GPU合成多个图层 │ │ ├─► 图层混合 │ │ ├─► 效果处理 │ │ └─► 生成最终图像 │ │ │ └─► 输出到GraphicBuffer │ │ │ └─► 作为客户端目标提交 │ ├─► 提交显示 │ │ │ └─► SurfaceFlinger::postComposition() │ │ │ └─► HWComposer::presentAndGetReleaseFences(displayId, earliestPresentTime) │ │ │ └─► 显示和获取释放栅栏的详细流程 │ │ │ ├─► 设置客户端目标 │ │ │ │ │ └─► setClientTarget(displayId, slot, acquireFence, target, │ │ dataspace, hdrSdrRatio) │ │ │ │ │ └─► ComposerHal::setClientTarget(display, slot, target, │ │ acquireFence, dataspace, damage, │ │ hdrSdrRatio) │ │ │ │ │ └─► 硬件服务处理客户端目标 │ │ │ │ │ └─► 调用libdrm分配GEM对象 │ │ │ │ │ ├─► 分配GEM缓冲对象 │ │ │ │ │ │ │ └─► drmIoctl(fd, DRM_IOCTL_GEM_CREATE, create) │ │ │ │ │ │ │ └─► 内核创建GEM对象 │ │ │ │ │ │ │ ├─► DRM Core: drm_gem_create() │ │ │ │ │ │ │ │ │ └─► GPU驱动: gem_create() │ │ │ │ ├─► 分配显存 │ │ │ │ ├─► 创建GEM对象 │ │ │ │ └─│ 返回GEM句柄 │ │ │ │ │ │ │ └─► 返回gem_handle │ │ │ │ │ ├─► 映射GEM对象到用户空间 │ │ │ │ │ │ │ └─► drmIoctl(fd, DRM_IOCTL_GEM_MMAP, map) │ │ │ │ │ │ │ └─► 内核处理映射请求 │ │ │ │ │ │ │ ├─► DRM Core: drm_gem_mmap() │ │ │ │ │ │ │ │ │ └─► GPU驱动: gem_mmap() │ │ │ │ ├─► 获取物理地址 │ │ │ │ ├─► 设置页表映射 │ │ │ │ └─│ 返回偏移量 │ │ │ │ │ │ │ └─► mmap()系统调用 │ │ │ │ │ │ │ └─► 映射到用户空间虚拟地址 │ │ │ │ │ │ │ └─► 返回用户空间地址 │ │ │ │ │ ├─► 复制像素数据 │ │ │ │ │ │ │ └─► memcpy(addr, buffer_data, size) │ │ │ │ │ │ │ └─► 将客户端合成的数据复制到GEM缓冲区 │ │ │ │ │ └─► 创建帧缓冲区 │ │ │ │ │ └─► drmModeAddFB(fd, width, height, depth, bpp, │ │ pitch, gem_handle, fb_id) │ │ │ │ │ └─► libdrm/xf86drmMode.c │ │ │ │ │ └─► drmModeAddFB() │ │ │ │ │ ├─► 准备drm_mode_fb_cmd结构 │ │ │ │ │ ├─► ioctl(DRM_IOCTL_MODE_ADDFB, fb_cmd) │ │ │ │ │ └─► 内核创建帧缓冲区 │ │ │ │ │ ├─► DRM Core: drm_mode_addfb() │ │ │ │ │ └─► GPU驱动: 用户空间帧缓冲区接口 │ │ │ │ │ ├─► 关联GEM对象到帧缓冲区 │ │ ├─► 设置帧缓冲区属性 │ │ └─│ 返回帧缓冲区ID │ │ │ │ │ └─► 返回fb_id │ │ │ └─► 显示到屏幕 │ │ │ └─► presentDisplay(displayId, earliestPresentTime) │ │ │ └─► ComposerHal::presentDisplay(display, outPresentFence) │ │ │ └─► AidlComposerHal::presentDisplay(display, outPresentFence) │ │ │ └─► mHal-presentDisplay(display, outPresentFence) │ │ │ └─► 硬件服务执行显示 │ │ │ └─► 厂商实现调用libdrm │ │ │ ├─► 设置显示模式 │ │ │ │ │ └─► drmModeSetCrtc(fd, crtc_id, fb_id, x, y, │ │ connectors, count, mode) │ │ │ │ │ └─► libdrm/xf86drmMode.c │ │ │ │ │ └─► drmModeSetCrtc() │ │ │ │ │ ├─► 准备drm_mode_crtc结构 │ │ │ ├─► 设置帧缓冲区ID │ │ │ ├─► 设置显示位置 │ │ │ ├─│ 设置连接器 │ │ │ └─│ 设置显示模式 │ │ │ │ │ ├─► ioctl(DRM_IOCTL_MODE_SETCRTC, crtc_req) │ │ │ │ │ └─► 内核配置CRTC │ │ │ │ │ ├─► DRM Core: drm_mode_setcrtc() │ │ │ │ │ │ │ └─► GPU驱动: 设置CRTC输出 │ │ │ │ │ │ │ ├─► 配置显示时序 │ │ │ │ ├─► 设置像素时钟 │ │ │ │ ├─│ 设置水平时序 │ │ │ │ ├─│ 设置垂直时序 │ │ │ │ └─│ 其他时序参数 │ │ │ │ │ │ │ ├─► 配置PLL │ │ │ │ ├─► 计算PLL参数 │ │ │ │ ├─│ 设置PLL频率 │ │ │ │ └─│ 锁定PLL │ │ │ │ │ │ │ ├─► 连接帧缓冲区 │ │ │ │ ├─│ 关联FB到CRTC │ │ │ │ └─│ 设置显示地址 │ │ │ │ │ │ │ ├─► 启用编码器 │ │ │ │ ├─│ 配置输出格式 │ │ │ │ ├─│ 设置信号电平 │ │ │ │ └─│ 启用输出驱动器 │ │ │ │ │ │ │ └─► 启用CRTC │ │ │ ├─│ 启用输出信号 │ │ │ ├─│ 开始扫描输出 │ │ │ └─│ 显示生效 │ │ │ │ │ └─► 硬件寄存器编程 │ │ ├─► 显示控制器编程 │ │ ├─► 时钟生成器配置 │ │ ├─► PLL配置 │ │ └─► 输出驱动器使能 │ │ │ └─► 页面翻转 │ │ │ └─► drmModePageFlip(fd, crtc_id, fb_id, flags, user_data) │ │ │ └─► libdrm/xf86drmMode.c │ │ │ └─► drmModePageFlip() │ │ │ ├─► 准备drm_mode_crtc_page_flip结构 │ │ ├─► 设置CRTC ID │ │ ├─► 设置新的帧缓冲区ID │ │ ├─► 设置翻转标志 │ │ │ ├─► DRM_MODE_PAGE_FLIP_EVENT - 事件通知 │ │ │ └─► DRM_MODE_PAGE_FLIP_ASYNC - 异步翻转 │ │ └─│ 设置用户数据 │ │ │ ├─► ioctl(DRM_IOCTL_MODE_PAGE_FLIP, flip_req) │ │ │ └─► 内核执行页面翻转 │ │ │ ├─► DRM Core: drm_mode_page_flip() │ │ │ └─► GPU驱动: 处理页面翻转 │ │ │ ├─► 双缓冲管理 │ │ ├─► 等待VBlank │ │ ├─► 切换前台/后台缓冲区 │ │ └─│ 交换缓冲区指针 │ │ │ ├─► 等待垂直同步 │ │ ├─► 阻塞等待VBlank信号 │ │ ├─│ 获取VBlank时间戳 │ │ └─│ 更新显示时间 │ │ │ └─► 生成释放栅栏 │ │ │ └─► 创建sync_file │ │ │ └─► 用于同步GPU操作 │ └─► 清理和释放资源 │ ├─► drmModeRmFB(fd, fb_id) │ │ │ └─► libdrm/xf86drmMode.c │ │ │ └─► drmModeRmFB() │ │ │ ├─► ioctl(DRM_IOCTL_MODE_RMFB, fb_id) │ │ │ └─► 内核删除帧缓冲区 │ │ │ └─► DRM Core: drm_mode_rmfb() │ │ │ └─► GPU驱动: 释放帧缓冲区资源 │ ├─│ 取消GEM对象关联 │ ├─│ 释放GEM对象 │ └─│ 更新资源状态 │ ├─► munmap(addr, size) │ │ │ └─► 解除用户空间映射 │ │ │ └─► 内核处理munmap │ │ │ └─► 释放页表映射 │ └─► drmClose(fd) │ └─► 关闭DRM设备文件描述符 │ └─► 释放设备资源4. 关键代码片段分析4.1 HWComposer 初始化代码片段// HWComposer.cpp 中的初始化代码HWComposer::HWComposer(std::unique_ptrHwc2::Composercomposer):mComposer(std::move(composer)),mMaxVirtualDisplayDimension(static_castsize_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_enableds,true)){}HWComposer::HWComposer(conststd::stringcomposerServiceName):HWComposer(Hwc2::Composer::create(composerServiceName)){}voidHWComposer::setCallback(HWC2::ComposerCallbackcallback){loadCapabilities();loadLayerMetadataSupport();loadOverlayProperties();loadHdrConversionCapabilities();if(mRegisteredCallback){ALOGW(Callback already registered. Ignored extra registration attempt.);return;}mRegisteredCallbacktrue;mComposer-registerCallback(callback);}4.2 显示设备分配代码片段voidHWComposer::allocatePhysicalDisplay(hal::HWDisplayId hwcDisplayId,PhysicalDisplayId displayId){mPhysicalDisplayIdMap[hwcDisplayId]displayId;if(!mPrimaryHwcDisplayId){mPrimaryHwcDisplayIdhwcDisplayId;}autodisplayDatamDisplayData[displayId];autonewDisplaystd::make_uniqueHWC2::impl::Display(*mComposer.get(),mCapabilities,hwcDisplayId,hal::DisplayType::PHYSICAL);newDisplay-setConnected(true);displayData.hwcDisplaystd::move(newDisplay);}4.3 设备组合变更获取代码片段status_tHWComposer::getDeviceCompositionChanges(HalDisplayId displayId,boolframeUsesClientComposition,std::optionalstd::chrono::steady_clock::time_pointearliestPresentTime,nsecs_t expectedPresentTime,Fps frameInterval,std::optionalDeviceRequestedChanges*outChanges){RETURN_IF_INVALID_DISPLAY(displayId,BAD_VALUE);autodisplayDatamDisplayData[displayId];prepareClientTarget(displayData,frameUsesClientComposition,earliestPresentTime,expectedPresentTime,frameInterval);std::vectorLayer*changedLayers;std::vectorCompositioncompositionTypes;uint32_tdisplayRequestMask0;std::vectorLayer*requestedLayers;std::vectoruint32_tlayerRequestMasks;autoerrordisplayData.hwcDisplay-validateAndGetChangedCompositionTypes(earliestPresentTime,expectedPresentTime,frameInterval,changedLayers,compositionTypes,displayRequestMask,requestedLayers,layerRequestMasks);if(errorhal::Error::NONE){DeviceRequestedChanges changes;changes.changedTypesbuildChangedTypesMap(changedLayers,compositionTypes);changes.displayRequestsdisplayRequestMask;changes.layerRequestsbuildLayerRequestsMap(requestedLayers,layerRequestMasks);// 获取客户端目标属性hal::V3_0::ClientTargetPropertyWithBrightness clientTargetProperty;errormComposer-getClientTargetProperty(displayData.hwcDisplay-getId(),clientTargetProperty);if(errorhal::Error::NONE){changes.clientTargetPropertyclientTargetProperty;}*outChangeschanges;}returnstatic_caststatus_t(error);}4.4 显示和栅栏获取代码片段status_tHWComposer::presentAndGetReleaseFences(HalDisplayId displayId,std::optionalstd::chrono::steady_clock::time_pointearliestPresentTime){RETURN_IF_INVALID_DISPLAY(displayId,BAD_VALUE);autodisplayDatamDisplayData[displayId];autoerrordisplayData.hwcDisplay-present(earliestPresentTime);if(error!hal::Error::NONE){RETURN_IF_HWC_ERROR(error,displayId,UNKNOWN_ERROR);}returnOK;}5. libdrm 调用序列图SurfaceFlinger HWComposer ComposerHal 硬件服务 libdrm 内核DRM │ │ │ │ │ │ │ │ │ │ │ │ ├─ init() │ │ │ │ │ │ │ │ │ │ │ │ ├─ create() ────────┤ │ │ │ │ │ │ ├─ create() ──────────┤ │ │ │ │ │ │ ├─ connect() ──────┤ │ │ │ │ │ │ ├─ drmOpen() ──────┤ │ │ │ │ │ │ ├─ open() │ │ │ │ │ │ │ ├─ 设备节点 │ │ │ │ │ │ └─ 返回fd │ │ │ │ │ ├─ 返回fd │ │ │ │ │ │ │ │ │ │ │ ├─ drmGetVersion() ─┤ │ │ │ │ │ │ ├─ ioctl(VERSION) │ │ │ │ │ │ │ ├─ 返回驱动信息 │ │ │ │ │ │ └─ 返回版本 │ │ │ │ │ ├─ 返回版本 │ │ │ │ │ │ │ │ │ │ │ ├─ drmModeGetResources() ────────────┤ │ │ │ │ │ │ ├─ 查询资源数量 │ │ │ │ │ │ ├─ 返回资源列表 │ │ │ │ │ │ └─ 构建资源结构 │ │ │ │ │ ├─ 返回资源信息 │ │ │ │ │ │ │ │ │ │ │ ├─ drmModeGetConnector() ──────────┤ │ │ │ │ │ │ ├─ 查询连接器状态 │ │ │ │ │ │ ├─ 获取支持模式 │ │ │ │ │ │ └─ 返回连接器信息 │ │ │ │ │ ├─ 返回连接器信息 │ │ │ │ │ │ │ │ │ │ │ ├─ drmModeGetEncoder() ────────────┤ │ │ │ │ │ │ ├─ 查询编码器信息 │ │ │ │ │ │ └─ 返回编码器信息 │ │ │ │ │ ├─ 返回编码器信息 │ │ │ │ │ │ │ │ │ │ │ ├─ drmModeGetCrtc() ───────────────┤ │ │ │ │ │ │ ├─ 查询CRTC状态 │ │ │ │ │ │ └─ 返回CRTC信息 │ │ │ │ │ ├─ 返回CRTC信息 │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ commit() │ │ │ │ │ │ │ │ │ │ │ ├─ getDeviceCompositionChanges() ──────────────┤ │ │ │ │ │ │ │ │ │ │ │ ├─ validateDisplay() ─┤ │ │ │ │ │ ├─ 重复上述资源查询 │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ setClientTarget() ───┤ │ │ │ │ │ ├─ setClientTarget() ─┤ │ │ │ │ │ ├─ 分配GEM对象 │ │ │ │ │ │ ├─ drmIoctl(GEM_CREATE) ──────────┤ │ │ │ │ │ ├─ 创建GEM对象 │ │ │ │ │ ├─ 分配显存 │ │ │ │ │ └─ 返回GEM句柄 │ │ │ │ │ │ │ │ │ ├─ drmIoctl(GEM_MMAP) ────────────┤ │ │ │ │ │ ├─ 映射GEM对象 │ │ │ │ │ ├─ 设置页表 │ │ │ │ │ └─ 返回偏移量 │ │ │ │ │ │ │ │ │ ├─ mmap() ─────────┤ │ │ │ │ │ │ ├─ 映射到用户空间 │ │ │ │ │ └─ 返回用户地址 │ │ │ │ │ │ │ │ │ ├─ drmModeAddFB() ─────────────────┤ │ │ │ │ │ ├─ 创建帧缓冲区 │ │ │ │ │ ├─ 关联GEM对象 │ │ │ │ │ └─ 返回FB ID │ │ │ │ │ │ │ │ │ │ │ │ ├─ presentAndGetReleaseFences() ───────────────┤ │ │ │ │ │ │ │ │ │ │ │ ├─ presentDisplay() ─┤ │ │ │ │ │ │ │ │ │ │ │ ├─ drmModeSetCrtc() ───────────────┤ │ │ │ │ │ ├─ 配置CRTC参数 │ │ │ │ │ ├─ 关联帧缓冲区 │ │ │ │ │ ├─ 设置时序 │ │ │ │ │ └─ 启用输出 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ drmModePageFlip() ────────────┤ │ │ │ │ │ ├─ 请求页面翻转 │ │ │ │ │ ├─ 等待VBlank │ │ │ │ │ ├─ 交换缓冲区 │ │ │ │ │ └─ 释放栅栏 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ 清理资源 │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ drmModeRmFB() ─────────────────┤ │ │ │ │ │ ├─ 删除帧缓冲区 │ │ │ │ │ ├─ 取消GEM关联 │ │ │ │ │ └─ 释放资源 │ │ │ │ │ │ │ │ │ ├─ munmap() ──────┤ │ │ │ │ │ │ ├─ 解除映射 │ │ │ │ │ └─ 释放页表 │ │ │ │ │ │ │ │ │ ├─ drmClose() ────┤ │ │ │ │ │ │ ├─ 关闭设备 │ │ │ │ │ └─ 释放资源

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2633248.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…