diff --git a/api/src/main/java/com/seibel/distanthorizons/api/enums/config/EDhApiUpdateBranch.java b/api/src/main/java/com/seibel/distanthorizons/api/enums/config/EDhApiUpdateBranch.java
index dc94d28f7..6b149a666 100644
--- a/api/src/main/java/com/seibel/distanthorizons/api/enums/config/EDhApiUpdateBranch.java
+++ b/api/src/main/java/com/seibel/distanthorizons/api/enums/config/EDhApiUpdateBranch.java
@@ -1,14 +1,41 @@
package com.seibel.distanthorizons.api.enums.config;
+import com.seibel.distanthorizons.coreapi.ModInfo;
+
/**
+ * AUTO,
* STABLE,
* NIGHTLY,
*
- * @since API 2.0.0
- * @version 2024-4-6
+ * @since API 2.1.0
+ * @version 2024-6-8
*/
public enum EDhApiUpdateBranch
{
+ AUTO,
STABLE,
- NIGHTLY
+ NIGHTLY;
+
+
+
+ /**
+ * If the updateBranch value is {@link EDhApiUpdateBranch#AUTO}
+ * this method will convert it either to {@link EDhApiUpdateBranch#STABLE} or {@link EDhApiUpdateBranch#NIGHTLY}
+ * based on this jar's state.
+ *
+ * If updateBranch is {@link EDhApiUpdateBranch#STABLE} or {@link EDhApiUpdateBranch#NIGHTLY}
+ * it just returns.
+ */
+ public static EDhApiUpdateBranch convertAutoToStableOrNightly(EDhApiUpdateBranch updateBranch)
+ {
+ if (updateBranch != EDhApiUpdateBranch.AUTO)
+ {
+ return updateBranch;
+ }
+ else
+ {
+ return ModInfo.IS_DEV_BUILD ? EDhApiUpdateBranch.NIGHTLY : EDhApiUpdateBranch.STABLE;
+ }
+ }
+
}
diff --git a/api/src/main/java/com/seibel/distanthorizons/coreapi/ModInfo.java b/api/src/main/java/com/seibel/distanthorizons/coreapi/ModInfo.java
index 72e1539a9..ed39817c5 100644
--- a/api/src/main/java/com/seibel/distanthorizons/coreapi/ModInfo.java
+++ b/api/src/main/java/com/seibel/distanthorizons/coreapi/ModInfo.java
@@ -42,7 +42,7 @@ public final class ModInfo
public static final String NAME = "DistantHorizons";
/** Human-readable version of NAME */
public static final String READABLE_NAME = "Distant Horizons";
- public static final String VERSION = "2.0.4-a-dev";
+ public static final String VERSION = "2.1.1-a-dev";
/** Returns true if the current build is an unstable developer build, false otherwise. */
public static boolean IS_DEV_BUILD = VERSION.toLowerCase().contains("dev");
diff --git a/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java b/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java
index 48fcfef10..74e4ca464 100644
--- a/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java
+++ b/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java
@@ -1118,16 +1118,6 @@ public class Config
+ "")
.build();
- public static ConfigEntry gpuUploadAsync = new ConfigEntry.Builder()
- .set(true)
- .comment(""
- + "If true geometry data will be uploaded on a DH controlled thread, reducing FPS stuttering. \n"
- + "If false uploading will be done on Minecraft's main rendering thread. \n"
- + "\n"
- + "Setting this to false may reduce crashes or corrupted geometry on systems with an AMD GPU when Sodium is installed.\n"
- + "")
- .build();
-
}
public static class AutoUpdater
@@ -1147,11 +1137,12 @@ public class Config
.build();
public static ConfigEntry updateBranch = new ConfigEntry.Builder()
- .set(
- ModInfo.IS_DEV_BUILD ? EDhApiUpdateBranch.NIGHTLY : EDhApiUpdateBranch.STABLE // If it's already a nightly build, then download the nightly build ofc
- )
+ .set(EDhApiUpdateBranch.AUTO)
.comment(""
- + " If DH should use the nightly (provided by Gitlab), or stable (provided by Modrinth) build")
+ + "If DH should use the nightly (provided by Gitlab), or stable (provided by Modrinth) build. \n"
+ + "If ["+EDhApiUpdateBranch.AUTO+"] is selected DH will update to new stable releases if the current jar is a stable jar \n"
+ + "and will update to new nightly builds if the current jar is a nightly jar (IE the version number ends in '-dev')."
+ + "")
.build();
}
diff --git a/core/src/main/java/com/seibel/distanthorizons/core/config/file/ConfigFileHandling.java b/core/src/main/java/com/seibel/distanthorizons/core/config/file/ConfigFileHandling.java
index 8e3e516d5..f20ccefba 100644
--- a/core/src/main/java/com/seibel/distanthorizons/core/config/file/ConfigFileHandling.java
+++ b/core/src/main/java/com/seibel/distanthorizons/core/config/file/ConfigFileHandling.java
@@ -271,7 +271,11 @@ public class ConfigFileHandling
if (SingletonInjector.INSTANCE.get(IMinecraftSharedWrapper.class).isDedicatedServer() && entry.getServersideShortName() == null)
return;
- nightConfig.setComment(entry.getNameWCategory(), " " + entry.getComment().replaceAll("\n", "\n ") + "\n ");
+ String comment = entry.getComment().replaceAll("\n", "\n ").trim();
+ // the new line makes it easier to read and separate configs
+ // the space makes sure the first word of a comment isn't directly in line with the "#"
+ comment = "\n " + comment;
+ nightConfig.setComment(entry.getNameWCategory(), comment);
}
@@ -393,4 +397,4 @@ public class ConfigFileHandling
}
}
*/
-}
+}
\ No newline at end of file
diff --git a/core/src/main/java/com/seibel/distanthorizons/core/config/gui/OpenGLConfigScreen.java b/core/src/main/java/com/seibel/distanthorizons/core/config/gui/OpenGLConfigScreen.java
index 35a6cf353..c39897a5c 100644
--- a/core/src/main/java/com/seibel/distanthorizons/core/config/gui/OpenGLConfigScreen.java
+++ b/core/src/main/java/com/seibel/distanthorizons/core/config/gui/OpenGLConfigScreen.java
@@ -82,8 +82,7 @@ public class OpenGLConfigScreen extends AbstractScreen
private void createBuffer()
{
- GLProxy.getInstance().recordOpenGlCall(() -> sharedContextBuffer = createTextingBuffer());
- GLProxy.ensureAllGLJobCompleted();
+ sharedContextBuffer = createTextingBuffer();
sameContextBuffer = createTextingBuffer();
}
diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBuffer.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBuffer.java
index 755b6b91c..8762bec32 100644
--- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBuffer.java
+++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBuffer.java
@@ -22,7 +22,6 @@ package com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
-import com.seibel.distanthorizons.core.enums.EGLProxyContext;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.pos.DhBlockPos;
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
@@ -92,58 +91,36 @@ public class ColumnRenderBuffer implements AutoCloseable
LodUtil.assertTrue(Thread.currentThread().getName().startsWith(ThreadUtil.THREAD_NAME_PREFIX), "Buffer uploading needs to be done on a DH thread to prevent locking up any MC threads.");
- // the async is relative to MC's render thread
- boolean uploadAsync = Config.Client.Advanced.GpuBuffers.gpuUploadAsync.get();
- if (uploadAsync)
+ // upload on MC's render thread
+ CompletableFuture uploadFuture = new CompletableFuture<>();
+ minecraftClient.executeOnRenderThread(() ->
{
- // upload here on a DH thread
- GLProxy glProxy = GLProxy.getInstance();
- EGLProxyContext oldContext = glProxy.getGlContext();
- glProxy.setGlContext(EGLProxyContext.LOD_BUILDER);
try
{
this.uploadBuffersUsingUploadMethod(builder, gpuUploadMethod);
+ uploadFuture.complete(null);
}
- finally
+ catch (InterruptedException e)
{
- glProxy.setGlContext(oldContext);
+ throw new CompletionException(e);
}
- }
- else
+ });
+
+
+ try
{
- // upload on MC's render thread
- CompletableFuture uploadFuture = new CompletableFuture<>();
- minecraftClient.executeOnRenderThread(() ->
- {
- try
- {
- this.uploadBuffersUsingUploadMethod(builder, gpuUploadMethod);
- uploadFuture.complete(null);
- }
- catch (InterruptedException e)
- {
- throw new CompletionException(e);
- }
- });
-
-
- try
- {
- // wait for the upload to finish
- uploadFuture.get(1000, TimeUnit.MILLISECONDS);
- }
- catch (ExecutionException e)
- {
- LOGGER.warn("Error uploading builder ["+builder+"] synchronously. Error: "+e.getMessage(), e);
- }
- catch (TimeoutException e)
- {
- // timeouts can be ignored because it generally means the
- // MC Render thread executor was closed
- //LOGGER.warn("Error uploading builder ["+builder+"] synchronously. Error: "+e.getMessage(), e);
- }
-
-
+ // wait for the upload to finish
+ uploadFuture.get(5_000, TimeUnit.MILLISECONDS);
+ }
+ catch (ExecutionException e)
+ {
+ LOGGER.warn("Error uploading builder ["+builder+"] synchronously. Error: "+e.getMessage(), e);
+ }
+ catch (TimeoutException e)
+ {
+ // timeouts can be ignored because it generally means the
+ // MC Render thread executor was closed
+ //LOGGER.warn("Error uploading builder ["+builder+"] synchronously. Error: "+e.getMessage(), e);
}
}
private void uploadBuffersUsingUploadMethod(LodQuadBuilder builder, EDhApiGpuUploadMethod gpuUploadMethod) throws InterruptedException
@@ -403,7 +380,7 @@ public class ColumnRenderBuffer implements AutoCloseable
{
if (buffer != null)
{
- buffer.destroy(false);
+ buffer.destroyAsync();
}
}
@@ -411,7 +388,7 @@ public class ColumnRenderBuffer implements AutoCloseable
{
if (buffer != null)
{
- buffer.destroy(false);
+ buffer.destroyAsync();
}
}
});
diff --git a/core/src/main/java/com/seibel/distanthorizons/core/enums/EGLProxyContext.java b/core/src/main/java/com/seibel/distanthorizons/core/enums/EGLProxyContext.java
deleted file mode 100644
index f069507a1..000000000
--- a/core/src/main/java/com/seibel/distanthorizons/core/enums/EGLProxyContext.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * This file is part of the Distant Horizons mod
- * licensed under the GNU LGPL v3 License.
- *
- * Copyright (C) 2020-2023 James Seibel
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- */
-
-package com.seibel.distanthorizons.core.enums;
-
-/**
- * Minecraft,
- * Lod_Builder,
- * Proxy_Worker,
- * None
- *
- * @author James Seibel
- * @version 10-1-2021
- */
-public enum EGLProxyContext
-{
- /** Minecraft's render thread */
- MINECRAFT,
-
- /** The context we send buffers to the GPU on */
- LOD_BUILDER,
-
- /** A context that can be used for miscellaneous tasks, owned by the GLProxy */
- PROXY_WORKER,
-
- /** used to un-bind threads */
- NONE,
-}
\ No newline at end of file
diff --git a/core/src/main/java/com/seibel/distanthorizons/core/jar/updater/SelfUpdater.java b/core/src/main/java/com/seibel/distanthorizons/core/jar/updater/SelfUpdater.java
index 16df88e2b..92a6940de 100644
--- a/core/src/main/java/com/seibel/distanthorizons/core/jar/updater/SelfUpdater.java
+++ b/core/src/main/java/com/seibel/distanthorizons/core/jar/updater/SelfUpdater.java
@@ -19,6 +19,7 @@
package com.seibel.distanthorizons.core.jar.updater;
+import com.seibel.distanthorizons.api.enums.config.EDhApiUpdateBranch;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.jar.JarUtils;
@@ -83,15 +84,8 @@ public class SelfUpdater
boolean returnValue = false;
try
{
- switch (Config.Client.Advanced.AutoUpdater.updateBranch.get())
- {
- case STABLE:
- returnValue = onStableStart();
- break;
- case NIGHTLY:
- returnValue = onNightlyStart();
- break;
- };
+ EDhApiUpdateBranch updateBranch = EDhApiUpdateBranch.convertAutoToStableOrNightly(Config.Client.Advanced.AutoUpdater.updateBranch.get());
+ returnValue = (updateBranch == EDhApiUpdateBranch.STABLE) ? onStableStart() : onNightlyStart();
}
catch (Exception e) // Shouldn't be needed, but just in case
{
diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLProxy.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLProxy.java
index c49f74ce9..ffe831b00 100644
--- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLProxy.java
+++ b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLProxy.java
@@ -19,22 +19,17 @@
package com.seibel.distanthorizons.core.render.glObject;
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.seibel.distanthorizons.api.enums.config.EDhApiGLErrorHandlingMode;
-import com.seibel.distanthorizons.api.enums.config.EDhApiGlProfileMode;
import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
-import com.seibel.distanthorizons.core.enums.EGLProxyContext;
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
-import com.seibel.distanthorizons.core.util.ReflectionUtil;
import com.seibel.distanthorizons.core.util.objects.GLMessage;
import com.seibel.distanthorizons.core.util.objects.GLMessageOutputStream;
import com.seibel.distanthorizons.core.util.objects.Pair;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.coreapi.ModInfo;
-import com.seibel.distanthorizons.coreapi.util.StringUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.glfw.GLFW;
@@ -48,9 +43,6 @@ import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
/**
* A singleton that holds references to different openGL contexts
@@ -74,34 +66,13 @@ public class GLProxy
public static final ConfigBasedLogger GL_LOGGER = new ConfigBasedLogger(LogManager.getLogger(GLProxy.class),
() -> Config.Client.Advanced.Logging.logRendererGLEvent.get());
- /** newest version first */
- private static final ArrayList> SUPPORTED_GL_VERSIONS = new ArrayList<>(
- Arrays.asList(
- new Pair<>(4,6), new Pair<>(4,5), new Pair<>(4,4), new Pair<>(4,3), new Pair<>(4,2), new Pair<>(4,1), new Pair<>(4,0),
- new Pair<>(3,3), new Pair<>(3,2)
- ));
-
private static GLProxy instance = null;
- private ExecutorService workerThread = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(GLProxy.class.getSimpleName() + "-Worker-Thread").build());
+ private final ConcurrentLinkedQueue renderThreadRunnableQueue = new ConcurrentLinkedQueue<>();
- private ConcurrentLinkedQueue renderThreadRunnableQueue = new ConcurrentLinkedQueue<>();
-
- /** Minecraft's GLFW window */
- public final long minecraftGlContext;
/** Minecraft's GL capabilities */
- public final GLCapabilities minecraftGlCapabilities;
-
- /** the LodBuilder's GLFW window */
- public final long lodBuilderGlContext;
- /** the LodBuilder's GL capabilities */
- public final GLCapabilities lodBuilderGlCapabilities;
-
- /** the proxyWorker's GLFW window */
- public final long proxyWorkerGlContext;
- /** the proxyWorker's GL capabilities */
- public final GLCapabilities proxyWorkerGlCapabilities;
+ public final GLCapabilities glCapabilities;
public boolean namedObjectSupported = false; // ~OpenGL 4.5 (UNUSED CURRENTLY)
public boolean bufferStorageSupported = false; // ~OpenGL 4.4
@@ -110,8 +81,6 @@ public class GLProxy
private final EDhApiGpuUploadMethod preferredUploadMethod;
public final GLMessage.Builder vanillaDebugMessageBuilder = GLMessage.Builder.DEFAULT_MESSAGE_BUILDER;
- public final GLMessage.Builder lodBuilderDebugMessageBuilder = GLMessage.Builder.DEFAULT_MESSAGE_BUILDER;
- public final GLMessage.Builder proxyWorkerDebugMessageBuilder = GLMessage.Builder.DEFAULT_MESSAGE_BUILDER;
@@ -139,14 +108,13 @@ public class GLProxy
// get Minecraft's GL context //
//============================//
- // get Minecraft's context
- this.minecraftGlContext = GLFW.glfwGetCurrentContext();
- this.minecraftGlCapabilities = GL.getCapabilities();
+ // get Minecraft's capabilities
+ this.glCapabilities = GL.getCapabilities();
// crash the game if the GPU doesn't support OpenGL 3.2
- if (!this.minecraftGlCapabilities.OpenGL32)
+ if (!this.glCapabilities.OpenGL32)
{
- String supportedVersionInfo = this.getFailedVersionInfo(this.minecraftGlCapabilities);
+ String supportedVersionInfo = this.getFailedVersionInfo(this.glCapabilities);
// See full requirement at above.
String errorMessage = ModInfo.READABLE_NAME + " was initializing " + GLProxy.class.getSimpleName()
@@ -154,7 +122,7 @@ public class GLProxy
"Additional info:\n" + supportedVersionInfo;
MC.crashMinecraft(errorMessage, new UnsupportedOperationException("Distant Horizon OpenGL requirements not met"));
}
- GL_LOGGER.info("minecraftGlCapabilities:\n" + this.versionInfoToString(this.minecraftGlCapabilities));
+ GL_LOGGER.info("minecraftGlCapabilities:\n" + this.versionInfoToString(this.glCapabilities));
if (Config.Client.Advanced.Debugging.OpenGl.overrideVanillaGLLogger.get())
{
@@ -163,155 +131,20 @@ public class GLProxy
- //================================//
- // create the lod builder context //
- //================================//
-
- String contextCreateErrorMessage = "";
- long potentialLodBuilderGlContext = 0;
- GLCapabilities potentialLodBuilderGlCapabilities = null;
-
- int majorGlVersion = Config.Client.Advanced.Debugging.OpenGl.glContextMajorVersion.get();
- int minorGlVersion = Config.Client.Advanced.Debugging.OpenGl.glContextMinorVersion.get();
-
- ArrayList> glVersions = new ArrayList<>();
- if (majorGlVersion != 0)
- {
- glVersions.add(new Pair<>(majorGlVersion, minorGlVersion));
- }
- else
- {
- glVersions.addAll(SUPPORTED_GL_VERSIONS);
- }
-
- for (Pair supportedGlVersion : glVersions)
- {
- int glMajorVersion = supportedGlVersion.first;
- int glMinorVersion = supportedGlVersion.second;
-
- GL_LOGGER.info("Attempting to create a context with GL version: ["+glMajorVersion+"."+glMinorVersion+"]");
-
-
-
- GLFW.glfwMakeContextCurrent(0L);
-
- // context creation setup
- GLFW.glfwDefaultWindowHints();
- // make the context window invisible
- GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE);
-
- boolean debugContextEnabled = Config.Client.Advanced.Debugging.OpenGl.enableGlDebugContext.get();
- boolean forwardCompatEnabled = Config.Client.Advanced.Debugging.OpenGl.enableGlForwardCompatibilityMode.get();
-
- GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, glMajorVersion);
- GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, glMinorVersion);
- GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_DEBUG_CONTEXT, debugContextEnabled ? GLFW.GLFW_TRUE : GLFW.GLFW_FALSE);
-
- GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT, forwardCompatEnabled ? GLFW.GLFW_TRUE : GLFW.GLFW_FALSE);
- int profileModeInt;
- EDhApiGlProfileMode profileModeEnum = Config.Client.Advanced.Debugging.OpenGl.glProfileMode.get();
- switch (profileModeEnum)
- {
- case CORE:
- profileModeInt = GLFW.GLFW_OPENGL_CORE_PROFILE;
- break;
- case COMPAT:
- profileModeInt = GLFW.GLFW_OPENGL_COMPAT_PROFILE;
- break;
- default:
- case ANY:
- profileModeInt = GLFW.GLFW_OPENGL_ANY_PROFILE;
- break;
- }
- GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, profileModeInt);
-
- contextCreateErrorMessage =
- "Failed to create OpenGL GLFW context for OpenGL Version: [" + glMajorVersion + "." + glMinorVersion + "] \n" +
- "with Debugging: [" + (debugContextEnabled ? "Enabled" : "Disabled") + "], \n" +
- "Forward Compatibility: [" + (true ? "Enabled" : "Disabled") + "], \n" +
- "and Profile: [" + profileModeEnum.name() + "]. ";
-
-
- // try creating the Lod Builder context
- potentialLodBuilderGlContext = GLFW.glfwCreateWindow(64, 64, "LOD Builder Window", 0L, this.minecraftGlContext);
- if (potentialLodBuilderGlContext == 0)
- {
- GL_LOGGER.info(contextCreateErrorMessage);
- GL_LOGGER.debug("Minecraft GL Capabilities:\n [\n" + ReflectionUtil.getAllFieldValuesAsString(this.minecraftGlCapabilities) + "\n]\n");
-
- continue;
- }
-
- // create the window
- GLFW.glfwMakeContextCurrent(potentialLodBuilderGlContext);
- GL_LOGGER.info("Successfully created a context with GL version: ["+glMajorVersion+"."+glMinorVersion+"]");
-
- // set and log the capabilities
- potentialLodBuilderGlCapabilities = GL.createCapabilities();
- GL_LOGGER.info("lodBuilderGlCapabilities:\n" + this.versionInfoToString(potentialLodBuilderGlCapabilities));
- // override the GL logger
- GLUtil.setupDebugMessageCallback(new PrintStream(new GLMessageOutputStream(GLProxy::logMessage, this.lodBuilderDebugMessageBuilder), true));
- // clear the context for the next stage
- GLFW.glfwMakeContextCurrent(0L);
-
- break;
- }
-
- if (potentialLodBuilderGlContext == 0)
- {
- // no context was created
- throw new UnsupportedOperationException("ERROR: Unable to create a GL Context using any of the supported GL versions: ["+ StringUtil.join(",", SUPPORTED_GL_VERSIONS) +"]");
- }
-
- this.lodBuilderGlContext = potentialLodBuilderGlContext;
- this.lodBuilderGlCapabilities = potentialLodBuilderGlCapabilities;
-
-
-
-
- //=================================//
- // create the proxy worker context //
- //=================================//
-
- // create the proxyWorker's context
- this.proxyWorkerGlContext = GLFW.glfwCreateWindow(64, 48, "LOD proxy worker Window", 0L, this.minecraftGlContext);
- if (this.proxyWorkerGlContext == 0)
- {
- GL_LOGGER.error(contextCreateErrorMessage +
- "\n Your OS and GPU Driver may have not support this combination.");
- GL_LOGGER.error("Minecraft GL Capabilities:\n [\n"+ReflectionUtil.getAllFieldValuesAsString(this.minecraftGlCapabilities)+"\n]\n");
-
- throw new UnsupportedOperationException("Forward Compat Core Profile 3.2 creation failure");
- }
- // create the window
- GLFW.glfwMakeContextCurrent(this.proxyWorkerGlContext);
- // set and log the capabilities
- this.proxyWorkerGlCapabilities = GL.createCapabilities();
- GL_LOGGER.info("proxyWorkerGlCapabilities:\n" + this.versionInfoToString(this.lodBuilderGlCapabilities));
- // override the GL logger
- GLUtil.setupDebugMessageCallback(new PrintStream(new GLMessageOutputStream(GLProxy::logMessage, this.proxyWorkerDebugMessageBuilder), true));
- // clear the context for the next stage
- GLFW.glfwMakeContextCurrent(0L);
-
-
-
//======================//
// get GPU capabilities //
//======================//
- // get capabilities from a context we use
- this.setGlContext(EGLProxyContext.LOD_BUILDER);
-
// Check if we can use the make-over version of Vertex Attribute, which is available in GL4.3 or after
- this.VertexAttributeBufferBindingSupported = this.minecraftGlCapabilities.glBindVertexBuffer != 0L; // Nullptr
+ this.VertexAttributeBufferBindingSupported = this.glCapabilities.glBindVertexBuffer != 0L; // Nullptr
// UNUSED currently
// Check if we can use the named version of all calls, which is available in GL4.5 or after
- this.namedObjectSupported = this.minecraftGlCapabilities.glNamedBufferData != 0L; //Nullptr
+ this.namedObjectSupported = this.glCapabilities.glNamedBufferData != 0L; //Nullptr
// get specific capabilities
// Check if we can use the Buffer Storage, which is available in GL4.4 or after
- this.bufferStorageSupported = this.minecraftGlCapabilities.glBufferStorage != 0L && this.lodBuilderGlCapabilities.glBufferStorage != 0L; // Nullptr
+ this.bufferStorageSupported = this.glCapabilities.glBufferStorage != 0L; // Nullptr
if (!this.bufferStorageSupported)
{
GL_LOGGER.warn("This GPU doesn't support Buffer Storage (OpenGL 4.4), falling back to using other methods.");
@@ -337,99 +170,12 @@ public class GLProxy
// clean up //
//==========//
- // Since this is created on the render thread, make sure the Minecraft context is used in the end
- this.setGlContext(EGLProxyContext.MINECRAFT);
-
// GLProxy creation success
GL_LOGGER.info(GLProxy.class.getSimpleName() + " creation successful. OpenGL smiles upon you this day.");
}
- //==================//
- // context handling //
- //==================//
-
- /**
- * A wrapper function to make switching contexts easier.
- * Does nothing if the calling thread is already using newContext.
- */
- public void setGlContext(EGLProxyContext newContext)
- {
- EGLProxyContext currentContext = this.getGlContext();
-
- // we don't have to change the context, we are already there.
- if (currentContext == newContext)
- return;
-
- long contextPointer;
- GLCapabilities newGlCapabilities = null;
-
- // get the pointer(s) for this context
- switch (newContext)
- {
- case LOD_BUILDER:
- contextPointer = this.lodBuilderGlContext;
- newGlCapabilities = this.lodBuilderGlCapabilities;
- break;
-
- case MINECRAFT:
- contextPointer = this.minecraftGlContext;
- newGlCapabilities = this.minecraftGlCapabilities;
- break;
-
- case PROXY_WORKER:
- contextPointer = this.proxyWorkerGlContext;
- newGlCapabilities = this.proxyWorkerGlCapabilities;
- break;
-
- default: // default should never happen, it is just here to make the compiler happy
- case NONE:
- // 0L is equivalent to null
- contextPointer = 0L;
- break;
- }
-
- GLFW.glfwMakeContextCurrent(contextPointer);
- GL.setCapabilities(newGlCapabilities);
- }
-
- /** Returns this thread's OpenGL context. */
- public EGLProxyContext getGlContext()
- {
- long currentContext = GLFW.glfwGetCurrentContext();
-
-
- if (currentContext == this.lodBuilderGlContext)
- {
- return EGLProxyContext.LOD_BUILDER;
- }
- else if (currentContext == this.minecraftGlContext)
- {
- return EGLProxyContext.MINECRAFT;
- }
- else if (currentContext == this.proxyWorkerGlContext)
- {
- return EGLProxyContext.PROXY_WORKER;
- }
- else if (currentContext == 0L)
- {
- return EGLProxyContext.NONE;
- }
- else
- {
- // hopefully this shouldn't happen
- throw new IllegalStateException(Thread.currentThread().getName() +
- " has a unknown OpenGl context: [" + currentContext + "]. "
- + "Minecraft context [" + this.minecraftGlContext + "], "
- + "LodBuilder context [" + this.lodBuilderGlContext + "], "
- + "ProxyWorker context [" + this.proxyWorkerGlContext + "], "
- + "no context [0].");
- }
- }
-
-
-
//=========//
// getters //
//=========//
@@ -457,33 +203,27 @@ public class GLProxy
return method == EDhApiGpuUploadMethod.AUTO ? this.preferredUploadMethod : method;
}
+ public boolean runningOnRenderThread()
+ {
+ long currentContext = GLFW.glfwGetCurrentContext();
+ return currentContext != 0L; // if the context isn't null, it's the MC context
+ }
+
//=========================//
// Worker Thread Runnables //
//=========================//
- /**
- * Asynchronously calls the given runnable on proxy's OpenGL context.
- * Useful for creating/destroying OpenGL objects in a thread
- * that doesn't normally have access to a OpenGL context.
- * No rendering can be done through this method.
- */
- public void recordOpenGlCall(Runnable renderCall)
+ public void queueRunningOnRenderThread(Runnable renderCall)
{
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
- this.workerThread.execute(() -> this.runOpenGlCall(renderCall, stackTrace, true));
+ this.renderThreadRunnableQueue.add(() -> this.runOpenGlCall(renderCall, stackTrace));
}
- private void runOpenGlCall(Runnable renderCall, StackTraceElement[] stackTrace, boolean useProxyWorkerContext)
+ private void runOpenGlCall(Runnable renderCall, StackTraceElement[] stackTrace)
{
try
{
- // set up the context if requested...
- if (useProxyWorkerContext)
- {
- this.setGlContext(EGLProxyContext.PROXY_WORKER);
- }
-
// ...run the actual code...
renderCall.run();
}
@@ -493,67 +233,28 @@ public class GLProxy
error.setStackTrace(stackTrace);
GL_LOGGER.error(Thread.currentThread().getName() + " ran into a issue: ", error);
}
- finally
- {
- // ...and make sure the context is released when the thread finishes
- if (useProxyWorkerContext)
- {
- this.setGlContext(EGLProxyContext.NONE);
- }
- }
}
- public static void ensureAllGLJobCompleted()
- {
- if (!hasInstance())
- {
- return;
- }
-
-
- LOGGER.info("Blocking until GL jobs finished...");
- try
- {
- instance.workerThread.shutdown();
- boolean worked = instance.workerThread.awaitTermination(30, TimeUnit.SECONDS);
- if (!worked)
- {
- LOGGER.error("GLWorkerThread shutdown timed out! Game may crash on exit due to cleanup failure!");
- }
- }
- catch (InterruptedException e)
- {
- LOGGER.error("GLWorkerThread shutdown is interrupted! Game may crash on exit due to cleanup failure!");
- e.printStackTrace();
- }
- finally
- {
- instance.workerThread = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(GLProxy.class.getSimpleName() + "-Worker-Thread").build());
- }
- LOGGER.info("All GL jobs finished!");
- }
-
-
-
- //=========================//
- // Render Thread Runnables //
- //=========================//
-
- public void queueRunningOnRenderThread(Runnable renderCall)
- {
- StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
- this.renderThreadRunnableQueue.add(() -> this.runOpenGlCall(renderCall, stackTrace, false));
- }
-
- /**
+ /**
* Doesn't do any thread/GL Context validation.
* Running this outside of the render thread may cause crashes or other issues.
*/
public void runRenderThreadTasks()
{
+ long startTime = System.nanoTime();
+
Runnable runnable = this.renderThreadRunnableQueue.poll();
while(runnable != null)
{
+ long currentTime = System.nanoTime();
+ long runDuration = currentTime - startTime;
+ // only try running for 4ms at a time to (hopefully) prevent random lag spikes
+ if (runDuration > 4_000_000)
+ {
+ break;
+ }
+
+
runnable.run();
runnable = this.renderThreadRunnableQueue.poll();
}
diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLBuffer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLBuffer.java
index 112a13cd0..7d8608a83 100644
--- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLBuffer.java
+++ b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLBuffer.java
@@ -20,7 +20,6 @@
package com.seibel.distanthorizons.core.render.glObject.buffer;
import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
-import com.seibel.distanthorizons.core.enums.EGLProxyContext;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
import com.seibel.distanthorizons.core.util.LodUtil;
@@ -94,9 +93,9 @@ public class GLBuffer implements AutoCloseable
protected void create(boolean asBufferStorage)
{
- if (GLProxy.getInstance().getGlContext() == EGLProxyContext.NONE)
+ if (!GLProxy.getInstance().runningOnRenderThread())
{
- LodUtil.assertNotReach("Thread ["+Thread.currentThread()+"] tried to create a GLBuffer outside a OpenGL context.");
+ LodUtil.assertNotReach("Thread ["+Thread.currentThread()+"] tried to create a GLBuffer outside the MC render thread.");
}
this.id = GL32.glGenBuffers();
@@ -109,7 +108,7 @@ public class GLBuffer implements AutoCloseable
}
- protected void destroy(boolean async)
+ protected void destroyAsync()
{
if (this.id == 0)
{
@@ -117,40 +116,33 @@ public class GLBuffer implements AutoCloseable
return;
}
- destroyBufferId(async, this.id);
+ destroyBufferIdAsync(this.id);
this.id = 0;
this.size = 0;
}
- private static void destroyBufferId(boolean async, int id)
+ private static void destroyBufferIdAsync(int id)
{
- EGLProxyContext glContext = GLProxy.getInstance().getGlContext();
- if (async
- && glContext != EGLProxyContext.PROXY_WORKER
- && glContext != EGLProxyContext.MINECRAFT)
- {
- GLProxy.getInstance().queueRunningOnRenderThread(() -> destroyBufferId(false, id));
- }
- else
- {
- // remove the phantom references
- if (BUFFER_ID_TO_PHANTOM.containsKey(id))
+ GLProxy.getInstance().queueRunningOnRenderThread(() ->
{
- Reference extends GLBuffer> phantom = BUFFER_ID_TO_PHANTOM.get(id);
- PHANTOM_TO_BUFFER_ID.remove(phantom);
- BUFFER_ID_TO_PHANTOM.remove(id);
- }
-
- // destroy the buffer if it exists,
- // the buffer may not exist if the destroy method is called twice
- if (GL32.glIsBuffer(id))
- {
- GL32.glDeleteBuffers(id);
- bufferCount.decrementAndGet();
+ // remove the phantom references
+ if (BUFFER_ID_TO_PHANTOM.containsKey(id))
+ {
+ Reference extends GLBuffer> phantom = BUFFER_ID_TO_PHANTOM.get(id);
+ PHANTOM_TO_BUFFER_ID.remove(phantom);
+ BUFFER_ID_TO_PHANTOM.remove(id);
+ }
- //LOGGER.info("destroyed buffer ["+id+"], remaining: ["+BUFFER_ID_TO_PHANTOM.size()+"]");
- }
- }
+ // destroy the buffer if it exists,
+ // the buffer may not exist if the destroy method is called twice
+ if (GL32.glIsBuffer(id))
+ {
+ GL32.glDeleteBuffers(id);
+ bufferCount.decrementAndGet();
+
+ //LOGGER.info("destroyed buffer ["+id+"], remaining: ["+BUFFER_ID_TO_PHANTOM.size()+"]");
+ }
+ });
}
@@ -205,7 +197,7 @@ public class GLBuffer implements AutoCloseable
LodUtil.assertTrue(this.bufferStorage, "Buffer is not bufferStorage but its trying to use bufferStorage upload method!");
int bbSize = bb.limit() - bb.position();
- this.destroy(true);
+ this.destroyAsync();
this.create(true);
this.bind();
GL44.glBufferStorage(this.getBufferBindingTarget(), bb, bufferStorageHint);
@@ -293,7 +285,7 @@ public class GLBuffer implements AutoCloseable
//===========//
@Override
- public void close() { this.destroy(true); }
+ public void close() { this.destroyAsync(); }
@Override
public String toString()
@@ -319,7 +311,7 @@ public class GLBuffer implements AutoCloseable
{
// recreate if the buffer storage type changed
this.bind();
- this.destroy(true);
+ this.destroyAsync();
this.create(uploadMethod.useBufferStorage);
this.bind();
}
@@ -362,7 +354,7 @@ public class GLBuffer implements AutoCloseable
if (PHANTOM_TO_BUFFER_ID.containsKey(phantomRef))
{
int id = PHANTOM_TO_BUFFER_ID.get(phantomRef);
- destroyBufferId(true, id);
+ destroyBufferIdAsync(id);
}
phantomRef = PHANTOM_REFERENCE_QUEUE.poll();
diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLElementBuffer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLElementBuffer.java
index 1dd5289ab..3d394075c 100644
--- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLElementBuffer.java
+++ b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLElementBuffer.java
@@ -35,7 +35,7 @@ public class GLElementBuffer extends GLBuffer
* bigger than the upload payload
*/
protected int indicesCount = 0;
- public int getIndicesCount() { return indicesCount; }
+ public int getIndicesCount() { return this.indicesCount; }
protected int type = GL32.GL_UNSIGNED_INT;
public int getType() { return type; }
@@ -45,10 +45,10 @@ public class GLElementBuffer extends GLBuffer
}
@Override
- public void destroy(boolean async)
+ public void destroyAsync()
{
- super.destroy(async);
- indicesCount = 0;
+ super.destroyAsync();
+ this.indicesCount = 0;
}
@Override
diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLVertexBuffer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLVertexBuffer.java
index 05fbe1287..f3957ef56 100644
--- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLVertexBuffer.java
+++ b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLVertexBuffer.java
@@ -39,7 +39,7 @@ public class GLVertexBuffer extends GLBuffer
* bigger than the upload payload
*/
protected int vertexCount = 0;
- public int getVertexCount() { return vertexCount; }
+ public int getVertexCount() { return this.vertexCount; }
// FIXME: This setter is needed for premapping buffer to manually set the vertexCount. Fix this.
public void setVertexCount(int vertexCount) { this.vertexCount = vertexCount; }
@@ -52,9 +52,9 @@ public class GLVertexBuffer extends GLBuffer
@Override
- public void destroy(boolean async)
+ public void destroyAsync()
{
- super.destroy(async);
+ super.destroyAsync();
this.vertexCount = 0;
}
diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java
index b8ec6d63f..6ea356fd8 100644
--- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java
+++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java
@@ -849,7 +849,7 @@ public class LodRenderer
}
if (this.quadIBO != null)
- this.quadIBO.destroy(false);
+ this.quadIBO.destroyAsync();
// Delete framebuffer, color texture, and depth texture
if (this.framebuffer != null && !this.usingMcFrameBuffer)
diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/TestRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/TestRenderer.java
index 5d13b95d5..9050f3083 100644
--- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/TestRenderer.java
+++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/TestRenderer.java
@@ -97,8 +97,7 @@ public class TestRenderer
private void createBuffer()
{
- GLProxy.getInstance().recordOpenGlCall(() -> sharedContextBuffer = createTextingBuffer());
- GLProxy.ensureAllGLJobCompleted();
+ sharedContextBuffer = createTextingBuffer();
sameContextBuffer = createTextingBuffer();
}
diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/objects/dataStreams/DhDataOutputStream.java b/core/src/main/java/com/seibel/distanthorizons/core/util/objects/dataStreams/DhDataOutputStream.java
index 5fff65581..6797af8d2 100644
--- a/core/src/main/java/com/seibel/distanthorizons/core/util/objects/dataStreams/DhDataOutputStream.java
+++ b/core/src/main/java/com/seibel/distanthorizons/core/util/objects/dataStreams/DhDataOutputStream.java
@@ -68,8 +68,8 @@ public class DhDataOutputStream extends DataOutputStream
ResettableArrayCache arrayCache = LZMA_RESETTABLE_ARRAY_CACHE_GETTER.get();
arrayCache.reset();
// Note: if the LZMA2Options are changed the array cache may need to be re-tested.
- // the array cache was specifically tested and tuned for LZMA preset 4
- return new XZOutputStream(stream, new LZMA2Options(4),
+ // the array cache was specifically tested and tuned for LZMA preset 3/4
+ return new XZOutputStream(stream, new LZMA2Options(3),
XZ.CHECK_CRC64, arrayCache);
default:
diff --git a/core/src/main/resources/assets/distanthorizons/lang/en_us.json b/core/src/main/resources/assets/distanthorizons/lang/en_us.json
index d75cc515c..39c108a5e 100644
--- a/core/src/main/resources/assets/distanthorizons/lang/en_us.json
+++ b/core/src/main/resources/assets/distanthorizons/lang/en_us.json
@@ -941,6 +941,8 @@
"Stable",
"distanthorizons.config.enum.EDhApiUpdateBranch.NIGHTLY":
"Nightly",
+ "distanthorizons.config.enum.EDhApiUpdateBranch.AUTO":
+ "Auto",
"distanthorizons.config.enum.EDhApiGrassSideRendering.AS_GRASS":
"As Grass",