Gastly
Topic Author
Posts: 2
Joined: 19 Feb 2026, 09:43

Help with texture lifetime management when loading textures dynamically in a Custom engine

24 Mar 2026, 17:08

Hi! I'm having issues with texture lifetime management when loading textures dynamically.

I'm working with a custom engine and I have implemented a TextureProvider
  • In LoadTexture(), I return Noesis::Ptr<Noesis::Texture>{new MyTextureWrapper(engineTexture)}
  • MyTextureWrapper holds a strong reference to our engine's texture resource
  • I cache weak references to textures in my backend to avoid reloading

My problem:
  • After closing a View or removing UI elements that use the textures, the texture refcount never decreases

MyTextureWrapper destructor is never called, even after:
  • Clearing the View elements that references the textures
  • Destroying the View



1. Does Noesis cache textures globally beyond the View lifetime?
2. When/how are Texture objects returned from LoadTexture() expected to be released?
3. Is there an API to clear the texture cache or force texture release?
4. Should I be doing something different in my TextureProvider implementation?

Thanks!
 
User avatar
jsantos
Site Admin
Posts: 4822
Joined: 20 Jan 2012, 17:18
Contact:

Re: Help with texture lifetime management when loading textures dynamically in a Custom engine

24 Mar 2026, 20:23

There are two important things to consider here:

1. Make sure that you are not only destroying the view, but also shutting down the corresponding IRenderer (just like you initialize it). We don’t keep extra strong references to textures, so once a texture is no longer used, it should be released.

2.
Noesis::Ptr<Noesis::Texture>{new MyTextureWrapper(engineTexture)}
This pattern is likely leaking memory because MyTextureWrapper is constructed with one reference, and then an additional reference is added by Ptr. If you are not manually calling the corresponding Release for that new, the wrapper will never be destroyed.

In our code, we follow alternative patterns that avoid this issue:

- Ptr<Texture>{*new MyTextureWrapper(engineTexture)}
- Ptr<Texture>{MakePtr<MyTextureWrapper>(engineTexture)}
 
blanchelawson
Posts: 2
Joined: 25 Mar 2026, 04:34

Re: Help with texture lifetime management when loading textures dynamically in a Custom engine

25 Mar 2026, 04:37

There are two important things to consider here:

1. Make sure that you are not only destroying the view, but also shutting down the corresponding IRenderer (just like you initialize it). We don’t keep extra strong references to textures, so once a texture is no longer used, it should be released.

2.
Noesis::Ptr<Noesis::Texture>{new MyTextureWrapper(engineTexture)}
This pattern is likely leaking memory because MyTextureWrapper is constructed with one reference, and then an additional reference is added by Ptr. If you are not manually calling the corresponding Release for that new, the wrapper will never be destroyed.

In our code, we follow alternative patterns that geometry dash lite avoid this issue:

- Ptr<Texture>{*new MyTextureWrapper(engineTexture)}
- Ptr<Texture>{MakePtr<MyTextureWrapper>(engineTexture)}
Thanks for the detailed explanation-this makes a lot of sense. I wasn’t properly shutting down the IRenderer, so that could definitely explain why textures weren’t being released. Also, good catch on the Ptr initialization pattern-I can see how that extra reference would cause a leak if not handled correctly. I’ll switch to using MakePtr or the alternative pattern you mentioned and test again. Appreciate the clarification!
 
Gastly
Topic Author
Posts: 2
Joined: 19 Feb 2026, 09:43

Re: Help with texture lifetime management when loading textures dynamically in a Custom engine

25 Mar 2026, 09:45

There are two important things to consider here:

1. Make sure that you are not only destroying the view, but also shutting down the corresponding IRenderer (just like you initialize it). We don’t keep extra strong references to textures, so once a texture is no longer used, it should be released.

2.
Noesis::Ptr<Noesis::Texture>{new MyTextureWrapper(engineTexture)}
This pattern is likely leaking memory because MyTextureWrapper is constructed with one reference, and then an additional reference is added by Ptr. If you are not manually calling the corresponding Release for that new, the wrapper will never be destroyed.

In our code, we follow alternative patterns that avoid this issue:

- Ptr<Texture>{*new MyTextureWrapper(engineTexture)}
- Ptr<Texture>{MakePtr<MyTextureWrapper>(engineTexture)}
Thank you very much! you are completely right, I was destroying the view as I should but I missed that we weren't never really releasing that new.
 
User avatar
jsantos
Site Admin
Posts: 4822
Joined: 20 Jan 2012, 17:18
Contact:

Re: Help with texture lifetime management when loading textures dynamically in a Custom engine

25 Mar 2026, 10:56

Happy to help! :)

Who is online

Users browsing this forum: Bing [Bot] and 4 guests