-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Performance issue when using high resolution resource packs #43
Comments
This was referenced Aug 27, 2023
Closed
I decided to dedicate some time to writing a caching patch. I've only tested this with Hyper Realistic Sky tornadoes, and it works fine. There are potential pitfalls in this approach. I believe the major one is the utilization of only 16 bits for the native image pointer when packing. Additionally, I'm concerned that I haven't packed enough information to differentiate other interpolation phases. diff --git a/gradlew b/gradlew
old mode 100644
new mode 100755
diff --git a/src/main/java/io/github/foundationgames/animatica/animation/AnimatedTexture.java b/src/main/java/io/github/foundationgames/animatica/animation/AnimatedTexture.java
index 0d46e2e..ba9d13c 100644
--- a/src/main/java/io/github/foundationgames/animatica/animation/AnimatedTexture.java
+++ b/src/main/java/io/github/foundationgames/animatica/animation/AnimatedTexture.java
@@ -2,7 +2,9 @@ package io.github.foundationgames.animatica.animation;
import com.google.common.collect.ImmutableList;
import io.github.foundationgames.animatica.Animatica;
+import io.github.foundationgames.animatica.util.NativeImageExtended;
import io.github.foundationgames.animatica.util.TextureUtil;
+import it.unimi.dsi.fastutil.longs.Long2ObjectArrayMap;
import net.minecraft.client.texture.NativeImage;
import net.minecraft.client.texture.NativeImageBackedTexture;
import net.minecraft.resource.ResourceManager;
@@ -12,9 +14,12 @@ import net.minecraft.util.math.MathHelper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
public class AnimatedTexture extends NativeImageBackedTexture {
+ private final Map<Long, NativeImage> imageCache = new Long2ObjectArrayMap<>();
+
public final Animation[] anims;
private final NativeImage original;
private int frame = 0;
@@ -75,7 +80,20 @@ public class AnimatedTexture extends NativeImageBackedTexture {
for (var anim : anims) {
phase = anim.getCurrentPhase();
if (phase instanceof InterpolatedPhase iPhase) {
- TextureUtil.blendCopy(anim.sourceTexture, 0, iPhase.prevV, 0, iPhase.v, anim.width, anim.height, image, anim.targetX, anim.targetY, iPhase.blend.getBlend(anim.getPhaseFrame()));
+ // This is a bit of a hacky way to get the pointer of the source texture, but it works
+ // we are only using the last 16 bits of the pointer, this might be a problem
+ // iPhase.v shouldn't need more than 16 bits to be honest, but this is just to be safe if we can, we should allocate the rest of the bits to the pointer
+ // PhaseFrame shouldn't need more than 16 bits as well, but again, just to be safe
+ // The targetY is also unlikely to need more than 16 bits because of max texture size (typically 2^14 on modern gpus)
+ long identifier = ((long) anim.getPhaseFrame()) << 48 | ((long) anim.targetY) << 32 | ((long) iPhase.v) << 16 | (((NativeImageExtended) (Object) anim.sourceTexture).getPointer());// this could be problematic but for testing purposes
+ if (this.imageCache.containsKey(identifier)) {
+ image.copyFrom(this.imageCache.get(identifier));
+ } else {
+ TextureUtil.blendCopy(anim.sourceTexture, 0, iPhase.prevV, 0, iPhase.v, anim.width, anim.height, image, anim.targetX, anim.targetY, iPhase.blend.getBlend(anim.getPhaseFrame()));
+ NativeImage cache = new NativeImage(image.getFormat(), image.getWidth(), image.getHeight(), true);
+ cache.copyFrom(image);
+ this.imageCache.put(identifier, cache);
+ }
} else {
TextureUtil.copy(anim.sourceTexture, 0, phase.v, anim.width, anim.height, image, anim.targetX, anim.targetY);
}
@@ -102,6 +120,9 @@ public class AnimatedTexture extends NativeImageBackedTexture {
anim.close();
}
+ this.imageCache.values().forEach(NativeImage::close);
+ this.imageCache.clear();
+
this.original.close();
super.close();
}
diff --git a/src/main/java/io/github/foundationgames/animatica/mixin/NativeImageMixin.java b/src/main/java/io/github/foundationgames/animatica/mixin/NativeImageMixin.java
new file mode 100644
index 0000000..e5c525c
--- /dev/null
+++ b/src/main/java/io/github/foundationgames/animatica/mixin/NativeImageMixin.java
@@ -0,0 +1,17 @@
+package io.github.foundationgames.animatica.mixin;
+
+import io.github.foundationgames.animatica.util.NativeImageExtended;
+import net.minecraft.client.texture.NativeImage;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+
+@Mixin(NativeImage.class)
+public class NativeImageMixin implements NativeImageExtended {
+ @Shadow
+ private long pointer;
+
+ @Override
+ public long getPointer() {
+ return this.pointer;
+ }
+}
diff --git a/src/main/java/io/github/foundationgames/animatica/util/NativeImageExtended.java b/src/main/java/io/github/foundationgames/animatica/util/NativeImageExtended.java
new file mode 100644
index 0000000..0e70473
--- /dev/null
+++ b/src/main/java/io/github/foundationgames/animatica/util/NativeImageExtended.java
@@ -0,0 +1,5 @@
+package io.github.foundationgames.animatica.util;
+
+public interface NativeImageExtended {
+ long getPointer();
+}
diff --git a/src/main/resources/animatica.mixins.json b/src/main/resources/animatica.mixins.json
index 0d022d5..11725d9 100644
--- a/src/main/resources/animatica.mixins.json
+++ b/src/main/resources/animatica.mixins.json
@@ -5,6 +5,7 @@
"compatibilityLevel": "JAVA_16",
"client": [
"RenderSystemMixin",
+ "NativeImageMixin",
"IdentifierMixin",
"VideoOptionsScreenMixin"
], |
ghost
mentioned this issue
Sep 25, 2023
3 tasks
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have identified a performance issue while using Animatica in conjunction with the Hyper Realistic Sky resource pack, which contains high-resolution textures. Upon profiling, I noticed that a significant amount of time is being spent on blending and copying operations.
One possible solution I can think of is caching the interpolated frames(NativeImage) so they can be reused rather than recalculating the interpolation, considering that animations always utilize the same set of textures.
The text was updated successfully, but these errors were encountered: