Delayed frames while using WebGPU

206 Views Asked by At

I have a WebApp that renders bicycle tracks on a map. Here is an example image:

Image of the app working fine

Here, the background Map is intentionally hidden for simplification.

Previously, everything was rendered using the CanvasRenderingContext2D API. I'm currently converting my code to WebGPU to improve performance. The green line is rendered using my custom code based on WebGPU. The red line is using the old CanvasRenderingContext2D api. As you can see, there are overlapping, so everything works fine.

The problem starts when I drag the map. The WebGPU rendering lags behind the old rendering, looking like this.

Lines no longer overlapping

If I stop dragging the map, everything looks fine again.

I initially thought that my code was buggy, but the problem is stranger than I thought. The problem occurs only ~ 80% of the time. Other times, everything works great. Switching tabs, opening dev tools, or changing the window size can make the problem appear or disappear. Therefore, I assume a performance problem or a browser bug.

The problem can be seen in Chrome and Edge Chromium. I don't think another browser engine has WebGPU support so far.

I have tried to build a small demo to reproduce the error but without success. Everything works fine in a smaller scenario. Therefore, I tend to assume a performance problem even more. I am using the context.setTransform function to move the content on the CanvasRenderingContext2D and a UniformBuffer on the WebGPU side. I have triple checked that both transformations are the same for every frame.

I have three ideas that could cause the problem:

  1. The UniformBuffer is updated via queue.writeBuffer every frame before the draw command is called. Maybe sometimes the order of the commands is wrong.
  2. The draw function is called via requestAnimationFrame. Maybe the next frame is drawn before the queue is executed completely. There is a function called queue.onSubmittedWorkDone to wait for the GPU to complete, but I can't see a way to use it in my render loop.
  3. Maybe the problem is caused by the two overlapping canvas elements. I have the same setup in my working minimal demo, so I'm not convinced.

If you have any idea what might cause the problem, I would be very delighted.

0

There are 0 best solutions below