javascript Chrome警告willReadFrequently属性设置为true

jogvjijk  于 2022-11-20  发布在  Java
关注(0)|答案(1)|浏览(4545)

Chrome不断打印此警告:“Canvas 2D:使用getImageData的多个回读操作在将willReadFrequently属性设置为true时速度更快。"。我检查了触发警告的代码,可以看到我将willReadFrequently属性设置为true。问题可能是什么?在其他地方也有这个警告,但在那里willReadFrequently属性解决了它。
Chrome 104-108中的问题肯定存在。顺便说一句,我在一个WebWorker中。这会不会是chrome的bug?

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
bgibtngc

bgibtngc1#

正如 MDN 关于 willReadFrequently 所说 :
这 将 强制 使用 软件 ( 而 不是 硬件 加速 ) 2D 画布 , 并 在 频繁 调用 getImageData ( ) 时 节省 内存 。
这 意味 着 画布 必须 完全 在 CPU 上 创建 、 绘制 和 读取 。 默认 情况 下 , 调用 getContext 提供 了 一 个 指向 GPU 上 画布 缓冲 区 的 句柄 , 如果 之前 对 该 画布 进行 了 调用 , 则 该 数据 已经 在 GPU 上 , 必须 将 其 复制 回 CPU , 从而 使 性能 警告 的 目标 落空 。
我 发现 在 我 的 例子 中 , 我 创建 了 一 个 画布 , 并 在 一 个 函数 中 写入 它 , 然后 返回 画布 。 在 我 的 代码 后面 , 该 函数 调用 的 结果 采用 了 同一 个 画布 , 并 创建 了 另 一 个 上下文 。 它 将 { willReadFrequently: true } 选项 参数 应用 于 该 调用 。但 这 是 第 二 次 为 该 画布 调用 getContext 。这 意味 着 此时 纹理 缓冲 区 已经 存在 于 GPU 上 , 第 二 个 getContext 调用 忽略 了 willReadFrequently 建议 , 因为 数据 已经 存在 于 GPU 上 。
因此 , 您 需要 追溯 到 画布 最初 创建 的 位置 , 然后 追溯 到 第 一 个 getContext 被 调用 并 绘制 到 的 位置 。 随后 的 canvas.getContext("2d", { willReadFrequently: true ) 调用 已经 太迟 了 ( 甚至 可能 忽略 该 选项 ) 。 考虑 一下 纹理 缓冲 区 是 何时 创建 的 , 并 跟踪 您 的 数据 流 , 以 确保 它 从 一 开始 就 存在 于 CPU 上 。

相关问题