Apple「随航」的无感体验里,藏着多少流畅的秘密?

Apple「随航」的无感体验里,藏着多少流畅的秘密?

在 WWDC26 发布的 iPadOS 27 与 macOS Golden Gate 中,随航迎来了堪称史诗级的更新 —— 你可以通过 iPad 的触控屏,用手指完整操控随航中的 macOS。某种程度上这也印证了「Apple 即将推出触屏版 MacBook」的传闻。 开发者文档中关于「随航」触控新特性的介绍。  图源:Apple 若你已经加入 iPadOS 以及 macOS 的 Beta 计划,更新至 iPadOS 27 与 macOS Golden Gate 后即可直接在随航功能中体验到这一新特性。经笔者实测,当前 Beta 版本中触控的延迟几乎难以察觉,交互也足够流畅。不过由于 macOS App 大多针对的是键鼠的操作逻辑,大部分 App 尚未针对触控交互进行专门优化,目前大部分的点击与滑动操作,本质上只是由系统转译为相应的鼠标操作。 虽然在现阶段,相信你在体验一段时间后可能还是会更愿意回到传统的键鼠操作。但在高强度使用随航近两年后,笔者对它最深的印象其实只有两个字:无感。有时它的流畅甚至会让我忘记两台设备之间并没有数据线连接。 本文试着从协议、编码、硬件等技术层面入手,为你解析随航功能流畅体验背后的秘密。 什么是随航? 或许有些读者对随航还不太熟悉。简单来说,随航(Sidecar)就是通过无线或有线传输的方式,将你的 iPad 作为 Mac 的扩展显示屏。不需要复杂的 App 连接、也不需要数据线,只需打开 Mac 和 iPad 进行配对,Mac 便拥有了第二块屏幕。 图源:Apple 你可以在 macOS 菜单栏中点击「控制中心 > 屏幕镜像」,然后在「镜像或扩展至」一栏中选择对应的 iPad 来开启随航。Mac 会通过蓝牙查找 iPad,然后以点对点 Wi-Fi 的形式传输画面。 你也可以前往「系统设置 > 显示器」中,在底部选择「镜像或扩展至 iPad」,然后从列表中选择一部 iPad。 连接完成后,iPad 会像普通外接显示器一样出现在 macOS 的显示器设置中,你可以调整它的位置、分辨率以及镜像或扩展方式。这里就不再赘言了。 除此之外,随航也针对 iPad 的特性进行了一些扩展,前文提到的「触控」特性便是其中之一。另外随航从推出之初便支持 Apple Pencil,你可以直接在 iPad 屏幕上使用 Apple Pencil 操作 Mac 应用;在兼容的应用中,压感、倾斜等笔触信息也能得到保留。从某种程度上说,开启随航的 iPad 可以当作一块带屏幕的数位板使用。 若想了解更为详细的内容,如具体的操作以及扩展功能,你可以访问 Apple 官网或查看少数派中有关随航的介绍。 在「随航」成为官方功能之前 从功能和体验层面来说,随航可以说是相当完善,但「让 iPad 变成 Mac 副屏」其实并不是 Apple 首创的想法——事实上,在第一代 iPad 正式发售的当天这一概念便已落地,并以一款 iPad「首发 App」的形式登陆 App Store。 它叫 iDisplay,由 SHAPE Services 开发。 iDisplay 官网(2012) iDisplay 会在 Mac 中安装一套扩展驱动,创建一块系统能够识别的虚拟显示器,再通过 Wi-Fi 将画面发送到 iPad。用户可以像使用普通副屏一样排列两块屏幕,把 Mac 窗口拖到 iPad 上;甚至在遥远的 2010 年,iDisplay 就能「十分先进」地将 iPad 的触摸及键入操作反向传回 Mac。 只是这款诞生于 iPad 发售之初的软件远远谈不上「流畅」,甚至有着堪称灾难的使用体验:无论是繁琐的前期设置、极不稳定的连接,还是动辄数秒的延迟,都表明它更像是一次对新技术的探索,而非成熟的解决方案。 所以同年,Avatron Software 推出了 Air Display。它采用了与 iDisplay 相似的思路,进行了一部分的优化,不过仍称不上「好用」,动态画面仍有不小的延迟。此后几年,围绕「iPad 作为扩展副屏」的解决方案不断涌现,但总体而言,彼时「将 iPad 作为扩展副屏」这个点子在大多数人看来还是一种新奇的功能玩法,或是应急需求,没有人真正将它视作生产力的一部分。 Air Display 演示界面。  图源:MacFormat(YouTube) 读到这相信你也在想:既然「无线」带来了那么多问题,那加上一根线不就行了?巧了,正有一群和你抱有同样想法的前 Apple 工程师。于是 Duet Display 来了。 Duet 官网(2014) 与上述使用过 Wi-Fi 传输的产品不同,Duet Display 须使用 Lightning 或 30 Pin 数据线连接 Mac 与 iPad。得益于有线这一较为稳定的传输方式,Duet Display 打出了「Retina、60 fps、No Lag」的宣传旗号。 但需要注意的是,这里的「有线连接」有别于普通的显示器连接,它并不能直接将 iPad 扩展为一块普通的显示器 —— 因为iPad 不能通过它直接接收 Mac 输出的视频信号,本质上,它只是将数据传输方式从无线改为有线;画面的生成与显示过程仍与先前的软件类似,需要先在 Mac 中创建一块虚拟显示器,再将画面处理后传送至 iPad。 因此 Duet 也并没有像宣传的那么美好:其 Retina 与 60 fps 模式会占用大量 CPU,部分旧款 Mac 仍会出现光标延迟、画面伪影与系统卡顿。所以再后来,市面上又出现了针对将 iPad 扩展为数位板的 Astropad、以及借助 DisplayPort 硬件适配器、让 Mac 将 iPad 识别为「真实外接显示器」的 Luna Display 等产品...... 时至今日,市场上依然活跃着不少第三方随航类软件,其中一些在满足特定需求方面仍有优势,在此暂且按下不表,有兴趣的读者可以根据自己的需求进一步探索。 让我们谈回 Apple。 2019 年 6 月 3 日,Craig Federighi 在 Apple 的 WWDC 2019 上首次公布了一项名为 Sidecar 的新功能,正式将「让 iPad 变成 Mac 副屏」纳入系统功能中。 WWDC19 Keynotes。  图源:Apple 这里有一段颇有意思的小插曲。随航亮相后,Astropad 作为前文介绍的 Astropad Studio 与 Luna Display 背后的团队,很快在官网发文「抗争」,声称 Apple「高度复制」了自己的产品线,并把这次遭遇称为被 Apple Sherlock1。这番指控究竟有多少事实依据,我们便不得而知了。 虽然 Sidecar 在整场发布会中只出现了不足 60 秒,但其中一些有趣的细节仍值得我们探索。毕竟很长一段时间里,Apple 的软件功能似乎都给人一种印象:它们或许未必最早出现,但被 Apple 整合进系统后,往往能呈现出相较第三方要更加完整的体验。 一帧画面的旅程 简单来说,一帧画面要显示在作为 Mac 副屏的 iPad 上,主要需要经过以下几个环节: 虚拟屏幕渲染 画面编码 数据传输 解码显示 前文中提到的 iDisplay、Air Display 等第三方软件,其实已经用上了「虚拟屏幕渲染」的思路。简单来说,它们会先在系统中创建一块虚拟的显示器,并像对待实体显示器一样,为其正常分配桌面空间和分辨率等。此时应用仍然按照正常方式绘制窗口,再由 macOS 中负责管理和合成屏幕画面的 WindowServer 组合成虚拟显示器上的完整画面。 不过这些画面最终不会被送往真正的物理显示接口,而是由系统或第三方软件读取,再进入后续的编码与传输流程。 相比之下,接下来的几个环节的精密协同,才是随航真正与第三方方案拉开差距的地方,也是其能够做到如此流畅的关键。 画面编码 为什么 WindowServer 合成出的画面还不能直接交给 iPad? 传统外接显示器的逻辑其实很简单,GPU 完成一帧画面的渲染与合成后,只需要按照显示器规格生成显示信号,再通过 HDMI、DisplayPort 或 Thunderbolt 等接口送往显示器即可。 但一块高分辨率屏幕每秒产生的数据量远比想象中庞大。做一个并不严谨的计算:以 2388 × 1668 分辨率的画面为例(2018—2022 款 11 英寸 iPad Pro,也是笔者所用的型号),假设每个像素使用 4 字节(RGBA)表示,那么每帧图像所占用的空间大约为 2388 × 1668 × 4 ÷ 1000² ≈ 15.9 MB。如果设备的刷新率为默认的 60Hz,一秒钟产生的原始画面数据便已经接近 1 GB。 对于上述针对外接显示器的有线传输来说,这样的数据量并不是什么大问题。HDMI 2.0 的最高传输带宽可以达到 18 Gbps,而 DisplayPort 1.2 则可以达到 21.6 Gbps,足以承载 4K 60Hz 级别的显示信号。但对于无线传输的随航来说,想要稳定传输如此庞大的原始画面数据显然并不现实。因此在画面离开 Mac 之前,还需要先经过一道关键步骤——编码。 本质上,随航所传输的其实是一条实时视频流,因此它对屏幕画面的压缩也沿用了现代视频 HEVC 编码的基本思路。 HEVC HEVC 是 High Efficiency Video Coding (高效率视频编码)的缩写,你或许对它的另一个名字更熟悉——H.265。它由 ITU-T 与 MPEG 共同制定,可以看作 H.264/AVC 的继任者。HEVC 的核心精髓便是「猜」,用尽可能少的原始画面,推算出接下来的视频内容,从而节省海量的空间。 那上述的「海量」究竟如何量化?简单做个演示,我们可以借助 FFmpeg 对系统 UI 进行无损录屏。在系统「终端」中输入以下指令,查看 FFmpeg 可以调用的视频设备: ffmpeg -hide_banner -f avfoundation -list_devices true -i "" 在输出结果中找到 Capture screen 0,并记下它前面的设备编号: 再输入以下指令开启无损录屏(若 Capture screen 0 指令得到的编号不为 3,则在第三行「3:none」中替换为实际的数字): ffmpeg -f avfoundation -framerate 30 -pixel_format bgr0 -capture_cursor 1 \ -i "3:none" \ -c:v ffv1 -level 3 -coder 1 -context 1 -slicecrc 1 -pix_fmt bgr0 \ "$HOME/Downloads/screen-lossless.mkv" 按 Q 即可停止录制。接下来我们在终端中输入以下命令,将刚刚录制的无损视频压缩为 HEVC: ffmpeg -i "$HOME/Downloads/screen-lossless.mkv" \ -c:v libx265 -preset medium -crf 23 \ -pix_fmt yuv420p \ "$HOME/Downloads/screen-hevc.mp4" 这种视觉上近乎无损的压缩,几乎节省了 99% 的文件体积: 为了模拟使用随航时画面变化更加频繁的场景(如播放视频),笔者在影视飓风官网的「飓风素材库」中下载了 Bo-Kaap-02 这条素材进行演示。 下图为使用 HEVC 压缩前后的首帧对比截图。相信你和我一样,哪怕是将下图铺满全屏,也很难分辨究竟哪边才是原片。 而经过 HEVC 编码后,原本 363.2 MB 的素材只剩下约 2% 的体积: 为了理解这 98% 的数据究竟去了哪里,我们需要先简单了解 HEVC 的编码原理,也就是笔者前文所说的「猜」的过程。 分块 在预测开始前,HEVC 会先将画面划分为一个个编码树单元,也就是 CTU(Coding Tree Unit)。在 HEVC 中,一个 CTU 最多覆盖 64 × 64 个亮度像素,并可以继续通过四叉树结构划分为尺寸更小的编码单元 CU(Coding Unit)。 HEVC分区结构演示。 图源: HHI 这种划分并不是固定的。天空、墙面等颜色和纹理较为平缓的区域,可以保留尺寸较大的 CU;车辆、树木和建筑边缘等细节密集的区域,则往往需要继续向下划分。编码器由此能够根据不同区域的复杂程度,选择更合适的处理粒度。在 StreamEye 中2,这一结构可以被直接观察到。 比如选中画面右侧较为平坦的白墙时,一个 CTU 内只有少量尺寸较大的 CU;切换到细节复杂的塔楼后,分块会明显变得更加密集。 画面右侧白墙构成较为简单,因此 CTU 内部仅经过一次四叉树划分 而塔楼的结构复杂,CTU 中进行了多次分块划分 确定 CU 的大小后,编码器还会为其选择预测方式,并根据需要将其划分为一个或多个预测单元,也就是 PU(Prediction Unit)。接下来,编码器会针对这些区域寻找尽可能接近原始画面的预测结果。而用于预测的信息主要有两个

查看原文