From 68ea8e13aca84da898a8a067c98eb0b8327a8de4 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Mon, 8 Feb 2010 14:40:06 -0800 Subject: partial fix for EXT-4352. fixed mutex deadlocks and turned on the multi-threaded texture fetching. --- indra/newview/lltexturefetch.cpp | 115 +++++++++++++++++++++++++++------------ 1 file changed, 79 insertions(+), 36 deletions(-) (limited to 'indra/newview/lltexturefetch.cpp') diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 404b79bfaf..bdc196e16c 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -73,13 +73,11 @@ private: } virtual void completed(bool success) { - mFetcher->lockQueue(); LLTextureFetchWorker* worker = mFetcher->getWorker(mID); if (worker) { worker->callbackCacheRead(success, mFormattedImage, mImageSize, mImageLocal); } - mFetcher->unlockQueue(); } private: LLTextureFetch* mFetcher; @@ -95,13 +93,11 @@ private: } virtual void completed(bool success) { - mFetcher->lockQueue(); LLTextureFetchWorker* worker = mFetcher->getWorker(mID); if (worker) { worker->callbackCacheWrite(success); } - mFetcher->unlockQueue(); } private: LLTextureFetch* mFetcher; @@ -117,13 +113,11 @@ private: } virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux) { - mFetcher->lockQueue(); LLTextureFetchWorker* worker = mFetcher->getWorker(mID); if (worker) { worker->callbackDecoded(success, raw, aux); } - mFetcher->unlockQueue(); } private: LLTextureFetch* mFetcher; @@ -166,6 +160,8 @@ public: void setGetStatus(U32 status, const std::string& reason) { + LLMutexLock lock(&mWorkMutex); + mGetStatus = status; mGetReason = reason; } @@ -307,7 +303,6 @@ public: } lldebugs << "HTTP COMPLETE: " << mID << llendl; - mFetcher->lockQueue(); LLTextureFetchWorker* worker = mFetcher->getWorker(mID); if (worker) { @@ -339,7 +334,6 @@ public: mFetcher->removeFromHTTPQueue(mID); llwarns << "Worker not found: " << mID << llendl; } - mFetcher->unlockQueue(); } private: @@ -1440,12 +1434,9 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con return false; } - LLTextureFetchWorker* worker = NULL; - LLMutexLock lock(&mQueueMutex); - map_t::iterator iter = mRequestMap.find(id); - if (iter != mRequestMap.end()) + LLTextureFetchWorker* worker = getWorker(id) ; + if (worker) { - worker = iter->second; if (worker->mHost != host) { llwarns << "LLTextureFetch::createRequest " << id << " called with multiple hosts: " @@ -1494,41 +1485,48 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con return false; // need to wait for previous aborted request to complete } worker->lockWorkMutex(); + worker->mActiveCount++; + worker->mNeedsAux = needs_aux; worker->setImagePriority(priority); worker->setDesiredDiscard(desired_discard, desired_size); - worker->unlockWorkMutex(); if (!worker->haveWork()) { worker->mState = LLTextureFetchWorker::INIT; + worker->unlockWorkMutex(); + worker->addWork(0, LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority); } + else + { + worker->unlockWorkMutex(); + } } else { worker = new LLTextureFetchWorker(this, url, id, host, priority, desired_discard, desired_size); + lockQueue() ; mRequestMap[id] = worker; - } + unlockQueue() ; + + worker->lockWorkMutex(); worker->mActiveCount++; worker->mNeedsAux = needs_aux; + worker->unlockWorkMutex(); + } + // llinfos << "REQUESTED: " << id << " Discard: " << desired_discard << llendl; return true; } -void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel) -{ - LLMutexLock lock(&mQueueMutex); - LLTextureFetchWorker* worker = getWorker(id); - if (worker) - { - removeRequest(worker, cancel); - } -} - // protected void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker) { + lockQueue() ; + bool in_request_map = (mRequestMap.find(worker->mID) != mRequestMap.end()) ; + unlockQueue() ; + LLMutexLock lock(&mNetworkQueueMutex); - if (mRequestMap.find(worker->mID) != mRequestMap.end()) + if (in_request_map) { // only add to the queue if in the request map // i.e. a delete has not been requested @@ -1564,10 +1562,34 @@ void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id) mHTTPTextureQueue.erase(id); } -// call lockQueue() first! +void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel) +{ + lockQueue() ; + LLTextureFetchWorker* worker = getWorkerAfterLock(id); + if (worker) + { + size_t erased_1 = mRequestMap.erase(worker->mID); + unlockQueue() ; + + llassert_always(erased_1 > 0) ; + + removeFromNetworkQueue(worker, cancel); + llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ; + + worker->scheduleDelete(); + } + else + { + unlockQueue() ; + } +} + void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel) { + lockQueue() ; size_t erased_1 = mRequestMap.erase(worker->mID); + unlockQueue() ; + llassert_always(erased_1 > 0) ; removeFromNetworkQueue(worker, cancel); llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ; @@ -1575,8 +1597,26 @@ void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel) worker->scheduleDelete(); } +S32 LLTextureFetch::getNumRequests() +{ + lockQueue() ; + S32 size = (S32)mRequestMap.size(); + unlockQueue() ; + + return size ; +} + +S32 LLTextureFetch::getNumHTTPRequests() +{ + mNetworkQueueMutex.lock() ; + S32 size = (S32)mHTTPTextureQueue.size(); + mNetworkQueueMutex.unlock() ; + + return size ; +} + // call lockQueue() first! -LLTextureFetchWorker* LLTextureFetch::getWorker(const LLUUID& id) +LLTextureFetchWorker* LLTextureFetch::getWorkerAfterLock(const LLUUID& id) { LLTextureFetchWorker* res = NULL; map_t::iterator iter = mRequestMap.find(id); @@ -1587,12 +1627,18 @@ LLTextureFetchWorker* LLTextureFetch::getWorker(const LLUUID& id) return res; } +LLTextureFetchWorker* LLTextureFetch::getWorker(const LLUUID& id) +{ + LLMutexLock lock(&mQueueMutex) ; + + return getWorkerAfterLock(id) ; +} + bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, LLPointer& raw, LLPointer& aux) { bool res = false; - LLMutexLock lock(&mQueueMutex); LLTextureFetchWorker* worker = getWorker(id); if (worker) { @@ -1644,7 +1690,6 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority) { bool res = false; - LLMutexLock lock(&mQueueMutex); LLTextureFetchWorker* worker = getWorker(id); if (worker) { @@ -1760,8 +1805,6 @@ void LLTextureFetch::sendRequestListToSimulators() } timer.reset(); - LLMutexLock lock(&mQueueMutex); - // Send requests typedef std::set request_list_t; typedef std::map< LLHost, request_list_t > work_request_map_t; @@ -1970,7 +2013,6 @@ bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size) bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, U16 data_size, U8* data) { - LLMutexLock lock(&mQueueMutex); LLTextureFetchWorker* worker = getWorker(id); bool res = true; @@ -2003,7 +2045,9 @@ bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 if (!res) { ++mBadPacketCount; + mNetworkQueueMutex.lock() ; mCancelQueue[host].insert(id); + mNetworkQueueMutex.unlock() ; return false; } @@ -2024,7 +2068,6 @@ bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data) { - LLMutexLock lock(&mQueueMutex); LLTextureFetchWorker* worker = getWorker(id); bool res = true; @@ -2048,7 +2091,9 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1 if (!res) { ++mBadPacketCount; + mNetworkQueueMutex.lock() ; mCancelQueue[host].insert(id); + mNetworkQueueMutex.unlock() ; return false; } @@ -2088,7 +2133,6 @@ BOOL LLTextureFetch::isFromLocalCache(const LLUUID& id) { BOOL from_cache = FALSE ; - LLMutexLock lock(&mQueueMutex); LLTextureFetchWorker* worker = getWorker(id); if (worker) { @@ -2110,7 +2154,6 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r F32 request_dtime = 999999.f; U32 fetch_priority = 0; - LLMutexLock lock(&mQueueMutex); LLTextureFetchWorker* worker = getWorker(id); if (worker && worker->haveWork()) { -- cgit v1.3 From 13e395aef2225601124d1df3ec4764859e8718f5 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Tue, 9 Feb 2010 12:53:05 -0800 Subject: more fix for EXT-4352: texture problem in viewer 2.0. fixed texture priority problem. --- indra/newview/lltexturefetch.cpp | 5 ++-- indra/newview/llviewertexture.cpp | 60 +++++++++++++++++++++++---------------- indra/newview/pipeline.cpp | 2 +- 3 files changed, 40 insertions(+), 27 deletions(-) (limited to 'indra/newview/lltexturefetch.cpp') diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index bdc196e16c..4a61130785 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -488,8 +488,9 @@ void LLTextureFetchWorker::setupPacketData() U32 LLTextureFetchWorker::calcWorkPriority() { -// llassert_always(mImagePriority >= 0 && mImagePriority <= LLViewerTexture::maxDecodePriority()); - static F32 PRIORITY_SCALE = (F32)LLWorkerThread::PRIORITY_LOWBITS / LLViewerFetchedTexture::maxDecodePriority(); + //llassert_always(mImagePriority >= 0 && mImagePriority <= LLViewerFetchedTexture::maxDecodePriority()); + static const F32 PRIORITY_SCALE = (F32)LLWorkerThread::PRIORITY_LOWBITS / LLViewerFetchedTexture::maxDecodePriority(); + mWorkPriority = (U32)(mImagePriority * PRIORITY_SCALE); return mWorkPriority; } diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 0ad269392d..051e1330d5 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -974,12 +974,6 @@ void LLViewerTexture::updateBindStatsForTester() //start of LLViewerFetchedTexture //---------------------------------------------------------------------------------------------- -//static -F32 LLViewerFetchedTexture::maxDecodePriority() -{ - return 6000000.f; -} - LLViewerFetchedTexture::LLViewerFetchedTexture(const LLUUID& id, const LLHost& host, BOOL usemipmaps) : LLViewerTexture(id, usemipmaps), mTargetHost(host) @@ -1426,6 +1420,13 @@ 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 @@ -1453,7 +1454,7 @@ F32 LLViewerFetchedTexture::calcDecodePriority() bool have_all_data = (cur_discard >= 0 && (cur_discard <= mDesiredDiscardLevel)); F32 pixel_priority = fsqrtf(mMaxVirtualSize); - F32 priority; + F32 priority = 0.f; if (mIsMissingAsset) { priority = 0.0f; @@ -1496,8 +1497,8 @@ F32 LLViewerFetchedTexture::calcDecodePriority() 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, 4); - priority = (ddiscard+1)*100000.f; + ddiscard = llclamp(ddiscard, 0, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY); + priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR; } else if ((mMinDiscardLevel > 0) && (cur_discard <= mMinDiscardLevel)) { @@ -1523,42 +1524,53 @@ F32 LLViewerFetchedTexture::calcDecodePriority() // 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; - //} + 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, 0, 4); - priority = (ddiscard+1)*100000.f; + ddiscard = llclamp(ddiscard, 0, 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-9,000,000] + [1-400,000] + [1-20,000] + [0-999] + // [10,000,000] + [1,000,000-9,000,000] + [100,000-500,000] + [1-20,000] + [0-999] if (priority > 0.0f) { - pixel_priority = llclamp(pixel_priority, 0.0f, 999.f); + pixel_priority = llclamp(pixel_priority, 0.0f, MAX_PRIORITY_PIXEL); - priority = pixel_priority + 1000.f * mBoostLevel; + priority += pixel_priority + PRIORITY_BOOST_LEVEL_FACTOR * mBoostLevel; if ( mBoostLevel > BOOST_HIGH) { - priority += 10000000.f; + priority += PRIORITY_BOOST_HIGH_FACTOR; } if(mAdditionalDecodePriority > 0.0f) { - // 1-9 - S32 additional_priority = (S32)(1.0f + mAdditionalDecodePriority*8.0f + .5f); // round - // priority range += 0-9,000,000 - priority += 1000000.f * (F32)additional_priority; + // priority range += 1,000,000.f-9,000,000.f + priority += PRIORITY_ADDITIONAL_FACTOR * (1.0 + mAdditionalDecodePriority * MAX_ADDITIONAL_LEVEL_FOR_PRIORITY); } } 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) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 4f4fc83819..bd22fc5f2e 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1970,7 +1970,7 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera) if (root && root->getParent() && root->getVObj() && root->getVObj()->isAttachment()) { LLVOAvatar* av = root->getParent()->getVObj()->asAvatar(); - if (av->isImpostor()) + if (av && av->isImpostor()) { return; } -- cgit v1.3 From e0e82c908dd7aef7a0d3010be4bbc9fa1ac4d32a Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Thu, 11 Feb 2010 18:02:16 -0800 Subject: more refinement for EXT-4352: texture problem in viewer 2.0. --- indra/newview/lltexturefetch.cpp | 7 ++++++- indra/newview/llviewertexture.cpp | 24 +++++++++--------------- 2 files changed, 15 insertions(+), 16 deletions(-) (limited to 'indra/newview/lltexturefetch.cpp') diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 4a61130785..6dcf4bc798 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -982,7 +982,12 @@ bool LLTextureFetchWorker::doWork(S32 param) } if (mLoadedDiscard < 0) { - llerrs << "Decode entered with invalid mLoadedDiscard. ID = " << mID << llendl; + //llerrs << "Decode entered with invalid mLoadedDiscard. ID = " << mID << llendl; + + //abort, don't decode + mState = DONE; + setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); + return true; } setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it mRawImage = NULL; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index dd16c4795f..b66f58d853 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1519,12 +1519,12 @@ F32 LLViewerFetchedTexture::calcDecodePriority() } else if (!isJustBound() && mCachedRawImageReady) { - if(mBoostLevel < BOOST_HIGH) - { - // We haven't rendered this in a while, de-prioritize it - desired_discard += 2; - } - else + //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; @@ -2342,14 +2342,8 @@ void LLViewerFetchedTexture::setCachedRawImage() { --i ; } - //if(mForSculpt) - //{ - // mRawImage->scaleDownWithoutBlending(w >> i, h >> i) ; - //} - //else - { - mRawImage->scale(w >> i, h >> i) ; - } + + mRawImage->scale(w >> i, h >> i) ; } mCachedRawImage = mRawImage ; mCachedRawDiscardLevel = mRawDiscardLevel + i ; @@ -2699,7 +2693,7 @@ void LLViewerLODTexture::processTextureStats() } else { - if(isLargeImage() && !isJustBound() && mAdditionalDecodePriority < 1.0f) + 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) ; -- cgit v1.3 From 03d79f1bf7e620c25245a06f442f809f0958ffbf Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Fri, 12 Feb 2010 14:21:36 -0800 Subject: some code dents change (nothing else). --- indra/newview/lltexturefetch.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/lltexturefetch.cpp') diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 6dcf4bc798..6c35464a51 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1515,8 +1515,8 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con unlockQueue() ; worker->lockWorkMutex(); - worker->mActiveCount++; - worker->mNeedsAux = needs_aux; + worker->mActiveCount++; + worker->mNeedsAux = needs_aux; worker->unlockWorkMutex(); } -- cgit v1.3