Android 图形架构

发表于 1年以前  | 总阅读数:2421 次

概述

要理解Android的图形架构,我们需要先理解window的概念。维基百科中给window的定义是:Window是图形用户界面(GUI)系统中显示器上一个单独的视图区域(可以想象你电脑桌面上一个个窗口)。

因此,Android图形架构的就是把各个应用创建的一个个window组合显示到显示屏上的架构。

首先我们要理解Android系统中以下概念:

Window:代表显示器上一个单独的视图区域的对象。它由WindowManager控制。由view构成。这些view构成一个View Hierarchy结构。而这个View Hierarchy被渲染到WindowFlinger创建给Window的Surface上。

View:代表和用户交互组件的基础模块。一个view占据屏幕上的一个矩形区域,并负责这个区域的图形绘制和交互事件。Android中每个window的view构成一个View Hierarchy结构。

Surface:由SurfaceFlinger创建给WindowManager,并被WindowManager交给Window用来绘制window中view的内容。

这些内容可以由view用canvas绘制,或者采用OpenGL ES等方法。它是指java对象,c++对应的对象是ANativeWindow。

简而言之,就是,Window中的view被绘制或渲染到Surface中,才能被显示在Display上。如图

那么,Window是怎么产生的呢?

每个Activity、DreamService、Dialog、MediaController、Toast或者自定义View在创建时都会创建一个对应的Window。

这些Window可以设置父子关系,如一般的Dialog会是它所属Activity的子Window。这些子Window会拥有自己单独的Surface。

多个Window组合在一起就构成了界面,也就是多个Surface的内容组合在一起就构成了界面的显示,其中Surface的组合则是由SufaceFlinger根据各个Window的z-order之类的元数据组合的,SurfaceFlinger组合之后确定了显示屏上哪个Window需要显示、显示多少、显示在屏上哪个位置等,然后再把组合后的数据传给图形硬件抽象层(HAL)。如图

Surface 如何被渲染(图片来源:Android 官方)

Android graphics components

上面提到,View用Canvas把内容绘制到Surface上,然后显示在界面上,那么被绘制到Surface上的内容是怎么显示的呢?

如上图(Surface 如何被渲染)中显示的,它们通过Buffer Data传递被绘制的内容。

App通过 Canvas 或Media Player或Camera Preview或OpenGL ES生产Graphics Data并渲染到Surface,而SurfaceFlinger把这些Data组合然后通过Hardware Composer显示。

如图:

Android 图形架构

简单来说,就是app生产graphics data,然后SurfaceFlinger合成组合所有的graphics data然后传递给Hardware Composer显示。

graphics data flow(图片来源:Android 官方)

其中,graphic data称为Buffer,生产这些graphic data的Canvas、Media Player、Camera Preview等称为图形流生产方(Image Stream Producers)。

而合成组合这些graphic data的SurfaceFlinger或OpenGL ES apps则称为图形流消耗方(Image Stream Consumers)。

这些graphic data最后通过HWC(Hardware Composer)显示在显示器上。其中一个graphic data称为Buffer,它们组成BufferQueue。

BufferQueue:BufferQueue是一个结合了buffer pool和队列的数据结构,它使用Binder IPC在进程间传递buffers。

BufferQueue的生产方调用IGraphicBufferProducer(SurfaceTexture的一部分)接口来生成graphic buffers。而它的消耗方和GL Consumer一起消耗它并把它渲染到Surface。

SurfaceFlinger & WindowManager

SurfaceFlinger: accepts buffers, composes buffers, and sends buffers to the display. (接收并合成buffers,然后把它们发送给display显示。)

WindowManager: provides SurfaceFlinger with buffers and window metadata, which SurfaceFlinger uses to composite surfaces to the display. (给SurfaceFlinger提供合成surfaces所需的buffers和window metadata。)

Layer: A combination of a surface and a SurfaceControl.

Surface: contains the BufferQueue. 一个供Image Stream生产者和Image Consumer交换buffers的接口。它包含BufferQuene。使应用可以渲染要显示在屏幕上的Images。

SurfaceControl: contains the layer metadata like the display frame. It's uses to manipulate the appeareance of the app on the screen.

