Fix memory leaks

- Fix CopycatPanelModel using wrong state during trapdoor special case
- Update Flywheel
This commit is contained in:
PepperCode1 2023-07-03 13:53:51 -07:00
parent 886398f679
commit 246543c76b
11 changed files with 70 additions and 49 deletions

View File

@ -159,6 +159,7 @@ repositories {
}
}
mavenLocal()
flatDir {
dirs 'libs'
}

View File

@ -23,7 +23,7 @@ use_parchment = true
# dependency versions
registrate_version = MC1.18.2-1.1.3
flywheel_minecraft_version = 1.18.2
flywheel_version = 0.6.9-100
flywheel_version = 0.6.9-101
jei_minecraft_version = 1.18.2
jei_version = 9.7.0.209
curios_minecraft_version = 1.18.2

View File

@ -7,6 +7,7 @@ import org.apache.commons.lang3.tuple.Pair;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.gl.error.GlError;
import com.jozufozu.flywheel.config.BackendType;
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferedData;
import com.jozufozu.flywheel.core.model.WorldModelBuilder;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.jozufozu.flywheel.event.BeginFrameEvent;
@ -15,7 +16,6 @@ import com.jozufozu.flywheel.event.ReloadRenderersEvent;
import com.jozufozu.flywheel.event.RenderLayerEvent;
import com.jozufozu.flywheel.util.WorldAttached;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllMovementBehaviours;
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
@ -171,11 +171,13 @@ public class ContraptionRenderDispatcher {
public static SuperByteBuffer buildStructureBuffer(VirtualRenderWorld renderWorld, Contraption c,
RenderType layer) {
Collection<StructureTemplate.StructureBlockInfo> values = c.getRenderedBlocks();
BufferBuilder builder = new WorldModelBuilder(layer).withRenderWorld(renderWorld)
ShadeSeparatedBufferedData data = new WorldModelBuilder(layer).withRenderWorld(renderWorld)
.withBlocks(values)
.withModelData(c.modelData)
.build();
return new SuperByteBuffer(builder);
SuperByteBuffer sbb = new SuperByteBuffer(data);
data.release();
return sbb;
}
public static int getLight(Level world, float lx, float ly, float lz) {

View File

@ -132,8 +132,9 @@ public class FlwContraption extends ContraptionRenderInfo {
}
private void buildLayers() {
for (ArrayModelRenderer buffer : renderLayers.values()) {
buffer.delete();
for (ArrayModelRenderer renderer : renderLayers.values()) {
renderer.delete();
renderer.getModel().delete();
}
renderLayers.clear();
@ -145,7 +146,7 @@ public class FlwContraption extends ContraptionRenderInfo {
Model layerModel = new WorldModelBuilder(layer).withRenderWorld(renderWorld)
.withModelData(contraption.modelData)
.withBlocks(renderedBlocks)
.intoMesh(layer + "_" + contraption.entity.getId());
.toModel(layer + "_" + contraption.entity.getId());
renderLayers.put(layer, new ArrayModelRenderer(layerModel));
}
}

View File

@ -42,7 +42,7 @@ public class CopycatPanelModel extends CopycatModel {
specialCopycatModelState = AllBlocks.COPYCAT_BARS.getDefaultState();
if (CopycatSpecialCases.isTrapdoorMaterial(material))
return blockRenderer.getBlockModel(material)
.getQuads(state, side, rand, wrappedData);
.getQuads(material, side, rand, wrappedData);
if (specialCopycatModelState != null) {
BakedModel blockModel = blockRenderer

View File

@ -49,7 +49,7 @@ public class WaterWheelInstance<T extends WaterWheelBlockEntity> extends CutoutR
dir = state.getValue(WaterWheelBlock.FACING);
}
PoseStack transform = CachedBufferer.rotateToFaceVertical(dir).get();
return new BlockModel(model, Blocks.AIR.defaultBlockState(), transform);
return BlockModel.of(model, Blocks.AIR.defaultBlockState(), transform);
});
}
}

View File

