diff options
Diffstat (limited to 'indra')
105 files changed, 2041 insertions, 4484 deletions
| diff --git a/indra/llappearance/lltexlayerparams.cpp b/indra/llappearance/lltexlayerparams.cpp index ce5c7142d5..06b4f6c75a 100644 --- a/indra/llappearance/lltexlayerparams.cpp +++ b/indra/llappearance/lltexlayerparams.cpp @@ -151,7 +151,7 @@ LLTexLayerParamAlpha::LLTexLayerParamAlpha(const LLTexLayerParamAlpha& pOther)  	mCachedProcessedTexture(pOther.mCachedProcessedTexture),  	mStaticImageTGA(pOther.mStaticImageTGA),  	mStaticImageRaw(pOther.mStaticImageRaw), -	mNeedsCreateTexture(pOther.mNeedsCreateTexture), +	mNeedsCreateTexture(pOther.mNeedsCreateTexture.load()),  	mStaticImageInvalid(pOther.mStaticImageInvalid),  	mAvgDistortionVec(pOther.mAvgDistortionVec),  	mCachedEffectiveWeight(pOther.mCachedEffectiveWeight) diff --git a/indra/llappearance/lltexlayerparams.h b/indra/llappearance/lltexlayerparams.h index e2440998b3..000f55685e 100644 --- a/indra/llappearance/lltexlayerparams.h +++ b/indra/llappearance/lltexlayerparams.h @@ -100,7 +100,7 @@ private:  	LLPointer<LLGLTexture>	mCachedProcessedTexture;  	LLPointer<LLImageTGA>	mStaticImageTGA;  	LLPointer<LLImageRaw>	mStaticImageRaw; -	BOOL					mNeedsCreateTexture; +	std::atomic<BOOL>		mNeedsCreateTexture;  	BOOL					mStaticImageInvalid;  	LL_ALIGN_16(LLVector4a				mAvgDistortionVec);  	F32						mCachedEffectiveWeight; diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 59aa731af2..62307c6e26 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -29,6 +29,7 @@ include_directories(  #     ${LLCOMMON_LIBRARIES})  set(llcommon_SOURCE_FILES +    commoncontrol.cpp      indra_constants.cpp      llallocator.cpp      llallocator_heap_profile.cpp @@ -130,6 +131,7 @@ set(llcommon_HEADER_FILES      chrono.h      classic_callback.h +    commoncontrol.h      ctype_workaround.h      fix_macros.h      indra_constants.h diff --git a/indra/llcommon/commoncontrol.cpp b/indra/llcommon/commoncontrol.cpp new file mode 100644 index 0000000000..81e66baf8c --- /dev/null +++ b/indra/llcommon/commoncontrol.cpp @@ -0,0 +1,106 @@ +/** + * @file   commoncontrol.cpp + * @author Nat Goodspeed + * @date   2022-06-08 + * @brief  Implementation for commoncontrol. + *  + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Copyright (c) 2022, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "commoncontrol.h" +// STL headers +// std headers +// external library headers +// other Linden headers +#include "llevents.h" +#include "llsdutil.h" + +LLSD LL::CommonControl::access(const LLSD& params) +{ +    // We can't actually introduce a link-time dependency on llxml, or on any +    // global LLControlGroup (*koff* gSavedSettings *koff*) but we can issue a +    // runtime query. If we're running as part of a viewer with +    // LLViewerControlListener, we can use that to interact with any +    // instantiated LLControGroup. +    LLSD response; +    { +        LLEventStream reply("reply"); +        LLTempBoundListener connection = reply.listen("listener", +                     [&response] (const LLSD& event) +                     { +                         response = event; +                         return false; +                     }); +        LLSD rparams{ params }; +        rparams["reply"] = reply.getName(); +        LLEventPumps::instance().obtain("LLViewerControl").post(rparams); +    } +    // LLViewerControlListener responds immediately. If it's listening at all, +    // it will already have set response. +    if (! response.isDefined()) +    { +        LLTHROW(NoListener("No LLViewerControl listener instantiated")); +    } +    LLSD error{ response["error"] }; +    if (error.isDefined()) +    { +        LLTHROW(ParamError(error)); +    } +    response.erase("error"); +    response.erase("reqid"); +    return response; +} + +/// set control group.key to defined default value +LLSD LL::CommonControl::set_default(const std::string& group, const std::string& key) +{ +    return access(llsd::map("op", "set", +                            "group", group, "key", key))["value"]; +} + +/// set control group.key to specified value +LLSD LL::CommonControl::set(const std::string& group, const std::string& key, const LLSD& value) +{ +    return access(llsd::map("op", "set", +                            "group", group, "key", key, "value", value))["value"]; +} + +/// toggle boolean control group.key +LLSD LL::CommonControl::toggle(const std::string& group, const std::string& key) +{ +    return access(llsd::map("op", "toggle", +                            "group", group, "key", key))["value"]; +} + +/// get the definition for control group.key, (! isDefined()) if bad +/// ["name"], ["type"], ["value"], ["comment"] +LLSD LL::CommonControl::get_def(const std::string& group, const std::string& key) +{ +    return access(llsd::map("op", "get", +                            "group", group, "key", key)); +} + +/// get the value of control group.key +LLSD LL::CommonControl::get(const std::string& group, const std::string& key) +{ +    return access(llsd::map("op", "get", +                            "group", group, "key", key))["value"]; +} + +/// get defined groups +std::vector<std::string> LL::CommonControl::get_groups() +{ +    auto groups{ access(llsd::map("op", "groups"))["groups"] }; +    return { groups.beginArray(), groups.endArray() }; +} + +/// get definitions for all variables in group +LLSD LL::CommonControl::get_vars(const std::string& group) +{ +    return access(llsd::map("op", "vars", "group", group))["vars"]; +} diff --git a/indra/llcommon/commoncontrol.h b/indra/llcommon/commoncontrol.h new file mode 100644 index 0000000000..07d4a45ac5 --- /dev/null +++ b/indra/llcommon/commoncontrol.h @@ -0,0 +1,75 @@ +/** + * @file   commoncontrol.h + * @author Nat Goodspeed + * @date   2022-06-08 + * @brief  Access LLViewerControl LLEventAPI, if process has one. + *  + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Copyright (c) 2022, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_COMMONCONTROL_H) +#define LL_COMMONCONTROL_H + +#include <vector> +#include "llexception.h" +#include "llsd.h" + +namespace LL +{ +    class CommonControl +    { +    public: +        struct Error: public LLException +        { +            Error(const std::string& what): LLException(what) {} +        }; + +        /// Exception thrown if there's no LLViewerControl LLEventAPI +        struct NoListener: public Error +        { +            NoListener(const std::string& what): Error(what) {} +        }; + +        struct ParamError: public Error +        { +            ParamError(const std::string& what): Error(what) {} +        }; + +        /// set control group.key to defined default value +        static +        LLSD set_default(const std::string& group, const std::string& key); + +        /// set control group.key to specified value +        static +        LLSD set(const std::string& group, const std::string& key, const LLSD& value); + +        /// toggle boolean control group.key +        static +        LLSD toggle(const std::string& group, const std::string& key); + +        /// get the definition for control group.key, (! isDefined()) if bad +        /// ["name"], ["type"], ["value"], ["comment"] +        static +        LLSD get_def(const std::string& group, const std::string& key); + +        /// get the value of control group.key +        static +        LLSD get(const std::string& group, const std::string& key); + +        /// get defined groups +        static +        std::vector<std::string> get_groups(); + +        /// get definitions for all variables in group +        static +        LLSD get_vars(const std::string& group); + +    private: +        static +        LLSD access(const LLSD& params); +    }; +} // namespace LL + +#endif /* ! defined(LL_COMMONCONTROL_H) */ diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index db94765871..b537102510 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -526,6 +526,7 @@ S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset)  //static  S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool)  { +    LL_PROFILE_ZONE_SCOPED;  	//*****************************************  	LLAPRFilePoolScope scope(pool);  	apr_file_t* file_handle = open(filename, scope.getVolatileAPRPool(), APR_READ|APR_BINARY);  @@ -570,6 +571,7 @@ S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nb  //static  S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool)  { +    LL_PROFILE_ZONE_SCOPED;  	apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY;  	if (offset < 0)  	{ diff --git a/indra/llcommon/llframetimer.cpp b/indra/llcommon/llframetimer.cpp index 58af32f1af..1e9920746b 100644 --- a/indra/llcommon/llframetimer.cpp +++ b/indra/llcommon/llframetimer.cpp @@ -29,11 +29,6 @@  #include "llframetimer.h" -// We don't bother building a stand alone lib; we just need to include the one source file for Tracy support -//#if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER -//	#include "TracyClient.cpp" -//#endif // LL_PROFILER_CONFIGURATION -  // Static members  //LLTimer	LLFrameTimer::sInternalTimer;  U64 LLFrameTimer::sStartTotalTime = totalTime(); diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 849867586a..749b66b472 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -35,6 +35,7 @@  # include <sys/types.h>  # include <mach/task.h>  # include <mach/mach_init.h> +#include <mach/mach_host.h>  #elif LL_LINUX  # include <unistd.h>  #endif @@ -109,6 +110,50 @@ void LLMemory::updateMemoryInfo()  	{  		sAvailPhysicalMemInKB = U32Kilobytes(0);  	} + +#elif defined(LL_DARWIN) +    task_vm_info info; +    mach_msg_type_number_t  infoCount = TASK_VM_INFO_COUNT; +    // MACH_TASK_BASIC_INFO reports the same resident_size, but does not tell us the reusable bytes or phys_footprint. +    if (task_info(mach_task_self(), TASK_VM_INFO, reinterpret_cast<task_info_t>(&info), &infoCount) == KERN_SUCCESS) +    { +        // Our Windows definition of PagefileUsage is documented by Microsoft as "the total amount of +        // memory that the memory manager has committed for a running process", which is rss. +        sAllocatedPageSizeInKB = U32Bytes(info.resident_size); + +        // Activity Monitor => Inspect Process => Real Memory Size appears to report resident_size +        // Activity monitor => main window memory column appears to report phys_footprint, which spot checks as at least 30% less. +        //        I think that is because of compression, which isn't going to give us a consistent measurement. We want uncompressed totals. +        // +        // In between is resident_size - reusable. This is what Chrome source code uses, with source comments saying it is 'the "Real Memory" value +        // reported for the app by the Memory Monitor in Instruments.' It is still about 8% bigger than phys_footprint. +        // +        // (On Windows, we use WorkingSetSize.) +        sAllocatedMemInKB = U32Bytes(info.resident_size - info.reusable); +     } +    else +    { +        LL_WARNS() << "task_info failed" << LL_ENDL; +    } + +    // Total installed and available physical memory are properties of the host, not just our process. +    vm_statistics64_data_t vmstat; +    mach_msg_type_number_t count = HOST_VM_INFO64_COUNT; +    mach_port_t host = mach_host_self(); +    vm_size_t page_size; +    host_page_size(host, &page_size); +    kern_return_t result = host_statistics64(host, HOST_VM_INFO64, reinterpret_cast<host_info_t>(&vmstat), &count); +    if (result == KERN_SUCCESS) { +        // This is what Chrome reports as 'the "Physical Memory Free" value reported by the Memory Monitor in Instruments.' +        // Note though that inactive pages are not included here and not yet free, but could become so under memory pressure. +        sAvailPhysicalMemInKB = U32Bytes(vmstat.free_count * page_size); +        sMaxPhysicalMemInKB = LLMemoryInfo::getHardwareMemSize(); +      } +    else +    { +        LL_WARNS() << "task_info failed" << LL_ENDL; +    } +  #else  	//not valid for other systems for now.  	sAllocatedMemInKB = U64Bytes(LLMemory::getCurrentRSS()); diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h index bc46128d21..c0f5868db3 100644 --- a/indra/llcommon/llprofiler.h +++ b/indra/llcommon/llprofiler.h @@ -134,6 +134,10 @@ extern thread_local bool gProfilerEnabled;          #define LL_PROFILE_ZONE_ERR(name)               LL_PROFILE_ZONE_NAMED_COLOR( name, 0XFF0000  )  // RGB yellow          #define LL_PROFILE_ZONE_INFO(name)              LL_PROFILE_ZONE_NAMED_COLOR( name, 0X00FFFF  )  // RGB cyan          #define LL_PROFILE_ZONE_WARN(name)              LL_PROFILE_ZONE_NAMED_COLOR( name, 0x0FFFF00 )  // RGB red +        //#define LL_PROFILE_ALLOC(ptr, size)             TracyAlloc(ptr, size) // memory allocation tracking currently not working +        //#define LL_PROFILE_FREE(ptr)                    TracyFree(ptr) +        #define LL_PROFILE_ALLOC(ptr, size)             (void)(ptr); (void)(size); +        #define LL_PROFILE_FREE(ptr)                    (void)(ptr);      #endif  #else      #define LL_PROFILER_FRAME_END diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 8cef4293cd..155e32ebae 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -26,20 +26,26 @@  #include "linden_common.h"  #include "llqueuedthread.h" +#include <chrono> +  #include "llstl.h"  #include "lltimer.h"	// ms_sleep() -#include "lltracethreadrecorder.h" +#include "llmutex.h"  //============================================================================  // MAIN THREAD  LLQueuedThread::LLQueuedThread(const std::string& name, bool threaded, bool should_pause) : -	LLThread(name), -	mThreaded(threaded), -	mIdleThread(TRUE), -	mNextHandle(0), -	mStarted(FALSE) +    LLThread(name), +    mIdleThread(TRUE), +    mNextHandle(0), +    mStarted(FALSE), +    mThreaded(threaded), +    mRequestQueue(name, 1024 * 1024)  { +    llassert(threaded); // not threaded implementation is deprecated +    mMainQueue = LL::WorkQueue::getInstance("mainloop"); +  	if (mThreaded)  	{  		if(should_pause) @@ -69,6 +75,11 @@ void LLQueuedThread::shutdown()  	unpause(); // MAIN THREAD  	if (mThreaded)  	{ +        if (mRequestQueue.size() == 0) +        { +            mRequestQueue.close(); +        } +  		S32 timeout = 100;  		for ( ; timeout>0; timeout--)  		{ @@ -104,6 +115,8 @@ void LLQueuedThread::shutdown()  	{  		LL_WARNS() << "~LLQueuedThread() called with active requests: " << active_count << LL_ENDL;  	} + +    mRequestQueue.close();  }  //---------------------------------------------------------------------------- @@ -112,6 +125,7 @@ void LLQueuedThread::shutdown()  // virtual  S32 LLQueuedThread::update(F32 max_time_ms)  { +    LL_PROFILE_ZONE_SCOPED;  	if (!mStarted)  	{  		if (!mThreaded) @@ -125,29 +139,34 @@ S32 LLQueuedThread::update(F32 max_time_ms)  S32 LLQueuedThread::updateQueue(F32 max_time_ms)  { -	F64 max_time = (F64)max_time_ms * .001; -	LLTimer timer; -	S32 pending = 1; - +    LL_PROFILE_ZONE_SCOPED;  	// Frame Update  	if (mThreaded)  	{ -		pending = getPending(); -		if(pending > 0) +        // schedule a call to threadedUpdate for every call to updateQueue +        if (!isQuitting()) +        { +            mRequestQueue.post([=]() +                { +                    LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qt - update"); +                    mIdleThread = FALSE; +                    threadedUpdate(); +                    mIdleThread = TRUE; +                } +            ); +        } + +		if(getPending() > 0)  		{ -		unpause(); -	} +		    unpause(); +	    }  	}  	else  	{ -		while (pending > 0) -		{ -			pending = processNextRequest(); -			if (max_time && timer.getElapsedTimeF64() > max_time) -				break; -		} +        mRequestQueue.runFor(std::chrono::microseconds((int) (max_time_ms*1000.f))); +        threadedUpdate();  	} -	return pending; +	return getPending();  }  void LLQueuedThread::incQueue() @@ -166,11 +185,7 @@ void LLQueuedThread::incQueue()  // May be called from any thread  S32 LLQueuedThread::getPending()  { -	S32 res; -	lockData(); -	res = mRequestQueue.size(); -	unlockData(); -	return res; +	return mRequestQueue.size();  }  // MAIN thread @@ -195,35 +210,28 @@ void LLQueuedThread::waitOnPending()  // MAIN thread  void LLQueuedThread::printQueueStats()  { -	lockData(); -	if (!mRequestQueue.empty()) +    U32 size = mRequestQueue.size(); +	if (size > 0)  	{ -		QueuedRequest *req = *mRequestQueue.begin(); -		LL_INFOS() << llformat("Pending Requests:%d Current status:%d", mRequestQueue.size(), req->getStatus()) << LL_ENDL; +		LL_INFOS() << llformat("Pending Requests:%d ", mRequestQueue.size()) << LL_ENDL;  	}  	else  	{  		LL_INFOS() << "Queued Thread Idle" << LL_ENDL;  	} -	unlockData();  }  // MAIN thread  LLQueuedThread::handle_t LLQueuedThread::generateHandle()  { -	lockData(); -	while ((mNextHandle == nullHandle()) || (mRequestHash.find(mNextHandle))) -	{ -		mNextHandle++; -	} -	const LLQueuedThread::handle_t res = mNextHandle++; -	unlockData(); +    U32 res = ++mNextHandle;  	return res;  }  // MAIN thread  bool LLQueuedThread::addRequest(QueuedRequest* req)  { +    LL_PROFILE_ZONE_SCOPED;  	if (mStatus == QUITTING)  	{  		return false; @@ -231,14 +239,14 @@ bool LLQueuedThread::addRequest(QueuedRequest* req)  	lockData();  	req->setStatus(STATUS_QUEUED); -	mRequestQueue.insert(req); -	mRequestHash.insert(req); +    mRequestHash.insert(req);  #if _DEBUG  // 	LL_INFOS() << llformat("LLQueuedThread::Added req [%08d]",handle) << LL_ENDL;  #endif  	unlockData(); -	incQueue(); +    llassert(!mDataLock->isSelfLocked()); +    mRequestQueue.post([this, req]() { processRequest(req); });  	return true;  } @@ -246,6 +254,7 @@ bool LLQueuedThread::addRequest(QueuedRequest* req)  // MAIN thread  bool LLQueuedThread::waitForResult(LLQueuedThread::handle_t handle, bool auto_complete)  { +    LL_PROFILE_ZONE_SCOPED;  	llassert (handle != nullHandle());  	bool res = false;  	bool waspaused = isPaused(); @@ -312,6 +321,7 @@ LLQueuedThread::status_t LLQueuedThread::getRequestStatus(handle_t handle)  void LLQueuedThread::abortRequest(handle_t handle, bool autocomplete)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;  	lockData();  	QueuedRequest* req = (QueuedRequest*)mRequestHash.find(handle);  	if (req) @@ -333,30 +343,9 @@ void LLQueuedThread::setFlags(handle_t handle, U32 flags)  	unlockData();  } -void LLQueuedThread::setPriority(handle_t handle, U32 priority) -{ -	lockData(); -	QueuedRequest* req = (QueuedRequest*)mRequestHash.find(handle); -	if (req) -	{ -		if(req->getStatus() == STATUS_INPROGRESS) -		{ -			// not in list -			req->setPriority(priority); -		} -		else if(req->getStatus() == STATUS_QUEUED) -		{ -			// remove from list then re-insert -			llverify(mRequestQueue.erase(req) == 1); -			req->setPriority(priority); -			mRequestQueue.insert(req); -		} -	} -	unlockData(); -} -  bool LLQueuedThread::completeRequest(handle_t handle)  { +    LL_PROFILE_ZONE_SCOPED;  	bool res = false;  	lockData();  	QueuedRequest* req = (QueuedRequest*)mRequestHash.find(handle); @@ -399,89 +388,115 @@ bool LLQueuedThread::check()  //============================================================================  // Runs on its OWN thread -S32 LLQueuedThread::processNextRequest() +void LLQueuedThread::processRequest(LLQueuedThread::QueuedRequest* req)  { -	QueuedRequest *req; +    LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; + +    mIdleThread = FALSE; +    //threadedUpdate(); +  	// Get next request from pool  	lockData(); -	while(1) +	if ((req->getFlags() & FLAG_ABORT) || (mStatus == QUITTING))  	{ -		req = NULL; -		if (mRequestQueue.empty()) +        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qtpr - abort"); +		req->setStatus(STATUS_ABORTED); +		req->finishRequest(false); +		if (req->getFlags() & FLAG_AUTO_COMPLETE)  		{ -			break; -		} -		req = *mRequestQueue.begin(); -		mRequestQueue.erase(mRequestQueue.begin()); -		if ((req->getFlags() & FLAG_ABORT) || (mStatus == QUITTING)) -		{ -			req->setStatus(STATUS_ABORTED); -			req->finishRequest(false); -			if (req->getFlags() & FLAG_AUTO_COMPLETE) -			{ -				mRequestHash.erase(req); -				req->deleteRequest(); -// 				check(); -			} -			continue; -		} -		llassert_always(req->getStatus() == STATUS_QUEUED); -		break; -	} -	U32 start_priority = 0 ; -	if (req) -	{ -		req->setStatus(STATUS_INPROGRESS); -		start_priority = req->getPriority(); -	} -	unlockData(); - -	// This is the only place we will call req->setStatus() after -	// it has initially been seet to STATUS_QUEUED, so it is -	// safe to access req. -	if (req) -	{ -		// process request		 -		bool complete = req->processRequest(); - -		if (complete) -		{ -			lockData(); -			req->setStatus(STATUS_COMPLETE); -			req->finishRequest(true); -			if (req->getFlags() & FLAG_AUTO_COMPLETE) -			{ -				mRequestHash.erase(req); -				req->deleteRequest(); +			mRequestHash.erase(req); +			req->deleteRequest();  // 				check(); -			} -			unlockData();  		} -		else -		{ -			lockData(); -			req->setStatus(STATUS_QUEUED); -			mRequestQueue.insert(req); -			unlockData(); -			if (mThreaded && start_priority < PRIORITY_NORMAL) -			{ -				ms_sleep(1); // sleep the thread a little -			} -		} -		 -		LLTrace::get_thread_recorder()->pushToParent(); +        unlockData();  	} +    else +    { +        llassert_always(req->getStatus() == STATUS_QUEUED); + +        if (req) +        { +            req->setStatus(STATUS_INPROGRESS); +        } +        unlockData(); + +        // This is the only place we will call req->setStatus() after +        // it has initially been seet to STATUS_QUEUED, so it is +        // safe to access req. +        if (req) +        { +            // process request		 +            bool complete = req->processRequest(); + +            if (complete) +            { +                LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qtpr - complete"); +                lockData(); +                req->setStatus(STATUS_COMPLETE); +                req->finishRequest(true); +                if (req->getFlags() & FLAG_AUTO_COMPLETE) +                { +                    mRequestHash.erase(req); +                    req->deleteRequest(); +                    // 				check(); +                } +                unlockData(); +            } +            else +            { +                LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qtpr - retry"); +                //put back on queue and try again in 0.1ms +                lockData(); +                req->setStatus(STATUS_QUEUED); +                 +                unlockData(); + +                llassert(!mDataLock->isSelfLocked()); + +#if 0 +                // try again on next frame +                // NOTE: tried using "post" with a time in the future, but this +                // would invariably cause this thread to wait for a long time (10+ ms) +                // while work is pending +                bool ret = LL::WorkQueue::postMaybe( +                    mMainQueue, +                    [=]() +                    { +                        LL_PROFILE_ZONE_NAMED("processRequest - retry"); +                        mRequestQueue.post([=]() +                            { +                                LL_PROFILE_ZONE_NAMED("processRequest - retry"); // <-- not redundant, track retry on both queues +                                processRequest(req); +                            }); +                    }); +                llassert(ret); +#else +                using namespace std::chrono_literals; +                auto retry_time = LL::WorkQueue::TimePoint::clock::now() + 16ms; +                mRequestQueue.post([=] +                    { +                        LL_PROFILE_ZONE_NAMED("processRequest - retry"); +                        while (LL::WorkQueue::TimePoint::clock::now() < retry_time) +                        { +                            std::this_thread::yield(); //note: don't use LLThread::yield here to avoid  +                        } +                        processRequest(req); +                    }); +#endif +                 +            } +        } +    } -	S32 pending = getPending(); -	return pending; +    mIdleThread = TRUE;  }  // virtual  bool LLQueuedThread::runCondition()  {  	// mRunCondition must be locked here -	if (mRequestQueue.empty() && mIdleThread) +	if (mRequestQueue.size() == 0 && mIdleThread)  		return false;  	else  		return true; @@ -495,18 +510,13 @@ void LLQueuedThread::run()  	startThread();  	mStarted = TRUE; -	while (1) + +	/*while (1)  	{ +        LL_PROFILE_ZONE_SCOPED;  		// this will block on the condition until runCondition() returns true, the thread is unpaused, or the thread leaves the RUNNING state.  		checkPause(); -		if (isQuitting()) -		{ -			LLTrace::get_thread_recorder()->pushToParent(); -			endThread(); -			break; -		} -  		mIdleThread = FALSE;  		threadedUpdate(); @@ -515,12 +525,18 @@ void LLQueuedThread::run()  		if (pending_work == 0)  		{ +            //LL_PROFILE_ZONE_NAMED("LLQueuedThread - sleep");  			mIdleThread = TRUE; -			ms_sleep(1); +			//ms_sleep(1);  		}  		//LLThread::yield(); // thread should yield after each request		 -	} +	}*/ +    mRequestQueue.runUntilClose(); + +    endThread();  	LL_INFOS() << "LLQueuedThread " << mName << " EXITING." << LL_ENDL; + +      }  // virtual @@ -540,10 +556,9 @@ void LLQueuedThread::threadedUpdate()  //============================================================================ -LLQueuedThread::QueuedRequest::QueuedRequest(LLQueuedThread::handle_t handle, U32 priority, U32 flags) : +LLQueuedThread::QueuedRequest::QueuedRequest(LLQueuedThread::handle_t handle, U32 flags) :  	LLSimpleHashEntry<LLQueuedThread::handle_t>(handle),  	mStatus(STATUS_UNKNOWN), -	mPriority(priority),  	mFlags(flags)  {  } diff --git a/indra/llcommon/llqueuedthread.h b/indra/llcommon/llqueuedthread.h index 5d3f873646..6b82ccc434 100644 --- a/indra/llcommon/llqueuedthread.h +++ b/indra/llcommon/llqueuedthread.h @@ -36,6 +36,7 @@  #include "llthread.h"  #include "llsimplehash.h" +#include "workqueue.h"  //============================================================================  // Note: ~LLQueuedThread is O(N) N=# of queued threads, assumed to be small @@ -45,15 +46,6 @@ class LL_COMMON_API LLQueuedThread : public LLThread  {  	//------------------------------------------------------------------------  public: -	enum priority_t { -		PRIORITY_IMMEDIATE = 0x7FFFFFFF, -		PRIORITY_URGENT =    0x40000000, -		PRIORITY_HIGH =      0x30000000, -		PRIORITY_NORMAL =    0x20000000, -		PRIORITY_LOW =       0x10000000, -		PRIORITY_LOWBITS =   0x0FFFFFFF, -		PRIORITY_HIGHBITS =  0x70000000 -	};  	enum status_t {  		STATUS_EXPIRED = -1,  		STATUS_UNKNOWN = 0, @@ -82,28 +74,17 @@ public:  		virtual ~QueuedRequest(); // use deleteRequest()  	public: -		QueuedRequest(handle_t handle, U32 priority, U32 flags = 0); +		QueuedRequest(handle_t handle, U32 flags = 0);  		status_t getStatus()  		{  			return mStatus;  		} -		U32 getPriority() const -		{ -			return mPriority; -		}  		U32 getFlags() const  		{  			return mFlags;  		} -		bool higherPriority(const QueuedRequest& second) const -		{ -			if ( mPriority == second.mPriority) -				return mHashKey < second.mHashKey; -			else -				return mPriority > second.mPriority; -		} - +		  	protected:  		status_t setStatus(status_t newstatus)  		{ @@ -121,28 +102,11 @@ public:  		virtual void finishRequest(bool completed); // Always called from thread after request has completed or aborted  		virtual void deleteRequest(); // Only method to delete a request -		void setPriority(U32 pri) -		{ -			// Only do this on a request that is not in a queued list! -			mPriority = pri; -		}; -		  	protected:  		LLAtomicBase<status_t> mStatus; -		U32 mPriority;  		U32 mFlags;  	}; -protected: -	struct queued_request_less -	{ -		bool operator()(const QueuedRequest* lhs, const QueuedRequest* rhs) const -		{ -			return lhs->higherPriority(*rhs); // higher priority in front of queue (set) -		} -	}; - -  	//------------------------------------------------------------------------  public: @@ -167,7 +131,7 @@ private:  protected:  	handle_t generateHandle();  	bool addRequest(QueuedRequest* req); -	S32  processNextRequest(void); +	void processRequest(QueuedRequest* req);  	void incQueue();  public: @@ -186,7 +150,6 @@ public:  	status_t getRequestStatus(handle_t handle);  	void abortRequest(handle_t handle, bool autocomplete);  	void setFlags(handle_t handle, U32 flags); -	void setPriority(handle_t handle, U32 priority);  	bool completeRequest(handle_t handle);  	// This is public for support classes like LLWorkerThread,  	// but generally the methods above should be used. @@ -200,8 +163,10 @@ protected:  	BOOL mStarted;  // required when mThreaded is false to call startThread() from update()  	LLAtomicBool mIdleThread; // request queue is empty (or we are quitting) and the thread is idle -	typedef std::set<QueuedRequest*, queued_request_less> request_queue_t; -	request_queue_t mRequestQueue; +	//typedef std::set<QueuedRequest*, queued_request_less> request_queue_t; +	//request_queue_t mRequestQueue; +    LL::WorkQueue mRequestQueue; +    LL::WorkQueue::weak_t mMainQueue;  	enum { REQUEST_HASH_SIZE = 512 }; // must be power of 2  	typedef LLSimpleHash<handle_t, REQUEST_HASH_SIZE> request_hash_t; diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 9b6bb3826c..45417bfa37 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -710,20 +710,28 @@ static U32Kilobytes LLMemoryAdjustKBResult(U32Kilobytes inKB)  }  #endif +#if LL_DARWIN +// static +U32Kilobytes LLMemoryInfo::getHardwareMemSize() +{ +    // This might work on Linux as well.  Someone check... +    uint64_t phys = 0; +    int mib[2] = { CTL_HW, HW_MEMSIZE }; + +    size_t len = sizeof(phys); +    sysctl(mib, 2, &phys, &len, NULL, 0); + +    return U64Bytes(phys); +} +#endif +  U32Kilobytes LLMemoryInfo::getPhysicalMemoryKB() const  {  #if LL_WINDOWS  	return LLMemoryAdjustKBResult(U32Kilobytes(mStatsMap["Total Physical KB"].asInteger()));  #elif LL_DARWIN -	// This might work on Linux as well.  Someone check... -	uint64_t phys = 0; -	int mib[2] = { CTL_HW, HW_MEMSIZE }; - -	size_t len = sizeof(phys);	 -	sysctl(mib, 2, &phys, &len, NULL, 0); -	 -	return U64Bytes(phys); +    return getHardwareMemSize();  #elif LL_LINUX  	U64 phys = 0; diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h index cb92cb0ac6..538e61c521 100644 --- a/indra/llcommon/llsys.h +++ b/indra/llcommon/llsys.h @@ -117,7 +117,10 @@ public:  	LLMemoryInfo(); ///< Default constructor  	void stream(std::ostream& s) const;	///< output text info to s -	U32Kilobytes getPhysicalMemoryKB() const;  +	U32Kilobytes getPhysicalMemoryKB() const; +#if LL_DARWIN +    static U32Kilobytes getHardwareMemSize(); // Because some Mac linkers won't let us reference extern gSysMemory from a different lib. +#endif  	//get the available memory infomation in KiloBytes.  	static void getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32Kilobytes& avail_virtual_mem_kb); diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index aaa6df325c..39dfee3755 100644 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -30,6 +30,9 @@  #include "u64.h" +#include <chrono> +#include <thread> +  #if LL_WINDOWS  #	include "llwin32headerslean.h"  #elif LL_LINUX || LL_DARWIN @@ -64,7 +67,13 @@ LLTimer* LLTimer::sTimer = NULL;  #if LL_WINDOWS  void ms_sleep(U32 ms)  { -	Sleep(ms); +    LL_PROFILE_ZONE_SCOPED; +    using TimePoint = std::chrono::steady_clock::time_point; +    auto resume_time = TimePoint::clock::now() + std::chrono::milliseconds(ms); +    while (TimePoint::clock::now() < resume_time) +    { +        std::this_thread::yield(); //note: don't use LLThread::yield here to avoid yielding for too long +    }  }  U32 micro_sleep(U64 us, U32 max_yields) diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp index 4b91b2caca..02ce4823b8 100644 --- a/indra/llcommon/llworkerthread.cpp +++ b/indra/llcommon/llworkerthread.cpp @@ -133,11 +133,11 @@ S32 LLWorkerThread::update(F32 max_time_ms)  //---------------------------------------------------------------------------- -LLWorkerThread::handle_t LLWorkerThread::addWorkRequest(LLWorkerClass* workerclass, S32 param, U32 priority) +LLWorkerThread::handle_t LLWorkerThread::addWorkRequest(LLWorkerClass* workerclass, S32 param)  {  	handle_t handle = generateHandle(); -	WorkRequest* req = new WorkRequest(handle, priority, workerclass, param); +	WorkRequest* req = new WorkRequest(handle, workerclass, param);  	bool res = addRequest(req);  	if (!res) @@ -160,8 +160,8 @@ void LLWorkerThread::deleteWorker(LLWorkerClass* workerclass)  //============================================================================  // Runs on its OWN thread -LLWorkerThread::WorkRequest::WorkRequest(handle_t handle, U32 priority, LLWorkerClass* workerclass, S32 param) : -	LLQueuedThread::QueuedRequest(handle, priority), +LLWorkerThread::WorkRequest::WorkRequest(handle_t handle, LLWorkerClass* workerclass, S32 param) : +	LLQueuedThread::QueuedRequest(handle),  	mWorkerClass(workerclass),  	mParam(param)  { @@ -180,6 +180,7 @@ void LLWorkerThread::WorkRequest::deleteRequest()  // virtual  bool LLWorkerThread::WorkRequest::processRequest()  { +    LL_PROFILE_ZONE_SCOPED;  	LLWorkerClass* workerclass = getWorkerClass();  	workerclass->setWorking(true);  	bool complete = workerclass->doWork(getParam()); @@ -190,6 +191,7 @@ bool LLWorkerThread::WorkRequest::processRequest()  // virtual  void LLWorkerThread::WorkRequest::finishRequest(bool completed)  { +    LL_PROFILE_ZONE_SCOPED;  	LLWorkerClass* workerclass = getWorkerClass();  	workerclass->finishWork(getParam(), completed);  	U32 flags = LLWorkerClass::WCF_WORK_FINISHED | (completed ? 0 : LLWorkerClass::WCF_WORK_ABORTED); @@ -203,7 +205,6 @@ LLWorkerClass::LLWorkerClass(LLWorkerThread* workerthread, const std::string& na  	: mWorkerThread(workerthread),  	  mWorkerClassName(name),  	  mRequestHandle(LLWorkerThread::nullHandle()), -	  mRequestPriority(LLWorkerThread::PRIORITY_NORMAL),  	  mMutex(),  	  mWorkFlags(0)  { @@ -292,7 +293,7 @@ bool LLWorkerClass::yield()  //----------------------------------------------------------------------------  // calls startWork, adds doWork() to queue -void LLWorkerClass::addWork(S32 param, U32 priority) +void LLWorkerClass::addWork(S32 param)  {  	mMutex.lock();  	llassert_always(!(mWorkFlags & (WCF_WORKING|WCF_HAVE_WORK))); @@ -306,7 +307,7 @@ void LLWorkerClass::addWork(S32 param, U32 priority)  	startWork(param);  	clearFlags(WCF_WORK_FINISHED|WCF_WORK_ABORTED);  	setFlags(WCF_HAVE_WORK); -	mRequestHandle = mWorkerThread->addWorkRequest(this, param, priority); +	mRequestHandle = mWorkerThread->addWorkRequest(this, param);  	mMutex.unlock();  } @@ -321,7 +322,6 @@ void LLWorkerClass::abortWork(bool autocomplete)  	if (mRequestHandle != LLWorkerThread::nullHandle())  	{  		mWorkerThread->abortRequest(mRequestHandle, autocomplete); -		mWorkerThread->setPriority(mRequestHandle, LLQueuedThread::PRIORITY_IMMEDIATE);  		setFlags(WCF_ABORT_REQUESTED);  	}  	mMutex.unlock(); @@ -395,16 +395,5 @@ void LLWorkerClass::scheduleDelete()  	}  } -void LLWorkerClass::setPriority(U32 priority) -{ -	mMutex.lock(); -	if (mRequestHandle != LLWorkerThread::nullHandle() && mRequestPriority != priority) -	{ -		mRequestPriority = priority; -		mWorkerThread->setPriority(mRequestHandle, priority); -	} -	mMutex.unlock(); -} -  //============================================================================ diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h index 0387e75c65..06bbb7369e 100644 --- a/indra/llcommon/llworkerthread.h +++ b/indra/llcommon/llworkerthread.h @@ -56,7 +56,7 @@ public:  		virtual ~WorkRequest(); // use deleteRequest()  	public: -		WorkRequest(handle_t handle, U32 priority, LLWorkerClass* workerclass, S32 param); +		WorkRequest(handle_t handle, LLWorkerClass* workerclass, S32 param);  		S32 getParam()  		{ @@ -90,7 +90,7 @@ public:  	/*virtual*/ S32 update(F32 max_time_ms); -	handle_t addWorkRequest(LLWorkerClass* workerclass, S32 param, U32 priority = PRIORITY_NORMAL); +	handle_t addWorkRequest(LLWorkerClass* workerclass, S32 param);  	S32 getNumDeletes() { return (S32)mDeleteList.size(); } // debug @@ -151,10 +151,6 @@ public:  	bool isWorking() { return getFlags(WCF_WORKING); }  	bool wasAborted() { return getFlags(WCF_ABORT_REQUESTED); } -	// setPriority(): changes the priority of a request -	void setPriority(U32 priority); -	U32  getPriority() { return mRequestPriority; } -		  	const std::string& getName() const { return mWorkerClassName; }  protected: @@ -169,7 +165,7 @@ protected:  	void setWorkerThread(LLWorkerThread* workerthread);  	// addWork(): calls startWork, adds doWork() to queue -	void addWork(S32 param, U32 priority = LLWorkerThread::PRIORITY_NORMAL); +	void addWork(S32 param);  	// abortWork(): requests that work be aborted  	void abortWork(bool autocomplete); @@ -193,7 +189,6 @@ protected:  	LLWorkerThread* mWorkerThread;  	std::string mWorkerClassName;  	handle_t mRequestHandle; -	U32 mRequestPriority; // last priority set  private:  	LLMutex mMutex; diff --git a/indra/llcommon/threadpool.cpp b/indra/llcommon/threadpool.cpp index ba914035e2..f49dd40a8b 100644 --- a/indra/llcommon/threadpool.cpp +++ b/indra/llcommon/threadpool.cpp @@ -17,14 +17,17 @@  // std headers  // external library headers  // other Linden headers +#include "commoncontrol.h"  #include "llerror.h"  #include "llevents.h" +#include "llsd.h"  #include "stringize.h"  LL::ThreadPool::ThreadPool(const std::string& name, size_t threads, size_t capacity): +    super(name),      mQueue(name, capacity),      mName("ThreadPool:" + name), -    mThreadCount(threads) +    mThreadCount(getConfiguredWidth(name, threads))  {}  void LL::ThreadPool::start() @@ -86,3 +89,58 @@ void LL::ThreadPool::run()  {      mQueue.runUntilClose();  } + +//static +size_t LL::ThreadPool::getConfiguredWidth(const std::string& name, size_t dft) +{ +    LLSD poolSizes; +    try +    { +        poolSizes = LL::CommonControl::get("Global", "ThreadPoolSizes"); +        // "ThreadPoolSizes" is actually a map containing the sizes of +        // interest -- or should be, if this process has an +        // LLViewerControlListener instance and its settings include +        // "ThreadPoolSizes". If we failed to retrieve it, perhaps we're in a +        // program that doesn't define that, or perhaps there's no such +        // setting, or perhaps we're asking too early, before the LLEventAPI +        // itself has been instantiated. In any of those cases, it seems worth +        // warning. +        if (! poolSizes.isDefined()) +        { +            // Note: we don't warn about absence of an override key for a +            // particular ThreadPool name, that's fine. This warning is about +            // complete absence of a ThreadPoolSizes setting, which we expect +            // in a normal viewer session. +            LL_WARNS("ThreadPool") << "No 'ThreadPoolSizes' setting for ThreadPool '" +                                   << name << "'" << LL_ENDL; +        } +    } +    catch (const LL::CommonControl::Error& exc) +    { +        // We don't want ThreadPool to *require* LLViewerControlListener. +        // Just log it and carry on. +        LL_WARNS("ThreadPool") << "Can't check 'ThreadPoolSizes': " << exc.what() << LL_ENDL; +    } + +    LL_DEBUGS("ThreadPool") << "ThreadPoolSizes = " << poolSizes << LL_ENDL; +    // LLSD treats an undefined value as an empty map when asked to retrieve a +    // key, so we don't need this to be conditional. +    LLSD sizeSpec{ poolSizes[name] }; +    // We retrieve sizeSpec as LLSD, rather than immediately as LLSD::Integer, +    // so we can distinguish the case when it's undefined. +    return sizeSpec.isInteger() ? sizeSpec.asInteger() : dft; +} + +//static +size_t LL::ThreadPool::getWidth(const std::string& name, size_t dft) +{ +    auto instance{ getInstance(name) }; +    if (instance) +    { +        return instance->getWidth(); +    } +    else +    { +        return getConfiguredWidth(name, dft); +    } +} diff --git a/indra/llcommon/threadpool.h b/indra/llcommon/threadpool.h index b79c9b9090..b49d511257 100644 --- a/indra/llcommon/threadpool.h +++ b/indra/llcommon/threadpool.h @@ -22,14 +22,25 @@  namespace LL  { -    class ThreadPool +    class ThreadPool: public LLInstanceTracker<ThreadPool, std::string>      { +    private: +        using super = LLInstanceTracker<ThreadPool, std::string>;      public:          /**           * Pass ThreadPool a string name. This can be used to look up the           * relevant WorkQueue. +         * +         * The number of threads you pass sets the compile-time default. But +         * if the user has overridden the LLSD map in the "ThreadPoolSizes" +         * setting with a key matching this ThreadPool name, that setting +         * overrides this parameter. +         * +         * Pass an explicit capacity to limit the size of the queue. +         * Constraining the queue can cause a submitter to block. Do not +         * constrain any ThreadPool accepting work from the main thread.           */ -        ThreadPool(const std::string& name, size_t threads=1, size_t capacity=1024); +        ThreadPool(const std::string& name, size_t threads=1, size_t capacity=1024*1024);          virtual ~ThreadPool();          /** @@ -57,6 +68,25 @@ namespace LL           */          virtual void run(); +        /** +         * getConfiguredWidth() returns the setting, if any, for the specified +         * ThreadPool name. Returns dft if the "ThreadPoolSizes" map does not +         * contain the specified name. +         */ +        static +        size_t getConfiguredWidth(const std::string& name, size_t dft=0); + +        /** +         * This getWidth() returns the width of the instantiated ThreadPool +         * with the specified name, if any. If no instance exists, returns its +         * getConfiguredWidth() if any. If there's no instance and no relevant +         * override, return dft. Presumably dft should match the threads +         * parameter passed to the ThreadPool constructor call that will +         * eventually instantiate the ThreadPool with that name. +         */ +        static +        size_t getWidth(const std::string& name, size_t dft); +      private:          void run(const std::string& name); diff --git a/indra/llcommon/workqueue.h b/indra/llcommon/workqueue.h index 96574a18b9..784327f929 100644 --- a/indra/llcommon/workqueue.h +++ b/indra/llcommon/workqueue.h @@ -162,9 +162,15 @@ namespace LL                         CALLABLE&& callable);          template <typename CALLABLE> +        bool tryPost(const TimePoint& time, CALLABLE&& callable) +        { +            return mQueue.tryPush(TimedWork(time, std::move(callable))); +        } + +        template <typename CALLABLE>          bool tryPost(CALLABLE&& callable)          { -            return mQueue.tryPush(TimedWork(TimePoint::clock::now(), std::move(callable))); +            return mQueue.tryPush(TimePoint::clock::now(), std::move(callable));          }          /*------------------------- handshake API --------------------------*/ diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp index 975ce8a4d5..bd0ac740db 100644 --- a/indra/llcorehttp/_httplibcurl.cpp +++ b/indra/llcorehttp/_httplibcurl.cpp @@ -113,6 +113,7 @@ void HttpLibcurl::shutdown()  void HttpLibcurl::start(int policy_count)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	llassert_always(policy_count <= HTTP_POLICY_CLASS_LIMIT);  	llassert_always(! mMultiHandles);					// One-time call only @@ -143,6 +144,7 @@ void HttpLibcurl::start(int policy_count)  // sleep otherwise ask for a normal polling interval.  HttpService::ELoopSpeed HttpLibcurl::processTransport()  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	HttpService::ELoopSpeed	ret(HttpService::REQUEST_SLEEP);  	// Give libcurl some cycles to do I/O & callbacks @@ -168,6 +170,7 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport()  		CURLMcode status(CURLM_CALL_MULTI_PERFORM);  		do  		{ +            LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("httppt - curl_multi_perform");  			running = 0;  			status = curl_multi_perform(mMultiHandles[policy_class], &running);  		} @@ -176,31 +179,34 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport()  		// Run completion on anything done  		CURLMsg * msg(NULL);  		int msgs_in_queue(0); -		while ((msg = curl_multi_info_read(mMultiHandles[policy_class], &msgs_in_queue))) -		{ -			if (CURLMSG_DONE == msg->msg) -			{ -				CURL * handle(msg->easy_handle); -				CURLcode result(msg->data.result); +        { +            LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("httppt - curl_multi_info_read"); +            while ((msg = curl_multi_info_read(mMultiHandles[policy_class], &msgs_in_queue))) +            { +                if (CURLMSG_DONE == msg->msg) +                { +                    CURL* handle(msg->easy_handle); +                    CURLcode result(msg->data.result); -				completeRequest(mMultiHandles[policy_class], handle, result); -				handle = NULL;					// No longer valid on return -				ret = HttpService::NORMAL;		// If anything completes, we may have a free slot. -												// Turning around quickly reduces connection gap by 7-10mS. -			} -			else if (CURLMSG_NONE == msg->msg) -			{ -				// Ignore this... it shouldn't mean anything. -				; -			} -			else -			{ -				LL_WARNS_ONCE(LOG_CORE) << "Unexpected message from libcurl.  Msg code:  " -										<< msg->msg -										<< LL_ENDL; -			} -			msgs_in_queue = 0; -		} +                    completeRequest(mMultiHandles[policy_class], handle, result); +                    handle = NULL;					// No longer valid on return +                    ret = HttpService::NORMAL;		// If anything completes, we may have a free slot. +                                                    // Turning around quickly reduces connection gap by 7-10mS. +                } +                else if (CURLMSG_NONE == msg->msg) +                { +                    // Ignore this... it shouldn't mean anything. +                    ; +                } +                else +                { +                    LL_WARNS_ONCE(LOG_CORE) << "Unexpected message from libcurl.  Msg code:  " +                        << msg->msg +                        << LL_ENDL; +                } +                msgs_in_queue = 0; +            } +        }  	}  	if (! mActiveOps.empty()) @@ -214,6 +220,7 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport()  // Caller has provided us with a ref count on op.  void HttpLibcurl::addOp(const HttpOpRequest::ptr_t &op)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	llassert_always(op->mReqPolicy < mPolicyCount);  	llassert_always(mMultiHandles[op->mReqPolicy] != NULL); @@ -257,6 +264,7 @@ void HttpLibcurl::addOp(const HttpOpRequest::ptr_t &op)  // method to kill the request.  bool HttpLibcurl::cancel(HttpHandle handle)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;      HttpOpRequest::ptr_t op = HttpOpRequest::fromHandle<HttpOpRequest>(handle);  	active_set_t::iterator it(mActiveOps.find(op));  	if (mActiveOps.end() == it) @@ -282,6 +290,7 @@ bool HttpLibcurl::cancel(HttpHandle handle)  // op to the reply queue with refcount intact.  void HttpLibcurl::cancelRequest(const HttpOpRequest::ptr_t &op)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	// Deactivate request  	op->mCurlActive = false; @@ -308,6 +317,7 @@ void HttpLibcurl::cancelRequest(const HttpOpRequest::ptr_t &op)  // Keep them synchronized as necessary.  bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode status)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;      HttpHandle ophandle(NULL);      CURLcode ccode(CURLE_OK); @@ -445,6 +455,7 @@ int HttpLibcurl::getActiveCountInClass(int policy_class) const  void HttpLibcurl::policyUpdated(int policy_class)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	if (policy_class < 0 || policy_class >= mPolicyCount || ! mMultiHandles)  	{  		return; diff --git a/indra/llcorehttp/_httpoperation.cpp b/indra/llcorehttp/_httpoperation.cpp index 3fc4e28910..3b64018132 100644 --- a/indra/llcorehttp/_httpoperation.cpp +++ b/indra/llcorehttp/_httpoperation.cpp @@ -62,7 +62,6 @@ HttpOperation::HttpOperation():      mReplyQueue(),      mUserHandler(),      mReqPolicy(HttpRequest::DEFAULT_POLICY_ID), -    mReqPriority(0U),      mTracing(HTTP_TRACE_OFF),      mMyHandle(LLCORE_HTTP_HANDLE_INVALID)  { diff --git a/indra/llcorehttp/_httpoperation.h b/indra/llcorehttp/_httpoperation.h index 1a75921c09..8c1364bab4 100644 --- a/indra/llcorehttp/_httpoperation.h +++ b/indra/llcorehttp/_httpoperation.h @@ -181,7 +181,6 @@ protected:  public:  	// Request Data  	HttpRequest::policy_t		mReqPolicy; -	HttpRequest::priority_t		mReqPriority;  	// Reply Data  	HttpStatus					mStatus; diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp index ba31290c24..d60eb6c95f 100644 --- a/indra/llcorehttp/_httpoprequest.cpp +++ b/indra/llcorehttp/_httpoprequest.cpp @@ -200,6 +200,7 @@ HttpOpRequest::~HttpOpRequest()  void HttpOpRequest::stageFromRequest(HttpService * service)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;      HttpOpRequest::ptr_t self(boost::dynamic_pointer_cast<HttpOpRequest>(shared_from_this()));      service->getPolicy().addOp(self);			// transfers refcount  } @@ -207,6 +208,7 @@ void HttpOpRequest::stageFromRequest(HttpService * service)  void HttpOpRequest::stageFromReady(HttpService * service)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;      HttpOpRequest::ptr_t self(boost::dynamic_pointer_cast<HttpOpRequest>(shared_from_this()));      service->getTransport().addOp(self);		// transfers refcount  } @@ -214,6 +216,7 @@ void HttpOpRequest::stageFromReady(HttpService * service)  void HttpOpRequest::stageFromActive(HttpService * service)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	if (mReplyLength)  	{  		// If non-zero, we received and processed a Content-Range @@ -250,6 +253,7 @@ void HttpOpRequest::stageFromActive(HttpService * service)  void HttpOpRequest::visitNotifier(HttpRequest * request)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	if (mUserHandler)  	{  		HttpResponse * response = new HttpResponse(); @@ -292,6 +296,7 @@ void HttpOpRequest::visitNotifier(HttpRequest * request)  HttpStatus HttpOpRequest::cancel()  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	mStatus = HttpStatus(HttpStatus::LLCORE, HE_OP_CANCELED);  	addAsReply(); @@ -301,12 +306,12 @@ HttpStatus HttpOpRequest::cancel()  HttpStatus HttpOpRequest::setupGet(HttpRequest::policy_t policy_id, -								   HttpRequest::priority_t priority,  								   const std::string & url,                                     const HttpOptions::ptr_t & options,  								   const HttpHeaders::ptr_t & headers)  { -	setupCommon(policy_id, priority, url, NULL, options, headers); +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; +	setupCommon(policy_id, url, NULL, options, headers);  	mReqMethod = HOR_GET;  	return HttpStatus(); @@ -314,14 +319,14 @@ HttpStatus HttpOpRequest::setupGet(HttpRequest::policy_t policy_id,  HttpStatus HttpOpRequest::setupGetByteRange(HttpRequest::policy_t policy_id, -											HttpRequest::priority_t priority,  											const std::string & url,  											size_t offset,  											size_t len,                                              const HttpOptions::ptr_t & options,                                              const HttpHeaders::ptr_t & headers)  { -	setupCommon(policy_id, priority, url, NULL, options, headers); +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; +	setupCommon(policy_id, url, NULL, options, headers);  	mReqMethod = HOR_GET;  	mReqOffset = offset;  	mReqLength = len; @@ -335,13 +340,13 @@ HttpStatus HttpOpRequest::setupGetByteRange(HttpRequest::policy_t policy_id,  HttpStatus HttpOpRequest::setupPost(HttpRequest::policy_t policy_id, -									HttpRequest::priority_t priority,  									const std::string & url,  									BufferArray * body,                                      const HttpOptions::ptr_t & options,                                      const HttpHeaders::ptr_t & headers)  { -	setupCommon(policy_id, priority, url, body, options, headers); +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; +	setupCommon(policy_id, url, body, options, headers);  	mReqMethod = HOR_POST;  	return HttpStatus(); @@ -349,13 +354,13 @@ HttpStatus HttpOpRequest::setupPost(HttpRequest::policy_t policy_id,  HttpStatus HttpOpRequest::setupPut(HttpRequest::policy_t policy_id, -								   HttpRequest::priority_t priority,  								   const std::string & url,  								   BufferArray * body,                                     const HttpOptions::ptr_t & options,  								   const HttpHeaders::ptr_t & headers)  { -	setupCommon(policy_id, priority, url, body, options, headers); +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; +	setupCommon(policy_id, url, body, options, headers);  	mReqMethod = HOR_PUT;  	return HttpStatus(); @@ -363,12 +368,12 @@ HttpStatus HttpOpRequest::setupPut(HttpRequest::policy_t policy_id,  HttpStatus HttpOpRequest::setupDelete(HttpRequest::policy_t policy_id, -    HttpRequest::priority_t priority,      const std::string & url,      const HttpOptions::ptr_t & options,      const HttpHeaders::ptr_t & headers)  { -    setupCommon(policy_id, priority, url, NULL, options, headers); +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; +    setupCommon(policy_id, url, NULL, options, headers);      mReqMethod = HOR_DELETE;      return HttpStatus(); @@ -376,13 +381,13 @@ HttpStatus HttpOpRequest::setupDelete(HttpRequest::policy_t policy_id,  HttpStatus HttpOpRequest::setupPatch(HttpRequest::policy_t policy_id, -    HttpRequest::priority_t priority,      const std::string & url,      BufferArray * body,      const HttpOptions::ptr_t & options,      const HttpHeaders::ptr_t & headers)  { -    setupCommon(policy_id, priority, url, body, options, headers); +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; +    setupCommon(policy_id, url, body, options, headers);      mReqMethod = HOR_PATCH;      return HttpStatus(); @@ -390,12 +395,12 @@ HttpStatus HttpOpRequest::setupPatch(HttpRequest::policy_t policy_id,  HttpStatus HttpOpRequest::setupCopy(HttpRequest::policy_t policy_id, -    HttpRequest::priority_t priority,      const std::string & url,      const HttpOptions::ptr_t & options,      const HttpHeaders::ptr_t &headers)  { -    setupCommon(policy_id, priority, url, NULL, options, headers); +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; +    setupCommon(policy_id, url, NULL, options, headers);      mReqMethod = HOR_COPY;      return HttpStatus(); @@ -403,12 +408,12 @@ HttpStatus HttpOpRequest::setupCopy(HttpRequest::policy_t policy_id,  HttpStatus HttpOpRequest::setupMove(HttpRequest::policy_t policy_id, -    HttpRequest::priority_t priority,      const std::string & url,      const HttpOptions::ptr_t & options,      const HttpHeaders::ptr_t &headers)  { -    setupCommon(policy_id, priority, url, NULL, options, headers); +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; +    setupCommon(policy_id, url, NULL, options, headers);      mReqMethod = HOR_MOVE;      return HttpStatus(); @@ -416,15 +421,14 @@ HttpStatus HttpOpRequest::setupMove(HttpRequest::policy_t policy_id,  void HttpOpRequest::setupCommon(HttpRequest::policy_t policy_id, -								HttpRequest::priority_t priority,  								const std::string & url,  								BufferArray * body,                                  const HttpOptions::ptr_t & options,  								const HttpHeaders::ptr_t & headers)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	mProcFlags = 0U;  	mReqPolicy = policy_id; -	mReqPriority = priority;  	mReqURL = url;  	if (body)  	{ @@ -465,6 +469,7 @@ void HttpOpRequest::setupCommon(HttpRequest::policy_t policy_id,  // *TODO:  Move this to _httplibcurl where it belongs.  HttpStatus HttpOpRequest::prepareRequest(HttpService * service)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	// Scrub transport and result data for retried op case  	mCurlActive = false;  	mCurlHandle = NULL; @@ -773,6 +778,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)  size_t HttpOpRequest::writeCallback(void * data, size_t size, size_t nmemb, void * userdata)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;      HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata));  	if (! op->mReplyBody) @@ -788,6 +794,7 @@ size_t HttpOpRequest::writeCallback(void * data, size_t size, size_t nmemb, void  size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void * userdata)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;      HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata));  	if (! op->mReqBody) @@ -819,6 +826,7 @@ size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void  int HttpOpRequest::seekCallback(void *userdata, curl_off_t offset, int origin)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;      HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata));      if (!op->mReqBody) @@ -850,6 +858,7 @@ int HttpOpRequest::seekCallback(void *userdata, curl_off_t offset, int origin)  size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, void * userdata)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	static const char status_line[] = "HTTP/";  	static const size_t status_line_len = sizeof(status_line) - 1;  	static const char con_ran_line[] = "content-range"; @@ -999,6 +1008,7 @@ size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, voi  CURLcode HttpOpRequest::curlSslCtxCallback(CURL *curl, void *sslctx, void *userdata)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;      HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata));      if (op->mCallbackSSLVerify) @@ -1025,6 +1035,7 @@ CURLcode HttpOpRequest::curlSslCtxCallback(CURL *curl, void *sslctx, void *userd  int HttpOpRequest::sslCertVerifyCallback(X509_STORE_CTX *ctx, void *param)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;      HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(param));  	if (op->mCallbackSSLVerify) @@ -1037,6 +1048,7 @@ int HttpOpRequest::sslCertVerifyCallback(X509_STORE_CTX *ctx, void *param)  int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffer, size_t len, void * userdata)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;      HttpOpRequest::ptr_t op(HttpOpRequest::fromHandle<HttpOpRequest>(userdata));  	std::string safe_line; diff --git a/indra/llcorehttp/_httpoprequest.h b/indra/llcorehttp/_httpoprequest.h index cdbe350785..ec84822cf4 100644 --- a/indra/llcorehttp/_httpoprequest.h +++ b/indra/llcorehttp/_httpoprequest.h @@ -105,13 +105,11 @@ public:  	/// Threading:  called by application thread  	///  	HttpStatus setupGet(HttpRequest::policy_t policy_id, -						HttpRequest::priority_t priority,  						const std::string & url,  						const HttpOptions::ptr_t & options,  						const HttpHeaders::ptr_t & headers);  	HttpStatus setupGetByteRange(HttpRequest::policy_t policy_id, -								 HttpRequest::priority_t priority,  								 const std::string & url,  								 size_t offset,  								 size_t len, @@ -119,40 +117,34 @@ public:  								 const HttpHeaders::ptr_t & headers);  	HttpStatus setupPost(HttpRequest::policy_t policy_id, -						 HttpRequest::priority_t priority,  						 const std::string & url,  						 BufferArray * body,                           const HttpOptions::ptr_t & options,  						 const HttpHeaders::ptr_t & headers);  	HttpStatus setupPut(HttpRequest::policy_t policy_id, -						HttpRequest::priority_t priority,  						const std::string & url,  						BufferArray * body,                          const HttpOptions::ptr_t & options,  						const HttpHeaders::ptr_t & headers);      HttpStatus setupDelete(HttpRequest::policy_t policy_id, -                        HttpRequest::priority_t priority,                          const std::string & url,                          const HttpOptions::ptr_t & options,                          const HttpHeaders::ptr_t & headers);      HttpStatus setupPatch(HttpRequest::policy_t policy_id, -                        HttpRequest::priority_t priority,                          const std::string & url,                          BufferArray * body,                          const HttpOptions::ptr_t & options,                          const HttpHeaders::ptr_t & headers);      HttpStatus setupCopy(HttpRequest::policy_t policy_id, -                        HttpRequest::priority_t priority,                          const std::string & url,                          const HttpOptions::ptr_t & options,                          const HttpHeaders::ptr_t & headers);      HttpStatus setupMove(HttpRequest::policy_t policy_id, -                        HttpRequest::priority_t priority,                          const std::string & url,                          const HttpOptions::ptr_t & options,                          const HttpHeaders::ptr_t & headers); @@ -172,7 +164,6 @@ protected:  	// Threading:  called by application thread  	//  	void setupCommon(HttpRequest::policy_t policy_id, -					 HttpRequest::priority_t priority,  					 const std::string & url,  					 BufferArray * body,                       const HttpOptions::ptr_t & options, @@ -239,19 +230,6 @@ public: -/// HttpOpRequestCompare isn't an operation but a uniform comparison -/// functor for STL containers that order by priority.  Mainly -/// used for the ready queue container but defined here. -class HttpOpRequestCompare -{ -public: -	bool operator()(const HttpOpRequest * lhs, const HttpOpRequest * rhs) -		{ -			return lhs->mReqPriority > rhs->mReqPriority; -		} -};  // end class HttpOpRequestCompare - -  // ---------------------------------------  // Free functions  // --------------------------------------- diff --git a/indra/llcorehttp/_httpopsetpriority.cpp b/indra/llcorehttp/_httpopsetpriority.cpp index d48c7a0b7d..b99b4e9e4a 100644 --- a/indra/llcorehttp/_httpopsetpriority.cpp +++ b/indra/llcorehttp/_httpopsetpriority.cpp @@ -24,6 +24,7 @@   * $/LicenseInfo$   */ +#if 0 // DEPRECATED  #include "_httpopsetpriority.h"  #include "httpresponse.h" @@ -61,3 +62,5 @@ void HttpOpSetPriority::stageFromRequest(HttpService * service)  }   // end namespace LLCore + +#endif diff --git a/indra/llcorehttp/_httpopsetpriority.h b/indra/llcorehttp/_httpopsetpriority.h index 43e2aa081b..fd543f37cc 100644 --- a/indra/llcorehttp/_httpopsetpriority.h +++ b/indra/llcorehttp/_httpopsetpriority.h @@ -27,7 +27,7 @@  #ifndef	_LLCORE_HTTP_SETPRIORITY_H_  #define	_LLCORE_HTTP_SETPRIORITY_H_ - +#if 0 // DEPRECATED  #include "httpcommon.h"  #include "httprequest.h"  #include "_httpoperation.h" @@ -49,7 +49,7 @@ namespace LLCore  class HttpOpSetPriority : public HttpOperation  {  public: -	HttpOpSetPriority(HttpHandle handle, HttpRequest::priority_t priority); +	HttpOpSetPriority(HttpHandle handle);  	virtual ~HttpOpSetPriority(); @@ -63,10 +63,10 @@ public:  protected:  	// Request Data  	HttpHandle					mHandle; -	HttpRequest::priority_t		mPriority;  }; // end class HttpOpSetPriority  }  // end namespace LLCore +#endif  #endif	// _LLCORE_HTTP_SETPRIORITY_H_ diff --git a/indra/llcorehttp/_httppolicy.cpp b/indra/llcorehttp/_httppolicy.cpp index 885f0ed61d..29f50c1693 100644 --- a/indra/llcorehttp/_httppolicy.cpp +++ b/indra/llcorehttp/_httppolicy.cpp @@ -330,37 +330,6 @@ HttpService::ELoopSpeed HttpPolicy::processReadyQueue()  	return result;  } - -bool HttpPolicy::changePriority(HttpHandle handle, HttpRequest::priority_t priority) -{ -	for (int policy_class(0); policy_class < mClasses.size(); ++policy_class) -	{ -		ClassState & state(*mClasses[policy_class]); -		// We don't scan retry queue because a priority change there -		// is meaningless.  The request will be issued based on retry -		// intervals not priority value, which is now moot. -		 -		// Scan ready queue for requests that match policy -		HttpReadyQueue::container_type & c(state.mReadyQueue.get_container()); -		for (HttpReadyQueue::container_type::iterator iter(c.begin()); c.end() != iter;) -		{ -			HttpReadyQueue::container_type::iterator cur(iter++); - -			if ((*cur)->getHandle() == handle) -			{ -				HttpOpRequest::ptr_t op(*cur); -				c.erase(cur);									// All iterators are now invalidated -				op->mReqPriority = priority; -				state.mReadyQueue.push(op);						// Re-insert using adapter class -				return true; -			} -		} -	} -	 -	return false; -} - -  bool HttpPolicy::cancel(HttpHandle handle)  {  	for (int policy_class(0); policy_class < mClasses.size(); ++policy_class) diff --git a/indra/llcorehttp/_httppolicy.h b/indra/llcorehttp/_httppolicy.h index 3c4126e14b..0b8806a3e2 100644 --- a/indra/llcorehttp/_httppolicy.h +++ b/indra/llcorehttp/_httppolicy.h @@ -110,12 +110,6 @@ public:  	/// Threading:  called by worker thread      void retryOp(const opReqPtr_t &); -	/// Attempt to change the priority of an earlier request. -	/// Request that Shadows HttpService's method -	/// -	/// Threading:  called by worker thread -	bool changePriority(HttpHandle handle, HttpRequest::priority_t priority); -  	/// Attempt to cancel a previous request.  	/// Shadows HttpService's method as well  	/// diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp index 56f52f1b09..294acd7f63 100644 --- a/indra/llcorehttp/_httpservice.cpp +++ b/indra/llcorehttp/_httpservice.cpp @@ -80,6 +80,7 @@ HttpService::HttpService()  HttpService::~HttpService()  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	mExitRequested = 1U;  	if (RUNNING == sState)  	{ @@ -131,6 +132,7 @@ HttpService::~HttpService()  void HttpService::init(HttpRequestQueue * queue)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	llassert_always(! sInstance);  	llassert_always(NOT_INITIALIZED == sState);  	sInstance = new HttpService(); @@ -145,6 +147,7 @@ void HttpService::init(HttpRequestQueue * queue)  void HttpService::term()  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	if (sInstance)  	{  		if (RUNNING == sState && sInstance->mThread) @@ -196,6 +199,7 @@ bool HttpService::isStopped()  /// Threading:  callable by consumer thread *once*.  void HttpService::startThread()  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	llassert_always(! mThread || STOPPED == sState);  	llassert_always(INITIALIZED == sState || STOPPED == sState); @@ -220,22 +224,6 @@ void HttpService::stopRequested()  } -/// Threading:  callable by worker thread. -bool HttpService::changePriority(HttpHandle handle, HttpRequest::priority_t priority) -{ -	bool found(false); - -	// Skip the request queue as we currently don't leave earlier -	// requests sitting there.  Start with the ready queue... -	found = mPolicy->changePriority(handle, priority); - -	// If not there, we could try the transport/active queue but priority -	// doesn't really have much effect there so we don't waste cycles. -	 -	return found; -} - -  /// Try to find the given request handle on any of the request  /// queues and cancel the operation.  /// @@ -244,6 +232,7 @@ bool HttpService::changePriority(HttpHandle handle, HttpRequest::priority_t prio  /// Threading:  callable by worker thread.  bool HttpService::cancel(HttpHandle handle)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	bool canceled(false);  	// Request can't be on request queue so skip that. @@ -264,6 +253,7 @@ bool HttpService::cancel(HttpHandle handle)  /// Threading:  callable by worker thread.  void HttpService::shutdown()  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	// Disallow future enqueue of requests  	mRequestQueue->stopQueue(); @@ -293,6 +283,8 @@ void HttpService::shutdown()  // requested to stop.  void HttpService::threadRun(LLCoreInt::HttpThread * thread)  { +    LL_PROFILER_SET_THREAD_NAME("HttpService"); +  	boost::this_thread::disable_interruption di;  	LLThread::registerThreadID(); @@ -300,6 +292,7 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread)  	ELoopSpeed loop(REQUEST_SLEEP);  	while (! mExitRequested)  	{ +        LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;          try          {  		    loop = processRequestQueue(loop); @@ -344,6 +337,7 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread)  HttpService::ELoopSpeed HttpService::processRequestQueue(ELoopSpeed loop)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	HttpRequestQueue::OpContainer ops;  	const bool wait_for_req(REQUEST_SLEEP == loop); @@ -384,6 +378,7 @@ HttpService::ELoopSpeed HttpService::processRequestQueue(ELoopSpeed loop)  HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,  										long * ret_value)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	if (opt < HttpRequest::PO_CONNECTION_LIMIT											// option must be in range  		|| opt >= HttpRequest::PO_LAST													// ditto  		|| (! sOptionDesc[opt].mIsLong)													// datatype is long @@ -416,6 +411,7 @@ HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ  HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,  										std::string * ret_value)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);  	if (opt < HttpRequest::PO_CONNECTION_LIMIT											// option must be in range @@ -443,6 +439,7 @@ HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ  HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,  	HttpRequest::policyCallback_t * ret_value)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);  	if (opt < HttpRequest::PO_CONNECTION_LIMIT											// option must be in range @@ -472,6 +469,7 @@ HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ  HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,  										long value, long * ret_value)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);  	if (opt < HttpRequest::PO_CONNECTION_LIMIT											// option must be in range @@ -517,6 +515,7 @@ HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ  HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,  										const std::string & value, std::string * ret_value)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);  	if (opt < HttpRequest::PO_CONNECTION_LIMIT											// option must be in range @@ -548,6 +547,7 @@ HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequ  HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,  	HttpRequest::policyCallback_t value, HttpRequest::policyCallback_t * ret_value)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);  	if (opt < HttpRequest::PO_CONNECTION_LIMIT											// option must be in range diff --git a/indra/llcorehttp/_httpservice.h b/indra/llcorehttp/_httpservice.h index d0c37ac195..551a718f20 100644 --- a/indra/llcorehttp/_httpservice.h +++ b/indra/llcorehttp/_httpservice.h @@ -147,15 +147,6 @@ public:  	void shutdown();  	/// Try to find the given request handle on any of the request -	/// queues and reset the priority (and queue position) of the -	/// request if found. -	/// -	/// @return			True if the request was found somewhere. -	/// -	/// Threading:  callable by worker thread. -	bool changePriority(HttpHandle handle, HttpRequest::priority_t priority); -	 -	/// Try to find the given request handle on any of the request  	/// queues and cancel the operation.  	///  	/// @return			True if the request was found and canceled. diff --git a/indra/llcorehttp/examples/http_texture_load.cpp b/indra/llcorehttp/examples/http_texture_load.cpp index c7376042b3..cc53b20add 100644 --- a/indra/llcorehttp/examples/http_texture_load.cpp +++ b/indra/llcorehttp/examples/http_texture_load.cpp @@ -469,11 +469,11 @@ bool WorkingSet::reload(LLCore::HttpRequest * hr, LLCore::HttpOptions::ptr_t & o  		LLCore::HttpHandle handle;  		if (offset || length)  		{ -			handle = hr->requestGetByteRange(0, 0, buffer, offset, length, opt, mHeaders, LLCore::HttpHandler::ptr_t(this, NoOpDeletor)); +			handle = hr->requestGetByteRange(0, buffer, offset, length, opt, mHeaders, LLCore::HttpHandler::ptr_t(this, NoOpDeletor));  		}  		else  		{ -            handle = hr->requestGet(0, 0, buffer, opt, mHeaders, LLCore::HttpHandler::ptr_t(this, NoOpDeletor)); +            handle = hr->requestGet(0, buffer, opt, mHeaders, LLCore::HttpHandler::ptr_t(this, NoOpDeletor));  		}  		if (! handle)  		{ diff --git a/indra/llcorehttp/httprequest.cpp b/indra/llcorehttp/httprequest.cpp index 2687f77217..de3854a101 100644 --- a/indra/llcorehttp/httprequest.cpp +++ b/indra/llcorehttp/httprequest.cpp @@ -32,7 +32,6 @@  #include "_httppolicy.h"  #include "_httpoperation.h"  #include "_httpoprequest.h" -#include "_httpopsetpriority.h"  #include "_httpopcancel.h"  #include "_httpopsetget.h" @@ -183,16 +182,16 @@ HttpStatus HttpRequest::getStatus() const  HttpHandle HttpRequest::requestGet(policy_t policy_id, -								   priority_t priority,  								   const std::string & url,                                     const HttpOptions::ptr_t & options,  								   const HttpHeaders::ptr_t & headers,  								   HttpHandler::ptr_t user_handler)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	HttpStatus status;  	HttpOpRequest::ptr_t op(new HttpOpRequest()); -	if (! (status = op->setupGet(policy_id, priority, url, options, headers))) +	if (! (status = op->setupGet(policy_id, url, options, headers)))  	{  		mLastReqStatus = status;          return LLCORE_HTTP_HANDLE_INVALID; @@ -210,7 +209,6 @@ HttpHandle HttpRequest::requestGet(policy_t policy_id,  HttpHandle HttpRequest::requestGetByteRange(policy_t policy_id, -											priority_t priority,  											const std::string & url,  											size_t offset,  											size_t len, @@ -218,10 +216,11 @@ HttpHandle HttpRequest::requestGetByteRange(policy_t policy_id,  											const HttpHeaders::ptr_t & headers,  											HttpHandler::ptr_t user_handler)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;  	HttpStatus status;  	HttpOpRequest::ptr_t op(new HttpOpRequest()); -	if (! (status = op->setupGetByteRange(policy_id, priority, url, offset, len, options, headers))) +	if (! (status = op->setupGetByteRange(policy_id, url, offset, len, options, headers)))  	{  		mLastReqStatus = status;          return LLCORE_HTTP_HANDLE_INVALID; @@ -239,7 +238,6 @@ HttpHandle HttpRequest::requestGetByteRange(policy_t policy_id,  HttpHandle HttpRequest::requestPost(policy_t policy_id, -									priority_t priority,  									const std::string & url,  									BufferArray * body,                                      const HttpOptions::ptr_t & options, @@ -249,7 +247,7 @@ HttpHandle HttpRequest::requestPost(policy_t policy_id,  	HttpStatus status;  	HttpOpRequest::ptr_t op(new HttpOpRequest()); -	if (! (status = op->setupPost(policy_id, priority, url, body, options, headers))) +	if (! (status = op->setupPost(policy_id, url, body, options, headers)))  	{  		mLastReqStatus = status;          return LLCORE_HTTP_HANDLE_INVALID; @@ -267,7 +265,6 @@ HttpHandle HttpRequest::requestPost(policy_t policy_id,  HttpHandle HttpRequest::requestPut(policy_t policy_id, -								   priority_t priority,  								   const std::string & url,  								   BufferArray * body,                                     const HttpOptions::ptr_t & options, @@ -277,7 +274,7 @@ HttpHandle HttpRequest::requestPut(policy_t policy_id,  	HttpStatus status;  	HttpOpRequest::ptr_t op (new HttpOpRequest()); -	if (! (status = op->setupPut(policy_id, priority, url, body, options, headers))) +	if (! (status = op->setupPut(policy_id, url, body, options, headers)))  	{  		mLastReqStatus = status;          return LLCORE_HTTP_HANDLE_INVALID; @@ -294,7 +291,6 @@ HttpHandle HttpRequest::requestPut(policy_t policy_id,  }  HttpHandle HttpRequest::requestDelete(policy_t policy_id, -    priority_t priority,      const std::string & url,      const HttpOptions::ptr_t & options,      const HttpHeaders::ptr_t & headers, @@ -303,7 +299,7 @@ HttpHandle HttpRequest::requestDelete(policy_t policy_id,      HttpStatus status;      HttpOpRequest::ptr_t op(new HttpOpRequest()); -    if (!(status = op->setupDelete(policy_id, priority, url, options, headers))) +    if (!(status = op->setupDelete(policy_id, url, options, headers)))      {          mLastReqStatus = status;          return LLCORE_HTTP_HANDLE_INVALID; @@ -320,7 +316,6 @@ HttpHandle HttpRequest::requestDelete(policy_t policy_id,  }  HttpHandle HttpRequest::requestPatch(policy_t policy_id, -    priority_t priority,      const std::string & url,      BufferArray * body,      const HttpOptions::ptr_t & options, @@ -330,7 +325,7 @@ HttpHandle HttpRequest::requestPatch(policy_t policy_id,      HttpStatus status;      HttpOpRequest::ptr_t op (new HttpOpRequest()); -    if (!(status = op->setupPatch(policy_id, priority, url, body, options, headers))) +    if (!(status = op->setupPatch(policy_id, url, body, options, headers)))      {          mLastReqStatus = status;          return LLCORE_HTTP_HANDLE_INVALID; @@ -347,7 +342,6 @@ HttpHandle HttpRequest::requestPatch(policy_t policy_id,  }  HttpHandle HttpRequest::requestCopy(policy_t policy_id, -    priority_t priority,      const std::string & url,      const HttpOptions::ptr_t & options,      const HttpHeaders::ptr_t & headers, @@ -356,7 +350,7 @@ HttpHandle HttpRequest::requestCopy(policy_t policy_id,      HttpStatus status;      HttpOpRequest::ptr_t op(new HttpOpRequest()); -    if (!(status = op->setupCopy(policy_id, priority, url, options, headers))) +    if (!(status = op->setupCopy(policy_id, url, options, headers)))      {          mLastReqStatus = status;          return LLCORE_HTTP_HANDLE_INVALID; @@ -374,7 +368,6 @@ HttpHandle HttpRequest::requestCopy(policy_t policy_id,  }  HttpHandle HttpRequest::requestMove(policy_t policy_id, -    priority_t priority,      const std::string & url,      const HttpOptions::ptr_t & options,      const HttpHeaders::ptr_t & headers, @@ -383,7 +376,7 @@ HttpHandle HttpRequest::requestMove(policy_t policy_id,      HttpStatus status;      HttpOpRequest::ptr_t op (new HttpOpRequest()); -    if (!(status = op->setupMove(policy_id, priority, url, options, headers))) +    if (!(status = op->setupMove(policy_id, url, options, headers)))      {          mLastReqStatus = status;          return LLCORE_HTTP_HANDLE_INVALID; @@ -483,24 +476,6 @@ HttpHandle HttpRequest::requestCancel(HttpHandle request, HttpHandler::ptr_t use  } -HttpHandle HttpRequest::requestSetPriority(HttpHandle request, priority_t priority, -										   HttpHandler::ptr_t handler) -{ -	HttpStatus status; - -	HttpOperation::ptr_t op (new HttpOpSetPriority(request, priority)); -	op->setReplyPath(mReplyQueue, handler); -	if (! (status = mRequestQueue->addOp(op)))			// transfers refcount -	{ -		mLastReqStatus = status; -        return LLCORE_HTTP_HANDLE_INVALID; -	} - -	mLastReqStatus = status; -	return op->getHandle(); -} - -  // ====================================  // Utility Methods  // ==================================== diff --git a/indra/llcorehttp/httprequest.h b/indra/llcorehttp/httprequest.h index a418eb6a7a..ca4b9e92bc 100644 --- a/indra/llcorehttp/httprequest.h +++ b/indra/llcorehttp/httprequest.h @@ -95,7 +95,6 @@ private:  public:  	typedef unsigned int policy_t; -	typedef unsigned int priority_t;  	typedef boost::shared_ptr<HttpRequest> ptr_t;      typedef boost::weak_ptr<HttpRequest>   wptr_t; @@ -316,8 +315,6 @@ public:  	///  	/// @param	policy_id		Default or user-defined policy class under  	///							which this request is to be serviced. -	/// @param	priority		Standard priority scheme inherited from -	///							Indra code base (U32-type scheme).  	/// @param	url				URL with any encoded query parameters to  	///							be accessed.  	/// @param	options			Optional instance of an HttpOptions object @@ -346,7 +343,6 @@ public:  	///							case, @see getStatus() will return more info.  	///  	HttpHandle requestGet(policy_t policy_id, -						  priority_t priority,  						  const std::string & url,                            const HttpOptions::ptr_t & options,  						  const HttpHeaders::ptr_t & headers, @@ -377,7 +373,6 @@ public:  	/// - Referer:  	///  	/// @param	policy_id		@see requestGet() -	/// @param	priority		"  	/// @param	url				"  	/// @param	offset			Offset of first byte into resource to be returned.  	/// @param	len				Count of bytes to be returned @@ -387,7 +382,6 @@ public:  	/// @return					"  	///  	HttpHandle requestGetByteRange(policy_t policy_id, -								   priority_t priority,  								   const std::string & url,  								   size_t offset,  								   size_t len, @@ -418,7 +412,6 @@ public:  	/// - Expect:  	///  	/// @param	policy_id		@see requestGet() -	/// @param	priority		"  	/// @param	url				"  	/// @param	body			Byte stream to be sent as the body.  No  	///							further encoding or escaping will be done @@ -429,7 +422,6 @@ public:  	/// @return					"  	///  	HttpHandle requestPost(policy_t policy_id, -						   priority_t priority,  						   const std::string & url,  						   BufferArray * body,                             const HttpOptions::ptr_t & options, @@ -459,7 +451,6 @@ public:  	/// - Content-Type:  	///  	/// @param	policy_id		@see requestGet() -	/// @param	priority		"  	/// @param	url				"  	/// @param	body			Byte stream to be sent as the body.  No  	///							further encoding or escaping will be done @@ -470,7 +461,6 @@ public:  	/// @return					"  	///  	HttpHandle requestPut(policy_t policy_id, -						  priority_t priority,  						  const std::string & url,  						  BufferArray * body,                            const HttpOptions::ptr_t & options, @@ -483,7 +473,6 @@ public:      /// encoding and communicating the content types.      ///      /// @param	policy_id		@see requestGet() -    /// @param	priority		"      /// @param	url				"      /// @param	options			@see requestGet()K(optional)      /// @param	headers			" @@ -491,7 +480,6 @@ public:      /// @return					"      ///      HttpHandle requestDelete(policy_t policy_id, -            priority_t priority,              const std::string & url,              const HttpOptions::ptr_t & options,              const HttpHeaders::ptr_t & headers, @@ -502,7 +490,6 @@ public:      /// encoding and communicating the content types.      ///      /// @param	policy_id		@see requestGet() -    /// @param	priority		"      /// @param	url				"      /// @param	body			Byte stream to be sent as the body.  No      ///							further encoding or escaping will be done @@ -513,7 +500,6 @@ public:      /// @return					"      ///      HttpHandle requestPatch(policy_t policy_id, -            priority_t priority,              const std::string & url,              BufferArray * body,              const HttpOptions::ptr_t & options, @@ -525,7 +511,6 @@ public:      /// encoding and communicating the content types.      ///      /// @param	policy_id		@see requestGet() -    /// @param	priority		"      /// @param	url				"      /// @param	options			@see requestGet()K(optional)      /// @param	headers			" @@ -533,7 +518,6 @@ public:      /// @return					"      ///      HttpHandle requestCopy(policy_t policy_id, -            priority_t priority,              const std::string & url,              const HttpOptions::ptr_t & options,              const HttpHeaders::ptr_t & headers, @@ -544,7 +528,6 @@ public:      /// encoding and communicating the content types.      ///      /// @param	policy_id		@see requestGet() -    /// @param	priority		"      /// @param	url				"      /// @param	options			@see requestGet()K(optional)      /// @param	headers			" @@ -552,7 +535,6 @@ public:      /// @return					"      ///      HttpHandle requestMove(policy_t policy_id, -            priority_t priority,              const std::string & url,              const HttpOptions::ptr_t & options,              const HttpHeaders::ptr_t & headers, @@ -593,18 +575,6 @@ public:  	HttpHandle requestCancel(HttpHandle request, HttpHandler::ptr_t); -	/// Request that a previously-issued request be reprioritized. -	/// The status of whether the change itself succeeded arrives -	/// via notification.   -	/// -	/// @param	request			Handle of previously-issued request to -	///							be changed. -	/// @param	priority		New priority value. -	/// @param	handler			@see requestGet() -	/// @return					" -	/// -	HttpHandle requestSetPriority(HttpHandle request, priority_t priority, HttpHandler::ptr_t handler); -  	/// @}  	/// @name UtilityMethods diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/test_httprequest.hpp index 154f6b12e9..3eaac10aeb 100644 --- a/indra/llcorehttp/tests/test_httprequest.hpp +++ b/indra/llcorehttp/tests/test_httprequest.hpp @@ -614,7 +614,6 @@ void HttpRequestTestObjectType::test<7>()  		// Issue a GET that can't connect  		mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT);  		HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, -													 0U,  													 "http://127.0.0.1:2/nothing/here",  													 0,  													 0, @@ -716,7 +715,6 @@ void HttpRequestTestObjectType::test<8>()  		// Issue a GET that *can* connect  		mStatus = HttpStatus(200);  		HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, -											0U,  											url_base,  											HttpOptions::ptr_t(),                                              HttpHeaders::ptr_t(), @@ -812,7 +810,6 @@ void HttpRequestTestObjectType::test<9>()  		// Issue a GET that *can* connect  		mStatus = HttpStatus(200);  		HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, -													 0U,  													 url_base,  													 0,  													 0, @@ -913,7 +910,6 @@ void HttpRequestTestObjectType::test<10>()  		body->append(body_text, strlen(body_text));  		mStatus = HttpStatus(200);  		HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID, -											0U,  											url_base,  											body,                                              HttpOptions::ptr_t(), @@ -1020,7 +1016,6 @@ void HttpRequestTestObjectType::test<11>()  		body->append(body_text, strlen(body_text));  		mStatus = HttpStatus(200);  		HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID, -											 0U,  											 url_base,  											 body,                                               HttpOptions::ptr_t(), @@ -1127,7 +1122,6 @@ void HttpRequestTestObjectType::test<12>()  		// Issue a GET that *can* connect  		mStatus = HttpStatus(200);  		HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, -													 0U,  													 url_base,  													 0,  													 0, @@ -1240,7 +1234,6 @@ void HttpRequestTestObjectType::test<13>()  			regex_container_t::value_type(boost::regex("X-LL-Special", boost::regex::icase),  										  boost::regex(".*", boost::regex::icase)));  		HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, -													 0U,  													 url_base,  													 0,	  												 0, @@ -1346,7 +1339,6 @@ void HttpRequestTestObjectType::test<14>()  		// Issue a GET that sleeps  		mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT);  		HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, -													 0U,  													 url_base,  													 0,  													 0, @@ -1454,7 +1446,6 @@ void HttpRequestTestObjectType::test<15>()  		mStatus = HttpStatus(200);  		handler.mCheckContentType = "application/llsd+xml";  		HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, -											0U,  											url_base,                                              HttpOptions::ptr_t(),                                              HttpHeaders::ptr_t(), @@ -1609,7 +1600,6 @@ void HttpRequestTestObjectType::test<16>()  				boost::regex("X-Reflect-content-encoding", boost::regex::icase),  				boost::regex(".*", boost::regex::icase)));  		HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, -											0U,  											url_base + "reflect/",  											options,  											HttpHeaders::ptr_t(), @@ -1684,7 +1674,6 @@ void HttpRequestTestObjectType::test<16>()  				boost::regex("X-Reflect-content-encoding", boost::regex::icase),  				boost::regex(".*", boost::regex::icase)));  		handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, -										  0U,  										  url_base + "reflect/",  										  0,  										  47, @@ -1863,7 +1852,6 @@ void HttpRequestTestObjectType::test<17>()  				boost::regex("X-Reflect-transfer_encoding", boost::regex::icase),  				boost::regex(".*chunked.*", boost::regex::icase)));  		HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID, -											 0U,  											 url_base + "reflect/",  											 ba,  											 options, @@ -2049,7 +2037,6 @@ void HttpRequestTestObjectType::test<18>()  				boost::regex(".*", boost::regex::icase)));  		HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID, -											0U,  											url_base + "reflect/",  											ba,  											options, @@ -2249,7 +2236,6 @@ void HttpRequestTestObjectType::test<19>()  				boost::regex("X-Reflect-content-encoding", boost::regex::icase),  				boost::regex(".*", boost::regex::icase)));  		HttpHandle handle = req->requestGet(HttpRequest::DEFAULT_POLICY_ID, -											0U,  											url_base + "reflect/",  											options,  											headers, @@ -2457,7 +2443,6 @@ void HttpRequestTestObjectType::test<20>()  				boost::regex(".*", boost::regex::icase)));  		HttpHandle handle = req->requestPost(HttpRequest::DEFAULT_POLICY_ID, -											 0U,  											 url_base + "reflect/",  											 ba,  											 options, @@ -2666,7 +2651,6 @@ void HttpRequestTestObjectType::test<21>()  				boost::regex("X-Reflect-content-type", boost::regex::icase),  				boost::regex("text/html", boost::regex::icase)));  		HttpHandle handle = req->requestPut(HttpRequest::DEFAULT_POLICY_ID, -											0U,  											url_base + "reflect/",  											ba,  											options, @@ -2797,7 +2781,6 @@ void HttpRequestTestObjectType::test<22>()  			char buffer[128];  			sprintf(buffer, "/bug2295/%d/", i);  			HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, -														 0U,  														 url_base + buffer,  														 0,  														 25, @@ -2829,7 +2812,6 @@ void HttpRequestTestObjectType::test<22>()  			char buffer[128];  			sprintf(buffer, "/bug2295/00000012/%d/", i);  			HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, -														 0U,  														 url_base + buffer,  														 0,  														 25, @@ -2861,7 +2843,6 @@ void HttpRequestTestObjectType::test<22>()  			char buffer[128];  			sprintf(buffer, "/bug2295/inv_cont_range/%d/", i);  			HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, -														 0U,  														 url_base + buffer,  														 0,  														 25, @@ -2984,7 +2965,6 @@ void HttpRequestTestObjectType::test<23>()  			std::ostringstream url;  			url << url_base << i << "/";  			HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, -														 0U,  														 url.str(),  														 0,  														 0, diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp index 0d8fb4863b..bb603d3d7f 100644 --- a/indra/llcrashlogger/llcrashlogger.cpp +++ b/indra/llcrashlogger/llcrashlogger.cpp @@ -418,7 +418,7 @@ bool LLCrashLogger::runCrashLogPost(std::string host, LLSD data, std::string msg  		updateApplication(llformat("%s, try %d...", msg.c_str(), i+1));          LL_INFOS("CRASHREPORT") << "POST crash data to " << host << LL_ENDL; -        LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(httpRequest.get(), LLCore::HttpRequest::DEFAULT_POLICY_ID, 0, +        LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(httpRequest.get(), LLCore::HttpRequest::DEFAULT_POLICY_ID,              host, data, httpOpts, LLCore::HttpHeaders::ptr_t(), LLCore::HttpHandler::ptr_t(new LLCrashLoggerHandler));          if (handle == LLCORE_HTTP_HANDLE_INVALID) diff --git a/indra/llfilesystem/lllfsthread.cpp b/indra/llfilesystem/lllfsthread.cpp index be8e83a56f..dbb69cd605 100644 --- a/indra/llfilesystem/lllfsthread.cpp +++ b/indra/llfilesystem/lllfsthread.cpp @@ -45,8 +45,7 @@ void LLLFSThread::initClass(bool local_is_threaded)  //static  S32 LLLFSThread::updateClass(U32 ms_elapsed)  { -	sLocal->update((F32)ms_elapsed); -	return sLocal->getPending(); +	return sLocal->update((F32)ms_elapsed);  }  //static @@ -58,6 +57,7 @@ void LLLFSThread::cleanupClass()  	{  		sLocal->update(0);  	} +    sLocal->shutdown();  	delete sLocal;  	sLocal = NULL;  } @@ -65,8 +65,7 @@ void LLLFSThread::cleanupClass()  //----------------------------------------------------------------------------  LLLFSThread::LLLFSThread(bool threaded) : -	LLQueuedThread("LFS", threaded), -	mPriorityCounter(PRIORITY_LOWBITS) +	LLQueuedThread("LFS", threaded)  {  	if(!mLocalAPRFilePoolp)  	{ @@ -84,14 +83,12 @@ LLLFSThread::~LLLFSThread()  LLLFSThread::handle_t LLLFSThread::read(const std::string& filename,	/* Flawfinder: ignore */   										U8* buffer, S32 offset, S32 numbytes, -										Responder* responder, U32 priority) +										Responder* responder)  { +    LL_PROFILE_ZONE_SCOPED;  	handle_t handle = generateHandle(); -	if (priority == 0) priority = PRIORITY_NORMAL | priorityCounter(); -	else if (priority < PRIORITY_LOW) priority |= PRIORITY_LOW; // All reads are at least PRIORITY_LOW - -	Request* req = new Request(this, handle, priority, +	Request* req = new Request(this, handle,  							   FILE_READ, filename,  							   buffer, offset, numbytes,  							   responder); @@ -107,13 +104,12 @@ LLLFSThread::handle_t LLLFSThread::read(const std::string& filename,	/* Flawfind  LLLFSThread::handle_t LLLFSThread::write(const std::string& filename,  										 U8* buffer, S32 offset, S32 numbytes, -										 Responder* responder, U32 priority) +										 Responder* responder)  { +    LL_PROFILE_ZONE_SCOPED;  	handle_t handle = generateHandle(); -	if (priority == 0) priority = PRIORITY_LOW | priorityCounter(); -	 -	Request* req = new Request(this, handle, priority, +	Request* req = new Request(this, handle,  							   FILE_WRITE, filename,  							   buffer, offset, numbytes,  							   responder); @@ -130,11 +126,11 @@ LLLFSThread::handle_t LLLFSThread::write(const std::string& filename,  //============================================================================  LLLFSThread::Request::Request(LLLFSThread* thread, -							  handle_t handle, U32 priority, +							  handle_t handle,  							  operation_t op, const std::string& filename,  							  U8* buffer, S32 offset, S32 numbytes,  							  Responder* responder) : -	QueuedRequest(handle, priority, FLAG_AUTO_COMPLETE), +	QueuedRequest(handle, FLAG_AUTO_COMPLETE),  	mThread(thread),  	mOperation(op),  	mFileName(filename), @@ -157,6 +153,7 @@ LLLFSThread::Request::~Request()  // virtual, called from own thread  void LLLFSThread::Request::finishRequest(bool completed)  { +    LL_PROFILE_ZONE_SCOPED;  	if (mResponder.notNull())  	{  		mResponder->completed(completed ? mBytesRead : 0); @@ -166,6 +163,7 @@ void LLLFSThread::Request::finishRequest(bool completed)  void LLLFSThread::Request::deleteRequest()  { +    LL_PROFILE_ZONE_SCOPED;  	if (getStatus() == STATUS_QUEUED)  	{  		LL_ERRS() << "Attempt to delete a queued LLLFSThread::Request!" << LL_ENDL; @@ -180,6 +178,7 @@ void LLLFSThread::Request::deleteRequest()  bool LLLFSThread::Request::processRequest()  { +    LL_PROFILE_ZONE_SCOPED;  	bool complete = false;  	if (mOperation ==  FILE_READ)  	{ diff --git a/indra/llfilesystem/lllfsthread.h b/indra/llfilesystem/lllfsthread.h index 58f658f7ba..f2693a1172 100644 --- a/indra/llfilesystem/lllfsthread.h +++ b/indra/llfilesystem/lllfsthread.h @@ -68,7 +68,7 @@ public:  	public:  		Request(LLLFSThread* thread, -				handle_t handle, U32 priority,  +				handle_t handle,  				operation_t op, const std::string& filename,  				U8* buffer, S32 offset, S32 numbytes,  				Responder* responder); @@ -120,22 +120,15 @@ public:  	// Return a Request handle  	handle_t read(const std::string& filename,	/* Flawfinder: ignore */   				  U8* buffer, S32 offset, S32 numbytes, -				  Responder* responder, U32 pri=0); +				  Responder* responder);  	handle_t write(const std::string& filename,  				   U8* buffer, S32 offset, S32 numbytes, -				   Responder* responder, U32 pri=0); -	 -	// Misc -	U32 priorityCounter() { return mPriorityCounter-- & PRIORITY_LOWBITS; } // Use to order IO operations +				   Responder* responder);  	// static initializers  	static void initClass(bool local_is_threaded = TRUE); // Setup sLocal  	static S32 updateClass(U32 ms_elapsed);  	static void cleanupClass();		// Delete sLocal - -	 -private: -	U32 mPriorityCounter;  public:  	static LLLFSThread* sLocal;		// Default local file thread diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index ad7124b5aa..186b01d60c 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -798,7 +798,6 @@ U8* LLImageBase::allocateDataSize(S32 width, S32 height, S32 ncomponents, S32 si  // LLImageRaw  //--------------------------------------------------------------------------- -S32 LLImageRaw::sGlobalRawMemory = 0;  S32 LLImageRaw::sRawImageCount = 0;  LLImageRaw::LLImageRaw() @@ -856,16 +855,13 @@ LLImageRaw::~LLImageRaw()  U8* LLImageRaw::allocateData(S32 size)  {  	U8* res = LLImageBase::allocateData(size); -	sGlobalRawMemory += getDataSize();  	return res;  }  // virtual  U8* LLImageRaw::reallocateData(S32 size)  { -	sGlobalRawMemory -= getDataSize();  	U8* res = LLImageBase::reallocateData(size); -	sGlobalRawMemory += getDataSize();  	return res;  } @@ -878,7 +874,6 @@ void LLImageRaw::releaseData()  // virtual  void LLImageRaw::deleteData()  { -	sGlobalRawMemory -= getDataSize();  	LLImageBase::deleteData();  } diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 59c192d9f8..9e50fd502b 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -276,7 +276,6 @@ protected:  	void setDataAndSize(U8 *data, S32 width, S32 height, S8 components) ;  public: -	static S32 sGlobalRawMemory;  	static S32 sRawImageCount;  private: diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index e1809dbe59..8dba1641a6 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -146,6 +146,7 @@ bool LLImageJ2C::initEncode(LLImageRaw &raw_image, int blocks_size, int precinct  bool LLImageJ2C::decode(LLImageRaw *raw_imagep, F32 decode_time)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	return decodeChannels(raw_imagep, decode_time, 0, 4);  } @@ -153,6 +154,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 )  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	LLTimer elapsed;  	bool res = true; diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp index 0dbb744bcf..0093958e6d 100644 --- a/indra/llimage/llimageworker.cpp +++ b/indra/llimage/llimageworker.cpp @@ -28,64 +28,88 @@  #include "llimageworker.h"  #include "llimagedxt.h" +#include "threadpool.h" + +/*--------------------------------------------------------------------------*/ +class ImageRequest +{ +public: +	ImageRequest(const LLPointer<LLImageFormatted>& image, +				 S32 discard, BOOL needs_aux, +				 const LLPointer<LLImageDecodeThread::Responder>& responder); +	virtual ~ImageRequest(); + +	/*virtual*/ bool processRequest(); +	/*virtual*/ void finishRequest(bool completed); + +private: +	// LLPointers stored in ImageRequest MUST be LLPointer instances rather +	// than references: we need to increment the refcount when storing these. +	// input +	LLPointer<LLImageFormatted> mFormattedImage; +	S32 mDiscardLevel; +	BOOL mNeedsAux; +	// output +	LLPointer<LLImageRaw> mDecodedImageRaw; +	LLPointer<LLImageRaw> mDecodedImageAux; +	BOOL mDecodedRaw; +	BOOL mDecodedAux; +	LLPointer<LLImageDecodeThread::Responder> mResponder; +}; +  //----------------------------------------------------------------------------  // MAIN THREAD -LLImageDecodeThread::LLImageDecodeThread(bool threaded) -	: LLQueuedThread("imagedecode", threaded) +LLImageDecodeThread::LLImageDecodeThread(bool /*threaded*/)  { -	mCreationMutex = new LLMutex(); +    mThreadPool.reset(new LL::ThreadPool("ImageDecode", 8)); +    mThreadPool->start();  }  //virtual   LLImageDecodeThread::~LLImageDecodeThread() -{ -	delete mCreationMutex ; -} +{}  // MAIN THREAD  // virtual  S32 LLImageDecodeThread::update(F32 max_time_ms)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; -	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); +    return getPending(); +} -		bool res = addRequest(req); -		if (!res) -		{ -			LL_ERRS() << "request added after LLLFSThread::cleanupClass()" << LL_ENDL; -		} -	} -	mCreationList.clear(); -	S32 res = LLQueuedThread::update(max_time_ms); -	return res; +S32 LLImageDecodeThread::getPending() +{ +    return mThreadPool->getQueue().size();  } -LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image,  -	U32 priority, S32 discard, BOOL needs_aux, Responder* responder) +LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage( +    const LLPointer<LLImageFormatted>& image,  +    S32 discard, +    BOOL needs_aux, +    const LLPointer<LLImageDecodeThread::Responder>& responder)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; -	LLMutexLock lock(mCreationMutex); -	handle_t handle = generateHandle(); -	mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder)); -	return handle; + +    // Instantiate the ImageRequest right in the lambda, why not? +    mThreadPool->getQueue().post( +        [req = ImageRequest(image, discard, needs_aux, responder)] +        () mutable +        { +            auto done = req.processRequest(); +            req.finishRequest(done); +        }); + +    // It's important to our consumer (LLTextureFetchWorker) that we return a +    // nonzero handle. It is NOT important that the nonzero handle be unique: +    // nothing is ever done with it except to compare it to zero, or zero it. +    return 17;  } -// Used by unit test only -// Returns the size of the mutex guarded list as an indication of sanity -S32 LLImageDecodeThread::tut_size() +void LLImageDecodeThread::shutdown()  { -	LLMutexLock lock(mCreationMutex); -	S32 res = mCreationList.size(); -	return res; +    mThreadPool->close();  }  LLImageDecodeThread::Responder::~Responder() @@ -94,11 +118,10 @@ LLImageDecodeThread::Responder::~Responder()  //---------------------------------------------------------------------------- -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), +ImageRequest::ImageRequest(const LLPointer<LLImageFormatted>& image,  +							S32 discard, BOOL needs_aux, +							const LLPointer<LLImageDecodeThread::Responder>& responder) +	: mFormattedImage(image),  	  mDiscardLevel(discard),  	  mNeedsAux(needs_aux),  	  mDecodedRaw(FALSE), @@ -107,7 +130,7 @@ LLImageDecodeThread::ImageRequest::ImageRequest(handle_t handle, LLImageFormatte  {  } -LLImageDecodeThread::ImageRequest::~ImageRequest() +ImageRequest::~ImageRequest()  {  	mDecodedImageRaw = NULL;  	mDecodedImageAux = NULL; @@ -118,10 +141,10 @@ LLImageDecodeThread::ImageRequest::~ImageRequest()  // Returns true when done, whether or not decode was successful. -bool LLImageDecodeThread::ImageRequest::processRequest() +bool ImageRequest::processRequest()  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; -	const F32 decode_time_slice = .1f; +	const F32 decode_time_slice = 0.f; //disable time slicing  	bool done = true;  	if (!mDecodedRaw && mFormattedImage.notNull())  	{ @@ -145,7 +168,7 @@ bool LLImageDecodeThread::ImageRequest::processRequest()  											  mFormattedImage->getHeight(),  											  mFormattedImage->getComponents());  		} -		done = mFormattedImage->decode(mDecodedImageRaw, decode_time_slice); // 1ms +		done = mFormattedImage->decode(mDecodedImageRaw, decode_time_slice);  		// some decoders are removing data when task is complete and there were errors  		mDecodedRaw = done && mDecodedImageRaw->getData();  	} @@ -158,14 +181,14 @@ bool LLImageDecodeThread::ImageRequest::processRequest()  											  mFormattedImage->getHeight(),  											  1);  		} -		done = mFormattedImage->decodeChannels(mDecodedImageAux, decode_time_slice, 4, 4); // 1ms +		done = mFormattedImage->decodeChannels(mDecodedImageAux, decode_time_slice, 4, 4);  		mDecodedAux = done && mDecodedImageAux->getData();  	}  	return done;  } -void LLImageDecodeThread::ImageRequest::finishRequest(bool completed) +void ImageRequest::finishRequest(bool completed)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	if (mResponder.notNull()) @@ -175,10 +198,3 @@ void LLImageDecodeThread::ImageRequest::finishRequest(bool completed)  	}  	// 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(); -} diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h index 1bfb0ddfd3..18398d9ae2 100644 --- a/indra/llimage/llimageworker.h +++ b/indra/llimage/llimageworker.h @@ -29,9 +29,13 @@  #include "llimage.h"  #include "llpointer.h" -#include "llworkerthread.h" -class LLImageDecodeThread : public LLQueuedThread +namespace LL +{ +    class ThreadPool; +} // namespace LL + +class LLImageDecodeThread  {  public:  	class Responder : public LLThreadSafeRefCount @@ -42,63 +46,24 @@ 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:  	LLImageDecodeThread(bool threaded = true);  	virtual ~LLImageDecodeThread(); -	handle_t decodeImage(LLImageFormatted* image, -						 U32 priority, S32 discard, BOOL needs_aux, -						 Responder* responder); +	// meant to resemble LLQueuedThread::handle_t +	typedef U32 handle_t; +	handle_t decodeImage(const LLPointer<LLImageFormatted>& image, +						 S32 discard, BOOL needs_aux, +						 const LLPointer<Responder>& responder); +	S32 getPending();  	S32 update(F32 max_time_ms); +	void shutdown(); -	// Used by unit tests to check the consistency of the thread instance -	S32 tut_size(); -	  private: -	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; +	// As of SL-17483, LLImageDecodeThread is no longer itself an +	// LLQueuedThread - instead this is the API by which we submit work to the +	// "ImageDecode" ThreadPool. +	std::unique_ptr<LL::ThreadPool> mThreadPool;  };  #endif diff --git a/indra/llimage/tests/llimageworker_test.cpp b/indra/llimage/tests/llimageworker_test.cpp index 9011ac615c..0a97b739b0 100644 --- a/indra/llimage/tests/llimageworker_test.cpp +++ b/indra/llimage/tests/llimageworker_test.cpp @@ -125,42 +125,11 @@ namespace tut  		}  	}; -	// 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("LLImageDecodeThread"); -	typedef test_group<imagerequest_test> imagerequest_t; -	typedef imagerequest_t::object imagerequest_object_t; -	tut::imagerequest_t tut_imagerequest("LLImageRequest"); -  	// ---------------------------------------------------------------------------------------  	// Test functions  	// Notes: @@ -172,64 +141,18 @@ namespace 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)); +		LLImageDecodeThread::handle_t decodeHandle = mThread->decodeImage(NULL, 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 @@ -242,24 +165,4 @@ namespace tut  		// 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"); -		} -	}  } diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index 925da5674b..8a641617fa 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -118,6 +118,7 @@ bool LLImageJ2COJ::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int block  bool LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	//  	// FIXME: Get the comment field out of the texture  	// diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index dac5349f57..2ad42d6b87 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -379,6 +379,7 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod  void LLImageJ2CKDU::cleanupCodeStream()  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	mInputp.reset();  	mDecodeState.reset();  	mCodeStreamp.reset(); @@ -426,6 +427,7 @@ bool LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int bloc  // decodeImpl() usage matters for production.  bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level, int* region)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	base.resetLastError();  	// *FIX: kdu calls our callback function if there's an error, and then bombs. @@ -509,6 +511,7 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco  // Returns true to mean done, whether successful or not.  bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	ECodeStreamMode mode = MODE_FAST;  	LLTimer decode_timer; @@ -1332,6 +1335,7 @@ the `buf' pointer may actually point into a larger buffer representing  multiple tiles.  For this reason, `row_gap' is needed to identify the  separation between consecutive rows in the real buffer. */  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	S32 c;  	// Now walk through the lines of the buffer, recovering them from the  	// relevant tile-component processing engines. @@ -1339,18 +1343,27 @@ separation between consecutive rows in the real buffer. */  	LLTimer decode_timer;  	while (mDims.size.y--)  	{ -		for (c = 0; c < mNumComponents; c++) -		{ -			mEngines[c].pull(mLines[c]); -		} +        { +            LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("kduptc - pull"); +            for (c = 0; c < mNumComponents; c++) +            { +                mEngines[c].pull(mLines[c]); +            } +        } +  		if ((mNumComponents >= 3) && mUseYCC)  		{ +            LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("kduptc - convert");  			kdu_convert_ycc_to_rgb(mLines[0],mLines[1],mLines[2]);  		} -		for (c = 0; c < mNumComponents; c++) -		{ -			transfer_bytes(mBuf+c,mLines[c],mNumComponents,mBitDepths[c]); -		} + +        { +            LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("kduptc - transfer"); +            for (c = 0; c < mNumComponents; c++) +            { +                transfer_bytes(mBuf + c, mLines[c], mNumComponents, mBitDepths[c]); +            } +        }  		mBuf += mRowGap;  		if (mDims.size.y % 10)  		{ diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index c67f59bc0c..ae066112c1 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -64,7 +64,6 @@ LLCore::HttpRequest::ptr_t		sHttpRequest;  LLCore::HttpHeaders::ptr_t		sHttpHeaders;  LLCore::HttpOptions::ptr_t		sHttpOptions;  LLCore::HttpRequest::policy_t	sHttpPolicy; -LLCore::HttpRequest::priority_t	sHttpPriority;  /* Sample response:  <?xml version="1.0"?> @@ -121,7 +120,6 @@ LLAvatarNameCache::LLAvatarNameCache()      sHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders());      sHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions());      sHttpPolicy = LLCore::HttpRequest::DEFAULT_POLICY_ID; -    sHttpPriority = 0;  }  LLAvatarNameCache::~LLAvatarNameCache() diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp index 7031f1aa8c..96af8bacee 100644 --- a/indra/llmessage/llcorehttputil.cpp +++ b/indra/llmessage/llcorehttputil.cpp @@ -131,7 +131,6 @@ bool responseToLLSD(HttpResponse * response, bool log, LLSD & out_llsd)  HttpHandle requestPostWithLLSD(HttpRequest * request,      HttpRequest::policy_t policy_id, -    HttpRequest::priority_t priority,      const std::string & url,      const LLSD & body,      const HttpOptions::ptr_t &options, @@ -145,7 +144,6 @@ HttpHandle requestPostWithLLSD(HttpRequest * request,      LLSDSerialize::toXML(body, bas);      handle = request->requestPost(policy_id, -        priority,          url,          ba,          options, @@ -158,7 +156,6 @@ HttpHandle requestPostWithLLSD(HttpRequest * request,  HttpHandle requestPutWithLLSD(HttpRequest * request,      HttpRequest::policy_t policy_id, -    HttpRequest::priority_t priority,      const std::string & url,      const LLSD & body,      const HttpOptions::ptr_t &options, @@ -172,7 +169,6 @@ HttpHandle requestPutWithLLSD(HttpRequest * request,      LLSDSerialize::toXML(body, bas);      handle = request->requestPut(policy_id, -        priority,          url,          ba,          options, @@ -184,7 +180,6 @@ HttpHandle requestPutWithLLSD(HttpRequest * request,  HttpHandle requestPatchWithLLSD(HttpRequest * request,      HttpRequest::policy_t policy_id, -    HttpRequest::priority_t priority,      const std::string & url,      const LLSD & body,      const HttpOptions::ptr_t &options, @@ -198,7 +193,6 @@ HttpHandle requestPatchWithLLSD(HttpRequest * request,      LLSDSerialize::toXML(body, bas);      handle = request->requestPatch(policy_id, -        priority,          url,          ba,          options, @@ -672,10 +666,9 @@ const std::string HttpCoroutineAdapter::HTTP_RESULTS_CONTENT("content");  const std::string HttpCoroutineAdapter::HTTP_RESULTS_RAW("raw");  HttpCoroutineAdapter::HttpCoroutineAdapter(const std::string &name, -    LLCore::HttpRequest::policy_t policyId, LLCore::HttpRequest::priority_t priority) : +    LLCore::HttpRequest::policy_t policyId) :      mAdapterName(name),      mPolicyId(policyId), -    mPriority(priority),      mYieldingHandle(LLCORE_HTTP_HANDLE_INVALID),      mWeakRequest(),      mWeakHandler() @@ -709,7 +702,7 @@ LLSD HttpCoroutineAdapter::postAndSuspend_(LLCore::HttpRequest::ptr_t &request,      // The HTTPCoroHandler does not self delete, so retrieval of a the contained       // pointer from the smart pointer is safe in this case.      LLCore::HttpHandle hhandle = requestPostWithLLSD(request, -        mPolicyId, mPriority, url, body, options, headers, +        mPolicyId, url, body, options, headers,          handler);      if (hhandle == LLCORE_HTTP_HANDLE_INVALID) @@ -832,7 +825,7 @@ LLSD HttpCoroutineAdapter::postAndSuspend_(LLCore::HttpRequest::ptr_t &request,      // The HTTPCoroHandler does not self delete, so retrieval of a the contained       // pointer from the smart pointer is safe in this case. -    LLCore::HttpHandle hhandle = request->requestPost(mPolicyId, mPriority, url, rawbody.get(), +    LLCore::HttpHandle hhandle = request->requestPost(mPolicyId, url, rawbody.get(),          options, headers, handler);      if (hhandle == LLCORE_HTTP_HANDLE_INVALID) @@ -890,7 +883,7 @@ LLSD HttpCoroutineAdapter::putAndSuspend_(LLCore::HttpRequest::ptr_t &request,      // The HTTPCoroHandler does not self delete, so retrieval of a the contained       // pointer from the smart pointer is safe in this case.      LLCore::HttpHandle hhandle = requestPutWithLLSD(request, -        mPolicyId, mPriority, url, body, options, headers, +        mPolicyId, url, body, options, headers,          handler);      if (hhandle == LLCORE_HTTP_HANDLE_INVALID) @@ -916,7 +909,7 @@ LLSD HttpCoroutineAdapter::putAndSuspend_(LLCore::HttpRequest::ptr_t &request,      // The HTTPCoroHandler does not self delete, so retrieval of a the contained       // pointer from the smart pointer is safe in this case. -    LLCore::HttpHandle hhandle = request->requestPut(mPolicyId, mPriority,  +    LLCore::HttpHandle hhandle = request->requestPut(mPolicyId,          url, rawbody.get(), options, headers, handler);      if (hhandle == LLCORE_HTTP_HANDLE_INVALID) @@ -972,7 +965,7 @@ LLSD HttpCoroutineAdapter::getAndSuspend_(LLCore::HttpRequest::ptr_t &request,      // The HTTPCoroHandler does not self delete, so retrieval of a the contained       // pointer from the smart pointer is safe in this case. -    LLCore::HttpHandle hhandle = request->requestGet(mPolicyId, mPriority, +    LLCore::HttpHandle hhandle = request->requestGet(mPolicyId,          url, options, headers, handler);      if (hhandle == LLCORE_HTTP_HANDLE_INVALID) @@ -1018,7 +1011,7 @@ LLSD HttpCoroutineAdapter::deleteAndSuspend_(LLCore::HttpRequest::ptr_t &request      checkDefaultHeaders(headers);      // The HTTPCoroHandler does not self delete, so retrieval of a the contained       // pointer from the smart pointer is safe in this case. -    LLCore::HttpHandle hhandle = request->requestDelete(mPolicyId, mPriority, +    LLCore::HttpHandle hhandle = request->requestDelete(mPolicyId,          url, options, headers, handler);      if (hhandle == LLCORE_HTTP_HANDLE_INVALID) @@ -1056,7 +1049,7 @@ LLSD HttpCoroutineAdapter::patchAndSuspend_(LLCore::HttpRequest::ptr_t &request,      // The HTTPCoroHandler does not self delete, so retrieval of a the contained       // pointer from the smart pointer is safe in this case.      LLCore::HttpHandle hhandle = requestPatchWithLLSD(request, -        mPolicyId, mPriority, url, body, options, headers, +        mPolicyId, url, body, options, headers,          handler);      if (hhandle == LLCORE_HTTP_HANDLE_INVALID) @@ -1098,7 +1091,7 @@ LLSD HttpCoroutineAdapter::copyAndSuspend_(LLCore::HttpRequest::ptr_t &request,      // The HTTPCoroHandler does not self delete, so retrieval of a the contained       // pointer from the smart pointer is safe in this case.      //  -    LLCore::HttpHandle hhandle = request->requestCopy(mPolicyId, mPriority, url, +    LLCore::HttpHandle hhandle = request->requestCopy(mPolicyId, url,          options, headers, handler);      if (hhandle == LLCORE_HTTP_HANDLE_INVALID) @@ -1140,7 +1133,7 @@ LLSD HttpCoroutineAdapter::moveAndSuspend_(LLCore::HttpRequest::ptr_t &request,      // The HTTPCoroHandler does not self delete, so retrieval of a the contained       // pointer from the smart pointer is safe in this case.      //  -    LLCore::HttpHandle hhandle = request->requestMove(mPolicyId, mPriority, url, +    LLCore::HttpHandle hhandle = request->requestMove(mPolicyId, url,          options, headers, handler);      if (hhandle == LLCORE_HTTP_HANDLE_INVALID) diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h index 6f0b865f83..430dc417ac 100644 --- a/indra/llmessage/llcorehttputil.h +++ b/indra/llmessage/llcorehttputil.h @@ -116,7 +116,6 @@ std::string responseToString(LLCore::HttpResponse * response);  ///  LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest * request,      LLCore::HttpRequest::policy_t policy_id, -    LLCore::HttpRequest::priority_t priority,      const std::string & url,      const LLSD & body,      const LLCore::HttpOptions::ptr_t &options, @@ -125,20 +124,18 @@ LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest * request,  inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & request,  	LLCore::HttpRequest::policy_t policy_id, -	LLCore::HttpRequest::priority_t priority,  	const std::string & url,  	const LLSD & body,  	const LLCore::HttpOptions::ptr_t & options,  	const LLCore::HttpHeaders::ptr_t & headers,      const LLCore::HttpHandler::ptr_t & handler)  { -    return requestPostWithLLSD(request.get(), policy_id, priority, +    return requestPostWithLLSD(request.get(), policy_id,          url, body, options, headers, handler);  }  inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & request,      LLCore::HttpRequest::policy_t policy_id, -    LLCore::HttpRequest::priority_t priority,      const std::string & url,      const LLSD & body,      const LLCore::HttpHandler::ptr_t &handler) @@ -146,7 +143,7 @@ inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & reque      LLCore::HttpOptions::ptr_t options;      LLCore::HttpHeaders::ptr_t headers; -    return requestPostWithLLSD(request.get(), policy_id, priority, +    return requestPostWithLLSD(request.get(), policy_id,          url, body, options, headers, handler);  } @@ -169,7 +166,6 @@ inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & reque  ///  LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest * request,  	LLCore::HttpRequest::policy_t policy_id, -	LLCore::HttpRequest::priority_t priority,  	const std::string & url,  	const LLSD & body,  	const LLCore::HttpOptions::ptr_t &options, @@ -178,20 +174,18 @@ LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest * request,  inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & request,  	LLCore::HttpRequest::policy_t policy_id, -	LLCore::HttpRequest::priority_t priority,  	const std::string & url,  	const LLSD & body,  	const LLCore::HttpOptions::ptr_t & options,  	const LLCore::HttpHeaders::ptr_t & headers,      LLCore::HttpHandler::ptr_t handler)  { -    return requestPutWithLLSD(request.get(), policy_id, priority, +    return requestPutWithLLSD(request.get(), policy_id,          url, body, options, headers, handler);  }  inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & request,      LLCore::HttpRequest::policy_t policy_id, -    LLCore::HttpRequest::priority_t priority,      const std::string & url,      const LLSD & body,      LLCore::HttpHandler::ptr_t handler) @@ -199,7 +193,7 @@ inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & reques      LLCore::HttpOptions::ptr_t options;      LLCore::HttpHeaders::ptr_t headers; -    return requestPutWithLLSD(request.get(), policy_id, priority, +    return requestPutWithLLSD(request.get(), policy_id,          url, body, options, headers, handler);  } @@ -221,7 +215,6 @@ inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & reques  ///  LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest * request,      LLCore::HttpRequest::policy_t policy_id, -    LLCore::HttpRequest::priority_t priority,      const std::string & url,      const LLSD & body,      const LLCore::HttpOptions::ptr_t &options, @@ -230,20 +223,18 @@ LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest * request,  inline LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & request,      LLCore::HttpRequest::policy_t policy_id, -    LLCore::HttpRequest::priority_t priority,      const std::string & url,      const LLSD & body,      const LLCore::HttpOptions::ptr_t & options,      const LLCore::HttpHeaders::ptr_t & headers,      const LLCore::HttpHandler::ptr_t & handler)  { -    return requestPatchWithLLSD(request.get(), policy_id, priority, +    return requestPatchWithLLSD(request.get(), policy_id,          url, body, options, headers, handler);  }  inline LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & request,      LLCore::HttpRequest::policy_t policy_id, -    LLCore::HttpRequest::priority_t priority,      const std::string & url,      const LLSD & body,      const LLCore::HttpHandler::ptr_t &handler) @@ -251,7 +242,7 @@ inline LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & requ      LLCore::HttpOptions::ptr_t options;      LLCore::HttpHeaders::ptr_t headers; -    return requestPatchWithLLSD(request.get(), policy_id, priority, +    return requestPatchWithLLSD(request.get(), policy_id,          url, body, options, headers, handler);  } @@ -329,8 +320,7 @@ public:      typedef boost::shared_ptr<HttpCoroutineAdapter> ptr_t;      typedef boost::weak_ptr<HttpCoroutineAdapter>   wptr_t; -    HttpCoroutineAdapter(const std::string &name, LLCore::HttpRequest::policy_t policyId, -        LLCore::HttpRequest::priority_t priority = 0L); +    HttpCoroutineAdapter(const std::string &name, LLCore::HttpRequest::policy_t policyId);      ~HttpCoroutineAdapter();      /// Execute a Post transaction on the supplied URL and yield execution of  @@ -673,7 +663,6 @@ private:      void checkDefaultHeaders(LLCore::HttpHeaders::ptr_t &headers);      std::string                     mAdapterName; -    LLCore::HttpRequest::priority_t mPriority;      LLCore::HttpRequest::policy_t   mPolicyId;      LLCore::HttpHandle              mYieldingHandle; diff --git a/indra/llmessage/tests/llcoproceduremanager_test.cpp b/indra/llmessage/tests/llcoproceduremanager_test.cpp index 6424117ef3..78424a28c8 100644 --- a/indra/llmessage/tests/llcoproceduremanager_test.cpp +++ b/indra/llmessage/tests/llcoproceduremanager_test.cpp @@ -48,7 +48,7 @@  #pragma warning(disable: 4702)  #endif -LLCoreHttpUtil::HttpCoroutineAdapter::HttpCoroutineAdapter(std::string const&, unsigned int, unsigned int) +LLCoreHttpUtil::HttpCoroutineAdapter::HttpCoroutineAdapter(std::string const&, unsigned int)  {  } diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 89dd68da76..6215727de0 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -53,13 +53,75 @@ const F32 MIN_TEXTURE_LIFETIME = 10.f;  //assumes i is a power of 2 > 0  U32 wpo2(U32 i); + +// texture memory accounting (for OS X) +static LLMutex sTexMemMutex; +static std::unordered_map<U32, U32> sTextureAllocs; +static U64 sTextureBytes = 0; + +// track a texture alloc on the currently bound texture. +// asserts that no currently tracked alloc exists +static void alloc_tex_image(U32 width, U32 height, U32 pixformat) +{ +    U32 texUnit = gGL.getCurrentTexUnitIndex(); +    U32 texName = gGL.getTexUnit(texUnit)->getCurrTexture(); +    S32 size = LLImageGL::dataFormatBytes(pixformat, width, height); + +    llassert(size >= 0); + +    sTexMemMutex.lock(); +    llassert(sTextureAllocs.find(texName) == sTextureAllocs.end()); + +    sTextureAllocs[texName] = size; +    sTextureBytes += size; + +    sTexMemMutex.unlock(); +} + +// track texture free on given texName +static void free_tex_image(U32 texName) +{ +    sTexMemMutex.lock(); +    auto iter = sTextureAllocs.find(texName); +    if (iter != sTextureAllocs.end()) +    { +        llassert(iter->second <= sTextureBytes); // sTextureBytes MUST NOT go below zero + +        sTextureBytes -= iter->second; + +        sTextureAllocs.erase(iter); +    } + +    sTexMemMutex.unlock(); +} + +// track texture free on given texNames +static void free_tex_images(U32 count, const U32* texNames) +{ +    for (int i = 0; i < count; ++i) +    { +        free_tex_image(texNames[i]); +    } +} + +// track texture free on currently bound texture +static void free_cur_tex_image() +{ +    U32 texUnit = gGL.getCurrentTexUnitIndex(); +    U32 texName = gGL.getTexUnit(texUnit)->getCurrTexture(); +    free_tex_image(texName); +} + +// static  +U64 LLImageGL::getTextureBytesAllocated() +{ +    return sTextureBytes; +} +  //statics  U32 LLImageGL::sUniqueCount				= 0;  U32 LLImageGL::sBindCount				= 0; -S32Bytes LLImageGL::sGlobalTextureMemory(0); -S32Bytes LLImageGL::sBoundTextureMemory(0); -S32Bytes LLImageGL::sCurBoundTextureMemory(0);  S32 LLImageGL::sCount					= 0;  BOOL LLImageGL::sGlobalUseAnisotropic	= FALSE; @@ -220,6 +282,7 @@ S32 LLImageGL::dataFormatBits(S32 dataformat)      case GL_RGBA:								    return 32;      case GL_SRGB_ALPHA:						        return 32;      case GL_BGRA:								    return 32;		// Used for QuickTime media textures on the Mac +    case GL_DEPTH_COMPONENT:                        return 24;      default:          LL_ERRS() << "LLImageGL::Unknown format: " << dataformat << LL_ENDL;          return 0; @@ -282,15 +345,6 @@ void LLImageGL::updateStats(F32 current_time)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	sLastFrameTime = current_time; -	sBoundTextureMemory = sCurBoundTextureMemory; -	sCurBoundTextureMemory = S32Bytes(0); -} - -//static -S32 LLImageGL::updateBoundTexMem(const S32Bytes mem, const S32 ncomponents, S32 category) -{ -	LLImageGL::sCurBoundTextureMemory += mem ; -	return LLImageGL::sCurBoundTextureMemory.value();  }  //---------------------------------------------------------------------------- @@ -623,7 +677,7 @@ void LLImageGL::forceUpdateBindStats(void) const  	mLastBindTime = sLastFrameTime;  } -BOOL LLImageGL::updateBindStats(S32Bytes tex_mem) const +BOOL LLImageGL::updateBindStats() const  {	  	if (mTexName != 0)  	{ @@ -635,7 +689,6 @@ BOOL LLImageGL::updateBindStats(S32Bytes tex_mem) const  		{  			// we haven't accounted for this texture yet this frame  			sUniqueCount++; -			updateBoundTexMem(tex_mem, mComponents, mCategory);  			mLastBindTime = sLastFrameTime;  			return TRUE ; @@ -1232,6 +1285,7 @@ void LLImageGL::deleteTextures(S32 numTextures, const U32 *textures)  {  	if (gGLManager.mInited)  	{ +        free_tex_images(numTextures, textures);  		glDeleteTextures(numTextures, textures);  	}  } @@ -1354,7 +1408,10 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt      stop_glerror();      {          LL_PROFILE_ZONE_NAMED("glTexImage2D"); + +        free_cur_tex_image();          glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels); +        alloc_tex_image(width, height, pixformat);      }      stop_glerror(); @@ -1601,11 +1658,6 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_      // things will break if we don't unbind after creation      gGL.getTexUnit(0)->unbind(mBindTarget); -    if (old_texname != 0) -    { -        sGlobalTextureMemory -= mTextureMemory; -    } -      //if we're on the image loading thread, be sure to delete old_texname and update mTexName on the main thread      if (!defer_copy)      { @@ -1626,7 +1678,6 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_      mTextureMemory = (S32Bytes)getMipBytes(mCurrentDiscardLevel); -    sGlobalTextureMemory += mTextureMemory;      mTexelsInGLTexture = getWidth() * getHeight();      // mark this as bound at this point, so we don't throw it out immediately @@ -1636,51 +1687,6 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_      return TRUE;  } -void LLImageGLThread::updateClass() -{ -    LL_PROFILE_ZONE_SCOPED; - -    // update available vram one per second -    static LLFrameTimer sTimer; - -    if (sTimer.getElapsedSeconds() < 1.f) -    { -        return; -    } -     -    sTimer.reset(); - -    auto func = []() -    { -        if (gGLManager.mHasATIMemInfo) -        { -            S32 meminfo[4]; -            glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo); -            LLImageGLThread::sFreeVRAMMegabytes = meminfo[0]; - -        } -        else if (gGLManager.mHasNVXMemInfo) -        { -            S32 free_memory; -            glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory); -            LLImageGLThread::sFreeVRAMMegabytes = free_memory / 1024; -        } -    }; - -     -    // post update to background thread if available, otherwise execute immediately -    auto queue = LL::WorkQueue::getInstance("LLImageGL"); -    if (sEnabled) -    { -        queue->post(func); -    } -    else -    { -        llassert(queue == nullptr); -        func(); -    } -} -  void LLImageGL::syncToMainThread(LLGLuint new_tex_name)  {      LL_PROFILE_ZONE_SCOPED; @@ -1874,7 +1880,6 @@ void LLImageGL::destroyGLTexture()  	{  		if(mTextureMemory != S32Bytes(0))  		{ -			sGlobalTextureMemory -= mTextureMemory;  			mTextureMemory = (S32Bytes)0;  		} @@ -2426,13 +2431,9 @@ void LLImageGL::checkActiveThread()  		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL,  nummips);  */   -std::atomic<S32> LLImageGLThread::sFreeVRAMMegabytes(4096); //if free vram is unknown, default to 4GB -  LLImageGLThread::LLImageGLThread(LLWindow* window) -    // We want exactly one thread, but a very large capacity: we never want -    // anyone, especially inner-loop render code, to have to block on post() -    // because we're full. -    : ThreadPool("LLImageGL", 1, 1024*1024) +    // We want exactly one thread. +    : ThreadPool("LLImageGL", 1)      , mWindow(window)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; @@ -2455,8 +2456,3 @@ void LLImageGLThread::run()      mWindow->destroySharedContext(mContext);  } -S32 LLImageGLThread::getFreeVRAMMegabytes() -{ -    return sFreeVRAMMegabytes; -} - diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index b419c9fab5..b4618fd35c 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -52,6 +52,13 @@ class LLImageGL : public LLRefCount  {  	friend class LLTexUnit;  public: + +    // Get an estimate of how many bytes have been allocated in vram for textures. +    // Does not include mipmaps. +    // NOTE: multiplying this number by two gives a good estimate for total +    // video memory usage based on testing in lagland against an NVIDIA GPU. +    static U64 getTextureBytesAllocated(); +  	// These 2 functions replace glGenTextures() and glDeleteTextures()  	static void generateTextures(S32 numTextures, U32 *textures);  	static void deleteTextures(S32 numTextures, const U32 *textures); @@ -61,7 +68,7 @@ public:  	static S32 dataFormatBytes(S32 dataformat, S32 width, S32 height);  	static S32 dataFormatComponents(S32 dataformat); -	BOOL updateBindStats(S32Bytes tex_mem) const ; +	BOOL updateBindStats() const ;  	F32 getTimePassedSinceLastBound();  	void forceUpdateBindStats(void) const; @@ -73,9 +80,6 @@ public:  	static void restoreGL();  	static void dirtyTexOptions(); -	// Sometimes called externally for textures not using LLImageGL (should go away...)	 -	static S32 updateBoundTexMem(const S32Bytes mem, const S32 ncomponents, S32 category) ; -	  	static bool checkSize(S32 width, S32 height);  	//for server side use only. @@ -165,7 +169,7 @@ public:  	void updatePickMask(S32 width, S32 height, const U8* data_in);  	BOOL getMask(const LLVector2 &tc); -	void checkTexSize(bool forced = false) const ; +    void checkTexSize(bool forced = false) const ;  	// Sets the addressing mode used to sample the texture   	//  (such as wrapping, mirrored wrapping, and clamp) @@ -265,9 +269,6 @@ public:  	static F32 sLastFrameTime;  	// Global memory statistics -	static S32Bytes sGlobalTextureMemory;	// Tracks main memory texmem -	static S32Bytes sBoundTextureMemory;	// Tracks bound texmem for last completed frame -	static S32Bytes sCurBoundTextureMemory;		// Tracks bound texmem for current frame  	static U32 sBindCount;					// Tracks number of texture binds for current frame  	static U32 sUniqueCount;				// Tracks number of unique texture binds for current frame  	static BOOL sGlobalUseAnisotropic; @@ -327,12 +328,6 @@ public:      // follows gSavedSettings "RenderGLMultiThreaded"      static bool sEnabled; -    // app should call this function periodically -    static void updateClass(); - -    // free video memory in megabytes -    static std::atomic<S32> sFreeVRAMMegabytes; -      LLImageGLThread(LLWindow* window);      // post a function to be executed on the LLImageGL background thread @@ -344,8 +339,6 @@ public:      void run() override; -    static S32 getFreeVRAMMegabytes(); -  private:      LLWindow* mWindow;      void* mContext = nullptr; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 3adb47f493..e5bd19e91c 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -224,7 +224,7 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)  					enable(gl_tex->getTarget());  					mCurrTexture = gl_tex->getTexName();  					glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture); -					if(gl_tex->updateBindStats(gl_tex->mTextureMemory)) +					if(gl_tex->updateBindStats())  					{  						texture->setActive() ;  						texture->updateBindStatsForTester() ; @@ -303,7 +303,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind, S32  		mCurrTexture = texname;  		glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture);  		stop_glerror(); -		texture->updateBindStats(texture->mTextureMemory);		 +        texture->updateBindStats();  		mHasMipMaps = texture->mHasMipMaps;  		if (texture->mTexOptionsDirty)  		{ @@ -342,7 +342,7 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap)              mCurrTexture = cubeMap->mImages[0]->getTexName();  			glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mCurrTexture);  			mHasMipMaps = cubeMap->mImages[0]->mHasMipMaps; -			cubeMap->mImages[0]->updateBindStats(cubeMap->mImages[0]->mTextureMemory); +			cubeMap->mImages[0]->updateBindStats();  			if (cubeMap->mImages[0]->mTexOptionsDirty)  			{  				cubeMap->mImages[0]->mTexOptionsDirty = false; diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index 70eb99c86c..32f0fa14c4 100644 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -145,6 +145,8 @@ if (WINDOWS)    list(APPEND llwindow_LINK_LIBRARIES         comdlg32     # Common Dialogs for ChooseColor         ole32 +       dxgi +       d3d9         )  endif (WINDOWS) diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index fd20f2ad15..8d064ec86c 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -141,7 +141,12 @@ attributedStringInfo getSegments(NSAttributedString *str)      CGLError the_err = CGLQueryRendererInfo (CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), &info, &num_renderers);      if(0 == the_err)      { -        CGLDescribeRenderer (info, 0, kCGLRPTextureMemoryMegabytes, &vram_megabytes); +        // The name, uses, and other platform definitions of gGLManager.mVRAM suggest that this is supposed to be total vram in MB, +        // rather than, say, just the texture memory. The two exceptions are: +        // 1. LLAppViewer::getViewerInfo() puts the value in a field labeled "TEXTURE_MEMORY" +        // 2. For years, this present function used kCGLRPTextureMemoryMegabytes +        // Now we use kCGLRPVideoMemoryMegabytes to bring it in line with everything else (except thatone label). +        CGLDescribeRenderer (info, 0, kCGLRPVideoMemoryMegabytes, &vram_megabytes);          CGLDestroyRendererInfo (info);      }      else diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 0edf39f6ef..2c538a60c9 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -162,7 +162,10 @@ public:  	virtual F32	getNativeAspectRatio() = 0;  	virtual F32 getPixelAspectRatio() = 0;  	virtual void setNativeAspectRatio(F32 aspect) = 0; -	 + +	// query VRAM usage +	virtual U32 getAvailableVRAMMegabytes() = 0; +  	virtual void beforeDialog() {};	// prepare to put up an OS dialog (if special measures are required, such as in fullscreen mode)  	virtual void afterDialog() {};	// undo whatever was done in beforeDialog() diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h index 410da79623..2f2c0de5bd 100644 --- a/indra/llwindow/llwindowheadless.h +++ b/indra/llwindow/llwindowheadless.h @@ -32,72 +32,79 @@  class LLWindowHeadless : public LLWindow  {  public: -	/*virtual*/ void show() {}; -	/*virtual*/ void hide() {}; -	/*virtual*/ void close() {}; -	/*virtual*/ BOOL getVisible() {return FALSE;}; -	/*virtual*/ BOOL getMinimized() {return FALSE;}; -	/*virtual*/ BOOL getMaximized() {return FALSE;}; -	/*virtual*/ BOOL maximize() {return FALSE;}; -	/*virtual*/ void minimize() {}; -	/*virtual*/ void restore() {}; -	/*virtual*/ BOOL getFullscreen() {return FALSE;}; -	/*virtual*/ BOOL getPosition(LLCoordScreen *position) {return FALSE;}; -	/*virtual*/ BOOL getSize(LLCoordScreen *size) {return FALSE;}; -	/*virtual*/ BOOL getSize(LLCoordWindow *size) {return FALSE;}; -	/*virtual*/ BOOL setPosition(LLCoordScreen position) {return FALSE;}; -	/*virtual*/ BOOL setSizeImpl(LLCoordScreen size) {return FALSE;}; -	/*virtual*/ BOOL setSizeImpl(LLCoordWindow size) {return FALSE;}; -	/*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp = NULL) {return FALSE;}; -    void* createSharedContext()  { return nullptr; } -    void makeContextCurrent(void*)  {} -    void destroySharedContext(void*)  {} -    /*virtual*/ void toggleVSync(bool enable_vsync) { } -    /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;}; -    /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;}; +	/*virtual*/ void show() override {} +	/*virtual*/ void hide() override {} +	/*virtual*/ void close() override {} +	/*virtual*/ BOOL getVisible() override {return FALSE;} +	/*virtual*/ BOOL getMinimized() override {return FALSE;} +	/*virtual*/ BOOL getMaximized() override {return FALSE;} +	/*virtual*/ BOOL maximize() override {return FALSE;} +	/*virtual*/ void minimize() override {} +	/*virtual*/ void restore() override {} +	// TODO: LLWindow::getFullscreen() is (intentionally?) NOT virtual. +	// Apparently the coder of LLWindowHeadless didn't realize that. Is it a +	// mistake to shadow the base-class method with an LLWindowHeadless +	// override when called on the subclass, yet call the base-class method +	// when indirecting through a polymorphic pointer or reference? +	BOOL getFullscreen() {return FALSE;} +	/*virtual*/ BOOL getPosition(LLCoordScreen *position) override {return FALSE;} +	/*virtual*/ BOOL getSize(LLCoordScreen *size) override {return FALSE;} +	/*virtual*/ BOOL getSize(LLCoordWindow *size) override {return FALSE;} +	/*virtual*/ BOOL setPosition(LLCoordScreen position) override {return FALSE;} +	/*virtual*/ BOOL setSizeImpl(LLCoordScreen size) override {return FALSE;} +	/*virtual*/ BOOL setSizeImpl(LLCoordWindow size) override {return FALSE;} +	/*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL enable_vsync, const LLCoordScreen * const posp = NULL) override {return FALSE;} +    void* createSharedContext() override  { return nullptr; } +    void makeContextCurrent(void*) override  {} +    void destroySharedContext(void*) override  {} +    /*virtual*/ void toggleVSync(bool enable_vsync) override { } +    /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) override {return FALSE;} +    /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) override {return FALSE;}  #if LL_WINDOWS -    /*virtual*/ BOOL getCursorDelta(LLCoordCommon* delta) { return FALSE; } +    /*virtual*/ BOOL getCursorDelta(LLCoordCommon* delta) override { return FALSE; }  #endif -	/*virtual*/ void showCursor() {}; -	/*virtual*/ void hideCursor() {}; -	/*virtual*/ void showCursorFromMouseMove() {}; -	/*virtual*/ void hideCursorUntilMouseMove() {}; -	/*virtual*/ BOOL isCursorHidden() {return FALSE;}; -	/*virtual*/ void updateCursor() {}; -	//virtual ECursorType getCursor() { return mCurrentCursor; }; -	/*virtual*/ void captureMouse() {}; -	/*virtual*/ void releaseMouse() {}; -	/*virtual*/ void setMouseClipping( BOOL b ) {}; -	/*virtual*/ BOOL isClipboardTextAvailable() {return FALSE; }; -	/*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst) {return FALSE; }; -	/*virtual*/ BOOL copyTextToClipboard(const LLWString &src) {return FALSE; }; -	/*virtual*/ void flashIcon(F32 seconds) {}; -	/*virtual*/ F32 getGamma() {return 1.0f; }; -	/*virtual*/ BOOL setGamma(const F32 gamma) {return FALSE; }; // Set the gamma -	/*virtual*/ void setFSAASamples(const U32 fsaa_samples) { } -	/*virtual*/ U32 getFSAASamples() { return 0; } -	/*virtual*/ BOOL restoreGamma() {return FALSE; };	// Restore original gamma table (before updating gamma) -	//virtual ESwapMethod getSwapMethod() { return mSwapMethod; } -	/*virtual*/ void gatherInput() {}; -	/*virtual*/ void delayInputProcessing() {}; -	/*virtual*/ void swapBuffers(); +	/*virtual*/ void showCursor() override {} +	/*virtual*/ void hideCursor() override {} +	/*virtual*/ void showCursorFromMouseMove() override {} +	/*virtual*/ void hideCursorUntilMouseMove() override {} +	/*virtual*/ BOOL isCursorHidden() override {return FALSE;} +	/*virtual*/ void updateCursor() override {} +	//virtual ECursorType getCursor() override { return mCurrentCursor; } +	/*virtual*/ void captureMouse() override {} +	/*virtual*/ void releaseMouse() override {} +	/*virtual*/ void setMouseClipping( BOOL b ) override {} +	/*virtual*/ BOOL isClipboardTextAvailable() override {return FALSE; } +	/*virtual*/ BOOL pasteTextFromClipboard(LLWString &dst) override {return FALSE; } +	/*virtual*/ BOOL copyTextToClipboard(const LLWString &src) override {return FALSE; } +	/*virtual*/ void flashIcon(F32 seconds) override {} +	/*virtual*/ F32 getGamma() override {return 1.0f; } +	/*virtual*/ BOOL setGamma(const F32 gamma) override {return FALSE; } // Set the gamma +	/*virtual*/ void setFSAASamples(const U32 fsaa_samples) override { } +	/*virtual*/ U32 getFSAASamples() override { return 0; } +	/*virtual*/ BOOL restoreGamma() override {return FALSE; }	// Restore original gamma table (before updating gamma) +	//virtual ESwapMethod getSwapMethod() override { return mSwapMethod; } +	/*virtual*/ void gatherInput() override {} +	/*virtual*/ void delayInputProcessing() override {} +	/*virtual*/ void swapBuffers() override;      // handy coordinate space conversion routines -	/*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordWindow *to) { return FALSE; }; -	/*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordScreen *to) { return FALSE; }; -	/*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordGL *to) { return FALSE; }; -	/*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordWindow *to) { return FALSE; }; -	/*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordGL *to) { return FALSE; }; -	/*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordScreen *to) { return FALSE; }; +	/*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordWindow *to) override { return FALSE; } +	/*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordScreen *to) override { return FALSE; } +	/*virtual*/ BOOL convertCoords(LLCoordWindow from, LLCoordGL *to) override { return FALSE; } +	/*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordWindow *to) override { return FALSE; } +	/*virtual*/ BOOL convertCoords(LLCoordScreen from, LLCoordGL *to) override { return FALSE; } +	/*virtual*/ BOOL convertCoords(LLCoordGL from, LLCoordScreen *to) override { return FALSE; } -	/*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions) { return NULL; }; -	/*virtual*/ F32	getNativeAspectRatio() { return 1.0f; }; -	/*virtual*/ F32 getPixelAspectRatio() { return 1.0f; }; -	/*virtual*/ void setNativeAspectRatio(F32 ratio) {} +	/*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions) override { return NULL; } +	/*virtual*/ F32	getNativeAspectRatio() override { return 1.0f; } +	/*virtual*/ F32 getPixelAspectRatio() override { return 1.0f; } +	/*virtual*/ void setNativeAspectRatio(F32 ratio) override {} -	/*virtual*/ void *getPlatformWindow() { return 0; }; -	/*virtual*/ void bringToFront() {}; +    U32 getAvailableVRAMMegabytes() override { return 4096; } + +	/*virtual*/ void *getPlatformWindow() override { return 0; } +	/*virtual*/ void bringToFront() override {}  	LLWindowHeadless(LLWindowCallbacks* callbacks,  		const std::string& title, const std::string& name, @@ -113,12 +120,12 @@ private:  class LLSplashScreenHeadless : public LLSplashScreen  {  public: -	LLSplashScreenHeadless() {}; -	virtual ~LLSplashScreenHeadless() {}; +	LLSplashScreenHeadless() {} +	virtual ~LLSplashScreenHeadless() {} -	/*virtual*/ void showImpl() {}; -	/*virtual*/ void updateImpl(const std::string& mesg) {}; -	/*virtual*/ void hideImpl() {}; +	/*virtual*/ void showImpl() override {} +	/*virtual*/ void updateImpl(const std::string& mesg) override {} +	/*virtual*/ void hideImpl() override {}  }; diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index bc4f07941b..4bcb9b3aef 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1222,6 +1222,16 @@ F32 LLWindowMacOSX::getPixelAspectRatio()  	return 1.f;  } +U32 LLWindowMacOSX::getAvailableVRAMMegabytes() { +    // MTL (and MoltenVK) has some additional gpu data, such as recommendedMaxWorkingSetSize and currentAllocatedSize. +    // But these are not available for OpenGL and/or our current mimimum OS version. +    // So we will estimate. +    static const U32 mb = 1024*1024; +    // We're asked for total available gpu memory, but we only have allocation info on texture usage. So estimate by doubling that. +    static const U32 total_factor = 2; // estimated total/textures +    return gGLManager.mVRAM - (LLImageGL::getTextureBytesAllocated() * total_factor/mb); +} +  //static SInt32 oldWindowLevel;  // MBW -- XXX -- There's got to be a better way than this.  Find it, please... diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index b0f339e1db..0f316f1ddf 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -100,6 +100,9 @@ public:  	F32 getPixelAspectRatio() override;  	void setNativeAspectRatio(F32 ratio) override { mOverrideAspectRatio = ratio; } +	// query VRAM usage +    /*virtual*/ U32 getAvailableVRAMMegabytes() override; +  	void beforeDialog() override;  	void afterDialog() override; diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 1f23040260..553507bc0c 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -47,6 +47,9 @@  #include "llglslshader.h"  #include "llthreadsafequeue.h"  #include "stringize.h" +#include "llframetimer.h" +#include "commoncontrol.h" // TODO: Remove after testing +#include "llsd.h" // TODO: Remove after testing  // System includes  #include <commdlg.h> @@ -61,6 +64,9 @@  #include <sstream>  #include <utility>                  // std::pair +#include <d3d9.h> +#include <dxgi1_4.h> +  // Require DirectInput version 8  #define DIRECTINPUT_VERSION 0x0800 @@ -347,6 +353,20 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool      void run() override; +    // initialzie DXGI adapter (for querying available VRAM) +    void initDX(); +     +    // initialize D3D (if DXGI cannot be used) +    void initD3D(); + +    // call periodically to update available VRAM +    void updateVRAMUsage(); + +    U32 getAvailableVRAMMegabytes() +    { +        return mAvailableVRAM; +    } +      /// called by main thread to post work to this window thread      template <typename CALLABLE>      void post(CALLABLE&& func) @@ -395,6 +415,15 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool      void gatherInput();      HWND mWindowHandle = NULL;      HDC mhDC = 0; + +    // best guess at available video memory in MB +    std::atomic<U32> mAvailableVRAM; + +    bool mTryUseDXGIAdapter; // TODO: Remove after testing +    IDXGIAdapter3* mDXGIAdapter = nullptr; +    bool mTryUseD3DDevice; // TODO: Remove after testing +    LPDIRECT3D9 mD3D = nullptr; +    LPDIRECT3DDEVICE9 mD3DDevice = nullptr;  }; @@ -4531,12 +4560,24 @@ std::vector<std::string> LLWindowWin32::getDynamicFallbackFontList()  	return std::vector<std::string>();  } +U32 LLWindowWin32::getAvailableVRAMMegabytes() +{ +    return mWindowThread ? mWindowThread->getAvailableVRAMMegabytes() : 0; +}  #endif // LL_WINDOWS  inline LLWindowWin32::LLWindowWin32Thread::LLWindowWin32Thread()      : ThreadPool("Window Thread", 1, MAX_QUEUE_SIZE)  { +    const LLSD skipDXGI{ LL::CommonControl::get("Global", "DisablePrimaryGraphicsMemoryAccounting") }; // TODO: Remove after testing +    LL_WARNS() << "DisablePrimaryGraphicsMemoryAccounting: " << skipDXGI << ", as boolean: " << skipDXGI.asBoolean() << LL_ENDL; +    mTryUseDXGIAdapter = !skipDXGI.asBoolean(); +    LL_WARNS() << "mTryUseDXGIAdapter: " << mTryUseDXGIAdapter << LL_ENDL; +    const LLSD skipD3D{ LL::CommonControl::get("Global", "DisableSecondaryGraphicsMemoryAccounting") }; // TODO: Remove after testing +    LL_WARNS() << "DisableSecondaryGraphicsMemoryAccounting: " << skipD3D << ", as boolean: " << skipD3D.asBoolean() << LL_ENDL; +    mTryUseD3DDevice = !skipD3D.asBoolean(); +    LL_WARNS() << "mTryUseD3DDevice: " << mTryUseD3DDevice << LL_ENDL;      ThreadPool::start();  } @@ -4586,17 +4627,216 @@ private:      std::string mPrev;  }; +// Print hardware debug info about available graphics adapters in ordinal order +void debugEnumerateGraphicsAdapters() +{ +    LL_INFOS("Window") << "Enumerating graphics adapters..." << LL_ENDL; + +    IDXGIFactory1* factory; +    HRESULT res = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&factory); +    if (FAILED(res) || !factory) +    { +        LL_WARNS() << "CreateDXGIFactory1 failed: 0x" << std::hex << res << LL_ENDL; +    } +    else +    { +        UINT graphics_adapter_index = 0; +        IDXGIAdapter3* dxgi_adapter; +        while (true) +        { +            res = factory->EnumAdapters(graphics_adapter_index, reinterpret_cast<IDXGIAdapter**>(&dxgi_adapter)); +            if (FAILED(res)) +            { +                if (graphics_adapter_index == 0) +                { +                    LL_WARNS() << "EnumAdapters failed: 0x" << std::hex << res << LL_ENDL; +                } +                else +                { +                    LL_INFOS("Window") << "Done enumerating graphics adapters" << LL_ENDL; +                } +            } +            else +            { +                DXGI_ADAPTER_DESC desc; +                dxgi_adapter->GetDesc(&desc); +                std::wstring description_w((wchar_t*)desc.Description); +                std::string description(description_w.begin(), description_w.end()); +                LL_INFOS("Window") << "Graphics adapter index: " << graphics_adapter_index << ", " +                    << "Description: " << description << ", " +                    << "DeviceId: " << desc.DeviceId << ", " +                    << "SubSysId: " << desc.SubSysId << ", " +                    << "AdapterLuid: " << desc.AdapterLuid.HighPart << "_" << desc.AdapterLuid.LowPart << ", " +                    << "DedicatedVideoMemory: " << desc.DedicatedVideoMemory / 1024 / 1024 << ", " +                    << "DedicatedSystemMemory: " << desc.DedicatedSystemMemory / 1024 / 1024 << ", " +                    << "SharedSystemMemory: " << desc.SharedSystemMemory / 1024 / 1024 << LL_ENDL; +            } + +            if (dxgi_adapter) +            { +                dxgi_adapter->Release(); +                dxgi_adapter = NULL; +            } +            else +            { +                break; +            } + +            graphics_adapter_index++; +        } +    } + +    if (factory) +    { +        factory->Release(); +    } +} + +void LLWindowWin32::LLWindowWin32Thread::initDX() +{ +    if (mDXGIAdapter == NULL && mTryUseDXGIAdapter) +    { +        debugEnumerateGraphicsAdapters(); + +        IDXGIFactory4* pFactory = nullptr; + +        HRESULT res = CreateDXGIFactory1(__uuidof(IDXGIFactory4), (void**)&pFactory); + +        if (FAILED(res)) +        { +            LL_WARNS() << "CreateDXGIFactory1 failed: 0x" << std::hex << res << LL_ENDL; +        } +        else +        { +            res = pFactory->EnumAdapters(0, reinterpret_cast<IDXGIAdapter**>(&mDXGIAdapter)); +            if (FAILED(res)) +            { +                LL_WARNS() << "EnumAdapters failed: 0x" << std::hex << res << LL_ENDL; +            } +            else +            { +                LL_INFOS() << "EnumAdapters success" << LL_ENDL; +            } +        } + +        if (pFactory) +        { +            pFactory->Release(); +        } +    } +} + +void LLWindowWin32::LLWindowWin32Thread::initD3D() +{ +    if (mDXGIAdapter == NULL && mD3DDevice == NULL && mTryUseD3DDevice && mWindowHandle != 0) +    { +        mD3D = Direct3DCreate9(D3D_SDK_VERSION); +         +        D3DPRESENT_PARAMETERS d3dpp; + +        ZeroMemory(&d3dpp, sizeof(d3dpp)); +        d3dpp.Windowed = TRUE; +        d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + +        HRESULT res = mD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mWindowHandle, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &mD3DDevice); +         +        if (FAILED(res)) +        { +            LL_WARNS() << "(fallback) CreateDevice failed: 0x" << std::hex << res << LL_ENDL; +        } +        else +        { +            LL_INFOS() << "(fallback) CreateDevice success" << LL_ENDL; +        } +    } +} + +void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage() +{ +    LL_PROFILE_ZONE_SCOPED; +    if (mDXGIAdapter != nullptr) +    { +        // NOTE: what lies below is hand wavy math based on compatibility testing and observation against a variety of hardware +        //  It doesn't make sense, but please don't refactor it to make sense. -- davep + +        DXGI_QUERY_VIDEO_MEMORY_INFO info; +        mDXGIAdapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &info); + +#if 0 // debug 0 budget and 0 CU +        info.Budget = 0; +        info.CurrentUsage = 0; +#endif + +        U32 budget_mb = info.Budget / 1024 / 1024; +        U32 afr_mb = info.AvailableForReservation / 1024 / 1024; +        // correct for systems that misreport budget +        if (budget_mb == 0) +        {  +            // fall back to available for reservation clamped between 512MB and 2GB +            budget_mb = llclamp(afr_mb, (U32) 512, (U32) 2048); +        } + +        U32 cu_mb = info.CurrentUsage / 1024 / 1024; + +        // get an estimated usage based on texture bytes allocated +        U32 eu_mb = LLImageGL::getTextureBytesAllocated() * 2 / 1024 / 1024; + +        if (cu_mb == 0) +        { // current usage is sometimes unreliable on Intel GPUs, fall back to estimated usage +            cu_mb = llmax((U32)1, eu_mb); +        } +        F32 eu_error = (F32)((S32)eu_mb - (S32)cu_mb) / (F32)cu_mb; + +        U32 target_mb = info.Budget / 1024 / 1024; + +        if (target_mb > 4096)  // if 4GB are installed, try to leave 2GB free  +        { +            target_mb -= 2048; +        } +        else // if less than 4GB are installed, try not to use more than half of it +        { +            target_mb /= 2; +        } + +        mAvailableVRAM = cu_mb < target_mb ? target_mb - cu_mb : 0; + +        LL_INFOS("Window") << "\nLocal\nAFR: " << info.AvailableForReservation / 1024 / 1024 +            << "\nBudget: " << info.Budget / 1024 / 1024 +            << "\nCR: " << info.CurrentReservation / 1024 / 1024 +            << "\nCU: " << info.CurrentUsage / 1024 / 1024 +            << "\nEU: " << eu_mb << llformat(" (%.2f)", eu_error) +            << "\nTU: " << target_mb +            << "\nAM: " << mAvailableVRAM << LL_ENDL; + +        /*mDXGIAdapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &info); +        LL_INFOS("Window") << "\nNon-Local\nAFR: " << info.AvailableForReservation / 1024 / 1024 +            << "\nBudget: " << info.Budget / 1024 / 1024 +            << "\nCR: " << info.CurrentReservation / 1024 / 1024 +            << "\nCU: " << info.CurrentUsage / 1024 / 1024 << LL_ENDL;*/ +    } +    else if (mD3DDevice != NULL) +    { // fallback to D3D9 +        mAvailableVRAM = mD3DDevice->GetAvailableTextureMem() / 1024 / 1024; +    } +} +  void LLWindowWin32::LLWindowWin32Thread::run()  {      sWindowThreadId = std::this_thread::get_id();      LogChange logger("Window"); +    initDX(); +      while (! getQueue().done())      {          LL_PROFILE_ZONE_SCOPED_CATEGORY_WIN32;          if (mWindowHandle != 0)          { +            // lazily call initD3D inside this loop to catch when mWindowHandle has been set +            // *TODO: Shutdown if this fails when mWindowHandle exists +            initD3D(); +              MSG msg;              BOOL status;              if (mhDC == 0) @@ -4629,6 +4869,13 @@ void LLWindowWin32::LLWindowWin32Thread::run()              getQueue().runPending();          } +        // update available vram once every 3 seconds +        static LLFrameTimer vramTimer; +        if (vramTimer.getElapsedTimeF32() > 3.f) +        { +            updateVRAMUsage(); +            vramTimer.reset(); +        }  #if 0          {              LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("w32t - Sleep"); @@ -4637,6 +4884,26 @@ void LLWindowWin32::LLWindowWin32Thread::run()          }  #endif      } + +    //clean up DXGI/D3D resources +    if (mDXGIAdapter) +    { +        mDXGIAdapter->Release(); +        mDXGIAdapter = nullptr; +    } + +    if (mD3DDevice) +    { +        mD3DDevice->Release(); +        mD3DDevice = nullptr; +    } + +    if (mD3D) +    { +        mD3D->Release(); +        mD3D = nullptr; +    } +  }  void LLWindowWin32::post(const std::function<void()>& func) diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index b391acc12d..bd53b3e92a 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -108,7 +108,9 @@ public:  	/*virtual*/ F32 getPixelAspectRatio();  	/*virtual*/ void setNativeAspectRatio(F32 ratio) { mOverrideAspectRatio = ratio; } -	/*virtual*/	BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b ); +    U32 getAvailableVRAMMegabytes() override; +	 +    /*virtual*/	BOOL dialogColorPicker(F32 *r, F32 *g, F32 *b );  	/*virtual*/ void *getPlatformWindow();  	/*virtual*/ void bringToFront(); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 950697a72a..213b34b4a6 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -321,7 +321,6 @@ set(viewer_SOURCE_FILES      llfloatertelehub.cpp      llfloatertestinspectors.cpp      llfloatertestlistview.cpp -    llfloatertexturefetchdebugger.cpp      llfloatertools.cpp      llfloatertopobjects.cpp      llfloatertos.cpp @@ -967,7 +966,6 @@ set(viewer_HEADER_FILES      llfloatertelehub.h      llfloatertestinspectors.h      llfloatertestlistview.h -    llfloatertexturefetchdebugger.h      llfloatertools.h      llfloatertopobjects.h      llfloatertos.h @@ -2519,6 +2517,19 @@ if (LL_TESTS)      "${test_libs}"      ) +  set(llviewercontrollistener_test_sources +    llviewercontrollistener.cpp +    ../llxml/llcontrol.cpp +    ../llxml/llxmltree.cpp +    ../llxml/llxmlparser.cpp +    ../llcommon/commoncontrol.cpp +    ) + +  LL_ADD_INTEGRATION_TEST(llviewercontrollistener +    "${llviewercontrollistener_test_sources}" +    "${test_libs}" +    ) +    LL_ADD_INTEGRATION_TEST(llviewernetwork       llviewernetwork.cpp      "${test_libs}" diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 0d1870903b..cd33690075 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3398,6 +3398,29 @@        <key>Value</key>        <integer>0</integer>      </map> +    <!-- TODO: Remove settings keys DisablePrimaryGraphicsMemoryAccounting and DisableSecondaryGraphicsMemoryAccounting after testing, and code that references them --> +    <key>DisablePrimaryGraphicsMemoryAccounting</key> +    <map> +      <key>Comment</key> +      <string>Disable the first method used to detect GPU memory use</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>DisableSecondaryGraphicsMemoryAccounting</key> +    <map> +      <key>Comment</key> +      <string>Disable the second method used to detect GPU memory use, used as a fallback when the first method fails</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>DisableTextHyperlinkActions</key>      <map>        <key>Comment</key> @@ -3924,7 +3947,7 @@          <key>Type</key>          <string>F32</string>          <key>Value</key> -        <real>0.1</real> +        <real>1.0</real>      </map>      <key>QueueInventoryFetchTimeout</key>      <map> @@ -10458,17 +10481,6 @@        <key>Value</key>        <real>12.0</real>      </map> -    <key>RenderTextureMemoryMultiple</key> -    <map> -      <key>Comment</key> -      <string>Multiple of texture memory value to use (should fit: 0 < value <= 1.0)</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>F32</string> -      <key>Value</key> -      <real>1.0</real> -    </map>      <key>RenderTrackerBeacon</key>      <map>        <key>Comment</key> @@ -12548,17 +12560,6 @@        <key>Value</key>        <real>20.0</real>      </map> -    <key>TexelPixelRatio</key> -    <map> -      <key>Comment</key> -      <string>texel pixel ratio = texel / pixel</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>F32</string> -      <key>Value</key> -      <real>1.0</real> -    </map>      <key>TextureCameraMotionThreshold</key>      <map>        <key>Comment</key> @@ -12658,17 +12659,6 @@        <key>Value</key>        <integer>0</integer>      </map> -    <key>TextureFetchDebuggerEnabled</key> -    <map> -      <key>Comment</key> -      <string>Enable the texture fetching debugger if set</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>Boolean</string> -      <key>Value</key> -      <integer>0</integer> -    </map>      <key>TextureFetchMinTimeToLog</key>      <map>        <key>Comment</key> @@ -12691,21 +12681,10 @@      <key>Value</key>      <real>0.0</real>    </map> -    <key>TextureFetchSource</key> +    <key>TextureFetchUpdateMinCount</key>      <map>        <key>Comment</key> -      <string>Debug use: Source to fetch textures</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>S32</string> -      <key>Value</key> -      <integer>0</integer> -    </map> -    <key>TextureFetchUpdateHighPriority</key> -    <map> -      <key>Comment</key> -      <string>Number of high priority textures to update per frame</string> +      <string>Minimum number of textures to update per frame</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> @@ -12713,91 +12692,14 @@        <key>Value</key>        <integer>32</integer>      </map> -    <key>TextureFetchUpdateMaxMediumPriority</key> -    <map> -      <key>Comment</key> -      <string>Maximum number of medium priority textures to update per frame</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>S32</string> -      <key>Value</key> -      <integer>256</integer> -    </map> -    <key>TextureFetchUpdateMinMediumPriority</key> -    <map> -      <key>Comment</key> -      <string>Minimum number of medium priority textures to update per frame</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>S32</string> -      <key>Value</key> -      <integer>32</integer> -    </map> -    <key>TextureFetchUpdatePriorityThreshold</key> -    <map> -      <key>Comment</key> -      <string>Threshold under which textures will be considered too low priority and skipped for update</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>F32</string> -      <key>Value</key> -      <real>0.0</real> -    </map> -    <key>TextureFetchUpdateSkipLowPriority</key> -    <map> -      <key>Comment</key> -      <string>Flag indicating if we want to skip textures with too low of a priority</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>Boolean</string> -      <key>Value</key> -      <integer>0</integer> -    </map> -    <key>TextureFetchUpdatePriorities</key> -    <map> -      <key>Comment</key> -      <string>Number of priority texture to update per frame</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>S32</string> -      <key>Value</key> -      <integer>32</integer> -    </map> -    <key>TextureListFetchingThreshold</key> -    <map> -      <key>Comment</key> -      <string>If the ratio between fetched and all textures in the list is greater than this threshold, which we assume that almost all textures are fetched</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>F32</string> -      <key>Value</key> -      <real>0.97</real> -    </map>      <key>TextureLoadFullRes</key>      <map>        <key>Comment</key>        <string>If TRUE, always load textures at full resolution (discard = 0)</string>        <key>Persist</key> -      <integer>0</integer> -      <key>Type</key> -      <string>Boolean</string> -      <key>Value</key> -      <integer>0</integer> -    </map> -    <key>TextureMemory</key> -    <map> -      <key>Comment</key> -      <string>Amount of memory to use for textures in MB (0 = autodetect)</string> -      <key>Persist</key>        <integer>1</integer>        <key>Type</key> -      <string>S32</string> +      <string>Boolean</string>        <key>Value</key>        <integer>0</integer>      </map> @@ -12867,7 +12769,9 @@        <key>Value</key>        <map>          <key>General</key> -        <integer>4</integer> +        <integer>1</integer> +        <key>ImageDecode</key> +        <integer>9</integer>        </map>      </map>      <key>ThrottleBandwidthKBPS</key> diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 3269158903..6b4ab1be17 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -60,7 +60,6 @@ WindLightUseAtmosShaders	1	1  WLSkyDetail					1	128  Disregard128DefaultDrawDistance	1	1  Disregard96DefaultDrawDistance	1	1 -RenderTextureMemoryMultiple		1	1.0  RenderCompressTextures		1	1  RenderShaderLightingMaxLevel	1	3  RenderPBR                   1   1 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 7bad9b56f1..311b669d7f 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -60,7 +60,6 @@ WindLightUseAtmosShaders	1	1  WLSkyDetail					1	128  Disregard128DefaultDrawDistance	1	1  Disregard96DefaultDrawDistance	1	1 -RenderTextureMemoryMultiple		1	1.0  RenderCompressTextures		1	1  RenderShaderLightingMaxLevel	1	3  RenderDeferred				1	1 diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 225a14dee0..0e2828332e 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -103,7 +103,6 @@  #include "lldiskcache.h"  #include "llvopartgroup.h"  #include "llweb.h" -#include "llfloatertexturefetchdebugger.h"  #include "llspellcheck.h"  #include "llscenemonitor.h"  #include "llavatarrenderinfoaccountant.h" @@ -1551,7 +1550,6 @@ bool LLAppViewer::doFrame()  			{  				S32 non_interactive_ms_sleep_time = 100;  				LLAppViewer::getTextureCache()->pause(); -				LLAppViewer::getImageDecodeThread()->pause();  				ms_sleep(non_interactive_ms_sleep_time);  			} @@ -1571,7 +1569,6 @@ bool LLAppViewer::doFrame()  					ms_sleep(milliseconds_to_sleep);  					// also pause worker threads during this wait period  					LLAppViewer::getTextureCache()->pause(); -					LLAppViewer::getImageDecodeThread()->pause();  				}  			} @@ -1620,7 +1617,6 @@ bool LLAppViewer::doFrame()  			{  				LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df getTextureCache" )  				LLAppViewer::getTextureCache()->pause(); -				LLAppViewer::getImageDecodeThread()->pause();  				LLAppViewer::getTextureFetch()->pause();  			}  			if(!total_io_pending) //pause file threads if nothing to process. @@ -1629,21 +1625,9 @@ bool LLAppViewer::doFrame()  				LLLFSThread::sLocal->pause();  			} -			//texture fetching debugger -			if(LLTextureFetchDebugger::isEnabled()) -			{ -				LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df tex_fetch_debugger_instance" ) -				LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance = -					LLFloaterReg::findTypedInstance<LLFloaterTextureFetchDebugger>("tex_fetch_debugger"); -				if(tex_fetch_debugger_instance) -				{ -					tex_fetch_debugger_instance->idle() ; -				} -			} -  			{  				LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df resumeMainloopTimeout" ) -			resumeMainloopTimeout(); +			    resumeMainloopTimeout();  			}  			pingMainloopTimeout("Main:End");  		} @@ -1695,16 +1679,20 @@ S32 LLAppViewer::updateTextureThreads(F32 max_time)  void LLAppViewer::flushLFSIO()  { -	while (1) -	{ -		S32 pending = LLLFSThread::updateClass(0); -		if (!pending) -		{ -			break; -		} -		LL_INFOS() << "Waiting for pending IO to finish: " << pending << LL_ENDL; -		ms_sleep(100); -	} +    S32 pending = LLLFSThread::updateClass(0); +    if (pending > 0) +    { +        LL_INFOS() << "Waiting for pending IO to finish: " << pending << LL_ENDL; +        while (1) +        { +            pending = LLLFSThread::updateClass(0); +            if (!pending) +            { +                break; +            } +            ms_sleep(100); +        } +    }  }  bool LLAppViewer::cleanup() @@ -1861,8 +1849,6 @@ bool LLAppViewer::cleanup()  	LL_INFOS() << "Cache files removed" << LL_ENDL; -	// Wait for any pending LFS IO -	flushLFSIO();  	LL_INFOS() << "Shutting down Views" << LL_ENDL;  	// Destroy the UI @@ -2062,13 +2048,13 @@ bool LLAppViewer::cleanup()  	sTextureCache->shutdown();  	sImageDecodeThread->shutdown();  	sPurgeDiskCacheThread->shutdown(); -    if (mGeneralThreadPool) -    { -        mGeneralThreadPool->close(); -    } +	if (mGeneralThreadPool) +	{ +		mGeneralThreadPool->close(); +	}  	sTextureFetch->shutDownTextureCacheThread() ; -	sTextureFetch->shutDownImageDecodeThread() ; +    LLLFSThread::sLocal->shutdown();  	LL_INFOS() << "Shutting down message system" << LL_ENDL;  	end_messaging_system(); @@ -2185,14 +2171,7 @@ void LLAppViewer::initGeneralThread()          return;      } -    LLSD poolSizes{ gSavedSettings.getLLSD("ThreadPoolSizes") }; -    LLSD sizeSpec{ poolSizes["General"] }; -    LLSD::Integer poolSize{ sizeSpec.isInteger() ? sizeSpec.asInteger() : 3 }; -    LL_DEBUGS("ThreadPool") << "Instantiating General pool with " -        << poolSize << " threads" << LL_ENDL; -    // We don't want anyone, especially the main thread, to have to block -    // due to this ThreadPool being full. -    mGeneralThreadPool = new LL::ThreadPool("General", poolSize, 1024 * 1024); +    mGeneralThreadPool = new LL::ThreadPool("General", 3);      mGeneralThreadPool->start();  } @@ -2202,13 +2181,12 @@ bool LLAppViewer::initThreads()  	LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange")); -	LLLFSThread::initClass(enable_threads && false); +	LLLFSThread::initClass(enable_threads && true); // TODO: fix crashes associated with this shutdo  	// Image decoding  	LLAppViewer::sImageDecodeThread = new LLImageDecodeThread(enable_threads && true);  	LLAppViewer::sTextureCache = new LLTextureCache(enable_threads && true);  	LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(), -													sImageDecodeThread,  													enable_threads && true,  													app_metrics_qa_mode);  	LLAppViewer::sPurgeDiskCacheThread = new LLPurgeDiskCacheThread(); @@ -3279,7 +3257,7 @@ LLSD LLAppViewer::getViewerInfo() const      info["LOD_FACTOR"] = gSavedSettings.getF32("RenderVolumeLODFactor");      info["RENDER_QUALITY"] = (F32)gSavedSettings.getU32("RenderQualityPerformance");      info["GPU_SHADERS"] = gSavedSettings.getBOOL("RenderDeferred") ? "Enabled" : "Disabled"; -    info["TEXTURE_MEMORY"] = gSavedSettings.getS32("TextureMemory"); +    info["TEXTURE_MEMORY"] = gGLManager.mVRAM;  #if LL_DARWIN      info["HIDPI"] = gHiDPISupport; @@ -4711,10 +4689,6 @@ void LLAppViewer::idle()  	//  	// Special case idle if still starting up  	// -	if (LLStartUp::getStartupState() >= STATE_WORLD_INIT) -	{ -		update_texture_time(); -	}  	if (LLStartUp::getStartupState() < STATE_STARTED)  	{  		// Skip rest if idle startup returns false (essentially, no world yet) diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index cc5cb667f0..be33e1b30a 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -148,7 +148,7 @@ void LLDrawPoolTerrain::boostTerrainDetailTextures()  	for (S32 i = 0; i < 4; i++)  	{  		compp->mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); -		compp->mDetailTextures[i]->addTextureStats(1024.f*1024.f); // assume large pixel area +        gPipeline.touchTexture(compp->mDetailTextures[i], 1024.f * 1024.f);  	}  } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 499d8d161d..52aacb607c 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -2321,6 +2321,7 @@ void LLFace::resetVirtualSize()  F32 LLFace::getTextureVirtualSize()  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	F32 radius;  	F32 cos_angle_to_view_dir;	  	BOOL in_frustum = calcPixelArea(cos_angle_to_view_dir, radius); diff --git a/indra/newview/llfloaterlagmeter.cpp b/indra/newview/llfloaterlagmeter.cpp index f72f2631a1..db00f69f03 100644 --- a/indra/newview/llfloaterlagmeter.cpp +++ b/indra/newview/llfloaterlagmeter.cpp @@ -179,7 +179,7 @@ void LLFloaterLagMeter::determineClient()  		{  			mClientCause->setText( getString("client_texture_loading_cause_msg", mStringArgs) );  		} -		else if(LLViewerTexture::sBoundTextureMemory > LLViewerTexture::sMaxBoundTextureMemory) +		else if(LLViewerTexture::isMemoryForTextureLow())  		{  			mClientCause->setText( getString("client_texture_memory_cause_msg", mStringArgs) );  		} diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index f1db12ddb0..34596d165b 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1225,12 +1225,7 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()  	shadow_text->setEnabled(enabled);  	// Hardware settings -	F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple"); -	S32Megabytes min_tex_mem = LLViewerTextureList::getMinVideoRamSetting(); -	S32Megabytes max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(false, mem_multiplier); -	getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMinValue(min_tex_mem.value()); -	getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMaxValue(max_tex_mem.value()); - +	  	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") ||  		!gGLManager.mHasVertexBufferObject)  	{ diff --git a/indra/newview/llfloatertexturefetchdebugger.cpp b/indra/newview/llfloatertexturefetchdebugger.cpp deleted file mode 100644 index cda4dc8bcc..0000000000 --- a/indra/newview/llfloatertexturefetchdebugger.cpp +++ /dev/null @@ -1,480 +0,0 @@ -/**  - * @file llfloatertexturefetchdebugger.cpp - * @brief LLFloaterTextureFetchDebugger class definition - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2012, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llfloatertexturefetchdebugger.h" - -#include "lluictrlfactory.h" -#include "llbutton.h" -#include "llspinctrl.h" -#include "llresmgr.h" - -#include "llmath.h" -#include "llviewerwindow.h" -#include "llappviewer.h" -#include "lltexturefetch.h" -#include "llviewercontrol.h" -#include "llviewerassetstats.h" //gTextureTimer - -LLFloaterTextureFetchDebugger::LLFloaterTextureFetchDebugger(const LLSD& key) -	: LLFloater(key), -	mDebugger(NULL) -{ -	setTitle("Texture Fetching Debugger Floater"); -	 -	mCommitCallbackRegistrar.add("TexFetchDebugger.ChangeTexelPixelRatio",	boost::bind(&LLFloaterTextureFetchDebugger::onChangeTexelPixelRatio, this)); - -	mCommitCallbackRegistrar.add("TexFetchDebugger.Start",	boost::bind(&LLFloaterTextureFetchDebugger::onClickStart, this)); -	mCommitCallbackRegistrar.add("TexFetchDebugger.Clear",	boost::bind(&LLFloaterTextureFetchDebugger::onClickClear, this)); -	mCommitCallbackRegistrar.add("TexFetchDebugger.Close",	boost::bind(&LLFloaterTextureFetchDebugger::onClickClose, this)); -	mCommitCallbackRegistrar.add("TexFetchDebugger.ResetFetchTime",	boost::bind(&LLFloaterTextureFetchDebugger::onClickResetFetchTime, this)); - -	mCommitCallbackRegistrar.add("TexFetchDebugger.CacheRead",	boost::bind(&LLFloaterTextureFetchDebugger::onClickCacheRead, this)); -	mCommitCallbackRegistrar.add("TexFetchDebugger.CacheWrite",	boost::bind(&LLFloaterTextureFetchDebugger::onClickCacheWrite, this)); -	mCommitCallbackRegistrar.add("TexFetchDebugger.HTTPLoad",	boost::bind(&LLFloaterTextureFetchDebugger::onClickHTTPLoad, this)); -	mCommitCallbackRegistrar.add("TexFetchDebugger.Decode",	boost::bind(&LLFloaterTextureFetchDebugger::onClickDecode, this)); -	mCommitCallbackRegistrar.add("TexFetchDebugger.GLTexture",	boost::bind(&LLFloaterTextureFetchDebugger::onClickGLTexture, this)); - -	mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisCache",	boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisCache, this)); -	mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisHTTP",	boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP, this)); -	mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchAllCache",	boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchAllCache, this)); -	mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchAllHTTP",	boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchAllHTTP, this)); -} -//---------------------------------------------- - -BOOL LLFloaterTextureFetchDebugger::postBuild(void)  -{	 -	mDebugger = LLAppViewer::getTextureFetch()->getFetchDebugger(); -	mStartStatus = (S32)LLTextureFetchDebugger::IDLE; - -	//set states for buttons -	mButtonStateMap["start_btn"] = true; -	mButtonStateMap["close_btn"] = true; -	mButtonStateMap["clear_btn"] = true; -	mButtonStateMap["cacheread_btn"] = false; -	mButtonStateMap["cachewrite_btn"] = false; -	mButtonStateMap["http_btn"] = false; -	mButtonStateMap["decode_btn"] = false; -	mButtonStateMap["gl_btn"] = false; - -	mButtonStateMap["refetchviscache_btn"] = false; -	mButtonStateMap["refetchvishttp_btn"] = false; -	mButtonStateMap["refetchallcache_btn"] = false; -	mButtonStateMap["refetchallhttp_btn"] = false; - -	updateButtons(); - -	getChild<LLUICtrl>("texel_pixel_ratio")->setValue(gSavedSettings.getF32("TexelPixelRatio")); - -	return TRUE ; -} - -LLFloaterTextureFetchDebugger::~LLFloaterTextureFetchDebugger() -{ -	//stop everything -	mDebugger->setStopDebug(); -} - -void LLFloaterTextureFetchDebugger::updateButtons() -{ -	for(std::map<std::string, bool>::iterator iter = mButtonStateMap.begin(); iter != mButtonStateMap.end(); ++iter) -	{ -		if(iter->second) -		{ -			childEnable(iter->first.c_str()); -		} -		else -		{ -			childDisable(iter->first.c_str()); -		} -	} -} - -void LLFloaterTextureFetchDebugger::disableButtons() -{ -	childDisable("start_btn"); -	childDisable("clear_btn"); -	childDisable("cacheread_btn"); -	childDisable("cachewrite_btn"); -	childDisable("http_btn"); -	childDisable("decode_btn"); -	childDisable("gl_btn"); -	childDisable("refetchviscache_btn"); -	childDisable("refetchvishttp_btn"); -	childDisable("refetchallcache_btn"); -	childDisable("refetchallhttp_btn"); -} -void LLFloaterTextureFetchDebugger::setStartStatus(S32 status) -{ -	llassert_always(LLTextureFetchDebugger::IDLE == (LLTextureFetchDebugger::e_debug_state)mStartStatus) ; -	mStartStatus = status; -} -	 -bool LLFloaterTextureFetchDebugger::idleStart() -{ -	if(mStartStatus != (S32)LLTextureFetchDebugger::IDLE) -	{ -		mDebugger->startWork((LLTextureFetchDebugger::e_debug_state)mStartStatus); -		mStartStatus = (S32)LLTextureFetchDebugger::IDLE; -		return true; -	} - -	return false; -} - -void LLFloaterTextureFetchDebugger::idle() -{	 -	if(idleStart()) -	{ -		return; -	} - -	const F32 max_time = 0.005f; //5ms -	LLTextureFetchDebugger::e_debug_state state = mDebugger->getState();	 -	if(mDebugger->update(max_time)) -	{ -		switch(state) -		{ -		case LLTextureFetchDebugger::IDLE: -			break; -		case LLTextureFetchDebugger::START_DEBUG: -			mButtonStateMap["cacheread_btn"] = true; -			mButtonStateMap["http_btn"] = true; -			mButtonStateMap["refetchviscache_btn"] = true; -			mButtonStateMap["refetchvishttp_btn"] = true; -			mButtonStateMap["refetchallcache_btn"] = true; -			mButtonStateMap["refetchallhttp_btn"] = true; -			break; -		case LLTextureFetchDebugger::READ_CACHE:			 -			mButtonStateMap["decode_btn"] = true;			 -			break; -		case LLTextureFetchDebugger::WRITE_CACHE:			 -			break; -		case LLTextureFetchDebugger::DECODING: -			mButtonStateMap["gl_btn"] = true;			 -			break; -		case LLTextureFetchDebugger::HTTP_FETCHING: -			mButtonStateMap["cacheread_btn"] = true; -			mButtonStateMap["cachewrite_btn"] = true; -			mButtonStateMap["decode_btn"] = true;			 -			break; -		case LLTextureFetchDebugger::GL_TEX:			 -			break; -		case LLTextureFetchDebugger::REFETCH_VIS_CACHE:			 -			break; -		case LLTextureFetchDebugger::REFETCH_VIS_HTTP:			 -			break; -		case LLTextureFetchDebugger::REFETCH_ALL_CACHE:			 -			break; -		case LLTextureFetchDebugger::REFETCH_ALL_HTTP: -			break; -		default: -			break; -		} - -		if(state != LLTextureFetchDebugger::IDLE) -		{ -			updateButtons(); -		} -	} -} - -//---------------------- -void LLFloaterTextureFetchDebugger::onChangeTexelPixelRatio() -{ -	gSavedSettings.setF32("TexelPixelRatio", getChild<LLUICtrl>("texel_pixel_ratio")->getValue().asReal()); -} - -void LLFloaterTextureFetchDebugger::onClickStart() -{ -	disableButtons(); - -	setStartStatus((S32)LLTextureFetchDebugger::START_DEBUG);	 - -	mButtonStateMap["start_btn"] = false; - -	updateButtons(); -} - -void LLFloaterTextureFetchDebugger::onClickClose() -{ -	setVisible(FALSE); -	 -	//stop everything -	mDebugger->setStopDebug(); - -	delete this; -} - -void LLFloaterTextureFetchDebugger::onClickResetFetchTime() -{ -	gTextureTimer.start(); -	gTextureTimer.pause(); -} - -void LLFloaterTextureFetchDebugger::onClickClear() -{ -	mButtonStateMap["start_btn"] = true; -	mButtonStateMap["close_btn"] = true; -	mButtonStateMap["clear_btn"] = true; -	mButtonStateMap["cacheread_btn"] = false; -	mButtonStateMap["cachewrite_btn"] = false; -	mButtonStateMap["http_btn"] = false; -	mButtonStateMap["decode_btn"] = false; -	mButtonStateMap["gl_btn"] = false; -	mButtonStateMap["refetchviscache_btn"] = true; -	mButtonStateMap["refetchvishttp_btn"] = true; -	updateButtons(); - -	//stop everything -	mDebugger->setStopDebug(); -	mDebugger->clearHistory(); -} - -void LLFloaterTextureFetchDebugger::onClickCacheRead() -{ -	disableButtons(); - -	setStartStatus((S32)LLTextureFetchDebugger::READ_CACHE); -} - -void LLFloaterTextureFetchDebugger::onClickCacheWrite() -{ -	disableButtons(); - -	setStartStatus((S32)LLTextureFetchDebugger::WRITE_CACHE); -} - -void LLFloaterTextureFetchDebugger::onClickHTTPLoad() -{ -	disableButtons(); - -	setStartStatus((S32)LLTextureFetchDebugger::HTTP_FETCHING); -} - -void LLFloaterTextureFetchDebugger::onClickDecode() -{ -	disableButtons(); - -	setStartStatus((S32)LLTextureFetchDebugger::DECODING); -} - -void LLFloaterTextureFetchDebugger::onClickGLTexture() -{ -	disableButtons(); - -	setStartStatus((S32)LLTextureFetchDebugger::GL_TEX);	 -} - -void LLFloaterTextureFetchDebugger::onClickRefetchVisCache() -{ -	disableButtons(); - -	setStartStatus((S32)LLTextureFetchDebugger::REFETCH_VIS_CACHE); -} - -void LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP() -{ -	disableButtons(); - -	setStartStatus((S32)LLTextureFetchDebugger::REFETCH_VIS_HTTP);	 -} - -void LLFloaterTextureFetchDebugger::onClickRefetchAllCache() -{ -	disableButtons(); - -	setStartStatus((S32)LLTextureFetchDebugger::REFETCH_ALL_CACHE); -} - -void LLFloaterTextureFetchDebugger::onClickRefetchAllHTTP() -{ -	disableButtons(); - -	setStartStatus((S32)LLTextureFetchDebugger::REFETCH_ALL_HTTP);	 -} - -void LLFloaterTextureFetchDebugger::draw() -{ -	//total number of fetched textures -	{ -		getChild<LLUICtrl>("total_num_fetched_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumFetchedTextures())); -	} - -	//total number of fetching requests -	{ -		getChild<LLUICtrl>("total_num_fetching_requests_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumFetchingRequests())); -	} - -	//total number of cache hits -	{ -		getChild<LLUICtrl>("total_num_cache_hits_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumCacheHits())); -	} - -	//total number of visible textures -	{ -		getChild<LLUICtrl>("total_num_visible_tex_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumVisibleFetchedTextures())); -	} - -	//total number of visible texture fetching requests -	{ -		getChild<LLUICtrl>("total_num_visible_tex_fetch_req_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumVisibleFetchingRequests())); -	} - -	//total number of fetched data -	{ -		getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getFetchedData() >> 10));		 -		getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getDecodedData() >> 10)); -		getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getFetchedPixels() / 1000000.f)); -	} - -	//total number of visible fetched data -	{		 -		getChild<LLUICtrl>("total_fetched_vis_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getVisibleFetchedData() >> 10));		 -		getChild<LLUICtrl>("total_fetched_vis_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getVisibleDecodedData() >> 10)); -	} - -	//total number of rendered fetched data -	{ -		getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getRenderedData() >> 10));		 -		getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getRenderedDecodedData() >> 10)); -		getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRenderedPixels() / 1000000.f)); -	} - -	//total time on cache readings -	if(mDebugger->getCacheReadTime() < 0.f) -	{ -		getChild<LLUICtrl>("total_time_cache_read_label")->setTextArg("[TIME]", std::string("----")); -	} -	else -	{ -		getChild<LLUICtrl>("total_time_cache_read_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getCacheReadTime())); -	} - -	//total time on cache writings -	if(mDebugger->getCacheWriteTime() < 0.f) -	{ -		getChild<LLUICtrl>("total_time_cache_write_label")->setTextArg("[TIME]", std::string("----")); -	} -	else -	{ -		getChild<LLUICtrl>("total_time_cache_write_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getCacheWriteTime())); -	} - -	//total time on decoding -	if(mDebugger->getDecodeTime() < 0.f) -	{ -		getChild<LLUICtrl>("total_time_decode_label")->setTextArg("[TIME]", std::string("----")); -	} -	else -	{ -		getChild<LLUICtrl>("total_time_decode_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getDecodeTime())); -	} - -	//total time on gl texture creation -	if(mDebugger->getGLCreationTime() < 0.f) -	{ -		getChild<LLUICtrl>("total_time_gl_label")->setTextArg("[TIME]", std::string("----")); -	} -	else -	{ -		getChild<LLUICtrl>("total_time_gl_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getGLCreationTime())); -	} - -	//total time on HTTP fetching -	if(mDebugger->getHTTPTime() < 0.f) -	{ -		getChild<LLUICtrl>("total_time_http_label")->setTextArg("[TIME]", std::string("----")); -	} -	else -	{ -		getChild<LLUICtrl>("total_time_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getHTTPTime())); -	} - -	//total time on entire fetching -	{ -		getChild<LLUICtrl>("total_time_fetch_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getTotalFetchingTime())); -	} - -	//total time on refetching visible textures from cache -	if(mDebugger->getRefetchVisCacheTime() < 0.f) -	{ -		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", std::string("----")); -		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", std::string("----")); -		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", std::string("----")); -	} -	else -	{ -		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisCacheTime())); -		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedVisData() >> 10)); -		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedVisPixels() / 1000000.f)); -	} - -	//total time on refetching all textures from cache -	if(mDebugger->getRefetchAllCacheTime() < 0.f) -	{ -		getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[TIME]", std::string("----")); -		getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[SIZE]", std::string("----")); -		getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[PIXEL]", std::string("----")); -	} -	else -	{ -		getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchAllCacheTime())); -		getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedAllData() >> 10)); -		getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedAllPixels() / 1000000.f)); -	} - -	//total time on refetching visible textures from http -	if(mDebugger->getRefetchVisHTTPTime() < 0.f) -	{ -		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[TIME]", std::string("----")); -		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", std::string("----")); -		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", std::string("----")); -	} -	else -	{ -		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisHTTPTime())); -		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedVisData() >> 10)); -		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedVisPixels() / 1000000.f)); -	} - -	//total time on refetching all textures from http -	if(mDebugger->getRefetchAllHTTPTime() < 0.f) -	{ -		getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[TIME]", std::string("----")); -		getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[SIZE]", std::string("----")); -		getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[PIXEL]", std::string("----")); -	} -	else -	{ -		getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchAllHTTPTime())); -		getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedAllData() >> 10)); -		getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedAllPixels() / 1000000.f)); -	} - -	LLFloater::draw(); -} diff --git a/indra/newview/llfloatertexturefetchdebugger.h b/indra/newview/llfloatertexturefetchdebugger.h deleted file mode 100644 index 637f3b03e5..0000000000 --- a/indra/newview/llfloatertexturefetchdebugger.h +++ /dev/null @@ -1,77 +0,0 @@ -/**  - * @file llfloatertexturefetchdebugger.h - * @brief texture fetching debugger window, debug use only - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -#ifndef LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H -#define LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H - -#include "llfloater.h" -class LLTextureFetchDebugger; - -class LLFloaterTextureFetchDebugger : public LLFloater -{ -	friend class LLFloaterReg; -public: -	/// initialize all the callbacks for the menu - -	virtual BOOL postBuild() ; -	virtual void draw() ; -	 -	void onChangeTexelPixelRatio(); -	 -	void onClickStart(); -	void onClickClear(); -	void onClickClose(); -	void onClickResetFetchTime(); - -	void onClickCacheRead(); -	void onClickCacheWrite(); -	void onClickHTTPLoad(); -	void onClickDecode(); -	void onClickGLTexture(); - -	void onClickRefetchVisCache(); -	void onClickRefetchVisHTTP(); -	void onClickRefetchAllCache(); -	void onClickRefetchAllHTTP(); -public: -	void idle() ; - -private:	 -	LLFloaterTextureFetchDebugger(const LLSD& key); -	virtual ~LLFloaterTextureFetchDebugger(); - -	void updateButtons(); -	void disableButtons(); - -	void setStartStatus(S32 status); -	bool idleStart(); -private:	 -	LLTextureFetchDebugger* mDebugger; -	std::map<std::string, bool> mButtonStateMap; -	S32 mStartStatus; -}; - -#endif // LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 37500176ea..c101033a5d 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -222,8 +222,6 @@ LLInventoryModel::LLInventoryModel()  	mHttpOptions(),  	mHttpHeaders(),  	mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID), -	mHttpPriorityFG(0), -	mHttpPriorityBG(0),  	mCategoryLock(),  	mItemLock(),  	mValidationInfo(new LLInventoryValidationInfo) @@ -2799,7 +2797,6 @@ LLCore::HttpHandle LLInventoryModel::requestPost(bool foreground,  	handle = LLCoreHttpUtil::requestPostWithLLSD(request,  												 mHttpPolicyClass, -												 (foreground ? mHttpPriorityFG : mHttpPriorityBG),  												 url,  												 body,  												 mHttpOptions, diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index eeec89bfb0..85343cf95c 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -617,8 +617,6 @@ private:  	LLCore::HttpOptions::ptr_t			mHttpOptions;  	LLCore::HttpHeaders::ptr_t			mHttpHeaders;  	LLCore::HttpRequest::policy_t		mHttpPolicyClass; -	LLCore::HttpRequest::priority_t		mHttpPriorityFG; -	LLCore::HttpRequest::priority_t		mHttpPriorityBG;  /**                    HTTP Transport   **                                                                            ** diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp index 11aa607393..27a9758ec3 100644 --- a/indra/newview/llmaterialmgr.cpp +++ b/indra/newview/llmaterialmgr.cpp @@ -133,8 +133,7 @@ LLMaterialMgr::LLMaterialMgr():  	mHttpRequest(),  	mHttpHeaders(),  	mHttpOptions(), -	mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID), -	mHttpPriority(0) +	mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID)  {  	LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp()); @@ -699,7 +698,7 @@ void LLMaterialMgr::processGetQueue()  			<< "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL;  		LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest,  -				mHttpPolicy, mHttpPriority, capURL,  +				mHttpPolicy, capURL,   				postData, mHttpOptions, mHttpHeaders, handler);  		if (handle == LLCORE_HTTP_HANDLE_INVALID) @@ -985,7 +984,7 @@ void LLMaterialMgr::processPutQueue()  										));  			LLCore::HttpHandle handle = LLCoreHttpUtil::requestPutWithLLSD( -				mHttpRequest, mHttpPolicy, mHttpPriority, capURL, +				mHttpRequest, mHttpPolicy, capURL,  				putData, mHttpOptions, mHttpHeaders, handler);  			if (handle == LLCORE_HTTP_HANDLE_INVALID) diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h index 843dc66fbc..f76cc27db1 100644 --- a/indra/newview/llmaterialmgr.h +++ b/indra/newview/llmaterialmgr.h @@ -141,7 +141,6 @@ private:  	LLCore::HttpHeaders::ptr_t		mHttpHeaders;  	LLCore::HttpOptions::ptr_t		mHttpOptions;  	LLCore::HttpRequest::policy_t	mHttpPolicy; -	LLCore::HttpRequest::priority_t	mHttpPriority;  	U32 getMaxEntries(const LLViewerRegion* regionp);  }; diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp index bc45eb6d3a..142977e939 100644 --- a/indra/newview/llmediadataclient.cpp +++ b/indra/newview/llmediadataclient.cpp @@ -355,7 +355,7 @@ void LLMediaDataClient::serviceQueue()  		// and make the post          LLCore::HttpHandler::ptr_t handler = request->createHandler(); -        LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, mHttpPolicy, 0, +        LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, mHttpPolicy,              url, sd_payload, mHttpOpts, mHttpHeaders, handler);          if (handle == LLCORE_HTTP_HANDLE_INVALID) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index d28e929b48..6fa71e130e 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -823,8 +823,7 @@ LLMeshRepoThread::LLMeshRepoThread()    mHttpLargeOptions(),    mHttpHeaders(),    mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID), -  mHttpLargePolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID), -  mHttpPriority(0) +  mHttpLargePolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID)  {  	LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp()); @@ -1268,7 +1267,6 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url,  	if (len < LARGE_MESH_FETCH_THRESHOLD)  	{  		handle = mHttpRequest->requestGetByteRange( mHttpPolicyClass, -                                                    mHttpPriority,                                                      url,                                                      (disable_range_req ? size_t(0) : offset),                                                      (disable_range_req ? size_t(0) : len), @@ -1283,7 +1281,6 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url,  	else  	{  		handle = mHttpRequest->requestGetByteRange(mHttpLargePolicyClass, -												   mHttpPriority,  												   url,  												   (disable_range_req ? size_t(0) : offset),  												   (disable_range_req ? size_t(0) : len), @@ -2130,7 +2127,6 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data,  	mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders);  	mHttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);  	mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicy(LLAppCoreHttp::AP_UPLOADS); -	mHttpPriority = 0;  }  LLMeshUploadThread::~LLMeshUploadThread() @@ -2649,7 +2645,6 @@ void LLMeshUploadThread::doWholeModelUpload()  		LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest,  																		mHttpPolicyClass, -																		mHttpPriority,  																		mWholeModelUploadURL,  																		body,  																		mHttpOptions, @@ -2700,7 +2695,6 @@ void LLMeshUploadThread::requestWholeModelFee()  	dump_llsd_to_file(mModelData, make_dump_name("whole_model_fee_request_", dump_num));  	LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest,  																	mHttpPolicyClass, -																	mHttpPriority,  																	mWholeModelFeeCapability,  																	mModelData,  																	mHttpOptions, diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 1989350303..5459bbb4af 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -321,7 +321,6 @@ public:  	LLCore::HttpHeaders::ptr_t			mHttpHeaders;  	LLCore::HttpRequest::policy_t		mHttpPolicyClass;  	LLCore::HttpRequest::policy_t		mHttpLargePolicyClass; -	LLCore::HttpRequest::priority_t		mHttpPriority;  	typedef std::set<LLCore::HttpHandler::ptr_t> http_request_set;  	http_request_set					mHttpRequestSet;			// Outstanding HTTP requests @@ -489,7 +488,6 @@ private:  	LLCore::HttpOptions::ptr_t			mHttpOptions;  	LLCore::HttpHeaders::ptr_t			mHttpHeaders;  	LLCore::HttpRequest::policy_t		mHttpPolicyClass; -	LLCore::HttpRequest::priority_t		mHttpPriority;  };  // Params related to streaming cost, render cost, and scene complexity tracking. diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index f445bc98eb..10b3683cc8 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3367,10 +3367,10 @@ public:  				}  			}	 -			if (drawable->getVOVolume() && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) +			/*if (drawable->getVOVolume() && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))  			{  				renderTexturePriority(drawable); -			} +			}*/  			if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_POINTS))  			{ @@ -3697,7 +3697,7 @@ void LLSpatialPartition::renderDebug()  									  LLPipeline::RENDER_DEBUG_BBOXES |  									  LLPipeline::RENDER_DEBUG_NORMALS |  									  LLPipeline::RENDER_DEBUG_POINTS | -									  LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY | +									  //LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY |  									  LLPipeline::RENDER_DEBUG_TEXTURE_ANIM |  									  LLPipeline::RENDER_DEBUG_RAYCAST |  									  LLPipeline::RENDER_DEBUG_AVATAR_VOLUME | diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index d4fc6f3de2..8f4eb9438b 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -95,14 +95,13 @@ private:  	};  public: -	LLTextureCacheWorker(LLTextureCache* cache, U32 priority, const LLUUID& id, +	LLTextureCacheWorker(LLTextureCache* cache, const LLUUID& id,  						 U8* data, S32 datasize, S32 offset,  						 S32 imagesize, // for writes  						 LLTextureCache::Responder* responder)  		: LLWorkerClass(cache, "LLTextureCacheWorker"),  		  mID(id),  		  mCache(cache), -		  mPriority(priority),  		  mReadData(NULL),  		  mWriteData(data),  		  mDataSize(datasize), @@ -115,7 +114,6 @@ public:  		  mBytesToRead(0),  		  mBytesRead(0)  	{ -		mPriority &= LLWorkerThread::PRIORITY_LOWBITS;  	}  	~LLTextureCacheWorker()  	{ @@ -129,13 +127,12 @@ public:  	virtual bool doWork(S32 param); // Called from LLWorkerThread::processRequest() -	handle_t read() { addWork(0, LLWorkerThread::PRIORITY_HIGH | mPriority); return mRequestHandle; } -	handle_t write() { addWork(1, LLWorkerThread::PRIORITY_HIGH | mPriority); return mRequestHandle; } +	handle_t read() { addWork(0); return mRequestHandle; } +	handle_t write() { addWork(1); return mRequestHandle; }  	bool complete() { return checkWork(); }  	void ioComplete(S32 bytes)  	{  		mBytesRead = bytes; -		setPriority(LLWorkerThread::PRIORITY_HIGH | mPriority);  	}  private: @@ -145,7 +142,6 @@ private:  protected:  	LLTextureCache* mCache; -	U32 mPriority;  	LLUUID	mID;  	U8* mReadData; @@ -164,11 +160,11 @@ protected:  class LLTextureCacheLocalFileWorker : public LLTextureCacheWorker  {  public: -	LLTextureCacheLocalFileWorker(LLTextureCache* cache, U32 priority, const std::string& filename, const LLUUID& id, +	LLTextureCacheLocalFileWorker(LLTextureCache* cache, const std::string& filename, const LLUUID& id,  						 U8* data, S32 datasize, S32 offset,  						 S32 imagesize, // for writes  						 LLTextureCache::Responder* responder)  -			: LLTextureCacheWorker(cache, priority, id, data, datasize, offset, imagesize, responder), +			: LLTextureCacheWorker(cache, id, data, datasize, offset, imagesize, responder),  			mFileName(filename)  	{ @@ -183,6 +179,7 @@ private:  bool LLTextureCacheLocalFileWorker::doRead()  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	S32 local_size = LLAPRFile::size(mFileName, mCache->getLocalAPRFilePool());  	if (local_size > 0 && mFileName.size() > 4) @@ -207,50 +204,6 @@ bool LLTextureCacheLocalFileWorker::doRead()  		return true;  	} -#if USE_LFS_READ -	if (mFileHandle == LLLFSThread::nullHandle()) -	{ -		mImageLocal = TRUE; -		mImageSize = local_size; -		if (!mDataSize || mDataSize + mOffset > local_size) -		{ -			mDataSize = local_size - mOffset; -		} -		if (mDataSize <= 0) -		{ -			// no more data to read -			mDataSize = 0; -			return true; -		} -		mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize); -		mBytesRead = -1; -		mBytesToRead = mDataSize; -		setPriority(LLWorkerThread::PRIORITY_LOW | mPriority); -		mFileHandle = LLLFSThread::sLocal->read(local_filename, mReadData, mOffset, mDataSize, -												new ReadResponder(mCache, mRequestHandle)); -		return false; -	} -	else -	{ -		if (mBytesRead >= 0) -		{ -			if (mBytesRead != mBytesToRead) -			{ -// 				LL_WARNS() << "Error reading file from local cache: " << local_filename -// 						<< " Bytes: " << mDataSize << " Offset: " << mOffset -// 						<< " / " << mDataSize << LL_ENDL; -				mDataSize = 0; // failed -				ll_aligned_free_16(mReadData); -				mReadData = NULL; -			} -			return true; -		} -		else -		{ -			return false; -		} -	} -#else  	if (!mDataSize || mDataSize > local_size)  	{  		mDataSize = local_size; @@ -274,7 +227,6 @@ bool LLTextureCacheLocalFileWorker::doRead()  		mImageLocal = TRUE;  	}  	return true; -#endif  }  bool LLTextureCacheLocalFileWorker::doWrite() @@ -286,12 +238,12 @@ bool LLTextureCacheLocalFileWorker::doWrite()  class LLTextureCacheRemoteWorker : public LLTextureCacheWorker  {  public: -	LLTextureCacheRemoteWorker(LLTextureCache* cache, U32 priority, const LLUUID& id, +	LLTextureCacheRemoteWorker(LLTextureCache* cache, const LLUUID& id,  						 U8* data, S32 datasize, S32 offset,  						 S32 imagesize, // for writes  						 LLPointer<LLImageRaw> raw, S32 discardlevel,  						 LLTextureCache::Responder* responder)  -			: LLTextureCacheWorker(cache, priority, id, data, datasize, offset, imagesize, responder), +			: LLTextureCacheWorker(cache, id, data, datasize, offset, imagesize, responder),  			mState(INIT),  			mRawImage(raw),  			mRawDiscardLevel(discardlevel) @@ -329,6 +281,7 @@ void LLTextureCacheWorker::startWork(S32 param)  // - the code supports offset reading but this is actually never exercised in the viewer  bool LLTextureCacheRemoteWorker::doRead()  { +    LL_PROFILE_ZONE_SCOPED;  	bool done = false;  	S32 idx = -1; @@ -580,6 +533,7 @@ bool LLTextureCacheRemoteWorker::doRead()  // - the code *does not* support offset writing so there are no difference between buffer addresses and start of data  bool LLTextureCacheRemoteWorker::doWrite()  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	bool done = false;  	S32 idx = -1;	 @@ -756,6 +710,7 @@ bool LLTextureCacheRemoteWorker::doWrite()  //virtual  bool LLTextureCacheWorker::doWork(S32 param)  { +    LL_PROFILE_ZONE_SCOPED;  	bool res = false;  	if (param == 0) // read  	{ @@ -775,11 +730,13 @@ bool LLTextureCacheWorker::doWork(S32 param)  //virtual (WORKER THREAD)  void LLTextureCacheWorker::finishWork(S32 param, bool completed)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	if (mResponder.notNull())  	{  		bool success = (completed && mDataSize > 0);  		if (param == 0)  		{ +            LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("tcwfw - read");  			// read  			if (success)  			{ @@ -789,12 +746,14 @@ void LLTextureCacheWorker::finishWork(S32 param, bool completed)  			}  			else  			{ +                LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("tcwfw - read fail");  				ll_aligned_free_16(mReadData);  				mReadData = NULL;  			}  		}  		else  		{ +            LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("tcwfw - write");  			// write  			mWriteData = NULL; // we never owned data  			mDataSize = 0; @@ -806,6 +765,7 @@ void LLTextureCacheWorker::finishWork(S32 param, bool completed)  //virtual (MAIN THREAD)  void LLTextureCacheWorker::endWork(S32 param, bool aborted)  { +    LL_PROFILE_ZONE_SCOPED;  	if (aborted)  	{  		// Let the destructor handle any cleanup @@ -861,6 +821,7 @@ LLTextureCache::~LLTextureCache()  //virtual  S32 LLTextureCache::update(F32 max_time_ms)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	static LLFrameTimer timer ;  	static const F32 MAX_TIME_INTERVAL = 300.f ; //seconds. @@ -874,22 +835,6 @@ S32 LLTextureCache::update(F32 max_time_ms)  	mCompletedList.clear();  	mListMutex.unlock(); -	lockWorkers(); -	 -	for (handle_list_t::iterator iter1 = priorty_list.begin(); -		 iter1 != priorty_list.end(); ++iter1) -	{ -		handle_t handle = *iter1; -		handle_map_t::iterator iter2 = mWriters.find(handle); -		if(iter2 != mWriters.end()) -		{ -			LLTextureCacheWorker* worker = iter2->second; -			worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mPriority); -		} -	} - -	unlockWorkers();  -	  	// call 'completed' with workers list unlocked (may call readComplete() or writeComplete()  	for (responder_list_t::iterator iter1 = completed_list.begin();  		 iter1 != completed_list.end(); ++iter1) @@ -1323,6 +1268,7 @@ void LLTextureCache::updateEntryTimeStamp(S32 idx, Entry& entry)  //update an existing entry, write to header file immediately.  bool LLTextureCache::updateEntry(S32& idx, Entry& entry, S32 new_image_size, S32 new_data_size)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	S32 new_body_size = llmax(0, new_data_size - TEXTURE_CACHE_ENTRY_SIZE) ;  	if(new_image_size == entry.mImageSize && new_body_size == entry.mBodySize) @@ -1872,6 +1818,7 @@ void LLTextureCache::purgeTextures(bool validate)  // call lockWorkers() first!  LLTextureCacheWorker* LLTextureCache::getReader(handle_t handle)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	LLTextureCacheWorker* res = NULL;  	handle_map_t::iterator iter = mReaders.find(handle);  	if (iter != mReaders.end()) @@ -1883,6 +1830,7 @@ LLTextureCacheWorker* LLTextureCache::getReader(handle_t handle)  LLTextureCacheWorker* LLTextureCache::getWriter(handle_t handle)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	LLTextureCacheWorker* res = NULL;  	handle_map_t::iterator iter = mWriters.find(handle);  	if (iter != mWriters.end()) @@ -1898,6 +1846,7 @@ LLTextureCacheWorker* LLTextureCache::getWriter(handle_t handle)  // Reads imagesize from the header, updates timestamp  S32 LLTextureCache::getHeaderCacheEntry(const LLUUID& id, Entry& entry)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	LLMutexLock lock(&mHeaderMutex);	  	S32 idx = openAndReadEntry(id, entry, false);  	if (idx >= 0) @@ -1910,6 +1859,7 @@ S32 LLTextureCache::getHeaderCacheEntry(const LLUUID& id, Entry& entry)  // Writes imagesize to the header, updates timestamp  S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imagesize, S32 datasize)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	mHeaderMutex.lock();  	S32 idx = openAndReadEntry(id, entry, true); // read or create  	mHeaderMutex.unlock(); @@ -1942,13 +1892,14 @@ S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imag  // Calls from texture pipeline thread (i.e. LLTextureFetch) -LLTextureCache::handle_t LLTextureCache::readFromCache(const std::string& filename, const LLUUID& id, U32 priority, +LLTextureCache::handle_t LLTextureCache::readFromCache(const std::string& filename, const LLUUID& id,  													   S32 offset, S32 size, ReadResponder* responder)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	// Note: checking to see if an entry exists can cause a stall,  	//  so let the thread handle it  	LLMutexLock lock(&mWorkersMutex); -	LLTextureCacheWorker* worker = new LLTextureCacheLocalFileWorker(this, priority, filename, id, +	LLTextureCacheWorker* worker = new LLTextureCacheLocalFileWorker(this, filename, id,  																	 NULL, size, offset, 0,  																	 responder);  	handle_t handle = worker->read(); @@ -1956,13 +1907,14 @@ LLTextureCache::handle_t LLTextureCache::readFromCache(const std::string& filena  	return handle;  } -LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id, U32 priority, +LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id,  													   S32 offset, S32 size, ReadResponder* responder)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	// Note: checking to see if an entry exists can cause a stall,  	//  so let the thread handle it  	LLMutexLock lock(&mWorkersMutex); -	LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id, +	LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, id,  																  NULL, size, offset,  																  0, NULL, 0, responder);  	handle_t handle = worker->read(); @@ -1973,6 +1925,7 @@ LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id, U32 pri  bool LLTextureCache::readComplete(handle_t handle, bool abort)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	lockWorkers();  	handle_map_t::iterator iter = mReaders.find(handle);  	LLTextureCacheWorker* worker = NULL; @@ -2000,7 +1953,7 @@ bool LLTextureCache::readComplete(handle_t handle, bool abort)  	return (complete || abort);  } -LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 priority, +LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id,  													  U8* data, S32 datasize, S32 imagesize,  													  LLPointer<LLImageRaw> rawimage, S32 discardlevel,  													  WriteResponder* responder) @@ -2018,7 +1971,7 @@ LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 prio  		mDoPurge = !mPurgeEntryList.empty();  	}  	LLMutexLock lock(&mWorkersMutex); -	LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id, +	LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, id,  																  data, datasize, 0,  																  imagesize, rawimage, discardlevel, responder);  	handle_t handle = worker->write(); @@ -2086,6 +2039,7 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d  //return the fast cache location  bool LLTextureCache::writeToFastCache(LLUUID image_id, S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	//rescale image if needed  	if (raw.isNull() || raw->isBufferInvalid() || !raw->getData())  	{ diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index e1c752b58e..f2a5978a7c 100644 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -119,13 +119,13 @@ public:  	void setReadOnly(BOOL read_only) ;  	S64 initCache(ELLPath location, S64 maxsize, BOOL texture_cache_mismatch); -	handle_t readFromCache(const std::string& local_filename, const LLUUID& id, U32 priority, S32 offset, S32 size, +	handle_t readFromCache(const std::string& local_filename, const LLUUID& id, S32 offset, S32 size,  						   ReadResponder* responder); -	handle_t readFromCache(const LLUUID& id, U32 priority, S32 offset, S32 size, +	handle_t readFromCache(const LLUUID& id, S32 offset, S32 size,  						   ReadResponder* responder);  	bool readComplete(handle_t handle, bool abort); -	handle_t writeToCache(const LLUUID& id, U32 priority, U8* data, S32 datasize, S32 imagesize, LLPointer<LLImageRaw> rawimage, S32 discardlevel, +	handle_t writeToCache(const LLUUID& id, U8* data, S32 datasize, S32 imagesize, LLPointer<LLImageRaw> rawimage, S32 discardlevel,  						  WriteResponder* responder);  	LLPointer<LLImageRaw> readFromFastCache(const LLUUID& id, S32& discardlevel);  	bool writeComplete(handle_t handle, bool abort = false); diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 35e4bb03ac..dc10e42446 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -62,8 +62,6 @@  #include "llcorehttputil.h"  #include "llhttpretrypolicy.h" -bool LLTextureFetchDebugger::sDebuggerEnabled = false ; -  LLTrace::CountStatHandle<F64> LLTextureFetch::sCacheHit("texture_cache_hit");  LLTrace::CountStatHandle<F64> LLTextureFetch::sCacheAttempt("texture_cache_attempt");  LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > LLTextureFetch::sCacheHitRate("texture_cache_hits"); @@ -213,35 +211,17 @@ const std::string sTesterName("TextureFetchTester");  //  // Worker State Machine  // -// (ASCII art needed) -// -// -// Priority Scheme -// -// [PRIORITY_LOW, PRIORITY_NORMAL)   - for WAIT_HTTP_RESOURCE state -//									   and other wait states -// [PRIORITY_HIGH, PRIORITY_URGENT)  - External event delivered, -//                                     rapidly transitioning through states, -//                                     no waiting allowed -// -// By itself, the above work queue model would fail the concurrency -// and liveness requirements of the interface.  A high priority -// request could find itself on the head and stalled for external -// reasons (see VWR-28996).  So a few additional constraints are -// required to keep things running: -// * Anything that can make forward progress must be kept at a -//   higher priority than anything that can't. -// * On completion of external events, the associated request -//   needs to be elevated beyond the normal range to handle -//   any data delivery and release any external resource. -// -// This effort is made to keep higher-priority entities moving -// forward in their state machines at every possible step of -// processing.  It's not entirely proven that this produces the -// experiencial benefits promised. +// "doWork" will be executed for a given worker on its respective +// LLQueuedThread.  If doWork returns true, the worker is treated  +// as completed.  If doWork returns false, the worker will be  +// put on the back of the work queue at the start of the next iteration +// of the mainloop.  If a worker is waiting on a resource, it should +// return false as soon as possible and not block to avoid starving +// other workers of cpu cycles.  // +  //////////////////////////////////////////////////////////////////////////////  // Tuning/Parameterization Constants @@ -262,8 +242,8 @@ static const S32 HTTP_REQUESTS_RANGE_END_MAX = 20000000;  //////////////////////////////////////////////////////////////////////////////  namespace  { -    // The NoOpDeletor is used when passing certain objects (the LLTextureFetchWorker and -    // the LLTextureFetchDebugger) in a smart pointer below for passage into  +    // The NoOpDeletor is used when passing certain objects (the LLTextureFetchWorker) +    // in a smart pointer below for passage into       // the LLCore::Http libararies. When the smart pointer is destroyed,  no       // action will be taken since we do not in these cases want the object to       // be destroyed at the end of the call. @@ -301,7 +281,6 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler  {  	friend class LLTextureFetch; -	friend class LLTextureFetchDebugger;  private:  	class CacheReadResponder : public LLTextureCache::ReadResponder @@ -386,14 +365,7 @@ private:  		bool operator()(const LLTextureFetchWorker* lhs, const LLTextureFetchWorker* rhs) const  		{  			// greater priority is "less" -			const F32 lpriority = lhs->mImagePriority; -			const F32 rpriority = rhs->mImagePriority; -			if (lpriority > rpriority) // higher priority -				return true; -			else if (lpriority < rpriority) -				return false; -			else -				return lhs < rhs; +            return lhs->mImagePriority > rhs->mImagePriority;  		}  	}; @@ -484,6 +456,9 @@ private:  	// Locks:  Mw  	void resetFormattedData(); +    // get the relative priority of this worker (should map to max virtual size) +    F32 getImagePriority() const; +  	// Locks:  Mw  	void setImagePriority(F32 priority); @@ -500,9 +475,6 @@ private:  	// Locks:  Mw  	void setupPacketData(); -	// Locks:  Mw (ctor invokes without lock) -	U32 calcWorkPriority(); -	  	// Locks:  Mw  	void removeFromCache(); @@ -573,16 +545,13 @@ private:  	LLHost mHost;  	std::string mUrl;  	U8 mType; -	F32 mImagePriority; -	U32 mWorkPriority; +	F32 mImagePriority; // should map to max virtual size  	F32 mRequestedPriority;  	S32 mDesiredDiscard;  	S32 mSimRequestedDiscard;  	S32 mRequestedDiscard;      S32 mLoadedDiscard;      S32 mDecodedDiscard; -	S32 mFullWidth; -	S32 mFullHeight;  	LLFrameTimer mRequestedDeltaTimer;  	LLFrameTimer mFetchDeltaTimer;  	LLTimer mCacheReadTimer; @@ -923,7 +892,6 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,  	  mHost(host),  	  mUrl(url),  	  mImagePriority(priority), -	  mWorkPriority(0),  	  mRequestedPriority(0.f),  	  mDesiredDiscard(-1),  	  mSimRequestedDiscard(-1), @@ -970,17 +938,15 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,  	  mCacheReadCount(0U),  	  mCacheWriteCount(0U),  	  mResourceWaitCount(0U), -	  mFetchRetryPolicy(10.0,3600.0,2.0,10) +	  mFetchRetryPolicy(10.f,3600.f,2.f,10)  {  	mCanUseNET = mUrl.empty() ; -	calcWorkPriority();  	mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL;  // 	LL_INFOS(LOG_TXT) << "Create: " << mID << " mHost:" << host << " Discard=" << discard << LL_ENDL;  	if (!mFetcher->mDebugPause)  	{ -		U32 work_priority = mWorkPriority | LLWorkerThread::PRIORITY_HIGH; -		addWork(0, work_priority ); +		addWork(0);  	}  	setDesiredDiscard(discard, size);  } @@ -1071,16 +1037,6 @@ void LLTextureFetchWorker::setupPacketData()  }  // Locks:  Mw (ctor invokes without lock) -U32 LLTextureFetchWorker::calcWorkPriority() -{ - 	//llassert_always(mImagePriority >= 0 && mImagePriority <= LLViewerFetchedTexture::maxDecodePriority()); -	static const F32 PRIORITY_SCALE = (F32)LLWorkerThread::PRIORITY_LOWBITS / LLViewerFetchedTexture::maxDecodePriority(); - -	mWorkPriority = llmin((U32)LLWorkerThread::PRIORITY_LOWBITS, (U32)(mImagePriority * PRIORITY_SCALE)); -	return mWorkPriority; -} - -// Locks:  Mw (ctor invokes without lock)  void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)  {  	bool prioritize = false; @@ -1088,11 +1044,9 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)  	{  		if (!haveWork())  		{ -			calcWorkPriority();  			if (!mFetcher->mDebugPause)  			{ -				U32 work_priority = mWorkPriority | LLWorkerThread::PRIORITY_HIGH; -				addWork(0, work_priority); +				addWork(0);  			}  		}  		else if (mDesiredDiscard < discard) @@ -1111,23 +1065,13 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)  	if ((prioritize && mState == INIT) || mState == DONE)  	{  		setState(INIT); -		U32 work_priority = mWorkPriority | LLWorkerThread::PRIORITY_HIGH; -		setPriority(work_priority);  	}  }  // Locks:  Mw  void LLTextureFetchWorker::setImagePriority(F32 priority)  { -// 	llassert_always(priority >= 0 && priority <= LLViewerTexture::maxDecodePriority()); -	F32 delta = fabs(priority - mImagePriority); -	if (delta > (mImagePriority * .05f) || mState == DONE) -	{ -		mImagePriority = priority; -		calcWorkPriority(); -		U32 work_priority = mWorkPriority | (getPriority() & LLWorkerThread::PRIORITY_HIGHBITS); -		setPriority(work_priority); -	} +	mImagePriority = priority; //should map to max virtual size, abort if zero  }  // Locks:  Mw @@ -1147,6 +1091,11 @@ void LLTextureFetchWorker::resetFormattedData()  	mHaveAllData = FALSE;  } +F32 LLTextureFetchWorker::getImagePriority() const +{ +    return mImagePriority; +} +  // Threads:  Tmain  void LLTextureFetchWorker::startWork(S32 param)  { @@ -1156,7 +1105,7 @@ void LLTextureFetchWorker::startWork(S32 param)  // Threads:  Ttf  bool LLTextureFetchWorker::doWork(S32 param)  { -    LL_PROFILE_ZONE_SCOPED; +    LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;  	if (gNonInteractive)  	{  		return true; @@ -1171,20 +1120,23 @@ bool LLTextureFetchWorker::doWork(S32 param)  	{  		if (mState < DECODE_IMAGE)  		{ +            LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - state < decode");  			return true; // abort  		}  	} -	if(mImagePriority < F_ALMOST_ZERO) +	if (mImagePriority < F_ALMOST_ZERO)  	{  		if (mState == INIT || mState == LOAD_FROM_NETWORK || mState == LOAD_FROM_SIMULATOR)  		{ +            LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - priority < 0");  			LL_DEBUGS(LOG_TXT) << mID << " abort: mImagePriority < F_ALMOST_ZERO" << LL_ENDL;  			return true; // abort  		}  	}  	if(mState > CACHE_POST && !mCanUseNET && !mCanUseHTTP)  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - state > cache_post");  		//nowhere to get data, abort.  		LL_WARNS(LOG_TXT) << mID << " abort, nowhere to get data" << LL_ENDL;  		return true ; @@ -1206,6 +1158,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  	if (mState == INIT)  	{		 +        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - INIT");  		mStateTimer.reset();  		mFetchTimer.reset();  		for(auto i : LOGGED_STATES)  @@ -1247,15 +1200,16 @@ bool LLTextureFetchWorker::doWork(S32 param)  	if (mState == LOAD_FROM_TEXTURE_CACHE)  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - LOAD_FROM_TEXTURE_CACHE");  		if (mCacheReadHandle == LLTextureCache::nullHandle())  		{ -			U32 cache_priority = mWorkPriority;  			S32 offset = mFormattedImage.notNull() ? mFormattedImage->getDataSize() : 0;  			S32 size = mDesiredSize - offset;  			if (size <= 0)  			{  				setState(CACHE_POST); -				return false; +                return doWork(param); +                // return false;  			}  			mFileSize = 0;  			mLoaded = FALSE;			 @@ -1264,35 +1218,28 @@ bool LLTextureFetchWorker::doWork(S32 param)  			if (mUrl.compare(0, 7, "file://") == 0)  			{ -				setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it -  				// read file from local disk  				++mCacheReadCount;  				std::string filename = mUrl.substr(7, std::string::npos);  				CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);  				mCacheReadTimer.reset();   -				mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, cache_priority, -																		  offset, size, responder); +				mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, offset, size, responder);  			}  			else if ((mUrl.empty() || mFTType==FTT_SERVER_BAKE) && mFetcher->canLoadFromCache())  			{ -				setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it -  				++mCacheReadCount;  				CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);  				mCacheReadTimer.reset(); -				mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID, cache_priority, +				mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID,  																		  offset, size, responder);;  			}  			else if(!mUrl.empty() && mCanUseHTTP)  			{ -				setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  				setState(WAIT_HTTP_RESOURCE);  			}  			else  			{ -				setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  				setState(LOAD_FROM_NETWORK);  			}  		} @@ -1325,6 +1272,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  	if (mState == CACHE_POST)  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - CACHE_POST");  		mCachedSize = mFormattedImage.notNull() ? mFormattedImage->getDataSize() : 0;  		// Successfully loaded  		if ((mCachedSize >= mDesiredSize) || mHaveAllData) @@ -1366,6 +1314,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  	if (mState == LOAD_FROM_NETWORK)  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - LOAD_FROM_NETWORK");  		// Check for retries to previous server failures.  		F32 wait_seconds;  		if (mFetchRetryPolicy.shouldRetry(wait_seconds)) @@ -1399,7 +1348,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  				{  					if (mFTType != FTT_DEFAULT)  					{ -						LL_WARNS(LOG_TXT) << "trying to seek a non-default texture on the sim. Bad!" << LL_ENDL; +                        LL_WARNS(LOG_TXT) << "Trying to fetch a texture of non-default type by UUID. This probably won't work!" << LL_ENDL;  					}  					setUrl(http_url + "/?texture_id=" + mID.asString().c_str());  					LL_DEBUGS(LOG_TXT) << "Texture URL: " << mUrl << LL_ENDL; @@ -1427,7 +1376,6 @@ bool LLTextureFetchWorker::doWork(S32 param)  		if (mCanUseHTTP && !mUrl.empty())  		{  			setState(WAIT_HTTP_RESOURCE); -			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  			if(mWriteToCacheState != NOT_WRITE)  			{  				mWriteToCacheState = CAN_WRITE ; @@ -1444,25 +1392,19 @@ bool LLTextureFetchWorker::doWork(S32 param)  			mSentRequest = QUEUED;  			mFetcher->addToNetworkQueue(this);  			recordTextureStart(false); -			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); -			  			return false;  		}  		else  		{  			// Shouldn't need to do anything here -			//llassert_always(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end()); -			// Make certain this is in the network queue -			//mFetcher->addToNetworkQueue(this); -			//recordTextureStart(false); -			//setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); - +			//llassert(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end());  			return false;  		}  	}  	if (mState == LOAD_FROM_SIMULATOR)  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - LOAD_FROM_SIMULATOR");  		if (mFormattedImage.isNull())  		{  			mFormattedImage = new LLImageJ2C; @@ -1492,7 +1434,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  				LL_WARNS(LOG_TXT) << mID << " processSimulatorPackets() failed to load buffer" << LL_ENDL;  				return true; // failed  			} -			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); +  			if (mLoadedDiscard < 0)  			{  				LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard @@ -1506,7 +1448,6 @@ bool LLTextureFetchWorker::doWork(S32 param)  		else  		{  			mFetcher->addToNetworkQueue(this); // failsafe -			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);  			recordTextureStart(false);  		}  		return false; @@ -1514,6 +1455,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  	if (mState == WAIT_HTTP_RESOURCE)  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_HTTP_RESOURCE");  		// NOTE:  		// control the number of the http requests issued for:  		// 1, not openning too many file descriptors at the same time; @@ -1524,7 +1466,6 @@ bool LLTextureFetchWorker::doWork(S32 param)  		if (mFetcher->getHttpWaitersCount() || ! acquireHttpSemaphore())  		{  			setState(WAIT_HTTP_RESOURCE2); -			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);  			mFetcher->addHttpWaiter(this->mID);  			++mResourceWaitCount;  			return false; @@ -1538,12 +1479,14 @@ bool LLTextureFetchWorker::doWork(S32 param)  	if (mState == WAIT_HTTP_RESOURCE2)  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_HTTP_RESOURCE2");  		// Just idle it if we make it to the head...  		return false;  	}  	if (mState == SEND_HTTP_REQ)  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - SEND_HTTP_REQ");  		// Also used in llmeshrepository  		static LLCachedControl<bool> disable_range_req(gSavedSettings, "HttpRangeRequestsDisable", false); @@ -1566,7 +1509,6 @@ bool LLTextureFetchWorker::doWork(S32 param)  				{  					// We already have all the data, just decode it  					mLoadedDiscard = mFormattedImage->getDiscardLevel(); -					setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  					if (mLoadedDiscard < 0)  					{  						LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard @@ -1574,7 +1516,8 @@ bool LLTextureFetchWorker::doWork(S32 param)  					}  					setState(DECODE_IMAGE);  					releaseHttpSemaphore(); -					return false; +					//return false; +                    return doWork(param);  				}  				else  				{ @@ -1635,7 +1578,6 @@ bool LLTextureFetchWorker::doWork(S32 param)  			// by people with questionable ISPs or networking gear that  			// doesn't handle these well.  			mHttpHandle = mFetcher->mHttpRequest->requestGet(mHttpPolicyClass, -															 mWorkPriority,  															 mUrl,  															 options,  															 mFetcher->mHttpHeaders, @@ -1644,7 +1586,6 @@ bool LLTextureFetchWorker::doWork(S32 param)  		else  		{  			mHttpHandle = mFetcher->mHttpRequest->requestGetByteRange(mHttpPolicyClass, -																	  mWorkPriority,  																	  mUrl,  																	  mRequestedOffset,  																	  (mRequestedOffset + mRequestedSize) > HTTP_REQUESTS_RANGE_END_MAX @@ -1669,7 +1610,6 @@ bool LLTextureFetchWorker::doWork(S32 param)  		mHttpActive = true;  		mFetcher->addToHTTPQueue(mID);  		recordTextureStart(true); -		setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);  		setState(WAIT_HTTP_REQ);	  		// fall through @@ -1677,6 +1617,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  	if (mState == WAIT_HTTP_REQ)  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_HTTP_REQ");  		// *NOTE:  As stated above, all transitions out of this state should  		// call releaseHttpSemaphore().  		if (mLoaded) @@ -1708,9 +1649,9 @@ bool LLTextureFetchWorker::doWork(S32 param)  						setState(INIT);  						mCanUseHTTP = false;  						mUrl.clear(); -						setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  						releaseHttpSemaphore(); -						return false; +						//return false; +                        return doWork(param);  					}  				}  				else if (http_service_unavail == mGetStatus) @@ -1730,7 +1671,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  									  << LL_ENDL;  				} -				if (mFTType != FTT_SERVER_BAKE) +                if (mFTType != FTT_SERVER_BAKE && mFTType != FTT_MAP_TILE)  				{  					mUrl.clear();  				} @@ -1738,7 +1679,6 @@ bool LLTextureFetchWorker::doWork(S32 param)  				{  					// Use available data  					mLoadedDiscard = mFormattedImage->getDiscardLevel(); -					setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  					if (mLoadedDiscard < 0)  					{  						LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard @@ -1746,7 +1686,8 @@ bool LLTextureFetchWorker::doWork(S32 param)  					}  					setState(DECODE_IMAGE);  					releaseHttpSemaphore(); -					return false;  +					//return false;  +                    return doWork(param);  				}  				// Fail harder @@ -1863,9 +1804,9 @@ bool LLTextureFetchWorker::doWork(S32 param)  			{  				mWriteToCacheState = SHOULD_WRITE ;  			} -			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  			releaseHttpSemaphore(); -			return false; +			//return false; +            return doWork(param);  		}  		else  		{ @@ -1875,17 +1816,16 @@ bool LLTextureFetchWorker::doWork(S32 param)  			// an enormous amount of time to load textures.  We'll revisit the  			// various possible timeout components (total request time, connection  			// time, I/O time, with and without retries, etc.) in the future. - -			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); +			  			return false;  		}  	}  	if (mState == DECODE_IMAGE)  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - DECODE_IMAGE");  		static LLCachedControl<bool> textures_decode_disabled(gSavedSettings, "TextureDecodeDisabled", false); -		setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it  		if (textures_decode_disabled)  		{  			// for debug use, don't decode @@ -1924,25 +1864,20 @@ bool LLTextureFetchWorker::doWork(S32 param)  		mAuxImage = NULL;  		llassert_always(mFormattedImage.notNull());  		S32 discard = mHaveAllData ? 0 : mLoadedDiscard; -		U32 image_priority = LLWorkerThread::PRIORITY_NORMAL | mWorkPriority;  		mDecoded  = FALSE;  		setState(DECODE_IMAGE_UPDATE);  		LL_DEBUGS(LOG_TXT) << mID << ": Decoding. Bytes: " << mFormattedImage->getDataSize() << " Discard: " << discard  						   << " All Data: " << mHaveAllData << LL_ENDL; -		mDecodeHandle = mFetcher->mImageDecodeThread->decodeImage(mFormattedImage, image_priority, discard, mNeedsAux, +		mDecodeHandle = LLAppViewer::getImageDecodeThread()->decodeImage(mFormattedImage, discard, mNeedsAux,  																  new DecodeResponder(mFetcher, mID, this));  		// fall though  	}  	if (mState == DECODE_IMAGE_UPDATE)  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - DECODE_IMAGE_UPDATE");  		if (mDecoded)  		{ -			if(mFetcher->getFetchDebugger() && !mInLocalCache) -			{ -				mFetcher->getFetchDebugger()->addHistoryEntry(this); -			} -              mDecodeTime = mDecodeTimer.getElapsedTimeF32();  			if (mDecodedDiscard < 0) @@ -1954,9 +1889,9 @@ bool LLTextureFetchWorker::doWork(S32 param)  					llassert_always(mDecodeHandle == 0);  					mFormattedImage = NULL;  					++mRetryAttempt; -					setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  					setState(INIT); -					return false; +					//return false; +                    return doWork(param);  				}  				else  				{ @@ -1969,7 +1904,6 @@ bool LLTextureFetchWorker::doWork(S32 param)  				llassert_always(mRawImage.notNull());  				LL_DEBUGS(LOG_TXT) << mID << ": Decoded. Discard: " << mDecodedDiscard  								   << " Raw Image: " << llformat("%dx%d",mRawImage->getWidth(),mRawImage->getHeight()) << LL_ENDL; -				setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  				setState(WRITE_TO_CACHE);  			}  			// fall through @@ -1982,12 +1916,14 @@ bool LLTextureFetchWorker::doWork(S32 param)  	if (mState == WRITE_TO_CACHE)  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WRITE_TO_CACHE");  		if (mWriteToCacheState != SHOULD_WRITE || mFormattedImage.isNull())  		{  			// If we're in a local cache or we didn't actually receive any new data,  			// or we failed to load anything, skip  			setState(DONE); -			return false; +			//return false; +            return doWork(param);  		}  		S32 datasize = mFormattedImage->getDataSize();  		if(mFileSize < datasize)//This could happen when http fetching and sim fetching mixed. @@ -2002,8 +1938,6 @@ bool LLTextureFetchWorker::doWork(S32 param)  			}  		}  		llassert_always(datasize); -		setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it -		U32 cache_priority = mWorkPriority;  		mWritten = FALSE;  		setState(WAIT_ON_WRITE);  		++mCacheWriteCount; @@ -2014,7 +1948,7 @@ bool LLTextureFetchWorker::doWork(S32 param)          // So make sure users of getRequestFinished() does not attempt to modify image while          // fetcher is working  		mCacheWriteTimer.reset(); -		mCacheWriteHandle = mFetcher->mTextureCache->writeToCache(mID, cache_priority, +		mCacheWriteHandle = mFetcher->mTextureCache->writeToCache(mID,  																  mFormattedImage->getData(), datasize,  																  mFileSize, mRawImage, mDecodedDiscard, responder);  		// fall through @@ -2022,6 +1956,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  	if (mState == WAIT_ON_WRITE)  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_ON_WRITE");  		if (writeToCacheComplete())  		{  			mCacheWriteTime = mCacheWriteTimer.getElapsedTimeF32(); @@ -2043,6 +1978,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  	if (mState == DONE)  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - DONE");  		if (mDecodedDiscard >= 0 && mDesiredDiscard < mDecodedDiscard)  		{  			// More data was requested, return to INIT @@ -2050,12 +1986,11 @@ bool LLTextureFetchWorker::doWork(S32 param)  			LL_DEBUGS(LOG_TXT) << mID << " more data requested, returning to INIT: "   							   << " mDecodedDiscard " << mDecodedDiscard << ">= 0 && mDesiredDiscard " << mDesiredDiscard  							   << "<" << " mDecodedDiscard " << mDecodedDiscard << LL_ENDL; -			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); -			return false; +			// return false; +            return doWork(param);  		}  		else  		{ -			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);              mFetchTime = mFetchTimer.getElapsedTimeF32();  			return true;  		} @@ -2068,6 +2003,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  // virtual  void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)  { +    LL_PROFILE_ZONE_SCOPED;  	static LLCachedControl<bool> log_to_viewer_log(gSavedSettings, "LogTextureDownloadsToViewerLog", false);  	static LLCachedControl<bool> log_to_sim(gSavedSettings, "LogTextureDownloadsToSimulator", false);  	static LLCachedControl<bool> log_texture_traffic(gSavedSettings, "LogTextureNetworkTraffic", false) ; @@ -2177,9 +2113,10 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe  // Threads:  Tmain  void LLTextureFetchWorker::endWork(S32 param, bool aborted)  { +	LL_PROFILE_ZONE_SCOPED;  	if (mDecodeHandle != 0)  	{ -		mFetcher->mImageDecodeThread->abortRequest(mDecodeHandle, false); +		// LL::ThreadPool has no operation to cancel a particular work item  		mDecodeHandle = 0;  	}  	mFormattedImage = NULL; @@ -2192,6 +2129,7 @@ void LLTextureFetchWorker::endWork(S32 param, bool aborted)  // virtual  void LLTextureFetchWorker::finishWork(S32 param, bool completed)  { +    LL_PROFILE_ZONE_SCOPED;  	// The following are required in case the work was aborted  	if (mCacheReadHandle != LLTextureCache::nullHandle())  	{ @@ -2445,7 +2383,6 @@ S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response,  	}  	mLoaded = TRUE; -	setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  	if (LLViewerStatsRecorder::instanceExists())  	{ @@ -2461,6 +2398,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response,  void LLTextureFetchWorker::callbackCacheRead(bool success, LLImageFormatted* image,  											 S32 imagesize, BOOL islocal)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	LLMutexLock lock(&mWorkMutex);										// +Mw  	if (mState != LOAD_FROM_TEXTURE_CACHE)  	{ @@ -2480,7 +2418,6 @@ void LLTextureFetchWorker::callbackCacheRead(bool success, LLImageFormatted* ima  		}  	}  	mLoaded = TRUE; -	setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  }																		// -Mw  // Threads:  Ttc @@ -2493,7 +2430,6 @@ void LLTextureFetchWorker::callbackCacheWrite(bool success)  		return;  	}  	mWritten = TRUE; -	setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  }																		// -Mw  ////////////////////////////////////////////////////////////////////////////// @@ -2532,7 +2468,6 @@ void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImag  	}  	mDecoded = TRUE;  // 	LL_INFOS(LOG_TXT) << mID << " : DECODE COMPLETE " << LL_ENDL; -	setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  }																		// -Mw  ////////////////////////////////////////////////////////////////////////////// @@ -2595,7 +2530,17 @@ void LLTextureFetchWorker::recordTextureDone(bool is_http, F64 byte_count)  //////////////////////////////////////////////////////////////////////////////  // public -LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode) +std::string LLTextureFetch::getStateString(S32 state) +{ +    if (state < 0 || state > sizeof(e_state_name) / sizeof(char*)) +    { +        return llformat("%d", state); +    } + +    return e_state_name[state]; +} + +LLTextureFetch::LLTextureFetch(LLTextureCache* cache, bool threaded, bool qa_mode)  	: LLWorkerThread("TextureFetch", threaded, true),  	  mDebugCount(0),  	  mDebugPause(FALSE), @@ -2604,7 +2549,6 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image  	  mQueueMutex(),  	  mNetworkQueueMutex(),  	  mTextureCache(cache), -	  mImageDecodeThread(imagedecodethread),  	  mTextureBandwidth(0),  	  mHTTPTextureBits(0),  	  mTotalHTTPRequests(0), @@ -2619,10 +2563,8 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image  	  mTotalCacheReadCount(0U),  	  mTotalCacheWriteCount(0U),  	  mTotalResourceWaitCount(0U), -	  mFetchDebugger(NULL),  	  mFetchSource(LLTextureFetch::FROM_ALL),  	  mOriginFetchSource(LLTextureFetch::FROM_ALL), -	  mFetcherLocked(FALSE),  	  mTextureInfoMainThread(false)  {  	mMaxBandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS"); @@ -2643,21 +2585,6 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image  	mHttpLowWater = HTTP_NONPIPE_REQUESTS_LOW_WATER;  	mHttpSemaphore = 0; -	// Conditionally construct debugger object after 'this' is -	// fully initialized. -	LLTextureFetchDebugger::sDebuggerEnabled = gSavedSettings.getBOOL("TextureFetchDebuggerEnabled"); -	if(LLTextureFetchDebugger::isEnabled()) -	{ -		mFetchDebugger = new LLTextureFetchDebugger(this, cache, imagedecodethread) ; -		mFetchSource = (e_tex_source)gSavedSettings.getS32("TextureFetchSource"); -		if(mFetchSource < 0 && mFetchSource >= INVALID_SOURCE) -		{ -			mFetchSource = LLTextureFetch::FROM_ALL; -			gSavedSettings.setS32("TextureFetchSource", 0); -		} -		mOriginFetchSource = mFetchSource; -	} -  	// If that test log has ben requested but not yet created, create it  	if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName))  	{ @@ -2686,19 +2613,13 @@ LLTextureFetch::~LLTextureFetch()  	delete mHttpRequest;  	mHttpRequest = NULL; -	delete mFetchDebugger; -	mFetchDebugger = NULL; -	  	// ~LLQueuedThread() called here  }  bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,  								   S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http)  { -	if(mFetcherLocked) -	{ -		return false; -	} +    LL_PROFILE_ZONE_SCOPED;  	if (mDebugPause)  	{  		return false; @@ -2773,6 +2694,11 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const  			return false; // need to wait for previous aborted request to complete  		}  		worker->lockWorkMutex();										// +Mw +        if (worker->mState == LLTextureFetchWorker::DONE && worker->mDesiredSize == llmax(desired_size, TEXTURE_CACHE_ENTRY_SIZE) && worker->mDesiredDiscard == desired_discard) { +			worker->unlockWorkMutex();									// -Mw + +            return false; // similar request has failed or is in a transitional state +        }  		worker->mActiveCount++;  		worker->mNeedsAux = needs_aux;  		worker->setImagePriority(priority); @@ -2786,7 +2712,7 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const  			worker->setState(LLTextureFetchWorker::INIT);  			worker->unlockWorkMutex();									// -Mw -			worker->addWork(0, LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority); +			worker->addWork(0);  		}  		else  		{ @@ -2818,6 +2744,7 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const  // protected  void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker)  { +    LL_PROFILE_ZONE_SCOPED;  	lockQueue();														// +Mfq  	bool in_request_map = (mRequestMap.find(worker->mID) != mRequestMap.end()) ;  	unlockQueue();														// -Mfq @@ -2839,6 +2766,7 @@ void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker)  // Threads:  T*  void LLTextureFetch::removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel)  { +    LL_PROFILE_ZONE_SCOPED;  	LLMutexLock lock(&mNetworkQueueMutex);								// +Mfnq  	size_t erased = mNetworkQueue.erase(worker->mID);  	if (cancel && erased > 0) @@ -2852,6 +2780,7 @@ void LLTextureFetch::removeFromNetworkQueue(LLTextureFetchWorker* worker, bool c  // protected  void LLTextureFetch::addToHTTPQueue(const LLUUID& id)  { +    LL_PROFILE_ZONE_SCOPED;  	LLMutexLock lock(&mNetworkQueueMutex);								// +Mfnq  	mHTTPTextureQueue.insert(id);  	mTotalHTTPRequests++; @@ -2860,6 +2789,7 @@ void LLTextureFetch::addToHTTPQueue(const LLUUID& id)  // Threads:  T*  void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id, S32Bytes received_size)  { +    LL_PROFILE_ZONE_SCOPED;  	LLMutexLock lock(&mNetworkQueueMutex);								// +Mfnq  	mHTTPTextureQueue.erase(id);  	mHTTPTextureBits += received_size; // Approximate - does not include header bits	 @@ -2872,6 +2802,7 @@ void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id, S32Bytes received_siz  // Threads:  T*  void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel)  { +    LL_PROFILE_ZONE_SCOPED;  	lockQueue();														// +Mfq  	LLTextureFetchWorker* worker = getWorkerAfterLock(id);  	if (worker) @@ -2898,6 +2829,7 @@ void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel)  // Threads:  T*  void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel)  { +    LL_PROFILE_ZONE_SCOPED;  	if(!worker)  	{  		return; @@ -2967,6 +2899,7 @@ U32 LLTextureFetch::getTotalNumHTTPRequests()  // Locks:  Mfq  LLTextureFetchWorker* LLTextureFetch::getWorkerAfterLock(const LLUUID& id)  { +    LL_PROFILE_ZONE_SCOPED;  	LLTextureFetchWorker* res = NULL;  	map_t::iterator iter = mRequestMap.find(id);  	if (iter != mRequestMap.end()) @@ -2990,6 +2923,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,  										LLPointer<LLImageRaw>& raw, LLPointer<LLImageRaw>& aux,  										LLCore::HttpStatus& last_http_get_status)  { +    LL_PROFILE_ZONE_SCOPED;  	bool res = false;  	LLTextureFetchWorker* worker = getWorker(id);  	if (worker) @@ -3004,7 +2938,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,  			if (!mDebugPause)  			{  // 				LL_WARNS(LOG_TXT) << "Adding work for inactive worker: " << id << LL_ENDL; -				worker->addWork(0, LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority); +				worker->addWork(0);  			}  		}  		else if (worker->checkWork()) @@ -3080,16 +3014,19 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,  // Threads:  T*  bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority)  { -	bool res = false; -	LLTextureFetchWorker* worker = getWorker(id); -	if (worker) -	{ -		worker->lockWorkMutex();										// +Mw -		worker->setImagePriority(priority); -		worker->unlockWorkMutex();										// -Mw -		res = true; -	} -	return res; +    LL_PROFILE_ZONE_SCOPED; +    mRequestQueue.tryPost([=]() +        { +            LLTextureFetchWorker* worker = getWorker(id); +            if (worker) +            { +                worker->lockWorkMutex();										// +Mw +                worker->setImagePriority(priority); +                worker->unlockWorkMutex();										// -Mw +            } +        }); +	 +	return true;  }  // Replicates and expands upon the base class's @@ -3106,6 +3043,7 @@ bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority)  //virtual  S32 LLTextureFetch::getPending()  { +    LL_PROFILE_ZONE_SCOPED;  	S32 res;  	lockData();															// +Ct      { @@ -3139,7 +3077,7 @@ bool LLTextureFetch::runCondition()  	}																	// -Mfq  	return ! (have_no_commands -			  && (mRequestQueue.empty() && mIdleThread));		// From base class +			  && (mRequestQueue.size() == 0 && mIdleThread));		// From base class  }  ////////////////////////////////////////////////////////////////////////////// @@ -3147,6 +3085,7 @@ bool LLTextureFetch::runCondition()  // Threads:  Ttf  void LLTextureFetch::commonUpdate()  { +    LL_PROFILE_ZONE_SCOPED;  	// Update low/high water levels based on pipelining.  We pick  	// up setting eventually, so the semaphore/request level can  	// fall outside the [0..HIGH_WATER] range.  Expect that. @@ -3183,6 +3122,7 @@ void LLTextureFetch::commonUpdate()  //virtual  S32 LLTextureFetch::update(F32 max_time_ms)  { +    LL_PROFILE_ZONE_SCOPED;  	static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS", 3000.0);  	{ @@ -3213,11 +3153,6 @@ S32 LLTextureFetch::update(F32 max_time_ms)  		commonUpdate();  	} -	if (mFetchDebugger) -	{ -		mFetchDebugger->tryToStopDebug(); //check if need to stop debugger. -	} -  	return res;  } @@ -3233,18 +3168,6 @@ void LLTextureFetch::shutDownTextureCacheThread()  	}  } -// called in the MAIN thread after the ImageDecodeThread shuts down. -// -// Threads:  Tmain -void LLTextureFetch::shutDownImageDecodeThread()  -{ -	if(mImageDecodeThread) -	{ -		llassert_always(mImageDecodeThread->isQuitting() || mImageDecodeThread->isStopped()) ; -		mImageDecodeThread = NULL ; -	} -} -  // Threads:  Ttf  void LLTextureFetch::startThread()  { @@ -3266,6 +3189,7 @@ void LLTextureFetch::endThread()  // Threads:  Ttf  void LLTextureFetch::threadedUpdate()  { +    LL_PROFILE_ZONE_SCOPED;  	llassert_always(mHttpRequest);  #if 0 @@ -3301,6 +3225,7 @@ void LLTextureFetch::threadedUpdate()  // Threads:  Tmain  void LLTextureFetch::sendRequestListToSimulators()  { +    LL_PROFILE_ZONE_SCOPED;  	// All requests  	const F32 REQUEST_DELTA_TIME = 0.10f; // 10 fps @@ -3351,7 +3276,6 @@ void LLTextureFetch::sendRequestListToSimulators()  				req->mLastPacket >= req->mTotalPackets-1)  			{  				// We have all the packets... make sure this is high priority -// 			req->setPriority(LLWorkerThread::PRIORITY_HIGH | req->mWorkPriority);  				continue;  			}  			F32 elapsed = req->mRequestedDeltaTimer.getElapsedTimeF32(); @@ -3499,6 +3423,7 @@ void LLTextureFetch::sendRequestListToSimulators()  // Locks:  Mw  bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)  { +    LL_PROFILE_ZONE_SCOPED;  	mRequestedDeltaTimer.reset();  	if (index >= mTotalPackets)  	{ @@ -3531,6 +3456,7 @@ bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)  void LLTextureFetchWorker::setState(e_state new_state)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	if (mFTType == FTT_SERVER_BAKE)  	{  	// NOTE: turning on these log statements is a reliable way to get @@ -3552,7 +3478,7 @@ void LLTextureFetchWorker::setState(e_state new_state)  			mSkippedStatesTime += d_time;  		}  	} -	 +  	mStateTimer.reset();  	mState = new_state;  } @@ -3561,6 +3487,7 @@ void LLTextureFetchWorker::setState(e_state new_state)  bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes,  										U16 data_size, U8* data)  { +    LL_PROFILE_ZONE_SCOPED;  	LLTextureFetchWorker* worker = getWorker(id);  	bool res = true; @@ -3612,7 +3539,6 @@ bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8  	llassert_always(totalbytes > 0);  	llassert_always(data_size == FIRST_PACKET_SIZE || data_size == worker->mFileSize);  	res = worker->insertPacket(0, data, data_size); -	worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);  	worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR);  	worker->unlockWorkMutex();											// -Mw  	return res; @@ -3622,6 +3548,7 @@ bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8  // Threads:  T*  bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data)  { +    LL_PROFILE_ZONE_SCOPED;  	LLTextureFetchWorker* worker = getWorker(id);  	bool res = true; @@ -3662,7 +3589,6 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1  	if ((worker->mState == LLTextureFetchWorker::LOAD_FROM_SIMULATOR) ||  		(worker->mState == LLTextureFetchWorker::LOAD_FROM_NETWORK))  	{ -		worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);  		worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR);  	}  	else @@ -3707,10 +3633,23 @@ BOOL LLTextureFetch::isFromLocalCache(const LLUUID& id)  	return from_cache ;  } +S32 LLTextureFetch::getFetchState(const LLUUID& id) +{ +    S32 state = LLTextureFetchWorker::INVALID; +    LLTextureFetchWorker* worker = getWorker(id); +    if (worker && worker->haveWork()) +    { +        state = worker->mState; +    } + +    return state; +} +  // Threads:  T*  S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& requested_priority_p,  								  U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p, bool& can_use_http)  { +    LL_PROFILE_ZONE_SCOPED;  	S32 state = LLTextureFetchWorker::INVALID;  	F32 data_progress = 0.0f;  	F32 requested_priority = 0.0f; @@ -3746,7 +3685,7 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r  		{  			requested_priority = worker->mImagePriority;  		} -		fetch_priority = worker->getPriority(); +		fetch_priority = worker->getImagePriority();  		can_use_http = worker->getCanUseHTTP() ;  		worker->unlockWorkMutex();										// -Mw  	} @@ -3760,19 +3699,6 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r  void LLTextureFetch::dump()  { -	LL_INFOS(LOG_TXT) << "LLTextureFetch REQUESTS:" << LL_ENDL; -	for (request_queue_t::iterator iter = mRequestQueue.begin(); -		 iter != mRequestQueue.end(); ++iter) -	{ -		LLQueuedThread::QueuedRequest* qreq = *iter; -		LLWorkerThread::WorkRequest* wreq = (LLWorkerThread::WorkRequest*)qreq; -		LLTextureFetchWorker* worker = (LLTextureFetchWorker*)wreq->getWorkerClass(); -		LL_INFOS(LOG_TXT) << " ID: " << worker->mID -						  << " PRI: " << llformat("0x%08x",wreq->getPriority()) -						  << " STATE: " << sStateDescs[worker->mState] -						  << LL_ENDL; -	} -  	LL_INFOS(LOG_TXT) << "LLTextureFetch ACTIVE_HTTP:" << LL_ENDL;  	for (queue_t::const_iterator iter(mHTTPTextureQueue.begin());  		 mHTTPTextureQueue.end() != iter; @@ -3839,6 +3765,7 @@ bool LLTextureFetch::isHttpWaiter(const LLUUID & tid)  // Locks:  -Mw (must not hold any worker when called)  void LLTextureFetch::releaseHttpWaiters()  { +    LL_PROFILE_ZONE_SCOPED;  	// Use mHttpSemaphore rather than mHTTPTextureQueue.size()  	// to avoid a lock.    	if (mHttpSemaphore >= mHttpLowWater) @@ -3935,7 +3862,6 @@ void LLTextureFetch::releaseHttpWaiters()  		}  		worker->setState(LLTextureFetchWorker::SEND_HTTP_REQ); -		worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);  		worker->unlockWorkMutex();										// -Mw  		removeHttpWaiter(worker->mID); @@ -4025,6 +3951,7 @@ void LLTextureFetch::commandDataBreak()  // Threads:  T*  void LLTextureFetch::cmdEnqueue(TFRequest * req)  { +    LL_PROFILE_ZONE_SCOPED;  	lockQueue();														// +Mfq  	mCommands.push_back(req);  	unlockQueue();														// -Mfq @@ -4035,6 +3962,7 @@ void LLTextureFetch::cmdEnqueue(TFRequest * req)  // Threads:  T*  LLTextureFetch::TFRequest * LLTextureFetch::cmdDequeue()  { +    LL_PROFILE_ZONE_SCOPED;  	TFRequest * ret = 0;  	lockQueue();														// +Mfq @@ -4051,6 +3979,7 @@ LLTextureFetch::TFRequest * LLTextureFetch::cmdDequeue()  // Threads:  Ttf  void LLTextureFetch::cmdDoWork()  { +    LL_PROFILE_ZONE_SCOPED;  	if (mDebugPause)  	{  		return;  // debug: don't do any work @@ -4141,7 +4070,7 @@ TFReqSendMetrics::~TFReqSendMetrics()  bool  TFReqSendMetrics::doWork(LLTextureFetch * fetcher)  { -	static const U32 report_priority(1); +    LL_PROFILE_ZONE_SCOPED;  	//if (! gViewerAssetStatsThread1)  	//	return true; @@ -4184,7 +4113,6 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)  		// Don't care about handle, this is a fire-and-forget operation.    		LLCoreHttpUtil::requestPostWithLLSD(&fetcher->getHttpRequest(),  											fetcher->getMetricsPolicyClass(), -											report_priority,  											mCapsURL,  											mStatsSD,  											LLCore::HttpOptions::ptr_t(), @@ -4246,971 +4174,6 @@ truncate_viewer_metrics(int max_regions, LLSD & metrics)  } // end of anonymous namespace - -/////////////////////////////////////////////////////////////////////////////////////////// -//Start LLTextureFetchDebugger -/////////////////////////////////////////////////////////////////////////////////////////// -//--------------------- -class LLDebuggerCacheReadResponder : public LLTextureCache::ReadResponder -{ -public: -	LLDebuggerCacheReadResponder(LLTextureFetchDebugger* debugger, S32 id, LLImageFormatted* image) -		: mDebugger(debugger), mID(id) -	{ -		setImage(image); -	} -	virtual void completed(bool success) -	{ -		mDebugger->callbackCacheRead(mID, success, mFormattedImage, mImageSize, mImageLocal); -	} -private: -	LLTextureFetchDebugger* mDebugger; -	S32 mID; -}; - -class LLDebuggerCacheWriteResponder : public LLTextureCache::WriteResponder -{ -public: -	LLDebuggerCacheWriteResponder(LLTextureFetchDebugger* debugger, S32 id) -		: mDebugger(debugger), mID(id) -	{ -	} -	virtual void completed(bool success) -	{ -		mDebugger->callbackCacheWrite(mID, success); -	} -private: -	LLTextureFetchDebugger* mDebugger; -	S32 mID; -}; - -class LLDebuggerDecodeResponder : public LLImageDecodeThread::Responder -{ -public: -	LLDebuggerDecodeResponder(LLTextureFetchDebugger* debugger, S32 id) -		: mDebugger(debugger), mID(id) -	{ -	} -	virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux) -	{ -		mDebugger->callbackDecoded(mID, success, raw, aux); -	} -private: -	LLTextureFetchDebugger* mDebugger; -	S32 mID; -}; - - -LLTextureFetchDebugger::LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) : -	LLCore::HttpHandler(), -	mFetcher(fetcher), -	mTextureCache(cache), -	mImageDecodeThread(imagedecodethread), -	mHttpHeaders(), -	mHttpPolicyClass(fetcher->getPolicyClass()), -	mNbCurlCompleted(0), -	mTempIndex(0), -	mHistoryListIndex(0) -{ -	init(); -} -	 -LLTextureFetchDebugger::~LLTextureFetchDebugger() -{ -	mFetchingHistory.clear(); -	mStopDebug = TRUE; -	tryToStopDebug(); -} - -void LLTextureFetchDebugger::init() -{ -	setDebuggerState(IDLE); -	 -	mCacheReadTime = -1.f; -	mCacheWriteTime = -1.f; -	mDecodingTime = -1.f; -	mHTTPTime = -1.f; -	mGLCreationTime = -1.f; - -	mTotalFetchingTime = 0.f; -	mRefetchVisCacheTime = -1.f; -	mRefetchVisHTTPTime = -1.f; -	mRefetchAllCacheTime = -1.f; -	mRefetchAllHTTPTime = -1.f; - -	mNumFetchedTextures = 0; -	mNumCacheHits = 0; -	mNumVisibleFetchedTextures = 0; -	mNumVisibleFetchingRequests = 0; -	mFetchedData = 0; -	mDecodedData = 0; -	mVisibleFetchedData = 0; -	mVisibleDecodedData = 0; -	mRenderedData = 0; -	mRenderedDecodedData = 0; -	mFetchedPixels = 0; -	mRenderedPixels = 0; -	mRefetchedVisData = 0; -	mRefetchedVisPixels = 0; -	mRefetchedAllData = 0; -	mRefetchedAllPixels = 0; - -	mFreezeHistory = FALSE; -	mStopDebug = FALSE; -	mClearHistory = FALSE; -	mRefetchNonVis = FALSE; -	 -	mNbCurlRequests = 0; - -	if (! mHttpHeaders) -	{ -        mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders); -		mHttpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_IMAGE_X_J2C); -	} -} - -void LLTextureFetchDebugger::startWork(e_debug_state state) -{ -	switch(state) -	{ -		case IDLE: -			break; -		case START_DEBUG: -			startDebug(); -			break; -		case READ_CACHE:			 -			debugCacheRead(); -			break; -		case WRITE_CACHE: -			debugCacheWrite(); -			break; -		case DECODING: -			debugDecoder(); -			break; -		case HTTP_FETCHING: -			debugHTTP(); -			break; -		case GL_TEX: -			debugGLTextureCreation(); -			break; -		case REFETCH_VIS_CACHE: -			debugRefetchVisibleFromCache(); -			break; -		case REFETCH_VIS_HTTP: -			debugRefetchVisibleFromHTTP(); -			break; -		case REFETCH_ALL_CACHE: -			debugRefetchAllFromCache(); -			break; -		case REFETCH_ALL_HTTP: -			debugRefetchAllFromHTTP(); -			break; -		default: -			break; -	} -	return; -} - -void LLTextureFetchDebugger::startDebug() -{ -	//lock the fetcher -	mFetcher->lockFetcher(true); -	mFreezeHistory = TRUE; -	mFetcher->resetLoadSource(); - -	//clear the current fetching queue -	gTextureList.clearFetchingRequests(); - -	setDebuggerState(START_DEBUG); -} - -bool LLTextureFetchDebugger::processStartDebug(F32 max_time) -{ -	mTimer.reset(); - -	//wait for all works to be done -	while(1) -	{ -		S32 pending = 0; -		pending += LLAppViewer::getTextureCache()->update(1);  -		pending += LLAppViewer::getImageDecodeThread()->update(1);  -		// pending += LLAppViewer::getTextureFetch()->update(1);  // This causes infinite recursion in some cases -		pending += mNbCurlRequests; -		if(!pending) -		{ -			break; -		} - -		if(mTimer.getElapsedTimeF32() > max_time) -		{ -			return false; -		} -	} - -	//collect statistics -	mTotalFetchingTime = gTextureTimer.getElapsedTimeF32() - mTotalFetchingTime; -	 -	std::set<LLUUID> fetched_textures; -	S32 size = mFetchingHistory.size(); -	for(S32 i = 0 ; i < size; i++) -	{ -		bool in_list = true; -		if(fetched_textures.find(mFetchingHistory[i].mID) == fetched_textures.end()) -		{ -			fetched_textures.insert(mFetchingHistory[i].mID); -			in_list = false; -		} - -        std::vector<LLViewerFetchedTexture*> textures; -        LLViewerTextureManager::findFetchedTextures(mFetchingHistory[i].mID, textures); -        std::vector<LLViewerFetchedTexture*>::iterator iter = textures.begin(); -        while (iter != textures.end()) -        { -            LLViewerFetchedTexture* tex = *iter++; -            // fetched data will be counted for both ui and regular elements -            if (tex && tex->isJustBound()) //visible -            { -                if (!in_list) -                { -                    mNumVisibleFetchedTextures++; -                } -                mNumVisibleFetchingRequests++; - -                mVisibleFetchedData += mFetchingHistory[i].mFetchedSize; -                mVisibleDecodedData += mFetchingHistory[i].mDecodedSize; - -                if (tex->getDiscardLevel() >= mFetchingHistory[i].mDecodedLevel) -                { -                    mRenderedData += mFetchingHistory[i].mFetchedSize; -                    mRenderedDecodedData += mFetchingHistory[i].mDecodedSize; -                    mRenderedPixels += tex->getWidth() * tex->getHeight(); -                } -            } -        } -	} - -	mNumFetchedTextures = fetched_textures.size(); - -	return true; -} - -void LLTextureFetchDebugger::tryToStopDebug() -{ -	if(!mStopDebug) -	{ -		return; -	} - -	//clear the current debug work -	S32 size = mFetchingHistory.size(); -	switch(mDebuggerState) -	{ -	case READ_CACHE:		 -		for(S32 i = 0 ; i < size; i++) -		{ -			if (mFetchingHistory[i]. mCacheHandle != LLTextureCache::nullHandle()) -			{ -				mTextureCache->readComplete(mFetchingHistory[i].mCacheHandle, true); -			} - 		}	 -		break; -	case WRITE_CACHE: -		for(S32 i = 0 ; i < size; i++) -		{ -			if (mFetchingHistory[i].mCacheHandle != LLTextureCache::nullHandle()) -			{ -				mTextureCache->writeComplete(mFetchingHistory[i].mCacheHandle, true); -			} -		} -		break; -	case DECODING: -		break; -	case HTTP_FETCHING: -		break; -	case GL_TEX: -		break; -	case REFETCH_VIS_CACHE: -		break; -	case REFETCH_VIS_HTTP: -		break; -	case REFETCH_ALL_CACHE: -		mRefetchList.clear(); -		break; -	case REFETCH_ALL_HTTP: -		mRefetchList.clear(); -		break; -	default: -		break; -	} - -	if(update(0.005f)) -	{ -		//unlock the fetcher -		mFetcher->lockFetcher(false); -		mFetcher->resetLoadSource(); -		mFreezeHistory = FALSE;		 -		mStopDebug = FALSE; - -		if(mClearHistory) -		{ -			mFetchingHistory.clear(); -			mHandleToFetchIndex.clear(); -			init();	 -			mTotalFetchingTime = gTextureTimer.getElapsedTimeF32(); //reset -		} -	} -} - -//called in the main thread and when the fetching queue is empty -void LLTextureFetchDebugger::clearHistory() -{ -	mClearHistory = TRUE;	 -} - -void LLTextureFetchDebugger::addHistoryEntry(LLTextureFetchWorker* worker) -{ -	if(worker->mRawImage.isNull() || worker->mFormattedImage.isNull()) -	{ -		return; -	} - -	if(mFreezeHistory) -	{ -		if(mDebuggerState == REFETCH_VIS_CACHE || mDebuggerState == REFETCH_VIS_HTTP) -		{ -			mRefetchedVisPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); -			mRefetchedVisData += worker->mFormattedImage->getDataSize(); -		} -		else -		{ -			mRefetchedAllPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); -			mRefetchedAllData += worker->mFormattedImage->getDataSize(); - -			// refetch list only requests/creates normal images, so requesting ui='false' -			LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(worker->mID, TEX_LIST_STANDARD); -			if(tex && mRefetchList[tex].begin() != mRefetchList[tex].end()) -			{ -				if(worker->mDecodedDiscard == mFetchingHistory[mRefetchList[tex][0]].mDecodedLevel) -				{ -					mRefetchList[tex].erase(mRefetchList[tex].begin()); -				} -			} -		} -		return; -	} - -	if(worker->mInCache) -	{ -		mNumCacheHits++; -	} -	mFetchedData += worker->mFormattedImage->getDataSize(); -	mDecodedData += worker->mRawImage->getDataSize(); -	mFetchedPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); - -	mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mDecodedDiscard,  -		worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize())); -} - -void LLTextureFetchDebugger::lockCache() -{ -} -	 -void LLTextureFetchDebugger::unlockCache() -{ -} -	 -void LLTextureFetchDebugger::debugCacheRead() -{ -	lockCache(); -	llassert_always(mDebuggerState == IDLE); -	mTimer.reset(); -	setDebuggerState(READ_CACHE); -	mCacheReadTime = -1.f; - -	S32 size = mFetchingHistory.size(); -	for(S32 i = 0 ; i < size ; i++) -	{		 -		mFetchingHistory[i].mFormattedImage = NULL; -		mFetchingHistory[i].mCacheHandle = mTextureCache->readFromCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL, 0, mFetchingHistory[i].mFetchedSize,  -			new LLDebuggerCacheReadResponder(this, i, mFetchingHistory[i].mFormattedImage)); -	} -} -	 -void LLTextureFetchDebugger::clearCache() -{ -	S32 size = mFetchingHistory.size(); -	{ -		std::set<LLUUID> deleted_list; -		for(S32 i = 0 ; i < size ; i++) -		{ -			if(deleted_list.find(mFetchingHistory[i].mID) == deleted_list.end()) -			{ -				deleted_list.insert(mFetchingHistory[i].mID); -				mTextureCache->removeFromCache(mFetchingHistory[i].mID); -			} -		} -	} -} - -void LLTextureFetchDebugger::debugCacheWrite() -{ -	//remove from cache -	clearCache(); - -	lockCache(); -	llassert_always(mDebuggerState == IDLE); -	mTimer.reset(); -	setDebuggerState(WRITE_CACHE); -	mCacheWriteTime = -1.f; - -	S32 size = mFetchingHistory.size(); -	for(S32 i = 0 ; i < size ; i++) -	{		 -		if(mFetchingHistory[i].mFormattedImage.notNull()) -		{ -			mFetchingHistory[i].mCacheHandle = mTextureCache->writeToCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL,  -				mFetchingHistory[i].mFormattedImage->getData(), mFetchingHistory[i].mFetchedSize, -				mFetchingHistory[i].mDecodedLevel == 0 ? mFetchingHistory[i].mFetchedSize : mFetchingHistory[i].mFetchedSize + 1,  -				NULL, 0, new LLDebuggerCacheWriteResponder(this, i));					 -		} -	} -} - -void LLTextureFetchDebugger::lockDecoder() -{ -} -	 -void LLTextureFetchDebugger::unlockDecoder() -{ -} - -void LLTextureFetchDebugger::debugDecoder() -{ -	lockDecoder(); -	llassert_always(mDebuggerState == IDLE); -	mTimer.reset(); -	setDebuggerState(DECODING); -	mDecodingTime = -1.f; - -	S32 size = mFetchingHistory.size(); -	for(S32 i = 0 ; i < size ; i++) -	{		 -		if(mFetchingHistory[i].mFormattedImage.isNull()) -		{ -			continue; -		} - -		mImageDecodeThread->decodeImage(mFetchingHistory[i].mFormattedImage, LLWorkerThread::PRIORITY_NORMAL,  -			mFetchingHistory[i].mDecodedLevel, mFetchingHistory[i].mNeedsAux, -			new LLDebuggerDecodeResponder(this, i)); -	} -} - -void LLTextureFetchDebugger::debugHTTP() -{ -	llassert_always(mDebuggerState == IDLE); - -	LLViewerRegion* region = gAgent.getRegion(); -	if (!region) -	{ -		LL_INFOS(LOG_TXT) << "Fetch Debugger : Current region undefined. Cannot fetch textures through HTTP." << LL_ENDL; -		return; -	} -	 -	mHTTPUrl = region->getViewerAssetUrl(); -	if (mHTTPUrl.empty()) -	{ -		LL_INFOS(LOG_TXT) << "Fetch Debugger : Current region URL undefined. Cannot fetch textures through HTTP." << LL_ENDL; -		return; -	} -	 -	mTimer.reset(); -	setDebuggerState(HTTP_FETCHING); -	mHTTPTime = -1.f; -	 -	S32 size = mFetchingHistory.size(); -	for (S32 i = 0 ; i < size ; i++) -	{ -		mFetchingHistory[i].mCurlState = FetchEntry::CURL_NOT_DONE; -		mFetchingHistory[i].mCurlReceivedSize = 0; -		mFetchingHistory[i].mFormattedImage = NULL; -	} -	mNbCurlRequests = 0; -	mNbCurlCompleted = 0; -	 -	fillCurlQueue(); -} - -S32 LLTextureFetchDebugger::fillCurlQueue() -{ -	if(mStopDebug) //stop -	{ -		mNbCurlCompleted = mFetchingHistory.size(); -		return 0; -	} -	if (mNbCurlRequests > HTTP_NONPIPE_REQUESTS_LOW_WATER) -	{ -		return mNbCurlRequests; -	} -	 -	S32 size = mFetchingHistory.size(); -	for (S32 i = 0 ; i < size ; i++) -	{		 -		if (mFetchingHistory[i].mCurlState != FetchEntry::CURL_NOT_DONE) -		{ -			continue; -		} -		std::string texture_url = mHTTPUrl + "/?texture_id=" + mFetchingHistory[i].mID.asString().c_str(); -		S32 requestedSize = mFetchingHistory[i].mRequestedSize; -		// We request the whole file if the size was not set. -		requestedSize = llmax(0,requestedSize); -		// We request the whole file if the size was set to an absurdly high value (meaning all file) -		requestedSize = (requestedSize == 33554432 ? 0 : requestedSize); - -		LLCore::HttpHandle handle = mFetcher->getHttpRequest().requestGetByteRange(mHttpPolicyClass, -																				   LLWorkerThread::PRIORITY_LOWBITS, -																				   texture_url, -																				   0, -																				   requestedSize, -																				   LLCore::HttpOptions::ptr_t(), -																				   mHttpHeaders, -                                                                                   LLCore::HttpHandler::ptr_t(this, &NoOpDeletor)); -		if (LLCORE_HTTP_HANDLE_INVALID != handle) -		{ -			mHandleToFetchIndex[handle] = i; -			mFetchingHistory[i].mHttpHandle = handle; -			mFetchingHistory[i].mCurlState = FetchEntry::CURL_IN_PROGRESS; -			mNbCurlRequests++; -			if (mNbCurlRequests >= HTTP_NONPIPE_REQUESTS_HIGH_WATER)	// emulate normal pipeline -			{ -				break; -			} -		} -		else  -		{ -			// Failed to queue request, log it and mark it done. -			LLCore::HttpStatus status(mFetcher->getHttpRequest().getStatus()); - -			LL_WARNS(LOG_TXT) << "Couldn't issue HTTP request in debugger for texture " -							  << mFetchingHistory[i].mID -							  << ", status: " << status.toTerseString() -							  << " reason:  " << status.toString() -							  << LL_ENDL; -			mFetchingHistory[i].mCurlState = FetchEntry::CURL_DONE; -		} -	} -	//LL_INFOS(LOG_TXT) << "Fetch Debugger : Having " << mNbCurlRequests << " requests through the curl thread." << LL_ENDL; -	return mNbCurlRequests; -} - -void LLTextureFetchDebugger::debugGLTextureCreation() -{ -	llassert_always(mDebuggerState == IDLE); -	setDebuggerState(GL_TEX); -	mTempTexList.clear(); - -	S32 size = mFetchingHistory.size(); -	for(S32 i = 0 ; i < size ; i++) -	{ -		if(mFetchingHistory[i].mRawImage.notNull()) -		{ -            std::vector<LLViewerFetchedTexture*> textures; -            gTextureList.findTexturesByID(mFetchingHistory[i].mID, textures); -            std::vector<LLViewerFetchedTexture*>::iterator iter = textures.begin(); -            while (iter != textures.end()) -            { -                LLViewerFetchedTexture* tex = *iter++; -                if (tex && !tex->isForSculptOnly()) -                { -                    tex->destroyGLTexture(); -                    mTempTexList.push_back(tex); -                } -            } -		} -	} -	 -	mGLCreationTime = -1.f; -	mTempIndex = 0; -	mHistoryListIndex = 0; -	 -	return; -} - -bool LLTextureFetchDebugger::processGLCreation(F32 max_time) -{ -	mTimer.reset(); - -	bool done = true; -	S32 size = mFetchingHistory.size(); -	S32 size1 = mTempTexList.size(); -	for(; mHistoryListIndex < size && mTempIndex < size1; mHistoryListIndex++) -	{ -		if(mFetchingHistory[mHistoryListIndex].mRawImage.notNull()) -		{ -			if(mFetchingHistory[mHistoryListIndex].mID == mTempTexList[mTempIndex]->getID()) -			{ -				mTempTexList[mTempIndex]->createGLTexture(mFetchingHistory[mHistoryListIndex].mDecodedLevel,  -					mFetchingHistory[mHistoryListIndex].mRawImage, 0, TRUE, mTempTexList[mTempIndex]->getBoostLevel()); -				mTempIndex++; -			} -		} - -		if(mTimer.getElapsedTimeF32() > max_time) -		{ -			done = false; -			break; -		} -	} - -	if(mGLCreationTime < 0.f) -	{ -		mGLCreationTime = mTimer.getElapsedTimeF32() ; -	} -	else -	{ -		mGLCreationTime += mTimer.getElapsedTimeF32() ; -	} - -	return done; -} - -//clear fetching results of all textures. -void LLTextureFetchDebugger::clearTextures() -{ -	S32 size = mFetchingHistory.size(); -	for(S32 i = 0 ; i < size ; i++) -	{ -        std::vector<LLViewerFetchedTexture*> textures; -        gTextureList.findTexturesByID(mFetchingHistory[i].mID, textures); -        std::vector<LLViewerFetchedTexture*>::iterator iter = textures.begin(); -        while (iter != textures.end()) -        { -            LLViewerFetchedTexture* tex = *iter++; -            if (tex) -            { -                tex->clearFetchedResults(); -            } -        } -	} -} - -void LLTextureFetchDebugger::makeRefetchList() -{ -	mRefetchList.clear(); -	S32 size = mFetchingHistory.size(); -	for(S32 i = 0 ; i < size; i++) -	{		 -		LLViewerFetchedTexture* tex = LLViewerTextureManager::getFetchedTexture(mFetchingHistory[i].mID); -		if(tex && tex->isJustBound()) //visible -		{ -			continue; //the texture fetch pipeline will take care of visible textures. -		} - -		// todo: Will attempt to refetch icons and ui elements as normal images (boost_none) -		// thus will create unnecessary LLViewerFetchedTexture, consider supporting separate UI textures -		mRefetchList[tex].push_back(i); 		 -	} -} - -void LLTextureFetchDebugger::scanRefetchList() -{ -	if(mStopDebug) -	{ -		return; -	} -	if(!mRefetchNonVis) -	{ -		return; -	} - -	for(std::map< LLPointer<LLViewerFetchedTexture>, std::vector<S32> >::iterator iter = mRefetchList.begin(); -		iter != mRefetchList.end(); ) -	{ -		if(iter->second.empty()) -		{ -			gTextureList.setDebugFetching(iter->first, -1); -			mRefetchList.erase(iter++);		// This is the correct method to "erase and move on" in an std::map -		} -		else -		{ -			gTextureList.setDebugFetching(iter->first, mFetchingHistory[iter->second[0]].mDecodedLevel); -			++iter; -		} -	} -} - -void LLTextureFetchDebugger::debugRefetchVisibleFromCache() -{ -	llassert_always(mDebuggerState == IDLE); -	setDebuggerState(REFETCH_VIS_CACHE); - -	clearTextures(); -	mFetcher->setLoadSource(LLTextureFetch::FROM_ALL); -	 -	mTimer.reset(); -	mFetcher->lockFetcher(false); -	mRefetchVisCacheTime = -1.f; -	mRefetchedVisData = 0; -	mRefetchedVisPixels = 0; -} - -void LLTextureFetchDebugger::debugRefetchVisibleFromHTTP() -{ -	llassert_always(mDebuggerState == IDLE); -	setDebuggerState(REFETCH_VIS_HTTP); - -	clearTextures(); -	mFetcher->setLoadSource(LLTextureFetch::FROM_HTTP_ONLY); - -	mTimer.reset(); -	mFetcher->lockFetcher(false); -	mRefetchVisHTTPTime = -1.f; -	mRefetchedVisData = 0; -	mRefetchedVisPixels = 0; -} - -void LLTextureFetchDebugger::debugRefetchAllFromCache() -{ -	llassert_always(mDebuggerState == IDLE); -	setDebuggerState(REFETCH_ALL_CACHE); - -	clearTextures(); -	makeRefetchList(); -	mFetcher->setLoadSource(LLTextureFetch::FROM_ALL); - -	mTimer.reset(); -	mFetcher->lockFetcher(false); -	mRefetchAllCacheTime = -1.f; -	mRefetchedAllData = 0; -	mRefetchedAllPixels = 0; -	mRefetchNonVis = FALSE; -} - -void LLTextureFetchDebugger::debugRefetchAllFromHTTP() -{ -	llassert_always(mDebuggerState == IDLE); -	setDebuggerState(REFETCH_ALL_HTTP); - -	clearTextures(); -	makeRefetchList(); -	mFetcher->setLoadSource(LLTextureFetch::FROM_HTTP_ONLY); - -	mTimer.reset(); -	mFetcher->lockFetcher(false); -	mRefetchAllHTTPTime = -1.f; -	mRefetchedAllData = 0; -	mRefetchedAllPixels = 0; -	mRefetchNonVis = TRUE; -} - -bool LLTextureFetchDebugger::update(F32 max_time) -{ -	switch(mDebuggerState) -	{ -	case START_DEBUG: -		if(processStartDebug(max_time)) -		{ -			setDebuggerState(IDLE); -		} -		break; -	case READ_CACHE: -		if(!mTextureCache->update(1)) -		{ -			mCacheReadTime = mTimer.getElapsedTimeF32() ; -			setDebuggerState(IDLE); -			unlockCache(); -		} -		break; -	case WRITE_CACHE: -		if(!mTextureCache->update(1)) -		{ -			mCacheWriteTime = mTimer.getElapsedTimeF32() ; -			setDebuggerState(IDLE); -			unlockCache(); -		} -		break; -	case DECODING: -		if(!mImageDecodeThread->update(1)) -		{ -			mDecodingTime =  mTimer.getElapsedTimeF32() ; -			setDebuggerState(IDLE); -			unlockDecoder(); -		} -		break; -	case HTTP_FETCHING: -		// Do some notifications... -		mFetcher->getHttpRequest().update(10); -		if (!fillCurlQueue() && mNbCurlCompleted == mFetchingHistory.size()) -		{ -			mHTTPTime =  mTimer.getElapsedTimeF32() ; -			setDebuggerState(IDLE); -		} -		break; -	case GL_TEX: -		if(processGLCreation(max_time)) -		{ -			setDebuggerState(IDLE); -			mTempTexList.clear(); -		} -		break; -	case REFETCH_VIS_CACHE: -		if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) -		{ -			mRefetchVisCacheTime = mTimer.getElapsedTimeF32() ; -			setDebuggerState(IDLE); -			mFetcher->lockFetcher(true); -			mFetcher->resetLoadSource(); -		} -		break; -	case REFETCH_VIS_HTTP: -		if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) -		{ -			mRefetchVisHTTPTime = mTimer.getElapsedTimeF32() ; -			setDebuggerState(IDLE); -			mFetcher->lockFetcher(true); -			mFetcher->resetLoadSource(); -		} -		break; -	case REFETCH_ALL_CACHE: -		scanRefetchList(); -		if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) -		{ -			if(!mRefetchNonVis) -			{ -				mRefetchNonVis = TRUE; //start to fetch non-vis -				scanRefetchList(); -				break; -			} - -			mRefetchAllCacheTime = mTimer.getElapsedTimeF32() ; -			setDebuggerState(IDLE);  -			mFetcher->lockFetcher(true); -			mFetcher->resetLoadSource(); -			mRefetchList.clear(); -			mRefetchNonVis = FALSE; -		} -		break; -	case REFETCH_ALL_HTTP: -		scanRefetchList(); -		if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) -		{ -			mRefetchAllHTTPTime = mTimer.getElapsedTimeF32() ; -			setDebuggerState(IDLE); -			mFetcher->lockFetcher(true); -			mFetcher->resetLoadSource(); -			mRefetchList.clear(); -			mRefetchNonVis = FALSE; -		} -		break; -	default: -		setDebuggerState(IDLE); -		break; -	} - -	return mDebuggerState == IDLE; -} - -void LLTextureFetchDebugger::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response) -{ -	handle_fetch_map_t::iterator iter(mHandleToFetchIndex.find(handle)); -	if (mHandleToFetchIndex.end() == iter) -	{ -		LL_INFOS(LOG_TXT) << "Fetch Debugger : Couldn't find handle " << handle << " in fetch list." << LL_ENDL; -		return; -	} -	 -	S32 fetch_ind(iter->second); -	mHandleToFetchIndex.erase(iter); -	if (fetch_ind >= mFetchingHistory.size() || mFetchingHistory[fetch_ind].mHttpHandle != handle) -	{ -		LL_INFOS(LOG_TXT) << "Fetch Debugger : Handle and fetch object in disagreement.  Punting." << LL_ENDL; -	} -	else -	{ -		callbackHTTP(mFetchingHistory[fetch_ind], response); -		mFetchingHistory[fetch_ind].mHttpHandle = LLCORE_HTTP_HANDLE_INVALID;	// Not valid after notification -	} -} - -void LLTextureFetchDebugger::callbackCacheRead(S32 id, bool success, LLImageFormatted* image, -						   S32 imagesize, BOOL islocal) -{ -	if (success) -	{ -		mFetchingHistory[id].mFormattedImage = image; -	} -	mTextureCache->readComplete(mFetchingHistory[id].mCacheHandle, false); -	mFetchingHistory[id].mCacheHandle = LLTextureCache::nullHandle(); -} - -void LLTextureFetchDebugger::callbackCacheWrite(S32 id, bool success) -{ -	mTextureCache->writeComplete(mFetchingHistory[id].mCacheHandle); -	mFetchingHistory[id].mCacheHandle = LLTextureCache::nullHandle(); -} - -void LLTextureFetchDebugger::callbackDecoded(S32 id, bool success, LLImageRaw* raw, LLImageRaw* aux) -{ -	if (success) -	{ -		llassert_always(raw); -		mFetchingHistory[id].mRawImage = raw; -	} -} - -void LLTextureFetchDebugger::callbackHTTP(FetchEntry & fetch, LLCore::HttpResponse * response) -{ -	static const LLCore::HttpStatus par_status(HTTP_PARTIAL_CONTENT); -	 -	LLCore::HttpStatus status(response->getStatus()); -	mNbCurlRequests--; -	mNbCurlCompleted++; -	fetch.mCurlState = FetchEntry::CURL_DONE; -	if (status) -	{ -		const bool partial(par_status == status); -		LLCore::BufferArray * ba(response->getBody());	// *Not* holding reference to body -		 -		S32 data_size = ba ? ba->size() : 0; -		fetch.mCurlReceivedSize += data_size; -		//LL_INFOS(LOG_TXT) << "Fetch Debugger : got results for " << fetch.mID << ", data_size = " << data_size << ", received = " << fetch.mCurlReceivedSize << ", requested = " << fetch.mRequestedSize << ", partial = " << partial << LL_ENDL; -		if ((fetch.mCurlReceivedSize >= fetch.mRequestedSize) || !partial || (fetch.mRequestedSize == 600)) -		{ -			U8* d_buffer = (U8*)ll_aligned_malloc_16(data_size); -			if (ba) -			{ -				ba->read(0, d_buffer, data_size); -			} -			 -			llassert_always(fetch.mFormattedImage.isNull()); -			{ -				// For now, create formatted image based on extension -				std::string texture_url = mHTTPUrl + "/?texture_id=" + fetch.mID.asString().c_str(); -				std::string extension = gDirUtilp->getExtension(texture_url); -				fetch.mFormattedImage = LLImageFormatted::createFromType(LLImageBase::getCodecFromExtension(extension)); -				if (fetch.mFormattedImage.isNull()) -				{ -					fetch.mFormattedImage = new LLImageJ2C; // default -				} -			} -						 -			fetch.mFormattedImage->setData(d_buffer, data_size);	 -		} -	} -	else //failed -	{ -		LL_INFOS(LOG_TXT) << "Fetch Debugger : CURL GET FAILED,  ID = " << fetch.mID -						  << ", status: " << status.toTerseString() -						  << " reason:  " << status.toString() << LL_ENDL; -	} -} - - -//--------------------- -/////////////////////////////////////////////////////////////////////////////////////////// -//End LLTextureFetchDebugger -/////////////////////////////////////////////////////////////////////////////////////////// -  LLTextureFetchTester::LLTextureFetchTester() : LLMetricPerformanceTesterBasic(sTesterName)   {  	mTextureFetchTime = 0; diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index bf6732963f..3ca88422a2 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -48,7 +48,6 @@ class LLTextureFetchWorker;  class LLImageDecodeThread;  class LLHost;  class LLViewerAssetStats; -class LLTextureFetchDebugger;  class LLTextureCache;  class LLTextureFetchTester; @@ -59,7 +58,9 @@ class LLTextureFetch : public LLWorkerThread  	friend class LLTextureFetchWorker;  public: -	LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode); +    static std::string getStateString(S32 state); + +	LLTextureFetch(LLTextureCache* cache, bool threaded, bool qa_mode);  	~LLTextureFetch();  	class TFRequest; @@ -116,10 +117,11 @@ public:      // Threads:  T*  	BOOL isFromLocalCache(const LLUUID& id); -	// @return	Magic number giving the internal state of the -	//			request.  We should make these codes public if we're -	//			going to return them as a status value. -	// +    // get the current fetch state, if any, from the given UUID +    S32 getFetchState(const LLUUID& id); + +	// @return	Fetch state of given image and associates statistics +	//          See also getStateString      // Threads:  T*  	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, bool& can_use_http); @@ -322,7 +324,6 @@ private:  	LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue.  	LLTextureCache* mTextureCache; -	LLImageDecodeThread* mImageDecodeThread;  	// Map of all requests by UUID  	typedef std::map<LLUUID,LLTextureFetchWorker*> map_t; @@ -409,10 +410,6 @@ public:  	static LLTextureFetchTester* sTesterp;  private: -	//debug use -	LLTextureFetchDebugger* mFetchDebugger; -	bool mFetcherLocked; -	  	e_tex_source mFetchSource;  	e_tex_source mOriginFetchSource; @@ -420,10 +417,6 @@ private:  	//LLAdaptiveRetryPolicy mFetchRetryPolicy;  public: -	//debug use -	LLTextureFetchDebugger* getFetchDebugger() { return mFetchDebugger;} -	void lockFetcher(bool lock) { mFetcherLocked = lock;} -  	void setLoadSource(e_tex_source source) {mFetchSource = source;}  	void resetLoadSource() {mFetchSource = mOriginFetchSource;}  	bool canLoadFromCache() { return mFetchSource != FROM_HTTP_ONLY;} @@ -431,216 +424,6 @@ public:  //debug use  class LLViewerFetchedTexture; -class LLTextureFetchDebugger : public LLCore::HttpHandler -{ -	friend class LLTextureFetch; -public: -	LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) ; -	~LLTextureFetchDebugger(); - -public: -	enum e_debug_state -	{ -		IDLE = 0, -		START_DEBUG, -		READ_CACHE, -		WRITE_CACHE, -		DECODING, -		HTTP_FETCHING, -		GL_TEX, -		REFETCH_VIS_CACHE, -		REFETCH_VIS_HTTP, -		REFETCH_ALL_CACHE, -		REFETCH_ALL_HTTP, -		INVALID -	}; - -private:	 -	struct FetchEntry -	{ -		enum e_curl_state -		{ -			CURL_NOT_DONE = 0, -			CURL_IN_PROGRESS, -			CURL_DONE -		}; -		LLUUID mID; -		S32 mRequestedSize; -		S32 mDecodedLevel; -		S32 mFetchedSize; -		S32 mDecodedSize; -		BOOL mNeedsAux; -		U32 mCacheHandle; -		LLPointer<LLImageFormatted> mFormattedImage; -		LLPointer<LLImageRaw> mRawImage; -		e_curl_state mCurlState; -		S32 mCurlReceivedSize; -		LLCore::HttpHandle mHttpHandle; - -		FetchEntry() : -			mDecodedLevel(-1), -			mFetchedSize(0), -			mDecodedSize(0), -			mHttpHandle(LLCORE_HTTP_HANDLE_INVALID) -			{} -		FetchEntry(LLUUID& id, S32 r_size, /*S32 f_discard, S32 c,*/ S32 level, S32 f_size, S32 d_size) : -			mID(id), -			mRequestedSize(r_size), -			mDecodedLevel(level), -			mFetchedSize(f_size), -			mDecodedSize(d_size), -			mNeedsAux(false), -			mHttpHandle(LLCORE_HTTP_HANDLE_INVALID) -			{} -	}; -	typedef std::vector<FetchEntry> fetch_list_t; -	fetch_list_t mFetchingHistory; - -	typedef std::map<LLCore::HttpHandle, S32> handle_fetch_map_t; -	handle_fetch_map_t mHandleToFetchIndex; - -	void setDebuggerState(e_debug_state new_state) { mDebuggerState = new_state; } -	e_debug_state mDebuggerState; -	 -	F32 mCacheReadTime; -	F32 mCacheWriteTime; -	F32 mDecodingTime; -	F32 mHTTPTime; -	F32 mGLCreationTime; - -	F32 mTotalFetchingTime; -	F32 mRefetchVisCacheTime; -	F32 mRefetchVisHTTPTime; -	F32 mRefetchAllCacheTime; -	F32 mRefetchAllHTTPTime; - -	LLTimer mTimer; -	 -	LLTextureFetch* mFetcher; -	LLTextureCache* mTextureCache; -	LLImageDecodeThread* mImageDecodeThread; -	LLCore::HttpHeaders::ptr_t mHttpHeaders; -	LLCore::HttpRequest::policy_t mHttpPolicyClass; -	 -	S32 mNumFetchedTextures; -	S32 mNumCacheHits; -	S32 mNumVisibleFetchedTextures; -	S32 mNumVisibleFetchingRequests; -	U32 mFetchedData; -	U32 mDecodedData; -	U32 mVisibleFetchedData; -	U32 mVisibleDecodedData; -	U32 mRenderedData; -	U32 mRenderedDecodedData; -	U32 mFetchedPixels; -	U32 mRenderedPixels; -	U32 mRefetchedVisData; -	U32 mRefetchedVisPixels; -	U32 mRefetchedAllData; -	U32 mRefetchedAllPixels; - -	BOOL mFreezeHistory; -	BOOL mStopDebug; -	BOOL mClearHistory; -	BOOL mRefetchNonVis; - -	std::string mHTTPUrl; -	S32 mNbCurlRequests; -	S32 mNbCurlCompleted; - -	std::map< LLPointer<LLViewerFetchedTexture>, std::vector<S32> > mRefetchList; // treats UI textures as normal textures -	std::vector< LLPointer<LLViewerFetchedTexture> > mTempTexList; -	S32 mTempIndex; -	S32 mHistoryListIndex; - -public: -	bool update(F32 max_time); //called in the main thread once per frame - -	//fetching history -	void clearHistory(); -	void addHistoryEntry(LLTextureFetchWorker* worker); -	 -	// Inherited from LLCore::HttpHandler -	// Threads:  Ttf -	virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response); - -	void startWork(e_debug_state state); -	void setStopDebug() {mStopDebug = TRUE;} -	void tryToStopDebug(); //stop everything -	void callbackCacheRead(S32 id, bool success, LLImageFormatted* image, -						   S32 imagesize, BOOL islocal); -	void callbackCacheWrite(S32 id, bool success); -	void callbackDecoded(S32 id, bool success, LLImageRaw* raw, LLImageRaw* aux); -	void callbackHTTP(FetchEntry & fetch, LLCore::HttpResponse * response); - -	e_debug_state getState()             {return mDebuggerState;} -	S32  getNumFetchedTextures()         {return mNumFetchedTextures;} -	S32  getNumFetchingRequests()        {return mFetchingHistory.size();} -	S32  getNumCacheHits()               {return mNumCacheHits;} -	S32  getNumVisibleFetchedTextures()  {return mNumVisibleFetchedTextures;} -	S32  getNumVisibleFetchingRequests() {return mNumVisibleFetchingRequests;} -	U32  getFetchedData()                {return mFetchedData;} -	U32  getDecodedData()                {return mDecodedData;} -	U32  getVisibleFetchedData()         {return mVisibleFetchedData;} -	U32  getVisibleDecodedData()         {return mVisibleDecodedData;} -	U32  getRenderedData()               {return mRenderedData;} -	U32  getRenderedDecodedData()        {return mRenderedDecodedData;} -	U32  getFetchedPixels()              {return mFetchedPixels;} -	U32  getRenderedPixels()             {return mRenderedPixels;} -	U32  getRefetchedVisData()              {return mRefetchedVisData;} -	U32  getRefetchedVisPixels()            {return mRefetchedVisPixels;} -	U32  getRefetchedAllData()              {return mRefetchedAllData;} -	U32  getRefetchedAllPixels()            {return mRefetchedAllPixels;} - -	F32  getCacheReadTime()     {return mCacheReadTime;} -	F32  getCacheWriteTime()    {return mCacheWriteTime;} -	F32  getDecodeTime()        {return mDecodingTime;} -	F32  getGLCreationTime()    {return mGLCreationTime;} -	F32  getHTTPTime()          {return mHTTPTime;} -	F32  getTotalFetchingTime() {return mTotalFetchingTime;} -	F32  getRefetchVisCacheTime() {return mRefetchVisCacheTime;} -	F32  getRefetchVisHTTPTime()  {return mRefetchVisHTTPTime;} -	F32  getRefetchAllCacheTime() {return mRefetchAllCacheTime;} -	F32  getRefetchAllHTTPTime()  {return mRefetchAllHTTPTime;} - -private: -	void init(); -	void clearTextures();//clear fetching results of all textures. -	void clearCache(); -	void makeRefetchList(); -	void scanRefetchList(); - -	void lockFetcher(); -	void unlockFetcher(); - -	void lockCache(); -	void unlockCache(); - -	void lockDecoder(); -	void unlockDecoder(); -	 -	S32 fillCurlQueue(); - -	void startDebug(); -	void debugCacheRead(); -	void debugCacheWrite();	 -	void debugHTTP(); -	void debugDecoder(); -	void debugGLTextureCreation(); -	void debugRefetchVisibleFromCache(); -	void debugRefetchVisibleFromHTTP(); -	void debugRefetchAllFromCache(); -	void debugRefetchAllFromHTTP(); - -	bool processStartDebug(F32 max_time); -	bool processGLCreation(F32 max_time); - -private: -	static bool sDebuggerEnabled; -public: -	static bool isEnabled() {return sDebuggerEnabled;} -}; -  class LLTextureFetchTester : public LLMetricPerformanceTesterBasic  { diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index b74577315e..f0e9cee101 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -49,6 +49,8 @@  #include "llviewerobjectlist.h"  #include "llviewertexture.h"  #include "llviewertexturelist.h" +#include "llviewerwindow.h" +#include "llwindow.h"  #include "llvovolume.h"  #include "llviewerstats.h"  #include "llworld.h" @@ -117,8 +119,8 @@ public:  			LLTextureBar* bar2p = (LLTextureBar*)i2;  			LLViewerFetchedTexture *i1p = bar1p->mImagep;  			LLViewerFetchedTexture *i2p = bar2p->mImagep; -			F32 pri1 = i1p->getDecodePriority(); // i1p->mRequestedDownloadPriority -			F32 pri2 = i2p->getDecodePriority(); // i2p->mRequestedDownloadPriority +			F32 pri1 = i1p->getMaxVirtualSize(); +			F32 pri2 = i2p->getMaxVirtualSize();  			if (pri1 > pri2)  				return true;  			else if (pri2 > pri1) @@ -177,7 +179,7 @@ void LLTextureBar::draw()  	{  		color = LLColor4::magenta; // except none and alm  	} -	else if (mImagep->getDecodePriority() <= 0.0f) +	else if (mImagep->getMaxVirtualSize() <= 0.0f)  	{  		color = LLColor4::grey; color[VALPHA] = .7f;  	} @@ -202,26 +204,13 @@ void LLTextureBar::draw()  	std::string uuid_str;  	mImagep->mID.toString(uuid_str);  	uuid_str = uuid_str.substr(0,7); -	if (mTextureView->mOrderFetch) -	{ -		tex_str = llformat("%s %7.0f %d(%d) 0x%08x(%8.0f)", -						   uuid_str.c_str(), -						   mImagep->mMaxVirtualSize, -						   mImagep->mDesiredDiscardLevel, -						   mImagep->mRequestedDiscardLevel, -						   mImagep->mFetchPriority, -						   mImagep->getDecodePriority()); -	} -	else -	{ -		tex_str = llformat("%s %7.0f %d(%d) %8.0f(0x%08x)", -						   uuid_str.c_str(), -						   mImagep->mMaxVirtualSize, -						   mImagep->mDesiredDiscardLevel, -						   mImagep->mRequestedDiscardLevel, -						   mImagep->getDecodePriority(), -						   mImagep->mFetchPriority); -	} +	 +    tex_str = llformat("%s %7.0f %d(%d)", +        uuid_str.c_str(), +        mImagep->mMaxVirtualSize, +        mImagep->mDesiredDiscardLevel, +        mImagep->mRequestedDiscardLevel); +  	LLFontGL::getFontMonospace()->renderUTF8(tex_str, 0, title_x1, getRect().getHeight(),  									 color, LLFontGL::LEFT, LLFontGL::TOP); @@ -500,10 +489,6 @@ private:  void LLGLTexMemBar::draw()  { -	S32Megabytes bound_mem = LLViewerTexture::sBoundTextureMemory; - 	S32Megabytes max_bound_mem = LLViewerTexture::sMaxBoundTextureMemory; -	S32Megabytes total_mem = LLViewerTexture::sTotalTextureMemory; -	S32Megabytes max_total_mem = LLViewerTexture::sMaxTotalTextureMem;  	F32 discard_bias = LLViewerTexture::sDesiredDiscardBias;  	F32 cache_usage = LLAppViewer::getTextureCache()->getUsage().valueInUnits<LLUnits::Megabytes>();  	F32 cache_max_usage = LLAppViewer::getTextureCache()->getMaxUsage().valueInUnits<LLUnits::Megabytes>(); @@ -549,15 +534,10 @@ void LLGLTexMemBar::draw()      U32 texFetchLatMed = U32(recording.getMean(LLTextureFetch::sTexFetchLatency).value() * 1000.0f);      U32 texFetchLatMax = U32(recording.getMax(LLTextureFetch::sTexFetchLatency).value() * 1000.0f); -	text = llformat("GL Tot: %d/%d MB GL Free: %d Sys Free: %d MB Bound: %4d/%4d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB", -					total_mem.value(), -					max_total_mem.value(), -                    LLImageGLThread::getFreeVRAMMegabytes(), +    text = llformat("GL Free: %d MB Sys Free: %d MB FBO: %d MB Bias: %.2f Cache: %.1f/%.1f MB", +                    gViewerWindow->getWindow()->getAvailableVRAMMegabytes(),                      LLMemory::getAvailableMemKB()/1024, -					bound_mem.value(), -					max_bound_mem.value(),  					LLRenderTarget::sBytesAllocated/(1024*1024), -					LLImageRaw::sGlobalRawMemory >> 20,  					discard_bias,  					cache_usage,  					cache_max_usage); @@ -837,7 +817,7 @@ void LLTextureView::draw()  				LL_INFOS() << imagep->getID()  						<< "\t" << tex_mem  						<< "\t" << imagep->getBoostLevel() -						<< "\t" << imagep->getDecodePriority() +						<< "\t" << imagep->getMaxVirtualSize()  						<< "\t" << imagep->getWidth()  						<< "\t" << imagep->getHeight()  						<< "\t" << cur_discard @@ -857,7 +837,7 @@ void LLTextureView::draw()  			}  			else  			{ -				pri = imagep->getDecodePriority(); +				pri = imagep->getMaxVirtualSize();  			}  			pri = llclamp(pri, 0.0f, HIGH_PRIORITY-1.f); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index d5f842d925..9682945208 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -341,12 +341,6 @@ static bool handleMaxPartCountChanged(const LLSD& newvalue)  	return true;  } -static bool handleVideoMemoryChanged(const LLSD& newvalue) -{ -	gTextureList.updateMaxResidentTexMem(S32Megabytes(newvalue.asInteger())); -	return true; -} -  static bool handleChatFontSizeChanged(const LLSD& newvalue)  {  	if(gConsole) @@ -706,7 +700,6 @@ void settings_setup_listeners()  	gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));  	gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));  	gSavedSettings.getControl("RenderPerformanceTest")->getSignal()->connect(boost::bind(&handleRenderPerfTestChanged, _2)); -	gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _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)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 6d98d9b10e..77b84c6789 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -797,8 +797,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  				LLViewerTexture::updateClass();  			} -            LLImageGLThread::updateClass(); -  			{  				LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_BUMP);  				gBumpImageList.updateImages();  // must be called before gTextureList version so that it's textures are thrown out first. diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 97cb8e2000..2daa919f5c 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -132,7 +132,6 @@  #include "llfloatertelehub.h"  #include "llfloatertestinspectors.h"  #include "llfloatertestlistview.h" -#include "llfloatertexturefetchdebugger.h"  #include "llfloatertools.h"  #include "llfloatertopobjects.h"  #include "llfloatertos.h" @@ -284,10 +283,6 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("mem_leaking", "floater_mem_leaking.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMemLeak>); -	if(gSavedSettings.getBOOL("TextureFetchDebuggerEnabled")) -	{ -		LLFloaterReg::add("tex_fetch_debugger", "floater_texture_fetch_debugger.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTextureFetchDebugger>); -	}  	LLFloaterReg::add("media_settings", "floater_media_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaSettings>);	  	LLFloaterReg::add("marketplace_listings", "floater_marketplace_listings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMarketplaceListings>);  	LLFloaterReg::add("marketplace_validation", "floater_marketplace_validation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMarketplaceValidation>); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 6aa1c5fece..6d61193a56 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2515,14 +2515,6 @@ class LLDevelopSetLoggingLevel : public view_listener_t  	}  }; -class LLDevelopTextureFetchDebugger : public view_listener_t -{ -	bool handleEvent(const LLSD& userdata) -	{ -		return gSavedSettings.getBOOL("TextureFetchDebuggerEnabled"); -	} -}; -  //////////////////  // ADMIN MENU   //  ////////////////// @@ -9471,8 +9463,6 @@ void initialize_menus()  	view_listener_t::addMenu(new LLDevelopCheckLoggingLevel(), "Develop.CheckLoggingLevel");  	view_listener_t::addMenu(new LLDevelopSetLoggingLevel(), "Develop.SetLoggingLevel"); -	//Develop (Texture Fetch Debug Console) -	view_listener_t::addMenu(new LLDevelopTextureFetchDebugger(), "Develop.SetTexFetchDebugger");  	//Develop (clear cache immediately)  	commit.add("Develop.ClearCache", boost::bind(&handle_cache_clear_immediately) );      //Develop (override environment map) diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 3385d317e6..796ff04a41 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -155,10 +155,7 @@ LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> >  static LLTrace::SampleStatHandle<bool>   							CHAT_BUBBLES("chatbubbles", "Chat Bubbles Enabled"); -LLTrace::SampleStatHandle<F64Megabytes >	GL_TEX_MEM("gltexmemstat"), -															GL_BOUND_MEM("glboundmemstat"), -															RAW_MEM("rawmemstat"), -															FORMATTED_MEM("formattedmemstat"); +LLTrace::SampleStatHandle<F64Megabytes > FORMATTED_MEM("formattedmemstat");  LLTrace::SampleStatHandle<F64Kilobytes >	DELTA_BANDWIDTH("deltabandwidth", "Increase/Decrease in bandwidth based on packet loss"),  															MAX_BANDWIDTH("maxbandwidth", "Max bandwidth setting"); @@ -319,8 +316,6 @@ U32Bytes			gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGOR  extern U32  gVisCompared;  extern U32  gVisTested; -LLFrameTimer gTextureTimer; -  void update_statistics()  {  	gTotalWorldData += gVLManager.getTotalBytes(); @@ -416,19 +411,6 @@ void update_statistics()  	}  } -void update_texture_time() -{ -	if (gTextureList.isPrioRequestsFetched()) -	{ -		gTextureTimer.pause(); -	} -	else -	{		 -		gTextureTimer.unpause(); -	} - -	record(LLStatViewer::TEXTURE_FETCH_TIME, gTextureTimer.getElapsedTimeF32()); -}  /*   * The sim-side LLSD is in newsim/llagentinfo.cpp:forwardViewerStats.   * diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index 017c79b2e3..c21c06256e 100644 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -191,10 +191,8 @@ extern LLTrace::SampleStatHandle<>		FPS_SAMPLE,  extern LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > PACKETS_LOST_PERCENT; -extern LLTrace::SampleStatHandle<F64Megabytes >	GL_TEX_MEM, -																	GL_BOUND_MEM, -																	RAW_MEM, -																	FORMATTED_MEM; +extern LLTrace::SampleStatHandle<F64Megabytes > FORMATTED_MEM; +  extern LLTrace::SampleStatHandle<F64Kilobytes >	DELTA_BANDWIDTH,  																	MAX_BANDWIDTH;  extern SimMeasurement<F64Milliseconds >	SIM_FRAME_TIME, @@ -296,7 +294,6 @@ void update_statistics();  void send_viewer_stats(bool include_preferences);  void update_texture_time(); -extern LLFrameTimer gTextureTimer;  extern U32Bytes	gTotalTextureData;  extern U32Bytes  gTotalObjectData;  extern U32Bytes  gTotalTextureBytesPerBoostLevel[] ; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index c389d2122e..0c23214b52 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -58,6 +58,8 @@  #include "llvovolume.h"  #include "llviewermedia.h"  #include "lltexturecache.h" +#include "llviewerwindow.h" +#include "llwindow.h"  ///////////////////////////////////////////////////////////////////////////////  // extern @@ -76,6 +78,8 @@ LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sSmokeImagep = NULL;  LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sFlatNormalImagep = NULL;  LLViewerMediaTexture::media_map_t LLViewerMediaTexture::sMediaMap;  LLTexturePipelineTester* LLViewerTextureManager::sTesterp = NULL; +F32 LLViewerFetchedTexture::sMaxVirtualSize = F32_MAX/2.f; +  const std::string sTesterName("TextureTester");  S32 LLViewerTexture::sImageCount = 0; @@ -84,11 +88,6 @@ S32 LLViewerTexture::sAuxCount = 0;  LLFrameTimer LLViewerTexture::sEvaluationTimer;  F32 LLViewerTexture::sDesiredDiscardBias = 0.f;  F32 LLViewerTexture::sDesiredDiscardScale = 1.1f; -S32Bytes LLViewerTexture::sBoundTextureMemory; -S32Bytes LLViewerTexture::sTotalTextureMemory; -S32Megabytes LLViewerTexture::sMaxBoundTextureMemory; -S32Megabytes LLViewerTexture::sMaxTotalTextureMem; -S32Bytes LLViewerTexture::sMaxDesiredTextureMem;  S8  LLViewerTexture::sCameraMovingDiscardBias = 0;  F32 LLViewerTexture::sCameraMovingBias = 0.0f;  S32 LLViewerTexture::sMaxSculptRez = 128; //max sculpt image size @@ -471,11 +470,6 @@ void LLViewerTextureManager::cleanup()  void LLViewerTexture::initClass()  {  	LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture(); -	 -	if(gSavedSettings.getBOOL("TextureFetchDebuggerEnabled")) -	{ -		sTexelPixelRatio = gSavedSettings.getF32("TexelPixelRatio"); -	}  }  // tuning params @@ -500,7 +494,7 @@ bool LLViewerTexture::isMemoryForTextureLow()      S32Megabytes physical;      getGPUMemoryForTextures(gpu, physical); -    return (gpu < MIN_FREE_TEXTURE_MEMORY) || (physical < MIN_FREE_MAIN_MEMORY); +    return (gpu < MIN_FREE_TEXTURE_MEMORY); // || (physical < MIN_FREE_MAIN_MEMORY);  }  //static @@ -514,7 +508,7 @@ bool LLViewerTexture::isMemoryForTextureSuficientlyFree()      S32Megabytes physical;      getGPUMemoryForTextures(gpu, physical); -    return (gpu > DESIRED_FREE_TEXTURE_MEMORY) && (physical > DESIRED_FREE_MAIN_MEMORY); +    return (gpu > DESIRED_FREE_TEXTURE_MEMORY); // && (physical > DESIRED_FREE_MAIN_MEMORY);  }  //static @@ -535,9 +529,9 @@ void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &p      timer.reset();      { -        gpu_res = (S32Megabytes) LLImageGLThread::getFreeVRAMMegabytes(); +        gpu_res = (S32Megabytes)gViewerWindow->getWindow()->getAvailableVRAMMegabytes(); -        //check main memory, only works for windows. +        //check main memory, only works for windows and macos.          LLMemory::updateMemoryInfo();          physical_res = LLMemory::getAvailableMemKB(); @@ -560,27 +554,7 @@ void LLViewerTexture::updateClass()  	LLViewerMediaTexture::updateClass(); -	sBoundTextureMemory = LLImageGL::sBoundTextureMemory; -	sTotalTextureMemory = LLImageGL::sGlobalTextureMemory; -	sMaxBoundTextureMemory = gTextureList.getMaxResidentTexMem(); -	sMaxTotalTextureMem = gTextureList.getMaxTotalTextureMem(); -	sMaxDesiredTextureMem = sMaxTotalTextureMem; //in Bytes, by default and when total used texture memory is small. - -	if (sBoundTextureMemory >= sMaxBoundTextureMemory || -		sTotalTextureMemory >= sMaxTotalTextureMem) -	{ -		//when texture memory overflows, lower down the threshold to release the textures more aggressively. -		sMaxDesiredTextureMem = llmin(sMaxDesiredTextureMem * 0.75f, F32Bytes(gMaxVideoRam)); -	 -		// If we are using more texture memory than we should, -		// scale up the desired discard level -		if (sEvaluationTimer.getElapsedTimeF32() > discard_delta_time) -		{ -			sDesiredDiscardBias += discard_bias_delta; -			sEvaluationTimer.reset(); -		} -	} -	else if(isMemoryForTextureLow()) +	if(isMemoryForTextureLow())  	{  		// Note: isMemoryForTextureLow() uses 1s delay, make sure we waited enough for it to recheck  		if (sEvaluationTimer.getElapsedTimeF32() > GPU_MEMORY_CHECK_WAIT_TIME) @@ -590,8 +564,6 @@ void LLViewerTexture::updateClass()  		}  	}  	else if (sDesiredDiscardBias > 0.0f -			 && sBoundTextureMemory < sMaxBoundTextureMemory * texmem_lower_bound_scale -			 && sTotalTextureMemory < sMaxTotalTextureMem * texmem_lower_bound_scale  			 && isMemoryForTextureSuficientlyFree())  	{  		// If we are using less texture memory than we should, @@ -661,7 +633,6 @@ void LLViewerTexture::init(bool firstinit)  	mMaxVirtualSize = 0.f;  	mMaxVirtualSizeResetInterval = 1;  	mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval; -	mAdditionalDecodePriority = 0.f;	  	mParcelMedia = NULL;  	memset(&mNumVolumes, 0, sizeof(U32)* LLRender::NUM_VOLUME_TEXTURE_CHANNELS); @@ -689,6 +660,11 @@ void LLViewerTexture::cleanup()  {  	notifyAboutMissingAsset(); +    if (LLAppViewer::getTextureFetch()) +    { +        LLAppViewer::getTextureFetch()->updateRequestPriority(mID, 0.f); +    } +  	mFaceList[LLRender::DIFFUSE_MAP].clear();  	mFaceList[LLRender::NORMAL_MAP].clear();  	mFaceList[LLRender::SPECULAR_MAP].clear(); @@ -745,6 +721,12 @@ void LLViewerTexture::setBoostLevel(S32 level)  		}  	} +    // strongly encourage anything boosted to load at full res +    if (mBoostLevel >= LLViewerTexture::BOOST_HIGH) +    { +        mMaxVirtualSize = 2048.f * 2048.f; +    } +  	if (mBoostLevel == LLViewerTexture::BOOST_SELECTED)  	{  		mSelectedTime = gFrameTimeSeconds; @@ -828,15 +810,8 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co  	}  	virtual_size *= sTexelPixelRatio; -	if(!mMaxVirtualSizeResetCounter) -	{ -		//flag to reset the values because the old values are used. -		resetMaxVirtualSizeResetCounter(); -		mMaxVirtualSize = virtual_size; -		mAdditionalDecodePriority = 0.f; -		mNeedsGLTexture = needs_gltexture; -	} -	else if (virtual_size > mMaxVirtualSize) + +	if (virtual_size > mMaxVirtualSize)  	{  		mMaxVirtualSize = virtual_size;  	} @@ -845,7 +820,6 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co  void LLViewerTexture::resetTextureStats()  {  	mMaxVirtualSize = 0.0f; -	mAdditionalDecodePriority = 0.f;	  	mMaxVirtualSizeResetCounter = 0;  } @@ -1114,7 +1088,6 @@ void LLViewerFetchedTexture::init(bool firstinit)  	if (firstinit)  	{ -		mDecodePriority = 0.f;  		mInImageList = 0;  	} @@ -1163,6 +1136,7 @@ void LLViewerFetchedTexture::init(bool firstinit)  LLViewerFetchedTexture::~LLViewerFetchedTexture()  { +    assert_main_thread();  	//*NOTE getTextureFetch can return NULL when Viewer is shutting down.  	// This is due to LLWearableList is singleton and is destroyed after   	// LLAppViewer::cleanup() was called. (see ticket EXT-177) @@ -1359,10 +1333,7 @@ void LLViewerFetchedTexture::dump()  void LLViewerFetchedTexture::destroyTexture()   {      LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; -	if(LLImageGL::sGlobalTextureMemory < sMaxDesiredTextureMem * 0.95f)//not ready to release unused memory. -	{ -		return ; -	} +  	if (mNeedsCreateTexture)//return if in the process of generating a new texture.  	{  		return; @@ -1598,6 +1569,7 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)  void LLViewerFetchedTexture::postCreateTexture()  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;      if (!mNeedsCreateTexture)      {          return; @@ -1621,6 +1593,8 @@ void LLViewerFetchedTexture::postCreateTexture()  void LLViewerFetchedTexture::scheduleCreateTexture()  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; +      if (!mNeedsCreateTexture)      {          mNeedsCreateTexture = TRUE; @@ -1697,6 +1671,7 @@ void LLViewerFetchedTexture::scheduleCreateTexture()  //virtual  void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	if(mKnownDrawWidth < width || mKnownDrawHeight < height)  	{  		mKnownDrawWidth = llmax(mKnownDrawWidth, width); @@ -1708,9 +1683,31 @@ void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height)  	addTextureStats((F32)(mKnownDrawWidth * mKnownDrawHeight));  } +void LLViewerFetchedTexture::setDebugText(const std::string& text) +{ +    for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch) +    { +        llassert(mNumFaces[ch] <= mFaceList[ch].size()); + +        for (U32 i = 0; i < mNumFaces[ch]; i++) +        { +            LLFace* facep = mFaceList[ch][i]; +            if (facep) +            { +                LLDrawable* drawable = facep->getDrawable(); +                if (drawable) +                { +                    drawable->getVObj()->setDebugText(text); +                } +            } +        } +    } +} +  //virtual  void LLViewerFetchedTexture::processTextureStats()  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	if(mFullyLoaded)  	{		  		if(mDesiredDiscardLevel > mMinDesiredDiscardLevel)//need to load more @@ -1718,6 +1715,7 @@ void LLViewerFetchedTexture::processTextureStats()  			mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel);  			mFullyLoaded = FALSE;  		} +        //setDebugText("fully loaded");  	}  	else  	{ @@ -1730,7 +1728,7 @@ void LLViewerFetchedTexture::processTextureStats()  			mDesiredDiscardLevel = 0;  		}  		else if (!LLPipeline::sRenderDeferred && mBoostLevel == LLGLTexture::BOOST_ALM) -		{ +		{ // ??? don't load spec and normal maps when alm is disabled ???  			mDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;  		}          else if (mDontDiscard && mBoostLevel == LLGLTexture::BOOST_ICON) @@ -1788,198 +1786,8 @@ void LLViewerFetchedTexture::processTextureStats()  	}  } -const F32 MAX_PRIORITY_PIXEL                         = 999.f;     //pixel area -const F32 PRIORITY_BOOST_LEVEL_FACTOR                = 1000.f;    //boost level -const F32 PRIORITY_DELTA_DISCARD_LEVEL_FACTOR        = 100000.f;  //delta discard -const S32 MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY       = 4; -const F32 PRIORITY_ADDITIONAL_FACTOR                 = 1000000.f; //additional  -const S32 MAX_ADDITIONAL_LEVEL_FOR_PRIORITY          = 8; -const F32 PRIORITY_BOOST_HIGH_FACTOR                 = 10000000.f;//boost high -F32 LLViewerFetchedTexture::calcDecodePriority() -{ -#ifndef LL_RELEASE_FOR_DOWNLOAD -	if (mID == LLAppViewer::getTextureFetch()->mDebugID) -	{ -		LLAppViewer::getTextureFetch()->mDebugCount++; // for setting breakpoints -	} -#endif -	 -	if (mNeedsCreateTexture) -	{ -		return mDecodePriority; // no change while waiting to create -	} -	if(mFullyLoaded && !mForceToSaveRawImage)//already loaded for static texture -	{ -		return -1.0f; //alreay fetched -	} - -	S32 cur_discard = getCurrentDiscardLevelForFetching(); -	bool have_all_data = (cur_discard >= 0 && (cur_discard <= mDesiredDiscardLevel)); -	F32 pixel_priority = (F32) sqrt(mMaxVirtualSize); - -	F32 priority = 0.f; - -	if (mIsMissingAsset) -	{ -		priority = 0.0f; -	} -	else if(mDesiredDiscardLevel >= cur_discard && cur_discard > -1) -	{ -		priority = -2.0f; -	} -	else if(mCachedRawDiscardLevel > -1 && mDesiredDiscardLevel >= mCachedRawDiscardLevel) -	{ -		priority = -3.0f; -	} -	else if (mDesiredDiscardLevel > getMaxDiscardLevel()) -	{ -		// Don't decode anything we don't need -		priority = -4.0f; -	} -	else if ((mBoostLevel == LLGLTexture::BOOST_UI || mBoostLevel == LLGLTexture::BOOST_ICON) && !have_all_data) -	{ -		priority = 1.f; -	} -	else if (pixel_priority < 0.001f && !have_all_data) -	{ -		// Not on screen but we might want some data -		if (mBoostLevel > BOOST_SELECTED) -		{ -			// Always want high boosted images -			priority = 1.f; -		} -		else -		{ -			priority = -5.f; //stop fetching -		} -	} -	else if (cur_discard < 0) -	{ -		//texture does not have any data, so we don't know the size of the image, treat it like 32 * 32. -		// priority range = 100,000 - 500,000 -		static const F64 log_2 = log(2.0); -		F32 desired = (F32)(log(32.0/pixel_priority) / log_2); -		S32 ddiscard = MAX_DISCARD_LEVEL - (S32)desired; -		ddiscard = llclamp(ddiscard, 0, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY); -		priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR; -		setAdditionalDecodePriority(0.1f);//boost the textures without any data so far. -	} -	else if ((mMinDiscardLevel > 0) && (cur_discard <= mMinDiscardLevel)) -	{ -		// larger mips are corrupted -		priority = -6.0f; -	} -	else -	{ -		// priority range = 100,000 - 500,000 -		S32 desired_discard = mDesiredDiscardLevel; -		if (!isJustBound() && mCachedRawImageReady) -		{ -			if(mBoostLevel < BOOST_HIGH) -			{ -				// We haven't rendered this in a while, de-prioritize it -				desired_discard += 2; -			} -			else -			{ -				// We haven't rendered this in the last half second, and we have a cached raw image, leave the desired discard as-is -				desired_discard = cur_discard; -			} -		} - -		S32 ddiscard = cur_discard - desired_discard; -		ddiscard = llclamp(ddiscard, -1, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY); -		priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR;		 -	} - -	// Priority Formula: -	// BOOST_HIGH  +  ADDITIONAL PRI + DELTA DISCARD + BOOST LEVEL + PIXELS -	// [10,000,000] + [1,000,000-9,000,000]  + [100,000-500,000]   + [1-20,000]  + [0-999] -	if (priority > 0.0f) -	{ -		bool large_enough = mCachedRawImageReady && ((S32)mTexelsPerImage > sMinLargeImageSize); -		if(large_enough) -		{ -			//Note:  -			//to give small, low-priority textures some chance to be fetched,  -			//cut the priority in half if the texture size is larger than 256 * 256 and has a 64*64 ready. -			priority *= 0.5f;  -		} - -		pixel_priority = llclamp(pixel_priority, 0.0f, MAX_PRIORITY_PIXEL);  - -		priority += pixel_priority + PRIORITY_BOOST_LEVEL_FACTOR * mBoostLevel; - -		if ( mBoostLevel > BOOST_HIGH) -		{ -			if(mBoostLevel > BOOST_SUPER_HIGH) -			{ -				//for very important textures, always grant the highest priority. -				priority += PRIORITY_BOOST_HIGH_FACTOR; -			} -			else if(mCachedRawImageReady) -			{ -				//Note:  -				//to give small, low-priority textures some chance to be fetched,  -				//if high priority texture has a 64*64 ready, lower its fetching priority. -				setAdditionalDecodePriority(0.5f); -			} -			else -			{ -				priority += PRIORITY_BOOST_HIGH_FACTOR; -			} -		}		 - -		if(mAdditionalDecodePriority > 0.0f) -		{ -			// priority range += 1,000,000.f-9,000,000.f -			F32 additional = PRIORITY_ADDITIONAL_FACTOR * (1.0 + mAdditionalDecodePriority * MAX_ADDITIONAL_LEVEL_FOR_PRIORITY); -			if(large_enough) -			{ -				//Note:  -				//to give small, low-priority textures some chance to be fetched,  -				//cut the additional priority to a quarter if the texture size is larger than 256 * 256 and has a 64*64 ready. -				additional *= 0.25f; -			} -			priority += additional; -		} -	} -	return priority; -} - -//static -F32 LLViewerFetchedTexture::maxDecodePriority() -{ -	static const F32 max_priority = PRIORITY_BOOST_HIGH_FACTOR +                           //boost_high -		PRIORITY_ADDITIONAL_FACTOR * (MAX_ADDITIONAL_LEVEL_FOR_PRIORITY + 1) +             //additional (view dependent factors) -		PRIORITY_DELTA_DISCARD_LEVEL_FACTOR * (MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY + 1) + //delta discard -		PRIORITY_BOOST_LEVEL_FACTOR * (BOOST_MAX_LEVEL - 1) +                              //boost level -		MAX_PRIORITY_PIXEL + 1.0f;                                                        //pixel area. -	 -	return max_priority; -} -  //============================================================================ -void LLViewerFetchedTexture::setDecodePriority(F32 priority) -{ -	mDecodePriority = priority; - -	if(mDecodePriority < F_ALMOST_ZERO) -	{ -		mStopFetchingTimer.reset(); -	} -} - -void LLViewerFetchedTexture::setAdditionalDecodePriority(F32 priority) -{ -	priority = llclamp(priority, 0.f, 1.f); -	if(mAdditionalDecodePriority < priority) -	{ -		mAdditionalDecodePriority = priority; -	} -} -  void LLViewerFetchedTexture::updateVirtualSize()   {	      LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; @@ -1988,6 +1796,18 @@ void LLViewerFetchedTexture::updateVirtualSize()  		addTextureStats(0.f, FALSE);//reset  	} +    if (getBoostLevel() >= LLViewerTexture::BOOST_HIGH) +    { //always load boosted textures at highest priority full res +        addTextureStats(sMaxVirtualSize); +        return; +    } + +    if (sDesiredDiscardBias > 0.f) +    { +        // running out of video memory, don't hold onto high res textures in the background +        mMaxVirtualSize = 0.f; +    } +  	for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)  	{				  		llassert(mNumFaces[ch] <= mFaceList[ch].size()); @@ -2009,8 +1829,12 @@ void LLViewerFetchedTexture::updateVirtualSize()  						setBoostLevel(LLViewerTexture::BOOST_SELECTED);  					}  					addTextureStats(facep->getVirtualSize()); -					setAdditionalDecodePriority(facep->getImportanceToCamera()); +                    //drawable->getVObj()->setDebugText(llformat("%d:%d", (S32)sqrtf(facep->getVirtualSize()), (S32)sqrtf(getMaxVirtualSize())));  				} +                else +                { +                    //drawable->getVObj()->setDebugText(""); +                }  			}  		}  	} @@ -2072,6 +1896,16 @@ bool LLViewerFetchedTexture::isActiveFetching()  	return mFetchState > 7 && mFetchState < 10 && monitor_enabled; //in state of WAIT_HTTP_REQ or DECODE_IMAGE.  } +void LLViewerFetchedTexture::setBoostLevel(S32 level) +{ +    LLViewerTexture::setBoostLevel(level); + +    if (level >= LLViewerTexture::BOOST_HIGH) +    { +        mDesiredDiscardLevel = 0; +    } +} +  bool LLViewerFetchedTexture::updateFetch()  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; @@ -2098,31 +1932,40 @@ bool LLViewerFetchedTexture::updateFetch()  	if (mNeedsCreateTexture)  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - needs create");  		// We may be fetching still (e.g. waiting on write)  		// but don't check until we've processed the raw data we have  		return false;  	}  	if (mIsMissingAsset)  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - missing asset");  		llassert_always(!mHasFetcher);  		return false; // skip  	}  	if (!mLoadedCallbackList.empty() && mRawImage.notNull())  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - callback pending");  		return false; // process any raw image data in callbacks before replacing  	}  	if(mInFastCacheList)  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - in fast cache");  		return false;  	} +    if (mGLTexturep.isNull()) +    { // fix for crash inside getCurrentDiscardLevelForFetching (shouldn't happen but appears to be happening) +        llassert(false); +        return false; +    }  	S32 current_discard = getCurrentDiscardLevelForFetching();  	S32 desired_discard = getDesiredDiscardLevel(); -	F32 decode_priority = getDecodePriority(); -	decode_priority = llclamp(decode_priority, 0.0f, maxDecodePriority()); +	F32 decode_priority = mMaxVirtualSize;  	if (mIsFetching)  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - is fetching");  		// Sets mRawDiscardLevel, mRawImage, mAuxRawImage  		S32 fetch_discard = current_discard; @@ -2140,17 +1983,25 @@ bool LLViewerFetchedTexture::updateFetch()  		if (finished)  		{  			mIsFetching = FALSE; +            mLastFetchState = -1; +            setDebugText("");  			mLastPacketTimer.reset();  		}  		else  		{  			mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,  																		mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP); +            /*if (mFetchState != mLastFetchState) +            { +                setDebugText(LLTextureFetch::getStateString(mFetchState)); +                mLastFetchState = mFetchState; +            }*/  		}  		// We may have data ready regardless of whether or not we are finished (e.g. waiting on write)  		if (mRawImage.notNull())  		{ +            LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - has raw image");  			LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);  			if (tester)  			{ @@ -2161,6 +2012,7 @@ bool LLViewerFetchedTexture::updateFetch()  			if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) &&  				(current_discard < 0 || mRawDiscardLevel < current_discard))  			{ +                LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - data good");  				mFullWidth = mRawImage->getWidth() << mRawDiscardLevel;  				mFullHeight = mRawImage->getHeight() << mRawDiscardLevel;  				setTexelsPerImage(); @@ -2197,6 +2049,7 @@ bool LLViewerFetchedTexture::updateFetch()  			}  			else  			{ +                LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - data not needed");  				// Data is ready but we don't need it  				// (received it already while fetcher was writing to disk)  				destroyRawImage(); @@ -2206,7 +2059,7 @@ bool LLViewerFetchedTexture::updateFetch()  		if (!mIsFetching)  		{ -			if ((decode_priority > 0) && (mRawDiscardLevel < 0 || mRawDiscardLevel == INVALID_DISCARD_LEVEL)) +			if ((decode_priority > 0) && (mRawDiscardLevel < 0))  			{  				// We finished but received no data  				if (getDiscardLevel() < 0) @@ -2229,13 +2082,13 @@ bool LLViewerFetchedTexture::updateFetch()  					if(current_discard >= 0)  					{  						mMinDiscardLevel = current_discard; -						desired_discard = current_discard; +						//desired_discard = current_discard;  					}  					else  					{  						S32 dis_level = getDiscardLevel();  						mMinDiscardLevel = dis_level; -						desired_discard = dis_level; +						//desired_discard = dis_level;  					}  				}  				destroyRawImage(); @@ -2249,12 +2102,6 @@ bool LLViewerFetchedTexture::updateFetch()  		}  		else  		{ -// 			// Useful debugging code for undesired deprioritization of textures. -// 			if (decode_priority <= 0.0f && desired_discard >= 0 && desired_discard < current_discard) -// 			{ -// 				LL_INFOS() << "Calling updateRequestPriority() with decode_priority = 0.0f" << LL_ENDL; -// 				calcDecodePriority(); -// 			}  			static const F32 MAX_HOLD_TIME = 5.0f; //seconds to wait before canceling fecthing if decode_priority is 0.f.  			if(decode_priority > 0.0f || mStopFetchingTimer.getElapsedTimeF32() > MAX_HOLD_TIME)  			{ @@ -2264,21 +2111,27 @@ bool LLViewerFetchedTexture::updateFetch()  		}  	} +    desired_discard = llmin(desired_discard, getMaxDiscardLevel()); +  	bool make_request = true;	 -	if (decode_priority <= 0) +	/*if (decode_priority <= 0)  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - priority <= 0");  		make_request = false;  	}  	else if(mDesiredDiscardLevel > getMaxDiscardLevel())  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - desired > max");  		make_request = false;  	} -	else if (mNeedsCreateTexture || mIsMissingAsset) +	else */ if (mNeedsCreateTexture || mIsMissingAsset)  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - create or missing");  		make_request = false;  	}  	else if (current_discard >= 0 && current_discard <= mMinDiscardLevel)  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - current < min");  		make_request = false;  	}  	else if(mCachedRawImage.notNull() // can be empty @@ -2295,6 +2148,7 @@ bool LLViewerFetchedTexture::updateFetch()  	if (make_request)  	{ +#if 0  		// Load the texture progressively: we try not to rush to the desired discard too fast.  		// If the camera is not moving, we do not tweak the discard level notch by notch but go to the desired discard with larger boosted steps  		// This mitigates the "textures stay blurry" problem when loading while not killing the texture memory while moving around @@ -2311,18 +2165,23 @@ bool LLViewerFetchedTexture::updateFetch()          {  			desired_discard = llmax(desired_discard, current_discard - delta_level);          } +#endif  		if (mIsFetching)  		{ +            // already requested a higher resolution mip  			if (mRequestedDiscardLevel <= desired_discard)  			{ +                LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - requested < desired");  				make_request = false;  			}  		}  		else  		{ +            // already at a higher resolution mip, don't discard  			if (current_discard >= 0 && current_discard <= desired_discard)  			{ +                LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - current <= desired");  				make_request = false;  			}  		} @@ -2330,6 +2189,7 @@ bool LLViewerFetchedTexture::updateFetch()  	if (make_request)  	{ +        LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - make request");  		S32 w=0, h=0, c=0;  		if (getDiscardLevel() >= 0)  		{ @@ -2351,6 +2211,7 @@ bool LLViewerFetchedTexture::updateFetch()  		if (fetch_request_created)  		{ +            LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - request created");  			mHasFetcher = TRUE;  			mIsFetching = TRUE;  			mRequestedDiscardLevel = desired_discard; @@ -2358,15 +2219,18 @@ bool LLViewerFetchedTexture::updateFetch()  													   mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);  		} -		// if createRequest() failed, we're finishing up a request for this UUID, -		// wait for it to complete +        // If createRequest() failed, that means one of two things: +        // 1. We're finishing up a request for this UUID, so we +        //    should wait for it to complete +        // 2. We've failed a request for this UUID, so there is +        //    no need to create another request  	}  	else if (mHasFetcher && !mIsFetching)  	{  		// Only delete requests that haven't received any network data  		// for a while.  Note - this is the normal mechanism for  		// deleting requests, not just a place to handle timeouts. -		const F32 FETCH_IDLE_TIME = 5.f; +		const F32 FETCH_IDLE_TIME = 0.1f;  		if (mLastPacketTimer.getElapsedTimeF32() > FETCH_IDLE_TIME)  		{   			LL_DEBUGS("Texture") << "exceeded idle time " << FETCH_IDLE_TIME << ", deleting request: " << getID() << LL_ENDL; @@ -2676,7 +2540,7 @@ bool LLViewerFetchedTexture::doLoadedCallbacks()  			LL_INFOS() << "baked texture: " << mID << "clears all call backs due to inactivity." << LL_ENDL;  			LL_INFOS() << mUrl << LL_ENDL;  			LL_INFOS() << "current discard: " << getDiscardLevel() << " current discard for fetch: " << getCurrentDiscardLevelForFetching() << -				" Desired discard: " << getDesiredDiscardLevel() << "decode Pri: " << getDecodePriority() << LL_ENDL; +				" Desired discard: " << getDesiredDiscardLevel() << "decode Pri: " << mMaxVirtualSize << LL_ENDL;  		}  		clearCallbackEntryList() ; //remove all callbacks. @@ -2907,7 +2771,7 @@ void LLViewerFetchedTexture::forceImmediateUpdate()  		return;  	}  	//if already called forceImmediateUpdate() -	if(mInImageList && mDecodePriority == LLViewerFetchedTexture::maxDecodePriority()) +	if(mInImageList && mMaxVirtualSize == LLViewerFetchedTexture::sMaxVirtualSize)  	{  		return;  	} @@ -2976,6 +2840,7 @@ bool LLViewerFetchedTexture::needsToSaveRawImage()  void LLViewerFetchedTexture::destroyRawImage()  {	 +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	if (mAuxRawImage.notNull() && !needsToSaveRawImage())  	{  		sAuxCount--; @@ -3059,6 +2924,7 @@ void LLViewerFetchedTexture::setCachedRawImage(S32 discard_level, LLImageRaw* im  void LLViewerFetchedTexture::setCachedRawImage()  {	 +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	if(mRawImage == mCachedRawImage)  	{  		return; @@ -3134,6 +3000,7 @@ void LLViewerFetchedTexture::checkCachedRawSculptImage()  void LLViewerFetchedTexture::saveRawImage()   { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	if(mRawImage.isNull() || mRawImage == mSavedRawImage || (mSavedRawDiscardLevel >= 0 && mSavedRawDiscardLevel <= mRawDiscardLevel))  	{  		return; @@ -3349,25 +3216,10 @@ void LLViewerLODTexture::processTextureStats()  		}  		else  		{ -			if(isLargeImage() && !isJustBound() && mAdditionalDecodePriority < 0.3f) -			{ -				//if is a big image and not being used recently, nor close to the view point, do not load hi-res data. -				mMaxVirtualSize = llmin(mMaxVirtualSize, (F32)LLViewerTexture::sMinLargeImageSize); -			} - -			if ((mCalculatedDiscardLevel >= 0.f) && -				(llabs(mMaxVirtualSize - mDiscardVirtualSize) < mMaxVirtualSize*.20f)) -			{ -				// < 20% change in virtual size = no change in desired discard -				discard_level = mCalculatedDiscardLevel;  -			} -			else -			{ -				// Calculate the required scale factor of the image using pixels per texel -				discard_level = (F32)(log(mTexelsPerImage/mMaxVirtualSize) / log_4); -				mDiscardVirtualSize = mMaxVirtualSize; -				mCalculatedDiscardLevel = discard_level; -			} +			// Calculate the required scale factor of the image using pixels per texel +			discard_level = (F32)(log(mTexelsPerImage/mMaxVirtualSize) / log_4); +			mDiscardVirtualSize = mMaxVirtualSize; +			mCalculatedDiscardLevel = discard_level;  		}  		if (mBoostLevel < LLGLTexture::BOOST_SCULPTED)  		{ @@ -3407,18 +3259,6 @@ void LLViewerLODTexture::processTextureStats()  				//needs to release texture memory urgently  				scaleDown();  			} -			// Limit the amount of GL memory bound each frame -			else if ( sBoundTextureMemory > sMaxBoundTextureMemory * texmem_middle_bound_scale && -				(!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel)) -			{ -				scaleDown(); -			} -			// Only allow GL to have 2x the video card memory -			else if ( sTotalTextureMemory > sMaxTotalTextureMem * texmem_middle_bound_scale && -				(!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel)) -			{ -				scaleDown(); -			}  		}  		if (isUpdateFrozen() // we are out of memory and nearing max allowed bias @@ -4199,7 +4039,6 @@ void LLTexturePipelineTester::compareTestSessions(llofstream* os)  	*os << llformat("%s\n", getTesterName().c_str());  	*os << llformat("AggregateResults\n"); -	compareTestResults(os, "TotalFetchingTime", base_sessionp->mTotalFetchingTime, current_sessionp->mTotalFetchingTime);  	compareTestResults(os, "TotalGrayTime", base_sessionp->mTotalGrayTime, current_sessionp->mTotalGrayTime);  	compareTestResults(os, "TotalStablizingTime", base_sessionp->mTotalStablizingTime, current_sessionp->mTotalStablizingTime);  	compareTestResults(os, "StartTimeLoadingSculpties", base_sessionp->mStartTimeLoadingSculpties, current_sessionp->mStartTimeLoadingSculpties);		 @@ -4259,7 +4098,6 @@ LLMetricPerformanceTesterWithSession::LLTestSession* LLTexturePipelineTester::lo  		return NULL;  	} -	F32 total_fetching_time = 0.f;  	F32 total_gray_time = 0.f;  	F32 total_stablizing_time = 0.f;  	F32 total_loading_sculpties_time = 0.f; @@ -4294,7 +4132,6 @@ LLMetricPerformanceTesterWithSession::LLTestSession* LLTexturePipelineTester::lo  		F32 cur_time   = (*log)[label]["Time"].asReal();  		if(start_time - start_fetching_time > F_ALMOST_ZERO) //fetching has paused for a while  		{ -			sessionp->mTotalFetchingTime += total_fetching_time;  			sessionp->mTotalGrayTime += total_gray_time;  			sessionp->mTotalStablizingTime += total_stablizing_time; @@ -4302,14 +4139,12 @@ LLMetricPerformanceTesterWithSession::LLTestSession* LLTexturePipelineTester::lo  			sessionp->mTotalTimeLoadingSculpties += total_loading_sculpties_time;  			start_fetching_time = start_time; -			total_fetching_time = 0.0f;  			total_gray_time = 0.f;  			total_stablizing_time = 0.f;  			total_loading_sculpties_time = 0.f;  		}  		else  		{ -			total_fetching_time = cur_time - start_time;  			total_gray_time = (*log)[label]["TotalGrayTime"].asReal();  			total_stablizing_time = (*log)[label]["TotalStablizingTime"].asReal(); @@ -4355,7 +4190,6 @@ LLMetricPerformanceTesterWithSession::LLTestSession* LLTexturePipelineTester::lo  		in_log = (*log).has(currentLabel);  	} -	sessionp->mTotalFetchingTime += total_fetching_time;  	sessionp->mTotalGrayTime += total_gray_time;  	sessionp->mTotalStablizingTime += total_stablizing_time; @@ -4377,8 +4211,6 @@ LLTexturePipelineTester::LLTextureTestSession::~LLTextureTestSession()  }  void LLTexturePipelineTester::LLTextureTestSession::reset()   { -	mTotalFetchingTime = 0.0f; -  	mTotalGrayTime = 0.0f;  	mTotalStablizingTime = 0.0f; diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 53cf911102..5893f549d0 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -134,7 +134,7 @@ public:  	/*virtual*/ bool isActiveFetching();  	/*virtual*/ const LLUUID& getID() const { return mID; } -	void setBoostLevel(S32 level); +	virtual void setBoostLevel(S32 level);  	S32  getBoostLevel() { return mBoostLevel; }  	void setTextureListType(S32 tex_type) { mTextureListType = tex_type; }  	S32 getTextureListType() { return mTextureListType; } @@ -188,19 +188,20 @@ private:  	virtual void switchToCachedImage(); -	static bool isMemoryForTextureLow() ;  	static bool isMemoryForTextureSuficientlyFree();  	static void getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical); +public: +    static bool isMemoryForTextureLow();  protected: +    friend class LLViewerTextureList;  	LLUUID mID;  	S32 mTextureListType; // along with mID identifies where to search for this texture in TextureList  	F32 mSelectedTime;				// time texture was last selected -	mutable F32 mMaxVirtualSize;	// The largest virtual size of the image, in pixels - how much data to we need?	 -	mutable S32  mMaxVirtualSizeResetCounter ; +	mutable F32 mMaxVirtualSize = 0.f;	// The largest virtual size of the image, in pixels - how much data to we need?	 +	mutable S32  mMaxVirtualSizeResetCounter;  	mutable S32  mMaxVirtualSizeResetInterval; -	mutable F32 mAdditionalDecodePriority;  // priority add to mDecodePriority.  	LLFrameTimer mLastReferencedTimer;	  	ll_face_list_t    mFaceList[LLRender::NUM_TEXTURE_CHANNELS]; //reverse pointer pointing to the faces using this image as texture @@ -226,11 +227,6 @@ public:  	static LLFrameTimer sEvaluationTimer;  	static F32 sDesiredDiscardBias;  	static F32 sDesiredDiscardScale; -	static S32Bytes sBoundTextureMemory; -	static S32Bytes sTotalTextureMemory; -	static S32Megabytes sMaxBoundTextureMemory; -	static S32Megabytes sMaxTotalTextureMem; -	static S32Bytes sMaxDesiredTextureMem ;  	static S8  sCameraMovingDiscardBias;  	static F32 sCameraMovingBias;  	static S32 sMaxSculptRez ; @@ -285,7 +281,6 @@ public:  	LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE);  public: -	static F32 maxDecodePriority();  	struct Compare  	{ @@ -294,9 +289,10 @@ public:  		{  			const LLViewerFetchedTexture* lhsp = (const LLViewerFetchedTexture*)lhs;  			const LLViewerFetchedTexture* rhsp = (const LLViewerFetchedTexture*)rhs; +              			// greater priority is "less" -			const F32 lpriority = lhsp->getDecodePriority(); -			const F32 rpriority = rhsp->getDecodePriority(); +			const F32 lpriority = lhsp->mMaxVirtualSize; +			const F32 rpriority = rhsp->mMaxVirtualSize;  			if (lpriority > rpriority) // higher priority  				return true;  			if (lpriority < rpriority) @@ -306,10 +302,10 @@ public:  	};  public: -	/*virtual*/ S8 getType() const ; +	/*virtual*/ S8 getType() const override;  	FTType getFTType() const; -	/*virtual*/ void forceImmediateUpdate() ; -	/*virtual*/ void dump() ; +	/*virtual*/ void forceImmediateUpdate() override; +	/*virtual*/ void dump() override;  	// Set callbacks to get called when the image gets updated with higher   	// resolution versions. @@ -335,7 +331,6 @@ public:  	void destroyTexture() ;  	virtual void processTextureStats() ; -	F32  calcDecodePriority() ;  	BOOL needsAux() const { return mNeedsAux; } @@ -343,20 +338,12 @@ public:  	void setTargetHost(LLHost host)			{ mTargetHost = host; }  	LLHost getTargetHost() const			{ return mTargetHost; } -	// Set the decode priority for this image... -	// DON'T CALL THIS UNLESS YOU KNOW WHAT YOU'RE DOING, it can mess up -	// the priority list, and cause horrible things to happen. -	void setDecodePriority(F32 priority = -1.0f); -	F32 getDecodePriority() const { return mDecodePriority; }; -	F32 getAdditionalDecodePriority() const { return mAdditionalDecodePriority; }; - -	void setAdditionalDecodePriority(F32 priority) ; -	  	void updateVirtualSize() ;  	S32  getDesiredDiscardLevel()			 { return mDesiredDiscardLevel; }  	void setMinDiscardLevel(S32 discard) 	{ mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); } +    void setBoostLevel(S32 level) override;  	bool updateFetch();  	bool setDebugFetching(S32 debug_level);  	bool isInDebug() const { return mInDebug; } @@ -369,10 +356,14 @@ public:  	// Override the computation of discard levels if we know the exact output  	// size of the image.  Used for UI textures to not decode, even if we have  	// more data. -	/*virtual*/ void setKnownDrawSize(S32 width, S32 height); +	/*virtual*/ void setKnownDrawSize(S32 width, S32 height) override; + +    // Set the debug text of all Viewer Objects associated with this texture +    // to the specified text +    void setDebugText(const std::string& text);  	void setIsMissingAsset(BOOL is_missing = true); -	/*virtual*/ BOOL isMissingAsset() const { return mIsMissingAsset; } +	/*virtual*/ BOOL isMissingAsset() const override { return mIsMissingAsset; }  	// returns dimensions of original image for local files (before power of two scaling)  	// and returns 0 for all asset system images @@ -415,7 +406,7 @@ public:  	BOOL        isRawImageValid()const { return mIsRawImageValid ; }	  	void        forceToSaveRawImage(S32 desired_discard = 0, F32 kept_time = 0.f) ;  	void        forceToRefetchTexture(S32 desired_discard = 0, F32 kept_time = 60.f); -	/*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ; +	/*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) override;  	void        destroySavedRawImage() ;  	LLImageRaw* getSavedRawImage() ;  	BOOL        hasSavedRawImage() const ; @@ -431,10 +422,10 @@ public:  	void        setInFastCacheList(bool in_list) { mInFastCacheList = in_list; }  	bool        isInFastCacheList() { return mInFastCacheList; } -	/*virtual*/bool  isActiveFetching(); //is actively in fetching by the fetching pipeline. +	/*virtual*/bool  isActiveFetching() override; //is actively in fetching by the fetching pipeline.  protected: -	/*virtual*/ void switchToCachedImage(); +	/*virtual*/ void switchToCachedImage() override;  	S32 getCurrentDiscardLevelForFetching() ;  private: @@ -472,11 +463,11 @@ protected:  	S32 mRequestedDiscardLevel;  	F32 mRequestedDownloadPriority;  	S32 mFetchState; +    S32 mLastFetchState = -1; // DEBUG  	U32 mFetchPriority;  	F32 mDownloadProgress;  	F32 mFetchDeltaTime;  	F32 mRequestDeltaTime; -	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 @@ -500,7 +491,7 @@ protected:  	F32             mLastCallBackActiveTime;  	LLPointer<LLImageRaw> mRawImage; -	S32 mRawDiscardLevel; +	S32 mRawDiscardLevel = -1;  	// Used ONLY for cloth meshes right now.  Make SURE you know what you're   	// doing if you use it for anything else! - djs @@ -534,6 +525,7 @@ protected:  	BOOL   mIsFetched ; //is loaded from remote or from cache, not generated locally.  public: +    static F32 sMaxVirtualSize; //maximum possible value of mMaxVirtualSize  	static LLPointer<LLViewerFetchedTexture> sMissingAssetImagep;	// Texture to show for an image asset that is not in the database  	static LLPointer<LLViewerFetchedTexture> sWhiteImagep;	// Texture to show NOTHING (whiteness)  	static LLPointer<LLViewerFetchedTexture> sDefaultImagep; // "Default" texture for error cases, the only case of fetched texture which is generated in local. @@ -774,7 +766,6 @@ private:  		void reset() ; -		F32 mTotalFetchingTime ;  		F32 mTotalGrayTime ;  		F32 mTotalStablizingTime ;  		F32 mStartTimeLoadingSculpties ;  diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index bbbf9ea7a3..1a766dd404 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -89,8 +89,6 @@ LLTextureKey::LLTextureKey(LLUUID id, ETexListType tex_type)  LLViewerTextureList::LLViewerTextureList()   	: mForceResetTextureStats(FALSE), -	mMaxResidentTexMemInMegaBytes(0), -	mMaxTotalTextureMemInMegaBytes(0),  	mInitialized(FALSE)  {  } @@ -99,12 +97,6 @@ void LLViewerTextureList::init()  {			  	mInitialized = TRUE ;  	sNumImages = 0; -	mMaxResidentTexMemInMegaBytes = (U32Bytes)0; -	mMaxTotalTextureMemInMegaBytes = (U32Bytes)0; -	 -	// Update how much texture RAM we're allowed to use. -	updateMaxResidentTexMem(S32Megabytes(0)); // 0 = use current -	  	doPreloadImages();  } @@ -204,10 +196,8 @@ static std::string get_texture_list_name()  void LLViewerTextureList::doPrefetchImages()  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; -	gTextureTimer.start(); -	gTextureTimer.pause(); -	if (LLAppViewer::instance()->getPurgeCache()) +    if (LLAppViewer::instance()->getPurgeCache())  	{  		// cache was purged, no point  		return; @@ -342,7 +332,7 @@ void LLViewerTextureList::dump()  	{  		LLViewerFetchedTexture* image = *it; -		LL_INFOS() << "priority " << image->getDecodePriority() +		LL_INFOS() << "priority " << image->getMaxVirtualSize()  		<< " boost " << image->getBoostLevel()  		<< " size " << image->getWidth() << "x" << image->getHeight()  		<< " discard " << image->getDiscardLevel() @@ -667,13 +657,14 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)  	assert_main_thread();  	llassert_always(mInitialized) ;  	llassert(image); +    image->validateRefCount();  	S32 count = 0;  	if (image->isInImageList())  	{  		count = mImageList.erase(image) ;  		if(count != 1)  -	{ +	    {  			LL_INFOS() << "Image  " << image->getID()   				<< " had mInImageList set but mImageList.erase() returned " << count  				<< LL_ENDL; @@ -699,6 +690,7 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)  			LL_INFOS() << "Image  " << image->getID() << " was in mUUIDMap with same pointer" << LL_ENDL ;  		}  		count = mImageList.erase(image) ; +        llassert(count != 0);  		if(count != 0)   		{	// it was in the list already?  			LL_WARNS() << "Image  " << image->getID()  @@ -784,17 +776,12 @@ void LLViewerTextureList::updateImages(F32 max_time)  		using namespace LLStatViewer;  		sample(NUM_IMAGES, sNumImages);  		sample(NUM_RAW_IMAGES, LLImageRaw::sRawImageCount); -		sample(GL_TEX_MEM, LLImageGL::sGlobalTextureMemory); -		sample(GL_BOUND_MEM, LLImageGL::sBoundTextureMemory); -		sample(RAW_MEM, F64Bytes(LLImageRaw::sGlobalRawMemory));  		sample(FORMATTED_MEM, F64Bytes(LLImageFormatted::sGlobalFormattedMemory));  	}  	//loading from fast cache   	max_time -= updateImagesLoadingFastCache(max_time); -	updateImagesDecodePriorities(); -	      F32 total_max_time = max_time;  	max_time -= updateImagesFetchTextures(max_time); @@ -825,7 +812,6 @@ void LLViewerTextureList::updateImages(F32 max_time)  			didone = image->doLoadedCallbacks();  		}  	} -	  	updateImagesUpdateStats();  } @@ -848,120 +834,78 @@ void LLViewerTextureList::clearFetchingRequests()  	}  } -void LLViewerTextureList::updateImagesDecodePriorities() +void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imagep)  { -    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; -	// Update the decode priority for N images each frame -	{ -		F32 lazy_flush_timeout = 30.f; // stop decoding -		F32 max_inactive_time  = 20.f; // actually delete -		S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference - -		//reset imagep->getLastReferencedTimer() when screen is showing the progress view to avoid removing pre-fetched textures too soon. -		bool reset_timer = gViewerWindow->getProgressView()->getVisible(); -         -        static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities");         // default: 32 -		const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds.value()) + 1, MAX_PRIO_UPDATES); -		S32 update_counter = llmin(max_update_count, mUUIDMap.size()); -		uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateKey); -		while ((update_counter-- > 0) && !mUUIDMap.empty()) -		{ -			if (iter == mUUIDMap.end()) -			{ -				iter = mUUIDMap.begin(); +    if (imagep->isInDebug() || imagep->isUnremovable()) +    { +        //update_counter--; +        return; //is in debug, ignore. +    } + +    F32 lazy_flush_timeout = 30.f; // stop decoding +    F32 max_inactive_time = 20.f; // actually delete +    S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference + +    // +    // Flush formatted images using a lazy flush +    // +    S32 num_refs = imagep->getNumRefs(); +    if (num_refs == min_refs) +    { +        if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > lazy_flush_timeout) +        { +            // Remove the unused image from the image list +            deleteImage(imagep); +            imagep = NULL; // should destroy the image								 +        } +        return; +    } +    else +    { +        if (imagep->hasSavedRawImage()) +        { +            if (imagep->getElapsedLastReferencedSavedRawImageTime() > max_inactive_time) +            { +                imagep->destroySavedRawImage();              } -            mLastUpdateKey = iter->first; -			LLPointer<LLViewerFetchedTexture> imagep = iter->second; -			++iter; // safe to increment now +        } -			if(imagep->isInDebug() || imagep->isUnremovable()) -			{ -				update_counter--; -				continue; //is in debug, ignore. -			} +        if (imagep->isDeleted()) +        { +            return; +        } +        else if (imagep->isDeletionCandidate()) +        { +            imagep->destroyTexture(); +            return; +        } +        else if (imagep->isInactive()) +        { +            if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > max_inactive_time) +            { +                imagep->setDeletionCandidate(); +            } +            return; +        } +        else +        { +            imagep->getLastReferencedTimer()->reset(); -			// -			// Flush formatted images using a lazy flush -			// -			S32 num_refs = imagep->getNumRefs(); -			if (num_refs == min_refs) -			{ -				if(reset_timer) -				{ -					imagep->getLastReferencedTimer()->reset(); -				} -				else if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > lazy_flush_timeout) -				{ -					// Remove the unused image from the image list -					deleteImage(imagep); -					imagep = NULL; // should destroy the image								 -				} -				continue; -			} -			else -			{ -				if(imagep->hasSavedRawImage()) -				{ -					if(imagep->getElapsedLastReferencedSavedRawImageTime() > max_inactive_time) -					{ -						imagep->destroySavedRawImage() ; -					} -				} - -				if(imagep->isDeleted()) -				{ -					continue ; -				} -				else if(imagep->isDeletionCandidate()) -				{ -					imagep->destroyTexture() ;																 -					continue ; -				} -				else if(imagep->isInactive()) -				{ -					if(reset_timer) -					{ -						imagep->getLastReferencedTimer()->reset(); -					} -					else if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > max_inactive_time) -					{ -						imagep->setDeletionCandidate() ; -					} -					continue ; -				} -				else -				{ -					imagep->getLastReferencedTimer()->reset(); - -					//reset texture state. -					imagep->setInactive() ;										 -				} -			} +            //reset texture state. +            imagep->setInactive(); +        } +    } -			if (!imagep->isInImageList()) -			{ -				continue; -			} -			if(imagep->isInFastCacheList()) -			{ -				continue; //wait for loading from the fast cache. -			} +    if (!imagep->isInImageList()) +    { +        return; +    } +    if (imagep->isInFastCacheList()) +    { +        return; //wait for loading from the fast cache. +    } -			imagep->processTextureStats(); -			F32 old_priority = imagep->getDecodePriority(); -			F32 old_priority_test = llmax(old_priority, 0.0f); -			F32 decode_priority = imagep->calcDecodePriority(); -			F32 decode_priority_test = llmax(decode_priority, 0.0f); -			// Ignore < 20% difference -			if ((decode_priority_test < old_priority_test * .8f) || -				(decode_priority_test > old_priority_test * 1.25f)) -			{ -				mImageList.erase(imagep) ; -				imagep->setDecodePriority(decode_priority); -				mImageList.insert(imagep); -			} -		} -	} +    imagep->processTextureStats();  }  void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level) @@ -973,17 +917,9 @@ void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debu  	}  	const F32 DEBUG_PRIORITY = 100000.f; -	F32 old_priority_test = llmax(tex->getDecodePriority(), 0.0f); -	F32 decode_priority_test = DEBUG_PRIORITY; -	 -	// Ignore < 20% difference -	if ((decode_priority_test < old_priority_test * .8f) || -		(decode_priority_test > old_priority_test * 1.25f)) -	{ -		removeImageFromList(tex); -		tex->setDecodePriority(decode_priority_test); -		addImageToList(tex); -	} +	removeImageFromList(tex); +    tex->mMaxVirtualSize = DEBUG_PRIORITY; +	addImageToList(tex);  }  /* @@ -1033,10 +969,6 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)  		LLViewerFetchedTexture *imagep = *curiter;  		imagep->createTexture();          imagep->postCreateTexture(); -		if (create_timer.getElapsedTimeF32() > max_time) -		{ -			break; -		}  	}  	mCreateTextureList.erase(mCreateTextureList.begin(), enditer);  	return create_timer.getElapsedTimeF32(); @@ -1064,10 +996,6 @@ F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time)  		enditer = iter;  		LLViewerFetchedTexture *imagep = *curiter;  		imagep->loadFromFastCache(); -		if (timer.getElapsedTimeF32() > max_time) -		{ -			break; -		}  	}  	mFastCacheList.erase(mFastCacheList.begin(), enditer);  	return timer.getElapsedTimeF32(); @@ -1086,8 +1014,7 @@ void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep)  	}  	imagep->processTextureStats(); -	F32 decode_priority = LLViewerFetchedTexture::maxDecodePriority() ; -	imagep->setDecodePriority(decode_priority); +    imagep->sMaxVirtualSize = LLViewerFetchedTexture::sMaxVirtualSize;  	addImageToList(imagep);  	return ; @@ -1096,76 +1023,55 @@ void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep)  F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; -	LLTimer image_op_timer; -	 -	// Update fetch for N images each frame -	static const S32 MAX_HIGH_PRIO_COUNT = gSavedSettings.getS32("TextureFetchUpdateHighPriority");         // default: 32 -	static const S32 MAX_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMaxMediumPriority");       // default: 256 -	static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinMediumPriority");       // default: 32 -	static const F32 MIN_PRIORITY_THRESHOLD = gSavedSettings.getF32("TextureFetchUpdatePriorityThreshold"); // default: 0.0 -	static const bool SKIP_LOW_PRIO = gSavedSettings.getBOOL("TextureFetchUpdateSkipLowPriority");          // default: false - -	size_t max_priority_count = llmin((S32) (MAX_HIGH_PRIO_COUNT*MAX_HIGH_PRIO_COUNT*gFrameIntervalSeconds.value())+1, MAX_HIGH_PRIO_COUNT); -	max_priority_count = llmin(max_priority_count, mImageList.size()); -	 -	size_t total_update_count = mUUIDMap.size(); -	size_t max_update_count = llmin((S32) (MAX_UPDATE_COUNT*MAX_UPDATE_COUNT*gFrameIntervalSeconds.value())+1, MAX_UPDATE_COUNT); -	max_update_count = llmin(max_update_count, total_update_count);	 -	 -	// MAX_HIGH_PRIO_COUNT high priority entries -	typedef std::vector<LLViewerFetchedTexture*> entries_list_t; -	entries_list_t entries; -	size_t update_counter = max_priority_count; -	image_priority_list_t::iterator iter1 = mImageList.begin(); -	while(update_counter > 0) -	{ -		entries.push_back(*iter1); -		 -		++iter1; -		update_counter--; -	} -	 -	// MAX_UPDATE_COUNT cycled entries -	update_counter = max_update_count;	 -	if(update_counter > 0) -	{ -		uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchKey); -		while ((update_counter > 0) && (total_update_count > 0)) -		{ -			if (iter2 == mUUIDMap.end()) -			{ -				iter2 = mUUIDMap.begin(); -			} -			LLViewerFetchedTexture* imagep = iter2->second; -            // Skip the textures where there's really nothing to do so to give some times to others. Also skip the texture if it's already in the high prio set. -            if (!SKIP_LOW_PRIO || (SKIP_LOW_PRIO && ((imagep->getDecodePriority() > MIN_PRIORITY_THRESHOLD) || imagep->hasFetcher()))) +    LLTimer image_op_timer; + +    typedef std::vector<LLPointer<LLViewerFetchedTexture> > entries_list_t; +    entries_list_t entries; + +    // update N textures at beginning of mImageList +    U32 update_count = 0; +    static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinCount");       // default: 32 +    // WIP -- dumb code here +    //update MIN_UPDATE_COUNT or 10% of other textures, whichever is greater +    update_count = llmax((U32) MIN_UPDATE_COUNT, (U32) mUUIDMap.size()/10); +    update_count = llmin(update_count, (U32) mUUIDMap.size()); +     +    { +        LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vtluift - copy"); + +        // copy entries out of UUID map for updating +        entries.reserve(update_count); +        uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateKey); +        while (update_count-- > 0) +        { +            if (iter == mUUIDMap.end())              { -                entries.push_back(imagep); -                update_counter--; +                iter = mUUIDMap.begin();              } +             +            if (iter->second->getGLTexture()) +            { +                entries.push_back(iter->second); +            } +            ++iter; +        } +    } + +    for (auto& imagep : entries) +    { +        if (imagep->getNumRefs() > 1) // make sure this image hasn't been deleted before attempting to update (may happen as a side effect of some other image updating) +        { +            updateImageDecodePriority(imagep); +            imagep->updateFetch(); +        } +    } + +    if (entries.size() > 0) +    { +        LLViewerFetchedTexture* imagep = *entries.rbegin(); +        mLastUpdateKey = LLTextureKey(imagep->getID(), (ETexListType)imagep->getTextureListType()); +    } -			iter2++; -			total_update_count--; -		} -	} -	 -	S32 fetch_count = 0; -	size_t min_update_count = llmin(MIN_UPDATE_COUNT,(S32)(entries.size()-max_priority_count)); -	S32 min_count = max_priority_count + min_update_count; -	for (entries_list_t::iterator iter3 = entries.begin(); -		 iter3 != entries.end(); ) -	{ -		LLViewerFetchedTexture* imagep = *iter3++; -		fetch_count += (imagep->updateFetch() ? 1 : 0); -		if (min_count <= min_update_count) -		{ -			mLastFetchKey = LLTextureKey(imagep->getID(), (ETexListType)imagep->getTextureListType()); -		} -		if ((min_count-- <= 0) && (image_op_timer.getElapsedTimeF32() > max_time)) -		{ -			break; -		} -	}  	return image_op_timer.getElapsedTimeF32();  } @@ -1209,8 +1115,6 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)  	{  		LLViewerFetchedTexture* imagep = *iter;  		imagep->processTextureStats(); -		F32 decode_priority = imagep->calcDecodePriority(); -		imagep->setDecodePriority(decode_priority);  		addImageToList(imagep);  	}  	image_list.clear(); @@ -1349,156 +1253,6 @@ LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImage  	return compressedImage;  } -// Returns min setting for TextureMemory (in MB) -S32Megabytes LLViewerTextureList::getMinVideoRamSetting() -{ -    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; -	U32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB(); -	//min texture mem sets to 64M if total physical mem is more than 1.5GB -	return (system_ram > U32Megabytes(1500)) ? S32Megabytes(64) : gMinVideoRam ; -} - -//static -// Returns max setting for TextureMemory (in MB) -S32Megabytes LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended, float mem_multiplier) -{ -    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; -	S32Megabytes max_texmem; -	if (gGLManager.mVRAM != 0) -	{ -		// Treat any card with < 32 MB (shudder) as having 32 MB -		//  - it's going to be swapping constantly regardless -		S32Megabytes max_vram(gGLManager.mVRAM); - -		if(gGLManager.mIsAMD) -		{ -			//shrink the availabe vram for ATI cards because some of them do not handel texture swapping well. -			max_vram = max_vram * 0.75f;  -		} - -		max_vram = llmax(max_vram, getMinVideoRamSetting()); -		max_texmem = max_vram; -		if (!get_recommended) -			max_texmem *= 2; -	} -	else -	{ -		if (!get_recommended) -		{ -			max_texmem = (S32Megabytes)512; -		} -		else if (gSavedSettings.getBOOL("NoHardwareProbe")) //did not do hardware detection at startup -		{ -			max_texmem = (S32Megabytes)512; -		} -		else -		{ -			max_texmem = (S32Megabytes)128; -		} -	} - -	S32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB(); // In MB -	//LL_INFOS() << "*** DETECTED " << system_ram << " MB of system memory." << LL_ENDL; -	if (get_recommended) -		max_texmem = llmin(max_texmem, system_ram/2); -	else -		max_texmem = llmin(max_texmem, system_ram); -		 -    // limit the texture memory to a multiple of the default if we've found some cards to behave poorly otherwise -	max_texmem = llmin(max_texmem, (S32Megabytes) (mem_multiplier * max_texmem)); - -	max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), gMaxVideoRam);  -	 -	return max_texmem; -} - -bool LLViewerTextureList::isPrioRequestsFetched() -{ -	static LLCachedControl<F32> prio_threshold(gSavedSettings, "TextureFetchUpdatePriorityThreshold", 0.0f); -	static LLCachedControl<F32> fetching_textures_threshold(gSavedSettings, "TextureListFetchingThreshold", 0.97f); -	S32 fetching_tex_count = 0; -	S32 tex_count_threshold = gTextureList.mImageList.size() * (1 - fetching_textures_threshold); - -	for (LLViewerTextureList::image_priority_list_t::iterator iter = gTextureList.mImageList.begin(); -		iter != gTextureList.mImageList.end(); ) -	{ -		LLPointer<LLViewerFetchedTexture> imagep = *iter++; -		if (imagep->getDecodePriority() > prio_threshold) -		{ -			if (imagep->hasFetcher() || imagep->isFetching()) -			{ -				fetching_tex_count++; -				if (fetching_tex_count >= tex_count_threshold) -				{ -					return false; -				} -			} -		} -	} - -	return true; -} - -const S32Megabytes VIDEO_CARD_FRAMEBUFFER_MEM(12); -const S32Megabytes MIN_MEM_FOR_NON_TEXTURE(512); -void LLViewerTextureList::updateMaxResidentTexMem(S32Megabytes mem) -{ -    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; -	// Initialize the image pipeline VRAM settings -	S32Megabytes cur_mem(gSavedSettings.getS32("TextureMemory")); -	F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple"); -	S32Megabytes default_mem = getMaxVideoRamSetting(true, mem_multiplier); // recommended default -	if (mem == (S32Bytes)0) -	{ -		mem = cur_mem > (S32Bytes)0 ? cur_mem : default_mem; -	} -	else if (mem < (S32Bytes)0) -	{ -		mem = default_mem; -	} - -	mem = llclamp(mem, getMinVideoRamSetting(), getMaxVideoRamSetting(false, mem_multiplier)); -	if (mem != cur_mem) -	{ -		gSavedSettings.setS32("TextureMemory", mem.value()); -		return; //listener will re-enter this function -	} - -	if (gGLManager.mVRAM == 0) -	{ -		LL_WARNS() << "VRAM amount not detected, defaulting to " << mem << " MB" << LL_ENDL; -	} - -	// TODO: set available resident texture mem based on use by other subsystems -	// currently max(12MB, VRAM/4) assumed... -	 -	S32Megabytes vb_mem = mem; -	S32Megabytes fb_mem = llmax(VIDEO_CARD_FRAMEBUFFER_MEM, vb_mem/4); -	mMaxResidentTexMemInMegaBytes = (vb_mem - fb_mem) ; //in MB -	 -	mMaxTotalTextureMemInMegaBytes = mMaxResidentTexMemInMegaBytes * 2; -	if (mMaxResidentTexMemInMegaBytes > (S32Megabytes)640) -	{ -		mMaxTotalTextureMemInMegaBytes -= (mMaxResidentTexMemInMegaBytes / 4); -	} - -	//system mem -	S32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB(); - -	//minimum memory reserved for non-texture use. -	//if system_raw >= 1GB, reserve at least 512MB for non-texture use; -	//otherwise reserve half of the system_ram for non-texture use. -	S32Megabytes min_non_texture_mem = llmin(system_ram / 2, MIN_MEM_FOR_NON_TEXTURE) ;  - -	if (mMaxTotalTextureMemInMegaBytes > system_ram - min_non_texture_mem) -	{ -		mMaxTotalTextureMemInMegaBytes = system_ram - min_non_texture_mem ; -	} -	 -	LL_INFOS() << "Total Video Memory set to: " << vb_mem << " MB" << LL_ENDL; -	LL_INFOS() << "Available Texture Memory set to: " << (vb_mem - fb_mem) << " MB" << LL_ENDL; -} -  ///////////////////////////////////////////////////////////////////////////////  // static diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index 99394e550c..cc6523c23e 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -124,25 +124,20 @@ public:  	void handleIRCallback(void **data, const S32 number); -	S32Megabytes	getMaxResidentTexMem() const	{ return mMaxResidentTexMemInMegaBytes; } -	S32Megabytes getMaxTotalTextureMem() const   { return mMaxTotalTextureMemInMegaBytes;}  	S32 getNumImages()					{ return mImageList.size(); } -	void updateMaxResidentTexMem(S32Megabytes mem); -	  	void doPreloadImages();  	void doPrefetchImages();  	void clearFetchingRequests();  	void setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level); -	static S32Megabytes getMinVideoRamSetting(); -	static S32Megabytes getMaxVideoRamSetting(bool get_recommended, float mem_multiplier); - -	static bool isPrioRequestsFetched(); -	  private: -	void updateImagesDecodePriorities(); +    // do some book keeping on the specified texture +    // - updates decode priority +    // - updates desired discard level +    // - cleans up textures that haven't been referenced in awhile +    void updateImageDecodePriority(LLViewerFetchedTexture* imagep);  	F32  updateImagesCreateTextures(F32 max_time);  	F32  updateImagesFetchTextures(F32 max_time);  	void updateImagesUpdateStats(); @@ -215,17 +210,14 @@ private:      typedef std::map< LLTextureKey, LLPointer<LLViewerFetchedTexture> > uuid_map_t;      uuid_map_t mUUIDMap;      LLTextureKey mLastUpdateKey; -    LLTextureKey mLastFetchKey; -	typedef std::set<LLPointer<LLViewerFetchedTexture>, LLViewerFetchedTexture::Compare> image_priority_list_t;	 +    typedef std::set < LLPointer<LLViewerFetchedTexture> > image_priority_list_t;  	image_priority_list_t mImageList;  	// simply holds on to LLViewerFetchedTexture references to stop them from being purged too soon  	std::set<LLPointer<LLViewerFetchedTexture> > mImagePreloads;  	BOOL mInitialized ; -	S32Megabytes	mMaxResidentTexMemInMegaBytes; -	S32Megabytes mMaxTotalTextureMemInMegaBytes;  	LLFrameTimer mForceDecodeTimer;  private: diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index aa8d58cc8a..e9815a7872 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -493,24 +493,12 @@ public:  		if (gSavedSettings.getBOOL("DebugShowTime"))  		{ -			{ -			const U32 y_inc2 = 15; -				LLFrameTimer& timer = gTextureTimer; -				F32 time = timer.getElapsedTimeF32(); -				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("Texture: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc2; -			} -			 -			{  			F32 time = gFrameTimeSeconds;  			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("Time: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc;  		} -		}  		if (gSavedSettings.getBOOL("DebugShowMemory"))  		{ @@ -5640,7 +5628,6 @@ void LLViewerWindow::stopGL(BOOL save_state)  		// Pause texture decode threads (will get unpaused during main loop)  		LLAppViewer::getTextureCache()->pause(); -		LLAppViewer::getImageDecodeThread()->pause();  		LLAppViewer::getTextureFetch()->pause();  		gSky.destroyGL(); @@ -5687,8 +5674,6 @@ void LLViewerWindow::stopGL(BOOL save_state)  			LLGLSLShader* shader = *(LLGLSLShader::sInstances.begin());  			shader->unload();  		} -		 -		LL_INFOS() << "Remaining allocated texture memory: " << LLImageGL::sGlobalTextureMemory.value() << " bytes" << LL_ENDL;  	}  } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index e55ee21414..30e3d77d29 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -5707,7 +5707,6 @@ void LLVOAvatar::checkTextureLoading()  }  const F32  SELF_ADDITIONAL_PRI = 0.75f ; -const F32  ADDITIONAL_PRI = 0.5f;  void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level)  {  	//Note: @@ -5722,15 +5721,6 @@ void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel  	mMinPixelArea = llmin(pixel_area, mMinPixelArea);	  	imagep->addTextureStats(pixel_area / texel_area_ratio);  	imagep->setBoostLevel(boost_level); -	 -	if(boost_level != LLGLTexture::BOOST_AVATAR_BAKED_SELF) -	{ -		imagep->setAdditionalDecodePriority(ADDITIONAL_PRI) ; -	} -	else -	{ -		imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ; -	}  }  //virtual	 diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 60a69a4ac4..4080a61fb0 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -1825,7 +1825,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const  			}  			else  			{ -				const LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() ); +				LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );  				LL_INFOS() << "LocTex " << name << ": "  						<< "Discard " << image->getDiscardLevel() << ", " @@ -1835,7 +1835,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const  					// makes textures easier to steal  						<< image->getID() << " "  #endif -						<< "Priority: " << image->getDecodePriority() +						<< "Priority: " << image->getMaxVirtualSize()  						<< LL_ENDL;  			}  		} @@ -2074,8 +2074,7 @@ const std::string LLVOAvatarSelf::verboseDebugDumpLocalTextureDataInfo(const LLV  									   << " glocdisc: " << getLocalDiscardLevel(tex_index, wearable_index)  									   << " discard: " << image->getDiscardLevel()  									   << " desired: " << image->getDesiredDiscardLevel() -									   << " decode: " << image->getDecodePriority() -									   << " addl: " << image->getAdditionalDecodePriority() +									   << " vsize: " << image->getMaxVirtualSize()  									   << " ts: " << image->getTextureState()  									   << " bl: " << image->getBoostLevel()  									   << " fl: " << image->isFullyLoaded() // this is not an accessor for mFullyLoaded - see comment there. @@ -2453,7 +2452,6 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe  				desired_pixels = llmin(mPixelArea, (F32)getTexImageArea());  				imagep->setBoostLevel(getAvatarBoostLevel()); -				imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;  				imagep->resetTextureStats();  				imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL);  				imagep->addTextureStats( desired_pixels / texel_area_ratio ); @@ -2823,7 +2821,6 @@ void LLVOAvatarSelf::deleteScratchTextures()  		LL_DEBUGS() << "Clearing Scratch Textures " << (S32Kilobytes)sScratchTexBytes << LL_ENDL;  		delete_and_clear(sScratchTexNames); -		LLImageGL::sGlobalTextureMemory -= sScratchTexBytes;  		sScratchTexBytes = S32Bytes(0);  	}  } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index d654c470e2..ad11fb3908 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -696,12 +696,13 @@ void LLVOVolume::animateTextures()  void LLVOVolume::updateTextures()  { -	const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds -	if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME) +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; +	//const F32 TEXTURE_AREA_REFRESH_TIME = 1.f; // seconds +	//if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME)  	{  		updateTextureVirtualSize(); -		if (mDrawable.notNull() && !isVisible() && !mDrawable->isActive()) +		/*if (mDrawable.notNull() && !isVisible() && !mDrawable->isActive())  		{ //delete vertex buffer to free up some VRAM  			LLSpatialGroup* group  = mDrawable->getSpatialGroup();  			if (group && (group->mVertexBuffer.notNull() || !group->mBufferMap.empty() || !group->mDrawMap.empty())) @@ -712,9 +713,7 @@ void LLVOVolume::updateTextures()  				//it becomes visible  				group->setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);  			} -		} - - +		}*/      }  } @@ -788,6 +787,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)  	const S32 num_faces = mDrawable->getNumFaces();  	F32 min_vsize=999999999.f, max_vsize=0.f;  	LLViewerCamera* camera = LLViewerCamera::getInstance(); +    std::stringstream debug_text;  	for (S32 i = 0; i < num_faces; i++)  	{  		LLFace* face = mDrawable->getFace(i); @@ -814,10 +814,14 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)  		else  		{  			vsize = face->getTextureVirtualSize(); +            imagep->addTextureStats(vsize);  		} -		mPixelArea = llmax(mPixelArea, face->getPixelArea());		 +		mPixelArea = llmax(mPixelArea, face->getPixelArea()); +        // if the face has gotten small enough to turn off texture animation and texture +        // animation is running, rebuild the render batch for this face to turn off +        // texture animation  		if (face->mTextureMatrix != NULL)  		{  			if ((vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE) || @@ -837,10 +841,11 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)  			LLViewerFetchedTexture* img = LLViewerTextureManager::staticCastToFetchedTexture(imagep) ;  			if(img)  			{ -				F32 pri = img->getDecodePriority(); +                debug_text << img->getDiscardLevel() << ":" << img->getDesiredDiscardLevel() << ":" << img->getWidth() << ":" << (S32) sqrtf(vsize) << ":" << (S32) sqrtf(img->getMaxVirtualSize()) << "\n"; +				/*F32 pri = img->getDecodePriority();  				pri = llmax(pri, 0.0f);  				if (pri < min_vsize) min_vsize = pri; -				if (pri > max_vsize) max_vsize = pri; +				if (pri > max_vsize) max_vsize = pri;*/  			}  		}  		else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA)) @@ -872,14 +877,6 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)  				F32 lodf = ((F32)(lod + 1.0f)/4.f);  				F32 tex_size = lodf * LLViewerTexture::sMaxSculptRez ;  				mSculptTexture->addTextureStats(2.f * tex_size * tex_size, FALSE); -			 -				//if the sculpty very close to the view point, load first -				{				 -					LLVector3 lookAt = getPositionAgent() - camera->getOrigin(); -					F32 dist = lookAt.normVec() ; -					F32 cos_angle_to_view_dir = lookAt * camera->getXAxis() ;				 -					mSculptTexture->setAdditionalDecodePriority(0.8f * LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist)) ; -				}  			}  			S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture @@ -923,7 +920,8 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)  	}   	else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))   	{ - 		setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize))); + 		//setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize))); +        setDebugText(debug_text.str());   	}  	else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA))  	{ diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index 32c8ce66a0..2b400c5586 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -395,7 +395,7 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip, const  	mHandler = LLXMLRPCTransaction::Handler::ptr_t(new Handler( mHttpRequest, this )); -	mPostH = mHttpRequest->requestPost(LLCore::HttpRequest::DEFAULT_POLICY_ID, 0,  +	mPostH = mHttpRequest->requestPost(LLCore::HttpRequest::DEFAULT_POLICY_ID,  		mURI, body.get(), httpOpts, httpHeaders, mHandler);  } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 9161b43159..91d276c8df 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -442,6 +442,7 @@ void LLPipeline::connectRefreshCachedSettingsSafe(const std::string name)  void LLPipeline::init()  { +    LL_WARNS() << "Begin pipeline initialization" << LL_ENDL; // TODO: Remove after testing  	refreshCachedSettings();      mRT = &mMainRT; @@ -460,6 +461,7 @@ void LLPipeline::init()  	mInitialized = true;  	stop_glerror(); +    LL_WARNS() << "No GL errors yet. Pipeline initialization will continue." << LL_ENDL; // TODO: Remove after testing  	//create render pass pools  	getPool(LLDrawPool::POOL_ALPHA); @@ -521,7 +523,9 @@ void LLPipeline::init()  	// Enable features +    LL_WARNS() << "Shader initialization start" << LL_ENDL; // TODO: Remove after testing  	LLViewerShaderMgr::instance()->setShaders(); +    LL_WARNS() << "Shader initialization end" << LL_ENDL; // TODO: Remove after testing  	stop_glerror(); @@ -3745,7 +3749,7 @@ void LLPipeline::touchTexture(LLViewerTexture* tex, F32 vsize)      if (tex)      {          LLImageGL* gl_tex = tex->getGLTexture(); -        if (gl_tex && gl_tex->updateBindStats(gl_tex->mTextureMemory)) +        if (gl_tex && gl_tex->updateBindStats())          {              tex->setActive();              tex->addTextureStats(vsize); @@ -3815,25 +3819,47 @@ void LLPipeline::postSort(LLCamera& camera)  			group->rebuildGeom();  		} -		for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j) -		{ -			LLSpatialGroup::drawmap_elem_t& src_vec = j->second;	 -			if (!hasRenderType(j->first)) -			{ -				continue; -			} -			 -			for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k) -			{ +        for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j) +        { +            LLSpatialGroup::drawmap_elem_t& src_vec = j->second; +            if (!hasRenderType(j->first)) +            { +                continue; +            } + +            // DEBUG -- force a texture virtual size update every frame +            /*if (group->getSpatialPartition()->mDrawableType == LLPipeline::RENDER_TYPE_VOLUME) +            { +                LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("plps - update vsize"); +                auto& entries = group->getData(); +                for (auto& entry : entries) +                { +                    if (entry) +                    { +                        auto* data = entry->getDrawable(); +                        if (data) +                        { +                            LLVOVolume* volume = ((LLDrawable*)data)->getVOVolume(); +                            if (volume) +                            { +                                volume->updateTextureVirtualSize(true); +                            } +                        } +                    } +                } +            }*/ + +            for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k) +            {                  LLDrawInfo* info = *k; -				 -				sCull->pushDrawInfo(j->first, info); + +                sCull->pushDrawInfo(j->first, info);                  if (!sShadowRender && !sReflectionRender && !gCubeSnapshot)                  {                      touchTextures(info);                      addTrianglesDrawn(info->mCount, info->mDrawMode);                  } -			} +            }  		}  		if (hasRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA)) diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml index b7708b057d..97a87d56f4 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml @@ -272,22 +272,6 @@       Hardware    </text> -  <slider -    control_name="TextureMemory" -    decimal_digits="0" -    follows="left|top" -    height="16" -    increment="16" -    initial_value="32" -    label="Texture Memory (MB):" -    label_width="185" -    layout="topleft" -    left="30" -    max_val="4096" -    name="GraphicsCardTextureMemory" -    tool_tip="Amount of memory to allocate for textures. Defaults to video card memory. Reducing this may improve performance but may also make textures blurry." -    top_delta="16" -    width="335" />    <check_box      control_name="RenderAnisotropic" diff --git a/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml deleted file mode 100644 index 9278a1a598..0000000000 --- a/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml +++ /dev/null @@ -1,440 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - legacy_header_height="18" - can_minimize="false" - height="600" - layout="topleft" - name="TexFetchDebugger" - help_topic="texfetchdebugger" - title="Texture Fetching Debugger" - width="540"> -  <text -   type="string" -   length="1" -   follows="left|top" -   height="25" -   layout="topleft" -   left="10" -   name="total_num_fetched_label" -   top="30" -   width="400"> -    1, Total number of fetched textures: [NUM] -  </text> -  <text -   type="string" -   length="1" -   follows="left|top" -   height="25" -   layout="topleft" -   left_delta="0" -   name="total_num_fetching_requests_label" -   top_delta="25" -   width="400"> -    2, Total number of fetching requests: [NUM] -  </text> -  <text -   type="string" -   length="1" -   follows="left|top" -   height="25" -   layout="topleft" -   left_delta="0" -   name="total_num_cache_hits_label" -   top_delta="25" -   width="400"> -    3, Total number of cache hits: [NUM] -  </text> -  <text -   type="string" -   length="1" -   follows="left|top" -   height="25" -   layout="topleft" -   left_delta="0" -   name="total_num_visible_tex_label" -   top_delta="25" -   width="400"> -    4, Total number of visible textures: [NUM] -  </text> -  <text -   type="string" -   length="1" -   follows="left|top" -   height="25" -   layout="topleft" -   left_delta="0" -   name="total_num_visible_tex_fetch_req_label" -   top_delta="25" -   width="450"> -    5, Total number of visible texture fetching requests: [NUM] -  </text> -  <text -   type="string" -   length="1" -   follows="left|top" -   height="25" -   layout="topleft" -   left_delta="0" -   name="total_fetched_data_label" -   top_delta="25" -   width="530"> -    6, Total number of fetched data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels -  </text> -  <text -   type="string" -   length="1" -   follows="left|top" -   height="25" -   layout="topleft" -   left_delta="0" -   name="total_fetched_vis_data_label" -   top_delta="25" -   width="480"> -    7, Total number of visible data: [SIZE1]KB, Decoded Data: [SIZE2]KB -  </text> -  <text -   type="string" -   length="1" -   follows="left|top" -   height="25" -   layout="topleft" -   left_delta="0" -   name="total_fetched_rendered_data_label" -   top_delta="25" -   width="530"> -    8, Total number of rendered data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels -  </text> -  <text -   type="string" -   length="1" -   follows="left|top" -   height="25" -   layout="topleft" -   left_delta="0" -   name="total_time_cache_read_label" -   top_delta="25" -   width="400"> -    9, Total time on cache readings: [TIME] seconds -  </text> -  <text -   type="string" -   length="1" -   follows="left|top" -   height="25" -   layout="topleft" -   left_delta="0" -   name="total_time_cache_write_label" -   top_delta="25" -   width="400"> -    10, Total time on cache writings: [TIME] seconds -  </text> -  <text -   type="string" -   length="1" -   follows="left|top" -   height="25" -   layout="topleft" -   left_delta="0" -   name="total_time_decode_label" -   top_delta="25" -   width="400"> -    11, Total time on decodings: [TIME] seconds -  </text> -  <text -   type="string" -   length="1" -   follows="left|top" -   height="25" -   layout="topleft" -   left_delta="0" -   name="total_time_gl_label" -   top_delta="25" -   width="400"> -    12, Total time on gl texture creation: [TIME] seconds -  </text> -  <text -   type="string" -   length="1" -   follows="left|top" -   height="25" -   layout="topleft" -   left_delta="0" -   name="total_time_http_label" -   top_delta="25" -   width="400"> -    13, Total time on HTTP fetching: [TIME] seconds -  </text> -  <text -   type="string" -   length="1" -   follows="left|top" -   height="25" -   layout="topleft" -   left_delta="0" -   name="total_time_fetch_label" -   top_delta="25" -   width="400"> -    14, Total time on entire fetching: [TIME] seconds -  </text> -  <text -  type="string" -  length="1" -  follows="left|top" -  height="25" -  layout="topleft" -  left_delta="0" -  name="total_time_refetch_vis_cache_label" -  top_delta="25" -  width="540"> -    15, Refetching visibles from cache, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels -  </text> -  <text -  type="string" -  length="1" -  follows="left|top" -  height="25" -  layout="topleft" -  left_delta="0" -  name="total_time_refetch_all_cache_label" -  top_delta="25" -  width="540"> -    16, Refetching all textures from cache, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels -  </text> -  <text -  type="string" -  length="1" -  follows="left|top" -  height="25" -  layout="topleft" -  left_delta="0" -  name="total_time_refetch_vis_http_label" -  top_delta="25" -  width="540"> -    17, Refetching visibles from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels -  </text> -  <text -  type="string" -  length="1" -  follows="left|top" -  height="25" -  layout="topleft" -  left_delta="0" -  name="total_time_refetch_all_http_label" -  top_delta="25" -  width="540"> -    18, Refetching all textures from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels -  </text> -  <spinner -     decimal_digits="2" -     follows="left|top" -     height="20" -     increment="0.01" -     initial_value="1.0" -     label="19, Ratio of Texel/Pixel:" -     label_width="130" -     layout="topleft" -     left_delta="0" -     max_val="10.0" -     min_val="0.01" -     name="texel_pixel_ratio" -     top_delta="30" -     width="200"> -    <spinner.commit_callback -		function="TexFetchDebugger.ChangeTexelPixelRatio" /> -  </spinner> -  <text -  type="string" -  length="1" -  follows="left|top" -  height="25" -  layout="topleft" -  left_delta="0" -  name="texture_source_label" -  top_delta="30" -  width="110"> -    20, Texture Source: -  </text> -  <radio_group -     control_name="TextureFetchSource" -     follows="top|left" -     draw_border="false" -     height="25" -     layout="topleft" -     left_pad="0" -     name="texture_source" -     top_delta="0" -     width="264"> -    <radio_item -     height="16" -     label="Cache + HTTP" -     layout="topleft" -     left="3" -     name="0" -     top="0" -     width="100" /> -    <radio_item -     height="16" -     label="HTTP Only" -     layout="topleft" -     left_delta="100" -     name="1" -     top_delta="0" -     width="200" /> -  </radio_group> -  <button -   follows="left|top" -   height="20" -   label="Start" -   layout="topleft" -   left="10" -   name="start_btn" -   top_delta="20" -   width="70"> -    <button.commit_callback -		function="TexFetchDebugger.Start" /> -  </button> -  <button -   follows="left|top" -   height="20" -   label="Reset" -   layout="topleft" -   left_pad="7" -   name="clear_btn" -   top_delta="0" -   width="70"> -    <button.commit_callback -		function="TexFetchDebugger.Clear" /> -  </button> -  <button -   follows="left|top" -   height="20" -   label="Close" -   layout="topleft" -   left_pad="7" -   name="close_btn" -   top_delta="0" -   width="70"> -    <button.commit_callback -		function="TexFetchDebugger.Close" /> -  </button> -  <button -   follows="left|top" -   height="22" -   label="Reset Fetching Time" -   layout="topleft" -   left_pad="175" -   name="reset_time_btn" -   top_delta="0" -   width="120"> -    <button.commit_callback -		function="TexFetchDebugger.ResetFetchTime" /> -  </button> -  <button -   follows="left|top" -   height="20" -   label="Cache Read" -   layout="topleft" -   left="10" -   name="cacheread_btn" -   top_delta="20" -   width="80"> -    <button.commit_callback -		function="TexFetchDebugger.CacheRead" /> -  </button> -  <button -   follows="left|top" -   height="20" -   label="Cache Write" -   layout="topleft" -   left_pad="7" -   name="cachewrite_btn" -   top_delta="0" -   width="80"> -    <button.commit_callback -		function="TexFetchDebugger.CacheWrite" /> -  </button> -  <button -   follows="left|top" -   height="20" -   label="HTTP" -   layout="topleft" -   left_pad="7" -   name="http_btn" -   top_delta="0" -   width="70"> -    <button.commit_callback -		function="TexFetchDebugger.HTTPLoad" /> -  </button> -  <button -   follows="left|top" -   height="20" -   label="Decode" -   layout="topleft" -   left_pad="7" -   name="decode_btn" -   top_delta="0" -   width="70"> -    <button.commit_callback -		function="TexFetchDebugger.Decode" /> -  </button> -  <button -   follows="left|top" -   height="20" -   label="GL Texture" -   layout="topleft" -   left_pad="7" -   name="gl_btn" -   top_delta="0" -   width="70"> -    <button.commit_callback -		function="TexFetchDebugger.GLTexture" /> -  </button> -  <button -   follows="left|top" -   height="20" -   label="Refetch Vis Cache" -   layout="topleft" -   left="10" -   name="refetchviscache_btn" -   top_delta="20" -   width="120"> -    <button.commit_callback -		function="TexFetchDebugger.RefetchVisCache" /> -  </button> -  <button -   follows="left|top" -   height="20" -   label="Refetch All Cache" -   layout="topleft" -   left_pad="7" -   name="refetchallcache_btn" -   top_delta="0" -   width="120"> -    <button.commit_callback -		function="TexFetchDebugger.RefetchAllCache" /> -  </button> -  <button -   follows="left|top" -   height="20" -   label="Refetch Vis HTTP" -   layout="topleft" -   left_pad="7" -   name="refetchvishttp_btn" -   top_delta="0" -   width="120"> -    <button.commit_callback -		function="TexFetchDebugger.RefetchVisHTTP" /> -  </button> -  <button -   follows="left|top" -   height="20" -   label="Refetch All HTTP" -   layout="topleft" -   left_pad="7" -   name="refetchallhttp_btn" -   top_delta="0" -   width="120"> -    <button.commit_callback -		function="TexFetchDebugger.RefetchAllHTTP" /> -  </button> -</floater> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index beb5a5048d..cf99240908 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2465,20 +2465,6 @@ function="World.EnvPreset"                 function="Advanced.ToggleConsole"                 parameter="scene monitor" />              </menu_item_check> -            <menu_item_call -              enabled="false" -              visible="false" -              label="Texture Fetch Debug Console" -              name="Texture Fetch Debug Console"> -              <menu_item_call.on_click -                function="Floater.Show" -                parameter="tex_fetch_debugger" /> -              <on_enable -                function="Develop.SetTexFetchDebugger" /> -              <on_visible -                function="Develop.SetTexFetchDebugger" /> -            </menu_item_call> -                        <menu_item_separator/>              <menu_item_call diff --git a/indra/newview/tests/llviewercontrollistener_test.cpp b/indra/newview/tests/llviewercontrollistener_test.cpp new file mode 100644 index 0000000000..6d100ef984 --- /dev/null +++ b/indra/newview/tests/llviewercontrollistener_test.cpp @@ -0,0 +1,174 @@ +/** + * @file   llviewercontrollistener_test.cpp + * @author Nat Goodspeed + * @date   2022-06-09 + * @brief  Test for llviewercontrollistener. + *  + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Copyright (c) 2022, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "llviewerprecompiledheaders.h" +// associated header +#include "llviewercontrollistener.h" +// STL headers +// std headers +// external library headers +// other Linden headers +#include "../test/lltut.h" +#include "../test/catch_and_store_what_in.h" // catch_what() +#include "commoncontrol.h" +#include "llcontrol.h"              // LLControlGroup +#include "llviewercontrollistener.h" + +/***************************************************************************** +*   TUT +*****************************************************************************/ +namespace tut +{ +    void ensure_contains(const std::string& msg, const std::string& substr) +    { +        ensure_contains("Exception does not contain " + substr, msg, substr); +    } + +    struct llviewercontrollistener_data +    { +        LLControlGroup Global{"FakeGlobal"}; + +        llviewercontrollistener_data() +        { +            Global.declareString("strvar", "woof", "string variable"); +            // together we will stroll the boolvar, ma cherie +            Global.declareBOOL("boolvar",  TRUE, "bool variable"); +        } +    }; +    typedef test_group<llviewercontrollistener_data> llviewercontrollistener_group; +    typedef llviewercontrollistener_group::object object; +    llviewercontrollistener_group llviewercontrollistenergrp("llviewercontrollistener"); + +    template<> template<> +    void object::test<1>() +    { +        set_test_name("CommonControl no listener"); +        // Not implemented: the linker drags in LLViewerControlListener when +        // we bring in LLViewerControl. +    } + +    template<> template<> +    void object::test<2>() +    { +        set_test_name("CommonControl bad group"); +        std::string threw{ catch_what<LL::CommonControl::ParamError>( +                [](){ LL::CommonControl::get("Nonexistent", "Variable"); }) }; +        ensure_contains(threw, "group"); +        ensure_contains(threw, "Nonexistent"); +    } + +    template<> template<> +    void object::test<3>() +    { +        set_test_name("CommonControl bad variable"); +        std::string threw{ catch_what<LL::CommonControl::ParamError>( +                [](){ LL::CommonControl::get("FakeGlobal", "Nonexistent"); }) }; +        ensure_contains(threw, "key"); +        ensure_contains(threw, "Nonexistent"); +    } + +    template<> template<> +    void object::test<4>() +    { +        set_test_name("CommonControl toggle string"); +        std::string threw{ catch_what<LL::CommonControl::ParamError>( +                [](){ LL::CommonControl::toggle("FakeGlobal", "strvar"); }) }; +        ensure_contains(threw, "non-boolean"); +        ensure_contains(threw, "strvar"); +    } + +    template<> template<> +    void object::test<5>() +    { +        set_test_name("CommonControl list bad group"); +        std::string threw{ catch_what<LL::CommonControl::ParamError>( +                [](){ LL::CommonControl::get_vars("Nonexistent"); }) }; +        ensure_contains(threw, "group"); +        ensure_contains(threw, "Nonexistent"); +    } + +    template<> template<> +    void object::test<6>() +    { +        set_test_name("CommonControl get"); +        auto strvar{ LL::CommonControl::get("FakeGlobal", "strvar") }; +        ensure_equals(strvar, "woof"); +        auto boolvar{ LL::CommonControl::get("FakeGlobal", "boolvar") }; +        ensure(boolvar); +    } + +    template<> template<> +    void object::test<7>() +    { +        set_test_name("CommonControl set, set_default, toggle"); + +        std::string newstr{ LL::CommonControl::set("FakeGlobal", "strvar", "mouse").asString() }; +        ensure_equals(newstr, "mouse"); +        ensure_equals(LL::CommonControl::get("FakeGlobal", "strvar").asString(), "mouse"); +        ensure_equals(LL::CommonControl::set_default("FakeGlobal", "strvar").asString(), "woof"); + +        bool newbool{ LL::CommonControl::set("FakeGlobal", "boolvar", false) }; +        ensure(! newbool); +        ensure(! LL::CommonControl::get("FakeGlobal", "boolvar").asBoolean()); +        ensure(LL::CommonControl::set_default("FakeGlobal", "boolvar").asBoolean()); +        ensure(! LL::CommonControl::toggle("FakeGlobal", "boolvar").asBoolean()); +    } + +    template<> template<> +    void object::test<8>() +    { +        set_test_name("CommonControl get_def"); +        LLSD def{ LL::CommonControl::get_def("FakeGlobal", "strvar") }; +        ensure_equals( +            def, +            llsd::map("name", "strvar", +                      "type", "String", +                      "value", "woof", +                      "comment", "string variable")); +    } + +    template<> template<> +    void object::test<9>() +    { +        set_test_name("CommonControl get_groups"); +        std::vector<std::string> groups{ LL::CommonControl::get_groups() }; +        ensure_equals(groups.size(), 1); +        ensure_equals(groups[0], "FakeGlobal"); +    } + +    template<> template<> +    void object::test<10>() +    { +        set_test_name("CommonControl get_vars"); +        LLSD vars{ LL::CommonControl::get_vars("FakeGlobal") }; +        // convert from array (unpredictable order) to map +        LLSD varsmap{ LLSD::emptyMap() }; +        for (auto& var : llsd::inArray(vars)) +        { +            varsmap[var["name"].asString()] = var; +        } +        // comparing maps is order-insensitive +        ensure_equals( +            varsmap, +            llsd::map( +                "strvar", +                llsd::map("name", "strvar", +                          "type", "String", +                          "value", "woof", +                          "comment", "string variable"), +                "boolvar", +                llsd::map("name", "boolvar", +                          "type", "Boolean", +                          "value", TRUE, +                          "comment", "bool variable"))); +    } +} // namespace tut diff --git a/indra/test/test.cpp b/indra/test/test.cpp index bb48216b2b..28f25087ac 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -401,7 +401,7 @@ public:  	{  		// Per http://confluence.jetbrains.net/display/TCD65/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-ServiceMessages  		std::string result; -		BOOST_FOREACH(char c, str) +		for (char c : str)  		{  			switch (c)  			{ | 
