From fc4730c24a3c1cf71bf90e60da7e18b85068e1a2 Mon Sep 17 00:00:00 2001 From: austin Date: Wed, 28 Aug 2024 21:36:46 -0400 Subject: [PATCH] add yoga double free minimization --- .../electrosphere/renderer/OpenGLState.java | 2 + .../renderer/light/LightManager.java | 8 +++- .../electrosphere/renderer/model/Mesh.java | 1 - .../renderer/ui/elements/BitmapCharacter.java | 27 ++++++----- .../renderer/ui/elements/Label.java | 2 +- .../ui/elements/StandardContainerElement.java | 46 ++++++++++--------- .../renderer/ui/elements/StandardElement.java | 35 ++++++++------ .../renderer/ui/elements/TextBox.java | 4 +- .../renderer/ui/elements/Window.java | 38 +++++++-------- .../renderer/ui/elements/Word.java | 4 +- .../renderer/ui/elementtypes/Element.java | 5 ++ 11 files changed, 97 insertions(+), 75 deletions(-) diff --git a/src/main/java/electrosphere/renderer/OpenGLState.java b/src/main/java/electrosphere/renderer/OpenGLState.java index 140a3eec..6e96fa57 100644 --- a/src/main/java/electrosphere/renderer/OpenGLState.java +++ b/src/main/java/electrosphere/renderer/OpenGLState.java @@ -6,6 +6,7 @@ import java.util.Map; import org.joml.Vector2i; import org.lwjgl.opengl.GL40; +import electrosphere.engine.Globals; import electrosphere.renderer.shader.ShaderProgram; /** @@ -179,6 +180,7 @@ public class OpenGLState { if(DISABLE_CACHING || program != activeShader){ activeShader = program; GL40.glUseProgram(activeShader.getShaderId()); + Globals.renderingEngine.checkError(); renderPipelineState.setCurrentShaderPointer(activeShader.getShaderId()); } } diff --git a/src/main/java/electrosphere/renderer/light/LightManager.java b/src/main/java/electrosphere/renderer/light/LightManager.java index 9eef5dfb..c1761992 100644 --- a/src/main/java/electrosphere/renderer/light/LightManager.java +++ b/src/main/java/electrosphere/renderer/light/LightManager.java @@ -9,11 +9,13 @@ import org.joml.Vector3f; import org.lwjgl.BufferUtils; import org.lwjgl.opengl.GL30; import org.lwjgl.opengl.GL31; +import org.lwjgl.opengl.GL40; import electrosphere.engine.Globals; import electrosphere.entity.types.camera.CameraEntityUtils; import electrosphere.logger.LoggerInterface; import electrosphere.renderer.OpenGLState; +import electrosphere.renderer.RenderingEngine; import electrosphere.renderer.shader.ShaderProgram; /** @@ -158,7 +160,11 @@ public class LightManager { public void bindBuffer(OpenGLState openGLState){ //get position of lights object in shader int bufferIndex = GL31.glGetUniformBlockIndex(openGLState.getActiveShader().getShaderId(), "Lights"); - Globals.renderingEngine.checkError(); + int glErrorCode = Globals.renderingEngine.getError(); + //TODO: fix manually ignoring GL_INVALID_VALUE from call + if(glErrorCode != 0 && glErrorCode != GL40.GL_INVALID_VALUE){ + LoggerInterface.loggerRenderer.DEBUG_LOOP(RenderingEngine.getErrorInEnglish(glErrorCode)); + } if(bufferIndex == ShaderProgram.INVALID_UNIFORM_NAME){ LoggerInterface.loggerRenderer.INFO("Tried to buffer light manager to shader that does not have it active."); } else { diff --git a/src/main/java/electrosphere/renderer/model/Mesh.java b/src/main/java/electrosphere/renderer/model/Mesh.java index 13bd430d..1e4fec83 100644 --- a/src/main/java/electrosphere/renderer/model/Mesh.java +++ b/src/main/java/electrosphere/renderer/model/Mesh.java @@ -365,7 +365,6 @@ public class Mesh { selectedProgram = shader; } openGLState.setActiveShader(renderPipelineState, selectedProgram); - Globals.renderingEngine.checkError(); } if(renderPipelineState.getUseLight()){ diff --git a/src/main/java/electrosphere/renderer/ui/elements/BitmapCharacter.java b/src/main/java/electrosphere/renderer/ui/elements/BitmapCharacter.java index 31ff2b15..9d078ec2 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/BitmapCharacter.java +++ b/src/main/java/electrosphere/renderer/ui/elements/BitmapCharacter.java @@ -7,6 +7,7 @@ import electrosphere.renderer.RenderPipelineState; import electrosphere.renderer.model.Material; import electrosphere.renderer.model.Model; import electrosphere.renderer.ui.elementtypes.DrawableElement; +import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.events.Event; import electrosphere.renderer.ui.font.Font; import org.joml.Vector3f; @@ -127,18 +128,20 @@ public class BitmapCharacter extends StandardElement implements DrawableElement @Override public void applyYoga(int parentX, int parentY) { - //get the values from yoga - float leftRaw = Yoga.YGNodeLayoutGetLeft(yogaNode); - float topRaw = Yoga.YGNodeLayoutGetTop(yogaNode); - //apply the values to this component - this.internalPositionX = (int)leftRaw; - this.internalPositionY = (int)topRaw; - this.internalWidth = (int)Yoga.YGNodeLayoutGetWidth(yogaNode); - this.internalHeight = (int)Yoga.YGNodeLayoutGetHeight(yogaNode); - //calculate absolute values - if(!useAbsolutePosition){ - this.absoluteX = parentX + internalPositionX; - this.absoluteY = parentY + internalPositionY; + if(this.yogaNode != Element.NULL_YOGA_ELEMENT){ + //get the values from yoga + float leftRaw = Yoga.YGNodeLayoutGetLeft(yogaNode); + float topRaw = Yoga.YGNodeLayoutGetTop(yogaNode); + //apply the values to this component + this.internalPositionX = (int)leftRaw; + this.internalPositionY = (int)topRaw; + this.internalWidth = (int)Yoga.YGNodeLayoutGetWidth(yogaNode); + this.internalHeight = (int)Yoga.YGNodeLayoutGetHeight(yogaNode); + //calculate absolute values + if(!useAbsolutePosition){ + this.absoluteX = parentX + internalPositionX; + this.absoluteY = parentY + internalPositionY; + } } } diff --git a/src/main/java/electrosphere/renderer/ui/elements/Label.java b/src/main/java/electrosphere/renderer/ui/elements/Label.java index 23660759..7fd662a4 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Label.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Label.java @@ -76,7 +76,7 @@ public class Label extends StandardContainerElement implements DrawableElement { void generateLetters(){ //free children for(Element child : childList){ - Yoga.YGNodeFree(child.getYogaNode()); + child.destroy(); } childList.clear(); int accumulatingWidth = 0; diff --git a/src/main/java/electrosphere/renderer/ui/elements/StandardContainerElement.java b/src/main/java/electrosphere/renderer/ui/elements/StandardContainerElement.java index 8aaaeb2a..35963962 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/StandardContainerElement.java +++ b/src/main/java/electrosphere/renderer/ui/elements/StandardContainerElement.java @@ -238,31 +238,35 @@ public class StandardContainerElement extends StandardElement implements Contain for(Element child : childList){ child.destroy(); } - Yoga.YGNodeFree(this.yogaNode); + if(this.yogaNode != Element.NULL_YOGA_ELEMENT){ + Yoga.YGNodeFree(this.yogaNode); + } } @Override public void applyYoga(int parentX, int parentY) { - //get the values from yoga - float leftRaw = Yoga.YGNodeLayoutGetLeft(yogaNode); - float topRaw = Yoga.YGNodeLayoutGetTop(yogaNode); - float widthRaw = Yoga.YGNodeLayoutGetWidth(yogaNode); - float heightRaw = Yoga.YGNodeLayoutGetHeight(yogaNode); - LoggerInterface.loggerUI.DEBUG("" + this); - LoggerInterface.loggerUI.DEBUG("pos(" + leftRaw + "," + topRaw + ") dim(" + widthRaw + "," + heightRaw + ")"); - //apply the values to this component - if(!useAbsolutePosition){ - this.internalPositionX = (int)leftRaw; - this.internalPositionY = (int)topRaw; - this.internalWidth = (int)widthRaw; - this.internalHeight = (int)heightRaw; - //calculate absolute values - this.absoluteX = parentX + internalPositionX; - this.absoluteY = parentY + internalPositionY; - } - //apply yoga values to all children - for(Element child : this.getChildren()){ - child.applyYoga(parentX + internalPositionX,parentY + internalPositionY); + if(this.yogaNode != Element.NULL_YOGA_ELEMENT){ + //get the values from yoga + float leftRaw = Yoga.YGNodeLayoutGetLeft(yogaNode); + float topRaw = Yoga.YGNodeLayoutGetTop(yogaNode); + float widthRaw = Yoga.YGNodeLayoutGetWidth(yogaNode); + float heightRaw = Yoga.YGNodeLayoutGetHeight(yogaNode); + LoggerInterface.loggerUI.DEBUG("" + this); + LoggerInterface.loggerUI.DEBUG("pos(" + leftRaw + "," + topRaw + ") dim(" + widthRaw + "," + heightRaw + ")"); + //apply the values to this component + if(!useAbsolutePosition){ + this.internalPositionX = (int)leftRaw; + this.internalPositionY = (int)topRaw; + this.internalWidth = (int)widthRaw; + this.internalHeight = (int)heightRaw; + //calculate absolute values + this.absoluteX = parentX + internalPositionX; + this.absoluteY = parentY + internalPositionY; + } + //apply yoga values to all children + for(Element child : this.getChildren()){ + child.applyYoga(parentX + internalPositionX,parentY + internalPositionY); + } } } diff --git a/src/main/java/electrosphere/renderer/ui/elements/StandardElement.java b/src/main/java/electrosphere/renderer/ui/elements/StandardElement.java index 79cce48a..c9c2eed9 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/StandardElement.java +++ b/src/main/java/electrosphere/renderer/ui/elements/StandardElement.java @@ -157,7 +157,10 @@ public class StandardElement implements Element { @Override public void destroy(){ - Yoga.YGNodeFree(this.yogaNode); + if(this.yogaNode != Element.NULL_YOGA_ELEMENT){ + Yoga.YGNodeFree(this.yogaNode); + this.yogaNode = Element.NULL_YOGA_ELEMENT; + } } @Override @@ -167,20 +170,22 @@ public class StandardElement implements Element { @Override public void applyYoga(int parentX, int parentY) { - //get the values from yoga - float leftRaw = Yoga.YGNodeLayoutGetLeft(yogaNode); - float topRaw = Yoga.YGNodeLayoutGetTop(yogaNode); - float widthRaw = Yoga.YGNodeLayoutGetWidth(yogaNode); - float heightRaw = Yoga.YGNodeLayoutGetHeight(yogaNode); - if(!useAbsolutePosition){ - //apply the values to this component - this.internalPositionX = (int)leftRaw; - this.internalPositionY = (int)topRaw; - this.internalWidth = (int)widthRaw; - this.internalHeight = (int)heightRaw; - //calculate absolute values - this.absoluteX = parentX + internalPositionX; - this.absoluteY = parentY + internalPositionY; + if(this.yogaNode != Element.NULL_YOGA_ELEMENT){ + //get the values from yoga + float leftRaw = Yoga.YGNodeLayoutGetLeft(yogaNode); + float topRaw = Yoga.YGNodeLayoutGetTop(yogaNode); + float widthRaw = Yoga.YGNodeLayoutGetWidth(yogaNode); + float heightRaw = Yoga.YGNodeLayoutGetHeight(yogaNode); + if(!useAbsolutePosition){ + //apply the values to this component + this.internalPositionX = (int)leftRaw; + this.internalPositionY = (int)topRaw; + this.internalWidth = (int)widthRaw; + this.internalHeight = (int)heightRaw; + //calculate absolute values + this.absoluteX = parentX + internalPositionX; + this.absoluteY = parentY + internalPositionY; + } } } diff --git a/src/main/java/electrosphere/renderer/ui/elements/TextBox.java b/src/main/java/electrosphere/renderer/ui/elements/TextBox.java index 37c00c70..0ae98810 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/TextBox.java +++ b/src/main/java/electrosphere/renderer/ui/elements/TextBox.java @@ -1,7 +1,5 @@ package electrosphere.renderer.ui.elements; -import org.lwjgl.util.yoga.Yoga; - import electrosphere.engine.Globals; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; @@ -110,7 +108,7 @@ public class TextBox extends StandardDrawableContainerElement { void generateLetters(){ //free children for(Element child : childList){ - Yoga.YGNodeFree(child.getYogaNode()); + child.destroy(); } childList.clear(); String[] words = text.split(" "); diff --git a/src/main/java/electrosphere/renderer/ui/elements/Window.java b/src/main/java/electrosphere/renderer/ui/elements/Window.java index 260d3885..7fa9634b 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Window.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Window.java @@ -355,24 +355,26 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme @Override public void applyYoga(int parentX, int parentY) { - Yoga.YGNodeStyleSetWidth(parentWindowYogaNode, Globals.WINDOW_WIDTH); - Yoga.YGNodeStyleSetHeight(parentWindowYogaNode, Globals.WINDOW_HEIGHT); - //calculate yoga layout - Yoga.YGNodeCalculateLayout(parentWindowYogaNode, width, height, Yoga.YGDirectionInherit); - //get the values from yoga - float leftRaw = Yoga.YGNodeLayoutGetLeft(yogaNode); - float topRaw = Yoga.YGNodeLayoutGetTop(yogaNode); - float widthRaw = Yoga.YGNodeLayoutGetWidth(yogaNode); - float heightRaw = Yoga.YGNodeLayoutGetHeight(yogaNode); - // //apply the values to this component - this.positionX = (int)leftRaw; - this.positionY = (int)topRaw; - this.width = (int)widthRaw; - this.height = (int)heightRaw; - //apply yoga values to all children - LoggerInterface.loggerUI.DEBUG("==Apply yoga to windoow=="); - for(Element child : this.getChildren()){ - child.applyYoga(this.positionX,this.positionY); + if(this.yogaNode != Element.NULL_YOGA_ELEMENT){ + Yoga.YGNodeStyleSetWidth(parentWindowYogaNode, Globals.WINDOW_WIDTH); + Yoga.YGNodeStyleSetHeight(parentWindowYogaNode, Globals.WINDOW_HEIGHT); + //calculate yoga layout + Yoga.YGNodeCalculateLayout(parentWindowYogaNode, width, height, Yoga.YGDirectionInherit); + //get the values from yoga + float leftRaw = Yoga.YGNodeLayoutGetLeft(yogaNode); + float topRaw = Yoga.YGNodeLayoutGetTop(yogaNode); + float widthRaw = Yoga.YGNodeLayoutGetWidth(yogaNode); + float heightRaw = Yoga.YGNodeLayoutGetHeight(yogaNode); + // //apply the values to this component + this.positionX = (int)leftRaw; + this.positionY = (int)topRaw; + this.width = (int)widthRaw; + this.height = (int)heightRaw; + //apply yoga values to all children + LoggerInterface.loggerUI.DEBUG("==Apply yoga to windoow=="); + for(Element child : this.getChildren()){ + child.applyYoga(this.positionX,this.positionY); + } } } diff --git a/src/main/java/electrosphere/renderer/ui/elements/Word.java b/src/main/java/electrosphere/renderer/ui/elements/Word.java index b108e66b..ec88e773 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Word.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Word.java @@ -1,7 +1,5 @@ package electrosphere.renderer.ui.elements; -import org.lwjgl.util.yoga.Yoga; - import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; import electrosphere.renderer.OpenGLState; @@ -88,7 +86,7 @@ public class Word extends StandardDrawableContainerElement { void generateLetters(){ //free children for(Element child : childList){ - Yoga.YGNodeFree(child.getYogaNode()); + child.destroy(); } childList.clear(); for(int i = 0; i < text.length(); i++){ diff --git a/src/main/java/electrosphere/renderer/ui/elementtypes/Element.java b/src/main/java/electrosphere/renderer/ui/elementtypes/Element.java index fca9f11a..875e1102 100644 --- a/src/main/java/electrosphere/renderer/ui/elementtypes/Element.java +++ b/src/main/java/electrosphere/renderer/ui/elementtypes/Element.java @@ -4,6 +4,11 @@ import electrosphere.renderer.ui.events.Event; public interface Element { + /** + * A yoga element that either hasn't been created or has already been destroyed + */ + public static final int NULL_YOGA_ELEMENT = -1; + //width and height public int getWidth(); public int getHeight();