以毫秒为单位测量 WebGL 纹理负载 [英] Measure WebGL texture load in ms

查看:33
本文介绍了以毫秒为单位测量 WebGL 纹理负载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How can i measure WebGL texture load in milliseconds?

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

Right now I have an array of images that will be renderd out as a map using a game loop and im interested in capturing the time it takes for WebGL to load every texture image in milliseconds. I wonder how that can be done to measure this because JavaScript is not synchronous with WebGL.

推荐答案

在 WebGL 中衡量任何时间的唯一方法是计算出在一定时间内您可以完成多少工作.选择一个目标速度,比如 30fps,使用 requestAnimationFrame,继续增加工作直到你超过目标.

The only way to measure any timing in WebGL is to figure out how much work you can do in a certain amount of time. Pick a target speed, say 30fps, use requestAnimationFrame, keep increasing the work until you're over the target.

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);

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

It's not quite that simple because the browsers, at least in my experience, don't seem to give a really stable timing for frames.

注意事项

  1. 不要假设 requestAnimationFrame 的帧率为 60fps.

  1. Don't assume requestAnimationFrame will be at 60fps.

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

There are plenty of devices that run faster (VR) or slower (low-end hd-dpi monitors).

在停止之前不要测量开始发出命令的时间

Don't measure time to start emitting commands until the time you stop

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

Measure the time since the last requestAnimationFrame. WebGL just inserts commands into a buffer. Those commands execute in the driver possibly even in another process so

var start = performance.now;         // WRONG!
gl.someCommand(...);                 // WRONG!
gl.flush(...);                       // WRONG!
var time = performance.now - start;  // WRONG!

  • 实际使用资源.

  • Actually use the resource.

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

    Many resources are lazily initialized so just uploading a resource but not using it will not give you an accurate measurement. You'll need to actually do a draw with each texture you upload. Of course make it small 1 pixel 1 triangle draw, with a simple shader. The shader must actually access the resource otherwise the driver my not do any lazy initialization.

    不要假设不同类型/大小的纹理会有成比例速度变化.

    Don't assume different types/sizes of textures will have proportional changes in speed.

    驱动不同的事物.例如,某些 GPU 可能不支持除了 RGBA 纹理之外的任何东西.如果您上传 LUMINANCE 纹理驱动程序会将其扩展为 RGBA.所以,如果你使用 RGBA 纹理计时并假设将上传相同尺寸的 LUMINANCE 纹理4 倍于你的错误

    Drivers to different things. For example some GPUs might not support anything but RGBA textures. If you upload a LUMINANCE texture the driver will expand it to RGBA. So, if you timed using RGBA textures and assumed a LUMINANCE texture of the same dimensions would upload 4x as fast you'd be wrong

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

    Similarly don't assume different size textures will upload at speed proportional to their sizes. Internal buffers of drivers and other limits mean that difference sizes might take differnent paths.

    换句话说,你不能假设 1024x1024 纹理会上传比 512x512 纹理慢 4 倍.

    In other words you can't assume 1024x1024 texture will upload 4x as slow as a 512x512 texture.

    请注意,即使这样也不能保证实际结果

    Be aware even this won't promise real-world results

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

    By this I mean for example if you're on tiled hardware (iPhone for example) then the way the GPU works is to gather all of the drawing commands, separate them into tiles, cull any draw that are invisible and only draw what's left where as most desktop GPUs draw every pixel of every triangle.

    因为平铺的 GPU做最后的一切这意味着如果你继续上传数据到相同的纹理并在每次上传之间绘制它会必须保留所有纹理的副本,直到绘制为止.在内部,它可能会在某个点刷新并在再次缓冲之前绘制它所拥有的内容.

    Because a tiled GPU does everything at the end it means if you keep uploading data to the same texture and draw between each upload it will have to keep copies of all your textures until it draws. Internally there might be some point at which it flushes and draws what it has before buffering again.

    即使是桌面驱动程序也想通过管道上传,所以您上传内容到纹理 B,绘制,将新内容上传到纹理 B,画.如果司机正在做第一张图它不想等待 GPU 来替换内容.相反,它只是想将新内容上传到其他地方没有被使用,然后何时可以将纹理指向新的内容.

    Even a desktop driver wants to pipeline uploads so you upload contents to texture B, draw, upload new contents to texture B, draw. If the driver is in the middle of doing the first drawing it doesn't want to wait for the GPU so it can replace the contents. Rather it just wants to upload the new contents somewhere else not being used and then when it can point the texture to the new contents.

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

    In normal use this isn't a problem because almost no one uploads tons of textures all the time. At most they upload 1 or 2 video frames or 1 or 2 procedurally generated textures. But when you're benchmarking you're stressing the driver and making it do things it won't actually be doing normally. In the example above it might assume a texture is unlikely to be uploaded 10000 times a frame you'll hit a limit where it has to freeze the pipeline until some of your queued up textures are drawn. That freeze will make your result appear slower than what you'd really get in normal use cases.

    关键是您可能会进行基准测试并被告知需要 5 毫秒上传纹理但实际上只需要 3 毫秒,你只是管道多次停滞,超出您的基准不太可能发生.

    The point being you might benchmark and get told it takes 5ms to upload a texture but in truth it only takes 3ms, you just stalled pipeline many times which outside your benchmark is unlikely to happen.

    这篇关于以毫秒为单位测量 WebGL 纹理负载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