aframevr / aframe

:a: Web framework for building virtual reality experiences.
https://aframe.io/
MIT License
16.66k stars 3.97k forks source link

360 image gallery with 15 photospheres crashes on iOS Safari #2640

Closed frankymacster closed 7 years ago

frankymacster commented 7 years ago

Description: I cloned a version of 360-image-gallery-boilerplate onto my computer and modified it to have 15 panoramas. On the iPad mini (Safari), when I switch between new photospheres (going to photospheres that I have not been to already), the experience gets slower and slower until it forces the tab to reload. This doesn't happen when going to previously visited photospheres.

I am currently working on a panorama viewer built with Aframe and some homes that we use have more than 40 panoramas. I have put together the example described above based on 360-image-gallery-boilerplate to see if it has to do with my code or with Aframe.

Could it be that there is some kind of memory leak caused by the updating of the material src attribute?

Thanks,

ngokevin commented 7 years ago

I think we need https://github.com/aframevr/aframe/issues/2166

But you can try clearing texture cache AFRAME.systems.material.textureCache. They resolve promises which you can call Texture.dispose(). But yeah, iOS has 10MB limit per tab or something.

frankymacster commented 7 years ago

Texture.dispose() didn't seem to work for me. I seemed to still be getting a memory leak. I ended up doing something like this instead:

let material = this.el.components.material.material;
if (!material.map) {
  material.map = new THREE.TextureLoader().load(src);
} else {
  material.map.image.src = src;
  material.map.needsUpdate = true;
}

I noticed that THREE.TextureLoader creates a new THREE.Texture object every time el.setAttribute('src', src) is called. This was creating a leak on the GPU as gl.texImage2D were accumulating. It's for this reason, I guess, that we need to call Texture.dispose(). But even when I call it, the memory leak occurs but at a slower rate. Setting the source this way material.map.image.src = src removed the memory leak completely.

Wouldn't it be more streamlined if el.setAttribute('src', src) would instantiate a THREE.TextureLoader only the first time it is set and afterward just change the image src?

Thanks again

frankymacster commented 6 years ago

This is still an issue. I observed the same thing going on in AFRAME 0.8.2. I get the impression that the textures are not being disposed when the src attribute of a component is updated.

winpassuser commented 1 year ago

This is still an issue. There should be an easy way to update the src of a material and clear the memory of the old material. I've tried the method above with needsupdate = true, but if the new image has different dimensions, the repeat parameter isn't applied correctly.