Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release VRAM when switching scenes #1751

Closed
dexterdeluxe88 opened this issue Nov 18, 2019 · 6 comments
Closed

Release VRAM when switching scenes #1751

dexterdeluxe88 opened this issue Nov 18, 2019 · 6 comments

Comments

@dexterdeluxe88
Copy link

Feature Request: Releasing the VRAM automatically when switching scenes.

https://forum.playcanvas.com/t/vram-doesnt-get-released-properly

In our game setups, we have two root nodes, called "Scene" and "Permanent". When switching scenes, we only destroy the "Scene" node, and keep the "Permanent" node. That's similar to "DontDestroyOnLoad" flag in Unity.

Example:

  • Scene
    -- Level Props for Level 1
    -- Everything scene specific
  • Permanent
    -- Sound Manager
    -- Global Logic
    -- Loading Transition GUI

So it would be great to have sort of a "destroyAndFreeMemory" function for that node.

@Maksims
Copy link
Contributor

Maksims commented Nov 18, 2019

I would assume you want to remove assets from the registry, that are used by Scene after it is destroyed?

Application has AssetRegistry, which holds all the information of assets and loads then when they are used in hierarchy and visible or marked as preload. If your assets are not marked as preload, then loading Scene, and rendering it, will trigger referenced assets to load. AssetRegistry lives not with Scene, but with Application.

Developer might reference same asset in multiple Scene Levels, and there are complex scenarios regarding this. So, there is no clearing mechanism built in to engine, as it is Developer responsibility to manage their assets registry.

One of the easiest solution for you, is using tags system:

  1. Mark all assets, with related tags, like "level-1", "level-2", etc. Some assets might have multiple level references.
  2. When unloading level, find all related assets, and destroy them, finding using: app.assets.findByTag('level-1').
  3. When loading another level, then you can first find level-2 assets, then level-1, and remove the ones used in level-2, so you don't unload and then load again same asset.

@dexterdeluxe88
Copy link
Author

Hi @Maksims

Thanks for the answer.

Yes, I want to remove assets from the registry, that are used by Scene after it is destroyed.

Your solution with the tags is great (logic-wise), but its a lot of overhead and needs a lot of meticulousness to mark everything.

That it is a developer responsibility to manage their assets registry - is a conceptual/design question. Do you know how other engines (e.g. Unity Project Tiny) handle this?

It could also be designed like this: Everything is released on scene switching. If I want to keep things in RAM, I can flag it as "DontDestroyOnLoad" or something.

In the end it depends on what is more common in the average projects: Assets which needs to survive through scene changes, or assets which should be destroyed on scene changes.

@Maksims
Copy link
Contributor

Maksims commented Nov 20, 2019

That it is a developer responsibility to manage their assets registry - is a conceptual/design question. Do you know how other engines (e.g. Unity Project Tiny) handle this?

Unity does not release assets when unloading scene. Assets have own registry, and not related to scene hierarchy at all.

It could also be designed like this: Everything is released on scene switching. If I want to keep things in RAM, I can flag it as "DontDestroyOnLoad" or something.

But that would lead to someone has to mark stuff to not unload. Which can be even worse. As this implies some underlying mechanics, that developer then has to have workaround for.

In the end it depends on what is more common in the average projects: Assets which needs to survive through scene changes, or assets which should be destroyed on scene changes.

From my experience, most common - is complex. If someone uses multiple scenes, then it is usually more advanced user, and has complex assets usage case.

You could make a naive approach script: that would build index of all assets, then go through your scene hierarchy, and find all assets that are used, remove them from that index object.
At the end you will have index of unused assets. So you can then destroy them.

@dexterdeluxe88
Copy link
Author

@Maksims
From the Unity docs: Assets are currently not unloaded, in order to free up asset memory call Resources.UnloadUnusedAssets

Is there an equivalent solution in PlayCanvas?

@Christopher-Hayes
Copy link
Contributor

Christopher-Hayes commented Jul 25, 2020

@Maksims
From the Unity docs: Assets are currently not unloaded, in order to free up asset memory call Resources.UnloadUnusedAssets

Is there an equivalent solution in PlayCanvas?

Nothing "out of the box", but if you filter by the loaded property there's this:
pc.app.assets.list().filter(asset => asset.loaded);

@yaustar
Copy link
Contributor

yaustar commented Jul 1, 2021

Closed as there is a solution provided to get all the assets that are currently loaded.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants