diff --git a/Engine/AppInstance.cpp b/Engine/AppInstance.cpp index ca43acf8b5..90189f9589 100644 --- a/Engine/AppInstance.cpp +++ b/Engine/AppInstance.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -398,7 +399,10 @@ AppInstance::getWritersWorkForCL(const CLArgs& cl,std::listfilename.toStdString(), eCreateNodeReasonInternal, getProject()); - + if (!writerNode) { + throw std::runtime_error(std::string("Failed to create writer for ") + it->filename.toStdString()); + } + //Connect the writer to the corresponding Output node input NodePtr output = getProject()->getNodeByFullySpecifiedName(it->name.toStdString()); if (!output) { @@ -412,7 +416,7 @@ AppInstance::getWritersWorkForCL(const CLArgs& cl,std::listconnectInput(outputInput, 0); } - +#pragma message WARN("what is the following line for?") writerNode->getScriptName().c_str(); } diff --git a/Engine/AppInstance.h b/Engine/AppInstance.h index a81cc8ed49..53b118fb04 100644 --- a/Engine/AppInstance.h +++ b/Engine/AppInstance.h @@ -322,6 +322,8 @@ class AppInstance virtual void renderAllViewers(bool /* canAbort*/) {} + virtual void abortAllViewers() {} + virtual void declareCurrentAppVariable_Python(); void execOnProjectCreatedCallback(); diff --git a/Engine/AppInstanceWrapper.cpp b/Engine/AppInstanceWrapper.cpp index 8f62fe1861..d98cc475de 100644 --- a/Engine/AppInstanceWrapper.cpp +++ b/Engine/AppInstanceWrapper.cpp @@ -24,6 +24,9 @@ #include "AppInstanceWrapper.h" +#include +#include + #include #include "Engine/AppInstance.h" diff --git a/Engine/AppManager.cpp b/Engine/AppManager.cpp index 9cc15ac994..3393a26621 100644 --- a/Engine/AppManager.cpp +++ b/Engine/AppManager.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #if defined(Q_OS_LINUX) @@ -795,14 +796,20 @@ AppManager::clearPluginsLoadedCache() void AppManager::clearAllCaches() { - clearDiskCache(); - clearNodeCache(); - std::map copy; { QMutexLocker k(&_imp->_appInstancesMutex); copy = _imp->_appInstances; } + + for (std::map::iterator it = copy.begin(); it != copy.end(); ++it) { + it->second.app->abortAllViewers(); + } + + clearDiskCache(); + clearNodeCache(); + + ///for each app instance clear all its nodes cache for (std::map::iterator it = copy.begin(); it != copy.end(); ++it) { it->second.app->clearOpenFXPluginsCaches(); diff --git a/Engine/AppManagerPrivate.cpp b/Engine/AppManagerPrivate.cpp index aee5189cf0..f75085cecd 100644 --- a/Engine/AppManagerPrivate.cpp +++ b/Engine/AppManagerPrivate.cpp @@ -28,9 +28,9 @@ #include // for getrlimit on linux #include // for getrlimit #endif - #include #include +#include #include GCC_DIAG_UNUSED_LOCAL_TYPEDEFS_OFF diff --git a/Engine/Backdrop.cpp b/Engine/Backdrop.cpp index 71228a2494..74697433e0 100644 --- a/Engine/Backdrop.cpp +++ b/Engine/Backdrop.cpp @@ -23,6 +23,10 @@ // ***** END PYTHON BLOCK ***** #include "Backdrop.h" + +#include +#include + #include "Engine/Transform.h" #include "Engine/KnobTypes.h" diff --git a/Engine/Bezier.cpp b/Engine/Bezier.cpp index 3c4b0efba2..42fe3a311c 100644 --- a/Engine/Bezier.cpp +++ b/Engine/Bezier.cpp @@ -28,8 +28,9 @@ #include #include #include -#include #include +#include +#include #include #include diff --git a/Engine/BezierCP.cpp b/Engine/BezierCP.cpp index 3eb94d87dc..089f508958 100644 --- a/Engine/BezierCP.cpp +++ b/Engine/BezierCP.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/Engine/BlockingBackgroundRender.cpp b/Engine/BlockingBackgroundRender.cpp index f4fb9fe049..5a10443881 100644 --- a/Engine/BlockingBackgroundRender.cpp +++ b/Engine/BlockingBackgroundRender.cpp @@ -24,6 +24,9 @@ #include "BlockingBackgroundRender.h" +#include +#include + #include "Global/Macros.h" CLANG_DIAG_OFF(deprecated-register) //'register' storage class specifier is deprecated #include diff --git a/Engine/CLArgs.cpp b/Engine/CLArgs.cpp index b9db18deb8..6e6def9189 100644 --- a/Engine/CLArgs.cpp +++ b/Engine/CLArgs.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include diff --git a/Engine/Cache.cpp b/Engine/Cache.cpp index 86eadf3d26..4cfc386292 100644 --- a/Engine/Cache.cpp +++ b/Engine/Cache.cpp @@ -24,6 +24,9 @@ #include "Cache.h" +#include +#include + NATRON_NAMESPACE_ENTER; NATRON_NAMESPACE_EXIT; diff --git a/Engine/CoonsRegularization.cpp b/Engine/CoonsRegularization.cpp index 0411ecfd8d..b4aa92b255 100644 --- a/Engine/CoonsRegularization.cpp +++ b/Engine/CoonsRegularization.cpp @@ -52,6 +52,7 @@ #include #include #include // min, max +#include #include #include "Engine/Bezier.h" diff --git a/Engine/Curve.cpp b/Engine/Curve.cpp index d540b1b9f1..229eeb93ca 100644 --- a/Engine/Curve.cpp +++ b/Engine/Curve.cpp @@ -25,6 +25,7 @@ #include "Curve.h" #include +#include #include #if !defined(SBK_RUN) && !defined(Q_MOC_RUN) diff --git a/Engine/CurveSerialization.cpp b/Engine/CurveSerialization.cpp index 1ef5b0be6e..51ad783579 100644 --- a/Engine/CurveSerialization.cpp +++ b/Engine/CurveSerialization.cpp @@ -24,6 +24,9 @@ #include "CurveSerialization.h" +#include +#include + // explicit template instantiations NATRON_NAMESPACE_ENTER; diff --git a/Engine/DiskCacheNode.cpp b/Engine/DiskCacheNode.cpp index 2c62bd5096..d1181c4f24 100644 --- a/Engine/DiskCacheNode.cpp +++ b/Engine/DiskCacheNode.cpp @@ -24,6 +24,7 @@ #include "DiskCacheNode.h" +#include #include #include "Engine/Node.h" diff --git a/Engine/Dot.cpp b/Engine/Dot.cpp index b1dcf194c0..f568d4a9fa 100644 --- a/Engine/Dot.cpp +++ b/Engine/Dot.cpp @@ -24,6 +24,9 @@ #include "Dot.h" +#include +#include + NATRON_NAMESPACE_ENTER; std::string diff --git a/Engine/EffectInstance.cpp b/Engine/EffectInstance.cpp index 2245adb377..dce3896eaf 100644 --- a/Engine/EffectInstance.cpp +++ b/Engine/EffectInstance.cpp @@ -28,9 +28,10 @@ #include #include #include // min, max -#include #include #include +#include +#include #include // QtCore on Qt4, QtConcurrent on Qt5 #include diff --git a/Engine/EffectInstancePrivate.cpp b/Engine/EffectInstancePrivate.cpp index 3481b6d50d..c40f628b58 100644 --- a/Engine/EffectInstancePrivate.cpp +++ b/Engine/EffectInstancePrivate.cpp @@ -24,6 +24,9 @@ #include "EffectInstancePrivate.h" +#include +#include + #include "Engine/AppInstance.h" #include "Engine/Node.h" #include "Engine/NodeGroup.h" diff --git a/Engine/EffectInstanceRenderRoI.cpp b/Engine/EffectInstanceRenderRoI.cpp index f2127ea0c5..9ef54c1a41 100644 --- a/Engine/EffectInstanceRenderRoI.cpp +++ b/Engine/EffectInstanceRenderRoI.cpp @@ -28,8 +28,9 @@ #include #include #include // min, max -#include #include +#include +#include #include #include // QtCore on Qt4, QtConcurrent on Qt5 diff --git a/Engine/ExistenceCheckThread.cpp b/Engine/ExistenceCheckThread.cpp index e2a75bb5d6..befb87d9c0 100644 --- a/Engine/ExistenceCheckThread.cpp +++ b/Engine/ExistenceCheckThread.cpp @@ -20,6 +20,9 @@ #include "ExistenceCheckThread.h" +#include +#include + #include #include #include diff --git a/Engine/FileDownloader.cpp b/Engine/FileDownloader.cpp index 37d3a63811..ac18878f84 100644 --- a/Engine/FileDownloader.cpp +++ b/Engine/FileDownloader.cpp @@ -23,7 +23,10 @@ // ***** END PYTHON BLOCK ***** #include "FileDownloader.h" + #include +#include + #include #include diff --git a/Engine/FileSystemModel.cpp b/Engine/FileSystemModel.cpp index a19bf63cbe..4ea3d133d4 100644 --- a/Engine/FileSystemModel.cpp +++ b/Engine/FileSystemModel.cpp @@ -25,6 +25,8 @@ #include "FileSystemModel.h" #include +#include +#include CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) diff --git a/Engine/FitCurve.cpp b/Engine/FitCurve.cpp index 9ac7c07726..c28599756d 100644 --- a/Engine/FitCurve.cpp +++ b/Engine/FitCurve.cpp @@ -25,6 +25,8 @@ #include "FitCurve.h" #include +#include +#include #ifndef M_PI_2 #define M_PI_2 1.57079632679489661923132169163975144 /* pi/2 */ diff --git a/Engine/FrameEntry.cpp b/Engine/FrameEntry.cpp index 4582b399d9..302f1d484b 100644 --- a/Engine/FrameEntry.cpp +++ b/Engine/FrameEntry.cpp @@ -24,6 +24,9 @@ #include "FrameEntry.h" +#include +#include + #include "Engine/RectI.h" NATRON_NAMESPACE_ENTER; diff --git a/Engine/FrameKey.cpp b/Engine/FrameKey.cpp index 5c143863f2..144a2c2807 100644 --- a/Engine/FrameKey.cpp +++ b/Engine/FrameKey.cpp @@ -24,6 +24,9 @@ #include "FrameKey.h" +#include +#include + NATRON_NAMESPACE_ENTER; FrameKey::FrameKey() diff --git a/Engine/FrameParamsSerialization.cpp b/Engine/FrameParamsSerialization.cpp index 194b384a30..70166b9a2c 100644 --- a/Engine/FrameParamsSerialization.cpp +++ b/Engine/FrameParamsSerialization.cpp @@ -24,6 +24,9 @@ #include "FrameParamsSerialization.h" +#include +#include + // explicit template instantiations NATRON_NAMESPACE_ENTER; diff --git a/Engine/GroupInput.cpp b/Engine/GroupInput.cpp index c2b541dafa..bc6266af6e 100644 --- a/Engine/GroupInput.cpp +++ b/Engine/GroupInput.cpp @@ -24,6 +24,9 @@ #include "GroupInput.h" +#include +#include + #include "Engine/KnobTypes.h" #include "Engine/Node.h" #include "Engine/NodeGroup.h" // kNatronGroupInputIsOptionalParamName, kNatronGroupInputIsMaskParamName diff --git a/Engine/GroupOutput.cpp b/Engine/GroupOutput.cpp index 2e85aaea28..7702b75379 100644 --- a/Engine/GroupOutput.cpp +++ b/Engine/GroupOutput.cpp @@ -24,6 +24,9 @@ #include "GroupOutput.h" +#include +#include + NATRON_NAMESPACE_ENTER; std::string diff --git a/Engine/Hash64.cpp b/Engine/Hash64.cpp index 57b60800eb..e97672386f 100644 --- a/Engine/Hash64.cpp +++ b/Engine/Hash64.cpp @@ -25,6 +25,9 @@ #include "Hash64.h" #include // for std::for_each +#include +#include + #if !defined(Q_MOC_RUN) && !defined(SBK_RUN) #include #endif diff --git a/Engine/HistogramCPU.cpp b/Engine/HistogramCPU.cpp index 52f0b7f0b3..8eaeb2eacd 100644 --- a/Engine/HistogramCPU.cpp +++ b/Engine/HistogramCPU.cpp @@ -25,6 +25,9 @@ #include "HistogramCPU.h" #include +#include +#include + #include #include diff --git a/Engine/Image.cpp b/Engine/Image.cpp index 325df0070b..4a7e9d456c 100644 --- a/Engine/Image.cpp +++ b/Engine/Image.cpp @@ -25,6 +25,8 @@ #include "Image.h" #include // min, max +#include +#include #include diff --git a/Engine/ImageComponents.cpp b/Engine/ImageComponents.cpp index 4cbd8ab28e..81ca9c7329 100644 --- a/Engine/ImageComponents.cpp +++ b/Engine/ImageComponents.cpp @@ -19,6 +19,9 @@ #include "ImageComponents.h" #include "ofxNatron.h" +#include +#include + NATRON_NAMESPACE_ENTER; static const char* rgbaComps[4] = {"R","G","B","A"}; diff --git a/Engine/ImageConvert.cpp b/Engine/ImageConvert.cpp index eabaece09c..14550b885f 100644 --- a/Engine/ImageConvert.cpp +++ b/Engine/ImageConvert.cpp @@ -25,6 +25,8 @@ #include "Image.h" #include // min, max +#include +#include #include #ifndef Q_MOC_RUN diff --git a/Engine/ImageCopyChannels.cpp b/Engine/ImageCopyChannels.cpp index 8262b0a43b..b3a96ca772 100644 --- a/Engine/ImageCopyChannels.cpp +++ b/Engine/ImageCopyChannels.cpp @@ -24,6 +24,9 @@ #include "Image.h" +#include +#include + #include //#define NATRON_COPY_CHANNELS_UNPREMULT @@ -349,11 +352,11 @@ Image::copyUnProcessedChannelsForComponents(const bool premult, copyUnProcessedChannelsForChannels(/*true, false, true, false, */processChannels, premult, roi, originalImage, originalPremult); // GA were processed (rare) } } else { - if (dstNComps >= 4 && doA) { + //if (dstNComps >= 4 && doA) { copyUnProcessedChannelsForChannels(/*true, false, false, true, */processChannels, premult, roi, originalImage, originalPremult); // GB were processed (rare) - } else { - copyUnProcessedChannelsForChannels(/*true, false, false, false, */processChannels, premult, roi, originalImage, originalPremult); // GBA were processed (rare) - } + //} else { + // copyUnProcessedChannelsForChannels(/*true, false, false, false, */processChannels, premult, roi, originalImage, originalPremult); // GBA were processed (rare) + //} } } } else { @@ -365,19 +368,19 @@ Image::copyUnProcessedChannelsForComponents(const bool premult, copyUnProcessedChannelsForChannels(/*false, true, true, false, */processChannels, premult, roi, originalImage, originalPremult); // RA were processed (rare) } } else { - if (dstNComps >= 4 && doA) { + //if (dstNComps >= 4 && doA) { copyUnProcessedChannelsForChannels(/*false, true, false, true, */processChannels, premult, roi, originalImage, originalPremult); // RB were processed (rare) - } else { - copyUnProcessedChannelsForChannels(/*false, true, false, false, */processChannels, premult, roi, originalImage, originalPremult); // RBA were processed (rare) - } + //} else { + // copyUnProcessedChannelsForChannels(/*false, true, false, false, */processChannels, premult, roi, originalImage, originalPremult); // RBA were processed (rare) + //} } } else { if (dstNComps >= 3 && doB) { - if (dstNComps >= 4 && doA) { + //if (dstNComps >= 4 && doA) { copyUnProcessedChannelsForChannels(/*false, false, true, true, */processChannels, premult, roi, originalImage, originalPremult); // RG were processed (rare) - } else { - copyUnProcessedChannelsForChannels(/*false, false, true, false, */processChannels, premult, roi, originalImage, originalPremult); // RGA were processed (rare) - } + //} else { + // copyUnProcessedChannelsForChannels(/*false, false, true, false, */processChannels, premult, roi, originalImage, originalPremult); // RGA were processed (rare) + //} } else { if (dstNComps >= 4 && doA) { copyUnProcessedChannelsForChannels(processChannels, premult, roi, originalImage, originalPremult); // RGB were processed diff --git a/Engine/ImageKey.cpp b/Engine/ImageKey.cpp index 010608e29e..71b91f2fb2 100644 --- a/Engine/ImageKey.cpp +++ b/Engine/ImageKey.cpp @@ -24,6 +24,9 @@ #include "ImageKey.h" +#include +#include + NATRON_NAMESPACE_ENTER; ImageKey::ImageKey() diff --git a/Engine/ImageMaskMix.cpp b/Engine/ImageMaskMix.cpp index d9de2a6bdc..cdb791db78 100644 --- a/Engine/ImageMaskMix.cpp +++ b/Engine/ImageMaskMix.cpp @@ -24,6 +24,9 @@ #include "Image.h" +#include +#include + NATRON_NAMESPACE_ENTER; template diff --git a/Engine/ImageParamsSerialization.cpp b/Engine/ImageParamsSerialization.cpp index d11440e332..61970ddcd7 100644 --- a/Engine/ImageParamsSerialization.cpp +++ b/Engine/ImageParamsSerialization.cpp @@ -24,6 +24,9 @@ #include "ImageParamsSerialization.h" +#include +#include + // explicit template instantiations NATRON_NAMESPACE_ENTER; diff --git a/Engine/Knob.cpp b/Engine/Knob.cpp index f4273c8073..254fe95ccb 100644 --- a/Engine/Knob.cpp +++ b/Engine/Knob.cpp @@ -26,6 +26,7 @@ #include "KnobImpl.h" #include // min, max +#include #include #include diff --git a/Engine/KnobFactory.cpp b/Engine/KnobFactory.cpp index 398e3e3c58..9c3b5814ec 100644 --- a/Engine/KnobFactory.cpp +++ b/Engine/KnobFactory.cpp @@ -24,6 +24,9 @@ #include "KnobFactory.h" +#include +#include + #include "Global/GlobalDefines.h" #include "Engine/Knob.h" diff --git a/Engine/KnobFile.cpp b/Engine/KnobFile.cpp index f66801b3d2..0be8219d82 100644 --- a/Engine/KnobFile.cpp +++ b/Engine/KnobFile.cpp @@ -25,6 +25,7 @@ #include "KnobFile.h" #include +#include #include #include diff --git a/Engine/KnobSerialization.cpp b/Engine/KnobSerialization.cpp index 6c330689c0..61de59ce73 100644 --- a/Engine/KnobSerialization.cpp +++ b/Engine/KnobSerialization.cpp @@ -26,6 +26,8 @@ #include "KnobSerialization.h" #include // min, max +#include +#include #include diff --git a/Engine/KnobTypes.cpp b/Engine/KnobTypes.cpp index 6caef3489f..1959a84d13 100644 --- a/Engine/KnobTypes.cpp +++ b/Engine/KnobTypes.cpp @@ -28,6 +28,7 @@ #include #include #include // min, max +#include #include GCC_DIAG_UNUSED_LOCAL_TYPEDEFS_OFF diff --git a/Engine/LibraryBinary.cpp b/Engine/LibraryBinary.cpp index 2e82f9d805..362ad1126e 100644 --- a/Engine/LibraryBinary.cpp +++ b/Engine/LibraryBinary.cpp @@ -24,8 +24,9 @@ #include "LibraryBinary.h" -#include #include +#include +#include #include "Global/GlobalDefines.h" #ifdef __NATRON_UNIX__ diff --git a/Engine/Log.cpp b/Engine/Log.cpp index c33627347e..403c5b95be 100644 --- a/Engine/Log.cpp +++ b/Engine/Log.cpp @@ -26,13 +26,13 @@ #ifdef NATRON_LOG - -#include #include #include #include #include #include +#include +#include #include #include diff --git a/Engine/Lut.cpp b/Engine/Lut.cpp index 0db65a0484..f7c4eedd98 100644 --- a/Engine/Lut.cpp +++ b/Engine/Lut.cpp @@ -26,6 +26,7 @@ #include // for memcpy #include // min, max +#include #include #include "Engine/RectI.h" diff --git a/Engine/MemoryFile.cpp b/Engine/MemoryFile.cpp index 8d40ca4cce..948641a5e8 100644 --- a/Engine/MemoryFile.cpp +++ b/Engine/MemoryFile.cpp @@ -39,6 +39,7 @@ #endif #include #include +#include #include #include "Global/Macros.h" diff --git a/Engine/NoOpBase.cpp b/Engine/NoOpBase.cpp index 6f349c1ddb..9eb1fb6c68 100644 --- a/Engine/NoOpBase.cpp +++ b/Engine/NoOpBase.cpp @@ -24,6 +24,9 @@ #include "NoOpBase.h" +#include +#include + #include "Engine/Transform.h" // Matrix3x3 NATRON_NAMESPACE_ENTER; diff --git a/Engine/Node.cpp b/Engine/Node.cpp index 4f0be930fc..3e4735513b 100644 --- a/Engine/Node.cpp +++ b/Engine/Node.cpp @@ -27,8 +27,9 @@ #include #include #include // min, max -#include #include +#include +#include #include #include @@ -6519,7 +6520,9 @@ Node::computeFrameRangeForReader(const KnobI* fileKnob) const KnobFile* isFile = dynamic_cast(fileKnob); assert(isFile); - + if (!isFile) { + throw std::logic_error("Node::computeFrameRangeForReader"); + } std::string pattern = isFile->getValue(); getApp()->getProject()->canonicalizePath(pattern); SequenceParsing::SequenceFromPattern seq; diff --git a/Engine/NodeGroup.cpp b/Engine/NodeGroup.cpp index 7104a89233..8538245a34 100644 --- a/Engine/NodeGroup.cpp +++ b/Engine/NodeGroup.cpp @@ -28,6 +28,7 @@ #include #include #include // min, max +#include #include #include @@ -2263,7 +2264,11 @@ static void exportRotoLayer(int indentLevel, boost::shared_ptr track = (*it2)->isSlaved(); if (track) { EffectInstance* effect = dynamic_cast(track->getHolder()); - assert(effect && effect->getNode()->isPointTrackerNode()); + assert(effect); + if (!effect) { + throw std::logic_error("exportRotoLayer"); + } + assert(effect->getNode() && effect->getNode()->isPointTrackerNode()); std::string trackerName = effect->getNode()->getScriptName_mt_safe(); int trackTime = (*it2)->getOffsetTime(); WRITE_INDENT(indentLevel); WRITE_STRING("tracker = group.getNode(\"" + QString(trackerName.c_str()) + "\")"); @@ -2416,6 +2421,9 @@ static bool exportKnobLinks(int indentLevel, EffectInstance* aliasHolder = dynamic_cast(alias->getHolder()); assert(aliasHolder); + if (!aliasHolder) { + throw std::logic_error("exportKnobLinks"); + } QString aliasName; if (aliasHolder == groupNode->getEffectInstance().get()) { aliasName = groupName; diff --git a/Engine/NodeGroupSerialization.cpp b/Engine/NodeGroupSerialization.cpp index cb8328e622..c7b6a04a15 100644 --- a/Engine/NodeGroupSerialization.cpp +++ b/Engine/NodeGroupSerialization.cpp @@ -24,6 +24,9 @@ #include "NodeGroupSerialization.h" +#include +#include + #include #include "Engine/AppManager.h" diff --git a/Engine/NodeGroupWrapper.cpp b/Engine/NodeGroupWrapper.cpp index c80a9d347d..2bc925bdd6 100644 --- a/Engine/NodeGroupWrapper.cpp +++ b/Engine/NodeGroupWrapper.cpp @@ -24,6 +24,9 @@ #include "NodeGroupWrapper.h" +#include +#include + #include "Engine/Node.h" #include "Engine/NodeGroup.h" #include "Engine/NodeWrapper.h" diff --git a/Engine/NodeSerialization.cpp b/Engine/NodeSerialization.cpp index 1076f3e13c..28ef238b6c 100644 --- a/Engine/NodeSerialization.cpp +++ b/Engine/NodeSerialization.cpp @@ -24,6 +24,9 @@ #include "NodeSerialization.h" +#include +#include + #include "Engine/AppInstance.h" #include "Engine/Knob.h" #include "Engine/Node.h" diff --git a/Engine/NodeWrapper.cpp b/Engine/NodeWrapper.cpp index 14658368c8..2921ac4282 100644 --- a/Engine/NodeWrapper.cpp +++ b/Engine/NodeWrapper.cpp @@ -24,6 +24,9 @@ #include "NodeWrapper.h" +#include +#include + #include "Engine/Node.h" #include "Engine/KnobTypes.h" #include "Engine/KnobFile.h" diff --git a/Engine/NonKeyParams.cpp b/Engine/NonKeyParams.cpp index 6dfa58cabe..585166d270 100644 --- a/Engine/NonKeyParams.cpp +++ b/Engine/NonKeyParams.cpp @@ -24,8 +24,10 @@ #include "NonKeyParams.h" -NATRON_NAMESPACE_ENTER; +#include +#include +NATRON_NAMESPACE_ENTER; NonKeyParams::NonKeyParams() : _elementsCount(0) diff --git a/Engine/NonKeyParamsSerialization.cpp b/Engine/NonKeyParamsSerialization.cpp index bd7e4bbf69..a188e4b664 100644 --- a/Engine/NonKeyParamsSerialization.cpp +++ b/Engine/NonKeyParamsSerialization.cpp @@ -24,6 +24,9 @@ #include "Engine/NonKeyParamsSerialization.h" +#include +#include + NATRON_NAMESPACE_ENTER; // explicit template instantiations diff --git a/Engine/OfxClipInstance.cpp b/Engine/OfxClipInstance.cpp index 43933551a4..855dc25f27 100644 --- a/Engine/OfxClipInstance.cpp +++ b/Engine/OfxClipInstance.cpp @@ -26,8 +26,9 @@ #include #include -#include #include +#include +#include #include #include @@ -311,24 +312,31 @@ OfxClipInstancePrivate::getComponentsPresentInternal(const OfxClipInstance::Clip * to have it thread-safe and local to a current calling time. */ const std::vector& -OfxClipInstance::getComponentsPresent() const +OfxClipInstance::getComponentsPresent() const OFX_EXCEPTION_SPEC { - - //The components present have just been computed in the previous call to getDimension() - //so we are fine here - ClipDataTLSPtr tls = _imp->tlsData->getOrCreateTLSData(); - return tls->componentsPresent; + try { + //The components present have just been computed in the previous call to getDimension() + //so we are fine here + ClipDataTLSPtr tls = _imp->tlsData->getOrCreateTLSData(); + return tls->componentsPresent; + } catch (...) { + throw OFX::Host::Property::Exception(kOfxStatErrUnknown); + } } int OfxClipInstance::getDimension(const std::string &name) const OFX_EXCEPTION_SPEC { - if (name == kFnOfxImageEffectPropComponentsPresent) { + if (name != kFnOfxImageEffectPropComponentsPresent) { + return OFX::Host::ImageEffect::ClipInstance::getDimension(name); + } + try { ClipDataTLSPtr tls = _imp->tlsData->getOrCreateTLSData(); const std::vector& components = _imp->getComponentsPresentInternal(tls); return (int)components.size(); + } catch (...) { + throw OFX::Host::Property::Exception(kOfxStatErrUnknown); } - return OFX::Host::ImageEffect::ClipInstance::getDimension(name); } diff --git a/Engine/OfxClipInstance.h b/Engine/OfxClipInstance.h index 4cbbdd14f5..e921b660fb 100644 --- a/Engine/OfxClipInstance.h +++ b/Engine/OfxClipInstance.h @@ -143,7 +143,7 @@ class OfxClipInstance /// return components from other planes. /// Returns a vector since the function getStringPropertyN does not exist. Only getStringProperty /// with an index exists. - virtual const std::vector& getComponentsPresent() const OVERRIDE FINAL WARN_UNUSED_RETURN; + virtual const std::vector& getComponentsPresent() const OFX_EXCEPTION_SPEC OVERRIDE FINAL WARN_UNUSED_RETURN; virtual int getDimension(const std::string &name) const OFX_EXCEPTION_SPEC OVERRIDE FINAL WARN_UNUSED_RETURN; diff --git a/Engine/OfxEffectInstance.cpp b/Engine/OfxEffectInstance.cpp index 8aa1ead406..b20b0a2d4c 100644 --- a/Engine/OfxEffectInstance.cpp +++ b/Engine/OfxEffectInstance.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include diff --git a/Engine/OfxHost.cpp b/Engine/OfxHost.cpp index 30f423ffc0..3790099a42 100644 --- a/Engine/OfxHost.cpp +++ b/Engine/OfxHost.cpp @@ -92,6 +92,7 @@ CLANG_DIAG_ON(unknown-pragmas) #include "Engine/Node.h" #include "Engine/OfxEffectInstance.h" #include "Engine/OfxImageEffectInstance.h" +#include "Engine/OutputSchedulerThread.h" #include "Engine/OfxMemory.h" #include "Engine/Plugin.h" #include "Engine/Project.h" @@ -99,6 +100,9 @@ CLANG_DIAG_ON(unknown-pragmas) #include "Engine/StandardPaths.h" #include "Engine/TLSHolder.h" +//An effect may not use more than this amount of threads +#define NATRON_MULTI_THREAD_SUITE_MAX_NUM_CPU 4 + NATRON_NAMESPACE_ENTER; // to disambiguate with the global-scope ::OfxHost @@ -1213,7 +1217,9 @@ OfxHost::multiThreadNumCPUS(unsigned int *nCPUs) const int activeThreadsCount = QThreadPool::globalInstance()->activeThreadCount(); // Add the number of threads already running by the multiThreadSuite + parallel renders +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL activeThreadsCount += appPTR->getNRunningThreads(); +#endif // Clamp to 0 activeThreadsCount = std::max( 0, activeThreadsCount); @@ -1231,10 +1237,10 @@ OfxHost::multiThreadNumCPUS(unsigned int *nCPUs) const if (hwConcurrency <= 0) { nThreadsPerEffect = 1; - } else if (hwConcurrency <= 4) { + } else if (hwConcurrency <= NATRON_MULTI_THREAD_SUITE_MAX_NUM_CPU) { nThreadsPerEffect = hwConcurrency; } else { - nThreadsPerEffect = 4; + nThreadsPerEffect = NATRON_MULTI_THREAD_SUITE_MAX_NUM_CPU; } } ///+1 because the current thread is going to wait during the multiThread call so we're better off diff --git a/Engine/OfxMemory.cpp b/Engine/OfxMemory.cpp index e485617ec1..281b235dde 100644 --- a/Engine/OfxMemory.cpp +++ b/Engine/OfxMemory.cpp @@ -24,6 +24,9 @@ #include "OfxMemory.h" +#include +#include + #include "Global/Macros.h" CLANG_DIAG_OFF(deprecated) #include diff --git a/Engine/OfxOverlayInteract.cpp b/Engine/OfxOverlayInteract.cpp index 4fd5839ebd..0ae264a79c 100644 --- a/Engine/OfxOverlayInteract.cpp +++ b/Engine/OfxOverlayInteract.cpp @@ -24,6 +24,9 @@ #include "OfxOverlayInteract.h" +#include +#include + #include "Global/Macros.h" #include "Engine/OfxImageEffectInstance.h" #include "Engine/OfxEffectInstance.h" diff --git a/Engine/OfxParamInstance.cpp b/Engine/OfxParamInstance.cpp index d0dd12f16c..73397709d7 100644 --- a/Engine/OfxParamInstance.cpp +++ b/Engine/OfxParamInstance.cpp @@ -25,6 +25,9 @@ #include "OfxParamInstance.h" #include +#include +#include + #include GCC_DIAG_UNUSED_LOCAL_TYPEDEFS_OFF #include @@ -3363,8 +3366,16 @@ OfxParametricInstance::initializeInteract(OverlaySupport* widget) OfxPluginEntryPoint* interactEntryPoint = (OfxPluginEntryPoint*)getProperties().getPointerProperty(kOfxParamPropParametricInteractBackground); if (interactEntryPoint) { - OfxEffectInstance* effect = dynamic_cast(_knob.lock()->getHolder()); + boost::shared_ptr knob = _knob.lock(); + assert(knob); + if (!knob) { + throw std::logic_error("OfxParametricInstance::initializeInteract"); + } + OfxEffectInstance* effect = dynamic_cast(knob->getHolder()); assert(effect); + if (!effect) { + throw std::logic_error("OfxParametricInstance::initializeInteract"); + } _overlayInteract = new OfxOverlayInteract( ( *effect->effectInstance() ),8,true ); _overlayInteract->setCallingViewport(widget); _overlayInteract->createInstanceAction(); diff --git a/Engine/OutputEffectInstance.cpp b/Engine/OutputEffectInstance.cpp index 678da5420e..df755e748f 100644 --- a/Engine/OutputEffectInstance.cpp +++ b/Engine/OutputEffectInstance.cpp @@ -27,8 +27,9 @@ #include #include #include // min, max -#include #include +#include +#include #include // QtCore on Qt4, QtConcurrent on Qt5 #include diff --git a/Engine/OutputSchedulerThread.cpp b/Engine/OutputSchedulerThread.cpp index b00dd146c6..45e537bd94 100644 --- a/Engine/OutputSchedulerThread.cpp +++ b/Engine/OutputSchedulerThread.cpp @@ -28,6 +28,8 @@ #include #include #include // min, max +#include +#include #include #include @@ -61,6 +63,17 @@ #define NATRON_FPS_REFRESH_RATE_SECONDS 1.5 +/* + When defined, parallel frame renders are spawned from a timer so that the frames + appear to be rendered all at the same speed. + When undefined each time a frame is computed a new thread will be spawned + until we reach the maximum allowed parallel frame renders. + */ +//#define NATRON_SCHEDULER_SPAWN_THREADS_WITH_TIMER + +#ifdef NATRON_SCHEDULER_SPAWN_THREADS_WITH_TIMER +#define NATRON_SCHEDULER_THREADS_SPAWN_DEFAULT_TIMEOUT_MS 500 +#endif NATRON_NAMESPACE_ENTER; @@ -152,10 +165,12 @@ struct ProducedFrame bool isAborted; }; +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL static bool isBufferFull(int nbBufferedElement, int hardwardIdealThreadCount) { return nbBufferedElement >= hardwardIdealThreadCount * 3; } +#endif struct OutputSchedulerThreadPrivate { @@ -176,9 +191,10 @@ struct OutputSchedulerThreadPrivate QWaitCondition startRequestsCond; QMutex startRequestsMutex; - int abortRequested; // true when the user wants to stop the engine, e.g: the user disconnected the viewer - bool isAbortRequestBlocking; + int abortRequested; // true when the user wants to stop the engine, e.g: the user disconnected the viewer, protected by abortedRequestedMutex + bool isAbortRequestBlocking; // protected by abortedRequestedMutex + //If true then a current frame render can start playback, protected by abortedRequestedMutex bool canAutoRestartPlayback; QWaitCondition abortedRequestedCondition; @@ -221,23 +237,40 @@ struct OutputSchedulerThreadPrivate mutable QMutex renderThreadsMutex; RenderThreads renderThreads; QWaitCondition allRenderThreadsInactiveCond; // wait condition to make sure all render threads are asleep + +#ifdef NATRON_PLAYBACK_USES_THREAD_POOL + QThreadPool* threadPool; + +#else + QWaitCondition allRenderThreadsQuitCond; //to make sure all render threads have quit + + + std::list framesToRender; + + ///Render threads wait in this condition and the scheduler wake them when it needs to render some frames + QWaitCondition framesToRenderNotEmptyCond; + +#endif ///Work queue filled by the scheduler thread when in playback/render on disk QMutex framesToRenderMutex; // protects framesToRender & currentFrameRequests - std::list framesToRender; ///index of the last frame pushed (framesToRender.back()) ///we store this because when we call pushFramesToRender we need to know what was the last frame that was queued ///Protected by framesToRenderMutex int lastFramePushedIndex; - - ///Render threads wait in this condition and the scheduler wake them when it needs to render some frames - QWaitCondition framesToRenderNotEmptyCond; - - + boost::weak_ptr outputEffect; //< The effect used as output device RenderEngine* engine; + +#ifdef NATRON_SCHEDULER_SPAWN_THREADS_WITH_TIMER + QTimer threadSpawnsTimer; + + QMutex lastRecordedFPSMutex; + double lastRecordedFPS; + +#endif OutputSchedulerThreadPrivate(RenderEngine* engine,const boost::shared_ptr& effect,OutputSchedulerThread::ProcessFrameModeEnum mode) @@ -275,15 +308,24 @@ struct OutputSchedulerThreadPrivate , renderThreadsMutex() , renderThreads() , allRenderThreadsInactiveCond() +#ifdef NATRON_PLAYBACK_USES_THREAD_POOL + , threadPool(QThreadPool::globalInstance()) +#else , allRenderThreadsQuitCond() - , framesToRenderMutex() , framesToRender() - , lastFramePushedIndex(0) , framesToRenderNotEmptyCond() +#endif + , framesToRenderMutex() + , lastFramePushedIndex(0) , outputEffect(effect) , engine(engine) +#ifdef NATRON_SCHEDULER_SPAWN_THREADS_WITH_TIMER + , threadSpawnsTimer() + , lastRecordedFPSMutex() + , lastRecordedFPS(0.) +#endif { - + } bool appendBufferedFrame(double time, @@ -326,11 +368,16 @@ struct OutputSchedulerThreadPrivate void appendRunnable(RenderThreadTask* runnable) { + assert(!renderThreadsMutex.tryLock()); RenderThread r; r.thread = runnable; r.active = true; renderThreads.push_back(r); +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL runnable->start(); +#else + threadPool->start(runnable); +#endif } @@ -385,14 +432,24 @@ struct OutputSchedulerThreadPrivate void waitForRenderThreadsToBeDone() { assert( !renderThreadsMutex.tryLock() ); - while (renderThreads.size() > 0 && getNActiveRenderThreads() > 0) { + while (renderThreads.size() > 0 +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL + /* + When not using the thread pool we use the same threads for computing several frames. + When using the thread-pool tasks are actually just removed from renderThreads when they are finisehd + */ + && getNActiveRenderThreads() > 0 +#endif + ) { allRenderThreadsInactiveCond.wait(&renderThreadsMutex); } } int getNActiveRenderThreads() const { ///Private shouldn't lock - assert( !renderThreadsMutex.tryLock() ); + assert(!renderThreadsMutex.tryLock()); + +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL int ret = 0; for (RenderThreads::const_iterator it = renderThreads.begin(); it != renderThreads.end(); ++it) { if (it->active) { @@ -400,8 +457,16 @@ struct OutputSchedulerThreadPrivate } } return ret; +#else + /* + When not using the thread pool we use the same threads for computing several frames. + When using the thread-pool tasks are actually just removed from renderThreads when they are finisehd + */ + return (int)renderThreads.size(); +#endif } +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL void removeQuitRenderThreadsInternal() { for (;;) { @@ -420,7 +485,9 @@ struct OutputSchedulerThreadPrivate } } } - +#endif + +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL void removeAllQuitRenderThreads() { ///Private shouldn't lock assert(!renderThreadsMutex.tryLock()); @@ -430,9 +497,11 @@ struct OutputSchedulerThreadPrivate ///Wake-up the main-thread if it was waiting for all threads to quit allRenderThreadsQuitCond.wakeOne(); } +#endif void waitForRenderThreadsToQuit() { +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL RenderThreads threads; { QMutexLocker l(&renderThreadsMutex); @@ -448,6 +517,13 @@ struct OutputSchedulerThreadPrivate removeQuitRenderThreadsInternal(); assert(renderThreads.empty()); } +#else + /* + We don't need the threads to actually quit, just need the runnables to be done + */ + QMutexLocker l(&renderThreadsMutex); + waitForRenderThreadsToBeDone(); +#endif } @@ -458,14 +534,18 @@ OutputSchedulerThread::OutputSchedulerThread(RenderEngine* engine,const boost::s : QThread() , _imp(new OutputSchedulerThreadPrivate(engine,effect,mode)) { - QObject::connect(this, SIGNAL(s_doProcessOnMainThread(BufferedFrames,bool,int)), this, - SLOT(doProcessFrameMainThread(BufferedFrames,bool,int))); + QObject::connect(this, SIGNAL(s_doProcessOnMainThread(BufferedFrames)), this, + SLOT(doProcessFrameMainThread(BufferedFrames))); QObject::connect(_imp->timer.get(), SIGNAL(fpsChanged(double,double)), _imp->engine, SIGNAL(fpsChanged(double,double))); QObject::connect(this, SIGNAL(s_abortRenderingOnMainThread(bool,bool)), this, SLOT(abortRendering(bool,bool))); +#ifdef NATRON_SCHEDULER_SPAWN_THREADS_WITH_TIMER + QObject::connect(&_imp->threadSpawnsTimer, SIGNAL(timeout()), this, SLOT(onThreadSpawnsTimerTriggered())); +#endif + setObjectName("Scheduler thread"); } @@ -584,6 +664,7 @@ OutputSchedulerThreadPrivate::getNearestInSequence(OutputSchedulerThread::Render } +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL void OutputSchedulerThread::pushFramesToRender(int startingFrame,int nThreads) { @@ -623,7 +704,6 @@ OutputSchedulerThread::pushFramesToRenderInternal(int startingFrame,int nThreads ///Push 2x the count of threads to be sure no one will be waiting while ((int)_imp->framesToRender.size() < nThreads * 2) { _imp->framesToRender.push_back(startingFrame); - _imp->lastFramePushedIndex = startingFrame; if (!OutputSchedulerThreadPrivate::getNextFrameInSequence(pMode, direction, startingFrame, @@ -699,6 +779,7 @@ OutputSchedulerThread::pushFramesToRender(int nThreads) } } + int OutputSchedulerThread::pickFrameToRender(RenderThreadTask* thread,bool* enableRenderStats, std::vector* viewsToRender) { @@ -772,6 +853,140 @@ OutputSchedulerThread::pickFrameToRender(RenderThreadTask* thread,bool* enableRe return -1; } +#else // NATRON_PLAYBACK_USES_THREAD_POOL + +void +OutputSchedulerThread::startTasksFromLastStartedFrame() +{ + int frame; + bool canContinue; + + { + QMutexLocker l(&_imp->framesToRenderMutex); + + RenderDirectionEnum direction; + int firstFrame,lastFrame,frameStep; + { + QMutexLocker l(&_imp->runArgsMutex); + direction = _imp->livingRunArgs.timelineDirection; + firstFrame = _imp->livingRunArgs.firstFrame; + lastFrame = _imp->livingRunArgs.lastFrame; + frameStep = _imp->livingRunArgs.frameStep; + } + + PlaybackModeEnum pMode = _imp->engine->getPlaybackMode(); + + frame = _imp->lastFramePushedIndex; + if (firstFrame == lastFrame && frame == firstFrame) { + return; + } + + ///If startingTime is already taken into account in the framesToRender, push new frames from the last one in the stack instead + canContinue = OutputSchedulerThreadPrivate::getNextFrameInSequence(pMode, direction, frame, + firstFrame, lastFrame, frameStep, &frame, &direction); + } + if (canContinue) { + QMutexLocker l(&_imp->renderThreadsMutex); + startTasks(frame); + } + +} + +void +OutputSchedulerThread::startTasks(int startingFrame) +{ + + int maxThreads = _imp->threadPool->maxThreadCount(); + int activeThreads = _imp->getNActiveRenderThreads(); + + //This thread is from the thread pool so do not count it as it is probably done anyway + if (QThread::currentThread() != this) { + activeThreads -= 1; + } + + + + int nFrames; +#ifdef NATRON_SCHEDULER_SPAWN_THREADS_WITH_TIMER + //We check every now and then if we need to start new threads + { + int nbAvailableThreads = maxThreads - activeThreads; + if (nbAvailableThreads <= 0) { + return; + } + nFrames = 1; + } +#else + //Start one more thread until we use all the thread pool. + //We leave some CPU available so that the multi-thread suite can take advantage of it + nFrames = std::max(std::min(maxThreads - activeThreads, 2), 1); +#endif + + + RenderDirectionEnum direction; + int firstFrame,lastFrame,frameStep; + bool useStats; + std::vector viewsToRender; + { + QMutexLocker l(&_imp->runArgsMutex); + direction = _imp->livingRunArgs.timelineDirection; + firstFrame = _imp->livingRunArgs.firstFrame; + lastFrame = _imp->livingRunArgs.lastFrame; + frameStep = _imp->livingRunArgs.frameStep; + useStats = _imp->livingRunArgs.enableRenderStats; + viewsToRender = _imp->livingRunArgs.viewsToRender; + } + + PlaybackModeEnum pMode = _imp->engine->getPlaybackMode(); + if (firstFrame == lastFrame) { + RenderThreadTask* task = createRunnable(startingFrame, useStats, viewsToRender); + _imp->appendRunnable(task); + + QMutexLocker k(&_imp->framesToRenderMutex); + _imp->lastFramePushedIndex = startingFrame; + } else { + int frame = startingFrame; + for (int i = 0; i < nFrames; ++i) { + RenderThreadTask* task = createRunnable(frame, useStats, viewsToRender); + _imp->appendRunnable(task); + + + { + QMutexLocker k(&_imp->framesToRenderMutex); + _imp->lastFramePushedIndex = frame; + } + + if (!OutputSchedulerThreadPrivate::getNextFrameInSequence(pMode, direction, frame, + firstFrame, lastFrame, frameStep, &frame, &direction)) { + break; + } + } + } +} + +#endif //NATRON_PLAYBACK_USES_THREAD_POOL + + +void +OutputSchedulerThread::onThreadSpawnsTimerTriggered() +{ +#ifdef NATRON_SCHEDULER_SPAWN_THREADS_WITH_TIMER + +#ifdef NATRON_PLAYBACK_USES_THREAD_POOL + startTasksFromLastStartedFrame(); +#else + /////////// + /////If we were analysing the CPU activity, now set the appropriate number of threads to render. + int newNThreads, lastNThreads; + adjustNumberOfThreads(&newNThreads,&lastNThreads); + + /////////// + /////Append render requests for the render threads + pushFramesToRender(newNThreads); +#endif + +#endif +} void OutputSchedulerThread::notifyThreadAboutToQuit(RenderThreadTask* thread) @@ -780,8 +995,14 @@ OutputSchedulerThread::notifyThreadAboutToQuit(RenderThreadTask* thread) RenderThreads::iterator found = _imp->getRunnableIterator(thread); if (found != _imp->renderThreads.end()) { found->active = false; +#ifdef NATRON_PLAYBACK_USES_THREAD_POOL + _imp->renderThreads.erase(found); +#endif _imp->allRenderThreadsInactiveCond.wakeOne(); + +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL _imp->allRenderThreadsQuitCond.wakeOne(); +#endif } } @@ -792,10 +1013,13 @@ OutputSchedulerThread::isBeingAborted() const return _imp->abortFlag; } + void OutputSchedulerThread::startRender() { + + if ( isFPSRegulationNeeded() ) { _imp->timer->playState = ePlayStateRunning; } @@ -826,19 +1050,21 @@ OutputSchedulerThread::startRender() QMutexLocker l(&_imp->workingMutex); _imp->working = true; } - + +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL int nThreads; { QMutexLocker l(&_imp->renderThreadsMutex); _imp->removeAllQuitRenderThreads(); nThreads = (int)_imp->renderThreads.size(); } - + ///Start with one thread if it doesn't exist if (nThreads == 0) { int lastNThreads; adjustNumberOfThreads(&nThreads, &lastNThreads); } +#endif QMutexLocker l(&_imp->renderThreadsMutex); @@ -846,9 +1072,10 @@ OutputSchedulerThread::startRender() SchedulingPolicyEnum policy = getSchedulingPolicy(); if (policy == eSchedulingPolicyFFA) { - +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL ///push all frame range and let the threads deal with it pushAllFrameRange(); +#endif } else { ///If the output effect is sequential (only WriteFFMPEG for now) @@ -869,12 +1096,23 @@ OutputSchedulerThread::startRender() return; } } +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL ///Push as many frames as there are threads pushFramesToRender(startingFrame,nThreads); +#endif } - +#ifdef NATRON_PLAYBACK_USES_THREAD_POOL + startTasks(startingFrame); +#endif + +#ifdef NATRON_SCHEDULER_SPAWN_THREADS_WITH_TIMER + QMutexLocker k(&_imp->lastRecordedFPSMutex); + double timeoutMS = _imp->lastRecordedFPS == 0. ? NATRON_SCHEDULER_THREADS_SPAWN_DEFAULT_TIMEOUT_MS : (1. / _imp->lastRecordedFPS) * 1000; + _imp->threadSpawnsTimer.start(timeoutMS); +#endif + } void @@ -882,19 +1120,35 @@ OutputSchedulerThread::stopRender() { _imp->timer->playState = ePlayStatePause; +#ifdef NATRON_SCHEDULER_SPAWN_THREADS_WITH_TIMER + QMutexLocker k(&_imp->lastRecordedFPSMutex); + _imp->lastRecordedFPS = _imp->timer->getActualFrameRate(); + _imp->threadSpawnsTimer.stop(); +#endif + ///Wait for all render threads to be done + +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL ///Clear the work queue { QMutexLocker framesLocker (&_imp->framesToRenderMutex); _imp->framesToRender.clear(); } - - { +#endif + + ///Remove all current threads so the new render doesn't have many threads concurrently trying to do the same thing at the same time +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL + stopRenderThreads(0); +#endif + _imp->waitForRenderThreadsToQuit(); + + + /*{ QMutexLocker l(&_imp->renderThreadsMutex); _imp->removeAllQuitRenderThreads(); _imp->waitForRenderThreadsToBeDone(); - } + }*/ ///If the output effect is sequential (only WriteFFMPEG for now) @@ -1086,6 +1340,9 @@ OutputSchedulerThread::run() } if (!renderFinished) { +#ifndef NATRON_SCHEDULER_SPAWN_THREADS_WITH_TIMER + +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL /////////// /////If we were analysing the CPU activity, now set the appropriate number of threads to render. int newNThreads, lastNThreads; @@ -1094,6 +1351,11 @@ OutputSchedulerThread::run() /////////// /////Append render requests for the render threads pushFramesToRender(newNThreads); +#else + startTasksFromLastStartedFrame(); +#endif + +#endif } } // if (!renderFinished) { @@ -1112,17 +1374,6 @@ OutputSchedulerThread::run() if (_imp->mode == eProcessFrameBySchedulerThread) { processFrame(framesToRender); - - if (!renderFinished) { - ///Timeline might have changed if another thread moved the playhead - int timelineCurrentTime = timelineGetTime(); - if (timelineCurrentTime != expectedTimeToRender) { - timelineGoTo(timelineCurrentTime); - } else { - timelineGoTo(nextFrameToRender); - } - - } } else { ///Process on main-thread @@ -1141,26 +1392,27 @@ OutputSchedulerThread::run() } _imp->processRunning = true; - - int timeToSeek = 0; - if (!renderFinished) { - ///Timeline might have changed if another thread moved the playhead - int timelineCurrentTime = timelineGetTime(); - if (timelineCurrentTime != expectedTimeToRender) { - timeToSeek = timelineCurrentTime; - } else { - timeToSeek = nextFrameToRender; - } - - } + - Q_EMIT s_doProcessOnMainThread(framesToRender,!renderFinished, timeToSeek); + Q_EMIT s_doProcessOnMainThread(framesToRender); while (_imp->processRunning) { _imp->processCondition.wait(&_imp->processMutex); } + + } // if (_imp->mode == eProcessFrameBySchedulerThread) { + if (!renderFinished) { + ///Timeline might have changed if another thread moved the playhead + int timelineCurrentTime = timelineGetTime(); + if (timelineCurrentTime != expectedTimeToRender) { + timelineGoTo(timelineCurrentTime); + } else { + timelineGoTo(nextFrameToRender); + } + + } //////////// /////At this point the frame has been processed by the output device @@ -1221,6 +1473,7 @@ OutputSchedulerThread::run() } +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL void OutputSchedulerThread::adjustNumberOfThreads(int* newNThreads, int *lastNThreads) { @@ -1269,6 +1522,7 @@ OutputSchedulerThread::adjustNumberOfThreads(int* newNThreads, int *lastNThreads *newNThreads = std::max(1,currentParallelRenders); } } +#endif void OutputSchedulerThread::notifyFrameRendered(int frame, @@ -1320,10 +1574,18 @@ OutputSchedulerThread::notifyFrameRendered(int frame, } else { l.unlock(); +#ifndef NATRON_SCHEDULER_SPAWN_THREADS_WITH_TIMER + +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL /////////// /////If we were analysing the CPU activity, now set the appropriate number of threads to render. int newNThreads; adjustNumberOfThreads(&newNThreads, &nbCurParallelRenders); +#else + startTasksFromLastStartedFrame(); +#endif + +#endif } } else { { @@ -1497,7 +1759,7 @@ OutputSchedulerThread::appendToBuffer(double time, void -OutputSchedulerThread::doProcessFrameMainThread(const BufferedFrames& frames,bool mustSeekTimeline,int time) +OutputSchedulerThread::doProcessFrameMainThread(const BufferedFrames& frames) { assert(QThread::currentThread() == qApp->thread()); { @@ -1510,10 +1772,7 @@ OutputSchedulerThread::doProcessFrameMainThread(const BufferedFrames& frames,boo processFrame(frames); - - if (mustSeekTimeline) { - timelineGoTo(time); - } + QMutexLocker processLocker (&_imp->processMutex); _imp->processRunning = false; @@ -1835,7 +2094,7 @@ void OutputSchedulerThread::stopRenderThreads(int nThreadsToStop) { - +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL { ///First flag the number of threads to stop @@ -1854,13 +2113,20 @@ OutputSchedulerThread::stopRenderThreads(int nThreadsToStop) _imp->removeAllQuitRenderThreads(); } - ///Wake-up all threads to make sure that they are notified that they must quit { QMutexLocker framesLocker(&_imp->framesToRenderMutex); _imp->framesToRenderNotEmptyCond.wakeAll(); } +#else + Q_UNUSED(nThreadsToStop); + QMutexLocker l(&_imp->renderThreadsMutex); + _imp->waitForRenderThreadsToBeDone(); +#endif + + + } @@ -1907,34 +2173,66 @@ struct RenderThreadTaskPrivate boost::weak_ptr output; +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL QMutex mustQuitMutex; bool mustQuit; bool hasQuit; QMutex runningMutex; bool running; - - RenderThreadTaskPrivate(const boost::shared_ptr& output,OutputSchedulerThread* scheduler) +#else + int time; + bool useRenderStats; + std::vector viewsToRender; +#endif + + RenderThreadTaskPrivate(const boost::shared_ptr& output, + OutputSchedulerThread* scheduler + #ifdef NATRON_PLAYBACK_USES_THREAD_POOL + , + const int time, + const bool useRenderStats, + const std::vector& viewsToRender + #endif + ) : scheduler(scheduler) , output(output) +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL , mustQuitMutex() , mustQuit(false) , hasQuit(false) , runningMutex() , running(false) +#else + , time(time) + , useRenderStats(useRenderStats) + , viewsToRender(viewsToRender) +#endif { } }; +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL RenderThreadTask::RenderThreadTask(const boost::shared_ptr& output,OutputSchedulerThread* scheduler) : QThread() , _imp(new RenderThreadTaskPrivate(output,scheduler)) { setObjectName("Parallel render thread"); } - +#else +RenderThreadTask::RenderThreadTask(const boost::shared_ptr& output, + OutputSchedulerThread* scheduler, + const int time, + const bool useRenderStats, + const std::vector& viewsToRender) +: QRunnable() +, _imp(new RenderThreadTaskPrivate(output, scheduler, time, useRenderStats, viewsToRender)) +{ + +} +#endif RenderThreadTask::~RenderThreadTask() { @@ -1944,6 +2242,7 @@ void RenderThreadTask::run() { +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL notifyIsRunning(true); for (;;) { @@ -1971,9 +2270,14 @@ RenderThreadTask::run() } notifyIsRunning(false); _imp->scheduler->notifyThreadAboutToQuit(this); +#else // NATRON_PLAYBACK_USES_THREAD_POOL + renderFrame(_imp->time, _imp->viewsToRender, _imp->useRenderStats); + _imp->scheduler->notifyThreadAboutToQuit(this); +#endif } +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL bool RenderThreadTask::hasQuit() const { @@ -2010,6 +2314,7 @@ RenderThreadTask::notifyIsRunning(bool running) appPTR->fetchAndAddNRunningThreads(running ? 1 : - 1); } +#endif //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// @@ -2033,11 +2338,25 @@ class DefaultRenderFrameRunnable : public RenderThreadTask public: + +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL DefaultRenderFrameRunnable(const boost::shared_ptr& writer,OutputSchedulerThread* scheduler) : RenderThreadTask(writer,scheduler) { } +#else + DefaultRenderFrameRunnable(const boost::shared_ptr& writer, + OutputSchedulerThread* scheduler, + const int time, + const bool useRenderStats, + const std::vector& viewsToRender) + : RenderThreadTask(writer,scheduler, time, useRenderStats, viewsToRender) + { + + } +#endif + virtual ~DefaultRenderFrameRunnable() { @@ -2239,11 +2558,19 @@ class DefaultRenderFrameRunnable : public RenderThreadTask } }; +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL RenderThreadTask* DefaultScheduler::createRunnable() { return new DefaultRenderFrameRunnable(_effect.lock(),this); } +#else +RenderThreadTask* +DefaultScheduler::createRunnable(int frame, bool useRenderStarts, const std::vector& viewsToRender) +{ + return new DefaultRenderFrameRunnable(_effect.lock(),this, frame, useRenderStarts, viewsToRender); +} +#endif @@ -2599,12 +2926,26 @@ class ViewerRenderFrameRunnable : public RenderThreadTask public: +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL ViewerRenderFrameRunnable(const boost::shared_ptr& viewer,OutputSchedulerThread* scheduler) : RenderThreadTask(viewer,scheduler) , _viewer(viewer) { } +#else + ViewerRenderFrameRunnable(const boost::shared_ptr& viewer, + OutputSchedulerThread* scheduler, + const int frame, + const bool useRenderStarts, + const std::vector& viewsToRender) + : RenderThreadTask(viewer,scheduler, frame, useRenderStarts, viewsToRender) + , _viewer(viewer) + { + + } +#endif + virtual ~ViewerRenderFrameRunnable() { @@ -2705,11 +3046,21 @@ class ViewerRenderFrameRunnable : public RenderThreadTask } }; + +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL RenderThreadTask* ViewerDisplayScheduler::createRunnable() { return new ViewerRenderFrameRunnable(_viewer.lock(),this); } +#else +RenderThreadTask* +ViewerDisplayScheduler::createRunnable(int frame, bool useRenderStarts, const std::vector& viewsToRender) +{ + return new ViewerRenderFrameRunnable(_viewer.lock(),this, frame, useRenderStarts, viewsToRender); +} +#endif + void ViewerDisplayScheduler::handleRenderFailure(const std::string& /*errorMessage*/) diff --git a/Engine/OutputSchedulerThread.h b/Engine/OutputSchedulerThread.h index a3b125fe90..98bc74347b 100644 --- a/Engine/OutputSchedulerThread.h +++ b/Engine/OutputSchedulerThread.h @@ -34,6 +34,9 @@ #include "Global/GlobalDefines.h" #include "Engine/EngineFwd.h" +//#define NATRON_PLAYBACK_USES_THREAD_POOL + + NATRON_NAMESPACE_ENTER; typedef boost::shared_ptr RenderStatsPtr; @@ -89,18 +92,32 @@ typedef std::list BufferedFrames; class OutputSchedulerThread; struct RenderThreadTaskPrivate; + +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL class RenderThreadTask : public QThread +#else +class RenderThreadTask : public QRunnable +#endif { public: - + +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL RenderThreadTask(const boost::shared_ptr& output,OutputSchedulerThread* scheduler); +#else + RenderThreadTask(const boost::shared_ptr& output, + OutputSchedulerThread* scheduler, + const int time, + const bool useRenderStats, + const std::vector& viewsToRender); +#endif virtual ~RenderThreadTask(); virtual void run() OVERRIDE FINAL; +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL /** * @brief Call this to quit the thread whenever it will return to the pickFrameToRender function **/ @@ -111,6 +128,7 @@ class RenderThreadTask : public QThread bool hasQuit() const; void notifyIsRunning(bool running); +#endif protected: @@ -268,11 +286,12 @@ GCC_DIAG_SUGGEST_OVERRIDE_ON **/ int getNActiveRenderThreads() const; +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL /** * @brief Called by render-threads to pick some work to do or to get asleep if theres nothing to do **/ int pickFrameToRender(RenderThreadTask* thread, bool* enableRenderStats, std::vector* viewsToRender); - +#endif /** * @brief Called by the render-threads when mustQuit() is true on the thread @@ -299,7 +318,7 @@ GCC_DIAG_SUGGEST_OVERRIDE_ON public Q_SLOTS: - void doProcessFrameMainThread(const BufferedFrames& frames,bool mustSeekTimeline,int time); + void doProcessFrameMainThread(const BufferedFrames& frames); /** @brief Aborts all computations. This turns on the flag abortRequested and will inform the engine that it needs to stop. @@ -317,10 +336,13 @@ public Q_SLOTS: **/ void abortRendering(bool autoRestart, bool blocking); +private Q_SLOTS: + + void onThreadSpawnsTimerTriggered(); Q_SIGNALS: - void s_doProcessOnMainThread(const BufferedFrames& frames,bool mustSeekTimeline,int time); + void s_doProcessOnMainThread(const BufferedFrames& frames); void s_abortRenderingOnMainThread(bool userRequested,bool blocking); @@ -378,10 +400,12 @@ public Q_SLOTS: * @brief Must create a runnable task that will render 1 frame in a separate thread. * The internal thread pool will take care of the thread * The task will pick frames to render until there are no more to be rendered. - * @param playbackOrRender Used as a hint to know that we're rendering for playback or render on disk - * and not just for one frame **/ +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL virtual RenderThreadTask* createRunnable() = 0; +#else + virtual RenderThreadTask* createRunnable(int frame, bool useRenderStarts, const std::vector& viewsToRender) = 0; +#endif /** * @brief Called upon failure of a thread to render an image @@ -417,6 +441,7 @@ public Q_SLOTS: virtual void run() OVERRIDE FINAL; +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL /** * @brief Called by the scheduler threads to wake-up render threads and make them do some work * It calls pushFramesToRenderInternal. It starts pushing frames from lastFramePushedIndex @@ -438,6 +463,10 @@ public Q_SLOTS: * @param optimalNThreads[out] Will be set to the new number of threads **/ void adjustNumberOfThreads(int* newNThreads, int *lastNThreads); +#else + void startTasksFromLastStartedFrame(); + void startTasks(int startingFrame); +#endif /** * @brief Make nThreadsToStop quit running. If 0 then all threads will be destroyed. @@ -476,7 +505,11 @@ class DefaultScheduler : public OutputSchedulerThread virtual int timelineGetTime() const OVERRIDE FINAL WARN_UNUSED_RETURN; +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL virtual RenderThreadTask* createRunnable() OVERRIDE FINAL WARN_UNUSED_RETURN; +#else + virtual RenderThreadTask* createRunnable(int frame, bool useRenderStarts, const std::vector& viewsToRender) OVERRIDE FINAL WARN_UNUSED_RETURN; +#endif virtual void handleRenderFailure(const std::string& errorMessage) OVERRIDE FINAL; @@ -517,7 +550,11 @@ class ViewerDisplayScheduler : public OutputSchedulerThread virtual void getFrameRangeToRender(int& first,int& last) const OVERRIDE FINAL; +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL virtual RenderThreadTask* createRunnable() OVERRIDE FINAL WARN_UNUSED_RETURN; +#else + virtual RenderThreadTask* createRunnable(int frame, bool useRenderStarts, const std::vector& viewsToRender) OVERRIDE FINAL WARN_UNUSED_RETURN; +#endif virtual void handleRenderFailure(const std::string& errorMessage) OVERRIDE FINAL; diff --git a/Engine/ParallelRenderArgs.cpp b/Engine/ParallelRenderArgs.cpp index 405aa12f26..260d4c600e 100644 --- a/Engine/ParallelRenderArgs.cpp +++ b/Engine/ParallelRenderArgs.cpp @@ -24,6 +24,9 @@ #include "ParallelRenderArgs.h" +#include +#include + #include "Engine/AppManager.h" #include "Engine/Settings.h" #include "Engine/EffectInstance.h" diff --git a/Engine/ParameterWrapper.cpp b/Engine/ParameterWrapper.cpp index ca5398089b..8ed86f943c 100644 --- a/Engine/ParameterWrapper.cpp +++ b/Engine/ParameterWrapper.cpp @@ -23,6 +23,10 @@ // ***** END PYTHON BLOCK ***** #include "ParameterWrapper.h" + +#include +#include + #include "Engine/EffectInstance.h" #include "Engine/Node.h" diff --git a/Engine/Plugin.cpp b/Engine/Plugin.cpp index 410afe01d0..3ce753e17e 100644 --- a/Engine/Plugin.cpp +++ b/Engine/Plugin.cpp @@ -24,6 +24,9 @@ #include "Plugin.h" +#include +#include + #include #include "Engine/AppManager.h" diff --git a/Engine/PluginMemory.cpp b/Engine/PluginMemory.cpp index 258e6b5003..81845cb092 100644 --- a/Engine/PluginMemory.cpp +++ b/Engine/PluginMemory.cpp @@ -24,8 +24,9 @@ #include "PluginMemory.h" -#include #include +#include +#include #include "Global/Macros.h" CLANG_DIAG_OFF(deprecated) diff --git a/Engine/PrecompNode.cpp b/Engine/PrecompNode.cpp index 478a40e4f2..0417254f06 100644 --- a/Engine/PrecompNode.cpp +++ b/Engine/PrecompNode.cpp @@ -22,9 +22,11 @@ #include // ***** END PYTHON BLOCK ***** - #include "PrecompNode.h" +#include +#include + #include "Global/GlobalDefines.h" #include "Global/QtCompat.h" diff --git a/Engine/ProcessHandler.cpp b/Engine/ProcessHandler.cpp index 76a856b6c9..9fdafdb695 100644 --- a/Engine/ProcessHandler.cpp +++ b/Engine/ProcessHandler.cpp @@ -24,6 +24,7 @@ #include "ProcessHandler.h" +#include #include #include diff --git a/Engine/Project.cpp b/Engine/Project.cpp index 07827ceac0..17d7ad1c51 100644 --- a/Engine/Project.cpp +++ b/Engine/Project.cpp @@ -29,6 +29,7 @@ #include #include // strtoul #include // errno +#include #include #include "Global/Macros.h" diff --git a/Engine/ProjectPrivate.cpp b/Engine/ProjectPrivate.cpp index 69e154a688..7fe7aeb501 100644 --- a/Engine/ProjectPrivate.cpp +++ b/Engine/ProjectPrivate.cpp @@ -24,8 +24,9 @@ #include "ProjectPrivate.h" -#include #include +#include +#include #include #include diff --git a/Engine/ProjectSerialization.cpp b/Engine/ProjectSerialization.cpp index 8090d44835..b464ebbcdc 100644 --- a/Engine/ProjectSerialization.cpp +++ b/Engine/ProjectSerialization.cpp @@ -24,6 +24,9 @@ #include "ProjectSerialization.h" +#include +#include + #include "Engine/AppManager.h" #include "Engine/Project.h" #include "Engine/RotoLayer.h" diff --git a/Engine/PySideCompat.cpp b/Engine/PySideCompat.cpp index ccd07c71c6..623d70aff2 100644 --- a/Engine/PySideCompat.cpp +++ b/Engine/PySideCompat.cpp @@ -24,6 +24,9 @@ #include // ***** END PYTHON BLOCK ***** +#include +#include + // Compatibility function for pyside versions before this commit: // https://qt.gitorious.org/pyside/pyside/commit/b3669dca4e4321b204d10b06018d35900b1847ee diff --git a/Engine/RectD.cpp b/Engine/RectD.cpp index 4a10c08e8a..114d3cf07f 100644 --- a/Engine/RectD.cpp +++ b/Engine/RectD.cpp @@ -25,6 +25,8 @@ #include "RectD.h" #include +#include +#include #include "Engine/RectI.h" diff --git a/Engine/RectI.cpp b/Engine/RectI.cpp index 6ec846a9af..9137fa07cd 100644 --- a/Engine/RectI.cpp +++ b/Engine/RectI.cpp @@ -25,6 +25,8 @@ #include "RectI.h" #include // min, max +#include +#include #include "Engine/RectD.h" diff --git a/Engine/RenderStats.cpp b/Engine/RenderStats.cpp index c9f89db39f..f069628f7e 100644 --- a/Engine/RenderStats.cpp +++ b/Engine/RenderStats.cpp @@ -26,6 +26,9 @@ #include "RenderStats.h" +#include +#include + #include #include "Engine/Node.h" diff --git a/Engine/RotoContext.cpp b/Engine/RotoContext.cpp index 81154c0d4d..88d4761854 100644 --- a/Engine/RotoContext.cpp +++ b/Engine/RotoContext.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/Engine/RotoDrawableItem.cpp b/Engine/RotoDrawableItem.cpp index d5978a7185..bad9408a4c 100644 --- a/Engine/RotoDrawableItem.cpp +++ b/Engine/RotoDrawableItem.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/Engine/RotoItem.cpp b/Engine/RotoItem.cpp index e7c0bb5720..148335fbc2 100644 --- a/Engine/RotoItem.cpp +++ b/Engine/RotoItem.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/Engine/RotoLayer.cpp b/Engine/RotoLayer.cpp index 6e9a30b277..e9130659fa 100644 --- a/Engine/RotoLayer.cpp +++ b/Engine/RotoLayer.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -163,6 +164,9 @@ RotoLayer::save(RotoItemSerialization *obj) const RotoLayerSerialization* s = dynamic_cast(obj); assert(s); + if (!s) { + throw std::logic_error("RotoLayer::save"); + } RotoItems items; { QMutexLocker l(&itemMutex); diff --git a/Engine/RotoPaint.cpp b/Engine/RotoPaint.cpp index 3c6ee54212..7156ddd0c9 100644 --- a/Engine/RotoPaint.cpp +++ b/Engine/RotoPaint.cpp @@ -25,6 +25,7 @@ #include "RotoPaint.h" #include +#include #include #include "Engine/AppInstance.h" diff --git a/Engine/RotoSmear.cpp b/Engine/RotoSmear.cpp index e118f5d678..8b71714950 100644 --- a/Engine/RotoSmear.cpp +++ b/Engine/RotoSmear.cpp @@ -25,6 +25,8 @@ #include "RotoSmear.h" #include // min, max +#include +#include #include "Engine/Node.h" #include "Engine/Image.h" diff --git a/Engine/RotoStrokeItem.cpp b/Engine/RotoStrokeItem.cpp index 9ef136f5e9..62c96ebe05 100644 --- a/Engine/RotoStrokeItem.cpp +++ b/Engine/RotoStrokeItem.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -671,6 +672,9 @@ RotoStrokeItem::clone(const RotoItem* other) const RotoStrokeItem* otherStroke = dynamic_cast(other); assert(otherStroke); + if (!otherStroke) { + throw std::logic_error("RotoStrokeItem::clone"); + } { QMutexLocker k(&itemMutex); _imp->strokes.clear(); @@ -701,6 +705,9 @@ RotoStrokeItem::save(RotoItemSerialization* obj) const RotoDrawableItem::save(obj); RotoStrokeItemSerialization* s = dynamic_cast(obj); assert(s); + if (!s) { + throw std::logic_error("RotoStrokeItem::save"); + } { QMutexLocker k(&itemMutex); s->_brushType = (int)_imp->type; @@ -727,6 +734,9 @@ RotoStrokeItem::load(const RotoItemSerialization & obj) RotoDrawableItem::load(obj); const RotoStrokeItemSerialization* s = dynamic_cast(&obj); assert(s); + if (!s) { + throw std::logic_error("RotoStrokeItem::load"); + } { QMutexLocker k(&itemMutex); _imp->type = (RotoStrokeType)s->_brushType; diff --git a/Engine/RotoWrapper.cpp b/Engine/RotoWrapper.cpp index f5f71c5507..b5f4a297ba 100644 --- a/Engine/RotoWrapper.cpp +++ b/Engine/RotoWrapper.cpp @@ -24,6 +24,9 @@ #include "RotoWrapper.h" +#include +#include + #include "Engine/Bezier.h" #include "Engine/BezierCP.h" #include "Engine/EffectInstance.h" diff --git a/Engine/ScriptObject.cpp b/Engine/ScriptObject.cpp index 9b14c1292f..faed484e68 100644 --- a/Engine/ScriptObject.cpp +++ b/Engine/ScriptObject.cpp @@ -25,6 +25,9 @@ #include "ScriptObject.h" #include +#include +#include + #include NATRON_NAMESPACE_ENTER; diff --git a/Engine/Settings.cpp b/Engine/Settings.cpp index 1d982ba4d1..d4e09f8605 100644 --- a/Engine/Settings.cpp +++ b/Engine/Settings.cpp @@ -24,6 +24,7 @@ #include "Settings.h" +#include #include #include @@ -45,6 +46,7 @@ #include "Engine/KnobFile.h" #include "Engine/KnobTypes.h" #include "Engine/LibraryBinary.h" +#include "Engine/OutputSchedulerThread.h" #include "Engine/Node.h" #include "Engine/Plugin.h" #include "Engine/Project.h" @@ -212,6 +214,7 @@ Settings::initializeKnobsGeneral() _numberOfThreads->setDisplayMinimum(-1); _generalTab->addKnob(_numberOfThreads); +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL _numberOfParallelRenders = AppManager::createKnob(this, "Number of parallel renders (0=\"guess\")"); _numberOfParallelRenders->setHintToolTip("Controls the number of parallel frame that will be rendered at the same time by the renderer." "A value of 0 indicate that " NATRON_APPLICATION_NAME " should automatically determine " @@ -224,6 +227,7 @@ Settings::initializeKnobsGeneral() _numberOfParallelRenders->disableSlider(); _numberOfParallelRenders->setAnimationEnabled(false); _generalTab->addKnob(_numberOfParallelRenders); +#endif _useThreadPool = AppManager::createKnob(this, "Effects use thread-pool"); _useThreadPool->setName("useThreadPool"); @@ -1375,7 +1379,11 @@ Settings::setDefaultValues() _loadProjectsWorkspace->setDefaultValue(false); _useNodeGraphHints->setDefaultValue(true); _numberOfThreads->setDefaultValue(0,0); + +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL _numberOfParallelRenders->setDefaultValue(0,0); +#endif + _useThreadPool->setDefaultValue(true); _nThreadsPerEffect->setDefaultValue(0); _renderInSeparateProcess->setDefaultValue(false,0); @@ -2944,14 +2952,19 @@ Settings::getCheckerboardColor2(double* r,double* g,double* b,double* a) const int Settings::getNumberOfParallelRenders() const { +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL return _numberOfParallelRenders->getValue(); - +#else + return 1; +#endif } void Settings::setNumberOfParallelRenders(int nb) { +#ifndef NATRON_PLAYBACK_USES_THREAD_POOL _numberOfParallelRenders->setValue(nb, 0); +#endif } bool diff --git a/Engine/StandardPaths.cpp b/Engine/StandardPaths.cpp index b070e846da..a2a4e7e59d 100644 --- a/Engine/StandardPaths.cpp +++ b/Engine/StandardPaths.cpp @@ -24,6 +24,9 @@ #include "StandardPaths.h" +#include +#include + #include #include #include diff --git a/Engine/StringAnimationManager.cpp b/Engine/StringAnimationManager.cpp index 670d4e342f..0b6e2f2c86 100644 --- a/Engine/StringAnimationManager.cpp +++ b/Engine/StringAnimationManager.cpp @@ -26,6 +26,10 @@ #include #include +#include +#include + + #include #include "Engine/Knob.h" diff --git a/Engine/TLSHolder.cpp b/Engine/TLSHolder.cpp index 51b82755b0..2da8b5ac76 100644 --- a/Engine/TLSHolder.cpp +++ b/Engine/TLSHolder.cpp @@ -25,6 +25,9 @@ #include "TLSHolder.h" #include "TLSHolderImpl.h" +#include +#include + #include "Engine/OfxClipInstance.h" #include "Engine/OfxHost.h" #include "Engine/OfxParamInstance.h" diff --git a/Engine/TextureRect.cpp b/Engine/TextureRect.cpp index 76d89cb132..21c4da77e1 100644 --- a/Engine/TextureRect.cpp +++ b/Engine/TextureRect.cpp @@ -24,6 +24,9 @@ #include "TextureRect.h" +#include +#include + #include "Engine/RectI.h" NATRON_NAMESPACE_ENTER; diff --git a/Engine/TimeLine.cpp b/Engine/TimeLine.cpp index e5b69e8bdb..59c20b00bf 100644 --- a/Engine/TimeLine.cpp +++ b/Engine/TimeLine.cpp @@ -24,12 +24,14 @@ #include "TimeLine.h" +#include +#include + #ifndef NDEBUG #include #include #endif -#include #include "Engine/Project.h" #include "Engine/AppInstance.h" #include "Engine/Node.h" diff --git a/Engine/Timer.cpp b/Engine/Timer.cpp index 9472e5c77d..48610b4cc9 100644 --- a/Engine/Timer.cpp +++ b/Engine/Timer.cpp @@ -27,6 +27,9 @@ #include #include #include +#include +#include + #include #include "Global/GlobalDefines.h" @@ -213,10 +216,18 @@ Timer::waitUntilNextFrameIsDue () if (t > NATRON_FPS_REFRESH_RATE_SECONDS) { double actualFrameRate = _framesSinceLastFpsFrame / t; - if (actualFrameRate != _actualFrameRate) { - _actualFrameRate = actualFrameRate; - Q_EMIT fpsChanged(_actualFrameRate,getDesiredFrameRate()); + double curActualFrameRate; + { + QMutexLocker l(_mutex); + if (actualFrameRate != _actualFrameRate) { + _actualFrameRate = actualFrameRate; + } + curActualFrameRate = _actualFrameRate; } + + + Q_EMIT fpsChanged(curActualFrameRate,getDesiredFrameRate()); + _framesSinceLastFpsFrame = 0; } @@ -228,6 +239,13 @@ Timer::waitUntilNextFrameIsDue () _framesSinceLastFpsFrame += 1; } // waitUntilNextFrameIsDue +double +Timer::getActualFrameRate() const +{ + QMutexLocker l(_mutex); + return _actualFrameRate; +} + void Timer::setDesiredFrameRate (double fps) { diff --git a/Engine/Timer.h b/Engine/Timer.h index 7b90352373..b64cce1626 100644 --- a/Engine/Timer.h +++ b/Engine/Timer.h @@ -94,6 +94,7 @@ class Timer : public QObject void setDesiredFrameRate (double fps); double getDesiredFrameRate() const; + double getActualFrameRate() const; //------------------- // Current play state @@ -118,7 +119,7 @@ class Timer : public QObject int _framesSinceLastFpsFrame; // actual frame rate, averaged double _actualFrameRate; // over several frames - QMutex* _mutex; //< protects _spf which is the only member that can + QMutex* _mutex; //< protects _spf and _actualFrameRate }; diff --git a/Engine/ViewerInstance.cpp b/Engine/ViewerInstance.cpp index 4b8e62edc3..bb6aebe298 100644 --- a/Engine/ViewerInstance.cpp +++ b/Engine/ViewerInstance.cpp @@ -27,6 +27,7 @@ #include // min, max #include +#include #include GCC_DIAG_UNUSED_LOCAL_TYPEDEFS_OFF diff --git a/Gui/AboutWindow.cpp b/Gui/AboutWindow.cpp index b0f3dcc595..c2b8a786cf 100644 --- a/Gui/AboutWindow.cpp +++ b/Gui/AboutWindow.cpp @@ -24,6 +24,8 @@ #include "AboutWindow.h" +#include + #include "Global/Macros.h" CLANG_DIAG_OFF(deprecated) #include diff --git a/Gui/ActionShortcuts.cpp b/Gui/ActionShortcuts.cpp index a6c1151f6a..8d67475788 100644 --- a/Gui/ActionShortcuts.cpp +++ b/Gui/ActionShortcuts.cpp @@ -23,7 +23,11 @@ // ***** END PYTHON BLOCK ***** #include "ActionShortcuts.h" + +#include + #include + #include "Gui/GuiApplicationManager.h" NATRON_NAMESPACE_ENTER; diff --git a/Gui/AddKnobDialog.cpp b/Gui/AddKnobDialog.cpp index 557a1c1309..b115095217 100644 --- a/Gui/AddKnobDialog.cpp +++ b/Gui/AddKnobDialog.cpp @@ -25,6 +25,7 @@ #include "AddKnobDialog.h" #include // floor +#include #include #include diff --git a/Gui/AnimatedCheckBox.cpp b/Gui/AnimatedCheckBox.cpp index c3ab1ad2b7..d9c2c3171a 100644 --- a/Gui/AnimatedCheckBox.cpp +++ b/Gui/AnimatedCheckBox.cpp @@ -24,6 +24,8 @@ #include "AnimatedCheckBox.h" +#include + #include #include #include diff --git a/Gui/AnimationButton.cpp b/Gui/AnimationButton.cpp index 0345b5296a..4c8e440fc7 100644 --- a/Gui/AnimationButton.cpp +++ b/Gui/AnimationButton.cpp @@ -25,6 +25,7 @@ #include "AnimationButton.h" #include // min, max +#include #include "Global/Macros.h" CLANG_DIAG_OFF(deprecated) diff --git a/Gui/AutoHideToolBar.cpp b/Gui/AutoHideToolBar.cpp index c6ef437749..9861bcd7ff 100644 --- a/Gui/AutoHideToolBar.cpp +++ b/Gui/AutoHideToolBar.cpp @@ -24,6 +24,8 @@ #include "AutoHideToolBar.h" +#include + #include "Gui/Gui.h" NATRON_NAMESPACE_ENTER; diff --git a/Gui/BackdropGui.cpp b/Gui/BackdropGui.cpp index c0f839a0ac..d1f8d37a4c 100644 --- a/Gui/BackdropGui.cpp +++ b/Gui/BackdropGui.cpp @@ -25,6 +25,7 @@ #include "BackdropGui.h" #include // min, max +#include CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) diff --git a/Gui/Button.cpp b/Gui/Button.cpp index aee76ef701..7996fc6ff9 100644 --- a/Gui/Button.cpp +++ b/Gui/Button.cpp @@ -24,7 +24,10 @@ #include "Button.h" +#include + #include + #include "Gui/GuiApplicationManager.h" NATRON_NAMESPACE_ENTER; diff --git a/Gui/ChannelsComboBox.cpp b/Gui/ChannelsComboBox.cpp index e1fa069024..9ffe1b51a7 100644 --- a/Gui/ChannelsComboBox.cpp +++ b/Gui/ChannelsComboBox.cpp @@ -25,6 +25,7 @@ #include "ChannelsComboBox.h" #include +#include #include "Global/Macros.h" diff --git a/Gui/ClickableLabel.cpp b/Gui/ClickableLabel.cpp index 0b4678e903..2cfba922c9 100644 --- a/Gui/ClickableLabel.cpp +++ b/Gui/ClickableLabel.cpp @@ -24,6 +24,8 @@ #include "ClickableLabel.h" +#include + #include #include #include diff --git a/Gui/ComboBox.cpp b/Gui/ComboBox.cpp index 68502e5045..8e27e8d0b3 100644 --- a/Gui/ComboBox.cpp +++ b/Gui/ComboBox.cpp @@ -26,6 +26,7 @@ #include #include // min, max +#include #include #include diff --git a/Gui/CurveGui.cpp b/Gui/CurveGui.cpp index a4fb4d258c..e532dad10a 100644 --- a/Gui/CurveGui.cpp +++ b/Gui/CurveGui.cpp @@ -26,6 +26,7 @@ #include #include // min, max +#include #include #include diff --git a/Gui/CurveWidget.cpp b/Gui/CurveWidget.cpp index 588a37ac0f..03f3c12559 100644 --- a/Gui/CurveWidget.cpp +++ b/Gui/CurveWidget.cpp @@ -25,6 +25,7 @@ #include "CurveWidget.h" #include // floor +#include GCC_DIAG_UNUSED_PRIVATE_FIELD_OFF // /opt/local/include/QtGui/qmime.h:119:10: warning: private field 'type' is not used [-Wunused-private-field] @@ -1604,6 +1605,9 @@ CurveWidget::loopSelectedCurve() } KnobCurveGui* knobCurve = dynamic_cast(curve.get()); assert(knobCurve); + if (!knobCurve) { + throw std::logic_error("CurveWidget::loopSelectedCurve"); + } PyModalDialog dialog(_imp->_gui); boost::shared_ptr firstFrame(dialog.createIntParam("firstFrame", "First frame")); firstFrame->setAnimationEnabled(false); @@ -1643,6 +1647,9 @@ CurveWidget::negateSelectedCurve() } KnobCurveGui* knobCurve = dynamic_cast(curve.get()); assert(knobCurve); + if (!knobCurve) { + throw std::logic_error("CurveWidget::negateSelectedCurve"); + } std::stringstream ss; ss << "-curve(frame, " << knobCurve->getDimension() << ")"; std::string script = ss.str(); @@ -1671,6 +1678,9 @@ CurveWidget::reverseSelectedCurve() } KnobCurveGui* knobCurve = dynamic_cast(curve.get()); assert(knobCurve); + if (!knobCurve) { + throw std::logic_error("CurveWidget::reverseSelectedCurve"); + } std::stringstream ss; ss << "curve(-frame, " << knobCurve->getDimension() << ")"; std::string script = ss.str(); diff --git a/Gui/CurveWidgetDialogs.cpp b/Gui/CurveWidgetDialogs.cpp index 475dc0e8a4..7ccaf704a7 100644 --- a/Gui/CurveWidgetDialogs.cpp +++ b/Gui/CurveWidgetDialogs.cpp @@ -25,6 +25,7 @@ #include "CurveWidgetDialogs.h" #include // std::abs +#include // GCC_DIAG_UNUSED_PRIVATE_FIELD_OFF //// /opt/local/include/QtGui/qmime.h:119:10: warning: private field 'type' is not used [-Wunused-private-field] diff --git a/Gui/CurveWidgetPrivate.cpp b/Gui/CurveWidgetPrivate.cpp index db47fd7b5b..42284e62d2 100644 --- a/Gui/CurveWidgetPrivate.cpp +++ b/Gui/CurveWidgetPrivate.cpp @@ -26,6 +26,7 @@ #include // floor #include // min, max +#include #include #include @@ -1109,6 +1110,9 @@ CurveWidgetPrivate::moveSelectedKeyFrames(const QPointF & oldClick_opengl, } else { BezierCPCurveGui* bezierCurve = dynamic_cast((*it)->curve.get()); assert(bezierCurve); + if (!bezierCurve) { + throw std::logic_error("CurveWidgetPrivate::moveSelectedKeyFrames"); + } std::set keyframes; bezierCurve->getBezier()->getKeyframeTimes(&keyframes); std::set::iterator found = keyframes.find((*it)->key.getTime()); diff --git a/Gui/CustomParamInteract.cpp b/Gui/CustomParamInteract.cpp index a56ff971b7..ec8fb3e600 100644 --- a/Gui/CustomParamInteract.cpp +++ b/Gui/CustomParamInteract.cpp @@ -24,6 +24,8 @@ #include "CustomParamInteract.h" +#include + #include #include #include diff --git a/Gui/DockablePanelPrivate.cpp b/Gui/DockablePanelPrivate.cpp index 3648939e5a..efffc46937 100644 --- a/Gui/DockablePanelPrivate.cpp +++ b/Gui/DockablePanelPrivate.cpp @@ -26,6 +26,7 @@ #include #include +#include #if !defined(Q_MOC_RUN) && !defined(SBK_RUN) #include diff --git a/Gui/DockablePanelTabWidget.cpp b/Gui/DockablePanelTabWidget.cpp index dddafd3792..29ad368eed 100644 --- a/Gui/DockablePanelTabWidget.cpp +++ b/Gui/DockablePanelTabWidget.cpp @@ -24,6 +24,8 @@ #include "DockablePanelTabWidget.h" +#include + #include GCC_DIAG_UNUSED_PRIVATE_FIELD_OFF //// /opt/local/include/QtGui/qmime.h:119:10: warning: private field 'type' is not used [-Wunused-private-field] diff --git a/Gui/DopeSheet.cpp b/Gui/DopeSheet.cpp index 11379a3eca..86c6c8343f 100644 --- a/Gui/DopeSheet.cpp +++ b/Gui/DopeSheet.cpp @@ -25,9 +25,10 @@ #include "DopeSheet.h" #include +#include // Qt includes -#include //REMOVEME +#include #include #include #include diff --git a/Gui/DopeSheetEditor.cpp b/Gui/DopeSheetEditor.cpp index 662cd1a4a7..e15ec75b6f 100644 --- a/Gui/DopeSheetEditor.cpp +++ b/Gui/DopeSheetEditor.cpp @@ -24,6 +24,8 @@ #include "DopeSheetEditor.h" +#include + #include #include #include diff --git a/Gui/DopeSheetEditorUndoRedo.cpp b/Gui/DopeSheetEditorUndoRedo.cpp index 88e138013c..0f12d346dd 100644 --- a/Gui/DopeSheetEditorUndoRedo.cpp +++ b/Gui/DopeSheetEditorUndoRedo.cpp @@ -24,7 +24,9 @@ #include "DopeSheetEditorUndoRedo.h" -#include //REMOVEME +#include + +#include #include "Engine/Knob.h" #include "Engine/Node.h" diff --git a/Gui/DopeSheetHierarchyView.cpp b/Gui/DopeSheetHierarchyView.cpp index cbc469dc78..3d2280ca91 100644 --- a/Gui/DopeSheetHierarchyView.cpp +++ b/Gui/DopeSheetHierarchyView.cpp @@ -24,6 +24,8 @@ #include "DopeSheetHierarchyView.h" +#include + #include //REMOVEME #include #include @@ -951,6 +953,9 @@ void HierarchyView::onKeyframeSelectionChanged(bool recurse) HierarchyViewSelectionModel *mySelecModel = dynamic_cast(selectionModel()); assert(mySelecModel); + if (!mySelecModel) { + throw std::logic_error("HierarchyView::onKeyframeSelectionChanged"); + } // Retrieve the knob contexts with selected keyframes DSKnobPtrList toCheck; diff --git a/Gui/DotGui.cpp b/Gui/DotGui.cpp index bb38750a8d..d5b733538f 100644 --- a/Gui/DotGui.cpp +++ b/Gui/DotGui.cpp @@ -26,6 +26,7 @@ #include #include // min, max +#include CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) diff --git a/Gui/Edge.cpp b/Gui/Edge.cpp index 7f0e1fa231..58f6d52d34 100644 --- a/Gui/Edge.cpp +++ b/Gui/Edge.cpp @@ -26,6 +26,7 @@ #include // min, max #include +#include #include #include diff --git a/Gui/ExportGroupTemplateDialog.cpp b/Gui/ExportGroupTemplateDialog.cpp index 06d77cc934..9124d69ea2 100644 --- a/Gui/ExportGroupTemplateDialog.cpp +++ b/Gui/ExportGroupTemplateDialog.cpp @@ -26,6 +26,8 @@ #include #include // min, max +#include + #include CLANG_DIAG_OFF(deprecated) diff --git a/Gui/FileTypeMainWindow_win.cpp b/Gui/FileTypeMainWindow_win.cpp index 9a8875c454..e7d6af0afe 100644 --- a/Gui/FileTypeMainWindow_win.cpp +++ b/Gui/FileTypeMainWindow_win.cpp @@ -40,6 +40,9 @@ #include "FileTypeMainWindow_win.h" #ifdef __NATRON_WIN32__ + +#include + // —— general includes ————————————————————————— #include #include diff --git a/Gui/FloatingWidget.cpp b/Gui/FloatingWidget.cpp index deb3f74e1e..f4034f317c 100644 --- a/Gui/FloatingWidget.cpp +++ b/Gui/FloatingWidget.cpp @@ -26,6 +26,7 @@ #include #include // min, max +#include #include #include // qApp diff --git a/Gui/GroupBoxLabel.cpp b/Gui/GroupBoxLabel.cpp index 369934eb2f..962de3cdd8 100644 --- a/Gui/GroupBoxLabel.cpp +++ b/Gui/GroupBoxLabel.cpp @@ -26,6 +26,7 @@ #include #include // min, max +#include CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) diff --git a/Gui/Gui.h b/Gui/Gui.h index 03de000937..a25b064ab4 100644 --- a/Gui/Gui.h +++ b/Gui/Gui.h @@ -475,6 +475,8 @@ GCC_DIAG_SUGGEST_OVERRIDE_ON void redrawAllViewers(); void renderAllViewers(bool canAbort); + + void abortAllViewers(); void toggleAutoHideGraphInputs(); diff --git a/Gui/Gui05.cpp b/Gui/Gui05.cpp index 6e0852244e..666ac8e023 100644 --- a/Gui/Gui05.cpp +++ b/Gui/Gui05.cpp @@ -25,6 +25,7 @@ #include "Gui.h" #include +#include #include "Global/Macros.h" diff --git a/Gui/Gui30.cpp b/Gui/Gui30.cpp index 1c425cf474..566f952bdc 100644 --- a/Gui/Gui30.cpp +++ b/Gui/Gui30.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include "Global/Macros.h" diff --git a/Gui/Gui40.cpp b/Gui/Gui40.cpp index 9f9b17cbd4..92c175e377 100644 --- a/Gui/Gui40.cpp +++ b/Gui/Gui40.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include "Global/Macros.h" diff --git a/Gui/Gui50.cpp b/Gui/Gui50.cpp index 19bded8cfe..3a7418ec29 100644 --- a/Gui/Gui50.cpp +++ b/Gui/Gui50.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include "Global/Macros.h" @@ -758,6 +759,17 @@ Gui::renderAllViewers(bool canAbort) } } +void +Gui::abortAllViewers() +{ + assert(QThread::currentThread() == qApp->thread()); + for (std::list::const_iterator it = _imp->_viewerTabs.begin(); it != _imp->_viewerTabs.end(); ++it) { + if ( (*it)->isVisible() ) { + (*it)->getInternalNode()->getNode()->abortAnyProcessing(); + } + } +} + void Gui::toggleAutoHideGraphInputs() { diff --git a/Gui/GuiAppInstance.cpp b/Gui/GuiAppInstance.cpp index 157f58cb13..a00a0ad60c 100644 --- a/Gui/GuiAppInstance.cpp +++ b/Gui/GuiAppInstance.cpp @@ -1096,6 +1096,12 @@ GuiAppInstance::renderAllViewers(bool canAbort) _imp->_gui->renderAllViewers(canAbort); } +void +GuiAppInstance::abortAllViewers() +{ + _imp->_gui->abortAllViewers(); +} + void GuiAppInstance::reloadStylesheet() { diff --git a/Gui/GuiAppInstance.h b/Gui/GuiAppInstance.h index 7289ffded5..68da98845a 100644 --- a/Gui/GuiAppInstance.h +++ b/Gui/GuiAppInstance.h @@ -172,6 +172,7 @@ GCC_DIAG_SUGGEST_OVERRIDE_ON virtual void renderAllViewers(bool canAbort) OVERRIDE FINAL; + virtual void abortAllViewers() OVERRIDE FINAL; virtual void queueRedrawForAllViewers() OVERRIDE FINAL; diff --git a/Gui/GuiApplicationManager.cpp b/Gui/GuiApplicationManager.cpp index c91788a48f..5ed8fe62c5 100644 --- a/Gui/GuiApplicationManager.cpp +++ b/Gui/GuiApplicationManager.cpp @@ -25,7 +25,8 @@ #include "GuiApplicationManager.h" #include "GuiApplicationManagerPrivate.h" -///gui +#include + #include "Global/Macros.h" CLANG_DIAG_OFF(deprecated) @@ -35,12 +36,10 @@ CLANG_DIAG_OFF(uninitialized) #include #include #include +#include CLANG_DIAG_ON(deprecated) CLANG_DIAG_ON(uninitialized) - -#include - #include "Engine/Settings.h" #include "Engine/EffectInstance.h" // PLUGINID_OFX_* diff --git a/Gui/GuiApplicationManagerPrivate.cpp b/Gui/GuiApplicationManagerPrivate.cpp index a871953018..c4b4a5f2d3 100644 --- a/Gui/GuiApplicationManagerPrivate.cpp +++ b/Gui/GuiApplicationManagerPrivate.cpp @@ -24,10 +24,11 @@ #include "GuiApplicationManagerPrivate.h" -#include "Global/Macros.h" +#include #include +#include "Global/Macros.h" CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) diff --git a/Gui/GuiPrivate.cpp b/Gui/GuiPrivate.cpp index 5dcecb8efd..355d5196b6 100644 --- a/Gui/GuiPrivate.cpp +++ b/Gui/GuiPrivate.cpp @@ -27,6 +27,7 @@ #include #include #include // min, max +#include #include #include diff --git a/Gui/Histogram.cpp b/Gui/Histogram.cpp index 4ef27fe9f0..785ef90665 100644 --- a/Gui/Histogram.cpp +++ b/Gui/Histogram.cpp @@ -25,6 +25,7 @@ #include "Histogram.h" #include // min, max +#include #include #include diff --git a/Gui/HostOverlay.cpp b/Gui/HostOverlay.cpp index af97e66614..1657b43761 100644 --- a/Gui/HostOverlay.cpp +++ b/Gui/HostOverlay.cpp @@ -26,6 +26,7 @@ #include #include +#include #include diff --git a/Gui/InfoViewerWidget.cpp b/Gui/InfoViewerWidget.cpp index 81a5bdb6a9..897baa8b13 100644 --- a/Gui/InfoViewerWidget.cpp +++ b/Gui/InfoViewerWidget.cpp @@ -25,7 +25,8 @@ #include "InfoViewerWidget.h" #include -#include +#include + #include #include #include diff --git a/Gui/KnobGui.cpp b/Gui/KnobGui.cpp index 7faf89de52..51bfaf9ed4 100644 --- a/Gui/KnobGui.cpp +++ b/Gui/KnobGui.cpp @@ -23,6 +23,8 @@ // ***** END PYTHON BLOCK ***** #include +#include + #include #include "Engine/KnobTypes.h" diff --git a/Gui/KnobGui10.cpp b/Gui/KnobGui10.cpp index 2dcbd468ce..c377ac2755 100644 --- a/Gui/KnobGui10.cpp +++ b/Gui/KnobGui10.cpp @@ -22,13 +22,14 @@ #include // ***** END PYTHON BLOCK ***** +#include +#include + #include "Engine/Knob.h" #include "Engine/KnobTypes.h" #include "Gui/KnobGui.h" #include "Gui/KnobGuiPrivate.h" -#include - #include "Gui/KnobUndoCommand.h" // SetExpressionCommand... NATRON_NAMESPACE_ENTER; diff --git a/Gui/KnobGui20.cpp b/Gui/KnobGui20.cpp index d0c9da8fd2..781a2b32f8 100644 --- a/Gui/KnobGui20.cpp +++ b/Gui/KnobGui20.cpp @@ -26,6 +26,7 @@ #include "Gui/KnobGuiPrivate.h" #include +#include #include "Gui/KnobUndoCommand.h" // SetExpressionCommand... diff --git a/Gui/KnobGuiBool.cpp b/Gui/KnobGuiBool.cpp index 4a922985b8..b387d82530 100644 --- a/Gui/KnobGuiBool.cpp +++ b/Gui/KnobGuiBool.cpp @@ -26,6 +26,7 @@ #include #include // min, max +#include CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) diff --git a/Gui/KnobGuiButton.cpp b/Gui/KnobGuiButton.cpp index a8ec5e90f2..68067346fd 100644 --- a/Gui/KnobGuiButton.cpp +++ b/Gui/KnobGuiButton.cpp @@ -26,6 +26,7 @@ #include #include // min, max +#include CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) diff --git a/Gui/KnobGuiChoice.cpp b/Gui/KnobGuiChoice.cpp index 954172c8d5..711cd7f6dc 100644 --- a/Gui/KnobGuiChoice.cpp +++ b/Gui/KnobGuiChoice.cpp @@ -26,6 +26,7 @@ #include #include // min, max +#include CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) diff --git a/Gui/KnobGuiDouble.cpp b/Gui/KnobGuiDouble.cpp index 5f1995a3c7..073591b382 100644 --- a/Gui/KnobGuiDouble.cpp +++ b/Gui/KnobGuiDouble.cpp @@ -26,6 +26,7 @@ #include #include // min, max +#include CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) diff --git a/Gui/KnobGuiFactory.cpp b/Gui/KnobGuiFactory.cpp index 2589c15b1c..5fc2828167 100644 --- a/Gui/KnobGuiFactory.cpp +++ b/Gui/KnobGuiFactory.cpp @@ -24,6 +24,8 @@ #include "KnobGuiFactory.h" +#include + #include "Engine/AppManager.h" #include "Engine/LibraryBinary.h" diff --git a/Gui/KnobGuiFile.cpp b/Gui/KnobGuiFile.cpp index 086a62ad9c..aec790e1c0 100644 --- a/Gui/KnobGuiFile.cpp +++ b/Gui/KnobGuiFile.cpp @@ -24,6 +24,8 @@ #include "KnobGuiFile.h" +#include + #include // in QtGui on Qt4, in QtWidgets on Qt5 #include // in QtGui on Qt4, in QtWidgets on Qt5 #include diff --git a/Gui/KnobGuiGroup.cpp b/Gui/KnobGuiGroup.cpp index 94270c3ee8..d3002a80ea 100644 --- a/Gui/KnobGuiGroup.cpp +++ b/Gui/KnobGuiGroup.cpp @@ -26,6 +26,7 @@ #include #include // min, max +#include CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) diff --git a/Gui/KnobGuiInt.cpp b/Gui/KnobGuiInt.cpp index 5a05aa3a21..3593543f10 100644 --- a/Gui/KnobGuiInt.cpp +++ b/Gui/KnobGuiInt.cpp @@ -26,6 +26,7 @@ #include #include // min, max +#include CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) diff --git a/Gui/KnobGuiParametric.cpp b/Gui/KnobGuiParametric.cpp index 4003c70999..bcb66f6716 100644 --- a/Gui/KnobGuiParametric.cpp +++ b/Gui/KnobGuiParametric.cpp @@ -26,6 +26,7 @@ #include #include // min, max +#include CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) diff --git a/Gui/KnobGuiPrivate.cpp b/Gui/KnobGuiPrivate.cpp index 23f5ace327..aedfbfd98f 100644 --- a/Gui/KnobGuiPrivate.cpp +++ b/Gui/KnobGuiPrivate.cpp @@ -24,6 +24,8 @@ #include "Gui/KnobGuiPrivate.h" +#include + NATRON_NAMESPACE_ENTER; diff --git a/Gui/KnobGuiSeparator.cpp b/Gui/KnobGuiSeparator.cpp index f57e0ff2dd..6d1388711a 100644 --- a/Gui/KnobGuiSeparator.cpp +++ b/Gui/KnobGuiSeparator.cpp @@ -26,6 +26,7 @@ #include #include // min, max +#include CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) diff --git a/Gui/KnobGuiString.cpp b/Gui/KnobGuiString.cpp index b381eb7989..f41a1c123c 100644 --- a/Gui/KnobGuiString.cpp +++ b/Gui/KnobGuiString.cpp @@ -26,6 +26,7 @@ #include #include // min, max +#include CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) diff --git a/Gui/KnobUndoCommand.cpp b/Gui/KnobUndoCommand.cpp index 7413fef3bf..9863b5c9a1 100644 --- a/Gui/KnobUndoCommand.cpp +++ b/Gui/KnobUndoCommand.cpp @@ -24,6 +24,8 @@ #include "KnobUndoCommand.h" +#include + #include "Engine/KnobTypes.h" #include "Engine/KnobFile.h" #include "Engine/Node.h" diff --git a/Gui/Label.cpp b/Gui/Label.cpp index 7ce3b0021f..938e2416c5 100644 --- a/Gui/Label.cpp +++ b/Gui/Label.cpp @@ -24,6 +24,8 @@ #include "Label.h" +#include + #include #include diff --git a/Gui/LineEdit.cpp b/Gui/LineEdit.cpp index 8843ab580f..1cbbaa76b9 100644 --- a/Gui/LineEdit.cpp +++ b/Gui/LineEdit.cpp @@ -24,6 +24,8 @@ #include "LineEdit.h" +#include + CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) #include diff --git a/Gui/LogWindow.cpp b/Gui/LogWindow.cpp index 4366570ea9..9712c1e493 100644 --- a/Gui/LogWindow.cpp +++ b/Gui/LogWindow.cpp @@ -25,6 +25,7 @@ #include "LogWindow.h" #include +#include CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) diff --git a/Gui/ManageUserParamsDialog.cpp b/Gui/ManageUserParamsDialog.cpp index 87c8783c37..794309de97 100644 --- a/Gui/ManageUserParamsDialog.cpp +++ b/Gui/ManageUserParamsDialog.cpp @@ -24,6 +24,8 @@ #include "ManageUserParamsDialog.h" +#include + #if !defined(Q_MOC_RUN) && !defined(SBK_RUN) #include #endif @@ -339,10 +341,19 @@ ManageUserParamsDialog::onPickClicked() NodeSettingsPanel* nodePanel = dynamic_cast(_imp->panel); assert(nodePanel); + if (!nodePanel) { + throw std::logic_error("ManageUserParamsDialog::onPickClicked"); + } NodeGuiPtr nodeGui = nodePanel->getNode(); assert(nodeGui); + if (!nodeGui) { + throw std::logic_error("ManageUserParamsDialog::onPickClicked"); + } NodePtr node = nodeGui->getNode(); assert(node); + if (!node) { + throw std::logic_error("ManageUserParamsDialog::onPickClicked"); + } KnobPtr duplicate = selectedKnob->createDuplicateOnNode(node->getEffectInstance().get(), useAlias, page, group, -1); if (duplicate) { diff --git a/Gui/Menu.cpp b/Gui/Menu.cpp index f3ec74c1a8..707c55782e 100644 --- a/Gui/Menu.cpp +++ b/Gui/Menu.cpp @@ -24,6 +24,8 @@ #include "Menu.h" +#include + #include "Global/Macros.h" #include "Gui/GuiApplicationManager.h" CLANG_DIAG_OFF(deprecated) diff --git a/Gui/MessageBox.cpp b/Gui/MessageBox.cpp index c15c25d564..a65e2e7f21 100644 --- a/Gui/MessageBox.cpp +++ b/Gui/MessageBox.cpp @@ -24,6 +24,8 @@ #include "MessageBox.h" +#include + #include "Global/Macros.h" CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) diff --git a/Gui/MultiInstancePanel.cpp b/Gui/MultiInstancePanel.cpp index 05497663e7..ada61f34a2 100644 --- a/Gui/MultiInstancePanel.cpp +++ b/Gui/MultiInstancePanel.cpp @@ -451,8 +451,14 @@ MultiInstancePanel::initializeKnobs() ///find the corresponding knob in the main instance knobs KnobPtr other = _imp->getMainInstance()->getKnobByName( isPage->getName() ); assert(other); - KnobPage* otherPage = dynamic_cast( other.get() ); + if (!other) { + throw std::logic_error("MultiInstancePanel::initializeKnobs"); + } + KnobPage* otherPage = dynamic_cast( other.get() ); assert(otherPage); + if (!otherPage) { + throw std::logic_error("MultiInstancePanel::initializeKnobs"); + } KnobsVec otherChildren = otherPage->getChildren(); bool isNodePage = otherPage->getName() == "Node"; for (U32 j = 0; j < otherChildren.size(); ++j) { diff --git a/Gui/NewLayerDialog.cpp b/Gui/NewLayerDialog.cpp index 6adce01fb7..9360e3597d 100644 --- a/Gui/NewLayerDialog.cpp +++ b/Gui/NewLayerDialog.cpp @@ -26,6 +26,7 @@ #include #include // min, max +#include CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) diff --git a/Gui/NodeBackdrop.cpp b/Gui/NodeBackdrop.cpp index 37f6f27dd6..c06f54ea15 100644 --- a/Gui/NodeBackdrop.cpp +++ b/Gui/NodeBackdrop.cpp @@ -6,6 +6,8 @@ #include "NodeBackDrop.h" +#include + CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) #include diff --git a/Gui/NodeBackdropSerialization.cpp b/Gui/NodeBackdropSerialization.cpp index 3363dc386c..7212131532 100644 --- a/Gui/NodeBackdropSerialization.cpp +++ b/Gui/NodeBackdropSerialization.cpp @@ -24,6 +24,8 @@ #include "NodeBackdropSerialization.h" +#include + NATRON_NAMESPACE_ENTER; NodeBackdropSerialization::NodeBackdropSerialization() diff --git a/Gui/NodeCreationDialog.cpp b/Gui/NodeCreationDialog.cpp index 306af13baa..706b65d7a2 100644 --- a/Gui/NodeCreationDialog.cpp +++ b/Gui/NodeCreationDialog.cpp @@ -24,6 +24,8 @@ #include "NodeCreationDialog.h" +#include + CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) #include diff --git a/Gui/NodeGraph.cpp b/Gui/NodeGraph.cpp index 94a0d6a9d7..ca7a38cc5f 100644 --- a/Gui/NodeGraph.cpp +++ b/Gui/NodeGraph.cpp @@ -31,6 +31,7 @@ #include #include #include // min, max +#include #include "Engine/Backdrop.h" #include "Engine/Dot.h" diff --git a/Gui/NodeGraph05.cpp b/Gui/NodeGraph05.cpp index 46b5beccae..efa6acf1da 100644 --- a/Gui/NodeGraph05.cpp +++ b/Gui/NodeGraph05.cpp @@ -31,6 +31,7 @@ #include #include #include // min, max +#include #include "Engine/Node.h" #include "Engine/Project.h" diff --git a/Gui/NodeGraph13.cpp b/Gui/NodeGraph13.cpp index 78fe00db69..8227c1189e 100644 --- a/Gui/NodeGraph13.cpp +++ b/Gui/NodeGraph13.cpp @@ -28,6 +28,7 @@ #include // ceil #include #include // min, max +#include #include "Engine/Settings.h" diff --git a/Gui/NodeGraph15.cpp b/Gui/NodeGraph15.cpp index 697a51744c..fae18cc66f 100644 --- a/Gui/NodeGraph15.cpp +++ b/Gui/NodeGraph15.cpp @@ -25,6 +25,8 @@ #include "NodeGraph.h" #include "NodeGraphPrivate.h" +#include + GCC_DIAG_UNUSED_PRIVATE_FIELD_OFF CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) @@ -271,7 +273,7 @@ NodeGraph::mouseReleaseEvent(QMouseEvent* e) selectedNodeCenter.y() + selectedNodeBbox.height() / 2.) + NodeGui::DEFAULT_OFFSET_BETWEEN_NODES); - CreateNodeArgs args(PLUGINID_OFX_MERGE, eCreateNodeReasonUserCreate, getGroup()); + CreateNodeArgs args(PLUGINID_OFX_MERGE, eCreateNodeReasonInternal, getGroup()); args.xPosHint = newNodePos.x(); args.yPosHint = newNodePos.y(); diff --git a/Gui/NodeGraph20.cpp b/Gui/NodeGraph20.cpp index 6a6d89fe21..292ec1ad74 100644 --- a/Gui/NodeGraph20.cpp +++ b/Gui/NodeGraph20.cpp @@ -26,6 +26,7 @@ #include "NodeGraphPrivate.h" #include // abs +#include GCC_DIAG_UNUSED_PRIVATE_FIELD_OFF CLANG_DIAG_OFF(deprecated) @@ -486,8 +487,8 @@ NodeGraph::mouseMoveEvent(QMouseEvent* e) case eEventStateDraggingNode: { mustUpdate = true; mustUpdateNavigator = true; - bool controlDown = modCASIsControl(e); - bool shiftdown = modCASIsControlShift(e); + bool controlDown = modifierHasControl(e); + bool shiftdown = modifierHasShift(e); moveSelectedNodesBy(shiftdown, controlDown, lastMousePosScene, newPos, sceneR, true); break; } diff --git a/Gui/NodeGraph25.cpp b/Gui/NodeGraph25.cpp index 4e204cc774..dcb1c4271c 100644 --- a/Gui/NodeGraph25.cpp +++ b/Gui/NodeGraph25.cpp @@ -25,6 +25,8 @@ #include "NodeGraph.h" #include "NodeGraphPrivate.h" +#include + GCC_DIAG_UNUSED_PRIVATE_FIELD_OFF CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) diff --git a/Gui/NodeGraph30.cpp b/Gui/NodeGraph30.cpp index 40153dc42e..7fbb9a4438 100644 --- a/Gui/NodeGraph30.cpp +++ b/Gui/NodeGraph30.cpp @@ -26,6 +26,7 @@ #include "NodeGraphPrivate.h" #include // abs +#include GCC_DIAG_UNUSED_PRIVATE_FIELD_OFF CLANG_DIAG_OFF(deprecated) diff --git a/Gui/NodeGraph35.cpp b/Gui/NodeGraph35.cpp index 4cdac0770b..eb7ec752b5 100644 --- a/Gui/NodeGraph35.cpp +++ b/Gui/NodeGraph35.cpp @@ -26,6 +26,7 @@ #include "NodeGraphPrivate.h" #include +#include GCC_DIAG_UNUSED_PRIVATE_FIELD_OFF CLANG_DIAG_OFF(deprecated) diff --git a/Gui/NodeGraph40.cpp b/Gui/NodeGraph40.cpp index f207e55278..5a5f23e1ff 100644 --- a/Gui/NodeGraph40.cpp +++ b/Gui/NodeGraph40.cpp @@ -26,6 +26,8 @@ #include "NodeGraphPrivate.h" #include +#include + #if !defined(Q_MOC_RUN) && !defined(SBK_RUN) GCC_DIAG_UNUSED_LOCAL_TYPEDEFS_OFF GCC_DIAG_OFF(unused-parameter) diff --git a/Gui/NodeGraph45.cpp b/Gui/NodeGraph45.cpp index eefbfa6432..61a43e4fa4 100644 --- a/Gui/NodeGraph45.cpp +++ b/Gui/NodeGraph45.cpp @@ -27,6 +27,7 @@ #include #include +#include GCC_DIAG_UNUSED_PRIVATE_FIELD_OFF CLANG_DIAG_OFF(deprecated) diff --git a/Gui/NodeGraphPrivate.cpp b/Gui/NodeGraphPrivate.cpp index fd1e2fa6b5..3c764dd857 100644 --- a/Gui/NodeGraphPrivate.cpp +++ b/Gui/NodeGraphPrivate.cpp @@ -22,6 +22,8 @@ #include // ***** END PYTHON BLOCK ***** +#include + #include "NodeGraphPrivate.h" #include "NodeGraph.h" diff --git a/Gui/NodeGraphPrivate10.cpp b/Gui/NodeGraphPrivate10.cpp index a878935fd7..3ad0bc4ddb 100644 --- a/Gui/NodeGraphPrivate10.cpp +++ b/Gui/NodeGraphPrivate10.cpp @@ -22,6 +22,8 @@ #include // ***** END PYTHON BLOCK ***** +#include + #include "NodeGraphPrivate.h" #include "NodeGraph.h" diff --git a/Gui/NodeGraphTextItem.cpp b/Gui/NodeGraphTextItem.cpp index 1630fc4fcb..383f59aeb3 100644 --- a/Gui/NodeGraphTextItem.cpp +++ b/Gui/NodeGraphTextItem.cpp @@ -25,6 +25,7 @@ #include "NodeGraphTextItem.h" #include +#include #include #include diff --git a/Gui/NodeGraphUndoRedo.cpp b/Gui/NodeGraphUndoRedo.cpp index 82a3fed400..c7c55d13bb 100644 --- a/Gui/NodeGraphUndoRedo.cpp +++ b/Gui/NodeGraphUndoRedo.cpp @@ -25,6 +25,7 @@ #include "NodeGraphUndoRedo.h" #include // min, max +#include CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) diff --git a/Gui/NodeGui.cpp b/Gui/NodeGui.cpp index dfaa67d554..08f9cd9149 100644 --- a/Gui/NodeGui.cpp +++ b/Gui/NodeGui.cpp @@ -26,6 +26,8 @@ #include #include // min, max +#include + #include CLANG_DIAG_OFF(deprecated) @@ -192,6 +194,7 @@ NodeGui::NodeGui(QGraphicsItem *parent) , _overlayLocked(false) , _availableViewsIndicator() , _passThroughIndicator() +, identityStateSet(false) { } @@ -3554,9 +3557,13 @@ NodeGui::onIdentityStateChanged(int inputNb) if (inputNb >= 0) { ptInput = node->getInput(inputNb); } - if (ptInput && ptInput == _identityInput.lock()) { + NodePtr prevIdentityInput = _identityInput.lock(); + if (identityStateSet && ((ptInput && ptInput == prevIdentityInput) || + (!ptInput && !prevIdentityInput))) { return; } + + identityStateSet = true; _identityInput = ptInput; diff --git a/Gui/NodeGui.h b/Gui/NodeGui.h index ef9c29b06a..8988602c02 100644 --- a/Gui/NodeGui.h +++ b/Gui/NodeGui.h @@ -664,6 +664,7 @@ public Q_SLOTS: boost::shared_ptr _availableViewsIndicator; boost::shared_ptr _passThroughIndicator; NodeWPtr _identityInput; + bool identityStateSet; }; diff --git a/Gui/NodeGuiSerialization.cpp b/Gui/NodeGuiSerialization.cpp index 688b6d77fc..b0904a8c2d 100644 --- a/Gui/NodeGuiSerialization.cpp +++ b/Gui/NodeGuiSerialization.cpp @@ -24,6 +24,8 @@ #include "NodeGuiSerialization.h" +#include + CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) #include diff --git a/Gui/NodeSettingsPanel.cpp b/Gui/NodeSettingsPanel.cpp index ac80138d43..9cf4880e60 100644 --- a/Gui/NodeSettingsPanel.cpp +++ b/Gui/NodeSettingsPanel.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include diff --git a/Gui/PanelWidget.cpp b/Gui/PanelWidget.cpp index e9cf130c9a..f58d18b698 100644 --- a/Gui/PanelWidget.cpp +++ b/Gui/PanelWidget.cpp @@ -23,7 +23,10 @@ // ***** END PYTHON BLOCK ***** #include "PanelWidget.h" + #include +#include + #include #include diff --git a/Gui/PickKnobDialog.cpp b/Gui/PickKnobDialog.cpp index 2fe9ad36ab..757fba4c32 100644 --- a/Gui/PickKnobDialog.cpp +++ b/Gui/PickKnobDialog.cpp @@ -24,10 +24,11 @@ #include "PickKnobDialog.h" -#include "Global/Macros.h" - +#include #include +#include "Global/Macros.h" + #if !defined(Q_MOC_RUN) && !defined(SBK_RUN) #include #endif diff --git a/Gui/PreferencesPanel.cpp b/Gui/PreferencesPanel.cpp index 6a4f2b7389..1ef7c6f9a6 100644 --- a/Gui/PreferencesPanel.cpp +++ b/Gui/PreferencesPanel.cpp @@ -24,6 +24,8 @@ #include "PreferencesPanel.h" +#include + CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) #include diff --git a/Gui/PreviewThread.cpp b/Gui/PreviewThread.cpp index 5191a92d2c..4c2a599de1 100644 --- a/Gui/PreviewThread.cpp +++ b/Gui/PreviewThread.cpp @@ -21,8 +21,10 @@ // "Since Python may define some pre-processor definitions which affect the standard headers on some systems, you must include Python.h before any standard headers are included." #include // ***** END PYTHON BLOCK ***** + #include #include +#include #include "PreviewThread.h" @@ -164,6 +166,10 @@ PreviewThread::run() if (front.node) { + + ///Mark this thread as running + appPTR->fetchAndAddNRunningThreads(1); + //process the request if valid int w = NATRON_PREVIEW_WIDTH; int h = NATRON_PREVIEW_HEIGHT; @@ -183,6 +189,9 @@ PreviewThread::run() front.node->copyPreviewImageBuffer(_imp->data, w, h); } } + + ///Unmark this thread as running + appPTR->fetchAndAddNRunningThreads(-1); } diff --git a/Gui/ProjectGui.cpp b/Gui/ProjectGui.cpp index e20a3e31d1..9ffeeb4e38 100644 --- a/Gui/ProjectGui.cpp +++ b/Gui/ProjectGui.cpp @@ -505,7 +505,9 @@ ProjectGui::load(boost::archive::xml_iarchive & ar assert(nodeGui_i); NodeGui* nodeGui = dynamic_cast(nodeGui_i.get()); assert(nodeGui); - nodeGui->setVisibleSettingsPanel(true); + if (nodeGui) { + nodeGui->setVisibleSettingsPanel(true); + } } } } diff --git a/Gui/ProjectGuiSerialization.cpp b/Gui/ProjectGuiSerialization.cpp index 8889ed80a1..4ad1efe118 100644 --- a/Gui/ProjectGuiSerialization.cpp +++ b/Gui/ProjectGuiSerialization.cpp @@ -24,6 +24,8 @@ #include "ProjectGuiSerialization.h" +#include + #include "Global/Macros.h" CLANG_DIAG_OFF(deprecated) diff --git a/Gui/PropertiesBinWrapper.cpp b/Gui/PropertiesBinWrapper.cpp index 02134da390..b24955e4c3 100644 --- a/Gui/PropertiesBinWrapper.cpp +++ b/Gui/PropertiesBinWrapper.cpp @@ -24,6 +24,8 @@ #include "PropertiesBinWrapper.h" +#include + #include #include "Gui/Gui.h" diff --git a/Gui/PythonPanels.cpp b/Gui/PythonPanels.cpp index 260090e866..3acc58f891 100644 --- a/Gui/PythonPanels.cpp +++ b/Gui/PythonPanels.cpp @@ -24,6 +24,8 @@ #include "PythonPanels.h" +#include + #include "Global/Macros.h" CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) diff --git a/Gui/QtEnumConvert.cpp b/Gui/QtEnumConvert.cpp index d9c997ff50..e2a2777651 100644 --- a/Gui/QtEnumConvert.cpp +++ b/Gui/QtEnumConvert.cpp @@ -24,6 +24,8 @@ #include "QtEnumConvert.h" +#include + NATRON_NAMESPACE_ENTER; ///what a painful mapping! diff --git a/Gui/RenderStatsDialog.cpp b/Gui/RenderStatsDialog.cpp index 1e477e3e59..8116845c64 100644 --- a/Gui/RenderStatsDialog.cpp +++ b/Gui/RenderStatsDialog.cpp @@ -22,10 +22,11 @@ #include // ***** END PYTHON BLOCK ***** -#include - #include "RenderStatsDialog.h" +#include +#include + #include #include #include diff --git a/Gui/RenderingProgressDialog.cpp b/Gui/RenderingProgressDialog.cpp index a5200bed1f..7523e14408 100644 --- a/Gui/RenderingProgressDialog.cpp +++ b/Gui/RenderingProgressDialog.cpp @@ -25,6 +25,7 @@ #include "RenderingProgressDialog.h" #include +#include CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) diff --git a/Gui/ResizableMessageBox.cpp b/Gui/ResizableMessageBox.cpp index d723a1e4b4..1205db6a57 100644 --- a/Gui/ResizableMessageBox.cpp +++ b/Gui/ResizableMessageBox.cpp @@ -24,6 +24,8 @@ #include "ResizableMessageBox.h" +#include + #include #include diff --git a/Gui/RightClickableWidget.cpp b/Gui/RightClickableWidget.cpp index d69721b462..09d445d236 100644 --- a/Gui/RightClickableWidget.cpp +++ b/Gui/RightClickableWidget.cpp @@ -24,6 +24,8 @@ #include "RightClickableWidget.h" +#include + #include #include GCC_DIAG_UNUSED_PRIVATE_FIELD_OFF diff --git a/Gui/RotoGui.cpp b/Gui/RotoGui.cpp index 25ef165521..fd9081c183 100644 --- a/Gui/RotoGui.cpp +++ b/Gui/RotoGui.cpp @@ -25,6 +25,7 @@ #include "RotoGui.h" #include // min, max +#include #include "Global/GLIncludes.h" diff --git a/Gui/RotoPanel.cpp b/Gui/RotoPanel.cpp index 5c34ccff8d..86130d56dd 100644 --- a/Gui/RotoPanel.cpp +++ b/Gui/RotoPanel.cpp @@ -24,6 +24,8 @@ #include "RotoPanel.h" +#include + CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) #include @@ -1184,9 +1186,11 @@ RotoPanel::onCurrentItemCompOperatorChanged(int index) if (_imp->tree->itemWidget(it->treeItem,COL_OPERATOR) == comboboxSender) { RotoDrawableItem* drawable = dynamic_cast( it->rotoItem.get() ); assert(drawable); - boost::shared_ptr op = drawable->getOperatorKnob(); - KeyFrame k; - op->setValue(index, 0, eValueChangedReasonUserEdited,&k); + if (drawable) { + boost::shared_ptr op = drawable->getOperatorKnob(); + KeyFrame k; + op->setValue(index, 0, eValueChangedReasonUserEdited,&k); + } _imp->context->clearSelection(RotoItem::eSelectionReasonOther); _imp->context->select(it->rotoItem, RotoItem::eSelectionReasonOther); _imp->context->evaluateChange(); diff --git a/Gui/RotoUndoCommand.cpp b/Gui/RotoUndoCommand.cpp index 52c74a5dd7..e7fa6ecaf9 100644 --- a/Gui/RotoUndoCommand.cpp +++ b/Gui/RotoUndoCommand.cpp @@ -24,6 +24,8 @@ #include "RotoUndoCommand.h" +#include + CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) #include diff --git a/Gui/ScaleSliderQWidget.cpp b/Gui/ScaleSliderQWidget.cpp index 7ca0e17982..aa7dc767f9 100644 --- a/Gui/ScaleSliderQWidget.cpp +++ b/Gui/ScaleSliderQWidget.cpp @@ -27,6 +27,8 @@ #include #include // for std::pow() #include +#include + GCC_DIAG_UNUSED_PRIVATE_FIELD_OFF // /opt/local/include/QtGui/qmime.h:119:10: warning: private field 'type' is not used [-Wunused-private-field] #include diff --git a/Gui/ScriptEditor.cpp b/Gui/ScriptEditor.cpp index eda5f0b797..ff4a665988 100644 --- a/Gui/ScriptEditor.cpp +++ b/Gui/ScriptEditor.cpp @@ -24,6 +24,8 @@ #include "ScriptEditor.h" +#include + #include #include #include diff --git a/Gui/ScriptTextEdit.cpp b/Gui/ScriptTextEdit.cpp index 87510071a8..eeacb9eacc 100644 --- a/Gui/ScriptTextEdit.cpp +++ b/Gui/ScriptTextEdit.cpp @@ -22,6 +22,8 @@ #include // ***** END PYTHON BLOCK ***** +#include + #include "ScriptTextEdit.h" #include "Global/Macros.h" CLANG_DIAG_OFF(deprecated) diff --git a/Gui/SequenceFileDialog.cpp b/Gui/SequenceFileDialog.cpp index b3e36f6aa0..83e730f06b 100644 --- a/Gui/SequenceFileDialog.cpp +++ b/Gui/SequenceFileDialog.cpp @@ -33,6 +33,7 @@ #include #include #include +#include CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) diff --git a/Gui/SerializableWindow.cpp b/Gui/SerializableWindow.cpp index db8db622c8..356ce4d0d1 100644 --- a/Gui/SerializableWindow.cpp +++ b/Gui/SerializableWindow.cpp @@ -24,6 +24,8 @@ #include "SerializableWindow.h" +#include + #include NATRON_NAMESPACE_ENTER; diff --git a/Gui/Shaders.cpp b/Gui/Shaders.cpp index 68a2a737fe..1ce641b477 100644 --- a/Gui/Shaders.cpp +++ b/Gui/Shaders.cpp @@ -24,6 +24,8 @@ #include "Global/Macros.h" +#include + NATRON_NAMESPACE_ENTER; const char* fragRGB = diff --git a/Gui/ShortCutEditor.cpp b/Gui/ShortCutEditor.cpp index 28fef09f91..03887d0f22 100644 --- a/Gui/ShortCutEditor.cpp +++ b/Gui/ShortCutEditor.cpp @@ -25,6 +25,7 @@ #include "ShortCutEditor.h" #include +#include #include "Global/Macros.h" CLANG_DIAG_OFF(deprecated) diff --git a/Gui/SpinBox.cpp b/Gui/SpinBox.cpp index eed869b600..c1c42ecd04 100644 --- a/Gui/SpinBox.cpp +++ b/Gui/SpinBox.cpp @@ -27,6 +27,7 @@ #include #include #include // min, max +#include GCC_DIAG_UNUSED_PRIVATE_FIELD_OFF // /opt/local/include/QtGui/qmime.h:119:10: warning: private field 'type' is not used [-Wunused-private-field] diff --git a/Gui/SpinBoxValidator.cpp b/Gui/SpinBoxValidator.cpp index 04a6927137..7fbf1628de 100644 --- a/Gui/SpinBoxValidator.cpp +++ b/Gui/SpinBoxValidator.cpp @@ -25,6 +25,8 @@ #include "SpinBoxValidator.h" +#include + #include "Engine/KnobTypes.h" #include "Gui/KnobUndoCommand.h" #include "Gui/KnobGuiDouble.h" diff --git a/Gui/SplashScreen.cpp b/Gui/SplashScreen.cpp index c20e637fe9..3ba55619d2 100644 --- a/Gui/SplashScreen.cpp +++ b/Gui/SplashScreen.cpp @@ -25,6 +25,7 @@ #include "SplashScreen.h" #include +#include #include "Global/Macros.h" CLANG_DIAG_OFF(deprecated) diff --git a/Gui/Splitter.cpp b/Gui/Splitter.cpp index b7481493cf..bfc46d9fe5 100644 --- a/Gui/Splitter.cpp +++ b/Gui/Splitter.cpp @@ -25,6 +25,7 @@ #include "Splitter.h" #include +#include NATRON_NAMESPACE_ENTER; diff --git a/Gui/TabGroup.cpp b/Gui/TabGroup.cpp index 5612b88fd6..6f7fff9fa4 100644 --- a/Gui/TabGroup.cpp +++ b/Gui/TabGroup.cpp @@ -24,6 +24,8 @@ #include "TabGroup.h" +#include + #include #include #include diff --git a/Gui/TableModelView.cpp b/Gui/TableModelView.cpp index 89ecc6e130..820c5da724 100644 --- a/Gui/TableModelView.cpp +++ b/Gui/TableModelView.cpp @@ -27,6 +27,7 @@ #include #include // min, max #include +#include #include #include diff --git a/Gui/TextRenderer.cpp b/Gui/TextRenderer.cpp index 8115979540..636b213c80 100644 --- a/Gui/TextRenderer.cpp +++ b/Gui/TextRenderer.cpp @@ -24,6 +24,8 @@ #include "TextRenderer.h" +#include + #include #include "Global/Macros.h" diff --git a/Gui/Texture.cpp b/Gui/Texture.cpp index 22fe43e300..2c675a1685 100644 --- a/Gui/Texture.cpp +++ b/Gui/Texture.cpp @@ -24,7 +24,8 @@ #include "Texture.h" -#include +#include + #include "Global/GLIncludes.h" #include "Gui/ViewerGL.h" diff --git a/Gui/TimeLineGui.cpp b/Gui/TimeLineGui.cpp index dcecf63628..5fac895fd7 100644 --- a/Gui/TimeLineGui.cpp +++ b/Gui/TimeLineGui.cpp @@ -26,6 +26,8 @@ #include #include +#include + #include GCC_DIAG_UNUSED_PRIVATE_FIELD_OFF // /opt/local/include/QtGui/qmime.h:119:10: warning: private field 'type' is not used [-Wunused-private-field] diff --git a/Gui/ToolButton.cpp b/Gui/ToolButton.cpp index b74332a971..6dca756874 100644 --- a/Gui/ToolButton.cpp +++ b/Gui/ToolButton.cpp @@ -25,6 +25,8 @@ #include "ToolButton.h" #include +#include + CLANG_DIAG_OFF(deprecated) #include #include diff --git a/Gui/TrackerGui.cpp b/Gui/TrackerGui.cpp index 8b1e4f967d..4d93766b01 100644 --- a/Gui/TrackerGui.cpp +++ b/Gui/TrackerGui.cpp @@ -24,6 +24,8 @@ #include "TrackerGui.h" +#include + CLANG_DIAG_OFF(deprecated) CLANG_DIAG_OFF(uninitialized) #include diff --git a/Gui/Utils.cpp b/Gui/Utils.cpp index 5d5826304d..04ed64d8ab 100644 --- a/Gui/Utils.cpp +++ b/Gui/Utils.cpp @@ -24,6 +24,8 @@ #include "Utils.h" +#include + NATRON_NAMESPACE_ENTER; namespace GuiUtils { diff --git a/Gui/VerticalColorBar.cpp b/Gui/VerticalColorBar.cpp index 18d1adf791..cb59f097df 100644 --- a/Gui/VerticalColorBar.cpp +++ b/Gui/VerticalColorBar.cpp @@ -24,6 +24,8 @@ #include "VerticalColorBar.h" +#include + #include #include diff --git a/Gui/ViewerGL.cpp b/Gui/ViewerGL.cpp index 6d66144811..8f648b7405 100644 --- a/Gui/ViewerGL.cpp +++ b/Gui/ViewerGL.cpp @@ -48,6 +48,7 @@ GCC_DIAG_UNUSED_PRIVATE_FIELD_ON #include "Engine/NodeGuiI.h" #include "Engine/Project.h" #include "Engine/Settings.h" +#include "Engine/Timer.h" // for gettimeofday #include "Engine/ViewerInstance.h" #include "Gui/ActionShortcuts.h" // kShortcutGroupViewer ... diff --git a/Gui/ViewerGLPrivate.cpp b/Gui/ViewerGLPrivate.cpp index 1be18575d8..b3fba78591 100644 --- a/Gui/ViewerGLPrivate.cpp +++ b/Gui/ViewerGLPrivate.cpp @@ -27,6 +27,7 @@ #include #include // min, max #include // sin, cos +#include #include "Global/GLIncludes.h" //! // qApp diff --git a/Gui/ViewerTab.cpp b/Gui/ViewerTab.cpp index 1c189e6722..8c40bba2c9 100644 --- a/Gui/ViewerTab.cpp +++ b/Gui/ViewerTab.cpp @@ -26,6 +26,7 @@ #include "ViewerTabPrivate.h" #include +#include #include #include diff --git a/Gui/ViewerTab20.cpp b/Gui/ViewerTab20.cpp index 2bd46b69ea..4b80f9a99a 100644 --- a/Gui/ViewerTab20.cpp +++ b/Gui/ViewerTab20.cpp @@ -26,6 +26,7 @@ #include "ViewerTabPrivate.h" #include +#include #include "Global/GLIncludes.h" //!(getInternalNode()->getNode().get()); assert(node); + if (!node) { + throw std::logic_error("ViewerTab::connectToInput"); + } bool isAutoWipeEnabled = appPTR->getCurrentSettings()->isAutoWipeEnabled(); if (isAutoWipeEnabled) { getInternalNode()->setActivateInputChangeRequestedFromViewer(true); diff --git a/Gui/ViewerTab40.cpp b/Gui/ViewerTab40.cpp index 99537f67d1..49388eac0b 100644 --- a/Gui/ViewerTab40.cpp +++ b/Gui/ViewerTab40.cpp @@ -26,6 +26,7 @@ #include "ViewerTabPrivate.h" #include +#include #include diff --git a/Gui/ViewerTabPrivate.cpp b/Gui/ViewerTabPrivate.cpp index 50fc5270f0..8865ba3bdc 100644 --- a/Gui/ViewerTabPrivate.cpp +++ b/Gui/ViewerTabPrivate.cpp @@ -25,6 +25,7 @@ #include "ViewerTabPrivate.h" #include +#include #include diff --git a/Gui/ticks.cpp b/Gui/ticks.cpp index 649054d42d..39a606fc5b 100644 --- a/Gui/ticks.cpp +++ b/Gui/ticks.cpp @@ -34,6 +34,7 @@ #include #include #include // min, max +#include // tick_size_10 // diff --git a/libs/OpenFX b/libs/OpenFX index 09582ed60a..9899556b65 160000 --- a/libs/OpenFX +++ b/libs/OpenFX @@ -1 +1 @@ -Subproject commit 09582ed60af616ada6fbb1b5b46a0a39fd7cf619 +Subproject commit 9899556b6540865c457cf6852460f5cd8295ea7c diff --git a/tools/MacOSX/build-plugins.sh b/tools/MacOSX/build-plugins.sh index b9c2d0f4ae..ba1bac587c 100755 --- a/tools/MacOSX/build-plugins.sh +++ b/tools/MacOSX/build-plugins.sh @@ -161,14 +161,18 @@ done # move all libraries to the same place, put symbolic links instead for plugin in "$PLUGINDIR/OFX/Natron"/*.ofx.bundle; do - cd $plugin/Contents/Libraries + cd "$plugin/Contents/Libraries" + # relative path to the Natron.app/Contents/Frameworks dir + frameworks=../../../../../../Frameworks for lib in lib*.dylib; do - if [ -f "../../../../Frameworks/$lib" ]; then - rm "$lib" - else - mv "$lib" "../../../../Frameworks/$lib" + if [ -f "$lib" ]; then + if [ -f "$frameworks/$lib" ]; then + rm "$lib" + else + mv "$lib" "$frameworks/$lib" + fi + ln -sf "$frameworks/$lib" "$lib" fi - ln -sf "../../../../Frameworks/$lib" "$lib" done if [ "$COMPILER" = "gcc" ]; then # use gcc's libraries everywhere for l in gcc_s.1 gomp.1 stdc++.6; do diff --git a/tools/Windows/include/scripts/build-natron.sh b/tools/Windows/include/scripts/build-natron.sh index f530673c33..9c0b3dfb71 100644 --- a/tools/Windows/include/scripts/build-natron.sh +++ b/tools/Windows/include/scripts/build-natron.sh @@ -138,7 +138,7 @@ if [ "$DISABLE_BREAKPAD" = "1" ]; then CONFIG_BREAKPAD_FLAG="CONFIG+=disable-breakpad" fi -$INSTALL_PATH/bin/qmake -r CONFIG+=relwithdebinfo ${CONFIG_BREAKPAD_FLAG} CONFIG+=silent CONFIG+=${BIT}bit DEFINES+=QT_NO_DEBUG_OUTPUT ../Project.pro || exit 1 +$INSTALL_PATH/bin/qmake -r CONFIG+=relwithdebinfo ${EXTRA_QMAKE_FLAG} ${CONFIG_BREAKPAD_FLAG} CONFIG+=silent CONFIG+=${BIT}bit DEFINES+=QT_NO_DEBUG_OUTPUT ../Project.pro || exit 1 make -j${MKJOBS} || exit 1 cp App/release/Natron.exe $INSTALL_PATH/bin/ || exit 1