Clear the resource cache from the worker thread

pull/893/head
scrawl 9 years ago
parent 6f9ca0f68f
commit d855a13b44

@ -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…
Cancel
Save