Skip to content
Snippets Groups Projects
Commit dea5450d authored by andreykproductengine's avatar andreykproductengine
Browse files

SL-4730 Prevent viewer from getting more texture details when low on memory

parent c99a66a4
No related branches found
No related tags found
No related merge requests found
......@@ -100,7 +100,7 @@ const S32 MAX_CACHED_RAW_TERRAIN_IMAGE_AREA = 128 * 128;
const S32 DEFAULT_ICON_DIMENTIONS = 32;
S32 LLViewerTexture::sMinLargeImageSize = 65536; //256 * 256.
S32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA;
BOOL LLViewerTexture::sFreezeImageScalingDown = FALSE;
bool LLViewerTexture::sFreezeImageUpdates = false;
F32 LLViewerTexture::sCurrentTime = 0.0f;
F32 LLViewerTexture::sTexelPixelRatio = 1.0f;
......@@ -484,53 +484,68 @@ static LLTrace::BlockTimerStatHandle FTM_TEXTURE_MEMORY_CHECK("Memory Check");
//static
bool LLViewerTexture::isMemoryForTextureLow()
{
static LLFrameTimer timer;
static bool low_mem = false;
// Note: we need to figure out a better source for 'min' values,
// what is free for low end at minimal settings is 'nothing left'
// for higher end gpus at high settings.
const S32Megabytes MIN_FREE_TEXTURE_MEMORY(20);
const S32Megabytes MIN_FREE_MAIN_MEMORY(100);
if(timer.getElapsedTimeF32() < GPU_MEMORY_CHECK_WAIT_TIME) //call this once per second.
{
return low_mem;
}
timer.reset();
S32Megabytes gpu;
S32Megabytes physical;
getGPUMemoryForTextures(gpu, physical);
LL_RECORD_BLOCK_TIME(FTM_TEXTURE_MEMORY_CHECK);
return (gpu < MIN_FREE_TEXTURE_MEMORY) || (physical < MIN_FREE_MAIN_MEMORY);
}
const S32Megabytes MIN_FREE_TEXTURE_MEMORY(20); //MB Changed to 20 MB per MAINT-6882
const S32Megabytes MIN_FREE_MAIN_MEMORY(100); //MB
//static
bool LLViewerTexture::isMemoryForTextureSuficientlyFree()
{
const S32Megabytes DESIRED_FREE_TEXTURE_MEMORY(50);
const S32Megabytes DESIRED_FREE_MAIN_MEMORY(200);
low_mem = false;
if (gGLManager.mHasATIMemInfo)
{
S32 meminfo[4];
glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
S32Megabytes gpu;
S32Megabytes physical;
getGPUMemoryForTextures(gpu, physical);
if((S32Megabytes)meminfo[0] < MIN_FREE_TEXTURE_MEMORY)
{
low_mem = true;
}
return (gpu > DESIRED_FREE_TEXTURE_MEMORY) && (physical > DESIRED_FREE_MAIN_MEMORY);
}
if(!low_mem) //check main memory, only works for windows.
{
LLMemory::updateMemoryInfo();
if(LLMemory::getAvailableMemKB() < MIN_FREE_TEXTURE_MEMORY)
{
low_mem = true;
}
}
}
//Enabled this branch per MAINT-6882
else if (gGLManager.mHasNVXMemInfo)
{
S32 free_memory;
glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory);
if ((S32Megabytes)(free_memory / 1024) < MIN_FREE_TEXTURE_MEMORY)
{
low_mem = true;
}
}
//static
void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical)
{
static LLFrameTimer timer;
static S32Megabytes gpu_res = S32Megabytes(S32_MAX);
static S32Megabytes physical_res = S32Megabytes(S32_MAX);
if (timer.getElapsedTimeF32() < GPU_MEMORY_CHECK_WAIT_TIME) //call this once per second.
{
gpu = gpu_res;
physical = physical_res;
return;
}
timer.reset();
LL_RECORD_BLOCK_TIME(FTM_TEXTURE_MEMORY_CHECK);
if (gGLManager.mHasATIMemInfo)
{
S32 meminfo[4];
glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
gpu_res = (S32Megabytes)meminfo[0];
//check main memory, only works for windows.
LLMemory::updateMemoryInfo();
physical_res = LLMemory::getAvailableMemKB();
}
else if (gGLManager.mHasNVXMemInfo)
{
S32 free_memory;
glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory);
gpu_res = (S32Megabytes)(free_memory / 1024);
}
return low_mem;
gpu = gpu_res;
physical = physical_res;
}
static LLTrace::BlockTimerStatHandle FTM_TEXTURE_UPDATE_MEDIA("Media");
......@@ -575,17 +590,18 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity
}
else if(isMemoryForTextureLow())
{
// Note: isMemoryForTextureLow() uses 1s delay, make sure we waited enough for it to restore
// Note: isMemoryForTextureLow() uses 1s delay, make sure we waited enough for it to recheck
if (sEvaluationTimer.getElapsedTimeF32() > GPU_MEMORY_CHECK_WAIT_TIME)
{
sDesiredDiscardBias += discard_bias_delta;
sEvaluationTimer.reset();
}
}
else if (sDesiredDiscardBias > 0.0f &&
sBoundTextureMemory < sMaxBoundTextureMemory * texmem_lower_bound_scale &&
sTotalTextureMemory < sMaxTotalTextureMem * texmem_lower_bound_scale)
{
else if (sDesiredDiscardBias > 0.0f
&& sBoundTextureMemory < sMaxBoundTextureMemory * texmem_lower_bound_scale
&& sTotalTextureMemory < sMaxTotalTextureMem * texmem_lower_bound_scale
&& isMemoryForTextureSuficientlyFree())
{
// If we are using less texture memory than we should,
// scale down the desired discard level
if (sEvaluationTimer.getElapsedTimeF32() > discard_delta_time)
......@@ -595,14 +611,8 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity
}
}
sDesiredDiscardBias = llclamp(sDesiredDiscardBias, desired_discard_bias_min, desired_discard_bias_max);
F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed();
F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed();
sCameraMovingBias = llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1);
sCameraMovingDiscardBias = (S8)(sCameraMovingBias);
LLViewerTexture::sFreezeImageScalingDown = (sBoundTextureMemory < 0.75f * sMaxBoundTextureMemory * texmem_middle_bound_scale) &&
(sTotalTextureMemory < 0.75f * sMaxTotalTextureMem * texmem_middle_bound_scale);
LLViewerTexture::sFreezeImageUpdates = sDesiredDiscardBias > (desired_discard_bias_max - 1.0f);
}
//end of static functions
......@@ -3126,9 +3136,9 @@ S8 LLViewerLODTexture::getType() const
return LLViewerTexture::LOD_TEXTURE;
}
BOOL LLViewerLODTexture::isUpdateFrozen()
bool LLViewerLODTexture::isUpdateFrozen()
{
return LLViewerTexture::sFreezeImageScalingDown && !getDiscardLevel();
return LLViewerTexture::sFreezeImageUpdates;
}
// This is gauranteed to get called periodically for every texture
......@@ -3254,9 +3264,16 @@ void LLViewerLODTexture::processTextureStats()
(!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel))
{
scaleDown();
}
}
if (isUpdateFrozen() // we are out of memory and nearing max allowed bias
&& mBoostLevel < LLGLTexture::BOOST_SCULPTED
&& mDesiredDiscardLevel < current_discard)
{
// stop requesting more
mDesiredDiscardLevel = current_discard;
}
}
if(mForceToSaveRawImage && mDesiredSavedRawDiscardLevel >= 0)
......
......@@ -186,6 +186,9 @@ class LLViewerTexture : public LLGLTexture
virtual void switchToCachedImage();
static bool isMemoryForTextureLow() ;
static bool isMemoryForTextureSuficientlyFree();
static void getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical);
protected:
LLUUID mID;
S32 mTextureListType; // along with mID identifies where to search for this texture in TextureList
......@@ -227,7 +230,7 @@ class LLViewerTexture : public LLGLTexture
static S32 sMaxSculptRez ;
static S32 sMinLargeImageSize ;
static S32 sMaxSmallImageSize ;
static BOOL sFreezeImageScalingDown ;//do not scale down image res if set.
static bool sFreezeImageUpdates;
static F32 sCurrentTime ;
enum EDebugTexels
......@@ -543,7 +546,7 @@ class LLViewerLODTexture : public LLViewerFetchedTexture
/*virtual*/ S8 getType() const;
// Process image stats to determine priority/quality requirements.
/*virtual*/ void processTextureStats();
BOOL isUpdateFrozen() ;
bool isUpdateFrozen() ;
private:
void init(bool firstinit) ;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment