FIRE-141, Joint Motion GC, by Nicky Dasmijn

master
Arrehn 2011-10-02 16:00:25 -04:00
parent d0cdc90af8
commit e0695e88cd
2 changed files with 161 additions and 12 deletions

View File

@ -42,12 +42,15 @@
#include "llvfile.h"
#include "m3math.h"
#include "message.h"
#include "lltimer.h"
//-----------------------------------------------------------------------------
// Static Definitions
//-----------------------------------------------------------------------------
LLVFS* LLKeyframeMotion::sVFS = NULL;
LLKeyframeDataCache::keyframe_data_map_t LLKeyframeDataCache::sKeyframeDataMap;
LLKeyframeDataCache::tGarbage LLKeyframeDataCache::mGarbage;
//-----------------------------------------------------------------------------
// Globals
@ -62,6 +65,9 @@ static F32 MIN_ACCELERATION_SQUARED = 0.0005f * 0.0005f;
static F32 MAX_CONSTRAINTS = 10;
static U32 const MAX_CACHE_TIME_IN_SECONDS = 45*60;
static U32 const SCAN_CACHE_INTERVAL = 31;
//-----------------------------------------------------------------------------
// JointMotionList
//-----------------------------------------------------------------------------
@ -74,7 +80,8 @@ LLKeyframeMotion::JointMotionList::JointMotionList()
mEaseOutDuration(0.f),
mBasePriority(LLJoint::LOW_PRIORITY),
mHandPose(LLHandMotion::HAND_POSE_SPREAD),
mMaxPriority(LLJoint::LOW_PRIORITY)
mMaxPriority(LLJoint::LOW_PRIORITY),
mLocks(0)
{
}
@ -1849,7 +1856,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
}
// *FIX: support cleanup of old keyframe data
LLKeyframeDataCache::addKeyframeData(getID(), mJointMotionList);
LLKeyframeDataCache::addKeyframeData(getID(), mJointMotionList.get());
mAssetStatus = ASSET_LOADED;
setupPose();
@ -2208,7 +2215,7 @@ void LLKeyframeDataCache::dumpDiagInfo()
{
U32 joint_motion_kb;
LLKeyframeMotion::JointMotionList *motion_list_p = map_it->second;
LLKeyframeMotion::JointMotionList *motion_list_p = map_it->second.mList;
llinfos << "Motion: " << map_it->first << llendl;
@ -2230,7 +2237,18 @@ void LLKeyframeDataCache::dumpDiagInfo()
//--------------------------------------------------------------------
void LLKeyframeDataCache::addKeyframeData(const LLUUID& id, LLKeyframeMotion::JointMotionList* joint_motion_listp)
{
sKeyframeDataMap[id] = joint_motion_listp;
keyframe_data_map_t::iterator itr = sKeyframeDataMap.find(id);
if( sKeyframeDataMap.end() != itr )
{
mGarbage.push_back( itr->second.mList );
sKeyframeDataMap.erase(itr);
}
JointMotionListCacheEntry oCacheEntry;
oCacheEntry.mList = joint_motion_listp;
oCacheEntry.mLastAccessed = LLTimer::getTotalSeconds();
sKeyframeDataMap[id] = oCacheEntry;
tryShrinkCache();
}
//--------------------------------------------------------------------
@ -2241,9 +2259,11 @@ void LLKeyframeDataCache::removeKeyframeData(const LLUUID& id)
keyframe_data_map_t::iterator found_data = sKeyframeDataMap.find(id);
if (found_data != sKeyframeDataMap.end())
{
delete found_data->second;
delete found_data->second.mList;
sKeyframeDataMap.erase(found_data);
}
tryShrinkCache();
}
//--------------------------------------------------------------------
@ -2256,7 +2276,11 @@ LLKeyframeMotion::JointMotionList* LLKeyframeDataCache::getKeyframeData(const LL
{
return NULL;
}
return found_data->second;
found_data->second.mLastAccessed = LLTimer::getTotalSeconds();
tryShrinkCache();
return found_data->second.mList;
}
//--------------------------------------------------------------------
@ -2272,10 +2296,61 @@ LLKeyframeDataCache::~LLKeyframeDataCache()
//-----------------------------------------------------------------------------
void LLKeyframeDataCache::clear()
{
for_each(sKeyframeDataMap.begin(), sKeyframeDataMap.end(), DeletePairedPointer());
for( keyframe_data_map_t::iterator itr = sKeyframeDataMap.begin(); sKeyframeDataMap.end() != itr; ++itr )
delete itr->second.mList;
sKeyframeDataMap.clear();
}
void LLKeyframeDataCache::tryShrinkCache()
{
static U64 sLastRun(0);
U64 nNow = LLTimer::getTotalSeconds();
if( (sLastRun - nNow) < SCAN_CACHE_INTERVAL )
return;
tryDeleteGarbage();
int nKilled = 0;
for( keyframe_data_map_t::iterator itr = sKeyframeDataMap.begin(); sKeyframeDataMap.end() != itr; ++itr )
{
JointMotionListCacheEntry &oCacheEntry = itr->second;
if( !oCacheEntry.mList || oCacheEntry.mList->isLocked() )
continue;
if( (nNow - oCacheEntry.mLastAccessed) > MAX_CACHE_TIME_IN_SECONDS )
{
mGarbage.push_back( oCacheEntry.mList );
sKeyframeDataMap.erase( itr );
itr = sKeyframeDataMap.begin();
++nKilled;
}
}
sLastRun = LLTimer::getTotalSeconds();
}
void LLKeyframeDataCache::tryDeleteGarbage()
{
tGarbage dqGarbage;
int nZombies = 0;
for( tGarbage::iterator itr = mGarbage.begin(); mGarbage.end() != itr; ++itr )
{
if( (*itr)->isLocked() )
{
dqGarbage.push_back( *itr );
++nZombies;
}
else
delete *itr;
}
mGarbage = dqGarbage;
}
//-----------------------------------------------------------------------------
// JointConstraint()
//-----------------------------------------------------------------------------

