From 279b1884fc4895d861bcf12a784e0f82e9f8b9ea Mon Sep 17 00:00:00 2001 From: Bart Janssens Date: Wed, 6 Sep 2023 08:46:28 +0200 Subject: [PATCH 1/6] Checkpoint partial multi-threading support --- CMakeLists.txt | 2 ++ application_manager.cpp | 7 ++++--- foreign_thread_manager.cpp | 32 ++++++++++++++++++++++++++++++++ foreign_thread_manager.hpp | 17 +++++++++++++++++ julia_canvas.cpp | 4 ++++ 5 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 foreign_thread_manager.cpp create mode 100644 foreign_thread_manager.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 666fbd7..ab4d7aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,8 @@ qt6_add_qml_module(jlqml SOURCES application_manager.hpp application_manager.cpp + foreign_thread_manager.hpp + foreign_thread_manager.cpp julia_api.hpp julia_api.cpp julia_canvas.hpp diff --git a/application_manager.cpp b/application_manager.cpp index 3bbd55b..31d2b74 100644 --- a/application_manager.cpp +++ b/application_manager.cpp @@ -1,6 +1,8 @@ -#include "application_manager.hpp" #include "jlcxx/functions.hpp" +#include "foreign_thread_manager.hpp" +#include "application_manager.hpp" + namespace qmlwrap { @@ -11,11 +13,9 @@ void julia_message_output(QtMsgType type, const QMessageLogContext &context, con case QtDebugMsg: jl_safe_printf("Qt Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; -#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)) case QtInfoMsg: jl_safe_printf("Qt Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; -#endif case QtWarningMsg: jl_safe_printf("Qt Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; @@ -96,6 +96,7 @@ void ApplicationManager::exec() stoptimer(); app->exit(status); }); + ForeignThreadManager::instance().clear(QThread::currentThread()); const int status = app->exec(); if (status != 0) { diff --git a/foreign_thread_manager.cpp b/foreign_thread_manager.cpp new file mode 100644 index 0000000..ca18c1c --- /dev/null +++ b/foreign_thread_manager.cpp @@ -0,0 +1,32 @@ +#include "jlcxx/jlcxx.hpp" + +#include "foreign_thread_manager.hpp" + +ForeignThreadManager& ForeignThreadManager::instance() +{ + static ForeignThreadManager instance; + return instance; +} + +void ForeignThreadManager::add_thread(QThread *t) +{ + m_mutex.lock(); + if(!m_threads.contains(t)) + { + m_threads.insert(t); + jl_adopt_thread(); + } + m_mutex.unlock(); +} + +void ForeignThreadManager::clear(QThread* main_thread) +{ + m_mutex.lock(); + m_threads.clear(); + m_threads.insert(main_thread); + m_mutex.unlock(); +} + +ForeignThreadManager::ForeignThreadManager() +{ +} diff --git a/foreign_thread_manager.hpp b/foreign_thread_manager.hpp new file mode 100644 index 0000000..bd28539 --- /dev/null +++ b/foreign_thread_manager.hpp @@ -0,0 +1,17 @@ +#include +#include +#include + +class ForeignThreadManager +{ +public: + static ForeignThreadManager& instance(); + + void add_thread(QThread* t); + void clear(QThread* main_thread); + +private: + ForeignThreadManager(); + QSet m_threads; + QMutex m_mutex; +}; diff --git a/julia_canvas.cpp b/julia_canvas.cpp index 1284c66..81c6e71 100644 --- a/julia_canvas.cpp +++ b/julia_canvas.cpp @@ -2,7 +2,10 @@ #include #include +#include "foreign_thread_manager.hpp" + #include "julia_canvas.hpp" + namespace qmlwrap { @@ -12,6 +15,7 @@ JuliaCanvas::JuliaCanvas(QQuickItem *parent) : QQuickPaintedItem(parent) void JuliaCanvas::paint(QPainter *painter) { + ForeignThreadManager::instance().add_thread(QThread::currentThread()); // allocate buffer for julia callback to draw on int iwidth = width(); int iheight = height(); From ba80233dd7e9e9a0fc98a4f7e10a971bb94aa6f5 Mon Sep 17 00:00:00 2001 From: Bart Janssens Date: Wed, 6 Sep 2023 08:54:01 +0200 Subject: [PATCH 2/6] Fix compatibility with Qt 6.5 --- opengl_viewport.cpp | 4 ---- wrap_qml.cpp | 10 +++++----- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/opengl_viewport.cpp b/opengl_viewport.cpp index f8b1517..2a27379 100644 --- a/opengl_viewport.cpp +++ b/opengl_viewport.cpp @@ -64,11 +64,7 @@ OpenGLViewport::OpenGLViewport(QQuickItem *parent, RenderFunction* render_func) qFatal("QSG_RENDER_LOOP must be set to basic to use OpenGLViewport or MakieViewport. Add the line\nENV[\"QSG_RENDER_LOOP\"] = \"basic\"\nat the top of your Julia program"); } QObject::connect(this, &OpenGLViewport::renderFunctionChanged, this, &OpenGLViewport::update); -#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) setMirrorVertically(true); -#else - qWarning() << "setMirrorVertically not available before Qt 5.6, OpenGLViewport image will be upside-down"; -#endif } void OpenGLViewport::render() diff --git a/wrap_qml.cpp b/wrap_qml.cpp index 2f7174a..2d075d6 100644 --- a/wrap_qml.cpp +++ b/wrap_qml.cpp @@ -479,11 +479,7 @@ JLCXX_MODULE define_julia_module(jlcxx::Module& qml_module) qml_module.method("effectiveDevicePixelRatio", [] (QQuickWindow& w) { -#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)) - return w.effectiveDevicePixelRatio(); -#else - return 1.0; -#endif + return w.effectiveDevicePixelRatio(); }); qml_module.add_type("QQuickView", julia_base_type()) @@ -513,7 +509,11 @@ JLCXX_MODULE define_julia_module(jlcxx::Module& qml_module) } }); +#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)) + qml_module.method("qputenv", [] (const char* varName, QByteArray value) { qputenv(varName, value); }); +#else qml_module.method("qputenv", qputenv); +#endif qml_module.method("qgetenv", qgetenv); qml_module.method("qunsetenv", qunsetenv); From c7dcc14568eaa147f80c2fb6403ced85dac5d32a Mon Sep 17 00:00:00 2001 From: Bart Janssens Date: Wed, 6 Sep 2023 08:55:13 +0200 Subject: [PATCH 3/6] Set version to v0.5.3 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ab4d7aa..5c231e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ project(JlQML) cmake_minimum_required(VERSION 3.16.0) -set(JlQML_VERSION 0.5.2) +set(JlQML_VERSION 0.5.3) message(STATUS "Project version: v${JlQML_VERSION}") set(CMAKE_MACOSX_RPATH 1) From 77c1236f7a9882e05e8218fba4591fb4ad845bd0 Mon Sep 17 00:00:00 2001 From: Bart Janssens Date: Fri, 15 Sep 2023 00:30:22 +0200 Subject: [PATCH 4/6] Fix Wayland problem --- application_manager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/application_manager.cpp b/application_manager.cpp index 31d2b74..1ca4aa0 100644 --- a/application_manager.cpp +++ b/application_manager.cpp @@ -113,6 +113,7 @@ ApplicationManager::ApplicationManager() QSurfaceFormat format = QSurfaceFormat::defaultFormat(); format.setProfile(QSurfaceFormat::CoreProfile); + format.setRenderableType(QSurfaceFormat::OpenGL); format.setMajorVersion(3); format.setMinorVersion(3); //format.setOption(QSurfaceFormat::DebugContext); // note: this needs OpenGL 4.3 From 118f62395c3f69d200db570b0f272026e3e8933a Mon Sep 17 00:00:00 2001 From: Bart Janssens Date: Sat, 16 Sep 2023 11:24:21 +0200 Subject: [PATCH 5/6] Fix tests --- .github/workflows/test.yml | 4 ++-- foreign_thread_manager.cpp | 7 +++++++ test/setup-test.jl | 12 ------------ 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2af4cc7..ecbe44c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,8 +15,8 @@ jobs: fail-fast: false matrix: version: - - '1.7' - - '1.8' + - '1.6' + - '1.9' - 'nightly' os: - ubuntu-latest diff --git a/foreign_thread_manager.cpp b/foreign_thread_manager.cpp index ca18c1c..0cd1e7a 100644 --- a/foreign_thread_manager.cpp +++ b/foreign_thread_manager.cpp @@ -14,7 +14,14 @@ void ForeignThreadManager::add_thread(QThread *t) if(!m_threads.contains(t)) { m_threads.insert(t); + #if (JULIA_VERSION_MAJOR * 100 + JULIA_VERSION_MINOR) >= 109 jl_adopt_thread(); + #else + if(m_threads.size() > 1) + { + std::cout << "Warning: using multiple threads in Julia versions older than 1.9 will probably crash" << std::endl; + } + #endif } m_mutex.unlock(); } diff --git a/test/setup-test.jl b/test/setup-test.jl index 9f38ec6..d1ca05c 100644 --- a/test/setup-test.jl +++ b/test/setup-test.jl @@ -24,18 +24,6 @@ function libcxxwrap_jll_version() return VersionNumber(baseversion) end -@static if Sys.isapple() - jllversion = libcxxwrap_jll_version() - cd(joinpath(cxxwrap_root, "lib")) do - expected_dylib = "libcxxwrap_julia.$jllversion.dylib" - if !isfile(expected_dylib) - compiled_dylib = readlink("libcxxwrap_julia.dylib") - symlink(compiled_dylib, expected_dylib) - println("linked $expected_dylib to $compiled_dylib") - end - end -end - envdir = mktempdir() import Pkg Pkg.activate(envdir) From 2da29a9ba7ceb132bce6a97c40428cbb976e163c Mon Sep 17 00:00:00 2001 From: Bart Janssens Date: Sat, 16 Sep 2023 14:52:56 +0200 Subject: [PATCH 6/6] Test on Julia 1.8 instead of 1.6 --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ecbe44c..da2a57e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: fail-fast: false matrix: version: - - '1.6' + - '1.8' - '1.9' - 'nightly' os: