网站客服:zx81024163 |

关于硬件加速的那么点儿东西

2024-01-24 07:02:19发布    浏览572次    信息编号:94488

友情提醒:凡是以各种理由向你收取费用,均有骗子嫌疑,请提高警惕,不要轻易支付。

关于硬件加速的那么点儿东西

怎么突然就知道硬件加速了? 因为绘图时并不是所有函数都支持硬件加速,所以我有一个疑问,硬件加速不是好事吗? 我想不通为什么不支持,于是就查找资料,最后发现还是研究官方API文档比较靠谱。

硬件加速

的硬件加速仅自 3.0 (API 11) 起可用。 2D渲染管道支持硬件加速,但由于启用硬件加速需要额外的资源,因此会消耗更多的RAM。

API14(含14)之后,默认开启硬件加速。 侧面也写着11-13默认关闭,但我想我们不再考虑这个了。 毕竟现在开发的时候已经不考虑低版本手机了。 。 启用硬件加速的最简单方法是完全启用它,这称为一站式。 如果你只使用标准视图或图形,那么应该不会出现不好的绘制效果(这也是官方API文档的原话,所以请放心使用)。 但是,由于硬件加速并不支持所有 2D 绘图操作,因此如果您的应用程序具有自定义视图或调用某些绘图函数,则启用硬件加速可能会对您的应用程序产生一些影响,例如看不到某些元素或将它们渲染为不可见。 错误的像素,所以为了解决这个不兼容问题(API14以后绘图时使用不支持硬件加速的方法),专家的建议是通过真机测试启用硬件加速。 如果遇到问题,请执行以下四个级别的控制,我们可以选择启用或不启用硬件加速:

等级:

在文件中,将以下属性添加到标签中,为整个应用程序添加硬件加速:

等级:

如果您不想全局启用硬件加速,则无法单独指定硬件加速、在某个级别启动它或禁用硬件加速。 您可以使用标签指定它:

等级:

如果需要更细粒度的控制,可以启用硬件加速

PS:目前该级别不允许关闭硬件加速

视图级别:

您可以在运行时关闭指定View的硬件加速

第二个参数是Paint

或者在xml中的控件属性中,使用:=""来关闭硬件加速:例如

PS:目前不允许在运行时启用硬件加速。 查看或某些功能不支持硬件加速。

确定View是否启用了硬件加速

有时我们想知道应用程序是否打开了硬件加速,特别是对于自定义View场景,如果您的应用程序有大量自定义绘图并且并非所有操作都支持新的绘图管道(硬件加速)。 那么这两种不同的方法对于检测应用程序是否硬件加速特别有用:

如果 View 连接到启用了硬件加速的设备,View.() 返回 true

如果是硬件加速,.d 返回 true

不过,强烈建议使用。 而不是视图。 因为View的这种方法实在是不靠谱。 即使视图附加了硬件加速,仍然可以使用不启用硬件加速的视图来绘制它。 比如当我们把View绘制到上面的时候。 而且很多时候,如果我们不熟悉的话,我们不知道视图是否绑定在一起。

绘图模式

在硬件加速出现之前,最初的图像处理和渲染工作都是通过软件来实现的。

当我们启用硬件加速时,将使用一种新的绘图模式,该模式使用列表来渲染屏幕。 为了理解该列表及其工作原理,在了解绘图模式之前,我们应该了解在硬件加速出现之前使用的基于软件的绘图模式。

基于软件的绘图模式

在软件绘图模式下,视图的绘制按照以下两个步骤进行:

1. 使View层次结构无效

2.绘制View的层次结构

当应用程序需要更新其部分UI时,它会调用view方法,失效消息会通过各种渠道传递到View层次结构,然后屏幕中需要重绘的区域(脏区域)将被重新绘制。被计算。 系统还会绘制View层次结构中与脏区域相交的所有视图。 这种绘图模式有两个缺点:

首先,这种模式需要在每次绘制时执行大量代码。 例如,如果您的应用程序进行调用并且坐标位于其他视图上方,则系统将重绘这些视图,即使它们没有更改。 仅仅因为它们位于 和 相交的区域

其次,绘图模式存在一些隐藏的bug。 当系统重绘相交视图时,即使你不调用它,相交区域中发生变化的视图也可能会被重绘。 这时,你通过其他绘制视图来重绘视图。 当你无意中修改你的代码时,你可能已经忘记了这段代码有这个隐藏的bug。 修改代码后发现显示效果有问题。 如果重绘区域没有重绘,你就会怀疑你的代码逻辑有问题,所以你在修改视图的数据或者状态时,应该尽量为你修改的每个自定义View主动调用它们。 方法。

