Android图形系统概述

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

概述

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

Android官方图形架构

这幅图大致描述了图形数据的流转:OpenGL ES、MediaPlayer等生产者生产图形数据到Surface,Surface通过IGraphicBufferProducerGraphicBuffer跨进程传输给消费者SurfaceFlingerSurfaceFlinger根据WMS提供的窗口信息合成所有的Layer(对应于Surface),具体的合成策略由hwcomposerHAL模块决定并实施,最后也是由该模块送显到Display,而Gralloc模块则负责分配图形缓冲区。不过该图缺乏层次感,通过下图我们详细分析整个流程。
图形系统架构

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

  • Canvas
  • OpenGL ES

Canvas是一个2D图形API,是Android View树实际的渲染者。Canvas又可分为Skia软件绘制和hwui硬件加速绘制。
Android4.0之前默认是Skia绘制,该方式完全通过CPU完成绘图指令,并且全部在主线程操作,在复杂场景下单帧容易超过16ms导致卡顿。
从Android4.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,然后通过IGraphicBufferProducerGraphicBuffer提交到BufferQueue,让SurfaceFlinger进行后续的合成显示工作。

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

  • OpenGL ES:把这些图层合成到FrameBuffer,然后把FrameBuffer提交给hwcomposer完成剩余合成和显示工作。
  • hwcomposer:通过HWC模块合成部分图层和FrameBuffer,并显示到Display。

BufferQueue

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

  1. CanvasOpenGL ES生产图形数据,SurfaceFlinger消费图形数据。
  2. 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图形管道

该图可能较抽象,我们通过一个实例理解下这层关系,下图是微信添加朋友的弹窗界面:
<img src="https://ltlovezh.oss-cn-beijing.aliyuncs.com/graphics/%E5%BE%AE%E4%BF%A1.png" width="300" />
我们可以通过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实例。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容