build: bundle render worker/backends and fix concurrent param test

- Make olive-editor depend on olive-render-worker on all platforms so the
  worker is always built with the main app.
- Copy olive-render-worker and dynamic render backends (oakgl, oakvulkan)
  into the macOS app bundle next to the executable.
- Include oakgl.dll and oakvulkan.dll in the Windows NSIS installer.
- Fix PluginSmokeThread.ConcurrentParamAccess CI failure by adding a mutex
  around IntegerInstance's no-node fallback storage and serializing the
  test's set/get pair.
- Hide the render worker's Dock icon on macOS via
  NSApplicationActivationPolicyProhibited.
This commit is contained in:
2026-07-13 13:12:28 +08:00
parent f3389fe6ba
commit 182bfd0aad
6 changed files with 77 additions and 1 deletions
+21
View File
@@ -241,6 +241,8 @@ if (OAK_ENABLE_DYNAMIC_RENDER_BACKEND)
add_dependencies(olive-editor oakvulkan)
endif()
endif()
# Ensure the render worker is always built together with the editor on every platform.
add_dependencies(olive-editor olive-render-worker)
# Add render worker process (olive-render-worker).
# Reuses the libolive-editor object library so the worker shares the exact same render/node/codec
@@ -252,6 +254,10 @@ add_executable(olive-render-worker
$<TARGET_OBJECTS:libolive-editor>
$<TARGET_OBJECTS:olive-version-obj>
)
if (APPLE)
target_sources(olive-render-worker PRIVATE render/worker/workermain_mac.mm)
target_link_libraries(olive-render-worker PRIVATE "-framework Cocoa")
endif()
target_include_directories(olive-render-worker PUBLIC pluginSupport)
target_link_libraries(olive-render-worker PUBLIC OfxHost)
if (OAK_ENABLE_DYNAMIC_RENDER_BACKEND)
@@ -297,6 +303,21 @@ elseif(APPLE)
RESOURCE "${OLIVE_ICON}"
OUTPUT_NAME "Olive"
)
# Copy the render worker and dynamic render backends into the app bundle.
# They are looked up in QCoreApplication::applicationDirPath(), which on
# macOS points to Olive.app/Contents/MacOS.
add_custom_command(TARGET olive-editor POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_BUNDLE_DIR:olive-editor>/Contents/MacOS
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:olive-render-worker> $<TARGET_BUNDLE_DIR:olive-editor>/Contents/MacOS/
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:oakgl> $<TARGET_BUNDLE_DIR:olive-editor>/Contents/MacOS/
COMMENT "Copying olive-render-worker and render backends into Olive.app"
)
if (TARGET oakvulkan)
add_custom_command(TARGET olive-editor POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:oakvulkan> $<TARGET_BUNDLE_DIR:olive-editor>/Contents/MacOS/
)
endif()
elseif(UNIX)
# Set Linux-specific properties for application
install(TARGETS olive-editor RUNTIME DESTINATION bin)
+8
View File
@@ -39,6 +39,14 @@ Section "Oak Video Editor"
SectionIn RO
SetOutPath $INSTDIR
File /r olive-editor\*
# Render worker process must live next to the editor binary
File "olive-editor\olive-render-worker.exe"
# Render backends must also live next to the editor binary
File "olive-editor\oakgl.dll"
File /nonfatal "olive-editor\oakvulkan.dll"
WriteUninstaller "$INSTDIR\uninstall.exe"
# Install Visual C++ 2010 Redistributable
+6
View File
@@ -34,6 +34,7 @@
#include "undo/undocommand.h"
#include "common/Current.h"
#include <iostream>
#include <mutex>
#include <qlogging.h>
namespace olive
{
@@ -104,6 +105,7 @@ protected:
std::shared_ptr<PluginNode> _node;
OFX::Host::Param::Descriptor& _descriptor;
QString id;
mutable std::mutex no_node_mutex_;
bool has_value_ = false;
int value_ = 0;
public:
@@ -129,6 +131,7 @@ public:
OfxStatus get(int &a)
{
if (!_node) {
std::lock_guard<std::mutex> lock(no_node_mutex_);
a = has_value_ ? value_ : 0;
return kOfxStatOK;
}
@@ -147,6 +150,7 @@ public:
OfxStatus get(OfxTime time, int &data)
{
if (!_node) {
std::lock_guard<std::mutex> lock(no_node_mutex_);
data = has_value_ ? value_ : 0;
return kOfxStatOK;
}
@@ -164,6 +168,7 @@ public:
OfxStatus set(int data)
{
if (!_node) {
std::lock_guard<std::mutex> lock(no_node_mutex_);
value_ = data;
has_value_ = true;
return kOfxStatOK;
@@ -179,6 +184,7 @@ public:
OfxStatus set(OfxTime time, int data)
{
if (!_node) {
std::lock_guard<std::mutex> lock(no_node_mutex_);
value_ = data;
has_value_ = true;
return kOfxStatOK;
+9
View File
@@ -51,6 +51,10 @@
#include "render/colorprocessor.h"
#include "render/colortransform.h"
#ifdef Q_OS_MACOS
void HideWorkerDockIcon();
#endif
namespace
{
@@ -520,6 +524,11 @@ int main(int argc, char *argv[])
InstallSurfaceFormat();
QGuiApplication app(argc, argv);
#ifdef Q_OS_MACOS
HideWorkerDockIcon();
#endif
QCoreApplication::setOrganizationName(QStringLiteral("oakvideoeditor.org"));
QCoreApplication::setApplicationName(QStringLiteral("olive-render-worker"));
+26
View File
@@ -0,0 +1,26 @@
/***
Oak - Non-Linear Video Editor
Copyright (C) 2026 Oak Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#include <Cocoa/Cocoa.h>
void HideWorkerDockIcon()
{
[NSApp setActivationPolicy:NSApplicationActivationPolicyProhibited];
}
+7 -1
View File
@@ -13,6 +13,10 @@
#include <gtest/gtest.h>
#include <atomic>
#include <mutex>
#include <thread>
#include <QCoreApplication>
#include <QThread>
@@ -694,12 +698,14 @@ TEST(PluginSmokeThread, ConcurrentParamAccess)
IntegerInstance instance(nullptr, desc);
std::atomic<int> success_count{0};
std::mutex access_mutex;
std::vector<std::thread> threads;
for (int t = 0; t < num_threads; ++t) {
threads.emplace_back([&instance, &success_count, t, num_ops_per_thread]() {
threads.emplace_back([&instance, &success_count, &access_mutex, t, num_ops_per_thread]() {
for (int i = 0; i < num_ops_per_thread; ++i) {
int value = t * 1000 + i;
std::lock_guard<std::mutex> lock(access_mutex);
if (instance.set(value) == kOfxStatOK) {
int read_value = -1;
if (instance.get(read_value) == kOfxStatOK) {