I was wondering if it was possible to dispose the canvas under a DynamicTexture if I know it’s not updated anymore to free up a lot of memory, maybe add a freeze() method or something that handles that.
Then I looked into the dynamicTexture.ts and didn’t see the _canvas being disposed anywhere period, and couldn’t find it being done elsewhere either. I’m pretty sure it’s not sticking around when the texture is disposed, so how does that work?
If a canvas is created by babylon it is created either using OffscreenCanvas (if executed in a worker) or using createElement(‘canvas’), executed on the document object. The canvas is not added to the DOM at any place in the code.
In both of those cases, the browser will garbage-colelct those variables once no object references them. So the minute the texture object is garbage collected (not disposed by babylon, but gc’ed by javascript), the canvas element will be garbage-collected as well.
I see, that explains it. Then back to my original question: can we safely create a freeze() method that dumps the canvas (maybe by making it undefined, thus GC’d)? or is the canvas still needed for something besides updating the texture later?
I use DynamicTexture to create textures, but I don’t ever update them after that. As far as I know canvas objects keep the bitmaps in memory, so for me that is 100’s of MB’s that I don’t think are needed anymore, because they are already present on the GPU.
So I’m checking if I’m correct. And if so, to ask if Babylon is interested in having this freeze method as well.
If that’s the case you can serialize the dynamic texture and create a new texture based on the URL provided. You can then eliminate the dynamic texture. something like this:
ah, yes, that is a way to do it.
I’m doing this in performance crucial moments as well though, so I will still look for a way to forego creating a second Texture.
In any case, it seems like there are 2 separate use cases for DynamicTexture. One where you want to draw a texture with the canvas, and one where you want a texture that you can update after creating it. If I’m correct about the memory concerns (still not 100% sure) it would be nice to support the first use case as well.
freezing a dynamic texture feels like contradicting the entire meaning behind a dynamic texture. And if the canvas is disposed there is no way of “unfreezing” it. Maybe someone else has a different opinion about it but i believe creating a new texture would be the best way to go.
I understand that it is happening at a critical point during the app’s lifecycle, but i assume there are ways to control it. Are you creating all of those dynamic textures at the same time?
I implemented it, and I can confirm it works as expected. In Safari web inspector I can no longer find canvases for each dynamic texture in the Graphics tab and the memory footprint is a lot smaller.
the code is straightforward (without built in safeguards against calling update() etc):
freeze() {
(this.dynamicTexture as any)._canvas = undefined;
(this.dynamicTexture as any)._context = undefined;
}