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.cpp1417
1 files changed, 224 insertions, 1193 deletions
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index a1beec7c1f..38c9b3717d 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -62,8 +62,6 @@
#include "llcorehttputil.h"
#include "llhttpretrypolicy.h"
-bool LLTextureFetchDebugger::sDebuggerEnabled = false ;
-
LLTrace::CountStatHandle<F64> LLTextureFetch::sCacheHit("texture_cache_hit");
LLTrace::CountStatHandle<F64> LLTextureFetch::sCacheAttempt("texture_cache_attempt");
LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > LLTextureFetch::sCacheHitRate("texture_cache_hits");
@@ -213,35 +211,17 @@ const std::string sTesterName("TextureFetchTester");
//
// Worker State Machine
//
-// (ASCII art needed)
-//
-//
-// Priority Scheme
-//
-// [PRIORITY_LOW, PRIORITY_NORMAL) - for WAIT_HTTP_RESOURCE state
-// and other wait states
-// [PRIORITY_HIGH, PRIORITY_URGENT) - External event delivered,
-// rapidly transitioning through states,
-// no waiting allowed
-//
-// By itself, the above work queue model would fail the concurrency
-// and liveness requirements of the interface. A high priority
-// request could find itself on the head and stalled for external
-// reasons (see VWR-28996). So a few additional constraints are
-// required to keep things running:
-// * Anything that can make forward progress must be kept at a
-// higher priority than anything that can't.
-// * On completion of external events, the associated request
-// needs to be elevated beyond the normal range to handle
-// any data delivery and release any external resource.
-//
-// This effort is made to keep higher-priority entities moving
-// forward in their state machines at every possible step of
-// processing. It's not entirely proven that this produces the
-// experiencial benefits promised.
+// "doWork" will be executed for a given worker on its respective
+// LLQueuedThread. If doWork returns true, the worker is treated
+// as completed. If doWork returns false, the worker will be
+// put on the back of the work queue at the start of the next iteration
+// of the mainloop. If a worker is waiting on a resource, it should
+// return false as soon as possible and not block to avoid starving
+// other workers of cpu cycles.
//
+
//////////////////////////////////////////////////////////////////////////////
// Tuning/Parameterization Constants
@@ -259,11 +239,15 @@ static const S32 HTTP_NONPIPE_REQUESTS_LOW_WATER = 20;
// request (e.g. 'Range: <start>-') which seems to fix the problem.
static const S32 HTTP_REQUESTS_RANGE_END_MAX = 20000000;
+// stop after 720 seconds, might be overkill, but cap request can keep going forever.
+static const S32 MAX_CAP_MISSING_RETRIES = 720;
+static const S32 CAP_MISSING_EXPIRATION_DELAY = 1; // seconds
+
//////////////////////////////////////////////////////////////////////////////
namespace
{
- // The NoOpDeletor is used when passing certain objects (the LLTextureFetchWorker and
- // the LLTextureFetchDebugger) in a smart pointer below for passage into
+ // The NoOpDeletor is used when passing certain objects (the LLTextureFetchWorker)
+ // in a smart pointer below for passage into
// the LLCore::Http libararies. When the smart pointer is destroyed, no
// action will be taken since we do not in these cases want the object to
// be destroyed at the end of the call.
@@ -300,7 +284,6 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler
{
friend class LLTextureFetch;
- friend class LLTextureFetchDebugger;
private:
class CacheReadResponder : public LLTextureCache::ReadResponder
@@ -385,14 +368,7 @@ private:
bool operator()(const LLTextureFetchWorker* lhs, const LLTextureFetchWorker* rhs) const
{
// greater priority is "less"
- const F32 lpriority = lhs->mImagePriority;
- const F32 rpriority = rhs->mImagePriority;
- if (lpriority > rpriority) // higher priority
- return true;
- else if (lpriority < rpriority)
- return false;
- else
- return lhs < rhs;
+ return lhs->mImagePriority > rhs->mImagePriority;
}
};
@@ -482,6 +458,9 @@ private:
// Locks: Mw
void resetFormattedData();
+ // get the relative priority of this worker (should map to max virtual size)
+ F32 getImagePriority() const;
+
// Locks: Mw
void setImagePriority(F32 priority);
@@ -496,9 +475,6 @@ private:
void clearPackets();
- // Locks: Mw (ctor invokes without lock)
- U32 calcWorkPriority();
-
// Locks: Mw
void removeFromCache();
@@ -554,6 +530,7 @@ private:
e_state mState;
void setState(e_state new_state);
+ LLViewerRegion* getRegion();
e_write_to_cache_state mWriteToCacheState;
LLTextureFetch* mFetcher;
@@ -565,16 +542,13 @@ private:
LLHost mHost;
std::string mUrl;
U8 mType;
- F32 mImagePriority;
- U32 mWorkPriority;
+ F32 mImagePriority; // should map to max virtual size
F32 mRequestedPriority;
S32 mDesiredDiscard;
S32 mSimRequestedDiscard;
S32 mRequestedDiscard;
S32 mLoadedDiscard;
S32 mDecodedDiscard;
- S32 mFullWidth;
- S32 mFullHeight;
LLFrameTimer mRequestedDeltaTimer;
LLFrameTimer mFetchDeltaTimer;
LLTimer mCacheReadTimer;
@@ -610,6 +584,10 @@ private:
LLCore::HttpStatus mGetStatus;
std::string mGetReason;
LLAdaptiveRetryPolicy mFetchRetryPolicy;
+ bool mCanUseCapability;
+ LLTimer mRegionRetryTimer;
+ S32 mRegionRetryAttempt;
+ LLUUID mLastRegionId;
// Work Data
@@ -913,7 +891,6 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
mHost(host),
mUrl(url),
mImagePriority(priority),
- mWorkPriority(0),
mRequestedPriority(0.f),
mDesiredDiscard(-1),
mSimRequestedDiscard(-1),
@@ -960,15 +937,15 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
mCacheReadCount(0U),
mCacheWriteCount(0U),
mResourceWaitCount(0U),
- mFetchRetryPolicy(10.0,3600.0,2.0,10)
+ mFetchRetryPolicy(10.f,3600.f,2.f,10),
+ mCanUseCapability(true),
+ mRegionRetryAttempt(0)
{
- calcWorkPriority();
mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL;
// LL_INFOS(LOG_TXT) << "Create: " << mID << " mHost:" << host << " Discard=" << discard << LL_ENDL;
if (!mFetcher->mDebugPause)
{
- U32 work_priority = mWorkPriority | LLWorkerThread::PRIORITY_HIGH;
- addWork(0, work_priority );
+ addWork(0);
}
setDesiredDiscard(discard, size);
}
@@ -1026,16 +1003,6 @@ void LLTextureFetchWorker::clearPackets()
}
// Locks: Mw (ctor invokes without lock)
-U32 LLTextureFetchWorker::calcWorkPriority()
-{
- //llassert_always(mImagePriority >= 0 && mImagePriority <= LLViewerFetchedTexture::maxDecodePriority());
- static const F32 PRIORITY_SCALE = (F32)LLWorkerThread::PRIORITY_LOWBITS / LLViewerFetchedTexture::maxDecodePriority();
-
- mWorkPriority = llmin((U32)LLWorkerThread::PRIORITY_LOWBITS, (U32)(mImagePriority * PRIORITY_SCALE));
- return mWorkPriority;
-}
-
-// Locks: Mw (ctor invokes without lock)
void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)
{
bool prioritize = false;
@@ -1043,11 +1010,9 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)
{
if (!haveWork())
{
- calcWorkPriority();
if (!mFetcher->mDebugPause)
{
- U32 work_priority = mWorkPriority | LLWorkerThread::PRIORITY_HIGH;
- addWork(0, work_priority);
+ addWork(0);
}
}
else if (mDesiredDiscard < discard)
@@ -1066,23 +1031,13 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)
if ((prioritize && mState == INIT) || mState == DONE)
{
setState(INIT);
- U32 work_priority = mWorkPriority | LLWorkerThread::PRIORITY_HIGH;
- setPriority(work_priority);
}
}
// Locks: Mw
void LLTextureFetchWorker::setImagePriority(F32 priority)
{
-// llassert_always(priority >= 0 && priority <= LLViewerTexture::maxDecodePriority());
- F32 delta = fabs(priority - mImagePriority);
- if (delta > (mImagePriority * .05f) || mState == DONE)
- {
- mImagePriority = priority;
- calcWorkPriority();
- U32 work_priority = mWorkPriority | (getPriority() & LLWorkerThread::PRIORITY_HIGHBITS);
- setPriority(work_priority);
- }
+ mImagePriority = priority; //should map to max virtual size, abort if zero
}
// Locks: Mw
@@ -1102,6 +1057,11 @@ void LLTextureFetchWorker::resetFormattedData()
mHaveAllData = FALSE;
}
+F32 LLTextureFetchWorker::getImagePriority() const
+{
+ return mImagePriority;
+}
+
// Threads: Tmain
void LLTextureFetchWorker::startWork(S32 param)
{
@@ -1111,7 +1071,7 @@ void LLTextureFetchWorker::startWork(S32 param)
// Threads: Ttf
bool LLTextureFetchWorker::doWork(S32 param)
{
- LL_PROFILE_ZONE_SCOPED;
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
if (gNonInteractive)
{
return true;
@@ -1126,20 +1086,35 @@ bool LLTextureFetchWorker::doWork(S32 param)
{
if (mState < DECODE_IMAGE)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - state < decode");
return true; // abort
}
}
- if(mImagePriority < F_ALMOST_ZERO)
+ if (mImagePriority < F_ALMOST_ZERO)
{
if (mState == INIT || mState == LOAD_FROM_NETWORK)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - priority < 0");
LL_DEBUGS(LOG_TXT) << mID << " abort: mImagePriority < F_ALMOST_ZERO" << LL_ENDL;
return true; // abort
}
}
+ if (mState > CACHE_POST && !mCanUseCapability && mCanUseHTTP)
+ {
+ if (mRegionRetryAttempt > MAX_CAP_MISSING_RETRIES)
+ {
+ mCanUseHTTP = false;
+ }
+ else if (!mRegionRetryTimer.hasExpired())
+ {
+ return false;
+ }
+ // else retry
+ }
if(mState > CACHE_POST && !mCanUseHTTP)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - state > cache_post");
//nowhere to get data, abort.
LL_WARNS(LOG_TXT) << mID << " abort, nowhere to get data" << LL_ENDL;
return true ;
@@ -1161,6 +1136,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == INIT)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - INIT");
mStateTimer.reset();
mFetchTimer.reset();
for(auto i : LOGGED_STATES)
@@ -1202,15 +1178,16 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == LOAD_FROM_TEXTURE_CACHE)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - LOAD_FROM_TEXTURE_CACHE");
if (mCacheReadHandle == LLTextureCache::nullHandle())
{
- U32 cache_priority = mWorkPriority;
S32 offset = mFormattedImage.notNull() ? mFormattedImage->getDataSize() : 0;
S32 size = mDesiredSize - offset;
if (size <= 0)
{
setState(CACHE_POST);
- return false;
+ return doWork(param);
+ // return false;
}
mFileSize = 0;
mLoaded = FALSE;
@@ -1219,35 +1196,28 @@ bool LLTextureFetchWorker::doWork(S32 param)
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
++mCacheReadCount;
std::string filename = mUrl.substr(7, std::string::npos);
CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
mCacheReadTimer.reset();
- mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, cache_priority,
- offset, size, responder);
+ mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, offset, size, responder);
}
else if ((mUrl.empty() || mFTType==FTT_SERVER_BAKE) && mFetcher->canLoadFromCache())
{
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
-
++mCacheReadCount;
CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
mCacheReadTimer.reset();
- mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID, cache_priority,
+ mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID,
offset, size, responder);;
}
else if(!mUrl.empty() && mCanUseHTTP)
{
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
setState(WAIT_HTTP_RESOURCE);
}
else
{
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
setState(LOAD_FROM_NETWORK);
}
}
@@ -1280,6 +1250,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == CACHE_POST)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - CACHE_POST");
mCachedSize = mFormattedImage.notNull() ? mFormattedImage->getDataSize() : 0;
// Successfully loaded
if ((mCachedSize >= mDesiredSize) || mHaveAllData)
@@ -1321,6 +1292,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == LOAD_FROM_NETWORK)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - LOAD_FROM_NETWORK");
// Check for retries to previous server failures.
F32 wait_seconds;
if (mFetchRetryPolicy.shouldRetry(wait_seconds))
@@ -1341,16 +1313,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
// if (mHost.isInvalid()) get_url = false;
if ( use_http && mCanUseHTTP && mUrl.empty())//get http url.
{
- LLViewerRegion* region = NULL;
- if (mHost.isInvalid())
- {
- region = gAgent.getRegion();
- }
- else if (LLWorld::instanceExists())
- {
- region = LLWorld::getInstance()->getRegion(mHost);
- }
-
+ LLViewerRegion* region = getRegion();
if (region)
{
std::string http_url = region->getViewerAssetUrl();
@@ -1358,24 +1321,32 @@ bool LLTextureFetchWorker::doWork(S32 param)
{
if (mFTType != FTT_DEFAULT)
{
- LL_WARNS(LOG_TXT) << "trying to seek a non-default texture on the sim. Bad!" << LL_ENDL;
+ LL_WARNS(LOG_TXT) << "Trying to fetch a texture of non-default type by UUID. This probably won't work!" << LL_ENDL;
}
setUrl(http_url + "/?texture_id=" + mID.asString().c_str());
LL_DEBUGS(LOG_TXT) << "Texture URL: " << mUrl << LL_ENDL;
mWriteToCacheState = CAN_WRITE ; //because this texture has a fixed texture id.
+ mCanUseCapability = true;
+ mRegionRetryAttempt = 0;
+ mLastRegionId = region->getRegionID();
}
else
{
- mCanUseHTTP = false ;
- LL_WARNS(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL;
+ mCanUseCapability = false;
+ mRegionRetryAttempt++;
+ mRegionRetryTimer.setTimerExpirySec(CAP_MISSING_EXPIRATION_DELAY);
+ // ex: waiting for caps
+ LL_INFOS_ONCE(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL;
}
}
else
{
+ mCanUseCapability = false;
+ mRegionRetryAttempt++;
+ mRegionRetryTimer.setTimerExpirySec(CAP_MISSING_EXPIRATION_DELAY);
// This will happen if not logged in or if a region deoes not have HTTP Texture enabled
//LL_WARNS(LOG_TXT) << "Region not found for host: " << mHost << LL_ENDL;
- LL_WARNS(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL;
- mCanUseHTTP = false;
+ LL_INFOS_ONCE(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL;
}
}
else if (mFTType == FTT_SERVER_BAKE)
@@ -1383,10 +1354,9 @@ bool LLTextureFetchWorker::doWork(S32 param)
mWriteToCacheState = CAN_WRITE;
}
- if (mCanUseHTTP && !mUrl.empty())
+ if (mCanUseCapability && mCanUseHTTP && !mUrl.empty())
{
setState(WAIT_HTTP_RESOURCE);
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
if(mWriteToCacheState != NOT_WRITE)
{
mWriteToCacheState = CAN_WRITE ;
@@ -1401,6 +1371,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == WAIT_HTTP_RESOURCE)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_HTTP_RESOURCE");
// NOTE:
// control the number of the http requests issued for:
// 1, not openning too many file descriptors at the same time;
@@ -1408,10 +1379,11 @@ bool LLTextureFetchWorker::doWork(S32 param)
//
// If it looks like we're busy, keep this request here.
// Otherwise, advance into the HTTP states.
- if (mFetcher->getHttpWaitersCount() || ! acquireHttpSemaphore())
+
+ if (!mHttpHasResource && // sometimes we get into this state when we already have an http resource, go ahead and send the request in that case
+ (mFetcher->getHttpWaitersCount() || ! acquireHttpSemaphore()))
{
setState(WAIT_HTTP_RESOURCE2);
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
mFetcher->addHttpWaiter(this->mID);
++mResourceWaitCount;
return false;
@@ -1425,12 +1397,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == WAIT_HTTP_RESOURCE2)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_HTTP_RESOURCE2");
// Just idle it if we make it to the head...
return false;
}
if (mState == SEND_HTTP_REQ)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - SEND_HTTP_REQ");
// Also used in llmeshrepository
static LLCachedControl<bool> disable_range_req(gSavedSettings, "HttpRangeRequestsDisable", false);
@@ -1451,7 +1425,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
{
// We already have all the data, just decode it
mLoadedDiscard = mFormattedImage->getDiscardLevel();
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
if (mLoadedDiscard < 0)
{
LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard
@@ -1459,7 +1432,8 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
setState(DECODE_IMAGE);
releaseHttpSemaphore();
- return false;
+ //return false;
+ return doWork(param);
}
else
{
@@ -1520,7 +1494,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
// by people with questionable ISPs or networking gear that
// doesn't handle these well.
mHttpHandle = mFetcher->mHttpRequest->requestGet(mHttpPolicyClass,
- mWorkPriority,
mUrl,
options,
mFetcher->mHttpHeaders,
@@ -1529,7 +1502,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
else
{
mHttpHandle = mFetcher->mHttpRequest->requestGetByteRange(mHttpPolicyClass,
- mWorkPriority,
mUrl,
mRequestedOffset,
(mRequestedOffset + mRequestedSize) > HTTP_REQUESTS_RANGE_END_MAX
@@ -1554,7 +1526,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
mHttpActive = true;
mFetcher->addToHTTPQueue(mID);
recordTextureStart(true);
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
setState(WAIT_HTTP_REQ);
// fall through
@@ -1562,6 +1533,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == WAIT_HTTP_REQ)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_HTTP_REQ");
// *NOTE: As stated above, all transitions out of this state should
// call releaseHttpSemaphore().
if (mLoaded)
@@ -1586,10 +1558,37 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
return true;
}
+
+ if (mCanUseHTTP && !mUrl.empty() && cur_size <= 0)
+ {
+ LLViewerRegion* region = getRegion();
+ if (!region || mLastRegionId != region->getRegionID())
+ {
+ // cap failure? try on new region.
+ mUrl.clear();
+ ++mRetryAttempt;
+ mLastRegionId.setNull();
+ setState(INIT);
+ return false;
+ }
+ }
}
else if (http_service_unavail == mGetStatus)
{
LL_INFOS_ONCE(LOG_TXT) << "Texture server busy (503): " << mUrl << LL_ENDL;
+ if (mCanUseHTTP && !mUrl.empty() && cur_size <= 0)
+ {
+ LLViewerRegion* region = getRegion();
+ if (!region || mLastRegionId != region->getRegionID())
+ {
+ // try on new region.
+ mUrl.clear();
+ ++mRetryAttempt;
+ mLastRegionId.setNull();
+ setState(INIT);
+ return false;
+ }
+ }
}
else if (http_not_sat == mGetStatus)
{
@@ -1604,7 +1603,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
<< LL_ENDL;
}
- if (mFTType != FTT_SERVER_BAKE)
+ if (mFTType != FTT_SERVER_BAKE && mFTType != FTT_MAP_TILE)
{
mUrl.clear();
}
@@ -1612,7 +1611,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
{
// Use available data
mLoadedDiscard = mFormattedImage->getDiscardLevel();
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
if (mLoadedDiscard < 0)
{
LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard
@@ -1620,7 +1618,8 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
setState(DECODE_IMAGE);
releaseHttpSemaphore();
- return false;
+ //return false;
+ return doWork(param);
}
// Fail harder
@@ -1737,9 +1736,9 @@ bool LLTextureFetchWorker::doWork(S32 param)
{
mWriteToCacheState = SHOULD_WRITE ;
}
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
releaseHttpSemaphore();
- return false;
+ //return false;
+ return doWork(param);
}
else
{
@@ -1749,17 +1748,16 @@ bool LLTextureFetchWorker::doWork(S32 param)
// an enormous amount of time to load textures. We'll revisit the
// various possible timeout components (total request time, connection
// time, I/O time, with and without retries, etc.) in the future.
-
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
+
return false;
}
}
if (mState == DECODE_IMAGE)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - DECODE_IMAGE");
static LLCachedControl<bool> textures_decode_disabled(gSavedSettings, "TextureDecodeDisabled", false);
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
if (textures_decode_disabled)
{
// for debug use, don't decode
@@ -1798,25 +1796,20 @@ bool LLTextureFetchWorker::doWork(S32 param)
mAuxImage = NULL;
llassert_always(mFormattedImage.notNull());
S32 discard = mHaveAllData ? 0 : mLoadedDiscard;
- U32 image_priority = LLWorkerThread::PRIORITY_NORMAL | mWorkPriority;
mDecoded = FALSE;
setState(DECODE_IMAGE_UPDATE);
LL_DEBUGS(LOG_TXT) << mID << ": Decoding. Bytes: " << mFormattedImage->getDataSize() << " Discard: " << discard
<< " All Data: " << mHaveAllData << LL_ENDL;
- mDecodeHandle = mFetcher->mImageDecodeThread->decodeImage(mFormattedImage, image_priority, discard, mNeedsAux,
+ mDecodeHandle = LLAppViewer::getImageDecodeThread()->decodeImage(mFormattedImage, discard, mNeedsAux,
new DecodeResponder(mFetcher, mID, this));
// fall though
}
if (mState == DECODE_IMAGE_UPDATE)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - DECODE_IMAGE_UPDATE");
if (mDecoded)
{
- if(mFetcher->getFetchDebugger() && !mInLocalCache)
- {
- mFetcher->getFetchDebugger()->addHistoryEntry(this);
- }
-
mDecodeTime = mDecodeTimer.getElapsedTimeF32();
if (mDecodedDiscard < 0)
@@ -1828,9 +1821,9 @@ bool LLTextureFetchWorker::doWork(S32 param)
llassert_always(mDecodeHandle == 0);
mFormattedImage = NULL;
++mRetryAttempt;
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
setState(INIT);
- return false;
+ //return false;
+ return doWork(param);
}
else
{
@@ -1843,7 +1836,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
llassert_always(mRawImage.notNull());
LL_DEBUGS(LOG_TXT) << mID << ": Decoded. Discard: " << mDecodedDiscard
<< " Raw Image: " << llformat("%dx%d",mRawImage->getWidth(),mRawImage->getHeight()) << LL_ENDL;
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
setState(WRITE_TO_CACHE);
}
// fall through
@@ -1856,12 +1848,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == WRITE_TO_CACHE)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WRITE_TO_CACHE");
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
setState(DONE);
- return false;
+ //return false;
+ return doWork(param);
}
S32 datasize = mFormattedImage->getDataSize();
if(mFileSize < datasize)//This could happen when http fetching and sim fetching mixed.
@@ -1876,8 +1870,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
}
llassert_always(datasize);
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
- U32 cache_priority = mWorkPriority;
mWritten = FALSE;
setState(WAIT_ON_WRITE);
++mCacheWriteCount;
@@ -1888,7 +1880,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
// So make sure users of getRequestFinished() does not attempt to modify image while
// fetcher is working
mCacheWriteTimer.reset();
- mCacheWriteHandle = mFetcher->mTextureCache->writeToCache(mID, cache_priority,
+ mCacheWriteHandle = mFetcher->mTextureCache->writeToCache(mID,
mFormattedImage->getData(), datasize,
mFileSize, mRawImage, mDecodedDiscard, responder);
// fall through
@@ -1896,6 +1888,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == WAIT_ON_WRITE)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_ON_WRITE");
if (writeToCacheComplete())
{
mCacheWriteTime = mCacheWriteTimer.getElapsedTimeF32();
@@ -1917,6 +1910,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == DONE)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - DONE");
if (mDecodedDiscard >= 0 && mDesiredDiscard < mDecodedDiscard)
{
// More data was requested, return to INIT
@@ -1924,12 +1918,11 @@ bool LLTextureFetchWorker::doWork(S32 param)
LL_DEBUGS(LOG_TXT) << mID << " more data requested, returning to INIT: "
<< " mDecodedDiscard " << mDecodedDiscard << ">= 0 && mDesiredDiscard " << mDesiredDiscard
<< "<" << " mDecodedDiscard " << mDecodedDiscard << LL_ENDL;
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
- return false;
+ // return false;
+ return doWork(param);
}
else
{
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
mFetchTime = mFetchTimer.getElapsedTimeF32();
return true;
}
@@ -1942,6 +1935,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
// virtual
void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)
{
+ LL_PROFILE_ZONE_SCOPED;
static LLCachedControl<bool> log_to_viewer_log(gSavedSettings, "LogTextureDownloadsToViewerLog", false);
static LLCachedControl<bool> log_to_sim(gSavedSettings, "LogTextureDownloadsToSimulator", false);
static LLCachedControl<bool> log_texture_traffic(gSavedSettings, "LogTextureNetworkTraffic", false) ;
@@ -2051,9 +2045,10 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe
// Threads: Tmain
void LLTextureFetchWorker::endWork(S32 param, bool aborted)
{
+ LL_PROFILE_ZONE_SCOPED;
if (mDecodeHandle != 0)
{
- mFetcher->mImageDecodeThread->abortRequest(mDecodeHandle, false);
+ // LL::ThreadPool has no operation to cancel a particular work item
mDecodeHandle = 0;
}
mFormattedImage = NULL;
@@ -2066,6 +2061,7 @@ void LLTextureFetchWorker::endWork(S32 param, bool aborted)
// virtual
void LLTextureFetchWorker::finishWork(S32 param, bool completed)
{
+ LL_PROFILE_ZONE_SCOPED;
// The following are required in case the work was aborted
if (mCacheReadHandle != LLTextureCache::nullHandle())
{
@@ -2262,7 +2258,6 @@ S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response,
}
mLoaded = TRUE;
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
return data_size ;
}
@@ -2273,6 +2268,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response,
void LLTextureFetchWorker::callbackCacheRead(bool success, LLImageFormatted* image,
S32 imagesize, BOOL islocal)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
LLMutexLock lock(&mWorkMutex); // +Mw
if (mState != LOAD_FROM_TEXTURE_CACHE)
{
@@ -2292,7 +2288,6 @@ void LLTextureFetchWorker::callbackCacheRead(bool success, LLImageFormatted* ima
}
}
mLoaded = TRUE;
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
} // -Mw
// Threads: Ttc
@@ -2305,7 +2300,6 @@ void LLTextureFetchWorker::callbackCacheWrite(bool success)
return;
}
mWritten = TRUE;
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
} // -Mw
//////////////////////////////////////////////////////////////////////////////
@@ -2344,7 +2338,6 @@ void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImag
}
mDecoded = TRUE;
// LL_INFOS(LOG_TXT) << mID << " : DECODE COMPLETE " << LL_ENDL;
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
} // -Mw
//////////////////////////////////////////////////////////////////////////////
@@ -2407,7 +2400,17 @@ void LLTextureFetchWorker::recordTextureDone(bool is_http, F64 byte_count)
//////////////////////////////////////////////////////////////////////////////
// public
-LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode)
+std::string LLTextureFetch::getStateString(S32 state)
+{
+ if (state < 0 || state > sizeof(e_state_name) / sizeof(char*))
+ {
+ return llformat("%d", state);
+ }
+
+ return e_state_name[state];
+}
+
+LLTextureFetch::LLTextureFetch(LLTextureCache* cache, bool threaded, bool qa_mode)
: LLWorkerThread("TextureFetch", threaded, true),
mDebugCount(0),
mDebugPause(FALSE),
@@ -2416,7 +2419,6 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
mQueueMutex(),
mNetworkQueueMutex(),
mTextureCache(cache),
- mImageDecodeThread(imagedecodethread),
mTextureBandwidth(0),
mHTTPTextureBits(0),
mTotalHTTPRequests(0),
@@ -2431,10 +2433,8 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
mTotalCacheReadCount(0U),
mTotalCacheWriteCount(0U),
mTotalResourceWaitCount(0U),
- mFetchDebugger(NULL),
mFetchSource(LLTextureFetch::FROM_ALL),
mOriginFetchSource(LLTextureFetch::FROM_ALL),
- mFetcherLocked(FALSE),
mTextureInfoMainThread(false)
{
mMaxBandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS");
@@ -2455,21 +2455,6 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
mHttpLowWater = HTTP_NONPIPE_REQUESTS_LOW_WATER;
mHttpSemaphore = 0;
- // Conditionally construct debugger object after 'this' is
- // fully initialized.
- LLTextureFetchDebugger::sDebuggerEnabled = gSavedSettings.getBOOL("TextureFetchDebuggerEnabled");
- if(LLTextureFetchDebugger::isEnabled())
- {
- mFetchDebugger = new LLTextureFetchDebugger(this, cache, imagedecodethread) ;
- mFetchSource = (e_tex_source)gSavedSettings.getS32("TextureFetchSource");
- if(mFetchSource < 0 && mFetchSource >= INVALID_SOURCE)
- {
- mFetchSource = LLTextureFetch::FROM_ALL;
- gSavedSettings.setS32("TextureFetchSource", 0);
- }
- mOriginFetchSource = mFetchSource;
- }
-
// If that test log has ben requested but not yet created, create it
if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName))
{
@@ -2498,22 +2483,16 @@ LLTextureFetch::~LLTextureFetch()
delete mHttpRequest;
mHttpRequest = NULL;
- delete mFetchDebugger;
- mFetchDebugger = NULL;
-
// ~LLQueuedThread() called here
}
-bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
+S32 LLTextureFetch::createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http)
{
- if(mFetcherLocked)
- {
- return false;
- }
+ LL_PROFILE_ZONE_SCOPED;
if (mDebugPause)
{
- return false;
+ return -1;
}
if (f_type == FTT_SERVER_BAKE)
@@ -2529,7 +2508,7 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
<< host << " != " << worker->mHost << LL_ENDL;
removeRequest(worker, true);
worker = NULL;
- return false;
+ return -1;
}
}
@@ -2582,9 +2561,14 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
{
if (worker->wasAborted())
{
- return false; // need to wait for previous aborted request to complete
+ return -1; // need to wait for previous aborted request to complete
}
worker->lockWorkMutex(); // +Mw
+ if (worker->mState == LLTextureFetchWorker::DONE && worker->mDesiredSize == llmax(desired_size, TEXTURE_CACHE_ENTRY_SIZE) && worker->mDesiredDiscard == desired_discard) {
+ worker->unlockWorkMutex(); // -Mw
+
+ return -1; // similar request has failed or is in a transitional state
+ }
worker->mActiveCount++;
worker->mNeedsAux = needs_aux;
worker->setImagePriority(priority);
@@ -2598,7 +2582,7 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
worker->setState(LLTextureFetchWorker::INIT);
worker->unlockWorkMutex(); // -Mw
- worker->addWork(0, LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
+ worker->addWork(0);
}
else
{
@@ -2618,18 +2602,17 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
worker->setCanUseHTTP(can_use_http) ;
worker->unlockWorkMutex(); // -Mw
}
-
+
LL_DEBUGS(LOG_TXT) << "REQUESTED: " << id << " f_type " << fttype_to_string(f_type)
<< " Discard: " << desired_discard << " size " << desired_size << LL_ENDL;
- return true;
+ return desired_discard;
}
-
-
// Threads: T*
//
// protected
void LLTextureFetch::addToHTTPQueue(const LLUUID& id)
{
+ LL_PROFILE_ZONE_SCOPED;
LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq
mHTTPTextureQueue.insert(id);
mTotalHTTPRequests++;
@@ -2638,6 +2621,7 @@ void LLTextureFetch::addToHTTPQueue(const LLUUID& id)
// Threads: T*
void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id, S32Bytes received_size)
{
+ LL_PROFILE_ZONE_SCOPED;
LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq
mHTTPTextureQueue.erase(id);
mHTTPTextureBits += received_size; // Approximate - does not include header bits
@@ -2650,6 +2634,7 @@ void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id, S32Bytes received_siz
// Threads: T*
void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel)
{
+ LL_PROFILE_ZONE_SCOPED;
lockQueue(); // +Mfq
LLTextureFetchWorker* worker = getWorkerAfterLock(id);
if (worker)
@@ -2675,6 +2660,7 @@ void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel)
// Threads: T*
void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel)
{
+ LL_PROFILE_ZONE_SCOPED;
if(!worker)
{
return;
@@ -2743,6 +2729,7 @@ U32 LLTextureFetch::getTotalNumHTTPRequests()
// Locks: Mfq
LLTextureFetchWorker* LLTextureFetch::getWorkerAfterLock(const LLUUID& id)
{
+ LL_PROFILE_ZONE_SCOPED;
LLTextureFetchWorker* res = NULL;
map_t::iterator iter = mRequestMap.find(id);
if (iter != mRequestMap.end())
@@ -2766,6 +2753,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,
LLPointer<LLImageRaw>& raw, LLPointer<LLImageRaw>& aux,
LLCore::HttpStatus& last_http_get_status)
{
+ LL_PROFILE_ZONE_SCOPED;
bool res = false;
LLTextureFetchWorker* worker = getWorker(id);
if (worker)
@@ -2780,7 +2768,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,
if (!mDebugPause)
{
// LL_WARNS(LOG_TXT) << "Adding work for inactive worker: " << id << LL_ENDL;
- worker->addWork(0, LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
+ worker->addWork(0);
}
}
else if (worker->checkWork())
@@ -2856,16 +2844,19 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,
// Threads: T*
bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority)
{
- bool res = false;
- LLTextureFetchWorker* worker = getWorker(id);
- if (worker)
- {
- worker->lockWorkMutex(); // +Mw
- worker->setImagePriority(priority);
- worker->unlockWorkMutex(); // -Mw
- res = true;
- }
- return res;
+ LL_PROFILE_ZONE_SCOPED;
+ mRequestQueue.tryPost([=]()
+ {
+ LLTextureFetchWorker* worker = getWorker(id);
+ if (worker)
+ {
+ worker->lockWorkMutex(); // +Mw
+ worker->setImagePriority(priority);
+ worker->unlockWorkMutex(); // -Mw
+ }
+ });
+
+ return true;
}
// Replicates and expands upon the base class's
@@ -2882,16 +2873,17 @@ bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority)
//virtual
size_t LLTextureFetch::getPending()
{
- size_t res;
- lockData(); // +Ct
+ LL_PROFILE_ZONE_SCOPED;
+ size_t res;
+ lockData(); // +Ct
{
LLMutexLock lock(&mQueueMutex); // +Mfq
res = mRequestQueue.size();
res += mCommands.size();
} // -Mfq
- unlockData(); // -Ct
- return res;
+ unlockData(); // -Ct
+ return res;
}
// Locks: Ct
@@ -2915,7 +2907,7 @@ bool LLTextureFetch::runCondition()
} // -Mfq
return ! (have_no_commands
- && (mRequestQueue.empty() && mIdleThread)); // From base class
+ && (mRequestQueue.size() == 0 && mIdleThread)); // From base class
}
//////////////////////////////////////////////////////////////////////////////
@@ -2923,6 +2915,7 @@ bool LLTextureFetch::runCondition()
// Threads: Ttf
void LLTextureFetch::commonUpdate()
{
+ LL_PROFILE_ZONE_SCOPED;
// Update low/high water levels based on pipelining. We pick
// up setting eventually, so the semaphore/request level can
// fall outside the [0..HIGH_WATER] range. Expect that.
@@ -2959,6 +2952,7 @@ void LLTextureFetch::commonUpdate()
//virtual
size_t LLTextureFetch::update(F32 max_time_ms)
{
+ LL_PROFILE_ZONE_SCOPED;
static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS", 3000.0);
{
@@ -2978,11 +2972,6 @@ size_t LLTextureFetch::update(F32 max_time_ms)
commonUpdate();
}
- if (mFetchDebugger)
- {
- mFetchDebugger->tryToStopDebug(); //check if need to stop debugger.
- }
-
return res;
}
@@ -2998,18 +2987,6 @@ void LLTextureFetch::shutDownTextureCacheThread()
}
}
-// called in the MAIN thread after the ImageDecodeThread shuts down.
-//
-// Threads: Tmain
-void LLTextureFetch::shutDownImageDecodeThread()
-{
- if(mImageDecodeThread)
- {
- llassert_always(mImageDecodeThread->isQuitting() || mImageDecodeThread->isStopped()) ;
- mImageDecodeThread = NULL ;
- }
-}
-
// Threads: Ttf
void LLTextureFetch::startThread()
{
@@ -3031,6 +3008,7 @@ void LLTextureFetch::endThread()
// Threads: Ttf
void LLTextureFetch::threadedUpdate()
{
+ LL_PROFILE_ZONE_SCOPED;
llassert_always(mHttpRequest);
#if 0
@@ -3067,6 +3045,7 @@ void LLTextureFetch::threadedUpdate()
// Locks: Mw
bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)
{
+ LL_PROFILE_ZONE_SCOPED;
mRequestedDeltaTimer.reset();
if (index >= mTotalPackets)
{
@@ -3099,6 +3078,7 @@ bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)
void LLTextureFetchWorker::setState(e_state new_state)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
if (mFTType == FTT_SERVER_BAKE)
{
// NOTE: turning on these log statements is a reliable way to get
@@ -3120,11 +3100,25 @@ void LLTextureFetchWorker::setState(e_state new_state)
mSkippedStatesTime += d_time;
}
}
-
+
mStateTimer.reset();
mState = new_state;
}
+LLViewerRegion* LLTextureFetchWorker::getRegion()
+{
+ LLViewerRegion* region = NULL;
+ if (mHost.isInvalid())
+ {
+ region = gAgent.getRegion();
+ }
+ else if (LLWorld::instanceExists())
+ {
+ region = LLWorld::getInstance()->getRegion(mHost);
+ }
+ return region;
+}
+
//////////////////////////////////////////////////////////////////////////////
// Threads: T*
@@ -3143,10 +3137,23 @@ BOOL LLTextureFetch::isFromLocalCache(const LLUUID& id)
return from_cache ;
}
+S32 LLTextureFetch::getFetchState(const LLUUID& id)
+{
+ S32 state = LLTextureFetchWorker::INVALID;
+ LLTextureFetchWorker* worker = getWorker(id);
+ if (worker && worker->haveWork())
+ {
+ state = worker->mState;
+ }
+
+ return state;
+}
+
// Threads: T*
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, bool& can_use_http)
{
+ LL_PROFILE_ZONE_SCOPED;
S32 state = LLTextureFetchWorker::INVALID;
F32 data_progress = 0.0f;
F32 requested_priority = 0.0f;
@@ -3176,7 +3183,7 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r
{
requested_priority = worker->mImagePriority;
}
- fetch_priority = worker->getPriority();
+ fetch_priority = worker->getImagePriority();
can_use_http = worker->getCanUseHTTP() ;
worker->unlockWorkMutex(); // -Mw
}
@@ -3190,19 +3197,6 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r
void LLTextureFetch::dump()
{
- LL_INFOS(LOG_TXT) << "LLTextureFetch REQUESTS:" << LL_ENDL;
- for (request_queue_t::iterator iter = mRequestQueue.begin();
- iter != mRequestQueue.end(); ++iter)
- {
- LLQueuedThread::QueuedRequest* qreq = *iter;
- LLWorkerThread::WorkRequest* wreq = (LLWorkerThread::WorkRequest*)qreq;
- LLTextureFetchWorker* worker = (LLTextureFetchWorker*)wreq->getWorkerClass();
- LL_INFOS(LOG_TXT) << " ID: " << worker->mID
- << " PRI: " << llformat("0x%08x",wreq->getPriority())
- << " STATE: " << sStateDescs[worker->mState]
- << LL_ENDL;
- }
-
LL_INFOS(LOG_TXT) << "LLTextureFetch ACTIVE_HTTP:" << LL_ENDL;
for (queue_t::const_iterator iter(mHTTPTextureQueue.begin());
mHTTPTextureQueue.end() != iter;
@@ -3269,6 +3263,7 @@ bool LLTextureFetch::isHttpWaiter(const LLUUID & tid)
// Locks: -Mw (must not hold any worker when called)
void LLTextureFetch::releaseHttpWaiters()
{
+ LL_PROFILE_ZONE_SCOPED;
// Use mHttpSemaphore rather than mHTTPTextureQueue.size()
// to avoid a lock.
if (mHttpSemaphore >= mHttpLowWater)
@@ -3365,7 +3360,6 @@ void LLTextureFetch::releaseHttpWaiters()
}
worker->setState(LLTextureFetchWorker::SEND_HTTP_REQ);
- worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
worker->unlockWorkMutex(); // -Mw
removeHttpWaiter(worker->mID);
@@ -3455,6 +3449,7 @@ void LLTextureFetch::commandDataBreak()
// Threads: T*
void LLTextureFetch::cmdEnqueue(TFRequest * req)
{
+ LL_PROFILE_ZONE_SCOPED;
lockQueue(); // +Mfq
mCommands.push_back(req);
unlockQueue(); // -Mfq
@@ -3465,6 +3460,7 @@ void LLTextureFetch::cmdEnqueue(TFRequest * req)
// Threads: T*
LLTextureFetch::TFRequest * LLTextureFetch::cmdDequeue()
{
+ LL_PROFILE_ZONE_SCOPED;
TFRequest * ret = 0;
lockQueue(); // +Mfq
@@ -3481,6 +3477,7 @@ LLTextureFetch::TFRequest * LLTextureFetch::cmdDequeue()
// Threads: Ttf
void LLTextureFetch::cmdDoWork()
{
+ LL_PROFILE_ZONE_SCOPED;
if (mDebugPause)
{
return; // debug: don't do any work
@@ -3571,7 +3568,7 @@ TFReqSendMetrics::~TFReqSendMetrics()
bool
TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
{
- static const U32 report_priority(1);
+ LL_PROFILE_ZONE_SCOPED;
//if (! gViewerAssetStatsThread1)
// return true;
@@ -3614,7 +3611,6 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
// Don't care about handle, this is a fire-and-forget operation.
LLCoreHttpUtil::requestPostWithLLSD(&fetcher->getHttpRequest(),
fetcher->getMetricsPolicyClass(),
- report_priority,
mCapsURL,
mStatsSD,
LLCore::HttpOptions::ptr_t(),
@@ -3676,971 +3672,6 @@ truncate_viewer_metrics(int max_regions, LLSD & metrics)
} // end of anonymous namespace
-
-///////////////////////////////////////////////////////////////////////////////////////////
-//Start LLTextureFetchDebugger
-///////////////////////////////////////////////////////////////////////////////////////////
-//---------------------
-class LLDebuggerCacheReadResponder : public LLTextureCache::ReadResponder
-{
-public:
- LLDebuggerCacheReadResponder(LLTextureFetchDebugger* debugger, S32 id, LLImageFormatted* image)
- : mDebugger(debugger), mID(id)
- {
- setImage(image);
- }
- virtual void completed(bool success)
- {
- mDebugger->callbackCacheRead(mID, success, mFormattedImage, mImageSize, mImageLocal);
- }
-private:
- LLTextureFetchDebugger* mDebugger;
- S32 mID;
-};
-
-class LLDebuggerCacheWriteResponder : public LLTextureCache::WriteResponder
-{
-public:
- LLDebuggerCacheWriteResponder(LLTextureFetchDebugger* debugger, S32 id)
- : mDebugger(debugger), mID(id)
- {
- }
- virtual void completed(bool success)
- {
- mDebugger->callbackCacheWrite(mID, success);
- }
-private:
- LLTextureFetchDebugger* mDebugger;
- S32 mID;
-};
-
-class LLDebuggerDecodeResponder : public LLImageDecodeThread::Responder
-{
-public:
- LLDebuggerDecodeResponder(LLTextureFetchDebugger* debugger, S32 id)
- : mDebugger(debugger), mID(id)
- {
- }
- virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux)
- {
- mDebugger->callbackDecoded(mID, success, raw, aux);
- }
-private:
- LLTextureFetchDebugger* mDebugger;
- S32 mID;
-};
-
-
-LLTextureFetchDebugger::LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) :
- LLCore::HttpHandler(),
- mFetcher(fetcher),
- mTextureCache(cache),
- mImageDecodeThread(imagedecodethread),
- mHttpHeaders(),
- mHttpPolicyClass(fetcher->getPolicyClass()),
- mNbCurlCompleted(0),
- mTempIndex(0),
- mHistoryListIndex(0)
-{
- init();
-}
-
-LLTextureFetchDebugger::~LLTextureFetchDebugger()
-{
- mFetchingHistory.clear();
- mStopDebug = TRUE;
- tryToStopDebug();
-}
-
-void LLTextureFetchDebugger::init()
-{
- setDebuggerState(IDLE);
-
- mCacheReadTime = -1.f;
- mCacheWriteTime = -1.f;
- mDecodingTime = -1.f;
- mHTTPTime = -1.f;
- mGLCreationTime = -1.f;
-
- mTotalFetchingTime = 0.f;
- mRefetchVisCacheTime = -1.f;
- mRefetchVisHTTPTime = -1.f;
- mRefetchAllCacheTime = -1.f;
- mRefetchAllHTTPTime = -1.f;
-
- mNumFetchedTextures = 0;
- mNumCacheHits = 0;
- mNumVisibleFetchedTextures = 0;
- mNumVisibleFetchingRequests = 0;
- mFetchedData = 0;
- mDecodedData = 0;
- mVisibleFetchedData = 0;
- mVisibleDecodedData = 0;
- mRenderedData = 0;
- mRenderedDecodedData = 0;
- mFetchedPixels = 0;
- mRenderedPixels = 0;
- mRefetchedVisData = 0;
- mRefetchedVisPixels = 0;
- mRefetchedAllData = 0;
- mRefetchedAllPixels = 0;
-
- mFreezeHistory = FALSE;
- mStopDebug = FALSE;
- mClearHistory = FALSE;
- mRefetchNonVis = FALSE;
-
- mNbCurlRequests = 0;
-
- if (! mHttpHeaders)
- {
- mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders);
- mHttpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_IMAGE_X_J2C);
- }
-}
-
-void LLTextureFetchDebugger::startWork(e_debug_state state)
-{
- switch(state)
- {
- case IDLE:
- break;
- case START_DEBUG:
- startDebug();
- break;
- case READ_CACHE:
- debugCacheRead();
- break;
- case WRITE_CACHE:
- debugCacheWrite();
- break;
- case DECODING:
- debugDecoder();
- break;
- case HTTP_FETCHING:
- debugHTTP();
- break;
- case GL_TEX:
- debugGLTextureCreation();
- break;
- case REFETCH_VIS_CACHE:
- debugRefetchVisibleFromCache();
- break;
- case REFETCH_VIS_HTTP:
- debugRefetchVisibleFromHTTP();
- break;
- case REFETCH_ALL_CACHE:
- debugRefetchAllFromCache();
- break;
- case REFETCH_ALL_HTTP:
- debugRefetchAllFromHTTP();
- break;
- default:
- break;
- }
- return;
-}
-
-void LLTextureFetchDebugger::startDebug()
-{
- //lock the fetcher
- mFetcher->lockFetcher(true);
- mFreezeHistory = TRUE;
- mFetcher->resetLoadSource();
-
- //clear the current fetching queue
- gTextureList.clearFetchingRequests();
-
- setDebuggerState(START_DEBUG);
-}
-
-bool LLTextureFetchDebugger::processStartDebug(F32 max_time)
-{
- mTimer.reset();
-
- //wait for all works to be done
- while(1)
- {
- S32 pending = 0;
- pending += LLAppViewer::getTextureCache()->update(1);
- pending += LLAppViewer::getImageDecodeThread()->update(1);
- // pending += LLAppViewer::getTextureFetch()->update(1); // This causes infinite recursion in some cases
- pending += mNbCurlRequests;
- if(!pending)
- {
- break;
- }
-
- if(mTimer.getElapsedTimeF32() > max_time)
- {
- return false;
- }
- }
-
- //collect statistics
- mTotalFetchingTime = gTextureTimer.getElapsedTimeF32() - mTotalFetchingTime;
-
- std::set<LLUUID> fetched_textures;
- S32 size = mFetchingHistory.size();
- for(S32 i = 0 ; i < size; i++)
- {
- bool in_list = true;
- if(fetched_textures.find(mFetchingHistory[i].mID) == fetched_textures.end())
- {
- fetched_textures.insert(mFetchingHistory[i].mID);
- in_list = false;
- }
-
- std::vector<LLViewerFetchedTexture*> textures;
- LLViewerTextureManager::findFetchedTextures(mFetchingHistory[i].mID, textures);
- std::vector<LLViewerFetchedTexture*>::iterator iter = textures.begin();
- while (iter != textures.end())
- {
- LLViewerFetchedTexture* tex = *iter++;
- // fetched data will be counted for both ui and regular elements
- if (tex && tex->isJustBound()) //visible
- {
- if (!in_list)
- {
- mNumVisibleFetchedTextures++;
- }
- mNumVisibleFetchingRequests++;
-
- mVisibleFetchedData += mFetchingHistory[i].mFetchedSize;
- mVisibleDecodedData += mFetchingHistory[i].mDecodedSize;
-
- if (tex->getDiscardLevel() >= mFetchingHistory[i].mDecodedLevel)
- {
- mRenderedData += mFetchingHistory[i].mFetchedSize;
- mRenderedDecodedData += mFetchingHistory[i].mDecodedSize;
- mRenderedPixels += tex->getWidth() * tex->getHeight();
- }
- }
- }
- }
-
- mNumFetchedTextures = fetched_textures.size();
-
- return true;
-}
-
-void LLTextureFetchDebugger::tryToStopDebug()
-{
- if(!mStopDebug)
- {
- return;
- }
-
- //clear the current debug work
- S32 size = mFetchingHistory.size();
- switch(mDebuggerState)
- {
- case READ_CACHE:
- for(S32 i = 0 ; i < size; i++)
- {
- if (mFetchingHistory[i]. mCacheHandle != LLTextureCache::nullHandle())
- {
- mTextureCache->readComplete(mFetchingHistory[i].mCacheHandle, true);
- }
- }
- break;
- case WRITE_CACHE:
- for(S32 i = 0 ; i < size; i++)
- {
- if (mFetchingHistory[i].mCacheHandle != LLTextureCache::nullHandle())
- {
- mTextureCache->writeComplete(mFetchingHistory[i].mCacheHandle, true);
- }
- }
- break;
- case DECODING:
- break;
- case HTTP_FETCHING:
- break;
- case GL_TEX:
- break;
- case REFETCH_VIS_CACHE:
- break;
- case REFETCH_VIS_HTTP:
- break;
- case REFETCH_ALL_CACHE:
- mRefetchList.clear();
- break;
- case REFETCH_ALL_HTTP:
- mRefetchList.clear();
- break;
- default:
- break;
- }
-
- if(update(0.005f))
- {
- //unlock the fetcher
- mFetcher->lockFetcher(false);
- mFetcher->resetLoadSource();
- mFreezeHistory = FALSE;
- mStopDebug = FALSE;
-
- if(mClearHistory)
- {
- mFetchingHistory.clear();
- mHandleToFetchIndex.clear();
- init();
- mTotalFetchingTime = gTextureTimer.getElapsedTimeF32(); //reset
- }
- }
-}
-
-//called in the main thread and when the fetching queue is empty
-void LLTextureFetchDebugger::clearHistory()
-{
- mClearHistory = TRUE;
-}
-
-void LLTextureFetchDebugger::addHistoryEntry(LLTextureFetchWorker* worker)
-{
- if(worker->mRawImage.isNull() || worker->mFormattedImage.isNull())
- {
- return;
- }
-
- if(mFreezeHistory)
- {
- if(mDebuggerState == REFETCH_VIS_CACHE || mDebuggerState == REFETCH_VIS_HTTP)
- {
- mRefetchedVisPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight();
- mRefetchedVisData += worker->mFormattedImage->getDataSize();
- }
- else
- {
- mRefetchedAllPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight();
- mRefetchedAllData += worker->mFormattedImage->getDataSize();
-
- // refetch list only requests/creates normal images, so requesting ui='false'
- LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(worker->mID, TEX_LIST_STANDARD);
- if(tex && mRefetchList[tex].begin() != mRefetchList[tex].end())
- {
- if(worker->mDecodedDiscard == mFetchingHistory[mRefetchList[tex][0]].mDecodedLevel)
- {
- mRefetchList[tex].erase(mRefetchList[tex].begin());
- }
- }
- }
- return;
- }
-
- if(worker->mInCache)
- {
- mNumCacheHits++;
- }
- mFetchedData += worker->mFormattedImage->getDataSize();
- mDecodedData += worker->mRawImage->getDataSize();
- mFetchedPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight();
-
- mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mDecodedDiscard,
- worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize()));
-}
-
-void LLTextureFetchDebugger::lockCache()
-{
-}
-
-void LLTextureFetchDebugger::unlockCache()
-{
-}
-
-void LLTextureFetchDebugger::debugCacheRead()
-{
- lockCache();
- llassert_always(mDebuggerState == IDLE);
- mTimer.reset();
- setDebuggerState(READ_CACHE);
- mCacheReadTime = -1.f;
-
- S32 size = mFetchingHistory.size();
- for(S32 i = 0 ; i < size ; i++)
- {
- mFetchingHistory[i].mFormattedImage = NULL;
- mFetchingHistory[i].mCacheHandle = mTextureCache->readFromCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL, 0, mFetchingHistory[i].mFetchedSize,
- new LLDebuggerCacheReadResponder(this, i, mFetchingHistory[i].mFormattedImage));
- }
-}
-
-void LLTextureFetchDebugger::clearCache()
-{
- S32 size = mFetchingHistory.size();
- {
- std::set<LLUUID> deleted_list;
- for(S32 i = 0 ; i < size ; i++)
- {
- if(deleted_list.find(mFetchingHistory[i].mID) == deleted_list.end())
- {
- deleted_list.insert(mFetchingHistory[i].mID);
- mTextureCache->removeFromCache(mFetchingHistory[i].mID);
- }
- }
- }
-}
-
-void LLTextureFetchDebugger::debugCacheWrite()
-{
- //remove from cache
- clearCache();
-
- lockCache();
- llassert_always(mDebuggerState == IDLE);
- mTimer.reset();
- setDebuggerState(WRITE_CACHE);
- mCacheWriteTime = -1.f;
-
- S32 size = mFetchingHistory.size();
- for(S32 i = 0 ; i < size ; i++)
- {
- if(mFetchingHistory[i].mFormattedImage.notNull())
- {
- mFetchingHistory[i].mCacheHandle = mTextureCache->writeToCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL,
- mFetchingHistory[i].mFormattedImage->getData(), mFetchingHistory[i].mFetchedSize,
- mFetchingHistory[i].mDecodedLevel == 0 ? mFetchingHistory[i].mFetchedSize : mFetchingHistory[i].mFetchedSize + 1,
- NULL, 0, new LLDebuggerCacheWriteResponder(this, i));
- }
- }
-}
-
-void LLTextureFetchDebugger::lockDecoder()
-{
-}
-
-void LLTextureFetchDebugger::unlockDecoder()
-{
-}
-
-void LLTextureFetchDebugger::debugDecoder()
-{
- lockDecoder();
- llassert_always(mDebuggerState == IDLE);
- mTimer.reset();
- setDebuggerState(DECODING);
- mDecodingTime = -1.f;
-
- S32 size = mFetchingHistory.size();
- for(S32 i = 0 ; i < size ; i++)
- {
- if(mFetchingHistory[i].mFormattedImage.isNull())
- {
- continue;
- }
-
- mImageDecodeThread->decodeImage(mFetchingHistory[i].mFormattedImage, LLWorkerThread::PRIORITY_NORMAL,
- mFetchingHistory[i].mDecodedLevel, mFetchingHistory[i].mNeedsAux,
- new LLDebuggerDecodeResponder(this, i));
- }
-}
-
-void LLTextureFetchDebugger::debugHTTP()
-{
- llassert_always(mDebuggerState == IDLE);
-
- LLViewerRegion* region = gAgent.getRegion();
- if (!region)
- {
- LL_INFOS(LOG_TXT) << "Fetch Debugger : Current region undefined. Cannot fetch textures through HTTP." << LL_ENDL;
- return;
- }
-
- mHTTPUrl = region->getViewerAssetUrl();
- if (mHTTPUrl.empty())
- {
- LL_INFOS(LOG_TXT) << "Fetch Debugger : Current region URL undefined. Cannot fetch textures through HTTP." << LL_ENDL;
- return;
- }
-
- mTimer.reset();
- setDebuggerState(HTTP_FETCHING);
- mHTTPTime = -1.f;
-
- S32 size = mFetchingHistory.size();
- for (S32 i = 0 ; i < size ; i++)
- {
- mFetchingHistory[i].mCurlState = FetchEntry::CURL_NOT_DONE;
- mFetchingHistory[i].mCurlReceivedSize = 0;
- mFetchingHistory[i].mFormattedImage = NULL;
- }
- mNbCurlRequests = 0;
- mNbCurlCompleted = 0;
-
- fillCurlQueue();
-}
-
-S32 LLTextureFetchDebugger::fillCurlQueue()
-{
- if(mStopDebug) //stop
- {
- mNbCurlCompleted = mFetchingHistory.size();
- return 0;
- }
- if (mNbCurlRequests > HTTP_NONPIPE_REQUESTS_LOW_WATER)
- {
- return mNbCurlRequests;
- }
-
- S32 size = mFetchingHistory.size();
- for (S32 i = 0 ; i < size ; i++)
- {
- if (mFetchingHistory[i].mCurlState != FetchEntry::CURL_NOT_DONE)
- {
- continue;
- }
- std::string texture_url = mHTTPUrl + "/?texture_id=" + mFetchingHistory[i].mID.asString().c_str();
- S32 requestedSize = mFetchingHistory[i].mRequestedSize;
- // We request the whole file if the size was not set.
- requestedSize = llmax(0,requestedSize);
- // We request the whole file if the size was set to an absurdly high value (meaning all file)
- requestedSize = (requestedSize == 33554432 ? 0 : requestedSize);
-
- LLCore::HttpHandle handle = mFetcher->getHttpRequest().requestGetByteRange(mHttpPolicyClass,
- LLWorkerThread::PRIORITY_LOWBITS,
- texture_url,
- 0,
- requestedSize,
- LLCore::HttpOptions::ptr_t(),
- mHttpHeaders,
- LLCore::HttpHandler::ptr_t(this, &NoOpDeletor));
- if (LLCORE_HTTP_HANDLE_INVALID != handle)
- {
- mHandleToFetchIndex[handle] = i;
- mFetchingHistory[i].mHttpHandle = handle;
- mFetchingHistory[i].mCurlState = FetchEntry::CURL_IN_PROGRESS;
- mNbCurlRequests++;
- if (mNbCurlRequests >= HTTP_NONPIPE_REQUESTS_HIGH_WATER) // emulate normal pipeline
- {
- break;
- }
- }
- else
- {
- // Failed to queue request, log it and mark it done.
- LLCore::HttpStatus status(mFetcher->getHttpRequest().getStatus());
-
- LL_WARNS(LOG_TXT) << "Couldn't issue HTTP request in debugger for texture "
- << mFetchingHistory[i].mID
- << ", status: " << status.toTerseString()
- << " reason: " << status.toString()
- << LL_ENDL;
- mFetchingHistory[i].mCurlState = FetchEntry::CURL_DONE;
- }
- }
- //LL_INFOS(LOG_TXT) << "Fetch Debugger : Having " << mNbCurlRequests << " requests through the curl thread." << LL_ENDL;
- return mNbCurlRequests;
-}
-
-void LLTextureFetchDebugger::debugGLTextureCreation()
-{
- llassert_always(mDebuggerState == IDLE);
- setDebuggerState(GL_TEX);
- mTempTexList.clear();
-
- S32 size = mFetchingHistory.size();
- for(S32 i = 0 ; i < size ; i++)
- {
- if(mFetchingHistory[i].mRawImage.notNull())
- {
- std::vector<LLViewerFetchedTexture*> textures;
- gTextureList.findTexturesByID(mFetchingHistory[i].mID, textures);
- std::vector<LLViewerFetchedTexture*>::iterator iter = textures.begin();
- while (iter != textures.end())
- {
- LLViewerFetchedTexture* tex = *iter++;
- if (tex && !tex->isForSculptOnly())
- {
- tex->destroyGLTexture();
- mTempTexList.push_back(tex);
- }
- }
- }
- }
-
- mGLCreationTime = -1.f;
- mTempIndex = 0;
- mHistoryListIndex = 0;
-
- return;
-}
-
-bool LLTextureFetchDebugger::processGLCreation(F32 max_time)
-{
- mTimer.reset();
-
- bool done = true;
- S32 size = mFetchingHistory.size();
- S32 size1 = mTempTexList.size();
- for(; mHistoryListIndex < size && mTempIndex < size1; mHistoryListIndex++)
- {
- if(mFetchingHistory[mHistoryListIndex].mRawImage.notNull())
- {
- if(mFetchingHistory[mHistoryListIndex].mID == mTempTexList[mTempIndex]->getID())
- {
- mTempTexList[mTempIndex]->createGLTexture(mFetchingHistory[mHistoryListIndex].mDecodedLevel,
- mFetchingHistory[mHistoryListIndex].mRawImage, 0, TRUE, mTempTexList[mTempIndex]->getBoostLevel());
- mTempIndex++;
- }
- }
-
- if(mTimer.getElapsedTimeF32() > max_time)
- {
- done = false;
- break;
- }
- }
-
- if(mGLCreationTime < 0.f)
- {
- mGLCreationTime = mTimer.getElapsedTimeF32() ;
- }
- else
- {
- mGLCreationTime += mTimer.getElapsedTimeF32() ;
- }
-
- return done;
-}
-
-//clear fetching results of all textures.
-void LLTextureFetchDebugger::clearTextures()
-{
- S32 size = mFetchingHistory.size();
- for(S32 i = 0 ; i < size ; i++)
- {
- std::vector<LLViewerFetchedTexture*> textures;
- gTextureList.findTexturesByID(mFetchingHistory[i].mID, textures);
- std::vector<LLViewerFetchedTexture*>::iterator iter = textures.begin();
- while (iter != textures.end())
- {
- LLViewerFetchedTexture* tex = *iter++;
- if (tex)
- {
- tex->clearFetchedResults();
- }
- }
- }
-}
-
-void LLTextureFetchDebugger::makeRefetchList()
-{
- mRefetchList.clear();
- S32 size = mFetchingHistory.size();
- for(S32 i = 0 ; i < size; i++)
- {
- LLViewerFetchedTexture* tex = LLViewerTextureManager::getFetchedTexture(mFetchingHistory[i].mID);
- if(tex && tex->isJustBound()) //visible
- {
- continue; //the texture fetch pipeline will take care of visible textures.
- }
-
- // todo: Will attempt to refetch icons and ui elements as normal images (boost_none)
- // thus will create unnecessary LLViewerFetchedTexture, consider supporting separate UI textures
- mRefetchList[tex].push_back(i);
- }
-}
-
-void LLTextureFetchDebugger::scanRefetchList()
-{
- if(mStopDebug)
- {
- return;
- }
- if(!mRefetchNonVis)
- {
- return;
- }
-
- for(std::map< LLPointer<LLViewerFetchedTexture>, std::vector<S32> >::iterator iter = mRefetchList.begin();
- iter != mRefetchList.end(); )
- {
- if(iter->second.empty())
- {
- gTextureList.setDebugFetching(iter->first, -1);
- mRefetchList.erase(iter++); // This is the correct method to "erase and move on" in an std::map
- }
- else
- {
- gTextureList.setDebugFetching(iter->first, mFetchingHistory[iter->second[0]].mDecodedLevel);
- ++iter;
- }
- }
-}
-
-void LLTextureFetchDebugger::debugRefetchVisibleFromCache()
-{
- llassert_always(mDebuggerState == IDLE);
- setDebuggerState(REFETCH_VIS_CACHE);
-
- clearTextures();
- mFetcher->setLoadSource(LLTextureFetch::FROM_ALL);
-
- mTimer.reset();
- mFetcher->lockFetcher(false);
- mRefetchVisCacheTime = -1.f;
- mRefetchedVisData = 0;
- mRefetchedVisPixels = 0;
-}
-
-void LLTextureFetchDebugger::debugRefetchVisibleFromHTTP()
-{
- llassert_always(mDebuggerState == IDLE);
- setDebuggerState(REFETCH_VIS_HTTP);
-
- clearTextures();
- mFetcher->setLoadSource(LLTextureFetch::FROM_HTTP_ONLY);
-
- mTimer.reset();
- mFetcher->lockFetcher(false);
- mRefetchVisHTTPTime = -1.f;
- mRefetchedVisData = 0;
- mRefetchedVisPixels = 0;
-}
-
-void LLTextureFetchDebugger::debugRefetchAllFromCache()
-{
- llassert_always(mDebuggerState == IDLE);
- setDebuggerState(REFETCH_ALL_CACHE);
-
- clearTextures();
- makeRefetchList();
- mFetcher->setLoadSource(LLTextureFetch::FROM_ALL);
-
- mTimer.reset();
- mFetcher->lockFetcher(false);
- mRefetchAllCacheTime = -1.f;
- mRefetchedAllData = 0;
- mRefetchedAllPixels = 0;
- mRefetchNonVis = FALSE;
-}
-
-void LLTextureFetchDebugger::debugRefetchAllFromHTTP()
-{
- llassert_always(mDebuggerState == IDLE);
- setDebuggerState(REFETCH_ALL_HTTP);
-
- clearTextures();
- makeRefetchList();
- mFetcher->setLoadSource(LLTextureFetch::FROM_HTTP_ONLY);
-
- mTimer.reset();
- mFetcher->lockFetcher(false);
- mRefetchAllHTTPTime = -1.f;
- mRefetchedAllData = 0;
- mRefetchedAllPixels = 0;
- mRefetchNonVis = TRUE;
-}
-
-bool LLTextureFetchDebugger::update(F32 max_time)
-{
- switch(mDebuggerState)
- {
- case START_DEBUG:
- if(processStartDebug(max_time))
- {
- setDebuggerState(IDLE);
- }
- break;
- case READ_CACHE:
- if(!mTextureCache->update(1))
- {
- mCacheReadTime = mTimer.getElapsedTimeF32() ;
- setDebuggerState(IDLE);
- unlockCache();
- }
- break;
- case WRITE_CACHE:
- if(!mTextureCache->update(1))
- {
- mCacheWriteTime = mTimer.getElapsedTimeF32() ;
- setDebuggerState(IDLE);
- unlockCache();
- }
- break;
- case DECODING:
- if(!mImageDecodeThread->update(1))
- {
- mDecodingTime = mTimer.getElapsedTimeF32() ;
- setDebuggerState(IDLE);
- unlockDecoder();
- }
- break;
- case HTTP_FETCHING:
- // Do some notifications...
- mFetcher->getHttpRequest().update(10);
- if (!fillCurlQueue() && mNbCurlCompleted == mFetchingHistory.size())
- {
- mHTTPTime = mTimer.getElapsedTimeF32() ;
- setDebuggerState(IDLE);
- }
- break;
- case GL_TEX:
- if(processGLCreation(max_time))
- {
- setDebuggerState(IDLE);
- mTempTexList.clear();
- }
- break;
- case REFETCH_VIS_CACHE:
- if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
- {
- mRefetchVisCacheTime = mTimer.getElapsedTimeF32() ;
- setDebuggerState(IDLE);
- mFetcher->lockFetcher(true);
- mFetcher->resetLoadSource();
- }
- break;
- case REFETCH_VIS_HTTP:
- if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
- {
- mRefetchVisHTTPTime = mTimer.getElapsedTimeF32() ;
- setDebuggerState(IDLE);
- mFetcher->lockFetcher(true);
- mFetcher->resetLoadSource();
- }
- break;
- case REFETCH_ALL_CACHE:
- scanRefetchList();
- if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
- {
- if(!mRefetchNonVis)
- {
- mRefetchNonVis = TRUE; //start to fetch non-vis
- scanRefetchList();
- break;
- }
-
- mRefetchAllCacheTime = mTimer.getElapsedTimeF32() ;
- setDebuggerState(IDLE);
- mFetcher->lockFetcher(true);
- mFetcher->resetLoadSource();
- mRefetchList.clear();
- mRefetchNonVis = FALSE;
- }
- break;
- case REFETCH_ALL_HTTP:
- scanRefetchList();
- if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
- {
- mRefetchAllHTTPTime = mTimer.getElapsedTimeF32() ;
- setDebuggerState(IDLE);
- mFetcher->lockFetcher(true);
- mFetcher->resetLoadSource();
- mRefetchList.clear();
- mRefetchNonVis = FALSE;
- }
- break;
- default:
- setDebuggerState(IDLE);
- break;
- }
-
- return mDebuggerState == IDLE;
-}
-
-void LLTextureFetchDebugger::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)
-{
- handle_fetch_map_t::iterator iter(mHandleToFetchIndex.find(handle));
- if (mHandleToFetchIndex.end() == iter)
- {
- LL_INFOS(LOG_TXT) << "Fetch Debugger : Couldn't find handle " << handle << " in fetch list." << LL_ENDL;
- return;
- }
-
- S32 fetch_ind(iter->second);
- mHandleToFetchIndex.erase(iter);
- if (fetch_ind >= mFetchingHistory.size() || mFetchingHistory[fetch_ind].mHttpHandle != handle)
- {
- LL_INFOS(LOG_TXT) << "Fetch Debugger : Handle and fetch object in disagreement. Punting." << LL_ENDL;
- }
- else
- {
- callbackHTTP(mFetchingHistory[fetch_ind], response);
- mFetchingHistory[fetch_ind].mHttpHandle = LLCORE_HTTP_HANDLE_INVALID; // Not valid after notification
- }
-}
-
-void LLTextureFetchDebugger::callbackCacheRead(S32 id, bool success, LLImageFormatted* image,
- S32 imagesize, BOOL islocal)
-{
- if (success)
- {
- mFetchingHistory[id].mFormattedImage = image;
- }
- mTextureCache->readComplete(mFetchingHistory[id].mCacheHandle, false);
- mFetchingHistory[id].mCacheHandle = LLTextureCache::nullHandle();
-}
-
-void LLTextureFetchDebugger::callbackCacheWrite(S32 id, bool success)
-{
- mTextureCache->writeComplete(mFetchingHistory[id].mCacheHandle);
- mFetchingHistory[id].mCacheHandle = LLTextureCache::nullHandle();
-}
-
-void LLTextureFetchDebugger::callbackDecoded(S32 id, bool success, LLImageRaw* raw, LLImageRaw* aux)
-{
- if (success)
- {
- llassert_always(raw);
- mFetchingHistory[id].mRawImage = raw;
- }
-}
-
-void LLTextureFetchDebugger::callbackHTTP(FetchEntry & fetch, LLCore::HttpResponse * response)
-{
- static const LLCore::HttpStatus par_status(HTTP_PARTIAL_CONTENT);
-
- LLCore::HttpStatus status(response->getStatus());
- mNbCurlRequests--;
- mNbCurlCompleted++;
- fetch.mCurlState = FetchEntry::CURL_DONE;
- if (status)
- {
- const bool partial(par_status == status);
- LLCore::BufferArray * ba(response->getBody()); // *Not* holding reference to body
-
- S32 data_size = ba ? ba->size() : 0;
- fetch.mCurlReceivedSize += data_size;
- //LL_INFOS(LOG_TXT) << "Fetch Debugger : got results for " << fetch.mID << ", data_size = " << data_size << ", received = " << fetch.mCurlReceivedSize << ", requested = " << fetch.mRequestedSize << ", partial = " << partial << LL_ENDL;
- if ((fetch.mCurlReceivedSize >= fetch.mRequestedSize) || !partial || (fetch.mRequestedSize == 600))
- {
- U8* d_buffer = (U8*)ll_aligned_malloc_16(data_size);
- if (ba)
- {
- ba->read(0, d_buffer, data_size);
- }
-
- llassert_always(fetch.mFormattedImage.isNull());
- {
- // For now, create formatted image based on extension
- std::string texture_url = mHTTPUrl + "/?texture_id=" + fetch.mID.asString().c_str();
- std::string extension = gDirUtilp->getExtension(texture_url);
- fetch.mFormattedImage = LLImageFormatted::createFromType(LLImageBase::getCodecFromExtension(extension));
- if (fetch.mFormattedImage.isNull())
- {
- fetch.mFormattedImage = new LLImageJ2C; // default
- }
- }
-
- fetch.mFormattedImage->setData(d_buffer, data_size);
- }
- }
- else //failed
- {
- LL_INFOS(LOG_TXT) << "Fetch Debugger : CURL GET FAILED, ID = " << fetch.mID
- << ", status: " << status.toTerseString()
- << " reason: " << status.toString() << LL_ENDL;
- }
-}
-
-
-//---------------------
-///////////////////////////////////////////////////////////////////////////////////////////
-//End LLTextureFetchDebugger
-///////////////////////////////////////////////////////////////////////////////////////////
-
LLTextureFetchTester::LLTextureFetchTester() : LLMetricPerformanceTesterBasic(sTesterName)
{
mTextureFetchTime = 0;