Android图像缓存与Surface初始化

Android图像缓存与Surface初始化

  • 一.概述
  • 二.SurfaceControl的初始化
  • 三.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的渲染本质上是对图像生产消费模型中生产者的控制。

相关推荐
SY.ZHOU44 分钟前
Flutter 与原生通信
android·flutter·ios
Wgllss1 小时前
Android监听开机自启,是否在前后台,锁屏界面,息屏后自动亮屏,一直保持亮屏
android·架构·android jetpack
_一条咸鱼_1 小时前
大厂Android面试秘籍:Activity 组件间通信
android·面试·android jetpack
冉冉同学2 小时前
【HarmonyOS NEXT】解决微信浏览器无法唤起APP的问题
android·前端·harmonyos
韶博雅2 小时前
mysql表类型查询
android·数据库·mysql
studyForMokey3 小时前
【Android学习记录】工具使用
android·学习
小wanga3 小时前
【MySQL】索引特性
android·数据库·mysql
牛了爷爷3 小时前
php伪协议
android·开发语言·php
鸿蒙布道师4 小时前
鸿蒙NEXT开发文件预览工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
鸿蒙布道师4 小时前
鸿蒙NEXT开发全局上下文管理类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei