使用gl.finish()可以测量WebGL的渲染时间吗?

10

我正在尝试测量WebGL中图像加载所需的时间。

我想使用gl.finish()在图像加载前后获取时间戳,并相减以获得准确的测量结果,但是我找不到这种用法的好示例。

这种方法可行吗?如果可以,可以有人提供示例代码吗?


你已经有了大致的想法,那就去做吧... 这是在Javascript中获取时间戳的方法 new Date().getTime(); - vallentin
相关问题...这个机制(gl.finish)是由threejs或其他框架和示例用来显示FPS的吗? - david van brink
你最好使用一款性能分析器,因为某些实现会忽略那些调用。 - Anton D
2
如果您想要测量FPS,请参考https://dev59.com/gnHYa4cB1Zd3GeqPQtpY - gman
3个回答

9
现在可以使用EXT_disjoint_timer_query_webgl2扩展来计时WebGL2的执行时间。
const ext = gl.getExtension('EXT_disjoint_timer_query_webgl2');
const query = gl.createQuery();
gl.beginQuery(ext.TIME_ELAPSED_EXT, query);
/* gl.draw*, etc */
gl.endQuery(ext.TIME_ELAPSED_EXT);

稍后,您可以获取查询的经过时间:

const available = this.gl.getQueryParameter(query, this.gl.QUERY_RESULT_AVAILABLE);
if (available) {
    const elapsedNanos = gl.getQueryParameter(query, gl.QUERY_RESULT);
}

需要注意以下几点:

  • 一次只能执行一个时间查询。
  • 结果可能会异步可用。如果您在每帧中有多个时间查询调用,则可以考虑使用查询池。

6
不,实际上在Chrome中,gl.finish只是一个gl.flush。请查看代码并搜索“::finish”。由于Chrome是多进程的,而且实际上在另一个进程中从JavaScript发出GL调用,所以即使Chrome调用了gl.finish,它也会在另一个进程中发生,并且从JavaScript的角度来看,在任何情况下都不准确。Firefox显然正在出于类似原因做类似的事情。即使在Chrome之外,每个驱动程序都以不同的方式处理gl.finish。使用gl.finish进行计时并不是有用的信息,因为它不代表实际速度,因为它包括停止GPU管道。换句话说,使用gl.finish进行计时包括许多在实际使用中不会发生的开销,因此不是正常情况下执行某些操作的速度的准确测量。

一些GPU有GL扩展可获取时间信息。不幸的是,它们(a) 在WebGL中不可用,(b) 也不太可能会被使用,因为它们不具备可移植性,无法在许多手机中找到的瓦片GPU上运行。

与其问如何计时GL调用,你究竟想通过计时它们实现什么?也许人们可以提出解决方案。


我只是对时间感兴趣,因为我正在尝试根据渲染时间指纹识别客户端。难道没有其他解决方案来计时WebGL事件吗? - gilads
也许考虑在requestAnimationFrame事件之间定时调用。如果时间太长,则绘制较少。很抱歉我没有一个好的例子。 - gman

-7

由于 WebGL 是基于客户端的,因此事件时间取决于客户端机器的当前加载情况(CPU 负载)、GPU 负载以及客户端本身的实现。一种获取非常粗略估计的方法是使用 XmlHttpRequesthttp://en.wikipedia.org/wiki/XMLHttpRequest)测量从服务器到客户端的往返延迟。通过找到从服务器测量时间到本地时间的延迟,可以得到可能的负载度量。


你怎样使用 XmlHttpRequest 来包含图片加载所需的时间?(我看到了 onload() 但不确定它是否相关...)。你可以提供一些示例代码吗? - gilads

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