UAssetManager::ChangeBundleStateForPrimaryAssets allows adding new BundleNames to the list of BundleNames loaded for a PrimaryAssetId. Each BundleName specifies a BundleEntry with a list of assets. Each BundleEntry for a PrimaryAsset can be individually specified for whether it should be loaded.
ChangeBundleStateForPrimaryAssets is more flexible than LoadPrimaryAssets; it can add or remove BundleNames while keeping others unchanged. LoadPrimaryAssets always completely removes the existing BundleNames and specifies the loading of the input BundleNames.
Whether called externally or through LoadPrimaryAssets, it is possible that ChangeBundleStateForPrimaryAssets will indicate some BundleNames should be loaded that are already finished loading (they are present in the PrimaryAsset's FPrimaryAssetData.CurrentState), and it is possible it will indicate some BundleNames should be loaded that have a load pending (they are present in the PrimaryAsset's FPrimaryAssetData.PendingState).
In the case of already-requested bundles in the CurrentState, the system behaves with good performance: the already-loaded bundles are added to the FStreamableHandle in the PendingState, and a load request is sent for them. The load request exits immediately because the assets are already loaded. When all of the new assets are loaded for the PendingState, the FStreamableHandle from the old CurrentState is dropped and the PendingState is copied onto the CurrentState.
But for already-requested bundles in the PendingState, the performance is suboptimal. The bundles that were previously requested but are not yet completed loading and are in the PendingState are dropped immediately during the function, by a call to NameData->PendingState.Reset(true). They are then requested again and their load restarts.
Avoid the wasted performance cost of canceling and restarting the loads for the bundles that have already been requested.
Note that this change is risky, because we have a single streamable handle that holds all of the requested bundles, and it will need to be changed. We attempted a fix for this issue twice before, but in each case had to revert it because it caused memory leaks.
Record of pervious attempts:
If we cannot fix the performance for a while, we should make an easier change sooner: we should change the API for FStreamableHandle so that the DelegateToCall is informed of the cancellation state. It should be told whether the set of package loads completed fully or was fully cancelled or was partially cancelled, and if cancelled whether there is a new streaming handle that should be subscribed to.
There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-208804 in the post.
1 |
Component | UE - Foundation - Core - Cooker |
---|---|
Target Fix | 5.6 |
Created | Mar 4, 2024 |
---|---|
Updated | Oct 18, 2024 |