@ -5,7 +5,7 @@ import java.util.Map;
import java.util.Random;
import com.jozufozu.flywheel.core.model.ModelUtil;
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferBuilder;
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferedData;
import com.jozufozu.flywheel.core.model.ShadeSeparatingVertexConsumer;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
@ -79,11 +79,15 @@ public class SchematicRenderer {
}
protected void redraw() {
bufferCache.forEach((layer, sbb) -> sbb.delete());
bufferCache.clear();
for (RenderType layer : RenderType.chunkBufferLayers()) {
SuperByteBuffer buffer = drawLayer(layer);
if (!buffer.isEmpty())
bufferCache.put(layer, buffer);
else
buffer.delete();
}
}
@ -99,12 +103,12 @@ public class SchematicRenderer {
BoundingBox bounds = renderWorld.getBounds();
ShadeSeparatingVertexConsumer shadeSeparatingWrapper = objects.shadeSeparatingWrapper;
ShadeSeparatedBufferBuilder builder = new ShadeSeparatedBufferBuilder(512);
BufferBuilder shadedBuilder = objects.shadedBuilder;
BufferBuilder unshadedBuilder = objects.unshadedBuilder;
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
shadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
unshadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
shadeSeparatingWrapper.prepare(builder, unshadedBuilder);
shadeSeparatingWrapper.prepare(shadedBuilder, unshadedBuilder);
ForgeHooksClient.setRenderType(layer);
ModelBlockRenderer.enableCaching();
@ -127,13 +131,13 @@ public class SchematicRenderer {
ForgeHooksClient.setRenderType(null);
shadeSeparatingWrapper.clear();
unshadedBuilder.end();
builder.appendUnshadedVertices(unshadedBuilder);
builder.end();
ShadeSeparatedBufferedData bufferedData = ModelUtil.endAndCombine(shadedBuilder, unshadedBuilder);
renderWorld.renderMode = false;
return new SuperByteBuffer(builder);
SuperByteBuffer sbb = new SuperByteBuffer(bufferedData);
bufferedData.release();
return sbb;
}
private static int getLayerCount() {
@ -146,6 +150,7 @@ public class SchematicRenderer {
public final Random random = new Random();
public final BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
public final ShadeSeparatingVertexConsumer shadeSeparatingWrapper = new ShadeSeparatingVertexConsumer();
public final BufferBuilder shadedBuilder = new BufferBuilder(512);
public final BufferBuilder unshadedBuilder = new BufferBuilder(512);
}

View File

@ -8,7 +8,7 @@ import java.util.Random;
import java.util.function.Consumer;
import com.jozufozu.flywheel.core.model.ModelUtil;
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferBuilder;
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferedData;
import com.jozufozu.flywheel.core.model.ShadeSeparatingVertexConsumer;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.BufferBuilder;
@ -258,7 +258,7 @@ public class WorldSectionElement extends AnimatedSceneElement {
prevAnimatedRotation = animatedRotation;
if (!isVisible())
return;
loadTEsIfMissing(scene.getWorld());
loadBEsIfMissing(scene.getWorld());
renderedBlockEntities.removeIf(be -> scene.getWorld()
.getBlockEntity(be.getBlockPos()) != be);
tickableBlockEntities.removeIf(be -> scene.getWorld()
@ -277,7 +277,7 @@ public class WorldSectionElement extends AnimatedSceneElement {
redraw = false;
}
protected void loadTEsIfMissing(PonderWorld world) {
protected void loadBEsIfMissing(PonderWorld world) {
if (renderedBlockEntities != null)
return;
tickableBlockEntities = new ArrayList<>();
@ -405,7 +405,7 @@ public class WorldSectionElement extends AnimatedSceneElement {
}
private void renderBlockEntities(PonderWorld world, PoseStack ms, MultiBufferSource buffer, float pt) {
loadTEsIfMissing(world);
loadBEsIfMissing(world);
BlockEntityRenderHelper.renderBlockEntities(world, renderedBlockEntities, ms, buffer, pt);
}
@ -416,12 +416,12 @@ public class WorldSectionElement extends AnimatedSceneElement {
PoseStack poseStack = objects.poseStack;
Random random = objects.random;
ShadeSeparatingVertexConsumer shadeSeparatingWrapper = objects.shadeSeparatingWrapper;
ShadeSeparatedBufferBuilder builder = new ShadeSeparatedBufferBuilder(512);
BufferBuilder shadedBuilder = objects.shadedBuilder;
BufferBuilder unshadedBuilder = objects.unshadedBuilder;
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
shadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
unshadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
shadeSeparatingWrapper.prepare(builder, unshadedBuilder);
shadeSeparatingWrapper.prepare(shadedBuilder, unshadedBuilder);
world.setMask(this.section);
ForgeHooksClient.setRenderType(layer);
@ -440,7 +440,7 @@ public class WorldSectionElement extends AnimatedSceneElement {
}
if (!fluidState.isEmpty() && ItemBlockRenderTypes.canRenderInLayer(fluidState, layer))
dispatcher.renderLiquid(pos, world, builder, state, fluidState);
dispatcher.renderLiquid(pos, world, shadedBuilder, state, fluidState);
poseStack.popPose();
});
@ -449,17 +449,18 @@ public class WorldSectionElement extends AnimatedSceneElement {
world.clearMask();
shadeSeparatingWrapper.clear();
unshadedBuilder.end();
builder.appendUnshadedVertices(unshadedBuilder);
builder.end();
ShadeSeparatedBufferedData bufferedData = ModelUtil.endAndCombine(shadedBuilder, unshadedBuilder);
return new SuperByteBuffer(builder);
SuperByteBuffer sbb = new SuperByteBuffer(bufferedData);
bufferedData.release();
return sbb;
}
private static class ThreadLocalObjects {
public final PoseStack poseStack = new PoseStack();
public final Random random = new Random();
public final ShadeSeparatingVertexConsumer shadeSeparatingWrapper = new ShadeSeparatingVertexConsumer();
public final BufferBuilder shadedBuilder = new BufferBuilder(512);
public final BufferBuilder unshadedBuilder = new BufferBuilder(512);
}

View File

@ -1,7 +1,7 @@
package com.simibubi.create.foundation.render;
import com.jozufozu.flywheel.core.model.ModelUtil;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferedData;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
@ -22,8 +22,10 @@ public class BakedModelRenderHelper {
}
public static SuperByteBuffer standardModelRender(BakedModel model, BlockState referenceState, PoseStack ms) {
BufferBuilder builder = ModelUtil.getBufferBuilder(model, referenceState, ms);
return new SuperByteBuffer(builder);
ShadeSeparatedBufferedData data = ModelUtil.getBufferedData(model, referenceState, ms);
SuperByteBuffer sbb = new SuperByteBuffer(data);
data.release();
return sbb;
}
}

View File

@ -6,16 +6,14 @@ import java.util.function.IntPredicate;
import com.jozufozu.flywheel.api.vertex.ShadedVertexList;
import com.jozufozu.flywheel.api.vertex.VertexList;
import com.jozufozu.flywheel.backend.ShadersModHandler;
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferBuilder;
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferedData;
import com.jozufozu.flywheel.core.vertex.BlockVertexList;
import com.jozufozu.flywheel.util.DiffuseLightCalculator;
import com.jozufozu.flywheel.util.transform.TStack;
import com.jozufozu.flywheel.util.transform.Transform;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.BufferBuilder.DrawState;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.datafixers.util.Pair;
import com.mojang.math.Matrix3f;
import com.mojang.math.Matrix4f;
import com.mojang.math.Quaternion;
@ -41,7 +39,7 @@ public class SuperByteBuffer implements Transform<SuperByteBuffer>, TStack<Super
private final IntPredicate shadedPredicate;
// Vertex Position
private final PoseStack transforms;
private final PoseStack transforms = new PoseStack();
// Vertex Coloring
private boolean shouldColor;
@ -69,23 +67,28 @@ public class SuperByteBuffer implements Transform<SuperByteBuffer>, TStack<Super
// Temporary
private static final Long2IntMap WORLD_LIGHT_CACHE = new Long2IntOpenHashMap();
public SuperByteBuffer(BufferBuilder buf) {
Pair<DrawState, ByteBuffer> pair = buf.popNextBuffer();
DrawState drawState = pair.getFirst();
ByteBuffer buffer = pair.getSecond();
public SuperByteBuffer(ByteBuffer vertexBuffer, BufferBuilder.DrawState drawState, int unshadedStartVertex) {
int vertexCount = drawState.vertexCount();
int stride = drawState.format().getVertexSize();
if (buf instanceof ShadeSeparatedBufferBuilder separated) {
ShadedVertexList template = new BlockVertexList.Shaded(buffer, vertexCount, stride, separated.getUnshadedStartVertex());
ShadedVertexList template = new BlockVertexList.Shaded(vertexBuffer, vertexCount, stride, unshadedStartVertex);
shadedPredicate = template::isShaded;
this.template = template;
} else {
template = new BlockVertexList(buffer, vertexCount, stride);
shadedPredicate = index -> true;
transforms.pushPose();
}
transforms = new PoseStack();
public SuperByteBuffer(ShadeSeparatedBufferedData data) {
this(data.vertexBuffer(), data.drawState(), data.unshadedStartVertex());
}
public SuperByteBuffer(ByteBuffer vertexBuffer, BufferBuilder.DrawState drawState) {
int vertexCount = drawState.vertexCount();
int stride = drawState.format().getVertexSize();
template = new BlockVertexList(vertexBuffer, vertexCount, stride);
shadedPredicate = index -> true;
transforms.pushPose();
}
@ -246,6 +249,10 @@ public class SuperByteBuffer implements Transform<SuperByteBuffer>, TStack<Super
return template.isEmpty();
}
public void delete() {
template.delete();
}
public PoseStack getTransforms() {
return transforms;
}

View File

@ -15,12 +15,14 @@ public class SuperByteBufferCache {
public synchronized void registerCompartment(Compartment<?> compartment) {
caches.put(compartment, CacheBuilder.newBuilder()
.<Object, SuperByteBuffer>removalListener(n -> n.getValue().delete())
.build());
}
public synchronized void registerCompartment(Compartment<?> compartment, long ticksUntilExpired) {
caches.put(compartment, CacheBuilder.newBuilder()
.expireAfterAccess(ticksUntilExpired * 50, TimeUnit.MILLISECONDS)
.<Object, SuperByteBuffer>removalListener(n -> n.getValue().delete())
.build());
}