summaryrefslogtreecommitdiff
path: root/indra/newview/llviewertexturelist.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llviewertexturelist.cpp')
-rw-r--r--indra/newview/llviewertexturelist.cpp235
1 files changed, 166 insertions, 69 deletions
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 9a6c0569a9..49d7e8b842 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -58,7 +58,7 @@
#include "pipeline.h"
#include "llappviewer.h"
#include "llxuiparser.h"
-#include "llagent.h"
+#include "llviewerdisplay.h"
////////////////////////////////////////////////////////////////////////////
@@ -276,6 +276,7 @@ void LLViewerTextureList::shutdown()
// Flush all of the references
mLoadingStreamList.clear();
mCreateTextureList.clear();
+ mFastCacheList.clear();
mUUIDMap.clear();
@@ -453,6 +454,8 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
LLGLenum primary_format,
LLHost request_from_host)
{
+ static LLCachedControl<bool> fast_cache_fetching_enabled(gSavedSettings, "FastCacheFetchEnabled");
+
LLPointer<LLViewerFetchedTexture> imagep ;
switch(texture_type)
{
@@ -490,6 +493,11 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
imagep->forceActive() ;
}
+ if(fast_cache_fetching_enabled)
+ {
+ mFastCacheList.insert(imagep);
+ imagep->setInFastCacheList(true);
+ }
return imagep ;
}
@@ -503,6 +511,7 @@ LLViewerFetchedTexture *LLViewerTextureList::findImage(const LLUUID &image_id)
void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image)
{
+ assert_main_thread();
llassert_always(mInitialized) ;
llassert(image);
if (image->isInImageList())
@@ -519,6 +528,7 @@ void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image)
void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
{
+ assert_main_thread();
llassert_always(mInitialized) ;
llassert(image);
if (!image->isInImageList())
@@ -593,16 +603,24 @@ static LLFastTimer::DeclareTimer FTM_IMAGE_MARK_DIRTY("Dirty Images");
static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_PRIORITIES("Prioritize");
static LLFastTimer::DeclareTimer FTM_IMAGE_CALLBACKS("Callbacks");
static LLFastTimer::DeclareTimer FTM_IMAGE_FETCH("Fetch");
+static LLFastTimer::DeclareTimer FTM_FAST_CACHE_IMAGE_FETCH("Fast Cache Fetch");
static LLFastTimer::DeclareTimer FTM_IMAGE_CREATE("Create");
static LLFastTimer::DeclareTimer FTM_IMAGE_STATS("Stats");
void LLViewerTextureList::updateImages(F32 max_time)
{
- if(gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
+ static BOOL cleared = FALSE;
+ if(gTeleportDisplay)
{
- clearFetchingRequests();
+ if(!cleared)
+ {
+ clearFetchingRequests();
+ gPipeline.clearRebuildGroups();
+ cleared = TRUE;
+ }
return;
}
+ cleared = FALSE;
LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerStats::getInstance()->mTextureKBitStat.getMeanPerSec());
@@ -613,6 +631,11 @@ void LLViewerTextureList::updateImages(F32 max_time)
LLViewerStats::getInstance()->mRawMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageRaw::sGlobalRawMemory));
LLViewerStats::getInstance()->mFormattedMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageFormatted::sGlobalFormattedMemory));
+ {
+ //loading from fast cache
+ LLFastTimer t(FTM_FAST_CACHE_IMAGE_FETCH);
+ max_time -= updateImagesLoadingFastCache(max_time);
+ }
{
LLFastTimer t(FTM_IMAGE_UPDATE_PRIORITIES);
@@ -673,14 +696,13 @@ void LLViewerTextureList::clearFetchingRequests()
return;
}
+ LLAppViewer::getTextureFetch()->deleteAllRequests();
+
for (image_priority_list_t::iterator iter = mImageList.begin();
iter != mImageList.end(); ++iter)
{
- LLViewerFetchedTexture* image = *iter;
- if(image->hasFetcher())
- {
- image->forceToDeleteRequest() ;
- }
+ LLViewerFetchedTexture* imagep = *iter;
+ imagep->forceToDeleteRequest() ;
}
}
@@ -688,10 +710,11 @@ void LLViewerTextureList::updateImagesDecodePriorities()
{
// Update the decode priority for N images each frame
{
- const size_t max_update_count = llmin((S32) (1024*gFrameIntervalSeconds) + 1, 32); //target 1024 textures per second
- S32 update_counter = llmin(max_update_count, mUUIDMap.size()/10);
+ static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities"); // default: 32
+ const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds) + 1, MAX_PRIO_UPDATES);
+ S32 update_counter = llmin(max_update_count, mUUIDMap.size());
uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateUUID);
- while(update_counter > 0 && !mUUIDMap.empty())
+ while ((update_counter-- > 0) && !mUUIDMap.empty())
{
if (iter == mUUIDMap.end())
{
@@ -699,7 +722,13 @@ void LLViewerTextureList::updateImagesDecodePriorities()
}
mLastUpdateUUID = iter->first;
LLPointer<LLViewerFetchedTexture> imagep = iter->second;
- ++iter; // safe to incrament now
+ ++iter; // safe to increment now
+
+ if(imagep->isInDebug())
+ {
+ update_counter--;
+ continue; //is in debug, ignore.
+ }
//
// Flush formatted images using a lazy flush
@@ -754,7 +783,16 @@ void LLViewerTextureList::updateImagesDecodePriorities()
imagep->setInactive() ;
}
}
-
+
+ if (!imagep->isInImageList())
+ {
+ continue;
+ }
+ if(imagep->isInFastCacheList())
+ {
+ continue; //wait for loading from the fast cache.
+ }
+
imagep->processTextureStats();
F32 old_priority = imagep->getDecodePriority();
F32 old_priority_test = llmax(old_priority, 0.0f);
@@ -764,15 +802,35 @@ void LLViewerTextureList::updateImagesDecodePriorities()
if ((decode_priority_test < old_priority_test * .8f) ||
(decode_priority_test > old_priority_test * 1.25f))
{
- removeImageFromList(imagep);
+ mImageList.erase(imagep) ;
imagep->setDecodePriority(decode_priority);
- addImageToList(imagep);
+ mImageList.insert(imagep);
}
- update_counter--;
}
}
}
+void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level)
+{
+ if(!tex->setDebugFetching(debug_level))
+ {
+ return;
+ }
+
+ const F32 DEBUG_PRIORITY = 100000.f;
+ F32 old_priority_test = llmax(tex->getDecodePriority(), 0.0f);
+ F32 decode_priority_test = DEBUG_PRIORITY;
+
+ // Ignore < 20% difference
+ if ((decode_priority_test < old_priority_test * .8f) ||
+ (decode_priority_test > old_priority_test * 1.25f))
+ {
+ removeImageFromList(tex);
+ tex->setDecodePriority(decode_priority_test);
+ addImageToList(tex);
+ }
+}
+
/*
static U8 get_image_type(LLViewerFetchedTexture* imagep, LLHost target_host)
{
@@ -827,6 +885,36 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
return create_timer.getElapsedTimeF32();
}
+F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time)
+{
+ if (gGLManager.mIsDisabled) return 0.0f;
+ if(mFastCacheList.empty())
+ {
+ return 0.f;
+ }
+
+ //
+ // loading texture raw data from the fast cache directly.
+ //
+
+ LLTimer timer;
+ image_list_t::iterator enditer = mFastCacheList.begin();
+ for (image_list_t::iterator iter = mFastCacheList.begin();
+ iter != mFastCacheList.end();)
+ {
+ image_list_t::iterator curiter = iter++;
+ enditer = iter;
+ LLViewerFetchedTexture *imagep = *curiter;
+ imagep->loadFromFastCache();
+ if (timer.getElapsedTimeF32() > max_time)
+ {
+ break;
+ }
+ }
+ mFastCacheList.erase(mFastCacheList.begin(), enditer);
+ return timer.getElapsedTimeF32();
+}
+
void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep)
{
if(!imagep)
@@ -850,15 +938,24 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
{
LLTimer image_op_timer;
- // Update the decode priority for N images each frame
- // Make a list with 32 high priority entries + 256 cycled entries
- const size_t max_priority_count = llmin((S32) (256*10.f*gFrameIntervalSeconds)+1, 32);
- const size_t max_update_count = llmin((S32) (1024*10.f*gFrameIntervalSeconds)+1, 256);
+ // Update fetch for N images each frame
+ static const S32 MAX_HIGH_PRIO_COUNT = gSavedSettings.getS32("TextureFetchUpdateHighPriority"); // default: 32
+ static const S32 MAX_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMaxMediumPriority"); // default: 256
+ static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinMediumPriority"); // default: 32
+ static const F32 MIN_PRIORITY_THRESHOLD = gSavedSettings.getF32("TextureFetchUpdatePriorityThreshold"); // default: 0.0
+ static const bool SKIP_LOW_PRIO = gSavedSettings.getBOOL("TextureFetchUpdateSkipLowPriority"); // default: false
+
+ size_t max_priority_count = llmin((S32) (MAX_HIGH_PRIO_COUNT*MAX_HIGH_PRIO_COUNT*gFrameIntervalSeconds)+1, MAX_HIGH_PRIO_COUNT);
+ max_priority_count = llmin(max_priority_count, mImageList.size());
+
+ size_t total_update_count = mUUIDMap.size();
+ size_t max_update_count = llmin((S32) (MAX_UPDATE_COUNT*MAX_UPDATE_COUNT*gFrameIntervalSeconds)+1, MAX_UPDATE_COUNT);
+ max_update_count = llmin(max_update_count, total_update_count);
- // 32 high priority entries
+ // MAX_HIGH_PRIO_COUNT high priority entries
typedef std::vector<LLViewerFetchedTexture*> entries_list_t;
entries_list_t entries;
- size_t update_counter = llmin(max_priority_count, mImageList.size());
+ size_t update_counter = max_priority_count;
image_priority_list_t::iterator iter1 = mImageList.begin();
while(update_counter > 0)
{
@@ -868,43 +965,46 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
update_counter--;
}
- // 256 cycled entries
- update_counter = llmin(max_update_count, mUUIDMap.size());
+ // MAX_UPDATE_COUNT cycled entries
+ update_counter = max_update_count;
if(update_counter > 0)
{
uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchUUID);
- uuid_map_t::iterator iter2p = iter2;
- while(update_counter > 0)
+ while ((update_counter > 0) && (total_update_count > 0))
{
if (iter2 == mUUIDMap.end())
{
iter2 = mUUIDMap.begin();
}
- entries.push_back(iter2->second);
- iter2p = iter2++;
- update_counter--;
+ LLViewerFetchedTexture* imagep = iter2->second;
+ // Skip the textures where there's really nothing to do so to give some times to others. Also skip the texture if it's already in the high prio set.
+ if (!SKIP_LOW_PRIO || (SKIP_LOW_PRIO && ((imagep->getDecodePriority() > MIN_PRIORITY_THRESHOLD) || imagep->hasFetcher())))
+ {
+ entries.push_back(imagep);
+ update_counter--;
+ }
+
+ iter2++;
+ total_update_count--;
}
-
- mLastFetchUUID = iter2p->first;
}
S32 fetch_count = 0;
- S32 min_count = max_priority_count + max_update_count/4;
+ size_t min_update_count = llmin(MIN_UPDATE_COUNT,(S32)(entries.size()-max_priority_count));
+ S32 min_count = max_priority_count + min_update_count;
for (entries_list_t::iterator iter3 = entries.begin();
iter3 != entries.end(); )
{
LLViewerFetchedTexture* imagep = *iter3++;
-
- bool fetching = imagep->updateFetch();
- if (fetching)
+ fetch_count += (imagep->updateFetch() ? 1 : 0);
+ if (min_count <= min_update_count)
{
- fetch_count++;
+ mLastFetchUUID = imagep->getID();
}
- if (min_count <= 0 && image_op_timer.getElapsedTimeF32() > max_time)
+ if ((min_count-- <= 0) && (image_op_timer.getElapsedTimeF32() > max_time))
{
break;
}
- min_count--;
}
//if (fetch_count == 0)
//{
@@ -936,6 +1036,9 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)
{
LLTimer timer;
+ //loading from fast cache
+ updateImagesLoadingFastCache(max_time);
+
// Update texture stats and priorities
std::vector<LLPointer<LLViewerFetchedTexture> > image_list;
for (image_priority_list_t::iterator iter = mImageList.begin();
@@ -1583,49 +1686,43 @@ struct UIImageDeclarations : public LLInitParam::Block<UIImageDeclarations>
bool LLUIImageList::initFromFile()
{
- // construct path to canonical textures.xml in default skin dir
- std::string base_file_path = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, "default", "textures", "textures.xml");
+ // Look for textures.xml in all the right places. Pass
+ // constraint=LLDir::ALL_SKINS because we want to overlay textures.xml
+ // from all the skins directories.
+ std::vector<std::string> textures_paths =
+ gDirUtilp->findSkinnedFilenames(LLDir::TEXTURES, "textures.xml", LLDir::ALL_SKINS);
+ std::vector<std::string>::const_iterator pi(textures_paths.begin()), pend(textures_paths.end());
+ if (pi == pend)
+ {
+ llwarns << "No textures.xml found in skins directories" << llendl;
+ return false;
+ }
+ // The first (most generic) file gets special validations
LLXMLNodePtr root;
-
- if (!LLXMLNode::parseFile(base_file_path, root, NULL))
+ if (!LLXMLNode::parseFile(*pi, root, NULL))
{
- llwarns << "Unable to parse UI image list file " << base_file_path << llendl;
+ llwarns << "Unable to parse UI image list file " << *pi << llendl;
return false;
}
if (!root->hasAttribute("version"))
{
- llwarns << "No valid version number in UI image list file " << base_file_path << llendl;
+ llwarns << "No valid version number in UI image list file " << *pi << llendl;
return false;
}
UIImageDeclarations images;
LLXUIParser parser;
- parser.readXUI(root, images, base_file_path);
-
- // add components defined in current skin
- std::string skin_update_path = gDirUtilp->getSkinDir()
- + gDirUtilp->getDirDelimiter()
- + "textures"
- + gDirUtilp->getDirDelimiter()
- + "textures.xml";
- LLXMLNodePtr update_root;
- if (skin_update_path != base_file_path
- && LLXMLNode::parseFile(skin_update_path, update_root, NULL))
- {
- parser.readXUI(update_root, images, skin_update_path);
- }
-
- // add components defined in user override of current skin
- skin_update_path = gDirUtilp->getUserSkinDir()
- + gDirUtilp->getDirDelimiter()
- + "textures"
- + gDirUtilp->getDirDelimiter()
- + "textures.xml";
- if (skin_update_path != base_file_path
- && LLXMLNode::parseFile(skin_update_path, update_root, NULL))
- {
- parser.readXUI(update_root, images, skin_update_path);
+ parser.readXUI(root, images, *pi);
+
+ // add components defined in the rest of the skin paths
+ while (++pi != pend)
+ {
+ LLXMLNodePtr update_root;
+ if (LLXMLNode::parseFile(*pi, update_root, NULL))
+ {
+ parser.readXUI(update_root, images, *pi);
+ }
}
if (!images.validateBlock()) return false;