简介
Scenic 是一项系统服务,其主要职责是管理由平台上的所有应用以及 SysUI 共享的全局场景图。此场景图会协调应用在屏幕上显示内容的方式、接收用户输入事件的方式,还支持其他 Fuchsia 系统组件的功能。它是客户端之间几何/拓扑关系的“真相来源”。
景区责任
组合
Scenic 为客户端(应用、SysUI)提供了 API,以便操作全局场景图的子图,该子图的根位于 View。在此子图中,它们可以附加图形内容,并嵌入其他组件提供的 View。这种嵌入是递归的:组件与其父级的链接方式与与其子组件的链接方式相同。
(注意:“父级”和“子级”是指场景图拓扑中的相对位置,可能与组件拓扑不一致)
渲染/显示
为了最大限度地提高效率,Scenic 可以直接将客户端图片呈现给显示控制器,而无需启动 GPU!不过,由于各种原因,这并不总是可行的。Scenic 会在每个帧中动态决定是否可以直接显示客户端提供的图片,还是必须使用 GPU 对其进行合成。
视觉效果
Scenic 负责处理无法嵌入到客户端提供的内容中的视觉效果。例如,Scenic 的(已废弃)GFX API 允许客户将内容插入 3D 场景中,其中不同应用中的对象可以投射阴影并相互反射光线。同样,Flatland 旨在支持“群组不透明度”等效果。
此类效果的列表目前较少,但未来会不断增加。
显示屏管理
Fuchsia 的显示控制器 API 仅限于单个连接的客户端。由于 Scenic 需要以低延迟率在每帧显示内容,因此 Scenic 与显示控制器之间应是唯一的连接。不过,这意味着 Scenic 必须充当需要与显示屏控制器交互的任何其他方的代理。例如,SysUI 必须支持用户执行以下操作: - 查看哪些屏幕已连接 - 为每个屏幕选择分辨率和刷新率 - 在虚拟桌面中排列屏幕的相对位置
帧调度
Scenic、客户端和显示控制器都必须协同工作来调度帧,以尽可能缩短延迟时间、减少内存用量等。Scenic 通过以下方式支持此操作: - 在共享资源可供重复使用时发出通知(例如,当客户端可以安全地渲染到之前使用的缓冲区时) - 传达客户端在下一个 vsync 上呈现内容的截止期限 - 尽早唤醒自己,以执行显示帧的工作,包括: - 原子更新场景图 - 视需要使用 Vulkan 进行渲染 - 告知显示控制器要显示哪些图片
帧调度部分详细介绍了此主题。
输入
应用在场景图中的位置会影响输入事件(例如鼠标触摸事件)如何路由到该应用。例如: - 系统会以视图的坐标系向客户端传送输入事件;Scenic 会将输入流水线中的入站事件转换为适当的坐标系。 - 场景图拓扑中的位置很重要:位于另一个视图“之上”的视图将拥有优先权接收该事件 - 持续的手势(例如“点按并拖动”)会将所有手势事件发送到同一目标视图,即使用户的手指移动到目标视图的边界之外也是如此。
无障碍
Scenic 提供的功能供无障碍功能管理器实现各种功能。例如,Scenic 会公开场景图的全局视图,该视图支持“屏幕阅读器”功能。它还支持放大功能,方便视障用户使用。
诊断
Scenic 提供了诊断接口,可帮助开发者调试模型并衡量性能。
截取屏幕
Scenic 支持单个屏幕截图以及持续的屏幕截图。
场景图 API
Scenic 实现了各种 FIDL 协议,以履行上述职责。由于场景图在其中扮演着核心角色,因此用于操控场景图的 API 是最重要的 API 之一。
两个场景图 API?!为什么?
由于历史原因,Scenic 支持两种不同的类型的场景图,即已废弃的 Gfx API 和更“面向未来”的 Flatland API。因此,当前情况比较复杂。
Scenic 一次只能实例化一个场景图:可以是 Gfx 场景图,也可以是 Flatland 场景图,但不能同时是这两者。
未来的场景图 API
未来,可能会有其他用于操控场景图的 API。不同之处在于,这些 Future API 将被设计为与 Flatland API 很好地组合在一起,而不是每个 API 都引用与其他 API 不兼容的不同类型的场景图。例如,用于对 Flatland 场景图的子树应用模糊处理效果的视觉效果 API。
Scenic 和 Fuchsia
借助 Scenic 的 API,任何客户端都可以将其界面插入全局场景图。使用 Flutter 界面框架的进程就是一个例子;Flutter 的下层(称为 Flutter Engine)包含负责与 Scenic 通信的代码。
Scenic 包含多个内部子系统。Flatland 或 Gfx 中的某个实例会拥有场景图,并负责渲染。Input 负责将输入事件路由到客户端,这还涉及协调各个客户端之间的手势识别,以及管理焦点。
Scene Manager 是一项独立服务,负责呈现系统的界面;它使用 Scenic API 创建 Scenic 场景图的根,嵌入窗口管理器的界面,并使用其输入流水线库读取输入事件,并将其持续转发给 Scenic。
Scenic 是 Vulkan 图形驱动程序和系统显示驱动程序的客户端。
会话
Scenic 的两个组合协议(Flatland 和 Gfx)具有一些共同点,本文将对此进行讨论;如需详细了解其中任一协议,请参阅链接的页面。
在这两种情况下,“会话”都指客户端用于实现以下目标的 FIDL 通道: - 通过与其他会话建立关联(通过相互协定)参与视图树。 - 提供可由父级组件嵌入的视图 - 反之,通过自己的会话嵌入其他组件提供的子视图 - 指定将关联到全局场景图的视觉内容,其中包括: - 图片 - 空间转换 - 视觉效果,例如模糊处理或“群组不透明度” - 将呈现与显示帧速率以及其他组件的会话同步 - 当可以呈现另一帧时,Scenic 中的事件会通知客户端 - 栅栏可让您高效地向/从 Vulkan 等 API 发送信号
会话会提供与全局场景图的“保留模式”连接。例如,如果某个组件处于静态,Scenic 会继续显示其最近提供的帧。
销毁会话后,其与其他会话中的子视图和父视图之间的链接会断开,并且 Scenic 会释放与会话关联的所有内存和其他资源。