Tweak model loading
This commit is contained in:
parent
80a4585efd
commit
928d2e3f02
|
|
@ -134,13 +134,13 @@ dependencies {
|
|||
runtimeOnly fg.deobf("curse.maven:lazydfu-460819:${lazydfu_version}")
|
||||
|
||||
compileOnly fg.deobf("mezz.jei:jei-${minecraft_version}:${jei_version}")
|
||||
compileOnly fg.deobf("curse.maven:ferritecore-429235:4074330")
|
||||
|
||||
if(include_optimization_mods.toBoolean()) {
|
||||
runtimeOnly fg.deobf("curse.maven:roadrunner-529754:3683120")
|
||||
runtimeOnly fg.deobf("curse.maven:rubidium-574856:3949659")
|
||||
runtimeOnly fg.deobf("curse.maven:noexperimental-407174:3188120")
|
||||
runtimeOnly fg.deobf("curse.maven:spark-361579:3767277")
|
||||
runtimeOnly fg.deobf("curse.maven:ferritecore-429235:4074330")
|
||||
runtimeOnly fg.deobf("mezz.jei:jei-${minecraft_version}:${jei_version}")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.faster_baking;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.renderer.BlockModelShapes;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.model.ModelManager;
|
||||
import net.minecraft.client.renderer.model.ModelResourceLocation;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
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 java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Mixin(BlockModelShapes.class)
|
||||
public abstract class BlockModelShapesMixin {
|
||||
@Shadow @Final private ModelManager modelManager;
|
||||
|
||||
@Shadow @Final private Map<BlockState, IBakedModel> modelByStateCache;
|
||||
|
||||
/**
|
||||
* @author embeddedt
|
||||
* @reason parallelize cache rebuild
|
||||
*/
|
||||
@Overwrite
|
||||
public void rebuildCache() {
|
||||
this.modelByStateCache.clear();
|
||||
ArrayList<CompletableFuture<Pair<BlockState, IBakedModel>>> futures = new ArrayList<>();
|
||||
for(Block block : Registry.BLOCK) {
|
||||
block.getStateDefinition().getPossibleStates().forEach((state) -> {
|
||||
futures.add(CompletableFuture.supplyAsync(() -> {
|
||||
return Pair.of(state, this.modelManager.getModel(BlockModelShapes.stateToModelLocation(state)));
|
||||
}, Util.backgroundExecutor()));
|
||||
});
|
||||
}
|
||||
for(CompletableFuture<Pair<BlockState, IBakedModel>> future : futures) {
|
||||
Pair<BlockState, IBakedModel> pair = future.join();
|
||||
this.modelByStateCache.put(pair.getFirst(), pair.getSecond());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ import net.minecraftforge.fml.loading.progress.StartupMessageManager;
|
|||
import org.apache.commons.lang3.tuple.Triple;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
import org.embeddedt.modernfix.ModernFixClient;
|
||||
import org.spongepowered.asm.mixin.*;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
|
|
@ -44,16 +45,72 @@ public abstract class ModelBakeryMixin {
|
|||
@Shadow @Final private Map<ResourceLocation, IUnbakedModel> unbakedCache;
|
||||
@Shadow @Mutable
|
||||
@Final private Map<Triple<ResourceLocation, TransformationMatrix, Boolean>, IBakedModel> bakedCache;
|
||||
|
||||
@Shadow @Final private static ItemModelGenerator ITEM_MODEL_GENERATOR;
|
||||
@Shadow @Final public static BlockModel GENERATION_MARKER;
|
||||
|
||||
@Shadow public abstract IUnbakedModel getModel(ResourceLocation p_209597_1_);
|
||||
|
||||
private ConcurrentHashMap<ResourceLocation, IdentityHashMap<IModelTransform, IBakedModel>> fasterBakedCache;
|
||||
|
||||
private Map<Boolean, List<Map.Entry<ResourceLocation, IUnbakedModel>>> modelsToBakeParallel;
|
||||
|
||||
private boolean canBakeParallel(IUnbakedModel unbakedModel) {
|
||||
if(unbakedModel instanceof BlockModel) {
|
||||
BlockModel model = (BlockModel)unbakedModel;
|
||||
return !model.customData.hasCustomGeometry();
|
||||
} else
|
||||
} else if((unbakedModel instanceof Multipart) || (unbakedModel instanceof VariantList))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
private IBakedModel bakeModel(ResourceLocation pLocation, IModelTransform pTransform, java.util.function.Function<RenderMaterial, net.minecraft.client.renderer.texture.TextureAtlasSprite> textureGetter) {
|
||||
IUnbakedModel iunbakedmodel = this.unbakedCache.get(pLocation);
|
||||
if(iunbakedmodel == null)
|
||||
throw new IllegalStateException("we should not be baking unloaded models");
|
||||
if (iunbakedmodel instanceof BlockModel) {
|
||||
BlockModel blockmodel = (BlockModel)iunbakedmodel;
|
||||
if (blockmodel.getRootModel() == GENERATION_MARKER) {
|
||||
return ITEM_MODEL_GENERATOR.generateBlockModel(textureGetter, blockmodel).bake((ModelBakery)(Object)this, blockmodel, this.atlasSet::getSprite, pTransform, pLocation, false);
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure only one thread builds at a time if needed */
|
||||
if(canBakeParallel(iunbakedmodel)) {
|
||||
return iunbakedmodel.bake((ModelBakery)(Object)this, textureGetter, pTransform, pLocation);
|
||||
} else {
|
||||
synchronized(this.bakedCache) {
|
||||
return iunbakedmodel.bake((ModelBakery)(Object)this, textureGetter, pTransform, pLocation);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @author embeddedt
|
||||
* @reason avoid rehashing model data when unneeded
|
||||
*/
|
||||
@Overwrite(remap = false)
|
||||
public IBakedModel getBakedModel(ResourceLocation pLocation, IModelTransform pTransform, java.util.function.Function<RenderMaterial, net.minecraft.client.renderer.texture.TextureAtlasSprite> textureGetter) {
|
||||
/* Try to retrieve the model */
|
||||
IdentityHashMap<IModelTransform, IBakedModel> modelsForLocation = this.fasterBakedCache.computeIfAbsent(pLocation, loc -> new IdentityHashMap<>());
|
||||
synchronized (modelsForLocation) {
|
||||
IBakedModel result = modelsForLocation.get(pTransform);
|
||||
if(result != null)
|
||||
return result;
|
||||
}
|
||||
/* Otherwise, bake the model and then store it */
|
||||
synchronized(this.unbakedCache) {
|
||||
this.getModel(pLocation);
|
||||
}
|
||||
IBakedModel result = bakeModel(pLocation, pTransform, textureGetter);
|
||||
synchronized (modelsForLocation) {
|
||||
modelsForLocation.put(pTransform, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@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");
|
||||
|
|
@ -67,7 +124,8 @@ public abstract class ModelBakeryMixin {
|
|||
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.bakedCache = new ConcurrentHashMap<>();
|
||||
this.bakedCache = Collections.emptyMap();
|
||||
this.fasterBakedCache = new ConcurrentHashMap<>();
|
||||
this.modelsToBakeParallel = this.unbakedCache.entrySet().stream()
|
||||
.collect(Collectors.partitioningBy(entry -> {
|
||||
IUnbakedModel unbakedModel = entry.getValue();
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import net.minecraft.util.ResourceLocation;
|
|||
import net.minecraft.util.Util;
|
||||
import net.minecraft.util.math.vector.TransformationMatrix;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
import org.embeddedt.modernfix.util.AsyncStopwatch;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
|
|
@ -64,6 +65,7 @@ public abstract class ModelBakeryMixin {
|
|||
|
||||
@Inject(method = "processLoading", at = @At(value = "INVOKE", target = "Lnet/minecraft/profiler/IProfiler;popPush(Ljava/lang/String;)V", ordinal = 0))
|
||||
private void preloadJsonModels(IProfiler profilerIn, int maxMipmapLevel, CallbackInfo ci) {
|
||||
StartupMessageManager.mcLoaderConsumer().ifPresent(c -> c.accept("Loading models"));
|
||||
profilerIn.popPush("loadblockstates");
|
||||
AsyncStopwatch.measureAndLogSerialRunningTime("Parallel blockstate loading", () -> {
|
||||
ThreadLocal<BlockModelDefinition.ContainerHolder> containerHolder = ThreadLocal.withInitial(BlockModelDefinition.ContainerHolder::new);
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
"perf.blast_search_trees.MinecraftMixin",
|
||||
"perf.blast_search_trees.IngredientFilterInvoker",
|
||||
"perf.faster_baking.ModelBakeryMixin",
|
||||
"perf.faster_baking.BlockModelShapesMixin",
|
||||
"perf.cache_model_materials.VanillaModelMixin",
|
||||
"perf.cache_model_materials.MultipartMixin",
|
||||
"bugfix.packet_leak.ClientPlayNetHandlerMixin",
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user