Android里面的layer、DisplayList和hardwarebuffer之间是什么关系

这是一个非常核心的Android图形系统问题。我们可以把它们放在Android图形渲染的流水线中来理解它们的关系。

简单来说,这三者代表了Android图形系统中从绘制命令到最终像素的三个不同层级和阶段:

  1. DisplayList (渲染节点树) :绘制命令的录制与抽象 。它存在于应用进程 的CPU侧。

  2. HardwareBuffer (图形缓冲区) :承载最终像素数据的内存块 。它是跨进程共享 的数据载体。

  3. Layer (图层) :合成系统管理的基本单元 。它存在于系统进程 中,包裹着HardwareBuffer并附加了合成属性。

下面我们展开详细说明,并用一个比喻来串联。


1. DisplayList (渲染列表/渲染节点)

  • 是什么 : DisplayList本质上是一系列绘制操作(如drawRect, drawPath, drawText)的记录或抽象。在Android的硬件加速渲染中,当你的View需要绘制时,它并不会直接操作Canvas去画像素,而是将绘制命令"录制"到一个叫RenderNode的数据结构中(可以理解为一种更先进的DisplayList)。多个RenderNode会组成一棵树,对应View的层级结构。

  • 作用:

    • 避免重复绘制 : 一旦录制完成,如果View的内容没有改变(invalidate),系统可以直接复用之前录制的DisplayList,无需重新执行昂贵的绘制代码。

    • 优化与重排 : 在渲染之前,系统(特别是ThreadedRenderer)可以对这棵RenderNode树进行优化,比如合并绘制操作、离屏渲染等。

    • 转换为GPU指令 : 在渲染阶段,RenderNode树会被遍历,最终转化为一系列GLES/Vulkan命令,交由GPU执行。

  • 所在位置 : 应用进程内部。是CPU侧对绘制内容的描述。

2. HardwareBuffer (硬件缓冲)

  • 是什么 : 这是Android 9 (API 28) 引入的,用于替代GraphicBuffer的公共API。它是一块可以被跨进程共享的、专门用于图形数据的内存。你可以简单地把它理解为一幅"纹理 "或"像素缓冲区 "的抽象。常见的SurfaceTexture、ImageReader获取到的Image,其底层都是HardwareBuffer。

  • 作用:

    • 像素容器 : 它是GPU渲染结果的最终存放地。当RenderNode树被GPU处理完毕后,输出的图像就存放在一个HardwareBuffer中。

    • 跨进程传递 : 它是Android中生产者-消费者模型 的核心。应用(生产者)渲染好的Buffer,需要传递给SurfaceFlinger(消费者)进行合成。HardwareBuffer通过Binder传递其引用,实现了高效零拷贝的跨进程数据共享。

  • 所在位置 : 一块特殊的图形内存(可能是GPU专用内存,也可能是CPU、GPU都能访问的内存),由Gralloc(图形内存分配器) 分配。

3. Layer (图层)

  • 是什么 : Layer是SurfaceFlinger合成系统 中的核心概念。每一个具有图形界面的窗口(如Activity、Dialog、状态栏、导航栏)在SurfaceFlinger中都对应一个或多个Layer。它是合成器管理和操作的最小单位。

  • 作用:

    • 合成元信息 : 一个Layer不仅包含一个HardwareBuffer(即像素数据),还包含了一组合成属性,例如:

      • 位置​ (x, y坐标)

      • 大小

      • Z轴顺序​ (哪个Layer在上,哪个在下)

      • 透明度​ (alpha)

      • 变换矩阵​ (旋转、缩放)

      • 裁剪区域

    • 合成决策: SurfaceFlinger根据所有Layer的属性和Buffer内容,决定如何高效地将它们混合(通过GPU的合成器)成一个最终的帧,送显。

  • 所在位置 : 系统服务进程(system_server)中的SurfaceFlinger服务。


三者的关系与工作流程(比喻)

