From 15f25320096b9282972046b250653e93663dd28b Mon Sep 17 00:00:00 2001 From: Phoenix-Starlight Date: Sun, 3 Sep 2023 16:50:09 -0700 Subject: [PATCH 1/3] Dynamic sound loading --- .../SoundBufferLibraryMixin.java | 45 +++++++++++++++++++ .../dynamicresources/DynamicSoundHelpers.java | 14 ++++++ 2 files changed, 59 insertions(+) create mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/SoundBufferLibraryMixin.java create mode 100644 common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicSoundHelpers.java diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/SoundBufferLibraryMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/SoundBufferLibraryMixin.java new file mode 100644 index 000000000..5fec79e1a --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/SoundBufferLibraryMixin.java @@ -0,0 +1,45 @@ +package org.embeddedt.modernfix.common.mixin.perf.dynamic_resources; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.RemovalNotification; +import com.mojang.blaze3d.audio.SoundBuffer; +import net.minecraft.client.sounds.SoundBufferLibrary; +import net.minecraft.resources.ResourceLocation; +import org.embeddedt.modernfix.annotation.ClientOnlyMixin; +import org.embeddedt.modernfix.dynamicresources.DynamicSoundHelpers; +import org.embeddedt.modernfix.ModernFix; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import java.util.Map; + +@Mixin(SoundBufferLibrary.class) +@ClientOnlyMixin +public abstract class SoundBufferLibraryMixin { + + private static final boolean debugDynamicSoundLoading = Boolean.getBoolean("modernfix.debugDynamicSoundLoading"); + + @Shadow @Final @Mutable + private Map> cache = + CacheBuilder.newBuilder() + .maximumSize(DynamicSoundHelpers.MAX_SOUND_COUNT) + .expireAfterAccess(DynamicSoundHelpers.MAX_SOUND_LIFETIME_SECS, TimeUnit.SECONDS) + // Excessive use of type hinting due to it assuming Object as the broadest correct type + .>removalListener(this::onSoundRemoval) + .>build() + .asMap(); + + private > void onSoundRemoval(RemovalNotification notification) { + notification.getValue().thenAccept(SoundBuffer::discardAlBuffer); + if(debugDynamicSoundLoading) { + K k = notification.getKey(); + if(k == null) + return; + ModernFix.LOGGER.warn("Evicted sound {}", k); + } + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicSoundHelpers.java b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicSoundHelpers.java new file mode 100644 index 000000000..c78646665 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicSoundHelpers.java @@ -0,0 +1,14 @@ +package org.embeddedt.modernfix.dynamicresources; + +public class DynamicSoundHelpers { + /** + * The duration until a sound is eligible for eviction if unused. + */ + public static final int MAX_SOUND_LIFETIME_SECS = 120; + + /** + * The max amount of sounds loaded + * This was chosen because Minecraft Java can play up to 255 sounds, with a bit of leeway for extra sounds being loaded in. + */ + public static final int MAX_SOUND_COUNT = 300; +} From 569015916e70156129c4293f424a0c5da11c4bc3 Mon Sep 17 00:00:00 2001 From: Phoenix-Starlight Date: Fri, 15 Sep 2023 19:37:24 -0700 Subject: [PATCH 2/3] Split dynamic sounds into its own folder --- .../SoundBufferLibraryMixin.java | 2 +- common/src/main/resources/assets/modernfix/lang/en_us.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) rename common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/{dynamic_resources => dynamic_sounds}/SoundBufferLibraryMixin.java (96%) diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/SoundBufferLibraryMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_sounds/SoundBufferLibraryMixin.java similarity index 96% rename from common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/SoundBufferLibraryMixin.java rename to common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_sounds/SoundBufferLibraryMixin.java index 5fec79e1a..4869208c7 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/SoundBufferLibraryMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_sounds/SoundBufferLibraryMixin.java @@ -1,4 +1,4 @@ -package org.embeddedt.modernfix.common.mixin.perf.dynamic_resources; +package org.embeddedt.modernfix.common.mixin.perf.dynamic_sounds; import com.google.common.cache.CacheBuilder; import com.google.common.cache.RemovalNotification; diff --git a/common/src/main/resources/assets/modernfix/lang/en_us.json b/common/src/main/resources/assets/modernfix/lang/en_us.json index ec27bf0fb..98bc5ba1f 100644 --- a/common/src/main/resources/assets/modernfix/lang/en_us.json +++ b/common/src/main/resources/assets/modernfix/lang/en_us.json @@ -42,6 +42,7 @@ "modernfix.option.mixin.perf.deduplicate_location": "All versions, but disabled by default due to load time impact. Deduplicates resource location namespaces and paths. This saves RAM but also increases the cost of constructing a new `ResourceLocation` by quite a bit.", "modernfix.option.mixin.perf.dynamic_dfu": "All versions. Modifies DFU initialization to happen the first time something needs to be upgraded. This sounds similar to LazyDFU but is distinctly implemented, as it avoids loading *any* DFU classes/data structures, while LazyDFU only disables rule optimization. Essentially, this option is a safer version of DataFixerSlayer as it will still load DFU when needed.\n\nYou should typically continue to use LazyDFU even with this option enabled, as otherwise DFU rule optimization will cause lag.", "modernfix.option.mixin.perf.dynamic_resources": "All versions. See https://github.com/embeddedt/ModernFix/wiki/Dynamic-Resources-FAQ.", + "modernfix.option.mixin.perf.dynamic_sounds": "All versions. Allows the game to unload sounds, instead of sounds indefinitely persisting after being loaded.", "modernfix.option.mixin.perf.dynamic_structure_manager": "All versions. Allows the game to unload structure files after generation concludes instead of keeping them loaded forever.", "modernfix.option.mixin.perf.fast_registry_validation": "All versions. Forge needlessly looks up a method via reflection every single time a registry is validated. This patch simply caches the returned value since it will be the same every time.", "modernfix.option.mixin.perf.faster_font_loading": "All versions. Optimizes the font renderer to load fonts faster, speeding up resource reload.", From 45ff24868431bc3dc9a83817a4641475aad5c4f5 Mon Sep 17 00:00:00 2001 From: Phoenix-Starlight Date: Fri, 22 Sep 2023 18:33:21 -0700 Subject: [PATCH 3/3] Remove entry limit If limit+1 sounds get loaded the buffer deletion can fail due to it being bound to a source but not played yet. Also fixes a leak. --- .../mixin/perf/dynamic_sounds/SoundBufferLibraryMixin.java | 1 - .../modernfix/dynamicresources/DynamicSoundHelpers.java | 6 ------ 2 files changed, 7 deletions(-) diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_sounds/SoundBufferLibraryMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_sounds/SoundBufferLibraryMixin.java index 4869208c7..695065bcb 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_sounds/SoundBufferLibraryMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_sounds/SoundBufferLibraryMixin.java @@ -26,7 +26,6 @@ public abstract class SoundBufferLibraryMixin { @Shadow @Final @Mutable private Map> cache = CacheBuilder.newBuilder() - .maximumSize(DynamicSoundHelpers.MAX_SOUND_COUNT) .expireAfterAccess(DynamicSoundHelpers.MAX_SOUND_LIFETIME_SECS, TimeUnit.SECONDS) // Excessive use of type hinting due to it assuming Object as the broadest correct type .>removalListener(this::onSoundRemoval) diff --git a/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicSoundHelpers.java b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicSoundHelpers.java index c78646665..fba50c802 100644 --- a/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicSoundHelpers.java +++ b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicSoundHelpers.java @@ -5,10 +5,4 @@ public class DynamicSoundHelpers { * The duration until a sound is eligible for eviction if unused. */ public static final int MAX_SOUND_LIFETIME_SECS = 120; - - /** - * The max amount of sounds loaded - * This was chosen because Minecraft Java can play up to 255 sounds, with a bit of leeway for extra sounds being loaded in. - */ - public static final int MAX_SOUND_COUNT = 300; }