From a7e8c2d9d5d76b2ae0012f5532491a1782d0e64d Mon Sep 17 00:00:00 2001 From: James Ball Date: Tue, 28 Jun 2022 20:26:32 +0100 Subject: [PATCH] Make GPU rendering toggleable to prevent crashes due to bad initialisation --- CHANGELOG.md | 4 +++ pom.xml | 2 +- src/main/java/sh/ball/engine/Camera.java | 18 +++++++++++++ .../java/sh/ball/engine/CameraDrawKernel.java | 26 +++++++++++-------- src/main/java/sh/ball/engine/WorldObject.java | 9 ------- .../ball/gui/controller/MainController.java | 14 ++++++++++ .../sh/ball/gui/controller/ObjController.java | 4 +++ .../sh/ball/parser/obj/ObjFrameSettings.java | 4 ++- .../sh/ball/parser/obj/ObjFrameSource.java | 7 +++-- .../ball/parser/obj/ObjSettingsFactory.java | 8 ++++-- src/main/resources/fxml/main.fxml | 3 ++- 11 files changed, 72 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 778f2274..b974409a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +- 1.26.4 + - Make GPU rendering toggleable to prevent crashes due to bad initialisation + + - 1.26.3 - Fix potential bug with updating frequency spinner and slider from not-GUI thread diff --git a/pom.xml b/pom.xml index 5a0837bb..6e29b3a7 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ sh.ball osci-render - 1.26.3 + 1.26.4 osci-render diff --git a/src/main/java/sh/ball/engine/Camera.java b/src/main/java/sh/ball/engine/Camera.java index 4aa838b5..5d02f730 100644 --- a/src/main/java/sh/ball/engine/Camera.java +++ b/src/main/java/sh/ball/engine/Camera.java @@ -24,6 +24,8 @@ public class Camera { private double focalLength; private Vector3 pos; + private boolean hideEdges = false; + private boolean usingGpu = false; public Camera(double focalLength, Vector3 pos) { this.focalLength = focalLength; @@ -105,4 +107,20 @@ public class Camera { public double getFocalLength() { return focalLength; } + + public void hideEdges(boolean hideEdges) { + this.hideEdges = hideEdges; + } + + public boolean edgesHidden() { + return hideEdges; + } + + public void usingGpu(boolean usingGpu) { + this.usingGpu = usingGpu; + } + + public boolean isUsingGpu() { + return usingGpu; + } } diff --git a/src/main/java/sh/ball/engine/CameraDrawKernel.java b/src/main/java/sh/ball/engine/CameraDrawKernel.java index b8f1e5d9..3c57b915 100644 --- a/src/main/java/sh/ball/engine/CameraDrawKernel.java +++ b/src/main/java/sh/ball/engine/CameraDrawKernel.java @@ -36,7 +36,9 @@ public class CameraDrawKernel extends Kernel { private float focalLength; private int hideEdges = 0; private int usingObjectSet = 0; + private boolean initialisedGpu = false; private boolean failedGpu = false; + private int maxGroupSize = 256; public CameraDrawKernel() {} @@ -131,9 +133,13 @@ public class CameraDrawKernel extends Kernel { this.cameraPosZ = (float) cameraPos.z; this.focalLength = (float) camera.getFocalLength(); - this.hideEdges = object.edgesHidden() ? 1 : 0; + this.hideEdges = camera.edgesHidden() ? 1 : 0; - return executeGpu(); + if (!camera.isUsingGpu() || failedGpu || vertices.length / 3 < MIN_GPU_VERTICES) { + return executeCpu(); + } else { + return executeGpu(); + } } private List postProcessVertices() { @@ -164,16 +170,14 @@ public class CameraDrawKernel extends Kernel { } private List executeGpu() { - if (failedGpu || vertices.length / 3 < MIN_GPU_VERTICES) { - return executeCpu(); - } - try { - int maxGroupSize = 256; - try { - maxGroupSize = getKernelMaxWorkGroupSize(getTargetDevice()); - } catch (QueryFailedException e) { - logger.log(Level.WARNING, e.getMessage(), e); + if (!initialisedGpu) { + try { + maxGroupSize = getKernelMaxWorkGroupSize(getTargetDevice()); + initialisedGpu = true; + } catch (QueryFailedException e) { + logger.log(Level.WARNING, e.getMessage(), e); + } } execute(Range.create(roundUp(vertices.length / 3, maxGroupSize), maxGroupSize)); diff --git a/src/main/java/sh/ball/engine/WorldObject.java b/src/main/java/sh/ball/engine/WorldObject.java index 3e5892e5..94527223 100644 --- a/src/main/java/sh/ball/engine/WorldObject.java +++ b/src/main/java/sh/ball/engine/WorldObject.java @@ -26,7 +26,6 @@ public class WorldObject { private List> vertexPath; private Vector3 position; private Vector3 rotation; - private boolean hideEdges = false; public WorldObject(Vector3[] vertices, int[] edgeIndices, int[][] faceIndices) { vertexPath = new ArrayList<>(); @@ -319,12 +318,4 @@ public class WorldObject { return new WorldObject(new ArrayList<>(objVertices), new ArrayList<>(vertexPath), position, rotation); } - - public void hideEdges(boolean hideEdges) { - this.hideEdges = hideEdges; - } - - public boolean edgesHidden() { - return hideEdges; - } } diff --git a/src/main/java/sh/ball/gui/controller/MainController.java b/src/main/java/sh/ball/gui/controller/MainController.java index dcedc7df..4b0d1e9a 100644 --- a/src/main/java/sh/ball/gui/controller/MainController.java +++ b/src/main/java/sh/ball/gui/controller/MainController.java @@ -148,6 +148,8 @@ public class MainController implements Initializable, FrequencyListener, MidiLis @FXML private CheckMenuItem hideHiddenMeshesCheckMenuItem; @FXML + private CheckMenuItem renderUsingGpuCheckMenuItem; + @FXML private Spinner midiChannelSpinner; @FXML private Spinner attackSpinner; @@ -408,6 +410,8 @@ public class MainController implements Initializable, FrequencyListener, MidiLis hideHiddenMeshesCheckMenuItem.selectedProperty().addListener((e, old, hidden) -> objController.hideHiddenMeshes(hidden)); + renderUsingGpuCheckMenuItem.selectedProperty().addListener((e, old, usingGpu) -> objController.renderUsingGpu(usingGpu)); + NumberFormat format = NumberFormat.getIntegerInstance(); UnaryOperator filter = c -> { if (c.isContentChange()) { @@ -691,6 +695,7 @@ public class MainController implements Initializable, FrequencyListener, MidiLis } // FIXME: Is this safe since we are accessing GUI object in non-GUI thread? objController.hideHiddenMeshes(hideHiddenMeshesCheckMenuItem.isSelected()); + objController.renderUsingGpu(renderUsingGpuCheckMenuItem.isSelected()); executor.submit(producer); } else if (samples != null) { samples.enable(); @@ -1141,6 +1146,10 @@ public class MainController implements Initializable, FrequencyListener, MidiLis hiddenEdges.appendChild(document.createTextNode(String.valueOf(hideHiddenMeshesCheckMenuItem.isSelected()))); root.appendChild(hiddenEdges); + Element usingGpu = document.createElement("usingGpu"); + usingGpu.appendChild(document.createTextNode(String.valueOf(renderUsingGpuCheckMenuItem.isSelected()))); + root.appendChild(usingGpu); + Element translationIncrement = document.createElement("translationIncrement"); translationIncrement.appendChild(document.createTextNode(translationIncrementSpinner.getValue().toString())); root.appendChild(translationIncrement); @@ -1263,6 +1272,11 @@ public class MainController implements Initializable, FrequencyListener, MidiLis hideHiddenMeshesCheckMenuItem.setSelected(Boolean.parseBoolean(hiddenEdges.getTextContent())); } + Element usingGpu = (Element) root.getElementsByTagName("usingGpu").item(0); + if (usingGpu != null) { + renderUsingGpuCheckMenuItem.setSelected(Boolean.parseBoolean(usingGpu.getTextContent())); + } + Element translationIncrement = (Element) root.getElementsByTagName("translationIncrement").item(0); if (translationIncrement != null) { translationIncrementSpinner.getValueFactory().setValue(Double.parseDouble(translationIncrement.getTextContent())); diff --git a/src/main/java/sh/ball/gui/controller/ObjController.java b/src/main/java/sh/ball/gui/controller/ObjController.java index 3560afb9..223e6264 100644 --- a/src/main/java/sh/ball/gui/controller/ObjController.java +++ b/src/main/java/sh/ball/gui/controller/ObjController.java @@ -182,4 +182,8 @@ public class ObjController implements Initializable, SubController { @Override public void load(Element root) {} + + public void renderUsingGpu(boolean usingGpu) { + producer.setFrameSettings(ObjSettingsFactory.renderUsingGpu(usingGpu)); + } } diff --git a/src/main/java/sh/ball/parser/obj/ObjFrameSettings.java b/src/main/java/sh/ball/parser/obj/ObjFrameSettings.java index d5c43832..5e92cc21 100644 --- a/src/main/java/sh/ball/parser/obj/ObjFrameSettings.java +++ b/src/main/java/sh/ball/parser/obj/ObjFrameSettings.java @@ -11,8 +11,9 @@ public class ObjFrameSettings { public Double rotateSpeed; public boolean resetRotation = false; public Boolean hideEdges = null; + public Boolean usingGpu = null; - protected ObjFrameSettings(Double focalLength, Vector3 cameraPos, Vector3 baseRotation, Vector3 currentRotation, Double rotateSpeed, boolean resetRotation, Boolean hideEdges) { + protected ObjFrameSettings(Double focalLength, Vector3 cameraPos, Vector3 baseRotation, Vector3 currentRotation, Double rotateSpeed, boolean resetRotation, Boolean hideEdges, Boolean usingGpu) { this.focalLength = focalLength; this.cameraPos = cameraPos; this.baseRotation = baseRotation; @@ -20,6 +21,7 @@ public class ObjFrameSettings { this.rotateSpeed = rotateSpeed; this.resetRotation = resetRotation; this.hideEdges = hideEdges; + this.usingGpu = usingGpu; } protected ObjFrameSettings(double focalLength) { diff --git a/src/main/java/sh/ball/parser/obj/ObjFrameSource.java b/src/main/java/sh/ball/parser/obj/ObjFrameSource.java index c25702c7..2ee1df7c 100644 --- a/src/main/java/sh/ball/parser/obj/ObjFrameSource.java +++ b/src/main/java/sh/ball/parser/obj/ObjFrameSource.java @@ -68,7 +68,10 @@ public class ObjFrameSource implements FrameSource> { object.resetRotation(); } if (obj.hideEdges != null) { - object.hideEdges(obj.hideEdges); + camera.hideEdges(obj.hideEdges); + } + if (obj.usingGpu != null) { + camera.usingGpu(obj.usingGpu); } } } @@ -76,6 +79,6 @@ public class ObjFrameSource implements FrameSource> { // TODO: Refactor! @Override public Object getFrameSettings() { - return new ObjFrameSettings(null, null, baseRotation, currentRotation, null, false, object.edgesHidden()); + return new ObjFrameSettings(null, null, baseRotation, currentRotation, null, false, camera.edgesHidden(), camera.isUsingGpu()); } } diff --git a/src/main/java/sh/ball/parser/obj/ObjSettingsFactory.java b/src/main/java/sh/ball/parser/obj/ObjSettingsFactory.java index 235ee9a2..30a3585b 100644 --- a/src/main/java/sh/ball/parser/obj/ObjSettingsFactory.java +++ b/src/main/java/sh/ball/parser/obj/ObjSettingsFactory.java @@ -17,7 +17,7 @@ public class ObjSettingsFactory { } public static ObjFrameSettings rotation(Vector3 baseRotation, Vector3 currentRotation) { - return new ObjFrameSettings(null, null, baseRotation, currentRotation, null, false, null); + return new ObjFrameSettings(null, null, baseRotation, currentRotation, null, false, null, null); } public static ObjFrameSettings rotateSpeed(double rotateSpeed) { @@ -29,6 +29,10 @@ public class ObjSettingsFactory { } public static ObjFrameSettings hideEdges(Boolean hideEdges) { - return new ObjFrameSettings(null, null, null, null, null, false, hideEdges); + return new ObjFrameSettings(null, null, null, null, null, false, hideEdges, null); + } + + public static ObjFrameSettings renderUsingGpu(Boolean usingGpu) { + return new ObjFrameSettings(null, null, null, null, null, false, null, usingGpu); } } diff --git a/src/main/resources/fxml/main.fxml b/src/main/resources/fxml/main.fxml index d54c995c..6db0aaca 100644 --- a/src/main/resources/fxml/main.fxml +++ b/src/main/resources/fxml/main.fxml @@ -21,7 +21,7 @@ - + @@ -152,6 +152,7 @@ +