Android 图形系统概述

易百纳技术社区 2020-11-10 19:30:00 3003

图形系统是 Android 中非常重要的子系统,与其他子系统相互协作,完成图形界面的渲染和显示。

概述

官方提供了一个图形系统的关键组件协作图,如下所示:

Android官方图形架构

这幅图大致描述了图形数据的流转:OpenGL ES、MediaPlayer 等生产者生产图形数据到 Surface,Surface 通过 IGraphicBufferProducer把 GraphicBuffer 跨进程传输给消费者SurfaceFlinger。

SurfaceFlinger 根据 WMS 提供的窗口信息合成所有的 Layer(对应于 Surface ),具体的合成策略由 hwcomposerHAL 模块决定并实施,最后也是由该模块送显到 Display,而 Gralloc 模块则负责分配图形缓冲区。

不过该图缺乏层次感,通过下图我们详细分析整个流程。

图形系统架构

大体上,应用开发者可以通过两种方式将图像绘制到屏幕上:

Canvas

OpenGL ES

Canvas 是一个2D图形 API ,是 Android View 树实际的渲染者。Canvas 又可分为Skia 软件绘制和 hwui 硬件加速绘制。

Android 4.0 之前默认是 Skia 绘制,该方式完全通过 CPU 完成绘图指令,并且全部在主线程操作,在复杂场景下单帧容易超过16ms导致卡顿。

从 Android 4.0 开始,默认开启硬件加速渲染,而且 5.0 开始把渲染操作拆分到了两个线程:主线程和渲染线程,主线程负责记录渲染指令,渲染线程负责通过 OpenGL ES 完成渲染,两个线程可以并发执行。

除了Canvas,开发者还可以在异步线程直接通过 OpenGL ES 进行渲染,一般适用于游戏、视频播放等独立场景。

从应用侧来看,不管是 Canvas ,还是 OpenGL ES,最终渲染到的目标都是 Surface ,现在比较流行的跨平台UI框架 Flutter 在 Android 平台上也是直接渲染到 Surface 。

Surface是一个窗口,例如:一个Activity是一个Surface、一个Dialog也是一个Surface,承载了上层的图形数据,与SurfaceFlinger侧的Layer相对应。

Native层Surface实现了ANativeWindow结构体,在构造函数中持有一个IGraphicBufferProducer,用于和 BufferQueue 进行交互。

BufferQueue 是连接 Surface 和 Layer 的纽带,当上层图形数据渲染到 Surface 时,实际是渲染到了BufferQueue中的一个GraphicBuffer,然后通过IGraphicBufferProducer 把 GraphicBuffer 提交到 BufferQueue ,让 SurfaceFlinger 进行后续的合成显示工作。

SurfaceFlinger 负责合成所有的 Layer 并送显到 Display ,这些Layer主要有两种合成方式:

OpenGL ES:把这些图层合成到 FrameBuffer,然后把FrameBuffer提交给hwcomposer 完成剩余合成和显示工作。

hwcomposer:通过HWC模块合成部分图层和FrameBuffer,并显示到Display。

BufferQueue

Android 图形系统包含了两对生产者和消费者模型,它们都通过 BufferQueue 进行连接:

Canvas 和 OpenGL ES 生产图形数据,SurfaceFlinger消 费图形数据。

SurfaceFlinger合成所有图层的图形数据,Display显示合成结果。

Surface属于APP进程,Layer属于系统进程,如果它们之间只用一个Buffer,那么必然存在显示和性能问题,所以图形系统引入了BufferQueue,一个Buffer用于绘制,一个Buffer用于显示,双方处理完之后,交换一下Buffer,这样效率就高很多了。

BufferQueue的通信流程如下所示:

生产者从BufferQueue出队一个空闲GraphicBuffer,交给上层填充图形数据;

数据填充后,生产者把装载图形数据的GraphicBuffer入队到BufferQueue,也可以丢弃这块Buffer,直接cancelBuffer送回到BufferQueue;

消费者通过acquireBuffer获取一个有效缓存;

完成内容消费后(比如上屏),消费者调用releaseBuffer把Buffer交还给BufferQueue。

GraphicBuffer代表的图形缓冲区是由Gralloc模块分配的,并且可以跨进程传输(实际传输的只是一个指针)。

通常而言,APP端使用的是BufferQueue的IGraphicBufferProducer接口(在Surface类里面),用于生产;SurfaceFlinger端使用的是BufferQueue的IGraphicBufferConsumer接口(在GLConsumer类里面),用于消费。

Surface 与 SurfaceFlinger

Surface 表示 APP 进程的一个窗口,承载了窗口的图形数据,SurfaceFlinger 是系统进程合成所有窗口(Layer)的系统服务,负责合成所有 Surface 提供的图形数据,然后送显到屏幕。

SurfaceFlinger 既是上层应用的消费者,又是 Display 的生产者,起到了承上启下的作用。官方提供了一个架构图,如下所示:

Android图形管道

该图可能较抽象,我们通过一个实例理解下这层关系,下图是微信添加朋友的弹窗界面:

我们可以通过adb shell dumpsys SurfaceFlinger查看该界面包含几个窗口(Surface):

微信多Surface

从SurfaceFlinger的dump信息可以看到:

com.tencent.mm/com.tencent.mm.ui.LauncherUI#0是微信的主窗口,并且铺满了整个屏幕(0,0,1080,2340)。

PopupWindow:7020633#0是弹起的 PopupWindow,它是一个独立的窗口(Surface),屏幕坐标范围是(599,210,1058,983)。

StatusBar#0 表示系统状态栏,由系统进程负责绘制,屏幕坐标范围是(0,0,1080,80),即此状态栏高80像素。

NavigationBar#0 表示系统导航栏,由系统进程负责绘制,屏幕坐标范围是(0,2214,1080,2340),即此导航栏高126像素。

最后两个窗口也是系统窗口,具体作用不知。

上述所有图层的合成类型都是Device,即HWC硬件模块负责合成这些Layer。

SurfaceFlinger会合成上述所有图层(Layer),并送显到内嵌的Display 0。

总结

本篇文章从上到下简述了 Android 图形系统的流转流程,以及承载图形数据流转的重要结构:BufferQueue ,最后通过dump信息论证了多 Surface 实例。

来源:AIOT人人都是极客

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包 9 8 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
易百纳技术社区
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区