Systrace 学习笔记(1)

快捷键使用:

W : 放大 Systrace , 放大可以更好地看清局部细节

S : 缩小 Systrace, 缩小以查看整体

A : 左移

D : 右移

M : 高亮选中当前鼠标点击的段(这个比较常用,可以快速标识出这个方法的左右边界和执行时间,方便上下查看)

数字键1 : 切换到 Selection 模式 , 这个模式下鼠标可以点击某一个段查看其详细信息, 一般打开 Systrace 默认就是这个模式 , 也是最常用的一个模式 , 配合 M 和 ASDW 可以做基本的操作

数字键2 : 切换到 Pan 模式 , 这个模式下长按鼠标可以左右拖动, 有时候会用到

数字键3 : 切换到 Zoom 模式 , 这个模式下长按鼠标可以放大和缩小, 有时候会用到

数字键4 : 切换到 Timing 模式 , 这个模式下主要是用来衡量时间的,比如选择一个起点, 选择一个终点, 查看起点和终点这中间的操作所花费的时间.

三、Why 60 fps

软件的渲染率和硬件的刷新率要一起搭配,才能做到用户使用时足够流畅。

为什么手机的屏幕刷新率不能太高呢?

限于手机电池、硬软件的技术,目前移动设备上使用的60HZ,也就是60帧每秒,虽然在硬件和软件上,都能做到120HZ的刷新率,但是单位时间内高刷新次数也会带来高消耗,而移动端设备是不可能随时充着电的,所以手机屏幕的刷新率现在还不能太高,当然未来肯定能行。

四、 SystemServer 解读

窗口动画:

启动流程:点击App时,首先Launcher会启动一个StartingWindow,等App中启动页面的第一帧绘制好了,就会马上从Launcher切换回App的窗口动画。

ActivityManagerService:

AMS 相关的 Trace 一般会用 TRACE_TAG_ACTIVITY_MANAGER 这个 TAG,在 Systrace 中的名字是 ActivityManager。

WindowManagerService:

一般会用 TRACE_TAG_WINDOW_MANAGER 这个 TAG,在 Systrace 中 WindowManagerService 在 SystemServer 中多在 对应的 Binder 中出现。

Input:

主要是由 InputReader 和 InputDispatcher 这两个 Native 线程组成。

Binder:

SystemServer 由于提供大量的基础服务,所以进程间的通信非常繁忙,且大部分通信都是通过 Binder 。

HandlerThread:

BackgroundThread,许多对性能没有要求的任务,一般都会放到 BackgroundThread 中去执行。

ServiceThread:

ServiceThread 继承自 HandlerThread。

UIThread、IoThread、DisplayThread、AnimationThread、FgThread、SurfaceAnimationThread都是继承自 ServiceThread,分别实现不同的功能,根据线程功能不同,其线程优先级也不同。

每个 Thread 都有自己的 Looper 、Thread 和 MessageQueue,互相不会影响。Android 系统根据功能,会使用不同的 Thread 来完成。

五、 SurfaceFlinger 解读

SurfaceFlinger:

作用:合成图像的,将APP要画的图像处理后显示在硬件上;

触发:收到vsync信号后,开始已帧的形式绘图;

流程:当VSYNC 信号到达 --> 遍历层列表,以寻找新的缓冲区 --> 有新的缓冲区,获取该缓冲区;没有,使用以前获取的缓冲区 --> 收集完毕后,询问HWC如何合成。

流程图如下:

App --> BufferQueue:

App与BufferQueue交互流程:收到vsync信号后,应用主线程(UI Thread)被唤醒,主线程处理完数据后,会唤醒应用渲染线程RenderThread同步数据,RenderThread会从BufferQueue取出一个Buffer,然后往Buffer写入具体的 drawcall,完成后再将有数据的Buffer还给BufferQueue。

BufferQueue --> Surface Flinger:

思考后认为,App是不断往BufferQueue里面丢数据的,而vsync信号的发送与前面无关,就是系统提醒Surface Flinger可以画图了,那Surface Flinger就马上去BufferQueue取数据,然后画图。

