【发布时间】:2019-09-14 13:50:27
【问题描述】:
设置
我正在使用自定义RenderBox 进行绘图。
下面代码中的canvas对象来自PaintingContext in the paint method。
绘图
我正在尝试使用Canvas.drawRect 单独渲染像素。
我应该指出,它们有时比它们实际占据的屏幕像素更大,有时更小。
for (int i = 0; i < width * height; i++) {
// in this case the rect size is 1
canvas.drawRect(
Rect.fromLTWH(index % (width * height),
(index / (width * height)).floor(), 1, 1), Paint()..color = colors[i]);
}
存储
我将像素存储为 List<List<Color>>(上面代码中的colors)。我之前尝试过不同的嵌套列表,但它们在性能方面并没有引起任何明显的差异。
当使用999x999 图像填充列表时,我的 Android 模拟器测试设备上的内存增加了282.7MB。请注意,它只是暂时增加282.7MB。大约半分钟后,增幅下降到 153.6MB 并保持在那里(没有任何用户交互)。
渲染
在999x999 的分辨率下,上面的代码导致250.1 ms/frame 的GPU 最大值 和1835.9 ms/frame 的UI 最大值,这显然是不可接受的。尝试绘制999x999 图像时,UI 会冻结两秒钟,考虑到 4k 视频在同一设备上流畅运行,这应该是小菜一碟(我猜)。
CPU
我不确定如何使用 Android 分析器正确跟踪此问题,但在填充或更改列表时,即绘制像素(对于以上指标),CPU 使用率从0% 上升到60%。以下是 AVD 性能设置:
原因
我不知道从哪里开始,因为我什至不确定我的代码的哪一部分会导致冻结。是内存使用吗?还是图纸本身?
我一般会怎么做?我究竟做错了什么?我应该如何存储这些像素。
努力
我尝试了很多都没有帮助,所以我将尝试只指出最值得注意的:
-
我尝试将
List<List<Color>>转换为Imagefrom thedart:uilibrary 希望使用Canvas.drawImage。为了做到这一点,我尝试编码我自己的 PNG,但 I have not been able to render more than a single row。但是,看起来这不会提高性能。在尝试转换9999x9999图像时,我遇到了内存不足异常。现在,我想知道视频是如何渲染的,因为任何 4k 视频都会比9999x9999图像占用更多内存,如果它在内存中只有几秒钟。 -
我尝试实现
image包。然而,我在完成它之前就停下来了,因为我注意到它并不是要在 Flutter 中使用,而是在 HTML 中使用。使用它我不会有任何收获。 -
这对于我将得出的以下结论非常重要:我尝试仅绘制而不存储像素,即使用
Random.nextInt生成随机颜色.当尝试随机生成999x999图像时,这导致1824.7 ms/frames的GPU 最大值 和2362.7 ms/frame的UI 最大值,这更糟,尤其是在 GPU 部门。
结论
这是我在尝试使用Canvas.drawImage 进行渲染失败之前得出的结论:Canvas.drawRect 不适用于此任务,因为它甚至无法绘制简单的图像。
你如何在 Flutter 中做到这一点?
注意事项
-
这基本上是what I tried to ask over two months ago(是的,我一直在努力解决这个问题),但我认为我当时没有正确表达自己,我更不知道实际问题是什么。
-
我可以正确渲染的最高分辨率约为
10k像素。我至少需要1m。 -
我认为放弃 Flutter 并转向原生可能是我唯一的选择。但是,我想相信我完全错误地解决了这个问题。我花了大约三个月的时间试图弄清楚这一点,但我没有找到任何能引导我到任何地方的东西。
【问题讨论】:
-
instantiateImageCodec 表示支持
BMP格式,这相对容易从原始 ARGB 数据进行编码 - 尽管我不知道这种 ARGB->BMP 编码和 BMP->图像解码的速度有多快成为... -
还有:你的
Layer树有多大? -
[+9 毫秒] ????要在运行时进行热重载更改,请按“r”。要热重启(和重建状态),请按“R”。 [ +2 ms] SM T110 上的 Observatory 调试器和分析器可在以下网址获得:127.0.0.1:41854 [ ] 有关更详细的帮助消息,请按“h”。要分离,请按“d”;要退出,请按“q”。 [+129309 ms] 正在初始化热重载...