diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llcommon/llmutex.h | 5 | ||||
| -rw-r--r-- | indra/llmath/llvolume.cpp | 5 | ||||
| -rw-r--r-- | indra/llprimitive/llgltfmaterial.h | 1 | ||||
| -rw-r--r-- | indra/newview/llgltfmateriallist.cpp | 118 | ||||
| -rw-r--r-- | indra/newview/llmeshrepository.cpp | 141 | ||||
| -rw-r--r-- | indra/newview/llmeshrepository.h | 71 | ||||
| -rw-r--r-- | indra/newview/llselectmgr.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llspatialpartition.cpp | 115 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.cpp | 9 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.h | 2 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.cpp | 282 | ||||
| -rw-r--r-- | indra/newview/llvovolume.cpp | 275 | ||||
| -rw-r--r-- | indra/newview/llvovolume.h | 26 | ||||
| -rw-r--r-- | indra/newview/pipeline.h | 1 | 
14 files changed, 505 insertions, 550 deletions
| diff --git a/indra/llcommon/llmutex.h b/indra/llcommon/llmutex.h index 838d7d34c0..0d70da6178 100644 --- a/indra/llcommon/llmutex.h +++ b/indra/llcommon/llmutex.h @@ -36,7 +36,8 @@  //============================================================================ -#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO) +//#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO) +#define MUTEX_DEBUG 0 //disable mutex debugging as it's interfering with profiles  #if MUTEX_DEBUG  #include <map> @@ -61,7 +62,7 @@ protected:  	mutable LLThread::id_t	mLockingThread;  #if MUTEX_DEBUG -	std::map<LLThread::id_t, BOOL> mIsLocked; +	std::unordered_map<LLThread::id_t, BOOL> mIsLocked;  #endif  }; diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 2a906c8d41..b6cdcb2736 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -3351,12 +3351,12 @@ BOOL LLVolume::isFlat(S32 face)  bool LLVolumeParams::isSculpt() const  { -	return mSculptID.notNull(); +    return (mSculptType & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_NONE;  }  bool LLVolumeParams::isMeshSculpt() const  { -	return isSculpt() && ((mSculptType & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH); +	return (mSculptType & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH;  }  bool LLVolumeParams::operator==(const LLVolumeParams ¶ms) const @@ -3771,6 +3771,7 @@ bool LLVolumeParams::validate(U8 prof_curve, F32 prof_begin, F32 prof_end, F32 h  void LLVolume::getLoDTriangleCounts(const LLVolumeParams& params, S32* counts)  { //attempt to approximate the number of triangles that will result from generating a volume LoD set for the   	//supplied LLVolumeParams -- inaccurate, but a close enough approximation for determining streaming cost +    LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;  	F32 detail[] = {1.f, 1.5f, 2.5f, 4.f};	  	for (S32 i = 0; i < 4; i++)  	{ diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 0bd65fadef..ad7784f6d1 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -167,6 +167,7 @@ public:      // set the contents of this LLGLTFMaterial from the given json      // returns true if successful +    // if unsuccessful, the contents of this LLGLTFMaterial should be left unchanged and false is returned      // json - the json text to load from      // warn_msg - warning message from TinyGLTF if any      // error_msg - error_msg from TinyGLTF if any diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 151d7fa969..ed16a1cf7a 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -219,40 +219,36 @@ public:          struct ReturnData          {          public: -            LLPointer<LLGLTFMaterial> mMaterial; +            LLGLTFMaterial mMaterial;              S32 mSide;              bool mSuccess;          }; -        // fromJson() is performance heavy offload to a thread. -        main_queue->postTo( -            general_queue, -            [object_override]() // Work done on general queue +        if (!object_override.mSides.empty())          { -            std::vector<ReturnData> results; - -            if (!object_override.mSides.empty()) +            // fromJson() is performance heavy offload to a thread. +            main_queue->postTo( +                general_queue, +                [sides=object_override.mSides]() // Work done on general queue              { -                results.reserve(object_override.mSides.size()); +                std::vector<ReturnData> results; + +                results.reserve(sides.size());                  // parse json -                std::unordered_map<S32, std::string>::const_iterator iter = object_override.mSides.begin(); -                std::unordered_map<S32, std::string>::const_iterator end = object_override.mSides.end(); +                std::unordered_map<S32, std::string>::const_iterator iter = sides.begin(); +                std::unordered_map<S32, std::string>::const_iterator end = sides.end();                  while (iter != end)                  { -                    LLPointer<LLGLTFMaterial> override_data = new LLGLTFMaterial();                      std::string warn_msg, error_msg; -                    bool success = override_data->fromJSON(iter->second, warn_msg, error_msg); -                      ReturnData result; + +                    bool success = result.mMaterial.fromJSON(iter->second, warn_msg, error_msg); +                      result.mSuccess = success;                      result.mSide = iter->first; -                    if (success) -                    { -                        result.mMaterial = override_data; -                    } -                    else +                    if (!success)                      {                          LL_WARNS("GLTF") << "failed to parse GLTF override data.  errors: " << error_msg << " | warnings: " << warn_msg << LL_ENDL;                      } @@ -260,64 +256,68 @@ public:                      results.push_back(result);                      iter++;                  } -            } -            return results; -        }, -            [object_override, this](std::vector<ReturnData> results) // Callback to main thread +                return results; +            }, +            [object_id=object_override.mObjectId, this](std::vector<ReturnData> results) // Callback to main thread              { -            LLViewerObject * obj = gObjectList.findObject(object_override.mObjectId); +                LLViewerObject * obj = gObjectList.findObject(object_id); -            if (results.size() > 0 ) -            { -                std::unordered_set<S32> side_set; - -                for (int i = 0; i < results.size(); ++i) +                if (results.size() > 0 )                  { -                    if (results[i].mSuccess) +                    std::unordered_set<S32> side_set; + +                    for (auto const & result : results)                      { -                        // flag this side to not be nulled out later -                        side_set.insert(results[i].mSide); +                        S32 side = result.mSide; +                        if (result.mSuccess) +                        { +                            // copy to heap here because LLTextureEntry is going to take ownership with an LLPointer +                            LLGLTFMaterial * material = new LLGLTFMaterial(result.mMaterial); + +                            // flag this side to not be nulled out later +                            side_set.insert(side); -                        if (obj) +                            if (obj) +                            { +                                obj->setTEGLTFMaterialOverride(side, material); +                            } +                        } + +                        // unblock material editor +                        if (obj && obj->getTE(side) && obj->getTE(side)->isSelected())                          { -                            obj->setTEGLTFMaterialOverride(results[i].mSide, results[i].mMaterial); +                            doSelectionCallbacks(object_id, side);                          }                      } -                     -                    // unblock material editor -                    if (obj && obj->getTE(results[i].mSide) && obj->getTE(results[i].mSide)->isSelected()) -                    { -                        doSelectionCallbacks(object_override.mObjectId, results[i].mSide); -                    } -                } -                if (obj && side_set.size() != obj->getNumTEs()) -                { // object exists and at least one texture entry needs to have its override data nulled out -                    for (int i = 0; i < obj->getNumTEs(); ++i) -                    { -                        if (side_set.find(i) == side_set.end()) +                    if (obj && side_set.size() != obj->getNumTEs()) +                    { // object exists and at least one texture entry needs to have its override data nulled out +                        for (int i = 0; i < obj->getNumTEs(); ++i)                          { -                            obj->setTEGLTFMaterialOverride(i, nullptr); -                            if (obj->getTE(i) && obj->getTE(i)->isSelected()) +                            if (side_set.find(i) == side_set.end())                              { -                                doSelectionCallbacks(object_override.mObjectId, i); +                                obj->setTEGLTFMaterialOverride(i, nullptr); +                                if (obj->getTE(i) && obj->getTE(i)->isSelected()) +                                { +                                    doSelectionCallbacks(object_id, i); +                                }                              }                          }                      }                  } -            } -            else if (obj) -            { // override list was empty or an error occurred, null out all overrides for this object -                for (int i = 0; i < obj->getNumTEs(); ++i) -                { -                    obj->setTEGLTFMaterialOverride(i, nullptr); -                    if (obj->getTE(i) && obj->getTE(i)->isSelected()) +                else if (obj) +                { // override list was empty or an error occurred, null out all overrides for this object +                    for (int i = 0; i < obj->getNumTEs(); ++i)                      { -                        doSelectionCallbacks(obj->getID(), i); +                        obj->setTEGLTFMaterialOverride(i, nullptr); +                        if (obj->getTE(i) && obj->getTE(i)->isSelected()) +                        { +                            doSelectionCallbacks(obj->getID(), i); +                        }                      }                  } -            } -        }); +            }); +        }      }  private: diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index d301e14e10..67bf6827ad 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1342,10 +1342,11 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry)  	if (header_size > 0)  	{ -		const LLSD& header = header_it->second.second; -		S32 version = header["version"].asInteger(); -		S32 offset = header_size + header["skin"]["offset"].asInteger(); -		S32 size = header["skin"]["size"].asInteger(); +		const LLMeshHeader& header = header_it->second.second; + +        S32 version = header.mVersion; +		S32 offset = header_size + header.mSkinOffset; +		S32 size = header.mSkinSize;  		mHeaderMutex->unlock(); @@ -1456,9 +1457,9 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)  	if (header_size > 0)  	{  		const auto& header = header_it->second.second; -		S32 version = header["version"].asInteger(); -		S32 offset = header_size + header["physics_convex"]["offset"].asInteger(); -		S32 size = header["physics_convex"]["size"].asInteger(); +        S32 version = header.mVersion; +        S32 offset = header_size + header.mPhysicsConvexOffset; +        S32 size = header.mPhysicsConvexSize;  		mHeaderMutex->unlock(); @@ -1555,9 +1556,9 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)  	if (header_size > 0)  	{  		const auto& header = header_it->second.second; -		S32 version = header["version"].asInteger(); -		S32 offset = header_size + header["physics_mesh"]["offset"].asInteger(); -		S32 size = header["physics_mesh"]["size"].asInteger(); +        S32 version = header.mVersion; +        S32 offset = header_size + header.mPhysicsMeshOffset; +		S32 size = header.mPhysicsMeshSize;  		mHeaderMutex->unlock(); @@ -1753,9 +1754,9 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod,  	if (header_size > 0)  	{  		const auto& header = header_it->second.second; -		S32 version = header["version"].asInteger(); -		S32 offset = header_size + header[header_lod[lod]]["offset"].asInteger(); -		S32 size = header[header_lod[lod]]["size"].asInteger(); +        S32 version = header.mVersion; +        S32 offset = header_size + header.mLodOffset[lod]; +        S32 size = header.mLodSize[lod];  		mHeaderMutex->unlock();  		if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0) @@ -1857,8 +1858,10 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod,  EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size)  {  	const LLUUID mesh_id = mesh_params.getSculptID(); -	LLSD header; +	LLSD header_data; +    LLMeshHeader header; +  	U32 header_size = 0;  	if (data_size > 0)  	{ @@ -1869,23 +1872,25 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes  		boost::iostreams::stream<boost::iostreams::array_source> stream(result_ptr, data_size); -		if (!LLSDSerialize::fromBinary(header, stream, data_size)) +		if (!LLSDSerialize::fromBinary(header_data, stream, data_size))  		{  			LL_WARNS(LOG_MESH) << "Mesh header parse error.  Not a valid mesh asset!  ID:  " << mesh_id  							   << LL_ENDL;  			return MESH_PARSE_FAILURE;  		} -		if (!header.isMap()) +		if (!header_data.isMap())  		{  			LL_WARNS(LOG_MESH) << "Mesh header is invalid for ID: " << mesh_id << LL_ENDL;  			return MESH_INVALID;  		} -		if (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION) +        header.fromLLSD(header_data); + +		if (header.mVersion > MAX_MESH_VERSION)  		{  			LL_INFOS(LOG_MESH) << "Wrong version in header for " << mesh_id << LL_ENDL; -			header["404"] = 1; +			header.m404 = true;  		}  		// make sure there is at least one lod, function returns -1 and marks as 404 otherwise  		else if (LLMeshRepository::getActualMeshLOD(header, 0) >= 0) @@ -1897,7 +1902,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes  	{  		LL_INFOS(LOG_MESH) << "Non-positive data size.  Marking header as non-existent, will not retry.  ID:  " << mesh_id  						   << LL_ENDL; -		header["404"] = 1; +		header.m404 = 1;  	}  	{ @@ -1907,7 +1912,6 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes  			mMeshHeader[mesh_id] = { header_size, header };              LLMeshRepository::sCacheBytesHeaders += header_size;  		} -  		LLMutexLock lock(mMutex); // make sure only one thread access mPendingLOD at the same time. @@ -2977,7 +2981,7 @@ S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo  	if (iter != mMeshHeader.end())  	{ -		LLSD& header = iter->second.second; +		auto& header = iter->second.second;  		return LLMeshRepository::getActualMeshLOD(header, lod);  	} @@ -2986,23 +2990,23 @@ S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo  }  //static -S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod) +S32 LLMeshRepository::getActualMeshLOD(LLMeshHeader& header, S32 lod)  {  	lod = llclamp(lod, 0, 3); -	if (header.has("404")) +	if (header.m404)  	{  		return -1;  	} -	S32 version = header["version"]; +	S32 version = header.mVersion;  	if (version > MAX_MESH_VERSION)  	{  		return -1;  	} -	if (header[header_lod[lod]]["size"].asInteger() > 0) +	if (header.mLodSize[lod] > 0)  	{  		return lod;  	} @@ -3010,7 +3014,7 @@ S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod)  	//search down to find the next available lower lod  	for (S32 i = lod-1; i >= 0; --i)  	{ -		if (header[header_lod[i]]["size"].asInteger() > 0) +		if (header.mLodSize[i] > 0)  		{  			return i;  		} @@ -3019,15 +3023,16 @@ S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod)  	//search up to find then ext available higher lod  	for (S32 i = lod+1; i < 4; ++i)  	{ -		if (header[header_lod[i]]["size"].asInteger() > 0) +		if (header.mLodSize[i] > 0)  		{  			return i;  		}  	}  	//header exists and no good lod found, treat as 404 -	header["404"] = 1; -	return -1; +    header.m404 = true; + +    return -1;  }  // Handle failed or successful requests for mesh assets. @@ -3216,7 +3221,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b  	{  		// header was successfully retrieved from sim and parsed and is in cache  		S32 header_bytes = 0; -		LLSD header; +		LLMeshHeader header;  		gMeshRepo.mThread->mHeaderMutex->lock();  		LLMeshRepoThread::mesh_header_map::iterator iter = gMeshRepo.mThread->mMeshHeader.find(mesh_id); @@ -3227,8 +3232,8 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b  		}  		if (header_bytes > 0 -			&& !header.has("404") -			&& (!header.has("version") || header["version"].asInteger() <= MAX_MESH_VERSION)) +			&& !header.m404 +			&& (header.mVersion <= MAX_MESH_VERSION))  		{  			std::stringstream str; @@ -3237,13 +3242,12 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b  			for (U32 i = 0; i < LLModel::LOD_PHYSICS; ++i)  			{  				// figure out how many bytes we'll need to reserve in the file -				const std::string & lod_name = header_lod[i]; -				lod_bytes = llmax(lod_bytes, header[lod_name]["offset"].asInteger()+header[lod_name]["size"].asInteger()); +				lod_bytes = llmax(lod_bytes, header.mLodOffset[i]+header.mLodSize[i]);  			}  			// just in case skin info or decomposition is at the end of the file (which it shouldn't be) -			lod_bytes = llmax(lod_bytes, header["skin"]["offset"].asInteger() + header["skin"]["size"].asInteger()); -			lod_bytes = llmax(lod_bytes, header["physics_convex"]["offset"].asInteger() + header["physics_convex"]["size"].asInteger()); +			lod_bytes = llmax(lod_bytes, header.mSkinOffset+header.mSkinSize); +            lod_bytes = llmax(lod_bytes, header.mPhysicsConvexOffset + header.mPhysicsConvexSize);              // Do not unlock mutex untill we are done with LLSD.              // LLSD is smart and can work like smart pointer, is not thread safe. @@ -4257,8 +4261,8 @@ bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id)      mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);      if (iter != mMeshHeader.end() && iter->second.first > 0)      { -        LLSD &mesh = iter->second.second; -        if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0)) +        LLMeshHeader &mesh = iter->second.second; +        if (mesh.mPhysicsMeshSize > 0)          {              return true;          } @@ -4281,20 +4285,21 @@ void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3  S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;  	if (mThread && mesh_id.notNull() && LLPrimitive::NO_LOD != lod)  	{  		LLMutexLock lock(mThread->mHeaderMutex);  		LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id);  		if (iter != mThread->mMeshHeader.end() && iter->second.first > 0)  		{ -			const LLSD& header = iter->second.second; +			const LLMeshHeader& header = iter->second.second; -			if (header.has("404")) +			if (header.m404)  			{  				return -1;  			} -			S32 size = header[header_lod[lod]]["size"].asInteger(); +            S32 size = header.mLodSize[lod];  			return size;  		} @@ -4430,11 +4435,11 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLUUID mesh_id, F32 radius, S32* by  // FIXME replace with calc based on LLMeshCostData  //static -F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod, F32 *unscaled_value) +F32 LLMeshRepository::getStreamingCostLegacy(LLMeshHeader& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod, F32 *unscaled_value)  { -	if (header.has("404") -		|| !header.has("lowest_lod") -		|| (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION)) +	if (header.m404 +		|| header.mLodSize[0] <= 0 +		|| (header.mVersion > MAX_MESH_VERSION))  	{  		return 0.f;  	} @@ -4453,10 +4458,10 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte  	F32 minimum_size = (F32)minimum_size_ch;  	F32 bytes_per_triangle = (F32)bytes_per_triangle_ch; -	S32 bytes_lowest = header["lowest_lod"]["size"].asInteger(); -	S32 bytes_low = header["low_lod"]["size"].asInteger(); -	S32 bytes_mid = header["medium_lod"]["size"].asInteger(); -	S32 bytes_high = header["high_lod"]["size"].asInteger(); +	S32 bytes_lowest = header.mLodSize[0]; +	S32 bytes_low = header.mLodSize[1]; +	S32 bytes_mid = header.mLodSize[2]; +	S32 bytes_high = header.mLodSize[3];  	if (bytes_high == 0)  	{ @@ -4486,10 +4491,10 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte  	if (bytes)  	{  		*bytes = 0; -		*bytes += header["lowest_lod"]["size"].asInteger(); -		*bytes += header["low_lod"]["size"].asInteger(); -		*bytes += header["medium_lod"]["size"].asInteger(); -		*bytes += header["high_lod"]["size"].asInteger(); +		*bytes += header.mLodSize[0]; +		*bytes += header.mLodSize[1]; +		*bytes += header.mLodSize[2]; +		*bytes += header.mLodSize[3];  	}  	if (bytes_visible) @@ -4497,7 +4502,7 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte  		lod = LLMeshRepository::getActualMeshLOD(header, lod);  		if (lod >= 0 && lod <= 3)  		{ -			*bytes_visible = header[header_lod[lod]]["size"].asInteger(); +			*bytes_visible = header.mLodSize[lod];  		}  	} @@ -4539,34 +4544,29 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte  LLMeshCostData::LLMeshCostData()  { -    mSizeByLOD.resize(4); -    mEstTrisByLOD.resize(4); -      std::fill(mSizeByLOD.begin(), mSizeByLOD.end(), 0);      std::fill(mEstTrisByLOD.begin(), mEstTrisByLOD.end(), 0.f);  } -bool LLMeshCostData::init(const LLSD& header) +bool LLMeshCostData::init(const LLMeshHeader& header)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; -    mSizeByLOD.resize(4); -    mEstTrisByLOD.resize(4); - +          std::fill(mSizeByLOD.begin(), mSizeByLOD.end(), 0);      std::fill(mEstTrisByLOD.begin(), mEstTrisByLOD.end(), 0.f); -    S32 bytes_high = header["high_lod"]["size"].asInteger(); -    S32 bytes_med = header["medium_lod"]["size"].asInteger(); +    S32 bytes_high = header.mLodSize[3]; +    S32 bytes_med = header.mLodSize[2];      if (bytes_med == 0)      {          bytes_med = bytes_high;      } -    S32 bytes_low = header["low_lod"]["size"].asInteger(); +    S32 bytes_low = header.mLodSize[1];      if (bytes_low == 0)      {          bytes_low = bytes_med;      } -    S32 bytes_lowest = header["lowest_lod"]["size"].asInteger(); +    S32 bytes_lowest = header.mLodSize[0];      if (bytes_lowest == 0)      {          bytes_lowest = bytes_low; @@ -4701,6 +4701,7 @@ F32 LLMeshCostData::getTriangleBasedStreamingCost()  bool LLMeshRepository::getCostData(LLUUID mesh_id, LLMeshCostData& data)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;      data = LLMeshCostData();      if (mThread && mesh_id.notNull()) @@ -4709,11 +4710,11 @@ bool LLMeshRepository::getCostData(LLUUID mesh_id, LLMeshCostData& data)          LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id);          if (iter != mThread->mMeshHeader.end() && iter->second.first > 0)          { -            LLSD& header = iter->second.second; +            LLMeshHeader& header = iter->second.second; -            bool header_invalid = (header.has("404") -                                   || !header.has("lowest_lod") -                                   || (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION)); +            bool header_invalid = (header.m404 +                                   || header.mLodSize[0] <= 0 +                                   || header.mVersion > MAX_MESH_VERSION);              if (!header_invalid)              {                  return getCostData(header, data); @@ -4725,7 +4726,7 @@ bool LLMeshRepository::getCostData(LLUUID mesh_id, LLMeshCostData& data)      return false;  } -bool LLMeshRepository::getCostData(LLSD& header, LLMeshCostData& data) +bool LLMeshRepository::getCostData(LLMeshHeader& header, LLMeshCostData& data)  {      data = LLMeshCostData(); diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 6922367ff7..619e076fa6 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -194,6 +194,63 @@ private:      LLFrameTimer mTimer;  }; +class LLMeshHeader +{ +public: + +    LLMeshHeader() {} + +    explicit LLMeshHeader(const LLSD& header) +    { +        fromLLSD(header); +    } + +    void fromLLSD(const LLSD& header) +    { +        const char* lod[] = +        { +            "lowest_lod", +            "low_lod", +            "medium_lod", +            "high_lod" +        }; + +        mVersion = header["version"].asInteger(); + +        for (U32 i = 0; i < 4; ++i) +        { +            mLodOffset[i] = header[lod[i]]["offset"].asInteger(); +            mLodSize[i] = header[lod[i]]["size"].asInteger(); +        } + +        mSkinOffset = header["skin"]["offset"].asInteger(); +        mSkinSize = header["skin"]["size"].asInteger(); + +        mPhysicsConvexOffset = header["physics_convex"]["offset"].asInteger(); +        mPhysicsConvexSize = header["physics_convex"]["size"].asInteger(); + +        mPhysicsMeshOffset = header["physics_mesh"]["offset"].asInteger(); +        mPhysicsMeshSize = header["physics_mesh"]["size"].asInteger(); + +        m404 = header.has("404"); +    } + +    S32 mVersion = -1; +    S32 mSkinOffset = -1; +    S32 mSkinSize = -1; + +    S32 mPhysicsConvexOffset = -1; +    S32 mPhysicsConvexSize = -1; + +    S32 mPhysicsMeshOffset = -1; +    S32 mPhysicsMeshSize = -1; + +    S32 mLodOffset[4] = { -1 }; +    S32 mLodSize[4] = { -1 }; + +    bool m404 = false; +}; +  class LLMeshRepoThread : public LLThread  {  public: @@ -210,7 +267,7 @@ public:  	LLCondition* mSignal;  	//map of known mesh headers -	typedef boost::unordered_map<LLUUID, std::pair<U32, LLSD>> mesh_header_map; // pair is header_size and data +	typedef boost::unordered_map<LLUUID, std::pair<U32, LLMeshHeader>> mesh_header_map; // pair is header_size and data  	mesh_header_map mMeshHeader;  	class HeaderRequest : public RequestStats @@ -497,7 +554,7 @@ class LLMeshCostData  public:      LLMeshCostData(); -    bool init(const LLSD& header); +    bool init(const LLMeshHeader& header);      // Size for given LOD      S32 getSizeByLOD(S32 lod); @@ -532,10 +589,10 @@ public:  private:      // From the "size" field of the mesh header. LOD 0=lowest, 3=highest. -    std::vector<S32> mSizeByLOD; +    std::array<S32,4> mSizeByLOD;      // Estimated triangle counts derived from the LOD sizes. LOD 0=lowest, 3=highest. -    std::vector<F32> mEstTrisByLOD; +    std::array<F32,4> mEstTrisByLOD;  };  class LLMeshRepository @@ -566,9 +623,9 @@ public:      F32 getEstTrianglesMax(LLUUID mesh_id);      F32 getEstTrianglesStreamingCost(LLUUID mesh_id);  	F32 getStreamingCostLegacy(LLUUID mesh_id, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL); -	static F32 getStreamingCostLegacy(LLSD& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL); +	static F32 getStreamingCostLegacy(LLMeshHeader& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL);      bool getCostData(LLUUID mesh_id, LLMeshCostData& data); -    bool getCostData(LLSD& header, LLMeshCostData& data); +    bool getCostData(LLMeshHeader& header, LLMeshCostData& data);  	LLMeshRepository(); @@ -588,7 +645,7 @@ public:  	void notifyDecompositionReceived(LLModel::Decomposition* info);  	S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod); -	static S32 getActualMeshLOD(LLSD& header, S32 lod); +	static S32 getActualMeshLOD(LLMeshHeader& header, S32 lod);  	const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj = nullptr);  	LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id);  	void fetchPhysicsShape(const LLUUID& mesh_id); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 22c1176b05..045972b7a8 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -7833,7 +7833,7 @@ S32 LLObjectSelection::getSelectedObjectRenderCost()  				   for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter)  				   {  					   // add the cost of each individual texture in the linkset -					   cost += iter->second; +					   cost += LLVOVolume::getTextureCost(*iter);  				   }  				   textures.clear(); @@ -7855,7 +7855,7 @@ S32 LLObjectSelection::getSelectedObjectRenderCost()  			for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter)  			{  				// add the cost of each individual texture in the linkset -				cost += iter->second; +				cost += LLVOVolume::getTextureCost(*iter);  			}  			textures.clear(); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 4d99ee1386..f7df4286fe 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1826,116 +1826,6 @@ void renderUpdateType(LLDrawable* drawablep)  	}  } -void renderComplexityDisplay(LLDrawable* drawablep) -{ -	LLViewerObject* vobj = drawablep->getVObj(); -	if (!vobj) -	{ -		return; -	} - -	LLVOVolume *voVol = dynamic_cast<LLVOVolume*>(vobj); - -	if (!voVol) -	{ -		return; -	} - -	if (!voVol->isRoot()) -	{ -		return; -	} - -	LLVOVolume::texture_cost_t textures; -	F32 cost = (F32) voVol->getRenderCost(textures); - -	// add any child volumes -	LLViewerObject::const_child_list_t children = voVol->getChildren(); -	for (LLViewerObject::const_child_list_t::const_iterator iter = children.begin(); iter != children.end(); ++iter) -	{ -		const LLViewerObject *child = *iter; -		const LLVOVolume *child_volume = dynamic_cast<const LLVOVolume*>(child); -		if (child_volume) -		{ -			cost += child_volume->getRenderCost(textures); -		} -	} - -	// add texture cost -	for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter) -	{ -		// add the cost of each individual texture in the linkset -		cost += iter->second; -	} - -	F32 cost_max = (F32) LLVOVolume::getRenderComplexityMax(); - - - -	// allow user to set a static color scale -	if (gSavedSettings.getS32("RenderComplexityStaticMax") > 0) -	{ -		cost_max = gSavedSettings.getS32("RenderComplexityStaticMax"); -	} - -	F32 cost_ratio = cost / cost_max; -	 -	// cap cost ratio at 1.0f in case cost_max is at a low threshold -	cost_ratio = cost_ratio > 1.0f ? 1.0f : cost_ratio; -	 -	LLGLEnable blend(GL_BLEND); - -	LLColor4 color; -	const LLColor4 color_min = gSavedSettings.getColor4("RenderComplexityColorMin"); -	const LLColor4 color_mid = gSavedSettings.getColor4("RenderComplexityColorMid"); -	const LLColor4 color_max = gSavedSettings.getColor4("RenderComplexityColorMax"); - -	if (cost_ratio < 0.5f) -	{ -		color = color_min * (1 - cost_ratio * 2) + color_mid * (cost_ratio * 2); -	} -	else -	{ -		color = color_mid * (1 - (cost_ratio - 0.5) * 2) + color_max * ((cost_ratio - 0.5) * 2); -	} - -	LLSD color_val = color.getValue(); - -	// don't highlight objects below the threshold -	if (cost > gSavedSettings.getS32("RenderComplexityThreshold")) -	{ -		glColor4f(color[0],color[1],color[2],0.5f); - - -		S32 num_faces = drawablep->getNumFaces(); -		if (num_faces) -		{ -			for (S32 i = 0; i < num_faces; ++i) -			{ -				pushVerts(drawablep->getFace(i)); -			} -		} -		LLViewerObject::const_child_list_t children = voVol->getChildren(); -		for (LLViewerObject::const_child_list_t::const_iterator iter = children.begin(); iter != children.end(); ++iter) -		{ -			const LLViewerObject *child = *iter; -			if (child) -			{ -				num_faces = child->getNumFaces(); -				if (num_faces) -				{ -					for (S32 i = 0; i < num_faces; ++i) -					{ -						pushVerts(child->mDrawable->getFace(i)); -					} -				} -			} -		} -	} -	 -	voVol->setDebugText(llformat("%4.0f", cost));	 -} -  void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)  {  	if (set_color) @@ -3261,10 +3151,6 @@ public:  			{  				renderUpdateType(drawable);  			} -			if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY)) -			{ -				renderComplexityDisplay(drawable); -			}  			if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))  			{  				renderTexelDensity(drawable); @@ -3575,7 +3461,6 @@ void LLSpatialPartition::renderDebug()  									  LLPipeline::RENDER_DEBUG_AGENT_TARGET |  									  //LLPipeline::RENDER_DEBUG_BUILD_QUEUE |  									  LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA | -									  LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY |  									  LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))  	{  		return; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 8334ca329a..77b4804076 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -369,7 +369,7 @@ LLViewerObject::~LLViewerObject()      }  	// Delete memory associated with extra parameters. -	std::map<U16, ExtraParameter*>::iterator iter; +	std::unordered_map<U16, ExtraParameter*>::iterator iter;  	for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)  	{  		if(iter->second != NULL) @@ -1555,7 +1555,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  				unpackParticleSource(block_num, owner_id);  				// Mark all extra parameters not used -				std::map<U16, ExtraParameter*>::iterator iter; +				std::unordered_map<U16, ExtraParameter*>::iterator iter;  				for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)  				{  					iter->second->in_use = FALSE; @@ -1947,7 +1947,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  				}  				// Mark all extra parameters not used -				std::map<U16, ExtraParameter*>::iterator iter; +				std::unordered_map<U16, ExtraParameter*>::iterator iter;  				for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)  				{  					iter->second->in_use = FALSE; @@ -6242,7 +6242,8 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para  LLViewerObject::ExtraParameter* LLViewerObject::getExtraParameterEntry(U16 param_type) const  { -	std::map<U16, ExtraParameter*>::const_iterator itor = mExtraParameterList.find(param_type); +    LL_PROFILE_ZONE_SCOPED_CATEGORY_VIEWER; +	std::unordered_map<U16, ExtraParameter*>::const_iterator itor = mExtraParameterList.find(param_type);  	if (itor != mExtraParameterList.end())  	{  		return itor->second; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index cd2363a1b9..72505528f0 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -122,7 +122,7 @@ protected:  		BOOL in_use;  		LLNetworkData *data;  	}; -	std::map<U16, ExtraParameter*> mExtraParameterList; +	std::unordered_map<U16, ExtraParameter*> mExtraParameterList;  public:  	typedef std::list<LLPointer<LLViewerObject> > child_list_t; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index a7d544f184..95e9321d6f 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1448,7 +1448,7 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)                                  continue;                              }                          } -                        if (vol && vol->isRiggedMesh()) +                        if (vol && vol->isRiggedMeshFast())                          {                              continue;                          } @@ -10834,6 +10834,7 @@ void LLVOAvatar::updateVisualComplexity()  	mVisualComplexityStale = true;  } +  // Account for the complexity of a single top-level object associated  // with an avatar. This will be either an attached object or an animated  // object. @@ -10847,143 +10848,144 @@ void LLVOAvatar::accountRenderComplexityForObject(  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;      if (attached_object && !attached_object->isHUDAttachment()) -		{ +    {          mAttachmentVisibleTriangleCount += attached_object->recursiveGetTriangleCount();          mAttachmentEstTriangleCount += attached_object->recursiveGetEstTrianglesMax();          mAttachmentSurfaceArea += attached_object->recursiveGetScaledSurfaceArea(); -					textures.clear(); -					const LLDrawable* drawable = attached_object->mDrawable; -					if (drawable) -					{ -						const LLVOVolume* volume = drawable->getVOVolume(); -						if (volume) -						{ -                            F32 attachment_total_cost = 0; -                            F32 attachment_volume_cost = 0; -                            F32 attachment_texture_cost = 0; -                            F32 attachment_children_cost = 0; +        textures.clear(); +        const LLDrawable* drawable = attached_object->mDrawable; +        if (drawable) +        { +            const LLVOVolume* volume = drawable->getVOVolume(); +            if (volume) +            { +                F32 attachment_total_cost = 0; +                F32 attachment_volume_cost = 0; +                F32 attachment_texture_cost = 0; +                F32 attachment_children_cost = 0;                  const F32 animated_object_attachment_surcharge = 1000; -                if (attached_object->isAnimatedObject()) +                if (volume->isAnimatedObjectFast())                  {                      attachment_volume_cost += animated_object_attachment_surcharge;                  } -							attachment_volume_cost += volume->getRenderCost(textures); +                attachment_volume_cost += volume->getRenderCost(textures); -							const_child_list_t children = volume->getChildren(); -							for (const_child_list_t::const_iterator child_iter = children.begin(); -								  child_iter != children.end(); -								  ++child_iter) -							{ -								LLViewerObject* child_obj = *child_iter; -								LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj ); -								if (child) -								{ -									attachment_children_cost += child->getRenderCost(textures); -								} -							} +                const_child_list_t children = volume->getChildren(); +                for (const_child_list_t::const_iterator child_iter = children.begin(); +                    child_iter != children.end(); +                    ++child_iter) +                { +                    LLViewerObject* child_obj = *child_iter; +                    LLVOVolume* child = dynamic_cast<LLVOVolume*>(child_obj); +                    if (child) +                    { +                        attachment_children_cost += child->getRenderCost(textures); +                    } +                } -							for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin(); -								 volume_texture != textures.end(); -								 ++volume_texture) -							{ -								// add the cost of each individual texture in the linkset -								attachment_texture_cost += volume_texture->second; -							} -                            attachment_total_cost = attachment_volume_cost + attachment_texture_cost + attachment_children_cost; -                            LL_DEBUGS("ARCdetail") << "Attachment costs " << attached_object->getAttachmentItemID() -                                                   << " total: " << attachment_total_cost -                                                   << ", volume: " << attachment_volume_cost -                                                   << ", " << textures.size() -                                                   << " textures: " << attachment_texture_cost -                                                   << ", " << volume->numChildren() -                                                   << " children: " << attachment_children_cost -                                                   << LL_ENDL; -                            // Limit attachment complexity to avoid signed integer flipping of the wearer's ACI -                            cost += (U32)llclamp(attachment_total_cost, MIN_ATTACHMENT_COMPLEXITY, max_attachment_complexity); - -                            if (isSelf()) -                            { -                                LLObjectComplexity object_complexity; -                                object_complexity.objectName = attached_object->getAttachmentItemName(); -                                object_complexity.objectId = attached_object->getAttachmentItemID(); -                                object_complexity.objectCost = attachment_total_cost; -                                object_complexity_list.push_back(object_complexity); -                            } -						} -					} -				} -                if (isSelf() -                    && attached_object -                    && attached_object->isHUDAttachment() -                    && !attached_object->isTempAttachment() -                    && attached_object->mDrawable) +                for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin(); +                    volume_texture != textures.end(); +                    ++volume_texture)                  { -                    textures.clear(); -                    BOOL is_rigged_mesh = attached_object->isRiggedMesh(); +                    // add the cost of each individual texture in the linkset +                    attachment_texture_cost += LLVOVolume::getTextureCost(*volume_texture); +                } +                attachment_total_cost = attachment_volume_cost + attachment_texture_cost + attachment_children_cost; +                LL_DEBUGS("ARCdetail") << "Attachment costs " << attached_object->getAttachmentItemID() +                    << " total: " << attachment_total_cost +                    << ", volume: " << attachment_volume_cost +                    << ", " << textures.size() +                    << " textures: " << attachment_texture_cost +                    << ", " << volume->numChildren() +                    << " children: " << attachment_children_cost +                    << LL_ENDL; +                // Limit attachment complexity to avoid signed integer flipping of the wearer's ACI +                cost += (U32)llclamp(attachment_total_cost, MIN_ATTACHMENT_COMPLEXITY, max_attachment_complexity); + +                if (isSelf()) +                { +                    LLObjectComplexity object_complexity; +                    object_complexity.objectName = attached_object->getAttachmentItemName(); +                    object_complexity.objectId = attached_object->getAttachmentItemID(); +                    object_complexity.objectCost = attachment_total_cost; +                    object_complexity_list.push_back(object_complexity); +                } +            } +        } +    } +    if (isSelf() +        && attached_object +        && attached_object->isHUDAttachment() +        && !attached_object->isTempAttachment() +        && attached_object->mDrawable) +    { +        textures.clear();          mAttachmentSurfaceArea += attached_object->recursiveGetScaledSurfaceArea(); -                    const LLVOVolume* volume = attached_object->mDrawable->getVOVolume(); -                    if (volume) -                    { -                        LLHUDComplexity hud_object_complexity; -                        hud_object_complexity.objectName = attached_object->getAttachmentItemName(); -                        hud_object_complexity.objectId = attached_object->getAttachmentItemID(); -                        std::string joint_name; -                        gAgentAvatarp->getAttachedPointName(attached_object->getAttachmentItemID(), joint_name); -                        hud_object_complexity.jointName = joint_name; -                        // get cost and individual textures -                        hud_object_complexity.objectsCost += volume->getRenderCost(textures); -                        hud_object_complexity.objectsCount++; - -                        LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); -                        for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); -                            iter != child_list.end(); ++iter) -                        { -                            LLViewerObject* childp = *iter; -                            is_rigged_mesh |= childp->isRiggedMesh(); -                            const LLVOVolume* chld_volume = dynamic_cast<LLVOVolume*>(childp); -                            if (chld_volume) -                            { -                                // get cost and individual textures -                                hud_object_complexity.objectsCost += chld_volume->getRenderCost(textures); -                                hud_object_complexity.objectsCount++; -                            } -                        } -                        if (is_rigged_mesh && !attached_object->mRiggedAttachedWarned) -                        { -                            LLSD args;                             -                            LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID()); -                            args["NAME"] = itemp ? itemp->getName() : LLTrans::getString("Unknown"); -                            args["POINT"] = LLTrans::getString(getTargetAttachmentPoint(attached_object)->getName()); -                            LLNotificationsUtil::add("RiggedMeshAttachedToHUD", args); +        const LLVOVolume* volume = attached_object->mDrawable->getVOVolume(); +        if (volume) +        { +            BOOL is_rigged_mesh = volume->isRiggedMeshFast(); +            LLHUDComplexity hud_object_complexity; +            hud_object_complexity.objectName = attached_object->getAttachmentItemName(); +            hud_object_complexity.objectId = attached_object->getAttachmentItemID(); +            std::string joint_name; +            gAgentAvatarp->getAttachedPointName(attached_object->getAttachmentItemID(), joint_name); +            hud_object_complexity.jointName = joint_name; +            // get cost and individual textures +            hud_object_complexity.objectsCost += volume->getRenderCost(textures); +            hud_object_complexity.objectsCount++; + +            LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); +            for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); +                iter != child_list.end(); ++iter) +            { +                LLViewerObject* childp = *iter; +                const LLVOVolume* chld_volume = dynamic_cast<LLVOVolume*>(childp); +                if (chld_volume) +                { +                    is_rigged_mesh = is_rigged_mesh || chld_volume->isRiggedMeshFast(); +                    // get cost and individual textures +                    hud_object_complexity.objectsCost += chld_volume->getRenderCost(textures); +                    hud_object_complexity.objectsCount++; +                } +            } +            if (is_rigged_mesh && !attached_object->mRiggedAttachedWarned) +            { +                LLSD args; +                LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID()); +                args["NAME"] = itemp ? itemp->getName() : LLTrans::getString("Unknown"); +                args["POINT"] = LLTrans::getString(getTargetAttachmentPoint(attached_object)->getName()); +                LLNotificationsUtil::add("RiggedMeshAttachedToHUD", args); -                            attached_object->mRiggedAttachedWarned = true; -                        } +                attached_object->mRiggedAttachedWarned = true; +            } -                        hud_object_complexity.texturesCount += textures.size(); +            hud_object_complexity.texturesCount += textures.size(); -                        for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin(); -                            volume_texture != textures.end(); -                            ++volume_texture) -                        { -                            // add the cost of each individual texture (ignores duplicates) -                            hud_object_complexity.texturesCost += volume_texture->second; -                            LLViewerFetchedTexture *tex = LLViewerTextureManager::getFetchedTexture(volume_texture->first); -                            if (tex) -                            { -                                // Note: Texture memory might be incorect since texture might be still loading. -                                hud_object_complexity.texturesMemoryTotal += tex->getTextureMemory(); -                                if (tex->getOriginalHeight() * tex->getOriginalWidth() >= HUD_OVERSIZED_TEXTURE_DATA_SIZE) -                                { -                                    hud_object_complexity.largeTexturesCount++; -                                } -                            } -                        } -                        hud_complexity_list.push_back(hud_object_complexity); +            for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin(); +                volume_texture != textures.end(); +                ++volume_texture) +            { +                // add the cost of each individual texture (ignores duplicates) +                hud_object_complexity.texturesCost += LLVOVolume::getTextureCost(*volume_texture); +                const LLViewerTexture* img = *volume_texture; +                if (img->getType() == LLViewerTexture::FETCHED_TEXTURE) +                { +                    LLViewerFetchedTexture* tex = (LLViewerFetchedTexture*)img; +                    // Note: Texture memory might be incorect since texture might be still loading. +                    hud_object_complexity.texturesMemoryTotal += tex->getTextureMemory(); +                    if (tex->getOriginalHeight() * tex->getOriginalWidth() >= HUD_OVERSIZED_TEXTURE_DATA_SIZE) +                    { +                        hud_object_complexity.largeTexturesCount++;                      }                  } +            } +            hud_complexity_list.push_back(hud_object_complexity); +        } +    }  }  // Calculations for mVisualComplexity value @@ -11005,7 +11007,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()          max_attachment_complexity = llmax(max_attachment_complexity, DEFAULT_MAX_ATTACHMENT_COMPLEXITY);          // Diagnostic list of all textures on our avatar -        static std::set<LLUUID> all_textures; +        static std::unordered_set<const LLViewerTexture*> all_textures;  		U32 cost = VISUAL_COMPLEXITY_UNKNOWN;  		LLVOVolume::texture_cost_t textures; @@ -11074,46 +11076,6 @@ void LLVOAvatar::calculateUpdateRenderComplexity()  			}  		} -		// Diagnostic output to identify all avatar-related textures. -		// Does not affect rendering cost calculation. -		if (isSelf()) -		{ -			LL_DEBUGS("ARCdetail"); -			// print any attachment textures we didn't already know about. -			for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it) -			{ -				LLUUID image_id = it->first; -				if( ! (image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) -				   && (all_textures.find(image_id) == all_textures.end())) -				{ -					// attachment texture not previously seen. -					LL_CONT << "attachment_texture: " << image_id.asString() << '\n'; -					all_textures.insert(image_id); -				} -			} - -			// print any avatar textures we didn't already know about -			for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin(); -			 iter != LLAvatarAppearance::getDictionary()->getTextures().end(); -				 ++iter) -			{ -				const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; -				// TODO: MULTI-WEARABLE: handle multiple textures for self -				const LLViewerTexture* te_image = getImage(iter->first,0); -				if (!te_image) -					continue; -				LLUUID image_id = te_image->getID(); -				if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) -					continue; -				if (all_textures.find(image_id) == all_textures.end()) -				{ -					LL_CONT << "local_texture: " << texture_dict->mName << ": " << image_id << '\n'; -					all_textures.insert(image_id); -				} -			} -			LL_ENDL; -		} -          if ( cost != mVisualComplexity )          {              LL_DEBUGS("AvatarRender") << "Avatar "<< getID() diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 585c98bace..aa60578cee 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3190,7 +3190,13 @@ void LLVOVolume::setLightCutoff(F32 cutoff)  BOOL LLVOVolume::getIsLight() const  { -	return getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT); +    mIsLight = getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT); +    return mIsLight; +} + +bool LLVOVolume::getIsLightFast() const +{ +    return mIsLight;  }  LLColor3 LLVOVolume::getLightSRGBBaseColor() const @@ -3576,6 +3582,31 @@ BOOL LLVOVolume::hasLightTexture() const  	return FALSE;  } +bool LLVOVolume::isFlexibleFast() const +{ +    return mVolumep && mVolumep->getParams().getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE; +} + +bool LLVOVolume::isSculptedFast() const +{ +    return mVolumep && mVolumep->getParams().isSculpt(); +} + +bool LLVOVolume::isMeshFast() const +{ +    return mVolumep && mVolumep->getParams().isMeshSculpt(); +} + +bool LLVOVolume::isRiggedMeshFast() const +{ +    return mSkinInfo.notNull(); +} + +bool LLVOVolume::isAnimatedObjectFast() const +{ +    return mIsAnimatedObject; +} +  BOOL LLVOVolume::isVolumeGlobal() const  {  	if (mVolumeImpl) @@ -3736,8 +3767,8 @@ bool LLVOVolume::canBeAnimatedObject() const  bool LLVOVolume::isAnimatedObject() const  {      LLVOVolume *root_vol = (LLVOVolume*)getRootEdit(); -    bool root_is_animated_flag = root_vol->getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG; -    return root_is_animated_flag; +    mIsAnimatedObject = root_vol->getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG; +    return mIsAnimatedObject;  }  // Called any time parenting changes for a volume. Update flags and @@ -3924,6 +3955,34 @@ const LLMatrix4 LLVOVolume::getRenderMatrix() const  	return mDrawable->getWorldMatrix();  } +//static  +S32 LLVOVolume::getTextureCost(const LLViewerTexture* img) +{ +    static const U32 ARC_TEXTURE_COST = 16; // multiplier for texture resolution - performance tested + +    S32 texture_cost = 0; +    S8 type = img->getType(); +    if (type == LLViewerTexture::FETCHED_TEXTURE || type == LLViewerTexture::LOD_TEXTURE) +    { +        const LLViewerFetchedTexture* fetched_texturep = static_cast<const LLViewerFetchedTexture*>(img); +        if (fetched_texturep +            && fetched_texturep->getFTType() == FTT_LOCAL_FILE +            && (img->getID() == IMG_ALPHA_GRAD_2D || img->getID() == IMG_ALPHA_GRAD) +            ) +        { +            // These two textures appear to switch between each other, but are of different sizes (4x256 and 256x256). +            // Hardcode cost from larger one to not cause random complexity changes +            texture_cost = 320; +        } +    } +    if (texture_cost == 0) +    { +        texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (img->getFullHeight() / 128.f + img->getFullWidth() / 128.f)); +    } + +    return texture_cost; +} +  // Returns a base cost and adds textures to passed in set.  // total cost is returned value + 5 * size of the resulting set.  // Cannot include cost of textures, as they may be re-used in linked @@ -3940,17 +3999,16 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const  	// Get access to params we'll need at various points.    	// Skip if this is object doesn't have a volume (e.g. is an avatar). -	BOOL has_volume = (getVolume() != NULL); -	LLVolumeParams volume_params; -	LLPathParams path_params; -	LLProfileParams profile_params; +    if (getVolume() == NULL) +    { +        return 0; +    }  	U32 num_triangles = 0;  	// per-prim costs  	static const U32 ARC_PARTICLE_COST = 1; // determined experimentally  	static const U32 ARC_PARTICLE_MAX = 2048; // default values -	static const U32 ARC_TEXTURE_COST = 16; // multiplier for texture resolution - performance tested  	static const U32 ARC_LIGHT_COST = 500; // static cost for light-producing prims   	static const U32 ARC_MEDIA_FACE_COST = 1500; // static cost per media-enabled face  @@ -3985,45 +4043,41 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const  	const LLDrawable* drawablep = mDrawable;  	U32 num_faces = drawablep->getNumFaces(); -	if (has_volume) -	{ -		volume_params = getVolume()->getParams(); -		path_params = volume_params.getPathParams(); -		profile_params = volume_params.getProfileParams(); +	const LLVolumeParams& volume_params = getVolume()->getParams(); -        LLMeshCostData costs; -		if (getCostData(costs)) -		{ -            if (isAnimatedObject() && isRiggedMesh()) -            { -                // Scaling here is to make animated object vs -                // non-animated object ARC proportional to the -                // corresponding calculations for streaming cost. -                num_triangles = (ANIMATED_OBJECT_COST_PER_KTRI * 0.001 * costs.getEstTrisForStreamingCost())/0.06; -            } -            else -            { -                F32 radius = getScale().length()*0.5f; -                num_triangles = costs.getRadiusWeightedTris(radius); -            } -		} +    LLMeshCostData costs; +	if (getCostData(costs)) +	{ +        if (isAnimatedObjectFast() && isRiggedMeshFast()) +        { +            // Scaling here is to make animated object vs +            // non-animated object ARC proportional to the +            // corresponding calculations for streaming cost. +            num_triangles = (ANIMATED_OBJECT_COST_PER_KTRI * 0.001 * costs.getEstTrisForStreamingCost())/0.06; +        } +        else +        { +            F32 radius = getScale().length()*0.5f; +            num_triangles = costs.getRadiusWeightedTris(radius); +        }  	} +	  	if (num_triangles <= 0)  	{  		num_triangles = 4;  	} -	if (isSculpted()) +	if (isSculptedFast())  	{ -		if (isMesh()) +		if (isMeshFast())  		{  			// base cost is dependent on mesh complexity  			// note that 3 is the highest LOD as of the time of this coding.  			S32 size = gMeshRepo.getMeshSize(volume_params.getSculptID(), getLOD());  			if ( size > 0)  			{ -				if (isRiggedMesh()) +				if (isRiggedMeshFast())  				{  					// weighted attachment - 1 point for every 3 bytes  					weighted_mesh = 1; @@ -4037,21 +4091,15 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const  		}  		else  		{ -			const LLSculptParams *sculpt_params = (LLSculptParams *) getParameterEntry(LLNetworkData::PARAMS_SCULPT); -			LLUUID sculpt_id = sculpt_params->getSculptTexture(); -			if (textures.find(sculpt_id) == textures.end()) +            LLViewerFetchedTexture* texture = mSculptTexture; +			if (texture && textures.find(texture) == textures.end())  			{ -				LLViewerFetchedTexture *texture = LLViewerTextureManager::getFetchedTexture(sculpt_id); -				if (texture) -				{ -					S32 texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (texture->getFullHeight() / 128.f + texture->getFullWidth() / 128.f)); -					textures.insert(texture_cost_t::value_type(sculpt_id, texture_cost)); -				} +                textures.insert(texture);  			}  		}  	} -	if (isFlexible()) +	if (isFlexibleFast())  	{  		flexi = 1;  	} @@ -4060,85 +4108,66 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const  		particles = 1;  	} -	if (getIsLight()) +	if (getIsLightFast())  	{  		produces_light = 1;  	} -	for (S32 i = 0; i < num_faces; ++i) -	{ -		const LLFace* face = drawablep->getFace(i); -		if (!face) continue; -		const LLTextureEntry* te = face->getTextureEntry(); -		const LLViewerTexture* img = face->getTexture(); +    { +        LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME("ARC - face list"); +        for (S32 i = 0; i < num_faces; ++i) +        { +            const LLFace* face = drawablep->getFace(i); +            if (!face) continue; +            const LLTextureEntry* te = face->getTextureEntry(); +            const LLViewerTexture* img = face->getTexture(); -		if (img) -		{ -			if (textures.find(img->getID()) == textures.end()) -			{ -                S32 texture_cost = 0; -                S8 type = img->getType(); -                if (type == LLViewerTexture::FETCHED_TEXTURE || type == LLViewerTexture::LOD_TEXTURE) +            if (img) +            { +                textures.insert(img); +            } + +            if (face->isInAlphaPool()) +            { +                alpha = 1; +            } +            else if (img && img->getPrimaryFormat() == GL_ALPHA) +            { +                invisi = 1; +            } +            if (face->hasMedia()) +            { +                media_faces++; +            } + +            if (te) +            { +                if (te->getBumpmap())                  { -                    const LLViewerFetchedTexture* fetched_texturep = static_cast<const LLViewerFetchedTexture*>(img); -                    if (fetched_texturep -                        && fetched_texturep->getFTType() == FTT_LOCAL_FILE -                        && (img->getID() == IMG_ALPHA_GRAD_2D || img->getID() == IMG_ALPHA_GRAD) -                        ) -                    { -                        // These two textures appear to switch between each other, but are of different sizes (4x256 and 256x256). -                        // Hardcode cost from larger one to not cause random complexity changes -                        texture_cost = 320; -                    } +                    // bump is a multiplier, don't add per-face +                    bump = 1;                  } -                if (texture_cost == 0) +                if (te->getShiny())                  { -                    texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (img->getFullHeight() / 128.f + img->getFullWidth() / 128.f)); +                    // shiny is a multiplier, don't add per-face +                    shiny = 1;                  } -				textures.insert(texture_cost_t::value_type(img->getID(), texture_cost)); -			} -		} - -		if (face->isInAlphaPool()) -		{ -			alpha = 1; -		} -		else if (img && img->getPrimaryFormat() == GL_ALPHA) -		{ -			invisi = 1; -		} -		if (face->hasMedia()) -		{ -			media_faces++; -		} - -		if (te) -		{ -			if (te->getBumpmap()) -			{ -				// bump is a multiplier, don't add per-face -				bump = 1; -			} -			if (te->getShiny()) -			{ -				// shiny is a multiplier, don't add per-face -				shiny = 1; -			} -			if (te->getGlow() > 0.f) -			{ -				// glow is a multiplier, don't add per-face -				glow = 1; -			} -			if (face->mTextureMatrix != NULL) -			{ -				animtex = 1; -			} -			if (te->getTexGen()) -			{ -				planar = 1; -			} -		} -	} +                if (te->getGlow() > 0.f) +                { +                    // glow is a multiplier, don't add per-face +                    glow = 1; +                } +                if (face->mTextureMatrix != NULL) +                { +                    animtex = 1; +                } +                if (te->getTexGen()) +                { +                    planar = 1; +                } +            } +        } +    }  	// shame currently has the "base" cost of 1 point per 15 triangles, min 2.  	shame = num_triangles  * 5.f; @@ -4217,7 +4246,7 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const      // Streaming cost for animated objects includes a fixed cost      // per linkset. Add a corresponding charge here translated into      // triangles, but not weighted by any graphics properties. -    if (isAnimatedObject() && isRootEdit()) +    if (isAnimatedObjectFast() && isRootEdit())      {          shame += (ANIMATED_OBJECT_BASE_COST/0.06) * 5.0f;      } @@ -4232,7 +4261,7 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const  F32 LLVOVolume::getEstTrianglesMax() const  { -	if (isMesh() && getVolume()) +	if (isMeshFast() && getVolume())  	{  		return gMeshRepo.getEstTrianglesMax(getVolume()->getParams().getSculptID());  	} @@ -4241,7 +4270,7 @@ F32 LLVOVolume::getEstTrianglesMax() const  F32 LLVOVolume::getEstTrianglesStreamingCost() const  { -	if (isMesh() && getVolume()) +	if (isMeshFast() && getVolume())  	{  		return gMeshRepo.getEstTrianglesStreamingCost(getVolume()->getParams().getSculptID());  	} @@ -4256,7 +4285,7 @@ F32 LLVOVolume::getStreamingCost() const      LLMeshCostData costs;      if (getCostData(costs))      { -        if (isAnimatedObject() && isRootEdit()) +        if (isRootEdit() && isAnimatedObject())          {              // Root object of an animated object has this to account for skeleton overhead.              linkset_base_cost = ANIMATED_OBJECT_BASE_COST; @@ -4286,7 +4315,9 @@ F32 LLVOVolume::getStreamingCost() const  // virtual  bool LLVOVolume::getCostData(LLMeshCostData& costs) const  { -    if (isMesh()) +    LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; + +    if (isMeshFast())      {          return gMeshRepo.getCostData(getVolume()->getParams().getSculptID(), costs);      } @@ -4296,11 +4327,11 @@ bool LLVOVolume::getCostData(LLMeshCostData& costs) const  		S32 counts[4];  		LLVolume::getLoDTriangleCounts(volume->getParams(), counts); -		LLSD header; -		header["lowest_lod"]["size"] = counts[0] * 10; -		header["low_lod"]["size"] = counts[1] * 10; -		header["medium_lod"]["size"] = counts[2] * 10; -		header["high_lod"]["size"] = counts[3] * 10; +        LLMeshHeader header; +		header.mLodSize[0] = counts[0] * 10; +		header.mLodSize[1] = counts[1] * 10; +		header.mLodSize[2] = counts[2] * 10; +		header.mLodSize[3] = counts[3] * 10;  		return gMeshRepo.getCostData(header, costs);      } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 9cfd90a940..d509a7e2ab 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -34,8 +34,8 @@  #include "lllocalbitmaps.h"  #include "m3math.h"		// LLMatrix3  #include "m4math.h"		// LLMatrix4 -#include <map> -#include <set> +#include <unordered_map> +#include <unordered_set>  class LLViewerTextureAnim; @@ -146,7 +146,8 @@ public:  	const LLMatrix4&	getRelativeXform() const				{ return mRelativeXform; }  	const LLMatrix3&	getRelativeXformInvTrans() const		{ return mRelativeXformInvTrans; }  	/*virtual*/	const LLMatrix4	getRenderMatrix() const override; -				typedef std::map<LLUUID, S32> texture_cost_t; +				typedef std::unordered_set<const LLViewerTexture*> texture_cost_t; +                static S32 getTextureCost(const LLViewerTexture* img);  				U32 	getRenderCost(texture_cost_t &textures) const;      /*virtual*/	F32		getEstTrianglesMax() const override;      /*virtual*/	F32		getEstTrianglesStreamingCost() const override; @@ -267,6 +268,7 @@ public:  	void setSpotLightParams(LLVector3 params);  	BOOL getIsLight() const; +    bool getIsLightFast() const;      // Get the light color in sRGB color space NOT scaled by intensity. @@ -315,7 +317,15 @@ public:  	virtual BOOL isRiggedMesh() const override;  	virtual BOOL hasLightTexture() const override; -     +    // fast variants above that use state that is filled in later +    //  not reliable early in the life of an object, but should be used after +    //  object is loaded +    bool isFlexibleFast() const; +    bool isSculptedFast() const; +    bool isMeshFast() const; +    bool isRiggedMeshFast() const; +    bool isAnimatedObjectFast() const; +  	BOOL isVolumeGlobal() const;  	BOOL canBeFlexible() const;  	BOOL setIsFlexible(BOOL is_flexible); @@ -461,6 +471,13 @@ private:  	S32 mIndexInTex[LLRender::NUM_VOLUME_TEXTURE_CHANNELS];  	S32 mMDCImplCount; +    // cached value of getIsLight to avoid redundant map lookups +    // accessed by getIsLightFast +    mutable bool mIsLight = false; + +    // cached value of getIsAnimatedObject to avoid redundant map lookups +    // accessed by getIsAnimatedObjectFast +    mutable bool mIsAnimatedObject = false;  	bool mResetDebugText;  	LLPointer<LLRiggedVolume> mRiggedVolume; @@ -475,7 +492,6 @@ public:  	static LLPointer<LLObjectMediaDataClient> sObjectMediaClient;  	static LLPointer<LLObjectMediaNavigateClient> sObjectMediaNavigateClient; -  protected:  	static S32 sNumLODChanges; diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 8a0a9a7172..e92fa32fc6 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -603,7 +603,6 @@ public:  		RENDER_DEBUG_PHYSICS_SHAPES     =  0x02000000,  		RENDER_DEBUG_NORMALS	        =  0x04000000,  		RENDER_DEBUG_LOD_INFO	        =  0x08000000, -		RENDER_DEBUG_RENDER_COMPLEXITY  =  0x10000000,  		RENDER_DEBUG_ATTACHMENT_BYTES	=  0x20000000, // not used  		RENDER_DEBUG_TEXEL_DENSITY		=  0x40000000,  		RENDER_DEBUG_TRIANGLE_COUNT		=  0x80000000, | 
