From 7bc5bd5791690e9a20efcecf64e078f4e4e94c0d Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Fri, 23 Mar 2018 20:06:30 +0000 Subject: [PATCH] Force buffered sheets to commit data to a texture on buffer release. Previously ReleaseBuffer did not immediately null out the buffer, instead the releaseBufferOnCommit flag allows it to be nulled when the texture is next access and the pending changes from the buffer are committed to it. Now the texture is committed immediately, thus the buffer is null once ReleaseBuffer returns. Once loaded, we force a GC to reclaim temporary memory used during loading. Previously the buffer would not be null as it was pending commit to the texture and thus could not be reclaimed. As soon as we rendered the first frame, the buffer is nulled but we are now in a low GC state - and the buffer will not be reclaimed until the next gen 2 GC which may be dozens of minutes away. This change ensures the buffer is null in time for the post-load GC, and thus can be reclaimed before we start rendering. --- OpenRA.Game/Graphics/Sheet.cs | 4 ++++ OpenRA.Game/Map/MapCache.cs | 9 ++------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/OpenRA.Game/Graphics/Sheet.cs b/OpenRA.Game/Graphics/Sheet.cs index 5812eb41ec..9e594decb6 100644 --- a/OpenRA.Game/Graphics/Sheet.cs +++ b/OpenRA.Game/Graphics/Sheet.cs @@ -153,6 +153,10 @@ namespace OpenRA.Graphics return; dirty = true; releaseBufferOnCommit = true; + + // Commit data from the buffer to the texture, allowing the buffer to be released and reclaimed by GC. + if (Game.Renderer != null) + GetTexture(); } public void Dispose() diff --git a/OpenRA.Game/Map/MapCache.cs b/OpenRA.Game/Map/MapCache.cs index 1bf040f7fc..8c5e18d22f 100644 --- a/OpenRA.Game/Map/MapCache.cs +++ b/OpenRA.Game/Map/MapCache.cs @@ -276,13 +276,8 @@ namespace OpenRA } } - // The buffer is not fully reclaimed until changes are written out to the texture. - // We will access the texture in order to force changes to be written out, allowing the buffer to be freed. - Game.RunAfterTick(() => - { - sheetBuilder.Current.ReleaseBuffer(); - sheetBuilder.Current.GetTexture(); - }); + // Release the buffer by forcing changes to be written out to the texture, allowing the buffer to be reclaimed by GC. + Game.RunAfterTick(sheetBuilder.Current.ReleaseBuffer); Log.Write("debug", "MapCache.LoadAsyncInternal ended"); }