图片和图形之硬件加速(7)
原文
概要
从Android 3.0(API级别11)开始,Android 2D渲染管道支持硬件加速,这意味着在View画布上执行的所有绘图操作都 使用GPU。由于启用硬件加速所需的资源增加,您的应用程序将消耗更多的RAM。
如果您的目标API级别大于等于14,但也可以显式启用,则默认情况下会启用硬件加速。如果您的应用程序仅使用标准视图和 Drawables,则全局打开它不应导致任何不利的绘图效果。但是,由于所有2D绘图操作都不支持硬件加速,因此将其打开可能会影响某些自定义视图或绘图调用。问题通常表现为不可见的元素,例外或错误渲染的像素。为了解决这个问题,Android允许您在多个级别启用或禁用硬件加速。请参阅控制硬件加速。
如果您的应用程序执行自定义绘图,请在开启硬件加速功能的实际硬件设备上测试您的应用程序以发现任何问题 在不支持的绘图操作部分介绍了硬件加速,以及如何解决它们的已知问题。
另请参阅使用框架API 和Renderscript的OpenGL
控制硬件加速
您可以在以下级别控制硬件加速:
- Application
- Activity
- Window
- View
Application level
在Android清单文件中,将以下属性添加到 标记中,以便为整个应用程序启用硬件加速: <application>
<application android:hardwareAccelerated="true" ...>
Activity level
如果您的应用程序在全球范围内打开硬件加速时无法正常运行,您也可以控制它以进行单独的活动。要在活动级别启用或禁用硬件加速,可以使用android:hardwareAccelerated该元素的属性。以下示例为整个应用程序启用硬件加速,但为一个活动禁用它: <activity>
<application android:hardwareAccelerated="true"><activity ... /><activity android:hardwareAccelerated="false" />
</application>
Window level
如果您需要更细致的控制,则可以使用以下代码为给定窗口启用硬件加速:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
注意:您目前无法在窗口级别禁用硬件加速。
View level
您可以在运行时使用以下代码禁用单个视图的硬件加速:
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
注意:您目前无法在视图级别启用硬件加速。除禁用硬件加速外,视图图层还具有其他功能。有关其用途的更多信息,请参阅[查看图层](https://developer.android.com/guide/topics/graphics/hardware-accel#layers)。
确定视图是否是硬件加速的
对于一个应用程序来说,它是否有助于了解它当前是否是硬件加速的,特别是对于诸如自定义视图之类的东西。如果您的应用程序执行了大量的自定义绘制,并且并非所有操作都得到了新渲染管道的正确支持,那么这非常有用。
有两种不同的方法来检查应用程序是否是硬件加速的:
View.isHardwareAccelerated()true如果View连接到硬件加速窗口,则返回 。
- Canvas.isHardwareAccelerated()true如果Canvas硬件加速则 返回
如果您必须执行此操作,请检查您的绘图代码, Canvas.isHardwareAccelerated()而不是View.isHardwareAccelerated()在可能的情况下使用。当视图附加到硬件加速窗口时,仍然可以使用非硬件加速画布绘制视图。例如,为了缓存目的,将视图绘制到位图时会发生这种情况。
Android绘图模型
当启用硬件加速时,Android框架将利用新的绘图模型,利用显示列表将应用程序呈现在屏幕上。要充分了解显示列表以及它们可能如何影响您的应用程序,了解Android如何在没有硬件加速的情况下绘制视图也很有用。以下各节介绍基于软件和硬件加速的绘图模型。
基于软件的绘图模型
在软件绘图模型中,视图通过以下两个步骤绘制:
- 使层次结构失效
- 绘制层次结构
每当应用程序需要更新其UI的一部分时,它就会invalidate()在任何已更改内容的视图上调用(或其中一种变体)。无效消息一直传播到视图层次结构中,以计算需要重绘的屏幕区域(脏区域)。Android系统然后在与脏区相交的层级中绘制任何视图。不幸的是,这个绘图模型有两个缺点:
* 首先,这个模型需要在每个绘制过程中执行大量的代码。例如,如果您的应用程序调用invalidate()某个按钮,并且该按钮位于另一个视图的顶部,则Android系统即使没有更改也会重新绘制该视图。* 第二个问题是绘图模型可以隐藏应用程序中的错误。由于Android系统在与脏区域相交的情况下重绘视图,因此您更改的内容的视图可能会重新绘制,即使invalidate()未对其调用也是如此。发生这种情况时,您正在依靠另一个视图被无效以获得正确的行为。每次修改应用程序时,此行为都会更改。因此,invalidate()无论何时修改影响视图的绘图代码的数据或状态,都应该始终调用自定义视图。注意:Android视图会invalidate()在其属性发生更改时自动调用,例如背景颜色或a中的文本TextView。
硬件加速绘图模型
Android系统仍然使用invalidate()并draw()请求屏幕更新并呈现视图,但以不同的方式处理实际的图形。Android系统不是立即执行绘图命令,而是将它们记录在显示列表中,显示列表包含视图层次结构绘图代码的输出。另一个优化是Android系统只需要记录和更新显示列表,以查看通过invalidate() 调用标记为脏的视图。没有失效的视图可以通过重新发布之前记录的显示列表重新绘制。新的绘图模型包含三个阶段:
- Invalidate the hierarchy:使层次结构失效
- Record and update display lists:记录和更新显示列表
- Draw the display lists:绘制显示列表
有了这个模型,就不能依赖与脏区域相交的视图来draw()执行其方法。为确保Android系统记录视图的显示列表,您必须调用invalidate()。忘记这样做会导致视图在更改后看起来一样。
使用显示列表也有利于动画性能,因为设置特定的属性(如alpha或旋转)不需要使目标视图无效(它会自动完成)。此优化还适用于带有显示列表的视图(应用程序硬件加速时的任何视图)。例如,假设有一个LinearLayout包含ListView上面的a Button。显示列表LinearLayout如下所示:
- DrawDisplayList(ListView)
- DrawDisplayList(Button)
现在假设你想改变ListView不透明度。调用后setAlpha(0.5f)的ListView,显示列表现在包含这样的:
- SaveLayerAlpha(0.5)
- DrawDisplayList(ListView)
- Restore
- DrawDisplayList(Button)
复杂的绘图代码ListView没有执行。相反,系统只更新了更简单的显示列表LinearLayout。在未启用硬件加速的应用程序中,列表及其父项的绘图代码将再次执行。
不支持的绘图操作
当硬件加速时,2D渲染管线支持最常用的 Canvas绘图操作以及许多较少使用的操作。支持所有用于渲染Android应用程序的绘图操作,默认窗口小部件和布局以及反射和平铺纹理等常见高级视觉效果。
下表介绍了各个API级别的各种操作的支持级别:
画布缩放
硬件加速的二维渲染流水线首先被构建以支持未缩放的绘图,一些绘图操作在较高刻度值时显着降低质量。这些操作实现为以1.0比例绘制的纹理,由GPU转换。在API级别<17中,使用这些操作会导致缩放工件随着比例增加。
下表显示何时更改实施以正确处理大比例:
注:“简单”形状drawRect(), drawCircle(),drawOval(),drawRoundRect(),和 drawArc()(同useCenter = FALSE)与不具有PathEffect,并且不包含非默认连接(通过涂料发出的命令setStrokeJoin()/ setStrokeMiter())。在上面的图表中,这些绘图命令的其他实例属于“复杂”。
查看图层
在Android的所有版本中,视图都可以通过使用视图的绘图缓存或通过使用来渲染到屏幕外缓冲区Canvas.saveLayer()。离屏缓冲区或图层有几种用途。动画处理复杂视图或应用合成效果时,您可以使用它们获得更好的性能。例如,您可以使用Canvas.saveLayer()临时渲染视图到一个图层并使用不透明度因子将其复合到屏幕上来实现淡入淡出效果。
从Android 3.0(API级别11)开始,您可以更好地控制如何以及何时在View.setLayerType()方法中使用图层。该API采用两个参数:要使用的图层类型和Paint 描述应该如何合成图层的可选对象。您可以使用该Paint参数将颜色过滤器,特殊混合模式或不透明度应用于图层。视图可以使用三种图层类型之一:
- LAYER_TYPE_NONE:视图呈现正常,并且不被屏幕外缓冲区支持。这是默认行为。
- LAYER_TYPE_HARDWARE:如果应用程序是硬件加速的,则该视图在硬件中呈现为硬件纹理。如果应用程序不是硬件加速的,则此图层类型的行为与LAYER_TYPE_SOFTWARE。
- LAYER_TYPE_SOFTWARE:视图以软件呈现为位图。
您使用的图层类型取决于您的目标:
- 性能:使用硬件图层类型将视图渲染为硬件纹理。视图渲染到图层后,视图调用之前不需要执行其绘图代码invalidate()。然后可以将一些动画(如alpha动画)直接应用到图层上,这对于GPU来说非常有效。
- 视觉效果:使用硬件或软件图层类型,并对Paint视图应用特殊视觉处理。例如,您可以使用a绘制黑白视图ColorMatrixColorFilter。
- 兼容性:使用软件层类型强制视图以软件呈现。如果硬件加速的视图(例如,如果整个应用程序硬件加速),则会导致渲染问题,这是解决硬件渲染管道限制的简单方法。
查看图层和动画
当您的应用程序硬件加速时,硬件层可以提供更快更流畅的动画。在动画处理发生大量绘图操作的复杂视图时,以每秒60帧的速度运行动画并不总是可行。这可以通过使用硬件层将视图渲染为硬件纹理来缓解。然后可以使用硬件纹理来为视图设置动画,从而消除视图在动画时不断重新绘制自身的需要。除非您更改视图的属性,调用invalidate()或invalidate()手动调用,否则不会重新绘制视图。如果您在应用程序中运行动画并且没有获得您想要的平滑结果,请考虑在动画视图上启用硬件层。
当视图由硬件层支持时,其某些属性由图层在屏幕上合成的方式处理。设置这些属性将很有效,因为它们不要求视图失效并重绘。以下属性列表会影响图层合成的方式。为这些属性调用setter会导致最佳的失效并且不会重新绘制目标视图:
- alpha:更改图层的不透明度
- x,y,translationX,translationY:更改层的位置
- scaleX,scaleY:更改图层的大小
- rotation,rotationX,rotationY:改变层的三维空间定位
- pivotX,pivotY:更改图层的转换原点
这些属性是使用动画视图时使用的名称ObjectAnimator。如果你想访问这些属性,请调用适当的setter或getter。例如,要修改alpha属性,请调用setAlpha()。以下代码片断展示了围绕Y轴旋转3D视图的最有效方法:
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() {@Overridepublic void onAnimationEnd(Animator animation) {view.setLayerType(View.LAYER_TYPE_NONE, null);}
});
animator.start();
有关属性动画的更多信息,请参阅属性动画。
技巧和窍门
切换到硬件加速的2D图形可以立即提高性能,但您仍应该按照以下建议设计应用程序以有效使用GPU:
减少应用程序中的视图数量
系统绘制的视图越多,速度就越慢。这也适用于软件渲染管道。减少视图是优化UI的最简单方法之一。
避免透支
不要在彼此顶部绘制太多的图层。删除任何完全被其他不透明视图遮挡的视图。如果您需要绘制混合在一起的多个图层,请考虑将它们合并到一个图层中。使用当前硬件的一个很好的经验法则是每帧画面的像素数不会超过2.5倍(位图计数中的透明像素!)。
不要在绘制方法中创建渲染对象
一个常见的错误是每次创建一个新的Paint或新Path的渲染方法被调用。这迫使垃圾收集器更频繁地运行,并绕过硬件管道中的缓存和优化。
不要经常修改形状
实例中的复杂形状,路径和圆圈使用纹理蒙版进行渲染。每次创建或修改路径时,硬件管道都会创建一个新的掩码,这可能很昂贵。
不要经常修改位图
每次更改位图的内容时,下次绘制时都会再次将其作为GPU纹理上传。
小心使用阿尔法
当您使用setAlpha(),, AlphaAnimation或者使视图变得半透明时ObjectAnimator,它将呈现在屏幕缓冲区中,该缓冲区将所需填充率加倍。在非常大的视图上应用alpha时,请考虑将视图的图层类型设置为 LAYER_TYPE_HARDWARE。
联系我
QQ:94297366
微信打赏:https://pan.baidu.com/s/1dSBXk3eFZu3mAMkw3xu9KQ
转载于:https://blog.51cto.com/4789781/2120402
图片和图形之硬件加速(7)相关推荐
- GPU硬件加速的那些优秀的资源总结-续
renderlayerbacking如下: 注:renderlayerbacking负责管理renderlayer所需要的所有的后端存储,因为后端存储可能需要多个存储空间,在webkit中,存储空间使 ...
- 【读书笔记】【WebKit技术内 幕(三)】GPU硬件加速渲染、canvas与WebGL、 JavaScript与JavaScript 引擎、JavaScriptCore与V8
文章目录 前言 Something great 第8章 硬件加速机制 硬件加速基础 -- *** Chromium的硬件加速机制 -- *** 其他硬件加速模块 第9章 JavaScript引擎 Ja ...
- Office 2016 卡顿问题!如果其他方法都没有用就关掉硬件加速!
题目非常直接哈哈.这次是因为用Word 2016写东西的时候有明显的滞后,甚至打字都是我写一句话都要等1秒以后屏幕后半句才出来. 在网上试了很多方法,都没有解决这个问题.直到看到一个评论里提到取消硬件 ...
- android开启加速功能,Android硬件加速开发简介
从 Android 3.0(API Level 11)开始,Android 2D 渲染管线被设计为能更好地支持硬件加速功能. 硬件加速功能将所有在 View 组件的 Canvas 上执行的绘制操作都交 ...
- linux图形加速驱动下载,Linux 安装emby 并开启nvidia nvenc 硬件加速转码
安装环境: Linux系统自行准备安装本文章使用的是Ubuntu16.04 nvidia显卡自行去官方查询显卡是否支持nvenc (已知GT1030是不支持的)本文章使用GTX1050Ti 小惊喜 此 ...
- 微软详解Windows 8图形硬件加速 秒杀Win7
在最新的一篇博客中,微软介绍了Windows 8的硬件图形加速,除了支持更多的显卡,Windows 8实现了对所有应用程序的硬件图形加速. 为了提供更好的Windows和应用程序用户体验,微软在Win ...
- ART简单体验和Android图形硬件加速分析
原文链接:http://www.soomal.com/doc/10100004760.htm 平均/总评分:08.02/505 相关资料 收藏此图 相关图片 Android ART Android A ...
- Android 4.0的图形硬件加速及绘制技巧
[51CTO独家特稿]从Android 3.0开始,Android 2D的绘制流程就设计为能够更好地支持硬件加速.使用GPU的View在Canvas上进行画的操作时都会使用硬件加速.在最新的Andro ...
- imx6q android jni,Android 显示系统:飞思卡尔平台图形界面与GPU硬件加速
图形是Android平台中的一个大主题,包含java/jni图形框架和2d/3d图形引擎(skia.OpenGL-ES.renderscript). 本文档描述了飞思卡尔设备上的一般Android图形 ...
最新文章
- java8 lambda 表达式详解
- 5年5亿美金,华为昇腾如何构建全行业AI生态?
- 阿里开源新一代人机对话模型 ESIM,曾创下人机对话准确率新纪录
- sas和python哪个更容易_我该选择谁?SAS VS Python
- 【MySQL】Got fatal error 1236原因和解决方法
- centos7.2下安装mysql5.7数据库
- c语言由高到低的运算符,求解C语言关系运算符优先极由高到低列表(同级请用括号)...
- AC Automaton
- Java 判断目录是否为空
- vue——路由独有的生命周期函数 activated deactivated
- python清除实例化类_在Python中,如何尝试(和排除)类的实例化?
- [Android ] linux命令英文缩写的含义(方便记忆)
- 用python计算今天是今年的第几天_Python计算指定日期是今年的第几天(三种方法)...
- php文档注释提取工具phpdocumentor的使用
- linux下下载文件到谷歌云盘,如何使用wget下载谷歌云端硬盘里的文件
- 锐捷DHCPV6配置
- 使用PHP 的 curl 爬取 青果教务系统 课表
- 华为鸿蒙系统支持什么手机_华为鸿蒙系统支持的手机型号_华为鸿蒙系统最新消息...
- 猿辅导python编程老师面试_猿辅导辅导老师面试一系列的感受
- faster rcnn解读
热门文章
- win10 keplerzl安装报错
- MATLAB-plot3/ezplot3三维绘图
- 【Node.js】 基础语法
- opcclient源码OPC客户端DA源码(c#开发)
- 那些逆天的计算机术语翻译!!
- Blinker 天气时钟 esp8266+SH1106 OLCD屏显示
- 服装办理软件的数据预备过程
- [开源]CMSIS-DAP高速下载器
- windows开机自启动jar包的三种方式
- macOS Catalina 10.15.4(19E2269)原版镜像 by OpenCore-0.5.9-05-11编译版