16ms_do.md
June 5, 2018 · View on GitHub
16ms对于系统干了那些事
-
1.手机屏幕是由许多的像素点组成的,每个像素点通过显示不同的颜色最终屏幕呈现各种各样的图像.
-
2.像素从哪里来?
在GPU中有一块缓冲区叫做 Frame Buffer ,这个帧缓冲区可以认为是存储像素值的二位数组, 数组中的每一个值就对应了手机屏幕的像素点需要显示的颜色. 由于这个帧缓冲区的数值是在不断变化的,所以只要完成对屏幕的刷新就可以显示不同的图像了. 至于刷新工作手机的逻辑电路会定期的刷新 Frame Buffer的 目前主流的刷新频率为60次/秒
折算出来就是16ms刷新一次 -
3.Frame Buffer 中的数据怎么来
1)GPU 除了帧缓冲区 用以交给手机屏幕进行绘制外. 还有一个缓冲区 Back Buffer 这个用以交给应用的,让你往里面填充数据. GPU会定期交换 Back Buffer 和 Frame Buffer 也就是让Back Buffer中的数据转到 Frame Buffer 然后交给屏幕进行显示绘制, 同时让原先的Frame Buffer 变成 Back Buffer 让程序处理. 2)这也就是贯穿整个安卓系统的双缓冲机制,实际上的帧就保存在这两个缓冲区, A缓冲区用来显示当前帧,B缓冲区就用来缓存或者成为处理下一帧数据, 这样就可以做到一边处理一边显示,双缓冲主要加快栅格化速度 -
4.如何发生丢帧现象的
Frame Buffer和Back Buffer的数据是自动完成交换的,我们需要处理的是根据需求向 Back Buffer中填充数据即可, 那么在向Back Buffer填充数据期间此时如果需要两者交换处理怎么办呢? 由于在填充Back Buffer数据时 系统会将 Back Buffer 锁上,因此此时这次数据交换就会被放弃, 这样手机还是显示原来的内容?等到下次(再隔一个16ms)完成交换再显示新的图像时一共需要的时间是32ms,这就是丢帧.如果是严重丢帧就是需要等待更多的16ms -
5.从XML到显示屏幕的过程
1)绝大多数渲染操作都依赖两个硬件: CPU 、 GPU 。 CPU 负责 Measure 、 layout 、 Record 、 Execute 的计算操作, GPU 负责栅格化( Rasterization )操作。 2)CPU会将ui组件计算成多边形(polygons)和纹理(textures),然后交给GPU进行栅格化渲染, 最后GPU将数据传给屏幕进行绘制显示.当然在CPU通过OpenGL ES API处理传递给 GPU之间还需要经过 我们需要在 16 ms 内处理完所有 CPU 和 GPU 的计算、绘制、渲染等操作,才能获得应用的流畅体验。 -
6.避免帧丢失(为了避免帧丢失,我们就要确保更新时间不要超过16ms)
- 尽可能的减少布局的嵌套 避免无用的布局
- 对于自定义view 减少不必要的invalidate的调用
- 去除view中不必要的background, 比如ImageView,假如它显示的图片填满了它的空间,就没必要给它设置背景色
在向Back Buffer填充数据时 Back Buffer 会被锁定,然后会将一个指向它的 Canvas 对象交给程序. 应用程序收到这个对象后按照视图层次从上往下遍历. 在view 的onDraw(Canvas canvas)方法中就是这个对象, 减少视图层可以减少canvas的传递时间
invalidate 方法会使视图重绘,所以减少该方法的使用同时合理的使用该方法也会降低丢帧率.