Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ public interface SpriteContentsExtension {
boolean sodium$isActive();

boolean sodium$hasAnimation();

void sodium$setTicker(TextureAtlasSpriteTickerExtension ticker);
}
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package net.caffeinemc.mods.sodium.client.render.texture;

public interface TextureAtlasSpriteTickerExtension {
void sodium$ensureUpload();
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<SpriteContents.FrameInfo> getFrames();
List<SpriteContents.FrameInfo> sodium$getFrames();

@Invoker("uploadFrame")
void sodium$uploadFrame(int x, int y, int frameIndex);
}
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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
Expand All @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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<SpriteContents.FrameInfo> frames = ((AnimatedTextureAccessor)this.animationInfo).getFrames();
List<SpriteContents.FrameInfo> 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;
Expand All @@ -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();
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revisiting this, its probably problematic to change the bound texture here since we can't know at what point in the code a sprite is being marked active and it might mess up render state.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This issue is not present with just the first commit, but as stated in the initial pr message the behaviour from just the first commit is not 100% correct since it leaves a delay between the texture becoming visible and when its reticked

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a safe approach to this? Does anyone know whether this is safe?

List<SpriteContents.FrameInfo> 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;
}
}
Original file line number Diff line number Diff line change
@@ -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 = "<init>", 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());
}
}
2 changes: 2 additions & 0 deletions common/src/main/resources/sodium-common.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down