From ea24c0d4c88808e497c124b164b4136fbabd74c9 Mon Sep 17 00:00:00 2001 From: assiduous Date: Wed, 6 Nov 2024 22:50:02 -0800 Subject: [PATCH] HnTextureUtils: more aggressively throttle memory usage --- Hydrogent/src/HnTextureUtils.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Hydrogent/src/HnTextureUtils.cpp b/Hydrogent/src/HnTextureUtils.cpp index b041464d..e23f5f4c 100644 --- a/Hydrogent/src/HnTextureUtils.cpp +++ b/Hydrogent/src/HnTextureUtils.cpp @@ -202,9 +202,14 @@ HnLoadTextureResult LoadTextureFromSdfPath(const char* SdfPath, Int64 MemoryBudget, size_t LoaderMemorySize) { + // Keep track of estimated loader memory usage to avoid exceeding the budget. + // Unlike GetTextureLoaderMemoryUsage() that returns current memory usage, this value is an estimate + // of the memory that will be used by all loaders that are or will be in the process of loading textures. + static std::atomic EstimatedLoaderMemoryUsage{0}; + // Check memory budget before opening the asset. - // If we already tried to load this texture before, LoaderMemorySize will be non-zero - if (MemoryBudget != 0 && GetTextureLoaderMemoryUsage() + static_cast(LoaderMemorySize) > MemoryBudget) + // If we already tried to load this texture before, LoaderMemorySize will be non-zero. + if (MemoryBudget != 0 && std::max(GetTextureLoaderMemoryUsage(), EstimatedLoaderMemoryUsage.load()) + static_cast(LoaderMemorySize) > MemoryBudget) { // Reschedule the task return {HN_LOAD_TEXTURE_STATUS_BUDGET_EXCEEDED}; @@ -236,8 +241,11 @@ HnLoadTextureResult LoadTextureFromSdfPath(const char* SdfPath, if (MemoryBudget != 0) { LoaderMemorySize = GetTextureLoaderMemoryRequirement(Buffer.get(), Size, _LoadInfo) + Size; - if (GetTextureLoaderMemoryUsage() + static_cast(LoaderMemorySize) > MemoryBudget) + + Int64 LoaderMemoryUsage = EstimatedLoaderMemoryUsage.fetch_add(static_cast(LoaderMemorySize)); + if (std::max(GetTextureLoaderMemoryUsage(), LoaderMemoryUsage) + static_cast(LoaderMemorySize) > MemoryBudget) { + EstimatedLoaderMemoryUsage.fetch_add(static_cast(-LoaderMemorySize)); // Return LoaderMemorySize so that it can be used next time we try to load this texture return {HN_LOAD_TEXTURE_STATUS_BUDGET_EXCEEDED, LoaderMemorySize}; } @@ -252,6 +260,8 @@ HnLoadTextureResult LoadTextureFromSdfPath(const char* SdfPath, CreateTextureLoaderFromDataBlob(std::move(pAssetData), LoadInfo, &Res.pLoader); Res.LoadStatus = Res.pLoader ? HN_LOAD_TEXTURE_STATUS_SUCCESS : HN_LOAD_TEXTURE_STATUS_FAILED; + EstimatedLoaderMemoryUsage.fetch_add(static_cast(-LoaderMemorySize)); + return Res; }