View File

@ -152,7 +152,13 @@ public:
U32 getFileSize();
BOOL serialize(LLDataPacker& dp) const;
BOOL deserialize(LLDataPacker& dp);
BOOL isLoaded() { return mJointMotionList != NULL; }
BOOL isLoaded()
{
if (mJointMotionList)
return true;
else
return false;
}
// setters for modifying a keyframe animation
@ -413,6 +419,18 @@ public:
U32 dumpDiagInfo();
JointMotion* getJointMotion(U32 index) const { llassert(index < mJointMotionArray.size()); return mJointMotionArray[index]; }
U32 getNumJointMotions() const { return mJointMotionArray.size(); }
void lock()
{ ++mLocks; }
void unlock()
{ --mLocks; }
bool isLocked() const
{ return mLocks > 0; }
private:
long mLocks;
};
@ -422,7 +440,51 @@ protected:
//-------------------------------------------------------------------------
// Member Data
//-------------------------------------------------------------------------
JointMotionList* mJointMotionList;
class JointMotionListHolder
{
JointMotionList* mJointMotionList;
JointMotionListHolder( JointMotionListHolder const & );
JointMotionListHolder& operator=(JointMotionListHolder const& );
public:
JointMotionListHolder( JointMotionList *aIn )
: mJointMotionList( aIn )
{
if( mJointMotionList )
mJointMotionList->lock();
}
~JointMotionListHolder()
{
if( mJointMotionList )
mJointMotionList->unlock();
}
operator bool() const
{ return 0 != mJointMotionList; }
JointMotionList* get()
{ return mJointMotionList; }
JointMotionList* operator->()
{ return mJointMotionList; }
JointMotionList const* operator->() const
{ return mJointMotionList; }
void operator=( JointMotionList * aIn )
{
if( mJointMotionList )
mJointMotionList->unlock();
mJointMotionList = aIn;
if( mJointMotionList )
mJointMotionList->lock();
}
};
JointMotionListHolder mJointMotionList;
std::vector<LLPointer<LLJointState> > mJointStates;
LLJoint* mPelvisp;
LLCharacter* mCharacter;
@ -436,14 +498,26 @@ protected:
class LLKeyframeDataCache
{
struct JointMotionListCacheEntry
{
U64 mLastAccessed;
LLKeyframeMotion::JointMotionList *mList;
};
typedef std::map<LLUUID, JointMotionListCacheEntry> keyframe_data_map_t;
static keyframe_data_map_t sKeyframeDataMap;
typedef std::deque< LLKeyframeMotion::JointMotionList* > tGarbage;
static tGarbage mGarbage;
static void tryShrinkCache();
static void tryDeleteGarbage();
public:
// *FIX: implement this as an actual singleton member of LLKeyframeMotion
LLKeyframeDataCache(){};
~LLKeyframeDataCache();
typedef std::map<LLUUID, class LLKeyframeMotion::JointMotionList*> keyframe_data_map_t;
static keyframe_data_map_t sKeyframeDataMap;
static void addKeyframeData(const LLUUID& id, LLKeyframeMotion::JointMotionList*);
static LLKeyframeMotion::JointMotionList* getKeyframeData(const LLUUID& id);