布局渲染流程和原理 学习笔记

手机CPU  处理的任务繁多,出了逻辑计算以外还要做内存管理,显示操作,因此 在实际运算的时候性能会大打折扣,在没有GPU的时代,运算速度根本上今天负责三维游戏要求,即使CPU工作频率超过2GHZ,对他绘制的图形提高也不大,这是GPU设计出来了。

黄色的 Control 为控制器,用于协调控制整个 CPU 的运行,包括取出指令、控制其他模块的运行等;
绿色的 ALU ( Arithmetic Logic Unit )是算术逻辑单元,用于进行数学、逻辑运算;
橙色的 Cache 和 DRAM 分别为缓存和 RAM ,用于存储信息。

这里顺便补一下缓存的知识:

缓存是cpu的一部分,存在于CPU,gpu

cpu的存取速度非常快1秒可以存取处理10亿跳指令和数据,俗称:gpu主频1G,而内存速度很慢,快的内存也就几十兆,两者速度差距很大,缓存为了解决CPU速度和内存速度的差距问题。

内存中刚被CPU访问最频繁的数据和指令被复制进CPU的缓存中,这样CPU直接去取缓存中的指令。

关于一级缓存和二级缓存
 首先理解ROM和RAM,RAM掉电,数据不保存,ROM掉电数据保存。  rom相当于手机的磁盘,也就是手机存放文件的容量。

RAM分2种  :SRAM   DRAM    S  代表static  D代表Dynamic  中文意思:   静态随机访问存储器 动态随机访问存储器 。静态的比动态的速度快。但是SRAM 集成度低,存同样数据,SRAM比DRAM体积大6倍。价格也高。所以想了个折中办法,就是增加高速DRAM,虽然SRAM慢但是比普通DRAM快。

cpu中分一级缓存 SRAM和二级缓存高速DRAM,cpu找指令和数据先取一级缓存,然后再去找二级缓存,最后再去访问内存。

在回过来将cpu。  CPU 的控制器复杂 但是ALU少,  cpu擅长处理复杂的逻辑运算,但是不擅长数学尤其是浮点运算。

所以 cpu图形显示将交给GPU处理了

Cpu在处理View的时候将VIEW  转换成类似SVG的多为向量图像,然后再将向量图像交给GPU,GPU进行栅格化,然后绘制,填充像素。

栅格化:将向量突图形转换成位图显示再显示器。

分析应用卡顿原理:

60HZ刷新频率由来:

1.12fps  如果 画面再每秒10到12帧之间,可以看成连贯的

2.24fps  一般电影拍摄帧率每秒24帧.

3.30fps  早期游戏的帧率

4. 60fps  在与手机交互过程中,低于60帧,人能感觉出画面卡顿和迟滞现象

绘制计算

一个ui对象。需要cpu转成多维向量图像,然后GPU栅格化,然后进行刷新显示。但是必须等底层ui渲染之后才能进行刷新

安卓系统每隔16ms 发出VSSYNC信号  (1000ms/60=16.66ms),触发对UI渲染。如果每次计算都成功这样就能达到流畅的画面所需60FPS。所以计算绘制内容大多数操作必须在16MS内完成

卡顿原理

当某一帧画面的渲染计算时间超过16ms,垂直同步机制会让显示器硬件等待CPU和GPU计算完成后再进行渲染操作。这一帧画面停留超过16ms,就会造成卡顿。

也就是说 ,渲染计算 每16毫秒会刷新屏幕,如果在第16ms 的时候没计算完,那就要等到下一个16毫秒的间隔取判断了。

优化卡顿

渲染计算其实就做2件事:

1. 将ui对象转换成一系列多边形和纹理

2.cpu传递数据到gpu

针对这2个行为 的优化是1.CPU减少XML转换成对象的时间,2gpu减少重复绘制的时间

代码中的体现:

减少XML的层级,  能用relativelayout就不要用linearLayout,  我更喜欢用约束布局contraintlayout

过度绘制的概念

GPU的绘制过程类似刷墙,先绘制一个图层,比如白色背景,然后再绘制一个图,比如一个圆形图片,这样无用的而图层倍绘制再底层,造成不必要的浪费。

过度绘制查看工具使用

过度绘制分4个层次

è¿éåå¾çæè¿°

蓝色:绘制一次,无过度绘制

淡绿:绘制两次

淡红:绘制三次

深红:绘制四次及以上

打开开发者选项可以找到调试GPU过度绘制

计算渲染的耗时工具

当view 绘制内容发生变化,displayList会重新创建,再渲染,当View发生位移,DisplayList不会重新创建,只执行重新渲染操作。

中间有一根绿色的横线,代表16ms,我们需要确保每一帧花费的总时间都低于这条横线,这样才能够避免出现卡顿的问题。 

每根柱子包含三部分,

蓝色:测量绘制Display List时间

红色:OpenGL渲染Display List所需要时间

黄色:Cpu等待Gpu处理时间

注: OpenGL ES 是手持嵌入式设备的 3DAPI,跨平台的、功能完善的 2D 和 3D 图形应用程序接口 API,有一套固定渲染管线流程。

DisplayList 在 Android 把 XML 布局文件转换成 GPU 能够识别并绘制的对象。这个操作是在 DisplayList 的帮助下完成的。DisplayList 持有所有将要交给 GPU 绘制到屏幕上的数据信息。
 

自定义控件减少过度绘制

思路是如果几个图层叠在一起,就会造成过度绘制,解决的办法是对几个图层的画布Canvas进行裁剪,然后再绘制图片。然后再拼在一起。这样就可以避免过度绘制

关键代码如下

 DroidCard c = mDroidCards.get(i);
        canvas.save();
        canvas.clipRect((float)c.x,0f,(float)(mDroidCards.get(i+1).x),(float)c.height);
        canvas.drawBitmap(c.bitmap,c.x,0f,paint);
        canvas.restore();

布局减少过度绘制

造成原因是给生层次的布局控件设置了多个背景

首先我们可以去掉主题的样式背景色

 <style name="Theme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="android:windowBackground">@null</item>
    </style>

然后再控件中如果外面包裹的比如LinearLayout  已经是白色背景了,那么里面的一些 控件,如TextView或者ImageView就不用再去设置白色背景了。避免重复设置背景

总结

布局优化:

1.删除多余的嵌套层

2.删除重复的背景设置

3.自定义控件ondraw方法中对自定义控件的图层进行裁剪,避免图层重叠

该笔记源于一篇ui渲染优化的优秀文章,我只捡了概念性的知识点进行记录,想看更详细的可以看原文

https://blog.csdn.net/qq_18983205/article/details/80426538

猜你喜欢

转载自blog.csdn.net/xiexiaotian11/article/details/88777199
今日推荐