在Android Canvas中快速绘制大量线条:处理抗锯齿和KitKat的特性

时间:2015-08-20 19:16:44

标签: android performance android-canvas

我需要快速抽签(~10k /帧是常见数量)的线。绘制这些线的已知方法(单线程,抗锯齿):

  • drawLines()硬件加速Canvas。快速,但线条得到抗锯齿模糊(见下图)。此外,在KitKat上,如果点数组包含NaN
  • ,则不会绘制任何内容
  • drawLines(),软件呈现Canvas。速度适中,没有模糊,KitKat问题仍然存在
  • for (int i ...) drawLine()硬件加速Canvas。列出的三个中最慢的,没有模糊,没有KitKat个问题

有些东西告诉我有一些简单的技巧可以避免抗锯齿和KitKat问题保持高性能

对于第一个 - 例如,是否可以绘制那些没有抗锯齿的线,然后将抗锯齿应用于整个位图(最快选项的变体)?

对于第二个 - 没有想法,只有一些处理NaN的微调方法。无论如何,KitKat是一个相对较新且受欢迎的 - 应该有一些解决方案来解决它的问题 - 否则平台使用起来会非常头疼

UPD2:
这个问题包含两个独立的问题:
- 使用drawLines()进行硬件加速和任意(但有效)输入时的抗锯齿
- 如果输入包含drawLines() s,则KitKat拒绝在NaN上绘制任何内容

drawLines()是焦点,因为它比方式更快,例如,使用drawLine()逐个绘制线条

此外,下面的图片是将drawLines()两次应用于同一阵列的结果:

canvas.drawLines(toDraw, 0, qty, paint);
canvas.drawLines(toDraw, 2, qty-4, paint); //qty % 4 == 0

UPD
这就是模糊的样子。它位于行的末尾

Pic1

2 个答案:

答案 0 :(得分:2)

这里有一堆混乱的主题;让我们尝试解开它们。

排"模糊"

根据我们的聊天,此问题仅在您开始绘制长度为< 1px的。值得注意的是drawLines()将同时检测所有线段,并且由于该组中存在< 1px线,因此曲面细分器可能会翻倒。这就是你没有看到"模糊"使用单独的drawLine()命令;每个drawLine()仅对您提供的细分进行细分,因此错误仅限于那些超小细分(太小而无法看到)。 此处的修复是添加一些逻辑以从您的集合中删除< 1px长度行,这将解决问题,并允许您使用比{1}更快的问题其他方法。

NaNs问题

NaN会在GPU上造成很多问题,因此如果它们包含在您的绘图列表中,您会发现问题是有意义的。 (非常类似于导致模糊问题的< 1px线段)。再次,这就是为什么你不能使用单独的drawLines()命令看到视觉问题; NaNs打破了tesselator,并将其仅隔离到那些单个段,而不是整个行列表。再次此处的解决方案将指向过滤列表以删除NaN。

<强>性能

鉴于细分线的开销明显大于CPU检查以丢弃坏线,因此添加预处理以移除NaN和&lt; 1px线应该在您的性能预算范围内,并且会删除您所看到的视觉问题。

答案 1 :(得分:0)

嗯,解决方案只是聊天中写的内容的结果(见Colt的帖子):

1)原始输入数组被分成不包含NaN的片段 2)将这些片段分开,使得子片段中的线长度之间的最大差异小于4x(实验获得的值)。将drawLines()应用于最终的子阵列会导致没有模糊和相当好的性能