diff --git a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs
index f11ce9648..cb87fcb5a 100644
--- a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs
+++ b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs
@@ -1,5 +1,6 @@
using System;
using System.Buffers;
+using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
@@ -45,6 +46,8 @@ internal sealed class ModContentManager : BaseContentManager
/// If a map tilesheet's image source has no file extensions, the file extensions to check for in the local mod folder.
private static readonly string[] LocalTilesheetExtensions = [".png", ".xnb"];
+ private readonly Dictionary TextureCache = [];
+
/*********
** Public methods
@@ -216,10 +219,18 @@ private T LoadImageFile(IAssetName assetName, FileInfo file)
/// The file whose data to load.
/// Whether the data is being loaded for an (true) or (false) instance.
/// This is separate to let framework mods intercept the data before it's loaded, if needed.
- [SuppressMessage("ReSharper", "UnusedParameter.Local", Justification = "The 'forRawData' parameter is only added for mods which may intercept this method.")]
- [SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "The 'forRawData' parameter is only added for mods which may intercept this method.")]
private IRawTextureData LoadRawImageData(FileInfo file, bool forRawData)
{
+ if (this.TextureCache.TryGetValue(file.FullName, out var cacheResult))
+ {
+ var cacheColors = cacheResult.Data;
+ if (forRawData)
+ {
+ return new RawTextureData(cacheResult.Width, cacheResult.Height, (Color[])cacheColors.Clone());
+ }
+ return new RawTextureData(cacheResult.Width, cacheResult.Height, cacheColors);
+ }
+
// load raw data
int width;
int height;
@@ -238,13 +249,27 @@ private IRawTextureData LoadRawImageData(FileInfo file, bool forRawData)
// convert to XNA pixel format
var pixels = GC.AllocateUninitializedArray(rawPixels.Length);
+ Color[]? pixelCache = null;
+ if (forRawData)
+ pixelCache = GC.AllocateUninitializedArray(rawPixels.Length);
for (int i = 0; i < pixels.Length; i++)
{
SKPMColor pixel = rawPixels[i];
pixels[i] = pixel.Alpha == 0
? Color.Transparent
: new Color(r: pixel.Red, g: pixel.Green, b: pixel.Blue, alpha: pixel.Alpha);
+
+ if (pixelCache != null)
+ {
+ pixelCache[i] = pixel.Alpha == 0
+ ? Color.Transparent
+ : new Color(r: pixel.Red, g: pixel.Green, b: pixel.Blue, alpha: pixel.Alpha);
+ }
}
+ if (pixelCache != null)
+ this.TextureCache.Add(file.FullName, new RawTextureData(width, height, pixelCache));
+ else
+ this.TextureCache.Add(file.FullName, new RawTextureData(width, height, pixels));
return new RawTextureData(width, height, pixels);
}