diff options
author | McCabe Maxsted | 2010-08-07 01:11:59 -0700 |
---|---|---|
committer | McCabe Maxsted | 2010-08-07 06:26:15 -0700 |
commit | b1237876163022fc54d60045177d7a338b7550ef (patch) | |
tree | f99bf253095c4a381ffe78f0717d57317cf99878 | |
parent | Fixed curly quotes for jcfloaterareasearch (diff) | |
download | meta-impy-b1237876163022fc54d60045177d7a338b7550ef.zip meta-impy-b1237876163022fc54d60045177d7a338b7550ef.tar.gz meta-impy-b1237876163022fc54d60045177d7a338b7550ef.tar.bz2 meta-impy-b1237876163022fc54d60045177d7a338b7550ef.tar.xz |
Applied patch by Robin Cornelius for SNOW-780: textures fetched via http are not cached
-rw-r--r-- | linden/indra/newview/lltexturefetch.cpp | 133 |
1 files changed, 112 insertions, 21 deletions
diff --git a/linden/indra/newview/lltexturefetch.cpp b/linden/indra/newview/lltexturefetch.cpp index 326a1b6..820eaf7 100644 --- a/linden/indra/newview/lltexturefetch.cpp +++ b/linden/indra/newview/lltexturefetch.cpp | |||
@@ -169,6 +169,9 @@ public: | |||
169 | mGetReason = reason; | 169 | mGetReason = reason; |
170 | } | 170 | } |
171 | 171 | ||
172 | void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;} | ||
173 | bool getCanUseHTTP()const {return mCanUseHTTP ;} | ||
174 | |||
172 | protected: | 175 | protected: |
173 | LLTextureFetchWorker(LLTextureFetch* fetcher, const LLUUID& id, const LLHost& host, | 176 | LLTextureFetchWorker(LLTextureFetch* fetcher, const LLUUID& id, const LLHost& host, |
174 | F32 priority, S32 discard, S32 size); | 177 | F32 priority, S32 discard, S32 size); |
@@ -218,8 +221,15 @@ private: | |||
218 | QUEUED = 1, | 221 | QUEUED = 1, |
219 | SENT_SIM = 2 | 222 | SENT_SIM = 2 |
220 | }; | 223 | }; |
224 | enum e_write_to_cache_state //mWriteToCacheState | ||
225 | { | ||
226 | NOT_WRITE = 0, | ||
227 | CAN_WRITE = 1, | ||
228 | SHOULD_WRITE = 2 | ||
229 | }; | ||
221 | static const char* sStateDescs[]; | 230 | static const char* sStateDescs[]; |
222 | e_state mState; | 231 | e_state mState; |
232 | e_write_to_cache_state mWriteToCacheState; | ||
223 | LLTextureFetch* mFetcher; | 233 | LLTextureFetch* mFetcher; |
224 | LLPointer<LLImageFormatted> mFormattedImage; | 234 | LLPointer<LLImageFormatted> mFormattedImage; |
225 | LLPointer<LLImageRaw> mRawImage; | 235 | LLPointer<LLImageRaw> mRawImage; |
@@ -254,6 +264,8 @@ private: | |||
254 | BOOL mNeedsAux; | 264 | BOOL mNeedsAux; |
255 | BOOL mHaveAllData; | 265 | BOOL mHaveAllData; |
256 | BOOL mInLocalCache; | 266 | BOOL mInLocalCache; |
267 | bool mCanUseHTTP ; | ||
268 | bool mCanUseNET ; //can get from asset server. | ||
257 | S32 mHTTPFailCount; | 269 | S32 mHTTPFailCount; |
258 | S32 mRetryAttempt; | 270 | S32 mRetryAttempt; |
259 | S32 mActiveCount; | 271 | S32 mActiveCount; |
@@ -379,6 +391,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, | |||
379 | S32 size) // Desired size | 391 | S32 size) // Desired size |
380 | : LLWorkerClass(fetcher, "TextureFetch"), | 392 | : LLWorkerClass(fetcher, "TextureFetch"), |
381 | mState(INIT), | 393 | mState(INIT), |
394 | mWriteToCacheState(NOT_WRITE), | ||
382 | mFetcher(fetcher), | 395 | mFetcher(fetcher), |
383 | mID(id), | 396 | mID(id), |
384 | mHost(host), | 397 | mHost(host), |
@@ -407,6 +420,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, | |||
407 | mNeedsAux(FALSE), | 420 | mNeedsAux(FALSE), |
408 | mHaveAllData(FALSE), | 421 | mHaveAllData(FALSE), |
409 | mInLocalCache(FALSE), | 422 | mInLocalCache(FALSE), |
423 | mCanUseHTTP(true), | ||
410 | mHTTPFailCount(0), | 424 | mHTTPFailCount(0), |
411 | mRetryAttempt(0), | 425 | mRetryAttempt(0), |
412 | mActiveCount(0), | 426 | mActiveCount(0), |
@@ -417,6 +431,8 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, | |||
417 | mTotalPackets(0), | 431 | mTotalPackets(0), |
418 | mImageCodec(IMG_CODEC_INVALID) | 432 | mImageCodec(IMG_CODEC_INVALID) |
419 | { | 433 | { |
434 | mCanUseNET = mUrl.empty() ; | ||
435 | |||
420 | calcWorkPriority(); | 436 | calcWorkPriority(); |
421 | mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL; | 437 | mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL; |
422 | // llinfos << "Create: " << mID << " mHost:" << host << " Discard=" << discard << llendl; | 438 | // llinfos << "Create: " << mID << " mHost:" << host << " Discard=" << discard << llendl; |
@@ -573,13 +589,25 @@ bool LLTextureFetchWorker::doWork(S32 param) | |||
573 | { | 589 | { |
574 | LLMutexLock lock(&mWorkMutex); | 590 | LLMutexLock lock(&mWorkMutex); |
575 | 591 | ||
576 | if ((mFetcher->isQuitting() || (mImagePriority <= 0.0f) || getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) | 592 | if ((mFetcher->isQuitting() || getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) |
577 | { | 593 | { |
578 | if (mState < WRITE_TO_CACHE) | 594 | if (mState < DECODE_IMAGE) |
579 | { | 595 | { |
580 | return true; // abort | 596 | return true; // abort |
581 | } | 597 | } |
582 | } | 598 | } |
599 | if (mImagePriority < 1.0f) | ||
600 | { | ||
601 | if (mState == INIT || mState == LOAD_FROM_NETWORK || mState == LOAD_FROM_SIMULATOR) | ||
602 | { | ||
603 | return true; // abort | ||
604 | } | ||
605 | } | ||
606 | if (mState > CACHE_POST && !mCanUseNET && !mCanUseHTTP) | ||
607 | { | ||
608 | //nowhere to get data, abort. | ||
609 | return true ; | ||
610 | } | ||
583 | 611 | ||
584 | if (mFetcher->mDebugPause|| gDisconnected) | 612 | if (mFetcher->mDebugPause|| gDisconnected) |
585 | { | 613 | { |
@@ -647,7 +675,7 @@ bool LLTextureFetchWorker::doWork(S32 param) | |||
647 | mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID, cache_priority, | 675 | mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID, cache_priority, |
648 | offset, size, responder); | 676 | offset, size, responder); |
649 | } | 677 | } |
650 | else | 678 | else if(mCanUseHTTP) |
651 | { | 679 | { |
652 | if (!(mUrl.compare(0, 7, "http://") == 0)) | 680 | if (!(mUrl.compare(0, 7, "http://") == 0)) |
653 | { | 681 | { |
@@ -657,6 +685,11 @@ bool LLTextureFetchWorker::doWork(S32 param) | |||
657 | setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); | 685 | setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); |
658 | mState = SEND_HTTP_REQ; | 686 | mState = SEND_HTTP_REQ; |
659 | } | 687 | } |
688 | else | ||
689 | { | ||
690 | setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); | ||
691 | mState = LOAD_FROM_NETWORK; | ||
692 | } | ||
660 | } | 693 | } |
661 | 694 | ||
662 | if (mLoaded) | 695 | if (mLoaded) |
@@ -689,6 +722,10 @@ bool LLTextureFetchWorker::doWork(S32 param) | |||
689 | // we have enough data, decode it | 722 | // we have enough data, decode it |
690 | llassert_always(mFormattedImage->getDataSize() > 0); | 723 | llassert_always(mFormattedImage->getDataSize() > 0); |
691 | mState = DECODE_IMAGE; | 724 | mState = DECODE_IMAGE; |
725 | mWriteToCacheState = NOT_WRITE ; | ||
726 | LL_DEBUGS("Texture") << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize() | ||
727 | << " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight()) | ||
728 | << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL; | ||
692 | // fall through | 729 | // fall through |
693 | } | 730 | } |
694 | else | 731 | else |
@@ -716,7 +753,7 @@ bool LLTextureFetchWorker::doWork(S32 param) | |||
716 | bool get_url = gSavedSettings.getBOOL("ImagePipelineUseHTTP"); | 753 | bool get_url = gSavedSettings.getBOOL("ImagePipelineUseHTTP"); |
717 | if (!mUrl.empty()) get_url = false; | 754 | if (!mUrl.empty()) get_url = false; |
718 | // if (mHost != LLHost::invalid) get_url = false; | 755 | // if (mHost != LLHost::invalid) get_url = false; |
719 | if ( get_url ) | 756 | if ( get_url && mCanUseHTTP && mUrl.empty())//get http url. |
720 | { | 757 | { |
721 | LLViewerRegion* region = NULL; | 758 | LLViewerRegion* region = NULL; |
722 | if (mHost == LLHost::invalid) | 759 | if (mHost == LLHost::invalid) |
@@ -730,23 +767,35 @@ bool LLTextureFetchWorker::doWork(S32 param) | |||
730 | if (!http_url.empty()) | 767 | if (!http_url.empty()) |
731 | { | 768 | { |
732 | mUrl = http_url + "/?texture_id=" + mID.asString().c_str(); | 769 | mUrl = http_url + "/?texture_id=" + mID.asString().c_str(); |
770 | mWriteToCacheState = CAN_WRITE ; //because this texture has a fixed texture id. | ||
771 | } | ||
772 | else | ||
773 | { | ||
774 | mCanUseHTTP = false ; | ||
733 | } | 775 | } |
734 | } | 776 | } |
735 | else | 777 | else |
736 | { | 778 | { |
737 | llwarns << "Region not found for host: " << mHost << llendl; | 779 | // This will happen if not logged in or if a region deoes not have HTTP Texture enabled |
780 | //llwarns << "Region not found for host: " << mHost << llendl; | ||
781 | mCanUseHTTP = false; | ||
738 | } | 782 | } |
739 | } | 783 | } |
740 | if (!mUrl.empty()) | 784 | if (mCanUseHTTP && !mUrl.empty()) |
741 | { | 785 | { |
742 | mState = LLTextureFetchWorker::SEND_HTTP_REQ; | 786 | mState = LLTextureFetchWorker::SEND_HTTP_REQ; |
743 | setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); | 787 | setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); |
788 | if(mWriteToCacheState != NOT_WRITE) | ||
789 | { | ||
790 | mWriteToCacheState = CAN_WRITE ; | ||
791 | } | ||
744 | // don't return, fall through to next state | 792 | // don't return, fall through to next state |
745 | } | 793 | } |
746 | else if (mSentRequest == UNSENT) | 794 | else if (mSentRequest == UNSENT) |
747 | { | 795 | { |
748 | // Add this to the network queue and sit here. | 796 | // Add this to the network queue and sit here. |
749 | // LLTextureFetch::update() will send off a request which will change our state | 797 | // LLTextureFetch::update() will send off a request which will change our state |
798 | mWriteToCacheState = CAN_WRITE ; | ||
750 | mRequestedSize = mDesiredSize; | 799 | mRequestedSize = mDesiredSize; |
751 | mRequestedDiscard = mDesiredDiscard; | 800 | mRequestedDiscard = mDesiredDiscard; |
752 | mSentRequest = QUEUED; | 801 | mSentRequest = QUEUED; |
@@ -778,6 +827,7 @@ bool LLTextureFetchWorker::doWork(S32 param) | |||
778 | } | 827 | } |
779 | setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); | 828 | setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); |
780 | mState = DECODE_IMAGE; | 829 | mState = DECODE_IMAGE; |
830 | mWriteToCacheState = SHOULD_WRITE ; | ||
781 | } | 831 | } |
782 | else | 832 | else |
783 | { | 833 | { |
@@ -788,6 +838,7 @@ bool LLTextureFetchWorker::doWork(S32 param) | |||
788 | 838 | ||
789 | if (mState == SEND_HTTP_REQ) | 839 | if (mState == SEND_HTTP_REQ) |
790 | { | 840 | { |
841 | if(mCanUseHTTP) | ||
791 | { | 842 | { |
792 | const S32 HTTP_QUEUE_MAX_SIZE = 8; | 843 | const S32 HTTP_QUEUE_MAX_SIZE = 8; |
793 | // *TODO: Integrate this with llviewerthrottle | 844 | // *TODO: Integrate this with llviewerthrottle |
@@ -861,28 +912,59 @@ bool LLTextureFetchWorker::doWork(S32 param) | |||
861 | S32 cur_size = mFormattedImage.notNull() ? mFormattedImage->getDataSize() : 0; | 912 | S32 cur_size = mFormattedImage.notNull() ? mFormattedImage->getDataSize() : 0; |
862 | if (mRequestedSize < 0) | 913 | if (mRequestedSize < 0) |
863 | { | 914 | { |
864 | const S32 HTTP_MAX_RETRY_COUNT = 4; | 915 | S32 max_attempts; |
865 | llinfos << "HTTP GET failed for: " << mUrl | 916 | if (mGetStatus == HTTP_NOT_FOUND) |
866 | << " Status: " << mGetStatus << " Reason: " << mGetReason | 917 | { |
867 | << " Try:" << mHTTPFailCount+1 << "/" << HTTP_MAX_RETRY_COUNT << llendl; | 918 | mHTTPFailCount = max_attempts = 1; // Don't retry |
868 | if (cur_size == 0) | 919 | llwarns << "Texture missing from server (404): " << mUrl << llendl; |
920 | |||
921 | //roll back to try UDP | ||
922 | if(mCanUseNET) | ||
869 | { | 923 | { |
924 | mState = INIT ; | ||
925 | mCanUseHTTP = false ; | ||
926 | setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); | ||
927 | return false ; | ||
928 | } | ||
929 | } | ||
930 | else if (mGetStatus == HTTP_SERVICE_UNAVAILABLE) | ||
931 | { | ||
932 | // *TODO: Should probably introduce a timer here to delay future HTTP requsts | ||
933 | // for a short time (~1s) to ease server load? Ideally the server would queue | ||
934 | // requests instead of returning 503... we already limit the number pending. | ||
870 | ++mHTTPFailCount; | 935 | ++mHTTPFailCount; |
871 | if (mGetStatus == HTTP_NOT_FOUND || mHTTPFailCount >= HTTP_MAX_RETRY_COUNT) | 936 | max_attempts = mHTTPFailCount+1; // Keep retrying |
937 | LL_INFOS_ONCE("Texture") << "Texture server busy (503): " << mUrl << LL_ENDL; | ||
938 | } | ||
939 | else | ||
872 | { | 940 | { |
873 | resetFormattedData(); | 941 | const S32 HTTP_MAX_RETRY_COUNT = 3; |
874 | return true; // failed | 942 | max_attempts = HTTP_MAX_RETRY_COUNT + 1; |
943 | ++mHTTPFailCount; | ||
944 | llinfos << "HTTP GET failed for: " << mUrl | ||
945 | << " Status: " << mGetStatus << " Reason: '" << mGetReason << "'" | ||
946 | << " Attempt:" << mHTTPFailCount+1 << "/" << max_attempts << llendl; | ||
947 | } | ||
948 | |||
949 | if (mHTTPFailCount >= max_attempts) | ||
950 | { | ||
951 | if (cur_size > 0) | ||
952 | { | ||
953 | // Use available data | ||
954 | mLoadedDiscard = mFormattedImage->getDiscardLevel(); | ||
955 | mState = DECODE_IMAGE; | ||
956 | return false; | ||
875 | } | 957 | } |
876 | else | 958 | else |
877 | { | 959 | { |
878 | mState = SEND_HTTP_REQ; | 960 | resetFormattedData(); |
879 | return false; // retry | 961 | return true; // failed |
880 | } | 962 | } |
881 | } | 963 | } |
882 | else | 964 | else |
883 | { | 965 | { |
884 | mState = DECODE_IMAGE; | 966 | mState = SEND_HTTP_REQ; |
885 | return false; // use what we have | 967 | return false; // retry |
886 | } | 968 | } |
887 | } | 969 | } |
888 | 970 | ||
@@ -898,10 +980,15 @@ bool LLTextureFetchWorker::doWork(S32 param) | |||
898 | } | 980 | } |
899 | 981 | ||
900 | llassert_always(mBufferSize == cur_size + mRequestedSize); | 982 | llassert_always(mBufferSize == cur_size + mRequestedSize); |
901 | if (mHaveAllData) | 983 | if (mHaveAllData && mRequestedDiscard == 0) //the image file is fully loaded. |
902 | { | 984 | { |
903 | mFileSize = mBufferSize; | 985 | mFileSize = mBufferSize; |
904 | } | 986 | } |
987 | else //the file size is unknown. | ||
988 | { | ||
989 | mFileSize = mBufferSize + 1 ; //flag the file is not fully loaded. | ||
990 | } | ||
991 | |||
905 | U8* buffer = new U8[mBufferSize]; | 992 | U8* buffer = new U8[mBufferSize]; |
906 | if (cur_size > 0) | 993 | if (cur_size > 0) |
907 | { | 994 | { |
@@ -916,6 +1003,10 @@ bool LLTextureFetchWorker::doWork(S32 param) | |||
916 | mBufferSize = 0; | 1003 | mBufferSize = 0; |
917 | mLoadedDiscard = mRequestedDiscard; | 1004 | mLoadedDiscard = mRequestedDiscard; |
918 | mState = DECODE_IMAGE; | 1005 | mState = DECODE_IMAGE; |
1006 | if(mWriteToCacheState != NOT_WRITE) | ||
1007 | { | ||
1008 | mWriteToCacheState = SHOULD_WRITE ; | ||
1009 | } | ||
919 | setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); | 1010 | setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); |
920 | return false; | 1011 | return false; |
921 | } | 1012 | } |
@@ -980,7 +1071,7 @@ bool LLTextureFetchWorker::doWork(S32 param) | |||
980 | 1071 | ||
981 | if (mState == WRITE_TO_CACHE) | 1072 | if (mState == WRITE_TO_CACHE) |
982 | { | 1073 | { |
983 | if (mInLocalCache || mSentRequest == UNSENT || mFormattedImage.isNull()) | 1074 | if (mWriteToCacheState != SHOULD_WRITE || mFormattedImage.isNull()) |
984 | { | 1075 | { |
985 | // If we're in a local cache or we didn't actually receive any new data, | 1076 | // If we're in a local cache or we didn't actually receive any new data, |
986 | // or we failed to load anything, skip | 1077 | // or we failed to load anything, skip |