Chrome 警告 willReadFrequently 属性设置为 true

问题描述 投票:0回答:2

Chrome 不断打印此警告:“Canvas2D:将 willReadFrequently 属性设置为 true 时,使用 getImageData 进行多个读回操作会更快。”。我检查了触发警告的代码,您可以看到我将 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
javascript google-chrome browser
2个回答
50
投票

正如 MDN 所说 关于

willReadFrequently

这将强制使用软件(而不是硬件加速)2D 画布,并且可以在频繁调用 getImageData() 时节省内存。

这意味着画布必须完全在 CPU 上创建、绘制和读取。默认情况下,调用

getContext
会提供 GPU 上画布缓冲区的句柄,如果该调用之前发生在该画布上,则该数据已经在 GPU 上,并且必须将其复制回 CPU,从而击败了绩效警告的目标。

我发现在我的例子中,我正在创建画布并在一个函数中写入它,然后返回画布。后来在我的代码中,该函数调用的结果采用相同的画布并创建了另一个上下文。它应用了 该调用的

{ willReadFrequently: true }
选项参数,但这是第二次为此画布调用
getContext
。这意味着此时纹理缓冲区已经存在于 GPU 上,并且第二个
getContext
调用忽略了
willReadFrequently
建议,因为数据已经在 GPU 上。

因此,您需要追溯到画布首次创建的位置,然后调用并绘制其第一个

getContext
的位置。随后的
canvas.getContext("2d", { willReadFrequently: true })
调用已经来不及了(甚至可以省略该选项)。考虑一下纹理缓冲区何时被创建并跟踪数据流,以确保它自启动以来全部都存在于 CPU 上。


0
投票

围绕此警告还有一些启发。例如,Chrome 有时会根据某些条件自动从 GPU 渲染切换到 CPU 渲染。

参见https://www.schiener.io/2024-08-02/canvas-willreadfrequently

© www.soinside.com 2019 - 2024. All rights reserved.