Skip to content

Commit

Permalink
More work on untangling this mess
Browse files Browse the repository at this point in the history
  • Loading branch information
Aeltumn committed Jan 8, 2025
1 parent b53f008 commit 52bd975
Show file tree
Hide file tree
Showing 15 changed files with 219 additions and 146 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.noxcrew.noxesium.feature.ui;

import com.mojang.blaze3d.systems.RenderSystem;
import com.noxcrew.noxesium.feature.ui.render.DynamicElement;
import com.noxcrew.noxesium.feature.ui.render.Element;
import com.noxcrew.noxesium.feature.ui.render.SharedVertexBuffer;
import net.minecraft.client.gui.GuiGraphics;
import org.lwjgl.opengl.GL14;
Expand All @@ -27,7 +27,7 @@ public static void bind(GuiGraphics guiGraphics) {
GL14.glBlendColor(1f, 1f, 1f, 1f);

// Pre-enable the blending state
DynamicElement.DEFAULT_BLEND_STATE.apply();
Element.DEFAULT_BLEND_STATE.apply();
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.noxcrew.noxesium.feature.ui.render;

import com.noxcrew.noxesium.NoxesiumMod;
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;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.gui.GuiGraphics;
Expand All @@ -10,42 +13,35 @@
*/
public class DynamicElement extends Element {

private final List<SnapshotElementBuffer> buffers = new ArrayList<>();
private final List<SnapshotableElementBuffer> buffers = new ArrayList<>();
private final PerSecondRepeatingTask nextRender =
new PerSecondRepeatingTask(NoxesiumMod.getInstance().getConfig().maxUiFramerate);

private boolean canCheck = true;

private long nextRender = -1;
private long nextCheck = System.nanoTime() + 1000000000;
private int lastFps = 0;

private boolean movementDirection = false;
private boolean hasBufferLayoutChanged = false;
private long lastChange = System.currentTimeMillis();
private int matches = 0;

/**
* The current fps at which we re-render the UI elements.
* Returns the repeating task used for rendering.
*/
private double renderFps = NoxesiumMod.getInstance().getConfig().maxUiFramerate;
public PerSecondRepeatingTask getRenderTask() {
return nextRender;
}

/**
* Resets the display fps back to the maximum.
*/
private void resetToMax() {
if (!movementDirection) return;
public void resetToMax() {
nextRender.changeFrequency(NoxesiumMod.getInstance().getConfig().maxUiFramerate);

renderFps = NoxesiumMod.getInstance().getConfig().maxUiFramerate;
if (!movementDirection) return;
movementDirection = false;
matches = 0;
lastChange = System.currentTimeMillis();
}

/**
* The current frame rate of this group.
*/
public int renderFramerate() {
return (int) Math.floor(renderFps);
}

/**
* Returns the percentage of matching frames.
*/
Expand All @@ -60,15 +56,6 @@ public int buffers() {
return buffers.size();
}

/**
* Returns the true frame rate, the amount
* of times this element was rendered the last
* second.
*/
public int framerate() {
return lastFps;
}

/**
* Returns whether this element is ready to be considered
* for group merging/joining.
Expand All @@ -77,7 +64,7 @@ public boolean isReady() {
if (needsRedraw()) return false;
if (isNotEmpty()) {
for (var buffer : buffers) {
if (buffer instanceof SnapshotElementBuffer pboBuffer && !pboBuffer.hasValidPBO()) {
if (!buffer.hasValidPBO()) {
return false;
}
}
Expand All @@ -92,15 +79,6 @@ public void requestCheck() {
canCheck = true;
}

/**
* Triggers an update of the render framerate.
*/
public void updateRenderFramerate() {
// Just set the render fps back to the max framerate
// whenever the maximum framerate has changed.
renderFps = NoxesiumMod.getInstance().getConfig().maxUiFramerate;
}

/**
* Returns whether this element is often changing. Used to determine
* when it should be split up this buffer.
Expand All @@ -125,10 +103,11 @@ public boolean isMergeable() {
public void tick() {
// Determine if all buffers are the same,
// return the entire method if any buffer is not ready.
var verdict = !hasChangedLayers;
var verdict = !hasBufferLayoutChanged;
hasBufferLayoutChanged = false;
if (isNotEmpty()) {
for (var buffer : buffers) {
if (buffer instanceof SnapshotElementBuffer pboBuffer) {
if (buffer instanceof SnapshotableElementBuffer pboBuffer) {
// Process the snapshots
var snapshots = pboBuffer.snapshots();
if (snapshots == null) return;
Expand All @@ -149,12 +128,12 @@ public void tick() {

if (movementDirection) {
var max = NoxesiumMod.getInstance().getConfig().maxUiFramerate;
renderFps = Math.clamp(
nextRender.changeFrequency(Math.clamp(
Math.max(
max * (1.0 - ((double) (System.currentTimeMillis() - lastChange) / 10000d)),
max * ((double) (60 - matches) / 10d)),
0,
max);
max));

// If matches falls too far
if (matches <= 40) {
Expand All @@ -172,46 +151,32 @@ public void tick() {
// Request new PBOs from all buffers
if (isNotEmpty()) {
for (var buffer : buffers) {
if (buffer instanceof SnapshotElementBuffer pboBuffer) {
pboBuffer.requestNewPBO();
}
buffer.requestNewPBO();
}
}
}

/** Tries to make a snapshot of the current buffer. */
/**
* Tries to make a snapshot of the current buffer.
*/
private void trySnapshot() {
if (elementsWereDrawn && canCheck) {
var target = getTargetBuffer();
if (target instanceof SnapshotElementBuffer pboBuffer && pboBuffer.canSnapshot()) {
if (target instanceof SnapshotableElementBuffer pboBuffer) {
pboBuffer.snapshot();
}
}
}

@Override
public boolean update(long nanoTime, GuiGraphics guiGraphics, Runnable draw) {
// Always start by awaiting the GPU fence
// Always start by awaiting the GPU fence and updating if the PBO is ready
// for the next tick!
for (var buffer : buffers) {
if (buffer instanceof SnapshotElementBuffer pboBuffer) {
pboBuffer.awaitFence();
}
}

// Initialize the value if it's missing
if (nextRender == -1) {
nextRender = nanoTime;
buffer.awaitFence();
}

// Skip the update until we reach the next render time
if (!needsRedraw && !canCheck && (renderFps <= 20 || nextRender > nanoTime)) return false;
needsRedraw = false;

// Set the next render time
nextRender = nanoTime + (long) Math.floor(((1 / renderFps) * 1000000000));

var result = super.update(nanoTime, guiGraphics, draw);
if (result) {
if (super.update(nanoTime, guiGraphics, draw)) {
// Unset check once we're done with this frame, but
// snapshot first!
if (canCheck) {
Expand All @@ -223,6 +188,13 @@ public boolean update(long nanoTime, GuiGraphics guiGraphics, Runnable draw) {
return false;
}

@Override
public boolean shouldRedraw(long nanoTime) {
// If we can check we still increase the next render frame,
// but we ignore its result!
return nextRender.canInvoke(nanoTime) || canCheck;
}

@Override
public List<ElementBuffer> getBuffers() {
return (List<ElementBuffer>) (List<?>) buffers;
Expand All @@ -236,8 +208,15 @@ protected void onBufferUntargeted(ElementBuffer buffer) {
trySnapshot();
}

@Override
protected void onBufferRemoved(ElementBuffer buffer) {
super.onBufferRemoved(buffer);
hasBufferLayoutChanged = true;
}

@Override
public ElementBuffer createBuffer() {
return new SnapshotElementBuffer();
hasBufferLayoutChanged = true;
return new SnapshotableElementBuffer();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
import com.mojang.blaze3d.platform.GlStateManager;
import com.noxcrew.noxesium.feature.ui.render.api.BlendState;
import com.noxcrew.noxesium.feature.ui.render.api.BlendStateHook;
import com.noxcrew.noxesium.feature.ui.render.api.BufferData;
import com.noxcrew.noxesium.feature.ui.render.api.PerSecondTrackedValue;
import com.noxcrew.noxesium.feature.ui.render.buffer.BufferData;
import com.noxcrew.noxesium.feature.ui.render.buffer.ElementBuffer;
import java.io.Closeable;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.client.gui.GuiGraphics;
import org.jetbrains.annotations.Nullable;
import org.lwjgl.opengl.GL14;

/**
Expand All @@ -28,8 +30,15 @@ public abstract class Element implements Closeable, BlendStateHook {
private boolean lastBlending = true;
private int boundBufferIndex = -1;

private final PerSecondTrackedValue updates = new PerSecondTrackedValue();
private final PerSecondTrackedValue draws = new PerSecondTrackedValue();
/**
* The amount of updates that occurred in the last second.
*/
public final PerSecondTrackedValue updates = new PerSecondTrackedValue();

/**
* The amount of draws that occurred in the last second.
*/
public final PerSecondTrackedValue draws = new PerSecondTrackedValue();

/**
* Returns all buffers in this element.
Expand Down Expand Up @@ -118,7 +127,7 @@ public void submitTextureIds(List<BufferData> buffers) {
*/
public boolean update(long nanoTime, GuiGraphics guiGraphics, Runnable draw) {
this.updates.increment();
if (!shouldRedraw(nanoTime)) return false;
if (!needsRedraw && !shouldRedraw(nanoTime)) return false;

// Bind the first buffer, abort is something goes wrong
this.guiGraphics = guiGraphics;
Expand Down Expand Up @@ -149,7 +158,8 @@ public boolean update(long nanoTime, GuiGraphics guiGraphics, Runnable draw) {

var buffers = getBuffers();
for (var index = Math.max(1, this.boundBufferIndex + 1); index < buffers.size(); index++) {
buffers.remove(index).close();
var oldBuffer = buffers.remove(index);
onBufferRemoved(oldBuffer);
}
return true;
}
Expand Down Expand Up @@ -207,6 +217,13 @@ protected ElementBuffer getNextLayerBuffer() {
return newBuffer;
}

/**
* Called when [buffer] is removed from the buffer list.
*/
protected void onBufferRemoved(ElementBuffer buffer) {
buffer.close();
}

/**
* Called before [buffer] stops being the target buffer.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
import net.minecraft.client.gui.LayeredDraw;

/**
* Holds a group of layers and the buffer they are rendering into.
* Holds a group of layers and the dynamic buffer they are rendering into.
*/
public class ElementBufferGroup implements Closeable {
public class LayerGroup implements Closeable {

private final DynamicElement dynamic = new DynamicElement();
private final List<LayerWithReference> layers = new ArrayList<>();
Expand Down Expand Up @@ -60,7 +60,7 @@ public boolean shouldSplit() {
/**
* Returns whether this group can merge with another.
*/
public boolean canMerge(ElementBufferGroup other) {
public boolean canMerge(LayerGroup other) {
// If either needs a redraw we don't edit them as
// things might be inaccurate!
if (!dynamic.isReady() || !other.dynamic.isReady()) return false;
Expand All @@ -72,7 +72,9 @@ public boolean canMerge(ElementBufferGroup other) {
if (!dynamic.isMergeable() || !other.dynamic.isMergeable()) return false;

// Don't allow merging when render fps is too different
return Math.abs(dynamic.renderFramerate() - other.dynamic.renderFramerate()) < 10;
return Math.abs(dynamic.getRenderTask().getFramerate()
- other.dynamic.getRenderTask().getFramerate())
< 10;
}

/**
Expand All @@ -86,21 +88,21 @@ public int size() {
* Splits up this group into multiple, returns the
* new group and edits this group.
*/
public ElementBufferGroup split() {
public LayerGroup split() {
var total = size();
if (total < 2) throw new IllegalArgumentException("Cannot split up an un-splittable group");
var half = (int) Math.ceil(((double) total) / 2.0);
var toSplit = new ArrayList<>(layers.subList(half, total));
removeLayers(toSplit);
var newGroup = new ElementBufferGroup();
var newGroup = new LayerGroup();
newGroup.addLayers(toSplit);
return newGroup;
}

/**
* Merges another buffer group into this one.
*/
public void join(ElementBufferGroup other) {
public void join(LayerGroup other) {
addLayers(other.layers);
}

Expand All @@ -126,20 +128,6 @@ public String layerNames() {
.collect(Collectors.joining("/"));
}

/**
* Indicates that a check should run the very next frame.
*/
public void requestCheck() {
dynamic.requestCheck();
}

/**
* Triggers an update of the render framerate.
*/
public void updateRenderFramerate() {
dynamic.updateRenderFramerate();
}

@Override
public void close() {
dynamic.close();
Expand Down
Loading

0 comments on commit 52bd975

Please sign in to comment.