Reduce cost of joint lookups by reducing string allocations via use of std::string_view and heterogeneous map lookups (#3970)

master
Ansariel Hiller 2025-04-25 19:52:38 +02:00 committed by GitHub
parent 3e5f4fd0c4
commit 10a324a103
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 66 additions and 68 deletions

View File

@ -138,7 +138,7 @@ public:
LLVector3 mHeadOffset{}; // current head position LLVector3 mHeadOffset{}; // current head position
LLAvatarJoint* mRoot{ nullptr }; LLAvatarJoint* mRoot{ nullptr };
typedef std::map<std::string, LLJoint*> joint_map_t; typedef std::map<std::string, LLJoint*, std::less<>> joint_map_t;
joint_map_t mJointMap; joint_map_t mJointMap;
typedef std::map<std::string, LLVector3> joint_state_map_t; typedef std::map<std::string, LLVector3> joint_state_map_t;
@ -151,7 +151,7 @@ public:
public: public:
typedef std::vector<LLAvatarJoint*> avatar_joint_list_t; typedef std::vector<LLAvatarJoint*> avatar_joint_list_t;
const avatar_joint_list_t& getSkeleton() { return mSkeleton; } const avatar_joint_list_t& getSkeleton() { return mSkeleton; }
typedef std::map<std::string, std::string> joint_alias_map_t; typedef std::map<std::string, std::string, std::less<>> joint_alias_map_t;
const joint_alias_map_t& getJointAliases(); const joint_alias_map_t& getJointAliases();

View File

@ -131,7 +131,7 @@ LLQuaternion::Order bvhStringToOrder( char *str )
// LLBVHLoader() // LLBVHLoader()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string>& joint_alias_map ) LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string, std::less<>>& joint_alias_map )
{ {
reset(); reset();
errorLine = 0; errorLine = 0;

View File

@ -227,7 +227,7 @@ class LLBVHLoader
friend class LLKeyframeMotion; friend class LLKeyframeMotion;
public: public:
// Constructor // Constructor
LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string>& joint_alias_map ); LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string, std::less<>>& joint_alias_map );
~LLBVHLoader(); ~LLBVHLoader();
/* /*

View File

@ -77,12 +77,11 @@ LLCharacter::~LLCharacter()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// getJoint() // getJoint()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
LLJoint *LLCharacter::getJoint( const std::string &name ) LLJoint* LLCharacter::getJoint(std::string_view name)
{ {
LLJoint* joint = NULL; LLJoint* joint = nullptr;
LLJoint *root = getRootJoint(); if (LLJoint* root = getRootJoint())
if (root)
{ {
joint = root->findJoint(name); joint = root->findJoint(name);
} }

View File

@ -76,7 +76,7 @@ public:
// get the specified joint // get the specified joint
// default implementation does recursive search, // default implementation does recursive search,
// subclasses may optimize/cache results. // subclasses may optimize/cache results.
virtual LLJoint *getJoint( const std::string &name ); virtual LLJoint* getJoint(std::string_view name);
// get the position of the character // get the position of the character
virtual LLVector3 getCharacterPosition() = 0; virtual LLVector3 getCharacterPosition() = 0;

View File

@ -242,21 +242,20 @@ LLJoint *LLJoint::getRoot()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// findJoint() // findJoint()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
LLJoint *LLJoint::findJoint( const std::string &name ) LLJoint* LLJoint::findJoint(std::string_view name)
{ {
if (name == getName()) if (name == getName())
return this; return this;
for (LLJoint* joint : mChildren) for (LLJoint* joint : mChildren)
{ {
LLJoint *found = joint->findJoint(name); if (LLJoint* found = joint->findJoint(name))
if (found)
{ {
return found; return found;
} }
} }
return NULL; return nullptr;
} }

View File

@ -222,7 +222,7 @@ public:
LLJoint *getRoot(); LLJoint *getRoot();
// search for child joints by name // search for child joints by name
LLJoint *findJoint( const std::string &name ); LLJoint* findJoint(std::string_view name);
// add/remove children // add/remove children
void addChild( LLJoint *joint ); void addChild( LLJoint *joint );

View File

@ -880,7 +880,7 @@ LLDAELoader::LLDAELoader(
void* opaque_userdata, void* opaque_userdata,
JointTransformMap& jointTransformMap, JointTransformMap& jointTransformMap,
JointNameSet& jointsFromNodes, JointNameSet& jointsFromNodes,
std::map<std::string, std::string>& jointAliasMap, std::map<std::string, std::string, std::less<>>& jointAliasMap,
U32 maxJointsPerMesh, U32 maxJointsPerMesh,
U32 modelLimit, U32 modelLimit,
bool preprocess) bool preprocess)

View File

@ -47,19 +47,19 @@ public:
dae_model_map mModelsMap; dae_model_map mModelsMap;
LLDAELoader( LLDAELoader(
std::string filename, std::string filename,
S32 lod, S32 lod,
LLModelLoader::load_callback_t load_cb, LLModelLoader::load_callback_t load_cb,
LLModelLoader::joint_lookup_func_t joint_lookup_func, LLModelLoader::joint_lookup_func_t joint_lookup_func,
LLModelLoader::texture_load_func_t texture_load_func, LLModelLoader::texture_load_func_t texture_load_func,
LLModelLoader::state_callback_t state_cb, LLModelLoader::state_callback_t state_cb,
void* opaque_userdata, void* opaque_userdata,
JointTransformMap& jointTransformMap, JointTransformMap& jointTransformMap,
JointNameSet& jointsFromNodes, JointNameSet& jointsFromNodes,
std::map<std::string, std::string>& jointAliasMap, std::map<std::string, std::string, std::less<>>& jointAliasMap,
U32 maxJointsPerMesh, U32 maxJointsPerMesh,
U32 modelLimit, U32 modelLimit,
bool preprocess); bool preprocess);
virtual ~LLDAELoader() ; virtual ~LLDAELoader() ;
virtual bool OpenFile(const std::string& filename); virtual bool OpenFile(const std::string& filename);

View File

@ -66,19 +66,19 @@ static const std::string lod_suffix[LLModel::NUM_LODS] =
}; };
LLGLTFLoader::LLGLTFLoader(std::string filename, LLGLTFLoader::LLGLTFLoader(std::string filename,
S32 lod, S32 lod,
LLModelLoader::load_callback_t load_cb, LLModelLoader::load_callback_t load_cb,
LLModelLoader::joint_lookup_func_t joint_lookup_func, LLModelLoader::joint_lookup_func_t joint_lookup_func,
LLModelLoader::texture_load_func_t texture_load_func, LLModelLoader::texture_load_func_t texture_load_func,
LLModelLoader::state_callback_t state_cb, LLModelLoader::state_callback_t state_cb,
void * opaque_userdata, void * opaque_userdata,
JointTransformMap & jointTransformMap, JointTransformMap & jointTransformMap,
JointNameSet & jointsFromNodes, JointNameSet & jointsFromNodes,
std::map<std::string, std::string> &jointAliasMap, std::map<std::string, std::string, std::less<>> & jointAliasMap,
U32 maxJointsPerMesh, U32 maxJointsPerMesh,
U32 modelLimit) //, U32 modelLimit) //,
//bool preprocess) //bool preprocess)
: LLModelLoader( filename, : LLModelLoader( filename,
lod, lod,
load_cb, load_cb,

View File

@ -121,18 +121,18 @@ class LLGLTFLoader : public LLModelLoader
typedef std::map<std::string, LLImportMaterial> material_map; typedef std::map<std::string, LLImportMaterial> material_map;
LLGLTFLoader(std::string filename, LLGLTFLoader(std::string filename,
S32 lod, S32 lod,
LLModelLoader::load_callback_t load_cb, LLModelLoader::load_callback_t load_cb,
LLModelLoader::joint_lookup_func_t joint_lookup_func, LLModelLoader::joint_lookup_func_t joint_lookup_func,
LLModelLoader::texture_load_func_t texture_load_func, LLModelLoader::texture_load_func_t texture_load_func,
LLModelLoader::state_callback_t state_cb, LLModelLoader::state_callback_t state_cb,
void * opaque_userdata, void * opaque_userdata,
JointTransformMap & jointTransformMap, JointTransformMap & jointTransformMap,
JointNameSet & jointsFromNodes, JointNameSet & jointsFromNodes,
std::map<std::string, std::string> &jointAliasMap, std::map<std::string, std::string,std::less<>> &jointAliasMap,
U32 maxJointsPerMesh, U32 maxJointsPerMesh,
U32 modelLimit); //, U32 modelLimit); //,
//bool preprocess ); //bool preprocess );
virtual ~LLGLTFLoader(); virtual ~LLGLTFLoader();
virtual bool OpenFile(const std::string &filename); virtual bool OpenFile(const std::string &filename);

View File

@ -36,7 +36,7 @@ class LLJoint;
typedef std::map<std::string, LLMatrix4> JointTransformMap; typedef std::map<std::string, LLMatrix4> JointTransformMap;
typedef std::map<std::string, LLMatrix4>::iterator JointTransformMapIt; typedef std::map<std::string, LLMatrix4>::iterator JointTransformMapIt;
typedef std::map<std::string, std::string> JointMap; typedef std::map<std::string, std::string, std::less<>> JointMap;
typedef std::deque<std::string> JointNameSet; typedef std::deque<std::string> JointNameSet;
const S32 SLM_SUPPORTED_VERSION = 3; const S32 SLM_SUPPORTED_VERSION = 3;

View File

@ -179,7 +179,7 @@ void LLFloaterBvhPreview::setAnimCallbacks()
getChild<LLUICtrl>("ease_out_time")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateEaseOut, this, _1)); getChild<LLUICtrl>("ease_out_time")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateEaseOut, this, _1));
} }
std::map <std::string, std::string> LLFloaterBvhPreview::getJointAliases() std::map<std::string, std::string, std::less<>> LLFloaterBvhPreview::getJointAliases()
{ {
LLPointer<LLVOAvatar> av = (LLVOAvatar*)mAnimPreview->getDummyAvatar(); LLPointer<LLVOAvatar> av = (LLVOAvatar*)mAnimPreview->getDummyAvatar();
return av->getJointAliases(); return av->getJointAliases();
@ -252,7 +252,7 @@ bool LLFloaterBvhPreview::postBuild()
ELoadStatus load_status = E_ST_OK; ELoadStatus load_status = E_ST_OK;
S32 line_number = 0; S32 line_number = 0;
std::map<std::string, std::string> joint_alias_map = getJointAliases(); auto joint_alias_map = getJointAliases();
loaderp = new LLBVHLoader(file_buffer, load_status, line_number, joint_alias_map); loaderp = new LLBVHLoader(file_buffer, load_status, line_number, joint_alias_map);
std::string status = getString(STATUS[load_status]); std::string status = getString(STATUS[load_status]);

View File

@ -108,7 +108,7 @@ public:
S32 status, LLExtStat ext_status); S32 status, LLExtStat ext_status);
private: private:
void setAnimCallbacks() ; void setAnimCallbacks() ;
std::map <std::string, std::string> getJointAliases(); std::map<std::string, std::string, std::less<>> getJointAliases();
protected: protected:

View File

@ -1488,7 +1488,7 @@ void LLFloaterModelPreview::updateAvatarTab(bool highlight_overrides)
{ {
// Populate table // Populate table
std::map<std::string, std::string> joint_alias_map; std::map<std::string, std::string, std::less<>> joint_alias_map;
mModelPreview->getJointAliases(joint_alias_map); mModelPreview->getJointAliases(joint_alias_map);
S32 conflicts = 0; S32 conflicts = 0;

View File

@ -781,7 +781,7 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable
mLODFile[lod] = filename; mLODFile[lod] = filename;
std::map<std::string, std::string> joint_alias_map; std::map<std::string, std::string, std::less<>> joint_alias_map;
getJointAliases(joint_alias_map); getJointAliases(joint_alias_map);
LLHandle<LLModelPreview> preview_handle = getHandle(); LLHandle<LLModelPreview> preview_handle = getHandle();

View File

@ -6306,13 +6306,13 @@ const LLUUID& LLVOAvatar::getID() const
// getJoint() // getJoint()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// RN: avatar joints are multi-rooted to include screen-based attachments // RN: avatar joints are multi-rooted to include screen-based attachments
LLJoint *LLVOAvatar::getJoint( const std::string &name ) LLJoint* LLVOAvatar::getJoint(std::string_view name)
{ {
joint_map_t::iterator iter = mJointMap.find(name); joint_map_t::iterator iter = mJointMap.find(name);
LLJoint* jointp = NULL; LLJoint* jointp = nullptr;
if (iter == mJointMap.end() || iter->second == NULL) if (iter == mJointMap.end() || iter->second == nullptr)
{ //search for joint and cache found joint in lookup table { //search for joint and cache found joint in lookup table
if (mJointAliasMap.empty()) if (mJointAliasMap.empty())
{ {
@ -6329,7 +6329,7 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )
canonical_name = name; canonical_name = name;
} }
jointp = mRoot->findJoint(canonical_name); jointp = mRoot->findJoint(canonical_name);
mJointMap[name] = jointp; mJointMap[std::string(name)] = jointp;
} }
else else
{ //return cached pointer { //return cached pointer

View File

@ -202,7 +202,7 @@ public:
void startDefaultMotions(); void startDefaultMotions();
void dumpAnimationState(); void dumpAnimationState();
virtual LLJoint* getJoint(const std::string &name); virtual LLJoint* getJoint(std::string_view name);
LLJoint* getJoint(S32 num); LLJoint* getJoint(S32 num);
//if you KNOW joint_num is a valid animated joint index, use getSkeletonJoint for efficiency //if you KNOW joint_num is a valid animated joint index, use getSkeletonJoint for efficiency

View File

@ -695,17 +695,17 @@ void LLVOAvatarSelf::idleUpdate(LLAgent &agent, const F64 &time)
} }
// virtual // virtual
LLJoint *LLVOAvatarSelf::getJoint(const std::string &name) LLJoint* LLVOAvatarSelf::getJoint(std::string_view name)
{ {
std::lock_guard lock(mJointMapMutex); std::lock_guard lock(mJointMapMutex);
LLJoint *jointp = NULL; LLJoint* jointp = nullptr;
jointp = LLVOAvatar::getJoint(name); jointp = LLVOAvatar::getJoint(name);
if (!jointp && mScreenp) if (!jointp && mScreenp)
{ {
jointp = mScreenp->findJoint(name); jointp = mScreenp->findJoint(name);
if (jointp) if (jointp)
{ {
mJointMap[name] = jointp; mJointMap[std::string(name)] = jointp;
} }
} }
if (jointp && jointp != mScreenp && jointp != mRoot) if (jointp && jointp != mScreenp && jointp != mRoot)

View File

@ -90,7 +90,7 @@ public:
/*virtual*/ bool hasMotionFromSource(const LLUUID& source_id); /*virtual*/ bool hasMotionFromSource(const LLUUID& source_id);
/*virtual*/ void stopMotionFromSource(const LLUUID& source_id); /*virtual*/ void stopMotionFromSource(const LLUUID& source_id);
/*virtual*/ void requestStopMotion(LLMotion* motion); /*virtual*/ void requestStopMotion(LLMotion* motion);
/*virtual*/ LLJoint* getJoint(const std::string &name); /*virtual*/ LLJoint* getJoint(std::string_view name);
/*virtual*/ void renderJoints(); /*virtual*/ void renderJoints();