llcommon merge. Added LLUnits.

This commit is contained in:
Shyotl
2016-04-06 01:31:20 -05:00
parent 0fa7848b19
commit 0841479ccc
66 changed files with 1895 additions and 621 deletions

View File

@@ -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

View File

@@ -64,7 +64,7 @@ LLAlignedArray<T, alignment>::LLAlignedArray()
template <class T, U32 alignment>
LLAlignedArray<T, alignment>::~LLAlignedArray()
{
ll_aligned_free(mArray);
ll_aligned_free<alignment>(mArray);
mArray = NULL;
mElementCount = 0;
mCapacity = 0;
@@ -78,7 +78,7 @@ void LLAlignedArray<T, alignment>::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<alignment>(mCapacity*sizeof(T));
if (mArray)
{
ll_memcpy_nonaliased_aligned_16((char*)new_buf, (char*)mArray, sizeof(T)*mElementCount);
@@ -90,7 +90,7 @@ void LLAlignedArray<T, alignment>::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<alignment>(old_buf);
}
template <class T, U32 alignment>
@@ -99,11 +99,11 @@ void LLAlignedArray<T, alignment>::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<alignment>(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<alignment>(mArray);
}
/*for (U32 i = mElementCount; i < mCapacity; ++i)

View File

@@ -30,13 +30,17 @@
#include "llbase64.h"
#include <string>
#include "apr_base64.h"
// static
std::string LLBase64::encode(const U8* input, size_t input_size)
{
if (!(input && input_size > 0)) return LLStringUtil::null;
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];
@@ -49,12 +53,12 @@ std::string LLBase64::encode(const U8* input, size_t input_size)
b64_buffer,
input,
input_size);
std::string result;
result.assign(b64_buffer);
output.assign(b64_buffer);
delete[] b64_buffer;
return result;
}
return output;
}
// static
std::string LLBase64::encode(const std::string& in_str)

View File

@@ -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");

View File

@@ -38,9 +38,8 @@
#include <iosfwd>
#include <string>
#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

View File

@@ -65,7 +65,7 @@ LLEventTimer::~LLEventTimer()
void LLEventTimer::updateClass()
{
std::list<LLEventTimer*> 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();

View File

@@ -28,7 +28,7 @@
*/
#if LL_WINDOWS
#include <windows.h>
#include "llwin32headerslean.h"
#include <stdlib.h> // Windows errno
#else
#include <errno.h>

View File

@@ -39,7 +39,7 @@
#include <ctype.h>
#ifdef WIN32
#include <windows.h>
#include "llwin32headers.h"
#include <winnt.h>
#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"},

View File

@@ -30,7 +30,8 @@
LLFixedBuffer::LLFixedBuffer(const U32 max_lines)
: LLLineBuffer(),
mMaxLines(max_lines)
mMaxLines(max_lines),
mMutex()
{
mTimer.reset();
}

View File

@@ -194,13 +194,6 @@ public:
return mHandle;
}
protected:
typedef LLHandle<T> handle_type_t;
LLHandleProvider()
{
// provided here to enforce T deriving from LLHandleProvider<T>
}
template <typename U>
LLHandle<U> getDerivedHandle(typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0) const
{
@@ -209,6 +202,12 @@ protected:
return downcast_handle;
}
protected:
typedef LLHandle<T> handle_type_t;
LLHandleProvider()
{
// provided here to enforce T deriving from LLHandleProvider<T>
}
private:
mutable LLRootHandle<T> mHandle;

View File

@@ -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
return false;
}
mForceCheck = false;
mRefreshTimer.reset();
if (mForceCheck || mRefreshTimer.getElapsedTimeF32() >= mRefreshPeriod)
{
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)
if (LLFile::stat(mFilename, &stat_data))
{
// Couldn't stat the file, that means it doesn't exist or is
// broken somehow. Clear flags and return.
// broken somehow.
if (mLastExists)
{
mLastExists = false;
return true; // no longer existing is a change!
detected_change = true; // no longer existing is a change!
LL_DEBUGS() << "detected deleted file '" << mFilename << "'" << LL_ENDL;
}
return false;
}
// The file exists, decide if we want to load it.
if (mLastExists)
else
{
// The file existed last time, don't read it if it hasn't changed since
// last time.
if (stat_data.st_mtime <= mLastModTime)
// The file exists
if ( ! mLastExists )
{
return false;
// 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;
}
// We want to read the file. Update status info for the file.
mLastExists = true;
mLastStatTime = stat_data.st_mtime;
return true;
}
}
if (detected_change)
{
LL_INFOS() << "detected file change '" << mFilename << "'" << LL_ENDL;
}
return detected_change;
}
void LLLiveFile::Impl::changed()

View File

@@ -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);

View File

@@ -32,7 +32,7 @@
//#endif
#if defined(LL_WINDOWS)
//# include <windows.h>
#include "llwin32headerslean.h"
# include <psapi.h>
#elif defined(LL_DARWIN)
# include <sys/types.h>
@@ -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 ;
}

View File

@@ -27,7 +27,8 @@
#define LLMEMORY_H
#include "linden_common.h"
#include "llunits.h"
#include "stdtypes.h"
#include <new>
#include <cstdlib>
#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
//<singu>
// 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,7 +118,17 @@ template <typename T> 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 )
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
// for enable buffer overrun detection predefine LL_DEBUG_BUFFER_OVERRUN in current library
// change preprocessor code to: #if 1 && defined(LL_WINDOWS)
#if 0 && defined(LL_WINDOWS)
void* ll_aligned_malloc_fallback( size_t size, int align );
void ll_aligned_free_fallback( void* ptr );
//------------------------------------------------------------------------------------------------
#else
inline void* ll_aligned_malloc_fallback( size_t size, int align )
{
#if defined(LL_WINDOWS)
return _aligned_malloc(size, align);
@@ -116,7 +142,7 @@ inline void* ll_aligned_malloc( size_t size, int align )
#endif
}
inline void ll_aligned_free( void* ptr )
inline void ll_aligned_free_fallback( void* ptr )
{
#if defined(LL_WINDOWS)
_aligned_free(ptr);
@@ -127,6 +153,8 @@ inline void ll_aligned_free( void* ptr )
}
#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<size_t ALIGNMENT>
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<size_t ALIGNMENT>
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;
};

