首页 > 解决方案 > readPixels 性能,是什么让它这么慢?

问题描述

当尝试使用大量数据(但屏幕上几乎没有数据)进行命中测试时,即使帧时间远低于 16.7 毫秒(全部为 10 毫秒),读取像素确实很慢

我正在开发一个在 webgl 中运行的 datavis 平台,但让我感到困惑的是为什么 readpixels 这么慢。我们正在使用颜色选择方法来测试一个被拖动的项目,以便它可以放在物体等上。似乎上传到场景中的数据越多,尽管渲染(未读取)为 60fps 所需的时间就越长。它只拉出一个像素,因此它显然与它的阻塞方面有关,但为什么这需要比帧时间长近 4 倍?

if (xPos >= 0 && yPos >= 0 && xPos < drawBufferWidth && yPos < drawBufferHeight) {
   gl.readPixels(xPos, yPos, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, lastCapturedColourMap);
}

我希望帧速率越高,readpixels 的成本就越低,但这似乎是一个固定成本。谁能启发我?我正在寻找任何可能更好地了解实际使其变慢的原因或任何其他用于 webgl 中 2d 图形的替代命中测试方法的人

在此处输入图像描述

标签: javascriptwebgl

解决方案


正如 mlkn 指出的那样,它很慢,因为 WebGL 是流水线的。为了安全起见,它在 Chrome 中是双流水线的。

您从 JavaScript 发出一个 webgl 命令。该命令被复制到命令缓冲区。另一个进程,GPU 进程读取该命令,它验证您没有做坏事,然后调用一些相应的 GL 函数,该函数将命令写入驱动程序的命令缓冲区。另一个进程读取该命令。

在正常情况下,所有这些事情都是并行运行的。当您发出新命令时,GPU 进程正在读取先前的命令并将其传递给 GL。当 GPU 进程发出命令时,GPU 和 GPU 驱动程序在此之前停止处理先前的命令。

当您尝试读取时,所有并行运行的进程都必须停止,并且所有这些进程都必须等待所有命令处理,以便它们可以读取像素(到目前为止您发出的所有命令的结果)然后把它们传回去。然后他们都必须重新启动,但此时他们的所有命令列表都是空的,因此需要几个命令才能让所有这些命令再次并行执行。


推荐阅读