Reduce and reuse

- Create subclass to recycle PoseStack.Pose objects
- Add mixin/liblink to access a PoseStack's inner deque
This commit is contained in:
Jozufozu 2024-09-14 16:50:02 -07:00
parent 295ebc7573
commit ed35c5a429
8 changed files with 73 additions and 3 deletions

View file

@ -1,5 +1,6 @@
package dev.engine_room.flywheel.lib.internal; package dev.engine_room.flywheel.lib.internal;
import java.util.Deque;
import java.util.Map; import java.util.Map;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -21,4 +22,6 @@ public interface FlwLibLink {
Map<String, ModelPart> getModelPartChildren(ModelPart part); Map<String, ModelPart> getModelPartChildren(ModelPart part);
void compileModelPart(ModelPart part, PoseStack.Pose pose, VertexConsumer consumer, int light, int overlay, float red, float green, float blue, float alpha); void compileModelPart(ModelPart part, PoseStack.Pose pose, VertexConsumer consumer, int light, int overlay, float red, float green, float blue, float alpha);
Deque<PoseStack.Pose> getPoseStack(PoseStack stack);
} }

View file

@ -0,0 +1,42 @@
package dev.engine_room.flywheel.lib.util;
import java.util.ArrayDeque;
import java.util.Deque;
import com.mojang.blaze3d.vertex.PoseStack;
import dev.engine_room.flywheel.lib.internal.FlwLibLink;
/**
* A {@link PoseStack} that recycles {@link PoseStack.Pose} objects.
*
* <p>Vanilla's {@link PoseStack} can get quite expensive to use when each game object needs to
* maintain their own stack. This class helps alleviate memory pressure by making Pose objects
* long-lived. Note that this means that you <em>CANNOT</em> safely store a Pose object outside
* the RecyclingPoseStack that created it.
*/
public class RecyclingPoseStack extends PoseStack {
private final Deque<Pose> recycleBin = new ArrayDeque<>();
@Override
public void pushPose() {
if (recycleBin.isEmpty()) {
super.pushPose();
} else {
var last = last();
var recycle = recycleBin.pop();
recycle.pose()
.set(last.pose());
recycle.normal()
.set(last.normal());
FlwLibLink.INSTANCE.getPoseStack(this)
.addLast(recycle);
}
}
@Override
public void popPose() {
recycleBin.push(FlwLibLink.INSTANCE.getPoseStack(this)
.removeLast());
}
}

View file

@ -1,5 +1,6 @@
package dev.engine_room.flywheel.impl; package dev.engine_room.flywheel.impl;
import java.util.Deque;
import java.util.Map; import java.util.Map;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -9,6 +10,7 @@ import com.mojang.blaze3d.vertex.VertexConsumer;
import dev.engine_room.flywheel.impl.extension.PoseStackExtension; import dev.engine_room.flywheel.impl.extension.PoseStackExtension;
import dev.engine_room.flywheel.impl.mixin.ModelPartAccessor; import dev.engine_room.flywheel.impl.mixin.ModelPartAccessor;
import dev.engine_room.flywheel.impl.mixin.PoseStackAccessor;
import dev.engine_room.flywheel.lib.internal.FlwLibLink; import dev.engine_room.flywheel.lib.internal.FlwLibLink;
import dev.engine_room.flywheel.lib.transform.PoseTransformStack; import dev.engine_room.flywheel.lib.transform.PoseTransformStack;
import net.minecraft.client.model.geom.ModelPart; import net.minecraft.client.model.geom.ModelPart;
@ -33,4 +35,9 @@ public class FlwLibLinkImpl implements FlwLibLink {
public void compileModelPart(ModelPart part, PoseStack.Pose pose, VertexConsumer consumer, int light, int overlay, float red, float green, float blue, float alpha) { public void compileModelPart(ModelPart part, PoseStack.Pose pose, VertexConsumer consumer, int light, int overlay, float red, float green, float blue, float alpha) {
((ModelPartAccessor) (Object) part).flywheel$compile(pose, consumer, light, overlay, red, green, blue, alpha); ((ModelPartAccessor) (Object) part).flywheel$compile(pose, consumer, light, overlay, red, green, blue, alpha);
} }
@Override
public Deque<PoseStack.Pose> getPoseStack(PoseStack stack) {
return ((PoseStackAccessor) stack).flywheel$getPoseStack();
}
} }

View file

@ -0,0 +1,14 @@
package dev.engine_room.flywheel.impl.mixin;
import java.util.Deque;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import com.mojang.blaze3d.vertex.PoseStack;
@Mixin(PoseStack.class)
public interface PoseStackAccessor {
@Accessor("poseStack")
Deque<PoseStack.Pose> flywheel$getPoseStack();
}

View file