PS:当视图的属性发生变化时,例如颜色或文本,视图会自动调用重绘。

硬件加速绘图模式

系统仍然使用draw函数来请求屏幕刷新渲染界面,但实际绘制时是有区别的。 与立即执行绘图命令不同,系统会首先将它们记录在列表中。 该列表包含视图层次结构的绘制。 代码。 其他优化是系统只需要记录和更新列表,通过调用函数来标记那些视图,而那些没有标记为脏的视图可以简单地通过预先记录列表上的记录来重绘。 新的绘图模式包括三个步骤:

1.使View的层次结构失效

2.记录并更新显示列表

3.绘制显示列表

使用此模式,您可以不再依赖脏区域中的相交视图来绘制其他视图。 为了确保系统记录该视图的列表,必须调用它。 如果您不调用它,它将导致视图看起来与以前相同。 即使你已经改变了。 所以这同时解决了两个问题。 对于View层次结构中不想重绘的View,只要不调用该View即可。

使用列表对于动画效果也有好处,因为设置指定的属性(例如 alpha 或 )不需要调用目标视图,因为它会自动完成。 此优化也适用于视图的列表。 例如,假设上面有一个,那么 的列表将如下所示:

()

()

假设你现在通过调用(0.5)修改透明度,那么列表就变成这样:

(0.5)

()

()

复杂的绘图代码不会被执行,系统只更新列表。 如果应用程序没有启用硬件加速,那么其父容器的绘制代码将再次执行。

不支持绘图操作

当启用硬件加速时,2D渲染管道支持大多数常见的绘制操作和一些不常见的操作。 让我们分别列出它们。 其实我们只是在自定义View的时候担心被调用的函数是否不支持硬件。 速度加快,所以我们只需要在实际使用的时候检查一下即可。

今天的主角

首先建造的是 2D,其中一些是按比例建造的。 这些是由 GPU 以 1.0 比例绘制的。 在 API 级别

该表显示何时太大:

注意:'' (),(),(),(), ()(with =false) 与没有 , 且没有非连接 (()/()) 的 Paint。 其他抽签属于上表中的“,”。

如果您使用其中任何一个 或 ,您可以仅关闭您的其中一个。 这样,你仍然可以采取其他措施。 更多关于如何在您的 .

中间的部分读起来确实很烦人。 希望懂的人能告诉我一下。

看法

在 的所有版本中,视图都可以在屏幕外渲染,可以使用视图的绘制缓存,也可以使用 .()。 离屏缓存或图层有多种用途。 当你在一些复杂的视图上使用动画效果或一些复合效果时,可以使用它们来获得更好的显示效果。 例如,您可以使用 .() 实现渐变效果,将视图临时渲染到图层,然后将不透明元素合成到屏幕上。

从.0开始,使用时的控制方式更多了。 通过 View.() 函数,该 API 有两个参数:图层的类型和一个可选的 Paint 对象,该对象描述图层的合成方式。 您可以使用“绘制参数”向图层添加颜色,指定混合模式或不透明度,您可以从以下三种图层类型中进行选择:

:View 只会正常渲染,不会使用离屏缓存回退。 这是默认行为。

:如果应用程序启用了硬件加速,则该视图将使用硬件中的渲染。 如果应用程序无法启用硬件加速,那么其效果将是相同的。

:该视图将被渲染到使用软件中。

:,在3D游戏开发中称为纹理,在其中存储图片并在运行时读取它们。 当我们需要重绘时,同样的原理也适用于此,从硬件读取纹理然后进行绘制。

这些类型的图层取决于您的使用情况:

:使用硬件层类型将视图渲染到硬件。 由于视图被渲染到图层上,因此在视图调用该方法之前,将不再执行其绘制代码。 某些动画(例如 Alpha 动画)是使用 GPU 实现的。 可以有效地直接应用于图层。

:使用硬件或软件图层类型以及Paint对视图执行一些特殊处理。 例如,您可以使用黑白来通过 ER 绘制视图。

:使用软件图层类型强制某些视图使用软件进行渲染。 如果视图是硬件加速的(例如,如果您的整个应用程序是硬件加速的),则会出现渲染问题。 最简单的解决方案是限制硬件渲染管道(关闭View的硬件加速)。

