Android图形烘托体系是Android不可或缺的子体系之一,其自身复杂且与其他子体系存在千丝万缕的联系,各种模块众多,内容繁杂,各个版本都会有一定的更新,很难一篇文章道完天机,后续希望能出个系列文章好好讲解内里玄机,本文作为系列的开篇,希望能体系的讲解下各模块的机制,尽管之前也写过相关文章,可是本篇文章带来了不一样的内容。

众所周知手机已是人们生活中不可或缺的一部分,手机也天然的成为了移动端的一个最重要的流量底座,承载着用户各种精力和物质上的需求,其间交互体会和感触又是用户最直接的反应,而烘托体系是保障这一切的根基。

首先咱们以官方的一张图作为切入点

Android图形渲染系统新

该图展示了图形体系的要害组件协作流程和图形数据的流通:

  • OpenGLES、MediaPlayer、Camera等出产者出产GraphicBuffer到Surface
  • Surface经过IGraphicBufferProducer把GraphicBuffer跨进程传输给顾客SurfaceFlinger
  • SurfaceFlinger依据WMS供给的窗口信息组成一切的Layer,详细的组成策略由hwcomposerHAL模块决议并实施,
  • 最终也是由该模块送到Display模块,而Gralloc模块则担任分配图形缓冲区。

但上图是16年官方给出的,随着几年的更新也引入了一些新的模块,支撑了新的图形库-Vulkan,Gralloc和BufferQueue也做了相应的支撑,咱们能够继续细化下整体流程,全景图如下:

Android图形渲染系统新

从上图可看出整个烘托体系贯穿app和体系层,app在CPU侧进行图形数据的出产,然后交给GPU做烘托处理,最终由SurfaceFlinger和HWC配合进行组成并烘托上屏,其间涉及了多个中心模块的协作,下面咱们进行要点的讲解:

GraphicBufferProducers

产生graphicbuffers的出产者.例如OpenGLES,Vulkan,Media的视频解码器,Camera等.

GraphicBufferConsumers

最中心的顾客便是SurfaceFlinger,它运用OpenGL和HardwareComposer来组合一组surfaces

  • OpenGLES运用能消费图形流,比方cameraapp消费camera预览图形流;
  • 非OpenGLES运用也能消费,比方ImageReader类

Canvas

Canvas是一个2D图形API,是AndroidView树实践的烘托者。Canvas又可分为Skia软件绘制和hwui硬件加速绘制。

WindowManager

用于办理Window.Window是个笼统类,表明一个窗口,其完成是PhoneWIndow。WindowManager会监督生命周期、输入和聚焦事情、屏幕方向、转化、动画、方位、变形、Z轴顺序以及窗口的许多其他方面。当app经过WindowManager创立一个Window时,WindowManagerService会为每一个Window创立一个Surface,并将各种(包括屏幕信息,z-order等)信息发送给SurfaceFlinger。

Surface

Surface表明APP进程的一个窗口,承载了窗口的图形数据与SurfaceFlinger侧的Layer相对应。从App侧来看不管是Canvas,OpenGLES还是Vulkan最终烘托到的方针都是Surface,现在比较流行的跨渠道UI结构Flutter在Android渠道上也是直接烘托到Surface。

一个Activity是一个Surface、一个Dialog也是一个Surface。

BufferQueue

Android图形渲染系统新

安卓图形烘托规划有一个生成者顾客形式,BufferQueue便是这种形式的写照。Android图形体系包括了两对出产者和顾客模型,它们都经过BufferQueue进行衔接:

  • Canvas,OpenGLES和Vulkan出产图形数据,SurfaceFlinger消费图形数据。
  • SurfaceFlinger组成一切图层的图形数据,Display显现组成成果。

BufferQueue是衔接Surface和Layer的枢纽,当上层图形数据烘托到Surface时,实践是烘托到了BufferQueue中的一个GraphicBuffer,然后经过IGraphicBufferProducer把GraphicBuffer提交到BufferQueue,让SurfaceFlinger进行后续的组成显现作业。GraphicBuffer代表的图形缓冲区是由Gralloc模块分配的,并且能够跨进程传输(实践传输的只是一个指针),为了高效传输大块数据,运用匿名同享内存。

BufferQueue的经典作业流程如下:

  • 出产者恳求一块空闲的缓存区:dequeueBuffer()
  • 出产者填充缓存区并回来给行列:queueBuffer()
  • 顾客获取一块缓存区:acquireBuffer()
  • 顾客运用结束,则回来给行列:releaseBuffer()

