Skip to content

Commit 74a339b

Browse files
committed
Add more locking in various vanilla model loading paths
1 parent 6706656 commit 74a339b

File tree

5 files changed

+79
-6
lines changed

5 files changed

+79
-6
lines changed

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

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

33
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
4+
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
5+
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
6+
import net.minecraft.client.resources.model.BakedModel;
47
import net.minecraft.client.resources.model.ModelBakery;
8+
import net.minecraft.client.resources.model.ModelState;
59
import net.minecraft.client.resources.model.UnbakedModel;
610
import net.minecraft.resources.ResourceLocation;
711
import org.embeddedt.modernfix.ModernFix;
812
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
13+
import org.embeddedt.modernfix.duck.IExtendedModelBakery;
14+
import org.spongepowered.asm.mixin.Final;
915
import org.spongepowered.asm.mixin.Mixin;
1016
import org.spongepowered.asm.mixin.Shadow;
1117
import org.spongepowered.asm.mixin.Unique;
@@ -16,6 +22,7 @@
1622
public abstract class ModelBakerImplMixin {
1723
@Shadow public abstract UnbakedModel getModel(ResourceLocation location);
1824

25+
@Shadow @Final private ModelBakery field_40571;
1926
@Unique
2027
private int mfix$getDepth = 0;
2128

@@ -36,4 +43,15 @@ private UnbakedModel resolveParents(UnbakedModel model) {
3643
mfix$getDepth--;
3744
return model;
3845
}
46+
47+
@WrapMethod(method = "bake(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/client/resources/model/ModelState;)Lnet/minecraft/client/resources/model/BakedModel;")
48+
private BakedModel mfix$lockWhenBaking(ResourceLocation location, ModelState transform, Operation<BakedModel> original) {
49+
var lock = ((IExtendedModelBakery)this.field_40571).mfix$getLock();
50+
lock.lock();
51+
try {
52+
return original.call(location, transform);
53+
} finally {
54+
lock.unlock();
55+
}
56+
}
3957
}

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

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

33
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
4+
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
45
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
56
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
67
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
@@ -108,6 +109,16 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery {
108109
}
109110
}
110111

