diff options
| -rw-r--r-- | indra/newview/llviewermessage.cpp | 23 | ||||
| -rw-r--r-- | indra/newview/llviewertexture.cpp | 51 | ||||
| -rw-r--r-- | indra/newview/llviewertexture.h | 3 | ||||
| -rw-r--r-- | indra/newview/llvocache.cpp | 13 | 
4 files changed, 72 insertions, 18 deletions
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 7d39cc6059..d0e6af799c 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3364,6 +3364,17 @@ void send_agent_update(bool force_send, bool send_reliable)      msg->addVector3Fast(_PREHASH_CameraUpAxis, LLViewerCamera::getInstance()->getUpAxis());      static F32 last_draw_disatance_step = 1024; +    F32 memory_limited_draw_distance = gAgentCamera.mDrawDistance; + +    if (LLViewerTexture::sDesiredDiscardBias > 2.f && LLViewerTexture::isSystemMemoryLow()) +    { +        // If we are low on memory, reduce requested draw distance +        // Discard's bias is clamped to 4 so we need to check 2 to 4 range +        // Factor is intended to go from 1.0 to 2.0 +        F32 factor = 1.f + (LLViewerTexture::sDesiredDiscardBias - 2.f) / 2.f; +        memory_limited_draw_distance = llmax(gAgentCamera.mDrawDistance / factor, gAgentCamera.mDrawDistance / 2.f); +    } +      if (tp_state == LLAgent::TELEPORT_ARRIVING || LLStartUp::getStartupState() < STATE_MISC)      {          // Inform interest list, prioritize closer area. @@ -3372,25 +3383,25 @@ void send_agent_update(bool force_send, bool send_reliable)          // closer ones.          // Todo: revise and remove once server gets distance sorting.          last_draw_disatance_step = llmax((F32)(gAgentCamera.mDrawDistance / 2.f), 50.f); +        last_draw_disatance_step = llmin(last_draw_disatance_step, memory_limited_draw_distance);          msg->addF32Fast(_PREHASH_Far, last_draw_disatance_step);      } -    else if (last_draw_disatance_step < gAgentCamera.mDrawDistance) +    else if (last_draw_disatance_step < memory_limited_draw_distance)      {          static LLFrameTimer last_step_time;          if (last_step_time.getElapsedTimeF32() > 1.f)          {              // gradually increase draw distance -            // Idealy this should be not per second, but based on how loaded -            // mesh thread is, but hopefully this is temporary.              last_step_time.reset(); -            F32 step = gAgentCamera.mDrawDistance * 0.1f; -            last_draw_disatance_step = llmin(last_draw_disatance_step + step, gAgentCamera.mDrawDistance); +            F32 step = memory_limited_draw_distance * 0.1f; +            last_draw_disatance_step = llmin(last_draw_disatance_step + step, memory_limited_draw_distance);          }          msg->addF32Fast(_PREHASH_Far, last_draw_disatance_step);      }      else      { -        msg->addF32Fast(_PREHASH_Far, gAgentCamera.mDrawDistance); +        last_draw_disatance_step = memory_limited_draw_distance; +        msg->addF32Fast(_PREHASH_Far, memory_limited_draw_distance);      }      msg->addU32Fast(_PREHASH_ControlFlags, control_flags); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 52939dbbae..7a25fb03a5 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -527,8 +527,16 @@ void LLViewerTexture::updateClass()      if (is_low && !was_low)      { -        // slam to 1.5 bias the moment we hit low memory (discards off screen textures immediately) -        sDesiredDiscardBias = llmax(sDesiredDiscardBias, 1.5f); +        if (is_sys_low) +        { +            // Not having system memory is more serious, so discard harder +            sDesiredDiscardBias = llmax(sDesiredDiscardBias, 1.5f * getSystemMemoryBudgetFactor()); +        } +        else +        { +            // Slam to 1.5 bias the moment we hit low memory (discards off screen textures immediately) +            sDesiredDiscardBias = llmax(sDesiredDiscardBias, 1.5f); +        }          if (is_sys_low || over_pct > 2.f)          { // if we're low on system memory, emergency purge off screen textures to avoid a death spiral @@ -559,8 +567,13 @@ void LLViewerTexture::updateClass()          sEvaluationTimer.reset();          // lower discard bias over time when at least 10% of budget is free -        const F32 FREE_PERCENTAGE_TRESHOLD = -0.1f; -        if (sDesiredDiscardBias > 1.f && over_pct < FREE_PERCENTAGE_TRESHOLD) +        constexpr F32 FREE_PERCENTAGE_TRESHOLD = -0.1f; +        constexpr U32 FREE_SYS_MEM_TRESHOLD = 100; +        static LLCachedControl<U32> min_free_main_memory(gSavedSettings, "RenderMinFreeMainMemoryThreshold", 512); +        const S32Megabytes MIN_FREE_MAIN_MEMORY(min_free_main_memory() + FREE_SYS_MEM_TRESHOLD); +        if (sDesiredDiscardBias > 1.f +            && over_pct < FREE_PERCENTAGE_TRESHOLD +            && getFreeSystemMemory() > MIN_FREE_MAIN_MEMORY)          {              static LLCachedControl<F32> high_mem_discard_decrement(gSavedSettings, "RenderHighMemMinDiscardDecrement", .1f); @@ -627,24 +640,42 @@ void LLViewerTexture::updateClass()  }  //static -bool LLViewerTexture::isSystemMemoryLow() +U32Megabytes LLViewerTexture::getFreeSystemMemory()  {      static LLFrameTimer timer;      static U32Megabytes physical_res = U32Megabytes(U32_MAX); -    static LLCachedControl<U32> min_free_main_memory(gSavedSettings, "RenderMinFreeMainMemoryThreshold", 512); -    const U32Megabytes MIN_FREE_MAIN_MEMORY(min_free_main_memory); -      if (timer.getElapsedTimeF32() < MEMORY_CHECK_WAIT_TIME) //call this once per second.      { -        return physical_res < MIN_FREE_MAIN_MEMORY; +        return physical_res;      }      timer.reset();      LLMemory::updateMemoryInfo();      physical_res = LLMemory::getAvailableMemKB(); -    return physical_res < MIN_FREE_MAIN_MEMORY; +    return physical_res; +} + +//static +bool LLViewerTexture::isSystemMemoryLow() +{ +    static LLCachedControl<U32> min_free_main_memory(gSavedSettings, "RenderMinFreeMainMemoryThreshold", 512); +    const U32Megabytes MIN_FREE_MAIN_MEMORY(min_free_main_memory); +    return getFreeSystemMemory() < MIN_FREE_MAIN_MEMORY; +} + +F32 LLViewerTexture::getSystemMemoryBudgetFactor() +{ +    static LLCachedControl<U32> min_free_main_memory(gSavedSettings, "RenderMinFreeMainMemoryThreshold", 512); +    const S32Megabytes MIN_FREE_MAIN_MEMORY(min_free_main_memory); +    S32 free_budget = (S32Megabytes)getFreeSystemMemory() - MIN_FREE_MAIN_MEMORY; +    if (free_budget < 0) +    { +        // Result should range from 1 (0 free budget) to 2 (-512 free budget) +        return 1.f - free_budget / MIN_FREE_MAIN_MEMORY; +    } +    return 1.f;  }  //end of static functions diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index f9311d85cb..d32c302d8e 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -115,6 +115,7 @@ public:      static void initClass();      static void updateClass();      static bool isSystemMemoryLow(); +    static F32 getSystemMemoryBudgetFactor();      LLViewerTexture(bool usemipmaps = true);      LLViewerTexture(const LLUUID& id, bool usemipmaps) ; @@ -189,6 +190,8 @@ private:      friend class LLBumpImageList;      friend class LLUIImageList; +    static U32Megabytes getFreeSystemMemory(); +  protected:      friend class LLViewerTextureList;      LLUUID mID; diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 501828eee8..ac73c2def6 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -486,14 +486,23 @@ void LLVOCacheEntry::updateDebugSettings()      //min radius: all objects within this radius remain loaded in memory      static LLCachedControl<F32> min_radius(gSavedSettings,"SceneLoadMinRadius");      static const F32 MIN_RADIUS = 1.0f; -    const F32 draw_radius = gAgentCamera.mDrawDistance; + +    F32 draw_radius = gAgentCamera.mDrawDistance; +    if (LLViewerTexture::sDesiredDiscardBias > 2.f && LLViewerTexture::isSystemMemoryLow()) +    { +        // Discard's bias maximum is 4 so we need to check 2 to 4 range +        // Factor is intended to go from 1.0 to 2.0 +        F32 factor = 1.f + (LLViewerTexture::sDesiredDiscardBias - 2.f) / 2.f; +        // For safety cap reduction at 50%, we don't want to go below half of draw distance +        draw_radius = llmax(draw_radius / factor, draw_radius / 2.f); +    }      const F32 clamped_min_radius = llclamp((F32) min_radius, MIN_RADIUS, draw_radius); // [1, mDrawDistance]      sNearRadius = MIN_RADIUS + ((clamped_min_radius - MIN_RADIUS) * adjust_factor);      // a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold      static LLCachedControl<F32> rear_max_radius_frac(gSavedSettings,"SceneLoadRearMaxRadiusFraction");      const F32 min_radius_plus_one = sNearRadius + 1.f; -    const F32 max_radius = rear_max_radius_frac * gAgentCamera.mDrawDistance; +    const F32 max_radius = rear_max_radius_frac * draw_radius;      const F32 clamped_max_radius = llclamp(max_radius, min_radius_plus_one, draw_radius); // [sNearRadius, mDrawDistance]      sRearFarRadius = min_radius_plus_one + ((clamped_max_radius - min_radius_plus_one) * adjust_factor);  | 
