From 5ccdb4c1657bcd33101a3c42fc15323cf629c6f8 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Mon, 10 Apr 2023 11:49:12 -0400 Subject: [PATCH 1/2] Don't count render ticks until recipes and tags are sent --- .../embeddedt/modernfix/ModernFixClient.java | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/embeddedt/modernfix/ModernFixClient.java b/src/main/java/org/embeddedt/modernfix/ModernFixClient.java index 148ac4d7..3247ea38 100644 --- a/src/main/java/org/embeddedt/modernfix/ModernFixClient.java +++ b/src/main/java/org/embeddedt/modernfix/ModernFixClient.java @@ -9,12 +9,10 @@ import net.minecraft.client.gui.screens.TitleScreen; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.world.entity.Entity; -import net.minecraftforge.client.event.ClientPlayerNetworkEvent; -import net.minecraftforge.client.event.GuiOpenEvent; -import net.minecraftforge.client.event.GuiScreenEvent; -import net.minecraftforge.client.event.RenderGameOverlayEvent; +import net.minecraftforge.client.event.*; import net.minecraftforge.client.gui.ForgeIngameGui; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.TagsUpdatedEvent; import net.minecraftforge.event.TickEvent; import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.eventbus.api.EventPriority; @@ -40,6 +38,8 @@ public class ModernFixClient { public static float gameStartTimeSeconds = -1; + private static boolean recipesUpdated, tagsUpdated = false; + private String brandingString = null; public ModernFixClient() { @@ -58,6 +58,8 @@ public class ModernFixClient { public void resetWorldLoadStateMachine() { numRenderTicks = 0; worldLoadStartTime = -1; + recipesUpdated = false; + tagsUpdated = false; } @SubscribeEvent(priority = EventPriority.LOWEST) @@ -70,9 +72,25 @@ public class ModernFixClient { } } + @SubscribeEvent(priority = EventPriority.LOW) + public void onRecipesUpdated(RecipesUpdatedEvent event) { + recipesUpdated = true; + } + + @SubscribeEvent(priority = EventPriority.LOW) + public void onTagsUpdated(TagsUpdatedEvent event) { + tagsUpdated = true; + } + @SubscribeEvent public void onRenderTickEnd(TickEvent.RenderTickEvent event) { - if(event.phase == TickEvent.Phase.END && !(Minecraft.getInstance().screen instanceof DeferredLevelLoadingScreen) && worldLoadStartTime != -1 && Minecraft.getInstance().player != null && numRenderTicks++ >= 10) { + if(event.phase == TickEvent.Phase.END + && recipesUpdated + && tagsUpdated + && !(Minecraft.getInstance().screen instanceof DeferredLevelLoadingScreen) + && worldLoadStartTime != -1 + && Minecraft.getInstance().player != null + && numRenderTicks++ >= 10) { float timeSpentLoading = ((float)(System.nanoTime() - worldLoadStartTime) / 1000000000f); ModernFix.LOGGER.warn("Time from main menu to in-game was " + timeSpentLoading + " seconds"); ModernFix.LOGGER.warn("Total time to load game and open world was " + (timeSpentLoading + gameStartTimeSeconds) + " seconds"); From 6374d90d4a03a56a0b6077272df151184d375c9c Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Mon, 10 Apr 2023 15:58:12 -0400 Subject: [PATCH 2/2] Properly hold onto unbaked models as they are loaded --- .../dynamic_resources/ModelBakeryMixin.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ModelBakeryMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ModelBakeryMixin.java index a4784a9b..e81e8733 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ModelBakeryMixin.java +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ModelBakeryMixin.java @@ -92,6 +92,8 @@ public abstract class ModelBakeryMixin { private Cache, BakedModel> loadedBakedModels; private Cache loadedModels; + private HashMap smallLoadingCache = new HashMap<>(); + @Inject(method = "(Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/client/color/block/BlockColors;Z)V", at = @At("RETURN")) private void replaceTopLevelBakedModels(ResourceManager manager, BlockColors colors, boolean vanillaBakery, CallbackInfo ci) { @@ -230,6 +232,11 @@ public abstract class ModelBakeryMixin { return unbakedCache.get(rl); } + @Inject(method = "cacheAndQueueDependencies", at = @At("RETURN")) + private void addToSmallLoadingCache(ResourceLocation location, UnbakedModel model, CallbackInfo ci) { + smallLoadingCache.put(location, model); + } + /** * @author embeddedt @@ -258,21 +265,27 @@ public abstract class ModelBakeryMixin { if(debugDynamicModelLoading) LOGGER.info("Loading {}", resourcelocation); this.loadModel(resourcelocation); - // TODO: in theory the cache can get evicted right here and we lose the model - // very unlikely to occur though } } catch (ModelBakery.BlockStateDefinitionException var9) { LOGGER.warn(var9.getMessage()); this.unbakedCache.put(resourcelocation, iunbakedmodel); + smallLoadingCache.put(resourcelocation, iunbakedmodel); } catch (Exception var10) { LOGGER.warn("Unable to load model: '{}' referenced from: {}: {}", resourcelocation, modelLocation, var10); this.unbakedCache.put(resourcelocation, iunbakedmodel); + smallLoadingCache.put(resourcelocation, iunbakedmodel); } finally { this.loadingStack.remove(resourcelocation); } } - return this.unbakedCache.getOrDefault(modelLocation, iunbakedmodel); + // We have to get the result from the temporary cache used for a model load + // As in pathological cases (e.g. Pedestals on 1.19) unbakedCache can lose + // the model immediately + UnbakedModel result = smallLoadingCache.getOrDefault(modelLocation, iunbakedmodel); + // We are done with loading, so clear this cache to allow GC of any unneeded models + smallLoadingCache.clear(); + return result; } } }