1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-07 12:54:00 +00:00
OpenMW/apps/openmw/mwworld/cellpreloader.hpp
Bo Svensson a854a6e04a
removes UnrefQueue (#3181)
Currently, we use an `UnrefQueue` which supposedly aims to transfer destruction costs to another thread. The implications of this unusual pattern can not be well understood because some allocators might free resources more efficiently if they are freed by the same thread that allocated them. In addition, `UnrefQueue` complicates the validation of thread safety in our engine. Lastly, our current usage of `UnrefQueue` triggers `ref()`, `unref()` atomic operations as objects are passed into the queue. These operations could be more expensive than the actual destruction.

With this PR we thus remove `UnrefQueue`. We can expect these changes to have a minor impact at most because we free most resources elsewhere in `ResourceSystem::updateCache`.
2021-10-20 23:02:15 +02:00

122 lines
3.6 KiB
C++

#ifndef OPENMW_MWWORLD_CELLPRELOADER_H
#define OPENMW_MWWORLD_CELLPRELOADER_H
#include <map>
#include <osg/ref_ptr>
#include <osg/Vec3f>
#include <osg/Vec4i>
#include <components/sceneutil/workqueue.hpp>
namespace Resource
{
class ResourceSystem;
class BulletShapeManager;
}
namespace Terrain
{
class World;
class View;
}
namespace MWRender
{
class LandManager;
}
namespace Loading
{
class Listener;
}
namespace MWWorld
{
class CellStore;
class TerrainPreloadItem;
class CellPreloader
{
public:
CellPreloader(Resource::ResourceSystem* resourceSystem, Resource::BulletShapeManager* bulletShapeManager, Terrain::World* terrain, MWRender::LandManager* landManager);
~CellPreloader();
/// 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.
void preload(MWWorld::CellStore* cell, double timestamp);
void notifyLoaded(MWWorld::CellStore* cell);
void clear();
/// Removes preloaded cells that have not had a preload request for a while.
void updateCache(double timestamp);
/// How long to keep a preloaded cell in cache after it's no longer requested.
void setExpiryDelay(double expiryDelay);
/// The minimum number of preloaded cells before unused cells get thrown out.
void setMinCacheSize(unsigned int num);
/// The maximum number of preloaded cells.
void setMaxCacheSize(unsigned int num);
/// Enables the creation of instances in the preloading thread.
void setPreloadInstances(bool preload);
unsigned int getMaxCacheSize() const;
void setWorkQueue(osg::ref_ptr<SceneUtil::WorkQueue> workQueue);
typedef std::pair<osg::Vec3f, osg::Vec4i> PositionCellGrid;
void setTerrainPreloadPositions(const std::vector<PositionCellGrid>& positions);
bool syncTerrainLoad(const std::vector<CellPreloader::PositionCellGrid> &positions, double timestamp, Loading::Listener& listener);
void abortTerrainPreloadExcept(const PositionCellGrid *exceptPos);
bool isTerrainLoaded(const CellPreloader::PositionCellGrid &position, double referenceTime) const;
private:
Resource::ResourceSystem* mResourceSystem;
Resource::BulletShapeManager* mBulletShapeManager;
Terrain::World* mTerrain;
MWRender::LandManager* mLandManager;
osg::ref_ptr<SceneUtil::WorkQueue> mWorkQueue;
double mExpiryDelay;
unsigned int mMinCacheSize;
unsigned int mMaxCacheSize;
bool mPreloadInstances;
double mLastResourceCacheUpdate;
struct PreloadEntry
{
PreloadEntry(double timestamp, osg::ref_ptr<SceneUtil::WorkItem> workItem)
: mTimeStamp(timestamp)
, mWorkItem(workItem)
{
}
PreloadEntry()
: mTimeStamp(0.0)
{
}
double mTimeStamp;
osg::ref_ptr<SceneUtil::WorkItem> mWorkItem;
};
typedef std::map<const MWWorld::CellStore*, PreloadEntry> PreloadMap;
// Cells that are currently being preloaded, or have already finished preloading
PreloadMap mPreloadCells;
std::vector<osg::ref_ptr<Terrain::View> > mTerrainViews;
std::vector<PositionCellGrid> mTerrainPreloadPositions;
osg::ref_ptr<TerrainPreloadItem> mTerrainPreloadItem;
osg::ref_ptr<SceneUtil::WorkItem> mUpdateCacheItem;
std::vector<PositionCellGrid> mLoadedTerrainPositions;
double mLoadedTerrainTimestamp;
};
}
#endif