Android 图形系统概述

图形系统是 Android 中很是重要的子系统,与其余子系统相互协做,完成图形界面的渲染和显示。shell


概述


官方提供了一个图形系统的关键组件协做图,以下所示:缓存


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


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


不过该图缺少层次感,经过下图咱们详细分析整个流程。并发



大致上,应用开发者能够经过两种方式将图像绘制到屏幕上:app


  • Canvascomposer

  • 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 的生产者,起到了承上启下的做用。官方提供了一个架构图,以下所示:



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



咱们能够经过adb shell dumpsys SurfaceFlinger查看该界面包含几个窗口(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 实例。


做者:ltlovezh
连接:https://juejin.im/post/6844903955709820936


-- END --


进技术交流群,扫码添加个人微信:Byte-Flow



获取视频教程和源码



推荐:

Android OpenGL 渲染图像读取哪家强?

字节流动 OpenGL ES 技术交流群来啦

FFmpeg + OpenGL ES 实现 3D 全景播放器

FFmpeg + OpenGLES 实现视频解码播放和视频滤镜

一文掌握 YUV 图像的基本处理

Android OpenGL ES 从入门到精通系统性学习教程

OpenGL ES 实现动态(水波纹)涟漪效果


以为不错,点个在看呗~

本文分享自微信公众号 - 字节流动(google_developer)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索