summaryrefslogtreecommitdiff
path: root/indra/newview/lltexturefetch.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/lltexturefetch.cpp')
-rw-r--r--indra/newview/lltexturefetch.cpp196
1 files changed, 52 insertions, 144 deletions
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 5996fe3da7..52d227f827 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -2,25 +2,31 @@
* @file lltexturefetch.cpp
* @brief Object which fetches textures from the cache and/or network
*
- * $LicenseInfo:firstyear=2000&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, 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.
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
- * 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.
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
- * 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
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
*
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
@@ -284,8 +290,8 @@ class HTTPGetResponder : public LLCurl::Responder
{
LOG_CLASS(HTTPGetResponder);
public:
- HTTPGetResponder(LLTextureFetch* fetcher, const LLUUID& id, U64 startTime, S32 requestedSize, U32 offset, bool redir)
- : mFetcher(fetcher), mID(id), mStartTime(startTime), mRequestedSize(requestedSize), mOffset(offset), mFollowRedir(redir)
+ HTTPGetResponder(LLTextureFetch* fetcher, const LLUUID& id, U64 startTime, S32 requestedSize, U32 offset)
+ : mFetcher(fetcher), mID(id), mStartTime(startTime), mRequestedSize(requestedSize), mOffset(offset)
{
}
~HTTPGetResponder()
@@ -338,11 +344,6 @@ public:
llwarns << "Worker not found: " << mID << llendl;
}
}
-
- virtual bool followRedir()
- {
- return mFollowRedir;
- }
private:
LLTextureFetch* mFetcher;
@@ -350,7 +351,6 @@ private:
U64 mStartTime;
S32 mRequestedSize;
U32 mOffset;
- bool mFollowRedir;
};
//////////////////////////////////////////////////////////////////////////////
@@ -582,26 +582,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
{
LLMutexLock lock(&mWorkMutex);
- if ((mFetcher->isQuitting() || getFlags(LLWorkerClass::WCF_DELETE_REQUESTED)))
+ if ((mFetcher->isQuitting() || mImagePriority < 1.0f || getFlags(LLWorkerClass::WCF_DELETE_REQUESTED)))
{
if (mState < DECODE_IMAGE)
{
return true; // abort
}
}
- if(mImagePriority < 1.0f)
- {
- if (mState == INIT || mState == LOAD_FROM_NETWORK || mState == LOAD_FROM_SIMULATOR)
- {
- return true; // abort
- }
- }
- if(mState > CACHE_POST && !mCanUseNET && !mCanUseHTTP)
- {
- //nowhere to get data, abort.
- return true ;
- }
-
+
if (mFetcher->mDebugPause)
{
return false; // debug: don't do any work
@@ -789,7 +777,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
// don't return, fall through to next state
}
- else if (mSentRequest == UNSENT && mCanUseNET)
+ else if (mSentRequest == UNSENT)
{
// Add this to the network queue and sit here.
// LLTextureFetch::update() will send off a request which will change our state
@@ -842,16 +830,16 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == SEND_HTTP_REQ)
{
- if(mCanUseHTTP)
{
+ const S32 HTTP_QUEUE_MAX_SIZE = 8;
// *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)
+ F32 max_bandwidth = mFetcher->mMaxBandwidth;
+ if ((mFetcher->getHTTPQueueSize() >= HTTP_QUEUE_MAX_SIZE) ||
+ (mFetcher->getTextureBandwidth() > max_bandwidth))
{
// Make normal priority and return (i.e. wait until there is room in the queue)
setPriority(LLWorkerThread::PRIORITY_NORMAL | mWorkPriority);
@@ -866,17 +854,10 @@ bool LLTextureFetchWorker::doWork(S32 param)
cur_size = mFormattedImage->getDataSize(); // amount of data we already have
if (mFormattedImage->getDiscardLevel() == 0)
{
- if(cur_size > 0)
- {
- // We already have all the data, just decode it
- mLoadedDiscard = mFormattedImage->getDiscardLevel();
- mState = DECODE_IMAGE;
- return false;
- }
- else
- {
- return true ; //abort.
- }
+ // We already have all the data, just decode it
+ mLoadedDiscard = mFormattedImage->getDiscardLevel();
+ mState = DECODE_IMAGE;
+ return false;
}
}
mRequestedSize = mDesiredSize;
@@ -893,7 +874,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
mGetReason.clear();
LL_DEBUGS("Texture") << "HTTP GET: " << mID << " Offset: " << offset
<< " Bytes: " << mRequestedSize
- << " Bandwidth(kbps): " << mFetcher->getTextureBandwidth() << "/" << mFetcher->mMaxBandwidth
+ << " Bandwidth(kbps): " << mFetcher->getTextureBandwidth() << "/" << max_bandwidth
<< LL_ENDL;
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
mState = WAIT_HTTP_REQ;
@@ -903,7 +884,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
std::vector<std::string> headers;
headers.push_back("Accept: image/x-j2c");
res = mFetcher->mCurlGetRequest->getByteRange(mUrl, headers, offset, mRequestedSize,
- new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset, true));
+ new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset));
}
if (!res)
{
@@ -914,10 +895,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
// fall through
}
- else //can not use http fetch.
- {
- return true ; //abort
- }
}
if (mState == WAIT_HTTP_REQ)
@@ -951,6 +928,17 @@ bool LLTextureFetchWorker::doWork(S32 param)
max_attempts = mHTTPFailCount+1; // Keep retrying
LL_INFOS_ONCE("Texture") << "Texture server busy (503): " << mUrl << LL_ENDL;
}
+ else if(mGetStatus >= HTTP_MULTIPLE_CHOICES && mGetStatus < HTTP_BAD_REQUEST) //http re-direct
+ {
+ ++mHTTPFailCount;
+ max_attempts = 5 ; //try at most 5 times to avoid infinite redirection loop.
+
+ llwarns << "HTTP GET failed because of redirection: " << mUrl
+ << " Status: " << mGetStatus << " Reason: '" << mGetReason << llendl ;
+
+ //assign to the new url
+ mUrl = mGetReason ;
+ }
else
{
const S32 HTTP_MAX_RETRY_COUNT = 3;
@@ -983,17 +971,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
}
- llassert_always(mBufferSize == cur_size + mRequestedSize);
- if(!mBufferSize)//no data received.
- {
- delete[] mBuffer;
- mBuffer = NULL;
-
- //abort.
- mState = DONE;
- return true;
- }
-
if (mFormattedImage.isNull())
{
// For now, create formatted image based on extension
@@ -1004,7 +981,8 @@ bool LLTextureFetchWorker::doWork(S32 param)
mFormattedImage = new LLImageJ2C; // default
}
}
-
+
+ llassert_always(mBufferSize == cur_size + mRequestedSize);
if (mHaveAllData && mRequestedDiscard == 0) //the image file is fully loaded.
{
mFileSize = mBufferSize;
@@ -1063,12 +1041,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mFormattedImage->getDataSize() <= 0)
{
- //llerrs << "Decode entered with invalid mFormattedImage. ID = " << mID << llendl;
-
- //abort, don't decode
- mState = DONE;
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
- return true;
+ llerrs << "Decode entered with invalid mFormattedImage. ID = " << mID << llendl;
}
if (mLoadedDiscard < 0)
{
@@ -1265,7 +1238,7 @@ bool LLTextureFetchWorker::deleteOK()
if ((haveWork() &&
// not ok to delete from these states
- ((mState == WAIT_HTTP_REQ) ||
+ ((mState >= SEND_HTTP_REQ && mState <= WAIT_HTTP_REQ) ||
(mState >= WRITE_TO_CACHE && mState <= WAIT_ON_WRITE))))
{
delete_ok = false;
@@ -1526,11 +1499,6 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
{
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()
@@ -1678,65 +1646,6 @@ void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id)
mHTTPTextureQueue.erase(id);
}
-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)
{
lockQueue() ;
@@ -1903,8 +1812,7 @@ S32 LLTextureFetch::update(U32 max_time_ms)
lldebugs << "processed: " << processed << " messages." << llendl;
}
}
- clearHTTPThrottleFlag();
-
+
return res;
}