View File

@@ -34,6 +34,7 @@
#define LLMORTICIAN_H
#include "stdtypes.h"
#include <list>
class LL_COMMON_API LLMortician
{

View File

@@ -32,9 +32,7 @@
//#include <memory>
#if LL_WINDOWS
# define WIN32_LEAN_AND_MEAN
# include <winsock2.h>
# include <windows.h>
# include "llwin32headerslean.h"
# define _interlockedbittestandset _renamed_interlockedbittestandset
# define _interlockedbittestandreset _renamed_interlockedbittestandreset
# include <intrin.h>
@@ -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(); }

View File

@@ -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;

View File

@@ -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

View File

@@ -32,8 +32,6 @@
#include <map>
#include <set>
#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<BOOL> mIdleThread; // request queue is empty (or we are quitting) and the thread is idle
LLAtomic32<bool> mIdleThread; // request queue is empty (or we are quitting) and the thread is idle
typedef std::set<QueuedRequest*, queued_request_less> request_queue_t;
request_queue_t mRequestQueue;

View File

@@ -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()

View File

@@ -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;

View File

@@ -39,7 +39,7 @@
#include <iostream>
#include <sstream>
#include "windows.h"
#include "llwin32headerslean.h"
#include "Dbghelp.h"
typedef USHORT NTAPI RtlCaptureStackBackTrace_Function(

View File

@@ -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<std::type_info*> 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

View File

@@ -30,9 +30,7 @@
#include "llerror.h"
#if LL_WINDOWS
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <windows.h>
#include "llwin32headerslean.h"
#include <winnls.h> // for WideCharToMultiByte
#endif

View File

@@ -53,9 +53,7 @@
using namespace llsd;
#if LL_WINDOWS
# define WIN32_LEAN_AND_MEAN
# include <winsock2.h>
# include <windows.h>
# include "llwin32headerslean.h"
# include <psapi.h> // GetPerformanceInfo() et al.
# include <VersionHelpers.h>
#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
}

View File

@@ -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.

View File

@@ -31,9 +31,7 @@
#include "u64.h"
#if LL_WINDOWS
# define WIN32_LEAN_AND_MEAN
# include <winsock2.h>
# include <windows.h>
# include "llwin32headerslean.h"
#elif LL_LINUX || LL_SOLARIS || LL_DARWIN
# include <errno.h>
# include <sys/time.h>
@@ -83,7 +81,7 @@ 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);
ms_sleep((U32)(us / 1000));
return 0;
}
#elif LL_LINUX || LL_SOLARIS || LL_DARWIN
@@ -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);
}

View File

@@ -37,6 +37,7 @@
#include <string>
#include <list>
// 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 &timestr);
LL_COMMON_API void timeStructToFormattedString(struct tm * time, std::string format, std::string &timestr);
U64 LL_COMMON_API totalTime(); // Returns current system time in microseconds
U64MicrosecondsImplicit LL_COMMON_API totalTime(); // Returns current system time in microseconds
#endif

129
indra/llcommon/llunits.h Normal file
View File

@@ -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

838
indra/llcommon/llunittype.h Normal file
View File

