Merge remote-tracking branch 'origin/1.19.2' into 1.19.4

This commit is contained in:
embeddedt 2023-05-05 10:53:30 -04:00
commit 95ee0c60ca
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
7 changed files with 99 additions and 18 deletions

View File

@ -6,7 +6,7 @@ import net.minecraft.client.resources.model.ModelManager;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin; import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.embeddedt.modernfix.dynamicresources.ModelLocationCache; import org.embeddedt.modernfix.dynamicresources.ModelLocationCache;
import org.embeddedt.modernfix.util.DynamicMap; import org.embeddedt.modernfix.util.DynamicOverridableMap;
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;
@ -26,7 +26,7 @@ public class BlockModelShaperMixin {
@Inject(method = { "<init>", "replaceCache" }, at = @At("RETURN")) @Inject(method = { "<init>", "replaceCache" }, at = @At("RETURN"))
private void replaceModelMap(CallbackInfo ci) { private void replaceModelMap(CallbackInfo ci) {
// replace the backing map for mods which will access it // replace the backing map for mods which will access it
this.modelByStateCache = new DynamicMap<>(state -> modelManager.getModel(ModelLocationCache.get(state))); this.modelByStateCache = new DynamicOverridableMap<>(state -> modelManager.getModel(ModelLocationCache.get(state)));
} }
@Overwrite @Overwrite

View File

@ -3,10 +3,13 @@ package org.embeddedt.modernfix.common.mixin.perf.reduce_blockstate_cache_rebuil
import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockBehaviour;
import org.embeddedt.modernfix.duck.IBlockState; import org.embeddedt.modernfix.duck.IBlockState;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Dynamic;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
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.Redirect; import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(BlockBehaviour.BlockStateBase.class) @Mixin(BlockBehaviour.BlockStateBase.class)
@ -23,13 +26,7 @@ public abstract class BlockStateBaseMixin implements IBlockState {
cacheInvalid = true; cacheInvalid = true;
} }
@Redirect(method = "*", at = @At( private BlockBehaviour.BlockStateBase.Cache generateCache(BlockBehaviour.BlockStateBase base) {
value = "FIELD",
opcode = Opcodes.GETFIELD,
target = "Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase;cache:Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase$Cache;",
ordinal = 0
))
private BlockBehaviour.BlockStateBase.Cache initCacheIfNeeded(BlockBehaviour.BlockStateBase base) {
if(cacheInvalid) { if(cacheInvalid) {
// Ensure that only one block's cache is built at a time // Ensure that only one block's cache is built at a time
synchronized (BlockBehaviour.BlockStateBase.class) { synchronized (BlockBehaviour.BlockStateBase.class) {
@ -50,4 +47,32 @@ public abstract class BlockStateBaseMixin implements IBlockState {
} }
return this.cache; return this.cache;
} }
@Redirect(method = "*", at = @At(
value = "FIELD",
opcode = Opcodes.GETFIELD,
target = "Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase;cache:Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase$Cache;",
ordinal = 0
))
private BlockBehaviour.BlockStateBase.Cache dynamicCacheGen(BlockBehaviour.BlockStateBase base) {
return generateCache(base);
}
@Dynamic
@Inject(method = "getPathNodeType", at = @At("HEAD"), require = 0, remap = false)
private void generateCacheLithium(CallbackInfoReturnable<?> cir) {
generateCache((BlockBehaviour.BlockStateBase)(Object)this);
}
@Dynamic
@Inject(method = "getNeighborPathNodeType", at = @At("HEAD"), require = 0, remap = false)
private void generateCacheLithium2(CallbackInfoReturnable<?> cir) {
generateCache((BlockBehaviour.BlockStateBase)(Object)this);
}
@Dynamic
@Inject(method = "getAllFlags", at = @At("HEAD"), require = 0, remap = false)
private void generateCacheLithium3(CallbackInfoReturnable<?> cir) {
generateCache((BlockBehaviour.BlockStateBase)(Object)this);
}
} }

View File

@ -11,6 +11,18 @@ import net.minecraft.world.level.block.state.properties.Property;
import java.util.*; import java.util.*;
public class ModelBakeryHelpers { public class ModelBakeryHelpers {
/**
* The maximum number of baked models kept in memory at once.
*/
public static final int MAX_BAKED_MODEL_COUNT = 10000;
/**
* The maximum number of unbaked models kept in memory at once.
*/
public static final int MAX_UNBAKED_MODEL_COUNT = 10000;
/**
* The time in seconds after which a model becomes eligible for eviction if not used.
*/
public static final int MAX_MODEL_LIFETIME_SECS = 300;
private static <T extends Comparable<T>, V extends T> BlockState setPropertyGeneric(BlockState state, Property<T> prop, Object o) { private static <T extends Comparable<T>, V extends T> BlockState setPropertyGeneric(BlockState state, Property<T> prop, Object o) {
return state.setValue(prop, (V)o); return state.setValue(prop, (V)o);

View File

@ -75,7 +75,9 @@ public class EntityRendererMap implements Map<EntityType<?>, EntityRenderer<?>>
if(renderer == null) if(renderer == null)
throw new AssertionError("Returned entity renderer should never be null"); throw new AssertionError("Returned entity renderer should never be null");
return renderer; return renderer;
} catch(ExecutionException e) { } catch (IllegalStateException e) {
return null; /* emulate value not being present if recursive load occurs */
} catch (ExecutionException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }

View File

@ -0,0 +1,42 @@
package org.embeddedt.modernfix.util;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import java.util.function.Function;
public class DynamicOverridableMap<K, V> extends DynamicMap<K, V> {
private final Map<K, V> overrideMap;
public DynamicOverridableMap(Function<K, V> function) {
super(function);
overrideMap = new Object2ObjectOpenHashMap<>();
}
@Override
public @Nullable V put(K k, V v) {
if(v == null)
throw new IllegalArgumentException();
overrideMap.put(k, v);
return null;
}
@Override
public V get(Object o) {
V val = overrideMap.get(o);
if(val != null)
return val;
return super.get(o);
}
@Override
public void putAll(@NotNull Map<? extends K, ? extends V> map) {
for(V val : map.values()) {
if(val == null)
throw new IllegalArgumentException();
}
overrideMap.putAll(map);
}
}

View File

@ -77,15 +77,15 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery {
this.blockColors = val; this.blockColors = val;
this.ignoreModelLoad = true; this.ignoreModelLoad = true;
this.loadedBakedModels = CacheBuilder.newBuilder() this.loadedBakedModels = CacheBuilder.newBuilder()
.expireAfterAccess(3, TimeUnit.MINUTES) .expireAfterAccess(ModelBakeryHelpers.MAX_MODEL_LIFETIME_SECS, TimeUnit.SECONDS)
.maximumSize(1000) .maximumSize(ModelBakeryHelpers.MAX_BAKED_MODEL_COUNT)
.concurrencyLevel(8) .concurrencyLevel(8)
.removalListener(this::onModelRemoved) .removalListener(this::onModelRemoved)
.softValues() .softValues()
.build(); .build();
this.loadedModels = CacheBuilder.newBuilder() this.loadedModels = CacheBuilder.newBuilder()
.expireAfterAccess(3, TimeUnit.MINUTES) .expireAfterAccess(ModelBakeryHelpers.MAX_MODEL_LIFETIME_SECS, TimeUnit.SECONDS)
.maximumSize(1000) .maximumSize(ModelBakeryHelpers.MAX_UNBAKED_MODEL_COUNT)
.concurrencyLevel(8) .concurrencyLevel(8)
.removalListener(this::onModelRemoved) .removalListener(this::onModelRemoved)
//.softValues() //.softValues()

View File

@ -71,15 +71,15 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery {
private void replaceTopLevelBakedModels(ModelBakery bakery, BlockColors val) { private void replaceTopLevelBakedModels(ModelBakery bakery, BlockColors val) {
this.blockColors = val; this.blockColors = val;
this.loadedBakedModels = CacheBuilder.newBuilder() this.loadedBakedModels = CacheBuilder.newBuilder()
.expireAfterAccess(3, TimeUnit.MINUTES) .expireAfterAccess(ModelBakeryHelpers.MAX_MODEL_LIFETIME_SECS, TimeUnit.SECONDS)
.maximumSize(1000) .maximumSize(ModelBakeryHelpers.MAX_BAKED_MODEL_COUNT)
.concurrencyLevel(8) .concurrencyLevel(8)
.removalListener(this::onModelRemoved) .removalListener(this::onModelRemoved)
.softValues() .softValues()
.build(); .build();
this.loadedModels = CacheBuilder.newBuilder() this.loadedModels = CacheBuilder.newBuilder()
.expireAfterAccess(3, TimeUnit.MINUTES) .expireAfterAccess(ModelBakeryHelpers.MAX_MODEL_LIFETIME_SECS, TimeUnit.SECONDS)
.maximumSize(1000) .maximumSize(ModelBakeryHelpers.MAX_UNBAKED_MODEL_COUNT)
.concurrencyLevel(8) .concurrencyLevel(8)
.removalListener(this::onModelRemoved) .removalListener(this::onModelRemoved)
.softValues() .softValues()