Skip to content

Commit 168ab8e

Browse files
committed
Merge remote-tracking branch 'origin/1.20' into 1.21
2 parents 6e9dfaf + 2193aa1 commit 168ab8e

File tree

15 files changed

+379
-39
lines changed

15 files changed

+379
-39
lines changed

annotation-processor/src/main/java/org/fury_phoenix/mixinAp/annotation/MixinProcessor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import javax.lang.model.SourceVersion;
2020
import javax.lang.model.element.Element;
2121
import javax.lang.model.element.TypeElement;
22+
import javax.lang.model.util.Elements;
2223
import javax.tools.Diagnostic;
2324

2425
import org.fury_phoenix.mixinAp.config.MixinConfig;
@@ -80,7 +81,7 @@ private void processMixins(Set<? extends TypeElement> annotations, RoundEnvironm
8081
List<String> mixins =
8182
annotatedMixins.stream()
8283
.map(TypeElement.class::cast)
83-
.map(TypeElement::toString)
84+
.map(e -> processingEnv.getElementUtils().getBinaryName(e).toString())
8485
.collect(Collectors.toList());
8586

8687
mixinConfigList.putIfAbsent(aliases.get(annotation.getSimpleName().toString()), mixins);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package org.embeddedt.modernfix.common.mixin.feature.cause_lag_by_disabling_threads;
2+
3+
import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher;
4+
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
5+
import org.spongepowered.asm.mixin.Mixin;
6+
import org.spongepowered.asm.mixin.injection.At;
7+
import org.spongepowered.asm.mixin.injection.ModifyVariable;
8+
9+
import java.util.concurrent.Executor;
10+
import java.util.concurrent.LinkedBlockingQueue;
11+
import java.util.concurrent.ThreadPoolExecutor;
12+
import java.util.concurrent.TimeUnit;
13+
14+
@Mixin(ChunkRenderDispatcher.class)
15+
@ClientOnlyMixin
16+
public class ChunkRenderDispatcherMixin {
17+
private static final Executor MFIX_CHUNK_BUILD_EXECUTOR = new ThreadPoolExecutor(1, computeNumThreads(), 0L, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
18+
19+
private static int computeNumThreads() {
20+
return Math.max(Math.min(Runtime.getRuntime().availableProcessors() / 4, 10), 1);
21+
}
22+
23+
@ModifyVariable(method = "<init>*", at = @At("HEAD"), ordinal = 0, argsOnly = true)
24+
private static Executor replaceExecutor(Executor old) {
25+
return MFIX_CHUNK_BUILD_EXECUTOR;
26+
}
27+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.embeddedt.modernfix.common.mixin.feature.cause_lag_by_disabling_threads;
2+
3+
import net.minecraft.Util;
4+
import org.embeddedt.modernfix.util.DirectExecutorService;
5+
import org.spongepowered.asm.mixin.Final;
6+
import org.spongepowered.asm.mixin.Mixin;
7+
import org.spongepowered.asm.mixin.Mutable;
8+
import org.spongepowered.asm.mixin.Shadow;
9+
10+
import java.util.concurrent.ExecutorService;
11+
12+
@Mixin(Util.class)
13+
public class UtilMixin {
14+
@Shadow @Final @Mutable
15+
private static final ExecutorService BACKGROUND_EXECUTOR = new DirectExecutorService();
16+
}

common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/BlockModelShaperMixin.java

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package org.embeddedt.modernfix.common.mixin.perf.dynamic_resources;
22

3-
import it.unimi.dsi.fastutil.objects.Reference2ReferenceLinkedOpenHashMap;
43
import net.minecraft.client.renderer.block.BlockModelShaper;
54
import net.minecraft.client.resources.model.BakedModel;
65
import net.minecraft.client.resources.model.ModelManager;
76
import net.minecraft.client.resources.model.ModelResourceLocation;
7+
import net.minecraft.core.registries.BuiltInRegistries;
8+
import net.minecraft.world.level.block.Block;
89
import net.minecraft.world.level.block.state.BlockState;
910
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
11+
import org.embeddedt.modernfix.duck.IModelHoldingBlockState;
1012
import org.embeddedt.modernfix.dynamicresources.ModelLocationCache;
1113
import org.embeddedt.modernfix.util.DynamicOverridableMap;
1214
import org.spongepowered.asm.mixin.*;
@@ -24,13 +26,18 @@ public class BlockModelShaperMixin {
2426
@Shadow
2527
private Map<BlockState, BakedModel> modelByStateCache;
2628

27-
private ThreadLocal<Reference2ReferenceLinkedOpenHashMap<BlockState, BakedModel>> mfix$modelCache = ThreadLocal.withInitial(Reference2ReferenceLinkedOpenHashMap::new);
28-
2929
@Inject(method = { "<init>", "replaceCache" }, at = @At("RETURN"))
3030
private void replaceModelMap(CallbackInfo ci) {
3131
// replace the backing map for mods which will access it
3232
this.modelByStateCache = new DynamicOverridableMap<>(state -> modelManager.getModel(ModelLocationCache.get(state)));
33-
this.mfix$modelCache = ThreadLocal.withInitial(Reference2ReferenceLinkedOpenHashMap::new);
33+
// Clear the cached models on blockstate objects
34+
for(Block block : BuiltInRegistries.BLOCK) {
35+
for(BlockState state : block.getStateDefinition().getPossibleStates()) {
36+
if(state instanceof IModelHoldingBlockState modelHolder) {
37+
modelHolder.mfix$setModel(null);
38+
}
39+
}
40+
}
3441
}
3542

3643
private BakedModel cacheBlockModel(BlockState state) {
@@ -50,18 +57,18 @@ private BakedModel cacheBlockModel(BlockState state) {
5057
*/
5158
@Overwrite
5259
public BakedModel getBlockModel(BlockState state) {
53-
Reference2ReferenceLinkedOpenHashMap<BlockState, BakedModel> map = this.mfix$modelCache.get();
54-
BakedModel model = map.get(state);
60+
if(state instanceof IModelHoldingBlockState modelHolder) {
61+
BakedModel model = modelHolder.mfix$getModel();
5562

56-
if(model != null) {
57-
return model;
58-
}
63+
if(model != null) {
64+
return model;
65+
}
5966

60-
model = this.cacheBlockModel(state);
61-
map.putAndMoveToFirst(state, model);
62-
if(map.size() > 500) {
63-
map.removeLast();
67+
model = this.cacheBlockModel(state);
68+
modelHolder.mfix$setModel(model);
69+
return model;
70+
} else {
71+
return this.cacheBlockModel(state);
6472
}
65-
return model;
6673
}
6774
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package org.embeddedt.modernfix.common.mixin.perf.dynamic_resources;
2+
3+
import net.minecraft.client.resources.model.BakedModel;
4+
import net.minecraft.world.level.block.state.BlockBehaviour;
5+
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
6+
import org.embeddedt.modernfix.duck.IModelHoldingBlockState;
7+
import org.spongepowered.asm.mixin.Mixin;
8+
9+
import java.lang.ref.SoftReference;
10+
11+
@Mixin(BlockBehaviour.BlockStateBase.class)
12+
@ClientOnlyMixin
13+
public class BlockStateBaseMixin implements IModelHoldingBlockState {
14+
private volatile SoftReference<BakedModel> mfix$model;
15+
16+
@Override
17+
public BakedModel mfix$getModel() {
18+
var ref = mfix$model;
19+
return ref != null ? ref.get() : null;
20+
}
21+
22+
@Override
23+
public void mfix$setModel(BakedModel model) {
24+
mfix$model = model != null ? new SoftReference<>(model) : null;
25+
}
26+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package org.embeddedt.modernfix.common.mixin.perf.worldgen_allocation;
2+
3+
import net.minecraft.world.level.block.state.BlockState;
4+
import net.minecraft.world.level.levelgen.DensityFunction;
5+
import net.minecraft.world.level.levelgen.NoiseChunk;
6+
import net.minecraft.world.level.levelgen.material.MaterialRuleList;
7+
import org.jetbrains.annotations.Nullable;
8+
import org.spongepowered.asm.mixin.Final;
9+
import org.spongepowered.asm.mixin.Mixin;
10+
import org.spongepowered.asm.mixin.Overwrite;
11+
import org.spongepowered.asm.mixin.Shadow;
12+
13+
import java.util.List;
14+
15+
@Mixin(value = MaterialRuleList.class, priority = 100)
16+
public class MaterialRuleListMixin {
17+
@Shadow @Final private List<NoiseChunk.BlockStateFiller> materialRuleList;
18+
19+
/**
20+
* @author embeddedt
21+
* @reason Avoid iterator allocation
22+
*/
23+
@Overwrite
24+
@Nullable
25+
public BlockState calculate(DensityFunction.FunctionContext arg) {
26+
BlockState state = null;
27+
int s = this.materialRuleList.size();
28+
for(int i = 0; state == null && i < s; i++) {
29+
NoiseChunk.BlockStateFiller blockStateFiller = this.materialRuleList.get(i);
30+
state = blockStateFiller.calculate(arg);
31+
}
32+
return state;
33+
}
34+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package org.embeddedt.modernfix.common.mixin.perf.worldgen_allocation;
2+
3+
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
4+
import net.minecraft.world.level.levelgen.DensityFunction;
5+
import net.minecraft.world.level.levelgen.NoiseChunk;
6+
import org.spongepowered.asm.mixin.Final;
7+
import org.spongepowered.asm.mixin.Mixin;
8+
import org.spongepowered.asm.mixin.Mutable;
9+
import org.spongepowered.asm.mixin.Overwrite;
10+
import org.spongepowered.asm.mixin.Shadow;
11+
12+
import java.util.Map;
13+
14+
@Mixin(value = NoiseChunk.class, priority = 100)
15+
public abstract class NoiseChunkMixin {
16+
@Shadow @Final @Mutable
17+
private Map<DensityFunction, DensityFunction> wrapped = new Object2ObjectOpenHashMap<>();
18+
19+
@Shadow protected abstract DensityFunction wrapNew(DensityFunction densityFunction);
20+
21+
/**
22+
* @author embeddedt
23+
* @reason Avoid lambda allocation
24+
*/
25+
@Overwrite
26+
protected DensityFunction wrap(DensityFunction unwrapped) {
27+
DensityFunction func = this.wrapped.get(unwrapped);
28+
if (func == null) {
29+
func = this.wrapNew(unwrapped);
30+
this.wrapped.put(unwrapped, func);
31+
}
32+
return func;
33+
}
34+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.embeddedt.modernfix.common.mixin.perf.worldgen_allocation;
2+
3+
import net.minecraft.world.level.block.state.BlockState;
4+
import net.minecraft.world.level.levelgen.SurfaceRules;
5+
import org.spongepowered.asm.mixin.Final;
6+
import org.spongepowered.asm.mixin.Mixin;
7+
import org.spongepowered.asm.mixin.Overwrite;
8+
import org.spongepowered.asm.mixin.Shadow;
9+
10+
import java.util.List;
11+
12+
@Mixin(value = SurfaceRules.SequenceRule.class, priority = 100)
13+
public class SequenceRuleMixin {
14+
@Shadow @Final private List<SurfaceRules.SurfaceRule> rules;
15+
16+
/**
17+
* @author embeddedt
18+
* @reason Avoid iterator allocation
19+
*/
20+
@Overwrite
21+
public BlockState tryApply(int x, int y, int z) {
22+
int s = this.rules.size();
23+
//noinspection ForLoopReplaceableByForEach
24+
for(int i = 0; i < s; i++) {
25+
BlockState state = this.rules.get(i).tryApply(x, y, z);
26+
if(state != null) {
27+
return state;
28+
}
29+
}
30+
return null;
31+
}
32+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package org.embeddedt.modernfix.common.mixin.perf.worldgen_allocation;
2+
3+
import net.minecraft.core.BlockPos;
4+
import net.minecraft.core.Holder;
5+
import net.minecraft.world.level.biome.Biome;
6+
import org.embeddedt.modernfix.world.gen.PositionalBiomeGetter;
7+
import org.spongepowered.asm.mixin.Final;
8+
import org.spongepowered.asm.mixin.Mixin;
9+
import org.spongepowered.asm.mixin.Overwrite;
10+
import org.spongepowered.asm.mixin.Shadow;
11+
12+
import java.util.function.Function;
13+
import java.util.function.Supplier;
14+
15+
@Mixin(targets = {"net/minecraft/world/level/levelgen/SurfaceRules$Context"}, priority = 100)
16+
public class SurfaceRulesContextMixin {
17+
@Shadow private long lastUpdateY;
18+
19+
@Shadow private int blockY;
20+
21+
@Shadow private int waterHeight;
22+
23+
@Shadow private int stoneDepthBelow;
24+
25+
@Shadow private int stoneDepthAbove;
26+
27+
@Shadow private Supplier<Holder<Biome>> biome;
28+
29+
@Shadow @Final private Function<BlockPos, Holder<Biome>> biomeGetter;
30+
31+
@Shadow @Final private BlockPos.MutableBlockPos pos;
32+
33+
/**
34+
* @author embeddedt
35+
* @reason Reuse supplier object instead of creating new ones every time
36+
*/
37+
@Overwrite
38+
protected void updateY(int stoneDepthAbove, int stoneDepthBelow, int waterHeight, int blockX, int blockY, int blockZ) {
39+
++this.lastUpdateY;
40+
var getter = this.biome;
41+
if(getter == null) {
42+
this.biome = getter = new PositionalBiomeGetter(this.biomeGetter, this.pos);
43+
}
44+
((PositionalBiomeGetter)getter).update(blockX, blockY, blockZ);
45+
this.blockY = blockY;
46+
this.waterHeight = waterHeight;
47+
this.stoneDepthBelow = stoneDepthBelow;
48+
this.stoneDepthAbove = stoneDepthAbove;
49+
}
50+
}

common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ else if(isClientOnly && !ModernFixPlatformHooks.INSTANCE.isClient())
139139
mixinOptions.add(mixinCategoryName);
140140
}
141141
} catch(IOException e) {
142-
ModernFix.LOGGER.error("Error scanning file " + mixinPath, e);
142+
LOGGER.error("Error scanning file " + mixinPath, e);
143143
}
144144
}
145145
}
@@ -166,6 +166,7 @@ public DefaultSettingMapBuilder put(String key, Boolean value) {
166166
.put("mixin.feature.stalled_chunk_load_detection", false)
167167
.put("mixin.perf.blast_search_trees.force", false)
168168
.put("mixin.bugfix.restore_old_dragon_movement", false)
169+
.put("mixin.feature.cause_lag_by_disabling_threads", false)
169170
.put("mixin.perf.clear_mixin_classinfo", false)
170171
.put("mixin.perf.deduplicate_climate_parameters", false)
171172
.put("mixin.bugfix.packet_leak", false)

0 commit comments

Comments
 (0)