diff --git a/.gitignore b/.gitignore index b862e9e0c..858b010b3 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,11 @@ Examples/*/*.bundle *~ ofx-docgen +ofxTestLog.txt +ofxPluginLog.txt +CMakeUserPresets.json +cmake-build.log + build*/ build.log .cache/ diff --git a/CMakeLists.txt b/CMakeLists.txt index ea3262089..c7f0c5693 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.16.0) -project(openfx VERSION 1.4.0 LANGUAGES CXX) +project(openfx VERSION 1.4.0 LANGUAGES CXX CUDA) set_property(GLOBAL PROPERTY USE_FOLDERS ON) set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -9,8 +9,26 @@ if(APPLE) set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64") endif() -option(BUILD_EXAMPLE_PLUGINS "Build example plugins" OFF) option(OFX_SUPPORTS_OPENGLRENDER "Build with support for GPU rendering (OpenGL/CUDA/Metal/OpenCL)" ON) +option(BUILD_EXAMPLE_PLUGINS "Build example plugins" OFF) +option(OFX_SUPPORTS_OPENCLRENDER "Build examples with support for OpenCL GPU rendering" OFF) +option(OFX_SUPPORTS_CUDARENDER "Build examples with support for CUDA GPU rendering" OFF) + +if(OFX_SUPPORTS_OPENGLRENDER) + add_definitions(-DOFX_SUPPORTS_OPENGLRENDER) +endif() +if(OFX_SUPPORTS_OPENCLRENDER) + add_definitions(-DOFX_SUPPORTS_OPENCLRENDER) +endif() +if(OFX_SUPPORTS_CUDARENDER) + add_definitions(-DOFX_SUPPORTS_CUDARENDER) + set(CMAKE_CUDA_ARCHITECTURES "native") +endif() + +# We use #if DEBUG in the examples +set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DDEBUG") +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") + # Flags if(!MSVC) @@ -21,7 +39,7 @@ list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake ${CMAKE_BINARY_DIR} ) # Conan packages find_package(EXPAT) -find_package(opengl_system) +find_package(opengl_system REQUIRED) # Macros set(OFX_SUPPORT_SYMBOLS_DIR ${PROJECT_SOURCE_DIR}/symbols) diff --git a/Examples/CMakeLists.txt b/Examples/CMakeLists.txt index 9974a2665..3a418b790 100644 --- a/Examples/CMakeLists.txt +++ b/Examples/CMakeLists.txt @@ -1,5 +1,4 @@ set(OFX_SUPPORT_HEADER_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../Support/include") -file(GLOB_RECURSE OFX_SUPPORT_HEADER_FILES "${OFX_SUPPORT_HEADER_DIR}/*.h") set(PLUGINS Basic @@ -11,10 +10,6 @@ set(PLUGINS Test ) -set(GPU_PLUGINS - GPUGain - ) - foreach(PLUGIN IN LISTS PLUGINS) file(GLOB_RECURSE PLUGIN_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/${PLUGIN}/*.cpp") @@ -25,19 +20,7 @@ foreach(PLUGIN IN LISTS PLUGINS) target_include_directories(${TGT} PUBLIC ${OFX_HEADER_DIR} ${OFX_SUPPORT_HEADER_DIR}) endforeach() -if (OFX_SUPPORTS_OPENGLRENDER) - foreach(PLUGIN IN LISTS GPU_PLUGINS) - file(GLOB_RECURSE PLUGIN_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/${PLUGIN}/*.cpp") - file(GLOB_RECURSE PLUGIN_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/${PLUGIN}/*.mm") - - set(TGT example-${PLUGIN}) - add_ofx_plugin(${TGT} ${PLUGIN}) - target_sources(${TGT} PUBLIC ${PLUGIN_SOURCES}) - target_include_directories(${TGT} PUBLIC ${OFX_HEADER_DIR} ${OFX_SUPPORT_HEADER_DIR}) - target_link_libraries(${TGT} ${CONAN_LIBS}) - target_link_libraries(${TGT} "-framework Metal" "-framework Foundation" "-framework QuartzCore") - endforeach() -endif() +add_subdirectory(GPUGain) target_link_libraries(example-OpenGL PRIVATE opengl::opengl) target_link_libraries(example-Custom PRIVATE opengl::opengl) diff --git a/Examples/GPUGain/CMakeLists.txt b/Examples/GPUGain/CMakeLists.txt new file mode 100644 index 000000000..3ecf37701 --- /dev/null +++ b/Examples/GPUGain/CMakeLists.txt @@ -0,0 +1,22 @@ +set(PLUGIN GPUGain) +if (OFX_SUPPORTS_OPENGLRENDER) + file(GLOB_RECURSE PLUGIN_SOURCES "*.cpp") + if (NOT OFX_SUPPORTS_OPENCLRENDER) + list(FILTER PLUGIN_SOURCES EXCLUDE REGEX "OpenCLKernel") + endif() + if (OFX_SUPPORTS_CUDARENDER) + list(APPEND PLUGIN_SOURCES "CUDAKernel.cu") + endif() + if(APPLE) + file(GLOB_RECURSE PLUGIN_SOURCES "*.mm") # add Metal kernel + endif() + + set(TGT example-${PLUGIN}) + add_ofx_plugin(${TGT} ${PLUGIN}) + target_sources(${TGT} PUBLIC ${PLUGIN_SOURCES}) + target_include_directories(${TGT} PUBLIC ${OFX_HEADER_DIR} ${OFX_SUPPORT_HEADER_DIR}) + target_link_libraries(${TGT} ${CONAN_LIBS} OfxSupport opengl::opengl) + if(APPLE) + target_link_libraries(${TGT} "-framework Metal" "-framework Foundation" "-framework QuartzCore") + endif() +endif() diff --git a/Examples/GPUGain/GPUGain.cpp b/Examples/GPUGain/GPUGain.cpp index 56862c0c6..8e60ce67f 100644 --- a/Examples/GPUGain/GPUGain.cpp +++ b/Examples/GPUGain/GPUGain.cpp @@ -11,7 +11,7 @@ #include "ofxsLog.h" #define kPluginName "GPU Gain" -#define kPluginGrouping "OpenFX Sample" +#define kPluginGrouping "OFX Example" #define kPluginDescription "Apply separate RGB gain adjustments to each channels; CUDA/OpenCL/Metal" #define kPluginIdentifier "com.OpenFXSample.GPUGain" #define kPluginVersionMajor 1 @@ -86,6 +86,7 @@ extern void RunOpenCLKernel(void* p_CmdQ, int p_Width, int p_Height, float* p_Ga void GainExample::processImagesOpenCL() { +#ifdef OFX_SUPPORTS_OPENCLRENDER const OfxRectI& bounds = _srcImg->getBounds(); const int width = bounds.x2 - bounds.x1; const int height = bounds.y2 - bounds.y1; @@ -94,6 +95,7 @@ void GainExample::processImagesOpenCL() float* output = static_cast(_dstImg->getPixelData()); RunOpenCLKernel(_pOpenCLCmdQ, width, height, _scales, input, output); +#endif } void GainExample::multiThreadProcessImages(OfxRectI p_ProcWindow) diff --git a/Support/Library/ofxsImageEffect.cpp b/Support/Library/ofxsImageEffect.cpp index 4bdc0aa99..ee5cc091c 100644 --- a/Support/Library/ofxsImageEffect.cpp +++ b/Support/Library/ofxsImageEffect.cpp @@ -682,7 +682,11 @@ namespace OFX { /** @brief Does the plugin support CUDA Stream */ void ImageEffectDescriptor::setSupportsCudaStream(bool v) { + try { _effectProps.propSetString(kOfxImageEffectPropCudaStreamSupported, (v ? "true" : "false")); + } catch(OFX::Exception::PropertyUnknownToHost) { + OFX::Log::warning(true, "Host does not have kOfxImageEffectPropCudaStreamSupported property"); + } } /** @brief Does the plugin support Metal Render */ @@ -2532,7 +2536,7 @@ namespace OFX { const char* plugname) { OFX::Log::print("********************************************************************************"); - OFX::Log::print("START mainEntry (%s)", actionRaw); + OFX::Log::print("START mainEntry (%s for %s)", actionRaw, plugname); OFX::Log::indent(); OfxStatus stat = kOfxStatReplyDefault; try { @@ -2800,6 +2804,7 @@ namespace OFX { // catch suite exceptions catch (const OFX::Exception::Suite &ex) { + OFX::Log::error(true, "Caught OFX::Exception::Suite: %s", ex.what()); # ifdef DEBUG std::cout << "Caught OFX::Exception::Suite: " << ex.what() << std::endl; # endif @@ -2809,6 +2814,7 @@ namespace OFX { // catch host inadequate exceptions catch (const OFX::Exception::HostInadequate &e) { + OFX::Log::error(true, "Caught OFX::Exception::HostInadequate: %s", e.what()); # ifdef DEBUG std::cout << "Caught OFX::Exception::HostInadequate: " << e.what() << std::endl; # endif @@ -2818,6 +2824,7 @@ namespace OFX { // catch exception due to a property being unknown to the host, implies something wrong with host if not caught further down catch (const OFX::Exception::PropertyUnknownToHost &e) { + OFX::Log::error(true, "Caught OFX::Exception::PropertyUnknownToHost: %s", e.what()); # ifdef DEBUG std::cout << "Caught OFX::Exception::PropertyUnknownToHost: " << e.what() << std::endl; # endif @@ -2840,13 +2847,15 @@ namespace OFX { // Catch anything else, unknown catch (const std::exception &e) { + OFX::Log::error(true, "Caught std::exception: %s", e.what()); # ifdef DEBUG - std::cout << "Caught exception: " << e.what() << std::endl; + std::cout << "Caught std::exception: " << e.what() << std::endl; # endif stat = kOfxStatFailed; } catch (...) { + OFX::Log::error(true, "Caught unknown exception"); # ifdef DEBUG std::cout << "Caught Unknown exception" << std::endl; # endif @@ -2854,7 +2863,8 @@ namespace OFX { } OFX::Log::outdent(); - OFX::Log::print("STOP mainEntry (%s)\n", actionRaw); + OFX::Log::print("STOP mainEntry (%s for %s, returning %d=%s)\n", actionRaw, plugname, + stat, mapStatusToString(stat)); return stat; } diff --git a/Support/Library/ofxsLog.cpp b/Support/Library/ofxsLog.cpp index 070d8e252..8e4e0d194 100644 --- a/Support/Library/ofxsLog.cpp +++ b/Support/Library/ofxsLog.cpp @@ -25,7 +25,7 @@ namespace OFX { #define kLogFileEnvVar "OFX_PLUGIN_LOGFILE" /** @brief the global logfile name */ - static std::string gLogFileName(getenv(kLogFileEnvVar) ? getenv(kLogFileEnvVar) : "ofxTestLog.txt"); + static std::string gLogFileName(getenv(kLogFileEnvVar) ? getenv(kLogFileEnvVar) : "ofxPluginLog.txt"); /** @brief global indent level, not MP sane */ static int gIndent = 0; @@ -41,7 +41,7 @@ namespace OFX { { #ifdef DEBUG if(!gLogFP) { - gLogFP = fopen(gLogFileName.c_str(), "w"); + gLogFP = fopen(gLogFileName.c_str(), "a"); return gLogFP != 0; } #endif diff --git a/cmake/OpenFX.cmake b/cmake/OpenFX.cmake index 5b6ccb5a9..f31fb83b5 100644 --- a/cmake/OpenFX.cmake +++ b/cmake/OpenFX.cmake @@ -2,7 +2,7 @@ if(APPLE) set(PLUGINDIR "/Library/OFX/Plugins") set(ARCHDIR "MacOS") elseif(WIN32) - set(PLUGINDIR "C:/Program Files (x86)/Common Files/OFX/Plugins") + set(PLUGINDIR "C:/Program Files/Common Files/OFX/Plugins") set(ARCHDIR "Win64") elseif(UNIX) set(PLUGINDIR "/usr/OFX/Plugins") @@ -16,43 +16,54 @@ endif() # Arguments: TARGET # Optional argument: DIR, defaults to same as TARGET (use when renaming TARGET) function(add_ofx_plugin TARGET) - if(${ARGC} GREATER 1) - set(DIR ${ARGN}) - else() - set(DIR ${TARGET}) - endif() - if(APPLE) - add_library(${TARGET} MODULE) # build as an OSX bundle - else() - add_library(${TARGET} SHARED) # build as shared lib/DLL - endif() - set_target_properties(${TARGET} PROPERTIES SUFFIX ".ofx" PREFIX "") + if(${ARGC} GREATER 1) + set(DIR ${ARGN}) + else() + set(DIR ${TARGET}) + endif() + if(APPLE) + add_library(${TARGET} MODULE) # build as an OSX bundle + else() + add_library(${TARGET} SHARED) # build as shared lib/DLL + endif() + set_target_properties(${TARGET} PROPERTIES SUFFIX ".ofx" PREFIX "") - if(NOT DEFINED OFX_SUPPORT_SYMBOLS_DIR) - if (NOT DEFINED CONAN_OPENFX_ROOT) - message(FATAL_ERROR "Define OFX_SUPPORT_SYMBOLS_DIR to use add_ofx_plugin().") - endif() - set(OFX_SUPPORT_SYMBOLS_DIR ${CONAN_OPENFX_ROOT}/symbols) - endif() + if(NOT DEFINED OFX_SUPPORT_SYMBOLS_DIR) + if (NOT DEFINED CONAN_OPENFX_ROOT) + message(FATAL_ERROR "Define OFX_SUPPORT_SYMBOLS_DIR to use add_ofx_plugin().") + endif() + set(OFX_SUPPORT_SYMBOLS_DIR ${CONAN_OPENFX_ROOT}/symbols) + endif() - # Add extra flags to the link step of the plugin - if(APPLE) - set_target_properties(${TARGET} PROPERTIES - LINK_FLAGS "-fvisibility=hidden -exported_symbols_list,${OFX_SUPPORT_SYMBOLS_DIR}/osx.symbols") - elseif(WIN32) - if (MSVC) - set_target_properties(${TARGET} PROPERTIES - LINK_FLAGS "/def:${OFX_SUPPORT_SYMBOLS_DIR}/windows.symbols") + # Add extra flags to the link step of the plugin + if(APPLE) + set_target_properties(${TARGET} PROPERTIES + LINK_FLAGS "-fvisibility=hidden -exported_symbols_list,${OFX_SUPPORT_SYMBOLS_DIR}/osx.symbols") + elseif(WIN32) + if (MSVC) + set_target_properties(${TARGET} PROPERTIES + LINK_FLAGS "/def:${OFX_SUPPORT_SYMBOLS_DIR}/windows.symbols") elseif(MINGW OR MSYS) set_target_properties(${TARGET} PROPERTIES - LINK_FLAGS "-Wl,-fvisibility=hidden,--version-script=${OFX_SUPPORT_SYMBOLS_DIR}/mingw.symbols") + LINK_FLAGS "-Wl,-fvisibility=hidden,--version-script=${OFX_SUPPORT_SYMBOLS_DIR}/mingw.symbols") + endif() + else() # Linux + set_target_properties(${TARGET} PROPERTIES + LINK_FLAGS "-Wl,-fvisibility=hidden,--version-script=${OFX_SUPPORT_SYMBOLS_DIR}/linux.symbols") + endif() + + # To install plugins: cmake --install Build + install(TARGETS ${TARGET} DESTINATION "${PLUGINDIR}/${TARGET}.ofx.bundle/Contents/${ARCHDIR}") + + # Use info.plist in DIR or else current dir + file(REAL_PATH ${DIR}/Info.plist INFO_PLIST) + if(EXISTS ${INFO_PLIST}) + install(FILES ${INFO_PLIST} DESTINATION "${PLUGINDIR}/${TARGET}.ofx.bundle/Contents") + else() + file(REAL_PATH ./Info.plist INFO_PLIST) + if(EXISTS ${INFO_PLIST}) + install(FILES ${INFO_PLIST} DESTINATION "${PLUGINDIR}/${TARGET}.ofx.bundle/Contents") endif() - else() - set_target_properties(${TARGET} PROPERTIES - LINK_FLAGS "-Wl,-fvisibility=hidden,--version-script=${OFX_SUPPORT_SYMBOLS_DIR}/linux.symbols") - endif() + endif() - # To install plugins: cmake --install Build - install(TARGETS ${TARGET} DESTINATION "${PLUGINDIR}/${TARGET}.ofx.bundle/Contents/${ARCHDIR}") - install(FILES ${DIR}/Info.plist DESTINATION "${PLUGINDIR}/${TARGET}.ofx.bundle/Contents") endfunction() diff --git a/scripts/build-cmake.sh b/scripts/build-cmake.sh index f96c61222..eb22b8e36 100755 --- a/scripts/build-cmake.sh +++ b/scripts/build-cmake.sh @@ -10,8 +10,8 @@ if [[ $1 = "-v" ]]; then VERBOSE="--verbose"; shift fi -if [[ -n ${1:-} ]]; then - GENERATOR=$1 +if [[ $1 = "-G" ]]; then + GENERATOR=$1; shift GENERATOR_OPTION="-c tools.cmake.cmaketoolchain:generator=${GENERATOR}" fi @@ -50,7 +50,7 @@ conan install ${GENERATOR_OPTION} -s build_type=$BUILDTYPE -pr:b=default --build echo === Running cmake # Generate the build files -cmake --preset ${PRESET_NAME} -DBUILD_EXAMPLE_PLUGINS=TRUE +cmake --preset ${PRESET_NAME} -DBUILD_EXAMPLE_PLUGINS=TRUE "$@" echo === Building plugins and support libs cmake --build ${CMAKE_BUILD_DIR} --config $BUILDTYPE $VERBOSE