Merge branch 'master' of git://github.com/siana/SingularityViewer
This commit is contained in:
@@ -105,9 +105,9 @@ void LLFloaterStats::buildStats()
|
|||||||
stat_barp = stat_viewp->addStat("Allocated memory", &(LLViewerStats::getInstance()->mMallocStat), "DebugStatModeMalloc");
|
stat_barp = stat_viewp->addStat("Allocated memory", &(LLViewerStats::getInstance()->mMallocStat), "DebugStatModeMalloc");
|
||||||
stat_barp->setUnitLabel(" MB");
|
stat_barp->setUnitLabel(" MB");
|
||||||
stat_barp->mMinBar = 0.f;
|
stat_barp->mMinBar = 0.f;
|
||||||
stat_barp->mMaxBar = 4000.f;
|
stat_barp->mMaxBar = 2048.f;
|
||||||
stat_barp->mTickSpacing = 100.f;
|
stat_barp->mTickSpacing = 128.f;
|
||||||
stat_barp->mLabelSpacing = 200.f;
|
stat_barp->mLabelSpacing = 512.f;
|
||||||
stat_barp->mPerSec = FALSE;
|
stat_barp->mPerSec = FALSE;
|
||||||
stat_barp->mDisplayMean = FALSE;
|
stat_barp->mDisplayMean = FALSE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,31 +2,25 @@
|
|||||||
* @file lltexturecache.cpp
|
* @file lltexturecache.cpp
|
||||||
* @brief Object which handles local texture caching
|
* @brief Object which handles local texture caching
|
||||||
*
|
*
|
||||||
* $LicenseInfo:firstyear=2000&license=viewergpl$
|
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
|
||||||
*
|
|
||||||
* Copyright (c) 2000-2009, Linden Research, Inc.
|
|
||||||
*
|
|
||||||
* Second Life Viewer Source Code
|
* Second Life Viewer Source Code
|
||||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
* Copyright (C) 2010, Linden Research, Inc.
|
||||||
* to you under the terms of the GNU General Public License, version 2.0
|
|
||||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
|
||||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
|
||||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
|
||||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
|
||||||
*
|
*
|
||||||
* There are special exceptions to the terms and conditions of the GPL as
|
* This library is free software; you can redistribute it and/or
|
||||||
* it is applied to this Source Code. View the full text of the exception
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
* License as published by the Free Software Foundation;
|
||||||
* online at
|
* version 2.1 of the License only.
|
||||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
|
||||||
*
|
*
|
||||||
* By copying, modifying or distributing this software, you acknowledge
|
* This library is distributed in the hope that it will be useful,
|
||||||
* that you have read and understood your obligations described above,
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* and agree to abide by those obligations.
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
* License along with this library; if not, write to the Free Software
|
||||||
* COMPLETENESS OR PERFORMANCE.
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||||
* $/LicenseInfo$
|
* $/LicenseInfo$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -251,9 +245,9 @@ bool LLTextureCacheLocalFileWorker::doRead()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (!mDataSize || mDataSize > local_size/* - mOffset*/)
|
if (!mDataSize || mDataSize > local_size - mOffset)
|
||||||
{
|
{
|
||||||
mDataSize = local_size/* - mOffset*/;
|
mDataSize = local_size - mOffset;
|
||||||
}
|
}
|
||||||
mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize);
|
mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize);
|
||||||
|
|
||||||
@@ -333,6 +327,7 @@ bool LLTextureCacheRemoteWorker::doRead()
|
|||||||
// First state / stage : find out if the file is local
|
// First state / stage : find out if the file is local
|
||||||
if (mState == INIT)
|
if (mState == INIT)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
std::string filename = mCache->getLocalFileName(mID);
|
std::string filename = mCache->getLocalFileName(mID);
|
||||||
// Is it a JPEG2000 file?
|
// Is it a JPEG2000 file?
|
||||||
{
|
{
|
||||||
@@ -367,20 +362,24 @@ bool LLTextureCacheRemoteWorker::doRead()
|
|||||||
}
|
}
|
||||||
// Determine the next stage: if we found a file, then LOCAL else CACHE
|
// Determine the next stage: if we found a file, then LOCAL else CACHE
|
||||||
mState = (local_size > 0 ? LOCAL : CACHE);
|
mState = (local_size > 0 ? LOCAL : CACHE);
|
||||||
|
|
||||||
|
llassert_always(mState == CACHE) ;
|
||||||
|
#else
|
||||||
|
mState = CACHE;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second state / stage : if the file is local, load it and leave
|
// Second state / stage : if the file is local, load it and leave
|
||||||
if (!done && (mState == LOCAL))
|
if (!done && (mState == LOCAL))
|
||||||
{
|
{
|
||||||
llassert(local_size != 0); // we're assuming there is a non empty local file here...
|
llassert(local_size != 0); // we're assuming there is a non empty local file here...
|
||||||
if (!mDataSize || mDataSize > local_size/* - mOffset*/)
|
if (!mDataSize || mDataSize > local_size - mOffset)
|
||||||
{
|
{
|
||||||
mDataSize = local_size/* - mOffset*/;
|
mDataSize = local_size - mOffset;
|
||||||
}
|
}
|
||||||
// Allocate read buffer
|
// Allocate read buffer
|
||||||
mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize);
|
mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize);
|
||||||
S32 bytes_read = LLAPRFile::readEx(local_filename,
|
S32 bytes_read = LLAPRFile::readEx(local_filename, mReadData, mOffset, mDataSize);
|
||||||
mReadData, mOffset, mDataSize);
|
|
||||||
if (bytes_read != mDataSize)
|
if (bytes_read != mDataSize)
|
||||||
{
|
{
|
||||||
llwarns << "Error reading file from local cache: " << local_filename
|
llwarns << "Error reading file from local cache: " << local_filename
|
||||||
@@ -513,19 +512,9 @@ bool LLTextureCacheRemoteWorker::doRead()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (mImageSize > TEXTURE_CACHE_ENTRY_SIZE)
|
|
||||||
{
|
|
||||||
LL_DEBUGS("TextureCache") << "LLTextureCacheWorker: no body for texture: " << mID << LL_ENDL;
|
|
||||||
FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
|
|
||||||
mReadData = NULL;
|
|
||||||
mDataSize = -1; // failed
|
|
||||||
done = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// No body, we're done.
|
// No body, we're done.
|
||||||
mDataSize = llmax(TEXTURE_CACHE_ENTRY_SIZE - mOffset, 0);
|
mDataSize = llmax(TEXTURE_CACHE_ENTRY_SIZE - mOffset, 0);
|
||||||
}
|
lldebugs << "No body file for: " << filename << llendl;
|
||||||
}
|
}
|
||||||
// Nothing else to do at that point...
|
// Nothing else to do at that point...
|
||||||
done = true;
|
done = true;
|
||||||
@@ -759,7 +748,6 @@ LLTextureCache::~LLTextureCache()
|
|||||||
{
|
{
|
||||||
clearDeleteList();
|
clearDeleteList();
|
||||||
writeUpdatedEntries();
|
writeUpdatedEntries();
|
||||||
purgeTextureFilesTimeSliced(true); // VWR-3878 - NB - force-flush all pending file deletes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -1427,21 +1415,22 @@ void LLTextureCache::readHeaderCache()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (num_entries - empty_entries > sCacheMaxEntries)
|
if (num_entries > sCacheMaxEntries)
|
||||||
{
|
{
|
||||||
// Special case: cache size was reduced, need to remove entries
|
// Special case: cache size was reduced, need to remove entries
|
||||||
// Note: After we prune entries, we will call this again and create the LRU
|
// Note: After we prune entries, we will call this again and create the LRU
|
||||||
U32 entries_to_purge = (num_entries - empty_entries) - sCacheMaxEntries;
|
U32 entries_to_purge = (num_entries - empty_entries) - sCacheMaxEntries;
|
||||||
llinfos << "Texture Cache Entries: " << num_entries << " Max: " << sCacheMaxEntries << " Empty: " << empty_entries << " Purging: " << entries_to_purge << llendl;
|
llinfos << "Texture Cache Entries: " << num_entries << " Max: " << sCacheMaxEntries << " Empty: " << empty_entries << " Purging: " << entries_to_purge << llendl;
|
||||||
// We can exit the following loop with the given condition, since if we'd reach the end of the lru set we'd have:
|
if (entries_to_purge > 0)
|
||||||
// purge_list.size() = lru.size() = num_entries - empty_entries = entries_to_purge + sCacheMaxEntries >= entries_to_purge
|
{
|
||||||
// So, it's certain that iter will never reach lru.end() first.
|
for (std::set<lru_data_t>::iterator iter = lru.begin(); iter != lru.end(); ++iter)
|
||||||
std::set<lru_data_t>::iterator iter = lru.begin();
|
|
||||||
while (purge_list.size() < entries_to_purge)
|
|
||||||
{
|
{
|
||||||
purge_list.insert(iter->second);
|
purge_list.insert(iter->second);
|
||||||
++iter;
|
if (purge_list.size() >= entries_to_purge)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
llassert_always(purge_list.size() >= entries_to_purge);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1555,18 +1544,11 @@ void LLTextureCache::purgeAllTextures(bool purge_directories)
|
|||||||
|
|
||||||
void LLTextureCache::purgeTextures(bool validate)
|
void LLTextureCache::purgeTextures(bool validate)
|
||||||
{
|
{
|
||||||
mDoPurge = FALSE;
|
|
||||||
|
|
||||||
if (mReadOnly)
|
if (mReadOnly)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!validate && mTexturesSizeTotal <= sCacheMaxTexturesSize)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mThreaded)
|
if (!mThreaded)
|
||||||
{
|
{
|
||||||
// *FIX:Mani - watchdog off.
|
// *FIX:Mani - watchdog off.
|
||||||
@@ -1582,15 +1564,12 @@ void LLTextureCache::purgeTextures(bool validate)
|
|||||||
U32 num_entries = openAndReadEntries(entries);
|
U32 num_entries = openAndReadEntries(entries);
|
||||||
if (!num_entries)
|
if (!num_entries)
|
||||||
{
|
{
|
||||||
LLAppViewer::instance()->resumeMainloopTimeout();
|
|
||||||
return; // nothing to purge
|
return; // nothing to purge
|
||||||
}
|
}
|
||||||
|
|
||||||
LL_INFOS("TextureCache") << "TEXTURE CACHE: Purging." << LL_ENDL;
|
|
||||||
|
|
||||||
// Use mTexturesSizeMap to collect UUIDs of textures with bodies
|
// Use mTexturesSizeMap to collect UUIDs of textures with bodies
|
||||||
typedef std::set<std::pair<U32,S32> > time_idx_set_t;
|
typedef std::set<std::pair<U32,S32> > time_idx_set_t;
|
||||||
time_idx_set_t time_idx_set;
|
std::set<std::pair<U32,S32> > time_idx_set;
|
||||||
for (size_map_t::iterator iter1 = mTexturesSizeMap.begin();
|
for (size_map_t::iterator iter1 = mTexturesSizeMap.begin();
|
||||||
iter1 != mTexturesSizeMap.end(); ++iter1)
|
iter1 != mTexturesSizeMap.end(); ++iter1)
|
||||||
{
|
{
|
||||||
@@ -1606,9 +1585,6 @@ void LLTextureCache::purgeTextures(bool validate)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
llerrs << "mTexturesSizeMap / mHeaderIDMap corrupted." << llendl ;
|
llerrs << "mTexturesSizeMap / mHeaderIDMap corrupted." << llendl ;
|
||||||
//clearCorruptedCache();
|
|
||||||
//LLAppViewer::instance()->resumeMainloopTimeout();
|
|
||||||
//return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1661,8 +1637,7 @@ void LLTextureCache::purgeTextures(bool validate)
|
|||||||
{
|
{
|
||||||
purge_count++;
|
purge_count++;
|
||||||
LL_DEBUGS("TextureCache") << "PURGING: " << filename << LL_ENDL;
|
LL_DEBUGS("TextureCache") << "PURGING: " << filename << LL_ENDL;
|
||||||
mFilesToDelete.insert(std::make_pair(entries[idx].mID, filename));
|
removeEntry(idx, entries[idx], filename) ;
|
||||||
removeEntry(idx, entries[idx], filename, false); // remove the entry but not the file
|
|
||||||
cache_size -= entries[idx].mBodySize;
|
cache_size -= entries[idx].mBodySize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1674,80 +1649,11 @@ void LLTextureCache::purgeTextures(bool validate)
|
|||||||
// *FIX:Mani - watchdog back on.
|
// *FIX:Mani - watchdog back on.
|
||||||
LLAppViewer::instance()->resumeMainloopTimeout();
|
LLAppViewer::instance()->resumeMainloopTimeout();
|
||||||
|
|
||||||
mSlicedPurgeTimer.reset();
|
|
||||||
|
|
||||||
LL_INFOS("TextureCache") << "TEXTURE CACHE:"
|
LL_INFOS("TextureCache") << "TEXTURE CACHE:"
|
||||||
<< " PURGED: " << purge_count
|
<< " PURGED: " << purge_count
|
||||||
<< " ENTRIES: " << num_entries
|
<< " ENTRIES: " << num_entries
|
||||||
<< " CACHE SIZE: " << mTexturesSizeTotal / (1024 * 1024) << " MB"
|
<< " CACHE SIZE: " << mTexturesSizeTotal / 1024*1024 << " MB"
|
||||||
<< llendl;
|
<< llendl;
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void LLTextureCache::purgeTextureFilesTimeSliced(bool force)
|
|
||||||
{
|
|
||||||
const F32 delay_between_passes = 2.0f; // seconds
|
|
||||||
const F32 max_time_per_pass = 0.1f; // seconds
|
|
||||||
|
|
||||||
if (!force && mSlicedPurgeTimer.getElapsedTimeF32() <= delay_between_passes)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mFilesToDelete.empty())
|
|
||||||
{
|
|
||||||
LL_INFOS("TextureCache") << "time sliced purging with " << mFilesToDelete.size()
|
|
||||||
<< " files scheduled for deletion" << LL_ENDL;
|
|
||||||
|
|
||||||
LLMutexLock lock(&mHeaderMutex);
|
|
||||||
mSlicedPurgeTimer.reset();
|
|
||||||
U32 purged = 0;
|
|
||||||
std::string filename;
|
|
||||||
|
|
||||||
for (LLTextureCache::purge_map_t::iterator iter = mFilesToDelete.begin(); iter != mFilesToDelete.end(); )
|
|
||||||
{
|
|
||||||
LLTextureCache::purge_map_t::iterator curiter = iter++;
|
|
||||||
// Only remove files for textures that have not been cached again
|
|
||||||
// since we selected them for removal !
|
|
||||||
if (mHeaderIDMap.find(curiter->first) == mHeaderIDMap.end())
|
|
||||||
{
|
|
||||||
filename = curiter->second;
|
|
||||||
if(LLAPRFile::isExist(filename))
|
|
||||||
LLAPRFile::remove(filename);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LL_DEBUGS("TextureCache") << curiter->second
|
|
||||||
<< " selected for removal, but texture cached again since !"
|
|
||||||
<< LL_ENDL;
|
|
||||||
}
|
|
||||||
mFilesToDelete.erase(curiter);
|
|
||||||
purged++;
|
|
||||||
|
|
||||||
if (!force && mSlicedPurgeTimer.getElapsedTimeF32() > max_time_per_pass)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mFilesToDelete.empty())
|
|
||||||
{
|
|
||||||
LL_INFOS("TextureCache") << "time sliced purge finished with " << purged
|
|
||||||
<< " files deleted in "
|
|
||||||
<< mSlicedPurgeTimer.getElapsedTimeF32()
|
|
||||||
<< "s" << LL_ENDL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LL_INFOS("TextureCache") << "time sliced purge: " << purged
|
|
||||||
<< " files deleted in "
|
|
||||||
<< mSlicedPurgeTimer.getElapsedTimeF32()
|
|
||||||
<< "s (" << mFilesToDelete.size()
|
|
||||||
<< " files left for next pass)" << LL_ENDL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mSlicedPurgeTimer.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -1888,11 +1794,12 @@ LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 prio
|
|||||||
}
|
}
|
||||||
if (mDoPurge)
|
if (mDoPurge)
|
||||||
{
|
{
|
||||||
|
// NOTE: This may cause an occasional hiccup,
|
||||||
|
// but it really needs to be done on the control thread
|
||||||
|
// (i.e. here)
|
||||||
purgeTextures(false);
|
purgeTextures(false);
|
||||||
|
mDoPurge = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
purgeTextureFilesTimeSliced(); // VWR-3878 - NB - purge textures from cache in a non-hiccup-way
|
|
||||||
|
|
||||||
LLMutexLock lock(&mWorkersMutex);
|
LLMutexLock lock(&mWorkersMutex);
|
||||||
LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id,
|
LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id,
|
||||||
data, datasize, 0,
|
data, datasize, 0,
|
||||||
@@ -1951,7 +1858,7 @@ void LLTextureCache::removeCachedTexture(const LLUUID& id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//called after mHeaderMutex is locked.
|
//called after mHeaderMutex is locked.
|
||||||
void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename, bool remove_file)
|
void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename)
|
||||||
{
|
{
|
||||||
bool file_maybe_exists = true; // Always attempt to remove when idx is invalid.
|
bool file_maybe_exists = true; // Always attempt to remove when idx is invalid.
|
||||||
|
|
||||||
@@ -1969,16 +1876,16 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename, b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mTexturesSizeTotal -= entry.mBodySize;
|
|
||||||
entry.mImageSize = -1;
|
entry.mImageSize = -1;
|
||||||
entry.mBodySize = 0;
|
entry.mBodySize = 0;
|
||||||
mHeaderIDMap.erase(entry.mID);
|
mHeaderIDMap.erase(entry.mID);
|
||||||
mTexturesSizeMap.erase(entry.mID);
|
mTexturesSizeMap.erase(entry.mID);
|
||||||
|
|
||||||
|
mTexturesSizeTotal -= entry.mBodySize;
|
||||||
mFreeList.insert(idx);
|
mFreeList.insert(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remove_file && file_maybe_exists)
|
if (file_maybe_exists)
|
||||||
{
|
{
|
||||||
LLAPRFile::remove(filename);
|
LLAPRFile::remove(filename);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,31 +2,25 @@
|
|||||||
* @file lltexturecache.h
|
* @file lltexturecache.h
|
||||||
* @brief Object for managing texture cachees.
|
* @brief Object for managing texture cachees.
|
||||||
*
|
*
|
||||||
* $LicenseInfo:firstyear=2000&license=viewergpl$
|
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
|
||||||
*
|
|
||||||
* Copyright (c) 2000-2009, Linden Research, Inc.
|
|
||||||
*
|
|
||||||
* Second Life Viewer Source Code
|
* Second Life Viewer Source Code
|
||||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
* Copyright (C) 2010, Linden Research, Inc.
|
||||||
* to you under the terms of the GNU General Public License, version 2.0
|
|
||||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
|
||||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
|
||||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
|
||||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
|
||||||
*
|
*
|
||||||
* There are special exceptions to the terms and conditions of the GPL as
|
* This library is free software; you can redistribute it and/or
|
||||||
* it is applied to this Source Code. View the full text of the exception
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
* License as published by the Free Software Foundation;
|
||||||
* online at
|
* version 2.1 of the License only.
|
||||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
|
||||||
*
|
*
|
||||||
* By copying, modifying or distributing this software, you acknowledge
|
* This library is distributed in the hope that it will be useful,
|
||||||
* that you have read and understood your obligations described above,
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* and agree to abide by those obligations.
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
* License along with this library; if not, write to the Free Software
|
||||||
* COMPLETENESS OR PERFORMANCE.
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||||
* $/LicenseInfo$
|
* $/LicenseInfo$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -154,7 +148,6 @@ private:
|
|||||||
void clearCorruptedCache();
|
void clearCorruptedCache();
|
||||||
void purgeAllTextures(bool purge_directories);
|
void purgeAllTextures(bool purge_directories);
|
||||||
void purgeTextures(bool validate);
|
void purgeTextures(bool validate);
|
||||||
void purgeTextureFilesTimeSliced(bool force = false);
|
|
||||||
LLAPRFile* openHeaderEntriesFile(bool readonly, S32 offset);
|
LLAPRFile* openHeaderEntriesFile(bool readonly, S32 offset);
|
||||||
void closeHeaderEntriesFile();
|
void closeHeaderEntriesFile();
|
||||||
void readEntriesHeader();
|
void readEntriesHeader();
|
||||||
@@ -166,7 +159,7 @@ private:
|
|||||||
void writeEntriesAndClose(const std::vector<Entry>& entries);
|
void writeEntriesAndClose(const std::vector<Entry>& entries);
|
||||||
void readEntryFromHeaderImmediately(S32& idx, Entry& entry) ;
|
void readEntryFromHeaderImmediately(S32& idx, Entry& entry) ;
|
||||||
void writeEntryToHeaderImmediately(S32& idx, Entry& entry, bool write_header = false) ;
|
void writeEntryToHeaderImmediately(S32& idx, Entry& entry, bool write_header = false) ;
|
||||||
void removeEntry(S32 idx, Entry& entry, std::string& filename, bool remove_file = true);
|
void removeEntry(S32 idx, Entry& entry, std::string& filename);
|
||||||
void removeCachedTexture(const LLUUID& id) ;
|
void removeCachedTexture(const LLUUID& id) ;
|
||||||
S32 getHeaderCacheEntry(const LLUUID& id, Entry& entry);
|
S32 getHeaderCacheEntry(const LLUUID& id, Entry& entry);
|
||||||
S32 setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imagesize, S32 datasize);
|
S32 setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imagesize, S32 datasize);
|
||||||
@@ -192,10 +185,6 @@ private:
|
|||||||
typedef std::vector<std::pair<LLPointer<Responder>, bool> > responder_list_t;
|
typedef std::vector<std::pair<LLPointer<Responder>, bool> > responder_list_t;
|
||||||
responder_list_t mCompletedList;
|
responder_list_t mCompletedList;
|
||||||
|
|
||||||
typedef std::map<LLUUID, std::string> purge_map_t;
|
|
||||||
purge_map_t mFilesToDelete;
|
|
||||||
LLTimer mSlicedPurgeTimer;
|
|
||||||
|
|
||||||
BOOL mReadOnly;
|
BOOL mReadOnly;
|
||||||
|
|
||||||
// HEADERS (Include first mip)
|
// HEADERS (Include first mip)
|
||||||
|
|||||||
@@ -83,6 +83,7 @@
|
|||||||
#include "llwlparammanager.h"
|
#include "llwlparammanager.h"
|
||||||
#include "llwaterparammanager.h"
|
#include "llwaterparammanager.h"
|
||||||
#include "llpostprocess.h"
|
#include "llpostprocess.h"
|
||||||
|
#include "sgmemstat.h"
|
||||||
|
|
||||||
// [RLVa:KB]
|
// [RLVa:KB]
|
||||||
#include "rlvhandler.h"
|
#include "rlvhandler.h"
|
||||||
@@ -229,6 +230,7 @@ void display_stats()
|
|||||||
U32 memory = (U32)(gMemoryAllocated / (1024*1024));
|
U32 memory = (U32)(gMemoryAllocated / (1024*1024));
|
||||||
llinfos << llformat("MEMORY: %d MB", memory) << llendl;
|
llinfos << llformat("MEMORY: %d MB", memory) << llendl;
|
||||||
llinfos << "THREADS: "<< LLThread::getCount() << llendl;
|
llinfos << "THREADS: "<< LLThread::getCount() << llendl;
|
||||||
|
llinfos << "MALLOC: " << SGMemStat::getPrintableStat() <<llendl;
|
||||||
LLMemory::logMemoryInfo(TRUE) ;
|
LLMemory::logMemoryInfo(TRUE) ;
|
||||||
gRecentMemoryTime.reset();
|
gRecentMemoryTime.reset();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,7 @@
|
|||||||
#include "llfeaturemanager.h"
|
#include "llfeaturemanager.h"
|
||||||
#include "llviewernetwork.h"
|
#include "llviewernetwork.h"
|
||||||
#include "llmeshrepository.h" //for LLMeshRepository::sBytesReceived
|
#include "llmeshrepository.h" //for LLMeshRepository::sBytesReceived
|
||||||
|
#include "sgmemstat.h"
|
||||||
#if LL_LCD_COMPILE
|
#if LL_LCD_COMPILE
|
||||||
#include "lllcd.h"
|
#include "lllcd.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -689,6 +690,17 @@ void update_statistics(U32 frame_count)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
static const F32 mem_stats_freq = 10.f;
|
||||||
|
static LLFrameTimer mem_stats_timer;
|
||||||
|
if (mem_stats_timer.getElapsedTimeF32() >= mem_stats_freq)
|
||||||
|
{
|
||||||
|
LLViewerStats::getInstance()->mMallocStat.addValue(SGMemStat::getMalloc()/1024.f/1024.f);
|
||||||
|
mem_stats_timer.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if LL_LCD_COMPILE
|
#if LL_LCD_COMPILE
|
||||||
bool LCDenabled = gLcdScreen->Enabled();
|
bool LCDenabled = gLcdScreen->Enabled();
|
||||||
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LOGITECH_LCD, LCDenabled);
|
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LOGITECH_LCD, LCDenabled);
|
||||||
|
|||||||
@@ -467,7 +467,7 @@ bool RlvUtil::sendChatReply(S32 nChannel, const std::string& strUTF8Text)
|
|||||||
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||||
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||||
gMessageSystem->nextBlockFast(_PREHASH_ChatData);
|
gMessageSystem->nextBlockFast(_PREHASH_ChatData);
|
||||||
gMessageSystem->addStringFast(_PREHASH_Message, strUTF8Text);
|
gMessageSystem->addStringFast(_PREHASH_Message, utf8str_truncate(strUTF8Text, MAX_MSG_STR_LEN));
|
||||||
gMessageSystem->addU8Fast(_PREHASH_Type, CHAT_TYPE_SHOUT);
|
gMessageSystem->addU8Fast(_PREHASH_Type, CHAT_TYPE_SHOUT);
|
||||||
gMessageSystem->addS32("Channel", nChannel);
|
gMessageSystem->addS32("Channel", nChannel);
|
||||||
gAgent.sendReliableMessage();
|
gAgent.sendReliableMessage();
|
||||||
|
|||||||
@@ -18,14 +18,80 @@
|
|||||||
#include "llviewerprecompiledheaders.h"
|
#include "llviewerprecompiledheaders.h"
|
||||||
#include "sgmemstat.h"
|
#include "sgmemstat.h"
|
||||||
|
|
||||||
|
#if (!LL_WINDOWS && !LL_LINUX)
|
||||||
bool SGMemStat::haveStat() {
|
bool SGMemStat::haveStat() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
F32 SGMemStat::getMalloc() {
|
F32 SGMemStat::getMalloc() {
|
||||||
return 0.f;
|
return 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
U32 SGMemStat::getNumObjects() {
|
U32 SGMemStat::getNumObjects() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string SGMemStat::getPrintableStat() {
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
typedef void (*MallocExtension_GetStats_t)(char* buffer, int buffer_length);
|
||||||
|
typedef int (*MallocExtension_GetNumericProperty_t)(const char* property, size_t* value);
|
||||||
|
//typedef int (*MallocExtension_SetNumericProperty_t)(const char* property, size_t value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MallocExtension_GetNumericProperty_t MallocExtension_GetNumericProperty = 0;
|
||||||
|
static MallocExtension_GetStats_t MallocExtension_GetStats = 0;
|
||||||
|
|
||||||
|
static void initialize() {
|
||||||
|
static bool initialized = false;
|
||||||
|
if (!initialized) {
|
||||||
|
apr_dso_handle_t* hprog = 0;
|
||||||
|
LLAPRPool pool;
|
||||||
|
pool.create();
|
||||||
|
#if LL_WINDOWS
|
||||||
|
apr_dso_load(&hprog, "libtcmalloc_minimal.dll", pool());
|
||||||
|
#else
|
||||||
|
apr_dso_load(&hprog, 0, pool());
|
||||||
|
#endif
|
||||||
|
apr_dso_sym((apr_dso_handle_sym_t*)&MallocExtension_GetNumericProperty,
|
||||||
|
hprog, "MallocExtension_GetNumericProperty");
|
||||||
|
apr_dso_sym((apr_dso_handle_sym_t*)&MallocExtension_GetStats,
|
||||||
|
hprog, "MallocExtension_GetStats");
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SGMemStat::haveStat() {
|
||||||
|
initialize();
|
||||||
|
return MallocExtension_GetNumericProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
F32 SGMemStat::getMalloc() {
|
||||||
|
if(MallocExtension_GetNumericProperty) {
|
||||||
|
size_t value;
|
||||||
|
MallocExtension_GetNumericProperty("generic.current_allocated_bytes", &value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
else return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
U32 SGMemStat::getNumObjects() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SGMemStat::getPrintableStat() {
|
||||||
|
initialize();
|
||||||
|
if (MallocExtension_GetStats) {
|
||||||
|
char buffer[4096];
|
||||||
|
buffer[4095] = 0;
|
||||||
|
MallocExtension_GetStats(buffer, 4095);
|
||||||
|
return std::string(buffer);
|
||||||
|
}
|
||||||
|
else return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ F32 getMalloc();
|
|||||||
|
|
||||||
U32 getNumObjects();
|
U32 getNumObjects();
|
||||||
|
|
||||||
|
std::string getPrintableStat();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user