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。它是一块可以被跨进程共享的、专门用于图形数据的内存。你可以简单地把它理解为一幅"纹理 "或"像素缓冲区 "的抽象。常见的SurfaceTextureImageReader获取到的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. 应用通过CanvasRenderNode(高级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,到最终屏幕显示之间,数据如何从指令变为像素,并被系统管理合成的完整路径。

相关推荐
stevenzqzq1 天前
ctrl +B和ctrl+shift +B的区别
android·ide·android studio
似霰1 天前
HIDL Hal 开发笔记5----Same-Process HALs 实例分析
android·framework·hal
robotx1 天前
安卓16 设置壁纸中应用网格,有两个5X5的选项
android
Yyuanyuxin1 天前
保姆级学习开发安卓手机软件(三)--安装模拟机并开始简单的进入开发
android·学习
Android小码家1 天前
llama.cpp+Android应用定制
android·llama
龚礼鹏1 天前
Android应用程序 c/c++ 崩溃排查流程二——AddressSanitizer工具使用
android·c语言·c++
Android-Flutter1 天前
android compose DropdownMenu 菜单项列表 使用
android
青莲8431 天前
Java内存模型(JMM)与JVM内存区域完整详解
android·前端·面试
林栩link1 天前
【车载Android】「场景引擎」设计思路分享
android