Chrome警告:将willReadFrequently属性设置为true

21

Chrome一直打印这个警告:“Canvas2D: 使用getImageData进行多个读取操作时,将willReadFrequently属性设置为true可以更快。” 我检查了代码,在触发警告的地方,您可以看到我已将willReadFrequently属性设置为true。可能问题是什么?在其他地方也有这种警告,但是那里的willReadFrequently属性解决了它。

Chrome 104-108中存在问题。顺便说一句,我在WebWorker中。这可能是一个Chrome错误吗?

    const offdesireCtx = offDesire.getContext("2d", { willReadFrequently: true });
    if (!offdesireCtx) {
        throw new Error("Desired OffscrenCanvas ctx undefined");
    }

    const offGetCtx = offGet.getContext("2d", { willReadFrequently: true });
    if (!offGetCtx) {
        throw new Error("Get OffscrenCanvas ctx undefined");
    }
   
    var imgd = offdesireCtx.getImageData(0, 0, tileSize, tileSize), pix = imgd.data; //Warning triggers
    var imgdGet = offGetCtx.getImageData(0, 0, tileSize, tileSize), pixGet = imgdGet.data; //Warning triggers
1个回答

39
MDN所述:willReadFrequently会强制使用软件(而非硬件加速)2D画布,当频繁调用getImageData()时可以节省内存。

这意味着画布必须完全在CPU上创建、绘制和读取。调用getContext默认提供了一个GPU上的画布缓冲区句柄,如果在此之前已经对该画布进行了调用,则数据已经在GPU上,需要将其复制回CPU,从而达不到性能警告的目的。

我发现,在我的情况下,我在一个函数中创建并向画布写入,然后返回画布。稍后在我的代码中,该函数调用的结果拿到同一画布并创建另一个上下文。它将{ willReadFrequently: true }选项参数应用于该调用,但这是第二次为此画布调用getContext。这意味着纹理缓冲区已经存在于GPU上,并且第二个getContext调用会忽略willReadFrequently建议,因为数据已经在GPU上。

所以你需要追溯到画布最初被创建的地方,然后追溯到第一次调用getContext并绘制的位置。后续的canvas.getContext("2d", { willReadFrequently: true })调用已经为时已晚了(而且可能甚至可以省略选项)。考虑纹理缓冲区何时被创建,并跟踪数据流以确保从一开始就全部在CPU上运行。


1
没错,我的代码也是这样的。谢谢! - Jung Ervin
3
应该是:canvas.getContext("2d", {willReadFrequently: true})。 - Simon S.
@SimonS. 你是在指出一个打字错误吗?我找不到你所说的内容。 - Keavon
@Keavon,查看帖子的编辑历史记录,确实存在一个拼写错误。 旧代码:canvas.getContext("2d", { willReadFrequently: true ) 新代码:canvas.getContext("2d", { willReadFrequently: true }) - Roe
哦,我想我完全忘记了那件事。奇怪的是,人们仍然在给指出不再相关的更正评论点赞。我曾经认为自己可能错过了一些明显需要修复的东西。 - Keavon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接