Window: containers for view objects. Window objects always backed by surface objects and controlled by WindowManager.

Window metadata: lifecycles, input and focus events, screen orientation, transitions, animations, position, transforms, z-order, and many other aspects of a window. Overseen by the WindowManager.

View: represents the basic building block for user interface components. A view occupies a rectangular area on the screen and is responsible for drawing and event handling.

When an app comes to the foreground, it requestes buffers from WindowManager. WindowManager then sends all of the window metadata to SurfaceFlinger and requests a layer.

SurfaceFlinger creates the layer and sends it to WindowManager. WindowManager then sends ther surface to the app, but keeps the SurfaceControl. 如图:

VSYNC:

APP 可以在任何时候提交buffers,但SurfaceFlinger仅仅在两次display刷新中间被唤醒并接收buffers,这样可减少内存使用,并避免可见的屏幕撕裂(如果显示内容在刷新期间更新,就有可能发生)。

当display处在两次刷新中间时,display会向SufaceFlinger发送VSYNC信号。VSYNC信号表示可以更新display且不用担心产生撕裂。

SurfaceFlinger收到VSYNC信号后,会遍历它的所有visible layers:如果该layer有新的buffer,获取它;如果没有,继续使用旧的buffer;如果该layer没有任何buffer,忽略它。

当所有layer的buffer都被收集完后,SurfaceFlinger向Hardware Composer(HWC)询问这些layer的合成类型,如果得到的结果是客户端合成,则合成。并把output buffer传给HWC。

VSYNC信号可同步display pipeline(显示管道)。display pipeline包含app渲染、SurfaceFlinger合成、HWC在显示器上显示图片。

VSYNC同步app因为要开始渲染而被唤醒的时间、SurfaceFlinger因为要合成屏幕而被唤醒的时间、和显示器刷新周期。

SurfaceFlinger通过setVsyncEnable方法控制HWC是否生成VSYNC事件,当HWC生成VSYNC事件后,会通过回调函数通知SurfaceFlinger。

在VSYNC事件发生时,显示器开始显示第N帧时,SurfaceFlinger开始合成第N+1帧,而app在处理等待的input事件并生成第N+2帧。

WinScope

可用WinScope web分析WindowManager或SurfaceFlinger在window转换期间和转换后的状态。

使用步骤:

1. 启用

WindowManager:

adb shell cmd window tracing start

SurfaceFlinger:adb shell su root service call SurfaceFlinger 1025 i32 1

2. 停用

WindowManager: adb shell cmd window tracing stop

SurfaceFlinger:adb shell su root service call SurfaceFlinger 1025 i32 0

3. 获取pb文件

WindowManager: adb pull /data/misc/wmtrace/wm_trace.pb wm_trace.pb

SurfaceFlinger:adb pull /data/misc/wmtrace/layers_trace.pb layers_trace.pb

4. 从 Android 源代码库中下载winscope.html:

curl 'https://android.googlesource.com/platform/prebuilts/misc/+/master/common/winscope/winscope.html?format=TEXT' | base64 -d > winscope.html

5. 打开winscope.html

6. 点击右上角的”OPEN FILE“按钮,选择要打开的pb文件,如图:

Analyzing a trace in WinScope

这个trace里面有下面几个部分:

Timeline — 事件的时间轴。

Screen — 显示屏幕上所有的可见Window。

Hierarchy — 包含系统已知的所有window,包括不可见的(这些window没有buffer,但是对其子window有用)。可见window信息的末尾会带有一个V标签。

Properties — 显示Hierarchy选中条目的具体信息。

WindowScope还可以从bug reports中读取WindowManager和SurfaceFlinger的快照,bug reports以proto文件的形式存储在proto文件夹中,用以下命令生成pb文件:

WindowManager: adb exec-out dumpsys window --proto > window_dump.pb

SurfaceFlinger: adb exec-out dumpsys SurfaceFlinger --proto > sf_dump.pb

Surface & SurfaceHolder

Layer:合成中最重要的单元。是Surface和SurfaceControl的结合。每个Layer都有一系列定义和其它layers交互的属性,如Z-order等。

Surface:A surface is an interface for a producer to exchange buffers with a consumer. Surface objects enable apps to render images to be presented on screens.

SurfaceHolder:**提供可以编辑和控制Surface的接口。**大部分和view交互的组件都关联一个SurfaceHolder来操作Surface,如SurfaceView。另外一些如MediaCodec之类的API,直接操作Surface。

View

构建用户界面的基础元素,每个View占据屏幕上的一个矩形,并负责这个矩形区域的绘图和事件处理。

Android的UI框架是一个view hierarchy结构,所有的UI元素经过一系列的测量和布局放置在一个矩形区域内。

View & Window & Surface

Window是图形用户界面(GUI)系统中显示器上一个单独的视图区域。界面上的dialog、activity、status bar都有其对应的Window,每个Window都有其对应的View Hierarchy结构。

当应用到前台时,WindowManager会为每个Window获取一个Surface,并把这个Surface给应用,应用在这块Surface上用Canvas或者其它方法绘制它所属Window中包含的View。

在界面的两次刷新中间时,SurfaceFlinger会根据Z-order等信息合成系统中所有window的显示区域,并最后渲染到屏幕上。

如果一个view要刷新,其实就是往它所属window的Surface的BufferQuene中更新新的buffer内容,等下次SurfaceFlinger遍历时取出来重新合成。

简单的说就是,Windows中的View要被渲染到Surface上才会被显示。

SurfaceView

一般来说一个View会和它所属window中的view共用一块Surface,但是SurfaceView拥有自己单独的Surface。

当SurfaceView所属的window变成可见时,framework会让SurfaceControl向SurfaceFlinger申请一块新的Surface给它。

默认情况下,这块surface会被放在app其它UI surface的后面,如果要把它放在top可以override默认的Z-order。

如果没有SurfaceView,当应用需要使用如GL context(OpenGL ES context)或media decoder(Camera API)这类external buffer source进行渲染时,需要复制buffer source中的buffers,并把它们合成到window对应surface中,才能让它们显示在屏幕上。

而使用SurfaceView的话,SurfaceFlinger直接把source buffers合成到屏幕上

SurfaceView的surface是BufferQueue的生产方,SurfaceFlinger是消耗方。

SurfaceTexture

SurfaceTexture是Surface和OpenGL ES(GLES) texture的组合。SurfaceTexture提供Surface给GLES渲染。

SurfaceTexture为消耗sources buffers的app持有一个BufferQueue。当source buffers的生产方往BufferQueue里插入一个新buffer时,onFrameAvailable() callback会被调用。

然后app可以调用updateTexImage(),这个方法会释放之前持有的buffer,从队列中获取生产方新插入的buffer,并进行EGL调用使buffer可作为external texture供GLES使用。

SurfaceTexture使用external texture,external texture的优点是能够直接用BufferQueue中的数据进行渲染。

SurfaceTexutre在为external textures创建BufferQueues时会把消耗方的使用标记设置为GRALLOC_USAGE_HW_TEXTURE,以确保GLES可以识别buffer中的数据。

TextureView

TextureView是SurfaceTexture和View的组合

TextureView类里面封装了一个SurfaceTexture,所以可以接收SurfaceTexture的回调和获取可用buffer。当buffer更新后,TextureView会触发view的invalidate()方法请求重绘。

GLES可以通过把TextureView中的SurfaceTexture传给创建EGL的调用来在TextureView上渲染。

如图,表示一个应用显示Camera preview的数据:

Camera的数据渲染到SurfaceTexture提供给它的Surface上,然后再把这些数据渲染到TextureView所属Window的Surface上,或渲染到SurfaceView自己的Surface上。

SurfaceView or TextureView

SurfaceView有自己专用的Surface,而TextureView和它所属Window上的view共用一块Suface。

在 API 24 及更高版本中,建议使用SurfaceView而不是TextureView。

两者功能类似并且都是 view hierarchy 中的一员。但是,它们实现方法不一样。SurfaceView虽然和其它view共享window的参数,但它的内容在渲染时是透明的。

TextureView具有更好的alpha和rotation处理能力.

SurfaceView在合成视频上分层的UI元素时性能更好:

1. 使用SurfaceView时,系统会为SurfaceView提供一个单独的合在层(layer),SurfaceFlinger将直接使用这个layer做为一个硬件叠加层和其它window的layer合成在一起。

2. 使用TextureView时,UI工具通过GPU将TextureView中的内容合成到它的view hierarchy中——当TextureView内容更新时,可能会导致其它view的重绘。

比如,放置在TextureView上面的view;而且因为在view的渲染完成后,SurfaceFlinger还要把它所属的app UI layer和其它layer合成在一起,所以导致所有TextureView上的可见像素都被合成了两次。

但TextureView在某些功能的实现上比SurfaceView要简单,比如缩放功能的实现:缩放SurfaceView需要FrameLayout的自定义实现,WindowManager需要告诉SurfaceFlinger新窗口的位置和大小等信息。

而缩放TextureView只需要使用TextureView#setTransform()配置转换矩阵。

EGLSurface & OpenGL ES

OpenGL ES:Open Graphics Libarary Embedded Systems,GLES,免费的、用于在嵌入式和移动系统如手机上渲染图形的跨平台API。

EGL:Embedded Graphics Libarary. EGL是Khronos渲染API(如GLES)与本地窗口系统之间的一个中间接口层。

texture:OpenGL的对象,包含一张或多张拥有相同图片格式的图片。可以做为Shader(着色器)的来源,也可以做为渲染目标。texture图片比光滑的图片多了表面的纹理。

不同设备的窗口系统千变万化,但GLES的API却是不变的,所以需要EGL协调设备的窗口系统和GLES。

Android用GLES来渲染图形,并用EGL来创建GLES的contexts和为GLES渲染提供绘制的地方。GLES方法用来渲染textured多边形,而EGL方法用来把渲染显示在屏幕上。

在使用GLES绘制前,你需要创建GL context。在EGL中,这意味着要创建一个EGLContext和一个EGLSurface。

这个GL context通过thread-local storage的方式被GLES访问操作,而不是当做一个参数被传递给GLES访问操作。渲染代码应该在当前的GLES线程而不是UI线程执行。

EGLSurface(Android)

EGLSurface是操作系统分配的window,它由eglCreateWindowSurface()方法创建

这个方法不仅创建一个EGLSurface,还会把创建的EGLSurface连接到做为输入参数的Surface的BufferQueue上(做为BufferQueue的生产方),而这个Surface由BufferQueue的消耗方(SurfaceView、SurfaceTexture、TextureView或者ImageReader等)创建。

这样,渲染这个EGLSurface的整个流程是:从BufferQueue中取出一个new buffer,渲染这个buffer,再把被填充的buffer重新插入到BufferQueue中供consumer使用。如下

EGL不提供lock/unlock方法,提供eglSwapBuffers()方法来提交当前绘制的帧。

一个Surface一次只能和一个EGLSurface关联(只能有一个生产方连接到BufferQueue),只有当关联的EGLSurface被销毁后(它将断开与BufferQueue的连接),才允许其它的EGLSurface关联。

一个线程可以更改它当前使用的EGLSurface,但一个EGLSurface只能同时被一个线程使用。

EGL和SurfaceHolder不一样,它是独立与Surface的一个概念。

你可以在一个并不由Surface支持的EGLSurface上绘图,你也可以在没有EGL的情况下使用Surface。EGLSurface仅仅为GLES提供一个绘图的地方。

ANativeWindow

公开的Surface类是用Java实现的,其对应的C/C++类Android NDK中半公开的ANativeWindow类。

参考

android develop图形文档:https//source.android.com/devices/graphics

本文由哈喽比特于1年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/lFVZZTEhLBL8yHwDt9xrEw

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:7月以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:7月以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:7月以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:7月以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:7月以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:7月以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:7月以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:7月以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:7月以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:7月以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:7月以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:7月以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:7月以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:7月以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:7月以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:7月以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:7月以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:7月以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:7月以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:7月以前  |  398次阅读  |  详细内容 »
 相关文章
简化Android的UI开发 4年以前  |  520694次阅读
Android 深色模式适配原理分析 3年以前  |  28618次阅读
Android阴影实现的几种方案 1年以前  |  10764次阅读
Android 样式系统 | 主题背景覆盖 3年以前  |  9576次阅读
 目录