@ -18,6 +18,7 @@ import dev.engine_room.flywheel.lib.material.SimpleMaterial;
import dev.engine_room.flywheel.lib.model.RetexturedMesh; import dev.engine_room.flywheel.lib.model.RetexturedMesh;
import dev.engine_room.flywheel.lib.model.part.InstanceTree; import dev.engine_room.flywheel.lib.model.part.InstanceTree;
import dev.engine_room.flywheel.lib.transform.TransformStack; import dev.engine_room.flywheel.lib.transform.TransformStack;
import dev.engine_room.flywheel.lib.util.RecyclingPoseStack;
import dev.engine_room.flywheel.lib.visual.AbstractBlockEntityVisual; import dev.engine_room.flywheel.lib.visual.AbstractBlockEntityVisual;
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
import it.unimi.dsi.fastutil.floats.Float2FloatFunction; import it.unimi.dsi.fastutil.floats.Float2FloatFunction;
@ -59,7 +60,7 @@ public class ChestVisual<T extends BlockEntity & LidBlockEntity> extends Abstrac
@Nullable @Nullable
private final InstanceTree lock; private final InstanceTree lock;
private final PoseStack poseStack = new PoseStack(); private final PoseStack poseStack = new RecyclingPoseStack();
private final BrightnessCombiner brightnessCombiner = new BrightnessCombiner(); private final BrightnessCombiner brightnessCombiner = new BrightnessCombiner();
@Nullable @Nullable
private final DoubleBlockCombiner.NeighborCombineResult<? extends ChestBlockEntity> neighborCombineResult; private final DoubleBlockCombiner.NeighborCombineResult<? extends ChestBlockEntity> neighborCombineResult;

View file

@ -16,6 +16,7 @@ import dev.engine_room.flywheel.lib.model.ModelHolder;
import dev.engine_room.flywheel.lib.model.Models; import dev.engine_room.flywheel.lib.model.Models;
import dev.engine_room.flywheel.lib.model.SingleMeshModel; import dev.engine_room.flywheel.lib.model.SingleMeshModel;
import dev.engine_room.flywheel.lib.model.part.ModelPartConverter; import dev.engine_room.flywheel.lib.model.part.ModelPartConverter;
import dev.engine_room.flywheel.lib.util.RecyclingPoseStack;
import dev.engine_room.flywheel.lib.visual.ComponentEntityVisual; import dev.engine_room.flywheel.lib.visual.ComponentEntityVisual;
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
import dev.engine_room.flywheel.lib.visual.SimpleTickableVisual; import dev.engine_room.flywheel.lib.visual.SimpleTickableVisual;
@ -52,7 +53,7 @@ public class MinecartVisual<T extends AbstractMinecart> extends ComponentEntityV
private final ModelHolder bodyModel; private final ModelHolder bodyModel;
private final PoseStack stack = new PoseStack(); private final PoseStack stack = new RecyclingPoseStack();
private BlockState blockState; private BlockState blockState;
private boolean active; private boolean active;

View file

@ -17,6 +17,7 @@ import dev.engine_room.flywheel.lib.model.ModelCache;
import dev.engine_room.flywheel.lib.model.SingleMeshModel; import dev.engine_room.flywheel.lib.model.SingleMeshModel;
import dev.engine_room.flywheel.lib.model.part.ModelPartConverter; import dev.engine_room.flywheel.lib.model.part.ModelPartConverter;
import dev.engine_room.flywheel.lib.transform.TransformStack; import dev.engine_room.flywheel.lib.transform.TransformStack;
import dev.engine_room.flywheel.lib.util.RecyclingPoseStack;
import dev.engine_room.flywheel.lib.visual.AbstractBlockEntityVisual; import dev.engine_room.flywheel.lib.visual.AbstractBlockEntityVisual;
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
import net.minecraft.client.model.geom.ModelLayers; import net.minecraft.client.model.geom.ModelLayers;
@ -45,7 +46,7 @@ public class ShulkerBoxVisual extends AbstractBlockEntityVisual<ShulkerBoxBlockE
private final TransformedInstance base; private final TransformedInstance base;
private final TransformedInstance lid; private final TransformedInstance lid;
private final PoseStack stack = new PoseStack(); private final PoseStack stack = new RecyclingPoseStack();
private float lastProgress = Float.NaN; private float lastProgress = Float.NaN;

View file

@ -13,6 +13,7 @@
"LevelRendererMixin", "LevelRendererMixin",
"MinecraftMixin", "MinecraftMixin",
"ModelPartAccessor", "ModelPartAccessor",
"PoseStackAccessor",
"PoseStackMixin", "PoseStackMixin",
"fix.FixFabulousDepthMixin", "fix.FixFabulousDepthMixin",
"fix.FixNormalScalingMixin", "fix.FixNormalScalingMixin",