Babylon leaks MSAA Renderbuffers on resize & dispose with WebGL

Hello :slight_smile:

In our project that uses Babylon, I wrote a tool that analyzes all WebGL resource allocating/deallocating and updating/uploading calls to allow us to approximately track WebGL memory usage.
When doing so, I found that we (and thus Babylon by extension) delete almost* all buffers and textures from the context when disposing, however MSAA renderbuffers from RenderTargetTextures are never deleted. And to make matters worse, the renderbuffers are re-created by Babylon when resizing, which means any time you resize the rendertarget texture (such as when resizing the canvas), the old MSAA renderbuffers are still present in memory.
(* I found a tiny buffer being left behind of some 44 bytes in rare cases, so a no-issue)

The effect of this can be seen if you analyze the GPU Process memory usage in Chrome, in a setup where you have a RenderTargetTexture with MSAA, that’s resized together with the canvas. Try then to resize the canvas back and forth with your mouse cursor and the memory usage can quickly go up to several gigabytes in a few seconds on a larger resolution.
It does seem like Chrome actually garbage collects the renderbuffers for you after a while though, so you might need to allocate faster than Chrome can release it for you.

Playground example:
The playground example will console log whenever a renderbuffer is created or deleted, and tracks the total count, which the console logs print out as well.
You can resize the canvas (and thus the rendertarget) by resizing the code editor.
It also has the “workaround”/fix that you can enable. I also made a PR with the same change.

Note: The reason I made the rendertarget larger than the canvas was to further show the effect, but it’s also a real use-case as you often have a couple of rendertargets for your canvas ( postprocessing, gbuffers and history buffers)

The issue in the code seems to be that the webGLHardwareTexture seems to own an MSAA renderbuffer as well in some cases, and it correctly disposes it in its release function. However, the release function is not used by thinEngine, who instead only deletes the WebGLTexture which is not enough in the cases where the texture holds an MSAA renderbuffer. You can see my PR for my proposed fix:


Indeed I reach 1.5GB of VRAM after a few seconds :scream: But then after a few more seconds, it’s indeed garbage collected by Chrome…

And it seems to work :+1: Playground running on your PR snapshot
Well played :slight_smile:


Good catch!!!

Since the PR was merged, marking this as the solution :slight_smile:

1 Like