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