Surface Flinger --> HWC:

这部分在文章中说明程度不够,目前只知道HWC是会根据SurfaceFlinger提供的信息来提供显示的方案——用于确定通过可用硬件来合成缓冲区的最有效方法。

六 Input 解读

当用户点开手机屏幕后,会做什么?用户会点击进入想看的页面、滑动切换的页面、点击后退按钮返回上一个以及按下Home键返回桌面,这些事件在安卓系统中都是以Message的形式传递,而上述这些操作,都属于InputMessage范畴,都是Input事件。

Input事件包含:

触摸事件(Down、Up、Move)

Key 事件(Home Key 、 Back Key)

本节主要描述当用户按下屏幕后,触发的流程是怎么样的。

流程中主要和这些内容有关:InputReader、InputDispatcher、OutboundQueue、WaitQueue、PendingInputEventQueue、deliverInputEvent和InputResponse 。

流程如下:

用户按下屏幕 --> InputReader读取Input事件,将其放入InboundQueue中,唤醒InputDispatcher线程 --> InputDispatcher从InboundQueue取出事件,依次对注册了Input事件的所有App(进程)做出以下操作:1. 派发给的OntboundQueue,2. 记录到各个App的WaitQueue --> InputDispatcher通过直接唤醒、Binder的方式将主线程UI Thread唤醒 --> UI Thread处理完成后,会将WaitQueue 里面的Input事件删除。

可以通过指令:adb shell dumpsys input获得一些重要的信息,如Device、InputReader、Inputdispatcher等等。

七、Vsync 解读

Vsync是什么?

Vsync是信号,用来控制App渲染图像、SurfaceFlinger合成图像的节奏。Vsync可以由硬件或软件产生,主要是由硬件HWC生成。

Vsync的流程:

HWC产生Vsync --> DispSync将Vsync生成Vsync-app和Vsync-sf --> 收到信号后,launcher的UI Thread负责将图像放入缓存,SF的UI Thread负责将缓存中的数据展示

从 App 绘制到屏幕显示,分为下面几个阶段:

第一阶段:App 在收到 Vsync-App 的时候,在主线程进行 measure、layout、draw(构建 DisplayList , 里面包含 OpenGL 渲染需要的命令及数据) 。这里对应的 Systrace 中的主线程 doFrame 操作;

image.png

第二阶段:CPU 将数据上传(共享或者拷贝)给 GPU, 这里 ARM 设备 内存一般是 GPU 和 CPU 共享内存。这里对应的 Systrace 中的渲染线程的 flush drawing commands 操作;

image.png

第三阶段:通知 GPU 渲染,真机一般不会阻塞等待 GPU 渲染结束,CPU 通知结束后就返回继续执行其他任务,使用 Fence 机制辅助 GPU CPU 进行同步操作;

第四 阶段:swapBuffers,并通知 SurfaceFlinger 图层合成。这里对应的 Systrace 中的渲染线程的 eglSwapBuffersWithDamageKHR 操作;

image.png

第五阶段:SurfaceFlinger 开始合成图层,如果之前提交的 GPU 渲染任务没结束,则等待 GPU 渲染完成,再合成(Fence 机制),合成依然是依赖 GPU,不过这就是下一个任务了.这里对应的 Systrace 中的 SurfaceFlinger 主线程的 onMessageReceived 操作(包括 handleTransaction、handleMessageInvalidate、handleMessageRefresh)SurfaceFlinger 在合成的时候,会将一些合成工作委托给 Hardware Composer,从而降低来自 OpenGL 和 GPU 的负载,只有 Hardware Composer 无法处理的图层,或者指定用 OpenGL 处理的图层,其他的 图层偶会使用 Hardware Composer 进行合成;

第六阶段 :最终合成好的数据放到屏幕对应的 Frame Buffer 中,固定刷新的时候就可以看到了。

收到Vsync信号时,会发生什么?

