Android硬件加速

简介:

概要


离Android 3.0开始(API L11)。Android开始使用硬件加速2D渲染。硬件加速的手段Android于View图形图像都使用GPU来进行绘制,使用硬件加速,在大部分时候都让绘制更加流畅,但付出的代价是须要消耗很多其它的内存资源。

硬件加速在API L14之上是默认开启的,对于主要的View绘制,通过硬件加速能够添加画图的流程性,可是要注意的是,并非全部的2D图形绘制API都支持硬件加速。

通过开发人员选项中的“强制进行GPU渲染”,用户能够为全局打开硬件加速。在3.0 以上的Android中,系统已经对大部分动画都进行了硬件加速。


名词解释

  • GPU:Graphic Processing Unit (图形处理器)
  • OpenGL:Open Graphic Library 定义了一个跨编程语言、跨平台的编程接口的规格,不同厂商会有不同的实现方法,它主要用于三维图象(二维的亦可)绘制。

  • SurfaceFlinger:Android中负责Surface之间叠加、混合操作的动态库
  • Skia:Android中的2D图形库

控制硬件加速


因为硬件加速对某些2D画图API的不支持,所以Android系统提供了四种级别的控制方式。


Application级别


在应用的Android清单文件里,把下列属性加入到<application>元素中,来开启整个应用程序的硬件加速,代码例如以下所看到的:

android:hardwareAccelerated="true"


Activity级别


比整个App范围稍小,我们能够在Activity范围内进行控制,代码例如以下所看到的:

android:hardwareAccelerated="true"


Window级别

针对单个的Window,Android相同能够控制硬件加速,代码例如以下所看到的:

getWindow().setFlags(
        WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
        WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

可是对Window来说。Android无法禁止硬件加速。



View级别


View级别是用的最多的控制硬件加速的级别,我们能够通过例如以下所看到的的代码来禁止硬件加速:

setLayerType(View.LAYER_TYPE_SOFTWARE, null);

与Window级别相反。我们无法在View级别开启硬件加速。


推断View是否已开启硬件加速


推断View是否支持硬件加速一般有例如以下所看到的的两种方法:


View.isHardwareAccelerated()
Canvas.isHardwareAccelerated()

尽量使用Canvas对象的推断方法。


Android画图模式


相对于是否开启硬件加速模式,Android的画图模式被分为两种——基于软件的画图模式与基于硬件的画图模式。


基于软件的画图模式


基于软件的画图模式在重绘View时,须要例如以下两个过程:

  • Invalidate the hierarchy
  • Draw the hierarchy

须要进行重绘时,系统发出invalidate()信号,并在View视图树中进行传递,计算须要又一次绘制的区域,可是这样的画图方式有两个不足:

  1. 当我们仅仅须要重绘视图树中的一个View时。视图树中的View都将进行重绘,并且遍历视图树也浪费大量时间。

    比如一个ViewA在还有一个ViewB之上。即使B没有发生变化,重绘A的时候,B也会重绘。

  2. 这样的方式隐藏了绘制中的bug。比如上面的样例中,因为ViewA、ViewB相互重叠,有须要重绘的the dirty region,那么假设B忘记了进行重绘的逻辑。那么A进行重绘的时候,就会将B重绘。也就是说使用错误的行为来得到了正确的现象。

    正是因为这个原因,开发人员须要保证在View须要发生重绘时,调用正确的invalidate()方法。

基于硬件的画图模式


基于硬件的画图方式相同使用invalidate()信号来进行重绘。但其绘制和渲染的方式不同。Android内部维护一个display list用于记录视图树的显示状态。当收到invalidate()信号时,系统仅仅须要更改须要重绘的视图的display list,而其它未发生改变的视图仅仅须要使用原来的display list就可以。整个过程分为三部分:

  • Invalidate the hierarchy
  • Record and update display lists
  • Draw the display lists

使用这样的方式。就能够避免软件画图中第二点的bug。

比如,假设有一个包括了一个Button对象的ListView对象的LinearLayout布局,那么LinearLayout布局的显示列表例如以下:

1. DrawDisplayList(ListView);

2.DrawDisplayList(Button)

假设如今要改变ListView对象的不透明度,那么在调用ListView对象的setAlpha(0.5f)方法时,显示列表就包括了下面处理:

1.SaveLayerAlpha(0.5);

2.DrawDisplayList(ListView);

3. Restore。

4.DrawDisplayList(Button)


不支持硬件加速的画图方法


假设应用程序受到这些错误的功能或限制的影响,那么能够通过调用setLayerType(View.LAYER_TYPE_SOFTWARE, null)方法针相应用程序受到影响的部分来关闭硬件加速。

详细哪些方法不支持硬件加速能够參考Google开发人员站点上的这篇文档 http://developer.android.com/guide/topics/graphics/hardware-accel.html


View Layers


在全部的Android版本号中,View都能够通过Canvas.saveLayer()方法来获得离屏缓冲的能力,离屏缓冲区或层有多种用途,特别是在呈现复杂的动画或使用组合效果时,能够获得更好的性能。比如,使用Canvas.saveLayer()能够实现淡入淡出的效果,先临时把一个View对象渲染在一个层中,然后把它和不透明因子合成到屏幕上显示。

从Android3.0(API Level 11)開始。用View.setLayerType()方法使用层的方式和时机会很多其它的控制。

这个API须要两个參数:一个是层的类型,还有一个是可选的,用于描写叙述层应该怎样被合成的Paint对象。

能够使用这个Paint对象来进行颜色过滤、特殊的混合模式、或者层的透明度。View对象能够使用下面三种层类型:


  • LAYER_TYPE_NONE:View对象用普通的方式来呈现,并且不是由屏幕外缓存来返回的。这样的类型是默认的行为;
  • LAYER_TYPE_HARDWARE:假设应用程序是硬件加速的,那么该View对象被呈如今硬件的一个硬件纹理中。假设没有被硬件加速,那么这样的层类型的行为与LAYER_TYPE_SOFTWARE相同。
  • LAYER_TYPE_SOFTWARE:View对象会被呈如今软件的一个位图中。

使用哪种层的类型。依赖下面目标:

  • 性能:使用硬件层类型,把View呈现到一个硬件纹理中。一旦该View对象被呈现到一个层中,那么它的画图代码直到调用该View对象的invalidate()方法时才会被运行。对于某些动画,如alpha动画,就能够直接使用该层。这么做对于GPU来说是很高效的。

  •  视觉效果:使用硬件或软件层类型和一个Paint对象。能够把一些特殊的视觉处理应用给一个View对象。

    比如,使用ColorMatrixColorFilter对象绘制一个黑白相间的View对象。

  •  兼容性:使用软件层类型会强制把一个View对象呈如今软件中。

    假设View对象被硬件加速(比如,假设整个应用程序都被硬件加速)发生呈现问题,那么使用软件层类型来解决硬件呈现管道的限制是一个easy的方法。


View layers and animations


当应用层使用硬件加速的时候。手机显示硬件能够让动画、显示效果更加平滑。假设你的动画效果不够流畅,那么就须要考虑在View层面上使用硬件加速来进行优化。在Android中,有些视图操作使用硬件加速是很高效的,因为这些操作不须要让对象失效后重绘,比如:

1. alpha:改变层的透明度

2. x,y,translation,translation:改变层的位置

3. scaleX,scaleY:改变成的缩放

4. rotation,rotation,rotationY:改变3D空间中视图的方向

5. pivotX,pivotY:改变层的变换控制点



对于以上属性的动画,在开启硬件加速后将会得到很高效的绘制,下面的代码展示了怎样高效的在3D空间中环绕Y轴旋转View对象。代码例如以下所看到的:

view.setLayerType(View.LAYER_TYPE_HARDWARE,null);
ObjectAnimator.ofFloat(view,"rotationY",180).start();

可是因为硬件加速会消耗系统内存。因此强烈建议在动画结束后取消硬件加速,代码例如以下所看到的:

View.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotationY", 180);
animator.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        view.setLayerType(View.LAYER_TYPE_NONE, null);
    }
});
animator.start();


