Skip to content

Commit

Permalink
Fully gut BufferedComponent
Browse files Browse the repository at this point in the history
  • Loading branch information
tr7zw committed Aug 2, 2024
1 parent f6b2595 commit 01dfe34
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 70 deletions.
58 changes: 56 additions & 2 deletions src/main/java/dev/tr7zw/exordium/components/BufferInstance.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package dev.tr7zw.exordium.components;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;

import dev.tr7zw.exordium.render.BufferedComponent;
import dev.tr7zw.exordium.util.PacingTracker;
import dev.tr7zw.exordium.util.ReloadListener;
import dev.tr7zw.exordium.versionless.config.Config;
import lombok.Getter;
import net.minecraft.resources.ResourceLocation;
Expand All @@ -13,11 +17,19 @@ public final class BufferInstance<T> {
private final ResourceLocation id;
private final BufferComponent<T> component;
private final BufferedComponent buffer;
private final PacingTracker pacing = new PacingTracker();
private final Supplier<Config.ComponentSettings> settings;
private final List<Supplier<Boolean>> updateListeners = new ArrayList<>();

private boolean isCapturing = false;

BufferInstance(ResourceLocation id, BufferComponent<T> component, Supplier<Config.ComponentSettings> settings) {
this.id = id;
this.component = component;
this.buffer = new BufferedComponent(settings);
this.settings = settings;
registerUpdateListener(() -> settings.get().isForceUpdates());
registerUpdateListener(new ReloadListener());
}

/**
Expand All @@ -28,7 +40,37 @@ public final class BufferInstance<T> {
* @return
*/
public boolean renderBuffer(int ticks, T context) {
return buffer.render(() -> component.hasChanged(ticks, context));
if (!settings.get().isEnabled()) {
// not enabled, skip
return false;
}
if (buffer.needsBlendstateSample()) {
// the intended blendstate is not know. Skip the buffer logic, let
// it render normally, then grab the expected state
return false;
}

boolean updateFrame = buffer.screenChanged()
|| (pacing.isCooldownOver() && (hasUpdate() || component.hasChanged(ticks, context)));

if (updateFrame) {
// start capturing
isCapturing = true;
buffer.captureComponent();
return false;
}
// we just render this buffered component
buffer.renderBuffer();
return true;
}

private boolean hasUpdate() {
for (Supplier<Boolean> listener : updateListeners) {
if (listener.get()) {
return true;
}
}
return false;
}

/**
Expand All @@ -38,7 +80,19 @@ public boolean renderBuffer(int ticks, T context) {
* @param context
*/
public void postRender(T context) {
buffer.renderEnd(() -> component.captureState(context));
buffer.captureBlendstateSample();
if (!isCapturing) {
// we were not capturing, so nothing to do
return;
}
isCapturing = false;
component.captureState(context);
pacing.setCooldown(System.currentTimeMillis() + (1000 / settings.get().getMaxFps()));
buffer.finishCapture();
}

public void registerUpdateListener(Supplier<Boolean> hasChanged) {
updateListeners.add(hasChanged);
}

}
95 changes: 27 additions & 68 deletions src/main/java/dev/tr7zw/exordium/render/BufferedComponent.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,23 @@
import com.mojang.blaze3d.pipeline.TextureTarget;
import dev.tr7zw.exordium.ExordiumModBase;
import dev.tr7zw.exordium.util.BlendStateHolder;
import dev.tr7zw.exordium.util.ReloadTracker;
import dev.tr7zw.exordium.util.ScreenTracker;
import dev.tr7zw.exordium.versionless.config.Config;
import lombok.Getter;
import net.minecraft.client.Minecraft;

//TODO: replace all protected to private once LegacyBuffer gets removed

