diff --git a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java b/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java index 03b6d2e4..23f20bd1 100644 --- a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java +++ b/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java @@ -39,6 +39,7 @@ public class ModernFixEarlyConfig { this.addMixinRule("perf.flatten_model_predicates", true); this.addMixinRule("perf.deduplicate_location", true); this.addMixinRule("perf.cache_blockstate_cache_arrays", true); + this.addMixinRule("perf.faster_baking", true); /* Keep this off if JEI isn't installed to prevent breaking vanilla gameplay */ this.addMixinRule("perf.blast_search_trees", FMLLoader.getLoadingModList().getModFileById("jei") != null); this.addMixinRule("safety", true); diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_baking/ModelBakeryMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_baking/ModelBakeryMixin.java new file mode 100644 index 00000000..addf1256 --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/faster_baking/ModelBakeryMixin.java @@ -0,0 +1,126 @@ +package org.embeddedt.modernfix.mixin.perf.faster_baking; + +import com.mojang.datafixers.util.Pair; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.model.*; +import net.minecraft.client.renderer.texture.AtlasTexture; +import net.minecraft.client.renderer.texture.SpriteMap; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.profiler.IProfiler; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.loading.progress.StartupMessageManager; +import org.apache.logging.log4j.Logger; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import javax.annotation.Nullable; +import java.util.*; +import java.util.stream.Collectors; + +@Mixin(ModelBakery.class) +public abstract class ModelBakeryMixin { + @Shadow @Final private Map topLevelModels; + + @Shadow @Final private Map bakedTopLevelModels; + + @Shadow @Deprecated @Nullable public abstract IBakedModel bake(ResourceLocation pLocation, IModelTransform pTransform); + + @Shadow @Final private static Logger LOGGER; + + @Shadow private Map> atlasPreparations; + + @Shadow @Nullable private SpriteMap atlasSet; + + @Shadow @Final private Map unbakedCache; + private Map> modelsToBakeParallel; + + private boolean canBakeParallel(IUnbakedModel unbakedModel) { + return false; + } + + @Inject(method = "processLoading", at = @At(value = "INVOKE", target = "Lnet/minecraft/profiler/IProfiler;pop()V")) + private void bakeModels(IProfiler pProfiler, int p_i226056_4_, CallbackInfo ci) { + pProfiler.popPush("atlas"); + Minecraft.getInstance().executeBlocking(() -> { + for(Pair pair : this.atlasPreparations.values()) { + AtlasTexture atlastexture = pair.getFirst(); + AtlasTexture.SheetData atlastexture$sheetdata = pair.getSecond(); + atlastexture.reload(atlastexture$sheetdata); + } + }); + pProfiler.popPush("baking"); + StartupMessageManager.mcLoaderConsumer().ifPresent(c -> c.accept("Baking models")); + this.atlasSet = new SpriteMap(this.atlasPreparations.values().stream().map(Pair::getFirst).collect(Collectors.toList())); + this.modelsToBakeParallel = this.topLevelModels.keySet().stream() + .collect(Collectors.partitioningBy(location -> { + return true; + /* + IUnbakedModel unbakedModel = this.unbakedCache.get(location); + if(unbakedModel == null) + return false; + else + return this.canBakeParallel(unbakedModel); + */ + })); + List parallelModels = this.modelsToBakeParallel.get(true); + parallelModels.forEach((p_229350_1_) -> { + IBakedModel ibakedmodel = null; + + try { + ibakedmodel = this.bake(p_229350_1_, ModelRotation.X0_Y0); + } catch (Exception exception) { + exception.printStackTrace(); + LOGGER.warn("Unable to bake model: '{}': {}", p_229350_1_, exception); + } + + if (ibakedmodel != null) { + this.bakedTopLevelModels.put(p_229350_1_, ibakedmodel); + } + }); + this.atlasSet = null; + } + + /** + * @author embeddedt + * @reason texture loading and baking are moved earlier in the launch process, only render thread stuff is done here + */ + @Overwrite + public SpriteMap uploadTextures(TextureManager pResourceManager, IProfiler pProfiler) { + pProfiler.push("atlas_upload"); + + for(Pair pair : this.atlasPreparations.values()) { + AtlasTexture atlastexture = pair.getFirst(); + AtlasTexture.SheetData atlastexture$sheetdata = pair.getSecond(); + pResourceManager.register(atlastexture.location(), atlastexture); + pResourceManager.bind(atlastexture.location()); + atlastexture.updateFilter(atlastexture$sheetdata); + } + this.atlasSet = new SpriteMap(this.atlasPreparations.values().stream().map(Pair::getFirst).collect(Collectors.toList())); + /* + StartupMessageManager.mcLoaderConsumer().ifPresent(c -> c.accept("Baking incompatible models")); + List serialModels = this.modelsToBakeParallel.get(false); + serialModels.forEach((p_229350_1_) -> { + IBakedModel ibakedmodel = null; + + try { + ibakedmodel = this.bake(p_229350_1_, ModelRotation.X0_Y0); + } catch (Exception exception) { + exception.printStackTrace(); + LOGGER.warn("Unable to bake model: '{}': {}", p_229350_1_, exception); + } + + if (ibakedmodel != null) { + this.bakedTopLevelModels.put(p_229350_1_, ibakedmodel); + } + }); + */ + this.modelsToBakeParallel = null; + pProfiler.pop(); + return this.atlasSet; + } +} diff --git a/src/main/resources/modernfix.mixins.json b/src/main/resources/modernfix.mixins.json index a0de7eb9..95f0518f 100644 --- a/src/main/resources/modernfix.mixins.json +++ b/src/main/resources/modernfix.mixins.json @@ -48,7 +48,8 @@ "perf.flatten_model_predicates.OrConditionMixin", "perf.flatten_model_predicates.PropertyValueConditionMixin", "perf.blast_search_trees.MinecraftMixin", - "perf.blast_search_trees.IngredientFilterInvoker" + "perf.blast_search_trees.IngredientFilterInvoker", + "perf.faster_baking.ModelBakeryMixin" ], "injectors": { "defaultRequire": 1