硬件加速的缺点


当我们使用硬件加速时。会消耗很多其它的内存(将近4倍),假设分给应用的内存没有这么多,那么就会从系统剩于内存中进行划分。因此,硬件加速不适用于系统的核心进程。好的应用,应该在硬件加速(GPU)与软件绘制(CPU)中找到平衡点。

        另外。须要注意的是。App中进行UI渲染是无法使用并发的,多核心无法带来显示上的性能提升。同一时候,分辨率也是影响流畅度的一个很重要的方面。为了能够在更高的分辨率上进行流畅的绘制效果,那么就须要使用更加强大的GPU进行渲染。








本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/4888232.html,如需转载请自行联系原作者

相关实践学习
部署Stable Diffusion玩转AI绘画(GPU云服务器)
本实验通过在ECS上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。
相关文章
|
缓存 移动开发 前端开发
“一文读懂”系列:Android中的硬件加速
前几天有个朋友问我“了不了解关于手机硬件加速方面的知识?”,嗯?其实我也想知道。。。
|
缓存 算法 Java
Android硬件加速(二)-RenderThread与OpenGL GPU渲染
Android硬件加速(二)-RenderThread与OpenGL GPU渲染
1200 0
Android硬件加速(二)-RenderThread与OpenGL GPU渲染
|
存储 缓存 算法
理解Android硬件加速原理的小白文
理解Android硬件加速原理的小白文
414 0
理解Android硬件加速原理的小白文
|
前端开发 Java Android开发
|
Android开发 缓存 异构计算
Android动画之硬件加速
你的动画写出来卡嘛?流畅嘛 如果你想提升动画的性能,那就是用它-hardware layers。 During animations your views may be redrawn each frame.
815 0
|
缓存 API Go
Android图形显示系统——上层显示2:硬件加速实现
Android界面绘制的硬件加速实现 Android的界面绘制的硬件加速采取上下整合的一套流程实现 一、代码结构 (一)Java HardwareRenderer-&gt;ThreadedRenderer:组织硬件加速渲染的类,下发创建显示列表和回放的指令。 GLES20RecordngCanvas GLES20Canvas HardWareCanvas:与
4820 0
|
API Android开发 开发者
Android硬件加速
概述 从Android 3.0开始(API L11),Android开始全面使用硬件加速来进行2D渲染,硬件加速是指Android中在View上进行绘制的图形图像都使用GPU来进行绘制,使用硬件加速,在大部分时候都让绘制更加流畅,但付出的代价是需要消耗更多的内存资源。
1073 0
|
Android开发
Android硬件加速以及WebView的onPause,onResume,OnDestroy
MainActivity如下: package cn.testwebview; import java.util.Timer; import java.
1036 0
|
16天前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
40 19
|
16天前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
41 14