From a3fd0801c3030ff9a5a6761c9618f381aa965983 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Mon, 26 Mar 2018 20:59:37 +0100 Subject: SL-897 - display for DebugAnimatedObjects now includes streaming cost triangle count --- indra/newview/llcontrolavatar.cpp | 7 ++- indra/newview/llmeshrepository.cpp | 90 +++++++++++++++++++++++++++++++++++--- indra/newview/llmeshrepository.h | 2 + indra/newview/llviewerobject.cpp | 5 +++ indra/newview/llviewerobject.h | 1 + indra/newview/llvovolume.cpp | 9 ++++ indra/newview/llvovolume.h | 1 + 7 files changed, 106 insertions(+), 9 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp index e1715d567b..a16fa3cd26 100644 --- a/indra/newview/llcontrolavatar.cpp +++ b/indra/newview/llcontrolavatar.cpp @@ -242,7 +242,9 @@ void LLControlAvatar::updateDebugText() std::string lod_string; S32 total_tris = 0; S32 total_verts = 0; - S32 est_tris = 0; + F32 est_tris = 0.f; + F32 est_streaming_tris = 0.f; + for (std::vector::iterator it = volumes.begin(); it != volumes.end(); ++it) { @@ -251,6 +253,7 @@ void LLControlAvatar::updateDebugText() total_tris += volp->getTriangleCount(&verts); total_verts += verts; est_tris += volp->getEstTrianglesMax(); + est_streaming_tris += volp->getEstTrianglesStreamingCost(); lod_string += llformat("%d",volp->getLOD()); if (volp && volp->mDrawable) { @@ -287,7 +290,7 @@ void LLControlAvatar::updateDebugText() addDebugText(llformat("CAV obj %d anim %d active %s impost %d", total_linkset_count, animated_volume_count, active_string.c_str(), (S32) isImpostor())); addDebugText(llformat("types %s lods %s", type_string.c_str(), lod_string.c_str())); - addDebugText(llformat("tris %d (est %d), verts %d", total_tris, est_tris, total_verts)); + addDebugText(llformat("tris %d (est %.1f, streaming %.1f), verts %d", total_tris, est_tris, est_streaming_tris, total_verts)); addDebugText(llformat("pxarea %s", LLStringOps::getReadableNumber(getPixelArea()).c_str())); #if 0 std::string region_name = "no region"; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 4f0fb56ba6..b27fdefb83 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -4062,9 +4062,14 @@ void LLMeshRepository::uploadError(LLSD& args) mUploadErrorQ.push(args); } -F32 LLMeshRepository::getEstTrianglesMax(LLUUID mesh_id) +bool LLMeshRepository::getLODSizes(LLUUID mesh_id, std::vector& lod_byte_sizes, std::vector& lod_tri_counts) { - F32 triangles_max = 0.f; + lod_byte_sizes.resize(4); + lod_tri_counts.resize(4); + + std::fill(lod_byte_sizes.begin(), lod_byte_sizes.end(), 0); + std::fill(lod_tri_counts.begin(), lod_tri_counts.end(), 0.f); + if (mThread && mesh_id.notNull()) { LLMutexLock lock(mThread->mHeaderMutex); @@ -4076,22 +4081,93 @@ F32 LLMeshRepository::getEstTrianglesMax(LLUUID mesh_id) || !header.has("lowest_lod") || (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION)) { - return 0.f; + return false; } S32 bytes_high = header["high_lod"]["size"].asInteger(); S32 bytes_med = header["medium_lod"]["size"].asInteger(); + if (bytes_med == 0) + { + bytes_med = bytes_high; + } S32 bytes_low = header["low_lod"]["size"].asInteger(); + if (bytes_low == 0) + { + bytes_low = bytes_med; + } S32 bytes_lowest = header["lowest_lod"]["size"].asInteger(); - S32 bytes_max = llmax(bytes_high, bytes_med, bytes_low, bytes_lowest); + if (bytes_lowest == 0) + { + bytes_lowest = bytes_low; + } + lod_byte_sizes[0] = bytes_high; + lod_byte_sizes[1] = bytes_med; + lod_byte_sizes[2] = bytes_low; + lod_byte_sizes[3] = bytes_lowest; F32 METADATA_DISCOUNT = (F32) gSavedSettings.getU32("MeshMetaDataDiscount"); //discount 128 bytes to cover the cost of LLSD tags and compression domain overhead F32 MINIMUM_SIZE = (F32) gSavedSettings.getU32("MeshMinimumByteSize"); //make sure nothing is "free" F32 bytes_per_triangle = (F32) gSavedSettings.getU32("MeshBytesPerTriangle"); - triangles_max = llmax((F32) bytes_max-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle; + + for (S32 i=0; i<4; i++) + { + lod_tri_counts[i] = llmax((F32) lod_byte_sizes[i]-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle; + } + + return true; + } + } + return false; +} + +F32 LLMeshRepository::getEstTrianglesMax(LLUUID mesh_id) +{ + std::vector lod_byte_sizes; + std::vector lod_tri_counts; + bool succ = getLODSizes(mesh_id, lod_byte_sizes, lod_tri_counts); + if (!succ) + { + return 0.f; + } + + return llmax(lod_tri_counts[0], lod_tri_counts[1], lod_tri_counts[2], lod_tri_counts[3]); +} + +F32 LLMeshRepository::getEstTrianglesStreamingCost(LLUUID mesh_id) +{ + std::vector lod_byte_sizes; + std::vector tris_by_lod; + bool succ = getLODSizes(mesh_id, lod_byte_sizes, tris_by_lod); + + if (!succ) + { + LL_DEBUGS("StreamingCost") << "couldn't get tris_by_lod" << LL_ENDL; + return 0.f; + } + + LL_DEBUGS("StreamingCost") << "tris_by_lod: " + << tris_by_lod[0] << ", " + << tris_by_lod[1] << ", " + << tris_by_lod[2] << ", " + << tris_by_lod[3] << LL_ENDL; + + F32 charged_tris = tris_by_lod[0]; + F32 allowed_tris = tris_by_lod[0]; + const F32 ENFORCE_FLOOR = 64.0f; + for (S32 i=1; i<4; i++) + { + // How many tris can we have in this LOD without affecting land impact? + // - normally an LOD should be at most half the size of the previous one. + // - once we reach a floor of ENFORCE_FLOOR, don't require LODs to get any smaller. + allowed_tris = llclamp(allowed_tris/2.0f,ENFORCE_FLOOR,tris_by_lod[i]); + F32 excess_tris = tris_by_lod[i]-allowed_tris; + if (excess_tris>0.f) + { + LL_DEBUGS("StreamingCost") << "excess tris in lod[" << i << "] " << excess_tris << " allowed " << allowed_tris << LL_ENDL; + charged_tris += excess_tris; } } - return triangles_max; + return charged_tris; } F32 LLMeshRepository::getStreamingCost(LLUUID mesh_id, F32 radius, S32* bytes, S32* bytes_visible, S32 lod, F32 *unscaled_value) @@ -4203,7 +4279,7 @@ F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32 F32 weighted_avg = triangles_high*high_area + triangles_mid*mid_area + triangles_low*low_area + - triangles_lowest*lowest_area; + triangles_lowest*lowest_area; if (unscaled_value) { diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index d2eac449f7..bae3f66a72 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -472,8 +472,10 @@ public: static LLDeadmanTimer sQuiescentTimer; // Time-to-complete-mesh-downloads after significant events + bool getLODSizes(LLUUID mesh_id, std::vector& lod_byte_sizes, std::vector& lod_tri_counts); // Estimated triangle count of the largest LOD F32 getEstTrianglesMax(LLUUID mesh_id); + F32 getEstTrianglesStreamingCost(LLUUID mesh_id); F32 getStreamingCost(LLUUID mesh_id, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL); static F32 getStreamingCost(LLSD& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 531f9a9527..f606abedf5 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -3692,6 +3692,11 @@ F32 LLViewerObject::getEstTrianglesMax() const return 0.f; } +F32 LLViewerObject::getEstTrianglesStreamingCost() const +{ + return 0.f; +} + F32 LLViewerObject::getStreamingCost(S32* bytes, S32* visible_bytes, F32* unscaled_value) const { return 0.f; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index ab0e74bc97..2fe14c2fcf 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -365,6 +365,7 @@ public: S32 getAnimatedObjectMaxTris() const; F32 recursiveGetEstTrianglesMax() const; virtual F32 getEstTrianglesMax() const; + virtual F32 getEstTrianglesStreamingCost() const; virtual F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL, F32* unscaled_value = NULL) const; virtual U32 getTriangleCount(S32* vcount = NULL) const; virtual U32 getHighLODTriangleCount(); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 69c2d2cccd..3b5129d994 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3905,6 +3905,15 @@ F32 LLVOVolume::getEstTrianglesMax() const return 0.f; } +F32 LLVOVolume::getEstTrianglesStreamingCost() const +{ + if (isMesh() && getVolume()) + { + return gMeshRepo.getEstTrianglesStreamingCost(getVolume()->getParams().getSculptID()); + } + return 0.f; +} + F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes, F32* unscaled_value) const { F32 radius = getScale().length()*0.5f; diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 4aec48e8ff..f6738945d8 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -135,6 +135,7 @@ public: typedef std::map texture_cost_t; U32 getRenderCost(texture_cost_t &textures) const; /*virtual*/ F32 getEstTrianglesMax() const; + /*virtual*/ F32 getEstTrianglesStreamingCost() const; F32 getStreamingCost(S32* bytes, S32* visible_bytes, F32* unscaled_value) const; /*virtual*/ F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL) { return getStreamingCost(bytes, visible_bytes, NULL); } -- cgit v1.2.3