我们可以用一个电影/动画制作流程来比喻:

  1. DisplayList (剧本和分镜):

    • 这是导演和编剧创作的内容。它详细描述了每个角色(View)在每个场景中应该做什么动作(绘制命令),但本身不是最终的电影画面。这对应了应用端录制RenderNode。
  2. HardwareBuffer (拍好的胶片/视频源文件):

    • 根据剧本,演员和摄影师实际拍摄,生成了包含具体画面的胶片或数字视频文件。这对应了GPU将RenderNode树渲染成一帧帧的图像,存入HardwareBuffer。每一段胶片/每一个视频文件就是一个HardwareBuffer。
  3. Layer (剪辑时间轴上的一个轨道):

    • 在后期剪辑时,剪辑师会把一段视频文件(HardwareBuffer)拖到时间轴的一个轨道上。这个轨道不仅包含了视频内容,还定义了它的出现时间、位置、长度、叠加效果(如透明度、滤镜) 。在Android中,SurfaceFlinger的合成器就像这个剪辑软件,每个Layer就是时间轴上的一个轨道,它"包裹"着视频源文件(HardwareBuffer),并附加了如何呈现的元信息。

技术工作流:

  1. 应用通过Canvas在RenderNode(高级DisplayList)中录制绘制命令。

  2. 应用请求渲染。RenderThread或GPU将RenderNode树执行 ,把光栅化后的像素 输出到该应用窗口对应的Surface所关联的HardwareBuffer中。

  3. 应用通过BufferQueue机制,将已渲染完成的HardwareBuffer入队。

  4. SurfaceFlinger作为消费者,从BufferQueue中出队 这个HardwareBuffer。

  5. SurfaceFlinger将这个HardwareBuffer和窗口的状态(位置、Z序等)一起,更新到对应的Layer对象中。

  6. 在下一个VSync信号到来时,SurfaceFigner遍历所有Layer,根据它们的属性和Buffer内容,调用HWC/GPU进行合成,并将最终结果送到显示设备。

总结与关系图

组件 层级 职责 数据形式
**DisplayList (RenderNode)**​ 应用/CPU 录制、优化绘制命令​ 绘制指令列表
HardwareBuffer​ 系统/GPU内存 承载像素数据,跨进程共享​ 像素内存块
Layer​ 系统服务(SurfaceFlinger) 合成管理单元,附加合成属性​ Buffer + 元信息(矩阵、透明度等)

核心关系:

  • DisplayList 生成 HardwareBuffer: GPU执行DisplayList中的命令,将结果渲染到HardwareBuffer中。

  • HardwareBuffer 是 Layer 的内容: 每个活动的Layer内部都持有一个当前有效的HardwareBuffer。

  • Layer 是合成系统对 HardwareBuffer 的封装与管理: 没有Layer,HardwareBuffer只是一堆孤立的像素;没有HardwareBuffer,Layer只是一个没有内容的空壳。

这个流程清晰地展示了从应用定义UI,到最终屏幕显示之间,数据如何从指令变为像素,并被系统管理合成的完整路径。

相关推荐
三少爷的鞋7 小时前
Java 线程自上而下,Kotlin 协程自下而上
android
好的佩奇8 小时前
Dart 之增强枚举
android·flutter·dart
梦影_9 小时前
MySQL进阶教程(五)—— SQL调优(下)
android·大数据·数据库·后端·sql·mysql·database
好的佩奇11 小时前
蓝牙之无线电与通信距离
android·flutter·蓝牙
vilya11 小时前
我把一套完整的 Python Agent 运行时塞进手机 APK:依赖闭包、Rust 轮子和三个真机坑
android
呆呆敲代码的小Y13 小时前
【实战精选面试题】C# 面试题详细解答,按难易程度排序
android·java·游戏·c#·游戏开发·unity面试题·c#面试题
思想觉悟15 小时前
SEAndroid实战
android·linux·c++
思想觉悟15 小时前
Aosp开发磨刀石之ADB速查
android·c++
应用市场18 小时前
用本机跑的开源音乐模型,给安卓小游戏做 20 秒无缝循环背景音乐
android·python·游戏开发·soundpool·音频处理
企业数字化笔记18 小时前
表单发布前怎么验收?版本引用、字段兼容和历史数据回归
android·数据挖掘·回归