No more leaks

- Free all DrawBuffers on renderer reload
- Add flw.debugMemorySafety flag to detect leaked untracked MemoryBlocks
- Replace VertexListProviderRegistry with static methods in
VertexListProvider and a VertexFormatMixin
- Make the DrawBuffer constructor accept a VertexFormat instead of a
RenderType
- Merge TStack into TransformStack
- Move all duck interfaces/extensions to extension package
- Make mixin style more consistent
This commit is contained in:
PepperCode1 2022-08-17 16:20:31 -07:00
parent cfa79ec550
commit 2fe69350ef
57 changed files with 317 additions and 233 deletions

View file

@ -45,6 +45,7 @@ minecraft {
property 'mixin.env.remapRefMap', 'true'
property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg"
property 'flw.dumpShaderSource', 'true'
property 'flw.debugMemorySafety', 'true'
arg '-mixin.config=flywheel.mixins.json'
@ -114,8 +115,8 @@ dependencies {
// switch to implementation for debugging
compileOnly fg.deobf("maven.modrinth:starlight-forge:1.0.2+1.18.2")
compileOnly fg.deobf("maven.modrinth:rubidium:0.5.2a")
compileOnly fg.deobf("curse.maven:oculus-581495:3821406")
compileOnly fg.deobf("maven.modrinth:rubidium:0.5.3a")
compileOnly fg.deobf("maven.modrinth:oculus:1.18.2-1.2.5a")
// https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497
// Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings

View file

@ -7,6 +7,7 @@ import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.RenderWork;
import com.jozufozu.flywheel.backend.ShadersModHandler;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import com.jozufozu.flywheel.backend.instancing.batching.DrawBuffer;
import com.jozufozu.flywheel.config.BackendTypeArgument;
import com.jozufozu.flywheel.config.FlwCommands;
import com.jozufozu.flywheel.config.FlwConfig;
@ -18,7 +19,6 @@ import com.jozufozu.flywheel.core.compile.ProgramCompiler;
import com.jozufozu.flywheel.core.model.Models;
import com.jozufozu.flywheel.event.EntityWorldHandler;
import com.jozufozu.flywheel.event.ForgeEvents;
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
import com.jozufozu.flywheel.mixin.PausedPartialTickAccessor;
import com.jozufozu.flywheel.vanilla.VanillaInstances;
import com.mojang.logging.LogUtils;
@ -77,9 +77,10 @@ public class Flywheel {
forgeEventBus.addListener(FlwCommands::registerClientCommands);
forgeEventBus.addListener(EventPriority.HIGHEST, QuadConverter::onRendererReload);
forgeEventBus.addListener(ProgramCompiler::invalidateAll);
forgeEventBus.addListener(Models::onReload);
forgeEventBus.addListener(EventPriority.HIGHEST, QuadConverter::onReloadRenderers);
forgeEventBus.addListener(ProgramCompiler::onReloadRenderers);
forgeEventBus.addListener(Models::onReloadRenderers);
forgeEventBus.addListener(DrawBuffer::onReloadRenderers);
forgeEventBus.addListener(InstancedRenderDispatcher::onReloadRenderers);
forgeEventBus.addListener(InstancedRenderDispatcher::onRenderStage);

View file

@ -1,5 +1,23 @@
package com.jozufozu.flywheel.api.vertex;
import com.jozufozu.flywheel.core.vertex.InferredVertexListProviderImpl;
import com.jozufozu.flywheel.extension.VertexFormatExtension;
import com.mojang.blaze3d.vertex.VertexFormat;
public interface VertexListProvider {
ReusableVertexList createVertexList();
static VertexListProvider get(VertexFormat format) {
VertexFormatExtension extension = (VertexFormatExtension) format;
VertexListProvider provider = extension.flywheel$getVertexListProvider();
if (provider == null) {
provider = new InferredVertexListProviderImpl(format);
extension.flywheel$setVertexListProvider(provider);
}
return provider;
}
static void set(VertexFormat format, VertexListProvider provider) {
((VertexFormatExtension) format).flywheel$setVertexListProvider(provider);
}
}

View file

@ -13,7 +13,7 @@ import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine;
import com.jozufozu.flywheel.core.Components;
import com.jozufozu.flywheel.core.RenderContext;
import com.jozufozu.flywheel.event.BeginFrameEvent;
import com.jozufozu.flywheel.util.ClientLevelExtension;
import com.jozufozu.flywheel.extension.ClientLevelExtension;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;

View file

@ -9,12 +9,12 @@ import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.instancer.InstancerManager;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstancingController;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityTypeExtension;
import com.jozufozu.flywheel.backend.instancing.blockentity.SimpleBlockEntityInstancingController;
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance;
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstancingController;
import com.jozufozu.flywheel.backend.instancing.entity.EntityTypeExtension;
import com.jozufozu.flywheel.backend.instancing.entity.SimpleEntityInstancingController;
import com.jozufozu.flywheel.extension.BlockEntityTypeExtension;
import com.jozufozu.flywheel.extension.EntityTypeExtension;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;

View file

@ -3,7 +3,8 @@ package com.jozufozu.flywheel.backend.instancing.batching;
import java.util.HashSet;
import java.util.Set;
import com.jozufozu.flywheel.util.RenderTypeExtension;
import com.jozufozu.flywheel.extension.BufferBuilderExtension;
import com.jozufozu.flywheel.extension.RenderTypeExtension;
import com.mojang.blaze3d.vertex.BufferBuilder;
import net.minecraft.client.renderer.RenderType;

View file

@ -67,6 +67,7 @@ public class BatchingEngine implements Engine {
public void renderStage(TaskEngine taskEngine, RenderContext context, RenderStage stage) {
// FIXME: properly support material stages
// This also breaks block outlines on batched block entities
// and makes translucent blocks occlude everything Flywheel renders
if (stage != RenderStage.AFTER_FINAL_END_BATCH) {
return;
}

View file

@ -1,24 +1,26 @@
package com.jozufozu.flywheel.backend.instancing.batching;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import org.jetbrains.annotations.ApiStatus;
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
import com.jozufozu.flywheel.api.vertex.VertexListProvider;
import com.jozufozu.flywheel.backend.memory.MemoryBlock;
import com.jozufozu.flywheel.core.vertex.VertexListProviderRegistry;
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
import com.jozufozu.flywheel.extension.BufferBuilderExtension;
import com.mojang.blaze3d.vertex.VertexFormat;
import net.minecraft.client.renderer.RenderType;
/**
* A byte buffer that can be used to draw vertices through multiple {@link ReusableVertexList}s.
*
* The number of vertices needs to be known ahead of time.
*/
public class DrawBuffer {
private final RenderType parent;
private static final List<DrawBuffer> ALL = new ArrayList<>();
private final VertexFormat format;
private final int stride;
private final VertexListProvider provider;
@ -29,11 +31,12 @@ public class DrawBuffer {
private int expectedVertices;
@ApiStatus.Internal
public DrawBuffer(RenderType parent) {
this.parent = parent;
format = parent.format();
public DrawBuffer(VertexFormat format) {
this.format = format;
stride = format.getVertexSize();
provider = VertexListProviderRegistry.getOrInfer(format);
provider = VertexListProvider.get(format);
ALL.add(this);
}
/**
@ -66,7 +69,8 @@ public class DrawBuffer {
public ReusableVertexList slice(int startVertex, int vertexCount) {
ReusableVertexList vertexList = provider.createVertexList();
vertexList.ptr(memory.ptr() + startVertex * stride);
vertexList.ptr(memory.ptr());
vertexList.shiftPtr(startVertex);
vertexList.setVertexCount(vertexCount);
return vertexList;
}
@ -101,7 +105,12 @@ public class DrawBuffer {
}
public void free() {
buffer = null;
memory.free();
memory = null;
buffer = null;
}
public static void onReloadRenderers(ReloadRenderersEvent event) {
ALL.forEach(DrawBuffer::free);
}
}

View file

@ -4,7 +4,6 @@ import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
import com.jozufozu.flywheel.backend.gl.array.GlVertexArray;
import com.jozufozu.flywheel.core.layout.BufferLayout;
public class DrawCall {

View file

@ -3,7 +3,6 @@ package com.jozufozu.flywheel.backend.instancing.instancing;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.instancer.Instancer;

View file

@ -0,0 +1,75 @@
package com.jozufozu.flywheel.backend.memory;
import java.lang.ref.Cleaner;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.util.StringUtil;
class DebugMemoryBlockImpl extends MemoryBlockImpl {
final CleaningAction cleaningAction;
final Cleaner.Cleanable cleanable;
DebugMemoryBlockImpl(long ptr, long size, Cleaner cleaner) {
super(ptr, size);
cleaningAction = new CleaningAction(ptr, size, getStackTrace());
cleanable = cleaner.register(this, cleaningAction);
}
@Override
void freeInner() {
super.freeInner();
cleaningAction.freed = true;
cleanable.clean();
}
static StackWalker.StackFrame[] getStackTrace() {
return StackWalker.getInstance().walk(s -> s.skip(4).toArray(StackWalker.StackFrame[]::new));
}
static MemoryBlock malloc(long size) {
MemoryBlock block = new DebugMemoryBlockImpl(FlwMemoryTracker.malloc(size), size, FlwMemoryTracker.CLEANER);
FlwMemoryTracker._allocCPUMemory(block.size());
return block;
}
static MemoryBlock calloc(long num, long size) {
MemoryBlock block = new DebugMemoryBlockImpl(FlwMemoryTracker.calloc(num, size), num * size, FlwMemoryTracker.CLEANER);
FlwMemoryTracker._allocCPUMemory(block.size());
return block;
}
static class CleaningAction implements Runnable {
final long ptr;
final long size;
final StackWalker.StackFrame[] allocationSite;
boolean freed;
CleaningAction(long ptr, long size, StackWalker.StackFrame[] allocationSite) {
this.ptr = ptr;
this.size = size;
this.allocationSite = allocationSite;
}
@Override
public void run() {
if (!freed) {
StringBuilder builder = new StringBuilder();
builder
.append("Reclaimed ")
.append(size)
.append(" bytes at address ")
.append(StringUtil.formatAddress(ptr))
.append(" that were leaked from allocation site:");
for (StackWalker.StackFrame frame : allocationSite) {
builder.append("\n\t");
builder.append(frame);
}
Flywheel.LOGGER.warn(builder.toString());
FlwMemoryTracker.free(ptr);
FlwMemoryTracker._freeCPUMemory(size);
}
}
}
}

View file

@ -5,7 +5,11 @@ import java.nio.ByteBuffer;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.util.StringUtil;
public class FlwMemoryTracker {
public static final boolean DEBUG_MEMORY_SAFETY = System.getProperty("flw.debugMemorySafety") != null;
static final Cleaner CLEANER = Cleaner.create();
private static long cpuMemory = 0;
@ -54,7 +58,7 @@ public class FlwMemoryTracker {
public static long realloc(long ptr, long size) {
ptr = MemoryUtil.nmemRealloc(ptr, size);
if (ptr == MemoryUtil.NULL) {
throw new OutOfMemoryError("Failed to reallocate " + size + " bytes for address 0x" + Long.toHexString(ptr));
throw new OutOfMemoryError("Failed to reallocate " + size + " bytes for address " + StringUtil.formatAddress(ptr));
}
return ptr;
}

View file

@ -26,18 +26,26 @@ public sealed interface MemoryBlock permits MemoryBlockImpl {
void free();
static MemoryBlock malloc(long size) {
return MemoryBlockImpl.mallocBlock(size);
if (FlwMemoryTracker.DEBUG_MEMORY_SAFETY) {
return DebugMemoryBlockImpl.malloc(size);
} else {
return MemoryBlockImpl.malloc(size);
}
}
static MemoryBlock mallocTracked(long size) {
return TrackedMemoryBlockImpl.mallocBlockTracked(size);
return TrackedMemoryBlockImpl.malloc(size);
}
static MemoryBlock calloc(long num, long size) {
return MemoryBlockImpl.callocBlock(num, size);
if (FlwMemoryTracker.DEBUG_MEMORY_SAFETY) {
return DebugMemoryBlockImpl.calloc(num, size);
} else {
return MemoryBlockImpl.calloc(num, size);
}
}
static MemoryBlock callocTracked(long num, long size) {
return TrackedMemoryBlockImpl.callocBlockTracked(num, size);
return TrackedMemoryBlockImpl.calloc(num, size);
}
}

View file

@ -4,7 +4,7 @@ import java.nio.ByteBuffer;
import org.lwjgl.system.MemoryUtil;
sealed class MemoryBlockImpl implements MemoryBlock permits TrackedMemoryBlockImpl {
non-sealed class MemoryBlockImpl implements MemoryBlock {
final long ptr;
final long size;
@ -86,13 +86,13 @@ sealed class MemoryBlockImpl implements MemoryBlock permits TrackedMemoryBlockIm
freeInner();
}
static MemoryBlock mallocBlock(long size) {
static MemoryBlock malloc(long size) {
MemoryBlock block = new MemoryBlockImpl(FlwMemoryTracker.malloc(size), size);
FlwMemoryTracker._allocCPUMemory(block.size());
return block;
}
static MemoryBlock callocBlock(long num, long size) {
static MemoryBlock calloc(long num, long size) {
MemoryBlock block = new MemoryBlockImpl(FlwMemoryTracker.calloc(num, size), num * size);
FlwMemoryTracker._allocCPUMemory(block.size());
return block;

View file

@ -2,7 +2,7 @@ package com.jozufozu.flywheel.backend.memory;
import java.lang.ref.Cleaner;
final class TrackedMemoryBlockImpl extends MemoryBlockImpl {
class TrackedMemoryBlockImpl extends MemoryBlockImpl {
final CleaningAction cleaningAction;
final Cleaner.Cleanable cleanable;
@ -24,13 +24,13 @@ final class TrackedMemoryBlockImpl extends MemoryBlockImpl {
cleanable.clean();
}
static MemoryBlock mallocBlockTracked(long size) {
static MemoryBlock malloc(long size) {
MemoryBlock block = new TrackedMemoryBlockImpl(FlwMemoryTracker.malloc(size), size, FlwMemoryTracker.CLEANER);
FlwMemoryTracker._allocCPUMemory(block.size());
return block;
}
static MemoryBlock callocBlockTracked(long num, long size) {
static MemoryBlock calloc(long num, long size) {
MemoryBlock block = new TrackedMemoryBlockImpl(FlwMemoryTracker.calloc(num, size), num * size, FlwMemoryTracker.CLEANER);
FlwMemoryTracker._allocCPUMemory(block.size());
return block;

View file

@ -85,7 +85,7 @@ public class QuadConverter {
}
// make sure this gets reset first, so it has a chance to repopulate
public static void onRendererReload(ReloadRenderersEvent event) {
public static void onReloadRenderers(ReloadRenderersEvent event) {
if (INSTANCE != null) {
INSTANCE.delete();
INSTANCE = null;

View file

@ -70,7 +70,7 @@ public class ProgramCompiler extends Memoizer<ProgramCompiler.Context, GlProgram
value.delete();
}
public static void invalidateAll(ReloadRenderersEvent ignored) {
public static void onReloadRenderers(ReloadRenderersEvent event) {
INSTANCE.invalidate();
}

View file

@ -9,11 +9,11 @@ import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
import com.jozufozu.flywheel.api.vertex.VertexListProvider;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.backend.memory.MemoryBlock;
import com.jozufozu.flywheel.core.Materials;
import com.jozufozu.flywheel.core.vertex.Formats;
import com.jozufozu.flywheel.core.vertex.VertexListProviderRegistry;
import com.mojang.blaze3d.vertex.BufferBuilder.DrawState;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.mojang.datafixers.util.Pair;
@ -58,7 +58,7 @@ public class ModelUtil {
long srcPtr = MemoryUtil.memAddress(src);
long dstPtr = dst.ptr();
ReusableVertexList srcList = VertexListProviderRegistry.getOrInfer(srcFormat).createVertexList();
ReusableVertexList srcList = VertexListProvider.get(srcFormat).createVertexList();
ReusableVertexList dstList = dstVertexType.createVertexList();
srcList.ptr(srcPtr);
dstList.ptr(dstPtr);

View file

@ -41,7 +41,7 @@ public class Models {
return stack;
}
public static void onReload(ReloadRenderersEvent event) {
public static void onReloadRenderers(ReloadRenderersEvent event) {
deleteAll(BLOCK_STATE.values());
deleteAll(PARTIAL.values());
deleteAll(PARTIAL_DIR.values());

View file

@ -1,7 +1,7 @@
package com.jozufozu.flywheel.core.structs.transformed;
import com.jozufozu.flywheel.core.structs.ColoredLitWriter;
import com.jozufozu.flywheel.util.MatrixWrite;
import com.jozufozu.flywheel.extension.MatrixWrite;
public class TransformedWriter extends ColoredLitWriter<TransformedPart> {
public static final TransformedWriter INSTANCE = new TransformedWriter();

View file

@ -8,7 +8,7 @@ import com.jozufozu.flywheel.core.Components;
import com.jozufozu.flywheel.core.RenderContext;
import com.jozufozu.flywheel.core.source.FileResolution;
import com.jozufozu.flywheel.event.BeginFrameEvent;
import com.jozufozu.flywheel.util.MatrixWrite;
import com.jozufozu.flywheel.extension.MatrixWrite;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.Vec3i;

View file

@ -6,16 +6,6 @@ public abstract class AbstractVertexList implements ReusableVertexList {
protected long ptr;
protected int vertexCount;
@Override
public int getVertexCount() {
return vertexCount;
}
@Override
public void setVertexCount(int vertexCount) {
this.vertexCount = vertexCount;
}
@Override
public long ptr() {
return ptr;
@ -25,4 +15,14 @@ public abstract class AbstractVertexList implements ReusableVertexList {
public void ptr(long ptr) {
this.ptr = ptr;
}
@Override
public int getVertexCount() {
return vertexCount;
}
@Override
public void setVertexCount(int vertexCount) {
this.vertexCount = vertexCount;
}
}

View file

@ -50,15 +50,4 @@ public class InferredVertexFormatInfo {
this.lightOffset = lightOffset;
this.normalOffset = normalOffset;
}
protected InferredVertexFormatInfo(InferredVertexFormatInfo formatInfo) {
format = formatInfo.format;
stride = formatInfo.stride;
positionOffset = formatInfo.positionOffset;
colorOffset = formatInfo.colorOffset;
textureOffset = formatInfo.textureOffset;
overlayOffset = formatInfo.overlayOffset;
lightOffset = formatInfo.lightOffset;
normalOffset = formatInfo.normalOffset;
}
}

View file

@ -4,18 +4,33 @@ import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
import com.jozufozu.flywheel.util.RenderMath;
import com.mojang.blaze3d.vertex.VertexFormat;
import net.minecraft.client.renderer.texture.OverlayTexture;
public final class InferredVertexListImpl extends InferredVertexFormatInfo implements ReusableVertexList {
private long ptr;
private int vertexCount;
public class InferredVertexListImpl extends AbstractVertexList implements ReusableVertexList {
protected final VertexFormat format;
protected final int stride;
protected final int positionOffset;
protected final int colorOffset;
protected final int textureOffset;
protected final int overlayOffset;
protected final int lightOffset;
protected final int normalOffset;
public InferredVertexListImpl(InferredVertexFormatInfo formatInfo) {
super(formatInfo);
format = formatInfo.format;
stride = formatInfo.stride;
positionOffset = formatInfo.positionOffset;
colorOffset = formatInfo.colorOffset;
textureOffset = formatInfo.textureOffset;
overlayOffset = formatInfo.overlayOffset;
lightOffset = formatInfo.lightOffset;
normalOffset = formatInfo.normalOffset;
}
private long idxPtr(int index) {
protected long idxPtr(int index) {
return ptr + index * stride;
}
@ -187,28 +202,8 @@ public final class InferredVertexListImpl extends InferredVertexFormatInfo imple
MemoryUtil.memPutByte(idxPtr(index) + normalOffset + 2, RenderMath.nb(normalZ));
}
@Override
public int getVertexCount() {
return vertexCount;
}
@Override
public long ptr() {
return ptr;
}
@Override
public void ptr(long ptr) {
this.ptr = ptr;
}
@Override
public void shiftPtr(int vertices) {
ptr += vertices * stride;
}
@Override
public void setVertexCount(int vertexCount) {
this.vertexCount = vertexCount;
}
}

View file

@ -1,55 +0,0 @@
package com.jozufozu.flywheel.core.vertex;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.vertex.VertexListProvider;
import com.mojang.blaze3d.vertex.VertexFormat;
public class VertexListProviderRegistry {
private static final Map<VertexFormat, Holder> HOLDERS = new ConcurrentHashMap<>();
private static Holder getOrCreateHolder(VertexFormat format) {
return HOLDERS.computeIfAbsent(format, Holder::new);
}
public static void register(VertexFormat format, VertexListProvider provider) {
getOrCreateHolder(format).registeredProvider = provider;
}
@Nullable
public static VertexListProvider get(VertexFormat format) {
return getOrCreateHolder(format).get();
}
public static VertexListProvider getOrInfer(VertexFormat format) {
return getOrCreateHolder(format).getOrInfer();
}
private static class Holder {
public final VertexFormat format;
public VertexListProvider registeredProvider;
public VertexListProvider inferredProvider;
public Holder(VertexFormat format) {
this.format = format;
}
@Nullable
public VertexListProvider get() {
return registeredProvider;
}
public VertexListProvider getOrInfer() {
if (registeredProvider != null) {
return registeredProvider;
}
if (inferredProvider == null) {
inferredProvider = new InferredVertexListProviderImpl(format);
}
return inferredProvider;
}
}
}

View file

@ -1,7 +1,9 @@
package com.jozufozu.flywheel.backend.instancing.blockentity;
package com.jozufozu.flywheel.extension;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstancingController;
import net.minecraft.world.level.block.entity.BlockEntity;
public interface BlockEntityTypeExtension<T extends BlockEntity> {

View file

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.backend.instancing.batching;
package com.jozufozu.flywheel.extension;
import java.nio.ByteBuffer;

View file

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.util;
package com.jozufozu.flywheel.extension;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.world.entity.Entity;

View file

@ -1,7 +1,9 @@
package com.jozufozu.flywheel.backend.instancing.entity;
package com.jozufozu.flywheel.extension;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstancingController;
import net.minecraft.world.entity.Entity;
public interface EntityTypeExtension<T extends Entity> {

View file

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.util;
package com.jozufozu.flywheel.extension;
import java.nio.ByteBuffer;

View file

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.util;
package com.jozufozu.flywheel.extension;
import com.jozufozu.flywheel.backend.instancing.batching.DrawBuffer;

View file

@ -0,0 +1,19 @@
package com.jozufozu.flywheel.extension;
import com.jozufozu.flywheel.api.vertex.VertexListProvider;
import com.mojang.blaze3d.vertex.VertexFormat;
/**
* Duck interface to make VertexFormat store a VertexListProvider.
*
* @see VertexFormat
*/
public interface VertexFormatExtension {
/**
* @return The VertexListProvider associated with this VertexFormat.
*/
VertexListProvider flywheel$getVertexListProvider();
void flywheel$setVertexListProvider(VertexListProvider provider);
}

View file

@ -5,7 +5,7 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstancingController;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityTypeExtension;
import com.jozufozu.flywheel.extension.BlockEntityTypeExtension;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;

View file

@ -8,7 +8,7 @@ import org.lwjgl.system.MemoryUtil;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import com.jozufozu.flywheel.backend.instancing.batching.BufferBuilderExtension;
import com.jozufozu.flywheel.extension.BufferBuilderExtension;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.mojang.blaze3d.vertex.VertexFormatElement;

View file

@ -13,13 +13,13 @@ import com.mojang.blaze3d.vertex.VertexFormat;
@Mixin(BufferUploader.class)
public class BufferUploaderMixin {
@Shadow
@Nullable
private static VertexFormat lastFormat;
// Stop BufferUploader from clearing buffer state if nothing is bound
@Inject(method = "reset", at = @At("HEAD"))
private static void stopBufferUploaderFromClearingBufferStateIfNothingIsBound(CallbackInfo ci) {
private static void flywheel$onReset(CallbackInfo ci) {
// Trust our tracker over BufferUploader's.
if (GlStateTracker.getVertexArray() == 0) {
lastFormat = null;

View file

@ -16,9 +16,8 @@ import net.minecraft.world.level.block.entity.BlockEntity;
@Mixin(targets = "net.minecraft.client.renderer.chunk.ChunkRenderDispatcher$RenderChunk$RebuildTask")
public class ChunkRebuildHooksMixin {
@Inject(method = "handleBlockEntity", at = @At("HEAD"), cancellable = true)
private <E extends BlockEntity> void addAndFilterBEs(ChunkRenderDispatcher.CompiledChunk compiledChunk, Set<BlockEntity> set, E be, CallbackInfo ci) {
private <E extends BlockEntity> void flywheel$addAndFilterBEs(ChunkRenderDispatcher.CompiledChunk compiledChunk, Set<BlockEntity> set, E be, CallbackInfo ci) {
if (Backend.canUseInstancing(be.getLevel())) {
if (InstancedRenderRegistry.canInstance(be.getType()))
InstancedRenderDispatcher.getBlockEntities(be.getLevel()).queueAdd(be);

View file

@ -11,7 +11,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.google.common.collect.Lists;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
import com.jozufozu.flywheel.util.ClientLevelExtension;
import com.jozufozu.flywheel.extension.ClientLevelExtension;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.world.entity.Entity;
@ -19,7 +19,6 @@ import net.minecraft.world.level.entity.LevelEntityGetter;
@Mixin(ClientLevel.class)
public abstract class ClientLevelMixin implements ClientLevelExtension {
@Shadow
protected abstract LevelEntityGetter<Entity> getEntities();
@ -29,7 +28,7 @@ public abstract class ClientLevelMixin implements ClientLevelExtension {
}
@Inject(method = "entitiesForRendering", at = @At("RETURN"), cancellable = true)
private void filterEntities(CallbackInfoReturnable<Iterable<Entity>> cir) {
private void flywheel$filterEntities(CallbackInfoReturnable<Iterable<Entity>> cir) {
if (Backend.isOn()) {
Iterable<Entity> entities = cir.getReturnValue();
ArrayList<Entity> filtered = Lists.newArrayList(entities);

View file

@ -5,7 +5,7 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstancingController;
import com.jozufozu.flywheel.backend.instancing.entity.EntityTypeExtension;
import com.jozufozu.flywheel.extension.EntityTypeExtension;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;

View file

@ -16,9 +16,8 @@ import net.minecraft.client.renderer.LightTexture;
@Mixin(LevelRenderer.class)
public class FixFabulousDepthMixin {
@Inject(method = "renderLevel", at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/client/renderer/PostChain;process(F)V"))
private void disableTransparencyShaderDepth(PoseStack p_228426_1_, float p_228426_2_, long p_228426_3_, boolean p_228426_5_, Camera p_228426_6_, GameRenderer p_228426_7_, LightTexture p_228426_8_, Matrix4f p_228426_9_, CallbackInfo ci) {
private void flywheel$disableTransparencyShaderDepth(PoseStack poseStack, float partialTick, long finishNanoTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projectionMatrix, CallbackInfo ci) {
GlStateManager._depthMask(false);
}
}

View file

@ -11,23 +11,22 @@ import net.minecraft.client.renderer.FogRenderer;
@Mixin(FogRenderer.class)
public class FogUpdateMixin {
private static void flywheel$updateFog() {
Components.FOG_PROVIDER.update();
}
@Inject(method = "setupNoFog", at = @At("TAIL"))
private static void onNoFog(CallbackInfo ci) {
private static void flywheel$onNoFog(CallbackInfo ci) {
flywheel$updateFog();
}
@Inject(method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;FZF)V", remap = false, at = @At("TAIL"))
private static void onFog(CallbackInfo ci) {
private static void flywheel$onFog(CallbackInfo ci) {
flywheel$updateFog();
}
@Inject(method = "levelFogColor", at = @At("TAIL"))
private static void onFogColor(CallbackInfo ci) {
private static void flywheel$onFogColor(CallbackInfo ci) {
flywheel$updateFog();
}
private static void flywheel$updateFog() {
Components.FOG_PROVIDER.update();
}
}

View file

@ -11,19 +11,18 @@ import com.mojang.blaze3d.platform.GlStateManager;
@Mixin(GlStateManager.class)
public class GlStateManagerMixin {
@Inject(method = "_glBindBuffer", at = @At("TAIL"))
private static void onBindBuffer(int pTarget, int pBuffer, CallbackInfo ci) {
private static void flywheel$onBindBuffer(int pTarget, int pBuffer, CallbackInfo ci) {
GlStateTracker._setBuffer(GlBufferType.fromTarget(pTarget), pBuffer);
}
@Inject(method = "_glBindVertexArray", at = @At("TAIL"))
private static void onBindVertexArray(int pArray, CallbackInfo ci) {
private static void flywheel$onBindVertexArray(int pArray, CallbackInfo ci) {
GlStateTracker._setVertexArray(pArray);
}
@Inject(method = "_glUseProgram", at = @At("TAIL"))
private static void onUseProgram(int pProgram, CallbackInfo ci) {
private static void flywheel$onUseProgram(int pProgram, CallbackInfo ci) {
GlStateTracker._setProgram(pProgram);
}
}

View file

@ -16,14 +16,13 @@ import net.minecraft.world.level.chunk.LevelChunk;
@Mixin(LevelChunk.class)
public class InstanceAddMixin {
@Shadow
@Final
Level level;
@Inject(method = "setBlockEntity",
at = @At(value = "INVOKE_ASSIGN", target = "Ljava/util/Map;put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"))
private void blockEntityAdded(BlockEntity be, CallbackInfo ci) {
private void flywheel$onBlockEntityAdded(BlockEntity be, CallbackInfo ci) {
if (level.isClientSide && Backend.isOn()) {
InstancedRenderDispatcher.getBlockEntities(this.level)
.add(be);

View file

@ -16,13 +16,12 @@ import net.minecraft.world.level.block.entity.BlockEntity;
@Mixin(BlockEntity.class)
public class InstanceRemoveMixin {
@Shadow
@Nullable
protected Level level;
@Inject(at = @At("TAIL"), method = "setRemoved")
private void removeInstance(CallbackInfo ci) {
private void flywheel$removeInstance(CallbackInfo ci) {
if (level instanceof ClientLevel && Backend.isOn()) {
InstancedRenderDispatcher.getBlockEntities(this.level)
.remove((BlockEntity) (Object) this);

View file

@ -24,7 +24,7 @@ public class LevelRendererInstanceUpdateMixin {
* This gets called when a block is marked for rerender by vanilla.
*/
@Inject(at = @At("TAIL"), method = "setBlockDirty(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockState;)V")
private void checkUpdate(BlockPos pos, BlockState lastState, BlockState newState, CallbackInfo ci) {
private void flywheel$checkUpdate(BlockPos pos, BlockState lastState, BlockState newState, CallbackInfo ci) {
if (!Backend.isOn()) {
return;
}

View file

@ -28,7 +28,7 @@ import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.RenderBuffers;
import net.minecraftforge.common.MinecraftForge;
@Mixin(value = LevelRenderer.class, priority = 1001) // Higher priority to go after sodium
@Mixin(value = LevelRenderer.class, priority = 1001) // Higher priority to go after Sodium
public class LevelRendererMixin {
@Shadow
private ClientLevel level;
@ -38,20 +38,20 @@ public class LevelRendererMixin {
private RenderBuffers renderBuffers;
@Unique
private RenderContext renderContext;
private RenderContext flywheel$renderContext;
@Inject(at = @At("HEAD"), method = "renderLevel")
private void beginRender(PoseStack pPoseStack, float pPartialTick, long pFinishNanoTime, boolean pRenderBlockOutline, Camera pCamera, GameRenderer pGameRenderer, LightTexture pLightTexture, Matrix4f pProjectionMatrix, CallbackInfo ci) {
renderContext = new RenderContext((LevelRenderer) (Object) this, level, pPoseStack, RenderContext.createViewProjection(pPoseStack, pProjectionMatrix), pProjectionMatrix, renderBuffers, pCamera);
private void flywheel$beginRender(PoseStack pPoseStack, float pPartialTick, long pFinishNanoTime, boolean pRenderBlockOutline, Camera pCamera, GameRenderer pGameRenderer, LightTexture pLightTexture, Matrix4f pProjectionMatrix, CallbackInfo ci) {
flywheel$renderContext = new RenderContext((LevelRenderer) (Object) this, level, pPoseStack, RenderContext.createViewProjection(pPoseStack, pProjectionMatrix), pProjectionMatrix, renderBuffers, pCamera);
try (var restoreState = GlStateTracker.getRestoreState()) {
MinecraftForge.EVENT_BUS.post(new BeginFrameEvent(renderContext));
MinecraftForge.EVENT_BUS.post(new BeginFrameEvent(flywheel$renderContext));
}
}
@Inject(at = @At("TAIL"), method = "renderLevel")
private void endRender(PoseStack pPoseStack, float pPartialTick, long pFinishNanoTime, boolean pRenderBlockOutline, Camera pCamera, GameRenderer pGameRenderer, LightTexture pLightTexture, Matrix4f pProjectionMatrix, CallbackInfo ci) {
renderContext = null;
private void flywheel$endRender(PoseStack pPoseStack, float pPartialTick, long pFinishNanoTime, boolean pRenderBlockOutline, Camera pCamera, GameRenderer pGameRenderer, LightTexture pLightTexture, Matrix4f pProjectionMatrix, CallbackInfo ci) {
flywheel$renderContext = null;
}
@Inject(at = @At("TAIL"), method = "allChanged")
@ -61,92 +61,92 @@ public class LevelRendererMixin {
MinecraftForge.EVENT_BUS.post(new ReloadRenderersEvent(level));
}
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderBuffers;crumblingBufferSource()Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;", ordinal = 2, shift = Shift.BY, by = 2 // after the game renders the breaking overlay normally
), method = "renderLevel")
private void renderCrumbling(PoseStack poseStack, float partialTick, long finishNanoTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projectionMatrix, CallbackInfo ci) {
if (renderContext != null) {
// TODO: Crumbling
}
}
// @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderBuffers;crumblingBufferSource()Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;", ordinal = 2, shift = Shift.BY, by = 2 // after the game renders the breaking overlay normally
// ), method = "renderLevel")
// private void flywheel$renderCrumbling(PoseStack poseStack, float partialTick, long finishNanoTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projectionMatrix, CallbackInfo ci) {
// if (flywheel$renderContext != null) {
// // TODO: Crumbling
// }
// }
// STAGE DISPATCHING
@Unique
private void flywheel$dispatch(RenderStage stage) {
if (renderContext != null) {
if (flywheel$renderContext != null) {
try (var restoreState = GlStateTracker.getRestoreState()) {
MinecraftForge.EVENT_BUS.post(new RenderStageEvent(renderContext, stage));
MinecraftForge.EVENT_BUS.post(new RenderStageEvent(flywheel$renderContext, stage));
}
}
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=sky"))
private void onStage$beforeSky(CallbackInfo ci) {
private void flywheel$onStage$beforeSky(CallbackInfo ci) {
flywheel$dispatch(RenderStage.BEFORE_SKY);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=fog"))
private void onStage$afterSky(CallbackInfo ci) {
private void flywheel$onStage$afterSky(CallbackInfo ci) {
flywheel$dispatch(RenderStage.AFTER_SKY);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=terrain"))
private void onStage$beforeTerrain(CallbackInfo ci) {
private void flywheel$onStage$beforeTerrain(CallbackInfo ci) {
flywheel$dispatch(RenderStage.BEFORE_TERRAIN);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=entities"))
private void onStage$afterSolidTerrain(CallbackInfo ci) {
private void flywheel$onStage$afterSolidTerrain(CallbackInfo ci) {
flywheel$dispatch(RenderStage.AFTER_SOLID_TERRAIN);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderBuffers;bufferSource()Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;", ordinal = 0))
private void onStage$beforeEntities(CallbackInfo ci) {
private void flywheel$onStage$beforeEntities(CallbackInfo ci) {
flywheel$dispatch(RenderStage.BEFORE_ENTITIES);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=blockentities"))
private void onStage$beforeBlockEntities(CallbackInfo ci) {
private void flywheel$onStage$beforeBlockEntities(CallbackInfo ci) {
flywheel$dispatch(RenderStage.AFTER_ENTITIES);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/OutlineBufferSource;endOutlineBatch()V", ordinal = 0))
private void onStage$afterSolidBlockEntities(CallbackInfo ci) {
private void flywheel$onStage$afterSolidBlockEntities(CallbackInfo ci) {
flywheel$dispatch(RenderStage.AFTER_BLOCK_ENTITIES);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch()V", ordinal = 0))
private void onStage$beforeCrumbling(CallbackInfo ci) {
private void flywheel$onStage$beforeCrumbling(CallbackInfo ci) {
flywheel$dispatch(RenderStage.BEFORE_CRUMBLING);
}
@Inject(method = "renderLevel", at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/LevelRenderer;translucentTarget:Lcom/mojang/blaze3d/pipeline/RenderTarget;", opcode = Opcodes.GETFIELD, ordinal = 0))
private void onStage$afterFinalEndBatch$fabulous(CallbackInfo ci) {
private void flywheel$onStage$afterFinalEndBatch$fabulous(CallbackInfo ci) {
flywheel$dispatch(RenderStage.AFTER_FINAL_END_BATCH);
}
@Inject(method = "renderLevel", at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/LevelRenderer;particlesTarget:Lcom/mojang/blaze3d/pipeline/RenderTarget;", opcode = Opcodes.GETFIELD, ordinal = 0))
private void onStage$afterTranslucentTerrain$fabulous(CallbackInfo ci) {
private void flywheel$onStage$afterTranslucentTerrain$fabulous(CallbackInfo ci) {
flywheel$dispatch(RenderStage.AFTER_TRANSLUCENT_TERRAIN);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch()V", ordinal = 2, shift = Shift.AFTER))
private void onStage$afterFinalEndBatch(CallbackInfo ci) {
private void flywheel$onStage$afterFinalEndBatch(CallbackInfo ci) {
flywheel$dispatch(RenderStage.AFTER_FINAL_END_BATCH);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/LevelRenderer;renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLcom/mojang/math/Matrix4f;)V", ordinal = 6, shift = Shift.AFTER))
private void onStage$afterTranslucentTerrain(CallbackInfo ci) {
private void flywheel$onStage$afterTranslucentTerrain(CallbackInfo ci) {
flywheel$dispatch(RenderStage.AFTER_TRANSLUCENT_TERRAIN);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/particle/ParticleEngine;render(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;Lnet/minecraft/client/renderer/LightTexture;Lnet/minecraft/client/Camera;FLnet/minecraft/client/renderer/culling/Frustum;)V", shift = Shift.AFTER))
private void onStage$afterParticles(CallbackInfo ci) {
private void flywheel$onStage$afterParticles(CallbackInfo ci) {
flywheel$dispatch(RenderStage.AFTER_PARTICLES);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/LevelRenderer;renderSnowAndRain(Lnet/minecraft/client/renderer/LightTexture;FDDD)V", shift = Shift.AFTER))
private void onStage$afterWeather(CallbackInfo ci) {
private void flywheel$onStage$afterWeather(CallbackInfo ci) {
flywheel$dispatch(RenderStage.AFTER_WEATHER);
}
}

View file

@ -7,7 +7,6 @@ import net.minecraft.client.Minecraft;
@Mixin(Minecraft.class)
public interface PausedPartialTickAccessor {
@Accessor("pausePartialTick")
float flywheel$getPartialTicksPaused();
}

View file

@ -5,7 +5,7 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import com.jozufozu.flywheel.backend.instancing.batching.DrawBuffer;
import com.jozufozu.flywheel.util.RenderTypeExtension;
import com.jozufozu.flywheel.extension.RenderTypeExtension;
import net.minecraft.client.renderer.RenderType;
@ -18,7 +18,7 @@ public class RenderTypeMixin implements RenderTypeExtension {
@NotNull
public DrawBuffer flywheel$getDrawBuffer() {
if (flywheel$drawBuffer == null) {
flywheel$drawBuffer = new DrawBuffer((RenderType) (Object) this);
flywheel$drawBuffer = new DrawBuffer(((RenderType) (Object) this).format());
}
return flywheel$drawBuffer;
}

View file

@ -0,0 +1,24 @@
package com.jozufozu.flywheel.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import com.jozufozu.flywheel.api.vertex.VertexListProvider;
import com.jozufozu.flywheel.extension.VertexFormatExtension;
import com.mojang.blaze3d.vertex.VertexFormat;
@Mixin(VertexFormat.class)
public class VertexFormatMixin implements VertexFormatExtension {
@Unique
private VertexListProvider flywheel$vertexListProvider;
@Override
public VertexListProvider flywheel$getVertexListProvider() {
return flywheel$vertexListProvider;
}
@Override
public void flywheel$setVertexListProvider(VertexListProvider provider) {
flywheel$vertexListProvider = provider;
}
}

View file

@ -1,6 +1,8 @@
package com.jozufozu.flywheel.mixin.light;
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;
@ -15,6 +17,9 @@ import net.minecraft.world.level.chunk.ChunkSource;
@Mixin(ClientChunkCache.class)
public abstract class LightUpdateMixin extends ChunkSource {
@Shadow
@Final
ClientLevel level;
/**
* JUSTIFICATION: This method is called after a lighting tick once per subchunk where a
@ -23,11 +28,8 @@ public abstract class LightUpdateMixin extends ChunkSource {
* and we should too.
*/
@Inject(at = @At("HEAD"), method = "onLightUpdate")
private void onLightUpdate(LightLayer type, SectionPos pos, CallbackInfo ci) {
ClientChunkCache thi = ((ClientChunkCache) (Object) this);
ClientLevel world = (ClientLevel) thi.getLevel();
LightUpdater.get(world)
private void flywheel$onLightUpdate(LightLayer type, SectionPos pos, CallbackInfo ci) {
LightUpdater.get(level)
.onLightUpdate(type, pos.asLong());
}
}

View file

@ -15,9 +15,8 @@ import net.minecraft.network.protocol.game.ClientboundLightUpdatePacket;
@Mixin(ClientPacketListener.class)
public class NetworkLightUpdateMixin {
@Inject(at = @At("TAIL"), method = "handleLightUpdatePacket")
private void onLightPacket(ClientboundLightUpdatePacket packet, CallbackInfo ci) {
private void flywheel$onLightPacket(ClientboundLightUpdatePacket packet, CallbackInfo ci) {
RenderWork.enqueue(() -> {
ClientLevel world = Minecraft.getInstance().level;

View file

@ -6,12 +6,11 @@ import org.lwjgl.system.MemoryUtil;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import com.jozufozu.flywheel.util.MatrixWrite;
import com.jozufozu.flywheel.extension.MatrixWrite;
import com.mojang.math.Matrix3f;
@Mixin(Matrix3f.class)
public abstract class Matrix3fMixin implements MatrixWrite {
@Shadow protected float m00;
@Shadow protected float m01;
@Shadow protected float m02;

View file

@ -6,12 +6,11 @@ import org.lwjgl.system.MemoryUtil;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import com.jozufozu.flywheel.util.MatrixWrite;
import com.jozufozu.flywheel.extension.MatrixWrite;
import com.mojang.math.Matrix4f;
@Mixin(Matrix4f.class)
public abstract class Matrix4fMixin implements MatrixWrite {
@Shadow protected float m00;
@Shadow protected float m01;
@Shadow protected float m02;

View file

@ -8,34 +8,33 @@ import com.mojang.math.Quaternion;
@Mixin(PoseStack.class)
public abstract class PoseStackMixin implements TransformStack {
@Override
public TransformStack multiply(Quaternion quaternion) {
((PoseStack)(Object) this).mulPose(quaternion);
((PoseStack) (Object) this).mulPose(quaternion);
return this;
}
@Override
public TransformStack scale(float factorX, float factorY, float factorZ) {
((PoseStack)(Object) this).scale(factorX, factorY, factorZ);
((PoseStack) (Object) this).scale(factorX, factorY, factorZ);
return this;
}
@Override
public TransformStack pushPose() {
((PoseStack)(Object) this).pushPose();
((PoseStack) (Object) this).pushPose();
return this;
}
@Override
public TransformStack popPose() {
((PoseStack)(Object) this).popPose();
((PoseStack) (Object) this).popPose();
return this;
}
@Override
public TransformStack translate(double x, double y, double z) {
((PoseStack)(Object) this).translate(x, y, z);
((PoseStack) (Object) this).translate(x, y, z);
return this;
}
}

View file

@ -45,6 +45,10 @@ public class StringUtil {
}
}
public static String formatAddress(long address) {
return "0x" + Long.toHexString(address);
}
public static String args(String functionName, Object... args) {
return functionName + '(' + Arrays.stream(args)

View file

@ -1,7 +0,0 @@
package com.jozufozu.flywheel.util.transform;
public interface TStack<Self> {
Self pushPose();
Self popPose();
}

View file

@ -2,7 +2,11 @@ package com.jozufozu.flywheel.util.transform;
import com.mojang.blaze3d.vertex.PoseStack;
public interface TransformStack extends Transform<TransformStack>, TStack<TransformStack> {
public interface TransformStack extends Transform<TransformStack> {
TransformStack pushPose();
TransformStack popPose();
static TransformStack cast(PoseStack stack) {
return (TransformStack) stack;
}

View file

@ -22,6 +22,7 @@
"LevelRendererMixin",
"PausedPartialTickAccessor",
"RenderTypeMixin",
"VertexFormatMixin",
"light.LightUpdateMixin",
"light.NetworkLightUpdateMixin",
"matrix.Matrix3fMixin",