37

在我看来,我正在绘制一条相当大的路径,并且遇到了一些性能问题。该路径目前有 32,000 点长,但我的应用程序应该扩展到至少 128,000 点。我真的无法对路径的大小做任何事情,因为数据集就是那么大,我需要能够一次显示整个路径并允许放大。

我正在使用运行 Android 4.2 的 Nexus 10,它默认为未明确禁用它的应用程序启用硬件加速。

该路径是使用以下代码创建的(我省略了一些设置和其他不相关的部分):

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 ms,其中 2/3 在 Draw 阶段,1/3 在 process 阶段。

显然,即使我没有硬件加速的更快版本也仍然太慢而无法达到 60 fps,或者当我转移到更大的数据集时甚至几乎无法使用。

将路径渲染到位图然后仅转换该位图以适应屏幕的想法在我的情况下也是有问题的。我需要支持将路径放大到很远,并且为了在路径质量不变得更差的情况下进行放大,我必须渲染路径的超大位图(并且可能会遇到内存限制和纹理大小限制)。当放大很远时,我要么只创建路径的一部分的新图像,要么切换到直接渲染路径,如果性能仍然与我所拥有的相似,这可能会导致延迟大于帧速率现在。

我现在想知道的是

  • 绘制线条/路径只是 GPU 不擅长的事情,不应该尝试硬件加速,还是我可能做错了什么导致性能不佳?
  • 我能做些什么来以可接受的性能绘制如此巨大的路径吗?
4

3 回答 3

51

绘制线条/路径只是 GPU 不擅长的事情,不应该尝试硬件加速,还是我可能做错了什么导致性能不佳?

路径总是使用 CPU 渲染。当应用程序是硬件加速时,这意味着渲染器将首先使用 CPU 将您的路径绘制成位图,然后将该位图作为纹理上传到 GPU,最后在屏幕上绘制纹理。

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

我能做些什么来以可接受的性能绘制如此巨大的路径吗?

您应该自己使用Canvas.drawLines()或将路径渲染为Bitmap您管理的路径。

于 2013-03-04T18:46:52.287 回答
5

看起来您可能会遇到 GPU 的一般瓶颈。看看以下链接:

如何让路线绘制更高效

Android画布路径实时性能

从画布切换到 OpenGL

尤其是第一个,它建议您制作位图并绘制它。如果您更改为 openGL,看起来您可以获得更好的性能。可能有一些神奇的方法可以让现有方法发挥作用,但目前我还没有意识到这一点。

为什么您会看到您所做的行为可能是因为您在每次绘制之间将所有数据发送到 GPU。您应该将其缓存在 GPU 上并改用翻译。不重新创建数据并将其全部发送到 GPU。您可能受 I/O 限制,这意味着 CPU 和 GPU 之间的传输速率限制了您的性能。根据您提供的数据,我不能 100% 确定这一点,但这是我最好的猜测。尝试不同的缓存技术,主要是来自链接 #1 的 png-cache。

于 2013-02-23T12:15:42.653 回答
3

绘制路径不仅仅涉及“告诉”GPU 绘制线条。路径具有许多特征,例如如何处理线的末端或点线,这不是GPU 加速的。当您遇到使 CPU 和 GPU 加速组合变慢的许多行时,可能会出现另一个问题。上面建议的解决方案,canvas.drawLines而不是canvs.drawPath尝试不使用花哨的Paint方法可能会有所帮助。

如果这没有帮助,您可以尝试使用 GLSurfaceView 并将线条直接渲染到其中。这将涉及一些 OpenGL ES 知识,但应该不会很难做到,并且可能会更有效。

于 2013-03-06T22:52:20.050 回答