视图层和

当您的应用程序进行硬件加速时,硬件层类型可以传输更快、更流畅的动画。 当您处理包含许多绘图操作的复杂视图时,运行动画并不总是 60 帧。 每秒。 这个问题可以通过使用硬件层将视图渲染到一块硬件中来优化。 硬件可用于对视图进行动画处理,从而无需在启动动画时重绘自己的视图。 除非您更改视图,否则不会重新绘制视图。 属性,然后调用()。 如果您在应用程序中运行动画但没有获得所需的流畅结果,请考虑在动画视图上启用硬件加速。 当视图从硬件层回滚时,它的一些属性将通过将层合成到屏幕上来处理。 设置这些属性会更有效,因为它不需要重绘或使视图失效。 以下是一些可以通过这种方式合成到屏幕上的属性,并且调用这些属性上的方法可以消除在目标视图上重绘的需要。

alpha:改变图层的不透明度

x,y,,:改变图层的位置

,:改变图层大小

,,: 改变三维空间中图层的排列方向

,:改变图层的转移点

这些属性在动画视图时以相同的方式使用。 如果要访问这些属性,请调用这些属性的总和。 例如,要修改 alpha 属性,请调用 3D 视图的轴旋转:

视图。(视图。,空);

.(视图, "", 180).start();

由于硬件层会消耗视频存储,因此强烈建议仅在动画持续时间内启用它们,并在动画完成时将其关闭。 您可以通过使用动画侦听器来完成此操作。 这个比较详细,不过可以针对View进行优化,毕竟手机内存那么小

视图。(视图。,空);

= .(视图, "", 180);

.(新之三() {

@

空白 ( ) {

视图。(视图。,空);

});

。开始();

最后,还有 API 提到的一些提示和技巧。

切换到硬件加速,界面会更加流畅,但是如果我们想让GPU在开发应用时更加高效,我们应该注意以下几点:

减少应用程序中的视图数量

绘制的视图越多,速度必然会越慢。 使用软件渲染管道也是如此。 减少视图数量是优化 UI 最简单的方法。

避免透支

不要在上面画太多相互融合的图层。 删除被其他不透明视图完全覆盖的视图。 如果您需要在顶部绘制多个相互混合的图层,请考虑将它们放入单个图层中。 对于当前硬件来说,一个好的经验法则是每帧绘制的像素数不要超过屏幕上像素数的 2.5 倍(像素位图中的透明像素!),简而言之,不要嵌套太多层。

不要继续创建 Paint 和 Path 对象

一个常见的错误是每次调用draw方法时总是创建一个新的Paint对象或一个新的Path对象,这迫使垃圾收集器频繁运行,并且还丢失了硬件管道中的缓存和优化。

不要频繁改变外观

例如,复杂的形状、路径和圆形都使用蒙版进行渲染。 每次修改路径时,硬件管道都会创建一个新的掩码,这是非常昂贵的。

不要频繁修改

每次修改一帧的内容,下次绘制时都会再次上传到GPU。

谨慎使用阿尔法

当你使用, or, or 来改变View的透明度时,在离屏缓存中渲染时需要两倍的填充率。 当您需要修改非常大的视图上的 Alpha 时,您应该考虑将视图的图层类型设置为

最后,总结一下关于硬件加速我们应该了解的知识:

1、硬件加速从API 11开始引入,API 14之后默认开启。支持标准的绘图操作和控件,但在自定义View或一些特殊绘图功能时,需要考虑是否需要关闭硬件加速。

2、当我们面临不支持硬件加速的情况时,我们需要限制硬件加速。 这个兼容性问题是因为硬件加速将View的绘图函数转换成用来完成实际绘图的函数,所以难免会出现不支持原来的收据函数,导致这些绘图函数失效的情况。

3、硬件加速的消耗问题。 因为使用时需要将系统加载到内存中,所以API调用会占用8MB,但实际上会占用更多的内存,而且硬件的使用必然会增加功耗。 。

4、另一方面,硬件加速的优势在于列表设计。 如果我们使用这个,我们就不需要每次重绘时都执行很多代码,因为对于脏区域,基于软件的绘制模式会重绘脏区域。 列表中的所有控件只会更新,然后才会绘制列表中的控件。

哎,你还是要好好学英语啊! 准备下一步啃。

提醒:请联系我时一定说明是从星空网上看到的!