Fix memory leaks when moving between dimensions

This commit is contained in:
James Seibel
2023-10-20 19:23:07 -05:00
parent 2d4f057eb0
commit 146d9da417
3 changed files with 101 additions and 55 deletions
@@ -140,6 +140,8 @@ public class LodRenderer
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
private final ReentrantLock setupLock = new ReentrantLock();
public final RenderBufferHandler bufferHandler;
// The shader program
@@ -148,9 +150,9 @@ public class LodRenderer
public boolean isSetupComplete = false;
// frameBuffer and texture ID's for this renderer
private int framebufferId;
private int colorTextureId;
private int depthTextureId;
private int framebufferId = -1;
private int colorTextureId = -1;
private int depthTextureId = -1;
@@ -497,21 +499,31 @@ public class LodRenderer
return;
}
EVENT_LOGGER.info("Setting up renderer");
this.isSetupComplete = true;
this.shaderProgram = new LodRenderProgram(LodFogConfig.generateFogConfig()); // TODO this doesn't actually use the fog config
if (ENABLE_IBO)
try
{
this.quadIBO = new QuadElementBuffer();
this.quadIBO.reserve(AbstractRenderBuffer.MAX_QUADS_PER_BUFFER);
this.setupLock.lock();
EVENT_LOGGER.info("Setting up renderer");
this.isSetupComplete = true;
this.shaderProgram = new LodRenderProgram(LodFogConfig.generateFogConfig()); // TODO this doesn't actually use the fog config
if (ENABLE_IBO)
{
this.quadIBO = new QuadElementBuffer();
this.quadIBO.reserve(AbstractRenderBuffer.MAX_QUADS_PER_BUFFER);
}
// Generate framebuffer, color texture, and depth render buffer
this.framebufferId = GL32.glGenFramebuffers();
this.colorTextureId = GL32.glGenTextures();
this.depthTextureId = GL32.glGenTextures();
EVENT_LOGGER.info("Renderer setup complete");
}
finally
{
this.setupLock.unlock();
}
// Generate framebuffer, color texture, and depth render buffer
this.framebufferId = GL32.glGenFramebuffers();
this.colorTextureId = GL32.glGenTextures();
this.depthTextureId = GL32.glGenTextures();
EVENT_LOGGER.info("Renderer setup complete");
}
private Color getFogColor(float partialTicks)
@@ -561,38 +573,48 @@ public class LodRenderer
*/
private void cleanup()
{
if (!this.isSetupComplete)
{
EVENT_LOGGER.warn("Renderer cleanup called but Renderer has not completed setup!");
return;
}
if (!GLProxy.hasInstance())
if (GLProxy.getInstance() == null)
{
// shouldn't normally happen, but just in case
EVENT_LOGGER.warn("Renderer Cleanup called but the GLProxy has never been initalized!");
return;
}
this.isSetupComplete = false;
GLProxy.getInstance().recordOpenGlCall(() ->
try
{
EVENT_LOGGER.info("Renderer Cleanup Started");
this.setupLock.lock();
this.isSetupComplete = false;
this.shaderProgram.free();
this.shaderProgram = null;
if (this.quadIBO != null)
GLProxy.getInstance().recordOpenGlCall(() ->
{
this.quadIBO.destroy(false);
}
// Delete framebuffer, color texture, and depth texture
//GL32.glBindRenderbuffer(GL32.GL_RENDERBUFFER, 0);
GL32.glDeleteFramebuffers(this.framebufferId);
GL32.glDeleteTextures(this.colorTextureId);
GL32.glDeleteTextures(this.depthTextureId);
EVENT_LOGGER.info("Renderer Cleanup Complete");
});
EVENT_LOGGER.info("Renderer Cleanup Started");
if (this.shaderProgram != null)
{
this.shaderProgram.free();
this.shaderProgram = null;
}
if (this.quadIBO != null)
{
this.quadIBO.destroy(false);
}
// Delete framebuffer, color texture, and depth texture
if (this.framebufferId != -1)
GL32.glDeleteFramebuffers(this.framebufferId);
if (this.colorTextureId != -1)
GL32.glDeleteTextures(this.colorTextureId);
if (this.depthTextureId != -1)
GL32.glDeleteTextures(this.depthTextureId);
EVENT_LOGGER.info("Renderer Cleanup Complete");
});
}
catch (Exception e)
{
this.setupLock.unlock();
}
}
}
@@ -46,6 +46,9 @@ public class DhApplyShader extends AbstractShaderRenderer
public int tempDepthTextureId;
private DhApplyShader() { }
@Override
public void onInit()
{
@@ -22,6 +22,7 @@ package com.seibel.distanthorizons.core.sql;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
@@ -55,7 +56,16 @@ public class DatabaseUpdater
public static <TDTO extends IBaseDTO> void runAutoUpdateScripts(AbstractDhRepo<TDTO> repo) throws SQLException
{
// get the resource scripts
ArrayList<SqlScript> scriptList = getAutoUpdateScripts();
ArrayList<SqlScript> scriptList;
try
{
scriptList = getAutoUpdateScripts();
}
catch (IOException e)
{
LOGGER.error("Get auto update SQL scripts failed. Error: " + e.getMessage(), e);
return;
}
@@ -155,25 +165,31 @@ public class DatabaseUpdater
//===============//
/** @throws NullPointerException if any of the script files failed to be read. */
private static ArrayList<SqlScript> getAutoUpdateScripts() throws NullPointerException
private static ArrayList<SqlScript> getAutoUpdateScripts() throws NullPointerException, IOException
{
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
// get the script list
InputStream scriptListInputStream = loader.getResourceAsStream(SQL_SCRIPT_LIST_FILE);
if (scriptListInputStream == null)
String scriptListString;
try (InputStream scriptListInputStream = loader.getResourceAsStream(SQL_SCRIPT_LIST_FILE))
{
throw new NullPointerException("Failed to find the SQL Script list file ["+SQL_SCRIPT_LIST_FILE+"], no auto update scripts can be run.");
if (scriptListInputStream == null)
{
throw new NullPointerException("Failed to find the SQL Script list file [" + SQL_SCRIPT_LIST_FILE + "], no auto update scripts can be run.");
}
try (Scanner scanner = new Scanner(scriptListInputStream).useDelimiter("\\A"))
{
scriptListString = scanner.hasNext() ? scanner.next() : "";
}
}
Scanner scanner = new Scanner(scriptListInputStream).useDelimiter("\\A");
String result = scanner.hasNext() ? scanner.next() : "";
// get each script
ArrayList<SqlScript> scriptList = new ArrayList<>();
String[] sqlScriptNames = result.split("\n");
String[] sqlScriptNames = scriptListString.split("\n");
for (String scriptName : sqlScriptNames)
{
scriptName = scriptName.trim();
@@ -185,15 +201,20 @@ public class DatabaseUpdater
scriptName = SQL_SCRIPT_RESOURCE_FOLDER + scriptName.trim();
// get the script's content
InputStream scriptInputStream = loader.getResourceAsStream(scriptName);
if (scriptInputStream == null)
try(InputStream scriptInputStream = loader.getResourceAsStream(scriptName))
{
throw new NullPointerException("Failed to find the SQL Script file ["+scriptName+"], no auto update scripts can be run.");
if (scriptInputStream == null)
{
throw new NullPointerException("Failed to find the SQL Script file [" + scriptName + "], no auto update scripts can be run.");
}
try (Scanner fileScanner = new Scanner(scriptInputStream).useDelimiter("\\A"))
{
scriptListString = fileScanner.hasNext() ? fileScanner.next() : "";
}
scriptList.add(new SqlScript(scriptName, scriptListString));
}
scanner = new Scanner(scriptInputStream).useDelimiter("\\A");
result = scanner.hasNext() ? scanner.next() : "";
scriptList.add(new SqlScript(scriptName, result));
}
return scriptList;