Android图像缓存与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的渲染本质上是对图像生产消费模型中生产者的控制。

相关推荐
Be_Somebody2 分钟前
[这可能是最好的Spring教程!]Maven的模块管理——如何拆分大项目并且用parent继承保证代码的简介性
java·spring boot·spring·spring入门
一个数据小开发19 分钟前
业务开发问题之ConcurrentHashMap
java·开发语言·高并发·map
会飞的架狗师35 分钟前
【Spring】Spring框架中有有哪些常见的设计模式
java·spring·设计模式
Jakarta EE1 小时前
在JPA和EJB中用乐观锁解决并发问题
java
七月.末1 小时前
安卓aab包的安装教程,附带adb环境的配置
android·adb
花心蝴蝶.1 小时前
并发编程中常见的锁策略
java·jvm·windows
A_cot1 小时前
一篇Spring Boot 笔记
java·spring boot·笔记·后端·mysql·spring·maven
tryCbest2 小时前
java8之Stream流
java·后端
江梦寻3 小时前
解决SLF4J: Class path contains multiple SLF4J bindings问题
java·开发语言·spring boot·后端·spring·intellij-idea·idea
鸡鸭扣3 小时前
springboot苍穹外卖实战:五、公共字段自动填充(aop切面实现)+新增菜品功能+oss
java·spring boot·后端