WebGL非常好且异步,因为您可以发送一长串渲染命令而无需等待它们完成。但是,如果由于某种原因您确实需要等待渲染完成,则必须与gl.finish()
同步执行。当然gl.finish
接受回调并立即返回会更好吗?
问题:有没有办法可靠地模仿这个?
用法案例:我将大量顶点渲染到大型离屏画布,然后使用drawImage
将此大画布的各个部分复制到页面上的小画布上。我实际上并没有使用gl.finish()
,但drawImage()
似乎具有相同的效果。在我的应用程序中,只有当用户执行操作(例如,单击按钮)时才会触发重新渲染,并且可能需要几百毫秒。如果在渲染期间浏览器仍然响应允许滚动等,那将是很好的。我特别关注Chrome解决方案,尽管在Firefox和Safari中也可以使用它。
可能(错误)答案:您可以尝试估算渲染时间,然后设置以调用gl.finish()
开始的超时。但是,对所有大小的顶点缓冲区和所有用户可靠地进行此估计将非常棘手且不准确。
可能的(非)回答: requestAnimationFrame
正在寻找我正在寻找的......但它不是,是吗?
2018年可能的答案:也许ImageBitmap
API解决了这个问题 - 请参阅MDN docs。
答案 0 :(得分:5)
你已经部分地回答了你的答案:drawImage()
确实有类似于完成的行为,因为它会在读回图像数据之前强制完成所有未完成的绘图命令。问题是即使gl.finish()
做了你想要的,等待渲染完成,你仍然会像现在一样使用它。渲染完成时,主线程将被阻止,从而中断用户与页面交互的能力。
理想情况下,在这种情况下你想要的是某种回调,它指示何时完成一组绘制命令而没有实际阻塞等待它们。不幸的是,没有这样的回调(考虑到浏览器的内部工作方式,提供一个回复将会非常困难!)
在你的情况下,一个不错的中间地带可能是在你感觉图像准备就绪时做一些明智的估计。例如,在调用requestAnimationFrame
之前,一旦您调出了绘制调用旋转3或4 drawImage
s。如果你一直观察它需要更长时间(10帧?)然后旋转更长时间。这将允许用户继续正常地与页面进行交互,并且在执行绘制图像时不会产生任何延迟,因为内容已经完成渲染,或者因为您在渲染过程中进行同步步骤而导致延迟少得多。根据您网站的预期用途,非实时呈现甚至可能会在呈现之前旋转一整秒左右。
这当然不是一个完美的解决方案,我希望我有更好的答案。也许WebGL将来能够查询这种类型的状态,因为它在像你这样的情况下会很有价值,但是现在这可能是你能做到的最好的。