diff options
author | Nyx (Neal Orman) <nyx@lindenlab.com> | 2010-09-01 10:59:45 -0400 |
---|---|---|
committer | Nyx (Neal Orman) <nyx@lindenlab.com> | 2010-09-01 10:59:45 -0400 |
commit | e3fec30097a28689a7022d06005d7d59a3004f0c (patch) | |
tree | e143c9775e3c2867bb95b7726598f5b057a04770 /indra/newview | |
parent | d8fd52341a2ff47c6f929540628f2f0017c8b185 (diff) |
CTS-231 WIP create new ARC algorithm to be more accurate and account for meshes
First pass - uses the new algorithm to hopefully be more accurate of render load
on low-end machines. Also accounts for mesh complexity, including if a mesh is
weighted or non-weighted.
Code reviewed by davep
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/llfloatertools.cpp | 8 | ||||
-rw-r--r-- | indra/newview/llmeshrepository.cpp | 24 | ||||
-rw-r--r-- | indra/newview/llmeshrepository.h | 3 | ||||
-rw-r--r-- | indra/newview/llvoavatar.cpp | 17 | ||||
-rw-r--r-- | indra/newview/llvovolume.cpp | 211 | ||||
-rw-r--r-- | indra/newview/llvovolume.h | 5 |
6 files changed, 236 insertions, 32 deletions
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 5472531fa7..fa5d9b0892 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -1007,7 +1007,7 @@ void LLFloaterTools::onClickGridOptions() S32 LLFloaterTools::calcRenderCost() { S32 cost = 0; - std::set<LLUUID> textures; + LLVOVolume::texture_cost_t textures; for (LLObjectSelection::iterator selection_iter = LLSelectMgr::getInstance()->getSelection()->begin(); selection_iter != LLSelectMgr::getInstance()->getSelection()->end(); @@ -1020,7 +1020,11 @@ S32 LLFloaterTools::calcRenderCost() if (viewer_volume) { cost += viewer_volume->getRenderCost(textures); - cost += textures.size() * LLVOVolume::ARC_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; + } textures.clear(); } } diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 96a170ef07..069642b711 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -2104,6 +2104,30 @@ void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3 thread->start(); } +S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod) +{ + if (mThread) + { + LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); + if (iter != mThread->mMeshHeader.end()) + { + LLSD& header = iter->second; + + if (header.has("404")) + { + return -1; + } + + S32 size = header[header_lod[lod]]["size"].asInteger(); + return size; + } + + } + + return -1; + +} + void LLMeshUploadThread::sendCostRequest(LLMeshUploadData& data) { //write model file to memory buffer diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index d5e21c35cc..b26598ce31 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -405,8 +405,7 @@ public: void uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures); - - + S32 getMeshSize(const LLUUID& mesh_id, S32 lod); typedef std::map<LLVolumeParams, std::set<LLUUID> > mesh_load_map; mesh_load_map mLoadingMeshes[4]; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 0c8a518de0..a6b3c436f4 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -7968,7 +7968,7 @@ void LLVOAvatar::getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& d void LLVOAvatar::idleUpdateRenderCost() { - static const U32 ARC_BODY_PART_COST = 20; + static const U32 ARC_BODY_PART_COST = 200; static const U32 ARC_LIMIT = 2048; static std::set<LLUUID> all_textures; @@ -7979,7 +7979,7 @@ void LLVOAvatar::idleUpdateRenderCost() } U32 cost = 0; - std::set<LLUUID> textures; + LLVOVolume::texture_cost_t textures; for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) { @@ -8017,16 +8017,24 @@ void LLVOAvatar::idleUpdateRenderCost() } } } + } + + 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; + } + // Diagnostic output to identify all avatar-related textures. // Does not affect rendering cost calculation. // Could be wrapped in a debug option if output becomes problematic. if (isSelf()) { // print any attachment textures we didn't already know about. - for (std::set<LLUUID>::iterator it = textures.begin(); it != textures.end(); ++it) + for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it) { - LLUUID image_id = *it; + LLUUID image_id = it->first; if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) continue; if (all_textures.find(image_id) == all_textures.end()) @@ -8057,7 +8065,6 @@ void LLVOAvatar::idleUpdateRenderCost() } } } - cost += textures.size() * LLVOVolume::ARC_TEXTURE_COST; setDebugText(llformat("%d", cost)); F32 green = 1.f-llclamp(((F32) cost-(F32)ARC_LIMIT)/(F32)ARC_LIMIT, 0.f, 1.f); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 0a7611c527..bf4cfc870f 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2872,17 +2872,31 @@ const LLMatrix4 LLVOVolume::getRenderMatrix() const // total cost is returned value + 5 * size of the resulting set. // Cannot include cost of textures, as they may be re-used in linked // children, and cost should only be increased for unique textures -Nyx -U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const +U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const { // base cost of each prim should be 10 points static const U32 ARC_PRIM_COST = 10; + + // get access to params we'll need at various points + LLVolumeParams volume_params = getVolume()->getParams(); + LLPathParams path_params = volume_params.getPathParams(); + LLProfileParams profile_params = volume_params.getProfileParams(); + // per-prim costs static const U32 ARC_INVISI_COST = 1; - static const U32 ARC_SHINY_COST = 1; - static const U32 ARC_GLOW_COST = 1; - static const U32 ARC_FLEXI_COST = 8; static const U32 ARC_PARTICLE_COST = 16; - static const U32 ARC_BUMP_COST = 4; + static const U32 ARC_CUT_COST = 1; + static const U32 ARC_TEXTURE_COST = 5; + + // per-prim multipliers + static const U32 ARC_HOLLOW_MULT = 2; + static const U32 ARC_TWIST_MULT = 2; + static const U32 ARC_CIRC_PROF_MULT = 2; + static const U32 ARC_CIRC_PATH_MULT = 2; + static const U32 ARC_GLOW_MULT = 2; + static const U32 ARC_BUMP_MULT = 2; + static const U32 ARC_FLEXI_MULT = 4; + static const U32 ARC_SHINY_MULT = 2; // per-face costs static const U32 ARC_PLANAR_COST = 1; @@ -2901,6 +2915,61 @@ U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const U32 scale = 0; U32 bump = 0; U32 planar = 0; + U32 cuts = 0; + U32 hollow = 0; + U32 twist = 0; + U32 circular_profile = 0; + U32 circular_path = 0; + + const LLDrawable* drawablep = mDrawable; + + if (isSculpted()) + { + if (isMesh()) + { + // 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(),3); + if ( size > 0) + { + if (gMeshRepo.getSkinInfo(volume_params.getSculptID())) + { + // weighted attachment - 1 point for every 3 bytes + shame = (U32)(size / 3.f); + } + else + { + // non-weighted attachment - 1 point for every 4 bytes + shame = (U32)(size / 4.f); + } + + if (shame == 0) + { + // someone made a really tiny mesh. + shame = 1; + } + } + else + { + // something went wrong - user should know their content isn't render-free + return 0; + } + } + 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 = LLViewerTextureManager::getFetchedTexture(sculpt_id); + if (texture) + { + S32 texture_cost = ARC_TEXTURE_COST * (texture->getFullHeight() / 128 + texture->getFullWidth() / 128 + 1); + textures.insert(texture_cost_t::value_type(sculpt_id, texture_cost)); + } + } + } + } if (isFlexible()) { @@ -2913,14 +2982,63 @@ U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const const LLVector3& sc = getScale(); scale += (U32) sc.mV[0] + (U32) sc.mV[1] + (U32) sc.mV[2]; + if (scale > 4) + { + // scale is a multiplier, cap it at 4. + scale = 4; + } - const LLDrawable* drawablep = mDrawable; + // add points for cut prims + if (path_params.getBegin() != 0.f || path_params.getEnd() != 1.f) + { + ++cuts; + } - if (isSculpted()) + if (profile_params.getBegin() != 0.f || profile_params.getEnd() != 1.f) + { + ++cuts; + } + + // double cost for hollow prims / sculpties + if (volume_params.getHollow() != 0.f) { - const LLSculptParams *sculpt_params = (LLSculptParams *) getParameterEntry(LLNetworkData::PARAMS_SCULPT); - LLUUID sculpt_id = sculpt_params->getSculptTexture(); - textures.insert(sculpt_id); + hollow = 1; + } + + // twist - scale by twist extent / 90 + if (volume_params.getTwistBegin() != 0.f) + { + U32 scale = abs((S32)(volume_params.getTwistBegin() / 90.f) + 1); + twist += scale; + } + + // twist - scale by twist extent / 90 + if (volume_params.getTwist() != 0.f) + { + U32 scale = abs((S32)(volume_params.getTwist() / 90.f) + 1); + twist += scale; + } + + // double cost for circular profiles / sculpties + if (profile_params.getCurveType() == LL_PCODE_PROFILE_CIRCLE || + profile_params.getCurveType() == LL_PCODE_PROFILE_CIRCLE_HALF) + { + circular_profile = 1; + } + + // double cost for circular paths / sculpties + if (path_params.getCurveType() == LL_PCODE_PATH_CIRCLE || + path_params.getCurveType() == LL_PCODE_PATH_CIRCLE2) + { + circular_path = 1; + } + + // treat sculpties as hollow prims with circular paths & profiles + if (isSculpted() && !isMesh()) + { + hollow = 1; + circular_profile = 1; + circular_path = 1; } for (S32 i = 0; i < drawablep->getNumFaces(); ++i) @@ -2931,7 +3049,11 @@ U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const if (img) { - textures.insert(img->getID()); + if (textures.find(img->getID()) == textures.end()) + { + S32 texture_cost = ARC_TEXTURE_COST * (img->getFullHeight() / 128 + img->getFullWidth() / 128 + 1); + textures.insert(texture_cost_t::value_type(img->getID(), texture_cost)); + } } if (face->getPoolType() == LLDrawPool::POOL_ALPHA) @@ -2940,21 +3062,24 @@ U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const } else if (img && img->getPrimaryFormat() == GL_ALPHA) { - invisi = 1; + invisi++; } 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) @@ -2968,17 +3093,63 @@ U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const } } + // shame currently has the "base" cost of 10 for normal prims, variable for mesh - shame += invisi * ARC_INVISI_COST; - shame += shiny * ARC_SHINY_COST; - shame += glow * ARC_GLOW_COST; - shame += alpha * ARC_ALPHA_COST; - shame += flexi * ARC_FLEXI_COST; + // add modifier settings + shame += cuts * ARC_CUT_COST; + shame += planar * ARC_PLANAR_COST; shame += animtex * ARC_ANIM_TEX_COST; + shame += alpha * ARC_ALPHA_COST; + shame += invisi * ARC_INVISI_COST; + + // multiply shame by multipliers + if (hollow) + { + shame *= hollow * ARC_HOLLOW_MULT; + } + + if (twist) + { + shame *= twist * ARC_TWIST_MULT; + } + + if (circular_profile) + { + shame *= circular_profile * ARC_CIRC_PROF_MULT; + } + + if (circular_path) + { + shame *= circular_path * ARC_CIRC_PATH_MULT; + } + + if (glow) + { + shame *= glow * ARC_GLOW_MULT; + } + + if (bump) + { + shame *= bump * ARC_BUMP_MULT; + } + + if (flexi) + { + shame *= flexi * ARC_FLEXI_MULT; + } + + if (shiny) + { + shame *= shiny * ARC_SHINY_MULT; + } + + if (scale) + { + shame *= scale; + } + + // add additional costs shame += particles * ARC_PARTICLE_COST; - shame += bump * ARC_BUMP_COST; - shame += planar * ARC_PLANAR_COST; - shame += scale; LLViewerObject::const_child_list_t& child_list = getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index f97214295a..eeb98726c9 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -120,7 +120,8 @@ public: const LLMatrix4& getRelativeXform() const { return mRelativeXform; } const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; } /*virtual*/ const LLMatrix4 getRenderMatrix() const; - U32 getRenderCost(std::set<LLUUID> &textures) const; + typedef std::map<LLUUID, S32> texture_cost_t; + U32 getRenderCost(texture_cost_t &textures) const; /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face = -1, // which face to check, -1 = ALL_SIDES @@ -330,8 +331,6 @@ public: static LLPointer<LLObjectMediaDataClient> sObjectMediaClient; static LLPointer<LLObjectMediaNavigateClient> sObjectMediaNavigateClient; - static const U32 ARC_TEXTURE_COST = 5; - protected: static S32 sNumLODChanges; |