Kaydet (Commit) 707f787c authored tarafından Michael Meeks's avatar Michael Meeks

lok: enable pre-loading with Vcl's builder

Cache vclbuilder's loaded modules globally & simplify logic.

Pre-populate that cache on preload for LOK vs. a somewhat
inelegant pre-canned list of dialog libraries.

Change-Id: I86d936862a41495fd37908f3ee7eb2e0c363d651
Reviewed-on: https://gerrit.libreoffice.org/49550Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarMichael Meeks <michael.meeks@collabora.com>
üst f8da7757
......@@ -98,6 +98,8 @@
#include <svl/undo.hxx>
#include <unotools/datetime.hxx>
#include <i18nlangtag/languagetag.hxx>
#include <vcl/builder.hxx>
#include <vcl/abstdlg.hxx>
#include <app.hxx>
......@@ -3811,7 +3813,9 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char
// 2) comphelper::setProcessServiceFactory(xSFactory);
// 3) InitVCL()
aService->initialize({css::uno::makeAny<OUString>("preload")});
// Force load some modules
VclBuilder::preload();
VclAbstractDialogFactory::Create();
preloadData();
// Release Solar Mutex, lo_startmain thread should acquire it.
......
......@@ -94,17 +94,13 @@ public:
return m_sHelpRoot;
}
/// Pre-loads all modules containing UI information
static void preload();
private:
VclBuilder(const VclBuilder&) = delete;
VclBuilder& operator=(const VclBuilder&) = delete;
typedef std::map<OUString, std::unique_ptr<osl::Module>> ModuleMap;
//We store these until the builder is deleted, that way we can use the
//ui-previewer on custom widgets and guarantee the modules they are from
//exist for the duration of the dialog
ModuleMap m_aModuleMap;
//If the toplevel window has any properties which need to be set on it,
//but the toplevel is the owner of the builder, then its ctor
//has not been completed during the building, so properties for it
......
......@@ -1099,6 +1099,49 @@ void VclBuilder::cleanupWidgetOwnScrolling(vcl::Window *pScrollParent, vcl::Wind
extern "C" { static void thisModule() {} }
#endif
// We store these forever, closing modules is non-ideal from a performance
// perspective, code pages will be freed up by the OS anyway if unused for
// a while in many cases, and this helps us pre-init.
typedef std::map<OUString, std::unique_ptr<osl::Module>> ModuleMap;
static ModuleMap g_aModuleMap;
static osl::Module g_aMergedLib;
#ifndef SAL_DLLPREFIX
# define SAL_DLLPREFIX ""
#endif
void VclBuilder::preload()
{
#ifndef DISABLE_DYNLOADING
#if ENABLE_MERGELIBS
g_aMergedLibs->loadRelative(&thisModule, SVLIBRARY("merged"));
#endif
// find -name '*ui*' | xargs grep 'class=".*lo-' |
// sed 's/.*class="//' | sed 's/-.*$//' | sort | uniq
static const char *aWidgetLibs[] = {
"sfxlo", "svtlo", "svxcorelo", "foruilo",
"vcllo", "svxlo", "cuilo", "swlo",
"swuilo", "sclo", "sdlo", "chartcontrollerlo",
"smlo", "scuilo", "basctllo", "sduilo",
"scnlo", "xsltdlglo", "pcrlo" // "dbulo"
};
for (auto & lib : aWidgetLibs)
{
OUStringBuffer sModuleBuf;
sModuleBuf.append(SAL_DLLPREFIX);
sModuleBuf.append(OUString::createFromAscii(lib));
sModuleBuf.append(SAL_DLLEXTENSION);
osl::Module* pModule = new osl::Module;
OUString sModule = sModuleBuf.makeStringAndClear();
if (pModule->loadRelative(&thisModule, sModule))
g_aModuleMap.insert(std::make_pair(sModule, std::unique_ptr<osl::Module>(pModule)));
else
delete pModule;
}
#endif // DISABLE_DYNLOADING
}
VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OString &name, const OString &id,
stringmap &rMap)
{
......@@ -1581,40 +1624,32 @@ VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OString &
}
else
{
#ifndef SAL_DLLPREFIX
#define SAL_DLLPREFIX ""
#endif
sal_Int32 nDelim = name.indexOf('-');
if (nDelim != -1)
{
OUString sFunction(OStringToOUString(OString("make") + name.copy(nDelim+1), RTL_TEXTENCODING_UTF8));
#ifndef DISABLE_DYNLOADING
OUStringBuffer sModuleBuf;
sModuleBuf.append(SAL_DLLPREFIX);
sModuleBuf.append(OStringToOUString(name.copy(0, nDelim), RTL_TEXTENCODING_UTF8));
sModuleBuf.append(SAL_DLLEXTENSION);
#endif
OUString sFunction(OStringToOUString(OString("make") + name.copy(nDelim+1), RTL_TEXTENCODING_UTF8));
#ifndef DISABLE_DYNLOADING
OUString sModule = sModuleBuf.makeStringAndClear();
ModuleMap::iterator aI = m_aModuleMap.find(sModule);
if (aI == m_aModuleMap.end())
ModuleMap::iterator aI = g_aModuleMap.find(sModule);
if (aI == g_aModuleMap.end())
{
osl::Module* pModule = new osl::Module;
bool ok = false;
#if ENABLE_MERGELIBS
sModuleBuf.append(SAL_DLLPREFIX);
sModuleBuf.append("mergedlo");
sModuleBuf.append(SAL_DLLEXTENSION);
OUString sMergedModule = sModuleBuf.makeStringAndClear();
bool ok = pModule->loadRelative(&thisModule, sMergedModule);
if (!pModule->getFunctionSymbol(sFunction))
{
ok = pModule->loadRelative(&thisModule, sModule);
}
#else
bool ok = pModule->loadRelative(&thisModule, sModule);
if (!g_aMergedLib.is())
g_aMergedLib->loadRelative(&thisModule, SVLIBRARY("merged"));
ok = g_aMergedLib->getFunctionSymbol(sFunction);
#endif
assert(ok && "bad module name in .ui"); (void)ok;
aI = m_aModuleMap.insert(std::make_pair(sModule, std::unique_ptr<osl::Module>(pModule))).first;
if (!ok)
ok = pModule->loadRelative(&thisModule, sModule);
assert(ok && "bad module name in .ui");
aI = g_aModuleMap.insert(std::make_pair(sModule, std::unique_ptr<osl::Module>(pModule))).first;
}
customMakeWidget pFunction = reinterpret_cast<customMakeWidget>(aI->second->getFunctionSymbol(sFunction));
#else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment