Meet the next generation of CarPlay architecture
CarPlay 进阶 20m

下一代 CarPlay 架构详解

Meet the next generation of CarPlay architecture

2024年6月10日

在 Apple 官方观看视频

一句话判断

下一代 CarPlay 的技术架构从”iPhone 投屏到单屏”进化到”多屏多层混合渲染”,通过 Remote UI、Local UI、Punch-through UI 和 Overlay UI 四层架构实现了跨源(iPhone + 车机)无缝合成的驾驶界面。

这场 Session 讲了什么

CarPlay 自发布以来,汽车本身发生了很大变化——屏幕更大、数量更多、功能更丰富。下一代 CarPlay 的目标是为所有驾驶员屏幕提供内容:仪表盘、中控、副驾屏等,形成完全集成的界面。

架构层面,最大的变化是从单视频流扩展到多流。传统 CarPlay 只需要 iPhone 输出一个视频流到车载系统解码显示。下一代 CarPlay 需要为车内每个屏幕各提供一个独立的 iPhone 视频流。

UI 被拆分为四层。Overlay UI 是最顶层,包含车辆特定的警告灯和关键指示器,完全由车机系统渲染。Remote UI 是 iPhone 提供的丰富内容层,地图、音频、胎压、行程信息都在这里。Local UI 是车机本地渲染的驾驶相关仪表和指示器,特点是低延迟、抗 Wi-Fi 干扰、快速启动。Punch-through UI 允许将车辆特有的 UI(如驾驶辅助、外部摄像头)无缝嵌入体验中。

这四层由一个专用合成器(Compositor)统一处理,它接收 iPhone 视频流、本地渲染 UI 和 Punch-through UI,用 OpenGL 合成为统一输出帧,再交给系统合成器显示到每个屏幕上。

值得深挖的点

帧级同步:让多源渲染看起来像一个整体

四层 UI 有的是 iPhone 远程渲染的,有的是车机本地渲染的,如何让它们看起来天衣无缝?答案是帧级同步(Frame Level Synchronization)。

每一帧 iPhone 远程渲染的视频都携带一个 presentation timestamp(展示时间戳),指定它应该在何时被展示给驾驶员。下一代 CarPlay 新增了一个从 iPhone 到每个屏幕的低延迟通道叫 UI sync。iPhone 通过这个通道精心编排 UI 元素在屏幕上的过渡动画,不管是哪个渲染源产生的。

车机端的行为脚本(behavior scripts)解析这些同步信息,将 Local UI、Punch-through UI 和 Remote UI 的帧逐一匹配,以 60fps 甚至更高帧率同步合成。车厂在这其中的角色至关重要——需要确保视频帧和 UI sync 数据包在整个系统中及时传递,并保留相关联的时间戳。

Local UI 的渲染机制

Local UI 解决了一个实际问题:当 iPhone 还没连接上的时候,仪表盘也得有内容显示。车门打开、驾驶员走近的瞬间,屏幕就得亮起来,这时候可能 iPhone 还没被检测到。

Local UI 基于一个 OpenGL 渲染器在车机端运行,配合资源包(asset package)工作。资源包包含图像和行为脚本,脚本实现了生成 UI 的逻辑。每个车型的资源包是定制的,在配对时从 iPhone 传输到车机。使用前车机会验证资源包的真实性。这个机制既带来了本地渲染的全部好处,又开放了 UI 随时间刷新的可能性——车厂可以通过 iPhone 端更新来推送新的仪表盘样式。

代码片段

UI 层次结构概念模型

// 下一代 CarPlay 的 UI 层次(概念模型,非实际 API)
// 从底到顶的四层架构

struct NextGenCarPlayUI {
    // 第 1 层:Remote UI - iPhone 视频流
    // 包含地图、音频、胎压、行程信息等
    // 每个屏幕一个独立的视频流
    let remoteUIStreams: [DisplayID: VideoStream]
    
    // 第 2 层:Local UI - 车机本地渲染
    // 低延迟仪表、指示器
    // 使用 OpenGL 渲染器 + 资源包 + 行为脚本
    let localUIRenderer: LocalOpenGLRenderer
    let assetPackage: VehicleAssetPackage
    
    // 第 3 层:Punch-through UI - 车辆特有功能
    // 驾驶辅助、外部摄像头等视觉丰富功能
    let punchThroughUI: [DisplayID: VehicleFeature]
    
    // 第 4 层:Overlay UI - 车机系统直接合成
    // 警告灯、关键指示器
    let overlayUI: OverlayElements
}

合成器工作流程

// 合成器将三层合成为统一帧(概念示意)
func composeFrame(for display: DisplayID) -> Frame {
    // 1. 获取 iPhone 视频帧(带 presentation timestamp)
    let remoteFrame = remoteUIStreams[display]?.currentFrame
    
    // 2. 获取本地渲染 UI
    let localFrame = localUIRenderer.render(
        assets: assetPackage,
        sync: uiSyncChannel.latestSync
    )
    
    // 3. 获取 Punch-through UI(如果有)
    let punchThrough = punchThroughUI[display]?.render()
    
    // 4. OpenGL 合成为统一帧
    var composited = compositor.combine(
        remote: remoteFrame,
        local: localFrame,
        punchThrough: punchThrough
    )
    
    // 5. Overlay UI 由系统合成器在最上层处理
    // 不在这个合成器的职责范围内
    return composited
}

UI sync 同步机制

// iPhone 端发送 UI sync 数据包
// 每个显示屏幕一个专用低延迟通道

UI Sync Channel:
  - 目标: 让 iPhone 精确编排 UI 过渡
  - 内容: 布局过渡参数、动画编排指令
  - 频率: 60fps+(取决于屏幕能力)
  
工作流程:
  1. iPhone 渲染帧 + 附加 presentation timestamp
  2. 通过 UI sync 通道发送编排指令到车机
  3. 行为脚本解析指令,匹配本地帧和远程帧
  4. 合成器按 timestamp 同步输出

坑点:行为脚本的执行必须严格遵循 timestamp,如果车机端处理延迟导致帧不匹配,会出现画面撕裂或动画卡顿。车厂需要确保视频帧和 UI sync 数据包的传输路径足够短。

最佳实践

对于车厂开发者,理解这四层架构的职责划分是关键。Overlay UI 完全由你们控制,包括警告灯重新设计和位置调整。Local UI 需要实现 OpenGL 渲染器并处理资源包的验证和加载。Punch-through UI 是你们展现车辆差异化功能的机会,但要注意过渡动画要与整体体验保持一致。帧级同步是整个系统最核心的要求——确保数据传输路径低延迟、timestamp 保留完整,这是用户体验的基础。

还有什么值得关注

  • 下一代 CarPlay 是纯无线体验,稳定性和性能是关键,重新连接必须无缝
  • 资源包在配对时从 iPhone 传输,支持后续通过 iPhone 更新推送 UI 刷新
  • 所有层的合成最终由车机端的专用合成器完成,合成器基于 OpenGL 实现
WWDC 2024