From 0841479ccc424b39a252117977d620dc6ccd7afd Mon Sep 17 00:00:00 2001 From: Shyotl Date: Wed, 6 Apr 2016 01:31:20 -0500 Subject: [PATCH] llcommon merge. Added LLUnits. --- indra/llcommon/CMakeLists.txt | 4 + indra/llcommon/llalignedarray.h | 10 +- indra/llcommon/llbase64.cpp | 42 +- indra/llcommon/lldate.cpp | 6 +- indra/llcommon/lldate.h | 9 +- indra/llcommon/lleventtimer.cpp | 2 +- indra/llcommon/llfile.cpp | 2 +- indra/llcommon/llfindlocale.cpp | 4 +- indra/llcommon/llfixedbuffer.cpp | 3 +- indra/llcommon/llhandle.h | 13 +- indra/llcommon/lllivefile.cpp | 81 +-- indra/llcommon/llmd5.cpp | 12 +- indra/llcommon/llmemory.cpp | 56 +- indra/llcommon/llmemory.h | 134 +++- indra/llcommon/llmortician.h | 1 + indra/llcommon/llprocessor.cpp | 6 +- indra/llcommon/llprocessor.h | 4 +- indra/llcommon/llqueuedthread.cpp | 11 +- indra/llcommon/llqueuedthread.h | 4 +- indra/llcommon/llrefcount.cpp | 17 +- indra/llcommon/llsdserialize_xml.cpp | 3 +- indra/llcommon/llstacktrace.cpp | 2 +- indra/llcommon/llstl.h | 25 +- indra/llcommon/llstring.cpp | 4 +- indra/llcommon/llsys.cpp | 46 +- indra/llcommon/llsys.h | 6 +- indra/llcommon/lltimer.cpp | 118 ++-- indra/llcommon/lltimer.h | 50 +- indra/llcommon/llunits.h | 129 ++++ indra/llcommon/llunittype.h | 838 ++++++++++++++++++++++++++ indra/llcommon/lluuid.cpp | 4 +- indra/llcommon/llwin32headers.h | 42 ++ indra/llcommon/llwin32headerslean.h | 40 ++ indra/llcommon/llworkerthread.cpp | 11 +- indra/llmath/llvolume.cpp | 17 +- indra/llrender/llgltexture.cpp | 2 +- indra/llrender/llgltexture.h | 2 +- indra/llrender/llimagegl.cpp | 52 +- indra/llrender/llimagegl.h | 23 +- indra/llrender/llvertexbuffer.cpp | 6 +- indra/llui/llnotifications.cpp | 2 +- indra/newview/llappviewer.cpp | 15 +- indra/newview/llappviewer.h | 2 +- indra/newview/llfeaturemanager.cpp | 2 +- indra/newview/llfloaterabout.cpp | 2 +- indra/newview/llpaneldisplay.cpp | 8 +- indra/newview/llspatialpartition.h | 14 + indra/newview/lltexturecache.h | 6 +- indra/newview/lltexturefetch.cpp | 10 +- indra/newview/lltextureview.cpp | 38 +- indra/newview/llviewercontrol.cpp | 2 +- indra/newview/llviewerdisplay.cpp | 6 +- indra/newview/llviewermessage.cpp | 21 +- indra/newview/llviewerstats.cpp | 69 ++- indra/newview/llviewerstats.h | 6 +- indra/newview/llviewertexture.cpp | 131 ++-- indra/newview/llviewertexture.h | 15 +- indra/newview/llviewertexturelist.cpp | 127 ++-- indra/newview/llviewertexturelist.h | 17 +- indra/newview/llviewerwindow.cpp | 2 +- indra/newview/llvoavatar.cpp | 10 +- indra/newview/llvoavatar.h | 2 +- indra/newview/llvoavatarself.cpp | 16 +- indra/newview/llvoavatarself.h | 2 +- indra/newview/llvovolume.cpp | 148 +++-- indra/newview/pipeline.cpp | 2 +- 66 files changed, 1895 insertions(+), 621 deletions(-) create mode 100644 indra/llcommon/llunits.h create mode 100644 indra/llcommon/llunittype.h create mode 100644 indra/llcommon/llwin32headers.h create mode 100644 indra/llcommon/llwin32headerslean.h diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 00c4b4109..3344d1932 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -230,9 +230,13 @@ set(llcommon_HEADER_FILES llthreadsafequeue.h lltimer.h lltreeiterators.h + llunits.h + llunittype.h lltypeinfolookup.h lluri.h lluuid.h + llwin32headers.h + llwin32headerslean.h llworkerthread.h metaclass.h metaclasst.h diff --git a/indra/llcommon/llalignedarray.h b/indra/llcommon/llalignedarray.h index 14e25e78d..d6ab5ed3d 100644 --- a/indra/llcommon/llalignedarray.h +++ b/indra/llcommon/llalignedarray.h @@ -64,7 +64,7 @@ LLAlignedArray::LLAlignedArray() template LLAlignedArray::~LLAlignedArray() { - ll_aligned_free(mArray); + ll_aligned_free(mArray); mArray = NULL; mElementCount = 0; mCapacity = 0; @@ -78,7 +78,7 @@ void LLAlignedArray::push_back(const T& elem) { mCapacity++; mCapacity *= 2; - T* new_buf = (T*) ll_aligned_malloc(mCapacity*sizeof(T), alignment); + T* new_buf = (T*) ll_aligned_malloc(mCapacity*sizeof(T)); if (mArray) { ll_memcpy_nonaliased_aligned_16((char*)new_buf, (char*)mArray, sizeof(T)*mElementCount); @@ -90,7 +90,7 @@ void LLAlignedArray::push_back(const T& elem) mArray[mElementCount++] = elem; //delete old array here to prevent error on a.push_back(a[0]) - ll_aligned_free(old_buf); + ll_aligned_free(old_buf); } template @@ -99,11 +99,11 @@ void LLAlignedArray::resize(U32 size) if (mCapacity < size) { mCapacity = size+mCapacity*2; - T* new_buf = mCapacity > 0 ? (T*) ll_aligned_malloc(mCapacity*sizeof(T), alignment) : NULL; + T* new_buf = mCapacity > 0 ? (T*) ll_aligned_malloc(mCapacity*sizeof(T)) : NULL; if (mArray) { ll_memcpy_nonaliased_aligned_16((char*) new_buf, (char*) mArray, sizeof(T)*mElementCount); - ll_aligned_free(mArray); + ll_aligned_free(mArray); } /*for (U32 i = mElementCount; i < mCapacity; ++i) diff --git a/indra/llcommon/llbase64.cpp b/indra/llcommon/llbase64.cpp index 4e75e4591..6705a6542 100644 --- a/indra/llcommon/llbase64.cpp +++ b/indra/llcommon/llbase64.cpp @@ -30,32 +30,36 @@ #include "llbase64.h" #include + #include "apr_base64.h" + // static std::string LLBase64::encode(const U8* input, size_t input_size) { - if (!(input && input_size > 0)) return LLStringUtil::null; - - // Yes, it returns int. - int b64_buffer_length = apr_base64_encode_len(input_size); - char* b64_buffer = new char[b64_buffer_length]; - - // This is faster than apr_base64_encode() if you know - // you're not on an EBCDIC machine. Also, the output is - // null terminated, even though the documentation doesn't - // specify. See apr_base64.c for details. JC - b64_buffer_length = apr_base64_encode_binary( - b64_buffer, - input, - input_size); - std::string result; - result.assign(b64_buffer); - delete[] b64_buffer; - - return result; + std::string output; + if (input + && input_size > 0) + { + // Yes, it returns int. + int b64_buffer_length = apr_base64_encode_len(input_size); + char* b64_buffer = new char[b64_buffer_length]; + + // This is faster than apr_base64_encode() if you know + // you're not on an EBCDIC machine. Also, the output is + // null terminated, even though the documentation doesn't + // specify. See apr_base64.c for details. JC + b64_buffer_length = apr_base64_encode_binary( + b64_buffer, + input, + input_size); + output.assign(b64_buffer); + delete[] b64_buffer; + } + return output; } + // static std::string LLBase64::encode(const std::string& in_str) { diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp index 065a72215..e5af5ced2 100644 --- a/indra/llcommon/lldate.cpp +++ b/indra/llcommon/lldate.cpp @@ -55,8 +55,8 @@ LLDate::LLDate(const LLDate& date) : mSecondsSinceEpoch(date.mSecondsSinceEpoch) {} -LLDate::LLDate(F64 seconds_since_epoch) : - mSecondsSinceEpoch(seconds_since_epoch) +LLDate::LLDate(F64SecondsImplicit seconds_since_epoch) : + mSecondsSinceEpoch(seconds_since_epoch.value()) {} LLDate::LLDate(const std::string& iso8601_date) @@ -83,7 +83,7 @@ std::string LLDate::asString() const // is one of the standards used and the prefered format std::string LLDate::asRFC1123() const { - return toHTTPDateString(LLStringExplicit("%A, %d %b %Y %H:%M:%S GMT")); + return toHTTPDateString (std::string ("%A, %d %b %Y %H:%M:%S GMT")); } LLFastTimer::DeclareTimer FT_DATE_FORMAT("Date Format"); diff --git a/indra/llcommon/lldate.h b/indra/llcommon/lldate.h index 7e8ae6368..863c3d02a 100644 --- a/indra/llcommon/lldate.h +++ b/indra/llcommon/lldate.h @@ -38,9 +38,8 @@ #include #include -#include "llpreprocessor.h" - #include "stdtypes.h" +#include "llunits.h" /** * @class LLDate @@ -64,9 +63,9 @@ public: /** * @brief Construct a date from a seconds since epoch value. * - * @pararm seconds_since_epoch The number of seconds since UTC epoch. + * @param seconds_since_epoch The number of seconds since UTC epoch. */ - LLDate(F64 seconds_since_epoch); + LLDate(F64SecondsImplicit seconds_since_epoch); /** * @brief Construct a date from a string representation @@ -163,4 +162,6 @@ LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLDate& date); // Helper function to stream in a date LL_COMMON_API std::istream& operator>>(std::istream& s, LLDate& date); + + #endif // LL_LLDATE_H diff --git a/indra/llcommon/lleventtimer.cpp b/indra/llcommon/lleventtimer.cpp index 957b502dc..c491e37cb 100644 --- a/indra/llcommon/lleventtimer.cpp +++ b/indra/llcommon/lleventtimer.cpp @@ -65,7 +65,7 @@ LLEventTimer::~LLEventTimer() void LLEventTimer::updateClass() { std::list completed_timers; - for (instance_iter iter = beginInstances(), iter_end = endInstances(); iter != iter_end;) + for (instance_iter iter = beginInstances(), end_iter = endInstances(); iter != end_iter;) { LLEventTimer& timer = *iter++; F32 et = timer.mEventTimer.getElapsedTimeF32(); diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index 7660baa90..4f8ec6756 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -28,7 +28,7 @@ */ #if LL_WINDOWS -#include +#include "llwin32headerslean.h" #include // Windows errno #else #include diff --git a/indra/llcommon/llfindlocale.cpp b/indra/llcommon/llfindlocale.cpp index 505f5c540..d91620926 100644 --- a/indra/llcommon/llfindlocale.cpp +++ b/indra/llcommon/llfindlocale.cpp @@ -39,7 +39,7 @@ #include #ifdef WIN32 -#include +#include "llwin32headers.h" #include #endif @@ -183,7 +183,7 @@ canonise_fl(FL_Locale *l) { #define RML(pn,sn) MAKELANGID(LANG_##pn, SUBLANG_##sn) struct IDToCode { LANGID id; - char* code; + const char* code; }; static const IDToCode both_to_code[] = { {ML(ENGLISH,US), "en_US.ISO_8859-1"}, diff --git a/indra/llcommon/llfixedbuffer.cpp b/indra/llcommon/llfixedbuffer.cpp index 4b5cdbe28..bd4db8be8 100644 --- a/indra/llcommon/llfixedbuffer.cpp +++ b/indra/llcommon/llfixedbuffer.cpp @@ -30,7 +30,8 @@ LLFixedBuffer::LLFixedBuffer(const U32 max_lines) : LLLineBuffer(), - mMaxLines(max_lines) + mMaxLines(max_lines), + mMutex() { mTimer.reset(); } diff --git a/indra/llcommon/llhandle.h b/indra/llcommon/llhandle.h index 6af5e198d..401e4d759 100644 --- a/indra/llcommon/llhandle.h +++ b/indra/llcommon/llhandle.h @@ -194,13 +194,6 @@ public: return mHandle; } -protected: - typedef LLHandle handle_type_t; - LLHandleProvider() - { - // provided here to enforce T deriving from LLHandleProvider - } - template LLHandle getDerivedHandle(typename boost::enable_if< typename boost::is_convertible >::type* dummy = 0) const { @@ -209,6 +202,12 @@ protected: return downcast_handle; } +protected: + typedef LLHandle handle_type_t; + LLHandleProvider() + { + // provided here to enforce T deriving from LLHandleProvider + } private: mutable LLRootHandle mHandle; diff --git a/indra/llcommon/lllivefile.cpp b/indra/llcommon/lllivefile.cpp index ce6ac4fac..88274a91c 100644 --- a/indra/llcommon/lllivefile.cpp +++ b/indra/llcommon/lllivefile.cpp @@ -88,46 +88,51 @@ LLLiveFile::~LLLiveFile() bool LLLiveFile::Impl::check() { - if (!mForceCheck && mRefreshTimer.getElapsedTimeF32() < mRefreshPeriod) + bool detected_change = false; + // Skip the check if not enough time has elapsed and we're not + // forcing a check of the file + if (mForceCheck || mRefreshTimer.getElapsedTimeF32() >= mRefreshPeriod) { - // Skip the check if not enough time has elapsed and we're not - // forcing a check of the file - return false; - } - mForceCheck = false; - mRefreshTimer.reset(); + mForceCheck = false; // force only forces one check + mRefreshTimer.reset(); // don't check again until mRefreshPeriod has passed - // Stat the file to see if it exists and when it was last modified. - llstat stat_data; - int res = LLFile::stat(mFilename, &stat_data); - - if (res) - { - // Couldn't stat the file, that means it doesn't exist or is - // broken somehow. Clear flags and return. - if (mLastExists) - { - mLastExists = false; - return true; // no longer existing is a change! - } - return false; - } - - // The file exists, decide if we want to load it. - if (mLastExists) - { - // The file existed last time, don't read it if it hasn't changed since - // last time. - if (stat_data.st_mtime <= mLastModTime) - { - return false; - } - } - - // We want to read the file. Update status info for the file. - mLastExists = true; - mLastStatTime = stat_data.st_mtime; - return true; + // Stat the file to see if it exists and when it was last modified. + llstat stat_data; + if (LLFile::stat(mFilename, &stat_data)) + { + // Couldn't stat the file, that means it doesn't exist or is + // broken somehow. + if (mLastExists) + { + mLastExists = false; + detected_change = true; // no longer existing is a change! + LL_DEBUGS() << "detected deleted file '" << mFilename << "'" << LL_ENDL; + } + } + else + { + // The file exists + if ( ! mLastExists ) + { + // last check, it did not exist - that counts as a change + LL_DEBUGS() << "detected created file '" << mFilename << "'" << LL_ENDL; + detected_change = true; + } + else if ( stat_data.st_mtime > mLastModTime ) + { + // file modification time is newer than last check + LL_DEBUGS() << "detected updated file '" << mFilename << "'" << LL_ENDL; + detected_change = true; + } + mLastExists = true; + mLastStatTime = stat_data.st_mtime; + } + } + if (detected_change) + { + LL_INFOS() << "detected file change '" << mFilename << "'" << LL_ENDL; + } + return detected_change; } void LLLiveFile::Impl::changed() diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp index 46775313d..1881620e6 100644 --- a/indra/llcommon/llmd5.cpp +++ b/indra/llcommon/llmd5.cpp @@ -119,6 +119,12 @@ void LLMD5::update (const uint1 *input, const uint4 input_length) { buffer_space = 64 - buffer_index; // how much space is left in buffer + // now, transform each 64-byte piece of the input, bypassing the buffer + if (input == NULL || input_length == 0){ + std::cerr << "LLMD5::update: Invalid input!" << std::endl; + return; + } + // Transform as many times as possible. if (input_length >= buffer_space) { // ie. we have enough to fill the buffer // fill the rest of the buffer and transform @@ -128,12 +134,6 @@ void LLMD5::update (const uint1 *input, const uint4 input_length) { buffer_space); transform (buffer); - // now, transform each 64-byte piece of the input, bypassing the buffer - if (input == NULL || input_length == 0){ - std::cerr << "LLMD5::update: Invalid input!" << std::endl; - return; - } - for (input_index = buffer_space; input_index + 63 < input_length; input_index += 64) transform (input+input_index); diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index aba33abde..f843f3c96 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -32,7 +32,7 @@ //#endif #if defined(LL_WINDOWS) -//# include +#include "llwin32headerslean.h" # include #elif defined(LL_DARWIN) # include @@ -50,11 +50,11 @@ //static char* LLMemory::reserveMem = 0; -U32 LLMemory::sAvailPhysicalMemInKB = U32_MAX ; -U32 LLMemory::sMaxPhysicalMemInKB = 0; -U32 LLMemory::sAllocatedMemInKB = 0; -U32 LLMemory::sAllocatedPageSizeInKB = 0 ; -U32 LLMemory::sMaxHeapSizeInKB = U32_MAX ; +U32Kilobytes LLMemory::sAvailPhysicalMemInKB(U32_MAX); +U32Kilobytes LLMemory::sMaxPhysicalMemInKB(0); +U32Kilobytes LLMemory::sAllocatedMemInKB(0); +U32Kilobytes LLMemory::sAllocatedPageSizeInKB(0); +U32Kilobytes LLMemory::sMaxHeapSizeInKB(U32_MAX); BOOL LLMemory::sEnableMemoryFailurePrevention = FALSE; #if __DEBUG_PRIVATE_MEM__ @@ -93,9 +93,9 @@ void LLMemory::freeReserve() } //static -void LLMemory::initMaxHeapSizeGB(F32 max_heap_size_gb, BOOL prevent_heap_failure) +void LLMemory::initMaxHeapSizeGB(F32Gigabytes max_heap_size, BOOL prevent_heap_failure) { - sMaxHeapSizeInKB = (U32)(max_heap_size_gb * 1024 * 1024) ; + sMaxHeapSizeInKB = max_heap_size; sEnableMemoryFailurePrevention = prevent_heap_failure ; } @@ -112,10 +112,10 @@ void LLMemory::updateMemoryInfo() return ; } - sAllocatedMemInKB = (U32)(counters.WorkingSetSize / 1024) ; - sAllocatedPageSizeInKB = (U32)(counters.PagefileUsage / 1024) ; + sAllocatedMemInKB = (U32Bytes)(counters.WorkingSetSize) ; + sAllocatedPageSizeInKB = (U32Bytes)(counters.PagefileUsage) ; - U32 avail_phys, avail_virtual; + U32Kilobytes avail_phys, avail_virtual; LLMemoryInfo::getAvailableMemoryKB(avail_phys, avail_virtual) ; sMaxPhysicalMemInKB = llmin(avail_phys + sAllocatedMemInKB, sMaxHeapSizeInKB); @@ -125,14 +125,16 @@ void LLMemory::updateMemoryInfo() } else { - sAvailPhysicalMemInKB = 0 ; + sAvailPhysicalMemInKB = U32Kilobytes(0); } #else //not valid for other systems for now. - sAllocatedMemInKB = (U32)(LLMemory::getCurrentRSS() / 1024) ; - sMaxPhysicalMemInKB = U32_MAX ; - sAvailPhysicalMemInKB = U32_MAX ; + sAllocatedMemInKB = (U32Bytes)LLMemory::getCurrentRSS(); + sMaxPhysicalMemInKB = (U32Bytes)U32_MAX ; + sAvailPhysicalMemInKB = (U32Bytes)U32_MAX ; #endif + + return ; } // @@ -184,8 +186,8 @@ void LLMemory::logMemoryInfo(BOOL update) //static bool LLMemory::isMemoryPoolLow() { - static const U32 LOW_MEMEOY_POOL_THRESHOLD_KB = 64 * 1024 ; //64 MB for emergency use - const static U32 MAX_SIZE_CHECKED_MEMORY_BLOCK = 64 * 1024 * 1024 ; //64 MB + static const U32Megabytes LOW_MEMORY_POOL_THRESHOLD(64); + const static U32Megabytes MAX_SIZE_CHECKED_MEMORY_BLOCK(64); static void* last_reserved_address = NULL ; if(!sEnableMemoryFailurePrevention) @@ -193,32 +195,32 @@ bool LLMemory::isMemoryPoolLow() return false ; //no memory failure prevention. } - if(sAvailPhysicalMemInKB < (LOW_MEMEOY_POOL_THRESHOLD_KB >> 2)) //out of physical memory + if(sAvailPhysicalMemInKB < (LOW_MEMORY_POOL_THRESHOLD / 4)) //out of physical memory { return true ; } - if(sAllocatedPageSizeInKB + (LOW_MEMEOY_POOL_THRESHOLD_KB >> 2) > sMaxHeapSizeInKB) //out of virtual address space. + if(sAllocatedPageSizeInKB + (LOW_MEMORY_POOL_THRESHOLD / 4) > sMaxHeapSizeInKB) //out of virtual address space. { return true ; } - bool is_low = (S32)(sAvailPhysicalMemInKB < LOW_MEMEOY_POOL_THRESHOLD_KB || - sAllocatedPageSizeInKB + LOW_MEMEOY_POOL_THRESHOLD_KB > sMaxHeapSizeInKB) ; + bool is_low = (S32)(sAvailPhysicalMemInKB < LOW_MEMORY_POOL_THRESHOLD + || sAllocatedPageSizeInKB + LOW_MEMORY_POOL_THRESHOLD > sMaxHeapSizeInKB) ; //check the virtual address space fragmentation if(!is_low) { if(!last_reserved_address) { - last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK) ; + last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK.value()) ; } else { - last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK) ; + last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK.value()) ; if(!last_reserved_address) //failed, try once more { - last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK) ; + last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK.value()) ; } } @@ -229,19 +231,19 @@ bool LLMemory::isMemoryPoolLow() } //static -U32 LLMemory::getAvailableMemKB() +U32Kilobytes LLMemory::getAvailableMemKB() { return sAvailPhysicalMemInKB ; } //static -U32 LLMemory::getMaxMemKB() +U32Kilobytes LLMemory::getMaxMemKB() { return sMaxPhysicalMemInKB ; } //static -U32 LLMemory::getAllocatedMemKB() +U32Kilobytes LLMemory::getAllocatedMemKB() { return sAllocatedMemInKB ; } diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 48cd2b7b2..efd61590a 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -27,7 +27,8 @@ #define LLMEMORY_H #include "linden_common.h" - +#include "llunits.h" +#include "stdtypes.h" #include #include #if !LL_WINDOWS @@ -42,6 +43,21 @@ class LLMutex ; #define LL_CHECK_MEMORY #endif + +#if LL_WINDOWS +#define LL_ALIGN_OF __alignof +#else +#define LL_ALIGN_OF __align_of__ +#endif + +#if LL_WINDOWS +#define LL_DEFAULT_HEAP_ALIGN 8 +#elif LL_DARWIN +#define LL_DEFAULT_HEAP_ALIGN 16 +#elif LL_LINUX +#define LL_DEFAULT_HEAP_ALIGN 8 +#endif + // // ll_assert_aligned seems to only exist to set breakpoints in case an alignment check fails. // However, the implementation was horrible: the test was done using a integer modulo after @@ -102,31 +118,43 @@ template T* LL_NEXT_ALIGNED_ADDRESS_64(T* address) #define LL_ALIGN_16(var) LL_ALIGN_PREFIX(16) var LL_ALIGN_POSTFIX(16) -inline void* ll_aligned_malloc( size_t size, int align ) -{ -#if defined(LL_WINDOWS) - return _aligned_malloc(size, align); -#else - void* mem = malloc( size + (align - 1) + sizeof(void*) ); - char* aligned = ((char*)mem) + sizeof(void*); - aligned += align - ((uintptr_t)aligned & (align - 1)); +//------------------------------------------------------------------------------------------------ +//------------------------------------------------------------------------------------------------ + // for enable buffer overrun detection predefine LL_DEBUG_BUFFER_OVERRUN in current library + // change preprocessor code to: #if 1 && defined(LL_WINDOWS) - ((void**)aligned)[-1] = mem; - return aligned; -#endif -} - -inline void ll_aligned_free( void* ptr ) -{ -#if defined(LL_WINDOWS) - _aligned_free(ptr); +#if 0 && defined(LL_WINDOWS) + void* ll_aligned_malloc_fallback( size_t size, int align ); + void ll_aligned_free_fallback( void* ptr ); +//------------------------------------------------------------------------------------------------ #else - if (ptr) + inline void* ll_aligned_malloc_fallback( size_t size, int align ) { - free( ((void**)ptr)[-1] ); + #if defined(LL_WINDOWS) + return _aligned_malloc(size, align); + #else + void* mem = malloc( size + (align - 1) + sizeof(void*) ); + char* aligned = ((char*)mem) + sizeof(void*); + aligned += align - ((uintptr_t)aligned & (align - 1)); + + ((void**)aligned)[-1] = mem; + return aligned; + #endif + } + + inline void ll_aligned_free_fallback( void* ptr ) + { + #if defined(LL_WINDOWS) + _aligned_free(ptr); + #else + if (ptr) + { + free( ((void**)ptr)[-1] ); + } + #endif } #endif -} +//------------------------------------------------------------------------------------------------ #if !LL_USE_TCMALLOC inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed with ll_aligned_free_16(). @@ -189,7 +217,7 @@ inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed wi #if defined(LL_WINDOWS) return _aligned_malloc(size, 32); #elif defined(LL_DARWIN) - return ll_aligned_malloc( size, 32 ); + return ll_aligned_malloc_fallback( size, 32 ); #else void *rtn; if (LL_LIKELY(0 == posix_memalign(&rtn, 32, size))) @@ -204,12 +232,54 @@ inline void ll_aligned_free_32(void *p) #if defined(LL_WINDOWS) _aligned_free(p); #elif defined(LL_DARWIN) - ll_aligned_free( p ); + ll_aligned_free_fallback( p ); #else free(p); // posix_memalign() is compatible with heap deallocator #endif } +// general purpose dispatch functions that are forced inline so they can compile down to a single call +template +LL_FORCE_INLINE void* ll_aligned_malloc(size_t size) +{ + if (LL_DEFAULT_HEAP_ALIGN % ALIGNMENT == 0) + { + return malloc(size); + } + else if (ALIGNMENT == 16) + { + return ll_aligned_malloc_16(size); + } + else if (ALIGNMENT == 32) + { + return ll_aligned_malloc_32(size); + } + else + { + return ll_aligned_malloc_fallback(size, ALIGNMENT); + } +} + +template +LL_FORCE_INLINE void ll_aligned_free(void* ptr) +{ + if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN) + { + free(ptr); + } + else if (ALIGNMENT == 16) + { + ll_aligned_free_16(ptr); + } + else if (ALIGNMENT == 32) + { + return ll_aligned_free_32(ptr); + } + else + { + return ll_aligned_free_fallback(ptr); + } +} // Copy words 16-byte blocks from src to dst. Source and destination MUST NOT OVERLAP. // Source and dest must be 16-byte aligned and size must be multiple of 16. @@ -297,22 +367,22 @@ public: static U64 getCurrentRSS(); static U32 getWorkingSetSize(); static void* tryToAlloc(void* address, U32 size); - static void initMaxHeapSizeGB(F32 max_heap_size_gb, BOOL prevent_heap_failure); + static void initMaxHeapSizeGB(F32Gigabytes max_heap_size, BOOL prevent_heap_failure); static void updateMemoryInfo() ; static void logMemoryInfo(BOOL update = FALSE); static bool isMemoryPoolLow(); - static U32 getAvailableMemKB() ; - static U32 getMaxMemKB() ; - static U32 getAllocatedMemKB() ; + static U32Kilobytes getAvailableMemKB() ; + static U32Kilobytes getMaxMemKB() ; + static U32Kilobytes getAllocatedMemKB() ; private: static char* reserveMem; - static U32 sAvailPhysicalMemInKB ; - static U32 sMaxPhysicalMemInKB ; - static U32 sAllocatedMemInKB; - static U32 sAllocatedPageSizeInKB ; + static U32Kilobytes sAvailPhysicalMemInKB ; + static U32Kilobytes sMaxPhysicalMemInKB ; + static U32Kilobytes sAllocatedMemInKB; + static U32Kilobytes sAllocatedPageSizeInKB ; - static U32 sMaxHeapSizeInKB; + static U32Kilobytes sMaxHeapSizeInKB; static BOOL sEnableMemoryFailurePrevention; }; diff --git a/indra/llcommon/llmortician.h b/indra/llcommon/llmortician.h index 59d284182..074e38fe4 100644 --- a/indra/llcommon/llmortician.h +++ b/indra/llcommon/llmortician.h @@ -34,6 +34,7 @@ #define LLMORTICIAN_H #include "stdtypes.h" +#include class LL_COMMON_API LLMortician { diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index 5c731c691..f86923f9d 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -32,9 +32,7 @@ //#include #if LL_WINDOWS -# define WIN32_LEAN_AND_MEAN -# include -# include +# include "llwin32headerslean.h" # define _interlockedbittestandset _renamed_interlockedbittestandset # define _interlockedbittestandreset _renamed_interlockedbittestandreset # include @@ -881,7 +879,7 @@ LLProcessorInfo::LLProcessorInfo() : mImpl(NULL) LLProcessorInfo::~LLProcessorInfo() {} -F64 LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); } +F64MegahertzImplicit LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); } bool LLProcessorInfo::hasSSE() const { return mImpl->hasSSE(); } bool LLProcessorInfo::hasSSE2() const { return mImpl->hasSSE2(); } bool LLProcessorInfo::hasAltivec() const { return mImpl->hasAltivec(); } diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h index fc2c8dacf..681dd6314 100644 --- a/indra/llcommon/llprocessor.h +++ b/indra/llcommon/llprocessor.h @@ -33,6 +33,8 @@ #ifndef LLPROCESSOR_H #define LLPROCESSOR_H +#include "llunits.h" + class LLProcessorInfoImpl; class LL_COMMON_API LLProcessorInfo @@ -41,7 +43,7 @@ public: LLProcessorInfo(); ~LLProcessorInfo(); - F64 getCPUFrequency() const; + F64MegahertzImplicit getCPUFrequency() const; bool hasSSE() const; bool hasSSE2() const; bool hasAltivec() const; diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 5ba7b8bd8..8fe3acf54 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -35,7 +35,7 @@ LLQueuedThread::LLQueuedThread(const std::string& name, bool threaded, bool should_pause) : LLThread(name), mThreaded(threaded), - mIdleThread(TRUE), + mIdleThread(true), mNextHandle(0), mStarted(FALSE) { @@ -552,14 +552,15 @@ void LLQueuedThread::run() break; } - mIdleThread = FALSE; + mIdleThread = false; threadedUpdate(); - int res = processNextRequest(); - if (res == 0) + int pending_work = processNextRequest(); + + if (pending_work == 0) { - mIdleThread = TRUE; + mIdleThread = true; ms_sleep(1); } //LLThread::yield(); // thread should yield after each request diff --git a/indra/llcommon/llqueuedthread.h b/indra/llcommon/llqueuedthread.h index dda7bf69c..2da59b8ed 100644 --- a/indra/llcommon/llqueuedthread.h +++ b/indra/llcommon/llqueuedthread.h @@ -32,8 +32,6 @@ #include #include -#include "llapr.h" - #include "llthread.h" #include "llsimplehash.h" @@ -204,7 +202,7 @@ public: protected: BOOL mThreaded; // if false, run on main thread and do updates during update() BOOL mStarted; // required when mThreaded is false to call startThread() from update() - LLAtomic32 mIdleThread; // request queue is empty (or we are quitting) and the thread is idle + LLAtomic32 mIdleThread; // request queue is empty (or we are quitting) and the thread is idle typedef std::set request_queue_t; request_queue_t mRequestQueue; diff --git a/indra/llcommon/llrefcount.cpp b/indra/llcommon/llrefcount.cpp index 297c5bb7c..74f4c046f 100644 --- a/indra/llcommon/llrefcount.cpp +++ b/indra/llcommon/llrefcount.cpp @@ -31,15 +31,15 @@ #if LL_REF_COUNT_DEBUG #include "llthread.h" -#include "llapr.h" #endif -LLRefCount::LLRefCount(const LLRefCount& other) -: mRef(0) -{ +LLRefCount::LLRefCount(const LLRefCount& other) : #if LL_REF_COUNT_DEBUG - mCrashAtUnlock = FALSE ; + mMutex(), + mCrashAtUnlock(FALSE), #endif + mRef(0) +{ } LLRefCount& LLRefCount::operator=(const LLRefCount&) @@ -49,11 +49,12 @@ LLRefCount& LLRefCount::operator=(const LLRefCount&) } LLRefCount::LLRefCount() : +#if LL_REF_COUNT_DEBUG + mMutex(), + mCrashAtUnlock(FALSE), +#endif mRef(0) { -#if LL_REF_COUNT_DEBUG - mCrashAtUnlock = FALSE ; -#endif } LLRefCount::~LLRefCount() diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp index 0ffb0e9e1..72e6ac611 100644 --- a/indra/llcommon/llsdserialize_xml.cpp +++ b/indra/llcommon/llsdserialize_xml.cpp @@ -337,10 +337,9 @@ void clear_eol(std::istream& input) static unsigned get_till_eol(std::istream& input, char *buf, unsigned bufsize) { unsigned count = 0; - char c; while (count < bufsize && input.good()) { - input.get(c); + char c = input.get(); buf[count++] = c; if (is_eol(c)) break; diff --git a/indra/llcommon/llstacktrace.cpp b/indra/llcommon/llstacktrace.cpp index e0446c5d0..5f47f8544 100644 --- a/indra/llcommon/llstacktrace.cpp +++ b/indra/llcommon/llstacktrace.cpp @@ -39,7 +39,7 @@ #include #include -#include "windows.h" +#include "llwin32headerslean.h" #include "Dbghelp.h" typedef USHORT NTAPI RtlCaptureStackBackTrace_Function( diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h index 9c66bc886..df4f842d9 100644 --- a/indra/llcommon/llstl.h +++ b/indra/llcommon/llstl.h @@ -508,6 +508,27 @@ llbind2nd(const _Operation& __oper, const _Tp& __x) return llbinder2nd<_Operation>(__oper, _Arg2_type(__x)); } +/** + * Compare std::type_info* pointers a la std::less. We break this out as a + * separate function for use in two different std::less specializations. + */ +inline +bool before(const std::type_info* lhs, const std::type_info* rhs) +{ +#if LL_LINUX && defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 4)) + // If we're building on Linux with gcc, and it's either gcc 3.x or + // 4.{0,1,2,3}, then we have to use a workaround. Note that we use gcc on + // Mac too, and some people build with gcc on Windows (cygwin or mingw). + // On Linux, different load modules may produce different type_info* + // pointers for the same type. Have to compare name strings to get good + // results. + return strcmp(lhs->name(), rhs->name()) < 0; +#else // not Linux, or gcc 4.4+ + // Just use before(), as we normally would + return lhs->before(*rhs) ? true : false; +#endif +} + /** * Specialize std::less to use std::type_info::before(). * See MAINT-1175. It is NEVER a good idea to directly compare std::type_info* @@ -522,7 +543,7 @@ namespace std { bool operator()(const std::type_info* lhs, const std::type_info* rhs) const { - return lhs->before(*rhs); + return before(lhs, rhs); } }; @@ -532,7 +553,7 @@ namespace std { bool operator()(std::type_info* lhs, std::type_info* rhs) const { - return lhs->before(*rhs); + return before(lhs, rhs); } }; } // std diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index f898efe04..93aa4b4f8 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -30,9 +30,7 @@ #include "llerror.h" #if LL_WINDOWS -#define WIN32_LEAN_AND_MEAN -#include -#include +#include "llwin32headerslean.h" #include // for WideCharToMultiByte #endif diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index fd724365e..96fca1496 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -53,9 +53,7 @@ using namespace llsd; #if LL_WINDOWS -# define WIN32_LEAN_AND_MEAN -# include -# include +# include "llwin32headerslean.h" # include // GetPerformanceInfo() et al. # include #elif LL_DARWIN @@ -705,7 +703,7 @@ LLMemoryInfo::LLMemoryInfo() } #if LL_WINDOWS -static U32 LLMemoryAdjustKBResult(U32 inKB) +static U32Kilobytes LLMemoryAdjustKBResult(U32Kilobytes inKB) { // Moved this here from llfloaterabout.cpp @@ -716,16 +714,16 @@ static U32 LLMemoryAdjustKBResult(U32 inKB) // returned from the GetMemoryStatusEx function. Here we keep the // original adjustment from llfoaterabout.cpp until this can be // fixed somehow. - inKB += 1024; + inKB += U32Megabytes(1); return inKB; } #endif -U32 LLMemoryInfo::getPhysicalMemoryKB() const +U32Kilobytes LLMemoryInfo::getPhysicalMemoryKB() const { #if LL_WINDOWS - return LLMemoryAdjustKBResult(mStatsMap["Total Physical KB"].asInteger()); + return LLMemoryAdjustKBResult(U32Kilobytes(mStatsMap["Total Physical KB"].asInteger())); #elif LL_DARWIN // This might work on Linux as well. Someone check... @@ -735,17 +733,17 @@ U32 LLMemoryInfo::getPhysicalMemoryKB() const size_t len = sizeof(phys); sysctl(mib, 2, &phys, &len, NULL, 0); - return (U32)(phys >> 10); + return U64Bytes(phys); #elif LL_LINUX U64 phys = 0; phys = (U64)(getpagesize()) * (U64)(get_phys_pages()); - return (U32)(phys >> 10); + return U64Bytes(phys); #elif LL_SOLARIS U64 phys = 0; phys = (U64)(getpagesize()) * (U64)(sysconf(_SC_PHYS_PAGES)); - return (U32)(phys >> 10); + return U64Bytes(phys); #else return 0; @@ -753,32 +751,32 @@ U32 LLMemoryInfo::getPhysicalMemoryKB() const #endif } -U32 LLMemoryInfo::getPhysicalMemoryClamped() const +U32Bytes LLMemoryInfo::getPhysicalMemoryClamped() const { // Return the total physical memory in bytes, but clamp it // to no more than U32_MAX - U32 phys_kb = getPhysicalMemoryKB(); - if (phys_kb >= 4194304 /* 4GB in KB */) + U32Kilobytes phys_kb = getPhysicalMemoryKB(); + if (phys_kb >= U32Gigabytes(4)) { - return U32_MAX; + return U32Bytes(U32_MAX); } else { - return phys_kb << 10; + return phys_kb; } } //static -void LLMemoryInfo::getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_virtual_mem_kb) +void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32Kilobytes& avail_virtual_mem_kb) { #if LL_WINDOWS // Sigh, this shouldn't be a static method, then we wouldn't have to // reload this data separately from refresh() LLSD statsMap(loadStatsMap()); - avail_physical_mem_kb = statsMap["Avail Physical KB"].asInteger(); - avail_virtual_mem_kb = statsMap["Avail Virtual KB"].asInteger(); + avail_physical_mem_kb = (U32Kilobytes)statsMap["Avail Physical KB"].asInteger(); + avail_virtual_mem_kb = (U32Kilobytes)statsMap["Avail Virtual KB"].asInteger(); #elif LL_DARWIN // mStatsMap is derived from vm_stat, look for (e.g.) "kb free": @@ -795,8 +793,8 @@ void LLMemoryInfo::getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_v // Pageins: 2097212. // Pageouts: 41759. // Object cache: 841598 hits of 7629869 lookups (11% hit rate) - avail_physical_mem_kb = -1 ; - avail_virtual_mem_kb = -1 ; + avail_physical_mem_kb = (U32Kilobytes)-1 ; + avail_virtual_mem_kb = (U32Kilobytes)-1 ; #elif LL_LINUX // mStatsMap is derived from MEMINFO_FILE: @@ -847,15 +845,15 @@ void LLMemoryInfo::getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_v // DirectMap4k: 434168 kB // DirectMap2M: 477184 kB // (could also run 'free', but easier to read a file than run a program) - avail_physical_mem_kb = -1 ; - avail_virtual_mem_kb = -1 ; + avail_physical_mem_kb = (U32Kilobytes)-1 ; + avail_virtual_mem_kb = (U32Kilobytes)-1 ; #else //do not know how to collect available memory info for other systems. //leave it blank here for now. - avail_physical_mem_kb = -1 ; - avail_virtual_mem_kb = -1 ; + avail_physical_mem_kb = (U32Kilobytes)-1 ; + avail_virtual_mem_kb = (U32Kilobytes)-1 ; #endif } diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h index 52b884e5a..accdbb5d2 100644 --- a/indra/llcommon/llsys.h +++ b/indra/llcommon/llsys.h @@ -112,15 +112,15 @@ public: LLMemoryInfo(); ///< Default constructor void stream(std::ostream& s) const; ///< output text info to s - U32 getPhysicalMemoryKB() const; ///< Memory size in KiloBytes + U32Kilobytes getPhysicalMemoryKB() const; /*! Memory size in bytes, if total memory is >= 4GB then U32_MAX will ** be returned. */ - U32 getPhysicalMemoryClamped() const; ///< Memory size in clamped bytes + U32Bytes getPhysicalMemoryClamped() const; ///< Memory size in clamped bytes //get the available memory infomation in KiloBytes. - static void getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_virtual_mem_kb); + static void getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32Kilobytes& avail_virtual_mem_kb); // Retrieve a map of memory statistics. The keys of the map are platform- // dependent. The values are in kilobytes to try to avoid integer overflow. diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index 1ef4aa414..e458cc66a 100644 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -31,11 +31,9 @@ #include "u64.h" #if LL_WINDOWS -# define WIN32_LEAN_AND_MEAN -# include -# include +# include "llwin32headerslean.h" #elif LL_LINUX || LL_SOLARIS || LL_DARWIN -# include +# include # include #else # error "architecture not supported" @@ -81,10 +79,10 @@ void ms_sleep(U32 ms) U32 micro_sleep(U64 us, U32 max_yields) { - // max_yields is unused; just fiddle with it to avoid warnings. - max_yields = 0; - ms_sleep(us / 1000); - return 0; + // max_yields is unused; just fiddle with it to avoid warnings. + max_yields = 0; + ms_sleep((U32)(us / 1000)); + return 0; } #elif LL_LINUX || LL_SOLARIS || LL_DARWIN static void _sleep_loop(struct timespec& thiswait) @@ -216,56 +214,68 @@ U64 get_clock_count() #endif -void update_clock_frequencies() +TimerInfo::TimerInfo() +: mClockFrequency(0.0), + mTotalTimeClockCount(0), + mLastTotalTimeClockCount(0) +{} + +void TimerInfo::update() { - gClockFrequency = calc_clock_frequency(); - gClockFrequencyInv = 1.0/gClockFrequency; - gClocksToMicroseconds = gClockFrequencyInv * SEC_TO_MICROSEC; + mClockFrequency = calc_clock_frequency(); + mClockFrequencyInv = 1.0/mClockFrequency; + mClocksToMicroseconds = mClockFrequencyInv; } +TimerInfo& get_timer_info() +{ + static TimerInfo sTimerInfo; + return sTimerInfo; +} /////////////////////////////////////////////////////////////////////////////// // returns a U64 number that represents the number of // microseconds since the Unix epoch - Jan 1, 1970 -U64 totalTime() +U64MicrosecondsImplicit totalTime() { U64 current_clock_count = get_clock_count(); - if (!gTotalTimeClockCount) + if (!get_timer_info().mTotalTimeClockCount || get_timer_info().mClocksToMicroseconds.value() == 0) { - update_clock_frequencies(); - gTotalTimeClockCount = current_clock_count; + get_timer_info().update(); + get_timer_info().mTotalTimeClockCount = current_clock_count; #if LL_WINDOWS - // Synch us up with local time (even though we PROBABLY don't need to, this is how it was implemented) + // Sync us up with local time (even though we PROBABLY don't need to, this is how it was implemented) // Unix platforms use gettimeofday so they are synced, although this probably isn't a good assumption to // make in the future. - gTotalTimeClockCount = (U64)(time(NULL) * gClockFrequency); + get_timer_info().mTotalTimeClockCount = (U64)(time(NULL) * get_timer_info().mClockFrequency); #endif // Update the last clock count - gLastTotalTimeClockCount = current_clock_count; + get_timer_info().mLastTotalTimeClockCount = current_clock_count; } else { - if (LL_LIKELY(current_clock_count >= gLastTotalTimeClockCount)) + if (current_clock_count >= get_timer_info().mLastTotalTimeClockCount) { // No wrapping, we're all okay. - gTotalTimeClockCount += current_clock_count - gLastTotalTimeClockCount; + get_timer_info().mTotalTimeClockCount += current_clock_count - get_timer_info().mLastTotalTimeClockCount; } else { // We've wrapped. Compensate correctly - gTotalTimeClockCount += (0xFFFFFFFFFFFFFFFFULL - gLastTotalTimeClockCount) + current_clock_count; + get_timer_info().mTotalTimeClockCount += (0xFFFFFFFFFFFFFFFFULL - get_timer_info().mLastTotalTimeClockCount) + current_clock_count; } // Update the last clock count - gLastTotalTimeClockCount = current_clock_count; + get_timer_info().mLastTotalTimeClockCount = current_clock_count; } // Return the total clock tick count in microseconds. - return (U64)(gTotalTimeClockCount*gClocksToMicroseconds); + U64Microseconds time(get_timer_info().mTotalTimeClockCount*get_timer_info().mClocksToMicroseconds); + return time; } @@ -273,9 +283,9 @@ U64 totalTime() LLTimer::LLTimer() { - if (!gClockFrequency) + if (!get_timer_info().mClockFrequency) { - update_clock_frequencies(); + get_timer_info().update(); } mStarted = TRUE; @@ -283,20 +293,32 @@ LLTimer::LLTimer() } LLTimer::~LLTimer() +{} + +// static +void LLTimer::initClass() { + if (!sTimer) sTimer = new LLTimer; } // static -U64 LLTimer::getTotalTime() +void LLTimer::cleanupClass() +{ + delete sTimer; sTimer = NULL; +} + +// static +U64MicrosecondsImplicit LLTimer::getTotalTime() { // simply call into the implementation function. - return totalTime(); + U64MicrosecondsImplicit total_time = totalTime(); + return total_time; } // static -F64 LLTimer::getTotalSeconds() +F64SecondsImplicit LLTimer::getTotalSeconds() { - return U64_to_F64(getTotalTime()) * USEC_TO_SEC_F64; + return F64Microseconds(U64_to_F64(getTotalTime())); } void LLTimer::reset() @@ -343,43 +365,43 @@ U64 getElapsedTimeAndUpdate(U64& lastClockCount) } -F64 LLTimer::getElapsedTimeF64() const +F64SecondsImplicit LLTimer::getElapsedTimeF64() const { U64 last = mLastClockCount; - return (F64)getElapsedTimeAndUpdate(last) * gClockFrequencyInv; + return (F64)getElapsedTimeAndUpdate(last) * get_timer_info().mClockFrequencyInv; } -F32 LLTimer::getElapsedTimeF32() const +F32SecondsImplicit LLTimer::getElapsedTimeF32() const { return (F32)getElapsedTimeF64(); } -F64 LLTimer::getElapsedTimeAndResetF64() +F64SecondsImplicit LLTimer::getElapsedTimeAndResetF64() { - return (F64)getElapsedTimeAndUpdate(mLastClockCount) * gClockFrequencyInv; + return (F64)getElapsedTimeAndUpdate(mLastClockCount) * get_timer_info().mClockFrequencyInv; } -F32 LLTimer::getElapsedTimeAndResetF32() +F32SecondsImplicit LLTimer::getElapsedTimeAndResetF32() { return (F32)getElapsedTimeAndResetF64(); } /////////////////////////////////////////////////////////////////////////////// -void LLTimer::setTimerExpirySec(F32 expiration) +void LLTimer::setTimerExpirySec(F32SecondsImplicit expiration) { mExpirationTicks = get_clock_count() - + (U64)((F32)(expiration * gClockFrequency)); + + (U64)((F32)(expiration * get_timer_info().mClockFrequency.value())); } -F32 LLTimer::getRemainingTimeF32() const +F32SecondsImplicit LLTimer::getRemainingTimeF32() const { U64 cur_ticks = get_clock_count(); if (cur_ticks > mExpirationTicks) { return 0.0f; } - return F32((mExpirationTicks - cur_ticks) * gClockFrequencyInv); + return F32((mExpirationTicks - cur_ticks) * get_timer_info().mClockFrequencyInv); } @@ -392,7 +414,7 @@ BOOL LLTimer::checkExpirationAndReset(F32 expiration) } mExpirationTicks = cur_ticks - + (U64)((F32)(expiration * gClockFrequency)); + + (U64)((F32)(expiration * get_timer_info().mClockFrequency)); return TRUE; } @@ -491,20 +513,20 @@ BOOL is_daylight_savings() struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_daylight_time) { - S32 pacific_offset_hours; + S32Hours pacific_offset_hours; if (pacific_daylight_time) { - pacific_offset_hours = 7; + pacific_offset_hours = S32Hours(7); } else { - pacific_offset_hours = 8; + pacific_offset_hours = S32Hours(8); } // We subtract off the PST/PDT offset _before_ getting // "UTC" time, because this will handle wrapping around // for 5 AM UTC -> 10 PM PDT of the previous day. - utc_time -= pacific_offset_hours * MIN_PER_HOUR * SEC_PER_MIN; + utc_time -= S32SecondsImplicit(pacific_offset_hours); // Internal buffer to PST/PDT (see above) struct tm* internal_time = gmtime(&utc_time); @@ -521,7 +543,7 @@ struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_daylight_time) } -void microsecondsToTimecodeString(U64 current_time, std::string& tcstring) +void microsecondsToTimecodeString(U64MicrosecondsImplicit current_time, std::string& tcstring) { U64 hours; U64 minutes; @@ -543,9 +565,9 @@ void microsecondsToTimecodeString(U64 current_time, std::string& tcstring) } -void secondsToTimecodeString(F32 current_time, std::string& tcstring) +void secondsToTimecodeString(F32SecondsImplicit current_time, std::string& tcstring) { - microsecondsToTimecodeString((U64)((F64)(SEC_TO_MICROSEC*current_time)), tcstring); + microsecondsToTimecodeString(current_time, tcstring); } diff --git a/indra/llcommon/lltimer.h b/indra/llcommon/lltimer.h index 0d2e8e86d..d43267bb6 100644 --- a/indra/llcommon/lltimer.h +++ b/indra/llcommon/lltimer.h @@ -37,6 +37,7 @@ #include #include // units conversions +#include "llunits.h" #ifndef USEC_PER_SEC const U32 USEC_PER_SEC = 1000000; #endif @@ -61,21 +62,28 @@ public: LLTimer(); ~LLTimer(); - static void initClass() { if (!sTimer) sTimer = new LLTimer; } - static void cleanupClass() { delete sTimer; sTimer = NULL; } + static void initClass(); + static void cleanupClass(); // Return a high precision number of seconds since the start of // this application instance. - static F64 getElapsedSeconds() + static F64SecondsImplicit getElapsedSeconds() + { + if (sTimer) { return sTimer->getElapsedTimeF64(); } + else + { + return 0; + } + } // Return a high precision usec since epoch - static U64 getTotalTime(); + static U64MicrosecondsImplicit getTotalTime(); // Return a high precision seconds since epoch - static F64 getTotalSeconds(); + static F64SecondsImplicit getTotalSeconds(); // MANIPULATORS @@ -83,19 +91,19 @@ public: void stop() { mStarted = FALSE; } void reset(); // Resets the timer void setLastClockCount(U64 current_count); // Sets the timer so that the next elapsed call will be relative to this time - void setTimerExpirySec(F32 expiration); + void setTimerExpirySec(F32SecondsImplicit expiration); BOOL checkExpirationAndReset(F32 expiration); BOOL hasExpired() const; - F32 getElapsedTimeAndResetF32(); // Returns elapsed time in seconds with reset - F64 getElapsedTimeAndResetF64(); + F32SecondsImplicit getElapsedTimeAndResetF32(); // Returns elapsed time in seconds with reset + F64SecondsImplicit getElapsedTimeAndResetF64(); - F32 getRemainingTimeF32() const; + F32SecondsImplicit getRemainingTimeF32() const; static BOOL knownBadTimer(); // ACCESSORS - F32 getElapsedTimeF32() const; // Returns elapsed time in seconds - F64 getElapsedTimeF64() const; // Returns elapsed time in seconds + F32SecondsImplicit getElapsedTimeF32() const; // Returns elapsed time in seconds + F64SecondsImplicit getElapsedTimeF64() const; // Returns elapsed time in seconds bool getStarted() const { return mStarted; } @@ -106,6 +114,20 @@ public: // // Various functions for initializing/accessing clock and timing stuff. Don't use these without REALLY knowing how they work. // +struct TimerInfo +{ + TimerInfo(); + void update(); + + F64HertzImplicit mClockFrequency; + F64SecondsImplicit mClockFrequencyInv; + F64MicrosecondsImplicit mClocksToMicroseconds; + U64 mTotalTimeClockCount; + U64 mLastTotalTimeClockCount; +}; + +TimerInfo& get_timer_info(); + LL_COMMON_API U64 get_clock_count(); LL_COMMON_API F64 calc_clock_frequency(); LL_COMMON_API void update_clock_frequencies(); @@ -160,10 +182,10 @@ LL_COMMON_API BOOL is_daylight_savings(); // struct tm* internal_time = utc_to_pacific_time(utc_time, gDaylight); LL_COMMON_API struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_daylight_time); -LL_COMMON_API void microsecondsToTimecodeString(U64 current_time, std::string& tcstring); -LL_COMMON_API void secondsToTimecodeString(F32 current_time, std::string& tcstring); +LL_COMMON_API void microsecondsToTimecodeString(U64MicrosecondsImplicit current_time, std::string& tcstring); +LL_COMMON_API void secondsToTimecodeString(F32SecondsImplicit current_time, std::string& tcstring); LL_COMMON_API void timeToFormattedString(time_t time, std::string format, std::string ×tr); LL_COMMON_API void timeStructToFormattedString(struct tm * time, std::string format, std::string ×tr); -U64 LL_COMMON_API totalTime(); // Returns current system time in microseconds +U64MicrosecondsImplicit LL_COMMON_API totalTime(); // Returns current system time in microseconds #endif diff --git a/indra/llcommon/llunits.h b/indra/llcommon/llunits.h new file mode 100644 index 000000000..0fcb8281a --- /dev/null +++ b/indra/llcommon/llunits.h @@ -0,0 +1,129 @@ +/** + * @file llunits.h + * @brief Unit definitions + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLUNITTYPE_H +#define LL_LLUNITTYPE_H + +#include "stdtypes.h" +#include "llunittype.h" + +// +// Unit declarations +// + +namespace LLUnits +{ +LL_DECLARE_BASE_UNIT(Bytes, "B"); +// technically, these are kibibytes, mibibytes, etc. but we should stick with commonly accepted terminology +LL_DECLARE_DERIVED_UNIT(Kilobytes, "KB", Bytes, / 1024); +LL_DECLARE_DERIVED_UNIT(Megabytes, "MB", Kilobytes, / 1024); +LL_DECLARE_DERIVED_UNIT(Gigabytes, "GB", Megabytes, / 1024); +} + +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Bytes); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Kilobytes); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Megabytes); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Gigabytes); + +namespace LLUnits +{ +// technically, these are kibibits, mibibits, etc. but we should stick with commonly accepted terminology +LL_DECLARE_DERIVED_UNIT(Bits, "b", Bytes, * 8 ); +LL_DECLARE_DERIVED_UNIT(Kilobits, "Kb", Bits, / 1024); +LL_DECLARE_DERIVED_UNIT(Megabits, "Mb", Kilobits, / 1024); +LL_DECLARE_DERIVED_UNIT(Gigabits, "Gb", Megabits, / 1024); +} + +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Bits); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Kilobits); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Megabits); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Gigabits); + +namespace LLUnits +{ +LL_DECLARE_BASE_UNIT(Seconds, "s"); +LL_DECLARE_DERIVED_UNIT(Minutes, "min", Seconds, / 60); +LL_DECLARE_DERIVED_UNIT(Hours, "h", Minutes, / 60); +LL_DECLARE_DERIVED_UNIT(Days, "d", Hours, / 24); +LL_DECLARE_DERIVED_UNIT(Milliseconds, "ms", Seconds, * 1000); +LL_DECLARE_DERIVED_UNIT(Microseconds, "\x09\x3cs", Milliseconds, * 1000); +LL_DECLARE_DERIVED_UNIT(Nanoseconds, "ns", Microseconds, * 1000); +} + +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Seconds); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Minutes); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Hours); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Days); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Milliseconds); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Microseconds); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Nanoseconds); + +namespace LLUnits +{ +LL_DECLARE_BASE_UNIT(Meters, "m"); +LL_DECLARE_DERIVED_UNIT(Kilometers, "km", Meters, / 1000); +LL_DECLARE_DERIVED_UNIT(Centimeters, "cm", Meters, * 100); +LL_DECLARE_DERIVED_UNIT(Millimeters, "mm", Meters, * 1000); +} + +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Meters); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Kilometers); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Centimeters); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Millimeters); + +namespace LLUnits +{ +// rare units +LL_DECLARE_BASE_UNIT(Hertz, "Hz"); +LL_DECLARE_DERIVED_UNIT(Kilohertz, "KHz", Hertz, / 1000); +LL_DECLARE_DERIVED_UNIT(Megahertz, "MHz", Kilohertz, / 1000); +LL_DECLARE_DERIVED_UNIT(Gigahertz, "GHz", Megahertz, / 1000); + +LL_DECLARE_BASE_UNIT(Radians, "rad"); +LL_DECLARE_DERIVED_UNIT(Degrees, "deg", Radians, * 57.29578f); + +LL_DECLARE_BASE_UNIT(Percent, "%"); +LL_DECLARE_DERIVED_UNIT(Ratio, "x", Percent, / 100); + +LL_DECLARE_BASE_UNIT(Triangles, "tris"); +LL_DECLARE_DERIVED_UNIT(Kilotriangles, "ktris", Triangles, / 1000); + +} // namespace LLUnits + +// rare units +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Hertz); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Kilohertz); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Megahertz); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Gigahertz); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Radians); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Degrees); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Percent); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Ratio); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Triangles); +LL_DECLARE_UNIT_TYPEDEFS(LLUnits, Kilotriangles); + + +#endif // LL_LLUNITTYPE_H diff --git a/indra/llcommon/llunittype.h b/indra/llcommon/llunittype.h new file mode 100644 index 000000000..ac8504ca6 --- /dev/null +++ b/indra/llcommon/llunittype.h @@ -0,0 +1,838 @@ +/** + * @file llunit.h + * @brief Unit conversion classes + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_UNITTYPE_H +#define LL_UNITTYPE_H + +#include "stdtypes.h" +#include "llpreprocessor.h" +#include "llerror.h" + +//lightweight replacement of type traits for simple type equality check +template +struct LLIsSameType +{ + static const bool value = false; +}; + +template +struct LLIsSameType +{ + static const bool value = true; +}; + +// workaround for decltype() not existing and typeof() not working inline in gcc 4.2 +template +struct LLResultTypeAdd +{ + typedef LL_TYPEOF(S() + T()) type_t; +}; + +template +struct LLResultTypeSubtract +{ + typedef LL_TYPEOF(S() - T()) type_t; +}; + +template +struct LLResultTypeMultiply +{ + typedef LL_TYPEOF(S() * T()) type_t; +}; + +template +struct LLResultTypeDivide +{ + typedef LL_TYPEOF(S() / T(1)) type_t; +}; + +template +struct LLResultTypePromote +{ + typedef LL_TYPEOF((true) ? S() : T()) type_t; +}; + +template +struct LLUnit +{ + typedef LLUnit self_t; + typedef STORAGE_TYPE storage_t; + typedef void is_unit_t; + + // value initialization + LL_FORCE_INLINE explicit LLUnit(storage_t value = storage_t()) + : mValue(value) + {} + + + LL_FORCE_INLINE static self_t convert(self_t v) + { + return v; + } + + template + LL_FORCE_INLINE static self_t convert(LLUnit v) + { + self_t result; + result.mValue = (STORAGE_TYPE)v.value(); + return result; + } + + template + LL_FORCE_INLINE static self_t convert(LLUnit v) + { + self_t result; + STORAGE_TYPE divisor = ll_convert_units(v, result); + result.mValue /= divisor; + return result; + } + + template + LL_FORCE_INLINE static self_t convert(LLUnit v) + { + typedef typename LLResultTypePromote::type_t result_storage_t; + LLUnit result; + result_storage_t divisor = ll_convert_units(v, result); + result.value(result.value() / divisor); + return self_t(result.value()); + } + + + // unit initialization and conversion + template + LL_FORCE_INLINE LLUnit(LLUnit other) + : mValue(convert(other).mValue) + {} + + LL_FORCE_INLINE storage_t value() const + { + return mValue; + } + + LL_FORCE_INLINE void value(storage_t value) + { + mValue = value; + } + + template + storage_t valueInUnits() + { + return LLUnit(*this).value(); + } + + template + void valueInUnits(storage_t value) + { + *this = LLUnit(value); + } + + LL_FORCE_INLINE void operator += (self_t other) + { + mValue += convert(other).mValue; + } + + LL_FORCE_INLINE void operator -= (self_t other) + { + mValue -= convert(other).mValue; + } + + LL_FORCE_INLINE void operator *= (storage_t multiplicand) + { + mValue *= multiplicand; + } + + LL_FORCE_INLINE void operator *= (self_t multiplicand) + { + // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template + LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE, "Multiplication of unit types not supported."); + } + + LL_FORCE_INLINE void operator /= (storage_t divisor) + { + mValue /= divisor; + } + + void operator /= (self_t divisor) + { + // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template + LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE, "Illegal in-place division of unit types."); + } + + template + LL_FORCE_INLINE bool operator == (LLUnit other) const + { + return mValue == convert(other).value(); + } + + template + LL_FORCE_INLINE bool operator != (LLUnit other) const + { + return mValue != convert(other).value(); + } + + template + LL_FORCE_INLINE bool operator < (LLUnit other) const + { + return mValue < convert(other).value(); + } + + template + LL_FORCE_INLINE bool operator <= (LLUnit other) const + { + return mValue <= convert(other).value(); + } + + template + LL_FORCE_INLINE bool operator > (LLUnit other) const + { + return mValue > convert(other).value(); + } + + template + LL_FORCE_INLINE bool operator >= (LLUnit other) const + { + return mValue >= convert(other).value(); + } + +protected: + storage_t mValue; +}; + +template +std::ostream& operator <<(std::ostream& s, const LLUnit& unit) +{ + s << unit.value() << UNITS::getUnitLabel(); + return s; +} + +template +std::istream& operator >>(std::istream& s, LLUnit& unit) +{ + STORAGE_TYPE val; + s >> val; + unit.value(val); + return s; +} + +template +struct LLUnitImplicit : public LLUnit +{ + typedef LLUnitImplicit self_t; + typedef typename LLUnit::storage_t storage_t; + typedef LLUnit base_t; + + LL_FORCE_INLINE LLUnitImplicit(storage_t value = storage_t()) + : base_t(value) + {} + + template + LL_FORCE_INLINE LLUnitImplicit(LLUnit other) + : base_t(other) + {} + + // unlike LLUnit, LLUnitImplicit is *implicitly* convertable to a POD value (F32, S32, etc) + // this allows for interoperability with legacy code + LL_FORCE_INLINE operator storage_t() const + { + return base_t::value(); + } + + using base_t::operator +=; + LL_FORCE_INLINE void operator += (storage_t value) + { + base_t::mValue += value; + } + + // this overload exists to explicitly catch use of another implicit unit + // without ambiguity between conversion to storage_t vs conversion to base_t + template + LL_FORCE_INLINE void operator += (LLUnitImplicit other) + { + base_t::mValue += base_t::convert(other).value(); + } + + using base_t::operator -=; + LL_FORCE_INLINE void operator -= (storage_t value) + { + base_t::mValue -= value; + } + + // this overload exists to explicitly catch use of another implicit unit + // without ambiguity between conversion to storage_t vs conversion to base_t + template + LL_FORCE_INLINE void operator -= (LLUnitImplicit other) + { + base_t::mValue -= base_t::convert(other).value(); + } + + template + LL_FORCE_INLINE bool operator == (LLUnit other) const + { + return base_t::mValue == base_t::convert(other).value(); + } + + template + LL_FORCE_INLINE bool operator == (LLUnitImplicit other) const + { + return base_t::mValue == base_t::convert(other).value(); + } + + template + LL_FORCE_INLINE bool operator == (STORAGE_T other) const + { + return base_t::mValue == other; + } + + template + LL_FORCE_INLINE bool operator != (LLUnit other) const + { + return base_t::mValue != convert(other).value(); + } + + template + LL_FORCE_INLINE bool operator != (LLUnitImplicit other) const + { + return base_t::mValue != base_t::convert(other).value(); + } + + template + LL_FORCE_INLINE bool operator != (STORAGE_T other) const + { + return base_t::mValue != other; + } + + template + LL_FORCE_INLINE bool operator < (LLUnit other) const + { + return base_t::mValue < base_t::convert(other).value(); + } + + template + LL_FORCE_INLINE bool operator < (LLUnitImplicit other) const + { + return base_t::mValue < base_t::convert(other).value(); + } + + template + LL_FORCE_INLINE bool operator < (STORAGE_T other) const + { + return base_t::mValue < other; + } + + template + LL_FORCE_INLINE bool operator <= (LLUnit other) const + { + return base_t::mValue <= base_t::convert(other).value(); + } + + template + LL_FORCE_INLINE bool operator <= (LLUnitImplicit other) const + { + return base_t::mValue <= base_t::convert(other).value(); + } + + template + LL_FORCE_INLINE bool operator <= (STORAGE_T other) const + { + return base_t::mValue <= other; + } + + template + LL_FORCE_INLINE bool operator > (LLUnit other) const + { + return base_t::mValue > base_t::convert(other).value(); + } + + template + LL_FORCE_INLINE bool operator > (LLUnitImplicit other) const + { + return base_t::mValue > base_t::convert(other).value(); + } + + template + LL_FORCE_INLINE bool operator > (STORAGE_T other) const + { + return base_t::mValue > other; + } + + template + LL_FORCE_INLINE bool operator >= (LLUnit other) const + { + return base_t::mValue >= base_t::convert(other).value(); + } + + template + LL_FORCE_INLINE bool operator >= (LLUnitImplicit other) const + { + return base_t::mValue >= base_t::convert(other).value(); + } + + template + LL_FORCE_INLINE bool operator >= (STORAGE_T other) const + { + return base_t::mValue >= other; + } +}; + +template +std::ostream& operator <<(std::ostream& s, const LLUnitImplicit& unit) +{ + s << unit.value() << UNITS::getUnitLabel(); + return s; +} + +template +std::istream& operator >>(std::istream& s, LLUnitImplicit& unit) +{ + STORAGE_TYPE val; + s >> val; + unit = val; + return s; +} + +template +LL_FORCE_INLINE S2 ll_convert_units(LLUnit in, LLUnit& out) +{ + S2 divisor(1); + + LL_STATIC_ASSERT((LLIsSameType::value + || !LLIsSameType::value + || !LLIsSameType::value), + "conversion requires compatible units"); + + if (LLIsSameType::value) + { + // T1 and T2 same type, just assign + out.value((S2)in.value()); + } + else if (T1::sLevel > T2::sLevel) + { + // reduce T1 + LLUnit new_in; + divisor *= (S2)ll_convert_units(in, new_in); + divisor *= (S2)ll_convert_units(new_in, out); + } + else + { + // reduce T2 + LLUnit new_out; + divisor *= (S2)ll_convert_units(in, new_out); + divisor *= (S2)ll_convert_units(new_out, out); + } + return divisor; +} + +template +struct LLStorageType +{ + typedef T type_t; +}; + +template +struct LLStorageType > +{ + typedef STORAGE_TYPE type_t; +}; + +// all of these operators need to perform type promotion on the storage type of the units, so they +// cannot be expressed as operations on identical types with implicit unit conversion +// e.g. typeof(S32Bytes(x) + F32Megabytes(y)) <==> F32Bytes + +// +// operator + +// +template +LL_FORCE_INLINE LLUnit::type_t, UNITS1> operator + (LLUnit first, LLUnit second) +{ + LLUnit::type_t, UNITS1> result(first); + result += second; + return result; +} + +template +LLUnit operator + (LLUnit first, UNITLESS second) +{ + LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE, "operator + requires compatible unit types"); + return LLUnit(0); +} + +template +LLUnit operator + (UNITLESS first, LLUnit second) +{ + LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE, "operator + requires compatible unit types"); + return LLUnit(0); +} + +template +LL_FORCE_INLINE LLUnitImplicit::type_t, UNITS1> operator + (LLUnitImplicit first, LLUnitImplicit second) +{ + LLUnitImplicit::type_t, UNITS1> result(first); + result += second; + return result; +} + +template +LL_FORCE_INLINE LLUnitImplicit::type_t, UNITS1> operator + (LLUnit first, LLUnitImplicit second) +{ + LLUnitImplicit::type_t, UNITS1> result(first); + result += second; + return result; +} + +template +LL_FORCE_INLINE LLUnitImplicit::type_t, UNITS1> operator + (LLUnitImplicit first, LLUnit second) +{ + LLUnitImplicit::type_t, UNITS1> result(first); + result += LLUnitImplicit(second); + return result; +} + +template +LL_FORCE_INLINE LLUnitImplicit::type_t>::type_t, UNITS> operator + (LLUnitImplicit first, UNITLESS_TYPE second) +{ + LLUnitImplicit::type_t>::type_t, UNITS> result(first); + result += second; + return result; +} + +template +LL_FORCE_INLINE LLUnitImplicit::type_t, STORAGE_TYPE>:: + type_t, UNITS> operator + (UNITLESS_TYPE first, LLUnitImplicit second) +{ + LLUnitImplicit::type_t, STORAGE_TYPE>::type_t, UNITS> result(first); + result += second; + return result; +} + +// +// operator - +// +template +LL_FORCE_INLINE LLUnit::type_t, UNITS1> operator - (LLUnit first, LLUnit second) +{ + LLUnit::type_t, UNITS1> result(first); + result -= second; + return result; +} + +template +LLUnit operator - (LLUnit first, UNITLESS second) +{ + LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE, "operator - requires compatible unit types"); + return LLUnit(0); +} + +template +LLUnit operator - (UNITLESS first, LLUnit second) +{ + LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE, "operator - requires compatible unit types"); + return LLUnit(0); +} + +template +LL_FORCE_INLINE LLUnitImplicit::type_t, UNITS1> operator - (LLUnitImplicit first, LLUnitImplicit second) +{ + LLUnitImplicit::type_t, UNITS1> result(first); + result -= second; + return result; +} + +template +LL_FORCE_INLINE LLUnitImplicit::type_t, UNITS1> operator - (LLUnit first, LLUnitImplicit second) +{ + LLUnitImplicit::type_t, UNITS1> result(first); + result -= second; + return result; +} + +template +LL_FORCE_INLINE LLUnitImplicit::type_t, UNITS1> operator - (LLUnitImplicit first, LLUnit second) +{ + LLUnitImplicit::type_t, UNITS1> result(first); + result -= LLUnitImplicit(second); + return result; +} + +template +LL_FORCE_INLINE LLUnitImplicit::type_t>::type_t, UNITS> operator - (LLUnitImplicit first, UNITLESS_TYPE second) +{ + LLUnitImplicit::type_t>::type_t, UNITS> result(first); + result -= second; + return result; +} + +template +LL_FORCE_INLINE LLUnitImplicit::type_t, STORAGE_TYPE>::type_t, UNITS> operator - (UNITLESS_TYPE first, LLUnitImplicit second) +{ + LLUnitImplicit::type_t, STORAGE_TYPE>::type_t, UNITS> result(first); + result -= second; + return result; +} + +// +// operator * +// +template +LLUnit operator * (LLUnit, LLUnit) +{ + // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template + LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE1, "multiplication of unit types results in new unit type - not supported."); + return LLUnit(); +} + +template +LL_FORCE_INLINE LLUnit::type_t>::type_t, UNITS> operator * (LLUnit first, UNITLESS_TYPE second) +{ + return LLUnit::type_t>::type_t, UNITS>(first.value() * second); +} + +template +LL_FORCE_INLINE LLUnit::type_t, STORAGE_TYPE>::type_t, UNITS> operator * (UNITLESS_TYPE first, LLUnit second) +{ + return LLUnit::type_t, STORAGE_TYPE>::type_t, UNITS>(first * second.value()); +} + +template +LLUnitImplicit operator * (LLUnitImplicit, LLUnitImplicit) +{ + // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template + LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE1, "multiplication of unit types results in new unit type - not supported."); + return LLUnitImplicit(); +} + +template +LL_FORCE_INLINE LLUnitImplicit::type_t>::type_t, UNITS> operator * (LLUnitImplicit first, UNITLESS_TYPE second) +{ + return LLUnitImplicit::type_t, UNITS>(first.value() * second); +} + +template +LL_FORCE_INLINE LLUnitImplicit::type_t, STORAGE_TYPE>::type_t, UNITS> operator * (UNITLESS_TYPE first, LLUnitImplicit second) +{ + return LLUnitImplicit::type_t, STORAGE_TYPE>::type_t, UNITS>(first * second.value()); +} + + +// +// operator / +// + +template +LL_FORCE_INLINE LLUnit::type_t>::type_t, UNITS> operator / (LLUnit first, UNITLESS_TYPE second) +{ + return LLUnit::type_t>::type_t, UNITS>(first.value() / second); +} + +template +LL_FORCE_INLINE typename LLResultTypeDivide::type_t operator / (LLUnit first, LLUnit second) +{ + return first.value() / first.convert(second).value(); +} + +template +LL_FORCE_INLINE LLUnitImplicit::type_t>::type_t, UNITS> operator / (LLUnitImplicit first, UNITLESS_TYPE second) +{ + return LLUnitImplicit::type_t>::type_t, UNITS>(first.value() / second); +} + +template +LL_FORCE_INLINE typename LLResultTypeDivide::type_t operator / (LLUnitImplicit first, LLUnitImplicit second) +{ + return (typename LLResultTypeDivide::type_t)(first.value() / first.convert(second).value()); +} + +template +LL_FORCE_INLINE typename LLResultTypeDivide::type_t operator / (LLUnit first, LLUnitImplicit second) +{ + return (typename LLResultTypeDivide::type_t)(first.value() / first.convert(second).value()); +} + +template +LL_FORCE_INLINE typename LLResultTypeDivide::type_t operator / (LLUnitImplicit first, LLUnit second) +{ + return (typename LLResultTypeDivide::type_t)(first.value() / first.convert(second).value()); +} + +template +struct LLGetUnitLabel +{ + static const char* getUnitLabel() { return ""; } +}; + +template +struct LLGetUnitLabel > +{ + static const char* getUnitLabel() { return T::getUnitLabel(); } +}; + +template +struct LLUnitLinearOps +{ + typedef LLUnitLinearOps self_t; + + LLUnitLinearOps(T val) + : mValue(val), + mDivisor(1) + {} + + template + self_t operator * (OTHER_T other) + { + return mValue * other; + } + + template + self_t operator / (OTHER_T other) + { + mDivisor *= other; + return *this; + } + + template + self_t operator + (OTHER_T other) + { + mValue += other * mDivisor; + return *this; + } + + template + self_t operator - (OTHER_T other) + { + mValue -= other * mDivisor; + return *this; + } + + T mValue; + T mDivisor; +}; + +template +struct LLUnitInverseLinearOps +{ + typedef LLUnitInverseLinearOps self_t; + + LLUnitInverseLinearOps(T val) + : mValue(val), + mDivisor(1), + mMultiplicand(1) + {} + + template + self_t operator * (OTHER_T other) + { + mDivisor *= other; + return *this; + } + + template + self_t operator / (OTHER_T other) + { + mValue *= other; + mMultiplicand *= other; + return *this; + } + + template + self_t operator + (OTHER_T other) + { + mValue -= other * mMultiplicand; + return *this; + } + + template + self_t operator - (OTHER_T other) + { + mValue += other * mMultiplicand; + return *this; + } + + T mValue; + T mDivisor; + T mMultiplicand; +}; + +#define LL_DECLARE_BASE_UNIT(base_unit_name, unit_label) \ +struct base_unit_name \ +{ \ + static const int sLevel = 0; \ + typedef base_unit_name base_unit_t; \ + static const char* getUnitLabel() { return unit_label; } \ + template \ + static LLUnit fromValue(T value) { return LLUnit(value); } \ + template \ + static LLUnit fromValue(LLUnit value) \ + { return LLUnit(value); } \ +} + + +#define LL_DECLARE_DERIVED_UNIT(unit_name, unit_label, base_unit_name, conversion_operation) \ +struct unit_name \ +{ \ + static const int sLevel = base_unit_name::sLevel + 1; \ + typedef base_unit_name base_unit_t; \ + static const char* getUnitLabel() { return unit_label; } \ + template \ + static LLUnit fromValue(T value) { return LLUnit(value); } \ + template \ + static LLUnit fromValue(LLUnit value) \ + { return LLUnit(value); } \ +}; \ + \ +template \ +LL_FORCE_INLINE S2 ll_convert_units(LLUnit in, LLUnit& out) \ +{ \ + typedef typename LLResultTypePromote::type_t result_storage_t; \ + LLUnitInverseLinearOps result = \ + LLUnitInverseLinearOps(in.value()) conversion_operation; \ + out = LLUnit((S2)result.mValue); \ + return result.mDivisor; \ +} \ + \ +template \ +LL_FORCE_INLINE S2 ll_convert_units(LLUnit in, LLUnit& out) \ +{ \ + typedef typename LLResultTypePromote::type_t result_storage_t; \ + LLUnitLinearOps result = \ + LLUnitLinearOps(in.value()) conversion_operation; \ + out = LLUnit((S2)result.mValue); \ + return result.mDivisor; \ +} + +#define LL_DECLARE_UNIT_TYPEDEFS(ns, unit_name) \ + typedef LLUnit F32##unit_name; \ + typedef LLUnitImplicit F32##unit_name##Implicit;\ + typedef LLUnit F64##unit_name; \ + typedef LLUnitImplicit F64##unit_name##Implicit;\ + typedef LLUnit S32##unit_name; \ + typedef LLUnitImplicit S32##unit_name##Implicit;\ + typedef LLUnit S64##unit_name; \ + typedef LLUnitImplicit S64##unit_name##Implicit;\ + typedef LLUnit U32##unit_name; \ + typedef LLUnitImplicit U32##unit_name##Implicit;\ + typedef LLUnit U64##unit_name; \ + typedef LLUnitImplicit U64##unit_name##Implicit + +#endif //LL_UNITTYPE_H diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index ce83fbf55..3952a63eb 100644 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp @@ -27,9 +27,7 @@ // We can't use WIN32_LEAN_AND_MEAN here, needs lots of includes. #if LL_WINDOWS -#undef WIN32_LEAN_AND_MEAN -#include -#include +#include "llwin32headers.h" #endif #include "lldefs.h" diff --git a/indra/llcommon/llwin32headers.h b/indra/llcommon/llwin32headers.h new file mode 100644 index 000000000..8cfa40ada --- /dev/null +++ b/indra/llcommon/llwin32headers.h @@ -0,0 +1,42 @@ +/** + * @file llwin32headers.h + * @brief sanitized include of windows header files + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLWINDOWS_H +#define LL_LLWINDOWS_H + +#ifdef LL_WINDOWS +#ifndef NOMINMAX +#define NOMINMAX +#endif +#undef WIN32_LEAN_AND_MEAN +#include +#include +// reset to default, which is lean +#define WIN32_LEAN_AND_MEAN +#undef NOMINMAX +#endif + +#endif diff --git a/indra/llcommon/llwin32headerslean.h b/indra/llcommon/llwin32headerslean.h new file mode 100644 index 000000000..314e7a85d --- /dev/null +++ b/indra/llcommon/llwin32headerslean.h @@ -0,0 +1,40 @@ +/** + * @file llwin32headerslean.h + * @brief sanitized include of windows header files + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLWINDOWS_H +#define LL_LLWINDOWS_H + +#ifdef LL_WINDOWS +#ifndef NOMINMAX +#define NOMINMAX +#endif +#define WIN32_LEAN_AND_MEAN +#include +#include +#undef NOMINMAX +#endif + +#endif diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp index e66c570f4..20b99bdc8 100644 --- a/indra/llcommon/llworkerthread.cpp +++ b/indra/llcommon/llworkerthread.cpp @@ -37,7 +37,7 @@ LLWorkerThread::LLWorkerThread(const std::string& name, bool threaded, bool should_pause) : LLQueuedThread(name, threaded, should_pause) { - mDeleteMutex = new LLMutex; + mDeleteMutex = new LLMutex(); } LLWorkerThread::~LLWorkerThread() @@ -199,6 +199,7 @@ LLWorkerClass::LLWorkerClass(LLWorkerThread* workerthread, const std::string& na mWorkerClassName(name), mRequestHandle(LLWorkerThread::nullHandle()), mRequestPriority(LLWorkerThread::PRIORITY_NORMAL), + mMutex(), mWorkFlags(0) { if (!mWorkerThread) @@ -345,10 +346,14 @@ bool LLWorkerClass::checkWork(bool aborting) } LLQueuedThread::status_t status = workreq->getStatus(); - if (status == LLWorkerThread::STATUS_COMPLETE || status == LLWorkerThread::STATUS_ABORTED) + if (status == LLWorkerThread::STATUS_ABORTED) + { + complete = !(workreq->getFlags() & LLWorkerThread::FLAG_LOCKED); + abort = true; + } + else if (status == LLWorkerThread::STATUS_COMPLETE) { complete = !(workreq->getFlags() & LLWorkerThread::FLAG_LOCKED); - abort = status == LLWorkerThread::STATUS_ABORTED; } else { diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 3de6dab3c..6c6ea1d05 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4699,7 +4699,7 @@ LLVolumeFace::~LLVolumeFace() void LLVolumeFace::freeData() { - ll_aligned_free(mPositions); + ll_aligned_free<64>(mPositions); mPositions = NULL; //normals and texture coordinates are part of the same buffer as mPositions, do not free them separately @@ -5273,7 +5273,7 @@ void LLVolumeFace::cacheOptimize() //allocate space for new buffer S32 num_verts = mNumVertices; S32 size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF; - LLVector4a* pos = (LLVector4a*) ll_aligned_malloc(sizeof(LLVector4a)*2*num_verts+size, 64); + LLVector4a* pos = (LLVector4a*) ll_aligned_malloc<64>(sizeof(LLVector4a)*2*num_verts+size); LLVector4a* norm = pos + num_verts; LLVector2* tc = (LLVector2*) (norm + num_verts); @@ -5323,7 +5323,7 @@ void LLVolumeFace::cacheOptimize() mIndices[i] = new_idx[mIndices[i]]; } - ll_aligned_free(mPositions); + ll_aligned_free<64>(mPositions); // DO NOT free mNormals and mTexCoords as they are part of mPositions buffer ll_aligned_free_16(mWeights); ll_aligned_free_16(mTangents); @@ -6041,7 +6041,7 @@ void LLVolumeFace::createTangents() void LLVolumeFace::resizeVertices(S32 num_verts) { - ll_aligned_free(mPositions); + ll_aligned_free<64>(mPositions); //DO NOT free mNormals and mTexCoords as they are part of mPositions buffer ll_aligned_free_16(mTangents); @@ -6052,7 +6052,7 @@ void LLVolumeFace::resizeVertices(S32 num_verts) //pad texture coordinate block end to allow for QWORD reads S32 size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF; - mPositions = (LLVector4a*) ll_aligned_malloc(sizeof(LLVector4a)*2*num_verts+size, 64); + mPositions = (LLVector4a*) ll_aligned_malloc<64>(sizeof(LLVector4a)*2*num_verts+size); mNormals = mPositions+num_verts; mTexCoords = (LLVector2*) (mNormals+num_verts); @@ -6092,7 +6092,7 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con LLVector4a* old_buf = mPositions; - mPositions = (LLVector4a*) ll_aligned_malloc(new_size, 64); + mPositions = (LLVector4a*) ll_aligned_malloc<64>(new_size); mNormals = mPositions+new_verts; mTexCoords = (LLVector2*) (mNormals+new_verts); @@ -6111,7 +6111,7 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con //tex coords LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) (old_buf+mNumVertices*2), old_tc_size); - ll_aligned_free(old_buf); + ll_aligned_free<64>(old_buf); // } @@ -6120,6 +6120,7 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con //just clear tangents ll_aligned_free_16(mTangents); mTangents = NULL; + ll_aligned_free<64>(old_buf); mNumAllocatedVertices = new_verts; @@ -6220,7 +6221,7 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat //allocate new buffer space LLVector4a* old_buf = mPositions; - mPositions = (LLVector4a*) ll_aligned_malloc(new_size, 64); + mPositions = (LLVector4a*) ll_aligned_malloc<64>(new_size); mNormals = mPositions + new_count; mTexCoords = (LLVector2*) (mNormals+new_count); diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp index 5154a854f..aa1e4371a 100644 --- a/indra/llrender/llgltexture.cpp +++ b/indra/llrender/llgltexture.cpp @@ -298,7 +298,7 @@ LLTexUnit::eTextureAddressMode LLGLTexture::getAddressMode(void) const return mGLTexturep->getAddressMode() ; } -S32 LLGLTexture::getTextureMemory() const +S32Bytes LLGLTexture::getTextureMemory() const { llassert(mGLTexturep.notNull()) ; diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h index 1b6107858..a27fcb630 100644 --- a/indra/llrender/llgltexture.h +++ b/indra/llrender/llgltexture.h @@ -138,7 +138,7 @@ public: S32 getDiscardLevel() const; S8 getComponents() const; BOOL getBoundRecently() const; - S32 getTextureMemory() const ; + S32Bytes getTextureMemory() const ; LLGLenum getPrimaryFormat() const; BOOL getIsAlphaMask(const F32 max_rmse) const ; LLTexUnit::eTextureType getTarget(void) const ; diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 68ff5d6a0..76aa596fb 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -50,9 +50,9 @@ U32 wpo2(U32 i); U32 LLImageGL::sUniqueCount = 0; U32 LLImageGL::sBindCount = 0; -S32 LLImageGL::sGlobalTextureMemoryInBytes = 0; -S32 LLImageGL::sBoundTextureMemoryInBytes = 0; -S32 LLImageGL::sCurBoundTextureMemory = 0; +S32Bytes LLImageGL::sGlobalTextureMemory(0); +S32Bytes LLImageGL::sBoundTextureMemory(0); +S32Bytes LLImageGL::sCurBoundTextureMemory(0); S32 LLImageGL::sCount = 0; BOOL LLImageGL::sGlobalUseAnisotropic = FALSE; @@ -78,9 +78,9 @@ S32 LLImageGL::sCurTexPickSize = -1 ; LLPointer LLImageGL::sHighlightTexturep = NULL; S32 LLImageGL::sMaxCategories = 1 ; -std::vector LLImageGL::sTextureMemByCategory; -std::vector LLImageGL::sTextureMemByCategoryBound ; -std::vector LLImageGL::sTextureCurMemByCategoryBound ; +std::vector LLImageGL::sTextureMemByCategory; +std::vector LLImageGL::sTextureMemByCategoryBound ; +std::vector LLImageGL::sTextureCurMemByCategoryBound ; //------------------------ // **************************************************************************************************** //End for texture auditing use only @@ -292,8 +292,8 @@ void LLImageGL::updateStats(F32 current_time) { LLFastTimer t(FTM_IMAGE_UPDATE_STATS); sLastFrameTime = current_time; - sBoundTextureMemoryInBytes = sCurBoundTextureMemory; - sCurBoundTextureMemory = 0; + sBoundTextureMemory = sCurBoundTextureMemory; + sCurBoundTextureMemory = S32Bytes(0); if(gAuditTexture) { @@ -305,22 +305,22 @@ void LLImageGL::updateStats(F32 current_time) for(U32 i = 0 ; i < sTextureCurMemByCategoryBound.size() ; i++) { sTextureMemByCategoryBound[i] = sTextureCurMemByCategoryBound[i] ; - sTextureCurMemByCategoryBound[i] = 0 ; + sTextureCurMemByCategoryBound[i] = (S32Bytes)0 ; } } } //static -S32 LLImageGL::updateBoundTexMem(const S32 mem, const S32 ncomponents, S32 category) +S32 LLImageGL::updateBoundTexMem(const S32Bytes mem, const S32 ncomponents, S32 category) { if(gAuditTexture && ncomponents > 0 && category > -1) { - sTextureCurBoundCounter[getTextureCounterIndex(mem / ncomponents)]++ ; + sTextureCurBoundCounter[getTextureCounterIndex(mem.value() / ncomponents)]++ ; sTextureCurMemByCategoryBound[category] += mem ; } LLImageGL::sCurBoundTextureMemory += mem ; - return LLImageGL::sCurBoundTextureMemory; + return LLImageGL::sCurBoundTextureMemory.value(); } //---------------------------------------------------------------------------- @@ -480,7 +480,7 @@ void LLImageGL::init(BOOL usemipmaps) // so that it is obvious by visual inspection if we forgot to // init a field. - mTextureMemory = 0; + mTextureMemory = (S32Bytes)0; mLastBindTime = 0.f; mPickMask = NULL; @@ -644,7 +644,7 @@ void LLImageGL::forceUpdateBindStats(void) const mLastBindTime = sLastFrameTime; } -BOOL LLImageGL::updateBindStats(S32 tex_mem) const +BOOL LLImageGL::updateBindStats(S32Bytes tex_mem) const { if (mTexName != 0) { @@ -1677,7 +1677,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ if (old_name != 0) { - sGlobalTextureMemoryInBytes -= mTextureMemory; + sGlobalTextureMemory -= mTextureMemory; if(gAuditTexture) { @@ -1689,8 +1689,8 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ stop_glerror(); } - mTextureMemory = getMipBytes(discard_level); - sGlobalTextureMemoryInBytes += mTextureMemory; + mTextureMemory = (S32Bytes)getMipBytes(discard_level); + sGlobalTextureMemory += mTextureMemory; if(gAuditTexture) { @@ -1829,14 +1829,14 @@ void LLImageGL::destroyGLTexture() { if (mTexName != 0) { - if(mTextureMemory) + if(mTextureMemory != S32Bytes(0)) { if(gAuditTexture) { decTextureCounter(mTextureMemory, mComponents, mCategory) ; } - sGlobalTextureMemoryInBytes -= mTextureMemory; - mTextureMemory = 0; + sGlobalTextureMemory -= mTextureMemory; + mTextureMemory = (S32Bytes)0; } LLImageGL::deleteTextures(1, &mTexName); @@ -2356,19 +2356,19 @@ S32 LLImageGL::getTextureCounterIndex(U32 val) } //static -void LLImageGL::incTextureCounter(U32 val, S32 ncomponents, S32 category) +void LLImageGL::incTextureCounter(S32Bytes val, S32 ncomponents, S32 category) { - sTextureLoadedCounter[getTextureCounterIndex(val)]++ ; + sTextureLoadedCounter[getTextureCounterIndex(val.value())]++ ; if(category > -1) - sTextureMemByCategory[category] += (S32)val * ncomponents ; + sTextureMemByCategory[category] += (S32Bytes)val * ncomponents ; } //static -void LLImageGL::decTextureCounter(U32 val, S32 ncomponents, S32 category) +void LLImageGL::decTextureCounter(S32Bytes val, S32 ncomponents, S32 category) { - sTextureLoadedCounter[getTextureCounterIndex(val)]-- ; + sTextureLoadedCounter[getTextureCounterIndex(val.value())]-- ; if(category > -1) - sTextureMemByCategory[category] -= (S32)val * ncomponents ; + sTextureMemByCategory[category] -= (S32Bytes)val * ncomponents ; } void LLImageGL::setCurTexSizebar(S32 index, BOOL set_pick_size) diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index ecb5222de..61d4efcc5 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -34,6 +34,7 @@ #include "llpointer.h" #include "llrefcount.h" #include "v2math.h" +#include "llunits.h" #include "llrender.h" @@ -55,7 +56,7 @@ public: static S32 dataFormatBytes(S32 dataformat, S32 width, S32 height); static S32 dataFormatComponents(S32 dataformat); - BOOL updateBindStats(S32 tex_mem) const ; + BOOL updateBindStats(S32Bytes tex_mem) const ; F32 getTimePassedSinceLastBound(); void forceUpdateBindStats(void) const; @@ -68,7 +69,7 @@ public: static void dirtyTexOptions(); // Sometimes called externally for textures not using LLImageGL (should go away...) - static S32 updateBoundTexMem(const S32 mem, const S32 ncomponents, S32 category) ; + static S32 updateBoundTexMem(const S32Bytes mem, const S32 ncomponents, S32 category) ; static bool checkSize(S32 width, S32 height); @@ -172,7 +173,7 @@ public: void setNeedsAlphaAndPickMask(BOOL need_mask); public: // Various GL/Rendering options - S32 mTextureMemory; + S32Bytes mTextureMemory; mutable F32 mLastBindTime; // last time this was bound, by discard level private: @@ -228,9 +229,9 @@ public: static F32 sLastFrameTime; // Global memory statistics - static S32 sGlobalTextureMemoryInBytes; // Tracks main memory texmem - static S32 sBoundTextureMemoryInBytes; // Tracks bound texmem for last completed frame - static S32 sCurBoundTextureMemory; // Tracks bound texmem for current frame + static S32Bytes sGlobalTextureMemory; // Tracks main memory texmem + static S32Bytes sBoundTextureMemory; // Tracks bound texmem for last completed frame + static S32Bytes sCurBoundTextureMemory; // Tracks bound texmem for current frame static U32 sBindCount; // Tracks number of texture binds for current frame static U32 sUniqueCount; // Tracks number of unique texture binds for current frame static BOOL sGlobalUseAnisotropic; @@ -274,8 +275,8 @@ public: static void setHighlightTexture(S32 category) ; static S32 getTextureCounterIndex(U32 val) ; - static void incTextureCounter(U32 val, S32 ncomponents, S32 category) ; - static void decTextureCounter(U32 val, S32 ncomponents, S32 category) ; + static void incTextureCounter(S32Bytes val, S32 ncomponents, S32 category) ; + static void decTextureCounter(S32Bytes val, S32 ncomponents, S32 category) ; static void setCurTexSizebar(S32 index, BOOL set_pick_size = TRUE) ; static void resetCurTexSizebar(); //---------------------------------------- @@ -283,9 +284,9 @@ public: //for debug use: show texture category distribution //---------------------------------------- - static std::vector sTextureMemByCategory; - static std::vector sTextureMemByCategoryBound ; - static std::vector sTextureCurMemByCategoryBound ; + static std::vector sTextureMemByCategory; + static std::vector sTextureMemByCategoryBound ; + static std::vector sTextureCurMemByCategoryBound ; //---------------------------------------- // **************************************************************************************************** //End of definitions for texture auditing use only diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 62db38a5c..0988b0581 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -187,7 +187,7 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed) if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB) { glBufferDataARB(mType, size, 0, mUsage); - ret = (U8*) ll_aligned_malloc(size, 64); + ret = (U8*) ll_aligned_malloc<64>(size); } else { //always use a true hint of static draw when allocating non-client-backed buffers @@ -240,7 +240,7 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size) llassert(vbo_block_size(size) == size); deleteBuffer(name); - ll_aligned_free((U8*) buffer); + ll_aligned_free<64>((U8*) buffer); if (mType == GL_ARRAY_BUFFER_ARB) { @@ -294,7 +294,7 @@ void LLVBOPool::cleanup() if (r.mClientData) { - ll_aligned_free((void*) r.mClientData); + ll_aligned_free<64>((void*) r.mClientData); } l.pop_front(); diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 3d66d0d36..2ab04547c 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -415,7 +415,7 @@ LLNotification::LLNotification(const LLNotification::Params& p) : mTimestamp(p.timestamp), mSubstitutions(p.substitutions), mPayload(p.payload), - mExpiresAt(0), + mExpiresAt(F64SecondsImplicit()), mResponseFunctorName(p.functor_name), mTemporaryResponder(p.mTemporaryResponder), mRespondedTo(false), diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 74e55f09a..11a573f7d 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -279,7 +279,7 @@ BOOL gUseWireframe = FALSE; LLVFS* gStaticVFS = NULL; LLMemoryInfo gSysMemory; -U64 gMemoryAllocated = 0; // updated in display_stats() in llviewerdisplay.cpp +U64Bytes gMemoryAllocated(0); // updated in display_stats() in llviewerdisplay.cpp std::string gLastVersionChannel; @@ -955,9 +955,8 @@ bool LLAppViewer::init() // get RAM data from XML std::stringstream minRAMString(LLNotificationTemplates::instance().getGlobalString("UnsupportedRAMAmount")); - U64 minRAM = 0; + U64Bytes minRAM; minRAMString >> minRAM; - minRAM = minRAM * 1024 * 1024; if(!LLFeatureManager::getInstance()->isGPUSupported() && LLFeatureManager::getInstance()->getGPUClass() != GPU_CLASS_UNKNOWN) { @@ -1037,7 +1036,7 @@ void LLAppViewer::initMaxHeapSize() //F32 max_heap_size_gb = llmin(1.6f, (F32)gSavedSettings.getF32("MaxHeapSize")) ; - F32 max_heap_size_gb = gSavedSettings.getF32("MaxHeapSize") ; + F32Gigabytes max_heap_size_gb = (F32Gigabytes)gSavedSettings.getF32("MaxHeapSize") ; //This is all a bunch of CRAP. We run LAA on windows. 64bit windows supports LAA out of the box. 32bit does not, unless PAE is on. #if LL_WINDOWS @@ -1051,7 +1050,7 @@ void LLAppViewer::initMaxHeapSize() if(fnIsWow64Process && fnIsWow64Process(GetCurrentProcess(), &bWow64Process) && bWow64Process) { - max_heap_size_gb = 3.7f; + max_heap_size_gb = F32Gigabytes(3.7f); } else if(ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management"), &hKey)) { @@ -1060,7 +1059,7 @@ void LLAppViewer::initMaxHeapSize() if(ERROR_SUCCESS == RegQueryValueEx(hKey, TEXT("PhysicalAddressExtension"), NULL, NULL, (LPBYTE)&dwResult, &dwSize)) { if(dwResult) - max_heap_size_gb = 3.7f; + max_heap_size_gb = F32Gigabytes(3.7f); } RegCloseKey(hKey); } @@ -2694,8 +2693,8 @@ void LLAppViewer::writeSystemInfo() gDebugInfo["CPUInfo"]["CPUSSE"] = gSysCPU.hasSSE(); gDebugInfo["CPUInfo"]["CPUSSE2"] = gSysCPU.hasSSE2(); - gDebugInfo["RAMInfo"]["Physical"] = (LLSD::Integer)(gSysMemory.getPhysicalMemoryKB()); - gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer)(gMemoryAllocated>>10); // MB -> KB + gDebugInfo["RAMInfo"]["Physical"] = (LLSD::Integer)(gSysMemory.getPhysicalMemoryKB().value()); + gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer)(gMemoryAllocated.valueInUnits()); gDebugInfo["OSInfo"] = getOSInfo().getOSStringSimple(); // The user is not logged on yet, but record the current grid choice login url diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index f461c259b..777f06207 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -333,7 +333,7 @@ extern BOOL gUseWireframe; extern LLVFS *gStaticVFS; extern LLMemoryInfo gSysMemory; -extern U64 gMemoryAllocated; +extern U64Bytes gMemoryAllocated; extern std::string gLastVersionChannel; diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index aedcd47b2..42f46fb2e 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -676,7 +676,7 @@ void LLFeatureManager::applyBaseMasks() maskFeatures(gpustr); // now mask cpu type ones - if (gSysMemory.getPhysicalMemoryClamped() <= 256*1024*1024) + if (gSysMemory.getPhysicalMemoryClamped() <= U32Megabytes(256)) { maskFeatures("RAM256MB"); } diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index d05ff2a1e..cd2cfdb17 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -233,7 +233,7 @@ LLFloaterAbout::LLFloaterAbout() else support.append(" None\n"); */ - U32 memory = gSysMemory.getPhysicalMemoryKB() / 1024; + U32Megabytes memory = gSysMemory.getPhysicalMemoryKB(); // Moved hack adjustment to Windows memory size into llsys.cpp std::string mem_text = llformat("Memory: %u MB\n", memory ); diff --git a/indra/newview/llpaneldisplay.cpp b/indra/newview/llpaneldisplay.cpp index 688c03f6c..715d59f70 100644 --- a/indra/newview/llpaneldisplay.cpp +++ b/indra/newview/llpaneldisplay.cpp @@ -472,9 +472,13 @@ void LLPanelDisplay::refreshEnabledState() mWindowSizeLabel->setVisible(!isFullScreen); mCtrlWindowSize->setVisible(!isFullScreen); + F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple"); + S32Megabytes min_tex_mem = LLViewerTextureList::getMinVideoRamSetting(); + S32Megabytes max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(false, mem_multiplier); + // Hardware tab - getChild("GrapicsCardTextureMemory")->setMinValue(LLViewerTextureList::getMinVideoRamSetting()); - getChild("GrapicsCardTextureMemory")->setMaxValue(LLViewerTextureList::getMaxVideoRamSetting()); + getChild("GrapicsCardTextureMemory")->setMinValue(min_tex_mem.value()); + getChild("GrapicsCardTextureMemory")->setMaxValue(max_tex_mem.value()); if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") || !gGLManager.mHasVertexBufferObject) diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 8ca0b78b3..ea6c156a7 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -619,11 +619,25 @@ class LLVolumeGeometryManager: public LLGeometryManager DISTANCE_SORT } eSortType; + LLVolumeGeometryManager(); + virtual ~LLVolumeGeometryManager(); virtual void rebuildGeom(LLSpatialGroup* group); virtual void rebuildMesh(LLSpatialGroup* group); virtual void getGeometry(LLSpatialGroup* group); void genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE); void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type); +private: + void allocateFaces(U32 pMaxFaceCount); + void freeFaces(); + + static int32_t sInstanceCount; + static LLFace** sFullbrightFaces; + static LLFace** sBumpFaces; + static LLFace** sSimpleFaces; + static LLFace** sNormFaces; + static LLFace** sSpecFaces; + static LLFace** sNormSpecFaces; + static LLFace** sAlphaFaces; }; //spatial partition that uses volume geometry manager (implemented in LLVOVolume.cpp) diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index 0a35767ec..6aeea41a4 100644 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -129,8 +129,8 @@ public: // debug S32 getNumReads() { return mReaders.size(); } S32 getNumWrites() { return mWriters.size(); } - S64 getUsage() { return mTexturesSizeTotal; } - S64 getMaxUsage() { return sCacheMaxTexturesSize; } + S64Bytes getUsage() { return S64Bytes(mTexturesSizeTotal); } + S64Bytes getMaxUsage() { return S64Bytes(sCacheMaxTexturesSize); } U32 getEntries() { return mHeaderEntriesInfo.mEntries; } U32 getMaxEntries() { return sCacheMaxEntries; }; BOOL isInCache(const LLUUID& id) ; @@ -202,7 +202,7 @@ private: typedef std::map size_map_t; size_map_t mTexturesSizeMap; S64 mTexturesSizeTotal; - LLAtomic32 mDoPurge; + LLAtomic32 mDoPurge; typedef std::map idx_entry_map_t; idx_entry_map_t mUpdatedEntryMap; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 432d34ec8..a8f9eed3a 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -316,11 +316,11 @@ private: U8 mImageCodec; LLViewerAssetStats::duration_t mMetricsStartTime; - unsigned int mHttpReplySize; // Actual received data size - unsigned int mHttpReplyOffset; // Actual received data offset + U32 mHttpReplySize, // Actual received data size + mHttpReplyOffset; // Actual received data offset // State history - U32 mCacheReadCount; - U32 mCacheWriteCount; + U32 mCacheReadCount, + mCacheWriteCount; }; ////////////////////////////////////////////////////////////////////////////// @@ -425,7 +425,7 @@ public: worker->setGetStatus(mStatus, mReason); LL_WARNS() << "CURL GET FAILED, status:" << mStatus << " reason:" << mReason << LL_ENDL; } - S32 data_size = worker->callbackHttpGet(mReplyOffset, mReplyLength, channels, buffer, partial, success); + S32BytesImplicit data_size = worker->callbackHttpGet(mReplyOffset, mReplyLength, channels, buffer, partial, success); if(log_texture_traffic && data_size > 0) { diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index b201bfcca..14ee16c5c 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -407,7 +407,7 @@ void LLTextureBar::draw() default:; }; std::string num_str = llformat("%4dx%4d (%+d) %7d %s", mImagep->getWidth(), mImagep->getHeight(), - mImagep->getDiscardLevel(), mImagep->hasGLTexture() ? mImagep->getTextureMemory() : 0, boost_lvl.c_str()); + mImagep->getDiscardLevel(), mImagep->hasGLTexture() ? mImagep->getTextureMemory().value() : 0, boost_lvl.c_str()); LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, title_x4, getRect().getHeight(), color, LLFontGL::LEFT, LLFontGL::TOP); } @@ -564,18 +564,18 @@ private: void LLGLTexMemBar::draw() { - S32 bound_mem = BYTES_TO_MEGA_BYTES(LLViewerTexture::sBoundTextureMemoryInBytes); - S32 max_bound_mem = LLViewerTexture::sMaxBoundTextureMemInMegaBytes; - S32 total_mem = BYTES_TO_MEGA_BYTES(LLViewerTexture::sTotalTextureMemoryInBytes); - S32 max_total_mem = LLViewerTexture::sMaxTotalTextureMemInMegaBytes; + S32Megabytes bound_mem = LLViewerTexture::sBoundTextureMemory; + S32Megabytes max_bound_mem = LLViewerTexture::sMaxBoundTextureMemory; + S32Megabytes total_mem = LLViewerTexture::sTotalTextureMemory; + S32Megabytes max_total_mem = LLViewerTexture::sMaxTotalTextureMem; F32 discard_bias = LLViewerTexture::sDesiredDiscardBias; - F32 cache_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getUsage()) ; - F32 cache_max_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getMaxUsage()) ; - S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); - S32 v_offset = 0; - F32 total_texture_downloaded = (F32)gTotalTextureBytes / (1024 * 1024); - F32 total_object_downloaded = (F32)gTotalObjectBytes / (1024 * 1024); - U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests() ; + F32 cache_usage = LLAppViewer::getTextureCache()->getUsage().valueInUnits(); + F32 cache_max_usage = LLAppViewer::getTextureCache()->getMaxUsage().valueInUnits(); + S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); + S32 v_offset = 0;//(S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f); + F32Bytes total_texture_downloaded = gTotalTextureData; + F32Bytes total_object_downloaded = gTotalObjectData; + U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests(); //---------------------------------------------------------------------------- LLGLSUIDefault gls_ui; LLColor4 text_color(1.f, 1.f, 1.f, 0.75f); @@ -588,10 +588,10 @@ void LLGLTexMemBar::draw() global_raw_memory = *AIAccess(LLImageRaw::sGlobalRawMemory); } text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d", - total_mem, - max_total_mem, - bound_mem, - max_bound_mem, + total_mem.value(), + max_total_mem.value(), + bound_mem.value(), + max_bound_mem.value(), LLRenderTarget::sBytesAllocated/(1024*1024), global_raw_memory >> 20, discard_bias, cache_usage, cache_max_usage, total_texture_downloaded, total_object_downloaded, total_http_requests); @@ -890,7 +890,7 @@ void LLTextureView::draw() if (mPrintList) { - S32 tex_mem = imagep->hasGLTexture() ? imagep->getTextureMemory() : 0 ; + S32 tex_mem = imagep->hasGLTexture() ? imagep->getTextureMemory().value() : 0 ; LL_INFOS() << imagep->getID() << "\t" << tex_mem << "\t" << imagep->getBoostLevel() @@ -1317,7 +1317,7 @@ void LLTextureSizeView::drawTextureCategoryGraph() for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++) { U32 k = LLViewerTexture::getIndexFromCategory(i) ; - mTextureSizeBar[i]->setTop(LLImageGL::sTextureMemByCategory[k] >> 20, LLImageGL::sTextureMemByCategoryBound[k] >> 20, size_bar_scale) ; + mTextureSizeBar[i]->setTop(LLImageGL::sTextureMemByCategory[k].value() >> 20, LLImageGL::sTextureMemByCategoryBound[k].value() >> 20, size_bar_scale) ; mTextureSizeBar[i]->draw() ; } LLImageGL::resetCurTexSizebar(); @@ -1335,7 +1335,7 @@ F32 LLTextureSizeView::drawTextureCategoryDistributionGraph() S32 count = 0 ; for(U32 i = 0 ; i < LLImageGL::sTextureMemByCategory.size() ; i++) { - S32 tmp = LLImageGL::sTextureMemByCategory[i] >> 20 ; + S32 tmp = LLImageGL::sTextureMemByCategory[i].value() >> 20 ; if(tmp > count) { count = tmp ; diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 4ac560651..9ef5a9859 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -325,7 +325,7 @@ static bool handleMaxPartCountChanged(const LLSD& newvalue) static bool handleVideoMemoryChanged(const LLSD& newvalue) { - gTextureList.updateMaxResidentTexMem(newvalue.asInteger()); + gTextureList.updateMaxResidentTexMem(S32Megabytes(newvalue.asInteger())); return true; } diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 562605b19..4a600728f 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -236,9 +236,9 @@ void display_stats() F32 mem_log_freq = gSavedSettings.getF32("MemoryLogFrequency"); if (mem_log_freq > 0.f && gRecentMemoryTime.getElapsedTimeF32() >= mem_log_freq) { - gMemoryAllocated = LLMemory::getCurrentRSS(); - U32 memory = (U32)(gMemoryAllocated / (1024*1024)); - LL_INFOS() << llformat("MEMORY: %d MB", memory) << LL_ENDL; + gMemoryAllocated = (U64Bytes)LLMemory::getCurrentRSS(); + U32Megabytes memory = gMemoryAllocated; + LL_INFOS() << llformat("MEMORY: %d MB", memory.value()) << LL_ENDL; LL_INFOS() << "THREADS: "<< LLThread::getCount() << LL_ENDL; LL_INFOS() << "MALLOC: " << SGMemStat::getPrintableStat() <getReceiveCompressedSize()) { - gObjectBits += mesgsys->getReceiveCompressedSize() * 8; + gObjectData += (U32Bytes)mesgsys->getReceiveCompressedSize(); } else { - gObjectBits += mesgsys->getReceiveSize() * 8; + gObjectData += (U32Bytes)mesgsys->getReceiveSize(); } // Update the object... @@ -5185,11 +5186,11 @@ void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data // Update the data counters if (mesgsys->getReceiveCompressedSize()) { - gObjectBits += mesgsys->getReceiveCompressedSize() * 8; + gObjectData += (U32Bytes)mesgsys->getReceiveCompressedSize(); } else { - gObjectBits += mesgsys->getReceiveSize() * 8; + gObjectData += (U32Bytes)mesgsys->getReceiveSize(); } // Update the object... @@ -5201,11 +5202,11 @@ void process_cached_object_update(LLMessageSystem *mesgsys, void **user_data) // Update the data counters if (mesgsys->getReceiveCompressedSize()) { - gObjectBits += mesgsys->getReceiveCompressedSize() * 8; + gObjectData += (U32Bytes)mesgsys->getReceiveCompressedSize(); } else { - gObjectBits += mesgsys->getReceiveSize() * 8; + gObjectData += (U32Bytes)mesgsys->getReceiveSize(); } // Update the object... @@ -5217,11 +5218,11 @@ void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_ { if (mesgsys->getReceiveCompressedSize()) { - gObjectBits += mesgsys->getReceiveCompressedSize() * 8; + gObjectData += (U32Bytes)mesgsys->getReceiveCompressedSize(); } else { - gObjectBits += mesgsys->getReceiveSize() * 8; + gObjectData += (U32Bytes)mesgsys->getReceiveSize(); } gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_TERSE_IMPROVED); diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 41cf0f276..a957af521 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -451,8 +451,8 @@ void output_statistics(void*) LL_INFOS() << "Number of orphans: " << gObjectList.getOrphanCount() << LL_ENDL; LL_INFOS() << "Number of dead objects: " << gObjectList.mNumDeadObjects << LL_ENDL; LL_INFOS() << "Num images: " << gTextureList.getNumImages() << LL_ENDL; - LL_INFOS() << "Texture usage: " << LLImageGL::sGlobalTextureMemoryInBytes << LL_ENDL; - LL_INFOS() << "Texture working set: " << LLImageGL::sBoundTextureMemoryInBytes << LL_ENDL; + LL_INFOS() << "Texture usage: " << LLImageGL::sGlobalTextureMemory.value() << LL_ENDL; + LL_INFOS() << "Texture working set: " << LLImageGL::sBoundTextureMemory.value() << LL_ENDL; LL_INFOS() << "Raw usage: " << global_raw_memory << LL_ENDL; LL_INFOS() << "Formatted usage: " << LLImageFormatted::sGlobalFormattedMemory << LL_ENDL; LL_INFOS() << "Zombie Viewer Objects: " << LLViewerObject::getNumZombieObjects() << LL_ENDL; @@ -570,19 +570,25 @@ void output_statistics(void*) } -U32 gTotalLandIn = 0, gTotalLandOut = 0; -U32 gTotalWaterIn = 0, gTotalWaterOut = 0; +U32 gTotalLandIn = 0, + gTotalLandOut = 0, + gTotalWaterIn = 0, + gTotalWaterOut = 0; -F32 gAveLandCompression = 0.f, gAveWaterCompression = 0.f; -F32 gBestLandCompression = 1.f, gBestWaterCompression = 1.f; -F32 gWorstLandCompression = 0.f, gWorstWaterCompression = 0.f; +F32 gAveLandCompression = 0.f, + gAveWaterCompression = 0.f, + gBestLandCompression = 1.f, + gBestWaterCompression = 1.f, + gWorstLandCompression = 0.f, + gWorstWaterCompression = 0.f; - - -U32 gTotalWorldBytes = 0, gTotalObjectBytes = 0, gTotalTextureBytes = 0, gSimPingCount = 0; -U32 gObjectBits = 0; -F32 gAvgSimPing = 0.f; -U32 gTotalTextureBytesPerBoostLevel[LLGLTexture::MAX_GL_IMAGE_CATEGORY] = {0}; +U32Bytes gTotalWorldData, + gTotalObjectData, + gTotalTextureData; +U32 gSimPingCount = 0; +U32Bits gObjectData; +F32Milliseconds gAvgSimPing(0.f); +U32Bytes gTotalTextureBytesPerBoostLevel[LLGLTexture::MAX_GL_IMAGE_CATEGORY] = {U32Bytes(0)}; extern U32 gVisCompared; extern U32 gVisTested; @@ -591,8 +597,8 @@ LLFrameTimer gTextureTimer; void update_statistics() { - gTotalWorldBytes += gVLManager.getTotalBytes(); - gTotalObjectBytes += gObjectBits / 8; + gTotalWorldData += U32Bytes(gVLManager.getTotalBytes()); + gTotalObjectData += gObjectData; LLViewerStats& stats = LLViewerStats::instance(); @@ -634,7 +640,7 @@ void update_statistics() if (cdp) { stats.mSimPingStat.addValue(cdp->getPingDelay()); - gAvgSimPing = ((gAvgSimPing * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1); + gAvgSimPing = F32Milliseconds(((gAvgSimPing.value() * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1)); gSimPingCount++; } else @@ -643,11 +649,11 @@ void update_statistics() } stats.mFPSStat.addValue(1); - F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits()); - stats.mLayersKBitStat.addValue(layer_bits/1024.f); - stats.mObjectKBitStat.addValue(gObjectBits/1024.f); + F64Bits layer_bits = F64Bits(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits()); + stats.mLayersKBitStat.addValue((F32)layer_bits.valueInUnits()); + stats.mObjectKBitStat.addValue(gObjectData.valueInUnits()); stats.mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending()); - stats.mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f); + stats.mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET) / 1024); gTransferManager.resetTransferBitsIn(LLTCT_ASSET); if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) @@ -675,7 +681,7 @@ void update_statistics() // Reset all of these values. gVLManager.resetBitCounts(); - gObjectBits = 0; + gObjectData = (U32Bytes)0; // gDecodedBits = 0; // Only update texture stats periodically so that they are less noisy @@ -685,10 +691,10 @@ void update_statistics() if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq) { stats.mHTTPTextureKBitStat.addValue(AICurlInterface::getHTTPBandwidth()/125.f); - stats.mUDPTextureKBitStat.addValue(LLViewerTextureList::sTextureBits/1024.f); + stats.mUDPTextureKBitStat.addValue(LLViewerTextureList::sTextureBits.valueInUnits()); stats.mTexturePacketsStat.addValue(LLViewerTextureList::sTexturePackets); - gTotalTextureBytes += LLViewerTextureList::sTextureBits / 8; - LLViewerTextureList::sTextureBits = 0; + gTotalTextureData += U32Bits(LLViewerTextureList::sTextureBits); + LLViewerTextureList::sTextureBits = U32Bits(0); LLViewerTextureList::sTexturePackets = 0; texture_stats_timer.reset(); } @@ -792,14 +798,14 @@ void send_stats() gSimFrames = (F32) gFrameCount; agent["agents_in_view"] = LLVOAvatar::sNumVisibleAvatars; - agent["ping"] = gAvgSimPing; + agent["ping"] = gAvgSimPing.value(); agent["meters_traveled"] = gAgent.getDistanceTraveled(); agent["regions_visited"] = gAgent.getRegionsVisited(); agent["mem_use"] = LLMemory::getCurrentRSS() / 1024.0; LLSD &system = body["system"]; - system["ram"] = (S32) gSysMemory.getPhysicalMemoryKB(); + system["ram"] = (S32) gSysMemory.getPhysicalMemoryKB().value(); system["os"] = LLAppViewer::instance()->getOSInfo().getOSStringSimple(); system["cpu"] = gSysCPU.getCPUString(); unsigned char MACAddress[MAC_ADDRESS_BYTES]; @@ -823,9 +829,9 @@ void send_stats() LLSD &download = body["downloads"]; - download["world_kbytes"] = gTotalWorldBytes / 1024.0; - download["object_kbytes"] = gTotalObjectBytes / 1024.0; - download["texture_kbytes"] = gTotalTextureBytes / 1024.0; + download["world_kbytes"] = F64Kilobytes(gTotalWorldData).value(); + download["object_kbytes"] = F64Kilobytes(gTotalObjectData).value(); + download["texture_kbytes"] = F64Kilobytes(gTotalTextureData).value(); download["mesh_kbytes"] = LLMeshRepository::sBytesReceived/1024.0; LLSD &in = body["stats"]["net"]["in"]; @@ -886,7 +892,10 @@ void send_stats() body["MinimalSkin"] = false; LLViewerStats::getInstance()->addToMessage(body); - LLHTTPClient::post(url, body, new ViewerStatsResponder); + + LL_INFOS("LogViewerStatsPacket") << "Sending viewer statistics: " << body << LL_ENDL; + LLHTTPClient::post(url, body, new ViewerStatsResponder()); + } LLViewerStats::PhaseMap::PhaseMap() diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index f6300d1e2..90b75a866 100644 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -321,7 +321,7 @@ void update_statistics(); void send_stats(); extern LLFrameTimer gTextureTimer; -extern U32 gTotalTextureBytes; -extern U32 gTotalObjectBytes; -extern U32 gTotalTextureBytesPerBoostLevel[] ; +extern U32Bytes gTotalTextureData; +extern U32Bytes gTotalObjectData; +extern U32Bytes gTotalTextureBytesPerBoostLevel[] ; #endif // LL_LLVIEWERSTATS_H diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 11b05813c..f67f9f16e 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -63,6 +63,11 @@ #include "lltexturecache.h" /////////////////////////////////////////////////////////////////////////////// +// extern +const S32Megabytes gMinVideoRam(32); +const S32Megabytes gMaxVideoRam(1024); + + // statics LLPointer LLViewerTexture::sNullImagep = NULL; LLPointer LLViewerTexture::sBlackImagep = NULL; @@ -83,12 +88,12 @@ S32 LLViewerTexture::sAuxCount = 0; LLFrameTimer LLViewerTexture::sEvaluationTimer; F32 LLViewerTexture::sDesiredDiscardBias = 0.f; F32 LLViewerTexture::sDesiredDiscardScale = 1.1f; -S32 LLViewerTexture::sBoundTextureMemoryInBytes = 0; -S32 LLViewerTexture::sTotalTextureMemoryInBytes = 0; -S32 LLViewerTexture::sMaxBoundTextureMemInMegaBytes = 0; -S32 LLViewerTexture::sMaxTotalTextureMemInMegaBytes = 0; -S32 LLViewerTexture::sMaxDesiredTextureMemInBytes = 0 ; -S8 LLViewerTexture::sCameraMovingDiscardBias = 0 ; +S32Bytes LLViewerTexture::sBoundTextureMemory; +S32Bytes LLViewerTexture::sTotalTextureMemory; +S32Megabytes LLViewerTexture::sMaxBoundTextureMemory; +S32Megabytes LLViewerTexture::sMaxTotalTextureMem; +S32Bytes LLViewerTexture::sMaxDesiredTextureMem; +S8 LLViewerTexture::sCameraMovingDiscardBias = 0; F32 LLViewerTexture::sCameraMovingBias = 0.0f ; S32 LLViewerTexture::sMaxSculptRez = 128 ; //max sculpt image size const S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64 ; @@ -450,8 +455,9 @@ bool LLViewerTexture::isMemoryForTextureLow() timer.reset() ; LLFastTimer t(FTM_TEXTURE_MEMORY_CHECK); - const static S32 MIN_FREE_TEXTURE_MEMORY = 5 ; //MB - const static S32 MIN_FREE_MAIN_MEMORy = 100 ; //MB + + static const S32Megabytes MIN_FREE_TEXTURE_MEMORY(5); //MB + static const S32Megabytes MIN_FREE_MAIN_MEMORY(100); //MB bool low_mem = false ; if (gGLManager.mHasATIMemInfo) @@ -459,7 +465,7 @@ bool LLViewerTexture::isMemoryForTextureLow() S32 meminfo[4]; glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo); - if(meminfo[0] / 1024 < MIN_FREE_TEXTURE_MEMORY) + if((S32Megabytes)meminfo[0] < MIN_FREE_TEXTURE_MEMORY) { low_mem = true ; } @@ -467,7 +473,7 @@ bool LLViewerTexture::isMemoryForTextureLow() if(!low_mem) //check main memory, only works for windows. { LLMemory::updateMemoryInfo() ; - if(LLMemory::getAvailableMemKB() / 1024 < MIN_FREE_MAIN_MEMORy) + if(LLMemory::getAvailableMemKB() < MIN_FREE_TEXTURE_MEMORY) { low_mem = true ; } @@ -511,17 +517,17 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity LLViewerMediaTexture::updateClass() ; } - sBoundTextureMemoryInBytes = LLImageGL::sBoundTextureMemoryInBytes;//in bytes - sTotalTextureMemoryInBytes = LLImageGL::sGlobalTextureMemoryInBytes;//in bytes - sMaxBoundTextureMemInMegaBytes = gTextureList.getMaxResidentTexMem();//in MB - sMaxTotalTextureMemInMegaBytes = gTextureList.getMaxTotalTextureMem() ;//in MB - sMaxDesiredTextureMemInBytes = MEGA_BYTES_TO_BYTES(sMaxTotalTextureMemInMegaBytes) ; //in Bytes, by default and when total used texture memory is small. + sBoundTextureMemory = LLImageGL::sBoundTextureMemory; + sTotalTextureMemory = LLImageGL::sGlobalTextureMemory; + sMaxBoundTextureMemory = S32Megabytes(gTextureList.getMaxResidentTexMem()); + sMaxTotalTextureMem = S32Megabytes(gTextureList.getMaxTotalTextureMem()); + sMaxDesiredTextureMem = sMaxTotalTextureMem; //in Bytes, by default and when total used texture memory is small. - if (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) >= sMaxBoundTextureMemInMegaBytes || - BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) >= sMaxTotalTextureMemInMegaBytes) + if (sBoundTextureMemory >= sMaxBoundTextureMemory || + sTotalTextureMemory >= sMaxTotalTextureMem) { - //when texture memory overflows, lower down the threashold to release the textures more aggressively. - sMaxDesiredTextureMemInBytes = llmin((S32)(sMaxDesiredTextureMemInBytes * 0.75f) , MEGA_BYTES_TO_BYTES(MAX_VIDEO_RAM_IN_MEGA_BYTES)) ;//512 MB + //when texture memory overflows, lower down the threshold to release the textures more aggressively. + sMaxDesiredTextureMem = llmin(sMaxDesiredTextureMem * 0.75f, F32Bytes(gMaxVideoRam)); // If we are using more texture memory than we should, // scale up the desired discard level @@ -537,8 +543,8 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity sEvaluationTimer.reset(); } else if (sDesiredDiscardBias > 0.0f && - BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) < sMaxBoundTextureMemInMegaBytes * texmem_lower_bound_scale && - BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) < sMaxTotalTextureMemInMegaBytes * texmem_lower_bound_scale) + sBoundTextureMemory < sMaxBoundTextureMemory * texmem_lower_bound_scale && + sTotalTextureMemory < sMaxTotalTextureMem * texmem_lower_bound_scale) { // If we are using less texture memory than we should, // scale down the desired discard level @@ -549,15 +555,14 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity } } sDesiredDiscardBias = llclamp(sDesiredDiscardBias, desired_discard_bias_min, desired_discard_bias_max); - //LLViewerTexture::sUseTextureAtlas = gSavedSettings.getBOOL("EnableTextureAtlas") ; - F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ; + 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 = (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) < 0.75f * sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale) && - (BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) < 0.75f * sMaxTotalTextureMemInMegaBytes * texmem_middle_bound_scale) ; + LLViewerTexture::sFreezeImageScalingDown = (sBoundTextureMemory < 0.75f * sMaxBoundTextureMemory * texmem_middle_bound_scale) && + (sTotalTextureMemory < 0.75f * sMaxTotalTextureMem * texmem_middle_bound_scale); } //end of static functions @@ -1156,7 +1161,7 @@ void LLViewerFetchedTexture::dump() // ONLY called from LLViewerFetchedTextureList void LLViewerFetchedTexture::destroyTexture() { - if(LLImageGL::sGlobalTextureMemoryInBytes < sMaxDesiredTextureMemInBytes * 0.95f)//not ready to release unused memory. + if(LLImageGL::sGlobalTextureMemory < sMaxDesiredTextureMem * 0.95f)//not ready to release unused memory. { return ; } @@ -3049,13 +3054,13 @@ void LLViewerLODTexture::processTextureStats() scaleDown() ; } // Limit the amount of GL memory bound each frame - else if ( BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) > sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale && + else if ( sBoundTextureMemory > sMaxBoundTextureMemory * texmem_middle_bound_scale && (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel)) { scaleDown() ; } // Only allow GL to have 2x the video card memory - else if ( BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) > sMaxTotalTextureMemInMegaBytes*texmem_middle_bound_scale && + else if ( sTotalTextureMemory > sMaxTotalTextureMem * texmem_middle_bound_scale && (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel)) { scaleDown() ; @@ -3639,10 +3644,10 @@ LLTexturePipelineTester::LLTexturePipelineTester() : LLMetricPerformanceTesterWi addMetric("TotalBytesBoundForLargeImage") ; addMetric("PercentageBytesBound") ; - mTotalBytesLoaded = 0 ; - mTotalBytesLoadedFromCache = 0 ; - mTotalBytesLoadedForLargeImage = 0 ; - mTotalBytesLoadedForSculpties = 0 ; + mTotalBytesLoaded = (S32Bytes)0; + mTotalBytesLoadedFromCache = (S32Bytes)0; + mTotalBytesLoadedForLargeImage = (S32Bytes)0; + mTotalBytesLoadedForSculpties = (S32Bytes)0; reset() ; } @@ -3656,8 +3661,8 @@ void LLTexturePipelineTester::update() { mLastTotalBytesUsed = mTotalBytesUsed ; mLastTotalBytesUsedForLargeImage = mTotalBytesUsedForLargeImage ; - mTotalBytesUsed = 0 ; - mTotalBytesUsedForLargeImage = 0 ; + mTotalBytesUsed = (S32Bytes)0; + mTotalBytesUsedForLargeImage = (S32Bytes)0; if(LLAppViewer::getTextureFetch()->getNumRequests() > 0) //fetching list is not empty { @@ -3698,10 +3703,10 @@ void LLTexturePipelineTester::reset() mStartStablizingTime = 0.0f ; mEndStablizingTime = 0.0f ; - mTotalBytesUsed = 0 ; - mTotalBytesUsedForLargeImage = 0 ; - mLastTotalBytesUsed = 0 ; - mLastTotalBytesUsedForLargeImage = 0 ; + mTotalBytesUsed = (S32Bytes)0; + mTotalBytesUsedForLargeImage = (S32Bytes)0; + mLastTotalBytesUsed = (S32Bytes)0; + mLastTotalBytesUsedForLargeImage = (S32Bytes)0; mStartFetchingTime = 0.0f ; @@ -3716,59 +3721,59 @@ void LLTexturePipelineTester::reset() void LLTexturePipelineTester::outputTestRecord(LLSD *sd) { std::string currentLabel = getCurrentLabelName(); - (*sd)[currentLabel]["TotalBytesLoaded"] = (LLSD::Integer)mTotalBytesLoaded ; - (*sd)[currentLabel]["TotalBytesLoadedFromCache"] = (LLSD::Integer)mTotalBytesLoadedFromCache ; - (*sd)[currentLabel]["TotalBytesLoadedForLargeImage"] = (LLSD::Integer)mTotalBytesLoadedForLargeImage ; - (*sd)[currentLabel]["TotalBytesLoadedForSculpties"] = (LLSD::Integer)mTotalBytesLoadedForSculpties ; + (*sd)[currentLabel]["TotalBytesLoaded"] = (LLSD::Integer)mTotalBytesLoaded.value(); + (*sd)[currentLabel]["TotalBytesLoadedFromCache"] = (LLSD::Integer)mTotalBytesLoadedFromCache.value(); + (*sd)[currentLabel]["TotalBytesLoadedForLargeImage"] = (LLSD::Integer)mTotalBytesLoadedForLargeImage.value(); + (*sd)[currentLabel]["TotalBytesLoadedForSculpties"] = (LLSD::Integer)mTotalBytesLoadedForSculpties.value(); - (*sd)[currentLabel]["StartFetchingTime"] = (LLSD::Real)mStartFetchingTime ; - (*sd)[currentLabel]["TotalGrayTime"] = (LLSD::Real)mTotalGrayTime ; - (*sd)[currentLabel]["TotalStablizingTime"] = (LLSD::Real)mTotalStablizingTime ; + (*sd)[currentLabel]["StartFetchingTime"] = (LLSD::Real)mStartFetchingTime; + (*sd)[currentLabel]["TotalGrayTime"] = (LLSD::Real)mTotalGrayTime; + (*sd)[currentLabel]["TotalStablizingTime"] = (LLSD::Real)mTotalStablizingTime; - (*sd)[currentLabel]["StartTimeLoadingSculpties"] = (LLSD::Real)mStartTimeLoadingSculpties ; - (*sd)[currentLabel]["EndTimeLoadingSculpties"] = (LLSD::Real)mEndTimeLoadingSculpties ; + (*sd)[currentLabel]["StartTimeLoadingSculpties"] = (LLSD::Real)mStartTimeLoadingSculpties; + (*sd)[currentLabel]["EndTimeLoadingSculpties"] = (LLSD::Real)mEndTimeLoadingSculpties; - (*sd)[currentLabel]["Time"] = LLImageGL::sLastFrameTime ; - (*sd)[currentLabel]["TotalBytesBound"] = (LLSD::Integer)mLastTotalBytesUsed ; - (*sd)[currentLabel]["TotalBytesBoundForLargeImage"] = (LLSD::Integer)mLastTotalBytesUsedForLargeImage ; - (*sd)[currentLabel]["PercentageBytesBound"] = (LLSD::Real)(100.f * mLastTotalBytesUsed / mTotalBytesLoaded) ; + (*sd)[currentLabel]["Time"] = LLImageGL::sLastFrameTime; + (*sd)[currentLabel]["TotalBytesBound"] = (LLSD::Integer)mLastTotalBytesUsed.value(); + (*sd)[currentLabel]["TotalBytesBoundForLargeImage"] = (LLSD::Integer)mLastTotalBytesUsedForLargeImage.value(); + (*sd)[currentLabel]["PercentageBytesBound"] = (LLSD::Real)(100.f * mLastTotalBytesUsed / mTotalBytesLoaded); } void LLTexturePipelineTester::updateTextureBindingStats(const LLViewerTexture* imagep) { - U32 mem_size = (U32)imagep->getTextureMemory() ; - mTotalBytesUsed += mem_size ; + U32Bytes mem_size = imagep->getTextureMemory(); + mTotalBytesUsed += mem_size; - if(MIN_LARGE_IMAGE_AREA <= (U32)(mem_size / (U32)imagep->getComponents())) + if(MIN_LARGE_IMAGE_AREA <= (U32)(mem_size.value() / (U32)imagep->getComponents())) { - mTotalBytesUsedForLargeImage += mem_size ; + mTotalBytesUsedForLargeImage += mem_size; } } void LLTexturePipelineTester::updateTextureLoadingStats(const LLViewerFetchedTexture* imagep, const LLImageRaw* raw_imagep, BOOL from_cache) { - U32 data_size = (U32)raw_imagep->getDataSize() ; - mTotalBytesLoaded += data_size ; + U32Bytes data_size = (U32Bytes)raw_imagep->getDataSize(); + mTotalBytesLoaded += data_size; if(from_cache) { - mTotalBytesLoadedFromCache += data_size ; + mTotalBytesLoadedFromCache += data_size; } - if(MIN_LARGE_IMAGE_AREA <= (U32)(data_size / (U32)raw_imagep->getComponents())) + if(MIN_LARGE_IMAGE_AREA <= (U32)(data_size.value() / (U32)raw_imagep->getComponents())) { - mTotalBytesLoadedForLargeImage += data_size ; + mTotalBytesLoadedForLargeImage += data_size; } if(imagep->forSculpt()) { - mTotalBytesLoadedForSculpties += data_size ; + mTotalBytesLoadedForSculpties += data_size; if(mStartTimeLoadingSculpties > mEndTimeLoadingSculpties) { - mStartTimeLoadingSculpties = LLImageGL::sLastFrameTime ; + mStartTimeLoadingSculpties = LLImageGL::sLastFrameTime; } - mEndTimeLoadingSculpties = LLImageGL::sLastFrameTime ; + mEndTimeLoadingSculpties = LLImageGL::sLastFrameTime; } } diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 94eeaf19e..3ef8b0bea 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -41,8 +41,9 @@ #include #include -#define MIN_VIDEO_RAM_IN_MEGA_BYTES 32 -#define MAX_VIDEO_RAM_IN_MEGA_BYTES 512 // 512MB max for performance reasons. +extern const S32Megabytes gMinVideoRam; +extern const S32Megabytes gMaxVideoRam; + class LLImageGL ; class LLImageRaw; @@ -210,11 +211,11 @@ public: static LLFrameTimer sEvaluationTimer; static F32 sDesiredDiscardBias; static F32 sDesiredDiscardScale; - static S32 sBoundTextureMemoryInBytes; - static S32 sTotalTextureMemoryInBytes; - static S32 sMaxBoundTextureMemInMegaBytes; - static S32 sMaxTotalTextureMemInMegaBytes; - static S32 sMaxDesiredTextureMemInBytes ; + static S32Bytes sBoundTextureMemory; + static S32Bytes sTotalTextureMemory; + static S32Megabytes sMaxBoundTextureMemory; + static S32Megabytes sMaxTotalTextureMem; + static S32Bytes sMaxDesiredTextureMem ; static S8 sCameraMovingDiscardBias; static F32 sCameraMovingBias; static S32 sMaxSculptRez ; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index d67fc1e08..d31f257da 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -72,7 +72,7 @@ void (*LLViewerTextureList::sUUIDCallback)(void **, const LLUUID&) = NULL; -U32 LLViewerTextureList::sTextureBits = 0; +U32Bits LLViewerTextureList::sTextureBits(0); U32 LLViewerTextureList::sTexturePackets = 0; S32 LLViewerTextureList::sNumImages = 0; @@ -95,8 +95,8 @@ void LLViewerTextureList::init() mInitialized = TRUE ; sNumImages = 0; mUpdateStats = TRUE; - mMaxResidentTexMemInMegaBytes = 0; - mMaxTotalTextureMemInMegaBytes = 0 ; + mMaxResidentTexMemInMegaBytes = (U32Bytes)0; + mMaxTotalTextureMemInMegaBytes = (U32Bytes)0; if (gNoRender) { // Don't initialize GL stuff if we're not rendering. @@ -104,7 +104,7 @@ void LLViewerTextureList::init() } // Update how much texture RAM we're allowed to use. - updateMaxResidentTexMem(0); // 0 = use current + updateMaxResidentTexMem(S32Megabytes(0)); // 0 = use current doPreloadImages(); } @@ -706,8 +706,8 @@ void LLViewerTextureList::updateImages(F32 max_time) } LLViewerStats::getInstance()->mNumImagesStat.addValue(sNumImages); LLViewerStats::getInstance()->mNumRawImagesStat.addValue(LLImageRaw::sRawImageCount); - LLViewerStats::getInstance()->mGLTexMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sGlobalTextureMemoryInBytes)); - LLViewerStats::getInstance()->mGLBoundMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sBoundTextureMemoryInBytes)); + LLViewerStats::getInstance()->mGLTexMemStat.addValue((F32)LLImageGL::sGlobalTextureMemory.valueInUnits()); + LLViewerStats::getInstance()->mGLBoundMemStat.addValue((F32)LLImageGL::sBoundTextureMemory.valueInUnits()); LLViewerStats::getInstance()->mRawMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(global_raw_memory)); LLViewerStats::getInstance()->mFormattedMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageFormatted::sGlobalFormattedMemory)); @@ -960,12 +960,10 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) 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); - //Old: size_t max_priority_count = llmin((S32) (MAX_HIGH_PRIO_COUNT*40.f*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); - //Old: size_t max_priority_count = llmin((S32) (MAX_UPDATE_COUNT*40.f*gFrameIntervalSeconds)+1, MAX_UPDATE_COUNT); max_update_count = llmin(max_update_count, total_update_count); // MAX_HIGH_PRIO_COUNT high priority entries @@ -1218,20 +1216,16 @@ LLPointer LLViewerTextureList::convertToUploadFile(LLPointer 2000) - return 128; - else if (system_ram > 1000) - return 64; - else - return MIN_VIDEO_RAM_IN_MEGA_BYTES; + S32Megabytes system_ram = gSysMemory.getPhysicalMemoryClamped(); + //min texture mem sets to 64M if total physical mem is more than 1.5GB + return (system_ram > S32Megabytes(1500)) ? S32Megabytes(64) : gMinVideoRam ; } //static // Returns max setting for TextureMemory (in MB) -S32 LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended) +S32Megabytes LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended, float mem_multiplier) { #if LL_LINUX if (gGLManager.mIsIntel && gGLManager.mGLVersion >= 3.f && !gGLManager.mVRAM) @@ -1239,12 +1233,12 @@ S32 LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended) gGLManager.mVRAM = 512; } #endif - S32 max_texmem; + S32Megabytes max_texmem; if (gGLManager.mVRAM != 0) { // Treat any card with < 32 MB (shudder) as having 32 MB // - it's going to be swapping constantly regardless - S32 max_vram = gGLManager.mVRAM; + S32Megabytes max_vram(gGLManager.mVRAM); max_vram = llmax(max_vram, getMinVideoRamSetting()); max_texmem = max_vram; if (!get_recommended) @@ -1252,72 +1246,81 @@ S32 LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended) } else { - if (get_recommended) - max_texmem = 128; + if (!get_recommended) + { + max_texmem = (S32Megabytes)512; + } + else if (gSavedSettings.getBOOL("NoHardwareProbe")) //did not do hardware detection at startup + { + max_texmem = (S32Megabytes)512; + } else - max_texmem = 512; + { + max_texmem = (S32Megabytes)128; + } + LL_WARNS() << "VRAM amount not detected, defaulting to " << max_texmem << " MB" << LL_ENDL; } - S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()); // In MB + S32Megabytes system_ram = gSysMemory.getPhysicalMemoryClamped(); // In MB //LL_INFOS() << "*** DETECTED " << system_ram << " MB of system memory." << LL_ENDL; if (get_recommended) - max_texmem = llmin(max_texmem, (S32)(system_ram/2)); + max_texmem = llmin(max_texmem, system_ram/2); else - max_texmem = llmin(max_texmem, (S32)(system_ram)); + max_texmem = llmin(max_texmem, system_ram); - max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), MAX_VIDEO_RAM_IN_MEGA_BYTES); + // limit the texture memory to a multiple of the default if we've found some cards to behave poorly otherwise + max_texmem = llmin(max_texmem, (S32Megabytes) (mem_multiplier * max_texmem)); + + max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), gMaxVideoRam); return max_texmem; } -const S32 VIDEO_CARD_FRAMEBUFFER_MEM = 12; // MB -const S32 MIN_MEM_FOR_NON_TEXTURE = 512 ; //MB -void LLViewerTextureList::updateMaxResidentTexMem(S32 mem) +const S32Megabytes VIDEO_CARD_FRAMEBUFFER_MEM(12); +const S32Megabytes MIN_MEM_FOR_NON_TEXTURE(512); +void LLViewerTextureList::updateMaxResidentTexMem(S32Megabytes mem) { // Initialize the image pipeline VRAM settings - S32 cur_mem = gSavedSettings.getS32("TextureMemory"); + S32Megabytes cur_mem(gSavedSettings.getS32("TextureMemory")); F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple"); - S32 default_mem = getMaxVideoRamSetting(true); // recommended default - if (mem == 0) + S32Megabytes default_mem = getMaxVideoRamSetting(true, mem_multiplier); // recommended default + if (mem == (S32Bytes)0) { - mem = cur_mem > 0 ? cur_mem : default_mem; + mem = cur_mem > (S32Bytes)0 ? cur_mem : default_mem; } - else if (mem < 0) + else if (mem < (S32Bytes)0) { mem = default_mem; } - // limit the texture memory to a multiple of the default if we've found some cards to behave poorly otherwise - mem = llmin(mem, (S32) (mem_multiplier * (F32) default_mem)); - - mem = llclamp(mem, getMinVideoRamSetting(), getMaxVideoRamSetting()); + mem = llclamp(mem, getMinVideoRamSetting(), getMaxVideoRamSetting(false, mem_multiplier)); if (mem != cur_mem) { - gSavedSettings.setS32("TextureMemory", mem); + gSavedSettings.setS32("TextureMemory", mem.value()); return; //listener will re-enter this function } // TODO: set available resident texture mem based on use by other subsystems // currently max(12MB, VRAM/4) assumed... - S32 vb_mem = mem; - S32 fb_mem = llmax(VIDEO_CARD_FRAMEBUFFER_MEM, vb_mem/4); + S32Megabytes vb_mem = mem; + S32Megabytes fb_mem = llmax(VIDEO_CARD_FRAMEBUFFER_MEM, vb_mem/4); mMaxResidentTexMemInMegaBytes = (vb_mem - fb_mem) ; //in MB mMaxTotalTextureMemInMegaBytes = mMaxResidentTexMemInMegaBytes * 2; - if (mMaxResidentTexMemInMegaBytes > 640) + if (mMaxResidentTexMemInMegaBytes > (S32Megabytes)640) { - mMaxTotalTextureMemInMegaBytes -= (mMaxResidentTexMemInMegaBytes >> 2); + mMaxTotalTextureMemInMegaBytes -= (mMaxResidentTexMemInMegaBytes / 4); } //system mem - S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()); // In MB + S32Megabytes system_ram = gSysMemory.getPhysicalMemoryClamped(); //minimum memory reserved for non-texture use. //if system_raw >= 1GB, reserve at least 512MB for non-texture use; //otherwise reserve half of the system_ram for non-texture use. - S32 min_non_texture_mem = llmin(system_ram / 2, MIN_MEM_FOR_NON_TEXTURE) ; + S32Megabytes min_non_texture_mem = llmin(system_ram / 2, MIN_MEM_FOR_NON_TEXTURE) ; if (mMaxTotalTextureMemInMegaBytes > system_ram - min_non_texture_mem) { @@ -1345,17 +1348,17 @@ void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_d char ip_string[256]; u32_to_ip_string(msg->getSenderIP(),ip_string); - U32 received_size ; + U32Bytes received_size ; if (msg->getReceiveCompressedSize()) { - received_size = msg->getReceiveCompressedSize() ; + received_size = (U32Bytes)msg->getReceiveCompressedSize() ; } else { - received_size = msg->getReceiveSize() ; + received_size = (U32Bytes)msg->getReceiveSize() ; } // Only used for statistics and texture console. - gTextureList.sTextureBits += received_size * 8; + gTextureList.sTextureBits += received_size; gTextureList.sTexturePackets++; U8 codec; @@ -1419,16 +1422,16 @@ void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_d char ip_string[256]; u32_to_ip_string(msg->getSenderIP(),ip_string); - U32 received_size ; + U32Bytes received_size ; if (msg->getReceiveCompressedSize()) { - received_size = msg->getReceiveCompressedSize() ; + received_size = (U32Bytes)msg->getReceiveCompressedSize() ; } else { - received_size = msg->getReceiveSize() ; + received_size = (U32Bytes)msg->getReceiveSize() ; } - gTextureList.sTextureBits += received_size * 8; + gTextureList.sTextureBits += received_size; gTextureList.sTexturePackets++; //llprintline("Start decode, image header..."); @@ -1494,24 +1497,6 @@ void LLViewerTextureList::processImageNotInDatabase(LLMessageSystem *msg,void ** /////////////////////////////////////////////////////////////////////////////// -//static -const U32 SIXTEEN_MEG = 0x1000000; -S32 LLViewerTextureList::calcMaxTextureRAM() -{ - // Decide the maximum amount of RAM we should allow the user to allocate to texture cache - LLMemoryInfo memory_info; - U32 available_memory = memory_info.getPhysicalMemoryClamped(); - - clamp_rescale((F32)available_memory, - (F32)(SIXTEEN_MEG * 16), - (F32)U32_MAX, - (F32)(SIXTEEN_MEG * 4), - (F32)(U32_MAX >> 1)); - return available_memory; -} - -/////////////////////////////////////////////////////////////////////////////// - // explicitly cleanup resources, as this is a singleton class with process // lifetime so ability to perform std::map operations in destructor is not // guaranteed. diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index 57d6bc91d..3d2fd127c 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -71,7 +71,6 @@ public: static BOOL verifyUploadFile(const std::string& out_filename, const U8 codec); static LLPointer convertToUploadFile(LLPointer raw_image); static void processImageNotInDatabase( LLMessageSystem *msg, void **user_data ); - static S32 calcMaxTextureRAM(); static void receiveImageHeader(LLMessageSystem *msg, void **user_data); static void receiveImagePacket(LLMessageSystem *msg, void **user_data); @@ -101,19 +100,19 @@ public: void setUpdateStats(BOOL b) { mUpdateStats = b; } - S32 getMaxResidentTexMem() const { return mMaxResidentTexMemInMegaBytes; } - S32 getMaxTotalTextureMem() const { return mMaxTotalTextureMemInMegaBytes;} + S32Megabytes getMaxResidentTexMem() const { return mMaxResidentTexMemInMegaBytes; } + S32Megabytes getMaxTotalTextureMem() const { return mMaxTotalTextureMemInMegaBytes;} S32 getNumImages() { return mImageList.size(); } - void updateMaxResidentTexMem(S32 mem); + void updateMaxResidentTexMem(S32Megabytes mem); void doPreloadImages(); void doPrefetchImages(); void clearFetchingRequests(); - static S32 getMinVideoRamSetting(); - static S32 getMaxVideoRamSetting(bool get_recommended = false); + static S32Megabytes getMinVideoRamSetting(); + static S32Megabytes getMaxVideoRamSetting(bool get_recommended, float mem_multiplier); private: void updateImagesDecodePriorities(); @@ -195,12 +194,12 @@ private: BOOL mInitialized ; BOOL mUpdateStats; - S32 mMaxResidentTexMemInMegaBytes; - S32 mMaxTotalTextureMemInMegaBytes; + S32Megabytes mMaxResidentTexMemInMegaBytes; + S32Megabytes mMaxTotalTextureMemInMegaBytes; LLFrameTimer mForceDecodeTimer; public: - static U32 sTextureBits; + static U32Bits sTextureBits; static U32 sTexturePackets; private: diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 1b753104e..492c35eca 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -5356,7 +5356,7 @@ void LLViewerWindow::stopGL(BOOL save_state) gGL.resetVertexBuffers(); - LL_INFOS() << "Remaining allocated texture memory: " << LLImageGL::sGlobalTextureMemoryInBytes << " bytes" << LL_ENDL; + LL_INFOS() << "Remaining allocated texture memory: " << LLImageGL::sGlobalTextureMemory << " bytes" << LL_ENDL; } } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 61c6f3fdf..6f015d907 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -5169,9 +5169,9 @@ std::string LLVOAvatar::bakedTextureOriginInfo() return result; } -S32 LLVOAvatar::totalTextureMemForUUIDS(std::set& ids) +S32Bytes LLVOAvatar::totalTextureMemForUUIDS(std::set& ids) { - S32 result = 0; + S32Bytes result(0); for (std::set::const_iterator it = ids.begin(); it != ids.end(); ++it) { LLViewerFetchedTexture *imagep = gTextureList.findImage(*it); @@ -5236,12 +5236,12 @@ void LLVOAvatar::collectTextureUUIDs(std::set& ids) void LLVOAvatar::releaseOldTextures() { - S32 current_texture_mem = 0; + S32Bytes current_texture_mem; // Any textures that we used to be using but are no longer using should no longer be flagged as "NO_DELETE" std::set baked_texture_ids; collectBakedTextureUUIDs(baked_texture_ids); - S32 new_baked_mem = totalTextureMemForUUIDS(baked_texture_ids); + S32Bytes new_baked_mem = totalTextureMemForUUIDS(baked_texture_ids); std::set local_texture_ids; collectLocalTextureUUIDs(local_texture_ids); @@ -5250,7 +5250,7 @@ void LLVOAvatar::releaseOldTextures() std::set new_texture_ids; new_texture_ids.insert(baked_texture_ids.begin(),baked_texture_ids.end()); new_texture_ids.insert(local_texture_ids.begin(),local_texture_ids.end()); - S32 new_total_mem = totalTextureMemForUUIDS(new_texture_ids); + S32Bytes new_total_mem = totalTextureMemForUUIDS(new_texture_ids); //S32 old_total_mem = totalTextureMemForUUIDS(mTextureIDs); //LL_DEBUGS("Avatar") << getFullname() << " old_total_mem: " << old_total_mem << " new_total_mem (L/B): " << new_total_mem << " (" << new_local_mem <<", " << new_baked_mem << ")" << LL_ENDL; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 8e3ece6d9..db2150166 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -184,7 +184,7 @@ public: void updateLODRiggedAttachments( void ); void updateSoftwareSkinnedVertices(const LLMeshSkinInfo* skin, const LLVector4a* weight, const LLVolumeFace& vol_face, LLVertexBuffer *buffer); /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. - S32 totalTextureMemForUUIDS(std::set& ids); + S32Bytes totalTextureMemForUUIDS(std::set& ids); bool allTexturesCompletelyDownloaded(std::set& ids) const; bool allLocalTexturesCompletelyDownloaded() const; bool allBakedTexturesCompletelyDownloaded() const; diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 46b991c9e..2fb35c181 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -157,7 +157,7 @@ typedef LLHTTPClient::ResponderIgnore LLHoverHeightResponder; //----------------------------------------------------------------------------- // Static Data //----------------------------------------------------------------------------- -S32 LLVOAvatarSelf::sScratchTexBytes = 0; +S32Bytes LLVOAvatarSelf::sScratchTexBytes(0); LLMap< LLGLenum, LLGLuint*> LLVOAvatarSelf::sScratchTexNames; LLMap< LLGLenum, F32*> LLVOAvatarSelf::sScratchTexLastBindTime; @@ -3215,8 +3215,8 @@ void LLVOAvatarSelf::deleteScratchTextures() { if(gAuditTexture) { - S32 total_tex_size = sScratchTexBytes ; - S32 tex_size = SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT ; + S32Bytes total_tex_size = sScratchTexBytes ; + S32Bytes tex_size(SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT) ; if( sScratchTexNames.checkData( GL_LUMINANCE ) ) { @@ -3249,7 +3249,7 @@ void LLVOAvatarSelf::deleteScratchTextures() total_tex_size -= 4 * tex_size ; } //others - while(total_tex_size > 0) + while(total_tex_size > S32Bytes(0)) { LLImageGL::decTextureCounter(tex_size, 4, LLViewerTexture::AVATAR_SCRATCH_TEX) ; total_tex_size -= 4 * tex_size ; @@ -3264,14 +3264,14 @@ void LLVOAvatarSelf::deleteScratchTextures() stop_glerror(); } - if( sScratchTexBytes ) + if( sScratchTexBytes.value() ) { - LL_DEBUGS() << "Clearing Scratch Textures " << (sScratchTexBytes/1024) << "KB" << LL_ENDL; + LL_DEBUGS() << "Clearing Scratch Textures " << (S32Kilobytes)sScratchTexBytes << "KB" << LL_ENDL; sScratchTexNames.deleteAllData(); sScratchTexLastBindTime.deleteAllData(); - LLImageGL::sGlobalTextureMemoryInBytes -= sScratchTexBytes; - sScratchTexBytes = 0; + LLImageGL::sGlobalTextureMemory -= sScratchTexBytes; + sScratchTexBytes = S32Bytes(0); } } diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 1988a51fd..ea55884a6 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -273,7 +273,7 @@ public: public: static void deleteScratchTextures(); private: - static S32 sScratchTexBytes; + static S32Bytes sScratchTexBytes; static LLMap< LLGLenum, LLGLuint*> sScratchTexNames; static LLMap< LLGLenum, F32*> sScratchTexLastBindTime; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index b6ff1dfab..50a843697 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4001,7 +4001,8 @@ U32 LLVOVolume::getPartitionType() const } LLVolumePartition::LLVolumePartition(LLViewerRegion* regionp) -: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB, regionp) +: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB, regionp), +LLVolumeGeometryManager() { mLODPeriod = 32; mDepthMask = FALSE; @@ -4012,7 +4013,8 @@ LLVolumePartition::LLVolumePartition(LLViewerRegion* regionp) } LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep, LLViewerRegion* regionp) -: LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK, regionp) +: LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK, regionp), +LLVolumeGeometryManager() { mDepthMask = FALSE; mLODPeriod = 32; @@ -4073,6 +4075,70 @@ bool can_batch_texture(const LLFace* facep) return true; } +const static U32 MAX_FACE_COUNT = 4096U; +int32_t LLVolumeGeometryManager::sInstanceCount = 0; +LLFace** LLVolumeGeometryManager::sFullbrightFaces = NULL; +LLFace** LLVolumeGeometryManager::sBumpFaces = NULL; +LLFace** LLVolumeGeometryManager::sSimpleFaces = NULL; +LLFace** LLVolumeGeometryManager::sNormFaces = NULL; +LLFace** LLVolumeGeometryManager::sSpecFaces = NULL; +LLFace** LLVolumeGeometryManager::sNormSpecFaces = NULL; +LLFace** LLVolumeGeometryManager::sAlphaFaces = NULL; + +LLVolumeGeometryManager::LLVolumeGeometryManager() + : LLGeometryManager() +{ + llassert(sInstanceCount >= 0); + if (sInstanceCount == 0) + { + allocateFaces(MAX_FACE_COUNT); + } + + ++sInstanceCount; +} + +LLVolumeGeometryManager::~LLVolumeGeometryManager() +{ + llassert(sInstanceCount > 0); + --sInstanceCount; + + if (sInstanceCount <= 0) + { + freeFaces(); + sInstanceCount = 0; + } +} + +void LLVolumeGeometryManager::allocateFaces(U32 pMaxFaceCount) +{ + sFullbrightFaces = static_cast(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); + sBumpFaces = static_cast(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); + sSimpleFaces = static_cast(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); + sNormFaces = static_cast(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); + sSpecFaces = static_cast(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); + sNormSpecFaces = static_cast(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); + sAlphaFaces = static_cast(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*))); +} + +void LLVolumeGeometryManager::freeFaces() +{ + ll_aligned_free<64>(sFullbrightFaces); + ll_aligned_free<64>(sBumpFaces); + ll_aligned_free<64>(sSimpleFaces); + ll_aligned_free<64>(sNormFaces); + ll_aligned_free<64>(sSpecFaces); + ll_aligned_free<64>(sNormSpecFaces); + ll_aligned_free<64>(sAlphaFaces); + + sFullbrightFaces = NULL; + sBumpFaces = NULL; + sSimpleFaces = NULL; + sNormFaces = NULL; + sSpecFaces = NULL; + sNormSpecFaces = NULL; + sAlphaFaces = NULL; +} + static LLFastTimer::DeclareTimer FTM_REGISTER_FACE("Register Face"); void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type) @@ -4427,16 +4493,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) group->clearDrawMap(); mFaceList.clear(); - - const U32 MAX_FACE_COUNT = 4096; - - static LLFace** fullbright_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64); - static LLFace** bump_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64); - static LLFace** simple_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64); - static LLFace** norm_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*), 64); - static LLFace** spec_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*), 64); - static LLFace** normspec_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*), 64); - static LLFace** alpha_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64); U32 fullbright_count = 0; U32 bump_count = 0; @@ -4931,7 +4987,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { //can be treated as alpha mask if (simple_count < MAX_FACE_COUNT) { - simple_faces[simple_count++] = facep; + sSimpleFaces[simple_count++] = facep; } } else @@ -4942,7 +4998,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } if (alpha_count < MAX_FACE_COUNT) { - alpha_faces[alpha_count++] = facep; + sAlphaFaces[alpha_count++] = facep; } } } @@ -4967,14 +5023,14 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { //has normal and specular maps (needs texcoord1, texcoord2, and tangent) if (normspec_count < MAX_FACE_COUNT) { - normspec_faces[normspec_count++] = facep; + sNormSpecFaces[normspec_count++] = facep; } } else { //has normal map (needs texcoord1 and tangent) if (norm_count < MAX_FACE_COUNT) { - norm_faces[norm_count++] = facep; + sNormFaces[norm_count++] = facep; } } } @@ -4982,14 +5038,14 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { //has specular map but no normal map, needs texcoord2 if (spec_count < MAX_FACE_COUNT) { - spec_faces[spec_count++] = facep; + sSpecFaces[spec_count++] = facep; } } else { //has neither specular map nor normal map, only needs texcoord0 if (simple_count < MAX_FACE_COUNT) { - simple_faces[simple_count++] = facep; + sSimpleFaces[simple_count++] = facep; } } } @@ -4997,14 +5053,14 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { //needs normal + tangent if (bump_count < MAX_FACE_COUNT) { - bump_faces[bump_count++] = facep; + sBumpFaces[bump_count++] = facep; } } else if (te->getShiny() || !te->getFullbright()) { //needs normal if (simple_count < MAX_FACE_COUNT) { - simple_faces[simple_count++] = facep; + sSimpleFaces[simple_count++] = facep; } } else @@ -5012,7 +5068,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) facep->setState(LLFace::FULLBRIGHT); if (fullbright_count < MAX_FACE_COUNT) { - fullbright_faces[fullbright_count++] = facep; + sFullbrightFaces[fullbright_count++] = facep; } } } @@ -5022,7 +5078,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { //needs normal + tangent if (bump_count < MAX_FACE_COUNT) { - bump_faces[bump_count++] = facep; + sBumpFaces[bump_count++] = facep; } } else if ((te->getShiny() && LLPipeline::sRenderBump) || @@ -5030,7 +5086,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { //needs normal if (simple_count < MAX_FACE_COUNT) { - simple_faces[simple_count++] = facep; + sSimpleFaces[simple_count++] = facep; } } else @@ -5038,7 +5094,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) facep->setState(LLFace::FULLBRIGHT); if (fullbright_count < MAX_FACE_COUNT) { - fullbright_faces[fullbright_count++] = facep; + sFullbrightFaces[fullbright_count++] = facep; } } } @@ -5051,7 +5107,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (type == LLDrawPool::POOL_ALPHA) { - cur_type = &alpha_faces; + cur_type = &sAlphaFaces; cur_count = &alpha_count; if (te->getColor().mV[3] > 0.f) @@ -5066,30 +5122,30 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { if (mat->getSpecularID().notNull()) { //has normal and specular maps (needs texcoord1, texcoord2, and tangent) - cur_type = &normspec_faces; + cur_type = &sNormSpecFaces; cur_count = &normspec_count; } else { //has normal map (needs texcoord1 and tangent) - cur_type = &norm_faces; + cur_type = &sNormFaces; cur_count = &norm_count; } } else if (mat->getSpecularID().notNull()) { //has specular map but no normal map, needs texcoord2 - cur_type = &spec_faces; + cur_type = &sSpecFaces; cur_count = &spec_count; } } } else if(type == LLDrawPool::POOL_ALPHA_MASK) { - cur_type = &simple_faces; + cur_type = &sSimpleFaces; cur_count = &simple_count; } else if(type == LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK) { - cur_type = &fullbright_faces; + cur_type = &sFullbrightFaces; cur_count = &fullbright_count; } else @@ -5103,30 +5159,30 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { //needs normal + tangent if(te->getBumpmap() > 0 && te->getBumpmap() < 18) { - cur_type = &bump_faces; + cur_type = &sBumpFaces; cur_count = &bump_count; } else if(te->getShiny()) { - cur_type = &simple_faces; + cur_type = &sSimpleFaces; cur_count = &simple_count; } } else if (type == LLDrawPool::POOL_SIMPLE) { //needs normal + tangent - cur_type = &simple_faces; + cur_type = &sSimpleFaces; cur_count = &simple_count; } else if (type == LLDrawPool::POOL_FULLBRIGHT) { //doesn't need normal... if(LLPipeline::sRenderBump && te->getShiny()) //unless it's shiny.. { - cur_type = &simple_faces; + cur_type = &sSimpleFaces; cur_count = &simple_count; } else { - cur_type = &fullbright_faces; + cur_type = &sFullbrightFaces; cur_count = &fullbright_count; } } @@ -5140,23 +5196,23 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { if (mat->getSpecularID().notNull()) { //has normal and specular maps (needs texcoord1, texcoord2, and tangent) - cur_type = &normspec_faces; + cur_type = &sNormSpecFaces; cur_count = &normspec_count; } else { //has normal map (needs texcoord1 and tangent) - cur_type = &norm_faces; + cur_type = &sNormFaces; cur_count = &norm_count; } } else if (mat->getSpecularID().notNull()) { //has specular map but no normal map, needs texcoord2 - cur_type = &spec_faces; + cur_type = &sSpecFaces; cur_count = &spec_count; } else { //has neither specular map nor normal map, only needs texcoord0 - cur_type = &simple_faces; + cur_type = &sSimpleFaces; cur_count = &simple_count; } } @@ -5218,13 +5274,13 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if(emissive) additional_flags |= LLVertexBuffer::MAP_EMISSIVE; - genDrawInfo(group, simple_mask | additional_flags, simple_faces, simple_count, FALSE, batch_textures); - genDrawInfo(group, fullbright_mask | additional_flags, fullbright_faces, fullbright_count, FALSE, batch_textures); - genDrawInfo(group, alpha_mask | additional_flags, alpha_faces, alpha_count, TRUE, batch_textures); - genDrawInfo(group, bump_mask | additional_flags, bump_faces, bump_count, FALSE); - genDrawInfo(group, norm_mask | additional_flags, norm_faces, norm_count, FALSE); - genDrawInfo(group, spec_mask | additional_flags, spec_faces, spec_count, FALSE); - genDrawInfo(group, normspec_mask | additional_flags, normspec_faces, normspec_count, FALSE); + genDrawInfo(group, simple_mask | additional_flags, sSimpleFaces, simple_count, FALSE, batch_textures); + genDrawInfo(group, fullbright_mask | additional_flags, sFullbrightFaces, fullbright_count, FALSE, batch_textures); + genDrawInfo(group, alpha_mask | additional_flags, sAlphaFaces, alpha_count, TRUE, batch_textures); + genDrawInfo(group, bump_mask | additional_flags, sBumpFaces, bump_count, FALSE); + genDrawInfo(group, norm_mask | additional_flags, sNormFaces, norm_count, FALSE); + genDrawInfo(group, spec_mask | additional_flags, sSpecFaces, spec_count, FALSE); + genDrawInfo(group, normspec_mask | additional_flags, sNormSpecFaces, normspec_count, FALSE); if (!LLPipeline::sDelayVBUpdate) { diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 3befdff47..7eaf9f529 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2830,7 +2830,7 @@ void LLPipeline::updateGeom(F32 max_dtime) S32 count = 0; - max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, max_dtime); + max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, F32SecondsImplicit(max_dtime)); LLSpatialGroup* last_group = NULL; LLSpatialBridge* last_bridge = NULL;