public class BufferedComponent {

private static final Minecraft MINECRAFT = Minecraft.getInstance();
@Getter
private static Model model = null;
private final Supplier<Config.ComponentSettings> settings;
private final RenderTarget guiTarget = new TextureTarget(100, 100, true, false);
private final ScreenTracker screenTracker = new ScreenTracker(guiTarget);
private final BlendStateHolder blendStateHolder = new BlendStateHolder();
private long cooldown = System.currentTimeMillis();
private int reloadCount = 0;
private boolean isRendering = false;
private boolean forceBlending = false;
protected static Model model = null;
protected final Supplier<Config.ComponentSettings> settings;
protected final RenderTarget guiTarget = new TextureTarget(100, 100, true, false);
protected final ScreenTracker screenTracker = new ScreenTracker(guiTarget);
protected final BlendStateHolder blendStateHolder = new BlendStateHolder();
protected boolean forceBlending = false;

public BufferedComponent(Supplier<Config.ComponentSettings> settings) {
this(false, settings);
Expand All @@ -37,7 +35,7 @@ public BufferedComponent(boolean forceBlending, Supplier<Config.ComponentSetting
this.settings = settings;
}

private static void refreshModel(int screenWidth, int screenHeight) {
protected static void refreshModel(int screenWidth, int screenHeight) {
if (model != null) {
model.close();
}
Expand All @@ -50,99 +48,60 @@ private static void refreshModel(int screenWidth, int screenHeight) {
model = new Model(modelData, uvData);
}

/**
* @return true if the buffer was used. False = render as usual
*/
public boolean render(Supplier<Boolean> hasChanged) {
if (!settings.get().isEnabled()) {
return false;
}
if (!blendStateHolder.isBlendStateFetched()) { // the intended blendstate is not know. Skip the buffer logic,
// let
// it render normally, then grab the expected state
return false;
}
boolean forceRender = false;
public void captureComponent() {
// Check for Screen size/scaling changes
if (screenTracker.hasChanged()) {
screenTracker.updateState();
refreshModel(MINECRAFT.getWindow().getGuiScaledWidth(), MINECRAFT.getWindow().getGuiScaledHeight());
forceRender = true;
}
//
if (model == null) {
refreshModel(MINECRAFT.getWindow().getGuiScaledWidth(), MINECRAFT.getWindow().getGuiScaledHeight());
}
boolean updateFrame = forceRender || (System.currentTimeMillis() > cooldown
&& (settings.get().isForceUpdates() || needsRenderPaced(hasChanged)));

if (!updateFrame) {
// we just render this component
ExordiumModBase.instance.getDelayedRenderCallManager().addBufferedComponent(this);
blendStateHolder.apply();
return true;
}

guiTarget.setClearColor(0, 0, 0, 0);
guiTarget.clear(false);
guiTarget.bindWrite(false);
isRendering = true;
ExordiumModBase.instance.setTemporaryScreenOverwrite(guiTarget);

ExordiumModBase.correctBlendMode();
if (forceBlending || settings.get().isForceBlend()) {
ExordiumModBase.setForceBlend(true);
}
guiTarget.bindWrite(false);
return false;
}

public void renderEnd(Runnable capture) {
if (!blendStateHolder.isBlendStateFetched()) {
// capture the expected blend state
blendStateHolder.fetch();
}
if (!isRendering) {
// the buffer was used, nothing to do
return;
}
capture.run(); // capture the current state of the component as the current rendered state
public void renderBuffer() {
ExordiumModBase.instance.getDelayedRenderCallManager().addBufferedComponent(this);
// set the blendstate to what it would be if the normal render logic had run
blendStateHolder.apply();
}

public void finishCapture() {
ExordiumModBase.instance.setTemporaryScreenOverwrite(null);
guiTarget.unbindWrite();
Minecraft.getInstance().getMainRenderTarget().bindWrite(true);
cooldown = System.currentTimeMillis() + (1000 / settings.get().getMaxFps());
isRendering = false;
if (forceBlending || settings.get().isForceBlend()) {
ExordiumModBase.setForceBlend(false);
}
ExordiumModBase.instance.getDelayedRenderCallManager().addBufferedComponent(this);
blendStateHolder.apply();
renderBuffer();
}

public int getTextureId() {
return guiTarget.getColorTextureId();
}

public boolean isRendering() {
return isRendering;
public boolean needsBlendstateSample() {
return !blendStateHolder.isBlendStateFetched();
}

/**
* Checks for changes
*
* @return
*/
private boolean needsRenderPaced(Supplier<Boolean> hasChanged) {
boolean reloadOccurred = false;
if (reloadCount != ReloadTracker.getReloadCount()) {
reloadCount = ReloadTracker.getReloadCount();
reloadOccurred = true;
public void captureBlendstateSample() {
if (needsBlendstateSample()) {
blendStateHolder.fetch();
}
}

if (reloadOccurred || hasChanged.get()) {
return true;
}
cooldown = System.currentTimeMillis() + (1000 / ExordiumModBase.instance.config.pollRate);
return false;
public boolean screenChanged() {
return screenTracker.hasChanged();
}

}
91 changes: 91 additions & 0 deletions src/main/java/dev/tr7zw/exordium/render/LegacyBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,24 @@

import java.util.function.Supplier;

import dev.tr7zw.exordium.ExordiumModBase;
import dev.tr7zw.exordium.util.PacingTracker;
import dev.tr7zw.exordium.util.ReloadTracker;
import dev.tr7zw.exordium.versionless.config.Config;
import dev.tr7zw.exordium.versionless.config.Config.ComponentSettings;
import net.minecraft.client.Minecraft;

/**
* Class to contain old Buffer render code, will be removed
*/
@Deprecated
public class LegacyBuffer extends BufferedComponent {

private static final Minecraft MINECRAFT = Minecraft.getInstance();
private int reloadCount = 0;
private PacingTracker pacing = new PacingTracker();
private boolean isRendering = false;

public LegacyBuffer(Supplier<ComponentSettings> settings) {
super(settings);
}
Expand All @@ -19,6 +28,69 @@ public LegacyBuffer(boolean forceBlending, Supplier<Config.ComponentSettings> se
super(forceBlending, settings);
}

public boolean render(Supplier<Boolean> hasChanged) {
if (!settings.get().isEnabled()) {
return false;
}
if (!blendStateHolder.isBlendStateFetched()) { // the intended blendstate is not know. Skip the buffer logic,
// let
// it render normally, then grab the expected state
return false;
}
boolean forceRender = false;
// Check for Screen size/scaling changes
if (screenTracker.hasChanged()) {
screenTracker.updateState();
refreshModel(MINECRAFT.getWindow().getGuiScaledWidth(), MINECRAFT.getWindow().getGuiScaledHeight());
forceRender = true;
}
//
if (model == null) {
refreshModel(MINECRAFT.getWindow().getGuiScaledWidth(), MINECRAFT.getWindow().getGuiScaledHeight());
}
boolean updateFrame = forceRender
|| (pacing.isCooldownOver() && (settings.get().isForceUpdates() || needsRenderPaced(hasChanged)));

if (!updateFrame) {
// we just render this component
renderBuffer();
return true;
}
guiTarget.setClearColor(0, 0, 0, 0);
guiTarget.clear(false);
guiTarget.bindWrite(false);
isRendering = true;
ExordiumModBase.instance.setTemporaryScreenOverwrite(guiTarget);

ExordiumModBase.correctBlendMode();
if (forceBlending || settings.get().isForceBlend()) {
ExordiumModBase.setForceBlend(true);
}
guiTarget.bindWrite(false);
return false;
}

public void renderEnd(Runnable capture) {
if (!blendStateHolder.isBlendStateFetched()) {
// capture the expected blend state
blendStateHolder.fetch();
}
if (!isRendering) {
// the buffer was used, nothing to do
return;
}
capture.run(); // capture the current state of the component as the current rendered state
ExordiumModBase.instance.setTemporaryScreenOverwrite(null);
guiTarget.unbindWrite();
Minecraft.getInstance().getMainRenderTarget().bindWrite(true);
pacing.setCooldown(System.currentTimeMillis() + (1000 / settings.get().getMaxFps()));
isRendering = false;
if (forceBlending || settings.get().isForceBlend()) {
ExordiumModBase.setForceBlend(false);
}
renderBuffer();
}

@Deprecated
public boolean render() {
return render(this::shouldRenderNextCappedFrame);
Expand Down Expand Up @@ -46,4 +118,23 @@ public void captureState() {
throw new IllegalAccessError("Method not implemented");
}

/**
* Checks for changes
*
* @return
*/
private boolean needsRenderPaced(Supplier<Boolean> hasChanged) {
boolean reloadOccurred = false;
if (reloadCount != ReloadTracker.getReloadCount()) {
reloadCount = ReloadTracker.getReloadCount();
reloadOccurred = true;
}

if (reloadOccurred || hasChanged.get()) {
return true;
}
pacing.setCooldown(System.currentTimeMillis() + (1000 / ExordiumModBase.instance.config.pollRate));
return false;
}

}
16 changes: 16 additions & 0 deletions src/main/java/dev/tr7zw/exordium/util/PacingTracker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package dev.tr7zw.exordium.util;

import lombok.Getter;
import lombok.Setter;

public class PacingTracker {

@Getter
@Setter
private long cooldown = 0;

public boolean isCooldownOver() {
return System.currentTimeMillis() > cooldown;
}

}
Loading

0 comments on commit 01dfe34

Please sign in to comment.