diff options
Diffstat (limited to 'indra/newview')
| -rw-r--r-- | indra/newview/llappviewer.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llfloaterperformance.cpp | 11 | ||||
| -rw-r--r-- | indra/newview/llperfstats.cpp | 67 | ||||
| -rw-r--r-- | indra/newview/llperfstats.h | 68 | ||||
| -rw-r--r-- | indra/newview/llviewerstats.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.cpp | 146 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.h | 30 | ||||
| -rw-r--r-- | indra/newview/llworld.cpp | 6 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 42 | 
9 files changed, 201 insertions, 173 deletions
| diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 6efbaeacf7..c9fc0e2cc8 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4698,6 +4698,8 @@ void LLAppViewer::idle()  	LLFrameTimer::updateFrameTime();  	LLFrameTimer::updateFrameCount();  	LLEventTimer::updateClass(); +    LLPerfStats::updateClass(); +  	// LLApp::stepFrame() performs the above three calls plus mRunner.run().  	// Not sure why we don't call stepFrame() here, except that LLRunner seems  	// completely redundant with LLEventTimer. diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp index 8c5745aa43..19fc3e673e 100644 --- a/indra/newview/llfloaterperformance.cpp +++ b/indra/newview/llfloaterperformance.cpp @@ -456,15 +456,8 @@ void LLFloaterPerformance::populateNearbyList()              row[1]["column"] = "complex_value";              row[1]["type"] = "text"; -            if (is_slow && !showTunedART) -            { -                row[1]["value"] = llformat( "%.f", LLPerfStats::raw_to_us( avatar->getLastART() ) ); -            } -            else -            { -                // use GPU time in us -                row[1]["value"] = llformat( "%.f", render_av_gpu_ms * 1000.f); -            } +            // use GPU time in us +            row[1]["value"] = llformat( "%.f", render_av_gpu_ms * 1000.f);              row[1]["font"]["name"] = "SANSSERIF";              row[3]["column"] = "name"; diff --git a/indra/newview/llperfstats.cpp b/indra/newview/llperfstats.cpp index b680d8761b..2281475d4a 100644 --- a/indra/newview/llperfstats.cpp +++ b/indra/newview/llperfstats.cpp @@ -39,6 +39,11 @@ extern LLControlGroup gSavedSettings;  namespace LLPerfStats  { +    // avatar timing metrics in ms (updated once per mainloop iteration) +    std::atomic<F32> sTotalAvatarTime = 0.f; +    std::atomic<F32> sAverageAvatarTime = 0.f; +    std::atomic<F32> sMaxAvatarTime = 0.f; +      std::atomic<int64_t> tunedAvatars{0};      std::atomic<U64> renderAvatarMaxART_ns{(U64)(ART_UNLIMITED_NANOS)}; // highest render time we'll allow without culling features      bool belowTargetFPS{false}; @@ -141,14 +146,12 @@ namespace LLPerfStats          resetChanges();      } -    StatsRecorder::StatsRecorder():q(1024*16),t(&StatsRecorder::run) +    StatsRecorder::StatsRecorder():q(1024*16)      {          // create a queue -        // create a thread to consume from the queue          tunables.initialiseFromSettings();          LLPerfStats::cpu_hertz = (F64)LLTrace::BlockTimer::countsPerSecond();          LLPerfStats::vsync_max_fps = gViewerWindow->getWindow()->getRefreshRate(); -        t.detach();      }      // static @@ -200,20 +203,6 @@ namespace LLPerfStats              }          } -        auto& statsMapAv = statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_AVATAR)]; -        for(auto& stat_entry : statsMapAv) -        { -            for(auto& stat : avatarStatsToAvg) -            { -                auto val = stat_entry.second[static_cast<size_t>(stat)]; -                if(val > SMOOTHING_PERIODS) -                { -                    auto avg = statsDoubleBuffer[writeBuffer ^ 1][static_cast<size_t>(ObjType_t::OT_AVATAR)][stat_entry.first][static_cast<size_t>(stat)]; -                    stat_entry.second[static_cast<size_t>(stat)] = avg + (val / SMOOTHING_PERIODS) - (avg / SMOOTHING_PERIODS); -                } -            } -        } -          // swap the buffers          if(enabled())          { @@ -293,6 +282,36 @@ namespace LLPerfStats          }      } +    // called once per main loop iteration on main thread +    void updateClass() +    { +        LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; +         +        sTotalAvatarTime = LLVOAvatar::getTotalGPURenderTime(); +        sAverageAvatarTime = LLVOAvatar::getAverageGPURenderTime(); +        sMaxAvatarTime = LLVOAvatar::getMaxGPURenderTime(); + +        auto& general = LL::WorkQueue::getInstance("General"); + +        if (general) +        { +            general->post([] { StatsRecorder::update(); }); +        } +    } + +    // called once per main loop iteration on General thread +    void StatsRecorder::update() +    { +        LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; +        StatsRecord upd; +        auto& instance{ StatsRecorder::getInstance() }; + +        while (enabled() && !LLApp::isQuitting() && instance.q.tryPop(upd)) +        { +            instance.processUpdate(upd); +        } +    } +      //static      int StatsRecorder::countNearbyAvatars(S32 distance)      { @@ -327,6 +346,8 @@ namespace LLPerfStats      // static      void StatsRecorder::updateAvatarParams()      { +        LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; +          if(tunables.autoTuneTimeout)          {              LLPerfStats::lastSleepedFrame = gFrameCount; @@ -380,10 +401,10 @@ namespace LLPerfStats              }          } -        auto av_render_max_raw = LLPerfStats::StatsRecorder::getMax(ObjType_t::OT_AVATAR, LLPerfStats::StatType_t::RENDER_COMBINED); +        auto av_render_max_raw = ms_to_raw(sMaxAvatarTime);          // Is our target frame time lower than current? If so we need to take action to reduce draw overheads.          // cumulative avatar time (includes idle processing, attachments and base av) -        auto tot_avatar_time_raw = LLPerfStats::StatsRecorder::getSum(ObjType_t::OT_AVATAR, LLPerfStats::StatType_t::RENDER_COMBINED); +        auto tot_avatar_time_raw = ms_to_raw(sTotalAvatarTime);           // The frametime budget we have based on the target FPS selected          auto target_frame_time_raw = (U64)llround(LLPerfStats::cpu_hertz / (target_fps == 0 ? 1 : target_fps)); @@ -417,7 +438,7 @@ namespace LLPerfStats              // if so we've got work to do              // how much of the frame was spent on non avatar related work? -            U64 non_avatar_time_raw = tot_frame_time_raw - tot_avatar_time_raw; +            U64 non_avatar_time_raw = tot_frame_time_raw > tot_avatar_time_raw ? tot_frame_time_raw - tot_avatar_time_raw : 0;              // If the target frame time < scene time (estimated as non_avatar time)              U64 target_avatar_time_raw; @@ -475,7 +496,11 @@ namespace LLPerfStats                  {                      new_render_limit_ns = renderAvatarMaxART_ns;                  } -                new_render_limit_ns -= LLPerfStats::ART_MIN_ADJUST_DOWN_NANOS; + +                if (new_render_limit_ns > LLPerfStats::ART_MIN_ADJUST_DOWN_NANOS) +                { +                    new_render_limit_ns -= LLPerfStats::ART_MIN_ADJUST_DOWN_NANOS; +                }                  // bounce at the bottom to prevent "no limit"                   new_render_limit_ns = std::max((U64)new_render_limit_ns, (U64)LLPerfStats::ART_MINIMUM_NANOS); diff --git a/indra/newview/llperfstats.h b/indra/newview/llperfstats.h index a4768272b9..bb5677f237 100644 --- a/indra/newview/llperfstats.h +++ b/indra/newview/llperfstats.h @@ -42,6 +42,10 @@ extern U32 gFrameCount;  extern LLUUID gAgentID;  namespace LLPerfStats  { + +    // called once per main loop iteration +    void updateClass(); +  // Note if changing these, they should correspond with the log range of the correpsonding sliders      static constexpr U64 ART_UNLIMITED_NANOS{50000000};      static constexpr U64 ART_MINIMUM_NANOS{100000}; @@ -68,7 +72,6 @@ namespace LLPerfStats      enum class ObjType_t{          OT_GENERAL=0, // Also Unknown. Used for n/a type stats such as scenery -        OT_AVATAR,          OT_COUNT      };      enum class StatType_t{ @@ -162,6 +165,9 @@ namespace LLPerfStats          using Queue = LLThreadSafeQueue<StatsRecord>;      public: +        // called once per main loop iteration on General thread +        static void update(); +          static inline StatsRecorder& getInstance()          {              static StatsRecorder instance; @@ -241,7 +247,6 @@ namespace LLPerfStats              auto ot{upd.objType};              auto& key{upd.objID}; -            auto& avKey{upd.avID};              auto type {upd.statType};              auto val {upd.time}; @@ -251,13 +256,6 @@ namespace LLPerfStats                  doUpd(key, ot, type,val);                  return;              } - -            if (ot == ObjType_t::OT_AVATAR) -            { -                // LL_INFOS("perfstats") << "Avatar update:" << LL_ENDL; -                doUpd(avKey, ot, type, val); -                return; -            }          }          static inline void doUpd(const LLUUID& key, ObjType_t ot, StatType_t type, uint64_t val) @@ -286,42 +284,7 @@ namespace LLPerfStats          static void toggleBuffer();          static void clearStatsBuffers(); -        // thread entry -        static void run() -        { -            StatsRecord upd[10]; -            auto & instance {StatsRecorder::getInstance()}; -            LL_PROFILER_SET_THREAD_NAME("PerfStats"); - -            while( enabled() && !LLApp::isExiting() ) -            { -                auto count = 0; -                while (count < 10) -                { -                    if (instance.q.tryPopFor(std::chrono::milliseconds(10), upd[count])) -                    { -                        count++; -                    } -                    else -                    { -                        break; -                    } -                } -                //LL_PROFILER_THREAD_BEGIN("PerfStats"); -                if(count) -                { -                    // LL_INFOS("perfstats") << "processing " << count << " updates." << LL_ENDL; -                    for(auto i =0; i < count; i++) -                    { -                        instance.processUpdate(upd[i]); -                    } -                } -                //LL_PROFILER_THREAD_END("PerfStats"); -            } -        } -          Queue q; -        std::thread t;          ~StatsRecorder() = default;          StatsRecorder(const StatsRecorder&) = delete; @@ -354,13 +317,6 @@ namespace LLPerfStats              LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;          }; -        template < ObjType_t OD = ObjTypeDiscriminator, -                   std::enable_if_t<OD == ObjType_t::OT_AVATAR> * = nullptr> -        RecordTime( const LLUUID & av, StatType_t type ):RecordTime<ObjTypeDiscriminator>(std::move(av), LLUUID::null, type) -        { -            //LL_PROFILE_ZONE_COLOR(tracy::Color::Purple); -        }; -          ~RecordTime()          {               if(!LLPerfStats::StatsRecorder::enabled()) @@ -375,13 +331,19 @@ namespace LLPerfStats          };      }; -     +      inline double raw_to_ns(U64 raw)    { return (static_cast<double>(raw) * 1000000000.0) / LLPerfStats::cpu_hertz; };      inline double raw_to_us(U64 raw)    { return (static_cast<double>(raw) *    1000000.0) / LLPerfStats::cpu_hertz; };      inline double raw_to_ms(U64 raw)    { return (static_cast<double>(raw) *       1000.0) / LLPerfStats::cpu_hertz; }; +    inline U64 ns_to_raw(double ns)     { return (U64)(LLPerfStats::cpu_hertz * (ns / 1000000000.0)); } +    inline U64 us_to_raw(double us)     { return (U64)(LLPerfStats::cpu_hertz * (us / 1000000.0)); } +    inline U64 ms_to_raw(double ms)     { return (U64)(LLPerfStats::cpu_hertz * (ms / 1000.0)); + +    } +     +      using RecordSceneTime = RecordTime<ObjType_t::OT_GENERAL>; -    using RecordAvatarTime = RecordTime<ObjType_t::OT_AVATAR>;  };// namespace LLPerfStats diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 609e8290da..37999e58ff 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -472,7 +472,7 @@ void update_statistics()              auto tot_frame_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FRAME);              // cumulative avatar time (includes idle processing, attachments and base av) -            auto tot_avatar_time_raw = LLPerfStats::StatsRecorder::getSum(LLPerfStats::ObjType_t::OT_AVATAR, LLPerfStats::StatType_t::RENDER_COMBINED); +            auto tot_avatar_time_raw = LLPerfStats::us_to_raw(LLVOAvatar::getTotalGPURenderTime());              // cumulative avatar render specific time (a bit arbitrary as the processing is too.)              // auto tot_av_idle_time_raw = LLPerfStats::StatsRecorder::getSum(AvType, LLPerfStats::StatType_t::RENDER_IDLE);              // auto tot_avatar_render_time_raw = tot_avatar_time_raw - tot_av_idle_time_raw; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 95e9321d6f..af65588709 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2562,7 +2562,6 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)  		return;  	}      // record time and refresh "tooSlow" status -    LLPerfStats::RecordAvatarTime T(getID(), LLPerfStats::StatType_t::RENDER_IDLE); // per avatar "idle" time.      updateTooSlow();  	static LLCachedControl<bool> disable_all_render_types(gSavedSettings, "DisableAllRenderTypes"); @@ -8310,14 +8309,6 @@ bool LLVOAvatar::isTooSlow() const      return mTooSlow;  } -// use Avatar Render Time as complexity metric -// markARTStale - Mark stale and set the frameupdate to now so that we can wait at least one frame to get a revised number. -void LLVOAvatar::markARTStale() -{ -    mARTStale=true; -    mLastARTUpdateFrame = LLFrameTimer::getFrameCount(); -} -  // Udpate Avatar state based on render time  void LLVOAvatar::updateTooSlow()  { @@ -8328,41 +8319,9 @@ void LLVOAvatar::updateTooSlow()      // mTooSlow - Is the avatar flagged as being slow (includes shadow time)      // mTooSlowWithoutShadows - Is the avatar flagged as being slow even with shadows removed. -    // mARTStale - the rendertime we have is stale because of an update. We need to force a re-render to re-assess slowness - -    if( mARTStale ) -    { -        if ( LLFrameTimer::getFrameCount() - mLastARTUpdateFrame < 5 )  -        { -            // LL_INFOS() << this->getFullname() << " marked stale " << LL_ENDL; -            // we've not had a chance to update yet (allow a few to be certain a full frame has passed) -            return; -        } - -        mARTStale = false; -        mTooSlow = false; -        mTooSlowWithoutShadows = false; -        // LL_INFOS() << this->getFullname() << " refreshed ART combined = " << mRenderTime << " @ " << mLastARTUpdateFrame << LL_ENDL; -    } - -    // Either we're not stale or we've updated. - -    U64 render_time_raw; -    U64 render_geom_time_raw; - -    if( !mTooSlow )  -    { -        // we are fully rendered, so we use the live values -        std::lock_guard<std::mutex> lock{LLPerfStats::bufferToggleLock}; -        render_time_raw = LLPerfStats::StatsRecorder::get(LLPerfStats::ObjType_t::OT_AVATAR, id, LLPerfStats::StatType_t::RENDER_COMBINED); -        render_geom_time_raw = LLPerfStats::StatsRecorder::get(LLPerfStats::ObjType_t::OT_AVATAR, id, LLPerfStats::StatType_t::RENDER_GEOMETRY); -    } -    else -    { -        // use the cached values. -        render_time_raw = mRenderTime; -        render_geom_time_raw = mGeomTime; -    } +     +    // get max render time in ms +    F32 max_art_ms = (F32) (LLPerfStats::renderAvatarMaxART_ns / 1000000.0);  	bool autotune = LLPerfStats::tunables.userAutoTuneEnabled && !mIsControlAvatar && !isSelf(); @@ -8378,19 +8337,13 @@ void LLVOAvatar::updateTooSlow()      }  	bool exceeds_max_ART = -        ((LLPerfStats::renderAvatarMaxART_ns > 0) && (LLPerfStats::raw_to_ns(render_time_raw) >= LLPerfStats::renderAvatarMaxART_ns)); +        ((LLPerfStats::renderAvatarMaxART_ns > 0) &&  +            (mGPURenderTime >= max_art_ms)); // NOTE: don't use getGPURenderTime accessor here to avoid "isTooSlow" feedback loop      if (exceeds_max_ART && !ignore_tune)      { -        if( !mTooSlow ) // if we were previously not slow (with or without shadows.) -        {			 -            // if we weren't capped, we are now -            mLastARTUpdateFrame = LLFrameTimer::getFrameCount(); -            mRenderTime = render_time_raw; -            mGeomTime = render_geom_time_raw; -            mARTStale = false; -            mTooSlow = true; -        } +        mTooSlow = true; +                  if(!mTooSlowWithoutShadows) // if we were not previously above the full impostor cap          {              bool render_friend_or_exception =  	( alwaysRenderFriends && LLAvatarTracker::instance().isBuddy( id ) ) || @@ -8398,13 +8351,12 @@ void LLVOAvatar::updateTooSlow()              if( (!isSelf() || allowSelfImpostor) && !render_friend_or_exception  )              {                  // Note: slow rendering Friends still get their shadows zapped. -                mTooSlowWithoutShadows = (LLPerfStats::raw_to_ns(render_geom_time_raw) >= LLPerfStats::renderAvatarMaxART_ns); +                mTooSlowWithoutShadows = getGPURenderTime()*2.f >= max_art_ms;  // NOTE: assumes shadow rendering doubles render time              }          }      }      else      { -        // LL_INFOS() << this->getFullname() << " ("<< (combined?"combined":"geometry") << ") good render time = " << LLPerfStats::raw_to_ns(render_time_raw) << " vs ("<< LLVOAvatar::sRenderTimeCap_ns << " set @ " << mLastARTUpdateFrame << LL_ENDL;          mTooSlow = false;          mTooSlowWithoutShadows = false; @@ -11103,6 +11055,21 @@ void LLVOAvatar::calculateUpdateRenderComplexity()              // HUD complexity              LLHUDRenderNotifier::getInstance()->updateNotificationHUD(hud_complexity_list);          } + +        //schedule an update to ART next frame if needed +        if (LLPerfStats::tunables.userAutoTuneEnabled &&  +            LLPerfStats::tunables.userFPSTuningStrategy != LLPerfStats::TUNE_SCENE_ONLY && +            !isVisuallyMuted()) +        { +            LLUUID id = getID(); // <== use id to make sure this avatar didn't get deleted between frames +            LL::WorkQueue::getInstance("mainloop")->post([this, id]() +                { +                    if (gObjectList.findObject(id) != nullptr) +                    { +                        gPipeline.profileAvatar(this); +                    } +                }); +        }      }  } @@ -11465,6 +11432,9 @@ void LLVOAvatar::readProfileQuery(S32 retries)          glGetQueryObjectui64v(mGPUTimerQuery, GL_QUERY_RESULT, &time_elapsed);          mGPURenderTime = time_elapsed / 1000000.f;          mGPUProfilePending = false; + +        setDebugText(llformat("%d", (S32)(mGPURenderTime * 1000.f))); +      }      else      { // wait until next frame @@ -11477,3 +11447,67 @@ void LLVOAvatar::readProfileQuery(S32 retries)      }  } + +F32 LLVOAvatar::getGPURenderTime() +{ +    return isVisuallyMuted() ? 0.f : mGPURenderTime; +} + +// static +F32 LLVOAvatar::getTotalGPURenderTime() +{ +    LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; + +    F32 ret = 0.f; + +    for (LLCharacter* iter : LLCharacter::sInstances) +    { +        LLVOAvatar* inst = (LLVOAvatar*) iter; +        ret += inst->getGPURenderTime(); +    } + +    return ret; +} + +F32 LLVOAvatar::getMaxGPURenderTime() +{ +    LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; + +    F32 ret = 0.f; + +    for (LLCharacter* iter : LLCharacter::sInstances) +    { +        LLVOAvatar* inst = (LLVOAvatar*)iter; +        ret = llmax(inst->getGPURenderTime(), ret); +    } + +    return ret; +} + +F32 LLVOAvatar::getAverageGPURenderTime() +{ +    LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; + +    F32 ret = 0.f; + +    S32 count = 0; + +    for (LLCharacter* iter : LLCharacter::sInstances) +    { +        LLVOAvatar* inst = (LLVOAvatar*)iter; +        if (!inst->isTooSlow()) +        { +            ret += inst->getGPURenderTime(); +            ++count; +        } +    } + +    if (count > 0) +    { +        ret /= count; +    } + +    return ret; +} + + diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 2ca44b041a..e8604464ae 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -309,11 +309,21 @@ public:      void readProfileQuery(S32 retries);      // get the GPU time in ms of rendering this avatar including all attachments -    // returns -1 if this avatar has not been profiled using gPipeline.profileAvatar -    F32             getGPURenderTime() { return mGPURenderTime; } +    // returns 0.f if this avatar has not been profiled using gPipeline.profileAvatar +    // or the avatar is visually muted +    F32             getGPURenderTime(); + +    // get the total GPU render time in ms of all avatars that have been benched +    static F32      getTotalGPURenderTime(); + +    // get the max GPU render time in ms of all avatars that have been benched +    static F32      getMaxGPURenderTime(); + +    // get the average GPU render time in ms of all avatars that have been benched +    static F32      getAverageGPURenderTime();      // get the CPU time in ms of rendering this avatar including all attachments -    // return -1 if this avatar has not been profiled using gPipeline.mProfileAvatar +    // return 0.f if this avatar has not been profiled using gPipeline.mProfileAvatar      F32             getCPURenderTime() { return mCPURenderTime; } @@ -401,8 +411,7 @@ public:  	void 			logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed);      void            calcMutedAVColor(); -    void            markARTStale(); - +      protected:  	LLViewerStats::PhaseMap& getPhases() { return mPhases; }  	BOOL			updateIsFullyLoaded(); @@ -423,11 +432,6 @@ private:  	LLFrameTimer	mFullyLoadedTimer;  	LLFrameTimer	mRuthTimer; -    U32				mLastARTUpdateFrame{0}; -    U64				mRenderTime{0}; -    U64				mGeomTime{0}; -    bool			mARTStale{true}; -    bool			mARTCapped{false};      // variables to hold "slowness" status      bool			mTooSlow{false};      bool			mTooSlowWithoutShadows{false}; @@ -557,11 +561,11 @@ private:      // profile results      // GPU render time in ms -    F32 mGPURenderTime = -1.f; +    F32 mGPURenderTime = 0.f;      bool mGPUProfilePending = false;      // CPU render time in ms -    F32 mCPURenderTime = -1.f; +    F32 mCPURenderTime = 0.f;  	// the isTooComplex method uses these mutable values to avoid recalculating too frequently      // DEPRECATED -- obsolete avatar render cost values @@ -1203,8 +1207,6 @@ public:  	// COF version of last appearance message received for this av.  	S32 mLastUpdateReceivedCOFVersion; -    U64 getLastART() const { return mRenderTime; } -  /**                    Diagnostics   **                                                                            **   *******************************************************************************/ diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 732ef1da6c..0e0dbdc071 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -1441,7 +1441,11 @@ F32 LLWorld::getNearbyAvatarsAndMaxGPUTime(std::vector<LLCharacter*> &valid_near                  char_iter++;                  continue;              } -            gPipeline.profileAvatar(avatar); + +            if (!avatar->isTooSlow()) +            { +                gPipeline.profileAvatar(avatar); +            }              nearby_max_complexity = llmax(nearby_max_complexity, avatar->getGPURenderTime());              valid_nearby_avs.push_back(*char_iter);          } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 4d9a8a594a..6ea86c4cbb 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -10073,6 +10073,9 @@ void LLPipeline::profileAvatar(LLVOAvatar* avatar, bool profile_attachments)      LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; +    // don't continue to profile an avatar that is known to be too slow +    llassert(!avatar->isTooSlow()); +      LLGLSLShader* cur_shader = LLGLSLShader::sCurBoundShaderPtr;      mRT->deferredScreen.bindTarget(); @@ -10345,25 +10348,28 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool  		resY = llmin(nhpo2((U32) (fov*pa)), (U32) 512);  		resX = llmin(nhpo2((U32) (atanf(tdim.mV[0]/distance)*2.f*RAD_TO_DEG*pa)), (U32) 512); -		if (!avatar->mImpostor.isComplete()) -		{ -            avatar->mImpostor.allocate(resX, resY, GL_RGBA, true); +        if (!for_profile) +        { +            if (!avatar->mImpostor.isComplete()) +            { +                avatar->mImpostor.allocate(resX, resY, GL_RGBA, true); -			if (LLPipeline::sRenderDeferred) -			{ -				addDeferredAttachments(avatar->mImpostor, true); -			} -		 -			gGL.getTexUnit(0)->bind(&avatar->mImpostor); -			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); -			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -		} -		else if(resX != avatar->mImpostor.getWidth() || resY != avatar->mImpostor.getHeight()) -		{ -			avatar->mImpostor.resize(resX,resY); -		} +                if (LLPipeline::sRenderDeferred) +                { +                    addDeferredAttachments(avatar->mImpostor, true); +                } + +                gGL.getTexUnit(0)->bind(&avatar->mImpostor); +                gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +                gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +            } +            else if (resX != avatar->mImpostor.getWidth() || resY != avatar->mImpostor.getHeight()) +            { +                avatar->mImpostor.resize(resX, resY); +            } -		avatar->mImpostor.bindTarget(); +            avatar->mImpostor.bindTarget(); +        }  	}  	F32 old_alpha = LLDrawPoolAvatar::sMinimumAlpha; @@ -10466,7 +10472,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool  		gGL.popMatrix();  	} -    if (!preview_avatar) +    if (!preview_avatar && !for_profile)      {          avatar->mImpostor.flush();          avatar->setImpostorDim(tdim); | 
