diff options
-rw-r--r-- | indra/newview/llface.cpp | 6 | ||||
-rw-r--r-- | indra/newview/llviewerobject.cpp | 16 | ||||
-rw-r--r-- | indra/newview/llviewerobject.h | 2 | ||||
-rw-r--r-- | indra/newview/llvoavatar.cpp | 275 | ||||
-rw-r--r-- | indra/newview/llvoavatar.h | 9 | ||||
-rw-r--r-- | indra/newview/llvovolume.cpp | 61 | ||||
-rw-r--r-- | indra/newview/llvovolume.h | 5 |
7 files changed, 227 insertions, 147 deletions
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 3d5e2d356e..eebdb62aff 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -330,11 +330,7 @@ void LLFace::dirtyTexture() { vobj->mLODChanged = TRUE; - LLVOAvatar* avatar = vobj->getAvatar(); - if (avatar) - { //avatar render cost may have changed - avatar->updateVisualComplexity(); - } + vobj->updateVisualComplexity(); } gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE); } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 616db8ae2f..94e1390c42 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -3627,6 +3627,22 @@ U32 LLViewerObject::getHighLODTriangleCount() return 0; } +U32 LLViewerObject::recursiveGetTriangleCount(S32* vcount) const +{ + S32 total_tris = getTriangleCount(vcount); + LLViewerObject::const_child_list_t& child_list = getChildren(); + for (LLViewerObject::const_child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); ++iter) + { + LLViewerObject* childp = *iter; + if (childp) + { + total_tris += childp->getTriangleCount(vcount); + } + } + return total_tris; +} + void LLViewerObject::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) { LLVector4a center; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 345fd1fb27..a84b6da96c 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -364,6 +364,8 @@ public: virtual U32 getTriangleCount(S32* vcount = NULL) const; virtual U32 getHighLODTriangleCount(); + U32 recursiveGetTriangleCount(S32* vcount = NULL) const; + void setObjectCost(F32 cost); F32 getObjectCost(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 0fcb4ffc55..d5301c38ba 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -620,6 +620,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, LLViewerObject(id, pcode, regionp), mSpecialRenderMode(0), mAttachmentSurfaceArea(0.f), + mAttachmentVisibleTriangleCount(0), + mAttachmentEstTriangleCount(0.f), mReportedVisualComplexity(VISUAL_COMPLEXITY_UNKNOWN), mTurning(FALSE), mLastSkeletonSerialNum( 0 ), @@ -9167,8 +9169,13 @@ void LLVOAvatar::idleUpdateRenderComplexity() { if (isControlAvatar()) { - // ARC for animated object attachments is accounted with the avatar they're attached to. - return; + LLControlAvatar *cav = dynamic_cast<LLControlAvatar*>(this); + bool is_attachment = cav && cav->mRootVolp && cav->mRootVolp->isAttachment(); // For attached animated objects + if (is_attachment) + { + // ARC for animated object attachments is accounted with the avatar they're attached to. + return; + } } // Render Complexity @@ -9218,10 +9225,14 @@ void LLVOAvatar::idleUpdateRenderComplexity() // Visual rank info_line = llformat("%d rank", mVisibilityRank); // Use grey for imposters, white for normal rendering or no impostors - info_color.set(isImpostor() ? LLColor4::grey : LLColor4::white); + info_color.set(isImpostor() ? LLColor4::grey : (isControlAvatar() ? LLColor4::yellow : LLColor4::white)); info_style = LLFontGL::NORMAL; mText->addLine(info_line, info_color, info_style); + // Triangle count + mText->addLine(llformat("Tris %u",mAttachmentVisibleTriangleCount), info_color, info_style); + mText->addLine(llformat("Est Tris %f",mAttachmentEstTriangleCount), info_color, info_style); + // Attachment Surface Area static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit", 1000.0f); info_line = llformat("%.0f m^2", mAttachmentSurfaceArea); @@ -9263,6 +9274,133 @@ 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. +void LLVOAvatar::accountRenderComplexityForObject( + const LLViewerObject *attached_object, + const F32 max_attachment_complexity, + LLVOVolume::texture_cost_t& textures, + U32& cost, + hud_complexity_list_t& hud_complexity_list) +{ + if (attached_object && !attached_object->isHUDAttachment()) + { + mAttachmentVisibleTriangleCount += attached_object->recursiveGetTriangleCount(); + mAttachmentEstTriangleCount += attached_object->recursiveGetEstTrianglesMax(); + + 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; + // AXON placeholder value, will revisit in testing. + const F32 animated_object_attachment_surcharge = 20000; + + if (attached_object->isAnimatedObject()) + { + attachment_volume_cost += animated_object_attachment_surcharge; + } + 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); + } + } + + 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: " << 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() + && attached_object + && attached_object->isHUDAttachment() + && !attached_object->isTempAttachment() + && attached_object->mDrawable) + { + textures.clear(); + + 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; + 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++; + } + } + + 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); + } + } +} + // Calculations for mVisualComplexity value void LLVOAvatar::calculateUpdateRenderComplexity() { @@ -9301,7 +9439,24 @@ void LLVOAvatar::calculateUpdateRenderComplexity() } LL_DEBUGS("ARCdetail") << "Avatar body parts complexity: " << cost << LL_ENDL; + mAttachmentVisibleTriangleCount = 0; + mAttachmentEstTriangleCount = 0.f; + + // A standalone animated object needs to be accounted for + // using its associated volume. Attached animated objects + // will be covered by the subsequent loop over attachments. + LLControlAvatar *control_av = dynamic_cast<LLControlAvatar*>(this); + if (control_av) + { + LLVOVolume *volp = control_av->mRootVolp; + if (volp && !volp->isAttachment()) + { + accountRenderComplexityForObject(volp, max_attachment_complexity, + textures, cost, hud_complexity_list); + } + } + // Account for complexity of all attachments. for (attachment_map_t::const_iterator attachment_point = mAttachmentPoints.begin(); attachment_point != mAttachmentPoints.end(); ++attachment_point) @@ -9312,118 +9467,8 @@ void LLVOAvatar::calculateUpdateRenderComplexity() ++attachment_iter) { const LLViewerObject* attached_object = (*attachment_iter); - if (attached_object && !attached_object->isHUDAttachment()) - { - 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; - // AXON placeholder value, will revisit in testing. - const F32 animated_object_attachment_surcharge = 20000; - - if (attached_object->isAnimatedObject()) - { - attachment_volume_cost += animated_object_attachment_surcharge; - } - 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); - } - } - - 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: " << 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() - && attached_object - && attached_object->isHUDAttachment() - && !attached_object->isTempAttachment() - && attached_object->mDrawable) - { - textures.clear(); - - 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; - 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++; - } - } - - 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); - } - } + accountRenderComplexityForObject(attached_object, max_attachment_complexity, + textures, cost, hud_complexity_list); } } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 5a40a45eae..5f7d23050e 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -50,6 +50,8 @@ #include "llviewertexlayer.h" #include "material_codes.h" // LL_MCODE_END #include "llviewerstats.h" +#include "llvovolume.h" +#include "llavatarrendernotifier.h" extern const LLUUID ANIM_AGENT_BODY_NOISE; extern const LLUUID ANIM_AGENT_BREATHE_ROT; @@ -268,6 +270,11 @@ public: static void invalidateNameTags(); void addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font); void idleUpdateRenderComplexity(); + void accountRenderComplexityForObject(const LLViewerObject *attached_object, + const F32 max_attachment_complexity, + LLVOVolume::texture_cost_t& textures, + U32& cost, + hud_complexity_list_t& hud_complexity_list); void calculateUpdateRenderComplexity(); static const U32 VISUAL_COMPLEXITY_UNKNOWN; void updateVisualComplexity(); @@ -431,6 +438,8 @@ public: private: F32 mAttachmentSurfaceArea; //estimated surface area of attachments + U32 mAttachmentVisibleTriangleCount; + F32 mAttachmentEstTriangleCount; bool shouldAlphaMask(); BOOL mNeedsSkin; // avatar has been animated and verts have not been updated diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index efddc9235e..7fec240d1b 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1103,16 +1103,26 @@ void LLVOVolume::updateSculptTexture() } +void LLVOVolume::updateVisualComplexity() +{ + LLVOAvatar* avatar = getAvatarAncestor(); + if (avatar) + { + avatar->updateVisualComplexity(); + } + LLVOAvatar* rigged_avatar = getAvatar(); + if(rigged_avatar && (rigged_avatar != avatar)) + { + rigged_avatar->updateVisualComplexity(); + } +} + void LLVOVolume::notifyMeshLoaded() { mSculptChanged = TRUE; gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, TRUE); - LLVOAvatar* avatar = getAvatar(); - if (avatar) - { - avatar->updateVisualComplexity(); - } + updateVisualComplexity(); } // sculpt replaces generate() for sculpted surfaces @@ -1302,18 +1312,7 @@ BOOL LLVOVolume::calcLOD() { if (isRootEdit() && getChildren().size()>0) { - S32 total_tris = getTriangleCount(); - LLViewerObject::const_child_list_t& child_list = getChildren(); - for (LLViewerObject::const_child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); ++iter) - { - LLViewerObject* childp = *iter; - LLVOVolume *child_volp = dynamic_cast<LLVOVolume*>(childp); - if (child_volp) - { - total_tris += child_volp->getTriangleCount(); - } - } + S32 total_tris = recursiveGetTriangleCount(); setDebugText(llformat("TRIS %d TOTAL %d", getTriangleCount(), total_tris)); } else @@ -1333,7 +1332,8 @@ BOOL LLVOVolume::calcLOD() { mAppAngle = ll_round((F32) atan2( mDrawable->getRadius(), mDrawable->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f); mLOD = cur_detail; - return TRUE; + + return TRUE; } return FALSE; @@ -1691,6 +1691,11 @@ bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled) if ((new_lod != old_lod) || mSculptChanged) { + if (mDrawable->isState(LLDrawable::RIGGED)) + { + updateVisualComplexity(); + } + compiled = TRUE; sNumLODChanges += new_num_faces; @@ -3342,7 +3347,7 @@ void LLVOVolume::setExtendedMeshFlags(U32 flags) parameterChanged(LLNetworkData::PARAMS_EXTENDED_MESH, true); if (isAttachment() && getAvatarAncestor()) { - getAvatarAncestor()->updateVisualComplexity(); + updateVisualComplexity(); if (flags & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG) { // Making a rigged mesh into an animated object @@ -3392,7 +3397,7 @@ bool LLVOVolume::isAnimatedObject() const if (root_is_animated_flag) { bool root_can_be_animated = root_vol->canBeAnimatedObject(); - bool this_can_be_animated = ((root_vol == this) && root_can_be_animated) || canBeAnimatedObject(); + bool this_can_be_animated = (root_vol == this) ? root_can_be_animated : canBeAnimatedObject(); if (this_can_be_animated && root_can_be_animated) { return true; @@ -4923,25 +4928,29 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) group->mBuilt = 1.f; LLVOAvatar* pAvatarVO = NULL; + LLVOAvatar *attached_av = NULL; LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge(); if (bridge) { + LLViewerObject* vobj = bridge->mDrawable->getVObj(); if (bridge->mAvatar.isNull()) { - LLViewerObject* vobj = bridge->mDrawable->getVObj(); if (vobj) { bridge->mAvatar = vobj->getAvatar(); } } - + if (vobj) + { + attached_av = vobj->getAvatarAncestor(); + } pAvatarVO = bridge->mAvatar; } - if (pAvatarVO) + if (attached_av) { - pAvatarVO->subtractAttachmentArea( group->mSurfaceArea ); + attached_av->subtractAttachmentArea( group->mSurfaceArea ); } group->mGeometryBytes = 0; @@ -5518,9 +5527,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) mFaceList.clear(); - if (pAvatarVO) + if (attached_av) { - pAvatarVO->addAttachmentArea( group->mSurfaceArea ); + attached_av->addAttachmentArea( group->mSurfaceArea ); } } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 24bcf41c74..bc8fa9a3d3 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -315,7 +315,10 @@ public: bool hasMedia() const; LLVector3 getApproximateFaceNormal(U8 face_id); - + + // Flag any corresponding avatars as needing update. + void updateVisualComplexity(); + void notifyMeshLoaded(); // Returns 'true' iff the media data for this object is in flight |