SurfaceFlinger 和 WindowManager

SurfaceFlinger 接受缓冲区、合成缓冲区并将缓冲区发送到显示屏。WindowManager 向 SurfaceFlinger 提供缓冲区和窗口元数据,SurfaceFlinger 使用这些数据将表面合成到显示屏。

SurfaceFlinger

SurfaceFlinger 可以通过两种方式接受缓冲区:通过 BufferQueue 和 SurfaceControl,或通过 ASurfaceControl。

SurfaceFlinger 接受缓冲区的一种方式是通过 BufferQueue 和 SurfaceControl。当应用进入前台时,它会从 WindowManager 请求缓冲区。然后,WindowManager 从 SurfaceFlinger 请求一个图层。图层是 surface(包含 BufferQueue)和 SurfaceControl(包含图层元数据,例如显示帧)的组合。SurfaceFlinger 创建图层并将其发送到 WindowManager。然后,WindowManager 将 surface 发送到应用,但保留 SurfaceControl 以操纵应用在屏幕上的外观。

Android 10 添加了 ASurfaceControl,这是 SurfaceFlinger 可以接受缓冲区的另一种方式。ASurfaceControl 将 surface 和 SurfaceControl 组合到一个事务包中,该事务包被发送到 SurfaceFlinger。ASurfaceControl 与一个图层相关联,应用通过 ASurfaceTransactions 更新该图层。然后,应用通过回调获取有关 ASurfaceTransactions 的信息,回调传递包含信息的 ASurfaceTransactionStats,例如锁定时间、获取时间等等。

下表包含有关 ASurfaceControl 及其相关组件的更多详细信息。

组件 描述
ASurfaceControl 封装 SurfaceControl 并使应用能够创建与显示屏上的图层相对应的 SurfaceControl。

可以创建为 ANativeWindow 的子项,也可以创建为另一个 ASurfaceControl 的子项。
ASurfaceTransaction 封装 Transaction 以使客户端能够编辑图层的描述性属性(例如几何形状),并将更新后的缓冲区发送到 SurfaceFlinger。
ASurfaceTransactionStats 通过预注册的回调向应用发送有关已呈现事务的信息,例如锁定时间、获取时间和之前的释放栅栏。

虽然应用可以随时提交缓冲区,但 SurfaceFlinger 仅在显示屏刷新之间唤醒以接受缓冲区,刷新频率可能因设备而异。这可以最大限度地减少内存使用,并避免屏幕上出现可见的撕裂现象,这种现象可能在刷新期间更新显示屏时发生。

当显示屏处于刷新之间时,显示屏会向 SurfaceFlinger 发送 VSYNC 信号。VSYNC 信号表示显示屏可以在没有撕裂的情况下刷新。当 SurfaceFlinger 接收到 VSYNC 信号时,SurfaceFlinger 会遍历其图层列表以查找新的缓冲区。如果 SurfaceFlinger 找到新的缓冲区,SurfaceFlinger 会获取该缓冲区;否则,SurfaceFlinger 继续使用之前获取的缓冲区。SurfaceFlinger 必须始终显示某些内容,因此它会保留一个缓冲区。如果从未在图层上提交过缓冲区,则会忽略该图层。

在 SurfaceFlinger 收集完所有可见图层的缓冲区后,它会询问硬件合成器 (HWC) 应如何执行合成。如果 HWC 将图层合成类型标记为客户端合成,则 SurfaceFlinger 会合成这些图层。然后,SurfaceFlinger 将输出缓冲区传递给 HWC

WindowManager

WindowManager 控制 window 对象,window 对象是 view 对象的容器。Window 对象始终由 surface 对象支持。WindowManager 负责管理窗口的生命周期、输入和焦点事件、屏幕方向、过渡、动画、位置、变换、Z 顺序以及许多其他方面。WindowManager 将所有窗口元数据发送到 SurfaceFlinger,以便 SurfaceFlinger 可以使用这些数据在显示屏上合成 surface。

预旋转

许多硬件叠加层不支持旋转(即使支持,也会消耗处理能力);解决方案是在缓冲区到达 SurfaceFlinger 之前对其进行变换。Android 在 ANativeWindow 中支持查询提示 (NATIVE_WINDOW_TRANSFORM_HINT),以表示 SurfaceFlinger 最有可能应用于缓冲区的变换。GL 驱动程序可以使用此提示在缓冲区到达 SurfaceFlinger 之前对其进行预变换,以便缓冲区到达时已正确变换。

例如,当收到旋转 90 度的提示时,生成矩阵并将其应用于缓冲区,以防止缓冲区超出页面末尾。为了节省电量,请执行此预旋转。有关详细信息,请参阅 system/core/include/system/window.h 中定义的 ANativeWindow 接口。