以ms为单位测量WebGL纹理加载

时间:2015-04-23 09:53:34

标签: javascript webgl

如何以毫秒为单位测量WebGL纹理加载?

现在我有一个图像数组,它们将使用游戏循环渲染为地图,并且我有兴趣捕获WebGL以毫秒为单位加载每个纹理图像所需的时间。我想知道如何衡量这一点,因为JavaScript与WebGL不同步。

1 个答案:

答案 0 :(得分:0)

衡量WebGL中任何时间的唯一方法是弄清楚在一定时间内你可以做多少工作。选择目标速度,比如30fps,使用requestAnimationFrame,继续增加工作直到你超过目标。

var targetSpeed  = 1/30;
var amountOfWork = 1;

var then = 0;
function test(time) {
   time *= 0.001;  // because I like seconds 

   var deltaTime = time - then;
   then = time;

   if (deltaTime < targetTime) {
     amountOfWork += 1;
   }

   for (var ii = 0; ii < amountOfWork; ++ii) {
     doWork();
   }

   requestAnimationFrame(test);
}
requestAnimationFrame(test);

这并不是那么简单,因为浏览器,至少根据我的经验,似乎没有为帧提供真正稳定的时间。

注意事项

  1. 不要假设requestAnimationFrame将为60fps。

    有很多设备运行速度更快(VR)或更慢(低端hd-dpi显示器)。

  2. 在停止播放之前,请勿测量开始发出命令的时间

    测量自上次requestAnimationFrame以来的时间。 WebGL就好 将命令插入缓冲区。这些命令在驱动程序中执行 甚至可能在另一个过程中如此

    var start = performance.now;         // WRONG!
    gl.someCommand(...);                 // WRONG!
    gl.flush(...);                       // WRONG!
    var time = performance.now - start;  // WRONG!
    
  3. 实际使用资源。

    许多资源都是懒惰地初始化,所以只需上传一个资源 但不使用它不会给你一个准确的测量。你会 需要实际绘制上传的每个纹理。当然 使用简单的着色器使其成为小的1像素1三角形绘图。该 着色器必须实际访问资源,否则驱动程序 我不做任何懒惰的初始化。

  4. 不要假设不同类型/尺寸的纹理会有比例 速度的变化。

    司机不同的事情。例如,某些GPU可能不支持 什么,但RGBA纹理。如果您上传了LUMINANCE纹理 驱动程序将它扩展为RGBA。所以,如果你定时使用RGBA纹理 并假设上传相同尺寸的LUMINANCE纹理 快4倍你错了

    同样不要假设将上传不同大小的纹理 速度与其尺寸成正比。驱动程序的内部缓冲区 和其他限制意味着差异大小可能会有所不同 路径。

    换句话说,你不能假设1024x1024纹理会上传 4x与512x512纹理一样慢。

  5. 请注意,即使这不会保证真实世界的结果

    我的意思是,例如,如果您使用平铺硬件(iPhone 例如,然后GPU工作的方式是收集所有 绘图命令,将它们分成瓷砖,剔除任何 绘制是看不见的,只画出剩下的东西 大多数桌面GPU绘制每个三角形的每个像素。

    因为平铺的GPU 如果你继续上传,最后一切都意味着什么 数据到相同的纹理,并在每次上传之间绘制它 必须保留所有纹理的副本,直到它绘制。 在内部可能会有一些点冲洗和 在再次缓冲之前绘制它的内容。

    即使是桌面驱动程序也希望管道上传,以便您上传 内容到纹理B,绘制,上传新内容到纹理B, 画。如果驾驶员正在进行第一次绘图 它不想等待GPU,因此它可以替换内容。 相反,它只是想在其他地方上传新内容 没有被使用,然后它可以将纹理指向新的 内容。

    在正常使用中,这不是问题,因为几乎没有人上传 一直有大量的纹理。他们最多上传1或2个视频 帧或1或2程序生成的纹理。但是当你的时候 基准测试你是在强调驱动程序并使其成功 它实际上不会正常运作。在上面的例子中它可能 假设纹理不可能每帧上传10000次 你将达到一个限制,它必须冻结管道,直到 绘制了一些排队的纹理。冻结会使 你的结果看起来比正常情况下要慢 用例。

    关键是你可以进行基准测试并告知它需要5ms 上传一个纹理,但事实上它只需要3毫秒,你只是 在您的基准测试之外的许多次停滞的管道 不太可能发生。