From: <sag...@us...> - 2015-06-07 19:51:58
|
Revision: 5267 http://sourceforge.net/p/modplug/code/5267 Author: saga-games Date: 2015-06-07 19:51:52 +0000 (Sun, 07 Jun 2015) Log Message: ----------- [New] Added hidden settin VST Plugins.EnableAutoSuspend which activates plugin auto-suspension for all plugins (later, this will be configurable per plugin, hopefully). If a plugin didn't emit any sound during the last four seconds and no notes were triggered, its sound output is automatically suspended. [Fix] Plugin Bridge Hopefully fix a great bunch of deadlocked plugins by periodically processing window messages when waiting for the return value of a dispatch call. Modified Paths: -------------- trunk/OpenMPT/mptrack/TrackerSettings.cpp trunk/OpenMPT/mptrack/TrackerSettings.h trunk/OpenMPT/pluginBridge/Bridge.cpp trunk/OpenMPT/pluginBridge/BridgeWrapper.cpp trunk/OpenMPT/soundlib/plugins/PluginManager.cpp Modified: trunk/OpenMPT/mptrack/TrackerSettings.cpp =================================================================== --- trunk/OpenMPT/mptrack/TrackerSettings.cpp 2015-06-07 19:38:01 UTC (rev 5266) +++ trunk/OpenMPT/mptrack/TrackerSettings.cpp 2015-06-07 19:51:52 UTC (rev 5267) @@ -247,6 +247,7 @@ , mruListLength(conf, "Misc", "MRUListLength", 10) // Plugins , bridgeAllPlugins(conf, "VST Plugins", "BridgeAllPlugins", false) + , enableAutoSuspend(conf, "VST Plugins", "EnableAutoSuspend", false) , DebugTraceEnable(conf, "Debug", "TraceEnable", false) , DebugTraceSize(conf, "Debug", "TraceSize", 1000000) , DebugTraceAlwaysDump(conf, "Debug", "TraceAlwaysDump", false) Modified: trunk/OpenMPT/mptrack/TrackerSettings.h =================================================================== --- trunk/OpenMPT/mptrack/TrackerSettings.h 2015-06-07 19:38:01 UTC (rev 5266) +++ trunk/OpenMPT/mptrack/TrackerSettings.h 2015-06-07 19:51:52 UTC (rev 5267) @@ -595,6 +595,7 @@ // Plugins Setting<bool> bridgeAllPlugins; + Setting<bool> enableAutoSuspend; // Debug Modified: trunk/OpenMPT/pluginBridge/Bridge.cpp =================================================================== --- trunk/OpenMPT/pluginBridge/Bridge.cpp 2015-06-07 19:38:01 UTC (rev 5266) +++ trunk/OpenMPT/pluginBridge/Bridge.cpp 2015-06-07 19:51:52 UTC (rev 5267) @@ -10,11 +10,11 @@ // TODO // Translate VstIntPtr size in remaining structs!!! VstFileSelect, VstVariableIo, VstOfflineTask, VstAudioFile, VstWindow (all but VstFileSelect are currently not supported by OpenMPT) -// Fix Purity Demo GUI freeze more nicely // Optimize out audioMasterProcessEvents the same way as effProcessEvents? // Find a nice solution for audioMasterIdle that doesn't break TAL-Elek7ro-II // Maybe don't keep opening and closing aux mem files - but they are rarely needed, so would this actually be worth it? -// Kirnu GUI deadlocks +// Kirnu GUI deadlocks during playback +// jthalamus GUI crash // Low priority: // Speed up things like consecutive calls to CVstPlugin::GetFormattedProgramName by a custom opcode (is this necessary?) @@ -282,7 +282,20 @@ // Wait until the message thread notifies us. Signal &ackHandle = ackSignals[addr->header.signalID]; const HANDLE objects[] = { ackHandle.ack, ackHandle.send, otherProcess }; - result = WaitForMultipleObjects(CountOf(objects), objects, FALSE, INFINITE); + do + { + result = WaitForMultipleObjects(CountOf(objects), objects, FALSE, INFINITE); + if(result == WAIT_TIMEOUT) + { + MSG msg; + while(::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + continue; + } + } while (result == WAIT_TIMEOUT); addr->CopyFromSharedMemory(sendMsg); } @@ -516,22 +529,20 @@ TCHAR str[_MAX_PATH]; GetModuleFileName(library, str, CountOf(str)); + windowParent = reinterpret_cast<HWND>(msg->ptr); ptr = window = CreateWindow( WINDOWCLASSNAME, str, WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT, 1, 1, + windowParent, NULL, - NULL, windowClass.hInstance, NULL); - windowParent = reinterpret_cast<HWND>(msg->ptr); - // ProteusVX and Dexed will freeze somewhere in a SetParent call if we do this before dispatching the message to the plugin. - // On the other hand, opening two shared KORG M1 editor instances makes the second instance crash the bridge if there is no parent. - if(nativeEffect->uniqueID == CCONST('K', 'L', 'M', '1')) - SetParent(window, windowParent); + // Opening two shared KORG M1 editor instances makes the second instance crash the bridge if there is no parent. + SetParent(window, windowParent); } break; @@ -659,11 +670,6 @@ break; case effEditOpen: - // Quick hack to get Purity demo to work (wants to show a message box during first effEditIdle call, this seems to fail after SetParent) - Dispatch(effEditIdle, 0, 0, nullptr, 0.0f); - - // Need to do this after creating. Otherwise, we'll freeze. We also need to do this after the open call, or else ProteusVX will freeze in a SetParent call. - SetParent(window, windowParent); SetProp(window, _T("MPT"), this); ShowWindow(window, SW_SHOW); break; Modified: trunk/OpenMPT/pluginBridge/BridgeWrapper.cpp =================================================================== --- trunk/OpenMPT/pluginBridge/BridgeWrapper.cpp 2015-06-07 19:38:01 UTC (rev 5266) +++ trunk/OpenMPT/pluginBridge/BridgeWrapper.cpp 2015-06-07 19:51:52 UTC (rev 5267) @@ -42,11 +42,11 @@ exeName = theApp.GetAppDirPath(); if(bitness == 32) { - exeName = exeName + MPT_PATHSTRING("PluginBridge32.exe"); + exeName += MPT_PATHSTRING("PluginBridge32.exe"); } if(bitness == 64) { - exeName = exeName + MPT_PATHSTRING("PluginBridge64.exe"); + exeName += MPT_PATHSTRING("PluginBridge64.exe"); } // First, check for validity of the bridge executable. if(!exeName.IsFile()) @@ -268,7 +268,7 @@ throw BridgeException("Could not initialize plugin bridge, it probably crashed."); } else if(initMsg.init.result != 1) { - throw BridgeException(mpt::ToLocale(initMsg.init.str).c_str()); + throw BridgeException(mpt::ToCharset(mpt::CharsetUTF8, initMsg.init.str).c_str()); } else { if(sharedMem->effect.flags & effFlagsCanReplacing) sharedMem->effect.processReplacing = ProcessReplacing; @@ -379,7 +379,19 @@ // Wait until the message thread notifies us. Signal &ackHandle = ackSignals[addr->header.signalID]; const HANDLE objects[] = { ackHandle.ack, ackHandle.send, otherProcess }; - result = WaitForMultipleObjects(CountOf(objects), objects, FALSE, INFINITE); + do + { + result = WaitForMultipleObjects(CountOf(objects), objects, FALSE, 100); + if(result == WAIT_TIMEOUT) + { + MSG msg; + while(::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + } + } while (result == WAIT_TIMEOUT); addr->CopyFromSharedMemory(sendMsg); // Bridge caught an exception while processing this request Modified: trunk/OpenMPT/soundlib/plugins/PluginManager.cpp =================================================================== --- trunk/OpenMPT/soundlib/plugins/PluginManager.cpp 2015-06-07 19:38:01 UTC (rev 5266) +++ trunk/OpenMPT/soundlib/plugins/PluginManager.cpp 2015-06-07 19:51:52 UTC (rev 5267) @@ -222,7 +222,7 @@ // If there was some error, don't try normal loading as well... unless the user really wants it. if(isNative) { - const std::wstring msg = L"The following error occured while trying to load\n" + plugin.dllPath.ToWide() + L"\n\n" + mpt::ToWide(mpt::CharsetLocale, e.what()) + const std::wstring msg = L"The following error occured while trying to load\n" + plugin.dllPath.ToWide() + L"\n\n" + mpt::ToWide(mpt::CharsetUTF8, e.what()) + L"\n\nDo you want to try to load the plugin natively?"; if(Reporting::Confirm(msg, L"OpenMPT Plugin Bridge") == cnfNo) { @@ -482,6 +482,7 @@ //----------------------------------------------------------------------------------- { VSTPluginLib *pFound = nullptr; + mixPlugin.SetAutoSuspend(TrackerSettings::Instance().enableAutoSuspend); // Find plugin in library int8 match = 0; // "Match quality" of found plugin. Higher value = better match. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |