Implement parallel baking for vanilla models
This commit is contained in:
parent
0111a8e2ec
commit
6ebc3bbe03
|
|
@ -3,15 +3,19 @@ package org.embeddedt.modernfix.mixin.perf.faster_baking;
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.model.*;
|
import net.minecraft.client.renderer.model.*;
|
||||||
|
import net.minecraft.client.renderer.model.multipart.Multipart;
|
||||||
|
import net.minecraft.client.renderer.model.multipart.Selector;
|
||||||
import net.minecraft.client.renderer.texture.AtlasTexture;
|
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||||
import net.minecraft.client.renderer.texture.SpriteMap;
|
import net.minecraft.client.renderer.texture.SpriteMap;
|
||||||
import net.minecraft.client.renderer.texture.TextureManager;
|
import net.minecraft.client.renderer.texture.TextureManager;
|
||||||
import net.minecraft.profiler.IProfiler;
|
import net.minecraft.profiler.IProfiler;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.Util;
|
||||||
import net.minecraft.util.math.vector.TransformationMatrix;
|
import net.minecraft.util.math.vector.TransformationMatrix;
|
||||||
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
|
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
|
||||||
import org.apache.commons.lang3.tuple.Triple;
|
import org.apache.commons.lang3.tuple.Triple;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.embeddedt.modernfix.ModernFix;
|
||||||
import org.spongepowered.asm.mixin.*;
|
import org.spongepowered.asm.mixin.*;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
|
@ -40,17 +44,14 @@ public abstract class ModelBakeryMixin {
|
||||||
@Shadow @Final private Map<ResourceLocation, IUnbakedModel> unbakedCache;
|
@Shadow @Final private Map<ResourceLocation, IUnbakedModel> unbakedCache;
|
||||||
@Shadow @Mutable
|
@Shadow @Mutable
|
||||||
@Final private Map<Triple<ResourceLocation, TransformationMatrix, Boolean>, IBakedModel> bakedCache;
|
@Final private Map<Triple<ResourceLocation, TransformationMatrix, Boolean>, IBakedModel> bakedCache;
|
||||||
private Map<Boolean, List<ResourceLocation>> modelsToBakeParallel;
|
private Map<Boolean, List<Map.Entry<ResourceLocation, IUnbakedModel>>> modelsToBakeParallel;
|
||||||
|
|
||||||
private boolean canBakeParallel(IUnbakedModel unbakedModel) {
|
private boolean canBakeParallel(IUnbakedModel unbakedModel) {
|
||||||
if(!(unbakedModel instanceof BlockModel))
|
if(unbakedModel instanceof BlockModel) {
|
||||||
return false;
|
|
||||||
else {
|
|
||||||
BlockModel model = (BlockModel)unbakedModel;
|
BlockModel model = (BlockModel)unbakedModel;
|
||||||
if(model.customData.hasCustomGeometry())
|
return !model.customData.hasCustomGeometry();
|
||||||
return false;
|
} else
|
||||||
return true;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "processLoading", at = @At(value = "INVOKE", target = "Lnet/minecraft/profiler/IProfiler;pop()V"))
|
@Inject(method = "processLoading", at = @At(value = "INVOKE", target = "Lnet/minecraft/profiler/IProfiler;pop()V"))
|
||||||
|
|
@ -67,33 +68,59 @@ public abstract class ModelBakeryMixin {
|
||||||
StartupMessageManager.mcLoaderConsumer().ifPresent(c -> c.accept("Baking models"));
|
StartupMessageManager.mcLoaderConsumer().ifPresent(c -> c.accept("Baking models"));
|
||||||
this.atlasSet = new SpriteMap(this.atlasPreparations.values().stream().map(Pair::getFirst).collect(Collectors.toList()));
|
this.atlasSet = new SpriteMap(this.atlasPreparations.values().stream().map(Pair::getFirst).collect(Collectors.toList()));
|
||||||
this.bakedCache = new ConcurrentHashMap<>();
|
this.bakedCache = new ConcurrentHashMap<>();
|
||||||
this.modelsToBakeParallel = this.topLevelModels.keySet().stream()
|
this.modelsToBakeParallel = this.unbakedCache.entrySet().stream()
|
||||||
.collect(Collectors.partitioningBy(location -> {
|
.collect(Collectors.partitioningBy(entry -> {
|
||||||
//IUnbakedModel unbakedModel = this.unbakedCache.get(location);
|
IUnbakedModel unbakedModel = entry.getValue();
|
||||||
return false;
|
|
||||||
/*
|
|
||||||
if(unbakedModel == null)
|
if(unbakedModel == null)
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
return this.canBakeParallel(unbakedModel);
|
return this.canBakeParallel(unbakedModel);
|
||||||
*/
|
|
||||||
}));
|
}));
|
||||||
List<ResourceLocation> parallelModels = this.modelsToBakeParallel.get(false);
|
List<Map.Entry<ResourceLocation, IUnbakedModel>> serialModels = this.modelsToBakeParallel.get(false);
|
||||||
List<CompletableFuture<Void>> futures = new ArrayList<>();
|
List<Map.Entry<ResourceLocation, IUnbakedModel>> parallelModels = this.modelsToBakeParallel.get(true);
|
||||||
parallelModels.forEach((p_229350_1_) -> {
|
ModernFix.LOGGER.debug("Collected "
|
||||||
|
+ serialModels.size()
|
||||||
|
+ " serial models, "
|
||||||
|
+ parallelModels.size()
|
||||||
|
+ " parallel models");
|
||||||
|
List<CompletableFuture<Pair<ResourceLocation, IBakedModel>>> futures = new ArrayList<>();
|
||||||
|
/* First submit the parallel models */
|
||||||
|
for(Map.Entry<ResourceLocation, IUnbakedModel> entry : parallelModels) {
|
||||||
|
ResourceLocation loc = entry.getKey();
|
||||||
|
futures.add(CompletableFuture.supplyAsync(() -> {
|
||||||
|
IBakedModel ibakedmodel = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
ibakedmodel = this.bake(loc, ModelRotation.X0_Y0);
|
||||||
|
} catch (Exception exception) {
|
||||||
|
exception.printStackTrace();
|
||||||
|
LOGGER.warn("Unable to bake model: '{}': {}", loc, exception);
|
||||||
|
}
|
||||||
|
return ibakedmodel != null ? Pair.of(loc, ibakedmodel) : null;
|
||||||
|
}, Util.backgroundExecutor()));
|
||||||
|
}
|
||||||
|
futures.forEach(future -> {
|
||||||
|
Pair<ResourceLocation, IBakedModel> pair = future.join();
|
||||||
|
if(pair != null && this.topLevelModels.containsKey(pair.getFirst()))
|
||||||
|
this.bakedTopLevelModels.put(pair.getFirst(), pair.getSecond());
|
||||||
|
});
|
||||||
|
/* Then process serial models */
|
||||||
|
serialModels.forEach((p_229350_1_) -> {
|
||||||
IBakedModel ibakedmodel = null;
|
IBakedModel ibakedmodel = null;
|
||||||
|
ResourceLocation loc = p_229350_1_.getKey();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ibakedmodel = this.bake(p_229350_1_, ModelRotation.X0_Y0);
|
ibakedmodel = this.bake(loc, ModelRotation.X0_Y0);
|
||||||
} catch (Exception exception) {
|
} catch (Exception exception) {
|
||||||
exception.printStackTrace();
|
exception.printStackTrace();
|
||||||
LOGGER.warn("Unable to bake model: '{}': {}", p_229350_1_, exception);
|
LOGGER.warn("Unable to bake model: '{}': {}", loc, exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ibakedmodel != null) {
|
if (ibakedmodel != null) {
|
||||||
this.bakedTopLevelModels.put(p_229350_1_, ibakedmodel);
|
this.bakedTopLevelModels.put(loc, ibakedmodel);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.modelsToBakeParallel = null;
|
||||||
this.atlasSet = null;
|
this.atlasSet = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,25 +140,6 @@ public abstract class ModelBakeryMixin {
|
||||||
atlastexture.updateFilter(atlastexture$sheetdata);
|
atlastexture.updateFilter(atlastexture$sheetdata);
|
||||||
}
|
}
|
||||||
this.atlasSet = new SpriteMap(this.atlasPreparations.values().stream().map(Pair::getFirst).collect(Collectors.toList()));
|
this.atlasSet = new SpriteMap(this.atlasPreparations.values().stream().map(Pair::getFirst).collect(Collectors.toList()));
|
||||||
/*
|
|
||||||
StartupMessageManager.mcLoaderConsumer().ifPresent(c -> c.accept("Baking incompatible models"));
|
|
||||||
List<ResourceLocation> 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();
|
pProfiler.pop();
|
||||||
return this.atlasSet;
|
return this.atlasSet;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user