App和SF同时收到Vsync信号(在vsync-offset = 0时);

App开始对这一帧的Buffer进行渲染,SF开始对上一帧的Buffer进行合成;

Vsync Offset是什么?

Vsync Offset是指,让App和SF收到Vsync信号有一个时间间隔,而非同时收到。

为什么要有Vsync Offset?

因为如果Offset默认为0,那么SF收到Vsync信号后,合成的是上一帧App绘制的数据,如果我们让Offset不为0,那么可以做到当App绘制完这一帧的数据后,再让SF去合成这一帧的数据,用户就能提前看到一帧的动画。但是难以确定Offset的时间,很难做到合成绘制当前帧动画。

HW_Vsync

参考博主的文章,可以知道HW_Vsync并不会一直开启,而会使用DispSync线程模拟硬件信号,通过3到32个HW_Vsync模拟出SW_Vsync,只要收到的Present Fence没有超过误差,HW_VSYNC 就会关掉,使用SW_Vsync,不然会继续接收HW_VSYNC 计算 SW_VSYNC 的值,直到误差小于threshold。

不是每次申请 Vsync 都会由硬件产生 Vsync,只有此次请求 vsync 的时间距离上次合成时间大于 500ms,才会通知 hwc,请求 HW_VSYNC。

八、 Vsync-App :基于 Choreographer 的渲染机制详解

Choreographer 扮演 Android 渲染链路中承上启下的角色:

承上:负责接收和处理 App 的各种更新消息和回调,等到 Vsync 到来的时候统一处理。比如集中处理 Input(主要是 Input 事件的处理) 、Animation(动画相关)、Traversal(包括 measure、layout、draw 等操作) ,判断卡顿掉帧情况,记录 CallBack 耗时等

启下:负责请求和接收 Vsync 信号。接收 Vsync 事件回调(通过 FrameDisplayEventReceiver.onVsync );请求 Vsync(FrameDisplayEventReceiver.scheduleVsync) .

九、MainThread 和 RenderThread 解读

主线程和渲染线程一帧的工作流程:

image.png

主线程处于 Sleep 状态,等待 Vsync 信号

Vsync 信号到来,主线程被唤醒,Choreographer 回调 FrameDisplayEventReceiver.onVsync 开始一帧的绘制

处理 App 这一帧的 Input 事件(如果有的话)

处理 App 这一帧的 Animation 事件(如果有的话)

处理 App 这一帧的 Traversal 事件(如果有的话)

主线程与渲染线程同步渲染数据,同步结束后,主线程结束一帧的绘制,可以继续处理下一个 Message(如果有的话,IdleHandler 如果不为空,这时候也会触发处理),或者进入 Sleep 状态等待下一个 Vsync

渲染线程首先需要从 BufferQueue 里面取一个 Buffer(dequeueBuffer) , 进行数据处理之后,调用 OpenGL 相关的函数,真正地进行渲染操作,然后将这个渲染好的 Buffer 还给 BufferQueue (queueBuffer) , SurfaceFlinger 在 Vsync-SF 到了之后,将所有准备好的 Buffer 取出进行合成(这个流程在讲 SurfaceFlinger 的时候会提到)

硬件加速是什么:

硬件加速是指在计算机中通过把计算量非常大的工作分配给专门的硬件硬件)来处理以减轻中央处理器的工作量之技术。

就是CPU把工作分给GPU和APU了。

硬件加速流程:

1.CPU从文件系统里读出原始数据(DirectSHow的源滤镜),分离出压缩的视频数据(分离器)。放在系统内存中。GPU、APU不运行。

2.CPU把压缩音视频数据交给GPU、APU, 这时总线上开始忙了,压缩数据从系统内存拷贝到显卡上的显存里和声卡上的声存里(如果有的话)。

3.CPU要求GPU、APU开始硬件解码,CPU不运行,GPU、APU开始忙。当然CPU会定期查询一下GPU、APU忙的怎么样了。

4.GPU、APU开始用自己的电路解码视频数据(已经在显、声存里了),解压后的数据还是放在显声存里面。

