美文网首页
Android自定义 View 1-8 硬件加速

Android自定义 View 1-8 硬件加速

作者: 青果果 | 来源:发表于2017-11-17 18:35 被阅读0次

    从凯哥Blog copy 过来 HenCoder Android 自定义 View 1-8 硬件加速

    只挑重点精华部分

    概念

    所谓硬件加速,指的是把某些计算工作交给专门的硬件来做,而不是和普通的计算工作一样交给 CPU 来处理。这样不仅减轻了 CPU 的压力,而且由于有了「专人」的处理,这份计算工作的速度也被加快了。这就是「硬件加速」。
    而对于 Android 来说,硬件加速有它专属的意思:在 Android 里,硬件加速专指把 View 中绘制的计算工作交给 GPU 来处理。进一步地再明确一下,这个「绘制的计算工作」指的就是把绘制方法中的那些 Canvas.drawXXX() 变成实际的像素这件事。

    原理

    在硬件加速关闭的时候,Canvas 绘制的工作方式是:把要绘制的内容写进一个 Bitmap,然后在之后的渲染过程中,这个 Bitmap 的像素内容被直接用于渲染到屏幕。这种绘制方式的主要计算工作在于把绘制操作转换为像素的过程(例如由一句 Canvas.drawCircle() 来获得一个具体的圆的像素信息),这个过程的计算是由 CPU 来完成的。

    而在硬件加速开启时,Canvas 的工作方式改变了:它只是把绘制的内容转换为 GPU 的操作保存了下来,然后就把它交给 GPU,最终由 GPU 来完成实际的显示工作。

    为什么就加速了

    硬件加速能够让绘制变快,主要有三个原因:

    1.本来由 CPU 自己来做的事,分摊给了 GPU 一部分,自然可以提高效率;
    2.相对于 CPU 来说,GPU 自身的设计本来就对于很多常见类型内容的计算(例如简单的圆形、简单的方形)具有优势;
    3.由于绘制流程的不同,硬件加速在界面内容发生重绘的时候绘制流程可以得到优化,避免了一些重复操作,从而大幅提升绘制效率。

    其中前两点可以总结为一句:用了 GPU,绘制就是快。原因很直观,不再多说。

    在硬件加速开启时,前面说过,绘制的内容会被转换成 GPU 的操作保存下来(承载的形式称为 display list,对应的类也叫做 DisplayList),再转交给 GPU。由于所有的绘制内容都没有变成最终的像素,所以它们之间是相互独立的,那么在界面内容发生改变的时候,只要把发生了改变的 View 调用 invalidate() 方法以更新它所对应的 GPU 操作就好,至于它的父 View 和兄弟 View,只需要保持原样。那么这个工作量就很小了。

    正是由于上面的原因,硬件加速不仅是由于 GPU 的引入而提高了绘制效率,还由于绘制机制的改变,而极大地提高了界面内容改变时的刷新效率。

    所以把上面的三条压缩总结一下,硬件加速更快的原因有两条:

    1.用了 GPU,绘制变快了;
    2.绘制机制的改变,导致界面内容改变时的刷新效率极大提高。

    限制

    如果仅仅是这样,硬件加速只有好处没有缺陷,那大家都不必关心硬件加速了

    可事实就是,硬件加速不只是好处,也有它的限制:受到GPU 绘制方式的限制,Canvas 的有些方法在硬件加速开启式会失效或无法正常工作。比如,在硬件加速开启时, clipPath() 在 API 18 及以上的系统中才有效,等等......
    所有的原生自带控件,都没有用到 API 版本不兼容的绘制操作,可以放心使用。所以你只要检查你写的自定义绘制就好。

    总结

    硬件加速指的是使用 GPU 来完成绘制的计算工作,代替 CPU。它从工作分摊和绘制机制优化这两个角度提升了绘制的速度。

    1.用了 GPU,绘制变快了;
    2.绘制机制的改变,导致界面内容改变时的刷新效率极大提高。

    硬件加速可以使用 setLayerType() 来关闭硬件加速,但这个方法其实是用来设置 View Layer 的:
    参数为 LAYER_TYPE_SOFTWARE 时,使用软件来绘制 View Layer,绘制到一个 Bitmap,并顺便关闭硬件加速;
    参数为 LAYER_TYPE_HARDWARE 时,使用 GPU 来绘制 View Layer,绘制到一个 OpenGL texture(如果硬件加速关闭,那么行为和 VIEW_TYPE_SOFTWARE 一致);
    参数为 LAYER_TYPE_NONE 时,关闭 View Layer。
    View Layer 可以加速无 invalidate() 时的刷新效率,但对于需要调用 invalidate() 的刷新无法加速。

    View Layer 绘制所消耗的实际时间是比不使用 View Layer 时要高的,所以要慎重使用。

    相关文章

      网友评论

          本文标题:Android自定义 View 1-8 硬件加速

          本文链接:https://www.haomeiwen.com/subject/clajvxtx.html