112+
@WrapMethod(method = "getModel")
113+
private UnbakedModel mfix$lockWhenGettingModel(ResourceLocation modelLocation, Operation<UnbakedModel> original) {
114+
modelBakeryLock.lock();
115+
try {
116+
return original.call(modelLocation);
117+
} finally {
118+
modelBakeryLock.unlock();
119+
}
120+
}
121+
111122
@Override
112123
public UnbakedModel mfix$getMissingModel() {
113124
return missingModel;
@@ -199,10 +210,26 @@ private void onInitialLoadFinish(BlockColors blockColors, ProfilerFiller profile
199210
private static final int MAXIMUM_CACHE_SIZE = 1000;
200211

201212
private void runCleanup() {
202-
((LRUMap<?, ?>)this.unbakedCache).dropEntriesToMeetSize(MAXIMUM_CACHE_SIZE);
203-
((LRUMap<?, ?>)this.bakedCache).dropEntriesToMeetSize(MAXIMUM_CACHE_SIZE);
204-
((LRUMap<?, ?>)this.topLevelModels).dropEntriesToMeetSize(MAXIMUM_CACHE_SIZE);
205-
((LRUMap<?, ?>)this.bakedTopLevelModels).dropEntriesToMeetSize(MAXIMUM_CACHE_SIZE);
213+
try {
214+
((LRUMap<?, ?>)this.unbakedCache).dropEntriesToMeetSize(MAXIMUM_CACHE_SIZE);
215+
} catch(RuntimeException e) {
216+
throw new IllegalStateException("Exception dropping entries in unbaked cache", e);
217+
}
218+
try {
219+
((LRUMap<?, ?>)this.bakedCache).dropEntriesToMeetSize(MAXIMUM_CACHE_SIZE);
220+
} catch(RuntimeException e) {
221+
throw new IllegalStateException("Exception dropping entries in baked cache", e);
222+
}
223+
try {
224+
((LRUMap<?, ?>)this.topLevelModels).dropEntriesToMeetSize(MAXIMUM_CACHE_SIZE);
225+
} catch(RuntimeException e) {
226+
throw new IllegalStateException("Exception dropping entries in top level models", e);
227+
}
228+
try {
229+
((LRUMap<?, ?>)this.bakedTopLevelModels).dropEntriesToMeetSize(MAXIMUM_CACHE_SIZE);
230+
} catch(RuntimeException e) {
231+
throw new IllegalStateException("Exception dropping entries in baked top level models", e);
232+
}
206233
}
207234

208235
@Override
@@ -235,4 +262,9 @@ private void runCleanup() {
235262
public Map<ModelResourceLocation, BakedModel> getBakedTopLevelModels() {
236263
return this.mfix$emulatedBakedRegistry;
237264
}
265+
266+
@Override
267+
public ReentrantLock mfix$getLock() {
268+
return this.modelBakeryLock;
269+
}
238270
}

common/src/main/java/org/embeddedt/modernfix/duck/IExtendedModelBakery.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
import net.minecraft.client.resources.model.ModelResourceLocation;
44
import net.minecraft.client.resources.model.UnbakedModel;
55

6+
import java.util.concurrent.locks.ReentrantLock;
7+
68
public interface IExtendedModelBakery {
79
void mfix$tick();
810
void mfix$finishLoading();
911
UnbakedModel mfix$loadUnbakedModelDynamic(ModelResourceLocation location);
1012
UnbakedModel mfix$getMissingModel();
13+
ReentrantLock mfix$getLock();
1114
}

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ mixinextras_version=0.4.1
77
mod_id=modernfix
88
minecraft_version=1.21.1
99
enabled_platforms=fabric,neoforge
10-
forge_version=21.1.15
10+
forge_version=21.1.111
1111
parchment_version=2024.07.07
1212
parchment_mc_version=1.21
1313
refined_storage_version=4392788

neoforge/src/main/java/org/embeddedt/modernfix/neoforge/mixin/perf/dynamic_resources/ModelBakerImplMixin.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
package org.embeddedt.modernfix.neoforge.mixin.perf.dynamic_resources;
22

3+
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
4+
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
5+
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
6+
import net.minecraft.client.resources.model.BakedModel;
7+
import net.minecraft.client.resources.model.Material;
38
import net.minecraft.client.resources.model.ModelBakery;
49
import net.minecraft.client.resources.model.ModelResourceLocation;
10+
import net.minecraft.client.resources.model.ModelState;
511
import net.minecraft.client.resources.model.UnbakedModel;
12+
import net.minecraft.resources.ResourceLocation;
613
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
714
import org.embeddedt.modernfix.duck.IExtendedModelBakery;
815
import org.spongepowered.asm.mixin.Final;
916
import org.spongepowered.asm.mixin.Mixin;
1017
import org.spongepowered.asm.mixin.Overwrite;
1118
import org.spongepowered.asm.mixin.Shadow;
1219

13-
@Mixin(targets = {"net/minecraft/client/resources/model/ModelBakery$ModelBakerImpl"})
20+
import java.util.function.Function;
21+
22+
@Mixin(ModelBakery.ModelBakerImpl.class)
1423
@ClientOnlyMixin
1524
public class ModelBakerImplMixin {
1625
@Shadow @Final private ModelBakery field_40571;
@@ -25,4 +34,15 @@ public UnbakedModel getTopLevelModel(ModelResourceLocation location) {
2534
UnbakedModel model = bakery.mfix$loadUnbakedModelDynamic(location);
2635
return model == bakery.mfix$getMissingModel() ? null : model;
2736
}
37+
38+
@WrapMethod(method = "bake(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/client/resources/model/ModelState;Ljava/util/function/Function;)Lnet/minecraft/client/resources/model/BakedModel;", remap = false)
39+
private BakedModel mfix$lockWhenBaking(ResourceLocation location, ModelState transform, Function<Material, TextureAtlasSprite> textureGetter, Operation<BakedModel> original) {
40+
var lock = ((IExtendedModelBakery)this.field_40571).mfix$getLock();
41+
lock.lock();
42+
try {
43+
return original.call(location, transform, textureGetter);
44+
} finally {
45+
lock.unlock();
46+
}
47+
}
2848
}

0 commit comments

Comments
 (0)