From db0d07ed133f8bff372d3d6cc1570bde83ee4131 Mon Sep 17 00:00:00 2001 From: Supakorn 'Jamie' Rassameemasmuang Date: Sun, 31 Dec 2023 21:43:49 -0700 Subject: [PATCH] VK: Use thread safe queue for export signaling. --- include/vkrender.h | 11 ++++++++++- src/vkrender.cc | 47 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/include/vkrender.h b/include/vkrender.h index 4568db6f9..a10bde18c 100644 --- a/include/vkrender.h +++ b/include/vkrender.h @@ -41,6 +41,8 @@ #include "triple.h" #include "seconds.h" #include "statistics.h" +#include "ThreadSafeQueue.h" +#include "vkRenderMessages.h" namespace camp { @@ -379,6 +381,11 @@ class AsyVkRender DrawMode mode = DRAWMODE_NORMAL; std::string title = ""; + /** + * @remark Main thread is the consumer, other thread is the sender of messages; + */ + ThreadSafeQueue messageQueue; + #ifdef HAVE_PTHREAD pthread_t mainthread; @@ -928,9 +935,10 @@ class AsyVkRender void nextFrame(); void display(); - void poll(); + optional poll(); void mainLoop(); void cleanup(); + void processMessages(VulkanRendererMessage const& msg); void idleFunc(std::function f); void idle(); @@ -938,6 +946,7 @@ class AsyVkRender // user controls static void exportHandler(int=0); void Export(int imageIndex); + bool readyForExport=false; void quit(); double spinStep(); diff --git a/src/vkrender.cc b/src/vkrender.cc index 1cead03fb..328a88b25 100644 --- a/src/vkrender.cc +++ b/src/vkrender.cc @@ -6,6 +6,7 @@ #include #include +#include "ThreadSafeQueue.h" #define SHADER_DIRECTORY "shaders/" #define VALIDATION_LAYER "VK_LAYER_KHRONOS_validation" @@ -3860,7 +3861,7 @@ void AsyVkRender::display() } } -void AsyVkRender::poll() +optional AsyVkRender::poll() { if (View) { if (glfwWindowShouldClose(window)) { @@ -3876,14 +3877,38 @@ void AsyVkRender::poll() if (View) { glfwPollEvents(); } + + return messageQueue.dequeue(); +} + +void AsyVkRender::processMessages(VulkanRendererMessage const& msg) +{ + switch (msg) + { + case exportRender: { + if (readyForExport) + { + readyForExport= false; + exportHandler(0); + } + } + break; + default: + break; + } } void AsyVkRender::mainLoop() { int nFrames = 0; - while (poll(), true) { - + while (true) { + auto const message = poll(); + if (message.has_value()) + { + processMessages(*message); + } + if (redraw || queueExport) { redraw = false; display(); @@ -3899,18 +3924,28 @@ void AsyVkRender::mainLoop() } vkDeviceWaitIdle(*device); - + if(!View) { if(vkthread) { if(havewindow) { + // from where can this thread be called? + // signals to the main thread to start exporting readyAfterExport=true; #ifdef HAVE_PTHREAD - pthread_kill(mainthread,SIGUSR1); + if (pthread_equal(pthread_self(), this->mainthread)) + { + exportHandler(); + } + else + { + messageQueue.enqueue(exportRender); + } #endif } else { + // from main thread initialized=true; + readyForExport=true; readyAfterExport=true; - Signal(SIGUSR1,exportHandler); exportHandler(); } } else {