mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 18:19:55 +00:00
Clear the resource cache from the worker thread
This commit is contained in:
parent
6f9ca0f68f
commit
d855a13b44
7 changed files with 49 additions and 14 deletions
|
@ -233,11 +233,15 @@ namespace MWRender
|
|||
|
||||
void RenderingManager::clearCache()
|
||||
{
|
||||
mResourceSystem->updateCache(mViewer->getFrameStamp()->getReferenceTime());
|
||||
if (mTerrain.get())
|
||||
mTerrain->clearCache();
|
||||
}
|
||||
|
||||
double RenderingManager::getReferenceTime() const
|
||||
{
|
||||
return mViewer->getFrameStamp()->getReferenceTime();
|
||||
}
|
||||
|
||||
osg::Group* RenderingManager::getLightRoot()
|
||||
{
|
||||
return mLightRoot.get();
|
||||
|
|
|
@ -67,6 +67,8 @@ namespace MWRender
|
|||
|
||||
void clearCache();
|
||||
|
||||
double getReferenceTime() const;
|
||||
|
||||
osg::Group* getLightRoot();
|
||||
|
||||
void setNightEyeFactor(float factor);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <iostream>
|
||||
|
||||
#include <components/resource/scenemanager.hpp>
|
||||
#include <components/resource/resourcesystem.hpp>
|
||||
#include <components/resource/bulletshapemanager.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
@ -33,6 +34,7 @@ namespace MWWorld
|
|||
std::vector<std::string>& mOut;
|
||||
};
|
||||
|
||||
/// Worker thread item: preload models in a cell.
|
||||
class PreloadItem : public SceneUtil::WorkItem
|
||||
{
|
||||
public:
|
||||
|
@ -92,8 +94,30 @@ namespace MWWorld
|
|||
std::vector<osg::ref_ptr<const Resource::BulletShape> > mPreloadedShapes;
|
||||
};
|
||||
|
||||
CellPreloader::CellPreloader(Resource::SceneManager *sceneManager, Resource::BulletShapeManager* bulletShapeManager)
|
||||
: mSceneManager(sceneManager)
|
||||
/// Worker thread item: update the resource system's cache, effectively deleting unused entries.
|
||||
class UpdateCacheItem : public SceneUtil::WorkItem
|
||||
{
|
||||
public:
|
||||
UpdateCacheItem(Resource::ResourceSystem* resourceSystem, double referenceTime)
|
||||
: mReferenceTime(referenceTime)
|
||||
, mResourceSystem(resourceSystem)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void doWork()
|
||||
{
|
||||
osg::Timer timer;
|
||||
mResourceSystem->updateCache(mReferenceTime);
|
||||
std::cout << "cleared cache in " << timer.time_m() << std::endl;
|
||||
}
|
||||
|
||||
private:
|
||||
double mReferenceTime;
|
||||
Resource::ResourceSystem* mResourceSystem;
|
||||
};
|
||||
|
||||
CellPreloader::CellPreloader(Resource::ResourceSystem* resourceSystem, Resource::BulletShapeManager* bulletShapeManager)
|
||||
: mResourceSystem(resourceSystem)
|
||||
, mBulletShapeManager(bulletShapeManager)
|
||||
{
|
||||
mWorkQueue = new SceneUtil::WorkQueue;
|
||||
|
@ -120,7 +144,7 @@ namespace MWWorld
|
|||
return;
|
||||
}
|
||||
|
||||
osg::ref_ptr<PreloadItem> item (new PreloadItem(cell, mSceneManager, mBulletShapeManager));
|
||||
osg::ref_ptr<PreloadItem> item (new PreloadItem(cell, mResourceSystem->getSceneManager(), mBulletShapeManager));
|
||||
mWorkQueue->addWorkItem(item);
|
||||
|
||||
mPreloadCells[cell] = PreloadEntry(timestamp, item);
|
||||
|
@ -129,6 +153,7 @@ namespace MWWorld
|
|||
void CellPreloader::updateCache(double timestamp)
|
||||
{
|
||||
// time (in seconds) to keep a preloaded cell in cache after it's no longer needed
|
||||
// additionally we could support a minimum/maximum size for the cache
|
||||
const double expiryTime = 60.0;
|
||||
|
||||
for (PreloadMap::iterator it = mPreloadCells.begin(); it != mPreloadCells.end();)
|
||||
|
@ -138,6 +163,9 @@ namespace MWWorld
|
|||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
// the resource cache is cleared from the worker thread so that we're not holding up the main thread with delete operations
|
||||
mWorkQueue->addWorkItem(new UpdateCacheItem(mResourceSystem, timestamp));
|
||||
}
|
||||
|
||||
void CellPreloader::setWorkQueue(osg::ref_ptr<SceneUtil::WorkQueue> workQueue)
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Resource
|
||||
{
|
||||
class SceneManager;
|
||||
class ResourceSystem;
|
||||
class BulletShapeManager;
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ namespace MWWorld
|
|||
class CellPreloader
|
||||
{
|
||||
public:
|
||||
CellPreloader(Resource::SceneManager* sceneManager, Resource::BulletShapeManager* bulletShapeManager);
|
||||
CellPreloader(Resource::ResourceSystem* resourceSystem, Resource::BulletShapeManager* bulletShapeManager);
|
||||
|
||||
/// Ask a background thread to preload rendering meshes and collision shapes for objects in this cell.
|
||||
/// @note The cell itself must be in State_Loaded or State_Preloaded.
|
||||
|
@ -30,7 +30,7 @@ namespace MWWorld
|
|||
void setWorkQueue(osg::ref_ptr<SceneUtil::WorkQueue> workQueue);
|
||||
|
||||
private:
|
||||
Resource::SceneManager* mSceneManager;
|
||||
Resource::ResourceSystem* mResourceSystem;
|
||||
Resource::BulletShapeManager* mBulletShapeManager;
|
||||
osg::ref_ptr<SceneUtil::WorkQueue> mWorkQueue;
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "class.hpp"
|
||||
#include "cellvisitors.hpp"
|
||||
#include "cellstore.hpp"
|
||||
#include "cellpreloader.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -402,6 +403,7 @@ namespace MWWorld
|
|||
|
||||
mCellChanged = true;
|
||||
|
||||
mPreloader->updateCache(mRendering.getReferenceTime());
|
||||
mRendering.clearCache();
|
||||
}
|
||||
|
||||
|
@ -439,6 +441,7 @@ namespace MWWorld
|
|||
Scene::Scene (MWRender::RenderingManager& rendering, MWPhysics::PhysicsSystem *physics)
|
||||
: mCurrentCell (0), mCellChanged (false), mPhysics(physics), mRendering(rendering)
|
||||
{
|
||||
mPreloader.reset(new CellPreloader(rendering.getResourceSystem(), physics->getShapeManager()));
|
||||
}
|
||||
|
||||
Scene::~Scene()
|
||||
|
@ -515,6 +518,7 @@ namespace MWWorld
|
|||
|
||||
MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell);
|
||||
|
||||
mPreloader->updateCache(mRendering.getReferenceTime());
|
||||
mRendering.clearCache();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
#ifndef GAME_MWWORLD_SCENE_H
|
||||
#define GAME_MWWORLD_SCENE_H
|
||||
|
||||
//#include "../mwrender/renderingmanager.hpp"
|
||||
|
||||
#include "ptr.hpp"
|
||||
#include "globals.hpp"
|
||||
|
||||
#include <set>
|
||||
#include <memory>
|
||||
|
||||
namespace osg
|
||||
{
|
||||
|
@ -43,6 +42,7 @@ namespace MWWorld
|
|||
{
|
||||
class Player;
|
||||
class CellStore;
|
||||
class CellPreloader;
|
||||
|
||||
class Scene
|
||||
{
|
||||
|
@ -57,6 +57,7 @@ namespace MWWorld
|
|||
bool mCellChanged;
|
||||
MWPhysics::PhysicsSystem *mPhysics;
|
||||
MWRender::RenderingManager& mRendering;
|
||||
std::auto_ptr<CellPreloader> mPreloader;
|
||||
|
||||
void insertCell (CellStore &cell, bool rescale, Loading::Listener* loadingListener);
|
||||
|
||||
|
|
|
@ -54,13 +54,9 @@ namespace Resource
|
|||
|
||||
void ResourceSystem::updateCache(double referenceTime)
|
||||
{
|
||||
// TODO: call updateCache from the worker thread so the main thread isn't held up by the delete operations
|
||||
// change ObjectCache to not hold lock while the unref happens
|
||||
|
||||
osg::Timer timer;
|
||||
// TODO: change ObjectCache to not hold lock while the unref happens
|
||||
for (std::vector<ResourceManager*>::iterator it = mResourceManagers.begin(); it != mResourceManagers.end(); ++it)
|
||||
(*it)->updateCache(referenceTime);
|
||||
std::cout << "updateCache took " << timer.time_m() << " ms" << std::endl;
|
||||
}
|
||||
|
||||
void ResourceSystem::addResourceManager(ResourceManager *resourceMgr)
|
||||
|
|
Loading…
Reference in a new issue