Make mipmap attribution hook not suck and thread-safe (#1967)

This commit is contained in:
Eclipse-Sol authored and GitHub committed 2026-07-27 19:14:19 -07:00
1 parent 4eb837a2c0
commit 5c4ef022d5
2 files changed
+17 -15

No files matched your search

@@ -8,8 +8,10 @@ import net.minecraft.block.BlockLeaves;
import net.minecraft.block.BlockMushroom;
import net.minecraft.block.BlockRedstoneWire;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Fallback {@link MipmapStrategy} assignments for sprites that carry no metadata.
@@ -17,8 +19,8 @@ import java.util.Map;
public final class MipmapStrategies {
private static final Map<Class<?>, MipmapStrategy> CLASS_RULES = new Object2ObjectOpenHashMap<>();
private static final Map<String, MipmapStrategy> SPRITE_RULES = new Object2ObjectOpenHashMap<>();
private static final LinkedList<MipmapStrategy> STRATEGY_STACK = new LinkedList<>();
private static final Map<String, MipmapStrategy> SPRITE_RULES = new ConcurrentHashMap<>();
private static final ThreadLocal<Deque<MipmapStrategy>> STRATEGY_STACK = ThreadLocal.withInitial(LinkedList::new);
static {
CLASS_RULES.put(BlockLeaves.class, MipmapStrategy.DARK_CUTOUT);
@@ -33,16 +35,17 @@ public final class MipmapStrategies {
public static void reset() {
SPRITE_RULES.clear();
STRATEGY_STACK.clear();
STRATEGY_STACK.remove();
}
public static void beginBlock(Block block) {
STRATEGY_STACK.push(resolve(block.getClass()));
STRATEGY_STACK.get().push(resolve(block.getClass()));
}
public static void endBlock() {
if (!STRATEGY_STACK.isEmpty()) {
STRATEGY_STACK.pop();
final Deque<MipmapStrategy> stack = STRATEGY_STACK.get();
if (!stack.isEmpty()) {
stack.pop();
}
}
@@ -51,7 +54,7 @@ public final class MipmapStrategies {
return;
}
MipmapStrategy strategy = STRATEGY_STACK.peek();
MipmapStrategy strategy = STRATEGY_STACK.get().peek();
if (strategy == null && textureType == 0 && iconName.contains("leaves")) {
strategy = MipmapStrategy.DARK_CUTOUT;
}
@@ -59,10 +62,8 @@ public final class MipmapStrategies {
return;
}
final MipmapStrategy existing = SPRITE_RULES.get(iconName);
if (existing == null || strategy.conflictPrecedence() > existing.conflictPrecedence()) {
SPRITE_RULES.put(iconName, strategy);
}
SPRITE_RULES.merge(iconName, strategy,
(existing, incoming) -> incoming.conflictPrecedence() > existing.conflictPrecedence() ? incoming : existing);
}
public static MipmapStrategy inheritedFor(int textureType, String iconName) {
@@ -6,6 +6,8 @@ import com.gtnewhorizons.angelica.rendering.celeritas.TextureMapExtension;
import com.gtnewhorizons.angelica.utils.MipmapStrategies;
import com.gtnewhorizons.angelica.utils.MipmapStrategy;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import me.jellysquid.mods.sodium.client.gui.SodiumGameOptions;
import net.minecraft.block.Block;
@@ -27,7 +29,6 @@ import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@@ -74,15 +75,15 @@ public class MixinTextureMap implements TextureMapExtension {
/**
* Brackets each block's icon registration so the sprites it registers can be attributed to it.
*/
@Redirect(
@WrapOperation(
method = "registerIcons",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/block/Block;registerBlockIcons(Lnet/minecraft/client/renderer/texture/IIconRegister;)V"))
private void angelica$trackBlockIcons(Block block, IIconRegister reg) {
private void angelica$trackBlockIcons(Block block, IIconRegister reg, Operation<Void> original) {
MipmapStrategies.beginBlock(block);
try {
block.registerBlockIcons(reg);
original.call(block, reg);
} finally {
MipmapStrategies.endBlock();
}