绘制路径和硬件加速(Drawing paths and hardware acceleration)

2019-07-20 10:05发布

我画在我看来,一个相当大的路径,我遇到了一些性能问题。 路径是目前32,000个点长,但我的应用程序应扩展到至少128000个。 我真的不能做任何事情的路径的大小,因为数据集只是大,我需要能够同时显示整个路径,并允许在放大。

我使用的是Nexus 10搭载Android 4.2,它在默认情况下为不明确禁用应用程序启用硬件加速。

该路径用下面的代码创建(I省略了一些建立和其它无关的部分):

dataPath.moveTo(0, offset - (float) data[leftLimit]/ scalingFactor);
        for (int i = leftLimit; i < rightLimit; ++i) {
            x = (i - leftLimit) * dx;
            y = offset - (float) data[i]/ scalingFactor;
            dataPath.lineTo(x, y);
        }

然后在绘制onDraw()方法:

canvas.drawColor(Color.WHITE);
canvas.drawPath(dataPath, linePaint);

我测量它需要用画我的观点的时候adb shell dumpsys gfxinfo使用和不使用硬件加速,并以我吃惊的硬件加速慢得多:

随着硬件加速:

无硬件加速:

硬件加速的版本需要每帧200-300毫秒,最花费在处理阶段。 非加速版本需要大约50毫秒,与在拉伸阶段2/3和1/3的过程中的阶段。

显然,即使我快没有硬件加速版本仍然太慢实现60帧,或者当我移动到更大的数据集,甚至可以说勉强可用。

这个想法呈现路径为位图,然后只变换位图以适应屏幕也是在我的情况的问题。 我需要支持在很远的放大到路径,使不带路径质量越来越差很多,我将不得不渲染路径的超大位图缩放(和可能会遇到内存限制和纹理大小限制)。 而放大的时候为止,我将不得不要么创建的路径只有部分的新图像,或者切换到干脆直接渲染路径,这可能会导致比帧率延迟较大,如果仍表现相似,我有权现在。

我现在不知道是

  • 被画线/路径只是一些该GPU是坏的,并且不应该尝试硬件加速,或者我可能做错了什么,导致了糟糕的表现?
  • 有什么我能做的来绘制可接受的性能如此庞大的路径?

Answer 1:

被画线/路径只是一些该GPU是坏的,并且不应该尝试硬件加速,或者我可能做错了什么,导致了糟糕的表现?

路径是使用CPU渲染始终。 当应用程序是硬件加速,这意味着渲染器将使用的CPU为位图先画你的路,然后上载该位图作为纹理的GPU终于在屏幕上绘制纹理。

线条完全硬件加速。 而不是使用的Path ,我建议你使用Canvas.drawLines()在这种情况下。

有什么我能做的来绘制可接受的性能如此庞大的路径?

您应该使用Canvas.drawLines()或自己渲染路径成Bitmap ,你管理。



Answer 2:

好像你可能会运行到在GPU通用瓶颈。 看看下面的链接:

如何使路径描绘更有效

Android的帆布路径实时性能

从切换画布的OpenGL

特别是第一个,这表明,你犯了一个位图和绘制来代替。 它看起来像如果你改变OpenGL的你可以得到一些更好的性能。 有可能是让现有的方法工作的一些神奇的方式,但我不知道,在这个时刻。

为什么你所看到的行为,这样做可能是因为你的所有数据发送到每个消耗之间的GPU。 你应该缓存它的GPU和使用代替翻译。 不重新创建数据,并将其所有发送到GPU。 你可能是I / O限制 ,这意味着CPU之间的传输速率和GPU是什么制约着你的业绩。 我不能肯定这基于你所提供的数据100%,但是这是我最好的猜测。 尝试不同的缓存技术,主要是从#1线的PNG缓存。



Answer 3:

绘制路径将涉及的不仅仅是“告诉”的GPU绘制线条更多。 路径具有很多的特性,例如一个线是如何线的端部被处理过的或虚线,东西是 GPU加速。 有可能是又接连 hickup当你遇到很多线,使得CPU和GPU加速的组合走慢。 上述建议的解决方案迁移到canvas.drawLines代替canvs.drawPath并尽量不使用一个奇特的Paint方法可能有帮助。

如果没有帮助,你可以尝试使用GLSurfaceView并直接呈现线成代替。 这将涉及到一些OpenGL ES的知识,但不应该是天昏地暗做,可能有很多更有效。



文章来源: Drawing paths and hardware acceleration