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.cpp124
1 files changed, 99 insertions, 25 deletions
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 2ea6e5936d..52d227f827 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -166,9 +166,10 @@ public:
mGetReason = reason;
}
+ void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;}
+ bool getCanUseHTTP()const {return mCanUseHTTP ;}
+
protected:
- LLTextureFetchWorker(LLTextureFetch* fetcher, const LLUUID& id, const LLHost& host,
- F32 priority, S32 discard, S32 size);
LLTextureFetchWorker(LLTextureFetch* fetcher, const std::string& url, const LLUUID& id, const LLHost& host,
F32 priority, S32 discard, S32 size);
@@ -215,8 +216,15 @@ private:
QUEUED = 1,
SENT_SIM = 2
};
+ enum e_write_to_cache_state //mWriteToCacheState
+ {
+ NOT_WRITE = 0,
+ CAN_WRITE = 1,
+ SHOULD_WRITE = 2
+ };
static const char* sStateDescs[];
e_state mState;
+ e_write_to_cache_state mWriteToCacheState;
LLTextureFetch* mFetcher;
LLPointer<LLImageFormatted> mFormattedImage;
LLPointer<LLImageRaw> mRawImage;
@@ -242,15 +250,17 @@ private:
S32 mRequestedSize;
S32 mDesiredSize;
S32 mFileSize;
- S32 mCachedSize;
- BOOL mLoaded;
+ S32 mCachedSize;
e_request_state mSentRequest;
handle_t mDecodeHandle;
+ BOOL mLoaded;
BOOL mDecoded;
BOOL mWritten;
BOOL mNeedsAux;
BOOL mHaveAllData;
BOOL mInLocalCache;
+ bool mCanUseHTTP ;
+ bool mCanUseNET ; //can get from asset server.
S32 mHTTPFailCount;
S32 mRetryAttempt;
S32 mActiveCount;
@@ -319,11 +329,7 @@ public:
partial = true;
}
}
- else
- {
- worker->setGetStatus(status, reason);
-// llwarns << status << ": " << reason << llendl;
- }
+
if (!success)
{
worker->setGetStatus(status, reason);
@@ -377,6 +383,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
S32 size) // Desired size
: LLWorkerClass(fetcher, "TextureFetch"),
mState(INIT),
+ mWriteToCacheState(NOT_WRITE),
mFetcher(fetcher),
mID(id),
mHost(host),
@@ -405,6 +412,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
mNeedsAux(FALSE),
mHaveAllData(FALSE),
mInLocalCache(FALSE),
+ mCanUseHTTP(true),
mHTTPFailCount(0),
mRetryAttempt(0),
mActiveCount(0),
@@ -415,6 +423,8 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
mTotalPackets(0),
mImageCodec(IMG_CODEC_INVALID)
{
+ mCanUseNET = mUrl.empty() ;
+
calcWorkPriority();
mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL;
// llinfos << "Create: " << mID << " mHost:" << host << " Discard=" << discard << llendl;
@@ -595,7 +605,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
if (mState == INIT)
- {
+ {
mRawImage = NULL ;
mRequestedDiscard = -1;
mLoadedDiscard = -1;
@@ -634,23 +644,27 @@ bool LLTextureFetchWorker::doWork(S32 param)
return false;
}
mFileSize = 0;
- mLoaded = FALSE;
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
-
- CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
+ mLoaded = FALSE;
+
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
std::string filename = mUrl.substr(7, std::string::npos);
+ CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, cache_priority,
offset, size, responder);
}
else if (mUrl.empty())
{
+ setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
+
+ CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID, cache_priority,
offset, size, responder);
}
- else
+ else if(mCanUseHTTP)
{
if (!(mUrl.compare(0, 7, "http://") == 0))
{
@@ -659,8 +673,11 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
mState = SEND_HTTP_REQ;
- delete responder;
- responder = NULL;
+ }
+ else
+ {
+ setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
+ mState = LOAD_FROM_NETWORK;
}
}
@@ -694,6 +711,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
llassert_always(mFormattedImage->getDataSize() > 0);
mLoadedDiscard = mDesiredDiscard;
mState = DECODE_IMAGE;
+ mWriteToCacheState = NOT_WRITE ;
LL_DEBUGS("Texture") << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize()
<< " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight())
<< " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL;
@@ -721,7 +739,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
static LLCachedControl<bool> use_http(gSavedSettings,"ImagePipelineUseHTTP");
// if (mHost != LLHost::invalid) get_url = false;
- if ( use_http && mUrl.empty())//get http url.
+ if ( use_http && mCanUseHTTP && mUrl.empty())//get http url.
{
LLViewerRegion* region = NULL;
if (mHost == LLHost::invalid)
@@ -731,28 +749,39 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (region)
{
- std::string http_url = region->getCapability("GetTexture");
+ std::string http_url = region->getHttpUrl() ;
if (!http_url.empty())
{
mUrl = http_url + "/?texture_id=" + mID.asString().c_str();
+ mWriteToCacheState = CAN_WRITE ; //because this texture has a fixed texture id.
+ }
+ else
+ {
+ mCanUseHTTP = false ;
}
}
else
{
// This will happen if not logged in or if a region deoes not have HTTP Texture enabled
//llwarns << "Region not found for host: " << mHost << llendl;
+ mCanUseHTTP = false;
}
}
- if (!mUrl.empty())
+ if (mCanUseHTTP && !mUrl.empty())
{
mState = LLTextureFetchWorker::SEND_HTTP_REQ;
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
+ if(mWriteToCacheState != NOT_WRITE)
+ {
+ mWriteToCacheState = CAN_WRITE ;
+ }
// don't return, fall through to next state
}
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
+ mWriteToCacheState = CAN_WRITE ;
mRequestedSize = mDesiredSize;
mRequestedDiscard = mDesiredDiscard;
mSentRequest = QUEUED;
@@ -789,6 +818,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
mState = DECODE_IMAGE;
+ mWriteToCacheState = SHOULD_WRITE ;
}
else
{
@@ -878,7 +908,16 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mGetStatus == HTTP_NOT_FOUND)
{
mHTTPFailCount = max_attempts = 1; // Don't retry
- llinfos << "Texture missing from server (404): " << mUrl << llendl;
+ llwarns << "Texture missing from server (404): " << mUrl << llendl;
+
+ //roll back to try UDP
+ if(mCanUseNET)
+ {
+ mState = INIT ;
+ mCanUseHTTP = false ;
+ setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
+ return false ;
+ }
}
else if (mGetStatus == HTTP_SERVICE_UNAVAILABLE)
{
@@ -889,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;
@@ -898,6 +948,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
<< " Status: " << mGetStatus << " Reason: '" << mGetReason << "'"
<< " Attempt:" << mHTTPFailCount+1 << "/" << max_attempts << llendl;
}
+
if (mHTTPFailCount >= max_attempts)
{
if (cur_size > 0)
@@ -932,10 +983,15 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
llassert_always(mBufferSize == cur_size + mRequestedSize);
- if (mHaveAllData)
+ if (mHaveAllData && mRequestedDiscard == 0) //the image file is fully loaded.
{
mFileSize = mBufferSize;
}
+ else //the file size is unknown.
+ {
+ mFileSize = mBufferSize + 1 ; //flag the file is not fully loaded.
+ }
+
U8* buffer = new U8[mBufferSize];
if (cur_size > 0)
{
@@ -950,6 +1006,10 @@ bool LLTextureFetchWorker::doWork(S32 param)
mBufferSize = 0;
mLoadedDiscard = mRequestedDiscard;
mState = DECODE_IMAGE;
+ if(mWriteToCacheState != NOT_WRITE)
+ {
+ mWriteToCacheState = SHOULD_WRITE ;
+ }
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
return false;
}
@@ -1049,7 +1109,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == WRITE_TO_CACHE)
{
- if (mInLocalCache || mSentRequest == UNSENT || mFormattedImage.isNull())
+ 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
@@ -1057,6 +1117,17 @@ bool LLTextureFetchWorker::doWork(S32 param)
return false;
}
S32 datasize = mFormattedImage->getDataSize();
+ if(mFileSize < datasize)//This could happen when http fetching and sim fetching mixed.
+ {
+ if(mHaveAllData)
+ {
+ mFileSize = datasize ;
+ }
+ else
+ {
+ mFileSize = datasize + 1 ; //flag not fully loaded.
+ }
+ }
llassert_always(datasize);
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
U32 cache_priority = mWorkPriority;
@@ -1438,7 +1509,7 @@ LLTextureFetch::~LLTextureFetch()
}
bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
- S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux)
+ S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http)
{
if (mDebugPause)
{
@@ -1500,6 +1571,7 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con
worker->mNeedsAux = needs_aux;
worker->setImagePriority(priority);
worker->setDesiredDiscard(desired_discard, desired_size);
+ worker->setCanUseHTTP(can_use_http) ;
if (!worker->haveWork())
{
worker->mState = LLTextureFetchWorker::INIT;
@@ -1522,6 +1594,7 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con
worker->lockWorkMutex();
worker->mActiveCount++;
worker->mNeedsAux = needs_aux;
+ worker->setCanUseHTTP(can_use_http) ;
worker->unlockWorkMutex();
}
@@ -2182,7 +2255,7 @@ BOOL LLTextureFetch::isFromLocalCache(const LLUUID& id)
}
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)
+ U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p, bool& can_use_http)
{
S32 state = LLTextureFetchWorker::INVALID;
F32 data_progress = 0.0f;
@@ -2220,6 +2293,7 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r
requested_priority = worker->mImagePriority;
}
fetch_priority = worker->getPriority();
+ can_use_http = worker->getCanUseHTTP() ;
worker->unlockWorkMutex();
}
data_progress_p = data_progress;