From 0b4226f3e27488d4f6dd3293871ffb4b27eba94a Mon Sep 17 00:00:00 2001 From: bzzt lost a hitlab login Date: Tue, 5 May 2020 13:37:00 +0000 Subject: [PATCH] ico effieciency Signed-off-by: Bret Curtis --- apps/openmw/mwgui/loadingscreen.cpp | 32 ++++++++++++++------ apps/openmw/mwgui/loadingscreen.hpp | 10 ++++--- apps/openmw/mwgui/windowmanagerimp.cpp | 2 +- apps/openmw/mwrender/objectpaging.cpp | 36 +++++++++++++++++------ apps/openmw/mwrender/renderingmanager.cpp | 1 - 5 files changed, 57 insertions(+), 24 deletions(-) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index dcfe723f77..436e9c2bc9 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/statemanager.hpp" @@ -29,9 +30,9 @@ namespace MWGui { - LoadingScreen::LoadingScreen(const VFS::Manager* vfs, osgViewer::Viewer* viewer) + LoadingScreen::LoadingScreen(Resource::ResourceSystem* resourceSystem, osgViewer::Viewer* viewer) : WindowBase("openmw_loading_screen.layout") - , mVFS(vfs) + , mResourceSystem(resourceSystem) , mViewer(viewer) , mTargetFrameRate(120.0) , mLastWallpaperChangeTime(0.0) @@ -64,9 +65,9 @@ namespace MWGui void LoadingScreen::findSplashScreens() { - const std::map& index = mVFS->getIndex(); + const std::map& index = mResourceSystem->getVFS()->getIndex(); std::string pattern = "Splash/"; - mVFS->normalizeFilename(pattern); + mResourceSystem->getVFS()->normalizeFilename(pattern); /* priority given to the left */ const std::array supported_extensions {{".tga", ".dds", ".ktx", ".png", ".bmp", ".jpeg", ".jpg"}}; @@ -171,6 +172,11 @@ namespace MWGui // We are already using node masks to avoid the scene from being updated/rendered, but node masks don't work for computeBound() mViewer->getSceneData()->setComputeBoundingSphereCallback(new DontComputeBoundCallback); + if (const osgUtil::IncrementalCompileOperation* ico = mViewer->getIncrementalCompileOperation()) { + mOldIcoMin = ico->getMinimumTimeAvailableForGLCompileAndDeletePerFrame(); + mOldIcoMax = ico->getMaximumNumOfObjectsToCompilePerFrame(); + } + mVisible = visible; mLoadingBox->setVisible(mVisible); setVisible(true); @@ -215,6 +221,12 @@ namespace MWGui //std::cout << "loading took " << mTimer.time_m() - mLoadingOnTime << std::endl; setVisible(false); + if (osgUtil::IncrementalCompileOperation* ico = mViewer->getIncrementalCompileOperation()) + { + ico->setMinimumTimeAvailableForGLCompileAndDeletePerFrame(mOldIcoMin); + ico->setMaximumNumOfObjectsToCompilePerFrame(mOldIcoMax); + } + MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Loading); MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_LoadingWallpaper); } @@ -336,7 +348,13 @@ namespace MWGui MWBase::Environment::get().getInputManager()->update(0, true, true); - //osg::Timer timer; + mResourceSystem->reportStats(mViewer->getFrameStamp()->getFrameNumber(), mViewer->getViewerStats()); + if (osgUtil::IncrementalCompileOperation* ico = mViewer->getIncrementalCompileOperation()) + { + ico->setMinimumTimeAvailableForGLCompileAndDeletePerFrame(1.f/getTargetFrameRate()); + ico->setMaximumNumOfObjectsToCompilePerFrame(1000); + } + // at the time this function is called we are in the middle of a frame, // so out of order calls are necessary to get a correct frameNumber for the next frame. // refer to the advance() and frame() order in Engine::go() @@ -344,10 +362,6 @@ namespace MWGui mViewer->updateTraversal(); mViewer->renderingTraversals(); mViewer->advance(mViewer->getFrameStamp()->getSimulationTime()); - //std::cout << "frame took " << timer.time_m() << std::endl; - - //if (mViewer->getIncrementalCompileOperation()) - //std::cout << "num to compile " << mViewer->getIncrementalCompileOperation()->getToCompile().size() << std::endl; mLastRenderTime = mTimer.time_m(); } diff --git a/apps/openmw/mwgui/loadingscreen.hpp b/apps/openmw/mwgui/loadingscreen.hpp index c054f3bbd6..1be1b3a0ce 100644 --- a/apps/openmw/mwgui/loadingscreen.hpp +++ b/apps/openmw/mwgui/loadingscreen.hpp @@ -20,9 +20,9 @@ namespace osg class Texture2D; } -namespace VFS +namespace Resource { - class Manager; + class ResourceSystem; } namespace MWGui @@ -32,7 +32,7 @@ namespace MWGui class LoadingScreen : public WindowBase, public Loading::Listener { public: - LoadingScreen(const VFS::Manager* vfs, osgViewer::Viewer* viewer); + LoadingScreen(Resource::ResourceSystem* resourceSystem, osgViewer::Viewer* viewer); virtual ~LoadingScreen(); /// Overridden from Loading::Listener, see the Loading::Listener documentation for usage details @@ -53,7 +53,7 @@ namespace MWGui void setupCopyFramebufferToTextureCallback(); - const VFS::Manager* mVFS; + Resource::ResourceSystem* mResourceSystem; osg::ref_ptr mViewer; double mTargetFrameRate; @@ -70,6 +70,8 @@ namespace MWGui size_t mProgress; bool mShowWallpaper; + float mOldIcoMin = 0.f; + unsigned int mOldIcoMax = 0; MyGUI::Widget* mLoadingBox; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index ab7c3334ce..e1f7a4fbf3 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -230,7 +230,7 @@ namespace MWGui mKeyboardNavigation->setEnabled(keyboardNav); Gui::ImageButton::setDefaultNeedKeyFocus(keyboardNav); - mLoadingScreen = new LoadingScreen(mResourceSystem->getVFS(), mViewer); + mLoadingScreen = new LoadingScreen(mResourceSystem, mViewer); mWindows.push_back(mLoadingScreen); //set up the hardware cursor manager diff --git a/apps/openmw/mwrender/objectpaging.cpp b/apps/openmw/mwrender/objectpaging.cpp index 4121233093..0d547184c1 100644 --- a/apps/openmw/mwrender/objectpaging.cpp +++ b/apps/openmw/mwrender/objectpaging.cpp @@ -353,6 +353,7 @@ namespace MWRender { std::vector mInstances; AnalyzeVisitor::Result mAnalyzeResult; + bool mNeedCompile = false; }; typedef std::map, InstanceList> NodeMap; NodeMap nodes; @@ -398,7 +399,7 @@ namespace MWRender if (useAnim) model = Misc::ResourceHelpers::correctActorModelPath(model, mSceneManager->getVFS()); */ - osg::ref_ptr cnode = mSceneManager->getTemplate(model, compile); + osg::ref_ptr cnode = mSceneManager->getTemplate(model, false); float radius = cnode->getBound().radius() * ref.mScale; if (radius < d*mMinSize) @@ -415,6 +416,7 @@ namespace MWRender { const_cast(cnode.get())->accept(analyzeVisitor); // const-trickery required because there is no const version of NodeVisitor emplaced.first->second.mAnalyzeResult = analyzeVisitor.retrieveResult(); + emplaced.first->second.mNeedCompile = compile && cnode->referenceCount() <= 3; } emplaced.first->second.mInstances.push_back(&ref); } @@ -422,19 +424,29 @@ namespace MWRender osg::ref_ptr group = new osg::Group; osg::ref_ptr mergeGroup = new osg::Group; osg::ref_ptr templateRefs = new TemplateRef; + osgUtil::StateToCompile stateToCompile(0, nullptr); for (const auto& pair : nodes) { const osg::Node* cnode = pair.first; - // add a ref to the original template, to hint to the cache that it's still being used and should be kept in cache - templateRefs->mObjects.push_back(cnode); - const AnalyzeVisitor::Result& analyzeResult = pair.second.mAnalyzeResult; float mergeCost = analyzeResult.mNumVerts * size; float mergeBenefit = analyzeVisitor.getMergeBenefit(analyzeResult) * mMergeFactor; bool merge = mergeBenefit > mergeCost; + // add a ref to the original template, to hint to the cache that it's still being used and should be kept in cache + templateRefs->mObjects.push_back(cnode); + + if (pair.second.mNeedCompile) + { + int mode = osgUtil::GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES; + if (!merge) + mode |= osgUtil::GLObjectsVisitor::COMPILE_DISPLAY_LISTS; + stateToCompile._mode = mode; + const_cast(cnode)->accept(stateToCompile); + } + for (auto cref : pair.second.mInstances) { const ESM::CellRef& ref = *cref; @@ -479,15 +491,21 @@ namespace MWRender group->addChild(mergeGroup); - auto ico = mSceneManager->getIncrementalCompileOperation(); - if (compile && ico) + if (compile) { - auto compileSet = new osgUtil::IncrementalCompileOperation::CompileSet(mergeGroup); - ico->add(compileSet); - compileSet->_subgraphToCompile = group; // for ref counting in SceneManager::updateCache + stateToCompile._mode = osgUtil::GLObjectsVisitor::COMPILE_DISPLAY_LISTS; + mergeGroup->accept(stateToCompile); } } + auto ico = mSceneManager->getIncrementalCompileOperation(); + if (!stateToCompile.empty() && ico) + { + auto compileSet = new osgUtil::IncrementalCompileOperation::CompileSet(group); + compileSet->buildCompileMap(ico->getContextSet(), stateToCompile); + ico->add(compileSet, false); + } + group->getBound(); group->setNodeMask(Mask_Static); group->getOrCreateUserDataContainer()->addUserObject(templateRefs); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 41cfc56a4d..a545e0674b 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -260,7 +260,6 @@ namespace MWRender { mViewer->setIncrementalCompileOperation(new osgUtil::IncrementalCompileOperation); mViewer->getIncrementalCompileOperation()->setTargetFrameRate(Settings::Manager::getFloat("target framerate", "Cells")); - mViewer->getIncrementalCompileOperation()->setMaximumNumOfObjectsToCompilePerFrame(100); } mResourceSystem->getSceneManager()->setIncrementalCompileOperation(mViewer->getIncrementalCompileOperation());