android 图像显示框架二——流程分析

一.Android图形组件协作工作

首先先上流程图:

如下是Android12及以后得Android图形组件协作的流程图

上述的图片清晰的展示了Android图形系统最核心的基石------基于BufferQueue的生产者-消费者模式。整个流程是是描述一个图形缓存区(GraphicBuffer)从被绘制到最终被显示出来的完整生命周期。

全景概述:三大角色

整个架构围绕着三大角色展开,对应图中的三个主要部分:

1.图像生产者(Image Producer) :负责**生产(绘制)**图像内容,例如:应用程序、视频解码器。

2.图像消费者(Image Consumer) :负责**使用(消耗)**已生成的图像内容。例如:将图像合成后送到显示屏的SurfaceFlinger。

3.BufferQueue:作为核心中介 ,连接生产者和消费者,它管理着一组图形缓冲区(GraphicBuffer),是数据交换的通道。

模块详解:

1.图像生产者(右侧)

  • **是什么:**所有需要将画面绘制到屏幕上的实体。
  • 常见生产者:
  1. OpenGL ES/Vulkan:3D图形渲染库。
  2. Skia :2D图形绘制库,常用于应用界面绘制。
  3. Decoder:视频解码器,解码视频帧。

2.图像消费者(左侧)

  • **是什么:**获取并使用生产者提交的图像数据实体。
  • 核心消费者:
  1. SurfaceFlinger:Android系统的合成器。它接受多个应用(生产者)的缓冲区,将它们最终合成一帧,然后交个HWComposer显示到屏幕上。
  2. OpenGL ES:在某些情况下(如应用内纹理渲染),它也可以作为消费者。

3.核心枢纽:BufferQueue(中间)

这是整个流程的心脏,它内部包含了三个核心组件,共同管理着缓冲区的一生。

  • BufferQueueCore:
  1. 核心大脑:管理整个队列的状态。
  2. 资源池:持有固定数量的Buffer Slots(缓冲区槽位)和GraphicBuffer对象。GraphicBuffer是真正存储像素数据的内存块。
  3. 状态跟踪:跟踪每个缓冲区的状态(空闲、已排队、已获取)
  • BufferQueueProducer:
  1. 面向生产者的接口:生产者只与它交互
  2. 关键操作:

dequeueBuffer():向生产者分配一个空闲的缓冲区。

queueBuffer():接受生产者已经绘制完成的缓冲区,并将他置于已排队的状态,通知消费者。

  • BufferQueueConsumer:
  1. 面向消费者的接口:消费者只与它打交道
  2. 关键操作:

acquireBuffer():从队列中获取一个已排队的缓冲区,交个消费者使用

releaseBuffer():消费者使用完毕后,将其释放回空闲状态,可供生产者再次使用

缓冲区生命周期与数据流(重点)

让我们跟随一个GraphicBuffer的旅程,对应流程图中的箭头和文字:

1.dequeue(出队):

  • 生产者(如App)通过Surface------>dequeueBuffer()调用BufferQueueProducer。
  • Producer从BufferQueue的缓冲区槽位(Buffer Slots)中找到一个状态为FREE(空闲)的GraphicBuffer,将其状态改为DEQUEUED,并返回给生产者。

2.生产/渲染:

  • 生产者获取到GraphicBuffer后,使用OpenGL ES或者Skia等库在其上进行绘制,填充图像数据。

3.queue(入队):

  • 绘制完成后,生产者调用Surface------>queueBuffer()。
  • Producer将该GraphicBuffer的状态改成QUEUED(已排队),并将其放入队列中。同时,通过回调通知消费者:"有新的数据可以用了!"

4.acquire(获取):

  • 消费者(如SurfaceFlinger)被唤醒,调用acquireBuffer()。
  • BufferQueueConsumer从队列中取出一个QUEUED状态的缓冲区,将其状态改成ACQUIRED(已获取),然后交给消费者

5.消费(合成/显示):

  • 消费者对获取的缓冲区内容进行处理,对于SurfaceFlinger来说,就是将多个应用的缓冲区合成最终的画面

6.release(释放):

  • 消费者使用完毕后,调用releaseBuffer()。
  • Consumer将该GraphicBuffer的状态重置为FREE(空闲),并将其放会空闲池。
  • 此时,这个缓冲区又可以再次被生产者dequeue,开始新一轮的循环。

关键技术与进阶概念

1.同步机制-Fence(栅栏)

图中箭头旁的acquire和release信号,在实际实现中通常与Fence机制紧密相关。

  • 为什么需要:GPU渲染是异步的。当生产者queueBuffer是,GPU的渲染指令可能还没有真正执行完。直接让消费者读取可能读取不到完整的帧。
  • 如何工作:生产者提交缓冲区时,会附带一个Fence。消费者在acquire缓冲区后,会等待这个Fence发出"信号"(表示GPU渲染完成),才去读取缓冲区内容。这保证了数据同步,避免屏幕撕裂

2.BLASTBufferQueue(Buffer Latency and Synchronization Task)

  • 是什么:Android10/11中引入的现代化BufferQueue。
  • 解决什么问题:传统的Surface和BufferQueue是一对一绑定的。一个窗口(如Activity)通常只有一个Surface,这限制了性能(例如:难以实现无缝转场动画)
  • 优势:BLASTBufferQueue允许一个窗口管理多个缓冲区会话,提供了更加精细、更加灵活的缓冲区控制,显著改善了应用切换、分屏和动画的流畅度。可以看做是BufferQueue的增强版。

总结:

这张图精妙的描绘出Android图形系统解耦和异步处理的核心思想:

  • 解耦:生产者(App)和消费者(SurfaceFlinger)不需要知道对方的存在,也不需要同步工作。它们只与BufferQueue交互,从而可以独立、高效运行。
  • 流水线:通过缓冲区队列,实现了"绘制一帧"和"显示一帧"的并行操作。当消费者正在显示第N帧时,生产者可能已经在绘制第"N+1"帧了。这是Android系统保持界面流畅的关键。
相关推荐
帅锅锅0071 小时前
Android 源码学习之init进程
android·架构·操作系统
聆风吟º1 小时前
【Spring Boot 报错已解决】Spring Boot开发避坑指南:Hibernate实体类主键配置详解与异常修复
android·spring boot·hibernate
APP出海2 小时前
Google政策大更新:涉及金融(个人贷款),社交约会与游戏(未成年人相关),健康等所有类别App
android·游戏·金融·产品运营·产品经理
全栈软件开发3 小时前
音频在线剪切助手网页版源码
android·音视频
2501_915909063 小时前
Flutter 应用怎么加固,多工具组合的工程化实战(Flutter 加固/Dart 混淆/IPA 成品加固/Ipa Guard + CI)
android·flutter·ios·ci/cd·小程序·uni-app·iphone
qq_717410014 小时前
添加快速点击设置-关于设备-版本号弹出仿android13彩蛋
android
KdanMin4 小时前
Android MediaCodec 硬编解码实战:从Camera预览到H264流与回环渲染
android·开发语言
峰哥的Android进阶之路4 小时前
Android常见的内存性能优化场景解决方案
android·性能优化
清空mega4 小时前
第三章 Android常见界面控件
android·gitee
JoyCong19985 小时前
智能手机市场再次洗牌,远控何以成为数码生活新“连接器”?
android·智能手机·电脑·生活·远程工作·远程操作