diff options
Diffstat (limited to 'indra/newview/lltexturefetch.cpp')
-rw-r--r-- | indra/newview/lltexturefetch.cpp | 131 |
1 files changed, 96 insertions, 35 deletions
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 4e9ebce4d1..5996fe3da7 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -48,7 +48,6 @@ #include "llviewertexturelist.h" #include "llviewertexture.h" #include "llviewerregion.h" -#include "llviewerstats.h" #include "llworld.h" ////////////////////////////////////////////////////////////////////////////// @@ -145,7 +144,7 @@ public: ~LLTextureFetchWorker(); void relese() { --mActiveCount; } - S32 callbackHttpGet(const LLChannelDescriptors& channels, + void callbackHttpGet(const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer, bool partial, bool success); void callbackCacheRead(bool success, LLImageFormatted* image, @@ -330,9 +329,8 @@ public: worker->setGetStatus(status, reason); // llwarns << "CURL GET FAILED, status:" << status << " reason:" << reason << llendl; } - - S32 data_size = worker->callbackHttpGet(channels, buffer, partial, success); - mFetcher->removeFromHTTPQueue(mID, data_size); + mFetcher->removeFromHTTPQueue(mID); + worker->callbackHttpGet(channels, buffer, partial, success); } else { @@ -591,7 +589,7 @@ bool LLTextureFetchWorker::doWork(S32 param) return true; // abort } } - if(mImagePriority < F_ALMOST_ZERO) + if(mImagePriority < 1.0f) { if (mState == INIT || mState == LOAD_FROM_NETWORK || mState == LOAD_FROM_SIMULATOR) { @@ -846,10 +844,19 @@ bool LLTextureFetchWorker::doWork(S32 param) { if(mCanUseHTTP) { - //NOTE: - //it seems ok to let sim control the UDP traffic - //so there is no throttle for http here. - // + // *TODO: Integrate this with llviewerthrottle + // Note: LLViewerThrottle uses dynamic throttling which makes sense for UDP, + // but probably not for Textures. + // Set the throttle to the entire bandwidth, assuming UDP packets will get priority + // when they are needed + //F32 max_bandwidth = mFetcher->mMaxBandwidth; + if (mFetcher->isHTTPThrottled(mDesiredSize))// || + //mFetcher->getTextureBandwidth() > max_bandwidth) + { + // Make normal priority and return (i.e. wait until there is room in the queue) + setPriority(LLWorkerThread::PRIORITY_NORMAL | mWorkPriority); + return false; + } mFetcher->removeFromNetworkQueue(this, false); @@ -966,7 +973,6 @@ bool LLTextureFetchWorker::doWork(S32 param) else { resetFormattedData(); - mState = DONE; return true; // failed } } @@ -1259,7 +1265,8 @@ bool LLTextureFetchWorker::deleteOK() if ((haveWork() && // not ok to delete from these states - ((mState >= WRITE_TO_CACHE && mState <= WAIT_ON_WRITE)))) + ((mState == WAIT_HTTP_REQ) || + (mState >= WRITE_TO_CACHE && mState <= WAIT_ON_WRITE)))) { delete_ok = false; } @@ -1338,29 +1345,29 @@ bool LLTextureFetchWorker::processSimulatorPackets() ////////////////////////////////////////////////////////////////////////////// -S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels, +void LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer, bool partial, bool success) { - S32 data_size = 0 ; - LLMutexLock lock(&mWorkMutex); if (mState != WAIT_HTTP_REQ) { llwarns << "callbackHttpGet for unrequested fetch worker: " << mID << " req=" << mSentRequest << " state= " << mState << llendl; - return data_size; + return; } if (mLoaded) { llwarns << "Duplicate callback for " << mID.asString() << llendl; - return data_size ; // ignore duplicate callback + return; // ignore duplicate callback } if (success) { // get length of stream: - data_size = buffer->countAfter(channels.in(), NULL); + S32 data_size = buffer->countAfter(channels.in(), NULL); + + gTextureList.sTextureBits += data_size * 8; // Approximate - does not include header bits LL_DEBUGS("Texture") << "HTTP RECEIVED: " << mID.asString() << " Bytes: " << data_size << LL_ENDL; if (data_size > 0) @@ -1397,8 +1404,6 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels, } mLoaded = TRUE; setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); - - return data_size ; } ////////////////////////////////////////////////////////////////////////////// @@ -1517,11 +1522,15 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image mTextureCache(cache), mImageDecodeThread(imagedecodethread), mTextureBandwidth(0), - mHTTPTextureBits(0), mCurlGetRequest(NULL) { mMaxBandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS"); mTextureInfo.setUpLogging(gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog"), gSavedSettings.getBOOL("LogTextureDownloadsToSimulator"), gSavedSettings.getU32("TextureLoggingThreshold")); + + for(S32 i = 0 ; i < TOTAL_TEXTURE_TYPES; i++) + { + mHTTPThrottleFlag[i] = FALSE ; + } } LLTextureFetch::~LLTextureFetch() @@ -1663,11 +1672,69 @@ void LLTextureFetch::addToHTTPQueue(const LLUUID& id) mHTTPTextureQueue.insert(id); } -void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id, S32 received_size) +void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id) { LLMutexLock lock(&mNetworkQueueMutex); mHTTPTextureQueue.erase(id); - mHTTPTextureBits += received_size * 8; // Approximate - does not include header bits +} + +void LLTextureFetch::clearHTTPThrottleFlag() +{ + static const F32 WAIT_TIME = 0.3f ; //seconds. + static LLFrameTimer timer ; + + if(timer.getElapsedTimeF32() < WAIT_TIME) //wait for WAIT_TIME + { + return ; + } + timer.reset() ; + + LLMutexLock lock(&mNetworkQueueMutex); + for(S32 i = 0 ; i < TOTAL_TEXTURE_TYPES; i++)//reset the http throttle flags. + { + mHTTPThrottleFlag[i] = FALSE ; + } +} + +//check if need to throttle this fetching request. +//rule: if a request can not be inserted into the http queue due to a full queue, +// block all future insertions of requests with larger fetching size requirement. +//because: +// later insertions are usually at lower priorities; and +// small textures need chance to be fetched. +bool LLTextureFetch::isHTTPThrottled(S32 requested_size) +{ + static const S32 SMALL_TEXTURE_MAX_SIZE = 64 * 64 * 4 ; + static const S32 MEDIUM_TEXTURE_MAX_SIZE = 256 * 256 * 4 ; + static const U32 MAX_HTTP_QUEUE_SIZE = 8 ; + + //determine the class of the texture: SMALL, MEDIUM, or LARGE. + S32 type = LARGE_TEXTURE ; + if(requested_size <= SMALL_TEXTURE_MAX_SIZE) + { + type = SMALL_TEXTURE ; + } + else if(requested_size <= MEDIUM_TEXTURE_MAX_SIZE) + { + type = MEDIUM_TEXTURE ; + } + + LLMutexLock lock(&mNetworkQueueMutex); + + if(mHTTPTextureQueue.size() >= MAX_HTTP_QUEUE_SIZE)//if the http queue is full. + { + if(!mHTTPThrottleFlag[type + 1]) + { + for(S32 i = type + 1 ; i < TOTAL_TEXTURE_TYPES; i++) //block all requests with fetching size larger than this request. + { + mHTTPThrottleFlag[i] = TRUE ; + } + } + + return true ; + } + + return mHTTPThrottleFlag[type] ; //true if this request can not be inserted to the http queue. } void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel) @@ -1815,19 +1882,12 @@ bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority) //virtual S32 LLTextureFetch::update(U32 max_time_ms) { + S32 res; + static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS"); - - { - mNetworkQueueMutex.lock() ; - mMaxBandwidth = band_width ; - - gTextureList.sTextureBits += mHTTPTextureBits ; - mHTTPTextureBits = 0 ; - - mNetworkQueueMutex.unlock() ; - } - - S32 res = LLWorkerThread::update(max_time_ms); + mMaxBandwidth = band_width ; + + res = LLWorkerThread::update(max_time_ms); if (!mDebugPause) { @@ -1843,6 +1903,7 @@ S32 LLTextureFetch::update(U32 max_time_ms) lldebugs << "processed: " << processed << " messages." << llendl; } } + clearHTTPThrottleFlag(); return res; } |