Improvements to the auto tuning fps

master
Beq 2021-09-26 00:08:26 +01:00
parent 35410bdeb6
commit af4fe2fd2d
6 changed files with 86 additions and 38 deletions

View File

@ -587,7 +587,8 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
// if (oa == LLVOAvatar::AOA_INVISIBLE ||
// (impostor && oa == LLVOAvatar::AOA_JELLYDOLL))
// Note: Impostors should not cast shadows, also all JDs are impostor nowadays so we do not need the extra check at all.
if (impostor || (oa == LLVOAvatar::AOA_INVISIBLE) )
// also no shadows if the shadows are causing this avatar to breach the limit.
if ( avatarp->isTooSlow(true) || impostor || (oa == LLVOAvatar::AOA_INVISIBLE) )
// </FS:Beq>
{
// No shadows for jellydolled or invisible avs.

View File

@ -472,7 +472,8 @@ void LLFloaterPerformance::populateNearbyList()
// S32 complexity_short = llmax((S32)avatar->getVisualComplexity() / 1000, 1);
auto render_av = FSTelemetry::RecordObjectTime<const LLVOAvatar*>::get(avatar,FSTelemetry::ObjStatType::RENDER_COMBINED);
auto is_slow = avatar->isTooSlow();
auto is_slow = avatar->isTooSlow(true);
// auto is_slow_without_shadows = avatar->isTooSlow();
LLSD item;
item["id"] = avatar->getID();

View File

@ -2879,9 +2879,17 @@ void LLAvatarComplexityControls::updateMaxRenderTime(LLSliderCtrl* slider, LLTex
// Called when the IndirectMaxComplexity control changes
// Responsible for fixing the slider label (IndirectMaxComplexityText) and setting RenderAvatarMaxComplexity
auto indirect_value = slider->getValue().asReal();
gSavedSettings.setF32("RenderAvatarMaxART", indirect_value);
setRenderTimeText(indirect_value, value_label, short_val);
if(indirect_value == slider->getMaxValue())
{
LLVOAvatar::sRenderTimeCap_ns = 0;
setRenderTimeText(0.0, value_label, short_val);
}
else
{
LLVOAvatar::sRenderTimeCap_ns = llround(indirect_value * 1000000);
setRenderTimeText(indirect_value, value_label, short_val);
}
}
void LLAvatarComplexityControls::setRenderTimeText(F32 value, LLTextBox* text_box, bool short_val)

View File

@ -601,7 +601,7 @@ bool LLVOAvatar::sLimitNonImpostors = false; // True unless RenderAvatarMaxNonIm
F32 LLVOAvatar::sRenderDistance = 256.f;
S32 LLVOAvatar::sNumVisibleAvatars = 0;
S32 LLVOAvatar::sNumLODChangesThisFrame = 0;
U64 LLVOAvatar::sRenderTimeCap_ns {0};
// const LLUUID LLVOAvatar::sStepSoundOnLand("e8af4a28-aa83-4310-a7c4-c047e15ea0df"); - <FS:PP> Commented out for FIRE-3169: Option to change the default footsteps sound
const LLUUID LLVOAvatar::sStepSounds[LL_MCODE_END] =
{
@ -4696,7 +4696,7 @@ void LLVOAvatar::updateFootstepSounds()
void LLVOAvatar::computeUpdatePeriod()
{
bool visually_muted = isVisuallyMuted();
bool slow = isTooSlow();
bool slow = isTooSlow();// the geometry alone is forcing this to be slow so we must imposter
if (mDrawable.notNull()
&& slow
&& isVisible()
@ -9124,37 +9124,71 @@ BOOL LLVOAvatar::isFullyLoaded() const
}
// <FS:Beq> use Avatar Render Time as complexity metric
void LLVOAvatar::markARTStale()
{
// mark stale and set the frameupdate to now so that we can wait at least one frame.
mARTStale=true;
mLastARTUpdateFrame = LLFrameTimer::getFrameCount();
}
// default will test only the geometry (combined=false).
// this allows us to disable shadows separately on complex avatars.
//virtual
bool LLVOAvatar::isTooSlow() const
bool LLVOAvatar::isTooSlow(bool combined) const
{
static LLCachedControl<bool> use_render_time(gSavedSettings, "RenderAvatarUseART");
auto now = LLTimer::getElapsedSeconds();
if( ( mLastARTTime > 0 ) && ( now > (mLastARTTime + 2.0) ) ) //TODO(Beq) make this a constant. how frequently do we decloak to refresh the render time
auto abuse_constness = const_cast<LLVOAvatar*>(this);
if( mARTStale )
{
// LL_INFOS() << this->getFullname() << " timer expired need refresh mLastARTTime=" << mLastARTTime << " time now="<<now << "("<<now-mLastARTTime<< ")" << LL_ENDL;
// cached ART is stale
const_cast<LLVOAvatar*>(this)->mLastARTTime = 0;
return false; // force a render
}
else if (mLastARTTime == 0)
{
static LLCachedControl<F32> render_time_cap(gSavedSettings, "RenderAvatarMaxART");
auto render_time = FSTelemetry::RecordObjectTime<const LLVOAvatar*>::get(this,FSTelemetry::ObjStatType::RENDER_COMBINED);
if( (render_time_cap > 0.0) && (render_time >= llround(render_time_cap*1000000)) )
if (LLFrameTimer::getFrameCount() - mLastARTUpdateFrame < 2 )
{
const_cast<LLVOAvatar*>(this)->mLastARTTime = gFrameTimeSeconds;
const_cast<LLVOAvatar*>(this)->mLastART = render_time;
// LL_INFOS() << this->getFullname() << " (imposter) mLastART too high =" << mLastART << " vs ("<< llround(render_time_cap*1000000) << " set @ " << mLastARTTime << LL_ENDL;
return true;
}
else
{
// LL_INFOS() << this->getFullname() << " good render time " << LL_ENDL;
LL_INFOS() << this->getFullname() << " marked stale " << LL_ENDL;
// we've not had a chance to update yet (allow now+1 to be certain a full frame has passed)
return false;
}
abuse_constness->mARTStale = false;
abuse_constness->mARTCapped = false;
LL_INFOS() << this->getFullname() << " refreshed ART combined = " << mRenderTime << " @ " << mLastARTUpdateFrame << LL_ENDL;
}
// timer has not expired and time is non zero so must be true.
return true;
// Either we're not stale or we've updated.
U64 render_time;
U64 render_geom_time;
if(!mARTCapped)
{
// no cap, so we use the live values
render_time = FSTelemetry::RecordObjectTime<const LLVOAvatar*>::get(this,FSTelemetry::ObjStatType::RENDER_COMBINED);
render_geom_time = FSTelemetry::RecordObjectTime<const LLVOAvatar*>::get(this,FSTelemetry::ObjStatType::RENDER_GEOMETRY);
}
else
{
// use the cached values.
render_time = mRenderTime;
render_geom_time = mGeomTime;
}
if( (LLVOAvatar::sRenderTimeCap_ns > 0) && (render_time >= LLVOAvatar::sRenderTimeCap_ns) )
{
if(!mARTCapped)
{
// if we weren't capped, we are now
abuse_constness->mRenderTime = FSTelemetry::RecordObjectTime<const LLVOAvatar*>::get(this,FSTelemetry::ObjStatType::RENDER_COMBINED);
abuse_constness->mGeomTime = FSTelemetry::RecordObjectTime<const LLVOAvatar*>::get(this,FSTelemetry::ObjStatType::RENDER_GEOMETRY);
abuse_constness->mARTStale = false;
abuse_constness->mARTCapped = true;
abuse_constness->mLastARTUpdateFrame = LLFrameTimer::getFrameCount();
LL_INFOS() << this->getFullname() << " ("<< (combined?"combined":"geometry") << ") mLastART too high = " << render_time << " vs ("<< LLVOAvatar::sRenderTimeCap_ns << " set @ " << mLastARTUpdateFrame << LL_ENDL;
}
// return true only if that is the case in the context of the combined/geom_only flag.
return combined ? true : (render_geom_time >= LLVOAvatar::sRenderTimeCap_ns);
}
LL_INFOS() << this->getFullname() << " ("<< (combined?"combined":"geometry") << ") good render time = " << render_time << " vs ("<< LLVOAvatar::sRenderTimeCap_ns << " set @ " << mLastARTUpdateFrame << LL_ENDL;
abuse_constness->mARTCapped = false;
return false;
}
// </FS:Beq>
@ -11452,10 +11486,9 @@ BOOL LLVOAvatar::isImpostor()
{
return (
isVisuallyMuted() ||
(
(sLimitNonImpostors || isTooSlow() ) &&
(mUpdatePeriod > 1)
);
( (sLimitNonImpostors || isTooSlow(false) ) &&
(mUpdatePeriod > 1) )
);
}
BOOL LLVOAvatar::shouldImpostor(const F32 rank_factor)
@ -11470,7 +11503,7 @@ BOOL LLVOAvatar::shouldImpostor(const F32 rank_factor)
}
static LLCachedControl<bool> render_jellys_As_imposters(gSavedSettings, "RenderJellyDollsAsImpostors");
if (isTooSlow() && render_jellys_As_imposters)
if (isTooSlow(false) && render_jellys_As_imposters)
{
return true;
}

View File

@ -355,6 +355,7 @@ public:
static F32 sPhysicsLODFactor; // user-settable physics LOD factor
static BOOL sJointDebug; // output total number of joints being touched for each avatar
static BOOL sDebugAvatarRotation;
static U64 sRenderTimeCap_ns; // nanosecond time limit for avatar rendering 0 is unlimited.
static LLPartSysData sCloud;
//--------------------------------------------------------------------
@ -368,7 +369,7 @@ public:
//--------------------------------------------------------------------
public:
BOOL isFullyLoaded() const;
virtual bool isTooSlow() const;
virtual bool isTooSlow(bool combined = false) const;
virtual bool isTooComplex() const; // <FS:Ansariel> FIRE-29012: Standalone animesh avatars get affected by complexity limit; changed to virtual
bool visualParamWeightsAreDefault();
virtual bool getIsCloud() const;
@ -390,6 +391,7 @@ public:
void logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed);
void calcMutedAVColor();
void markARTStale();
protected:
LLViewerStats::PhaseMap& getPhases() { return mPhases; }
@ -407,8 +409,11 @@ private:
LLColor4 mMutedAVColor;
LLFrameTimer mFullyLoadedTimer;
LLFrameTimer mRuthTimer;
F64SecondsImplicit mLastARTTime{0};
U64 mLastART{0};
U32 mLastARTUpdateFrame{0};
U64 mRenderTime{0};
U64 mGeomTime{0};
bool mARTStale{true};
bool mARTCapped{false};
private:
LLViewerStats::PhaseMap mPhases;
@ -1192,7 +1197,7 @@ public:
// COF version of last appearance message received for this av.
S32 mLastUpdateReceivedCOFVersion;
U64 getLastART() const { return mLastART; }
U64 getLastART() const { return mRenderTime; }
/** Diagnostics
** **

View File

@ -101,7 +101,7 @@
label_width="165"
layout="topleft"
min_val="0.01"
max_val="10.0"
max_val="50.0"
name="RenderAvatarMaxART"
show_text="false"
left_delta="-304"