SurfaceFlinger

Android体系服务,会随着init进程执行init.rc而创立该服务。担任组成一切Surface供给的图形数据,然后送显到屏幕。SurfaceFlinger既是上层运用的顾客,又是Display的出产者。功用如下:

  • 分配图形缓冲区
  • 组成Surface
  • 办理VSYNC事情

Android图形渲染系统新
SurfaceFlinger便是将多个Surface里的内容进行组成,最终提交到屏幕的后缓冲区,等候屏幕的下一个笔直同步信号的到来,再显现到屏幕上。

SurfaceFlinger担任组成一切的Layer并送显到Display,这些Layer主要有三种组成方法:

  • OpenGLES:把这些图层组成到FrameBuffer,然后把FrameBuffer提交给hwcomposer完结剩余组成和显现作业。
  • hwcomposer:经过HWC模块组成部分图层和FrameBuffer,并显现到Display。
  • Vulkan:把这些图层组成到FrameBuffer,然后把FrameBuffer提交给hwcomposer完结剩余组成和显现作业。

OpenGL

传统的图形API,规范了图形接口,OpenglES是一个专用于嵌入式设备的OpenGL,但Opengl自身只供给接口和规范,详细的需要各渠道供给接口层去适配自己的窗口体系,比方Android渠道的EGL。生态好,适用广泛。

Vulkan

Android图形渲染系统新

Vulkan是新一代的图形显现API。也有业界称之为“下一代的OpenGL”,是下一代高性能及精细化控制的敞开的跨渠道的图形API。想要更深入了解的同学请参阅我之前的文章:Vulkan-性能及精细化控制、Vulkan-实践剖析、

Vulkan在Android7.0后也被google支撑了,Android上分为三层结构对Vulkan进行了适配支撑。

Vulkan验证层:在Vulkan运用开发期间运用的库,用于查找运用在VulkanAPI的运用方面的过错。在找出此类过错后,应移除这些库。

Vulkan运行时:原生库libvulkan.so供给原生VulkanAPI。Vulkan运行时的大部分功用由GPU供应商供给的驱动程序完成。Vulkan运行时会封装驱动程序、供给API阻拦功用(针对调试和其他开发者工具)以及办理驱动程序与渠道依赖项之间的交互。

Vulkan驱动程序:将VulkanAPI映射到特定于硬件的GPU指令以及与内核图形驱动程序的交互。

HardwareComposer(硬件混合烘托器)

Android中进行窗口(Layer)组成和显现的HAL层模块,显现子体系的硬件笼统完成。其内部完成是基于特定设备的,通常由屏幕硬件设备制造商(OEM)完结。主要用于确定组成缓冲区的最有效方法,SurfaceFlinger在搜集可见层的一切缓冲区后,便会询问HWC应如何进行组成。可分为Client组成和Device组成。SurfaceFlinger能够将某些组成作业委托给HardwareComposer,以分担GPU上的作业量。

HAL

硬件笼统层。HAL供给标准接口,给更高等级的接口结构显现设备硬件功用。HAL包括多个库模块,其间每个模块都为特定类型的硬件组件完成一组接口,例如相机或蓝牙等。当结构API恳求拜访设备硬件时,Android体系将为该硬件加载相应的库模块。

Gralloc

含义是GraphicsAlloc图形分配,用于图形出产时恳求分配内存.Android体系在硬件笼统层中供给了一个Gralloc模块,封装了对Framebuffer的一切拜访操作。

Gralloc模块契合Android标准的HAL架构规划;它分为fb和gralloc两个设备:前者担任打开内核中的Framebuffer、初始化配置,以及供给post,setSwapInterval等操作;后者则办理帧缓冲区的分配和释放。

FrameBuffer

Linux笼统出FrameBuffer这个设备来供用户态进程完成直接写屏。FrameBuffer是显卡硬件的笼统,能够经过FrameBuffer的读写直接对显存进行操作。

FrameBuffer自身不具备任何运算数据的能力,CPU将运算后的成果放到FrameBuffer,就会显现处理,中心不会对数据做处理。

Linux内核供给了统一的Framebuffer显现驱动,节点为/dev/graphics/fb*或许/dev/fb*,以fb0表明第一个Monitor,这个虚拟设备将不同硬件厂商完成的实在设备统一在一个结构下,这样运用层就能够经过标准的接口进行图形/图画的输入和输出。

微信大众号首发,欢迎各位code er重视大众号:江湖修行