enable raw image loading by default, rename setting

This commit is contained in:
Jesse Plamondon-Willard 2022-05-26 00:51:11 -04:00
parent 4708385f69
commit 769475166a
No known key found for this signature in database
GPG Key ID: CF8B1456B3E29F49
6 changed files with 25 additions and 25 deletions

View File

@ -3,11 +3,10 @@
# Release notes # Release notes
## Upcoming release ## Upcoming release
* For players: * For players:
* Added experimental image load rewrite (disabled by default). * Optimized mod image file loading.
_If you have many content mods installed, enabling `UseExperimentalImageLoading` in `smapi-internal/config.json` may reduce load times or stutters when they load many image files at once._
* For mod authors: * For mod authors:
* Added specialized `IRawTextureData` asset type. * Added a new `IRawTextureData` asset type.
_When you're only loading a mod file to patch it into an asset, you can now load it using `helper.ModContent.Load<IRawTextureData>(path)`. This reads the image data from disk without initializing a `Texture2D` instance through the GPU. You can then pass this to SMAPI APIs that accept `Texture2D` instances._ _You can now load image files through `helper.ModContent` as `IRawTextureData` instead of `Texture2D`. This provides the image size and raw pixel data, which you can pass into other SMAPI APIs like `asset.AsImage().PatchImage`. This is much more efficient when you don't need a full `Texture2D` instance, since it bypasses the GPU operations needed to create one._
* For mod authors: * For mod authors:
* Fixed map edits which change warps sometimes rebuilding the NPC pathfinding cache unnecessarily, which could cause a noticeable delay for players. * Fixed map edits which change warps sometimes rebuilding the NPC pathfinding cache unnecessarily, which could cause a noticeable delay for players.

View File