5.音视频数据刚解码完成以后还不能立刻拿去播放,因为还需要后期处理,如deinterlace, 3:2pulldown,多普勒效应,等等。GPU、APU再用自己的后期处理电路来进行处理。

6.后期处理以后的未压缩数据拿去播放, GPU再开始忙视频的缩放,亮度,gamma等事情。CPU还是闲。

7.GPU、APU终于忙完了,下面的视频数据在哪里?通知CPU,GPU、APU先歇会。CPU又开始忙了,回到第1步。

CPU拿到视频、音频数据后,拷贝给GPU、APU拿去做处理和显示,并且CPU会不断监听GPU和APU的进度。

软件绘制:

安卓系统默认开启硬件加速,我们可以针对某个App,关闭App的硬件加速。关闭后,CPU不会再将数据传递给GPU渲染,而是会直接调用 libSkia 来进行渲染,systrace中软件加速如图所示:

与硬件加速对比,主线程执行的时间变长了,更容易出现卡顿,同时帧与帧之间的空闲间隔也变短了,使得其他 Message 的执行时间被压缩。

硬件加速时,主线程和渲染线程的分工:

主线程负责处理进程 Message、处理 Input 事件、处理 Animation 逻辑、处理 Measure、Layout、Draw ,更新 DIsplayList ,但是不涉及 SurfaceFlinger 打交道;

渲染线程负责渲染渲染相关的工作,一部分工作也是 CPU 来完成的,一部分操作是调用 OpenGL 函数来完成的。

当启动硬件加速后,在 Measure、Layout、Draw 的 Draw 这个环节,Android 使用 DisplayList 进行绘制而非直接使用 CPU 绘制每一帧。DisplayList 是一系列绘制操作的记录,抽象为 RenderNode 类,这样间接的进行绘制操作的优点如下

DisplayList 可以按需多次绘制而无须同业务逻辑交互

特定的绘制操作(如 translation, scale 等)可以作用于整个 DisplayList 而无须重新分发绘制操作

当知晓了所有绘制操作后,可以针对其进行优化:例如,所有的文本可以一起进行绘制一次

可以将对 DisplayList 的处理转移至另一个线程(也就是 RenderThread)

主线程在 sync 结束后可以处理其他的 Message,而不用等待 RenderThread 结束

十、Binder 和锁竞争解读

Binder是什么?

Binder是解决安卓系统中进程通讯的工具。

Systrace中,和Binder相关的进程通信是怎么表现的?

在打开systrace图像右上角View Options的Flow events后,可以看到binder跨进程通讯的步骤,下面两张图显示了,开启binder调用 --> 获得对端进程响应 --> binder调用返回的流程。

Systrace显示锁的信息:

在systrace中我们可以看到一些线程下面的执行方法:monitor contention with owner xxxxx。

尾声

开发是需要一定的基础的,我是08年开始进入Android这行的,在这期间经历了Android的鼎盛时期,和所谓的Android”凉了“。中间当然也有着,不可说的心酸,看着身边朋友,同事一个个转前端,换行业,其实当时我的心也有过犹豫,但是我还是坚持下来了,这次的疫情就是一个好的机会,大浪淘沙,优胜劣汰。再等等,说不定下一个黄金浪潮就被你等到了。

  • 330页 PDF Android核心笔记

  • 几十套阿里 、字节跳动、腾讯、华为、美团等公司2020年的面试题

  • PDF和思维脑图,包含知识脉络 + 诸多细节

  • Android进阶系统学习视频

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

美团等公司2020年的面试题**

[外链图片转存中…(img-5pWeiRoL-1714517086572)]

[外链图片转存中…(img-5X6Op4Qn-1714517086573)]

  • PDF和思维脑图,包含知识脉络 + 诸多细节

[外链图片转存中…(img-grRI9uju-1714517086573)]

  • Android进阶系统学习视频

[外链图片转存中…(img-ooGGJReS-1714517086573)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 18
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值