Skip to content

Commit

Permalink
Improve error handling of WindowRenderLoop and WindowEventLoop
Browse files Browse the repository at this point in the history
  • Loading branch information
knokko committed Oct 22, 2024
1 parent fbf0f58 commit 5428ee5
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,6 @@ public void beforePresent(MemoryStack stack, VkPresentInfoKHR presentInfo, Acqui

@Override
void waitUntilStateCanBeDestroyed(State state) {
for (var image : state.acquiredImages()) image.presentFence.awaitSignal();
for (var image : state.acquiredImages()) image.presentFence.waitIfSubmitted();
}
}
18 changes: 10 additions & 8 deletions src/main/java/com/github/knokko/boiler/window/VkbWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -340,13 +340,15 @@ public void presentSwapchainImage(AcquiredImage image, AwaitableSubmission rende
public synchronized void destroy() {
if (hasBeenDestroyed) return;

cleaner.destroyEverything();
vkDestroySurfaceKHR(instance.vkInstance(), vkSurface, null);
surfaceCapabilities.free();

if (windowLoop != null) windowLoop.destroy(this);
else glfwDestroyWindow(glfwWindow);

hasBeenDestroyed = true;
try {
cleaner.destroyEverything();
vkDestroySurfaceKHR(instance.vkInstance(), vkSurface, null);
surfaceCapabilities.free();
} finally {
if (windowLoop != null) windowLoop.destroy(this);
else glfwDestroyWindow(glfwWindow);

hasBeenDestroyed = true;
}
}
}
68 changes: 39 additions & 29 deletions src/main/java/com/github/knokko/boiler/window/WindowRenderLoop.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,39 +43,45 @@ public WindowRenderLoop(
private void run() {
try (var stack = stackPush()) {
setup(window.instance, stack);
} catch (Throwable setupFailed) {
window.destroy();
throw setupFailed;
}

long currentFrame = 0;
while (!glfwWindowShouldClose(window.glfwWindow)) {
if (window.windowLoop == null) glfwPollEvents();

int frameIndex = (int) (currentFrame % numFramesInFlight);

try (var stack = stackPush()) {
AcquiredImage acquiredImage;
if (acquireSwapchainImageWithFence) acquiredImage = window.acquireSwapchainImageWithFence(presentMode);
else acquiredImage = window.acquireSwapchainImageWithSemaphore(presentMode);
if (acquiredImage == null) {
//noinspection BusyWait
sleep(100);
continue;
try {
long currentFrame = 0;
while (!glfwWindowShouldClose(window.glfwWindow)) {
if (window.windowLoop == null) glfwPollEvents();

int frameIndex = (int) (currentFrame % numFramesInFlight);

try (var stack = stackPush()) {
AcquiredImage acquiredImage;
if (acquireSwapchainImageWithFence)
acquiredImage = window.acquireSwapchainImageWithFence(presentMode);
else acquiredImage = window.acquireSwapchainImageWithSemaphore(presentMode);
if (acquiredImage == null) {
//noinspection BusyWait
sleep(100);
continue;
}

if (acquireSwapchainImageWithFence) acquiredImage.acquireFence.awaitSignal();

var renderSubmission = renderFrame(stack, frameIndex, acquiredImage, window.instance);
if (renderSubmission == null) throw new RuntimeException(
"Submission must not be null, make sure to submit a fence or timeline signal semaphore"
);
window.presentSwapchainImage(acquiredImage, renderSubmission);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}

if (acquireSwapchainImageWithFence) acquiredImage.acquireFence.awaitSignal();

var renderSubmission = renderFrame(stack, frameIndex, acquiredImage, window.instance);
if (renderSubmission == null) throw new RuntimeException(
"Submission must not be null, make sure to submit a fence or timeline signal semaphore"
);
window.presentSwapchainImage(acquiredImage, renderSubmission);
} catch (InterruptedException e) {
throw new RuntimeException(e);
currentFrame += 1;
}
currentFrame += 1;
} finally {
cleanUp(window.instance);
window.destroy();
}

cleanUp(window.instance);
window.destroy();
}

/**
Expand All @@ -91,7 +97,11 @@ public void start() {
didStart = true;

if (window.windowLoop == null) this.run();
else new Thread(this::run).start();
else {
var thread = new Thread(this::run);
thread.setDaemon(true); // Ensure that the render thread dies when the main thread dies (unexpectedly)
thread.start();
}
}

/**
Expand Down

0 comments on commit 5428ee5

Please sign in to comment.