diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/texture/SpriteContentsExtension.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/texture/SpriteContentsExtension.java index 8a5364d885..567dc3a87d 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/texture/SpriteContentsExtension.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/texture/SpriteContentsExtension.java @@ -5,4 +5,6 @@ public interface SpriteContentsExtension { boolean sodium$isActive(); boolean sodium$hasAnimation(); + + void sodium$setTicker(TextureAtlasSpriteTickerExtension ticker); } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/texture/SpriteContentsTickerExtension.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/texture/SpriteContentsTickerExtension.java new file mode 100644 index 0000000000..1599ad2b99 --- /dev/null +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/texture/SpriteContentsTickerExtension.java @@ -0,0 +1,7 @@ +package net.caffeinemc.mods.sodium.client.render.texture; + +import net.minecraft.resources.ResourceLocation; + +public interface SpriteContentsTickerExtension { + void sodium$ensureUpload(ResourceLocation atlas, int x, int y); +} diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/texture/TextureAtlasSpriteTickerExtension.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/texture/TextureAtlasSpriteTickerExtension.java new file mode 100644 index 0000000000..09f7270f7c --- /dev/null +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/texture/TextureAtlasSpriteTickerExtension.java @@ -0,0 +1,5 @@ +package net.caffeinemc.mods.sodium.client.render.texture; + +public interface TextureAtlasSpriteTickerExtension { + void sodium$ensureUpload(); +} diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/AnimatedTextureAccessor.java b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/AnimatedTextureAccessor.java index 489d342bc6..888d28aea6 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/AnimatedTextureAccessor.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/AnimatedTextureAccessor.java @@ -5,9 +5,13 @@ import java.util.List; import net.minecraft.client.renderer.texture.SpriteContents; +import org.spongepowered.asm.mixin.gen.Invoker; @Mixin(SpriteContents.AnimatedTexture.class) public interface AnimatedTextureAccessor { @Accessor("frames") - List getFrames(); + List sodium$getFrames(); + + @Invoker("uploadFrame") + void sodium$uploadFrame(int x, int y, int frameIndex); } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/InterpolationDataAccessor.java b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/InterpolationDataAccessor.java new file mode 100644 index 0000000000..7bb1719ffe --- /dev/null +++ b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/InterpolationDataAccessor.java @@ -0,0 +1,11 @@ +package net.caffeinemc.mods.sodium.mixin.features.textures.animations.tracking; + +import net.minecraft.client.renderer.texture.SpriteContents; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(SpriteContents.InterpolationData.class) +public interface InterpolationDataAccessor { + @Invoker("uploadInterpolatedFrame") + void sodium$uploadInterpolatedFrame(int x, int y, SpriteContents.Ticker ticker); +} diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/SpriteContentsMixin.java b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/SpriteContentsMixin.java index 8c33326e88..b1890db278 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/SpriteContentsMixin.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/SpriteContentsMixin.java @@ -1,6 +1,7 @@ package net.caffeinemc.mods.sodium.mixin.features.textures.animations.tracking; import net.caffeinemc.mods.sodium.client.render.texture.SpriteContentsExtension; +import net.caffeinemc.mods.sodium.client.render.texture.TextureAtlasSpriteTickerExtension; import net.minecraft.client.renderer.texture.SpriteContents; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Final; @@ -17,10 +18,15 @@ public abstract class SpriteContentsMixin implements SpriteContentsExtension { @Unique private boolean active; + @Unique + private TextureAtlasSpriteTickerExtension ticker; @Override public void sodium$setActive(boolean value) { this.active = value; + if (this.ticker != null && value) { + this.ticker.sodium$ensureUpload(); + } } @Override @@ -32,4 +38,9 @@ public abstract class SpriteContentsMixin implements SpriteContentsExtension { public boolean sodium$isActive() { return this.active; } + + @Override + public void sodium$setTicker(TextureAtlasSpriteTickerExtension ticker) { + this.ticker = ticker; + } } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/SpriteContentsTickerMixin.java b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/SpriteContentsTickerMixin.java index 29b3b24ecf..3edb4f69a3 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/SpriteContentsTickerMixin.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/SpriteContentsTickerMixin.java @@ -2,7 +2,11 @@ import net.caffeinemc.mods.sodium.client.SodiumClientMod; import net.caffeinemc.mods.sodium.client.render.texture.SpriteContentsExtension; +import net.caffeinemc.mods.sodium.client.render.texture.SpriteContentsTickerExtension; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.SpriteContents; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -14,18 +18,27 @@ import java.util.List; @Mixin(SpriteContents.Ticker.class) -public class SpriteContentsTickerMixin { +public abstract class SpriteContentsTickerMixin implements SpriteContentsTickerExtension { + @Shadow + int frame; @Shadow int subFrame; @Shadow @Final SpriteContents.AnimatedTexture animationInfo; @Shadow - int frame; + @Final + @Nullable + private SpriteContents.InterpolationData interpolationData; @Unique private SpriteContents parent; + @Unique + private boolean skippedUpload; + @Unique + private int uploadedFrame; + /** * @author IMS * @reason Replace fragile Shadow @@ -36,14 +49,18 @@ public void assignParent(SpriteContents spriteContents, SpriteContents.AnimatedT } @Inject(method = "tickAndUpload", at = @At("HEAD"), cancellable = true) - private void preTick(CallbackInfo ci) { + private void preTick(int x, int y, CallbackInfo ci) { SpriteContentsExtension parent = (SpriteContentsExtension) this.parent; boolean onDemand = SodiumClientMod.options().performance.animateOnlyVisibleTextures; if (onDemand && !parent.sodium$isActive()) { + if (!this.skippedUpload) { + this.uploadedFrame = this.frame; + this.skippedUpload = true; + } this.subFrame++; - List frames = ((AnimatedTextureAccessor)this.animationInfo).getFrames(); + List frames = ((AnimatedTextureAccessor) this.animationInfo).sodium$getFrames(); if (this.subFrame >= ((SpriteContentsFrameInfoAccessor) (Object) frames.get(this.frame)).getTime()) { this.frame = (this.frame + 1) % frames.size(); this.subFrame = 0; @@ -57,4 +74,28 @@ private void postTick(CallbackInfo ci) { SpriteContentsExtension parent = (SpriteContentsExtension) this.parent; parent.sodium$setActive(false); } + + @Override + public void sodium$ensureUpload(ResourceLocation atlas, int x, int y) { + if (!this.skippedUpload) { + return; + } + + Minecraft.getInstance().getTextureManager().getTexture(atlas).bind(); + List frames = ((AnimatedTextureAccessor) this.animationInfo).sodium$getFrames(); + int index = frames.get(this.frame).index(); + if (this.interpolationData != null) { + if (this.subFrame == 0) { + ((AnimatedTextureAccessor) this.animationInfo).sodium$uploadFrame(x, y, index); + } else { + ((InterpolationDataAccessor) (Object) this.interpolationData).sodium$uploadInterpolatedFrame(x, y, (SpriteContents.Ticker) (Object) this); + } + } else { + int uploadedIndex = frames.get(this.uploadedFrame).index(); + if (index != uploadedIndex) { + ((AnimatedTextureAccessor) this.animationInfo).sodium$uploadFrame(x, y, index); + } + } + this.skippedUpload = false; + } } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/TextureAtlasSpriteTickerImplMixin.java b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/TextureAtlasSpriteTickerImplMixin.java new file mode 100644 index 0000000000..2c789e8d25 --- /dev/null +++ b/common/src/main/java/net/caffeinemc/mods/sodium/mixin/features/textures/animations/tracking/TextureAtlasSpriteTickerImplMixin.java @@ -0,0 +1,33 @@ +package net.caffeinemc.mods.sodium.mixin.features.textures.animations.tracking; + +import net.caffeinemc.mods.sodium.client.render.texture.SpriteContentsExtension; +import net.caffeinemc.mods.sodium.client.render.texture.SpriteContentsTickerExtension; +import net.caffeinemc.mods.sodium.client.render.texture.TextureAtlasSpriteTickerExtension; +import net.minecraft.client.renderer.texture.SpriteTicker; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(targets = "net/minecraft/client/renderer/texture/TextureAtlasSprite$1") +public abstract class TextureAtlasSpriteTickerImplMixin implements TextureAtlasSpriteTickerExtension { + @Shadow + @Final + TextureAtlasSprite field_40555; + @Shadow + @Final + SpriteTicker val$ticker; + + @Inject(method = "", at = @At("TAIL")) + private void passTickerToSpriteContents(CallbackInfo ci) { + ((SpriteContentsExtension) this.field_40555.contents()).sodium$setTicker(this); + } + + @Override + public void sodium$ensureUpload() { + ((SpriteContentsTickerExtension) this.val$ticker).sodium$ensureUpload(this.field_40555.atlasLocation(), this.field_40555.getX(), this.field_40555.getY()); + } +} diff --git a/common/src/main/resources/sodium-common.mixins.json b/common/src/main/resources/sodium-common.mixins.json index 4fdf585949..4bcd044d7b 100644 --- a/common/src/main/resources/sodium-common.mixins.json +++ b/common/src/main/resources/sodium-common.mixins.json @@ -75,7 +75,9 @@ "features.textures.SpriteContentsInvoker", "features.textures.animations.tracking.ModelBlockRendererMixin", "features.textures.animations.tracking.GuiGraphicsMixin", + "features.textures.animations.tracking.InterpolationDataAccessor", "features.textures.animations.tracking.TextureAtlasMixin", + "features.textures.animations.tracking.TextureAtlasSpriteTickerImplMixin", "features.textures.animations.tracking.TextureSheetParticleMixin", "features.textures.animations.tracking.AnimatedTextureAccessor", "features.textures.animations.tracking.SpriteContentsFrameInfoAccessor",