merge QAR-1829: texture pipeline branch in viewer-2.0.0.3
parent
2f2bdd83d6
commit
35e200881c
|
|
@ -251,10 +251,13 @@ BOOL LLHeadRotMotion::onUpdate(F32 time, U8* joint_mask)
|
|||
mLastHeadRot = head_rot_local;
|
||||
|
||||
// Set the head rotation.
|
||||
LLQuaternion torsoRotLocal = mNeckState->getJoint()->getParent()->getWorldRotation() * currentInvRootRotWorld;
|
||||
head_rot_local = head_rot_local * ~torsoRotLocal;
|
||||
mNeckState->setRotation( nlerp(NECK_LAG, LLQuaternion::DEFAULT, head_rot_local) );
|
||||
mHeadState->setRotation( nlerp(1.f - NECK_LAG, LLQuaternion::DEFAULT, head_rot_local));
|
||||
if(mNeckState->getJoint() && mNeckState->getJoint()->getParent())
|
||||
{
|
||||
LLQuaternion torsoRotLocal = mNeckState->getJoint()->getParent()->getWorldRotation() * currentInvRootRotWorld;
|
||||
head_rot_local = head_rot_local * ~torsoRotLocal;
|
||||
mNeckState->setRotation( nlerp(NECK_LAG, LLQuaternion::DEFAULT, head_rot_local) );
|
||||
mHeadState->setRotation( nlerp(1.f - NECK_LAG, LLQuaternion::DEFAULT, head_rot_local));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ void ll_init_apr()
|
|||
|
||||
if(!LLAPRFile::sAPRFilePoolp)
|
||||
{
|
||||
LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool() ;
|
||||
LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -99,13 +99,12 @@ void ll_cleanup_apr()
|
|||
//
|
||||
//LLAPRPool
|
||||
//
|
||||
LLAPRPool::LLAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag)
|
||||
{
|
||||
mParent = parent ;
|
||||
mReleasePoolFlag = releasePoolFlag ;
|
||||
mMaxSize = size ;
|
||||
mPool = NULL ;
|
||||
|
||||
LLAPRPool::LLAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag)
|
||||
: mParent(parent),
|
||||
mReleasePoolFlag(releasePoolFlag),
|
||||
mMaxSize(size),
|
||||
mPool(NULL)
|
||||
{
|
||||
createAPRPool() ;
|
||||
}
|
||||
|
||||
|
|
@ -148,31 +147,65 @@ void LLAPRPool::releaseAPRPool()
|
|||
}
|
||||
}
|
||||
|
||||
//virtual
|
||||
apr_pool_t* LLAPRPool::getAPRPool()
|
||||
{
|
||||
return mPool ;
|
||||
}
|
||||
|
||||
LLVolatileAPRPool::LLVolatileAPRPool(BOOL is_local, apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag)
|
||||
: LLAPRPool(parent, size, releasePoolFlag),
|
||||
mNumActiveRef(0),
|
||||
mNumTotalRef(0),
|
||||
mMutexPool(NULL),
|
||||
mMutexp(NULL)
|
||||
{
|
||||
//create mutex
|
||||
if(!is_local) //not a local apr_pool, that is: shared by multiple threads.
|
||||
{
|
||||
apr_pool_create(&mMutexPool, NULL); // Create a pool for mutex
|
||||
apr_thread_mutex_create(&mMutexp, APR_THREAD_MUTEX_UNNESTED, mMutexPool);
|
||||
}
|
||||
}
|
||||
|
||||
LLVolatileAPRPool::~LLVolatileAPRPool()
|
||||
{
|
||||
//delete mutex
|
||||
if(mMutexp)
|
||||
{
|
||||
apr_thread_mutex_destroy(mMutexp);
|
||||
apr_pool_destroy(mMutexPool);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//define this virtual function to avoid any mistakenly calling LLAPRPool::getAPRPool().
|
||||
//
|
||||
//virtual
|
||||
apr_pool_t* LLVolatileAPRPool::getAPRPool()
|
||||
{
|
||||
return LLVolatileAPRPool::getVolatileAPRPool() ;
|
||||
}
|
||||
|
||||
apr_pool_t* LLVolatileAPRPool::getVolatileAPRPool()
|
||||
{
|
||||
LLScopedLock lock(mMutexp) ;
|
||||
|
||||
mNumTotalRef++ ;
|
||||
mNumActiveRef++ ;
|
||||
|
||||
if(!mPool)
|
||||
{
|
||||
createAPRPool() ;
|
||||
}
|
||||
|
||||
return mPool ;
|
||||
}
|
||||
LLVolatileAPRPool::LLVolatileAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag)
|
||||
: LLAPRPool(parent, size, releasePoolFlag)
|
||||
{
|
||||
mNumActiveRef = 0 ;
|
||||
mNumTotalRef = 0 ;
|
||||
}
|
||||
|
||||
apr_pool_t* LLVolatileAPRPool::getVolatileAPRPool()
|
||||
{
|
||||
mNumTotalRef++ ;
|
||||
mNumActiveRef++ ;
|
||||
return getAPRPool() ;
|
||||
return mPool ;
|
||||
}
|
||||
|
||||
void LLVolatileAPRPool::clearVolatileAPRPool()
|
||||
{
|
||||
LLScopedLock lock(mMutexp) ;
|
||||
|
||||
if(mNumActiveRef > 0)
|
||||
{
|
||||
mNumActiveRef--;
|
||||
|
|
@ -251,10 +284,9 @@ void LLScopedLock::unlock()
|
|||
bool ll_apr_warn_status(apr_status_t status)
|
||||
{
|
||||
if(APR_SUCCESS == status) return false;
|
||||
#ifndef LL_WINDOWS
|
||||
char buf[MAX_STRING]; /* Flawfinder: ignore */
|
||||
LL_WARNS_ONCE("APR") << "APR: " << apr_strerror(status, buf, MAX_STRING) << LL_ENDL;
|
||||
#endif
|
||||
apr_strerror(status, buf, MAX_STRING);
|
||||
LL_WARNS("APR") << "APR: " << buf << LL_ENDL;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -268,10 +300,18 @@ void ll_apr_assert_status(apr_status_t status)
|
|||
// LLAPRFile functions
|
||||
//
|
||||
LLAPRFile::LLAPRFile()
|
||||
: mFile(NULL),
|
||||
mCurrentFilePoolp(NULL)
|
||||
{
|
||||
mFile = NULL ;
|
||||
mCurrentFilePoolp = NULL ;
|
||||
}
|
||||
|
||||
LLAPRFile::LLAPRFile(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool)
|
||||
: mFile(NULL),
|
||||
mCurrentFilePoolp(NULL)
|
||||
{
|
||||
open(filename, flags, pool);
|
||||
}
|
||||
|
||||
LLAPRFile::~LLAPRFile()
|
||||
{
|
||||
close() ;
|
||||
|
|
@ -295,11 +335,40 @@ apr_status_t LLAPRFile::close()
|
|||
return ret ;
|
||||
}
|
||||
|
||||
apr_status_t LLAPRFile::open(LLVolatileAPRPool* pool, const std::string& filename, apr_int32_t flags, S32* sizep)
|
||||
apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool, S32* sizep)
|
||||
{
|
||||
apr_status_t s ;
|
||||
s = open(filename, flags, pool ? pool->getVolatileAPRPool() : NULL, sizep) ;
|
||||
|
||||
//check if already open some file
|
||||
llassert_always(!mFile) ;
|
||||
llassert_always(!mCurrentFilePoolp) ;
|
||||
|
||||
apr_pool_t* apr_pool = pool ? pool->getVolatileAPRPool() : NULL ;
|
||||
s = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, getAPRFilePool(apr_pool));
|
||||
|
||||
if (s != APR_SUCCESS || !mFile)
|
||||
{
|
||||
mFile = NULL ;
|
||||
|
||||
if (sizep)
|
||||
{
|
||||
*sizep = 0;
|
||||
}
|
||||
}
|
||||
else if (sizep)
|
||||
{
|
||||
S32 file_size = 0;
|
||||
apr_off_t offset = 0;
|
||||
if (apr_file_seek(mFile, APR_END, &offset) == APR_SUCCESS)
|
||||
{
|
||||
llassert_always(offset <= 0x7fffffff);
|
||||
file_size = (S32)offset;
|
||||
offset = 0;
|
||||
apr_file_seek(mFile, APR_SET, &offset);
|
||||
}
|
||||
*sizep = file_size;
|
||||
}
|
||||
|
||||
if(!mCurrentFilePoolp)
|
||||
{
|
||||
mCurrentFilePoolp = pool ;
|
||||
|
|
@ -312,40 +381,25 @@ apr_status_t LLAPRFile::open(LLVolatileAPRPool* pool, const std::string& filenam
|
|||
|
||||
return s ;
|
||||
}
|
||||
apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, apr_pool_t* pool, S32* sizep)
|
||||
|
||||
//use gAPRPoolp.
|
||||
apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, BOOL use_global_pool)
|
||||
{
|
||||
apr_status_t s;
|
||||
|
||||
//check if already open some file
|
||||
llassert_always(!mFile) ;
|
||||
llassert_always(!mCurrentFilePoolp) ;
|
||||
llassert_always(use_global_pool) ; //be aware of using gAPRPoolp.
|
||||
|
||||
s = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, getAPRFilePool(pool));
|
||||
s = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, gAPRPoolp);
|
||||
if (s != APR_SUCCESS || !mFile)
|
||||
{
|
||||
mFile = NULL ;
|
||||
close() ;
|
||||
if (sizep)
|
||||
{
|
||||
*sizep = 0;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
if (sizep)
|
||||
{
|
||||
S32 file_size = 0;
|
||||
apr_off_t offset = 0;
|
||||
if (apr_file_seek(mFile, APR_END, &offset) == APR_SUCCESS)
|
||||
{
|
||||
llassert_always(offset <= 0x7fffffff);
|
||||
file_size = (S32)offset;
|
||||
offset = 0;
|
||||
apr_file_seek(mFile, APR_SET, &offset);
|
||||
}
|
||||
*sizep = file_size;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
@ -369,6 +423,7 @@ S32 LLAPRFile::read(void *buf, S32 nbytes)
|
|||
apr_status_t s = apr_file_read(mFile, buf, &sz);
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
ll_apr_warn_status(s);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
|
|
@ -386,6 +441,7 @@ S32 LLAPRFile::write(const void *buf, S32 nbytes)
|
|||
apr_status_t s = apr_file_write(mFile, buf, &sz);
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
ll_apr_warn_status(s);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
|
|
@ -434,6 +490,8 @@ apr_file_t* LLAPRFile::open(const std::string& filename, LLVolatileAPRPool* pool
|
|||
s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool->getVolatileAPRPool());
|
||||
if (s != APR_SUCCESS || !file_handle)
|
||||
{
|
||||
ll_apr_warn_status(s);
|
||||
LL_WARNS("APR") << " Attempting to open filename: " << filename << LL_ENDL;
|
||||
file_handle = NULL ;
|
||||
close(file_handle, pool) ;
|
||||
return NULL;
|
||||
|
|
@ -464,6 +522,7 @@ S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset)
|
|||
}
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
ll_apr_warn_status(s);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
|
|
@ -501,6 +560,8 @@ S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nb
|
|||
apr_status_t s = apr_file_read(file_handle, buf, &bytes_read);
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
LL_WARNS("APR") << " Attempting to read filename: " << filename << LL_ENDL;
|
||||
ll_apr_warn_status(s);
|
||||
bytes_read = 0;
|
||||
}
|
||||
else
|
||||
|
|
@ -549,6 +610,8 @@ S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 n
|
|||
apr_status_t s = apr_file_write(file_handle, buf, &bytes_written);
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
LL_WARNS("APR") << " Attempting to write filename: " << filename << LL_ENDL;
|
||||
ll_apr_warn_status(s);
|
||||
bytes_written = 0;
|
||||
}
|
||||
else
|
||||
|
|
@ -575,8 +638,8 @@ bool LLAPRFile::remove(const std::string& filename, LLVolatileAPRPool* pool)
|
|||
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
LL_DEBUGS("APR") << "LLAPRFile::remove failed on file: " << filename << LL_ENDL;
|
||||
ll_apr_warn_status(s);
|
||||
LL_WARNS("APR") << " Attempting to remove filename: " << filename << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -593,8 +656,8 @@ bool LLAPRFile::rename(const std::string& filename, const std::string& newname,
|
|||
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
LL_DEBUGS("APR") << "LLAPRFile::rename failed on file: " << filename << LL_ENDL;
|
||||
ll_apr_warn_status(s);
|
||||
LL_WARNS("APR") << " Attempting to rename filename: " << filename << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -667,8 +730,8 @@ bool LLAPRFile::makeDir(const std::string& dirname, LLVolatileAPRPool* pool)
|
|||
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
LL_DEBUGS("APR") << "LLAPRFile::makeDir failed on file: " << dirname << LL_ENDL;
|
||||
ll_apr_warn_status(s);
|
||||
LL_WARNS("APR") << " Attempting to make directory: " << dirname << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -685,8 +748,8 @@ bool LLAPRFile::removeDir(const std::string& dirname, LLVolatileAPRPool* pool)
|
|||
|
||||
if (s != APR_SUCCESS)
|
||||
{
|
||||
LL_DEBUGS("APR") << "LLAPRFile::removeDir failed on file: " << dirname << LL_ENDL;
|
||||
ll_apr_warn_status(s);
|
||||
LL_WARNS("APR") << " Attempting to remove directory: " << dirname << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -70,9 +70,9 @@ class LLAPRPool
|
|||
{
|
||||
public:
|
||||
LLAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE) ;
|
||||
~LLAPRPool() ;
|
||||
virtual ~LLAPRPool() ;
|
||||
|
||||
apr_pool_t* getAPRPool() ;
|
||||
virtual apr_pool_t* getAPRPool() ;
|
||||
apr_status_t getStatus() {return mStatus ; }
|
||||
|
||||
protected:
|
||||
|
|
@ -95,18 +95,21 @@ protected:
|
|||
class LLVolatileAPRPool : public LLAPRPool
|
||||
{
|
||||
public:
|
||||
LLVolatileAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE);
|
||||
~LLVolatileAPRPool(){}
|
||||
LLVolatileAPRPool(BOOL is_local = TRUE, apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE);
|
||||
virtual ~LLVolatileAPRPool();
|
||||
|
||||
apr_pool_t* getVolatileAPRPool() ;
|
||||
|
||||
/*virtual*/ apr_pool_t* getAPRPool() ; //define this virtual function to avoid any mistakenly calling LLAPRPool::getAPRPool().
|
||||
apr_pool_t* getVolatileAPRPool() ;
|
||||
void clearVolatileAPRPool() ;
|
||||
|
||||
BOOL isFull() ;
|
||||
BOOL isEmpty() {return !mNumActiveRef ;}
|
||||
|
||||
private:
|
||||
S32 mNumActiveRef ; //number of active pointers pointing to the apr_pool.
|
||||
S32 mNumTotalRef ; //number of total pointers pointing to the apr_pool since last creating.
|
||||
S32 mNumTotalRef ; //number of total pointers pointing to the apr_pool since last creating.
|
||||
|
||||
apr_thread_mutex_t *mMutexp;
|
||||
apr_pool_t *mMutexPool;
|
||||
} ;
|
||||
|
||||
/**
|
||||
|
|
@ -192,18 +195,21 @@ typedef LLAtomic32<S32> LLAtomicS32;
|
|||
// 1, a temperary pool passed to an APRFile function, which is used within this function and only once.
|
||||
// 2, a global pool.
|
||||
//
|
||||
class LLAPRFile
|
||||
|
||||
class LLAPRFile : boost::noncopyable
|
||||
{
|
||||
// make this non copyable since a copy closes the file
|
||||
private:
|
||||
apr_file_t* mFile ;
|
||||
LLVolatileAPRPool *mCurrentFilePoolp ; //currently in use apr_pool, could be one of them: sAPRFilePoolp, or a temp pool.
|
||||
|
||||
public:
|
||||
LLAPRFile() ;
|
||||
LLAPRFile(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool = NULL);
|
||||
~LLAPRFile() ;
|
||||
|
||||
apr_status_t open(LLVolatileAPRPool* pool, const std::string& filename, apr_int32_t flags, S32* sizep = NULL);
|
||||
apr_status_t open(const std::string& filename, apr_int32_t flags, apr_pool_t* pool = NULL, S32* sizep = NULL);
|
||||
|
||||
apr_status_t open(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool = NULL, S32* sizep = NULL);
|
||||
apr_status_t open(const std::string& filename, apr_int32_t flags, BOOL use_global_pool); //use gAPRPoolp.
|
||||
apr_status_t close() ;
|
||||
|
||||
// Returns actual offset, -1 if seek fails
|
||||
|
|
@ -217,8 +223,8 @@ public:
|
|||
apr_file_t* getFileHandle() {return mFile;}
|
||||
|
||||
private:
|
||||
apr_pool_t* getAPRFilePool(apr_pool_t* pool) ;
|
||||
|
||||
apr_pool_t* getAPRFilePool(apr_pool_t* pool) ;
|
||||
|
||||
//
|
||||
//*******************************************************************************************************************************
|
||||
//static components
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ LLQueuedThread::LLQueuedThread(const std::string& name, bool threaded) :
|
|||
LLThread(name),
|
||||
mThreaded(threaded),
|
||||
mIdleThread(TRUE),
|
||||
mNextHandle(0)
|
||||
mNextHandle(0),
|
||||
mStarted(FALSE)
|
||||
{
|
||||
if (mThreaded)
|
||||
{
|
||||
|
|
@ -53,6 +54,10 @@ LLQueuedThread::LLQueuedThread(const std::string& name, bool threaded) :
|
|||
// MAIN THREAD
|
||||
LLQueuedThread::~LLQueuedThread()
|
||||
{
|
||||
if (!mThreaded)
|
||||
{
|
||||
endThread();
|
||||
}
|
||||
shutdown();
|
||||
// ~LLThread() will be called here
|
||||
}
|
||||
|
|
@ -106,6 +111,11 @@ void LLQueuedThread::shutdown()
|
|||
// virtual
|
||||
S32 LLQueuedThread::update(U32 max_time_ms)
|
||||
{
|
||||
if (!mStarted)
|
||||
{
|
||||
startThread();
|
||||
mStarted = TRUE;
|
||||
}
|
||||
return updateQueue(max_time_ms);
|
||||
}
|
||||
|
||||
|
|
@ -452,26 +462,12 @@ S32 LLQueuedThread::processNextRequest()
|
|||
}
|
||||
}
|
||||
|
||||
S32 res;
|
||||
S32 pending = getPending();
|
||||
if (pending == 0)
|
||||
{
|
||||
if (isQuitting())
|
||||
{
|
||||
res = -1; // exit thread
|
||||
}
|
||||
else
|
||||
{
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
res = pending;
|
||||
}
|
||||
return res;
|
||||
|
||||
return pending;
|
||||
}
|
||||
|
||||
// virtual
|
||||
bool LLQueuedThread::runCondition()
|
||||
{
|
||||
// mRunCondition must be locked here
|
||||
|
|
@ -481,35 +477,53 @@ bool LLQueuedThread::runCondition()
|
|||
return true;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLQueuedThread::run()
|
||||
{
|
||||
// call checPause() immediately so we don't try to do anything before the class is fully constructed
|
||||
checkPause();
|
||||
startThread();
|
||||
mStarted = TRUE;
|
||||
|
||||
while (1)
|
||||
{
|
||||
// this will block on the condition until runCondition() returns true, the thread is unpaused, or the thread leaves the RUNNING state.
|
||||
checkPause();
|
||||
|
||||
if(isQuitting())
|
||||
if (isQuitting())
|
||||
{
|
||||
endThread();
|
||||
break;
|
||||
|
||||
//llinfos << "QUEUED THREAD RUNNING, queue size = " << mRequestQueue.size() << llendl;
|
||||
}
|
||||
|
||||
mIdleThread = FALSE;
|
||||
|
||||
threadedUpdate();
|
||||
|
||||
int res = processNextRequest();
|
||||
if (res == 0)
|
||||
{
|
||||
mIdleThread = TRUE;
|
||||
ms_sleep(1);
|
||||
}
|
||||
|
||||
if (res < 0) // finished working and want to exit
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//LLThread::yield(); // thread should yield after each request
|
||||
}
|
||||
llinfos << "LLQueuedThread " << mName << " EXITING." << llendl;
|
||||
}
|
||||
|
||||
llinfos << "QUEUED THREAD " << mName << " EXITING." << llendl;
|
||||
// virtual
|
||||
void LLQueuedThread::startThread()
|
||||
{
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLQueuedThread::endThread()
|
||||
{
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLQueuedThread::threadedUpdate()
|
||||
{
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
|
|
|||
|
|
@ -165,6 +165,9 @@ private:
|
|||
|
||||
virtual bool runCondition(void);
|
||||
virtual void run(void);
|
||||
virtual void startThread(void);
|
||||
virtual void endThread(void);
|
||||
virtual void threadedUpdate(void);
|
||||
|
||||
protected:
|
||||
handle_t generateHandle();
|
||||
|
|
@ -199,6 +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
|
||||
|
||||
typedef std::set<QueuedRequest*, queued_request_less> request_queue_t;
|
||||
|
|
|
|||
|
|
@ -33,9 +33,7 @@
|
|||
#ifndef LL_LLTHREAD_H
|
||||
#define LL_LLTHREAD_H
|
||||
|
||||
#include "llapr.h"
|
||||
#include "llapp.h"
|
||||
|
||||
#include "apr_thread_cond.h"
|
||||
|
||||
class LLThread;
|
||||
|
|
|
|||
|
|
@ -201,6 +201,7 @@ LLWorkerClass::~LLWorkerClass()
|
|||
{
|
||||
llassert_always(!(mWorkFlags & WCF_WORKING));
|
||||
llassert_always(mWorkFlags & WCF_DELETE_REQUESTED);
|
||||
llassert_always(!mMutex.isLocked());
|
||||
if (mRequestHandle != LLWorkerThread::nullHandle())
|
||||
{
|
||||
LLWorkerThread::WorkRequest* workreq = (LLWorkerThread::WorkRequest*)mWorkerThread->getRequest(mRequestHandle);
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ class LLWorkerClass;
|
|||
|
||||
class LLWorkerThread : public LLQueuedThread
|
||||
{
|
||||
friend class LLWorkerClass;
|
||||
public:
|
||||
class WorkRequest : public LLQueuedThread::QueuedRequest
|
||||
{
|
||||
|
|
@ -92,8 +93,11 @@ public:
|
|||
|
||||
handle_t addWorkRequest(LLWorkerClass* workerclass, S32 param, U32 priority = PRIORITY_NORMAL);
|
||||
|
||||
void deleteWorker(LLWorkerClass* workerclass); // schedule for deletion
|
||||
S32 getNumDeletes() { return (S32)mDeleteList.size(); } // debug
|
||||
|
||||
private:
|
||||
void deleteWorker(LLWorkerClass* workerclass); // schedule for deletion
|
||||
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
project(llimage)
|
||||
|
||||
include(00-Common)
|
||||
include(LLAddBuildTest)
|
||||
include(LLCommon)
|
||||
include(LLImage)
|
||||
include(LLMath)
|
||||
|
|
@ -59,3 +60,6 @@ target_link_libraries(llimage
|
|||
${PNG_LIBRARIES}
|
||||
${ZLIB_LIBRARIES}
|
||||
)
|
||||
|
||||
# Add tests
|
||||
#ADD_BUILD_TEST(llimageworker llimage)
|
||||
|
|
|
|||
|
|
@ -55,13 +55,9 @@ std::string LLImage::sLastErrorMessage;
|
|||
LLMutex* LLImage::sMutex = NULL;
|
||||
|
||||
//static
|
||||
void LLImage::initClass(LLWorkerThread* workerthread)
|
||||
void LLImage::initClass()
|
||||
{
|
||||
sMutex = new LLMutex(NULL);
|
||||
if (workerthread)
|
||||
{
|
||||
LLImageWorker::initImageWorker(workerthread);
|
||||
}
|
||||
LLImageJ2C::openDSO();
|
||||
}
|
||||
|
||||
|
|
@ -69,7 +65,6 @@ void LLImage::initClass(LLWorkerThread* workerthread)
|
|||
void LLImage::cleanupClass()
|
||||
{
|
||||
LLImageJ2C::closeDSO();
|
||||
LLImageWorker::cleanupImageWorker();
|
||||
delete sMutex;
|
||||
sMutex = NULL;
|
||||
}
|
||||
|
|
@ -316,6 +311,21 @@ void LLImageRaw::deleteData()
|
|||
LLImageBase::deleteData();
|
||||
}
|
||||
|
||||
void LLImageRaw::setDataAndSize(U8 *data, S32 width, S32 height, S8 components)
|
||||
{
|
||||
if(data == getData())
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
deleteData();
|
||||
|
||||
LLImageBase::setSize(width, height, components) ;
|
||||
LLImageBase::setDataAndSize(data, width * height * components) ;
|
||||
|
||||
sGlobalRawMemory += getDataSize();
|
||||
}
|
||||
|
||||
BOOL LLImageRaw::resize(U16 width, U16 height, S8 components)
|
||||
{
|
||||
if ((getWidth() == width) && (getHeight() == height) && (getComponents() == components))
|
||||
|
|
@ -816,6 +826,51 @@ void LLImageRaw::copyScaled( LLImageRaw* src )
|
|||
}
|
||||
}
|
||||
|
||||
//scale down image by not blending a pixel with its neighbors.
|
||||
BOOL LLImageRaw::scaleDownWithoutBlending( S32 new_width, S32 new_height)
|
||||
{
|
||||
LLMemType mt1(mMemType);
|
||||
|
||||
S8 c = getComponents() ;
|
||||
llassert((1 == c) || (3 == c) || (4 == c) );
|
||||
|
||||
S32 old_width = getWidth();
|
||||
S32 old_height = getHeight();
|
||||
|
||||
S32 new_data_size = old_width * new_height * c ;
|
||||
llassert_always(new_data_size > 0);
|
||||
|
||||
F32 ratio_x = (F32)old_width / new_width ;
|
||||
F32 ratio_y = (F32)old_height / new_height ;
|
||||
if( ratio_x < 1.0f || ratio_y < 1.0f )
|
||||
{
|
||||
return TRUE; // Nothing to do.
|
||||
}
|
||||
ratio_x -= 1.0f ;
|
||||
ratio_y -= 1.0f ;
|
||||
|
||||
U8* new_data = new U8[new_data_size] ;
|
||||
llassert_always(new_data != NULL) ;
|
||||
|
||||
U8* old_data = getData() ;
|
||||
S32 i, j, k, s, t;
|
||||
for(i = 0, s = 0, t = 0 ; i < new_height ; i++)
|
||||
{
|
||||
for(j = 0 ; j < new_width ; j++)
|
||||
{
|
||||
for(k = 0 ; k < c ; k++)
|
||||
{
|
||||
new_data[s++] = old_data[t++] ;
|
||||
}
|
||||
t += (S32)(ratio_x * c + 0.1f) ;
|
||||
}
|
||||
t += (S32)(ratio_y * old_width * c + 0.1f) ;
|
||||
}
|
||||
|
||||
setDataAndSize(new_data, new_width, new_height, c) ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ const S32 MAX_IMAGE_AREA = MAX_IMAGE_SIZE * MAX_IMAGE_SIZE;
|
|||
const S32 MAX_IMAGE_COMPONENTS = 8;
|
||||
const S32 MAX_IMAGE_DATA_SIZE = MAX_IMAGE_AREA * MAX_IMAGE_COMPONENTS;
|
||||
|
||||
// Note! These CANNOT be changed without invalidating the viewer VFS files, I think?
|
||||
// Note! These CANNOT be changed without modifying simulator code
|
||||
// *TODO: change both to 1024 when SIM texture fetching is deprecated
|
||||
const S32 FIRST_PACKET_SIZE = 600;
|
||||
const S32 MAX_IMG_PACKET_SIZE = 1000;
|
||||
|
||||
|
|
@ -61,7 +62,6 @@ const S32 MAX_IMG_PACKET_SIZE = 1000;
|
|||
class LLImageFormatted;
|
||||
class LLImageRaw;
|
||||
class LLColor4U;
|
||||
class LLWorkerThread;
|
||||
|
||||
typedef enum e_image_codec
|
||||
{
|
||||
|
|
@ -82,7 +82,7 @@ typedef enum e_image_codec
|
|||
class LLImage
|
||||
{
|
||||
public:
|
||||
static void initClass(LLWorkerThread* workerthread);
|
||||
static void initClass();
|
||||
static void cleanupClass();
|
||||
|
||||
static const std::string& getLastError();
|
||||
|
|
@ -131,7 +131,7 @@ public:
|
|||
|
||||
protected:
|
||||
// special accessor to allow direct setting of mData and mDataSize by LLImageFormatted
|
||||
void setDataAndSize(U8 *data, S32 size) { mData = data; mDataSize = size; };
|
||||
void setDataAndSize(U8 *data, S32 size) { mData = data; mDataSize = size; }
|
||||
|
||||
public:
|
||||
static void generateMip(const U8 *indata, U8* mipdata, int width, int height, S32 nchannels);
|
||||
|
|
@ -192,6 +192,7 @@ public:
|
|||
void contractToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE, BOOL scale_image = TRUE);
|
||||
void biasedScaleToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE);
|
||||
BOOL scale( S32 new_width, S32 new_height, BOOL scale_image = TRUE );
|
||||
BOOL scaleDownWithoutBlending( S32 new_width, S32 new_height) ;
|
||||
|
||||
// Fill the buffer with a constant color
|
||||
void fill( const LLColor4U& color );
|
||||
|
|
@ -240,6 +241,8 @@ protected:
|
|||
|
||||
U8 fastFractionalMult(U8 a,U8 b);
|
||||
|
||||
void setDataAndSize(U8 *data, S32 width, S32 height, S8 components) ;
|
||||
|
||||
public:
|
||||
static S32 sGlobalRawMemory;
|
||||
static S32 sRawImageCount;
|
||||
|
|
@ -310,7 +313,7 @@ protected:
|
|||
protected:
|
||||
S8 mCodec;
|
||||
S8 mDecoding;
|
||||
S8 mDecoded;
|
||||
S8 mDecoded; // unused, but changing LLImage layout requires recompiling static Mac/Linux libs. 2009-01-30 JC
|
||||
S8 mDiscardLevel;
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -264,6 +264,8 @@ void LLImageDXT::setFormat()
|
|||
// virtual
|
||||
BOOL LLImageDXT::decode(LLImageRaw* raw_image, F32 time)
|
||||
{
|
||||
// *TODO: Test! This has been tweaked since its intial inception,
|
||||
// but we don't use it any more!
|
||||
llassert_always(raw_image);
|
||||
|
||||
if (mFileFormat >= FORMAT_DXT1 && mFileFormat <= FORMAT_DXR5)
|
||||
|
|
@ -274,8 +276,17 @@ BOOL LLImageDXT::decode(LLImageRaw* raw_image, F32 time)
|
|||
|
||||
S32 width = getWidth(), height = getHeight();
|
||||
S32 ncomponents = getComponents();
|
||||
U8* data = NULL;
|
||||
if (mDiscardLevel >= 0)
|
||||
{
|
||||
data = getData() + getMipOffset(mDiscardLevel);
|
||||
calcDiscardWidthHeight(mDiscardLevel, mFileFormat, width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = getData() + getMipOffset(0);
|
||||
}
|
||||
S32 image_size = formatBytes(mFileFormat, width, height);
|
||||
U8* data = getData() + getMipOffset(0);
|
||||
|
||||
if ((!getData()) || (data + image_size > getData() + getDataSize()))
|
||||
{
|
||||
|
|
@ -300,10 +311,8 @@ BOOL LLImageDXT::getMipData(LLPointer<LLImageRaw>& raw, S32 discard)
|
|||
llerrs << "Request for invalid discard level" << llendl;
|
||||
}
|
||||
U8* data = getData() + getMipOffset(discard);
|
||||
// I'm not sure these are the correct initial values for height and width,
|
||||
// but previously they were being used uninitialized. JC
|
||||
S32 width = raw->getWidth();
|
||||
S32 height = raw->getHeight();
|
||||
S32 width = 0;
|
||||
S32 height = 0;
|
||||
calcDiscardWidthHeight(discard, mFileFormat, width, height);
|
||||
raw = new LLImageRaw(data, width, height, getComponents());
|
||||
return TRUE;
|
||||
|
|
|
|||
|
|
@ -277,6 +277,7 @@ BOOL LLImageJ2C::decode(LLImageRaw *raw_imagep, F32 decode_time)
|
|||
}
|
||||
|
||||
|
||||
// Returns TRUE to mean done, whether successful or not.
|
||||
BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 first_channel, S32 max_channel_count )
|
||||
{
|
||||
LLMemType mt1(mMemType);
|
||||
|
|
@ -289,7 +290,7 @@ BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 fir
|
|||
if (!getData() || (getDataSize() < 16))
|
||||
{
|
||||
setLastError("LLImageJ2C uninitialized");
|
||||
res = FALSE;
|
||||
res = TRUE; // done
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -342,7 +343,7 @@ BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, const char* comment_text,
|
|||
//static
|
||||
S32 LLImageJ2C::calcHeaderSizeJ2C()
|
||||
{
|
||||
return 600; //2048; // ??? hack... just needs to be >= actual header size...
|
||||
return FIRST_PACKET_SIZE; // Hack. just needs to be >= actual header size...
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
|
|||
|
|
@ -188,6 +188,7 @@ void LLImageJPEG::decodeTermSource (j_decompress_ptr cinfo)
|
|||
}
|
||||
|
||||
|
||||
// Returns true when done, whether or not decode was successful.
|
||||
BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
|
||||
{
|
||||
llassert_always(raw_image);
|
||||
|
|
@ -198,7 +199,7 @@ BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
|
|||
if (!getData() || (0 == getDataSize()))
|
||||
{
|
||||
setLastError("LLImageJPEG trying to decode an image with no data!");
|
||||
return FALSE;
|
||||
return TRUE; // done
|
||||
}
|
||||
|
||||
S32 row_stride = 0;
|
||||
|
|
@ -226,7 +227,7 @@ BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
|
|||
if(setjmp(sSetjmpBuffer))
|
||||
{
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
return FALSE;
|
||||
return TRUE; // done
|
||||
}
|
||||
try
|
||||
{
|
||||
|
|
@ -320,7 +321,7 @@ BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
|
|||
catch (int)
|
||||
{
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
return FALSE;
|
||||
return TRUE; // done
|
||||
}
|
||||
|
||||
// Check to see whether any corrupt-data warnings occurred
|
||||
|
|
@ -328,7 +329,7 @@ BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
|
|||
{
|
||||
// TODO: extract the warning to find out what went wrong.
|
||||
setLastError( "Unable to decode JPEG image.");
|
||||
return FALSE;
|
||||
return TRUE; // done
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
|||
|
|
@ -37,152 +37,138 @@
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//static
|
||||
LLWorkerThread* LLImageWorker::sWorkerThread = NULL;
|
||||
S32 LLImageWorker::sCount = 0;
|
||||
|
||||
//static
|
||||
void LLImageWorker::initImageWorker(LLWorkerThread* workerthread)
|
||||
// MAIN THREAD
|
||||
LLImageDecodeThread::LLImageDecodeThread(bool threaded)
|
||||
: LLQueuedThread("imagedecode", threaded)
|
||||
{
|
||||
sWorkerThread = workerthread;
|
||||
mCreationMutex = new LLMutex(getAPRPool());
|
||||
}
|
||||
|
||||
//static
|
||||
void LLImageWorker::cleanupImageWorker()
|
||||
// MAIN THREAD
|
||||
// virtual
|
||||
S32 LLImageDecodeThread::update(U32 max_time_ms)
|
||||
{
|
||||
LLMutexLock lock(mCreationMutex);
|
||||
for (creation_list_t::iterator iter = mCreationList.begin();
|
||||
iter != mCreationList.end(); ++iter)
|
||||
{
|
||||
creation_info& info = *iter;
|
||||
ImageRequest* req = new ImageRequest(info.handle, info.image,
|
||||
info.priority, info.discard, info.needs_aux,
|
||||
info.responder);
|
||||
addRequest(req);
|
||||
}
|
||||
mCreationList.clear();
|
||||
S32 res = LLQueuedThread::update(max_time_ms);
|
||||
return res;
|
||||
}
|
||||
|
||||
LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image,
|
||||
U32 priority, S32 discard, BOOL needs_aux, Responder* responder)
|
||||
{
|
||||
LLMutexLock lock(mCreationMutex);
|
||||
handle_t handle = generateHandle();
|
||||
mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder));
|
||||
return handle;
|
||||
}
|
||||
|
||||
// Used by unit test only
|
||||
// Returns the size of the mutex guarded list as an indication of sanity
|
||||
S32 LLImageDecodeThread::tut_size()
|
||||
{
|
||||
LLMutexLock lock(mCreationMutex);
|
||||
S32 res = mCreationList.size();
|
||||
return res;
|
||||
}
|
||||
|
||||
LLImageDecodeThread::Responder::~Responder()
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
LLImageWorker::LLImageWorker(LLImageFormatted* image, U32 priority,
|
||||
S32 discard,
|
||||
LLPointer<LLResponder> responder)
|
||||
: LLWorkerClass(sWorkerThread, "Image"),
|
||||
LLImageDecodeThread::ImageRequest::ImageRequest(handle_t handle, LLImageFormatted* image,
|
||||
U32 priority, S32 discard, BOOL needs_aux,
|
||||
LLImageDecodeThread::Responder* responder)
|
||||
: LLQueuedThread::QueuedRequest(handle, priority, FLAG_AUTO_COMPLETE),
|
||||
mFormattedImage(image),
|
||||
mDecodedType(-1),
|
||||
mDiscardLevel(discard),
|
||||
mPriority(priority),
|
||||
mNeedsAux(needs_aux),
|
||||
mDecodedRaw(FALSE),
|
||||
mDecodedAux(FALSE),
|
||||
mResponder(responder)
|
||||
{
|
||||
++sCount;
|
||||
}
|
||||
|
||||
LLImageWorker::~LLImageWorker()
|
||||
LLImageDecodeThread::ImageRequest::~ImageRequest()
|
||||
{
|
||||
mDecodedImage = NULL;
|
||||
mDecodedImageRaw = NULL;
|
||||
mDecodedImageAux = NULL;
|
||||
mFormattedImage = NULL;
|
||||
--sCount;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//virtual, main thread
|
||||
void LLImageWorker::startWork(S32 param)
|
||||
{
|
||||
llassert_always(mDecodedImage.isNull());
|
||||
mDecodedType = -1;
|
||||
}
|
||||
|
||||
bool LLImageWorker::doWork(S32 param)
|
||||
{
|
||||
bool decoded = false;
|
||||
if(mDecodedImage.isNull())
|
||||
{
|
||||
if (!mFormattedImage->updateData())
|
||||
{
|
||||
mDecodedType = -2; // failed
|
||||
return true;
|
||||
}
|
||||
if (mDiscardLevel >= 0)
|
||||
{
|
||||
mFormattedImage->setDiscardLevel(mDiscardLevel);
|
||||
}
|
||||
if (!(mFormattedImage->getWidth() * mFormattedImage->getHeight() * mFormattedImage->getComponents()))
|
||||
{
|
||||
decoded = true; // failed
|
||||
}
|
||||
else
|
||||
{
|
||||
mDecodedImage = new LLImageRaw(); // allow possibly smaller size set during decoding
|
||||
}
|
||||
}
|
||||
if (!decoded)
|
||||
{
|
||||
if (param == 0)
|
||||
{
|
||||
// Decode primary channels
|
||||
decoded = mFormattedImage->decode(mDecodedImage, .1f); // 1ms
|
||||
}
|
||||
else
|
||||
{
|
||||
// Decode aux channel
|
||||
decoded = mFormattedImage->decodeChannels(mDecodedImage, .1f, param, param); // 1ms
|
||||
}
|
||||
}
|
||||
if (decoded)
|
||||
{
|
||||
// Call the callback immediately; endWork doesn't get called until ckeckWork
|
||||
if (mResponder.notNull())
|
||||
{
|
||||
bool success = (!wasAborted() && mDecodedImage.notNull() && mDecodedImage->getDataSize() != 0);
|
||||
mResponder->completed(success);
|
||||
}
|
||||
}
|
||||
return decoded;
|
||||
}
|
||||
|
||||
void LLImageWorker::endWork(S32 param, bool aborted)
|
||||
{
|
||||
if (mDecodedType != -2)
|
||||
{
|
||||
mDecodedType = aborted ? -2 : param;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
BOOL LLImageWorker::requestDecodedAuxData(LLPointer<LLImageRaw>& raw, S32 channel, S32 discard)
|
||||
// Returns true when done, whether or not decode was successful.
|
||||
bool LLImageDecodeThread::ImageRequest::processRequest()
|
||||
{
|
||||
// For most codecs, only mDiscardLevel data is available.
|
||||
// (see LLImageDXT for exception)
|
||||
if (discard >= 0 && discard != mFormattedImage->getDiscardLevel())
|
||||
const F32 decode_time_slice = .1f;
|
||||
bool done = true;
|
||||
if (!mDecodedRaw && mFormattedImage.notNull())
|
||||
{
|
||||
llerrs << "Request for invalid discard level" << llendl;
|
||||
}
|
||||
checkWork();
|
||||
if (mDecodedType == -2)
|
||||
{
|
||||
return TRUE; // aborted, done
|
||||
}
|
||||
if (mDecodedType != channel)
|
||||
{
|
||||
if (!haveWork())
|
||||
// Decode primary channels
|
||||
if (mDecodedImageRaw.isNull())
|
||||
{
|
||||
addWork(channel, mPriority);
|
||||
// parse formatted header
|
||||
if (!mFormattedImage->updateData())
|
||||
{
|
||||
return true; // done (failed)
|
||||
}
|
||||
if (!(mFormattedImage->getWidth() * mFormattedImage->getHeight() * mFormattedImage->getComponents()))
|
||||
{
|
||||
return true; // done (failed)
|
||||
}
|
||||
if (mDiscardLevel >= 0)
|
||||
{
|
||||
mFormattedImage->setDiscardLevel(mDiscardLevel);
|
||||
}
|
||||
mDecodedImageRaw = new LLImageRaw(mFormattedImage->getWidth(),
|
||||
mFormattedImage->getHeight(),
|
||||
mFormattedImage->getComponents());
|
||||
}
|
||||
return FALSE;
|
||||
done = mFormattedImage->decode(mDecodedImageRaw, decode_time_slice); // 1ms
|
||||
mDecodedRaw = done;
|
||||
}
|
||||
else
|
||||
if (done && mNeedsAux && !mDecodedAux && mFormattedImage.notNull())
|
||||
{
|
||||
llassert_always(!haveWork());
|
||||
llassert_always(mDecodedType == channel);
|
||||
raw = mDecodedImage; // smart pointer acquires ownership of data
|
||||
mDecodedImage = NULL;
|
||||
return TRUE;
|
||||
// Decode aux channel
|
||||
if (!mDecodedImageAux)
|
||||
{
|
||||
mDecodedImageAux = new LLImageRaw(mFormattedImage->getWidth(),
|
||||
mFormattedImage->getHeight(),
|
||||
1);
|
||||
}
|
||||
done = mFormattedImage->decodeChannels(mDecodedImageAux, decode_time_slice, 4, 4); // 1ms
|
||||
mDecodedAux = done;
|
||||
}
|
||||
|
||||
return done;
|
||||
}
|
||||
|
||||
BOOL LLImageWorker::requestDecodedData(LLPointer<LLImageRaw>& raw, S32 discard)
|
||||
void LLImageDecodeThread::ImageRequest::finishRequest(bool completed)
|
||||
{
|
||||
if (mFormattedImage->getCodec() == IMG_CODEC_DXT)
|
||||
if (mResponder.notNull())
|
||||
{
|
||||
// special case
|
||||
LLImageDXT* imagedxt = (LLImageDXT*)((LLImageFormatted*)mFormattedImage);
|
||||
return imagedxt->getMipData(raw, discard);
|
||||
}
|
||||
else
|
||||
{
|
||||
return requestDecodedAuxData(raw, 0, discard);
|
||||
bool success = completed && mDecodedRaw && (!mNeedsAux || mDecodedAux);
|
||||
mResponder->completed(success, mDecodedImageRaw, mDecodedImageAux);
|
||||
}
|
||||
// Will automatically be deleted
|
||||
}
|
||||
|
||||
// Used by unit test only
|
||||
// Checks that a responder exists for this instance so that something can happen when completion is reached
|
||||
bool LLImageDecodeThread::ImageRequest::tut_isOK()
|
||||
{
|
||||
return mResponder.notNull();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,49 +37,72 @@
|
|||
#include "llpointer.h"
|
||||
#include "llworkerthread.h"
|
||||
|
||||
class LLImageWorker : public LLWorkerClass
|
||||
class LLImageDecodeThread : public LLQueuedThread
|
||||
{
|
||||
public:
|
||||
static void initImageWorker(LLWorkerThread* workerthread);
|
||||
static void cleanupImageWorker();
|
||||
class Responder : public LLThreadSafeRefCount
|
||||
{
|
||||
protected:
|
||||
virtual ~Responder();
|
||||
public:
|
||||
virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux) = 0;
|
||||
};
|
||||
|
||||
class ImageRequest : public LLQueuedThread::QueuedRequest
|
||||
{
|
||||
protected:
|
||||
virtual ~ImageRequest(); // use deleteRequest()
|
||||
|
||||
public:
|
||||
ImageRequest(handle_t handle, LLImageFormatted* image,
|
||||
U32 priority, S32 discard, BOOL needs_aux,
|
||||
LLImageDecodeThread::Responder* responder);
|
||||
|
||||
/*virtual*/ bool processRequest();
|
||||
/*virtual*/ void finishRequest(bool completed);
|
||||
|
||||
// Used by unit tests to check the consitency of the request instance
|
||||
bool tut_isOK();
|
||||
|
||||
private:
|
||||
// input
|
||||
LLPointer<LLImageFormatted> mFormattedImage;
|
||||
S32 mDiscardLevel;
|
||||
BOOL mNeedsAux;
|
||||
// output
|
||||
LLPointer<LLImageRaw> mDecodedImageRaw;
|
||||
LLPointer<LLImageRaw> mDecodedImageAux;
|
||||
BOOL mDecodedRaw;
|
||||
BOOL mDecodedAux;
|
||||
LLPointer<LLImageDecodeThread::Responder> mResponder;
|
||||
};
|
||||
|
||||
public:
|
||||
static LLWorkerThread* getWorkerThread() { return sWorkerThread; }
|
||||
LLImageDecodeThread(bool threaded = true);
|
||||
handle_t decodeImage(LLImageFormatted* image,
|
||||
U32 priority, S32 discard, BOOL needs_aux,
|
||||
Responder* responder);
|
||||
S32 update(U32 max_time_ms);
|
||||
|
||||
// LLWorkerThread
|
||||
public:
|
||||
LLImageWorker(LLImageFormatted* image, U32 priority, S32 discard,
|
||||
LLPointer<LLResponder> responder);
|
||||
~LLImageWorker();
|
||||
|
||||
// called from WORKER THREAD, returns TRUE if done
|
||||
/*virtual*/ bool doWork(S32 param);
|
||||
// Used by unit tests to check the consistency of the thread instance
|
||||
S32 tut_size();
|
||||
|
||||
BOOL requestDecodedData(LLPointer<LLImageRaw>& raw, S32 discard = -1);
|
||||
BOOL requestDecodedAuxData(LLPointer<LLImageRaw>& raw, S32 channel, S32 discard = -1);
|
||||
void releaseDecodedData();
|
||||
void cancelDecode();
|
||||
|
||||
private:
|
||||
// called from MAIN THREAD
|
||||
/*virtual*/ void startWork(S32 param); // called from addWork()
|
||||
/*virtual*/ void endWork(S32 param, bool aborted); // called from doWork()
|
||||
|
||||
protected:
|
||||
LLPointer<LLImageFormatted> mFormattedImage;
|
||||
LLPointer<LLImageRaw> mDecodedImage;
|
||||
S32 mDecodedType;
|
||||
S32 mDiscardLevel;
|
||||
|
||||
private:
|
||||
U32 mPriority;
|
||||
LLPointer<LLResponder> mResponder;
|
||||
|
||||
protected:
|
||||
static LLWorkerThread* sWorkerThread;
|
||||
|
||||
public:
|
||||
static S32 sCount;
|
||||
struct creation_info
|
||||
{
|
||||
handle_t handle;
|
||||
LLPointer<LLImageFormatted> image;
|
||||
U32 priority;
|
||||
S32 discard;
|
||||
BOOL needs_aux;
|
||||
LLPointer<Responder> responder;
|
||||
creation_info(handle_t h, LLImageFormatted* i, U32 p, S32 d, BOOL aux, Responder* r)
|
||||
: handle(h), image(i), priority(p), discard(d), needs_aux(aux), responder(r)
|
||||
{}
|
||||
};
|
||||
typedef std::list<creation_info> creation_list_t;
|
||||
creation_list_t mCreationList;
|
||||
LLMutex* mCreationMutex;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,260 @@
|
|||
/**
|
||||
* @file llimageworker_test.cpp
|
||||
* @author Merov Linden
|
||||
* @date 2009-04-28
|
||||
*
|
||||
* $LicenseInfo:firstyear=2006&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2006-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
// Precompiled header: almost always required for newview cpp files
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
// Class to test
|
||||
#include "../llimageworker.h"
|
||||
// For timer class
|
||||
#include "../llcommon/lltimer.h"
|
||||
// Tut header
|
||||
#include "../test/lltut.h"
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// Stubbing: Declarations required to link and run the class being tested
|
||||
// Notes:
|
||||
// * Add here stubbed implementation of the few classes and methods used in the class to be tested
|
||||
// * Add as little as possible (let the link errors guide you)
|
||||
// * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code)
|
||||
// * A simulator for a class can be implemented here. Please comment and document thoroughly.
|
||||
|
||||
LLImageBase::LLImageBase() {}
|
||||
LLImageBase::~LLImageBase() {}
|
||||
void LLImageBase::dump() { }
|
||||
void LLImageBase::sanityCheck() { }
|
||||
void LLImageBase::deleteData() { }
|
||||
U8* LLImageBase::allocateData(S32 size) { return NULL; }
|
||||
U8* LLImageBase::reallocateData(S32 size) { return NULL; }
|
||||
|
||||
LLImageRaw::LLImageRaw(U16 width, U16 height, S8 components) { }
|
||||
LLImageRaw::~LLImageRaw() { }
|
||||
void LLImageRaw::deleteData() { }
|
||||
U8* LLImageRaw::allocateData(S32 size) { return NULL; }
|
||||
U8* LLImageRaw::reallocateData(S32 size) { return NULL; }
|
||||
|
||||
// End Stubbing
|
||||
// -------------------------------------------------------------------------------------------
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// TUT
|
||||
// -------------------------------------------------------------------------------------------
|
||||
|
||||
namespace tut
|
||||
{
|
||||
// Test wrapper declarations
|
||||
|
||||
// Note: We derive the responder class for 2 reasons:
|
||||
// 1. It's a pure virtual class and we can't compile without completed() being implemented
|
||||
// 2. We actually need a responder to test that the thread work test completed
|
||||
// We implement this making no assumption on what's done in the thread or worker
|
||||
// though, just that the responder's completed() method is called in the end.
|
||||
// Note on responders: responders are ref counted and *will* be deleted by the request they are
|
||||
// attached to when the queued request is deleted. The recommended way of using them is to
|
||||
// create them when creating a request, put a callback method in completed() and not rely on
|
||||
// anything to survive in the responder object once completed() has been called. Let the request
|
||||
// do the deletion and clean up itself.
|
||||
class responder_test : public LLImageDecodeThread::Responder
|
||||
{
|
||||
public:
|
||||
responder_test(bool* res)
|
||||
{
|
||||
done = res;
|
||||
*done = false;
|
||||
}
|
||||
virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux)
|
||||
{
|
||||
*done = true;
|
||||
}
|
||||
private:
|
||||
// This is what can be thought of as the minimal implementation of a responder
|
||||
// Done will be switched to true when completed() is called and can be tested
|
||||
// outside the responder. A better way of doing this is to store a callback here.
|
||||
bool* done;
|
||||
};
|
||||
|
||||
// Test wrapper declaration : decode thread
|
||||
struct imagedecodethread_test
|
||||
{
|
||||
// Instance to be tested
|
||||
LLImageDecodeThread* mThread;
|
||||
|
||||
// Constructor and destructor of the test wrapper
|
||||
imagedecodethread_test()
|
||||
{
|
||||
mThread = NULL;
|
||||
}
|
||||
~imagedecodethread_test()
|
||||
{
|
||||
delete mThread;
|
||||
}
|
||||
};
|
||||
|
||||
// Test wrapper declaration : image worker
|
||||
// Note: this class is not meant to be instantiated outside an LLImageDecodeThread instance
|
||||
// but it's not a bad idea to get its public API a good shake as part of a thorough unit test set.
|
||||
// Some gotcha with the destructor though (see below).
|
||||
struct imagerequest_test
|
||||
{
|
||||
// Instance to be tested
|
||||
LLImageDecodeThread::ImageRequest* mRequest;
|
||||
bool done;
|
||||
|
||||
// Constructor and destructor of the test wrapper
|
||||
imagerequest_test()
|
||||
{
|
||||
done = false;
|
||||
mRequest = new LLImageDecodeThread::ImageRequest(0, 0,
|
||||
LLQueuedThread::PRIORITY_NORMAL, 0, FALSE,
|
||||
new responder_test(&done));
|
||||
}
|
||||
~imagerequest_test()
|
||||
{
|
||||
// We should delete the object *but*, because its destructor is protected, that cannot be
|
||||
// done from outside an LLImageDecodeThread instance... So we leak memory here... It's fine...
|
||||
//delete mRequest;
|
||||
}
|
||||
};
|
||||
|
||||
// Tut templating thingamagic: test group, object and test instance
|
||||
typedef test_group<imagedecodethread_test> imagedecodethread_t;
|
||||
typedef imagedecodethread_t::object imagedecodethread_object_t;
|
||||
tut::imagedecodethread_t tut_imagedecodethread("imagedecodethread");
|
||||
|
||||
typedef test_group<imagerequest_test> imagerequest_t;
|
||||
typedef imagerequest_t::object imagerequest_object_t;
|
||||
tut::imagerequest_t tut_imagerequest("imagerequest");
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// Test functions
|
||||
// Notes:
|
||||
// * Test as many as you possibly can without requiring a full blown simulation of everything
|
||||
// * The tests are executed in sequence so the test instance state may change between calls
|
||||
// * Remember that you cannot test private methods with tut
|
||||
// ---------------------------------------------------------------------------------------
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// Test the LLImageDecodeThread interface
|
||||
// ---------------------------------------------------------------------------------------
|
||||
//
|
||||
// Note on Unit Testing Queued Thread Classes
|
||||
//
|
||||
// Since methods on such a class are called on a separate loop and that we can't insert tut
|
||||
// ensure() calls in there, we exercise the class with 2 sets of tests:
|
||||
// - 1: Test as a single threaded instance: We declare the class but ask for no thread
|
||||
// to be spawned (easy with LLThreads since there's a boolean argument on the constructor
|
||||
// just for that). We can then unit test each public method like we do on a normal class.
|
||||
// - 2: Test as a threaded instance: We let the thread launch and check that its external
|
||||
// behavior is as expected (i.e. it runs, can accept a work order and processes
|
||||
// it). Typically though there's no guarantee that this exercises all the methods of the
|
||||
// class which is why we also need the previous "non threaded" set of unit tests for
|
||||
// complete coverage.
|
||||
//
|
||||
// ---------------------------------------------------------------------------------------
|
||||
|
||||
template<> template<>
|
||||
void imagedecodethread_object_t::test<1>()
|
||||
{
|
||||
// Test a *non threaded* instance of the class
|
||||
mThread = new LLImageDecodeThread(false);
|
||||
ensure("LLImageDecodeThread: non threaded constructor failed", mThread != NULL);
|
||||
// Test that we start with an empty list right at creation
|
||||
ensure("LLImageDecodeThread: non threaded init state incorrect", mThread->tut_size() == 0);
|
||||
// Insert something in the queue
|
||||
bool done = false;
|
||||
LLImageDecodeThread::handle_t decodeHandle = mThread->decodeImage(NULL, LLQueuedThread::PRIORITY_NORMAL, 0, FALSE, new responder_test(&done));
|
||||
// Verifies we got a valid handle
|
||||
ensure("LLImageDecodeThread: non threaded decodeImage(), returned handle is null", decodeHandle != 0);
|
||||
// Verifies that we do now have something in the queued list
|
||||
ensure("LLImageDecodeThread: non threaded decodeImage() insertion in threaded list failed", mThread->tut_size() == 1);
|
||||
// Trigger queue handling "manually" (on a threaded instance, this is done on the thread loop)
|
||||
S32 res = mThread->update(0);
|
||||
// Verifies that we successfully handled the list
|
||||
ensure("LLImageDecodeThread: non threaded update() list handling test failed", res == 0);
|
||||
// Verifies that the list is now empty
|
||||
ensure("LLImageDecodeThread: non threaded update() list emptying test failed", mThread->tut_size() == 0);
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void imagedecodethread_object_t::test<2>()
|
||||
{
|
||||
// Test a *threaded* instance of the class
|
||||
mThread = new LLImageDecodeThread(true);
|
||||
ensure("LLImageDecodeThread: threaded constructor failed", mThread != NULL);
|
||||
// Test that we start with an empty list right at creation
|
||||
ensure("LLImageDecodeThread: threaded init state incorrect", mThread->tut_size() == 0);
|
||||
// Insert something in the queue
|
||||
bool done = false;
|
||||
LLImageDecodeThread::handle_t decodeHandle = mThread->decodeImage(NULL, LLQueuedThread::PRIORITY_NORMAL, 0, FALSE, new responder_test(&done));
|
||||
// Verifies we get back a valid handle
|
||||
ensure("LLImageDecodeThread: threaded decodeImage(), returned handle is null", decodeHandle != 0);
|
||||
// Wait a little so to simulate the main thread doing something on its main loop...
|
||||
ms_sleep(500); // 500 milliseconds
|
||||
// Verifies that the responder has *not* been called yet in the meantime
|
||||
ensure("LLImageDecodeThread: responder creation failed", done == false);
|
||||
// Ask the thread to update: that means tells the queue to check itself and creates work requests
|
||||
mThread->update(1);
|
||||
// Wait till the thread has time to handle the work order (though it doesn't do much per work order...)
|
||||
const U32 INCREMENT_TIME = 500; // 500 milliseconds
|
||||
const U32 MAX_TIME = 20 * INCREMENT_TIME; // Do the loop 20 times max, i.e. wait 10 seconds but no more
|
||||
U32 total_time = 0;
|
||||
while ((done == false) && (total_time < MAX_TIME))
|
||||
{
|
||||
ms_sleep(INCREMENT_TIME);
|
||||
total_time += INCREMENT_TIME;
|
||||
}
|
||||
// Verifies that the responder has now been called
|
||||
ensure("LLImageDecodeThread: threaded work unit not processed", done == true);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// Test the LLImageDecodeThread::ImageRequest interface
|
||||
// ---------------------------------------------------------------------------------------
|
||||
|
||||
template<> template<>
|
||||
void imagerequest_object_t::test<1>()
|
||||
{
|
||||
// Test that we start with a correct request at creation
|
||||
ensure("LLImageDecodeThread::ImageRequest::ImageRequest() constructor test failed", mRequest->tut_isOK());
|
||||
bool res = mRequest->processRequest();
|
||||
// Verifies that we processed the request successfully
|
||||
ensure("LLImageDecodeThread::ImageRequest::processRequest() processing request test failed", res == true);
|
||||
// Check that we can call the finishing call safely
|
||||
try {
|
||||
mRequest->finishRequest(false);
|
||||
} catch (...) {
|
||||
fail("LLImageDecodeThread::ImageRequest::finishRequest() test failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3582,7 +3582,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
|
|||
if (face == -1) // ALL_SIDES
|
||||
{
|
||||
start_face = 0;
|
||||
end_face = getNumFaces() - 1;
|
||||
end_face = getNumVolumeFaces() - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -64,6 +64,9 @@ const LLUUID CATEGORIZE_LOST_AND_FOUND_ID(std::string("00000000-0000-0000-0000-0
|
|||
|
||||
const U64 TOXIC_ASSET_LIFETIME = (120 * 1000000); // microseconds
|
||||
|
||||
LLTempAssetStorage::~LLTempAssetStorage()
|
||||
{
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// LLAssetInfo
|
||||
|
|
|
|||
|
|
@ -204,7 +204,16 @@ typedef std::map<LLUUID,U64,lluuid_less> toxic_asset_map_t;
|
|||
typedef void (*LLGetAssetCallback)(LLVFS *vfs, const LLUUID &asset_id,
|
||||
LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status);
|
||||
|
||||
class LLAssetStorage
|
||||
class LLTempAssetStorage
|
||||
{
|
||||
public:
|
||||
virtual ~LLTempAssetStorage() =0;
|
||||
virtual void addTempAssetData(const LLUUID& asset_id,
|
||||
const LLUUID& agent_id,
|
||||
const std::string& host_name) = 0;
|
||||
};
|
||||
|
||||
class LLAssetStorage : public LLTempAssetStorage
|
||||
{
|
||||
public:
|
||||
// VFS member is public because static child methods need it :(
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ public:
|
|||
U32 report(CURLcode);
|
||||
void getTransferInfo(LLCurl::TransferInfo* info);
|
||||
|
||||
void prepRequest(const std::string& url, ResponderPtr, bool post = false);
|
||||
void prepRequest(const std::string& url, const std::vector<std::string>& headers, ResponderPtr, bool post = false);
|
||||
|
||||
const char* getErrorBuffer();
|
||||
|
||||
|
|
@ -432,7 +432,9 @@ size_t curlHeaderCallback(void* data, size_t size, size_t nmemb, void* user_data
|
|||
return n;
|
||||
}
|
||||
|
||||
void LLCurl::Easy::prepRequest(const std::string& url, ResponderPtr responder, bool post)
|
||||
void LLCurl::Easy::prepRequest(const std::string& url,
|
||||
const std::vector<std::string>& headers,
|
||||
ResponderPtr responder, bool post)
|
||||
{
|
||||
resetState();
|
||||
|
||||
|
|
@ -465,8 +467,13 @@ void LLCurl::Easy::prepRequest(const std::string& url, ResponderPtr responder, b
|
|||
{
|
||||
slist_append("Connection: keep-alive");
|
||||
slist_append("Keep-alive: 300");
|
||||
// Accept and other headers
|
||||
for (std::vector<std::string>::const_iterator iter = headers.begin();
|
||||
iter != headers.end(); ++iter)
|
||||
{
|
||||
slist_append((*iter).c_str());
|
||||
}
|
||||
}
|
||||
// *FIX: should have ACCEPT headers
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -676,15 +683,18 @@ LLCurlRequest::LLCurlRequest() :
|
|||
mActiveMulti(NULL),
|
||||
mActiveRequestCount(0)
|
||||
{
|
||||
mThreadID = LLThread::currentID();
|
||||
}
|
||||
|
||||
LLCurlRequest::~LLCurlRequest()
|
||||
{
|
||||
llassert_always(mThreadID == LLThread::currentID());
|
||||
for_each(mMultiSet.begin(), mMultiSet.end(), DeletePointer());
|
||||
}
|
||||
|
||||
void LLCurlRequest::addMulti()
|
||||
{
|
||||
llassert_always(mThreadID == LLThread::currentID());
|
||||
LLCurl::Multi* multi = new LLCurl::Multi();
|
||||
mMultiSet.insert(multi);
|
||||
mActiveMulti = multi;
|
||||
|
|
@ -714,17 +724,20 @@ bool LLCurlRequest::addEasy(LLCurl::Easy* easy)
|
|||
|
||||
void LLCurlRequest::get(const std::string& url, LLCurl::ResponderPtr responder)
|
||||
{
|
||||
getByteRange(url, 0, -1, responder);
|
||||
getByteRange(url, headers_t(), 0, -1, responder);
|
||||
}
|
||||
|
||||
bool LLCurlRequest::getByteRange(const std::string& url, S32 offset, S32 length, LLCurl::ResponderPtr responder)
|
||||
bool LLCurlRequest::getByteRange(const std::string& url,
|
||||
const headers_t& headers,
|
||||
S32 offset, S32 length,
|
||||
LLCurl::ResponderPtr responder)
|
||||
{
|
||||
LLCurl::Easy* easy = allocEasy();
|
||||
if (!easy)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
easy->prepRequest(url, responder);
|
||||
easy->prepRequest(url, headers, responder);
|
||||
easy->setopt(CURLOPT_HTTPGET, 1);
|
||||
if (length > 0)
|
||||
{
|
||||
|
|
@ -736,14 +749,17 @@ bool LLCurlRequest::getByteRange(const std::string& url, S32 offset, S32 length,
|
|||
return res;
|
||||
}
|
||||
|
||||
bool LLCurlRequest::post(const std::string& url, const LLSD& data, LLCurl::ResponderPtr responder)
|
||||
bool LLCurlRequest::post(const std::string& url,
|
||||
const headers_t& headers,
|
||||
const LLSD& data,
|
||||
LLCurl::ResponderPtr responder)
|
||||
{
|
||||
LLCurl::Easy* easy = allocEasy();
|
||||
if (!easy)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
easy->prepRequest(url, responder);
|
||||
easy->prepRequest(url, headers, responder);
|
||||
|
||||
LLSDSerialize::toXML(data, easy->getInput());
|
||||
S32 bytes = easy->getInput().str().length();
|
||||
|
|
@ -763,6 +779,7 @@ bool LLCurlRequest::post(const std::string& url, const LLSD& data, LLCurl::Respo
|
|||
// Note: call once per frame
|
||||
S32 LLCurlRequest::process()
|
||||
{
|
||||
llassert_always(mThreadID == LLThread::currentID());
|
||||
S32 res = 0;
|
||||
for (curlmulti_set_t::iterator iter = mMultiSet.begin();
|
||||
iter != mMultiSet.end(); )
|
||||
|
|
@ -782,6 +799,7 @@ S32 LLCurlRequest::process()
|
|||
|
||||
S32 LLCurlRequest::getQueued()
|
||||
{
|
||||
llassert_always(mThreadID == LLThread::currentID());
|
||||
S32 queued = 0;
|
||||
for (curlmulti_set_t::iterator iter = mMultiSet.begin();
|
||||
iter != mMultiSet.end(); )
|
||||
|
|
@ -1002,7 +1020,7 @@ void LLCurl::initClass()
|
|||
S32 mutex_count = CRYPTO_num_locks();
|
||||
for (S32 i=0; i<mutex_count; i++)
|
||||
{
|
||||
sSSLMutex.push_back(new LLMutex(gAPRPoolp));
|
||||
sSSLMutex.push_back(new LLMutex(NULL));
|
||||
}
|
||||
CRYPTO_set_id_callback(&LLCurl::ssl_thread_id);
|
||||
CRYPTO_set_locking_callback(&LLCurl::ssl_locking_callback);
|
||||
|
|
|
|||
|
|
@ -188,12 +188,14 @@ namespace boost
|
|||
class LLCurlRequest
|
||||
{
|
||||
public:
|
||||
typedef std::vector<std::string> headers_t;
|
||||
|
||||
LLCurlRequest();
|
||||
~LLCurlRequest();
|
||||
|
||||
void get(const std::string& url, LLCurl::ResponderPtr responder);
|
||||
bool getByteRange(const std::string& url, S32 offset, S32 length, LLCurl::ResponderPtr responder);
|
||||
bool post(const std::string& url, const LLSD& data, LLCurl::ResponderPtr responder);
|
||||
bool getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, LLCurl::ResponderPtr responder);
|
||||
bool post(const std::string& url, const headers_t& headers, const LLSD& data, LLCurl::ResponderPtr responder);
|
||||
S32 process();
|
||||
S32 getQueued();
|
||||
|
||||
|
|
@ -207,6 +209,7 @@ private:
|
|||
curlmulti_set_t mMultiSet;
|
||||
LLCurl::Multi* mActiveMulti;
|
||||
S32 mActiveRequestCount;
|
||||
U32 mThreadID; // debug
|
||||
};
|
||||
|
||||
class LLCurlEasyRequest
|
||||
|
|
|
|||
|
|
@ -20,8 +20,9 @@
|
|||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "llcurl.h"
|
||||
|
||||
LLCurl::Responder::Responder()
|
||||
LLCurl::Responder::Responder() : mReferenceCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ std::vector<std::string> put_urls;
|
|||
std::vector<LLSD> put_body;
|
||||
std::vector<boost::intrusive_ptr<LLCurl::Responder> > put_responders;
|
||||
|
||||
void LLHTTPClient::put(std::string const &url, LLSD const &body, boost::intrusive_ptr<LLCurl::Responder> responder,float)
|
||||
void LLHTTPClient::put(const std::string& url, const LLSD& body, boost::intrusive_ptr<LLCurl::Responder> responder, const LLSD& headers, const F32 timeout)
|
||||
{
|
||||
put_urls.push_back(url);
|
||||
put_responders.push_back(responder);
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@
|
|||
#include "llmath.h"
|
||||
#include "llgl.h"
|
||||
#include "llrender.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const F32 MIN_TEXTURE_LIFETIME = 10.f;
|
||||
|
||||
|
|
@ -60,21 +59,34 @@ std::list<U32> LLImageGL::sDeadTextureList;
|
|||
|
||||
BOOL LLImageGL::sGlobalUseAnisotropic = FALSE;
|
||||
F32 LLImageGL::sLastFrameTime = 0.f;
|
||||
BOOL LLImageGL::sAllowReadBackRaw = FALSE ;
|
||||
LLImageGL* LLImageGL::sDefaultGLTexture = NULL ;
|
||||
|
||||
std::set<LLImageGL*> LLImageGL::sImageList;
|
||||
|
||||
#if !LL_RELEASE_FOR_DOWNLOAD
|
||||
//****************************************************************************************************
|
||||
//The below for texture auditing use only
|
||||
//****************************************************************************************************
|
||||
//-----------------------
|
||||
//debug use
|
||||
BOOL gAuditTexture = FALSE ;
|
||||
#define MAX_TEXTURE_LOG_SIZE 22 //2048 * 2048
|
||||
std::vector<S32> LLImageGL::sTextureLoadedCounter(MAX_TEXTURE_LOG_SIZE + 1) ;
|
||||
std::vector<S32> LLImageGL::sTextureBoundCounter(MAX_TEXTURE_LOG_SIZE + 1) ;
|
||||
std::vector<S32> LLImageGL::sTextureCurBoundCounter(MAX_TEXTURE_LOG_SIZE + 1) ;
|
||||
S32 LLImageGL::sCurTexSizeBar = -1 ;
|
||||
S32 LLImageGL::sCurTexPickSize = -1 ;
|
||||
LLPointer<LLImageGL> LLImageGL::sDefaultTexturep = NULL;
|
||||
LLPointer<LLImageGL> LLImageGL::sHighlightTexturep = NULL;
|
||||
S32 LLImageGL::sMaxCatagories = 1 ;
|
||||
|
||||
std::vector<S32> LLImageGL::sTextureMemByCategory;
|
||||
std::vector<S32> LLImageGL::sTextureMemByCategoryBound ;
|
||||
std::vector<S32> LLImageGL::sTextureCurMemByCategoryBound ;
|
||||
//------------------------
|
||||
#endif
|
||||
//****************************************************************************************************
|
||||
//End for texture auditing use only
|
||||
//****************************************************************************************************
|
||||
|
||||
//**************************************************************************************
|
||||
//below are functions for debug use
|
||||
//do not delete them even though they are not currently being used.
|
||||
|
|
@ -144,6 +156,60 @@ void LLImageGL::checkTexSize() const
|
|||
//**************************************************************************************
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
BOOL is_little_endian()
|
||||
{
|
||||
S32 a = 0x12345678;
|
||||
U8 *c = (U8*)(&a);
|
||||
|
||||
return (*c == 0x78) ;
|
||||
}
|
||||
//static
|
||||
void LLImageGL::initClass(S32 num_catagories)
|
||||
{
|
||||
sMaxCatagories = num_catagories ;
|
||||
|
||||
sTextureMemByCategory.resize(sMaxCatagories);
|
||||
sTextureMemByCategoryBound.resize(sMaxCatagories) ;
|
||||
sTextureCurMemByCategoryBound.resize(sMaxCatagories) ;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLImageGL::cleanupClass()
|
||||
{
|
||||
sTextureMemByCategory.clear() ;
|
||||
sTextureMemByCategoryBound.clear() ;
|
||||
sTextureCurMemByCategoryBound.clear() ;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLImageGL::setHighlightTexture(S32 category)
|
||||
{
|
||||
const S32 dim = 128;
|
||||
sHighlightTexturep = new LLImageGL() ;
|
||||
LLPointer<LLImageRaw> image_raw = new LLImageRaw(dim,dim,3);
|
||||
U8* data = image_raw->getData();
|
||||
for (S32 i = 0; i<dim; i++)
|
||||
{
|
||||
for (S32 j = 0; j<dim; j++)
|
||||
{
|
||||
const S32 border = 2;
|
||||
if (i<border || j<border || i>=(dim-border) || j>=(dim-border))
|
||||
{
|
||||
*data++ = 0xff;
|
||||
*data++ = 0xff;
|
||||
*data++ = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
*data++ = 0xff;
|
||||
*data++ = 0xff;
|
||||
*data++ = 0x00;
|
||||
}
|
||||
}
|
||||
}
|
||||
sHighlightTexturep->createGLTexture(0, image_raw, 0, TRUE, category);
|
||||
image_raw = NULL;
|
||||
}
|
||||
|
||||
//static
|
||||
S32 LLImageGL::dataFormatBits(S32 dataformat)
|
||||
|
|
@ -211,19 +277,31 @@ void LLImageGL::updateStats(F32 current_time)
|
|||
sBoundTextureMemoryInBytes = sCurBoundTextureMemory;
|
||||
sCurBoundTextureMemory = 0;
|
||||
|
||||
#if !LL_RELEASE_FOR_DOWNLOAD
|
||||
for(U32 i = 0 ; i < sTextureCurBoundCounter.size() ; i++)
|
||||
if(gAuditTexture)
|
||||
{
|
||||
sTextureBoundCounter[i] = sTextureCurBoundCounter[i] ;
|
||||
sTextureCurBoundCounter[i] = 0 ;
|
||||
for(U32 i = 0 ; i < sTextureCurBoundCounter.size() ; i++)
|
||||
{
|
||||
sTextureBoundCounter[i] = sTextureCurBoundCounter[i] ;
|
||||
sTextureCurBoundCounter[i] = 0 ;
|
||||
}
|
||||
for(U32 i = 0 ; i < sTextureCurMemByCategoryBound.size() ; i++)
|
||||
{
|
||||
sTextureMemByCategoryBound[i] = sTextureCurMemByCategoryBound[i] ;
|
||||
sTextureCurMemByCategoryBound[i] = 0 ;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//static
|
||||
S32 LLImageGL::updateBoundTexMem(const S32 delta)
|
||||
S32 LLImageGL::updateBoundTexMem(const S32 mem, const S32 ncomponents, S32 category)
|
||||
{
|
||||
LLImageGL::sCurBoundTextureMemory += delta;
|
||||
if(gAuditTexture && ncomponents > 0 && category > -1)
|
||||
{
|
||||
sTextureCurBoundCounter[getTextureCounterIndex(mem / ncomponents)]++ ;
|
||||
sTextureCurMemByCategoryBound[category] += mem ;
|
||||
}
|
||||
|
||||
LLImageGL::sCurBoundTextureMemory += mem ;
|
||||
return LLImageGL::sCurBoundTextureMemory;
|
||||
}
|
||||
|
||||
|
|
@ -237,6 +315,7 @@ void LLImageGL::destroyGL(BOOL save_state)
|
|||
gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
}
|
||||
|
||||
sAllowReadBackRaw = true ;
|
||||
for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
|
||||
iter != sImageList.end(); iter++)
|
||||
{
|
||||
|
|
@ -246,7 +325,7 @@ void LLImageGL::destroyGL(BOOL save_state)
|
|||
if (save_state && glimage->isGLTextureCreated() && glimage->mComponents)
|
||||
{
|
||||
glimage->mSaveData = new LLImageRaw;
|
||||
if(!glimage->readBackRaw(glimage->mCurrentDiscardLevel, glimage->mSaveData, false))
|
||||
if(!glimage->readBackRaw(glimage->mCurrentDiscardLevel, glimage->mSaveData, false)) //necessary, keep it.
|
||||
{
|
||||
glimage->mSaveData = NULL ;
|
||||
}
|
||||
|
|
@ -256,6 +335,7 @@ void LLImageGL::destroyGL(BOOL save_state)
|
|||
stop_glerror();
|
||||
}
|
||||
}
|
||||
sAllowReadBackRaw = false ;
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
@ -273,7 +353,7 @@ void LLImageGL::restoreGL()
|
|||
{
|
||||
if (glimage->getComponents() && glimage->mSaveData->getComponents())
|
||||
{
|
||||
glimage->createGLTexture(glimage->mCurrentDiscardLevel, glimage->mSaveData);
|
||||
glimage->createGLTexture(glimage->mCurrentDiscardLevel, glimage->mSaveData, 0, TRUE, glimage->getCategory());
|
||||
stop_glerror();
|
||||
}
|
||||
glimage->mSaveData = NULL; // deletes data
|
||||
|
|
@ -355,7 +435,7 @@ void LLImageGL::init(BOOL usemipmaps)
|
|||
mPickMask = NULL;
|
||||
mTextureMemory = 0;
|
||||
mLastBindTime = 0.f;
|
||||
|
||||
|
||||
mTarget = GL_TEXTURE_2D;
|
||||
mBindTarget = LLTexUnit::TT_TEXTURE;
|
||||
mUseMipMaps = usemipmaps;
|
||||
|
|
@ -381,7 +461,11 @@ void LLImageGL::init(BOOL usemipmaps)
|
|||
mHasExplicitFormat = FALSE;
|
||||
|
||||
mGLTextureCreated = FALSE ;
|
||||
|
||||
mIsMask = FALSE;
|
||||
mCategory = -1 ;
|
||||
mAlphaStride = 0 ;
|
||||
mAlphaOffset = 0 ;
|
||||
mNeedsAlphaAndPickMask = TRUE ;
|
||||
|
||||
mDiscardLevelInAtlas = -1 ;
|
||||
|
|
@ -486,6 +570,10 @@ void LLImageGL::dump()
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void LLImageGL::forceUpdateBindStats(void) const
|
||||
{
|
||||
mLastBindTime = sLastFrameTime;
|
||||
}
|
||||
|
||||
BOOL LLImageGL::updateBindStats(S32 tex_mem) const
|
||||
{
|
||||
|
|
@ -499,7 +587,7 @@ BOOL LLImageGL::updateBindStats(S32 tex_mem) const
|
|||
{
|
||||
// we haven't accounted for this texture yet this frame
|
||||
sUniqueCount++;
|
||||
updateBoundTexMem(tex_mem);
|
||||
updateBoundTexMem(tex_mem, mComponents, mCategory);
|
||||
mLastBindTime = sLastFrameTime;
|
||||
|
||||
return TRUE ;
|
||||
|
|
@ -525,6 +613,8 @@ void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_for
|
|||
else
|
||||
mFormatType = type_format;
|
||||
mFormatSwapBytes = swap_bytes;
|
||||
|
||||
calcAlphaChannelOffsetAndStride() ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
@ -540,7 +630,6 @@ void LLImageGL::setImage(const LLImageRaw* imageraw)
|
|||
|
||||
void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
|
||||
{
|
||||
llpushcallstacks ;
|
||||
bool is_compressed = false;
|
||||
if (mFormatPrimary >= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && mFormatPrimary <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
|
||||
{
|
||||
|
|
@ -749,7 +838,6 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
|
|||
}
|
||||
stop_glerror();
|
||||
mGLTextureCreated = true;
|
||||
llpushcallstacks ;
|
||||
}
|
||||
|
||||
BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
|
||||
|
|
@ -840,7 +928,6 @@ void LLImageGL::postAddToAtlas()
|
|||
|
||||
BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update)
|
||||
{
|
||||
llpushcallstacks ;
|
||||
if (!width || !height)
|
||||
{
|
||||
return TRUE;
|
||||
|
|
@ -930,7 +1017,6 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
|
|||
stop_glerror();
|
||||
mGLTextureCreated = true;
|
||||
}
|
||||
llpushcallstacks ;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -942,8 +1028,9 @@ BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S3
|
|||
// Copy sub image from frame buffer
|
||||
BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height)
|
||||
{
|
||||
if (gGL.getTexUnit(0)->bind(this))
|
||||
if (gGL.getTexUnit(0)->bind(this, false, true))
|
||||
{
|
||||
//checkTexSize() ;
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height);
|
||||
mGLTextureCreated = true;
|
||||
stop_glerror();
|
||||
|
|
@ -1007,7 +1094,7 @@ BOOL LLImageGL::createGLTexture()
|
|||
return TRUE ;
|
||||
}
|
||||
|
||||
BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/)
|
||||
BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category)
|
||||
{
|
||||
if (gGLManager.mIsDisabled)
|
||||
{
|
||||
|
|
@ -1027,8 +1114,10 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
|
|||
discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
|
||||
|
||||
// Actual image width/height = raw image width/height * 2^discard_level
|
||||
S32 w = imageraw->getWidth() << discard_level;
|
||||
S32 h = imageraw->getHeight() << discard_level;
|
||||
S32 raw_w = imageraw->getWidth() ;
|
||||
S32 raw_h = imageraw->getHeight() ;
|
||||
S32 w = raw_w << discard_level;
|
||||
S32 h = raw_h << discard_level;
|
||||
|
||||
// setSize may call destroyGLTexture if the size does not match
|
||||
setSize(w, h, imageraw->getComponents());
|
||||
|
|
@ -1062,15 +1151,25 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
|
|||
default:
|
||||
llerrs << "Bad number of components for texture: " << (U32)getComponents() << llendl;
|
||||
}
|
||||
|
||||
calcAlphaChannelOffsetAndStride() ;
|
||||
}
|
||||
|
||||
if(!to_create) //not create a gl texture
|
||||
{
|
||||
destroyGLTexture();
|
||||
mCurrentDiscardLevel = discard_level;
|
||||
mLastBindTime = sLastFrameTime;
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
setCategory(category) ;
|
||||
const U8* rawdata = imageraw->getData();
|
||||
return createGLTexture(discard_level, rawdata, FALSE, usename);
|
||||
}
|
||||
|
||||
BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename)
|
||||
{
|
||||
llpushcallstacks ;
|
||||
llassert(data_in);
|
||||
|
||||
if (discard_level < 0)
|
||||
|
|
@ -1137,11 +1236,14 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
|||
if (old_name != 0)
|
||||
{
|
||||
sGlobalTextureMemoryInBytes -= mTextureMemory;
|
||||
#if !LL_RELEASE_FOR_DOWNLOAD
|
||||
decTextureCounter(mTextureMemory / mComponents) ;
|
||||
#endif
|
||||
|
||||
if(gAuditTexture)
|
||||
{
|
||||
decTextureCounter(mTextureMemory, mComponents, mCategory) ;
|
||||
}
|
||||
|
||||
LLImageGL::deleteTextures(1, &old_name);
|
||||
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
|
|
@ -1149,82 +1251,20 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
|||
sGlobalTextureMemoryInBytes += mTextureMemory;
|
||||
mTexelsInGLTexture = getWidth() * getHeight() ;
|
||||
|
||||
#if !LL_RELEASE_FOR_DOWNLOAD
|
||||
incTextureCounter(mTextureMemory / mComponents) ;
|
||||
#endif
|
||||
|
||||
if(gAuditTexture)
|
||||
{
|
||||
incTextureCounter(mTextureMemory, mComponents, mCategory) ;
|
||||
}
|
||||
// mark this as bound at this point, so we don't throw it out immediately
|
||||
mLastBindTime = sLastFrameTime;
|
||||
|
||||
llpushcallstacks ;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLImageGL::setDiscardLevel(S32 discard_level)
|
||||
{
|
||||
llassert(discard_level >= 0);
|
||||
llassert(mCurrentDiscardLevel >= 0);
|
||||
|
||||
discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
|
||||
|
||||
if (discard_level == mCurrentDiscardLevel)
|
||||
{
|
||||
// nothing to do
|
||||
return FALSE;
|
||||
}
|
||||
else if (discard_level < mCurrentDiscardLevel)
|
||||
{
|
||||
// larger image
|
||||
dump();
|
||||
llerrs << "LLImageGL::setDiscardLevel() called with larger discard level; use createGLTexture()" << llendl;
|
||||
return FALSE;
|
||||
}
|
||||
else if (mUseMipMaps)
|
||||
{
|
||||
LLPointer<LLImageRaw> imageraw = new LLImageRaw;
|
||||
while(discard_level > mCurrentDiscardLevel)
|
||||
{
|
||||
if (readBackRaw(discard_level, imageraw, false))
|
||||
{
|
||||
break;
|
||||
}
|
||||
discard_level--;
|
||||
}
|
||||
if (discard_level == mCurrentDiscardLevel)
|
||||
{
|
||||
// unable to increase the discard level
|
||||
return FALSE;
|
||||
}
|
||||
return createGLTexture(discard_level, imageraw);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if !LL_LINUX && !LL_SOLARIS
|
||||
// *FIX: This should not be skipped for the linux client.
|
||||
llerrs << "LLImageGL::setDiscardLevel() called on image without mipmaps" << llendl;
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLImageGL::isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents)
|
||||
{
|
||||
assert_glerror();
|
||||
S32 gl_discard = discard_level - mCurrentDiscardLevel;
|
||||
LLGLint glwidth = 0;
|
||||
glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_WIDTH, (GLint*)&glwidth);
|
||||
LLGLint glheight = 0;
|
||||
glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_HEIGHT, (GLint*)&glheight);
|
||||
LLGLint glcomponents = 0 ;
|
||||
glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_INTERNAL_FORMAT, (GLint*)&glcomponents);
|
||||
assert_glerror();
|
||||
|
||||
return glwidth >= image_width && glheight >= image_height && (GL_RGB8 == glcomponents || GL_RGBA8 == glcomponents) ;
|
||||
}
|
||||
|
||||
BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const
|
||||
{
|
||||
llpushcallstacks ;
|
||||
llassert_always(sAllowReadBackRaw) ;
|
||||
//llerrs << "should not call this function!" << llendl ;
|
||||
|
||||
if (discard_level < 0)
|
||||
{
|
||||
discard_level = mCurrentDiscardLevel;
|
||||
|
|
@ -1327,7 +1367,7 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
|
|||
return FALSE ;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
llpushcallstacks ;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
|
@ -1345,25 +1385,26 @@ void LLImageGL::deleteDeadTextures()
|
|||
stop_glerror();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
glDeleteTextures(1, &tex);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLImageGL::destroyGLTexture()
|
||||
{
|
||||
if (mTexName != 0)
|
||||
{
|
||||
if(mTextureMemory)
|
||||
{
|
||||
#if !LL_RELEASE_FOR_DOWNLOAD
|
||||
decTextureCounter(mTextureMemory / mComponents) ;
|
||||
#endif
|
||||
if(gAuditTexture)
|
||||
{
|
||||
decTextureCounter(mTextureMemory, mComponents, mCategory) ;
|
||||
}
|
||||
sGlobalTextureMemoryInBytes -= mTextureMemory;
|
||||
mTextureMemory = 0;
|
||||
}
|
||||
|
||||
|
||||
LLImageGL::deleteTextures(1, &mTexName);
|
||||
mTexName = 0;
|
||||
mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
|
||||
|
|
@ -1479,6 +1520,11 @@ S32 LLImageGL::getMipBytes(S32 discard_level) const
|
|||
return res;
|
||||
}
|
||||
|
||||
BOOL LLImageGL::isJustBound() const
|
||||
{
|
||||
return (BOOL)(sLastFrameTime - mLastBindTime < 0.5f);
|
||||
}
|
||||
|
||||
BOOL LLImageGL::getBoundRecently() const
|
||||
{
|
||||
return (BOOL)(sLastFrameTime - mLastBindTime < MIN_TEXTURE_LIFETIME);
|
||||
|
|
@ -1490,6 +1536,95 @@ void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType b
|
|||
mBindTarget = bind_target;
|
||||
}
|
||||
|
||||
const S8 INVALID_OFFSET = -99 ;
|
||||
void LLImageGL::setNeedsAlphaAndPickMask(BOOL need_mask)
|
||||
{
|
||||
if(mNeedsAlphaAndPickMask != need_mask)
|
||||
{
|
||||
mNeedsAlphaAndPickMask = need_mask;
|
||||
|
||||
if(mNeedsAlphaAndPickMask)
|
||||
{
|
||||
mAlphaOffset = 0 ;
|
||||
}
|
||||
else //do not need alpha mask
|
||||
{
|
||||
mAlphaOffset = INVALID_OFFSET ;
|
||||
mIsMask = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLImageGL::calcAlphaChannelOffsetAndStride()
|
||||
{
|
||||
if(mAlphaOffset == INVALID_OFFSET)//do not need alpha mask
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
mAlphaStride = -1 ;
|
||||
switch (mFormatPrimary)
|
||||
{
|
||||
case GL_LUMINANCE:
|
||||
case GL_ALPHA:
|
||||
mAlphaStride = 1;
|
||||
break;
|
||||
case GL_LUMINANCE_ALPHA:
|
||||
mAlphaStride = 2;
|
||||
break;
|
||||
case GL_RGB:
|
||||
mNeedsAlphaAndPickMask = FALSE ;
|
||||
mIsMask = FALSE;
|
||||
return ; //no alpha channel.
|
||||
case GL_RGBA:
|
||||
mAlphaStride = 4;
|
||||
break;
|
||||
case GL_BGRA_EXT:
|
||||
mAlphaStride = 4;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
mAlphaOffset = -1 ;
|
||||
if (mFormatType == GL_UNSIGNED_BYTE)
|
||||
{
|
||||
mAlphaOffset = mAlphaStride - 1 ;
|
||||
}
|
||||
else if(is_little_endian())
|
||||
{
|
||||
if (mFormatType == GL_UNSIGNED_INT_8_8_8_8)
|
||||
{
|
||||
mAlphaOffset = 0 ;
|
||||
}
|
||||
else if (mFormatType == GL_UNSIGNED_INT_8_8_8_8_REV)
|
||||
{
|
||||
mAlphaOffset = 3 ;
|
||||
}
|
||||
}
|
||||
else //big endian
|
||||
{
|
||||
if (mFormatType == GL_UNSIGNED_INT_8_8_8_8)
|
||||
{
|
||||
mAlphaOffset = 3 ;
|
||||
}
|
||||
else if (mFormatType == GL_UNSIGNED_INT_8_8_8_8_REV)
|
||||
{
|
||||
mAlphaOffset = 0 ;
|
||||
}
|
||||
}
|
||||
|
||||
if( mAlphaStride < 1 || //unsupported format
|
||||
mAlphaOffset < 0 || //unsupported type
|
||||
(mFormatPrimary == GL_BGRA_EXT && mFormatType != GL_UNSIGNED_BYTE)) //unknown situation
|
||||
{
|
||||
llwarns << "Cannot analyze alpha for image with format type " << std::hex << mFormatType << std::dec << llendl;
|
||||
|
||||
mNeedsAlphaAndPickMask = FALSE ;
|
||||
mIsMask = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h)
|
||||
{
|
||||
if(!mNeedsAlphaAndPickMask)
|
||||
|
|
@ -1497,37 +1632,8 @@ void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h)
|
|||
return ;
|
||||
}
|
||||
|
||||
if (mFormatType != GL_UNSIGNED_BYTE)
|
||||
{
|
||||
llwarns << "Cannot analyze alpha for image with format type " << std::hex << mFormatType << std::dec << llendl;
|
||||
}
|
||||
|
||||
U32 stride = 0;
|
||||
switch (mFormatPrimary)
|
||||
{
|
||||
case GL_LUMINANCE:
|
||||
case GL_ALPHA:
|
||||
stride = 1;
|
||||
break;
|
||||
case GL_LUMINANCE_ALPHA:
|
||||
stride = 2;
|
||||
break;
|
||||
case GL_RGB:
|
||||
//no alpha
|
||||
mIsMask = FALSE;
|
||||
return;
|
||||
case GL_RGBA:
|
||||
stride = 4;
|
||||
break;
|
||||
case GL_BGRA_EXT:
|
||||
stride = 4;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
U32 length = w * h;
|
||||
const GLubyte* current = ((const GLubyte*) data_in)+stride-1;
|
||||
const GLubyte* current = ((const GLubyte*) data_in) + mAlphaOffset ;
|
||||
|
||||
S32 sample[16];
|
||||
memset(sample, 0, sizeof(S32)*16);
|
||||
|
|
@ -1535,7 +1641,7 @@ void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h)
|
|||
for (U32 i = 0; i < length; i++)
|
||||
{
|
||||
++sample[*current/16];
|
||||
current += stride;
|
||||
current += mAlphaStride ;
|
||||
}
|
||||
|
||||
U32 total = 0;
|
||||
|
|
@ -1638,8 +1744,30 @@ BOOL LLImageGL::getMask(const LLVector2 &tc)
|
|||
return res;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
#if !LL_RELEASE_FOR_DOWNLOAD
|
||||
void LLImageGL::setCategory(S32 category)
|
||||
{
|
||||
if(!gAuditTexture)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
if(mCategory != category)
|
||||
{
|
||||
if(mCategory > -1)
|
||||
{
|
||||
sTextureMemByCategory[mCategory] -= mTextureMemory ;
|
||||
}
|
||||
if(category > -1 && category < sMaxCatagories)
|
||||
{
|
||||
sTextureMemByCategory[category] += mTextureMemory ;
|
||||
mCategory = category;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCategory = -1 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//for debug use
|
||||
//val is a "power of two" number
|
||||
S32 LLImageGL::getTextureCounterIndex(U32 val)
|
||||
|
|
@ -1663,18 +1791,33 @@ S32 LLImageGL::getTextureCounterIndex(U32 val)
|
|||
return ret ;
|
||||
}
|
||||
}
|
||||
void LLImageGL::incTextureCounter(U32 val)
|
||||
|
||||
//static
|
||||
void LLImageGL::incTextureCounter(U32 val, S32 ncomponents, S32 category)
|
||||
{
|
||||
sTextureLoadedCounter[getTextureCounterIndex(val)]++ ;
|
||||
sTextureMemByCategory[category] += (S32)val * ncomponents ;
|
||||
}
|
||||
void LLImageGL::decTextureCounter(U32 val)
|
||||
|
||||
//static
|
||||
void LLImageGL::decTextureCounter(U32 val, S32 ncomponents, S32 category)
|
||||
{
|
||||
sTextureLoadedCounter[getTextureCounterIndex(val)]-- ;
|
||||
sTextureMemByCategory[category] += (S32)val * ncomponents ;
|
||||
}
|
||||
void LLImageGL::setCurTexSizebar(S32 index)
|
||||
|
||||
void LLImageGL::setCurTexSizebar(S32 index, BOOL set_pick_size)
|
||||
{
|
||||
sCurTexSizeBar = index ;
|
||||
sCurTexPickSize = (1 << index) ;
|
||||
|
||||
if(set_pick_size)
|
||||
{
|
||||
sCurTexPickSize = (1 << index) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
sCurTexPickSize = -1 ;
|
||||
}
|
||||
}
|
||||
void LLImageGL::resetCurTexSizebar()
|
||||
{
|
||||
|
|
@ -1682,7 +1825,9 @@ void LLImageGL::resetCurTexSizebar()
|
|||
sCurTexPickSize = -1 ;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Manual Mip Generation
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ class LLTextureAtlas ;
|
|||
#define MEGA_BYTES_TO_BYTES(x) ((x) << 20)
|
||||
|
||||
//============================================================================
|
||||
|
||||
class LLImageGL : public LLRefCount
|
||||
{
|
||||
friend class LLTexUnit;
|
||||
|
|
@ -63,6 +62,7 @@ public:
|
|||
|
||||
BOOL updateBindStats(S32 tex_mem) const ;
|
||||
F32 getTimePassedSinceLastBound();
|
||||
void forceUpdateBindStats(void) const;
|
||||
|
||||
// needs to be called every frame
|
||||
static void updateStats(F32 current_time);
|
||||
|
|
@ -71,8 +71,9 @@ public:
|
|||
static void destroyGL(BOOL save_state = TRUE);
|
||||
static void restoreGL();
|
||||
|
||||
// Sometimes called externally for textures not using LLImageGL (should go away...)
|
||||
static S32 updateBoundTexMem(const S32 delta);
|
||||
// Sometimes called externally for textures not using LLImageGL (should go away...)
|
||||
static S32 updateBoundTexMem(const S32 mem, const S32 ncomponents, S32 category) ;
|
||||
|
||||
static bool checkSize(S32 width, S32 height);
|
||||
|
||||
//for server side use only.
|
||||
|
|
@ -91,6 +92,7 @@ protected:
|
|||
virtual ~LLImageGL();
|
||||
|
||||
void analyzeAlpha(const void* data_in, S32 w, S32 h);
|
||||
void calcAlphaChannelOffsetAndStride();
|
||||
|
||||
public:
|
||||
virtual void dump(); // debugging info to llinfos
|
||||
|
|
@ -105,14 +107,15 @@ public:
|
|||
static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels);
|
||||
|
||||
BOOL createGLTexture() ;
|
||||
BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0);
|
||||
BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE,
|
||||
S32 category = sMaxCatagories - 1);
|
||||
BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0);
|
||||
void setImage(const LLImageRaw* imageraw);
|
||||
void setImage(const U8* data_in, BOOL data_hasmips = FALSE);
|
||||
BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE);
|
||||
BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE);
|
||||
BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height);
|
||||
BOOL setDiscardLevel(S32 discard_level);
|
||||
|
||||
// Read back a raw image for this discard level, if it exists
|
||||
BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const;
|
||||
void destroyGLTexture();
|
||||
|
|
@ -131,6 +134,7 @@ public:
|
|||
S32 getBytes(S32 discard_level = -1) const;
|
||||
S32 getMipBytes(S32 discard_level = -1) const;
|
||||
BOOL getBoundRecently() const;
|
||||
BOOL isJustBound() const;
|
||||
LLGLenum getPrimaryFormat() const { return mFormatPrimary; }
|
||||
LLGLenum getFormatType() const { return mFormatType; }
|
||||
|
||||
|
|
@ -150,8 +154,6 @@ public:
|
|||
BOOL getUseMipMaps() const { return mUseMipMaps; }
|
||||
void setUseMipMaps(BOOL usemips) { mUseMipMaps = usemips; }
|
||||
|
||||
BOOL isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) ;
|
||||
|
||||
void updatePickMask(S32 width, S32 height, const U8* data_in);
|
||||
BOOL getMask(const LLVector2 &tc);
|
||||
|
||||
|
|
@ -178,7 +180,7 @@ public:
|
|||
void init(BOOL usemipmaps);
|
||||
virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors
|
||||
|
||||
void setNeedsAlphaAndPickMask(BOOL need_mask) {mNeedsAlphaAndPickMask = need_mask;}
|
||||
void setNeedsAlphaAndPickMask(BOOL need_mask);
|
||||
|
||||
BOOL preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image);
|
||||
void postAddToAtlas() ;
|
||||
|
|
@ -187,7 +189,7 @@ public:
|
|||
// Various GL/Rendering options
|
||||
S32 mTextureMemory;
|
||||
mutable F32 mLastBindTime; // last time this was bound, by discard level
|
||||
|
||||
|
||||
private:
|
||||
LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL
|
||||
U8* mPickMask; //downsampled bitmap approximation of alpha channel. NULL if no alpha channel
|
||||
|
|
@ -197,13 +199,15 @@ private:
|
|||
|
||||
BOOL mIsMask;
|
||||
BOOL mNeedsAlphaAndPickMask;
|
||||
|
||||
S8 mAlphaStride ;
|
||||
S8 mAlphaOffset ;
|
||||
|
||||
bool mGLTextureCreated ;
|
||||
LLGLuint mTexName;
|
||||
U16 mWidth;
|
||||
U16 mHeight;
|
||||
S8 mCurrentDiscardLevel;
|
||||
|
||||
|
||||
S8 mDiscardLevelInAtlas;
|
||||
U32 mTexelsInAtlas ;
|
||||
U32 mTexelsInGLTexture;
|
||||
|
|
@ -233,7 +237,7 @@ public:
|
|||
static S32 sCount;
|
||||
|
||||
static F32 sLastFrameTime;
|
||||
|
||||
|
||||
static LLGLuint sCurrentBoundTextures[MAX_GL_TEXTURE_UNITS]; // Currently bound texture ID
|
||||
|
||||
// Global memory statistics
|
||||
|
|
@ -246,30 +250,61 @@ public:
|
|||
static LLImageGL* sDefaultGLTexture ;
|
||||
static BOOL sAutomatedTest;
|
||||
|
||||
#if !LL_RELEASE_FOR_DOWNLOAD
|
||||
//for debug use: show texture size distribution
|
||||
//----------------------------------------
|
||||
static LLPointer<LLImageGL> sDefaultTexturep; //default texture to replace normal textures
|
||||
static std::vector<S32> sTextureLoadedCounter ;
|
||||
static std::vector<S32> sTextureBoundCounter ;
|
||||
static std::vector<S32> sTextureCurBoundCounter ;
|
||||
static S32 sCurTexSizeBar ;
|
||||
static S32 sCurTexPickSize ;
|
||||
|
||||
static S32 getTextureCounterIndex(U32 val) ;
|
||||
static void incTextureCounter(U32 val) ;
|
||||
static void decTextureCounter(U32 val) ;
|
||||
static void setCurTexSizebar(S32 index) ;
|
||||
static void resetCurTexSizebar();
|
||||
//----------------------------------------
|
||||
#endif
|
||||
|
||||
#if DEBUG_MISS
|
||||
BOOL mMissed; // Missed on last bind?
|
||||
BOOL getMissed() const { return mMissed; };
|
||||
#else
|
||||
BOOL getMissed() const { return FALSE; };
|
||||
#endif
|
||||
|
||||
public:
|
||||
static void initClass(S32 num_catagories) ;
|
||||
static void cleanupClass() ;
|
||||
private:
|
||||
static S32 sMaxCatagories ;
|
||||
|
||||
//the flag to allow to call readBackRaw(...).
|
||||
//can be removed if we do not use that function at all.
|
||||
static BOOL sAllowReadBackRaw ;
|
||||
//
|
||||
//****************************************************************************************************
|
||||
//The below for texture auditing use only
|
||||
//****************************************************************************************************
|
||||
private:
|
||||
S32 mCategory ;
|
||||
public:
|
||||
void setCategory(S32 category) ;
|
||||
S32 getCategory()const {return mCategory ;}
|
||||
|
||||
//for debug use: show texture size distribution
|
||||
//----------------------------------------
|
||||
static LLPointer<LLImageGL> sHighlightTexturep; //default texture to replace normal textures
|
||||
static std::vector<S32> sTextureLoadedCounter ;
|
||||
static std::vector<S32> sTextureBoundCounter ;
|
||||
static std::vector<S32> sTextureCurBoundCounter ;
|
||||
static S32 sCurTexSizeBar ;
|
||||
static S32 sCurTexPickSize ;
|
||||
|
||||
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 setCurTexSizebar(S32 index, BOOL set_pick_size = TRUE) ;
|
||||
static void resetCurTexSizebar();
|
||||
//----------------------------------------
|
||||
|
||||
//for debug use: show texture category distribution
|
||||
//----------------------------------------
|
||||
|
||||
static std::vector<S32> sTextureMemByCategory;
|
||||
static std::vector<S32> sTextureMemByCategoryBound ;
|
||||
static std::vector<S32> sTextureCurMemByCategoryBound ;
|
||||
//----------------------------------------
|
||||
//****************************************************************************************************
|
||||
//End of definitions for texture auditing use only
|
||||
//****************************************************************************************************
|
||||
|
||||
};
|
||||
|
||||
extern BOOL gAuditTexture;
|
||||
#endif // LL_LLIMAGEGL_H
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ void LLTexUnit::disable(void)
|
|||
}
|
||||
}
|
||||
|
||||
bool LLTexUnit::bind(LLTexture* texture, bool forceBind)
|
||||
bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
|
||||
{
|
||||
stop_glerror();
|
||||
if (mIndex < 0) return false;
|
||||
|
|
@ -198,9 +198,19 @@ bool LLTexUnit::bind(LLTexture* texture, bool forceBind)
|
|||
//if deleted, will re-generate it immediately
|
||||
texture->forceImmediateUpdate() ;
|
||||
|
||||
gl_tex->forceUpdateBindStats() ;
|
||||
return texture->bindDefaultImage(mIndex);
|
||||
}
|
||||
|
||||
//in audit, replace the selected texture by the default one.
|
||||
if(gAuditTexture && for_rendering && LLImageGL::sCurTexPickSize > 0)
|
||||
{
|
||||
if(texture->getWidth() * texture->getHeight() == LLImageGL::sCurTexPickSize)
|
||||
{
|
||||
gl_tex->updateBindStats(gl_tex->mTextureMemory);
|
||||
return bind(LLImageGL::sHighlightTexturep.get());
|
||||
}
|
||||
}
|
||||
if ((mCurrTexture != gl_tex->getTexName()) || forceBind)
|
||||
{
|
||||
activate();
|
||||
|
|
@ -223,7 +233,7 @@ bool LLTexUnit::bind(LLTexture* texture, bool forceBind)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool LLTexUnit::bind(LLImageGL* texture, bool forceBind)
|
||||
bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind)
|
||||
{
|
||||
stop_glerror();
|
||||
if (mIndex < 0) return false;
|
||||
|
|
@ -260,6 +270,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool forceBind)
|
|||
setTextureFilteringOption(texture->mFilterOption);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -149,8 +149,8 @@ public:
|
|||
|
||||
// Binds the LLImageGL to this texture unit
|
||||
// (automatically enables the unit for the LLImageGL's texture type)
|
||||
bool bind(LLImageGL* texture, bool forceBind = false);
|
||||
bool bind(LLTexture* texture, bool forceBind = false);
|
||||
bool bind(LLImageGL* texture, bool for_rendering = false, bool forceBind = false);
|
||||
bool bind(LLTexture* texture, bool for_rendering = false, bool forceBind = false);
|
||||
|
||||
// Binds a cubemap to this texture unit
|
||||
// (automatically enables the texture unit for cubemaps)
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ public:
|
|||
//
|
||||
//interfaces to access LLViewerTexture
|
||||
//
|
||||
virtual bool bindDefaultImage(const S32 stage = 0) const = 0 ;
|
||||
virtual bool bindDefaultImage(const S32 stage = 0) = 0 ;
|
||||
virtual void forceImmediateUpdate() = 0 ;
|
||||
virtual void setActive() = 0 ;
|
||||
virtual S32 getWidth(S32 discard_level = -1) const = 0 ;
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ bool LLLFSThread::Request::processRequest()
|
|||
{
|
||||
llassert(mOffset >= 0);
|
||||
LLAPRFile infile ;
|
||||
infile.open(mThread->getLocalAPRFilePool(), mFileName, LL_APR_RB);
|
||||
infile.open(mFileName, LL_APR_RB, mThread->getLocalAPRFilePool());
|
||||
if (!infile.getFileHandle())
|
||||
{
|
||||
llwarns << "LLLFS: Unable to read file: " << mFileName << llendl;
|
||||
|
|
@ -213,7 +213,7 @@ bool LLLFSThread::Request::processRequest()
|
|||
if (mOffset < 0)
|
||||
flags |= APR_APPEND;
|
||||
LLAPRFile outfile ;
|
||||
outfile.open(mThread->getLocalAPRFilePool(), mFileName, flags);
|
||||
outfile.open(mFileName, flags, mThread->getLocalAPRFilePool());
|
||||
if (!outfile.getFileHandle())
|
||||
{
|
||||
llwarns << "LLLFS: Unable to write file: " << mFileName << llendl;
|
||||
|
|
|
|||
|
|
@ -265,7 +265,6 @@ set(viewer_SOURCE_FILES
|
|||
llmaniprotate.cpp
|
||||
llmanipscale.cpp
|
||||
llmaniptranslate.cpp
|
||||
llmapresponders.cpp
|
||||
llmediactrl.cpp
|
||||
llmediadataclient.cpp
|
||||
llmediaremotectrl.cpp
|
||||
|
|
@ -387,6 +386,10 @@ set(viewer_SOURCE_FILES
|
|||
lltexturecache.cpp
|
||||
lltexturectrl.cpp
|
||||
lltexturefetch.cpp
|
||||
lltextureinfo.cpp
|
||||
lltextureinfodetails.cpp
|
||||
lltexturestats.cpp
|
||||
lltexturestatsuploader.cpp
|
||||
lltextureview.cpp
|
||||
lltoast.cpp
|
||||
lltoastalertpanel.cpp
|
||||
|
|
@ -508,6 +511,8 @@ set(viewer_SOURCE_FILES
|
|||
llwlparamset.cpp
|
||||
llworld.cpp
|
||||
llworldmap.cpp
|
||||
llworldmapmessage.cpp
|
||||
llworldmipmap.cpp
|
||||
llworldmapview.cpp
|
||||
llxmlrpctransaction.cpp
|
||||
noise.cpp
|
||||
|
|
@ -738,7 +743,6 @@ set(viewer_HEADER_FILES
|
|||
llmaniprotate.h
|
||||
llmanipscale.h
|
||||
llmaniptranslate.h
|
||||
llmapresponders.h
|
||||
llmediadataclient.h
|
||||
llmediaremotectrl.h
|
||||
llmemoryview.h
|
||||
|
|
@ -859,6 +863,10 @@ set(viewer_HEADER_FILES
|
|||
lltexturecache.h
|
||||
lltexturectrl.h
|
||||
lltexturefetch.h
|
||||
lltextureinfo.h
|
||||
lltextureinfodetails.h
|
||||
lltexturestats.h
|
||||
lltexturestatsuploader.h
|
||||
lltextureview.h
|
||||
lltoast.h
|
||||
lltoastalertpanel.h
|
||||
|
|
@ -982,6 +990,8 @@ set(viewer_HEADER_FILES
|
|||
llwlparamset.h
|
||||
llworld.h
|
||||
llworldmap.h
|
||||
llworldmapmessage.h
|
||||
llworldmipmap.h
|
||||
llworldmapview.h
|
||||
llxmlrpctransaction.h
|
||||
macmain.h
|
||||
|
|
@ -1574,6 +1584,12 @@ LL_ADD_INTEGRATION_TEST(llcapabilitylistener
|
|||
)
|
||||
|
||||
#ADD_VIEWER_BUILD_TEST(llmemoryview viewer)
|
||||
#ADD_VIEWER_BUILD_TEST(llagentaccess viewer)
|
||||
#ADD_VIEWER_BUILD_TEST(llworldmap viewer)
|
||||
#ADD_VIEWER_BUILD_TEST(llworldmipmap viewer)
|
||||
#ADD_VIEWER_BUILD_TEST(lltextureinfo viewer)
|
||||
#ADD_VIEWER_BUILD_TEST(lltextureinfodetails viewer)
|
||||
#ADD_VIEWER_BUILD_TEST(lltexturestatsuploader viewer)
|
||||
|
||||
|
||||
# Don't do these for DARWIN or LINUX here -- they're taken care of by viewer_manifest.py
|
||||
|
|
|
|||
|
|
@ -309,7 +309,18 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AutoAcceptNewInventory</key>
|
||||
<key>AuditTexture</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enable texture auditting.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>AutoAcceptNewInventory</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Automatically accept new notecards/textures/landmarks</string>
|
||||
|
|
@ -4545,6 +4556,17 @@
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>MiniMapPrimMaxRadius</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Radius of the largest prim to show on the MiniMap. Increasing beyond 256 may cause client lag.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>256.0</real>
|
||||
</map>
|
||||
<key>MiniMapRotate</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -4559,7 +4581,7 @@
|
|||
<key>MiniMapScale</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Miniature world map zoom levle (pixels per region)</string>
|
||||
<string>Miniature world map zoom level (pixels per region)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -8468,6 +8490,28 @@
|
|||
<key>Value</key>
|
||||
<real>20.0</real>
|
||||
</map>
|
||||
<key>TextureDisable</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>If TRUE, do not load textures for in-world content</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>TextureLoadFullRes</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>If TRUE, always load textures at full resolution (discard = 0)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>TextureMemory</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -10537,5 +10581,38 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
</map>
|
||||
<key>LogTextureDownloadsToViewerLog</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Send texture download details to the viewer log</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>LogTextureDownloadsToSimulator</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Send a digest of texture info to the sim</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>TextureLoggingThreshold</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Specifies the byte threshold at which texture download data should be sent to the sim.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
</map>
|
||||
</llsd>
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@
|
|||
#include "llstatusbar.h"
|
||||
#include "llteleportflags.h"
|
||||
#include "llteleporthistory.h"
|
||||
#include "lltexturestats.h"
|
||||
#include "lltexturestats.h"
|
||||
#include "lltool.h"
|
||||
#include "lltoolcomp.h"
|
||||
#include "lltoolmgr.h"
|
||||
|
|
@ -6087,17 +6089,16 @@ void LLAgent::teleportCancel()
|
|||
void LLAgent::teleportViaLocation(const LLVector3d& pos_global)
|
||||
{
|
||||
LLViewerRegion* regionp = getRegion();
|
||||
LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global);
|
||||
U64 handle = to_region_handle(pos_global);
|
||||
LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromHandle(handle);
|
||||
if(regionp && info)
|
||||
{
|
||||
U32 x_pos;
|
||||
U32 y_pos;
|
||||
from_region_handle(info->mHandle, &x_pos, &y_pos);
|
||||
LLVector3d region_origin = info->getGlobalOrigin();
|
||||
LLVector3 pos_local(
|
||||
(F32)(pos_global.mdV[VX] - x_pos),
|
||||
(F32)(pos_global.mdV[VY] - y_pos),
|
||||
(F32)(pos_global.mdV[VX] - region_origin.mdV[VX]),
|
||||
(F32)(pos_global.mdV[VY] - region_origin.mdV[VY]),
|
||||
(F32)(pos_global.mdV[VZ]));
|
||||
teleportRequest(info->mHandle, pos_local);
|
||||
teleportRequest(handle, pos_local);
|
||||
}
|
||||
else if(regionp &&
|
||||
teleportCore(regionp->getHandle() == to_region_handle_global((F32)pos_global.mdV[VX], (F32)pos_global.mdV[VY])))
|
||||
|
|
@ -6514,3 +6515,4 @@ LLAgentQueryManager::~LLAgentQueryManager()
|
|||
}
|
||||
|
||||
// EOF
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@
|
|||
#include "llallocator.h"
|
||||
#include "llares.h"
|
||||
#include "llcurl.h"
|
||||
#include "lltexturestats.h"
|
||||
#include "lltexturestats.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llviewerdisplay.h"
|
||||
#include "llviewermedia.h"
|
||||
|
|
@ -248,9 +250,6 @@ F32 gLogoutMaxTime = LOGOUT_REQUEST_TIME;
|
|||
|
||||
BOOL gDisconnected = FALSE;
|
||||
|
||||
// Map scale in pixels per region
|
||||
F32 gMapScale = 128.f;
|
||||
|
||||
// used to restore texture state after a mode switch
|
||||
LLFrameTimer gRestoreGLTimer;
|
||||
BOOL gRestoreGL = FALSE;
|
||||
|
|
@ -413,7 +412,7 @@ static void settings_to_globals()
|
|||
gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc");
|
||||
gAllowTapTapHoldRun = gSavedSettings.getBOOL("AllowTapTapHoldRun");
|
||||
gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates");
|
||||
gMapScale = gSavedSettings.getF32("MapScale");
|
||||
LLWorldMapView::sMapScale = gSavedSettings.getF32("MapScale");
|
||||
|
||||
LLCubeMap::sUseCubeMaps = LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap");
|
||||
}
|
||||
|
|
@ -426,7 +425,7 @@ static void settings_modify()
|
|||
LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4]
|
||||
gDebugGL = gSavedSettings.getBOOL("RenderDebugGL") || gDebugSession;
|
||||
gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline");
|
||||
|
||||
gAuditTexture = gSavedSettings.getBOOL("AuditTexture");
|
||||
#if LL_VECTORIZE
|
||||
if (gSysCPU.hasAltivec())
|
||||
{
|
||||
|
|
@ -547,7 +546,7 @@ LLAppViewer* LLAppViewer::sInstance = NULL;
|
|||
const std::string LLAppViewer::sGlobalSettingsName = "Global";
|
||||
|
||||
LLTextureCache* LLAppViewer::sTextureCache = NULL;
|
||||
LLWorkerThread* LLAppViewer::sImageDecodeThread = NULL;
|
||||
LLImageDecodeThread* LLAppViewer::sImageDecodeThread = NULL;
|
||||
LLTextureFetch* LLAppViewer::sTextureFetch = NULL;
|
||||
|
||||
LLAppViewer::LLAppViewer() :
|
||||
|
|
@ -639,6 +638,9 @@ bool LLAppViewer::init()
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
// *FIX: The following code isn't grouped into functions yet.
|
||||
|
||||
// Statistics / debug timer initialization
|
||||
init_statistics();
|
||||
|
||||
//
|
||||
// Various introspection concerning the libs we're using - particularly
|
||||
// the libs involved in getting to a full login screen.
|
||||
|
|
@ -1596,14 +1598,14 @@ bool LLAppViewer::initThreads()
|
|||
LLWatchdog::getInstance()->init(watchdog_killer_callback);
|
||||
}
|
||||
|
||||
LLVFSThread::initClass(enable_threads && true);
|
||||
LLLFSThread::initClass(enable_threads && true);
|
||||
LLVFSThread::initClass(enable_threads && false);
|
||||
LLLFSThread::initClass(enable_threads && false);
|
||||
|
||||
// Image decoding
|
||||
LLAppViewer::sImageDecodeThread = new LLWorkerThread("ImageDecode", enable_threads && true);
|
||||
LLAppViewer::sImageDecodeThread = new LLImageDecodeThread(enable_threads && true);
|
||||
LLAppViewer::sTextureCache = new LLTextureCache(enable_threads && true);
|
||||
LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(), enable_threads && false);
|
||||
LLImage::initClass(LLAppViewer::getImageDecodeThread());
|
||||
LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(), sImageDecodeThread, enable_threads && true);
|
||||
LLImage::initClass();
|
||||
|
||||
if (LLFastTimer::sLog || LLFastTimer::sMetricLog)
|
||||
{
|
||||
|
|
@ -2397,7 +2399,7 @@ void LLAppViewer::cleanupSavedSettings()
|
|||
}
|
||||
}
|
||||
|
||||
gSavedSettings.setF32("MapScale", gMapScale );
|
||||
gSavedSettings.setF32("MapScale", LLWorldMapView::sMapScale );
|
||||
|
||||
// Some things are cached in LLAgent.
|
||||
if (gAgent.mInitialized)
|
||||
|
|
@ -2723,7 +2725,7 @@ void LLAppViewer::initMarkerFile()
|
|||
|
||||
// Create the marker file for this execution & lock it
|
||||
apr_status_t s;
|
||||
s = mMarkerFile.open(mMarkerFileName, LL_APR_W, gAPRPoolp);
|
||||
s = mMarkerFile.open(mMarkerFileName, LL_APR_W, TRUE);
|
||||
|
||||
if (s == APR_SUCCESS && mMarkerFile.getFileHandle())
|
||||
{
|
||||
|
|
@ -4109,3 +4111,4 @@ void LLAppViewer::handleLoginComplete()
|
|||
|
||||
writeDebugInfo();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,12 +41,10 @@ class LLCommandLineParser;
|
|||
class LLFrameTimer;
|
||||
class LLPumpIO;
|
||||
class LLTextureCache;
|
||||
class LLImageDecodeThread;
|
||||
class LLTextureFetch;
|
||||
class LLTimer;
|
||||
class LLVFS;
|
||||
class LLWatchdogTimeout;
|
||||
class LLWorkerThread;
|
||||
|
||||
class LLCommandLineParser;
|
||||
|
||||
class LLAppViewer : public LLApp
|
||||
{
|
||||
|
|
@ -98,7 +96,7 @@ public:
|
|||
|
||||
// Thread accessors
|
||||
static LLTextureCache* getTextureCache() { return sTextureCache; }
|
||||
static LLWorkerThread* getImageDecodeThread() { return sImageDecodeThread; }
|
||||
static LLImageDecodeThread* getImageDecodeThread() { return sImageDecodeThread; }
|
||||
static LLTextureFetch* getTextureFetch() { return sTextureFetch; }
|
||||
|
||||
const std::string& getSerialNumber() { return mSerialNumber; }
|
||||
|
|
@ -228,7 +226,7 @@ private:
|
|||
|
||||
// Thread objects.
|
||||
static LLTextureCache* sTextureCache;
|
||||
static LLWorkerThread* sImageDecodeThread;
|
||||
static LLImageDecodeThread* sImageDecodeThread;
|
||||
static LLTextureFetch* sTextureFetch;
|
||||
|
||||
S32 mNumSessions;
|
||||
|
|
@ -322,9 +320,6 @@ extern F32 gSimFrames;
|
|||
|
||||
extern BOOL gDisconnected;
|
||||
|
||||
// Map scale in pixels per region
|
||||
extern F32 gMapScale;
|
||||
|
||||
extern LLFrameTimer gRestoreGLTimer;
|
||||
extern BOOL gRestoreGL;
|
||||
extern BOOL gUseWireframe;
|
||||
|
|
|
|||
|
|
@ -368,7 +368,7 @@ void LLSendTexLayerResponder::uploadComplete(const LLSD& content)
|
|||
std::string result = content["state"];
|
||||
LLUUID new_id = content["new_asset"];
|
||||
|
||||
llinfos << "LLSendTexLayerResponder::result from capabilities: " << result << llendl;
|
||||
llinfos << "result: " << result << "new_id:" << new_id << llendl;
|
||||
if (result == "complete"
|
||||
&& mBakedUploadData != NULL)
|
||||
{ // Invoke
|
||||
|
|
@ -382,6 +382,14 @@ void LLSendTexLayerResponder::uploadComplete(const LLSD& content)
|
|||
}
|
||||
}
|
||||
|
||||
void LLSendTexLayerResponder::error(U32 statusNum, const std::string& reason)
|
||||
{
|
||||
llinfos << "status: " << statusNum << " reason: " << reason << llendl;
|
||||
|
||||
// Invoke the original callback with an error result
|
||||
LLTexLayerSetBuffer::onTextureUploadComplete(LLUUID(), (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
|
||||
mBakedUploadData = NULL; // deleted in onTextureUploadComplete()
|
||||
}
|
||||
|
||||
LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(const LLSD& post_data,
|
||||
const LLUUID& vfile_id,
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ public:
|
|||
~LLSendTexLayerResponder();
|
||||
|
||||
virtual void uploadComplete(const LLSD& content);
|
||||
virtual void error(U32 statusNum, const std::string& reason);
|
||||
|
||||
LLBakedUploadData * mBakedUploadData;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ void LLColorSwatchCtrl::draw()
|
|||
{
|
||||
if (!mFallbackImageName.empty())
|
||||
{
|
||||
LLPointer<LLViewerTexture> fallback_image = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE);
|
||||
LLPointer<LLViewerFetchedTexture> fallback_image = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName, TRUE, FALSE, LLViewerTexture::LOD_TEXTURE);
|
||||
if( fallback_image->getComponents() == 4 )
|
||||
{
|
||||
gl_rect_2d_checkerboard( interior );
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
#include "llviewerwindow.h"
|
||||
#include "llappviewer.h"
|
||||
#include "llmemoryview.h"
|
||||
|
||||
#include "llviewertexture.h"
|
||||
//
|
||||
// Globals
|
||||
//
|
||||
|
|
@ -102,17 +102,29 @@ LLDebugView::LLDebugView(const LLDebugView::Params& p)
|
|||
gTextureView = LLUICtrlFactory::create<LLTextureView>(tvp);
|
||||
addChild(gTextureView);
|
||||
//gTextureView->reshape(r.getWidth(), r.getHeight(), TRUE);
|
||||
#if !LL_RELEASE_FOR_DOWNLOAD
|
||||
r.set(150, rect.getHeight() - 50, 900 + LLImageGL::sTextureLoadedCounter.size() * 30, 100);
|
||||
LLTextureSizeView::Params tsvp;
|
||||
tsvp.name("gTextureSizeView");
|
||||
tsvp.rect(r);
|
||||
tsvp.follows.flags(FOLLOWS_BOTTOM|FOLLOWS_LEFT);
|
||||
tsvp.visible(false);
|
||||
gTextureSizeView = LLUICtrlFactory::create<LLTextureSizeView>(tsvp);
|
||||
addChild(gTextureSizeView);
|
||||
#endif
|
||||
|
||||
if(gAuditTexture)
|
||||
{
|
||||
r.set(150, rect.getHeight() - 50, 900 + LLImageGL::sTextureLoadedCounter.size() * 30, 100);
|
||||
LLTextureSizeView::Params tsv ;
|
||||
tsv.name("gTextureSizeView");
|
||||
tsv.rect(r);
|
||||
tsv.follows.flags(FOLLOWS_BOTTOM|FOLLOWS_LEFT);
|
||||
tsv.visible(false);
|
||||
gTextureSizeView = LLUICtrlFactory::create<LLTextureSizeView>(tsv);
|
||||
addChild(gTextureSizeView);
|
||||
gTextureSizeView->setType(LLTextureSizeView::TEXTURE_MEM_OVER_SIZE) ;
|
||||
|
||||
r.set(150, rect.getHeight() - 50, 900 + LLViewerTexture::getTotalNumOfCategories() * 30, 100);
|
||||
LLTextureSizeView::Params tcv ;
|
||||
tcv.name("gTextureCategoryView");
|
||||
tcv.rect(r);
|
||||
tcv.follows.flags(FOLLOWS_BOTTOM|FOLLOWS_LEFT);
|
||||
tcv.visible(false);
|
||||
gTextureCategoryView = LLUICtrlFactory::create<LLTextureSizeView>(tcv);
|
||||
gTextureCategoryView->setType(LLTextureSizeView::TEXTURE_MEM_OVER_CATEGORY);
|
||||
addChild(gTextureCategoryView);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -122,5 +134,6 @@ LLDebugView::~LLDebugView()
|
|||
gDebugView = NULL;
|
||||
gTextureView = NULL;
|
||||
gTextureSizeView = NULL;
|
||||
gTextureCategoryView = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ void LLDrawable::init()
|
|||
mVObjp = NULL;
|
||||
// mFaces
|
||||
mSpatialGroupp = NULL;
|
||||
mVisible = 0;
|
||||
mVisible = sCurVisible - 2;//invisible for the current frame and the last frame.
|
||||
mRadius = 0.f;
|
||||
|
||||
mGeneration = -1;
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ S32 LLFacePool::drawLoopSetTex(face_array_t& face_list, S32 stage)
|
|||
iter != face_list.end(); iter++)
|
||||
{
|
||||
LLFace *facep = *iter;
|
||||
gGL.getTexUnit(stage)->bind(facep->getTexture());
|
||||
gGL.getTexUnit(stage)->bind(facep->getTexture(), TRUE) ;
|
||||
gGL.getTexUnit(0)->activate();
|
||||
res += facep->renderIndexed();
|
||||
}
|
||||
|
|
@ -474,17 +474,13 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)
|
|||
{
|
||||
if (params.mTexture.notNull())
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(params.mTexture.get());
|
||||
gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ;
|
||||
if (params.mTextureMatrix)
|
||||
{
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix);
|
||||
gPipeline.mTextureMatrixOps++;
|
||||
}
|
||||
if(params.mTexture.notNull())//will be removed.
|
||||
{
|
||||
params.mTexture->addTextureStats(params.mVSize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ void LLDrawPoolAlpha::render(S32 pass)
|
|||
gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
|
||||
glColor4f(1,0,0,1);
|
||||
LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f*1024.f);
|
||||
gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sSmokeImagep) ;
|
||||
gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sSmokeImagep, TRUE) ;
|
||||
renderAlphaHighlight(LLVertexBuffer::MAP_VERTEX |
|
||||
LLVertexBuffer::MAP_TEXCOORD0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -253,7 +253,7 @@ void LLDrawPoolTree::renderTree(BOOL selecting)
|
|||
LLGLState normalize(GL_NORMALIZE, TRUE);
|
||||
|
||||
// Bind the texture for this tree.
|
||||
gGL.getTexUnit(sDiffTex)->bind(mTexturep.get());
|
||||
gGL.getTexUnit(sDiffTex)->bind(mTexturep.get(), TRUE);
|
||||
|
||||
U32 indices_drawn = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ void LLViewerDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum
|
|||
{
|
||||
setExplicitFormat(internal_format, primary_format, type_format, swap_bytes);
|
||||
}
|
||||
createGLTexture(0, raw_image);
|
||||
createGLTexture(0, raw_image, 0, TRUE, LLViewerTexture::DYNAMIC_TEX);
|
||||
setAddressMode((mClamp) ? LLTexUnit::TAM_CLAMP : LLTexUnit::TAM_WRAP);
|
||||
mGLTexturep->setGLTextureCreated(false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
#include "llvovolume.h"
|
||||
#include "pipeline.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llviewerwindow.h"
|
||||
|
||||
#define LL_MAX_INDICES_COUNT 1000000
|
||||
|
||||
|
|
@ -175,6 +176,9 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
|
|||
mLastIndicesCount = mIndicesCount;
|
||||
mLastIndicesIndex = mIndicesIndex;
|
||||
|
||||
mImportanceToCamera = 0.f ;
|
||||
mBoundingSphereRadius = 0.0f ;
|
||||
|
||||
mAtlasInfop = NULL ;
|
||||
mUsingAtlas = FALSE ;
|
||||
}
|
||||
|
|
@ -186,6 +190,7 @@ void LLFace::destroy()
|
|||
{
|
||||
mTexture->removeFace(this) ;
|
||||
}
|
||||
|
||||
if (mDrawPoolp)
|
||||
{
|
||||
mDrawPoolp->removeFace(this);
|
||||
|
|
@ -207,7 +212,7 @@ void LLFace::destroy()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
setDrawInfo(NULL);
|
||||
|
||||
removeAtlas();
|
||||
|
|
@ -256,6 +261,7 @@ void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep)
|
|||
}
|
||||
mDrawPoolp = new_pool;
|
||||
}
|
||||
|
||||
setTexture(texturep) ;
|
||||
}
|
||||
|
||||
|
|
@ -750,7 +756,9 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
|
|||
}
|
||||
|
||||
mCenterLocal = (newMin+newMax)*0.5f;
|
||||
|
||||
LLVector3 tmp = (newMin - newMax) ;
|
||||
mBoundingSphereRadius = tmp.length() * 0.5f ;
|
||||
|
||||
updateCenterAgent();
|
||||
}
|
||||
|
||||
|
|
@ -1305,6 +1313,151 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
const F32 LEAST_IMPORTANCE = 0.05f ;
|
||||
const F32 LEAST_IMPORTANCE_FOR_LARGE_IMAGE = 0.3f ;
|
||||
|
||||
F32 LLFace::getTextureVirtualSize()
|
||||
{
|
||||
F32 radius;
|
||||
F32 cos_angle_to_view_dir;
|
||||
mPixelArea = calcPixelArea(cos_angle_to_view_dir, radius);
|
||||
|
||||
if (mPixelArea <= 0)
|
||||
{
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
//get area of circle in texture space
|
||||
LLVector2 tdim = mTexExtents[1] - mTexExtents[0];
|
||||
F32 texel_area = (tdim * 0.5f).lengthSquared()*3.14159f;
|
||||
if (texel_area <= 0)
|
||||
{
|
||||
// Probably animated, use default
|
||||
texel_area = 1.f;
|
||||
}
|
||||
|
||||
//apply texel area to face area to get accurate ratio
|
||||
//face_area /= llclamp(texel_area, 1.f/64.f, 16.f);
|
||||
F32 face_area = mPixelArea / llclamp(texel_area, 0.015625f, 128.f);
|
||||
|
||||
if(face_area > LLViewerTexture::sMaxSmallImageSize)
|
||||
{
|
||||
if(mImportanceToCamera < LEAST_IMPORTANCE) //if the face is not important, do not load hi-res.
|
||||
{
|
||||
static const F32 MAX_LEAST_IMPORTANCE_IMAGE_SIZE = 128.0f * 128.0f ;
|
||||
face_area = llmin(face_area * 0.5f, MAX_LEAST_IMPORTANCE_IMAGE_SIZE) ;
|
||||
}
|
||||
else if(face_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.
|
||||
{
|
||||
if(mImportanceToCamera < LEAST_IMPORTANCE_FOR_LARGE_IMAGE)//if the face is not important, do not load hi-res.
|
||||
{
|
||||
face_area = LLViewerTexture::sMinLargeImageSize ;
|
||||
}
|
||||
else if(mTexture.notNull() && mTexture->isLargeImage())
|
||||
{
|
||||
face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return face_area;
|
||||
}
|
||||
|
||||
F32 LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
|
||||
{
|
||||
//get area of circle around face
|
||||
LLVector3 center = getPositionAgent();
|
||||
LLVector3 size = (mExtents[1] - mExtents[0]) * 0.5f;
|
||||
|
||||
LLVector3 lookAt = center - LLViewerCamera::getInstance()->getOrigin();
|
||||
F32 dist = lookAt.normVec() ;
|
||||
|
||||
//get area of circle around node
|
||||
F32 app_angle = atanf(size.length()/dist);
|
||||
radius = app_angle*LLDrawable::sCurPixelAngle;
|
||||
F32 face_area = radius*radius * 3.14159f;
|
||||
|
||||
if(dist < mBoundingSphereRadius) //camera is very close
|
||||
{
|
||||
cos_angle_to_view_dir = 1.0f ;
|
||||
mImportanceToCamera = 1.0f ;
|
||||
}
|
||||
else
|
||||
{
|
||||
cos_angle_to_view_dir = lookAt * LLViewerCamera::getInstance()->getXAxis() ;
|
||||
mImportanceToCamera = LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist) ;
|
||||
}
|
||||
|
||||
return face_area ;
|
||||
}
|
||||
|
||||
//the projection of the face partially overlaps with the screen
|
||||
F32 LLFace::adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius )
|
||||
{
|
||||
F32 screen_radius = (F32)llmax(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight()) ;
|
||||
F32 center_angle = acosf(cos_angle_to_view_dir) ;
|
||||
F32 d = center_angle * LLDrawable::sCurPixelAngle ;
|
||||
|
||||
if(d + radius > screen_radius + 5.f)
|
||||
{
|
||||
//----------------------------------------------
|
||||
//calculate the intersection area of two circles
|
||||
//F32 radius_square = radius * radius ;
|
||||
//F32 d_square = d * d ;
|
||||
//F32 screen_radius_square = screen_radius * screen_radius ;
|
||||
//face_area =
|
||||
// radius_square * acosf((d_square + radius_square - screen_radius_square)/(2 * d * radius)) +
|
||||
// screen_radius_square * acosf((d_square + screen_radius_square - radius_square)/(2 * d * screen_radius)) -
|
||||
// 0.5f * sqrtf((-d + radius + screen_radius) * (d + radius - screen_radius) * (d - radius + screen_radius) * (d + radius + screen_radius)) ;
|
||||
//----------------------------------------------
|
||||
|
||||
//the above calculation is too expensive
|
||||
//the below is a good estimation: bounding box of the bounding sphere:
|
||||
F32 alpha = 0.5f * (radius + screen_radius - d) / radius ;
|
||||
alpha = llclamp(alpha, 0.f, 1.f) ;
|
||||
return alpha * alpha ;
|
||||
}
|
||||
return 1.0f ;
|
||||
}
|
||||
|
||||
const S8 FACE_IMPORTANCE_LEVEL = 4 ;
|
||||
const F32 FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[FACE_IMPORTANCE_LEVEL][2] = //{distance, importance_weight}
|
||||
{{16.1f, 1.0f}, {32.1f, 0.5f}, {48.1f, 0.2f}, {96.1f, 0.05f} } ;
|
||||
const F32 FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[FACE_IMPORTANCE_LEVEL][2] = //{cos(angle), importance_weight}
|
||||
{{0.985f /*cos(10 degrees)*/, 1.0f}, {0.94f /*cos(20 degrees)*/, 0.8f}, {0.866f /*cos(30 degrees)*/, 0.64f}, {0.0f, 0.36f}} ;
|
||||
|
||||
//static
|
||||
F32 LLFace::calcImportanceToCamera(F32 cos_angle_to_view_dir, F32 dist)
|
||||
{
|
||||
F32 importance = 0.f ;
|
||||
|
||||
if(cos_angle_to_view_dir > LLViewerCamera::getInstance()->getCosHalfFov() &&
|
||||
dist < FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[FACE_IMPORTANCE_LEVEL - 1][0])
|
||||
{
|
||||
F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ;
|
||||
F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed();
|
||||
|
||||
if(camera_moving_speed > 10.0f || camera_angular_speed > 1.0f)
|
||||
{
|
||||
//if camera moves or rotates too fast, ignore the importance factor
|
||||
return 0.f ;
|
||||
}
|
||||
|
||||
//F32 camera_relative_speed = camera_moving_speed * (lookAt * LLViewerCamera::getInstance()->getVelocityDir()) ;
|
||||
|
||||
S32 i = 0 ;
|
||||
for(i = 0; i < FACE_IMPORTANCE_LEVEL && dist > FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][0]; ++i);
|
||||
i = llmin(i, FACE_IMPORTANCE_LEVEL - 1) ;
|
||||
F32 dist_factor = FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][1] ;
|
||||
|
||||
for(i = 0; i < FACE_IMPORTANCE_LEVEL && cos_angle_to_view_dir < FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[i][0] ; ++i) ;
|
||||
i = llmin(i, FACE_IMPORTANCE_LEVEL - 1) ;
|
||||
importance = dist_factor * FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[i][1] ;
|
||||
}
|
||||
|
||||
return importance ;
|
||||
}
|
||||
|
||||
BOOL LLFace::verify(const U32* indices_array) const
|
||||
{
|
||||
BOOL ok = TRUE;
|
||||
|
|
|
|||
|
|
@ -188,6 +188,9 @@ public:
|
|||
void setIndicesIndex(S32 idx) { mIndicesIndex = idx; }
|
||||
void setDrawInfo(LLDrawInfo* draw_info);
|
||||
|
||||
F32 getTextureVirtualSize() ;
|
||||
F32 getImportanceToCamera()const {return mImportanceToCamera ;}
|
||||
|
||||
//for atlas
|
||||
LLTextureAtlasSlot* getAtlasInfo() ;
|
||||
void setAtlasInUse(BOOL flag);
|
||||
|
|
@ -200,6 +203,12 @@ public:
|
|||
void removeAtlas() ;
|
||||
BOOL switchTexture() ;
|
||||
|
||||
private:
|
||||
F32 adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius );
|
||||
F32 calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) ;
|
||||
public:
|
||||
static F32 calcImportanceToCamera(F32 to_view_dir, F32 dist);
|
||||
|
||||
public:
|
||||
|
||||
LLVector3 mCenterLocal;
|
||||
|
|
@ -214,7 +223,7 @@ public:
|
|||
LLMatrix4* mTextureMatrix;
|
||||
LLDrawInfo* mDrawInfo;
|
||||
|
||||
protected:
|
||||
private:
|
||||
friend class LLGeometryManager;
|
||||
friend class LLVolumeGeometryManager;
|
||||
|
||||
|
|
@ -244,9 +253,16 @@ protected:
|
|||
F32 mVSize;
|
||||
F32 mPixelArea;
|
||||
|
||||
//importance factor, in the range [0, 1.0].
|
||||
//1.0: the most important.
|
||||
//based on the distance from the face to the view point and the angle from the face center to the view direction.
|
||||
F32 mImportanceToCamera ;
|
||||
F32 mBoundingSphereRadius ;
|
||||
|
||||
|
||||
//atlas
|
||||
LLPointer<LLTextureAtlasSlot> mAtlasInfop ;
|
||||
BOOL mUsingAtlas ;
|
||||
BOOL mUsingAtlas ;
|
||||
|
||||
protected:
|
||||
static BOOL sSafeRenderSelect;
|
||||
|
|
|
|||
|
|
@ -50,12 +50,27 @@
|
|||
#include "lltextbox.h"
|
||||
#include "llviewermenu.h"
|
||||
|
||||
//
|
||||
// Constants
|
||||
//
|
||||
const F32 MAP_MINOR_DIR_THRESHOLD = 0.08f;
|
||||
|
||||
//
|
||||
// Member functions
|
||||
//
|
||||
|
||||
LLFloaterMap::LLFloaterMap(const LLSD& key)
|
||||
: LLFloater(key)
|
||||
: LLFloater(key),
|
||||
mPopupMenu(NULL),
|
||||
mTextBoxEast(NULL),
|
||||
mTextBoxNorth(NULL),
|
||||
mTextBoxWest(NULL),
|
||||
mTextBoxSouth(NULL),
|
||||
mTextBoxSouthEast(NULL),
|
||||
mTextBoxNorthEast(NULL),
|
||||
mTextBoxNorthWest(NULL),
|
||||
mTextBoxSouthWest(NULL),
|
||||
mMap(NULL)
|
||||
{
|
||||
//Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_map.xml", FALSE);
|
||||
}
|
||||
|
|
@ -92,6 +107,8 @@ BOOL LLFloaterMap::postBuild()
|
|||
mPopupMenu->setItemEnabled ("Stop Tracking", false);
|
||||
}
|
||||
|
||||
updateMinorDirections();
|
||||
|
||||
// Get the drag handle all the way in back
|
||||
sendChildToBack(getDragHandle());
|
||||
|
||||
|
|
@ -139,6 +156,23 @@ void LLFloaterMap::setDirectionPos( LLTextBox* text_box, F32 rotation )
|
|||
llround(map_half_height - text_half_height + radius * sin( rotation )) );
|
||||
}
|
||||
|
||||
void LLFloaterMap::updateMinorDirections()
|
||||
{
|
||||
if (mTextBoxNorthEast == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Hide minor directions if they cover too much of the map
|
||||
bool show_minors = mTextBoxNorthEast->getRect().getHeight() < MAP_MINOR_DIR_THRESHOLD *
|
||||
llmin(getRect().getWidth(), getRect().getHeight());
|
||||
|
||||
mTextBoxNorthEast->setVisible(show_minors);
|
||||
mTextBoxNorthWest->setVisible(show_minors);
|
||||
mTextBoxSouthWest->setVisible(show_minors);
|
||||
mTextBoxSouthEast->setVisible(show_minors);
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLFloaterMap::draw()
|
||||
{
|
||||
|
|
@ -180,17 +214,23 @@ void LLFloaterMap::draw()
|
|||
LLFloater::draw();
|
||||
}
|
||||
|
||||
void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
{
|
||||
LLFloater::reshape(width, height, called_from_parent);
|
||||
updateMinorDirections();
|
||||
}
|
||||
|
||||
void LLFloaterMap::handleZoom(const LLSD& userdata)
|
||||
{
|
||||
std::string level = userdata.asString();
|
||||
|
||||
F32 scale = 0.0f;
|
||||
if (level == std::string("close"))
|
||||
scale = MAP_SCALE_MAX;
|
||||
scale = LLNetMap::MAP_SCALE_MAX;
|
||||
else if (level == std::string("medium"))
|
||||
scale = MAP_SCALE_MID;
|
||||
scale = LLNetMap::MAP_SCALE_MID;
|
||||
else if (level == std::string("far"))
|
||||
scale = MAP_SCALE_MIN;
|
||||
scale = LLNetMap::MAP_SCALE_MIN;
|
||||
if (scale != 0.0f)
|
||||
{
|
||||
gSavedSettings.setF32("MiniMapScale", scale );
|
||||
|
|
|
|||
|
|
@ -51,12 +51,14 @@ public:
|
|||
/*virtual*/ BOOL postBuild();
|
||||
/*virtual*/ BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
|
||||
/*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
|
||||
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
/*virtual*/ void draw();
|
||||
|
||||
private:
|
||||
void handleZoom(const LLSD& userdata);
|
||||
void handleStopTracking (const LLSD& userdata);
|
||||
void setDirectionPos( LLTextBox* text_box, F32 rotation );
|
||||
void updateMinorDirections();
|
||||
|
||||
LLMenuGL* mPopupMenu;
|
||||
|
||||
|
|
|
|||
|
|
@ -790,7 +790,7 @@ void LLFloaterReporter::takeScreenshot()
|
|||
// store in the image list so it doesn't try to fetch from the server
|
||||
LLPointer<LLViewerFetchedTexture> image_in_list =
|
||||
LLViewerTextureManager::getFetchedTexture(mResourceDatap->mAssetInfo.mUuid, TRUE, FALSE, LLViewerTexture::FETCHED_TEXTURE);
|
||||
image_in_list->createGLTexture(0, raw);
|
||||
image_in_list->createGLTexture(0, raw, 0, TRUE, LLViewerTexture::OTHER);
|
||||
|
||||
// the texture picker then uses that texture
|
||||
LLTexturePicker* texture = getChild<LLTextureCtrl>("screenshot");
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@
|
|||
#include "llregionhandle.h"
|
||||
#include "llscrolllistctrl.h"
|
||||
#include "llslurl.h"
|
||||
#include "lltabcontainer.h"
|
||||
#include "lltextbox.h"
|
||||
#include "lltracker.h"
|
||||
#include "lltrans.h"
|
||||
|
|
@ -63,7 +62,9 @@
|
|||
#include "llviewermenu.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llviewerstats.h"
|
||||
#include "llviewertexture.h"
|
||||
#include "llworldmap.h"
|
||||
#include "llworldmapmessage.h"
|
||||
#include "llworldmapview.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llappviewer.h"
|
||||
|
|
@ -79,6 +80,12 @@
|
|||
//---------------------------------------------------------------------------
|
||||
static const F32 MAP_ZOOM_TIME = 0.2f;
|
||||
|
||||
// Merov: we switched from using the "world size" (which varies depending where the user went) to a fixed
|
||||
// width of 512 regions max visible at a time. This makes the zoom slider works in a consistent way across
|
||||
// sessions and doesn't prevent the user to pan the world if it was to grow a lot beyond that limit.
|
||||
// Currently (01/26/09), this value allows the whole grid to be visible in a 1024x1024 window.
|
||||
static const S32 MAX_VISIBLE_REGIONS = 512;
|
||||
|
||||
enum EPanDirection
|
||||
{
|
||||
PAN_UP,
|
||||
|
|
@ -160,11 +167,11 @@ LLFloaterWorldMap::LLFloaterWorldMap(const LLSD& key)
|
|||
gFloaterWorldMap = this;
|
||||
|
||||
mFactoryMap["objects_mapview"] = LLCallbackMap(createWorldMapView, NULL);
|
||||
mFactoryMap["terrain_mapview"] = LLCallbackMap(createWorldMapView, NULL);
|
||||
|
||||
//Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_world_map.xml", FALSE);
|
||||
mCommitCallbackRegistrar.add("WMap.Location", boost::bind(&LLFloaterWorldMap::onLocationCommit, this));
|
||||
mCommitCallbackRegistrar.add("WMap.AvatarCombo", boost::bind(&LLFloaterWorldMap::onAvatarComboCommit, this));
|
||||
mCommitCallbackRegistrar.add("WMap.Landmark", boost::bind(&LLFloaterWorldMap::onLandmarkComboCommit, this));
|
||||
mCommitCallbackRegistrar.add("WMap.SearchResult", boost::bind(&LLFloaterWorldMap::onCommitSearchResult, this));
|
||||
mCommitCallbackRegistrar.add("WMap.CommitLocation", boost::bind(&LLFloaterWorldMap::onCommitLocation, this));
|
||||
mCommitCallbackRegistrar.add("WMap.GoHome", boost::bind(&LLFloaterWorldMap::onGoHome, this));
|
||||
|
|
@ -183,17 +190,7 @@ void* LLFloaterWorldMap::createWorldMapView(void* data)
|
|||
|
||||
BOOL LLFloaterWorldMap::postBuild()
|
||||
{
|
||||
mTabs = getChild<LLTabContainer>("maptab");
|
||||
if (!mTabs) return FALSE;
|
||||
|
||||
mTabs->setCommitCallback(boost::bind(&LLFloaterWorldMap::onCommitBackground, this));
|
||||
|
||||
// The following callback syncs the worlmap tabs with the images.
|
||||
// Commented out since it was crashing when LLWorldMap became a singleton.
|
||||
// We should be fine without it but override the onOpen method and put it
|
||||
// there if it turns out to be needed. -MG
|
||||
//
|
||||
//onCommitBackground();
|
||||
mPanel = getChild<LLPanel>("objects_mapview");
|
||||
|
||||
LLComboBox *avatar_combo = getChild<LLComboBox>("friend combo");
|
||||
if (avatar_combo)
|
||||
|
|
@ -221,8 +218,8 @@ BOOL LLFloaterWorldMap::postBuild()
|
|||
landmark_combo->setTextEntryCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) );
|
||||
}
|
||||
|
||||
mCurZoomVal = log(gMapScale)/log(2.f);
|
||||
childSetValue("zoom slider", gMapScale);
|
||||
mCurZoomVal = log(LLWorldMapView::sMapScale)/log(2.f);
|
||||
childSetValue("zoom slider", LLWorldMapView::sMapScale);
|
||||
|
||||
setDefaultBtn(NULL);
|
||||
|
||||
|
|
@ -235,7 +232,7 @@ BOOL LLFloaterWorldMap::postBuild()
|
|||
LLFloaterWorldMap::~LLFloaterWorldMap()
|
||||
{
|
||||
// All cleaned up by LLView destructor
|
||||
mTabs = NULL;
|
||||
mPanel = NULL;
|
||||
|
||||
// Inventory deletes all observers on shutdown
|
||||
mInventory = NULL;
|
||||
|
|
@ -268,7 +265,7 @@ void LLFloaterWorldMap::onOpen(const LLSD& key)
|
|||
mIsClosing = FALSE;
|
||||
|
||||
LLWorldMapView* map_panel;
|
||||
map_panel = (LLWorldMapView*)mTabs->getCurrentPanel();
|
||||
map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel;
|
||||
map_panel->clearLastClick();
|
||||
|
||||
{
|
||||
|
|
@ -279,15 +276,8 @@ void LLFloaterWorldMap::onOpen(const LLSD& key)
|
|||
}
|
||||
map_panel->updateVisibleBlocks();
|
||||
|
||||
// Reload the agent positions when we show the window
|
||||
LLWorldMap::getInstance()->eraseItems();
|
||||
|
||||
// Reload any maps that may have changed
|
||||
LLWorldMap::getInstance()->clearSimFlags();
|
||||
|
||||
const S32 panel_num = mTabs->getCurrentPanelIndex();
|
||||
const bool request_from_sim = true;
|
||||
LLWorldMap::getInstance()->setCurrentLayer(panel_num, request_from_sim);
|
||||
// Reload items as they may have changed
|
||||
LLWorldMap::getInstance()->reloadItems();
|
||||
|
||||
// We may already have a bounding box for the regions of the world,
|
||||
// so use that to adjust the view.
|
||||
|
|
@ -321,12 +311,9 @@ void LLFloaterWorldMap::onOpen(const LLSD& key)
|
|||
// static
|
||||
void LLFloaterWorldMap::reloadIcons(void*)
|
||||
{
|
||||
LLWorldMap::getInstance()->eraseItems();
|
||||
|
||||
LLWorldMap::getInstance()->sendMapLayerRequest();
|
||||
LLWorldMap::getInstance()->reloadItems();
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
BOOL LLFloaterWorldMap::handleHover(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
|
|
@ -358,12 +345,6 @@ BOOL LLFloaterWorldMap::handleScrollWheel(S32 x, S32 y, S32 clicks)
|
|||
void LLFloaterWorldMap::reshape( S32 width, S32 height, BOOL called_from_parent )
|
||||
{
|
||||
LLFloater::reshape( width, height, called_from_parent );
|
||||
|
||||
// Might have changed size of world display area
|
||||
// JC: Technically, this is correct, but it makes the slider "pop"
|
||||
// if you resize the window, then draw the slider. Just leaving it
|
||||
// the way it was when you opened the window seems better.
|
||||
// adjustZoomSliderBounds();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -445,7 +426,7 @@ void LLFloaterWorldMap::draw()
|
|||
|
||||
childSetEnabled("Teleport", (BOOL)tracking_status);
|
||||
// childSetEnabled("Clear", (BOOL)tracking_status);
|
||||
childSetEnabled("Show Destination", (BOOL)tracking_status || LLWorldMap::getInstance()->mIsTrackingUnknownLocation);
|
||||
childSetEnabled("Show Destination", (BOOL)tracking_status || LLWorldMap::getInstance()->isTracking());
|
||||
childSetEnabled("copy_slurl", (mSLURL.size() > 0) );
|
||||
|
||||
setMouseOpaque(TRUE);
|
||||
|
|
@ -465,6 +446,18 @@ void LLFloaterWorldMap::draw()
|
|||
mCurZoomVal = lerp(mCurZoomVal, (F32)childGetValue("zoom slider").asReal(), interp);
|
||||
F32 map_scale = 256.f*pow(2.f, mCurZoomVal);
|
||||
LLWorldMapView::setScale( map_scale );
|
||||
|
||||
// Enable/disable checkboxes depending on the zoom level
|
||||
// If above threshold level (i.e. low res) -> Disable all checkboxes
|
||||
// If under threshold level (i.e. high res) -> Enable all checkboxes
|
||||
bool enable = LLWorldMapView::showRegionInfo();
|
||||
childSetEnabled("people_chk", enable);
|
||||
childSetEnabled("infohub_chk", enable);
|
||||
childSetEnabled("telehub_chk", enable);
|
||||
childSetEnabled("land_for_sale_chk", enable);
|
||||
childSetEnabled("event_chk", enable);
|
||||
childSetEnabled("event_mature_chk", enable);
|
||||
childSetEnabled("event_adult_chk", enable);
|
||||
|
||||
LLFloater::draw();
|
||||
}
|
||||
|
|
@ -553,14 +546,14 @@ void LLFloaterWorldMap::trackLandmark( const LLUUID& landmark_item_id )
|
|||
void LLFloaterWorldMap::trackEvent(const LLItemInfo &event_info)
|
||||
{
|
||||
mTrackedStatus = LLTracker::TRACKING_LOCATION;
|
||||
LLTracker::trackLocation(event_info.mPosGlobal, event_info.mName, event_info.mToolTip, LLTracker::LOCATION_EVENT);
|
||||
LLTracker::trackLocation(event_info.getGlobalPosition(), event_info.getName(), event_info.getToolTip(), LLTracker::LOCATION_EVENT);
|
||||
setDefaultBtn("Teleport");
|
||||
}
|
||||
|
||||
void LLFloaterWorldMap::trackGenericItem(const LLItemInfo &item)
|
||||
{
|
||||
mTrackedStatus = LLTracker::TRACKING_LOCATION;
|
||||
LLTracker::trackLocation(item.mPosGlobal, item.mName, item.mToolTip, LLTracker::LOCATION_ITEM);
|
||||
LLTracker::trackLocation(item.getGlobalPosition(), item.getName(), item.getToolTip(), LLTracker::LOCATION_ITEM);
|
||||
setDefaultBtn("Teleport");
|
||||
}
|
||||
|
||||
|
|
@ -569,29 +562,27 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)
|
|||
LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global);
|
||||
if (!sim_info)
|
||||
{
|
||||
LLWorldMap::getInstance()->mIsTrackingUnknownLocation = TRUE;
|
||||
LLWorldMap::getInstance()->mInvalidLocation = FALSE;
|
||||
LLWorldMap::getInstance()->mUnknownLocation = pos_global;
|
||||
// We haven't found a region for that point yet, leave the tracking to the world map
|
||||
LLWorldMap::getInstance()->setTracking(pos_global);
|
||||
LLTracker::stopTracking(NULL);
|
||||
S32 world_x = S32(pos_global.mdV[0] / 256);
|
||||
S32 world_y = S32(pos_global.mdV[1] / 256);
|
||||
LLWorldMap::getInstance()->sendMapBlockRequest(world_x, world_y, world_x, world_y, true);
|
||||
LLWorldMapMessage::getInstance()->sendMapBlockRequest(world_x, world_y, world_x, world_y, true);
|
||||
setDefaultBtn("");
|
||||
return;
|
||||
}
|
||||
if (sim_info->mAccess == SIM_ACCESS_DOWN)
|
||||
if (sim_info->isDown())
|
||||
{
|
||||
// Down sim. Show the blue circle of death!
|
||||
LLWorldMap::getInstance()->mIsTrackingUnknownLocation = TRUE;
|
||||
LLWorldMap::getInstance()->mUnknownLocation = pos_global;
|
||||
LLWorldMap::getInstance()->mInvalidLocation = TRUE;
|
||||
// Down region. Show the blue circle of death!
|
||||
// i.e. let the world map that this and tell it it's invalid
|
||||
LLWorldMap::getInstance()->setTracking(pos_global);
|
||||
LLWorldMap::getInstance()->setTrackingInvalid();
|
||||
LLTracker::stopTracking(NULL);
|
||||
setDefaultBtn("");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string sim_name;
|
||||
LLWorldMap::getInstance()->simNameFromPosGlobal( pos_global, sim_name );
|
||||
std::string sim_name = sim_info->getName();
|
||||
F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS );
|
||||
F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS );
|
||||
std::string full_name = llformat("%s (%d, %d, %d)",
|
||||
|
|
@ -603,9 +594,7 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)
|
|||
std::string tooltip("");
|
||||
mTrackedStatus = LLTracker::TRACKING_LOCATION;
|
||||
LLTracker::trackLocation(pos_global, full_name, tooltip);
|
||||
LLWorldMap::getInstance()->mIsTrackingUnknownLocation = FALSE;
|
||||
LLWorldMap::getInstance()->mIsTrackingDoubleClick = FALSE;
|
||||
LLWorldMap::getInstance()->mIsTrackingCommit = FALSE;
|
||||
LLWorldMap::getInstance()->cancelTracking(); // The floater is taking over the tracking
|
||||
|
||||
setDefaultBtn("Teleport");
|
||||
}
|
||||
|
|
@ -718,9 +707,9 @@ void LLFloaterWorldMap::trackURL(const std::string& region_name, S32 x_coord, S3
|
|||
|
||||
// pass sim name to combo box
|
||||
gFloaterWorldMap->mCompletingRegionName = region_name;
|
||||
LLWorldMap::getInstance()->sendNamedRegionRequest(region_name);
|
||||
LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name);
|
||||
LLStringUtil::toLower(gFloaterWorldMap->mCompletingRegionName);
|
||||
LLWorldMap::getInstance()->mIsTrackingCommit = TRUE;
|
||||
LLWorldMap::getInstance()->setTrackingCommit();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -787,19 +776,12 @@ void LLFloaterWorldMap::buildAvatarIDList()
|
|||
|
||||
// Delete all but the "None" entry
|
||||
S32 list_size = list->getItemCount();
|
||||
while (list_size > 1)
|
||||
if (list_size > 1)
|
||||
{
|
||||
list->selectNthItem(1);
|
||||
list->selectItemRange(1, -1);
|
||||
list->operateOnSelection(LLCtrlListInterface::OP_DELETE);
|
||||
--list_size;
|
||||
}
|
||||
|
||||
LLSD default_column;
|
||||
default_column["name"] = "friend name";
|
||||
default_column["label"] = "Friend Name";
|
||||
default_column["width"] = 500;
|
||||
list->addColumn(default_column);
|
||||
|
||||
// Get all of the calling cards for avatar that are currently online
|
||||
LLCollectMappableBuddies collector;
|
||||
LLAvatarTracker::instance().applyFunctor(collector);
|
||||
|
|
@ -820,10 +802,7 @@ void LLFloaterWorldMap::buildAvatarIDList()
|
|||
void LLFloaterWorldMap::buildLandmarkIDLists()
|
||||
{
|
||||
LLCtrlListInterface *list = childGetListInterface("landmark combo");
|
||||
if (!list)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!list) return;
|
||||
|
||||
// Delete all but the "None" entry
|
||||
S32 list_size = list->getItemCount();
|
||||
|
|
@ -864,7 +843,6 @@ void LLFloaterWorldMap::buildLandmarkIDLists()
|
|||
mLandmarkAssetIDList.put( item->getAssetUUID() );
|
||||
mLandmarkItemIDList.put( item->getUUID() );
|
||||
}
|
||||
list->sortByColumn(std::string("landmark name"), TRUE);
|
||||
|
||||
list->selectFirstItem();
|
||||
}
|
||||
|
|
@ -901,7 +879,7 @@ void LLFloaterWorldMap::clearLocationSelection(BOOL clear_ui)
|
|||
{
|
||||
childSetValue("spin z", 0);
|
||||
}
|
||||
LLWorldMap::getInstance()->mIsTrackingCommit = FALSE;
|
||||
LLWorldMap::getInstance()->cancelTracking();
|
||||
mCompletingRegionName = "";
|
||||
}
|
||||
|
||||
|
|
@ -937,18 +915,16 @@ void LLFloaterWorldMap::clearAvatarSelection(BOOL clear_ui)
|
|||
// can see the whole world, plus a little.
|
||||
void LLFloaterWorldMap::adjustZoomSliderBounds()
|
||||
{
|
||||
// World size in regions
|
||||
S32 world_width_regions = LLWorldMap::getInstance()->getWorldWidth() / REGION_WIDTH_UNITS;
|
||||
S32 world_height_regions = LLWorldMap::getInstance()->getWorldHeight() / REGION_WIDTH_UNITS;
|
||||
|
||||
// Pad the world size a little bit, so we have a nice border on
|
||||
// the edge
|
||||
world_width_regions++;
|
||||
world_height_regions++;
|
||||
// Merov: we switched from using the "world size" (which varies depending where the user went) to a fixed
|
||||
// width of 512 regions max visible at a time. This makes the zoom slider works in a consistent way across
|
||||
// sessions and doesn't prevent the user to pan the world if it was to grow a lot beyond that limit.
|
||||
// Currently (01/26/09), this value allows the whole grid to be visible in a 1024x1024 window.
|
||||
S32 world_width_regions = MAX_VISIBLE_REGIONS;
|
||||
S32 world_height_regions = MAX_VISIBLE_REGIONS;
|
||||
|
||||
// Find how much space we have to display the world
|
||||
LLWorldMapView* map_panel;
|
||||
map_panel = (LLWorldMapView*)mTabs->getCurrentPanel();
|
||||
map_panel = (LLWorldMapView*)mPanel;
|
||||
LLRect view_rect = map_panel->getRect();
|
||||
|
||||
// View size in pixels
|
||||
|
|
@ -1161,15 +1137,15 @@ void LLFloaterWorldMap::onLocationCommit()
|
|||
|
||||
LLStringUtil::toLower(str);
|
||||
mCompletingRegionName = str;
|
||||
LLWorldMap::getInstance()->mIsTrackingCommit = TRUE;
|
||||
LLWorldMap::getInstance()->setTrackingCommit();
|
||||
if (str.length() >= 3)
|
||||
{
|
||||
LLWorldMap::getInstance()->sendNamedRegionRequest(str);
|
||||
LLWorldMapMessage::getInstance()->sendNamedRegionRequest(str);
|
||||
}
|
||||
else
|
||||
{
|
||||
str += "#";
|
||||
LLWorldMap::getInstance()->sendNamedRegionRequest(str);
|
||||
LLWorldMapMessage::getInstance()->sendNamedRegionRequest(str);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1177,8 +1153,8 @@ void LLFloaterWorldMap::onClearBtn()
|
|||
{
|
||||
mTrackedStatus = LLTracker::TRACKING_NOTHING;
|
||||
LLTracker::stopTracking((void *)(intptr_t)TRUE);
|
||||
LLWorldMap::getInstance()->mIsTrackingUnknownLocation = FALSE;
|
||||
mSLURL = ""; // Clear the SLURL since it's invalid
|
||||
LLWorldMap::getInstance()->cancelTracking();
|
||||
mSLURL = ""; // Clear the SLURL since it's invalid
|
||||
mSetToUserPosition = TRUE; // Revert back to the current user position
|
||||
}
|
||||
|
||||
|
|
@ -1230,9 +1206,9 @@ void LLFloaterWorldMap::centerOnTarget(BOOL animate)
|
|||
pos_global = LLTracker::getTrackedPositionGlobal() - gAgent.getCameraPositionGlobal();
|
||||
}
|
||||
}
|
||||
else if(LLWorldMap::getInstance()->mIsTrackingUnknownLocation)
|
||||
else if(LLWorldMap::getInstance()->isTracking())
|
||||
{
|
||||
pos_global = LLWorldMap::getInstance()->mUnknownLocation - gAgent.getCameraPositionGlobal();;
|
||||
pos_global = LLWorldMap::getInstance()->getTrackedPositionGlobal() - gAgent.getCameraPositionGlobal();;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1240,8 +1216,8 @@ void LLFloaterWorldMap::centerOnTarget(BOOL animate)
|
|||
pos_global.clearVec();
|
||||
}
|
||||
|
||||
LLWorldMapView::setPan( -llfloor((F32)(pos_global.mdV[VX] * (F64)LLWorldMapView::sPixelsPerMeter)),
|
||||
-llfloor((F32)(pos_global.mdV[VY] * (F64)LLWorldMapView::sPixelsPerMeter)),
|
||||
LLWorldMapView::setPan( -llfloor((F32)(pos_global.mdV[VX] * (F64)LLWorldMapView::sMapScale / REGION_WIDTH_METERS)),
|
||||
-llfloor((F32)(pos_global.mdV[VY] * (F64)LLWorldMapView::sMapScale / REGION_WIDTH_METERS)),
|
||||
!animate);
|
||||
mWaitingForTracker = FALSE;
|
||||
}
|
||||
|
|
@ -1399,13 +1375,6 @@ void LLFloaterWorldMap::flyToAvatar()
|
|||
}
|
||||
}
|
||||
|
||||
void LLFloaterWorldMap::onCommitBackground()
|
||||
{
|
||||
// Find my index
|
||||
S32 index = mTabs->getCurrentPanelIndex();
|
||||
LLWorldMap::getInstance()->setCurrentLayer(index);
|
||||
}
|
||||
|
||||
void LLFloaterWorldMap::updateSims(bool found_null_sim)
|
||||
{
|
||||
if (mCompletingRegionName == "")
|
||||
|
|
@ -1422,24 +1391,23 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim)
|
|||
|
||||
S32 num_results = 0;
|
||||
std::map<U64, LLSimInfo*>::const_iterator it;
|
||||
for (it = LLWorldMap::getInstance()->mSimInfoMap.begin(); it != LLWorldMap::getInstance()->mSimInfoMap.end(); ++it)
|
||||
for (it = LLWorldMap::getInstance()->getRegionMap().begin(); it != LLWorldMap::getInstance()->getRegionMap().end(); ++it)
|
||||
{
|
||||
LLSimInfo* info = (*it).second;
|
||||
std::string sim_name = info->mName;
|
||||
std::string sim_name_lower = sim_name;
|
||||
LLSimInfo* info = it->second;
|
||||
std::string sim_name_lower = info->getName();
|
||||
LLStringUtil::toLower(sim_name_lower);
|
||||
|
||||
if (sim_name_lower.substr(0, name_length) == mCompletingRegionName)
|
||||
{
|
||||
if (sim_name_lower == mCompletingRegionName)
|
||||
{
|
||||
match = sim_name;
|
||||
match = info->getName();
|
||||
}
|
||||
|
||||
LLSD value;
|
||||
value["id"] = sim_name;
|
||||
value["id"] = info->getName();
|
||||
value["columns"][0]["column"] = "sim_name";
|
||||
value["columns"][0]["value"] = sim_name;
|
||||
value["columns"][0]["value"] = info->getName();
|
||||
list->addElement(value);
|
||||
num_results++;
|
||||
}
|
||||
|
|
@ -1496,15 +1464,13 @@ void LLFloaterWorldMap::onCommitSearchResult()
|
|||
LLStringUtil::toLower(sim_name);
|
||||
|
||||
std::map<U64, LLSimInfo*>::const_iterator it;
|
||||
for (it = LLWorldMap::getInstance()->mSimInfoMap.begin(); it != LLWorldMap::getInstance()->mSimInfoMap.end(); ++it)
|
||||
for (it = LLWorldMap::getInstance()->getRegionMap().begin(); it != LLWorldMap::getInstance()->getRegionMap().end(); ++it)
|
||||
{
|
||||
LLSimInfo* info = (*it).second;
|
||||
std::string info_sim_name = info->mName;
|
||||
LLStringUtil::toLower(info_sim_name);
|
||||
LLSimInfo* info = it->second;
|
||||
|
||||
if (sim_name == info_sim_name)
|
||||
if (info->isName(sim_name))
|
||||
{
|
||||
LLVector3d pos_global = from_region_handle( info->mHandle );
|
||||
LLVector3d pos_global = info->getGlobalOrigin();
|
||||
F64 local_x = childGetValue("spin x");
|
||||
F64 local_y = childGetValue("spin y");
|
||||
F64 local_z = childGetValue("spin z");
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ public:
|
|||
static const LLUUID& getHomeID() { return sHomeID; }
|
||||
|
||||
// A z_attenuation of 0.0f collapses the distance into the X-Y plane
|
||||
F32 getDistanceToDestination(const LLVector3d& pos_global, F32 z_attenuation = 0.5f) const;
|
||||
F32 getDistanceToDestination(const LLVector3d& pos_global, F32 z_attenuation = 0.5f) const;
|
||||
|
||||
void clearLocationSelection(BOOL clear_ui = FALSE);
|
||||
void clearAvatarSelection(BOOL clear_ui = FALSE);
|
||||
|
|
@ -121,8 +121,6 @@ protected:
|
|||
void onAvatarComboPrearrange();
|
||||
void onAvatarComboCommit();
|
||||
|
||||
void onCommitBackground();
|
||||
|
||||
void onComboTextEntry( );
|
||||
void onSearchTextEntry( LLLineEditor* ctrl );
|
||||
|
||||
|
|
@ -155,10 +153,10 @@ protected:
|
|||
|
||||
void cacheLandmarkPosition();
|
||||
|
||||
protected:
|
||||
LLTabContainer* mTabs;
|
||||
private:
|
||||
LLPanel* mPanel; // Panel displaying the map
|
||||
|
||||
// Sets gMapScale, in pixels per region
|
||||
// Ties to LLWorldMapView::sMapScale, in pixels per region
|
||||
F32 mCurZoomVal;
|
||||
LLFrameTimer mZoomTimer;
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#include "llstring.h"
|
||||
#include "llviewerinventory.h"
|
||||
#include "llviewerparcelmgr.h"
|
||||
#include "llworldmapmessage.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llwindow.h"
|
||||
#include "llworldmap.h"
|
||||
|
|
@ -268,13 +269,13 @@ void LLLandmarkActions::getSLURLfromPosGlobal(const LLVector3d& global_pos, slur
|
|||
{
|
||||
U64 new_region_handle = to_region_handle(global_pos);
|
||||
|
||||
LLWorldMap::url_callback_t url_cb = boost::bind(&LLLandmarkActions::onRegionResponseSLURL,
|
||||
LLWorldMapMessage::url_callback_t url_cb = boost::bind(&LLLandmarkActions::onRegionResponseSLURL,
|
||||
cb,
|
||||
global_pos,
|
||||
escaped,
|
||||
_2);
|
||||
|
||||
LLWorldMap::getInstance()->sendHandleRegionRequest(new_region_handle, url_cb, std::string("unused"), false);
|
||||
LLWorldMapMessage::getInstance()->sendHandleRegionRequest(new_region_handle, url_cb, std::string("unused"), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -285,18 +286,19 @@ void LLLandmarkActions::getRegionNameAndCoordsFromPosGlobal(const LLVector3d& gl
|
|||
if (sim_infop)
|
||||
{
|
||||
LLVector3 pos = sim_infop->getLocalPos(global_pos);
|
||||
cb(sim_infop->mName, llround(pos.mV[VX]), llround(pos.mV[VY]));
|
||||
std::string name = sim_infop->getName() ;
|
||||
cb(name, llround(pos.mV[VX]), llround(pos.mV[VY]));
|
||||
}
|
||||
else
|
||||
{
|
||||
U64 new_region_handle = to_region_handle(global_pos);
|
||||
|
||||
LLWorldMap::url_callback_t url_cb = boost::bind(&LLLandmarkActions::onRegionResponseNameAndCoords,
|
||||
LLWorldMapMessage::url_callback_t url_cb = boost::bind(&LLLandmarkActions::onRegionResponseNameAndCoords,
|
||||
cb,
|
||||
global_pos,
|
||||
_1);
|
||||
|
||||
LLWorldMap::getInstance()->sendHandleRegionRequest(new_region_handle, url_cb, std::string("unused"), false);
|
||||
LLWorldMapMessage::getInstance()->sendHandleRegionRequest(new_region_handle, url_cb, std::string("unused"), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -328,7 +330,8 @@ void LLLandmarkActions::onRegionResponseNameAndCoords(region_name_and_coords_cal
|
|||
if (sim_infop)
|
||||
{
|
||||
LLVector3 local_pos = sim_infop->getLocalPos(global_pos);
|
||||
cb(sim_infop->mName, llround(local_pos.mV[VX]), llround(local_pos.mV[VY]));
|
||||
std::string name = sim_infop->getName() ;
|
||||
cb(name, llround(local_pos.mV[VX]), llround(local_pos.mV[VY]));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@
|
|||
#include "llurlsimstring.h"
|
||||
#include "llviewerinventory.h"
|
||||
#include "llviewerparcelmgr.h"
|
||||
#include "llworldmap.h"
|
||||
#include "llworldmapmessage.h"
|
||||
#include "llappviewer.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llfloatermediabrowser.h"
|
||||
|
|
@ -386,14 +386,13 @@ void LLNavigationBar::onLocationSelection()
|
|||
|
||||
// Resolve the region name to its global coordinates.
|
||||
// If resolution succeeds we'll teleport.
|
||||
LLWorldMap::url_callback_t cb = boost::bind(
|
||||
LLWorldMapMessage::url_callback_t cb = boost::bind(
|
||||
&LLNavigationBar::onRegionNameResponse, this,
|
||||
typed_location, region_name, local_coords, _1, _2, _3, _4);
|
||||
// connect the callback each time, when user enter new location to get real location of agent after teleport
|
||||
mTeleportFinishConnection = LLViewerParcelMgr::getInstance()->
|
||||
setTeleportFinishedCallback(boost::bind(&LLNavigationBar::onTeleportFinished, this, _1,typed_location));
|
||||
|
||||
LLWorldMap::getInstance()->sendNamedRegionRequest(region_name, cb, std::string("unused"), false);
|
||||
LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name, cb, std::string("unused"), false);
|
||||
}
|
||||
|
||||
void LLNavigationBar::onTeleportFinished(const LLVector3d& global_agent_pos, const std::string& typed_location)
|
||||
|
|
|
|||
|
|
@ -65,9 +65,15 @@
|
|||
|
||||
static LLDefaultChildRegistry::Register<LLNetMap> r1("net_map");
|
||||
|
||||
const F32 LLNetMap::MAP_SCALE_MIN = 32;
|
||||
const F32 LLNetMap::MAP_SCALE_MID = 1024;
|
||||
const F32 LLNetMap::MAP_SCALE_MAX = 4096;
|
||||
|
||||
const F32 MAP_SCALE_INCREMENT = 16;
|
||||
const F32 MAP_MIN_PICK_DIST = 4;
|
||||
const F32 MAX_PRIM_RADIUS = 256.0f; // Don't try to draw giant mega-prims on the mini map
|
||||
const F32 MAP_SCALE_ZOOM_FACTOR = 1.04f; // Zoom in factor per click of scroll wheel (4%)
|
||||
const F32 MIN_DOT_RADIUS = 3.5f;
|
||||
const F32 DOT_SCALE = 0.75f;
|
||||
const F32 MIN_PICK_SCALE = 2.f;
|
||||
|
||||
LLNetMap::LLNetMap (const Params & p)
|
||||
: LLUICtrl (p),
|
||||
|
|
@ -89,6 +95,7 @@ LLNetMap::LLNetMap (const Params & p)
|
|||
mRotateMap(FALSE),
|
||||
mToolTipMsg()
|
||||
{
|
||||
mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS);
|
||||
}
|
||||
|
||||
LLNetMap::~LLNetMap()
|
||||
|
|
@ -101,17 +108,18 @@ void LLNetMap::setScale( F32 scale )
|
|||
|
||||
if (mObjectImagep.notNull())
|
||||
{
|
||||
F32 half_width = (F32)(getRect().getWidth() / 2);
|
||||
F32 half_height = (F32)(getRect().getHeight() / 2);
|
||||
F32 radius = sqrt( half_width * half_width + half_height * half_height );
|
||||
F32 region_widths = (2.f*radius)/mScale;
|
||||
F32 width = (F32)(getRect().getWidth());
|
||||
F32 height = (F32)(getRect().getHeight());
|
||||
F32 diameter = sqrt(width * width + height * height);
|
||||
F32 region_widths = diameter / mScale;
|
||||
F32 meters = region_widths * LLWorld::getInstance()->getRegionWidthInMeters();
|
||||
F32 num_pixels = (F32)mObjectImagep->getWidth();
|
||||
mObjectMapTPM = num_pixels/meters;
|
||||
mObjectMapPixels = 2.f*radius;
|
||||
mObjectMapTPM = num_pixels / meters;
|
||||
mObjectMapPixels = diameter;
|
||||
}
|
||||
|
||||
mPixelsPerMeter = mScale / REGION_WIDTH_METERS;
|
||||
mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS);
|
||||
|
||||
mUpdateNow = TRUE;
|
||||
}
|
||||
|
|
@ -302,6 +310,7 @@ void LLNetMap::draw()
|
|||
LLUI::getMousePositionLocal(this, &local_mouse_x, &local_mouse_y);
|
||||
mClosestAgentToCursor.setNull();
|
||||
F32 closest_dist = F32_MAX;
|
||||
F32 min_pick_dist = mDotRadius * MIN_PICK_SCALE;
|
||||
|
||||
// Draw avatars
|
||||
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
|
||||
|
|
@ -345,10 +354,10 @@ void LLNetMap::draw()
|
|||
LLWorldMapView::drawAvatar(
|
||||
pos_map.mV[VX], pos_map.mV[VY],
|
||||
show_as_friend ? map_avatar_friend_color : map_avatar_color,
|
||||
pos_map.mV[VZ]);
|
||||
pos_map.mV[VZ], mDotRadius);
|
||||
|
||||
F32 dist_to_cursor = dist_vec(LLVector2(pos_map.mV[VX], pos_map.mV[VY]), LLVector2(local_mouse_x,local_mouse_y));
|
||||
if(dist_to_cursor < MAP_MIN_PICK_DIST && dist_to_cursor < closest_dist)
|
||||
if(dist_to_cursor < min_pick_dist && dist_to_cursor < closest_dist)
|
||||
{
|
||||
closest_dist = dist_to_cursor;
|
||||
mClosestAgentToCursor = regionp->mMapAvatarIDs.get(i);
|
||||
|
|
@ -378,10 +387,12 @@ void LLNetMap::draw()
|
|||
// Draw dot for self avatar position
|
||||
pos_global = gAgent.getPositionGlobal();
|
||||
pos_map = globalPosToView(pos_global);
|
||||
LLUIImagePtr you = LLWorldMapView::sAvatarYouSmallImage;
|
||||
you->draw(
|
||||
llround(pos_map.mV[VX]) - you->getWidth()/2,
|
||||
llround(pos_map.mV[VY]) - you->getHeight()/2);
|
||||
LLUIImagePtr you = LLWorldMapView::sAvatarYouLargeImage;
|
||||
S32 dot_width = llround(mDotRadius * 2.f);
|
||||
you->draw(llround(pos_map.mV[VX] - mDotRadius),
|
||||
llround(pos_map.mV[VY] - mDotRadius),
|
||||
dot_width,
|
||||
dot_width);
|
||||
|
||||
// Draw frustum
|
||||
F32 meters_to_pixels = mScale/ LLWorld::getInstance()->getRegionWidthInMeters();
|
||||
|
|
@ -429,6 +440,12 @@ void LLNetMap::draw()
|
|||
LLUICtrl::draw();
|
||||
}
|
||||
|
||||
void LLNetMap::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
{
|
||||
LLUICtrl::reshape(width, height, called_from_parent);
|
||||
createObjectImage();
|
||||
}
|
||||
|
||||
LLVector3 LLNetMap::globalPosToView( const LLVector3d& global_pos )
|
||||
{
|
||||
LLVector3d relative_pos_global = global_pos - gAgent.getCameraPositionGlobal();
|
||||
|
|
@ -504,8 +521,12 @@ LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y )
|
|||
|
||||
BOOL LLNetMap::handleScrollWheel(S32 x, S32 y, S32 clicks)
|
||||
{
|
||||
// note that clicks are reversed from what you'd think
|
||||
setScale(llclamp(mScale - clicks*MAP_SCALE_INCREMENT, MAP_SCALE_MIN, MAP_SCALE_MAX));
|
||||
// note that clicks are reversed from what you'd think: i.e. > 0 means zoom out, < 0 means zoom in
|
||||
F32 scale = mScale;
|
||||
|
||||
scale *= pow(MAP_SCALE_ZOOM_FACTOR, -clicks);
|
||||
setScale(llclamp(scale, MAP_SCALE_MIN, MAP_SCALE_MAX));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -567,9 +588,7 @@ void LLNetMap::renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U &
|
|||
LLVector3 local_pos;
|
||||
local_pos.setVec( pos - mObjectImageCenterGlobal );
|
||||
|
||||
F32 radius_clamped = llmin(radius_meters, MAX_PRIM_RADIUS);
|
||||
|
||||
S32 diameter_pixels = llround(2 * radius_clamped * mObjectMapTPM);
|
||||
S32 diameter_pixels = llround(2 * radius_meters * mObjectMapTPM);
|
||||
renderPoint( local_pos, color, diameter_pixels );
|
||||
}
|
||||
|
||||
|
|
@ -662,13 +681,13 @@ void LLNetMap::renderPoint(const LLVector3 &pos_local, const LLColor4U &color,
|
|||
void LLNetMap::createObjectImage()
|
||||
{
|
||||
// Find the size of the side of a square that surrounds the circle that surrounds getRect().
|
||||
F32 half_width = (F32)(getRect().getWidth() / 2);
|
||||
F32 half_height = (F32)(getRect().getHeight() / 2);
|
||||
F32 radius = sqrt( half_width * half_width + half_height * half_height );
|
||||
S32 square_size = S32( 2 * radius );
|
||||
// ... which is, the diagonal of the rect.
|
||||
F32 width = (F32)getRect().getWidth();
|
||||
F32 height = (F32)getRect().getHeight();
|
||||
S32 square_size = llround( sqrt(width*width + height*height) );
|
||||
|
||||
// Find the least power of two >= the minimum size.
|
||||
const S32 MIN_SIZE = 32;
|
||||
const S32 MIN_SIZE = 64;
|
||||
const S32 MAX_SIZE = 256;
|
||||
S32 img_size = MIN_SIZE;
|
||||
while( (img_size*2 < square_size ) && (img_size < MAX_SIZE) )
|
||||
|
|
@ -684,7 +703,7 @@ void LLNetMap::createObjectImage()
|
|||
U8* data = mObjectRawImagep->getData();
|
||||
memset( data, 0, img_size * img_size * 4 );
|
||||
mObjectImagep = LLViewerTextureManager::getLocalTexture( mObjectRawImagep.get(), FALSE);
|
||||
setScale(mScale);
|
||||
}
|
||||
setScale(mScale);
|
||||
mUpdateNow = TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,9 +70,14 @@ protected:
|
|||
public:
|
||||
virtual ~LLNetMap();
|
||||
|
||||
static const F32 MAP_SCALE_MIN;
|
||||
static const F32 MAP_SCALE_MID;
|
||||
static const F32 MAP_SCALE_MAX;
|
||||
|
||||
/*virtual*/ void draw();
|
||||
/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
|
||||
/*virtual*/ BOOL handleToolTip( S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
|
||||
void setScale( F32 scale );
|
||||
void setRotateMap( BOOL b ) { mRotateMap = b; }
|
||||
|
|
@ -94,16 +99,17 @@ private:
|
|||
void drawTracking( const LLVector3d& pos_global,
|
||||
const LLColor4& color,
|
||||
BOOL draw_arrow = TRUE);
|
||||
|
||||
void createObjectImage();
|
||||
|
||||
void createObjectImage();
|
||||
|
||||
private:
|
||||
LLUIColor mBackgroundColor;
|
||||
|
||||
F32 mScale; // Size of a region in pixels
|
||||
F32 mPixelsPerMeter; // world meters to map pixels
|
||||
F32 mObjectMapTPM; // texels per meter on map
|
||||
F32 mObjectMapPixels; // Width of object map in pixels;
|
||||
F32 mObjectMapPixels; // Width of object map in pixels
|
||||
F32 mDotRadius; // Size of avatar markers
|
||||
F32 mTargetPanX;
|
||||
F32 mTargetPanY;
|
||||
F32 mCurPanX;
|
||||
|
|
|
|||
|
|
@ -357,7 +357,7 @@ void LLTeleportHistoryPanel::onCopySLURL()
|
|||
|
||||
U64 new_region_handle = to_region_handle(global_pos);
|
||||
|
||||
LLWorldMap::url_callback_t cb = boost::bind(
|
||||
LLWorldMapMessage::url_callback_t cb = boost::bind(
|
||||
&LLPanelPlacesTab::onRegionResponse, this,
|
||||
global_pos, _1, _2, _3, _4);
|
||||
|
||||
|
|
|
|||
|
|
@ -192,6 +192,11 @@ void LLPreviewTexture::draw()
|
|||
// Pump the texture priority
|
||||
F32 pixel_area = mLoadingFullImage ? (F32)MAX_IMAGE_AREA : (F32)(interior.getWidth() * interior.getHeight() );
|
||||
mImage->addTextureStats( pixel_area );
|
||||
if(pixel_area > 0.f)
|
||||
{
|
||||
//boost the previewed image priority to the highest to make it to get loaded first.
|
||||
mImage->setAdditionalDecodePriority(1.0f) ;
|
||||
}
|
||||
|
||||
// Don't bother decoding more than we can display, unless
|
||||
// we're loading the full image.
|
||||
|
|
@ -554,6 +559,7 @@ void LLPreviewTexture::loadAsset()
|
|||
{
|
||||
mImage = LLViewerTextureManager::getFetchedTexture(mImageID, MIPMAP_TRUE, FALSE, LLViewerTexture::LOD_TEXTURE);
|
||||
mImage->setBoostLevel(LLViewerTexture::BOOST_PREVIEW);
|
||||
mImage->forceToSaveRawImage(0) ;
|
||||
mAssetStatus = PREVIEW_ASSET_LOADING;
|
||||
updateDimensions();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2679,8 +2679,7 @@ void renderTexturePriority(LLDrawable* drawable)
|
|||
//LLViewerTexture* imagep = facep->getTexture();
|
||||
//if (imagep)
|
||||
{
|
||||
|
||||
//F32 vsize = LLVOVolume::getTextureVirtualSize(facep);
|
||||
|
||||
//F32 vsize = imagep->mMaxVirtualSize;
|
||||
F32 vsize = facep->getPixelArea();
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@
|
|||
#include "llfocusmgr.h"
|
||||
#include "llhttpsender.h"
|
||||
#include "lllocationhistory.h"
|
||||
#include "llimageworker.h"
|
||||
#include "llloginflags.h"
|
||||
#include "llmd5.h"
|
||||
#include "llmemorystream.h"
|
||||
|
|
@ -170,7 +171,7 @@
|
|||
#include "llvoclouds.h"
|
||||
#include "llweb.h"
|
||||
#include "llworld.h"
|
||||
#include "llworldmap.h"
|
||||
#include "llworldmapmessage.h"
|
||||
#include "llxfermanager.h"
|
||||
#include "pipeline.h"
|
||||
#include "llappviewer.h"
|
||||
|
|
@ -1812,6 +1813,7 @@ bool idle_startup()
|
|||
gViewerWindow->moveProgressViewToFront();
|
||||
|
||||
LLError::logToFixedBuffer(gDebugView->mDebugConsolep);
|
||||
|
||||
// set initial visibility of debug console
|
||||
gDebugView->mDebugConsolep->setVisible(gSavedSettings.getBOOL("ShowDebugConsole"));
|
||||
}
|
||||
|
|
@ -3266,9 +3268,8 @@ void register_viewer_callbacks(LLMessageSystem* msg)
|
|||
|
||||
msg->setHandlerFunc("AvatarPickerReply", LLFloaterAvatarPicker::processAvatarPickerReply);
|
||||
|
||||
msg->setHandlerFunc("MapLayerReply", LLWorldMap::processMapLayerReply);
|
||||
msg->setHandlerFunc("MapBlockReply", LLWorldMap::processMapBlockReply);
|
||||
msg->setHandlerFunc("MapItemReply", LLWorldMap::processMapItemReply);
|
||||
msg->setHandlerFunc("MapBlockReply", LLWorldMapMessage::processMapBlockReply);
|
||||
msg->setHandlerFunc("MapItemReply", LLWorldMapMessage::processMapItemReply);
|
||||
|
||||
msg->setHandlerFunc("EventInfoReply", LLPanelEvent::processEventInfoReply);
|
||||
msg->setHandlerFunc("PickInfoReply", &LLAvatarPropertiesProcessor::processPickInfoReply);
|
||||
|
|
|
|||
|
|
@ -234,12 +234,7 @@ void LLSurface::createSTexture()
|
|||
{
|
||||
if (!mSTexturep)
|
||||
{
|
||||
// Fill with dummy gray data.
|
||||
|
||||
//mSTexturep = LLViewerTextureManager::getLocalTexture(sTextureSize, sTextureSize, 3, FALSE);
|
||||
//mSTexturep->dontDiscard();
|
||||
//mSTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
|
||||
// Fill with dummy gray data.
|
||||
// GL NOT ACTIVE HERE
|
||||
LLPointer<LLImageRaw> raw = new LLImageRaw(sTextureSize, sTextureSize, 3);
|
||||
U8 *default_texture = raw->getData();
|
||||
|
|
|
|||
|
|
@ -1371,7 +1371,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph)
|
|||
|
||||
LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode();
|
||||
|
||||
gGL.getTexUnit(0)->bind(tex);
|
||||
gGL.getTexUnit(0)->bind(tex, TRUE);
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
|
||||
gl_rect_2d_simple_tex( width, height );
|
||||
|
|
@ -1393,7 +1393,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph)
|
|||
LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
|
||||
if( tex )
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(tex);
|
||||
gGL.getTexUnit(0)->bind(tex, TRUE);
|
||||
gl_rect_2d_simple_tex( width, height );
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
}
|
||||
|
|
@ -1506,7 +1506,7 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height)
|
|||
if( tex )
|
||||
{
|
||||
LLGLSNoAlphaTest gls_no_alpha_test;
|
||||
gGL.getTexUnit(0)->bind(tex);
|
||||
gGL.getTexUnit(0)->bind(tex, TRUE);
|
||||
gl_rect_2d_simple_tex( width, height );
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
}
|
||||
|
|
@ -1585,7 +1585,7 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
|
|||
|
||||
LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode();
|
||||
|
||||
gGL.getTexUnit(0)->bind(tex);
|
||||
gGL.getTexUnit(0)->bind(tex, TRUE);
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
|
||||
gl_rect_2d_simple_tex( width, height );
|
||||
|
|
@ -1608,7 +1608,7 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
|
|||
( (tex->getComponents() == 1) && getInfo()->mStaticImageIsMask ) )
|
||||
{
|
||||
LLGLSNoAlphaTest gls_no_alpha_test;
|
||||
gGL.getTexUnit(0)->bind(tex);
|
||||
gGL.getTexUnit(0)->bind(tex, TRUE);
|
||||
gl_rect_2d_simple_tex( width, height );
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
}
|
||||
|
|
@ -2034,7 +2034,7 @@ LLViewerTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_n
|
|||
// that once an image is a mask it's always a mask.
|
||||
tex->setExplicitFormat( GL_ALPHA8, GL_ALPHA );
|
||||
}
|
||||
tex->createGLTexture(0, image_raw);
|
||||
tex->createGLTexture(0, image_raw, 0, TRUE, LLViewerTexture::LOCAL);
|
||||
|
||||
gGL.getTexUnit(0)->bind(tex);
|
||||
tex->setAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -48,6 +48,27 @@ class LLTextureCache : public LLWorkerThread
|
|||
friend class LLTextureCacheRemoteWorker;
|
||||
friend class LLTextureCacheLocalFileWorker;
|
||||
|
||||
private:
|
||||
// Entries
|
||||
struct EntriesInfo
|
||||
{
|
||||
EntriesInfo() : mVersion(0.f), mEntries(0) {}
|
||||
F32 mVersion;
|
||||
U32 mEntries;
|
||||
};
|
||||
struct Entry
|
||||
{
|
||||
Entry() {}
|
||||
Entry(const LLUUID& id, S32 imagesize, S32 bodysize, U32 time) :
|
||||
mID(id), mImageSize(imagesize), mBodySize(bodysize), mTime(time) {}
|
||||
void init(const LLUUID& id, U32 time) { mID = id, mImageSize = 0; mBodySize = 0; mTime = time; }
|
||||
LLUUID mID; // 16 bytes
|
||||
S32 mImageSize; // total size of image if known
|
||||
S32 mBodySize; // size of body file in body cache
|
||||
U32 mTime; // seconds since 1/1/1970
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
|
||||
class Responder : public LLResponder
|
||||
|
|
@ -106,10 +127,16 @@ public:
|
|||
// debug
|
||||
S32 getNumReads() { return mReaders.size(); }
|
||||
S32 getNumWrites() { return mWriters.size(); }
|
||||
S64 getUsage() { return mTexturesSizeTotal; }
|
||||
S64 getMaxUsage() { return sCacheMaxTexturesSize; }
|
||||
U32 getEntries() { return mHeaderEntriesInfo.mEntries; }
|
||||
U32 getMaxEntries() { return sCacheMaxEntries; };
|
||||
BOOL isInCache(const LLUUID& id) ;
|
||||
BOOL isInLocal(const LLUUID& id) ;
|
||||
|
||||
protected:
|
||||
// Accessed by LLTextureCacheWorker
|
||||
bool appendToTextureEntryList(const LLUUID& id, S32 size);
|
||||
bool updateTextureEntryList(const LLUUID& id, S32 size);
|
||||
std::string getLocalFileName(const LLUUID& id);
|
||||
std::string getTextureFileName(const LLUUID& id);
|
||||
void addCompleted(Responder* responder, bool success);
|
||||
|
|
@ -122,7 +149,16 @@ private:
|
|||
void readHeaderCache();
|
||||
void purgeAllTextures(bool purge_directories);
|
||||
void purgeTextures(bool validate);
|
||||
S32 getHeaderCacheEntry(const LLUUID& id, bool touch, S32* imagesize = NULL);
|
||||
LLAPRFile* openHeaderEntriesFile(bool readonly, S32 offset);
|
||||
void closeHeaderEntriesFile();
|
||||
void readEntriesHeader();
|
||||
void writeEntriesHeader();
|
||||
S32 openAndReadEntry(const LLUUID& id, Entry& entry, bool create);
|
||||
void writeEntryAndClose(S32 idx, Entry& entry);
|
||||
U32 openAndReadEntries(std::vector<Entry>& entries);
|
||||
void writeEntriesAndClose(const std::vector<Entry>& entries);
|
||||
S32 getHeaderCacheEntry(const LLUUID& id, S32& imagesize);
|
||||
S32 setHeaderCacheEntry(const LLUUID& id, S32 imagesize);
|
||||
bool removeHeaderCacheEntry(const LLUUID& id);
|
||||
void lockHeaders() { mHeaderMutex.lock(); }
|
||||
void unlockHeaders() { mHeaderMutex.unlock(); }
|
||||
|
|
@ -132,6 +168,7 @@ private:
|
|||
LLMutex mWorkersMutex;
|
||||
LLMutex mHeaderMutex;
|
||||
LLMutex mListMutex;
|
||||
LLAPRFile* mHeaderAPRFile;
|
||||
|
||||
typedef std::map<handle_t, LLTextureCacheWorker*> handle_map_t;
|
||||
handle_map_t mReaders;
|
||||
|
|
@ -145,42 +182,28 @@ private:
|
|||
|
||||
BOOL mReadOnly;
|
||||
|
||||
// Entries
|
||||
struct EntriesInfo
|
||||
{
|
||||
F32 mVersion;
|
||||
U32 mEntries;
|
||||
};
|
||||
struct Entry
|
||||
{
|
||||
Entry() {}
|
||||
Entry(const LLUUID& id, S32 size, U32 time) : mID(id), mSize(size), mTime(time) {}
|
||||
LLUUID mID; // 128 bits
|
||||
S32 mSize; // total size of image if known (NOT size cached)
|
||||
U32 mTime; // seconds since 1/1/1970
|
||||
};
|
||||
|
||||
// HEADERS (Include first mip)
|
||||
std::string mHeaderEntriesFileName;
|
||||
std::string mHeaderDataFileName;
|
||||
EntriesInfo mHeaderEntriesInfo;
|
||||
typedef std::map<S32,LLUUID> index_map_t;
|
||||
index_map_t mLRU; // index, id; stored as a map for fast removal
|
||||
std::set<S32> mFreeList; // deleted entries
|
||||
std::set<LLUUID> mLRU;
|
||||
typedef std::map<LLUUID,S32> id_map_t;
|
||||
id_map_t mHeaderIDMap;
|
||||
|
||||
// BODIES (TEXTURES minus headers)
|
||||
std::string mTexturesDirName;
|
||||
std::string mTexturesDirEntriesFileName;
|
||||
typedef std::map<LLUUID,S32> size_map_t;
|
||||
size_map_t mTexturesSizeMap;
|
||||
S64 mTexturesSizeTotal;
|
||||
LLAtomic32<BOOL> mDoPurge;
|
||||
|
||||
|
||||
// Statics
|
||||
static F32 sHeaderCacheVersion;
|
||||
static U32 sCacheMaxEntries;
|
||||
static S64 sCacheMaxTexturesSize;
|
||||
};
|
||||
|
||||
extern const S32 TEXTURE_CACHE_ENTRY_SIZE;
|
||||
|
||||
#endif // LL_LLTEXTURECACHE_H
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -37,26 +37,29 @@
|
|||
#include "llimage.h"
|
||||
#include "lluuid.h"
|
||||
#include "llworkerthread.h"
|
||||
#include "llcurl.h"
|
||||
#include "lltextureinfo.h"
|
||||
|
||||
class LLViewerTexture;
|
||||
class LLTextureFetchWorker;
|
||||
class HTTPGetResponder;
|
||||
class LLTextureCache;
|
||||
class LLImageDecodeThread;
|
||||
class LLHost;
|
||||
|
||||
// Interface class
|
||||
class LLTextureFetch : public LLWorkerThread
|
||||
{
|
||||
friend class LLTextureFetchWorker;
|
||||
friend class HTTPGetResponder;
|
||||
|
||||
public:
|
||||
LLTextureFetch(LLTextureCache* cache, bool threaded);
|
||||
LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded);
|
||||
~LLTextureFetch();
|
||||
|
||||
/*virtual*/ S32 update(U32 max_time_ms);
|
||||
|
||||
bool createRequest(const LLUUID& id, const LLHost& host, F32 priority,
|
||||
S32 w, S32 h, S32 c, S32 discard, bool needs_aux);
|
||||
bool createRequest(const std::string& filename, const LLUUID& id, const LLHost& host, F32 priority,
|
||||
bool createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
|
||||
S32 w, S32 h, S32 c, S32 discard, bool needs_aux);
|
||||
void deleteRequest(const LLUUID& id, bool cancel);
|
||||
bool getRequestFinished(const LLUUID& id, S32& discard_level,
|
||||
|
|
@ -66,25 +69,39 @@ public:
|
|||
bool receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, U16 data_size, U8* data);
|
||||
bool receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data);
|
||||
|
||||
void setTextureBandwidth(F32 bandwidth) { mTextureBandwidth = bandwidth; }
|
||||
F32 getTextureBandwidth() { return mTextureBandwidth; }
|
||||
|
||||
// Debug
|
||||
BOOL isFromLocalCache(const LLUUID& id);
|
||||
S32 getFetchState(const LLUUID& id, F32& decode_progress_p, F32& requested_priority_p,
|
||||
U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p);
|
||||
void dump();
|
||||
S32 getNumRequests() { return mRequestMap.size(); }
|
||||
S32 getNumHTTPRequests() { return mHTTPTextureQueue.size(); }
|
||||
|
||||
// Public for access by callbacks
|
||||
void lockQueue() { mQueueMutex.lock(); }
|
||||
void unlockQueue() { mQueueMutex.unlock(); }
|
||||
LLTextureFetchWorker* getWorker(const LLUUID& id);
|
||||
|
||||
LLTextureInfo* getTextureInfo() { return &mTextureInfo; }
|
||||
|
||||
protected:
|
||||
void addToNetworkQueue(LLTextureFetchWorker* worker);
|
||||
void removeFromNetworkQueue(LLTextureFetchWorker* worker);
|
||||
void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel);
|
||||
void addToHTTPQueue(const LLUUID& id);
|
||||
void removeFromHTTPQueue(const LLUUID& id);
|
||||
S32 getHTTPQueueSize() { return (S32)mHTTPTextureQueue.size(); }
|
||||
void removeRequest(LLTextureFetchWorker* worker, bool cancel);
|
||||
// Called from worker thread (during doWork)
|
||||
void processCurlRequests();
|
||||
|
||||
private:
|
||||
void sendRequestListToSimulators();
|
||||
/*virtual*/ void startThread(void);
|
||||
/*virtual*/ void endThread(void);
|
||||
/*virtual*/ void threadedUpdate(void);
|
||||
|
||||
public:
|
||||
LLUUID mDebugID;
|
||||
|
|
@ -95,8 +112,11 @@ public:
|
|||
|
||||
private:
|
||||
LLMutex mQueueMutex;
|
||||
LLMutex mNetworkQueueMutex;
|
||||
|
||||
LLTextureCache* mTextureCache;
|
||||
LLImageDecodeThread* mImageDecodeThread;
|
||||
LLCurlRequest* mCurlGetRequest;
|
||||
|
||||
// Map of all requests by UUID
|
||||
typedef std::map<LLUUID,LLTextureFetchWorker*> map_t;
|
||||
|
|
@ -105,10 +125,13 @@ private:
|
|||
// Set of requests that require network data
|
||||
typedef std::set<LLUUID> queue_t;
|
||||
queue_t mNetworkQueue;
|
||||
queue_t mHTTPTextureQueue;
|
||||
typedef std::map<LLHost,std::set<LLUUID> > cancel_queue_t;
|
||||
cancel_queue_t mCancelQueue;
|
||||
|
||||
LLFrameTimer mNetworkTimer;
|
||||
F32 mTextureBandwidth;
|
||||
F32 mMaxBandwidth;
|
||||
LLTextureInfo mTextureInfo;
|
||||
};
|
||||
|
||||
#endif // LL_LLTEXTUREFETCH_H
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,290 @@
|
|||
/**
|
||||
* @file lltextureinfo.cpp
|
||||
* @brief Object which handles local texture info
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2000-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "lltextureinfo.h"
|
||||
#include "lltexturestats.h"
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
LLTextureInfo::LLTextureInfo() :
|
||||
mLogTextureDownloadsToViewerLog(false),
|
||||
mLogTextureDownloadsToSimulator(false),
|
||||
mTotalBytes(0),
|
||||
mTotalMilliseconds(0),
|
||||
mTextureDownloadsStarted(0),
|
||||
mTextureDownloadsCompleted(0),
|
||||
mTextureDownloadProtocol("NONE"),
|
||||
mTextureLogThreshold(100 * 1024),
|
||||
mCurrentStatsBundleStartTime(0)
|
||||
{
|
||||
mTextures.clear();
|
||||
}
|
||||
|
||||
void LLTextureInfo::setUpLogging(bool writeToViewerLog, bool sendToSim, U32 textureLogThreshold)
|
||||
{
|
||||
mLogTextureDownloadsToViewerLog = writeToViewerLog;
|
||||
mLogTextureDownloadsToSimulator = sendToSim;
|
||||
mTextureLogThreshold = textureLogThreshold;
|
||||
}
|
||||
|
||||
LLTextureInfo::~LLTextureInfo()
|
||||
{
|
||||
std::map<LLUUID, LLTextureInfoDetails *>::iterator iterator;
|
||||
for (iterator = mTextures.begin(); iterator != mTextures.end(); iterator++)
|
||||
{
|
||||
LLTextureInfoDetails *info = (*iterator).second;
|
||||
delete info;
|
||||
}
|
||||
|
||||
mTextures.clear();
|
||||
}
|
||||
|
||||
void LLTextureInfo::addRequest(const LLUUID& id)
|
||||
{
|
||||
LLTextureInfoDetails *info = new LLTextureInfoDetails();
|
||||
mTextures[id] = info;
|
||||
}
|
||||
|
||||
U32 LLTextureInfo::getTextureInfoMapSize()
|
||||
{
|
||||
return mTextures.size();
|
||||
}
|
||||
|
||||
bool LLTextureInfo::has(const LLUUID& id)
|
||||
{
|
||||
std::map<LLUUID, LLTextureInfoDetails *>::iterator iterator = mTextures.find(id);
|
||||
if (iterator == mTextures.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void LLTextureInfo::setRequestStartTime(const LLUUID& id, U64 startTime)
|
||||
{
|
||||
if (!has(id))
|
||||
{
|
||||
addRequest(id);
|
||||
}
|
||||
mTextures[id]->mStartTime = startTime;
|
||||
mTextureDownloadsStarted++;
|
||||
}
|
||||
|
||||
void LLTextureInfo::setRequestSize(const LLUUID& id, U32 size)
|
||||
{
|
||||
if (!has(id))
|
||||
{
|
||||
addRequest(id);
|
||||
}
|
||||
mTextures[id]->mSize = size;
|
||||
}
|
||||
|
||||
void LLTextureInfo::setRequestOffset(const LLUUID& id, U32 offset)
|
||||
{
|
||||
if (!has(id))
|
||||
{
|
||||
addRequest(id);
|
||||
}
|
||||
mTextures[id]->mOffset = offset;
|
||||
}
|
||||
|
||||
void LLTextureInfo::setRequestType(const LLUUID& id, LLTextureInfoDetails::LLRequestType type)
|
||||
{
|
||||
if (!has(id))
|
||||
{
|
||||
addRequest(id);
|
||||
}
|
||||
mTextures[id]->mType = type;
|
||||
}
|
||||
|
||||
void LLTextureInfo::setRequestCompleteTimeAndLog(const LLUUID& id, U64 completeTime)
|
||||
{
|
||||
if (!has(id))
|
||||
{
|
||||
addRequest(id);
|
||||
}
|
||||
mTextures[id]->mCompleteTime = completeTime;
|
||||
|
||||
std::string protocol = "NONE";
|
||||
switch(mTextures[id]->mType)
|
||||
{
|
||||
case LLTextureInfoDetails::REQUEST_TYPE_HTTP:
|
||||
protocol = "HTTP";
|
||||
break;
|
||||
|
||||
case LLTextureInfoDetails::REQUEST_TYPE_UDP:
|
||||
protocol = "UDP";
|
||||
break;
|
||||
|
||||
case LLTextureInfoDetails::REQUEST_TYPE_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (mLogTextureDownloadsToViewerLog)
|
||||
{
|
||||
llinfos << "texture=" << id
|
||||
<< " start=" << mTextures[id]->mStartTime
|
||||
<< " end=" << mTextures[id]->mCompleteTime
|
||||
<< " size=" << mTextures[id]->mSize
|
||||
<< " offset=" << mTextures[id]->mOffset
|
||||
<< " length_in_ms=" << (mTextures[id]->mCompleteTime - mTextures[id]->mStartTime) / 1000
|
||||
<< " protocol=" << protocol
|
||||
<< llendl;
|
||||
}
|
||||
|
||||
if(mLogTextureDownloadsToSimulator)
|
||||
{
|
||||
S32 texture_stats_upload_threshold = mTextureLogThreshold;
|
||||
mTotalBytes += mTextures[id]->mSize;
|
||||
mTotalMilliseconds += mTextures[id]->mCompleteTime - mTextures[id]->mStartTime;
|
||||
mTextureDownloadsCompleted++;
|
||||
mTextureDownloadProtocol = protocol;
|
||||
if (mTotalBytes >= texture_stats_upload_threshold)
|
||||
{
|
||||
LLSD texture_data;
|
||||
std::stringstream startTime;
|
||||
startTime << mCurrentStatsBundleStartTime;
|
||||
texture_data["start_time"] = startTime.str();
|
||||
std::stringstream endTime;
|
||||
endTime << completeTime;
|
||||
texture_data["end_time"] = endTime.str();
|
||||
texture_data["averages"] = getAverages();
|
||||
send_texture_stats_to_sim(texture_data);
|
||||
resetTextureStatistics();
|
||||
}
|
||||
}
|
||||
|
||||
mTextures.erase(id);
|
||||
}
|
||||
|
||||
LLSD LLTextureInfo::getAverages()
|
||||
{
|
||||
LLSD averagedTextureData;
|
||||
S32 averageDownloadRate;
|
||||
if(mTotalMilliseconds == 0)
|
||||
{
|
||||
averageDownloadRate = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
averageDownloadRate = (mTotalBytes * 8) / mTotalMilliseconds;
|
||||
}
|
||||
|
||||
averagedTextureData["bits_per_second"] = averageDownloadRate;
|
||||
averagedTextureData["bytes_downloaded"] = mTotalBytes;
|
||||
averagedTextureData["texture_downloads_started"] = mTextureDownloadsStarted;
|
||||
averagedTextureData["texture_downloads_completed"] = mTextureDownloadsCompleted;
|
||||
averagedTextureData["transport"] = mTextureDownloadProtocol;
|
||||
|
||||
return averagedTextureData;
|
||||
}
|
||||
|
||||
void LLTextureInfo::resetTextureStatistics()
|
||||
{
|
||||
mTotalMilliseconds = 0;
|
||||
mTotalBytes = 0;
|
||||
mTextureDownloadsStarted = 0;
|
||||
mTextureDownloadsCompleted = 0;
|
||||
mTextureDownloadProtocol = "NONE";
|
||||
mCurrentStatsBundleStartTime = LLTimer::getTotalTime();
|
||||
}
|
||||
|
||||
U32 LLTextureInfo::getRequestStartTime(const LLUUID& id)
|
||||
{
|
||||
if (!has(id))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::map<LLUUID, LLTextureInfoDetails *>::iterator iterator = mTextures.find(id);
|
||||
return (*iterator).second->mStartTime;
|
||||
}
|
||||
}
|
||||
|
||||
U32 LLTextureInfo::getRequestSize(const LLUUID& id)
|
||||
{
|
||||
if (!has(id))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::map<LLUUID, LLTextureInfoDetails *>::iterator iterator = mTextures.find(id);
|
||||
return (*iterator).second->mSize;
|
||||
}
|
||||
}
|
||||
|
||||
U32 LLTextureInfo::getRequestOffset(const LLUUID& id)
|
||||
{
|
||||
if (!has(id))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::map<LLUUID, LLTextureInfoDetails *>::iterator iterator = mTextures.find(id);
|
||||
return (*iterator).second->mOffset;
|
||||
}
|
||||
}
|
||||
|
||||
LLTextureInfoDetails::LLRequestType LLTextureInfo::getRequestType(const LLUUID& id)
|
||||
{
|
||||
if (!has(id))
|
||||
{
|
||||
return LLTextureInfoDetails::REQUEST_TYPE_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::map<LLUUID, LLTextureInfoDetails *>::iterator iterator = mTextures.find(id);
|
||||
return (*iterator).second->mType;
|
||||
}
|
||||
}
|
||||
|
||||
U32 LLTextureInfo::getRequestCompleteTime(const LLUUID& id)
|
||||
{
|
||||
if (!has(id))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::map<LLUUID, LLTextureInfoDetails *>::iterator iterator = mTextures.find(id);
|
||||
return (*iterator).second->mCompleteTime;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
* @file lltextureinfo.h
|
||||
* @brief Object for managing texture information.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2000-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLTEXTUREINFO_H
|
||||
#define LL_LLTEXTUREINFO_H
|
||||
|
||||
#include "lluuid.h"
|
||||
#include "lltextureinfodetails.h"
|
||||
#include <map>
|
||||
|
||||
class LLTextureInfo
|
||||
{
|
||||
public:
|
||||
LLTextureInfo();
|
||||
~LLTextureInfo();
|
||||
|
||||
void setUpLogging(bool writeToViewerLog, bool sendToSim, U32 textureLogThreshold);
|
||||
bool has(const LLUUID& id);
|
||||
void setRequestStartTime(const LLUUID& id, U64 startTime);
|
||||
void setRequestSize(const LLUUID& id, U32 size);
|
||||
void setRequestOffset(const LLUUID& id, U32 offset);
|
||||
void setRequestType(const LLUUID& id, LLTextureInfoDetails::LLRequestType type);
|
||||
void setRequestCompleteTimeAndLog(const LLUUID& id, U64 completeTime);
|
||||
U32 getRequestStartTime(const LLUUID& id);
|
||||
U32 getRequestSize(const LLUUID& id);
|
||||
U32 getRequestOffset(const LLUUID& id);
|
||||
LLTextureInfoDetails::LLRequestType getRequestType(const LLUUID& id);
|
||||
U32 getRequestCompleteTime(const LLUUID& id);
|
||||
void resetTextureStatistics();
|
||||
U32 getTextureInfoMapSize();
|
||||
LLSD getAverages();
|
||||
|
||||
private:
|
||||
void addRequest(const LLUUID& id);
|
||||
|
||||
std::map<LLUUID, LLTextureInfoDetails *> mTextures;
|
||||
|
||||
LLSD mAverages;
|
||||
|
||||
bool mLogTextureDownloadsToViewerLog;
|
||||
bool mLogTextureDownloadsToSimulator;
|
||||
S32 mTotalBytes;
|
||||
S32 mTotalMilliseconds;
|
||||
S32 mTextureDownloadsStarted;
|
||||
S32 mTextureDownloadsCompleted;
|
||||
std::string mTextureDownloadProtocol;
|
||||
U32 mTextureLogThreshold; // in bytes
|
||||
U64 mCurrentStatsBundleStartTime;
|
||||
};
|
||||
|
||||
#endif // LL_LLTEXTUREINFO_H
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* @file lltextureinfodetails.cpp
|
||||
* @brief Object which handles details of any individual texture
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2000-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "lltextureinfodetails.h"
|
||||
|
||||
LLTextureInfoDetails::LLTextureInfoDetails() : mStartTime(0), mCompleteTime(0), mSize(0), mType(REQUEST_TYPE_NONE), mOffset(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* @file lltextureinfo.h
|
||||
* @brief Object for managing texture information.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2000-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLTEXTUREINFODETAILS_H
|
||||
#define LL_LLTEXTUREINFODETAILS_H
|
||||
|
||||
#include "lluuid.h"
|
||||
|
||||
class LLTextureInfoDetails
|
||||
{
|
||||
public:
|
||||
enum LLRequestType
|
||||
{
|
||||
REQUEST_TYPE_NONE,
|
||||
REQUEST_TYPE_HTTP,
|
||||
REQUEST_TYPE_UDP
|
||||
};
|
||||
|
||||
U32 mStartTime;
|
||||
U32 mCompleteTime;
|
||||
U32 mOffset;
|
||||
U32 mSize;
|
||||
LLRequestType mType;
|
||||
|
||||
LLTextureInfoDetails();
|
||||
};
|
||||
|
||||
#endif // LL_LLTEXTUREINFODETAILS_H
|
||||
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* @file lltexturerstats.cpp
|
||||
* @brief texture stats helper methods
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2002-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "pipeline.h"
|
||||
#include "llagent.h"
|
||||
#include "lltexturefetch.h"
|
||||
#include "lltexturestats.h"
|
||||
#include "lltexturestatsuploader.h"
|
||||
#include "llviewerregion.h"
|
||||
|
||||
void send_texture_stats_to_sim(const LLSD &texture_stats)
|
||||
{
|
||||
LLSD texture_stats_report;
|
||||
// Only send stats if the agent is connected to a region.
|
||||
if (!gAgent.getRegion() || gNoRender)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLUUID agent_id = gAgent.getID();
|
||||
texture_stats_report["agent_id"] = agent_id;
|
||||
texture_stats_report["region_id"] = gAgent.getRegion()->getRegionID();
|
||||
texture_stats_report["stats_data"] = texture_stats;
|
||||
|
||||
std::string texture_cap_url = gAgent.getRegion()->getCapability("TextureStats");
|
||||
LLTextureStatsUploader tsu;
|
||||
llinfos << "uploading texture stats data to simulator" << llendl;
|
||||
tsu.uploadStatsToSimulator(texture_cap_url, texture_stats);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* @file lltexturestats.h
|
||||
* @brief texture stats utilities
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLTEXTURESTATS_H
|
||||
#define LL_LLTEXTURESTATS_H
|
||||
|
||||
#include "llappviewer.h"
|
||||
|
||||
// utility functions to capture data on texture download speeds and send to simulator periodically
|
||||
void send_texture_stats_to_sim(const LLSD &texture_stats);
|
||||
|
||||
#endif // LL_LLTEXTURESTATS_H
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
* @file lltexturerstats.cpp
|
||||
* @brief texture stats upload class
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2002-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "lltexturestatsuploader.h"
|
||||
|
||||
LLTextureStatsUploader::LLTextureStatsUploader()
|
||||
{
|
||||
}
|
||||
|
||||
LLTextureStatsUploader::~LLTextureStatsUploader()
|
||||
{
|
||||
}
|
||||
|
||||
void LLTextureStatsUploader::uploadStatsToSimulator(const std::string texture_cap_url, const LLSD &texture_stats)
|
||||
{
|
||||
if ( texture_cap_url != "" )
|
||||
{
|
||||
LLHTTPClient::post(texture_cap_url, texture_stats, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
llinfos << "Not sending texture stats: "
|
||||
<< texture_stats
|
||||
<< " as there is no cap url."
|
||||
<< llendl;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
* @file lltexturestatsuploader.h
|
||||
* @brief Class to send the texture stats to the simulatore
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLTEXTURESTATSUPLOADER_H
|
||||
#define LL_LLTEXTURESTATSUPLOADER_H
|
||||
|
||||
#include "llappviewer.h"
|
||||
|
||||
// utility functions to capture data on texture download speeds and send to simulator periodically
|
||||
|
||||
class LLTextureStatsUploader
|
||||
{
|
||||
public:
|
||||
LLTextureStatsUploader();
|
||||
~LLTextureStatsUploader();
|
||||
void uploadStatsToSimulator(const std::string texture_cap_url, const LLSD &texture_stats);
|
||||
};
|
||||
|
||||
#endif // LL_LLTEXTURESTATSUPLOADER_H
|
||||
|
|
@ -44,19 +44,21 @@
|
|||
#include "llrender.h"
|
||||
|
||||
#include "lltooltip.h"
|
||||
#include "llappviewer.h"
|
||||
#include "llselectmgr.h"
|
||||
#include "lltexlayer.h"
|
||||
#include "lltexturecache.h"
|
||||
#include "lltexturefetch.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewerobject.h"
|
||||
#include "llviewertexture.h"
|
||||
#include "llviewertexturelist.h"
|
||||
#include "llappviewer.h"
|
||||
|
||||
#include "llvovolume.h"
|
||||
extern F32 texmem_lower_bound_scale;
|
||||
|
||||
LLTextureView *gTextureView = NULL;
|
||||
LLTextureSizeView *gTextureSizeView = NULL;
|
||||
LLTextureSizeView *gTextureCategoryView = NULL;
|
||||
|
||||
//static
|
||||
std::set<LLViewerFetchedTexture*> LLTextureView::sDebugImages;
|
||||
|
|
@ -230,10 +232,10 @@ void LLTextureBar::draw()
|
|||
{ "DSK", LLColor4::blue }, // CACHE_POST
|
||||
{ "NET", LLColor4::green }, // LOAD_FROM_NETWORK
|
||||
{ "SIM", LLColor4::green }, // LOAD_FROM_SIMULATOR
|
||||
{ "URL", LLColor4::green2 },// LOAD_FROM_HTTP_GET_URL
|
||||
{ "HTP", LLColor4::green }, // LOAD_FROM_HTTP_GET_DATA
|
||||
{ "REQ", LLColor4::yellow },// SEND_HTTP_REQ
|
||||
{ "HTP", LLColor4::green }, // WAIT_HTTP_REQ
|
||||
{ "DEC", LLColor4::yellow },// DECODE_IMAGE
|
||||
{ "DEC", LLColor4::yellow },// DECODE_IMAGE_UPDATE
|
||||
{ "DEC", LLColor4::green }, // DECODE_IMAGE_UPDATE
|
||||
{ "WRT", LLColor4::purple },// WRITE_TO_CACHE
|
||||
{ "WRT", LLColor4::orange },// WAIT_ON_WRITE
|
||||
{ "END", LLColor4::red }, // DONE
|
||||
|
|
@ -261,7 +263,7 @@ void LLTextureBar::draw()
|
|||
|
||||
// Draw the progress bar.
|
||||
S32 bar_width = 100;
|
||||
S32 bar_left = 280;
|
||||
S32 bar_left = 260;
|
||||
left = bar_left;
|
||||
right = left + bar_width;
|
||||
|
||||
|
|
@ -286,30 +288,31 @@ void LLTextureBar::draw()
|
|||
S32 pip_x = title_x3 + pip_space/2;
|
||||
|
||||
// Draw the packet pip
|
||||
const F32 pip_max_time = 5.f;
|
||||
F32 last_event = mImagep->mLastPacketTimer.getElapsedTimeF32();
|
||||
if (last_event < 1.f)
|
||||
if (last_event < pip_max_time)
|
||||
{
|
||||
clr = LLColor4::white;
|
||||
}
|
||||
else
|
||||
{
|
||||
last_event = mImagep->mRequestDeltaTime;
|
||||
if (last_event < 1.f)
|
||||
if (last_event < pip_max_time)
|
||||
{
|
||||
clr = LLColor4::green;
|
||||
}
|
||||
else
|
||||
{
|
||||
last_event = mImagep->mFetchDeltaTime;
|
||||
if (last_event < 1.f)
|
||||
if (last_event < pip_max_time)
|
||||
{
|
||||
clr = LLColor4::yellow;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (last_event < 1.f)
|
||||
if (last_event < pip_max_time)
|
||||
{
|
||||
clr.setAlpha(1.f - last_event);
|
||||
clr.setAlpha(1.f - last_event/pip_max_time);
|
||||
gGL.color4fv(clr.mV);
|
||||
gl_rect_2d(pip_x, top, pip_x + pip_width, bottom);
|
||||
}
|
||||
|
|
@ -406,89 +409,113 @@ void LLGLTexMemBar::draw()
|
|||
S32 total_mem = BYTES_TO_MEGA_BYTES(LLViewerTexture::sTotalTextureMemoryInBytes);
|
||||
S32 max_total_mem = LLViewerTexture::sMaxTotalTextureMemInMegaBytes;
|
||||
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 h_offset = (S32)((texture_bar_height + 2.5f) * mTextureView->mNumTextureBars + 2.5f);
|
||||
//----------------------------------------------------------------------------
|
||||
LLGLSUIDefault gls_ui;
|
||||
F32 text_color[] = {1.f, 1.f, 1.f, 0.75f};
|
||||
LLColor4 text_color(1.f, 1.f, 1.f, 0.75f);
|
||||
LLColor4 color;
|
||||
|
||||
std::string text;
|
||||
text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB Discard Bias: %.2f",
|
||||
text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
|
||||
total_mem,
|
||||
max_total_mem,
|
||||
bound_mem,
|
||||
max_bound_mem,
|
||||
discard_bias);
|
||||
LLImageRaw::sGlobalRawMemory >> 20, discard_bias,
|
||||
cache_usage, cache_max_usage);
|
||||
//, cache_entries, cache_max_entries
|
||||
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, h_offset + line_height*3,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
S32 bar_left = 380;
|
||||
#if 0
|
||||
S32 bar_left = 400;
|
||||
S32 bar_width = 200;
|
||||
S32 top = line_height*3 - 2 + h_offset;
|
||||
S32 bottom = top - 6;
|
||||
S32 left = bar_left;
|
||||
S32 right = left + bar_width;
|
||||
|
||||
F32 bar_scale = (F32)bar_width / (max_bound_mem * 1.5f);
|
||||
F32 bar_scale;
|
||||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
// GL Mem Bar
|
||||
|
||||
left = bar_left;
|
||||
text = "GL";
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, line_height*3,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
left = bar_left+20;
|
||||
right = left + bar_width;
|
||||
|
||||
gGL.color4f(0.5f, 0.5f, 0.5f, 0.75f); // grey
|
||||
gl_rect_2d(left, top, right, bottom);
|
||||
|
||||
bar_scale = (F32)bar_width / (max_total_mem * 1.5f);
|
||||
right = left + llfloor(total_mem * bar_scale);
|
||||
right = llclamp(right, bar_left, bar_left + bar_width);
|
||||
|
||||
color = (total_mem < llfloor(max_total_mem * texmem_lower_bound_scale)) ? LLColor4::green :
|
||||
(total_mem < max_total_mem) ? LLColor4::yellow : LLColor4::red;
|
||||
color[VALPHA] = .75f;
|
||||
glColor4fv(color.mV);
|
||||
|
||||
gl_rect_2d(left, top, right, bottom); // red/yellow/green
|
||||
|
||||
//
|
||||
bar_left += bar_width + bar_space;
|
||||
//top = bottom - 2; bottom = top - 6;
|
||||
|
||||
// Bound Mem Bar
|
||||
|
||||
left = bar_left;
|
||||
text = "GL";
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, line_height*3,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
left = bar_left + 20;
|
||||
right = left + bar_width;
|
||||
|
||||
gGL.color4f(0.5f, 0.5f, 0.5f, 0.75f);
|
||||
gl_rect_2d(left, top, right, bottom);
|
||||
|
||||
|
||||
left = bar_left;
|
||||
right = left + llfloor(bound_mem * bar_scale);
|
||||
if (bound_mem < llfloor(max_bound_mem * texmem_lower_bound_scale))
|
||||
{
|
||||
gGL.color4f(0.f, 1.f, 0.f, 0.75f);
|
||||
}
|
||||
else if (bound_mem < max_bound_mem)
|
||||
{
|
||||
gGL.color4f(1.f, 1.f, 0.f, 0.75f);
|
||||
}
|
||||
else
|
||||
{
|
||||
gGL.color4f(1.f, 0.f, 0.f, 0.75f);
|
||||
}
|
||||
gl_rect_2d(left, top, right, bottom);
|
||||
color = (bound_mem < llfloor(max_bound_mem * texmem_lower_bound_scale)) ? LLColor4::green :
|
||||
(bound_mem < max_bound_mem) ? LLColor4::yellow : LLColor4::red;
|
||||
color[VALPHA] = .75f;
|
||||
glColor4fv(color.mV);
|
||||
|
||||
bar_scale = (F32)bar_width / (max_total_mem * 1.5f);
|
||||
|
||||
top = bottom - 2;
|
||||
bottom = top - 6;
|
||||
left = bar_left;
|
||||
right = left + llfloor(total_mem * bar_scale);
|
||||
if (total_mem < llfloor(max_total_mem * texmem_lower_bound_scale))
|
||||
{
|
||||
gGL.color4f(0.f, 1.f, 0.f, 0.75f);
|
||||
}
|
||||
else if (total_mem < max_total_mem)
|
||||
{
|
||||
gGL.color4f(1.f, 1.f, 0.f, 0.75f);
|
||||
}
|
||||
else
|
||||
{
|
||||
gGL.color4f(1.f, 0.f, 0.f, 0.75f);
|
||||
}
|
||||
gl_rect_2d(left, top, right, bottom);
|
||||
|
||||
#else
|
||||
S32 left = 0 ;
|
||||
#endif
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
text = llformat("Textures: Count: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d IW:%d(%d) RAW:%d mRaw:%d mAux:%d CB:%d",
|
||||
text = llformat("Textures: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d IW:%d RAW:%d HTP:%d",
|
||||
gTextureList.getNumImages(),
|
||||
LLAppViewer::getTextureFetch()->getNumRequests(), LLAppViewer::getTextureFetch()->getNumDeletes(),
|
||||
LLAppViewer::getTextureFetch()->mPacketCount, LLAppViewer::getTextureFetch()->mBadPacketCount,
|
||||
LLAppViewer::getTextureCache()->getNumReads(), LLAppViewer::getTextureCache()->getNumWrites(),
|
||||
LLLFSThread::sLocal->getPending(),
|
||||
LLImageWorker::sCount, LLImageWorker::getWorkerThread()->getNumDeletes(),
|
||||
LLImageRaw::sRawImageCount, LLViewerFetchedTexture::sRawCount, LLViewerFetchedTexture::sAuxCount,
|
||||
gTextureList.mCallbackList.size());
|
||||
LLAppViewer::getImageDecodeThread()->getPending(),
|
||||
LLImageRaw::sRawImageCount,
|
||||
LLAppViewer::getTextureFetch()->getNumHTTPRequests());
|
||||
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, h_offset + line_height*2,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
|
||||
left = 550;
|
||||
F32 bandwidth = LLAppViewer::getTextureFetch()->getTextureBandwidth();
|
||||
F32 max_bandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS");
|
||||
color = bandwidth > max_bandwidth ? LLColor4::red : bandwidth > max_bandwidth*.75f ? LLColor4::yellow : text_color;
|
||||
color[VALPHA] = text_color[VALPHA];
|
||||
text = llformat("BW:%.0f/%.0f",bandwidth, max_bandwidth);
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, line_height*2,
|
||||
color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
S32 dx1 = 0;
|
||||
if (LLAppViewer::getTextureFetch()->mDebugPause)
|
||||
|
|
@ -555,7 +582,7 @@ public:
|
|||
void setTop(S32 loaded, S32 bound, F32 scale) {mTopLoaded = loaded ; mTopBound = bound; mScale = scale ;}
|
||||
|
||||
void draw();
|
||||
BOOL handleHover(S32 x, S32 y, MASK mask) ;
|
||||
BOOL handleHover(S32 x, S32 y, MASK mask, BOOL set_pick_size) ;
|
||||
|
||||
private:
|
||||
S32 mIndex ;
|
||||
|
|
@ -568,19 +595,16 @@ private:
|
|||
F32 mScale ;
|
||||
};
|
||||
|
||||
BOOL LLGLTexSizeBar::handleHover(S32 x, S32 y, MASK mask)
|
||||
BOOL LLGLTexSizeBar::handleHover(S32 x, S32 y, MASK mask, BOOL set_pick_size)
|
||||
{
|
||||
#if !LL_RELEASE_FOR_DOWNLOAD
|
||||
if(y > mBottom && (y < mBottom + (S32)(mTopLoaded * mScale) || y < mBottom + (S32)(mTopBound * mScale)))
|
||||
{
|
||||
LLImageGL::setCurTexSizebar(mIndex);
|
||||
LLImageGL::setCurTexSizebar(mIndex, set_pick_size);
|
||||
}
|
||||
#endif
|
||||
return TRUE ;
|
||||
}
|
||||
void LLGLTexSizeBar::draw()
|
||||
{
|
||||
#if !LL_RELEASE_FOR_DOWNLOAD
|
||||
LLGLSUIDefault gls_ui;
|
||||
|
||||
if(LLImageGL::sCurTexSizeBar == mIndex)
|
||||
|
|
@ -601,7 +625,6 @@ void LLGLTexSizeBar::draw()
|
|||
F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f};
|
||||
gl_rect_2d(mLeft, mBottom + (S32)(mTopLoaded * mScale), (mLeft + mRight) / 2, mBottom, loaded_color) ;
|
||||
gl_rect_2d((mLeft + mRight) / 2, mBottom + (S32)(mTopBound * mScale), mRight, mBottom, bound_color) ;
|
||||
#endif
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -675,7 +698,13 @@ void LLTextureView::draw()
|
|||
<< "\t" << cur_discard
|
||||
<< llendl;
|
||||
}
|
||||
|
||||
|
||||
if (imagep->getID() == LLAppViewer::getTextureFetch()->mDebugID)
|
||||
{
|
||||
static S32 debug_count = 0;
|
||||
++debug_count; // for breakpoints
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (imagep->getDontDiscard())
|
||||
{
|
||||
|
|
@ -889,8 +918,7 @@ BOOL LLTextureView::handleKey(KEY key, MASK mask, BOOL called_from_parent)
|
|||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
LLTextureSizeView::LLTextureSizeView(const LLTextureSizeView::Params& p)
|
||||
: LLView(p)
|
||||
LLTextureSizeView::LLTextureSizeView(const LLTextureSizeView::Params& p) : LLContainerView(p)
|
||||
{
|
||||
setVisible(FALSE) ;
|
||||
|
||||
|
|
@ -910,7 +938,31 @@ LLTextureSizeView::~LLTextureSizeView()
|
|||
}
|
||||
void LLTextureSizeView::draw()
|
||||
{
|
||||
#if !LL_RELEASE_FOR_DOWNLOAD
|
||||
if(mType == TEXTURE_MEM_OVER_SIZE)
|
||||
{
|
||||
drawTextureSizeGraph();
|
||||
}
|
||||
else
|
||||
{
|
||||
drawTextureCategoryGraph() ;
|
||||
}
|
||||
|
||||
LLView::draw();
|
||||
}
|
||||
|
||||
BOOL LLTextureSizeView::handleHover(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
if(x > mTextureSizeBarRect.mLeft && x < mTextureSizeBarRect.mRight)
|
||||
{
|
||||
mTextureSizeBar[(x - mTextureSizeBarRect.mLeft) / mTextureSizeBarWidth]->handleHover(x, y, mask, (mType == TEXTURE_MEM_OVER_SIZE)) ;
|
||||
}
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
//draw real-time texture mem bar over size
|
||||
void LLTextureSizeView::drawTextureSizeGraph()
|
||||
{
|
||||
if(mTextureSizeBar.size() == 0)
|
||||
{
|
||||
S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
|
||||
|
|
@ -931,29 +983,16 @@ void LLTextureSizeView::draw()
|
|||
mTextureSizeBar[i]->draw() ;
|
||||
}
|
||||
LLImageGL::resetCurTexSizebar();
|
||||
|
||||
LLView::draw();
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL LLTextureSizeView::handleHover(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
if(x > mTextureSizeBarRect.mLeft && x < mTextureSizeBarRect.mRight)
|
||||
{
|
||||
mTextureSizeBar[(x - mTextureSizeBarRect.mLeft) / mTextureSizeBarWidth]->handleHover(x, y, mask) ;
|
||||
}
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
//draw background of texture size bar graph
|
||||
F32 LLTextureSizeView::drawTextureSizeDistributionGraph()
|
||||
{
|
||||
//scale
|
||||
F32 scale = 1.0f ;
|
||||
#if !LL_RELEASE_FOR_DOWNLOAD
|
||||
|
||||
LLGLSUIDefault gls_ui;
|
||||
|
||||
//scale
|
||||
{
|
||||
S32 count = 0 ;
|
||||
for(U32 i = 0 ; i < LLImageGL::sTextureLoadedCounter.size() ; i++)
|
||||
|
|
@ -1043,8 +1082,137 @@ F32 LLTextureSizeView::drawTextureSizeDistributionGraph()
|
|||
text = llformat("Texture Size Distribution") ;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 250, top + line_height * 3,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
#endif
|
||||
return scale ;
|
||||
}
|
||||
|
||||
//draw real-time texture mem bar over category
|
||||
void LLTextureSizeView::drawTextureCategoryGraph()
|
||||
{
|
||||
if(mTextureSizeBar.size() == 0)
|
||||
{
|
||||
S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
|
||||
mTextureSizeBar.resize(LLViewerTexture::getTotalNumOfCategories()) ;
|
||||
mTextureSizeBarRect.set(700, line_height * 2 + 400, 700 + mTextureSizeBar.size() * mTextureSizeBarWidth, line_height * 2) ;
|
||||
|
||||
for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++)
|
||||
{
|
||||
mTextureSizeBar[i] = new LLGLTexSizeBar(i, mTextureSizeBarRect.mLeft + i * mTextureSizeBarWidth ,
|
||||
line_height * 2, mTextureSizeBarRect.mLeft + (i + 1) * mTextureSizeBarWidth, line_height) ;
|
||||
}
|
||||
}
|
||||
|
||||
F32 size_bar_scale = drawTextureCategoryDistributionGraph() ;
|
||||
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]->draw() ;
|
||||
}
|
||||
LLImageGL::resetCurTexSizebar();
|
||||
}
|
||||
|
||||
//draw background for TEXTURE_MEM_OVER_CATEGORY
|
||||
F32 LLTextureSizeView::drawTextureCategoryDistributionGraph()
|
||||
{
|
||||
//scale
|
||||
F32 scale = 4.0f ;
|
||||
|
||||
LLGLSUIDefault gls_ui;
|
||||
|
||||
{
|
||||
S32 count = 0 ;
|
||||
for(U32 i = 0 ; i < LLImageGL::sTextureMemByCategory.size() ; i++)
|
||||
{
|
||||
S32 tmp = LLImageGL::sTextureMemByCategory[i] >> 20 ;
|
||||
if(tmp > count)
|
||||
{
|
||||
count = tmp ;
|
||||
}
|
||||
}
|
||||
if(count > mTextureSizeBarRect.getHeight() * 0.25f)
|
||||
{
|
||||
scale = (F32)mTextureSizeBarRect.getHeight() * 0.25f / count ;
|
||||
}
|
||||
}
|
||||
|
||||
S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
|
||||
S32 left = mTextureSizeBarRect.mLeft ;
|
||||
S32 bottom = mTextureSizeBarRect.mBottom ;
|
||||
S32 right = mTextureSizeBarRect.mRight ;
|
||||
S32 top = mTextureSizeBarRect.mTop ;
|
||||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
//background rect
|
||||
gl_rect_2d(left - 25, top + 30, right + 100, bottom - 25, LLColor4(0.0f, 0.0f, 0.0f, 0.25f)) ;
|
||||
|
||||
//--------------------------------------------------
|
||||
gGL.color4f(1.0f, 0.5f, 0.5f, 0.75f);
|
||||
gl_line_2d(left, bottom, right, bottom) ; //x axis
|
||||
gl_line_2d(left, bottom, left, top) ; //y axis
|
||||
|
||||
//ruler
|
||||
//--------------------------------------------------
|
||||
gGL.color4f(1.0f, 0.5f, 0.5f, 0.5f);
|
||||
for(S32 i = bottom + 50 ; i <= top ; i += 50)
|
||||
{
|
||||
gl_line_2d(left, i, right, i) ;
|
||||
}
|
||||
|
||||
//texts
|
||||
//--------------------------------------------------
|
||||
F32 text_color[] = {1.f, 1.f, 1.f, 0.75f};
|
||||
std::string text;
|
||||
|
||||
//-------
|
||||
//x axis: size label
|
||||
static char category[LLViewerTexture::MAX_GL_IMAGE_CATEGORY][4] =
|
||||
{"Non", "Bak", "Av", "Cld", "Scp", "Hi", "Trn", "Slt", "Hud", "Bsf", "UI", "Pvw", "Map", "Mvs", "Slf", "Loc", "Scr", "Dyn", "Mdi", "ALT", "Oth" } ;
|
||||
|
||||
text = llformat("%s", category[0]) ;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 12, bottom - line_height / 2,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
for(U32 i = 1 ; i < mTextureSizeBar.size() ; i++)
|
||||
{
|
||||
text = llformat("%s", category[i]) ;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + i * mTextureSizeBarWidth + 12, bottom - line_height / 2,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
}
|
||||
//-------
|
||||
|
||||
//y axis: number label
|
||||
for(S32 i = bottom + 50 ; i <= top ; i += 50)
|
||||
{
|
||||
text = llformat("%d", (S32)((i - bottom) / scale)) ;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, i + line_height / 2 ,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, right + 5, i + line_height / 2 ,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
}
|
||||
|
||||
text = llformat("MB") ;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, top + line_height * 2 ,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
//--------------------------------------------------
|
||||
F32 loaded_color[] = {1.0f, 0.0f, 0.0f, 0.75f};
|
||||
gl_rect_2d(left + 70, top + line_height * 2, left + 90, top + line_height, loaded_color) ;
|
||||
text = llformat("Loaded") ;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 100, top + line_height * 2,
|
||||
loaded_color,
|
||||
LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f};
|
||||
gl_rect_2d(left + 170, top + line_height * 2, left + 190, top + line_height, bound_color) ;
|
||||
text = llformat("Bound") ;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 200, top + line_height * 2,
|
||||
bound_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
//title
|
||||
text = llformat("Texture Category Distribution") ;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 250, top + line_height * 3,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
return scale ;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,24 +79,41 @@ public:
|
|||
};
|
||||
|
||||
class LLGLTexSizeBar;
|
||||
|
||||
class LLTextureSizeView : public LLView
|
||||
class LLTextureSizeView : public LLContainerView
|
||||
{
|
||||
public:
|
||||
protected:
|
||||
LLTextureSizeView(const Params&);
|
||||
friend class LLUICtrlFactory;
|
||||
public:
|
||||
~LLTextureSizeView();
|
||||
|
||||
/*virtual*/ void draw();
|
||||
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask) ;
|
||||
|
||||
void setType(S32 type) {mType = type ;}
|
||||
enum
|
||||
{
|
||||
TEXTURE_MEM_OVER_SIZE,
|
||||
TEXTURE_MEM_OVER_CATEGORY
|
||||
};
|
||||
private:
|
||||
//draw background for TEXTURE_MEM_OVER_SIZE
|
||||
F32 drawTextureSizeDistributionGraph() ;
|
||||
|
||||
//draw real-time texture mem bar over size
|
||||
void drawTextureSizeGraph();
|
||||
|
||||
//draw background for TEXTURE_MEM_OVER_CATEGORY
|
||||
F32 drawTextureCategoryDistributionGraph() ;
|
||||
//draw real-time texture mem bar over category
|
||||
void drawTextureCategoryGraph();
|
||||
|
||||
private:
|
||||
std::vector<LLGLTexSizeBar*> mTextureSizeBar ;
|
||||
LLRect mTextureSizeBarRect ;
|
||||
S32 mTextureSizeBarWidth ;
|
||||
S32 mTextureSizeBarWidth ;
|
||||
S32 mType ;
|
||||
};
|
||||
extern LLTextureView *gTextureView;
|
||||
extern LLTextureSizeView *gTextureSizeView;
|
||||
extern LLTextureSizeView *gTextureCategoryView;
|
||||
#endif // LL_TEXTURE_VIEW_H
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
#include "llstartup.h" // gStartupState
|
||||
#include "llurlsimstring.h"
|
||||
#include "llweb.h"
|
||||
#include "llworldmap.h"
|
||||
#include "llworldmapmessage.h"
|
||||
|
||||
// library includes
|
||||
#include "llsd.h"
|
||||
|
|
@ -201,7 +201,7 @@ bool LLURLDispatcherImpl::dispatchRegion(const std::string& url, bool right_mous
|
|||
//if(url_displayp) url_displayp->setName(region_name);
|
||||
|
||||
// Request a region handle by name
|
||||
LLWorldMap::getInstance()->sendNamedRegionRequest(region_name,
|
||||
LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name,
|
||||
LLURLDispatcherImpl::regionNameCallback,
|
||||
url,
|
||||
false); // don't teleport
|
||||
|
|
@ -240,7 +240,7 @@ void LLURLDispatcherImpl::regionNameCallback(U64 region_handle, const std::strin
|
|||
LLVector3d global_pos = from_region_handle(region_handle) + LLVector3d(local_pos);
|
||||
|
||||
U64 new_region_handle = to_region_handle(global_pos);
|
||||
LLWorldMap::getInstance()->sendHandleRegionRequest(new_region_handle,
|
||||
LLWorldMapMessage::getInstance()->sendHandleRegionRequest(new_region_handle,
|
||||
LLURLDispatcherImpl::regionHandleCallback,
|
||||
url, teleport);
|
||||
}
|
||||
|
|
@ -335,7 +335,7 @@ public:
|
|||
{
|
||||
url += tokens[i].asString() + "/";
|
||||
}
|
||||
LLWorldMap::getInstance()->sendNamedRegionRequest(region_name,
|
||||
LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name,
|
||||
LLURLDispatcherImpl::regionHandleCallback,
|
||||
url,
|
||||
true); // teleport
|
||||
|
|
|
|||
|
|
@ -109,10 +109,13 @@ LLViewerCamera::LLViewerCamera() : LLCamera()
|
|||
{
|
||||
calcProjection(getFar());
|
||||
mCameraFOVDefault = DEFAULT_FIELD_OF_VIEW;
|
||||
mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f);
|
||||
mPixelMeterRatio = 0.f;
|
||||
mScreenPixelArea = 0;
|
||||
mZoomFactor = 1.f;
|
||||
mZoomSubregion = 1;
|
||||
mAverageSpeed = 0.f;
|
||||
mAverageAngularSpeed = 0.f;
|
||||
gSavedSettings.getControl("CameraAngle")->getCommitSignal()->connect(boost::bind(&LLViewerCamera::updateCameraAngle, this, _2));
|
||||
}
|
||||
|
||||
|
|
@ -151,15 +154,22 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 ¢er,
|
|||
|
||||
setOriginAndLookAt(origin, up_direction, point_of_interest);
|
||||
|
||||
F32 dpos = (center - last_position).magVec();
|
||||
mVelocityDir = center - last_position ;
|
||||
F32 dpos = mVelocityDir.normVec() ;
|
||||
LLQuaternion rotation;
|
||||
rotation.shortestArc(last_axis, getAtAxis());
|
||||
|
||||
F32 x, y, z;
|
||||
F32 drot;
|
||||
rotation.getAngleAxis(&drot, &x, &y, &z);
|
||||
|
||||
mVelocityStat.addValue(dpos);
|
||||
mAngularVelocityStat.addValue(drot);
|
||||
|
||||
mAverageSpeed = mVelocityStat.getMeanPerSec() ;
|
||||
mAverageAngularSpeed = mAngularVelocityStat.getMeanPerSec() ;
|
||||
mCosHalfCameraFOV = cosf(0.5f * getView() * llmax(1.0f, getAspect()));
|
||||
|
||||
// update pixel meter ratio using default fov, not modified one
|
||||
mPixelMeterRatio = getViewHeightInPixels()/ (2.f*tanf(mCameraFOVDefault*0.5));
|
||||
// update screen pixel area
|
||||
|
|
@ -818,10 +828,12 @@ BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts)
|
|||
LLCamera::setView(vertical_fov_rads); // call base implementation
|
||||
}
|
||||
|
||||
void LLViewerCamera::setDefaultFOV(F32 vertical_fov_rads) {
|
||||
void LLViewerCamera::setDefaultFOV(F32 vertical_fov_rads)
|
||||
{
|
||||
vertical_fov_rads = llclamp(vertical_fov_rads, getMinView(), getMaxView());
|
||||
setView(vertical_fov_rads);
|
||||
mCameraFOVDefault = vertical_fov_rads;
|
||||
mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -91,17 +91,20 @@ public:
|
|||
BOOL projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoordGL &out_point, const BOOL clamp = TRUE) const;
|
||||
BOOL projectPosAgentToScreenEdge(const LLVector3 &pos_agent, LLCoordGL &out_point) const;
|
||||
|
||||
|
||||
const LLVector3* getVelocityDir() const {return &mVelocityDir;}
|
||||
LLStat *getVelocityStat() { return &mVelocityStat; }
|
||||
LLStat *getAngularVelocityStat() { return &mAngularVelocityStat; }
|
||||
F32 getCosHalfFov() {return mCosHalfCameraFOV;}
|
||||
F32 getAverageSpeed() {return mAverageSpeed ;}
|
||||
F32 getAverageAngularSpeed() {return mAverageAngularSpeed;}
|
||||
|
||||
void getPixelVectors(const LLVector3 &pos_agent, LLVector3 &up, LLVector3 &right);
|
||||
LLVector3 roundToPixel(const LLVector3 &pos_agent);
|
||||
|
||||
// Sets the current matrix
|
||||
/* virtual */ void setView(F32 vertical_fov_rads);
|
||||
// Sets the current matrix AND remembers result as default view
|
||||
void setDefaultFOV(F32 vertical_fov_rads);
|
||||
|
||||
void setDefaultFOV(F32 fov) ;
|
||||
F32 getDefaultFOV() { return mCameraFOVDefault; }
|
||||
|
||||
BOOL cameraUnderWater() const;
|
||||
|
|
@ -120,9 +123,14 @@ protected:
|
|||
|
||||
LLStat mVelocityStat;
|
||||
LLStat mAngularVelocityStat;
|
||||
LLVector3 mVelocityDir ;
|
||||
F32 mAverageSpeed ;
|
||||
F32 mAverageAngularSpeed ;
|
||||
|
||||
mutable LLMatrix4 mProjectionMatrix; // Cache of perspective matrix
|
||||
mutable LLMatrix4 mModelviewMatrix;
|
||||
F32 mCameraFOVDefault;
|
||||
F32 mCosHalfCameraFOV;
|
||||
LLVector3 mLastPointOfInterest;
|
||||
F32 mPixelMeterRatio; // Divide by distance from camera to get pixels per meter at that distance.
|
||||
S32 mScreenPixelArea; // Pixel area of entire window
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ std::string gCurrentVersion;
|
|||
|
||||
extern BOOL gResizeScreenTexture;
|
||||
extern BOOL gDebugGL;
|
||||
|
||||
extern BOOL gAuditTexture;
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Listeners
|
||||
|
||||
|
|
@ -378,6 +378,12 @@ static bool handleRenderUseImpostorsChanged(const LLSD& newvalue)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool handleAuditTextureChanged(const LLSD& newvalue)
|
||||
{
|
||||
gAuditTexture = newvalue.asBoolean();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool handleRenderDebugGLChanged(const LLSD& newvalue)
|
||||
{
|
||||
gDebugGL = newvalue.asBoolean() || gDebugSession;
|
||||
|
|
@ -566,6 +572,7 @@ void settings_setup_listeners()
|
|||
gSavedSettings.getControl("RenderDeferredShadow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
|
||||
gSavedSettings.getControl("RenderDeferredGI")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
|
||||
gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _2));
|
||||
gSavedSettings.getControl("AuditTexture")->getSignal()->connect(boost::bind(&handleAuditTextureChanged, _2));
|
||||
gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _2));
|
||||
gSavedSettings.getControl("ChatPersistTime")->getSignal()->connect(boost::bind(&handleChatPersistTimeChanged, _2));
|
||||
gSavedSettings.getControl("ConsoleMaxLines")->getSignal()->connect(boost::bind(&handleConsoleMaxLinesChanged, _2));
|
||||
|
|
|
|||
|
|
@ -712,7 +712,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
|||
|
||||
gBumpImageList.updateImages(); // must be called before gTextureList version so that it's textures are thrown out first.
|
||||
|
||||
const F32 max_image_decode_time = llmin(0.005f, 0.005f*10.f*gFrameIntervalSeconds); // 50 ms/second decode time (no more than 5ms/frame)
|
||||
F32 max_image_decode_time = 0.050f*gFrameIntervalSeconds; // 50 ms/second decode time
|
||||
max_image_decode_time = llclamp(max_image_decode_time, 0.001f, 0.005f ); // min 1ms/frame, max 5ms/frame)
|
||||
gTextureList.updateImages(max_image_decode_time);
|
||||
|
||||
//remove dead textures from GL
|
||||
|
|
|
|||
|
|
@ -606,6 +606,14 @@ class LLAdvancedToggleConsole : public view_listener_t
|
|||
{
|
||||
toggle_visibility( (void*)((LLView*)gDebugView->mDebugConsolep) );
|
||||
}
|
||||
else if (gTextureSizeView && "texture size" == console_type)
|
||||
{
|
||||
toggle_visibility( (void*)gTextureSizeView );
|
||||
}
|
||||
else if (gTextureCategoryView && "texture category" == console_type)
|
||||
{
|
||||
toggle_visibility( (void*)gTextureCategoryView );
|
||||
}
|
||||
else if ("fast timers" == console_type)
|
||||
{
|
||||
toggle_visibility( (void*)gDebugView->mFastTimerView );
|
||||
|
|
@ -633,6 +641,14 @@ class LLAdvancedCheckConsole : public view_listener_t
|
|||
{
|
||||
new_value = get_visibility( (void*)((LLView*)gDebugView->mDebugConsolep) );
|
||||
}
|
||||
else if (gTextureSizeView && "texture size" == console_type)
|
||||
{
|
||||
new_value = get_visibility( (void*)gTextureSizeView );
|
||||
}
|
||||
else if (gTextureCategoryView && "texture category" == console_type)
|
||||
{
|
||||
new_value = get_visibility( (void*)gTextureCategoryView );
|
||||
}
|
||||
else if ("fast timers" == console_type)
|
||||
{
|
||||
new_value = get_visibility( (void*)gDebugView->mFastTimerView );
|
||||
|
|
@ -1156,28 +1172,6 @@ class LLAdvancedCheckWireframe : public view_listener_t
|
|||
}
|
||||
};
|
||||
|
||||
//////////////////////
|
||||
// DISABLE TEXTURES //
|
||||
//////////////////////
|
||||
|
||||
class LLAdvancedToggleDisableTextures : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
LLViewerTexture::sDontLoadVolumeTextures = !LLViewerTexture::sDontLoadVolumeTextures;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LLAdvancedCheckDisableTextures : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
bool new_value = LLViewerTexture::sDontLoadVolumeTextures; // <-- make this using LLCacheControl
|
||||
return new_value;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////
|
||||
// TEXTURE ATLAS //
|
||||
//////////////////////
|
||||
|
|
@ -1909,7 +1903,7 @@ class LLAdvancedRebakeTextures : public view_listener_t
|
|||
};
|
||||
|
||||
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
#if 1 //ndef LL_RELEASE_FOR_DOWNLOAD
|
||||
///////////////////////////
|
||||
// DEBUG AVATAR TEXTURES //
|
||||
///////////////////////////
|
||||
|
|
@ -3511,9 +3505,8 @@ void set_god_level(U8 god_level)
|
|||
gIMMgr->refresh();
|
||||
LLViewerParcelMgr::getInstance()->notifyObservers();
|
||||
|
||||
// God mode changes sim visibility
|
||||
LLWorldMap::getInstance()->reset();
|
||||
LLWorldMap::getInstance()->setCurrentLayer(0);
|
||||
// God mode changes region visibility
|
||||
LLWorldMap::getInstance()->reloadItems(true);
|
||||
|
||||
// inventory in items may change in god mode
|
||||
gObjectList.dirtyAllObjectInventory();
|
||||
|
|
@ -7887,8 +7880,6 @@ void initialize_menus()
|
|||
view_listener_t::addMenu(new LLAdvancedSelectedTextureInfo(), "Advanced.SelectedTextureInfo");
|
||||
view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe");
|
||||
view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe");
|
||||
view_listener_t::addMenu(new LLAdvancedToggleDisableTextures(), "Advanced.ToggleDisableTextures");
|
||||
view_listener_t::addMenu(new LLAdvancedCheckDisableTextures(), "Advanced.CheckDisableTextures");
|
||||
view_listener_t::addMenu(new LLAdvancedToggleTextureAtlas(), "Advanced.ToggleTextureAtlas");
|
||||
view_listener_t::addMenu(new LLAdvancedCheckTextureAtlas(), "Advanced.CheckTextureAtlas");
|
||||
view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion");
|
||||
|
|
|
|||
|
|
@ -2906,7 +2906,7 @@ F32 LLViewerObject::getMidScale() const
|
|||
}
|
||||
|
||||
|
||||
void LLViewerObject::updateTextures(LLAgent &agent)
|
||||
void LLViewerObject::updateTextures()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ public:
|
|||
S32 getNumFaces() const { return mNumFaces; }
|
||||
|
||||
// Graphical stuff for objects - maybe broken out into render class later?
|
||||
virtual void updateTextures(LLAgent &agent);
|
||||
virtual void updateTextures();
|
||||
virtual void boostTexturePriority(BOOL boost_children = TRUE); // When you just want to boost priority of this object
|
||||
|
||||
virtual LLDrawable* createDrawable(LLPipeline *pipeline);
|
||||
|
|
|
|||
|
|
@ -642,7 +642,7 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
|
|||
|
||||
// Update distance & gpw
|
||||
objectp->setPixelAreaAndAngle(agent); // Also sets the approx. pixel area
|
||||
objectp->updateTextures(agent); // Update the image levels of textures for this object.
|
||||
objectp->updateTextures(); // Update the image levels of textures for this object.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1074,6 +1074,7 @@ void LLViewerObjectList::renderObjectsForMap(LLNetMap &netmap)
|
|||
LLColor4 group_own_below_water_color =
|
||||
LLUIColorTable::instance().getColor( "NetMapGroupOwnBelowWater" );
|
||||
|
||||
F32 max_radius = gSavedSettings.getF32("MiniMapPrimMaxRadius");
|
||||
|
||||
for (S32 i = 0; i < mMapObjects.count(); i++)
|
||||
{
|
||||
|
|
@ -1089,6 +1090,11 @@ void LLViewerObjectList::renderObjectsForMap(LLNetMap &netmap)
|
|||
|
||||
F32 approx_radius = (scale.mV[VX] + scale.mV[VY]) * 0.5f * 0.5f * 1.3f; // 1.3 is a fudge
|
||||
|
||||
// Limit the size of megaprims so they don't blot out everything on the minimap.
|
||||
// Attempting to draw very large megaprims also causes client lag.
|
||||
// See DEV-17370 and DEV-29869/SNOW-79 for details.
|
||||
approx_radius = llmin(approx_radius, max_radius);
|
||||
|
||||
LLColor4U color = above_water_color;
|
||||
if( objectp->permYouOwner() )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1427,11 +1427,11 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
|
|||
capabilityNames.append("EstateChangeInfo");
|
||||
capabilityNames.append("EventQueueGet");
|
||||
capabilityNames.append("FetchInventory");
|
||||
capabilityNames.append("WebFetchInventoryDescendents");
|
||||
capabilityNames.append("ObjectMedia");
|
||||
capabilityNames.append("ObjectMediaNavigate");
|
||||
capabilityNames.append("FetchLib");
|
||||
capabilityNames.append("FetchLibDescendents");
|
||||
capabilityNames.append("GetTexture");
|
||||
capabilityNames.append("GroupProposalBallot");
|
||||
capabilityNames.append("HomeLocation");
|
||||
capabilityNames.append("MapLayer");
|
||||
|
|
@ -1452,6 +1452,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
|
|||
capabilityNames.append("SendUserReportWithScreenshot");
|
||||
capabilityNames.append("ServerReleaseNotes");
|
||||
capabilityNames.append("StartGroupProposal");
|
||||
capabilityNames.append("TextureStats");
|
||||
capabilityNames.append("UntrustedSimulatorMessage");
|
||||
capabilityNames.append("UpdateAgentInformation");
|
||||
capabilityNames.append("UpdateAgentLanguage");
|
||||
|
|
@ -1464,6 +1465,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
|
|||
capabilityNames.append("UploadBakedTexture");
|
||||
capabilityNames.append("ViewerStartAuction");
|
||||
capabilityNames.append("ViewerStats");
|
||||
capabilityNames.append("WebFetchInventoryDescendents");
|
||||
// Please add new capabilities alphabetically to reduce
|
||||
// merge conflicts.
|
||||
|
||||
|
|
|
|||
|
|
@ -560,12 +560,18 @@ extern U32 gVisCompared;
|
|||
extern U32 gVisTested;
|
||||
|
||||
std::map<S32,LLFrameTimer> gDebugTimers;
|
||||
std::map<S32,std::string> gDebugTimerLabel;
|
||||
|
||||
void init_statistics()
|
||||
{
|
||||
// Label debug timers
|
||||
gDebugTimerLabel[0] = "Texture";
|
||||
}
|
||||
|
||||
void update_statistics(U32 frame_count)
|
||||
{
|
||||
gTotalWorldBytes += gVLManager.getTotalBytes();
|
||||
gTotalObjectBytes += gObjectBits / 8;
|
||||
gTotalTextureBytes += gTextureList.mTextureBits / 8;
|
||||
|
||||
// make sure we have a valid time delta for this frame
|
||||
if (gFrameIntervalSeconds > 0.f)
|
||||
|
|
@ -617,7 +623,6 @@ void update_statistics(U32 frame_count)
|
|||
F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits());
|
||||
LLViewerStats::getInstance()->mLayersKBitStat.addValue(layer_bits/1024.f);
|
||||
LLViewerStats::getInstance()->mObjectKBitStat.addValue(gObjectBits/1024.f);
|
||||
LLViewerStats::getInstance()->mTextureKBitStat.addValue(gTextureList.mTextureBits/1024.f);
|
||||
LLViewerStats::getInstance()->mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending());
|
||||
LLViewerStats::getInstance()->mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f);
|
||||
gTransferManager.resetTransferBitsIn(LLTCT_ASSET);
|
||||
|
|
@ -631,8 +636,6 @@ void update_statistics(U32 frame_count)
|
|||
gDebugTimers[0].unpause();
|
||||
}
|
||||
|
||||
LLViewerStats::getInstance()->mTexturePacketsStat.addValue(gTextureList.mTexturePackets);
|
||||
|
||||
{
|
||||
static F32 visible_avatar_frames = 0.f;
|
||||
static F32 avg_visible_avatars = 0;
|
||||
|
|
@ -652,8 +655,20 @@ void update_statistics(U32 frame_count)
|
|||
gObjectBits = 0;
|
||||
// gDecodedBits = 0;
|
||||
|
||||
gTextureList.mTextureBits = 0;
|
||||
gTextureList.mTexturePackets = 0;
|
||||
// Only update texture stats ones per second so that they are less noisy
|
||||
{
|
||||
static const F32 texture_stats_freq = 1.f;
|
||||
static LLFrameTimer texture_stats_timer;
|
||||
if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq)
|
||||
{
|
||||
LLViewerStats::getInstance()->mTextureKBitStat.addValue(LLViewerTextureList::sTextureBits/1024.f);
|
||||
LLViewerStats::getInstance()->mTexturePacketsStat.addValue(LLViewerTextureList::sTexturePackets);
|
||||
gTotalTextureBytes += LLViewerTextureList::sTextureBits / 8;
|
||||
LLViewerTextureList::sTextureBits = 0;
|
||||
LLViewerTextureList::sTexturePackets = 0;
|
||||
texture_stats_timer.reset();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -826,3 +841,4 @@ void send_stats()
|
|||
LLViewerStats::getInstance()->addToMessage(body);
|
||||
LLHTTPClient::post(url, body, new ViewerStatsResponder());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#define LL_LLVIEWERSTATS_H
|
||||
|
||||
#include "llstat.h"
|
||||
#include "lltextureinfo.h"
|
||||
|
||||
class LLViewerStats : public LLSingleton<LLViewerStats>
|
||||
{
|
||||
|
|
@ -205,10 +206,13 @@ private:
|
|||
static const F32 SEND_STATS_PERIOD = 300.0f;
|
||||
|
||||
// The following are from (older?) statistics code found in appviewer.
|
||||
void init_statistics();
|
||||
void reset_statistics();
|
||||
void output_statistics(void*);
|
||||
void update_statistics(U32 frame_count);
|
||||
void send_stats();
|
||||
|
||||
extern std::map<S32,LLFrameTimer> gDebugTimers;
|
||||
extern std::map<S32,std::string> gDebugTimerLabel;
|
||||
|
||||
#endif // LL_LLVIEWERSTATS_H
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -121,11 +121,23 @@ public:
|
|||
BOOST_UI = 15,
|
||||
BOOST_PREVIEW = 16,
|
||||
BOOST_MAP = 17,
|
||||
BOOST_MAP_LAYER = 18,
|
||||
BOOST_MAP_VISIBLE = 18,
|
||||
BOOST_AVATAR_SELF = 19, // needed for baking avatar
|
||||
BOOST_MAX_LEVEL
|
||||
BOOST_MAX_LEVEL,
|
||||
|
||||
//other texture Categories
|
||||
LOCAL = BOOST_MAX_LEVEL,
|
||||
AVATAR_SCRATCH_TEX,
|
||||
DYNAMIC_TEX,
|
||||
MEDIA,
|
||||
ATLAS,
|
||||
OTHER,
|
||||
MAX_GL_IMAGE_CATEGORY
|
||||
};
|
||||
|
||||
static S32 getTotalNumOfCategories() ;
|
||||
static S32 getIndexFromCategory(S32 category) ;
|
||||
static S32 getCategoryFromIndex(S32 index) ;
|
||||
|
||||
typedef std::list<LLFace*> ll_face_list_t ;
|
||||
|
||||
protected:
|
||||
|
|
@ -146,7 +158,7 @@ public:
|
|||
virtual BOOL isMissingAsset()const ;
|
||||
virtual void dump(); // debug info to llinfos
|
||||
|
||||
/*virtual*/ bool bindDefaultImage(const S32 stage = 0) const ;
|
||||
/*virtual*/ bool bindDefaultImage(const S32 stage = 0) ;
|
||||
/*virtual*/ void forceImmediateUpdate() ;
|
||||
|
||||
const LLUUID& getID() const { return mID; }
|
||||
|
|
@ -154,9 +166,9 @@ public:
|
|||
void setBoostLevel(S32 level);
|
||||
S32 getBoostLevel() { return mBoostLevel; }
|
||||
|
||||
//maxVirtualSize of the texture
|
||||
void addTextureStats(F32 virtual_size) const ;
|
||||
void resetTextureStats(BOOL zero = FALSE);
|
||||
void addTextureStats(F32 virtual_size, BOOL needs_gltexture = TRUE) const;
|
||||
void resetTextureStats();
|
||||
|
||||
virtual F32 getMaxVirtualSize() ;
|
||||
|
||||
LLFrameTimer* getLastReferencedTimer() {return &mLastReferencedTimer ;}
|
||||
|
|
@ -180,7 +192,7 @@ public:
|
|||
BOOL hasGLTexture() const ;
|
||||
LLGLuint getTexName() const ;
|
||||
BOOL createGLTexture() ;
|
||||
BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0);
|
||||
BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = LLViewerTexture::OTHER);
|
||||
|
||||
void setFilteringOption(LLTexUnit::eTextureFilterOptions option);
|
||||
void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
|
||||
|
|
@ -188,7 +200,8 @@ public:
|
|||
BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height);
|
||||
BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height);
|
||||
void setGLTextureCreated (bool initialized);
|
||||
|
||||
void setCategory(S32 category) ;
|
||||
|
||||
LLTexUnit::eTextureAddressMode getAddressMode(void) const ;
|
||||
S32 getMaxDiscardLevel() const;
|
||||
S32 getDiscardLevel() const;
|
||||
|
|
@ -201,8 +214,8 @@ public:
|
|||
BOOL getMask(const LLVector2 &tc);
|
||||
F32 getTimePassedSinceLastBound();
|
||||
BOOL getMissed() const ;
|
||||
BOOL isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) ;
|
||||
BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const;
|
||||
BOOL isJustBound()const ;
|
||||
void forceUpdateBindStats(void) const;
|
||||
|
||||
U32 getTexelsInAtlas() const ;
|
||||
U32 getTexelsInGLTexture() const ;
|
||||
|
|
@ -220,6 +233,7 @@ public:
|
|||
BOOL getDontDiscard() const { return mDontDiscard; }
|
||||
//-----------------
|
||||
|
||||
BOOL isLargeImage() ;
|
||||
/*virtual*/ void updateBindStatsForTester() ;
|
||||
protected:
|
||||
void cleanup() ;
|
||||
|
|
@ -228,6 +242,7 @@ protected:
|
|||
private:
|
||||
//note: do not make this function public.
|
||||
/*virtual*/ LLImageGL* getGLTexture() const ;
|
||||
virtual void switchToCachedImage();
|
||||
|
||||
protected:
|
||||
LLUUID mID;
|
||||
|
|
@ -237,7 +252,9 @@ protected:
|
|||
BOOL mUseMipMaps ;
|
||||
S8 mComponents;
|
||||
mutable F32 mMaxVirtualSize; // The largest virtual size of the image, in pixels - how much data to we need?
|
||||
mutable S8 mNeedsGLTexture;
|
||||
mutable BOOL mNeedsResetMaxVirtualSize ;
|
||||
mutable F32 mAdditionalDecodePriority; // priority add to mDecodePriority.
|
||||
LLFrameTimer mLastReferencedTimer;
|
||||
|
||||
ll_face_list_t mFaceList ; //reverse pointer pointing to the faces using this image as texture
|
||||
|
|
@ -270,7 +287,12 @@ public:
|
|||
static S32 sMaxBoundTextureMemInMegaBytes;
|
||||
static S32 sMaxTotalTextureMemInMegaBytes;
|
||||
static S32 sMaxDesiredTextureMemInBytes ;
|
||||
static BOOL sDontLoadVolumeTextures;
|
||||
static S8 sCameraMovingDiscardBias;
|
||||
static S32 sMaxSculptRez ;
|
||||
static S32 sMinLargeImageSize ;
|
||||
static S32 sMaxSmallImageSize ;
|
||||
static BOOL sFreezeImageScalingDown ;//do not scale down image res if set.
|
||||
static F32 sCurrentTime ;
|
||||
static BOOL sUseTextureAtlas ;
|
||||
|
||||
static LLPointer<LLViewerTexture> sNullImagep; // Null texture for non-textured objects.
|
||||
|
|
@ -290,9 +312,9 @@ class LLViewerFetchedTexture : public LLViewerTexture
|
|||
protected:
|
||||
/*virtual*/ ~LLViewerFetchedTexture();
|
||||
public:
|
||||
LLViewerFetchedTexture(const LLUUID& id, BOOL usemipmaps = TRUE);
|
||||
LLViewerFetchedTexture(const LLUUID& id, const LLHost& host = LLHost::invalid, BOOL usemipmaps = TRUE);
|
||||
LLViewerFetchedTexture(const LLImageRaw* raw, BOOL usemipmaps);
|
||||
LLViewerFetchedTexture(const std::string& full_path, const LLUUID& id, BOOL usemipmaps = TRUE);
|
||||
LLViewerFetchedTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps = TRUE);
|
||||
|
||||
public:
|
||||
static F32 maxDecodePriority();
|
||||
|
|
@ -328,6 +350,8 @@ public:
|
|||
bool hasCallbacks() { return mLoadedCallbackList.empty() ? false : true; }
|
||||
bool doLoadedCallbacks();
|
||||
|
||||
void addToCreateTexture();
|
||||
|
||||
// ONLY call from LLViewerTextureList
|
||||
BOOL createTexture(S32 usename = 0);
|
||||
void destroyTexture() ;
|
||||
|
|
@ -346,7 +370,12 @@ public:
|
|||
// the priority list, and cause horrible things to happen.
|
||||
void setDecodePriority(F32 priority = -1.0f);
|
||||
F32 getDecodePriority() const { return mDecodePriority; };
|
||||
|
||||
void setAdditionalDecodePriority(F32 priority) ;
|
||||
F32 maxAdditionalDecodePriority() ;
|
||||
|
||||
void updateVirtualSize() ;
|
||||
|
||||
// setDesiredDiscardLevel is only used by LLViewerTextureList
|
||||
void setDesiredDiscardLevel(S32 discard) { mDesiredDiscardLevel = discard; }
|
||||
S32 getDesiredDiscardLevel() { return mDesiredDiscardLevel; }
|
||||
|
|
@ -370,15 +399,15 @@ public:
|
|||
BOOL isInImageList() const {return mInImageList ;}
|
||||
void setInImageList(BOOL flag) {mInImageList = flag ;}
|
||||
|
||||
const std::string& getLocalFileName() const {return mLocalFileName ;}
|
||||
LLFrameTimer* getLastPacketTimer() {return &mLastPacketTimer;}
|
||||
|
||||
U32 getFetchPriority() const { return mFetchPriority ;}
|
||||
F32 getDownloadProgress() const {return mDownloadProgress ;}
|
||||
|
||||
LLImageRaw* readBackRawImage(S8 discard_level) ;
|
||||
LLImageRaw* reloadRawImage(S8 discard_level) ;
|
||||
void destroyRawImage();
|
||||
|
||||
const std::string& getUrl() const {return mUrl;}
|
||||
//---------------
|
||||
BOOL isDeleted() ;
|
||||
BOOL isInactive() ;
|
||||
|
|
@ -389,13 +418,36 @@ public:
|
|||
//---------------
|
||||
|
||||
void setForSculpt();
|
||||
BOOL isForSculpt() const {return mForSculpt;}
|
||||
BOOL forSculpt() const {return mForSculpt;}
|
||||
BOOL isForSculptOnly() const;
|
||||
|
||||
//raw image management
|
||||
void checkCachedRawSculptImage() ;
|
||||
LLImageRaw* getRawImage()const { return mRawImage ;}
|
||||
S32 getRawImageLevel() const {return mRawDiscardLevel;}
|
||||
LLImageRaw* getCachedRawImage() const { return mCachedRawImage ;}
|
||||
S32 getCachedRawImageLevel() const {return mCachedRawDiscardLevel;}
|
||||
BOOL isCachedRawImageReady() const {return mCachedRawImageReady ;}
|
||||
BOOL isRawImageValid()const { return mIsRawImageValid ; }
|
||||
void forceToSaveRawImage(S32 desired_discard = 0) ;
|
||||
void destroySavedRawImage() ;
|
||||
LLImageRaw* getSavedRawImage() ;
|
||||
BOOL hasSavedRawImage() const ;
|
||||
F32 getElapsedLastReferencedSavedRawImageTime() const ;
|
||||
BOOL isFullyLoaded() const;
|
||||
|
||||
protected:
|
||||
/*virtual*/ void switchToCachedImage();
|
||||
|
||||
private:
|
||||
void init(bool firstinit) ;
|
||||
void cleanup() ;
|
||||
|
||||
F32 calcDecodePriorityForUnknownTexture(F32 pixel_priority) ;
|
||||
void saveRawImage() ;
|
||||
BOOL forceFetch() ;
|
||||
void setCachedRawImage() ;
|
||||
BOOL keepReuestedDiscardLevel();
|
||||
|
||||
//for atlas
|
||||
void resetFaceAtlas() ;
|
||||
|
|
@ -414,12 +466,8 @@ protected:
|
|||
S32 mKnownDrawWidth;
|
||||
S32 mKnownDrawHeight;
|
||||
|
||||
std::string mLocalFileName;
|
||||
|
||||
S8 mDesiredDiscardLevel; // The discard level we'd LIKE to have - if we have it and there's space
|
||||
S8 mMinDesiredDiscardLevel; // The minimum discard level we'd like to have
|
||||
S32 mMinDiscardLevel;
|
||||
|
||||
std::string mUrl;
|
||||
|
||||
S32 mRequestedDiscardLevel;
|
||||
F32 mRequestedDownloadPriority;
|
||||
S32 mFetchState;
|
||||
|
|
@ -429,6 +477,10 @@ protected:
|
|||
F32 mRequestDeltaTime;
|
||||
S32 mDecodeFrame;
|
||||
S32 mVisibleFrame; // decode frame where image was last visible
|
||||
F32 mDecodePriority; // The priority for decoding this image.
|
||||
S32 mMinDiscardLevel;
|
||||
S8 mDesiredDiscardLevel; // The discard level we'd LIKE to have - if we have it and there's space
|
||||
S8 mMinDesiredDiscardLevel; // The minimum discard level we'd like to have
|
||||
|
||||
S8 mNeedsAux; // We need to decode the auxiliary channels
|
||||
S8 mDecodingAux; // Are we decoding high components
|
||||
|
|
@ -436,10 +488,10 @@ protected:
|
|||
S8 mHasFetcher; // We've made a fecth request
|
||||
S8 mIsFetching; // Fetch request is active
|
||||
|
||||
mutable S8 mIsMissingAsset; // True if we know that there is no image asset with this image id in the database.
|
||||
mutable S8 mIsMissingAsset; // True if we know that there is no image asset with this image id in the database.
|
||||
|
||||
F32 mDecodePriority; // The priority for decoding this image.
|
||||
typedef std::list<LLLoadedCallbackEntry*> callback_list_t;
|
||||
S8 mLoadedCallbackDesiredDiscardLevel;
|
||||
callback_list_t mLoadedCallbackList;
|
||||
|
||||
LLPointer<LLImageRaw> mRawImage;
|
||||
|
|
@ -449,6 +501,19 @@ protected:
|
|||
// doing if you use it for anything else! - djs
|
||||
LLPointer<LLImageRaw> mAuxRawImage;
|
||||
|
||||
//keep a copy of mRawImage for some special purposes
|
||||
//when mForceToSaveRawImage is set.
|
||||
BOOL mForceToSaveRawImage ;
|
||||
LLPointer<LLImageRaw> mSavedRawImage;
|
||||
S32 mSavedRawDiscardLevel;
|
||||
S32 mDesiredSavedRawDiscardLevel;
|
||||
F32 mLastReferencedSavedRawImageTime ;
|
||||
|
||||
//a small version of the copy of the raw image (<= 64 * 64)
|
||||
LLPointer<LLImageRaw> mCachedRawImage;
|
||||
S32 mCachedRawDiscardLevel;
|
||||
BOOL mCachedRawImageReady; //the rez of the mCachedRawImage reaches the upper limit.
|
||||
|
||||
LLHost mTargetHost; // if LLHost::invalid, just request from agent's simulator
|
||||
|
||||
// Timers
|
||||
|
|
@ -477,15 +542,17 @@ protected:
|
|||
/*virtual*/ ~LLViewerLODTexture(){}
|
||||
|
||||
public:
|
||||
LLViewerLODTexture(const LLUUID& id, BOOL usemipmaps = TRUE);
|
||||
LLViewerLODTexture(const std::string& full_path, const LLUUID& id, BOOL usemipmaps = TRUE);
|
||||
LLViewerLODTexture(const LLUUID& id, const LLHost& host = LLHost::invalid, BOOL usemipmaps = TRUE);
|
||||
LLViewerLODTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps = TRUE);
|
||||
|
||||
/*virtual*/ S8 getType() const;
|
||||
// Process image stats to determine priority/quality requirements.
|
||||
/*virtual*/ void processTextureStats();
|
||||
|
||||
BOOL isUpdateFrozen() ;
|
||||
|
||||
private:
|
||||
void init(bool firstinit) ;
|
||||
void scaleDown() ;
|
||||
|
||||
private:
|
||||
|
||||
|
|
@ -608,6 +675,15 @@ public:
|
|||
const LLUUID& force_id = LLUUID::null
|
||||
);
|
||||
|
||||
static LLViewerFetchedTexture* getFetchedTextureFromUrl(const std::string& url,
|
||||
BOOL usemipmap = TRUE,
|
||||
BOOL level_immediate = FALSE, // Get the requested level immediately upon creation.
|
||||
S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
|
||||
LLGLint internal_format = 0,
|
||||
LLGLenum primary_format = 0,
|
||||
const LLUUID& force_id = LLUUID::null
|
||||
);
|
||||
|
||||
static LLViewerFetchedTexture* getFetchedTextureFromHost(const LLUUID& image_id, LLHost host) ;
|
||||
|
||||
static void init() ;
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "llimagetga.h"
|
||||
#include "llimagejpeg.h"
|
||||
#include "llimagepng.h"
|
||||
#include "llimageworker.h"
|
||||
|
||||
#include "llsdserialize.h"
|
||||
#include "llsys.h"
|
||||
|
|
@ -68,10 +69,15 @@
|
|||
|
||||
void (*LLViewerTextureList::sUUIDCallback)(void **, const LLUUID&) = NULL;
|
||||
|
||||
const S32 IMAGES_PER_REQUEST = 42;
|
||||
const S32 IMAGES_MIN_UPDATES = 4; // Always update the highest N images each frame
|
||||
const S32 IMAGES_MAX_PACKET_UPDATES = 1; // Only send N packets of IMAGES_PER_REQUEST in a frame
|
||||
const F32 RESEND_IMAGE_REQUEST_TIME = 15.f; // seconds
|
||||
U32 LLViewerTextureList::sTextureBits = 0;
|
||||
U32 LLViewerTextureList::sTexturePackets = 0;
|
||||
S32 LLViewerTextureList::sNumImages = 0;
|
||||
LLStat LLViewerTextureList::sNumImagesStat(32, TRUE);
|
||||
LLStat LLViewerTextureList::sNumRawImagesStat(32, TRUE);
|
||||
LLStat LLViewerTextureList::sGLTexMemStat(32, TRUE);
|
||||
LLStat LLViewerTextureList::sGLBoundMemStat(32, TRUE);
|
||||
LLStat LLViewerTextureList::sRawMemStat(32, TRUE);
|
||||
LLStat LLViewerTextureList::sFormattedMemStat(32, TRUE);
|
||||
|
||||
LLViewerTextureList gTextureList;
|
||||
static LLFastTimer::DeclareTimer FTM_PROCESS_IMAGES("Process Images");
|
||||
|
|
@ -88,7 +94,7 @@ LLViewerTextureList::LLViewerTextureList()
|
|||
|
||||
void LLViewerTextureList::init()
|
||||
{
|
||||
mNumImages = 0;
|
||||
sNumImages = 0;
|
||||
mMaxResidentTexMemInMegaBytes = 0;
|
||||
mMaxTotalTextureMemInMegaBytes = 0 ;
|
||||
if (gNoRender)
|
||||
|
|
@ -231,6 +237,10 @@ void LLViewerTextureList::shutdown()
|
|||
{
|
||||
continue; // avoid UI, baked, and other special images
|
||||
}
|
||||
if(!image->getBoundRecently())
|
||||
{
|
||||
continue ;
|
||||
}
|
||||
S32 desired = image->getDesiredDiscardLevel();
|
||||
if (desired >= 0 && desired < MAX_DISCARD_LEVEL)
|
||||
{
|
||||
|
|
@ -321,13 +331,6 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string&
|
|||
LLGLenum primary_format,
|
||||
const LLUUID& force_id)
|
||||
{
|
||||
if (gNoRender)
|
||||
{
|
||||
// Never mind that this ignores image_set_id;
|
||||
// getImage() will handle that later.
|
||||
return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, TRUE);
|
||||
}
|
||||
|
||||
std::string full_path = gDirUtilp->findSkinnedFilename("textures", filename);
|
||||
if (full_path.empty())
|
||||
{
|
||||
|
|
@ -335,6 +338,26 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string&
|
|||
return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, TRUE);
|
||||
}
|
||||
|
||||
std::string url = "file://" + full_path;
|
||||
|
||||
return getImageFromUrl(url, usemipmaps, level_immediate, texture_type, internal_format, primary_format, force_id);
|
||||
}
|
||||
|
||||
LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string& url,
|
||||
BOOL usemipmaps,
|
||||
BOOL level_immediate,
|
||||
S8 texture_type,
|
||||
LLGLint internal_format,
|
||||
LLGLenum primary_format,
|
||||
const LLUUID& force_id)
|
||||
{
|
||||
if (gNoRender)
|
||||
{
|
||||
// Never mind that this ignores image_set_id;
|
||||
// getImage() will handle that later.
|
||||
return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, TRUE);
|
||||
}
|
||||
|
||||
// generate UUID based on hash of filename
|
||||
LLUUID new_id;
|
||||
if (force_id.notNull())
|
||||
|
|
@ -343,7 +366,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string&
|
|||
}
|
||||
else
|
||||
{
|
||||
new_id.generate(full_path);
|
||||
new_id.generate(url);
|
||||
}
|
||||
|
||||
LLPointer<LLViewerFetchedTexture> imagep = findImage(new_id);
|
||||
|
|
@ -353,10 +376,10 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string&
|
|||
switch(texture_type)
|
||||
{
|
||||
case LLViewerTexture::FETCHED_TEXTURE:
|
||||
imagep = new LLViewerFetchedTexture(full_path, new_id, usemipmaps);
|
||||
imagep = new LLViewerFetchedTexture(url, new_id, usemipmaps);
|
||||
break ;
|
||||
case LLViewerTexture::LOD_TEXTURE:
|
||||
imagep = new LLViewerLODTexture(full_path, new_id, usemipmaps);
|
||||
imagep = new LLViewerLODTexture(url, new_id, usemipmaps);
|
||||
break ;
|
||||
default:
|
||||
llerrs << "Invalid texture type " << texture_type << llendl ;
|
||||
|
|
@ -372,7 +395,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string&
|
|||
if (level_immediate)
|
||||
{
|
||||
imagep->dontDiscard();
|
||||
imagep->setBoostLevel(LLViewerFetchedTexture::BOOST_UI);
|
||||
imagep->setBoostLevel(LLViewerTexture::BOOST_UI);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -424,18 +447,15 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
|
|||
switch(texture_type)
|
||||
{
|
||||
case LLViewerTexture::FETCHED_TEXTURE:
|
||||
imagep = new LLViewerFetchedTexture(image_id, usemipmaps);
|
||||
imagep = new LLViewerFetchedTexture(image_id, request_from_host, usemipmaps);
|
||||
break ;
|
||||
case LLViewerTexture::LOD_TEXTURE:
|
||||
imagep = new LLViewerLODTexture(image_id, usemipmaps);
|
||||
imagep = new LLViewerLODTexture(image_id, request_from_host, usemipmaps);
|
||||
break ;
|
||||
default:
|
||||
llerrs << "Invalid texture type " << texture_type << llendl ;
|
||||
}
|
||||
|
||||
// Might want to request from host other than where the agent is. JC
|
||||
imagep->setTargetHost(request_from_host);
|
||||
|
||||
if (internal_format && primary_format)
|
||||
{
|
||||
imagep->setExplicitFormat(internal_format, primary_format);
|
||||
|
|
@ -446,7 +466,7 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
|
|||
if (level_immediate)
|
||||
{
|
||||
imagep->dontDiscard();
|
||||
imagep->setBoostLevel(LLViewerFetchedTexture::BOOST_UI);
|
||||
imagep->setBoostLevel(LLViewerTexture::BOOST_UI);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -509,7 +529,7 @@ void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image)
|
|||
{
|
||||
llwarns << "Image with ID " << image_id << " already in list" << llendl;
|
||||
}
|
||||
mNumImages++;
|
||||
sNumImages++;
|
||||
|
||||
addImageToList(new_image);
|
||||
mUUIDMap[image_id] = new_image;
|
||||
|
|
@ -526,7 +546,7 @@ void LLViewerTextureList::deleteImage(LLViewerFetchedTexture *image)
|
|||
}
|
||||
|
||||
llverify(mUUIDMap.erase(image->getID()) == 1);
|
||||
mNumImages--;
|
||||
sNumImages--;
|
||||
removeImageFromList(image);
|
||||
}
|
||||
}
|
||||
|
|
@ -546,7 +566,9 @@ static LLFastTimer::DeclareTimer FTM_IMAGE_MARK_DIRTY("Dirty Images");
|
|||
|
||||
void LLViewerTextureList::updateImages(F32 max_time)
|
||||
{
|
||||
LLViewerStats::getInstance()->mNumImagesStat.addValue(mNumImages);
|
||||
LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerStats::getInstance()->mTextureKBitStat.getMeanPerSec());
|
||||
|
||||
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));
|
||||
|
|
@ -554,10 +576,13 @@ void LLViewerTextureList::updateImages(F32 max_time)
|
|||
LLViewerStats::getInstance()->mFormattedMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageFormatted::sGlobalFormattedMemory));
|
||||
|
||||
updateImagesDecodePriorities();
|
||||
|
||||
F32 total_max_time = max_time;
|
||||
max_time -= updateImagesFetchTextures(max_time);
|
||||
max_time = llmin(llmax(max_time, 0.001f*10.f*gFrameIntervalSeconds), 0.001f);
|
||||
|
||||
max_time = llmax(max_time, total_max_time*.25f); // at least 25% of max_time
|
||||
max_time -= updateImagesCreateTextures(max_time);
|
||||
max_time = llmin(llmax(max_time, 0.001f*10.f*gFrameIntervalSeconds), 0.001f);
|
||||
|
||||
if (!mDirtyTextureList.empty())
|
||||
{
|
||||
LLFastTimer t(FTM_IMAGE_MARK_DIRTY);
|
||||
|
|
@ -570,7 +595,7 @@ void LLViewerTextureList::updateImages(F32 max_time)
|
|||
{
|
||||
//trigger loaded callbacks on local textures immediately
|
||||
LLViewerFetchedTexture* image = *iter++;
|
||||
if (!image->getLocalFileName().empty())
|
||||
if (!image->getUrl().empty())
|
||||
{
|
||||
// Do stuff to handle callbacks, update priorities, etc.
|
||||
didone = image->doLoadedCallbacks();
|
||||
|
|
@ -628,6 +653,14 @@ void LLViewerTextureList::updateImagesDecodePriorities()
|
|||
}
|
||||
else
|
||||
{
|
||||
if(imagep->hasSavedRawImage())
|
||||
{
|
||||
if(imagep->getElapsedLastReferencedSavedRawImageTime() > MAX_INACTIVE_TIME)
|
||||
{
|
||||
imagep->destroySavedRawImage() ;
|
||||
}
|
||||
}
|
||||
|
||||
if(imagep->isDeleted())
|
||||
{
|
||||
continue ;
|
||||
|
|
@ -758,74 +791,76 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
|
|||
const size_t max_update_count = llmin((S32) (1024*10.f*gFrameIntervalSeconds)+1, 256);
|
||||
|
||||
// 32 high priority entries
|
||||
std::set<LLViewerFetchedTexture*> entries;
|
||||
typedef std::vector<LLViewerFetchedTexture*> entries_list_t;
|
||||
entries_list_t entries;
|
||||
size_t update_counter = llmin(max_priority_count, mImageList.size());
|
||||
image_priority_list_t::iterator iter1 = mImageList.begin();
|
||||
while(update_counter > 0)
|
||||
{
|
||||
// added extra granularity and verbosity for crash logging during 1.19.1 RC. -Brad
|
||||
if(iter1 == mImageList.end())
|
||||
{
|
||||
llerrs << "DEV-12002: update_counter not calculated correctly!" << llendl;
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
LLPointer<LLViewerFetchedTexture> const & ptr = *iter1;
|
||||
|
||||
LLViewerFetchedTexture * img = ptr.get();
|
||||
|
||||
// added extra granularity and verbosity for crash logging during 1.19.1 RC. -Brad
|
||||
if(img == NULL)
|
||||
{
|
||||
llwarns << "DEV-12002: image is NULL!" << llendl;
|
||||
}
|
||||
|
||||
entries.insert(img);
|
||||
|
||||
entries.push_back(*iter1);
|
||||
|
||||
++iter1;
|
||||
update_counter--;
|
||||
}
|
||||
|
||||
// 256 cycled entries
|
||||
update_counter = llmin(max_update_count, mUUIDMap.size());
|
||||
uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchUUID);
|
||||
while(update_counter > 0)
|
||||
update_counter = llmin(max_update_count, mUUIDMap.size());
|
||||
if(update_counter > 0)
|
||||
{
|
||||
if (iter2 == mUUIDMap.end())
|
||||
uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchUUID);
|
||||
uuid_map_t::iterator iter2p = iter2;
|
||||
while(update_counter > 0)
|
||||
{
|
||||
iter2 = mUUIDMap.begin();
|
||||
if (iter2 == mUUIDMap.end())
|
||||
{
|
||||
iter2 = mUUIDMap.begin();
|
||||
}
|
||||
entries.push_back(iter2->second);
|
||||
iter2p = iter2++;
|
||||
update_counter--;
|
||||
}
|
||||
mLastFetchUUID = iter2->first;
|
||||
entries.insert(iter2->second);
|
||||
++iter2;
|
||||
update_counter--;
|
||||
|
||||
mLastFetchUUID = iter2p->first;
|
||||
}
|
||||
|
||||
S32 fetch_count = 0;
|
||||
S32 min_count = max_priority_count + max_update_count/4;
|
||||
for (std::set<LLViewerFetchedTexture*>::iterator iter3 = entries.begin();
|
||||
for (entries_list_t::iterator iter3 = entries.begin();
|
||||
iter3 != entries.end(); )
|
||||
{
|
||||
LLPointer<LLViewerFetchedTexture> imagep = *iter3++;
|
||||
|
||||
imagep->updateFetch();
|
||||
bool fetching = imagep->updateFetch();
|
||||
if (fetching)
|
||||
{
|
||||
fetch_count++;
|
||||
}
|
||||
if (min_count <= 0 && image_op_timer.getElapsedTimeF32() > max_time)
|
||||
{
|
||||
break;
|
||||
}
|
||||
min_count--;
|
||||
}
|
||||
if (fetch_count == 0)
|
||||
{
|
||||
gDebugTimers[0].pause();
|
||||
}
|
||||
else
|
||||
{
|
||||
gDebugTimers[0].unpause();
|
||||
}
|
||||
return image_op_timer.getElapsedTimeF32();
|
||||
}
|
||||
|
||||
void LLViewerTextureList::updateImagesUpdateStats()
|
||||
{
|
||||
if (mUpdateStats)
|
||||
if (mUpdateStats && mForceResetTextureStats)
|
||||
{
|
||||
for (image_priority_list_t::iterator iter = mImageList.begin();
|
||||
iter != mImageList.end(); )
|
||||
{
|
||||
LLViewerFetchedTexture* imagep = *iter++;
|
||||
imagep->resetTextureStats(mForceResetTextureStats);
|
||||
imagep->resetTextureStats();
|
||||
}
|
||||
mUpdateStats = FALSE;
|
||||
mForceResetTextureStats = FALSE;
|
||||
|
|
@ -1011,6 +1046,9 @@ LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImage
|
|||
return compressedImage;
|
||||
}
|
||||
|
||||
const S32 MIN_VIDEO_RAM = 32;
|
||||
const S32 MAX_VIDEO_RAM = 512; // 512MB max for performance reasons.
|
||||
|
||||
// Returns min setting for TextureMemory (in MB)
|
||||
S32 LLViewerTextureList::getMinVideoRamSetting()
|
||||
{
|
||||
|
|
@ -1129,13 +1167,13 @@ void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_d
|
|||
|
||||
if (msg->getReceiveCompressedSize())
|
||||
{
|
||||
gTextureList.mTextureBits += msg->getReceiveCompressedSize() * 8;
|
||||
gTextureList.sTextureBits += msg->getReceiveCompressedSize() * 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
gTextureList.mTextureBits += msg->getReceiveSize() * 8;
|
||||
gTextureList.sTextureBits += msg->getReceiveSize() * 8;
|
||||
}
|
||||
gTextureList.mTexturePackets++;
|
||||
gTextureList.sTexturePackets++;
|
||||
|
||||
U8 codec;
|
||||
U16 packets;
|
||||
|
|
@ -1194,13 +1232,13 @@ void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_d
|
|||
|
||||
if (msg->getReceiveCompressedSize())
|
||||
{
|
||||
gTextureList.mTextureBits += msg->getReceiveCompressedSize() * 8;
|
||||
gTextureList.sTextureBits += msg->getReceiveCompressedSize() * 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
gTextureList.mTextureBits += msg->getReceiveSize() * 8;
|
||||
gTextureList.sTextureBits += msg->getReceiveSize() * 8;
|
||||
}
|
||||
gTextureList.mTexturePackets++;
|
||||
gTextureList.sTexturePackets++;
|
||||
|
||||
//llprintline("Start decode, image header...");
|
||||
msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id);
|
||||
|
|
@ -1385,7 +1423,7 @@ void LLUIImageList::onUIImageLoaded( BOOL success, LLViewerFetchedTexture *src_v
|
|||
|
||||
// for images grabbed from local files, apply clipping rectangle to restore original dimensions
|
||||
// from power-of-2 gl image
|
||||
if (success && imagep.notNull() && src_vi && !src_vi->getLocalFileName().empty())
|
||||
if (success && imagep.notNull() && src_vi && (src_vi->getUrl().compare(0, 7, "file://")==0))
|
||||
{
|
||||
F32 clip_x = (F32)src_vi->getOriginalWidth() / (F32)src_vi->getFullWidth();
|
||||
F32 clip_y = (F32)src_vi->getOriginalHeight() / (F32)src_vi->getFullHeight();
|
||||
|
|
@ -1442,6 +1480,11 @@ bool LLUIImageList::initFromFile()
|
|||
llwarns << "Unable to parse UI image list file " << base_file_path << llendl;
|
||||
return false;
|
||||
}
|
||||
if (!root->hasAttribute("version"))
|
||||
{
|
||||
llwarns << "No valid version number in UI image list file " << base_file_path << llendl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::string> paths;
|
||||
// path to current selected skin
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ const BOOL GL_TEXTURE_NO = FALSE;
|
|||
const BOOL IMMEDIATE_YES = TRUE;
|
||||
const BOOL IMMEDIATE_NO = FALSE;
|
||||
|
||||
class LLImageJ2C;
|
||||
class LLMessageSystem;
|
||||
class LLTextureView;
|
||||
|
||||
|
|
@ -146,6 +145,15 @@ private:
|
|||
LLGLenum primary_format = 0,
|
||||
const LLUUID& force_id = LLUUID::null
|
||||
);
|
||||
|
||||
LLViewerFetchedTexture* getImageFromUrl(const std::string& url,
|
||||
BOOL usemipmap = TRUE,
|
||||
BOOL level_immediate = FALSE, // Get the requested level immediately upon creation.
|
||||
S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
|
||||
LLGLint internal_format = 0,
|
||||
LLGLenum primary_format = 0,
|
||||
const LLUUID& force_id = LLUUID::null
|
||||
);
|
||||
|
||||
LLViewerFetchedTexture* createImage(const LLUUID &image_id,
|
||||
BOOL usemipmap = TRUE,
|
||||
|
|
@ -190,11 +198,18 @@ private:
|
|||
LLFrameTimer mForceDecodeTimer;
|
||||
|
||||
public:
|
||||
U32 mTextureBits;
|
||||
U32 mTexturePackets;
|
||||
static U32 sTextureBits;
|
||||
static U32 sTexturePackets;
|
||||
|
||||
static LLStat sNumImagesStat;
|
||||
static LLStat sNumRawImagesStat;
|
||||
static LLStat sGLTexMemStat;
|
||||
static LLStat sGLBoundMemStat;
|
||||
static LLStat sRawMemStat;
|
||||
static LLStat sFormattedMemStat;
|
||||
|
||||
private:
|
||||
S32 mNumImages;
|
||||
static S32 sNumImages;
|
||||
static void (*sUUIDCallback)(void**, const LLUUID &);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@
|
|||
#include "llhudview.h"
|
||||
#include "llimagebmp.h"
|
||||
#include "llimagej2c.h"
|
||||
#include "llimageworker.h"
|
||||
#include "llkeyboard.h"
|
||||
#include "lllineeditor.h"
|
||||
#include "llmenugl.h"
|
||||
|
|
@ -157,7 +158,6 @@
|
|||
#include "lltoolselectland.h"
|
||||
#include "lltrans.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "lluploaddialog.h"
|
||||
#include "llurldispatcher.h" // SLURL from other app instance
|
||||
#include "llvieweraudio.h"
|
||||
#include "llviewercamera.h"
|
||||
|
|
@ -189,6 +189,7 @@
|
|||
#include "llbottomtray.h"
|
||||
#include "llnearbychatbar.h"
|
||||
#include "llagentui.h"
|
||||
#include "llwearablelist.h"
|
||||
|
||||
#include "llnotificationmanager.h"
|
||||
|
||||
|
|
@ -326,7 +327,9 @@ public:
|
|||
S32 hours = (S32)(time / (60*60));
|
||||
S32 mins = (S32)((time - hours*(60*60)) / 60);
|
||||
S32 secs = (S32)((time - hours*(60*60) - mins*60));
|
||||
addText(xpos, ypos, llformat(" Debug %d: %d:%02d:%02d", idx, hours,mins,secs)); ypos += y_inc2;
|
||||
std::string label = gDebugTimerLabel[idx];
|
||||
if (label.empty()) label = llformat("Debug: %d", idx);
|
||||
addText(xpos, ypos, llformat(" %s: %d:%02d:%02d", label.c_str(), hours,mins,secs)); ypos += y_inc2;
|
||||
}
|
||||
|
||||
F32 time = gFrameTimeSeconds;
|
||||
|
|
@ -1299,6 +1302,7 @@ LLViewerWindow::LLViewerWindow(
|
|||
|
||||
// Init the image list. Must happen after GL is initialized and before the images that
|
||||
// LLViewerWindow needs are requested.
|
||||
LLImageGL::initClass(LLViewerTexture::MAX_GL_IMAGE_CATEGORY) ;
|
||||
gTextureList.init();
|
||||
LLViewerTextureManager::init() ;
|
||||
gBumpImageList.init();
|
||||
|
|
@ -1657,6 +1661,8 @@ void LLViewerWindow::shutdownGL()
|
|||
gSky.cleanup();
|
||||
stop_glerror();
|
||||
|
||||
LLWearableList::instance().cleanup() ;
|
||||
|
||||
gTextureList.shutdown();
|
||||
stop_glerror();
|
||||
|
||||
|
|
@ -1670,7 +1676,10 @@ void LLViewerWindow::shutdownGL()
|
|||
stop_glerror();
|
||||
|
||||
LLViewerTextureManager::cleanup() ;
|
||||
|
||||
LLImageGL::cleanupClass() ;
|
||||
|
||||
llinfos << "All texturs and llimagegl images are destroyed!" << llendl ;
|
||||
|
||||
llinfos << "Cleaning up select manager" << llendl;
|
||||
LLSelectMgr::getInstance()->cleanup();
|
||||
|
||||
|
|
|
|||
|
|
@ -321,7 +321,7 @@ public:
|
|||
} ESnapshotType;
|
||||
BOOL saveSnapshot(const std::string& filename, S32 image_width, S32 image_height, BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR);
|
||||
BOOL rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, BOOL keep_window_aspect = TRUE, BOOL is_texture = FALSE,
|
||||
BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_IMAGE_SIZE );
|
||||
BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE );
|
||||
BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type) ;
|
||||
BOOL isSnapshotLocSet() const { return ! sSnapshotDir.empty(); }
|
||||
void resetSnapshotLoc() const { sSnapshotDir.clear(); }
|
||||
|
|
|
|||
|
|
@ -279,7 +279,6 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
|
|||
if (mRawImages[i].isNull())
|
||||
{
|
||||
// Read back a raw image for this discard level, if it exists
|
||||
mRawImages[i] = new LLImageRaw;
|
||||
S32 min_dim = llmin(mDetailTextures[i]->getFullWidth(), mDetailTextures[i]->getFullHeight());
|
||||
S32 ddiscard = 0;
|
||||
while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL)
|
||||
|
|
@ -287,12 +286,18 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
|
|||
ddiscard++;
|
||||
min_dim /= 2;
|
||||
}
|
||||
if (!mDetailTextures[i]->readBackRaw(ddiscard, mRawImages[i], false))
|
||||
|
||||
mDetailTextures[i]->reloadRawImage(ddiscard) ;
|
||||
if(mDetailTextures[i]->getRawImageLevel() != ddiscard)//raw iamge is not ready, will enter here again later.
|
||||
{
|
||||
llwarns << "Unable to read raw data for terrain detail texture: " << mDetailTextures[i]->getID() << llendl;
|
||||
mRawImages[i] = NULL;
|
||||
mDetailTextures[i]->destroyRawImage() ;
|
||||
lldebugs << "cached raw data for terrain detail texture is not ready yet: " << mDetailTextures[i]->getID() << llendl;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
mRawImages[i] = mDetailTextures[i]->getRawImage() ;
|
||||
mDetailTextures[i]->destroyRawImage() ;
|
||||
|
||||
if (mDetailTextures[i]->getWidth(ddiscard) != BASE_SIZE ||
|
||||
mDetailTextures[i]->getHeight(ddiscard) != BASE_SIZE ||
|
||||
mDetailTextures[i]->getComponents() != 3)
|
||||
|
|
|
|||
|
|
@ -988,7 +988,7 @@ void LLVOAvatar::resetImpostors()
|
|||
|
||||
// static
|
||||
void LLVOAvatar::deleteCachedImages(bool clearAll)
|
||||
{
|
||||
{
|
||||
if (LLTexLayerSet::sHasCaches)
|
||||
{
|
||||
lldebugs << "Deleting layer set caches" << llendl;
|
||||
|
|
@ -3897,7 +3897,7 @@ U32 LLVOAvatar::renderFootShadows()
|
|||
LLGLDepthTest test(GL_TRUE, GL_FALSE);
|
||||
//render foot shadows
|
||||
LLGLEnable blend(GL_BLEND);
|
||||
gGL.getTexUnit(0)->bind(mShadowImagep.get());
|
||||
gGL.getTexUnit(0)->bind(mShadowImagep, TRUE);
|
||||
glColor4fv(mShadow0Facep->getRenderColor().mV);
|
||||
mShadow0Facep->renderIndexed(foot_mask);
|
||||
glColor4fv(mShadow1Facep->getRenderColor().mV);
|
||||
|
|
@ -3945,7 +3945,7 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel)
|
|||
//------------------------------------------------------------------------
|
||||
// LLVOAvatar::updateTextures()
|
||||
//------------------------------------------------------------------------
|
||||
void LLVOAvatar::updateTextures(LLAgent &agent)
|
||||
void LLVOAvatar::updateTextures()
|
||||
{
|
||||
BOOL render_avatar = TRUE;
|
||||
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ public:
|
|||
virtual BOOL updateLOD();
|
||||
BOOL updateJointLODs();
|
||||
virtual BOOL isActive() const; // Whether this object needs to do an idleUpdate.
|
||||
virtual void updateTextures(LLAgent &agent);
|
||||
virtual void updateTextures();
|
||||
virtual S32 setTETexture(const U8 te, const LLUUID& uuid); // If setting a baked texture, need to request it from a non-local sim.
|
||||
virtual void onShift(const LLVector3& shift_vector);
|
||||
virtual U32 getPartitionType() const;
|
||||
|
|
|
|||
|
|
@ -1141,26 +1141,6 @@ void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *sr
|
|||
}
|
||||
}
|
||||
|
||||
// virtual
|
||||
/* //unused
|
||||
BOOL LLVOAvatarSelf::getLocalTextureRaw(ETextureIndex index, LLImageRaw* image_raw) const
|
||||
{
|
||||
if (!isIndexLocalTexture(index)) return FALSE;
|
||||
if (getLocalTextureID(index) == IMG_DEFAULT_AVATAR) return TRUE;
|
||||
|
||||
const LocalTextureData *local_tex_data = getLocalTextureData(index)[0];
|
||||
if (local_tex_data->mImage->readBackRaw(-1, image_raw, false))
|
||||
{
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// No data loaded yet
|
||||
setLocalTexture((ETextureIndex)index, getTEImage(index), FALSE); // <-- non-const, move this elsewhere
|
||||
return FALSE;
|
||||
}
|
||||
*/
|
||||
|
||||
// virtual
|
||||
BOOL LLVOAvatarSelf::getLocalTextureGL(ETextureIndex type, LLViewerTexture** tex_pp, U32 index) const
|
||||
{
|
||||
|
|
@ -1812,12 +1792,13 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe
|
|||
|
||||
if (!covered_by_baked)
|
||||
{
|
||||
if (getLocalTextureID(type, index) != IMG_DEFAULT_AVATAR)
|
||||
if (getLocalTextureID(type, index) != IMG_DEFAULT_AVATAR && imagep->getDiscardLevel() != 0)
|
||||
{
|
||||
F32 desired_pixels;
|
||||
desired_pixels = llmin(mPixelArea, (F32)getTexImageArea());
|
||||
imagep->setBoostLevel(getAvatarBoostLevel());
|
||||
imagep->addTextureStats( desired_pixels / texel_area_ratio );
|
||||
imagep->forceUpdateBindStats() ;
|
||||
if (imagep->getDiscardLevel() < 0)
|
||||
{
|
||||
mHasGrey = TRUE; // for statistics gathering
|
||||
|
|
@ -2115,6 +2096,49 @@ BOOL LLVOAvatarSelf::needsRenderBeam()
|
|||
// static
|
||||
void LLVOAvatarSelf::deleteScratchTextures()
|
||||
{
|
||||
if(gAuditTexture)
|
||||
{
|
||||
S32 total_tex_size = sScratchTexBytes ;
|
||||
S32 tex_size = SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT ;
|
||||
|
||||
if( sScratchTexNames.checkData( GL_LUMINANCE ) )
|
||||
{
|
||||
LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
|
||||
total_tex_size -= tex_size ;
|
||||
}
|
||||
if( sScratchTexNames.checkData( GL_ALPHA ) )
|
||||
{
|
||||
LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
|
||||
total_tex_size -= tex_size ;
|
||||
}
|
||||
if( sScratchTexNames.checkData( GL_COLOR_INDEX ) )
|
||||
{
|
||||
LLImageGL::decTextureCounter(tex_size, 1, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
|
||||
total_tex_size -= tex_size ;
|
||||
}
|
||||
if( sScratchTexNames.checkData( GL_LUMINANCE_ALPHA ) )
|
||||
{
|
||||
LLImageGL::decTextureCounter(tex_size, 2, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
|
||||
total_tex_size -= 2 * tex_size ;
|
||||
}
|
||||
if( sScratchTexNames.checkData( GL_RGB ) )
|
||||
{
|
||||
LLImageGL::decTextureCounter(tex_size, 3, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
|
||||
total_tex_size -= 3 * tex_size ;
|
||||
}
|
||||
if( sScratchTexNames.checkData( GL_RGBA ) )
|
||||
{
|
||||
LLImageGL::decTextureCounter(tex_size, 4, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
|
||||
total_tex_size -= 4 * tex_size ;
|
||||
}
|
||||
//others
|
||||
while(total_tex_size > 0)
|
||||
{
|
||||
LLImageGL::decTextureCounter(tex_size, 4, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
|
||||
total_tex_size -= 4 * tex_size ;
|
||||
}
|
||||
}
|
||||
|
||||
for( LLGLuint* namep = sScratchTexNames.getFirstData();
|
||||
namep;
|
||||
namep = sScratchTexNames.getNextData() )
|
||||
|
|
@ -2137,7 +2161,8 @@ void LLVOAvatarSelf::deleteScratchTextures()
|
|||
BOOL LLVOAvatarSelf::bindScratchTexture( LLGLenum format )
|
||||
{
|
||||
U32 texture_bytes = 0;
|
||||
GLuint gl_name = getScratchTexName( format, &texture_bytes );
|
||||
S32 components = 0;
|
||||
GLuint gl_name = getScratchTexName( format, components, &texture_bytes );
|
||||
if( gl_name )
|
||||
{
|
||||
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, gl_name);
|
||||
|
|
@ -2149,12 +2174,12 @@ BOOL LLVOAvatarSelf::bindScratchTexture( LLGLenum format )
|
|||
if( *last_bind_time != LLImageGL::sLastFrameTime )
|
||||
{
|
||||
*last_bind_time = LLImageGL::sLastFrameTime;
|
||||
LLImageGL::updateBoundTexMem(texture_bytes);
|
||||
LLImageGL::updateBoundTexMem(texture_bytes, components, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLImageGL::updateBoundTexMem(texture_bytes);
|
||||
LLImageGL::updateBoundTexMem(texture_bytes, components, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
|
||||
sScratchTexLastBindTime.addData( format, new F32(LLImageGL::sLastFrameTime) );
|
||||
}
|
||||
return TRUE;
|
||||
|
|
@ -2162,9 +2187,8 @@ BOOL LLVOAvatarSelf::bindScratchTexture( LLGLenum format )
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
LLGLuint LLVOAvatarSelf::getScratchTexName( LLGLenum format, U32* texture_bytes )
|
||||
{
|
||||
S32 components;
|
||||
LLGLuint LLVOAvatarSelf::getScratchTexName( LLGLenum format, S32& components, U32* texture_bytes )
|
||||
{
|
||||
GLenum internal_format;
|
||||
switch( format )
|
||||
{
|
||||
|
|
@ -2210,6 +2234,11 @@ LLGLuint LLVOAvatarSelf::getScratchTexName( LLGLenum format, U32* texture_bytes
|
|||
|
||||
sScratchTexBytes += *texture_bytes;
|
||||
LLImageGL::sGlobalTextureMemoryInBytes += *texture_bytes;
|
||||
|
||||
if(gAuditTexture)
|
||||
{
|
||||
LLImageGL::incTextureCounter(SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT, components, LLViewerTexture::AVATAR_SCRATCH_TEX) ;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ public:
|
|||
BOOL bindScratchTexture(LLGLenum format);
|
||||
static void deleteScratchTextures();
|
||||
protected:
|
||||
LLGLuint getScratchTexName(LLGLenum format, U32* texture_bytes);
|
||||
LLGLuint getScratchTexName(LLGLenum format, S32& components, U32* texture_bytes);
|
||||
private:
|
||||
static S32 sScratchTexBytes;
|
||||
static LLMap< LLGLenum, LLGLuint*> sScratchTexNames;
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ void LLVOClouds::setPixelAreaAndAngle(LLAgent &agent)
|
|||
mPixelArea = 1500*100;
|
||||
}
|
||||
|
||||
void LLVOClouds::updateTextures(LLAgent &agent)
|
||||
void LLVOClouds::updateTextures()
|
||||
{
|
||||
getTEImage(0)->addTextureStats(mPixelArea);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ public:
|
|||
/*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate.
|
||||
F32 getPartSize(S32 idx);
|
||||
|
||||
/*virtual*/ void updateTextures(LLAgent &agent);
|
||||
/*virtual*/ void updateTextures();
|
||||
/*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area
|
||||
|
||||
void updateFaceSize(S32 idx) { }
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue