十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Android 16图形系统架构解析:从绘制到显示全链路拆解

Android 16图形系统架构解析:从绘制到显示全链路拆解 做图形系统相关开发这些年被问得最多的问题其实就一个屏幕上的一张UI到底是怎么从App里的代码变成像素的尤其是到了Android 16这个版本图形栈涉及的东西更多了HDR、可变刷新率、多窗口、屏幕折叠形态……每一个新特性背后都牵扯着从App到内核到显示驱动的整条链路。如果对系统架构没有一个整体认识遇到性能问题基本只能靠猜。这篇我打算把Android 16的图形系统架构完整拆一遍从App侧的绘制、系统侧的合成到屏幕侧的显示把整条流水线讲清楚。适合做系统开发、应用性能优化、游戏引擎适配以及准备系统架构相关工作的朋友。哪怕你只做上层应用理解这条链路之后再看卡顿、掉帧、发热这类问题思路也会完全不一样。1. 为什么Android图形系统要搞这么复杂经常有人问Android图形栈为什么这么多层画一个按钮而已有必要绕这么大一圈吗我的答案是有必要而且不是一般的必要。原因不复杂图形系统要解决的不仅仅是“把图画出来”而是“把无数个App各自画的东西在同一块屏幕上正确、稳定、高效地拼接起来”还要管安全、管功耗、管不同硬件之间的差异。这本质上是一个多生产者、单消费者的实时调度系统。1.1 一个App在屏幕上画一帧要经过哪几道门先打个比方。你在餐厅点菜后厨做菜服务员端菜这叫一帧。但Android的实际情况是楼下几十个餐厅同时做菜每道菜都要送到同一个收银台上由一台合成机器把它们拼成一份套餐再由一个专门的传送带送到你桌上。App之间互相看不见更不能直接写在同一个屏幕上否则一个App崩溃或画错就会污染另一个App的内容这在安全上是绝对不能接受的。所以Android把图形链路拆成了三个大层次App层负责“画”调用Canvas、OpenGL ES或者Vulkan把UI、图片、游戏场景渲染到一块内存缓冲区里。这部分主要由HWUI、Skia和GPU驱动完成。系统层负责“合”SurfaceFlinger拿到所有App绘制好的缓冲区把它们按窗口层级、透明度、变换关系合成在一起生成一帧完整的画面。这里还可能把一部分工作交给硬件合成器HWC来做目的就是省电、省性能。显示层负责“送”合成后的画面通过显示控制器按照屏幕刷新率被主动推送到显示面板上。Android里的Vsync、Display、HWC HAL都在这层。这三个层次彼此通过BufferQueue、Binder、共享内存等机制衔接每一层都有自己的调度节奏。理解了这道分层后面所有细节都有地方安放。1.2 Android 16图形栈的整体面貌到了Android 16这套分层的大骨架并没有变依然是App绘制、SurfaceFlinger合成、HWC显示三层结构。但在细节上能明显感觉到两个趋势。一个是Vulkan的地位越来越高。在较早的系统版本里Skia渲染默认走OpenGL ES后端而现在的系统里Vulkan后端已经成为GPU加速渲染的推荐路径。对于GPU厂商来说Vulkan的驱动模型更贴近现代GPU能减少驱动层的魔法和转换对功耗、性能都更友好。Android 16的图形调度对Vulkan的支撑力度也在增强游戏和复杂动画的渲染路径更依赖这套新接口。另一个是帧率的精细化调度。现在屏幕已经不只是60Hz了90Hz、120Hz甚至可变刷新率越来越普遍。Android 16里App可以更准确地表达自己对帧率的需求系统也会根据内容动态调整刷新率这就让Vsync和帧调度变得更复杂绝不是“每秒固定触发60次”那么简单。后面我会专门说这块。这一层架构的总体目标归纳起来就是延迟要低、吞吐要稳、功耗要可控。所有模块的设计都是围绕这三个指标展开的。2. 核心引擎拆解SurfaceFlinger、HWUI与Vulkan在图形系统里有三个引擎是你无论如何都绕不开的负责系统合成的SurfaceFlinger负责应用UI绘制的HWUI和Skia以及底层图形API代表的Vulkan也包括OpenGL ES。它们各自干各自的活但边界有时候会让新人困惑。比如SurfaceFlinger是系统进程里的服务而HWUI是每个App进程里都在跑的渲染引擎。2.1 SurfaceFlinger到底在合成什么东西SurfaceFlinger是图形系统的“总装车间”。每个可见窗口在系统侧都会对应一个SurfaceSurfaceFlinger手里维护着这些Surface的图层Layer信息包括位置、大小、旋转角度、透明度、圆角裁剪、色彩空间等。当App绘制完一帧并提交缓冲区后SurfaceFlinger会把这些缓冲区拿过来配合图层的属性统一合成输出。为什么要“统一合成”因为屏幕只有一块但应用可能有几十个。如果不让一个中心化的服务来管让App各画各的画面就会互相冲突。而且很多系统UI比如状态栏、导航栏、壁纸、系统弹窗它们的绘制优先级、安全区域都需要被统一管理。SurfaceFlinger的合成过程不是简单地从上往下叠图它得处理的东西包括多图层混色Blend缩放、平移、旋转裁剪到窗口可见区域色彩空间转换比如HDR内容映射到SDR屏幕透明度和过渡动画在业界它被设计成一个响应型事件驱动系统平时大部分时间处于等待状态一旦某个Layer有新的缓冲区提交或者系统属性发生变化它就结束等待、主动或者由硬件信号触发去做一次合成。这种设计的本质是为了省电——没事的时候尽量睡。2.2 HWUI和Skia在App里的绘制链路再往App内部看绝大部分Android UI是通过HWUI来绘制的。你可以把它理解成一个专门为Android UI优化的渲染引擎它把View体系的绘制请求转换为GPU指令。而HWUI真正的渲染后端是SkiaSkia负责把画布相关的操作比如drawRect、drawBitmap、drawText转换为具体的GPU绘制指令。这个过程里有一个非常重要的组件叫RenderThread。老的Android版本里UI绘制和主线程的View遍历是混在一起的一个复杂的界面就容易把主线程拖垮。后来系统把“发起绘制命令”和“真正执行绘制命令”拆开了RenderThread专门在后台执行渲染工作。主线程只做View的测量、布局和生成显示列表RenderThread拿到显示列表后异步执行GPU指令。这样即使渲染耗时长也不会完全卡死主线程的输入响应。Skia的绘制后端有两种主要路径一种走OpenGL ES一种走Vulkan。传统上OpenGL ES是默认选项因为它兼容性最好但Vulkan后端的优势正在显现它减少了驱动层的隐式状态管理对多线程渲染的支持也更好。Android 16上如果你关注过AOSP的代码提交记录会发现Skia和HWUI在越来越多地把GL路径边缘化Vulkan路径被当成主车道来打造。2.3 Vulkan在系统级的位置很多游戏开发者都已经很熟悉Vulkan了但它在Android 16系统架构里的角色其实远不止“给游戏用”。系统自己也在用Vulkan做合成相关的加速部分厂商的SurfaceFlinger合成路径会用Vulkan替代老的GLES合成。也就是说Vulkan不只是一套“画画的API”它已经成为整个图形系统性能基础的一部分。为什么系统偏爱Vulkan最大的原因是可控性。OpenGL ES是一个高层的状态机驱动要处理大量的隐式同步和状态转换而Vulkan把显式同步、命令缓冲、队列管理全部暴露给开发者虽然用起来麻烦但换来的是可预测的性能。对于Android这样一个需要适配大量GPU的平台来说Vulkan能帮助减少驱动层的不确定性对功耗和帧率稳定性都有帮助。当然Vulkan的缺点也很明显学习成本高、代码量大、驱动要求更严格。所以系统里也不是所有路径都一步到位切到Vulkan很多老设备、老应用仍然走GLES但Android 16的趋势是明确的——新特性优先支持Vulkan老路径慢慢退居二线。3. BufferQueue、Gralloc与共享内存图形数据的高速公路有了引擎还得有“数据管道”。一个App渲染完的画面怎么交给SurfaceFlingerSurfaceFlinger合成完怎么交给屏幕答案就是BufferQueue。这个概念你必须在脑海里扎下根因为几乎所有图形性能问题追踪到最后都会落到这上面。3.1 BufferQueue的生产者消费者模型BufferQueue缓冲区队列本质上是一个“生产者-消费者”模型。App是生产者SurfaceFlinger是消费者。生产者的职责是从队列里申请一块空闲缓冲区把内容画进去然后把这块缓冲区提交入队消费者的职责是从队列里取走一块已提交的缓冲区做合成或者显示用完后再把它还给队列复用。这个循环里有几个关键状态DEQUEUED生产者已经拿到缓冲区正在往里面绘制此时缓冲区归生产者独占。QUEUED生产者绘制完毕把缓冲区放入队列等待消费者处理。ACQUIRED消费者把缓冲区取走正在使用中。FREE缓冲区处于空闲状态可供下一次dequeue。这四种状态之间的切换是整个图形系统最核心的同步逻辑。BufferQueue的核心价值在于复用内存缓冲区被反复使用不需要每帧重新分配这在性能上是决定性的。设想一下如果你每帧都从hardware allocator里申请一块新内存那光分配和释放的开销就能吃掉一大截性能。至于缓冲区的调度策略不同的生产者和消费者场景需求不同。普通应用窗口的缓冲区队列已经加入了“最大缓存帧数”、同步栅栏fence等机制用来协调CPU和GPU的进度避免消费者拿到一个还没画完的缓冲区。3.2 Gralloc和图形内存分配BufferQueue管理的是缓冲区的“生命周期”但真正分配图形的物理内存的是另一个核心模块Gralloc全称Graphics Allocator。它对上提供一个稳定的分配接口对下通过HAL硬件抽象层对接GPU和显示控制器由厂商的驱动决定内存分配在哪块区域。为什么不让BufferQueue直接malloc一块内存因为图形缓冲区是给GPU、显示控制器和硬件合成器用的它们对内存有特殊要求。比如某些内存需要连续物理地址某些需要能从显示控制器直接读取某些需要被CPU、GPU、DPU显示处理单元同时访问。普通的内存分配器满足不了这些硬件的对齐和缓存一致性要求。所以Gralloc的职责就是和硬件驱动配合分配出满足整个图形流水线需求的缓冲区。在Android 16的系统里图形缓冲区还有一个非常重要的身份它们是通过Binder共享出去的跨进程对象。App进程里的渲染线程把缓冲区填好后系统会把这个缓冲区关联的文件描述符通过Binder传给SurfaceFlinger进程。这里面的内存共享基于内核的dmabuf等机制实现可以做到物理内存在进程间零拷贝传递而不是真的把像素数据复制一份过去。这也是整套系统能维持高性能的关键所在。3.3 生产者消费者的跨进程协作细节你可以把BufferQueue想象成一个共享快递柜消费者把快递柜清空出来生产者把东西放进去并锁上门消费者再次打开取出。快递柜本身放在公共区域双方都能访问但取放规则由管理者制定。这套模型还有一个容易被忽略的重点同步栅栏fence。GPU在绘制缓冲区时不一定是立即完成的CPU提交完命令就去做别的事了。如果SurfaceFlinger在GPU还没画完的时候就去读缓冲区就会拿到乱七八糟的画面。为了解决这个问题生产者会在queue缓冲区的时候带上一个fence对象消费者在acquire缓冲区的时候先等待这个fence等GPU工作完成后才开始合成。这就让CPU、GPU之间可以并行工作而不是互相空等。实际上我在排查不少问题的时候发现很多诡异的画面撕裂、花屏问题根源往往不在渲染代码本身而是fence的传递或者超时逻辑出了问题。后面我会专门列一些常见问题。4. Vsync机制与帧调度Android的“节拍器”图形系统最终要跟屏幕的刷新节奏对齐。屏幕是60Hz就每秒刷新60次是120Hz就每秒刷新120次。如果App想画就画、想提交就提交你和屏幕之间就会发生错位屏幕可能两帧显示同一内容也可能在刷新中途换帧导致画面撕裂。Android用Vsync垂直同步信号来解决这个问题。4.1 Vsync信号从哪里来发到哪里去Vsync信号的核心来源是显示硬件。屏幕在完成一帧刷新后硬件会发出一个脉冲信号这个信号会被HWC或者显示控制器接收随后由系统转换成软件事件分发给不同进程。在Android 16的架构里Vsync的分发有两个主要方向。一个方向是发给各个App进程App收到后启动画面绘制另一个是发给SurfaceFlingerSurfaceFlinger收到后触发合成和提交显示。也就是说生产者和消费者的节拍器是可以分开调节的两个节拍器之间还可以有相位偏移让整个流水线像接力赛一样每个人在各自的赛道上不会互相撞车。App进程的Vsync最终会转化成Choreographer的回调。做过Android性能优化的朋友都知道Choreographer它负责在每一帧的固定阶段回调三种任务第一种是输入事件处理第二种是动画更新第三种是View测量、布局和绘制Traversal。这个顺序保证了你在onDraw里看到的动画值一定是最新的。4.2 刷新率变化与三缓冲以前60Hz的时代帧调度相对简单每16.6毫秒来一次VsyncApp在这段时间里完成一帧渲染SurfaceFlinger在下个Vsync完成合成。但Android 16时代屏幕刷新率已经变成一个可以动态调整的变量。手机可以根据内容切换90Hz、120Hz甚至可以降到1Hz来省电。可变刷新率带来一个新问题如果系统切到120Hz但App只按60Hz来提交帧那中间就有很多Vsync是空跳的如果切到低刷新率但突然出现一个高帧率游戏系统的响应速度就可能跟不上。所以现在的调度器需要根据App的行为、正在显示的内容类型、功耗预算动态调整刷新率。这套机制既有系统侧的算法也有App通过DisplayManager等接口上报的偏好两边配合才能做到既省电又不卡。还有一个和Vsync强相关的概念是“三缓冲”。老Android设备上容易掉帧一个原因是只有双缓冲App正在画的缓冲区、SurfaceFlinger正在用的缓冲区两个坑被占满了App就不得不等。后来加入了第三个缓冲区相当于多了一个缓冲位当瞬时负载波动时App不至于立刻被堵死。三缓冲的本质是用增加一帧延迟换取更平滑的帧率。你在游戏帧率曲线里看到那种持续30帧但帧间时间很均匀的情况往往背后就是缓冲深度的功劳。4.3 Frame Pacing让帧率更均匀的机制Android系统其实一直在解决“平均帧率好看但实际卡顿”的问题。你可能会看到某款游戏平均60FPS但体感却卡顿明显这是因为帧间隔不均匀有的帧8毫秒完成有的帧30毫秒才完成人眼对瞬时卡顿远比对平均帧率敏感。系统侧的Frame Pacing帧节奏控制就是为了缓解这个问题。它让App不要在任何一帧上提前跑太远也不要提交过晚而是尽量让每帧都落在正确的Vsync时间点上。这样渲染时间波动很大的工作负载也能表现出平滑的画面。Android 16上对这类帧调度机制做了更多细化尤其是在游戏场景里配合ADPFAndroid Dynamic Performance FrameworkApp可以获取到系统的预测性帧调度信息动态调整渲染负载把波动抹平。实际调优时我建议大家多关注systrace里每一帧的提交时间和Vsync的相位差不要只盯着FPS数字看。这个问题我在后面的排查部分还会展开。5. 合成与显示从SurfaceFlinger到屏幕的最后一百米App画好了帧BufferQueue完成了传递接下来就是SurfaceFlinger干活和屏幕显示了。这一段的效率和效果直接决定你看到的画面是不是顺滑、有没有色偏、HDR亮不亮、屏幕省不省电。5.1 SurfaceFlinger的合成策略SurfaceFlinger拿到各个Layer的缓冲区后需要考虑怎么“合成”出一帧。合成这个词听起来技术性很强但实际上就是决定“把哪些图层直接交给硬件把哪些图层先用GPU混合一次”。硬件合成器HWC通常能直接处理一定数量的图层。比如屏幕上有一个视频层、一个UI层、一个状态栏层如果硬件有对应的硬件图层Hardware LayerSurfaceFlinger就可以让HWC直接把这些硬件图层混合并输出到屏幕。这个过程完全不经过GPU功耗极低。但如果图层数目超过了硬件能力或者某些效果比如复杂的圆角、阴影、模糊没法用纯硬件图层来表达SurfaceFlinger就必须先把这些图层用GPU合成成一张纹理再交给HWC输出。这就是为什么在性能调优时经常有人强调“减少过度绘制”或者说“减少Layer数量”。每多一个图层SurfaceFlinger的工作量和HWC的压力都会增加。尤其是窗口动画期间如果一个页面把多个Surface都变成了可见Layer那些复杂效果有时会造成GPU和DPU的双重开销掉帧非常明显。5.2 HWC驱动的能力协商HWC是图形系统里最容易被忽略但又最关键的模块。每一代Android系统的图形架构演进都绕不开HWC和SurfaceFlinger的协议升级。在Android 16里HWC依然是显示链路里负责“最后一公里”的部件SurfaceFlinger把合成后的帧交给HWCHWC负责把帧在正确的时间点呈现到屏幕上。HWC和SurfaceFlinger之间有一套固定协议SurfaceFlinger会告诉HWC当前有哪些Layer、每个Layer的buffer handle是什么、合成模式是什么、是否做翻转裁剪以及一个关键的present fence。HWC驱动的能力各不相同有的硬件只能处理一两个图层有的能处理很多个还有的只支持特定格式比如HDR内容。SurfaceFlinger会根据HWC的能力动态调整处理策略。如果你做驱动或系统适配遇到屏幕显示异常、帧率异常、休眠唤醒后花屏这些问题第一步就是去看HWC的systrace段确认SurfaceFlinger有没有发错layer信息、HWC有没有报错。很多“屏幕闪烁”的疑难杂症最后都定位到了HWC和驱动之间的同步问题而不是SurfaceFlinger本身。5.3 显示链路、回读与色彩管理在Android 16上一个必须单独拿出来说的概念是色彩管理与HDR。以前Android屏幕大多只支持SDR一套8位RGB就够用了。但现在越来越多的屏幕原生支持HDR10、HDR10甚至杜比视界App也开始请求使用广色域和HDR渲染。图形系统在显示HDR内容时需要做好几件事一是保证HDR内容在渲染时工作在正确的色彩空间不丢失信息二是合成多个图层时SDR跟HDR内容要正确混合不能让SDR内容看起来发灰或者过曝三是由HWC在输出到屏幕时根据屏幕能力做色调映射tonemapping。在Android 16的系统架构里色彩管理已经渗透进了BufferQueue、SurfaceControl和HWC协议中一个Layer在创建的时候就需要明确声明它的色彩空间和HDR元数据。这块调起来其实有不少坑最常见的现象是HDR视频播放时旁边的UI文字显得过亮刺眼或者整体画面发白。这就是因为SDR和HDR内容在合成时没有做正确的混合处理或者驱动对元数据支持不完整。遇到这种问题光靠上层改代码解决不了多少必须沿着Data Space、HDR metadata、HWC能力协商这一条链路往下查。6. 跨进程协作从SystemServer到App再到HAL图形系统不是独立运行的它跟SystemServer里的一堆系统服务、App进程的UI线程、硬件驱动之间有着频繁的交叉调用。理解这些跨进程关系是真正看懂Android 16图形架构的最后一环。6.1 WindowManager、DisplayManager和SurfaceFlinger之间的分工你打开一个App的时候屏幕上的窗口是怎么建立的首先是Activity经过AMSActivity管理服务和WindowManagerWMS确认窗口属性WMS创建对应的WindowState并通过SurfaceControl接口向SurfaceFlinger申请创建对应的Layer。SurfaceFlinger返回一个SurfaceControl的句柄App端拿到这个句柄后才能跟对应的缓冲区队列建立连接。DisplayManager则负责管理屏幕设备。一个手机上可能有主屏、副屏、外接屏Android 16上还支持折叠屏多个显示状态。DisplayManager负责枚举显示设备、管理DisplayDevice并和SurfaceFlinger的Display模块协同决定每个Display上显示哪些Layer。这里的关键是所有跨进程通信都通过Binder完成。SurfaceFlinger拥有真正的Layer数据其他进程持有的只是控制句柄真正修改图层属性、提交缓冲区的操作都要通过Binder调用到SurfaceFlinger进程完成。这也意味着如果Binder调用过于频繁或者SurfaceFlinger进程被某个耗时操作拖住整个系统的UI都会受到影响。6.2 三进程协作的典型流程我们以最简单的一个按钮点击为例走一遍跨进程协作流程。点击触摸屏InputFlinger把触摸事件发给App的主线程。Choreographer在下一个Vsync回调中触发View的重绘。HWUI把绘制任务提交给RenderThreadRenderThread通过Vulkan或GLES完成GPU渲染。渲染结束后缓冲区入队到BufferQueue同时向SurfaceFlinger发送一个Binder通知。SurfaceFlinger收到通知后在下一次Vsync时把这张新缓冲区跟其他窗口的缓冲区进行合成。HWC按屏幕刷新率把最终画面呈现到面板上。这个过程涉及Input、App进程、GPU、BufferQueue、SurfaceFlinger、HWC等多个模块任何一环出现延迟都会反映成用户可感知的卡顿。在日常优化里我喜欢用Perfetto去抓一整段流程然后逐段看时间消耗输入分发用了多久App draw用了多久GPU渲染用了多久SurfaceFlinger合成用了多久HWC presentation等了多久。找出时间都花在哪一段问题就解决了一大半。6.3 与近期系统架构热点的关系最近“系统架构设计师”这个方向在技术社区讨论度很高其实Android图形系统就是一个很好的案例它具备一个大型分布式系统该有的分层、模块解耦、同步机制、故障隔离和性能工程而且你可以直接看源码、直接抓trace验证是学习系统架构不可多得的好素材。甚至你在研究分布式交换机、低空管控平台这类大规模系统的架构时里面遇到的调度、负载均衡、生产者消费者模型、背压控制等问题在Android图形栈里都能找到对偶的对应。从这个角度看搞懂Android图形架构不只是为了调一个App的流畅度它培养的是你对“复杂系统如何组织”的判断力。7. 常见问题与排查技巧实录最后分享一些我在实际开发中经常遇到的问题和排查思路。这些坑在官方文档里很难找到现成答案但几乎每个做图形优化的人都会碰到。7.1 App数据流卡顿不知道该看哪里这个场景最常见。游戏帧率不稳定滑动列表掉帧一开始大家都会去查App自身的代码改布局、优化图片加载但改了半天效果有限。我的经验是先抓Perfetto不要瞎猜。Perfetto里能看到App的Vsync回调时间、绘制耗时、GPU队列排队情况、BufferQueue的状态变化、SurfaceFlinger合成耗时和HWC的present时间。拿到数据后按这几条原则排查如果App的Draw和RenderThread耗时都很低但SurfaceFlinger的合成间隔不均匀问题很可能在系统侧要么是Layer太多要么是HWC压力大。如果App的Vsync回调本身就频繁延迟那要回去看主线程的message queue或者看Choreographer的callback耗时多半是应用逻辑把主线程抢占了。如果GPU时间很长先用GPU Inspector或者systrace里的GPU track定位是哪个pass耗时再决定是减少绘制指令还是降低特效等级。7.2 帧率正常但显示内容卡顿这听起来很矛盾但其实很常见。比如你跑一个60帧的AppSurfaceFlinger合成步骤也正常但画面就是一顿一顿的。这时候要重点检查帧间隔到底是不是均匀的。我对团队里的新人常说一句话比起帧率帧间隔更能反映真实体验。有的设备会在某个时间段强制切到低刷新率节奏导致App和屏幕的Vsync阶段错位App画好帧后要等好几个Vsync才被present出去表现就是“有时候突然卡一下”。遇到这种问题先在Pefetto里对比App的Vsync和HWC的Vsync是不是同一个节奏再看设备的刷新率切换策略是否过于激进。比如某些应用场景下系统为了省电会把120Hz切成60Hz但对游戏来说这个操作本身就是灾难。7.3 黑屏、闪烁和花屏问题这类问题通常不是上层代码的问题而是要往硬件合成和内存同步的方向查。我遇到过不少黑屏案例最后都归宿到HWC被给了一个未完成GPU写入的buffer也就是fence没等对还有的是Gralloc分配的内存被错误复用缓冲区还没读取完就被重新dequeue去写导致花屏。排查这类问题时强烈建议抓一下HWC的trace和驱动日志确认有没有明显的错误事件。如果是自研设备最好找驱动工程师一起看HWC协议交互很多问题其实出在HAL层的能力协商。上层应用开发者遇到这类问题可以尝试关闭硬件层合成强制走GPU合成如果症状消失基本可以判断是HWC或者驱动那一段的问题。7.4 值得记住的三个排查心得第一图形问题“动胜于猜”。不要凭感觉改代码先把trace抓出来用数据定位到具体模块再去看代码。第二同步和fence问题是最难复现也最难定位的一定要保留现场信息抓trace时把fence相关的dump也一并抓下来。第三很多“疑难杂症”其实是多帧累积的调度问题只看单帧截图是看不出来的必须看一段连续时间线上的行为。我个人在实际操作中最深的体会是Android图形系统的性能瓶颈往往不是某一个模块不够快而是模块之间的衔接节奏没有对齐。你能把BufferQueue的状态、Vsync的相位、SurfaceFlinger的合成间隔这几个点对上就已经超过大多数人了。新版系统更新再频繁这套底层逻辑也不会变花时间把基础架构啃透是回报率最高的投入。
返回列表