@ -32,8 +32,8 @@ namespace StardewModdingAPI.Framework
/// <summary>An asset key prefix for assets from SMAPI mod folders.</summary> /// <summary>An asset key prefix for assets from SMAPI mod folders.</summary>
private readonly string ManagedPrefix = "SMAPI"; private readonly string ManagedPrefix = "SMAPI";
/// <summary>Whether to use a newer approach when loading image files from mod folder which may be faster.</summary> /// <summary>Whether to use raw image data when possible, instead of initializing an XNA Texture2D instance through the GPU.</summary>
private readonly bool UseExperimentalImageLoading; private readonly bool UseRawImageLoading;
/// <summary>Get a file lookup for the given directory.</summary> /// <summary>Get a file lookup for the given directory.</summary>
private readonly Func<string, IFileLookup> GetFileLookup; private readonly Func<string, IFileLookup> GetFileLookup;
@ -133,8 +133,8 @@ namespace StardewModdingAPI.Framework
/// <param name="getFileLookup">Get a file lookup for the given directory.</param> /// <param name="getFileLookup">Get a file lookup for the given directory.</param>
/// <param name="onAssetsInvalidated">A callback to invoke when any asset names have been invalidated from the cache.</param> /// <param name="onAssetsInvalidated">A callback to invoke when any asset names have been invalidated from the cache.</param>
/// <param name="requestAssetOperations">Get the load/edit operations to apply to an asset by querying registered <see cref="IContentEvents.AssetRequested"/> event handlers.</param> /// <param name="requestAssetOperations">Get the load/edit operations to apply to an asset by querying registered <see cref="IContentEvents.AssetRequested"/> event handlers.</param>
/// <param name="useExperimentalImageLoading">Whether to use a newer approach when loading image files from mod folder which may be faster.</param> /// <param name="useRawImageLoading">Whether to use raw image data when possible, instead of initializing an XNA Texture2D instance through the GPU.</param>
public ContentCoordinator(IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, IMonitor monitor, Reflector reflection, JsonHelper jsonHelper, Action onLoadingFirstAsset, Action<BaseContentManager, IAssetName> onAssetLoaded, Func<string, IFileLookup> getFileLookup, Action<IList<IAssetName>> onAssetsInvalidated, Func<IAssetInfo, AssetOperationGroup?> requestAssetOperations, bool useExperimentalImageLoading) public ContentCoordinator(IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, IMonitor monitor, Reflector reflection, JsonHelper jsonHelper, Action onLoadingFirstAsset, Action<BaseContentManager, IAssetName> onAssetLoaded, Func<string, IFileLookup> getFileLookup, Action<IList<IAssetName>> onAssetsInvalidated, Func<IAssetInfo, AssetOperationGroup?> requestAssetOperations, bool useRawImageLoading)
{ {
this.GetFileLookup = getFileLookup; this.GetFileLookup = getFileLookup;
this.Monitor = monitor ?? throw new ArgumentNullException(nameof(monitor)); this.Monitor = monitor ?? throw new ArgumentNullException(nameof(monitor));
@ -145,7 +145,7 @@ namespace StardewModdingAPI.Framework
this.OnAssetsInvalidated = onAssetsInvalidated; this.OnAssetsInvalidated = onAssetsInvalidated;
this.RequestAssetOperations = requestAssetOperations; this.RequestAssetOperations = requestAssetOperations;
this.FullRootDirectory = Path.Combine(Constants.GamePath, rootDirectory); this.FullRootDirectory = Path.Combine(Constants.GamePath, rootDirectory);
this.UseExperimentalImageLoading = useExperimentalImageLoading; this.UseRawImageLoading = useRawImageLoading;
this.ContentManagers.Add( this.ContentManagers.Add(
this.MainContentManager = new GameContentManager( this.MainContentManager = new GameContentManager(
name: "Game1.content", name: "Game1.content",
@ -225,7 +225,7 @@ namespace StardewModdingAPI.Framework
jsonHelper: this.JsonHelper, jsonHelper: this.JsonHelper,
onDisposing: this.OnDisposing, onDisposing: this.OnDisposing,
fileLookup: this.GetFileLookup(rootDirectory), fileLookup: this.GetFileLookup(rootDirectory),
useExperimentalImageLoading: this.UseExperimentalImageLoading useRawImageLoading: this.UseRawImageLoading
); );
this.ContentManagers.Add(manager); this.ContentManagers.Add(manager);
return manager; return manager;

View File

@ -27,8 +27,8 @@ namespace StardewModdingAPI.Framework.ContentManagers
/********* /*********
** Fields ** Fields
*********/ *********/
/// <summary>Whether to use a newer approach when loading image files from mod folder which may be faster.</summary> /// <summary>Whether to use raw image data when possible, instead of initializing an XNA Texture2D instance through the GPU.</summary>
private readonly bool UseExperimentalImageLoading; private readonly bool UseRawImageLoading;
/// <summary>Encapsulates SMAPI's JSON file parsing.</summary> /// <summary>Encapsulates SMAPI's JSON file parsing.</summary>
private readonly JsonHelper JsonHelper; private readonly JsonHelper JsonHelper;
@ -62,15 +62,15 @@ namespace StardewModdingAPI.Framework.ContentManagers
/// <param name="jsonHelper">Encapsulates SMAPI's JSON file parsing.</param> /// <param name="jsonHelper">Encapsulates SMAPI's JSON file parsing.</param>
/// <param name="onDisposing">A callback to invoke when the content manager is being disposed.</param> /// <param name="onDisposing">A callback to invoke when the content manager is being disposed.</param>
/// <param name="fileLookup">A lookup for files within the <paramref name="rootDirectory"/>.</param> /// <param name="fileLookup">A lookup for files within the <paramref name="rootDirectory"/>.</param>
/// <param name="useExperimentalImageLoading">Whether to use a newer approach when loading image files from mod folder which may be faster.</param> /// <param name="useRawImageLoading">Whether to use raw image data when possible, instead of initializing an XNA Texture2D instance through the GPU.</param>
public ModContentManager(string name, IContentManager gameContentManager, IServiceProvider serviceProvider, string modName, string rootDirectory, CultureInfo currentCulture, ContentCoordinator coordinator, IMonitor monitor, Reflector reflection, JsonHelper jsonHelper, Action<BaseContentManager> onDisposing, IFileLookup fileLookup, bool useExperimentalImageLoading) public ModContentManager(string name, IContentManager gameContentManager, IServiceProvider serviceProvider, string modName, string rootDirectory, CultureInfo currentCulture, ContentCoordinator coordinator, IMonitor monitor, Reflector reflection, JsonHelper jsonHelper, Action<BaseContentManager> onDisposing, IFileLookup fileLookup, bool useRawImageLoading)
: base(name, serviceProvider, rootDirectory, currentCulture, coordinator, monitor, reflection, onDisposing, isNamespaced: true) : base(name, serviceProvider, rootDirectory, currentCulture, coordinator, monitor, reflection, onDisposing, isNamespaced: true)
{ {
this.GameContentManager = gameContentManager; this.GameContentManager = gameContentManager;
this.FileLookup = fileLookup; this.FileLookup = fileLookup;
this.JsonHelper = jsonHelper; this.JsonHelper = jsonHelper;
this.ModName = modName; this.ModName = modName;
this.UseExperimentalImageLoading = useExperimentalImageLoading; this.UseRawImageLoading = useRawImageLoading;
this.TryLocalizeKeys = false; this.TryLocalizeKeys = false;
} }
@ -199,7 +199,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
} }
// load // load
if (asRawData || this.UseExperimentalImageLoading) if (asRawData || this.UseRawImageLoading)
{ {
// load raw data // load raw data
using FileStream stream = File.OpenRead(file.FullName); using FileStream stream = File.OpenRead(file.FullName);

View File

@ -23,7 +23,7 @@ namespace StardewModdingAPI.Framework.Models
[nameof(LogNetworkTraffic)] = false, [nameof(LogNetworkTraffic)] = false,
[nameof(RewriteMods)] = true, [nameof(RewriteMods)] = true,
[nameof(UsePintail)] = true, [nameof(UsePintail)] = true,
[nameof(UseExperimentalImageLoading)] = false, [nameof(UseRawImageLoading)] = true,
[nameof(UseCaseInsensitivePaths)] = Constants.Platform is Platform.Android or Platform.Linux [nameof(UseCaseInsensitivePaths)] = Constants.Platform is Platform.Android or Platform.Linux
}; };
@ -67,8 +67,8 @@ namespace StardewModdingAPI.Framework.Models
/// <summary>Whether to use the experimental Pintail API proxying library, instead of the original proxying built into SMAPI itself.</summary> /// <summary>Whether to use the experimental Pintail API proxying library, instead of the original proxying built into SMAPI itself.</summary>
public bool UsePintail { get; } public bool UsePintail { get; }
/// <summary>Whether to use a newer approach when loading image files from mod folder which may be faster.</summary> /// <summary>Whether to use raw image data when possible, instead of initializing an XNA Texture2D instance through the GPU.</summary>
public bool UseExperimentalImageLoading { get; } public bool UseRawImageLoading { get; }
/// <summary>Whether to make SMAPI file APIs case-insensitive, even on Linux.</summary> /// <summary>Whether to make SMAPI file APIs case-insensitive, even on Linux.</summary>
public bool UseCaseInsensitivePaths { get; } public bool UseCaseInsensitivePaths { get; }
@ -96,12 +96,12 @@ namespace StardewModdingAPI.Framework.Models
/// <param name="verboseLogging">The log contexts for which to enable verbose logging, which may show a lot more information to simplify troubleshooting.</param> /// <param name="verboseLogging">The log contexts for which to enable verbose logging, which may show a lot more information to simplify troubleshooting.</param>
/// <param name="rewriteMods">Whether SMAPI should rewrite mods for compatibility.</param> /// <param name="rewriteMods">Whether SMAPI should rewrite mods for compatibility.</param>
/// <param name="usePintail">Whether to use the experimental Pintail API proxying library, instead of the original proxying built into SMAPI itself.</param> /// <param name="usePintail">Whether to use the experimental Pintail API proxying library, instead of the original proxying built into SMAPI itself.</param>
/// <param name="useExperimentalImageLoading">Whether to use a newer approach when loading image files from mod folder which may be faster.</param> /// <param name="useRawImageLoading">Whether to use raw image data when possible, instead of initializing an XNA Texture2D instance through the GPU.</param>
/// <param name="useCaseInsensitivePaths">>Whether to make SMAPI file APIs case-insensitive, even on Linux.</param> /// <param name="useCaseInsensitivePaths">>Whether to make SMAPI file APIs case-insensitive, even on Linux.</param>
/// <param name="logNetworkTraffic">Whether SMAPI should log network traffic.</param> /// <param name="logNetworkTraffic">Whether SMAPI should log network traffic.</param>
/// <param name="consoleColors">The colors to use for text written to the SMAPI console.</param> /// <param name="consoleColors">The colors to use for text written to the SMAPI console.</param>
/// <param name="suppressUpdateChecks">The mod IDs SMAPI should ignore when performing update checks or validating update keys.</param> /// <param name="suppressUpdateChecks">The mod IDs SMAPI should ignore when performing update checks or validating update keys.</param>
public SConfig(bool developerMode, bool? checkForUpdates, bool? paranoidWarnings, bool? useBetaChannel, string gitHubProjectName, string webApiBaseUrl, string[]? verboseLogging, bool? rewriteMods, bool? usePintail, bool? useExperimentalImageLoading, bool? useCaseInsensitivePaths, bool? logNetworkTraffic, ColorSchemeConfig consoleColors, string[]? suppressUpdateChecks) public SConfig(bool developerMode, bool? checkForUpdates, bool? paranoidWarnings, bool? useBetaChannel, string gitHubProjectName, string webApiBaseUrl, string[]? verboseLogging, bool? rewriteMods, bool? usePintail, bool? useRawImageLoading, bool? useCaseInsensitivePaths, bool? logNetworkTraffic, ColorSchemeConfig consoleColors, string[]? suppressUpdateChecks)
{ {
this.DeveloperMode = developerMode; this.DeveloperMode = developerMode;
this.CheckForUpdates = checkForUpdates ?? (bool)SConfig.DefaultValues[nameof(this.CheckForUpdates)]; this.CheckForUpdates = checkForUpdates ?? (bool)SConfig.DefaultValues[nameof(this.CheckForUpdates)];
@ -112,7 +112,7 @@ namespace StardewModdingAPI.Framework.Models
this.VerboseLogging = new HashSet<string>(verboseLogging ?? Array.Empty<string>(), StringComparer.OrdinalIgnoreCase); this.VerboseLogging = new HashSet<string>(verboseLogging ?? Array.Empty<string>(), StringComparer.OrdinalIgnoreCase);
this.RewriteMods = rewriteMods ?? (bool)SConfig.DefaultValues[nameof(this.RewriteMods)]; this.RewriteMods = rewriteMods ?? (bool)SConfig.DefaultValues[nameof(this.RewriteMods)];
this.UsePintail = usePintail ?? (bool)SConfig.DefaultValues[nameof(this.UsePintail)]; this.UsePintail = usePintail ?? (bool)SConfig.DefaultValues[nameof(this.UsePintail)];
this.UseExperimentalImageLoading = useExperimentalImageLoading ?? (bool)SConfig.DefaultValues[nameof(this.UseExperimentalImageLoading)]; this.UseRawImageLoading = useRawImageLoading ?? (bool)SConfig.DefaultValues[nameof(this.UseRawImageLoading)];
this.UseCaseInsensitivePaths = useCaseInsensitivePaths ?? (bool)SConfig.DefaultValues[nameof(this.UseCaseInsensitivePaths)]; this.UseCaseInsensitivePaths = useCaseInsensitivePaths ?? (bool)SConfig.DefaultValues[nameof(this.UseCaseInsensitivePaths)];
this.LogNetworkTraffic = logNetworkTraffic ?? (bool)SConfig.DefaultValues[nameof(this.LogNetworkTraffic)]; this.LogNetworkTraffic = logNetworkTraffic ?? (bool)SConfig.DefaultValues[nameof(this.LogNetworkTraffic)];
this.ConsoleColors = consoleColors; this.ConsoleColors = consoleColors;

View File

@ -1302,7 +1302,7 @@ namespace StardewModdingAPI.Framework
onAssetsInvalidated: this.OnAssetsInvalidated, onAssetsInvalidated: this.OnAssetsInvalidated,
getFileLookup: this.GetFileLookup, getFileLookup: this.GetFileLookup,
requestAssetOperations: this.RequestAssetOperations, requestAssetOperations: this.RequestAssetOperations,
useExperimentalImageLoading: this.Settings.UseExperimentalImageLoading useRawImageLoading: this.Settings.UseRawImageLoading
); );
if (this.ContentCore.Language != this.Translator.LocaleEnum) if (this.ContentCore.Language != this.Translator.LocaleEnum)
this.Translator.SetLocale(this.ContentCore.GetLocale(), this.ContentCore.Language); this.Translator.SetLocale(this.ContentCore.GetLocale(), this.ContentCore.Language);

View File

@ -61,9 +61,10 @@ copy all the settings, or you may cause bugs due to overridden changes in future
"UsePintail": true, "UsePintail": true,
/** /**
* Whether to use a newer approach when loading image files from mod folder which may be faster. * Whether to use raw image data when possible, instead of initializing an XNA Texture2D
* instance through the GPU.
*/ */
"UseExperimentalImageLoading": false, "UseRawImageLoading": true,
/** /**
* Whether to add a section to the 'mod issues' list for mods which directly use potentially * Whether to add a section to the 'mod issues' list for mods which directly use potentially