diff --git a/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/DynamicElement.java b/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/DynamicElement.java index b75bb2e..9a2dc7c 100644 --- a/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/DynamicElement.java +++ b/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/DynamicElement.java @@ -1,8 +1,6 @@ package com.noxcrew.noxesium.feature.ui.render; -import com.mojang.blaze3d.platform.GlStateManager; import com.noxcrew.noxesium.NoxesiumMod; -import com.noxcrew.noxesium.feature.ui.BufferHelper; import com.noxcrew.noxesium.feature.ui.render.api.PerSecondRepeatingTask; import com.noxcrew.noxesium.feature.ui.render.buffer.ElementBuffer; import com.noxcrew.noxesium.feature.ui.render.buffer.SnapshotableElementBuffer; @@ -173,7 +171,7 @@ public void trySnapshot() { for (var buffer : buffers) { buffer.snapshot(); } - // SharedVertexBuffer.rebindMainRenderTarget(); + SharedVertexBuffer.rebindMainRenderTarget(); } @Override @@ -188,6 +186,7 @@ public boolean update(long nanoTime, GuiGraphics guiGraphics, Runnable draw) { if (result) { hasRedrawnRecently = true; } + trySnapshot(); return result; } @@ -201,6 +200,14 @@ public List getBuffers() { return (List) (List) buffers; } + @Override + protected void onBufferUntargeted(ElementBuffer buffer) { + super.onBufferUntargeted(buffer); + + // Before targeting a new buffer we attempt to snapshot the previous one! + trySnapshot(); + } + @Override protected void onBufferRemoved(ElementBuffer buffer) { super.onBufferRemoved(buffer); diff --git a/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/NoxesiumUiRenderState.java b/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/NoxesiumUiRenderState.java index 4cc7a3a..1fe544b 100644 --- a/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/NoxesiumUiRenderState.java +++ b/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/NoxesiumUiRenderState.java @@ -6,13 +6,12 @@ import com.noxcrew.noxesium.feature.ui.render.api.NoxesiumRenderState; import com.noxcrew.noxesium.feature.ui.render.api.PerSecondRepeatingTask; import com.noxcrew.noxesium.feature.ui.render.buffer.BufferData; -import net.minecraft.client.DeltaTracker; -import net.minecraft.client.gui.GuiGraphics; - import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.CopyOnWriteArrayList; +import net.minecraft.client.DeltaTracker; +import net.minecraft.client.gui.GuiGraphics; /** * Stores the entire render state of the current UI. diff --git a/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/api/NoxesiumRenderState.java b/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/api/NoxesiumRenderState.java index 1940391..3b1b2ee 100644 --- a/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/api/NoxesiumRenderState.java +++ b/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/api/NoxesiumRenderState.java @@ -1,7 +1,6 @@ package com.noxcrew.noxesium.feature.ui.render.api; import com.noxcrew.noxesium.feature.ui.render.DynamicElement; - import java.io.Closeable; import java.util.List; @@ -20,15 +19,6 @@ public abstract class NoxesiumRenderState implements Closeable { */ public abstract List getDynamics(); - /** - * Attempts to take a snapshot if required. - */ - public void trySnapshot() { - for (var dynamic : getDynamics()) { - dynamic.trySnapshot(); - } - } - /** * Ticks this render state. */ diff --git a/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/api/NoxesiumRenderStateHolder.java b/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/api/NoxesiumRenderStateHolder.java index 08f1c89..0d77e0d 100644 --- a/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/api/NoxesiumRenderStateHolder.java +++ b/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/api/NoxesiumRenderStateHolder.java @@ -29,19 +29,6 @@ default void updateRenderFramerate() { } } - /** - * Triggers a snapshot attempt. - */ - default void trySnapshot() { - // Ignore if not on dynamic mode. - // if (!NoxesiumMod.getInstance().getConfig().shouldUseDynamicUiLimiting()) return; - - var state = get(); - if (state != null) { - state.trySnapshot(); - } - } - /** * Indicates that a check should run the very next frame. */ @@ -50,7 +37,7 @@ default void requestCheck() { // However, if we are using dynamic UI limiting we want to make // sure we always draw on frames after a client tick happened as // it has the newest frame data. - // if (!NoxesiumMod.getInstance().getConfig().shouldUseDynamicUiLimiting()) return; + if (!NoxesiumMod.getInstance().getConfig().shouldUseDynamicUiLimiting()) return; var state = get(); if (state != null) { diff --git a/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/buffer/SnapshotableElementBuffer.java b/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/buffer/SnapshotableElementBuffer.java index fdeab6e..360a6e3 100644 --- a/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/buffer/SnapshotableElementBuffer.java +++ b/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/buffer/SnapshotableElementBuffer.java @@ -1,21 +1,20 @@ package com.noxcrew.noxesium.feature.ui.render.buffer; +import com.google.common.base.Preconditions; import com.mojang.blaze3d.buffers.BufferType; import com.mojang.blaze3d.buffers.BufferUsage; import com.mojang.blaze3d.buffers.GpuBuffer; import com.mojang.blaze3d.buffers.GpuFence; import com.mojang.blaze3d.platform.GlStateManager; +import java.nio.ByteBuffer; + import com.noxcrew.noxesium.feature.ui.render.SharedVertexBuffer; -import net.minecraft.client.Minecraft; -import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL21; import org.lwjgl.opengl.GL30; -import org.lwjgl.opengl.GL40; +import org.lwjgl.opengl.GL30C; import org.lwjgl.opengl.GL44; -import java.nio.ByteBuffer; - /** * An element buffer that also has an attached PBO * and bound buffer so it can be snapshot. @@ -76,27 +75,18 @@ public boolean canSnapshot() { * Snapshots the current buffer contents to a PBO. */ public void snapshot() { - // Bind the frame buffer so we can snapshot from it - var start = System.nanoTime(); - // GlStateManager._glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, target.frameBufferId); + // Bind the frame buffer for reading (might already be bound but we check again) + SharedVertexBuffer.allowRebindingTarget = true; + GlStateManager._glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, target.frameBufferId); + SharedVertexBuffer.allowRebindingTarget = false; - // Bind the PBO to tell the GPU to read the frame buffer's - // texture into it directly + // Bind the PBO we currently want to use pbos[currentIndex].bind(); - System.out.println("bind took " + (System.nanoTime() - start) + " ns"); - start = System.nanoTime(); - - GL11.glBindTexture(GL11.GL_TEXTURE_2D, target.getColorTextureId()); - GL11.glGetTexImage( - GL11.GL_TEXTURE_2D, - 0, - GL30.GL_RGBA, - GL11.GL_UNSIGNED_BYTE, - 0 - ); - // GL11.glReadPixels(0, 0, lastWidth, lastHeight, GL30.GL_RGBA, GL11.GL_UNSIGNED_BYTE, 0); - System.out.println("read took " + (System.nanoTime() - start) + " ns"); + // Read the contents of the frame buffer into the PBO + // TODO This call seems to be taking up to 0.3ms instead of being instant. It's unclear + // what exactly is causing that time and it's very hard to find any information. + GL11.glReadPixels(0, 0, lastWidth, lastHeight, GL30.GL_RGBA, GL11.GL_UNSIGNED_BYTE, 0); // Unbind the PBO so it doesn't get modified afterwards GlStateManager._glBindBuffer(GL21.GL_PIXEL_PACK_BUFFER, 0); @@ -117,9 +107,9 @@ protected void configure(int width, int height) { if (pbos == null) { pbos = new GpuBuffer[2]; } - /*if (buffers == null) { + if (buffers == null) { buffers = new ByteBuffer[2]; - }*/ + } for (var i = 0; i < 2; i++) { if (pbos[i] == null) { pbos[i] = new GpuBuffer(BufferType.PIXEL_PACK, BufferUsage.STREAM_READ, 0); @@ -128,7 +118,7 @@ protected void configure(int width, int height) { lastWidth = width; lastHeight = height; - /*if (buffers[i] == null) { + if (buffers[i] == null) { // Configure the buffer to have a persistent size so we can keep it bound permanently var flags = GL30C.GL_MAP_READ_BIT | GL44.GL_MAP_PERSISTENT_BIT | GL44.GL_MAP_COHERENT_BIT; GL44.glBufferStorage(GL30.GL_PIXEL_PACK_BUFFER, pbos[i].size, flags); @@ -136,10 +126,10 @@ protected void configure(int width, int height) { // Create a persistent buffer to the PBOs contents buffers[i] = Preconditions.checkNotNull( GL30.glMapBufferRange(GL30.GL_PIXEL_PACK_BUFFER, 0, pbos[i].size, flags)); - }*/ + } } - // Unbind the PBOs + // Unbind the PBO as they are bound while resizing GlStateManager._glBindBuffer(GL30.GL_PIXEL_PACK_BUFFER, 0); } diff --git a/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/screen/NoxesiumScreenRenderState.java b/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/screen/NoxesiumScreenRenderState.java index 7038546..659504d 100644 --- a/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/screen/NoxesiumScreenRenderState.java +++ b/common/src/main/java/com/noxcrew/noxesium/feature/ui/render/screen/NoxesiumScreenRenderState.java @@ -7,7 +7,6 @@ import com.noxcrew.noxesium.feature.ui.render.buffer.BufferData; import java.util.ArrayList; import java.util.List; - import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.Screen; diff --git a/common/src/main/java/com/noxcrew/noxesium/mixin/ui/GLFWMixin.java b/common/src/main/java/com/noxcrew/noxesium/mixin/ui/GLFWMixin.java deleted file mode 100644 index b67fa92..0000000 --- a/common/src/main/java/com/noxcrew/noxesium/mixin/ui/GLFWMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.noxcrew.noxesium.mixin.ui; - -import com.noxcrew.noxesium.NoxesiumMod; -import com.noxcrew.noxesium.feature.ui.render.api.NoxesiumRenderStateHolder; -import org.lwjgl.glfw.GLFW; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -/** - * Hooks into frame buffer swapping. - */ -@Mixin(value = GLFW.class, remap = false) -public class GLFWMixin { - - @Inject(method = "glfwSwapBuffers", at = @At("RETURN")) - private static void glfwSwapBuffers(long window, CallbackInfo ci) { - NoxesiumMod.forEachRenderStateHolder(NoxesiumRenderStateHolder::trySnapshot); - } -} diff --git a/common/src/main/resources/noxesium-common.mixins.json b/common/src/main/resources/noxesium-common.mixins.json index a02f4e0..80fedf4 100644 --- a/common/src/main/resources/noxesium-common.mixins.json +++ b/common/src/main/resources/noxesium-common.mixins.json @@ -70,6 +70,5 @@ "defaultRequire": 1 }, "mixins": [ - "ui.GLFWMixin" ] }