@@ -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<typename S, typename T>
struct LLIsSameType
{
static const bool value = false;
};
template<typename T>
struct LLIsSameType<T, T>
{
static const bool value = true;
};
// workaround for decltype() not existing and typeof() not working inline in gcc 4.2
template<typename S, typename T>
struct LLResultTypeAdd
{
typedef LL_TYPEOF(S() + T()) type_t;
};
template<typename S, typename T>
struct LLResultTypeSubtract
{
typedef LL_TYPEOF(S() - T()) type_t;
};
template<typename S, typename T>
struct LLResultTypeMultiply
{
typedef LL_TYPEOF(S() * T()) type_t;
};
template<typename S, typename T>
struct LLResultTypeDivide
{
typedef LL_TYPEOF(S() / T(1)) type_t;
};
template<typename S, typename T>
struct LLResultTypePromote
{
typedef LL_TYPEOF((true) ? S() : T()) type_t;
};
template<typename STORAGE_TYPE, typename UNITS>
struct LLUnit
{
typedef LLUnit<STORAGE_TYPE, UNITS> 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<typename FROM_STORAGE_TYPE>
LL_FORCE_INLINE static self_t convert(LLUnit<FROM_STORAGE_TYPE, UNITS> v)
{
self_t result;
result.mValue = (STORAGE_TYPE)v.value();
return result;
}
template<typename FROM_UNITS>
LL_FORCE_INLINE static self_t convert(LLUnit<STORAGE_TYPE, FROM_UNITS> v)
{
self_t result;
STORAGE_TYPE divisor = ll_convert_units(v, result);
result.mValue /= divisor;
return result;
}
template<typename FROM_STORAGE_TYPE, typename FROM_UNITS>
LL_FORCE_INLINE static self_t convert(LLUnit<FROM_STORAGE_TYPE, FROM_UNITS> v)
{
typedef typename LLResultTypePromote<FROM_STORAGE_TYPE, STORAGE_TYPE>::type_t result_storage_t;
LLUnit<result_storage_t, UNITS> 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<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE LLUnit(LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> 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<typename NEW_UNITS>
storage_t valueInUnits()
{
return LLUnit<storage_t, NEW_UNITS>(*this).value();
}
template<typename NEW_UNITS>
void valueInUnits(storage_t value)
{
*this = LLUnit<storage_t, NEW_UNITS>(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<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator == (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return mValue == convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator != (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return mValue != convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator < (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return mValue < convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator <= (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return mValue <= convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator > (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return mValue > convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator >= (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return mValue >= convert(other).value();
}
protected:
storage_t mValue;
};
template<typename STORAGE_TYPE, typename UNITS>
std::ostream& operator <<(std::ostream& s, const LLUnit<STORAGE_TYPE, UNITS>& unit)
{
s << unit.value() << UNITS::getUnitLabel();
return s;
}
template<typename STORAGE_TYPE, typename UNITS>
std::istream& operator >>(std::istream& s, LLUnit<STORAGE_TYPE, UNITS>& unit)
{
STORAGE_TYPE val;
s >> val;
unit.value(val);
return s;
}
template<typename STORAGE_TYPE, typename UNITS>
struct LLUnitImplicit : public LLUnit<STORAGE_TYPE, UNITS>
{
typedef LLUnitImplicit<STORAGE_TYPE, UNITS> self_t;
typedef typename LLUnit<STORAGE_TYPE, UNITS>::storage_t storage_t;
typedef LLUnit<STORAGE_TYPE, UNITS> base_t;
LL_FORCE_INLINE LLUnitImplicit(storage_t value = storage_t())
: base_t(value)
{}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE LLUnitImplicit(LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> 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<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE void operator += (LLUnitImplicit<OTHER_STORAGE_TYPE, OTHER_UNITS> 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<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE void operator -= (LLUnitImplicit<OTHER_STORAGE_TYPE, OTHER_UNITS> other)
{
base_t::mValue -= base_t::convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator == (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return base_t::mValue == base_t::convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator == (LLUnitImplicit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return base_t::mValue == base_t::convert(other).value();
}
template<typename STORAGE_T>
LL_FORCE_INLINE bool operator == (STORAGE_T other) const
{
return base_t::mValue == other;
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator != (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return base_t::mValue != convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator != (LLUnitImplicit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return base_t::mValue != base_t::convert(other).value();
}
template<typename STORAGE_T>
LL_FORCE_INLINE bool operator != (STORAGE_T other) const
{
return base_t::mValue != other;
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator < (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return base_t::mValue < base_t::convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator < (LLUnitImplicit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return base_t::mValue < base_t::convert(other).value();
}
template<typename STORAGE_T>
LL_FORCE_INLINE bool operator < (STORAGE_T other) const
{
return base_t::mValue < other;
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator <= (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return base_t::mValue <= base_t::convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator <= (LLUnitImplicit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return base_t::mValue <= base_t::convert(other).value();
}
template<typename STORAGE_T>
LL_FORCE_INLINE bool operator <= (STORAGE_T other) const
{
return base_t::mValue <= other;
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator > (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return base_t::mValue > base_t::convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator > (LLUnitImplicit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return base_t::mValue > base_t::convert(other).value();
}
template<typename STORAGE_T>
LL_FORCE_INLINE bool operator > (STORAGE_T other) const
{
return base_t::mValue > other;
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator >= (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return base_t::mValue >= base_t::convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator >= (LLUnitImplicit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
{
return base_t::mValue >= base_t::convert(other).value();
}
template<typename STORAGE_T>
LL_FORCE_INLINE bool operator >= (STORAGE_T other) const
{
return base_t::mValue >= other;
}
};
template<typename STORAGE_TYPE, typename UNITS>
std::ostream& operator <<(std::ostream& s, const LLUnitImplicit<STORAGE_TYPE, UNITS>& unit)
{
s << unit.value() << UNITS::getUnitLabel();
return s;
}
template<typename STORAGE_TYPE, typename UNITS>
std::istream& operator >>(std::istream& s, LLUnitImplicit<STORAGE_TYPE, UNITS>& unit)
{
STORAGE_TYPE val;
s >> val;
unit = val;
return s;
}
template<typename S1, typename T1, typename S2, typename T2>
LL_FORCE_INLINE S2 ll_convert_units(LLUnit<S1, T1> in, LLUnit<S2, T2>& out)
{
S2 divisor(1);
LL_STATIC_ASSERT((LLIsSameType<T1, T2>::value
|| !LLIsSameType<T1, typename T1::base_unit_t>::value
|| !LLIsSameType<T2, typename T2::base_unit_t>::value),
"conversion requires compatible units");
if (LLIsSameType<T1, T2>::value)
{
// T1 and T2 same type, just assign
out.value((S2)in.value());
}
else if (T1::sLevel > T2::sLevel)
{
// reduce T1
LLUnit<S2, typename T1::base_unit_t> new_in;
divisor *= (S2)ll_convert_units(in, new_in);
divisor *= (S2)ll_convert_units(new_in, out);
}
else
{
// reduce T2
LLUnit<S2, typename T2::base_unit_t> new_out;
divisor *= (S2)ll_convert_units(in, new_out);
divisor *= (S2)ll_convert_units(new_out, out);
}
return divisor;
}
template<typename T>
struct LLStorageType
{
typedef T type_t;
};
template<typename STORAGE_TYPE, typename UNITS>
struct LLStorageType<LLUnit<STORAGE_TYPE, UNITS> >
{
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<typename STORAGE_TYPE1, typename UNITS1, typename STORAGE_TYPE2, typename UNITS2>
LL_FORCE_INLINE LLUnit<typename LLResultTypeAdd<STORAGE_TYPE1, STORAGE_TYPE2>::type_t, UNITS1> operator + (LLUnit<STORAGE_TYPE1, UNITS1> first, LLUnit<STORAGE_TYPE2, UNITS2> second)
{
LLUnit<typename LLResultTypeAdd<STORAGE_TYPE1, STORAGE_TYPE2>::type_t, UNITS1> result(first);
result += second;
return result;
}
template<typename STORAGE_TYPE, typename UNITS, typename UNITLESS>
LLUnit<STORAGE_TYPE, UNITS> operator + (LLUnit<STORAGE_TYPE, UNITS> first, UNITLESS second)
{
LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE, "operator + requires compatible unit types");
return LLUnit<STORAGE_TYPE, UNITS>(0);
}
template<typename STORAGE_TYPE, typename UNITS, typename UNITLESS>
LLUnit<STORAGE_TYPE, UNITS> operator + (UNITLESS first, LLUnit<STORAGE_TYPE, UNITS> second)
{
LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE, "operator + requires compatible unit types");
return LLUnit<STORAGE_TYPE, UNITS>(0);
}
template<typename STORAGE_TYPE1, typename UNITS1, typename STORAGE_TYPE2, typename UNITS2>
LL_FORCE_INLINE LLUnitImplicit<typename LLResultTypeAdd<STORAGE_TYPE1, STORAGE_TYPE2>::type_t, UNITS1> operator + (LLUnitImplicit<STORAGE_TYPE1, UNITS1> first, LLUnitImplicit<STORAGE_TYPE2, UNITS2> second)
{
LLUnitImplicit<typename LLResultTypeAdd<STORAGE_TYPE1, STORAGE_TYPE2>::type_t, UNITS1> result(first);
result += second;
return result;
}
template<typename STORAGE_TYPE1, typename UNITS1, typename STORAGE_TYPE2, typename UNITS2>
LL_FORCE_INLINE LLUnitImplicit<typename LLResultTypeAdd<STORAGE_TYPE1, STORAGE_TYPE2>::type_t, UNITS1> operator + (LLUnit<STORAGE_TYPE1, UNITS1> first, LLUnitImplicit<STORAGE_TYPE2, UNITS2> second)
{
LLUnitImplicit<typename LLResultTypeAdd<STORAGE_TYPE1, STORAGE_TYPE2>::type_t, UNITS1> result(first);
result += second;
return result;
}
template<typename STORAGE_TYPE1, typename UNITS1, typename STORAGE_TYPE2, typename UNITS2>
LL_FORCE_INLINE LLUnitImplicit<typename LLResultTypeAdd<STORAGE_TYPE1, STORAGE_TYPE2>::type_t, UNITS1> operator + (LLUnitImplicit<STORAGE_TYPE1, UNITS1> first, LLUnit<STORAGE_TYPE2, UNITS2> second)
{
LLUnitImplicit<typename LLResultTypeAdd<STORAGE_TYPE1, STORAGE_TYPE2>::type_t, UNITS1> result(first);
result += LLUnitImplicit<STORAGE_TYPE1, UNITS1>(second);
return result;
}
template<typename STORAGE_TYPE, typename UNITS, typename UNITLESS_TYPE>
LL_FORCE_INLINE LLUnitImplicit<typename LLResultTypeAdd<STORAGE_TYPE, typename LLStorageType<UNITLESS_TYPE>::type_t>::type_t, UNITS> operator + (LLUnitImplicit<STORAGE_TYPE, UNITS> first, UNITLESS_TYPE second)
{
LLUnitImplicit<typename LLResultTypeAdd<STORAGE_TYPE, typename LLStorageType<UNITLESS_TYPE>::type_t>::type_t, UNITS> result(first);
result += second;
return result;
}
template<typename STORAGE_TYPE, typename UNITS, typename UNITLESS_TYPE>
LL_FORCE_INLINE LLUnitImplicit<typename LLResultTypeAdd<typename LLStorageType<UNITLESS_TYPE>::type_t, STORAGE_TYPE>::
type_t, UNITS> operator + (UNITLESS_TYPE first, LLUnitImplicit<STORAGE_TYPE, UNITS> second)
{
LLUnitImplicit<typename LLResultTypeAdd<typename LLStorageType<UNITLESS_TYPE>::type_t, STORAGE_TYPE>::type_t, UNITS> result(first);
result += second;
return result;
}
//
// operator -
//
template<typename STORAGE_TYPE1, typename UNITS1, typename STORAGE_TYPE2, typename UNITS2>
LL_FORCE_INLINE LLUnit<typename LLResultTypeSubtract<STORAGE_TYPE1, STORAGE_TYPE2>::type_t, UNITS1> operator - (LLUnit<STORAGE_TYPE1, UNITS1> first, LLUnit<STORAGE_TYPE2, UNITS2> second)
{
LLUnit<typename LLResultTypeSubtract<STORAGE_TYPE1, STORAGE_TYPE2>::type_t, UNITS1> result(first);
result -= second;
return result;
}
template<typename STORAGE_TYPE, typename UNITS, typename UNITLESS>
LLUnit<STORAGE_TYPE, UNITS> operator - (LLUnit<STORAGE_TYPE, UNITS> first, UNITLESS second)
{
LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE, "operator - requires compatible unit types");
return LLUnit<STORAGE_TYPE, UNITS>(0);
}
template<typename STORAGE_TYPE, typename UNITS, typename UNITLESS>
LLUnit<STORAGE_TYPE, UNITS> operator - (UNITLESS first, LLUnit<STORAGE_TYPE, UNITS> second)
{
LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE, "operator - requires compatible unit types");
return LLUnit<STORAGE_TYPE, UNITS>(0);
}
template<typename STORAGE_TYPE1, typename UNITS1, typename STORAGE_TYPE2, typename UNITS2>
LL_FORCE_INLINE LLUnitImplicit<typename LLResultTypeSubtract<STORAGE_TYPE1, STORAGE_TYPE2>::type_t, UNITS1> operator - (LLUnitImplicit<STORAGE_TYPE1, UNITS1> first, LLUnitImplicit<STORAGE_TYPE2, UNITS2> second)
{
LLUnitImplicit<typename LLResultTypeSubtract<STORAGE_TYPE1, STORAGE_TYPE2>::type_t, UNITS1> result(first);
result -= second;
return result;
}
template<typename STORAGE_TYPE1, typename UNITS1, typename STORAGE_TYPE2, typename UNITS2>
LL_FORCE_INLINE LLUnitImplicit<typename LLResultTypeSubtract<STORAGE_TYPE1, STORAGE_TYPE2>::type_t, UNITS1> operator - (LLUnit<STORAGE_TYPE1, UNITS1> first, LLUnitImplicit<STORAGE_TYPE2, UNITS2> second)
{
LLUnitImplicit<typename LLResultTypeSubtract<STORAGE_TYPE1, STORAGE_TYPE2>::type_t, UNITS1> result(first);
result -= second;
return result;
}
template<typename STORAGE_TYPE1, typename UNITS1, typename STORAGE_TYPE2, typename UNITS2>
LL_FORCE_INLINE LLUnitImplicit<typename LLResultTypeSubtract<STORAGE_TYPE1, STORAGE_TYPE2>::type_t, UNITS1> operator - (LLUnitImplicit<STORAGE_TYPE1, UNITS1> first, LLUnit<STORAGE_TYPE2, UNITS2> second)
{
LLUnitImplicit<typename LLResultTypeSubtract<STORAGE_TYPE1, STORAGE_TYPE2>::type_t, UNITS1> result(first);
result -= LLUnitImplicit<STORAGE_TYPE1, UNITS1>(second);
return result;
}
template<typename STORAGE_TYPE, typename UNITS, typename UNITLESS_TYPE>
LL_FORCE_INLINE LLUnitImplicit<typename LLResultTypeSubtract<STORAGE_TYPE, typename LLStorageType<UNITLESS_TYPE>::type_t>::type_t, UNITS> operator - (LLUnitImplicit<STORAGE_TYPE, UNITS> first, UNITLESS_TYPE second)
{
LLUnitImplicit<typename LLResultTypeSubtract<STORAGE_TYPE, typename LLStorageType<UNITLESS_TYPE>::type_t>::type_t, UNITS> result(first);
result -= second;
return result;
}
template<typename STORAGE_TYPE, typename UNITS, typename UNITLESS_TYPE>
LL_FORCE_INLINE LLUnitImplicit<typename LLResultTypeSubtract<typename LLStorageType<UNITLESS_TYPE>::type_t, STORAGE_TYPE>::type_t, UNITS> operator - (UNITLESS_TYPE first, LLUnitImplicit<STORAGE_TYPE, UNITS> second)
{
LLUnitImplicit<typename LLResultTypeSubtract<typename LLStorageType<UNITLESS_TYPE>::type_t, STORAGE_TYPE>::type_t, UNITS> result(first);
result -= second;
return result;
}
//
// operator *
//
template<typename STORAGE_TYPE1, typename UNITS1, typename STORAGE_TYPE2, typename UNITS2>
LLUnit<STORAGE_TYPE1, UNITS1> operator * (LLUnit<STORAGE_TYPE1, UNITS1>, LLUnit<STORAGE_TYPE2, UNITS2>)
{
// 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<STORAGE_TYPE1, UNITS1>();
}
template<typename STORAGE_TYPE, typename UNITS, typename UNITLESS_TYPE>
LL_FORCE_INLINE LLUnit<typename LLResultTypeMultiply<STORAGE_TYPE, typename LLStorageType<UNITLESS_TYPE>::type_t>::type_t, UNITS> operator * (LLUnit<STORAGE_TYPE, UNITS> first, UNITLESS_TYPE second)
{
return LLUnit<typename LLResultTypeMultiply<STORAGE_TYPE, typename LLStorageType<UNITLESS_TYPE>::type_t>::type_t, UNITS>(first.value() * second);
}
template<typename STORAGE_TYPE, typename UNITS, typename UNITLESS_TYPE>
LL_FORCE_INLINE LLUnit<typename LLResultTypeMultiply<typename LLStorageType<UNITLESS_TYPE>::type_t, STORAGE_TYPE>::type_t, UNITS> operator * (UNITLESS_TYPE first, LLUnit<STORAGE_TYPE, UNITS> second)
{
return LLUnit<typename LLResultTypeMultiply<typename LLStorageType<UNITLESS_TYPE>::type_t, STORAGE_TYPE>::type_t, UNITS>(first * second.value());
}
template<typename STORAGE_TYPE1, typename UNITS1, typename STORAGE_TYPE2, typename UNITS2>
LLUnitImplicit<STORAGE_TYPE1, UNITS1> operator * (LLUnitImplicit<STORAGE_TYPE1, UNITS1>, LLUnitImplicit<STORAGE_TYPE2, UNITS2>)
{
// 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<STORAGE_TYPE1, UNITS1>();
}
template<typename STORAGE_TYPE, typename UNITS, typename UNITLESS_TYPE>
LL_FORCE_INLINE LLUnitImplicit<typename LLResultTypeMultiply<STORAGE_TYPE, typename LLStorageType<UNITLESS_TYPE>::type_t>::type_t, UNITS> operator * (LLUnitImplicit<STORAGE_TYPE, UNITS> first, UNITLESS_TYPE second)
{
return LLUnitImplicit<typename LLResultTypeMultiply<STORAGE_TYPE, UNITLESS_TYPE>::type_t, UNITS>(first.value() * second);
}
template<typename STORAGE_TYPE, typename UNITS, typename UNITLESS_TYPE>
LL_FORCE_INLINE LLUnitImplicit<typename LLResultTypeMultiply<typename LLStorageType<UNITLESS_TYPE>::type_t, STORAGE_TYPE>::type_t, UNITS> operator * (UNITLESS_TYPE first, LLUnitImplicit<STORAGE_TYPE, UNITS> second)
{
return LLUnitImplicit<typename LLResultTypeMultiply<typename LLStorageType<UNITLESS_TYPE>::type_t, STORAGE_TYPE>::type_t, UNITS>(first * second.value());
}
//
// operator /
//
template<typename STORAGE_TYPE, typename UNITS, typename UNITLESS_TYPE>
LL_FORCE_INLINE LLUnit<typename LLResultTypeDivide<STORAGE_TYPE, typename LLStorageType<UNITLESS_TYPE>::type_t>::type_t, UNITS> operator / (LLUnit<STORAGE_TYPE, UNITS> first, UNITLESS_TYPE second)
{
return LLUnit<typename LLResultTypeDivide<STORAGE_TYPE, typename LLStorageType<UNITLESS_TYPE>::type_t>::type_t, UNITS>(first.value() / second);
}
template<typename STORAGE_TYPE1, typename UNITS1, typename STORAGE_TYPE2, typename UNITS2>
LL_FORCE_INLINE typename LLResultTypeDivide<STORAGE_TYPE1, STORAGE_TYPE2>::type_t operator / (LLUnit<STORAGE_TYPE1, UNITS1> first, LLUnit<STORAGE_TYPE2, UNITS2> second)
{
return first.value() / first.convert(second).value();
}
template<typename STORAGE_TYPE, typename UNITS, typename UNITLESS_TYPE>
LL_FORCE_INLINE LLUnitImplicit<typename LLResultTypeDivide<STORAGE_TYPE, typename LLStorageType<UNITLESS_TYPE>::type_t>::type_t, UNITS> operator / (LLUnitImplicit<STORAGE_TYPE, UNITS> first, UNITLESS_TYPE second)
{
return LLUnitImplicit<typename LLResultTypeDivide<STORAGE_TYPE, typename LLStorageType<UNITLESS_TYPE>::type_t>::type_t, UNITS>(first.value() / second);
}
template<typename STORAGE_TYPE1, typename UNITS1, typename STORAGE_TYPE2, typename UNITS2>
LL_FORCE_INLINE typename LLResultTypeDivide<STORAGE_TYPE1, STORAGE_TYPE2>::type_t operator / (LLUnitImplicit<STORAGE_TYPE1, UNITS1> first, LLUnitImplicit<STORAGE_TYPE2, UNITS2> second)
{
return (typename LLResultTypeDivide<STORAGE_TYPE1, STORAGE_TYPE2>::type_t)(first.value() / first.convert(second).value());
}
template<typename STORAGE_TYPE1, typename UNITS1, typename STORAGE_TYPE2, typename UNITS2>
LL_FORCE_INLINE typename LLResultTypeDivide<STORAGE_TYPE1, STORAGE_TYPE2>::type_t operator / (LLUnit<STORAGE_TYPE1, UNITS1> first, LLUnitImplicit<STORAGE_TYPE2, UNITS2> second)
{
return (typename LLResultTypeDivide<STORAGE_TYPE1, STORAGE_TYPE2>::type_t)(first.value() / first.convert(second).value());
}
template<typename STORAGE_TYPE1, typename UNITS1, typename STORAGE_TYPE2, typename UNITS2>
LL_FORCE_INLINE typename LLResultTypeDivide<STORAGE_TYPE1, STORAGE_TYPE2>::type_t operator / (LLUnitImplicit<STORAGE_TYPE1, UNITS1> first, LLUnit<STORAGE_TYPE2, UNITS2> second)
{
return (typename LLResultTypeDivide<STORAGE_TYPE1, STORAGE_TYPE2>::type_t)(first.value() / first.convert(second).value());
}
template<typename T>
struct LLGetUnitLabel
{
static const char* getUnitLabel() { return ""; }
};
template<typename T, typename STORAGE_T>
struct LLGetUnitLabel<LLUnit<STORAGE_T, T> >
{
static const char* getUnitLabel() { return T::getUnitLabel(); }
};
template<typename T>
struct LLUnitLinearOps
{
typedef LLUnitLinearOps<T> self_t;
LLUnitLinearOps(T val)
: mValue(val),
mDivisor(1)
{}
template<typename OTHER_T>
self_t operator * (OTHER_T other)
{
return mValue * other;
}
template<typename OTHER_T>
self_t operator / (OTHER_T other)
{
mDivisor *= other;
return *this;
}
template<typename OTHER_T>
self_t operator + (OTHER_T other)
{
mValue += other * mDivisor;
return *this;
}
template<typename OTHER_T>
self_t operator - (OTHER_T other)
{
mValue -= other * mDivisor;
return *this;
}
T mValue;
T mDivisor;
};
template<typename T>
struct LLUnitInverseLinearOps
{
typedef LLUnitInverseLinearOps<T> self_t;
LLUnitInverseLinearOps(T val)
: mValue(val),
mDivisor(1),
mMultiplicand(1)
{}
template<typename OTHER_T>
self_t operator * (OTHER_T other)
{
mDivisor *= other;
return *this;
}
template<typename OTHER_T>
self_t operator / (OTHER_T other)
{
mValue *= other;
mMultiplicand *= other;
return *this;
}
template<typename OTHER_T>
self_t operator + (OTHER_T other)
{
mValue -= other * mMultiplicand;
return *this;
}
template<typename OTHER_T>
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<typename T> \
static LLUnit<T, base_unit_name> fromValue(T value) { return LLUnit<T, base_unit_name>(value); } \
template<typename STORAGE_T, typename UNIT_T> \
static LLUnit<STORAGE_T, base_unit_name> fromValue(LLUnit<STORAGE_T, UNIT_T> value) \
{ return LLUnit<STORAGE_T, base_unit_name>(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<typename T> \
static LLUnit<T, unit_name> fromValue(T value) { return LLUnit<T, unit_name>(value); } \
template<typename STORAGE_T, typename UNIT_T> \
static LLUnit<STORAGE_T, unit_name> fromValue(LLUnit<STORAGE_T, UNIT_T> value) \
{ return LLUnit<STORAGE_T, unit_name>(value); } \
}; \
\
template<typename S1, typename S2> \
LL_FORCE_INLINE S2 ll_convert_units(LLUnit<S1, unit_name> in, LLUnit<S2, base_unit_name>& out) \
{ \
typedef typename LLResultTypePromote<S1, S2>::type_t result_storage_t; \
LLUnitInverseLinearOps<result_storage_t> result = \
LLUnitInverseLinearOps<result_storage_t>(in.value()) conversion_operation; \
out = LLUnit<S2, base_unit_name>((S2)result.mValue); \
return result.mDivisor; \
} \
\
template<typename S1, typename S2> \
LL_FORCE_INLINE S2 ll_convert_units(LLUnit<S1, base_unit_name> in, LLUnit<S2, unit_name>& out) \
{ \
typedef typename LLResultTypePromote<S1, S2>::type_t result_storage_t; \
LLUnitLinearOps<result_storage_t> result = \
LLUnitLinearOps<result_storage_t>(in.value()) conversion_operation; \
out = LLUnit<S2, unit_name>((S2)result.mValue); \
return result.mDivisor; \
}
#define LL_DECLARE_UNIT_TYPEDEFS(ns, unit_name) \
typedef LLUnit<F32, ns::unit_name> F32##unit_name; \
typedef LLUnitImplicit<F32, ns::unit_name> F32##unit_name##Implicit;\
typedef LLUnit<F64, ns::unit_name> F64##unit_name; \
typedef LLUnitImplicit<F64, ns::unit_name> F64##unit_name##Implicit;\
typedef LLUnit<S32, ns::unit_name> S32##unit_name; \
typedef LLUnitImplicit<S32, ns::unit_name> S32##unit_name##Implicit;\
typedef LLUnit<S64, ns::unit_name> S64##unit_name; \
typedef LLUnitImplicit<S64, ns::unit_name> S64##unit_name##Implicit;\
typedef LLUnit<U32, ns::unit_name> U32##unit_name; \
typedef LLUnitImplicit<U32, ns::unit_name> U32##unit_name##Implicit;\
typedef LLUnit<U64, ns::unit_name> U64##unit_name; \
typedef LLUnitImplicit<U64, ns::unit_name> U64##unit_name##Implicit
#endif //LL_UNITTYPE_H

View File

@@ -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 <winsock2.h>
#include <windows.h>
#include "llwin32headers.h"
#endif
#include "lldefs.h"

View File

@@ -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 <winsock2.h>
#include <windows.h>
// reset to default, which is lean
#define WIN32_LEAN_AND_MEAN
#undef NOMINMAX
#endif
#endif

View File

@@ -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 <winsock2.h>
#include <windows.h>
#undef NOMINMAX
#endif
#endif

View File

@@ -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
{

View File

@@ -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);
//<singu>
}
@@ -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);

View File

@@ -298,7 +298,7 @@ LLTexUnit::eTextureAddressMode LLGLTexture::getAddressMode(void) const
return mGLTexturep->getAddressMode() ;
}
S32 LLGLTexture::getTextureMemory() const
S32Bytes LLGLTexture::getTextureMemory() const
{
llassert(mGLTexturep.notNull()) ;

View File

@@ -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 ;

View File

@@ -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> LLImageGL::sHighlightTexturep = NULL;
S32 LLImageGL::sMaxCategories = 1 ;
std::vector<S32> LLImageGL::sTextureMemByCategory;
std::vector<S32> LLImageGL::sTextureMemByCategoryBound ;
std::vector<S32> LLImageGL::sTextureCurMemByCategoryBound ;
std::vector<S32Bytes> LLImageGL::sTextureMemByCategory;
std::vector<S32Bytes> LLImageGL::sTextureMemByCategoryBound ;
std::vector<S32Bytes> 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)

View File

@@ -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<S32> sTextureMemByCategory;
static std::vector<S32> sTextureMemByCategoryBound ;
static std::vector<S32> sTextureCurMemByCategoryBound ;
static std::vector<S32Bytes> sTextureMemByCategory;
static std::vector<S32Bytes> sTextureMemByCategoryBound ;
static std::vector<S32Bytes> sTextureCurMemByCategoryBound ;
//----------------------------------------
// ****************************************************************************************************
//End of definitions for texture auditing use only

View File

@@ -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();

View File

@@ -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),

View File

@@ -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<LLUnits::Kilobytes>());
gDebugInfo["OSInfo"] = getOSInfo().getOSStringSimple();
// The user is not logged on yet, but record the current grid choice login url

View File

@@ -333,7 +333,7 @@ extern BOOL gUseWireframe;
extern LLVFS *gStaticVFS;
extern LLMemoryInfo gSysMemory;
extern U64 gMemoryAllocated;
extern U64Bytes gMemoryAllocated;
extern std::string gLastVersionChannel;

View File

@@ -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");
}

View File

@@ -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 );

View File

@@ -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<LLUICtrl>("GrapicsCardTextureMemory")->setMinValue(LLViewerTextureList::getMinVideoRamSetting());
getChild<LLUICtrl>("GrapicsCardTextureMemory")->setMaxValue(LLViewerTextureList::getMaxVideoRamSetting());
getChild<LLUICtrl>("GrapicsCardTextureMemory")->setMinValue(min_tex_mem.value());
getChild<LLUICtrl>("GrapicsCardTextureMemory")->setMaxValue(max_tex_mem.value());
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") ||
!gGLManager.mHasVertexBufferObject)

View File

@@ -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)

View File

@@ -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<LLUUID,S32> size_map_t;
size_map_t mTexturesSizeMap;
S64 mTexturesSizeTotal;
LLAtomic32<BOOL> mDoPurge;
LLAtomic32<bool> mDoPurge;
typedef std::map<S32, Entry> idx_entry_map_t;
idx_entry_map_t mUpdatedEntryMap;

View File

@@ -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)
{

View File

@@ -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,17 +564,17 @@ 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);
F32 cache_usage = LLAppViewer::getTextureCache()->getUsage().valueInUnits<LLUnits::Megabytes>();
F32 cache_max_usage = LLAppViewer::getTextureCache()->getMaxUsage().valueInUnits<LLUnits::Megabytes>();
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;
@@ -588,10 +588,10 @@ void LLGLTexMemBar::draw()
global_raw_memory = *AIAccess<S32>(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 ;

View File

@@ -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;
}

View File

@@ -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() <<LL_ENDL;
LLMemory::logMemoryInfo(TRUE) ;

View File

@@ -2809,7 +2809,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
LLSD args;
args["SUBJECT"] = subj;
args["MESSAGE"] = mes;
LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).timestamp(timestamp));
LLDate notice_date = LLDate(timestamp).notNull() ? LLDate(timestamp) : LLDate::now();
LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).timestamp(notice_date));
}
// Also send down the old path for now.
@@ -5162,18 +5163,18 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
// *TODO: Remove this dependency, or figure out a better way to handle
// this hack.
extern U32 gObjectBits;
extern U32Bits gObjectData;
void process_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...
@@ -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);

View File

@@ -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<LLUnits::Kilobits>());
stats.mObjectKBitStat.addValue(gObjectData.valueInUnits<LLUnits::Kilobits>());
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<LLUnits::Kilobits>());
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()

View File

@@ -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

View File

@@ -63,6 +63,11 @@
#include "lltexturecache.h"
///////////////////////////////////////////////////////////////////////////////
// extern
const S32Megabytes gMinVideoRam(32);
const S32Megabytes gMaxVideoRam(1024);
// statics
LLPointer<LLViewerTexture> LLViewerTexture::sNullImagep = NULL;
LLPointer<LLViewerTexture> LLViewerTexture::sBlackImagep = NULL;
@@ -83,11 +88,11 @@ 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 ;
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
@@ -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_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,10 +3721,10 @@ 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;
@@ -3729,17 +3734,17 @@ void LLTexturePipelineTester::outputTestRecord(LLSD *sd)
(*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]["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() ;
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;
}
@@ -3747,7 +3752,7 @@ void LLTexturePipelineTester::updateTextureBindingStats(const LLViewerTexture* i
void LLTexturePipelineTester::updateTextureLoadingStats(const LLViewerFetchedTexture* imagep, const LLImageRaw* raw_imagep, BOOL from_cache)
{
U32 data_size = (U32)raw_imagep->getDataSize() ;
U32Bytes data_size = (U32Bytes)raw_imagep->getDataSize();
mTotalBytesLoaded += data_size;
if(from_cache)
@@ -3755,7 +3760,7 @@ void LLTexturePipelineTester::updateTextureLoadingStats(const LLViewerFetchedTex
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;
}

View File

@@ -41,8 +41,9 @@
#include <map>
#include <list>
#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 ;

View File

@@ -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<LLUnits::Megabytes>());
LLViewerStats::getInstance()->mGLBoundMemStat.addValue((F32)LLImageGL::sBoundTextureMemory.valueInUnits<LLUnits::Megabytes>());
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<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImage
}
// Returns min setting for TextureMemory (in MB)
S32 LLViewerTextureList::getMinVideoRamSetting()
S32Megabytes LLViewerTextureList::getMinVideoRamSetting()
{
S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped());
if (system_ram > 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.

View File

@@ -71,7 +71,6 @@ public:
static BOOL verifyUploadFile(const std::string& out_filename, const U8 codec);
static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> 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:

View File

@@ -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;
}
}

View File

@@ -5169,9 +5169,9 @@ std::string LLVOAvatar::bakedTextureOriginInfo()
return result;
}
S32 LLVOAvatar::totalTextureMemForUUIDS(std::set<LLUUID>& ids)
S32Bytes LLVOAvatar::totalTextureMemForUUIDS(std::set<LLUUID>& ids)
{
S32 result = 0;
S32Bytes result(0);
for (std::set<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
{
LLViewerFetchedTexture *imagep = gTextureList.findImage(*it);
@@ -5236,12 +5236,12 @@ void LLVOAvatar::collectTextureUUIDs(std::set<LLUUID>& 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<LLUUID> 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<LLUUID> local_texture_ids;
collectLocalTextureUUIDs(local_texture_ids);
@@ -5250,7 +5250,7 @@ void LLVOAvatar::releaseOldTextures()
std::set<LLUUID> 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;

View File

@@ -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<LLUUID>& ids);
S32Bytes totalTextureMemForUUIDS(std::set<LLUUID>& ids);
bool allTexturesCompletelyDownloaded(std::set<LLUUID>& ids) const;
bool allLocalTexturesCompletelyDownloaded() const;
bool allBakedTexturesCompletelyDownloaded() const;

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*)));
sBumpFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*)));
sSimpleFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*)));
sNormFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*)));
sSpecFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*)));
sNormSpecFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*)));
sAlphaFaces = static_cast<LLFace**>(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)
@@ -4428,16 +4494,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
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;
U32 simple_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)
{

View File

@@ -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;