Android图像缓存与Surface初始化
- 一.概述
- 二.SurfaceControl的初始化
-
- 1.WMS层SurfaceController的创建
-
- [1.1 Native层SurfaceControl的创建](#1.1 Native层SurfaceControl的创建)
- [1.2 SurfaceFlinger中Layer的创建](#1.2 SurfaceFlinger中Layer的创建)
- [1.3 Native层SurfaceControl的关联](#1.3 Native层SurfaceControl的关联)
- 2.App层SurfaceController的初始化
- 三.Surface的初始化
-
- 1.SurfaceControl对Surface初始化
-
- [1.1 Native层Surface的创建](#1.1 Native层Surface的创建)
- [1.2 Native层Surface的关联](#1.2 Native层Surface的关联)
- 2.BLASTBufferQueue对Surface初始化
-
- [2.1 BLASTBufferQueue的创建](#2.1 BLASTBufferQueue的创建)
- [2.2 图像缓存的生产消费模型的创建](#2.2 图像缓存的生产消费模型的创建)
- [2.3 BLASTBufferQueue中消费者的创建](#2.3 BLASTBufferQueue中消费者的创建)
- [2.4 BLASTBufferQueue中Surface的创建](#2.4 BLASTBufferQueue中Surface的创建)
- [2.5 Surafce初始化Surafce](#2.5 Surafce初始化Surafce)
- 四.总结
-
- 1.Surface与SurfaceControl的初始化时机
- 2.SurfaceControl的初始化
-
- [2.1 概述](#2.1 概述)
- [2.2 过程](#2.2 过程)
- [2.3 Java层SurfaceControl与Native层SurfaceControl的关联](#2.3 Java层SurfaceControl与Native层SurfaceControl的关联)
- [2.4 SurfaceControl与Layer的关系](#2.4 SurfaceControl与Layer的关系)
- [2.5 SurfaceControl的渲染管理](#2.5 SurfaceControl的渲染管理)
- 3.Surface的初始化
-
- [3.1 概述](#3.1 概述)
- [3.2 过程](#3.2 过程)
- [3.3 Java层Surface与Native层Surface的关联](#3.3 Java层Surface与Native层Surface的关联)
- [3.4 BLASTBufferQueue与生产消费模型的关系](#3.4 BLASTBufferQueue与生产消费模型的关系)
- [3.5 Surface的渲染](#3.5 Surface的渲染)
一.概述
在Android系统中,绘制渲染与渲染管理是分开的,分别由Surface和SurfaceControl负责。
Surface是SurfaceFlinger管理的一块缓存,Surface的创建依赖SurfaceControl。SurfaceControl用于管理Surface的绘制层级与获取。
Surface和SurfaceControl声明在ViewRootImpl的全局成员变量中,在创建ViewRootImpl时会一起创建Surface和SurfaceControl。但是此时的Surface和SurfaceControl还没有初始化。
Surface和SurfaceControl的创建发生在App首次收到VSync信号。
当VSync信号到来时,会触发App的绘制流程,这时会调用ViewRootImpl的performTraversals方法,在performTraversals方法中会调用relayoutWindow方法。在ViewRootImpl的relayoutWindow方法中,会对Surface和SurfaceControl进行初始化。
二.SurfaceControl的初始化
IWindow是一个Binder接口,对应的实现为W。IWindow用于App进程感知窗口的变化。WindowManagerService会将窗口的移动、可见行、拖动、尺寸变化、系统弹窗关闭等变化通过IWindow反馈到App进程。
IWindowSession也是一个Binder接口,对应的实现是Session。IWindowSession用于App进程对窗口的管理。
App进程会通过IWindowSession来调用WindowManagerService,实现对窗口的创建、移除、重新测量等操作。
在Session的relayout方法中,会调用WindowManagerService的relayoutWindow方法。
在WindowManagerService的relayoutWindow方法中,主要做了三件事:
1)创建WindowState。WindowState用于记录App进程窗口的各种信息。
WindowManagerService通过WindowState对App进程窗口进行管理。
2)从WindowState中获取WindowStateAnimator。WindowStateAnimator用于处理窗口动画与管理Surface,如窗口的出现、消失、尺寸变化等。
3)创建WindowSurfaceController对SurfaceControl进行初始化。
在WindowManagerService的createSurfaceControl方法中,主要做了两件事:
1)创建WindowSurfaceController。WindowSurfaceController是对SurfaceControl的封装。
2)通过WindowSurfaceController对App层的SurfaceControl初始化。
1.WMS层SurfaceController的创建
在WindowStateAnimator的createSurfaceLocked方法中,会创建WindowSurfaceController。
在WindowSurfaceController的构造方法中,主要做了五件事:
1)保存WindowStateAnimator及其中重要的对象,如WindowServiceManager、WindowState等。
2)通过WindowState获取SurfaceControl.Builder。SurfaceControl.Builder是SurfaceControl提供的构造器,暴露了很多set方法用于配置SurfaceControl。
3)使用构造器对SurfaceControl进行配置,如设置名称、元数据、父节点的SurfaceControl等。
4)如果App开启了BlastBufferQueue,同时系统支持BlastBufferQueue,则设置SurfaceControl开启BlastBufferQueue。
5)根据配置创建WMS层的SurfaceControl。
1.1 Native层SurfaceControl的创建
在SurfaceControl的构造方法中,主要做了两件事:
1)创建 Native层的SurfaceControl,返回Native层SurfaceControl的指针。
2)对Native层SurfaceControl的指针进行保存。
SurfaceControl的nativeCreate方法对应的Native实现是android_view_SurfaceControl的nativeCreate函数。
在nativeCreate函数中,主要做了五件事:
1)获取SurfaceComposerClient对象,它是SurfaceFlinger的Binder的Bp端,通过它可以访问SurfaceFlinger。
2)通过Java层传入的父窗口的SurfaceControl的地址获取父窗口的SurfaceControl,作为创建当前窗口SurfaceControl的参数。
3)声明当前窗口的SurfaceControl。
4)调用SurfaceComposerClient的createSurfaceChecked方法,对当前窗口的SurfaceControl进行赋值及初始化。
5)返回当前窗口的SurfaceControl对应的指针。
ISurfaceComposerClient是SurfaceFlinger提供的Binder类,该接口的bp端实现是SurfaceComposerClient,bn端实现是surfaceflinger目录下的Client。
在SurfaceComposerClient的createSurfaceChecked方法中,主要做了三件事:
1)创建CreateSurfaceResult,CreateSurfaceResult用于保存Layer的相关信息。
2)将CreateSurfaceResult作为参数,调用bn端创建Layer。
3)从CreateSurfaceResult中获取参数,创建Native层的SurfaceControl。LayerHandle用于跨进程获取操作Layer。
1.2 SurfaceFlinger中Layer的创建
在Client的createSurface方法中,主要做了两件事:
1)将创建Layer需要的参数封装成LayerCreationArgs。
2)传入LayerCreationArgs,通过SurfaceFlinger创建Layer。
在SurfaceFlinger的createLayer方法中,会调用createBufferStateLayer方法创建Layer。
在SurfaceFlinger的createBufferStateLayer方法中,主要做了两件事:
1)创建Layer。
2)通过Layer获取LayerHandle,并保存到CreateSurfaceResult的handle中。
1.3 Native层SurfaceControl的关联
当Native层SurfaceControl创建完成时,会返回Native层SurfaceControl的地址到Java层。这时会调用assignNativeObject方法,对Native层SurfaceControl进行关联。
在SurfaceControl的assignNativeObject方法中,主要做了三件事:
1)如果SurfaceControl已经被初始化,则释放已有的Native层SurfaceControl。
2)保存当前的Native层SurfaceControl的地址。
3)如果当前的Native层SurfaceControl有效,则将为它进行注册。用于追踪进程的SurfaceControl。
2.App层SurfaceController的初始化
在WindowSurfaceController创建完成后,会调用getSurfaceControl方法。
在WindowSurfaceController的getSurfaceControl方法中,会调用App层SurfaceControl的copyFrom方法,对WindowSurfaceController中SurfaceControl进行拷贝。
在SurfaceControl的copyFrom方法中,调用nativeCopyFromSurfaceControl方法将WMS层SurfaceControl对应的Native层SurfaceControl指针关联到App层SurfaceControl上。
三.Surface的初始化
在SurfaceControl初始化完成后,会对Surface进行初始化。如果不使用BLASTBufferQueue,则直接使用SurfaceControl对Surface初始化,否则使用BLASTBufferQueue对Surface初始化。
1.SurfaceControl对Surface初始化
在ViewRootImpl的performTraversals方法中,如果App层不使用BLASTBufferQueue,Surface会通过copyFrom方法,使用SurfaceControl进行初始化。
在Surface的copyFrom方法中,主要做了两件事:
1)调用nativeGetFromSurfaceControl方法,创建Native层Surface。
2)保存Native层Surface对应的地址。
1.1 Native层Surface的创建
Surface的nativeGetFromSurfaceControl方法对应在Native层的实现为android_view_Surface的nativeGetFromSurfaceControl函数。
在nativeGetFromSurfaceControl函数中,主要做了三件事:
1)获取Native层的SurfaceControl。
2)通过SurfaceControl获取Surface。
3)将Surface转换成对应的地址并返回。
在SurfaceControl的getSurface方法中,会调用generateSurfaceLocked方法。在SurfaceControl的generateSurfaceLocked方法中,主要做了三件事:
1)为BLASTBufferQueue创建SurfaceControl。
2)创建BLASTBufferQueue。
3)从BLASTBufferQueue中获取Surface。
在BLASTBufferQueue的getSurface方法中,直接创建并返回了BBQSurface。
1.2 Native层Surface的关联
当Native层Surface创建完成时,会返回Native层Surface的地址到Java层。这时会调用updateNativeObject方法,对Native层Surface进行关联。
在Surface的updateNativeObject方法中,主要做了两件事:
1)如果当前Surface已经关联了Native层Surface,则释放已经关联的Native层Surface。
2)保存当前Native层Surface对应的地址。
2.BLASTBufferQueue对Surface初始化
在ViewRootImpl的performTraversals方法中,如果App层使用BLASTBufferQueue,会调用ViewRootImpl的updateBlastSurfaceIfNeeded方法对Surface进行初始化。
在ViewRootImpl的updateBlastSurfaceIfNeeded方法中,主要做了三件事:
1)创建BLASTBufferQueue。
2)从BLASTBufferQueue中获取Surface。
3)使用BLASTBufferQueue的Surface初始化App层Surface。
2.1 BLASTBufferQueue的创建
在BLASTBufferQueue的构造方法中,主要做了两件事:
1)调用重载的BLASTBufferQueue的构造方法,初始化Native层BLASTBufferQueue。
2)更新对SurfaceControl的引用。
BLASTBufferQueue的nativeCreate方法对应的Native实现为android_graphics_BLASTBufferQueue的nativeCreate函数。在nativeCreate函数中,直接创建了Native层的BLASTBufferQueue。
在BLASTBufferQueue的构造方法中,主要做了三件事:
1)创建图像缓存的生产消费模型,对IGraphicBufferProducer和IGraphicBufferConsumer进行赋值及初始化。IGraphicBufferProducer和IGraphicBufferConsumer用于GraphicBuffer缓存的获取与释放。
2)创建消费者。BLASTBufferItemConsumer用于帧缓存的消费,帧缓存BufferItem是对GraphicBuffer的封装。
3)设置图像缓存消费监听,后续绘制完成时会收到回调。
2.2 图像缓存的生产消费模型的创建
在BLASTBufferQueue的createBufferQueue方法中,主要做了三件事:
1)创建BufferQueueCore。BufferQueueCore负责缓冲区的核心调度。
2)创建生产模型IGraphicBufferProducer,对参数进行赋值。
3)创建消费模型IGraphicBufferConsumer,对参数进行赋值。
2.3 BLASTBufferQueue中消费者的创建
BLASTBufferItemConsumer是BLASTBufferQueue中图像缓存生产消费模型中的消费者,继承关系如下图所示:
在创建BLASTBufferItemConsumer时,会调用父类ConsumerBase的构造方法。
在ConsumerBase的构造方法中,主要做了三件事:
1)将ConsumerBase转换为ConsumerListener。
2)将ConsumerListener封装为ProxyConsumerListener。
3)向消费模型注册回调。
IGraphicBufferConsumer的cosumerConnect方法是一个跨进程调。最终会调用BufferQueueConsumer的connect方法。
在BufferQueueConsumer的connect方法中,会将IConsumerListener保存到BufferQueueCore中。
2.4 BLASTBufferQueue中Surface的创建
在ViewRootImpl中,当BLASTBufferQueue创建完毕后,会通过BLASTBufferQueue的createSurface方法创建出BLASTBufferQueue的Surface。
在BLASTBufferQueue的createSurface方法中,会调用nativeGetSurface方法创建Surface。
BLASTBufferQueue的nativeGetSurface方法对应的Native实现为android_graphics_BLASTBufferQueue的nativeGetSurface函数。在nativeGetSurface函数中,主要做了两件事:
1)获取BLASTBufferQueue。
2)通过BLASTBufferQueue获取Native层Surface,创建Java层Surface并绑定Native层Surface。
在BLASTBufferQueue的getSurface方法中,直接创建并返回了BBQSurface。
2.5 Surafce初始化Surafce
在ViewRootImpl中,当BLASTBufferQueue创建完Surafce后,App层Surface会调用transferFrom方法,使用BlastBufferQueue创建的Surface对自身进行初始化。
在Surface的transferFrom方法中,主要做了三件事:
1)获取BLASTBufferQueue创建的Surface中Native层Surface的地址。
2)解除BLASTBufferQueue创建的Surface与Native层Surface的关联。
3)将自身关联到Native层Surface上。
在Surface的setNativeObjectLocked方法中,会将Native层Surface对应的地址保存到全局变量中。
四.总结
1.Surface与SurfaceControl的初始化时机
在Android中,Surface负责绘制渲染,SurfaceControl负责渲染过程的管理。
Surface和SurfaceControl在App进程首次收到VSync信号时在ViewRootImpl中进行初始化。
2.SurfaceControl的初始化
2.1 概述
SurfaceControl的初始化过程本质上是请求WindowManagerService创建Native层SurfaceControl,并与Native层SurfaceControl进行关联的过程。
2.2 过程
在SurfaceControl初始化的过程中,WindowStateAnimator会通过WindowStateAnimator创建WindowSurfaceController。并将WindowSurfaceController中SurfaceControl对应的Native层SurfaceControl与App层SurfaceControl进行关联。
2.3 Java层SurfaceControl与Native层SurfaceControl的关联
Java层SurfaceControl与Native层SurfaceControl的关联本质上是Java层SurfaceControl对native层SurfaceControl地址的保存。
2.4 SurfaceControl与Layer的关系
Native层SurfaceControl的创建会触发SurfaceFlinger创建Layer。Native层SurfaceControl与SurfaceFlinger中的Layer是一一对应的。SurfaceControl通过LayerHandle实现跨进程控制Layer。
2.5 SurfaceControl的渲染管理
SurfaceControl对渲染的管理本质上是对SurfaceFlinger、Layer、BlastBufferQueue的管理。
3.Surface的初始化
3.1 概述
Surface的初始化过程本质上是通过SurfaceControl或BlastBufferQueue创建Native层Surface,并与Native层Surface进行关联的过程。
3.2 过程
在Android 12后,Surface可以选择通过SurfaceControl进行初始化或者通过BlastBufferQueue进行初始化。
但是由于Native层SurfaceControl与Native层BlastBufferQueue是关联在一起的。无论选择哪种初始化方式,实际上都是通过BlastBufferQueue进行初始化。
如果选择通过SurfaceControl进行初始化,那么在Native层SurfaceControl中,会创建Native层BlastBufferQueue。如果选择通过BlastBufferQueue进行初始化,那么Native层BlastBufferQueue会关联Native层SurfaceControl的LayerHandle。
3.3 Java层Surface与Native层Surface的关联
Java层Surface与Native层Surface的关联本质上是Java层Surface对Native层Surface地址的保存。
3.4 BLASTBufferQueue与生产消费模型的关系
Native层BLASTBufferQueue的创建会触发图像生产消费模型的创建。BLASTBufferItemConsumer负责处理图像消费的逻辑。BBQSurface负责处理图像生产的逻辑。
3.5 Surface的渲染
Surface的渲染本质上是对图像生产消费模型中生产者的控制。