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 方法会使视图重绘,所以减少该方法的使用同时合理的使用该方法也会降低丢帧率.

整个16ms并不是完全让我绘制界面的,还有layout,measue等方法的调用呢,所以留给用于绘制自己的界面的时间肯定是少于16ms的