SL-15961 Convert LLMeshRepository::mSkinMap into unordered_map and reduce number of per-frame lookups to said map.

meow-7.2.2
Runitai Linden 2021-09-14 20:18:58 -05:00
parent fb6cb050e4
commit f844b4e6b9
5 changed files with 65 additions and 57 deletions

View File

@ -184,6 +184,17 @@ struct boost::hash<LLUUID>
}
};
// Adapt boost hash to std hash
namespace std
{
template<> struct hash<LLUUID>
{
std::size_t operator()(LLUUID const& s) const noexcept
{
return boost::hash<LLUUID>()(s);
}
};
}
#endif

View File

@ -1836,7 +1836,7 @@ void LLDrawPoolAvatar::getRiggedGeometry(
void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
LLVOAvatar* avatar,
LLFace* face,
const LLMeshSkinInfo* skin,
const LLVOVolume* vobj,
LLVolume* volume,
LLVolumeFace& vol_face)
{
@ -1848,14 +1848,14 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
return;
}
if (!vobj || vobj->isNoLOD())
{
return;
}
LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer();
LLDrawable* drawable = face->getDrawable();
if (drawable->getVOVolume() && drawable->getVOVolume()->isNoLOD())
{
return;
}
const U32 max_joints = LLSkinningUtil::getMaxJointCount();
#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
@ -1895,23 +1895,26 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
}
#endif
// FIXME ugly const cast
LLSkinningUtil::scrubInvalidJoints(avatar, const_cast<LLMeshSkinInfo*>(skin));
U32 data_mask = face->getRiggedVertexBufferDataMask();
const LLMeshSkinInfo* skin = nullptr;
U32 data_mask = face->getRiggedVertexBufferDataMask();
if (!vol_face.mWeightsScrubbed)
{
LLSkinningUtil::scrubSkinWeights(weights, vol_face.mNumVertices, skin);
vol_face.mWeightsScrubbed = TRUE;
}
if (buffer.isNull() ||
buffer->getTypeMask() != data_mask ||
buffer->getNumVerts() != vol_face.mNumVertices ||
buffer->getNumIndices() != vol_face.mNumIndices ||
(drawable && drawable->isState(LLDrawable::REBUILD_ALL)))
{
LL_PROFILE_ZONE_NAMED("Rigged VBO Rebuild");
skin = vobj->getSkinInfo();
// FIXME ugly const cast
LLSkinningUtil::scrubInvalidJoints(avatar, const_cast<LLMeshSkinInfo*>(skin));
if (!vol_face.mWeightsScrubbed)
{
LLSkinningUtil::scrubSkinWeights(weights, vol_face.mNumVertices, skin);
vol_face.mWeightsScrubbed = TRUE;
}
if (drawable && drawable->isState(LLDrawable::REBUILD_ALL))
{
//rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues
@ -1937,18 +1940,13 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
}
}
if (buffer.isNull() ||
buffer->getNumVerts() != vol_face.mNumVertices ||
buffer->getNumIndices() != vol_face.mNumIndices)
{
// Allocation failed
return;
}
if (!buffer.isNull() &&
sShaderLevel <= 0 &&
face->mLastSkinTime < avatar->getLastSkinTime())
if (sShaderLevel <= 0 &&
face->mLastSkinTime < avatar->getLastSkinTime() &&
!buffer.isNull() &&
buffer->getNumVerts() == vol_face.mNumVertices &&
buffer->getNumIndices() == vol_face.mNumIndices)
{
LL_PROFILE_ZONE_NAMED("Software Skinning");
//perform software vertex skinning for this face
LLStrider<LLVector3> position;
LLStrider<LLVector3> normal;
@ -1965,6 +1963,11 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
LLVector4a* norm = has_normal ? (LLVector4a*) normal.get() : NULL;
if (skin == nullptr)
{
skin = vobj->getSkinInfo();
}
//build matrix palette
LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
U32 count = LLSkinningUtil::getMeshJointCount(skin);
@ -2380,16 +2383,10 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)
continue;
}
const LLMeshSkinInfo* skin = vobj->getSkinInfo();
if (!skin)
{
continue;
}
stop_glerror();
LLVolumeFace& vol_face = volume->getVolumeFace(te);
updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face);
updateRiggedFaceVertexBuffer(avatar, face, vobj, volume, vol_face);
}
}
}

View File

@ -30,6 +30,7 @@
#include "lldrawpool.h"
class LLVOAvatar;
class LLVOVolume;
class LLGLSLShader;
class LLFace;
class LLMeshSkinInfo;
@ -253,7 +254,7 @@ typedef enum
void getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face);
void updateRiggedFaceVertexBuffer(LLVOAvatar* avatar,
LLFace* facep,
const LLMeshSkinInfo* skin,
const LLVOVolume* vobj,
LLVolume* volume,
LLVolumeFace& vol_face);
void updateRiggedVertexBuffers(LLVOAvatar* avatar);

View File

@ -4046,28 +4046,26 @@ S32 LLMeshRepository::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo
const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj)
{
LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH);
if (mesh_id.notNull())
{
skin_map::iterator iter = mSkinMap.find(mesh_id);
if (iter != mSkinMap.end())
{
return &(iter->second);
}
if (mesh_id.notNull())
{
skin_map::iterator iter = mSkinMap.find(mesh_id);
if (iter != mSkinMap.end())
{
return &(iter->second);
}
//no skin info known about given mesh, try to fetch it
{
LLMutexLock lock(mMeshMutex);
//add volume to list of loading meshes
skin_load_map::iterator iter = mLoadingSkins.find(mesh_id);
if (iter == mLoadingSkins.end())
{ //no request pending for this skin info
mPendingSkinRequests.push(mesh_id);
}
mLoadingSkins[mesh_id].insert(requesting_obj->getID());
}
}
//no skin info known about given mesh, try to fetch it
{
LLMutexLock lock(mMeshMutex);
//add volume to list of loading meshes
skin_load_map::iterator iter = mLoadingSkins.find(mesh_id);
if (iter == mLoadingSkins.end())
{ //no request pending for this skin info
mPendingSkinRequests.push(mesh_id);
}
mLoadingSkins[mesh_id].insert(requesting_obj->getID());
}
}
return NULL;
}

View File

@ -27,6 +27,7 @@
#ifndef LL_MESH_REPOSITORY_H
#define LL_MESH_REPOSITORY_H
#include <unordered_map>
#include "llassettype.h"
#include "llmodel.h"
#include "lluuid.h"
@ -613,7 +614,7 @@ public:
typedef std::map<LLVolumeParams, std::set<LLUUID> > mesh_load_map;
mesh_load_map mLoadingMeshes[4];
typedef std::map<LLUUID, LLMeshSkinInfo> skin_map;
typedef std::unordered_map<LLUUID, LLMeshSkinInfo> skin_map;
skin_map mSkinMap;
typedef std::map<LLUUID, LLModel::Decomposition*> decomposition_map;