Skip to content

Commit

Permalink
Make sure crashed windows get destroyed
Browse files Browse the repository at this point in the history
  • Loading branch information
knokko committed Jan 3, 2025
1 parent 5966be0 commit ad23d85
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 17 deletions.
4 changes: 1 addition & 3 deletions src/main/java/com/github/knokko/boiler/window/VkbWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -346,9 +346,7 @@ public synchronized void destroy() {
vkDestroySurfaceKHR(instance.vkInstance(), vkSurface, null);
surfaceCapabilities.free();
} finally {
if (windowLoop != null) windowLoop.destroy(this);
else glfwDestroyWindow(glfwWindow);

if (windowLoop == null) glfwDestroyWindow(glfwWindow);
hasBeenDestroyed = true;
}
}
Expand Down
26 changes: 13 additions & 13 deletions src/main/java/com/github/knokko/boiler/window/WindowEventLoop.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public WindowEventLoop(double waitTimeout, Runnable updateCallback) {
}

public WindowEventLoop() {
this(0.0, null);
this(0.5, null);
}

private void update(VkbWindow resizedWindow) {
Expand Down Expand Up @@ -72,27 +72,26 @@ private void update(VkbWindow resizedWindow) {
}
}

private void initializeNewWindows() {
private void initializeAndDestroyWindows() {
stateMap.forEach((window, state) -> {
if (!state.initialized.isDone()) {
//noinspection resource
glfwSetFramebufferSizeCallback(window.glfwWindow, (glfwWindow, width, height) -> update(window));
state.initialized.complete(null);
}
if (state.renderLoop.thread != null && !state.renderLoop.thread.isAlive()) {
queue.add(new Task(null, state, window));
}
});
}

private void addWindow(VkbWindow window) {
stateMap.put(window, new State());
window.windowLoop = this;
}

/**
* Adds the given window (render loop) to the event loop. After this method returns, this event loop will
* handle swapchain recreations for the given window. This method can be called from any thread.
*/
public void addWindow(WindowRenderLoop renderLoop) {
addWindow(renderLoop.window);
stateMap.put(renderLoop.window, new State(renderLoop));
renderLoop.window.windowLoop = this;
renderLoop.start();
}

Expand All @@ -106,7 +105,7 @@ public void runMain() {
else glfwWaitEvents();
if (updateCallback != null) updateCallback.run();
update(null);
initializeNewWindows();
initializeAndDestroyWindows();
}
}

Expand All @@ -130,10 +129,6 @@ boolean shouldCheckResize(VkbWindow window) {
return getState(window).shouldCheckResize;
}

void destroy(VkbWindow window) {
queueResize(null, window);
}

void queueResize(Runnable resize, VkbWindow window) {
var state = getState(window);
queue.add(new Task(resize, state, window));
Expand All @@ -146,9 +141,14 @@ private record Task(Runnable runnable, State state, VkbWindow window) {

private static class State {

final WindowRenderLoop renderLoop;
final CompletableFuture<Object> initialized = new CompletableFuture<>();
final Semaphore resizeCompleted = new Semaphore(0);
volatile boolean shouldCheckResize;
volatile long lastResizeTime;

State(WindowRenderLoop renderLoop) {
this.renderLoop = renderLoop;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public abstract class WindowRenderLoop {
protected boolean acquireSwapchainImageWithFence;
protected int presentMode;
private volatile boolean didStart;
volatile Thread thread;

/**
* @param window The window
Expand Down Expand Up @@ -106,7 +107,7 @@ public void start() {

if (window.windowLoop == null) this.run();
else {
var thread = new Thread(this::run);
this.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 ad23d85

Please sign in to comment.