summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorMonty Brandenberg <monty@lindenlab.com>2013-06-19 13:55:54 -0400
committerMonty Brandenberg <monty@lindenlab.com>2013-06-19 13:55:54 -0400
commit626752beab7c12a355ab707d70aba6f4fe096c10 (patch)
tree6b73d3028b60934de70628d47f3c85c4803f357c /indra/newview
parent7c9d0b58aca072ff932b30f927e2876dfc6858aa (diff)
SH-4252 Add second policy class for large mesh asset downloads
Added second mesh class as well as an asset upload class. Refactored initialization to use less code and more data to cleanly get http started. Modified mesh to use the new http class for large requests (>2MB for now). Added additional timeout setting to llcorehttp to distinguish connection timeout from transport timeout and are now using transport timeout values for large asset downloads that may need more time.
Diffstat (limited to 'indra/newview')
-rwxr-xr-xindra/newview/llappcorehttp.cpp156
-rwxr-xr-xindra/newview/llappcorehttp.h36
-rwxr-xr-xindra/newview/llmeshrepository.cpp197
-rwxr-xr-xindra/newview/llmeshrepository.h21
-rwxr-xr-xindra/newview/lltexturefetch.cpp4
5 files changed, 243 insertions, 171 deletions
diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp
index 142344e277..b601b31d21 100755
--- a/indra/newview/llappcorehttp.cpp
+++ b/indra/newview/llappcorehttp.cpp
@@ -37,11 +37,13 @@ LLAppCoreHttp::LLAppCoreHttp()
: mRequest(NULL),
mStopHandle(LLCORE_HTTP_HANDLE_INVALID),
mStopRequested(0.0),
- mStopped(false),
- mPolicyDefault(-1),
- mPolicyTexture(-1),
- mPolicyMesh(-1)
-{}
+ mStopped(false)
+{
+ for (int i(0); i < LL_ARRAY_SIZE(mPolicies); ++i)
+ {
+ mPolicies[i] = LLCore::HttpRequest::DEFAULT_POLICY_ID;
+ }
+}
LLAppCoreHttp::~LLAppCoreHttp()
@@ -53,11 +55,43 @@ LLAppCoreHttp::~LLAppCoreHttp()
void LLAppCoreHttp::init()
{
+ static const struct
+ {
+ EAppPolicy mPolicy;
+ U32 mDefault;
+ U32 mMin;
+ U32 mMax;
+ U32 mDivisor;
+ std::string mKey;
+ const char * mUsage;
+ } init_data[] = // Default and dynamic values for classes
+ {
+ {
+ AP_TEXTURE, 8, 1, 12, 1,
+ "TextureFetchConcurrency",
+ "texture fetch"
+ },
+ {
+ AP_MESH, 8, 1, 32, 4,
+ "MeshMaxConcurrentRequests",
+ "mesh fetch"
+ },
+ {
+ AP_LARGE_MESH, 2, 1, 8, 1,
+ "",
+ "large mesh fetch"
+ },
+ {
+ AP_UPLOADS, 2, 1, 8, 1,
+ "",
+ "asset upload"
+ }
+ };
+
LLCore::HttpStatus status = LLCore::HttpRequest::createService();
if (! status)
{
- LL_ERRS("Init") << "Failed to initialize HTTP services. Reason: "
- << status.toString()
+ LL_ERRS("Init") << "Failed to initialize HTTP services. Reason: " << status.toString()
<< LL_ENDL;
}
@@ -66,8 +100,7 @@ void LLAppCoreHttp::init()
gDirUtilp->getCAFile());
if (! status)
{
- LL_ERRS("Init") << "Failed to set CA File for HTTP services. Reason: "
- << status.toString()
+ LL_ERRS("Init") << "Failed to set CA File for HTTP services. Reason: " << status.toString()
<< LL_ENDL;
}
@@ -77,8 +110,7 @@ void LLAppCoreHttp::init()
status = LLCore::HttpRequest::setPolicyGlobalOption(LLCore::HttpRequest::GP_LLPROXY, 1);
if (! status)
{
- LL_ERRS("Init") << "Failed to set HTTP proxy for HTTP services. Reason: "
- << status.toString()
+ LL_ERRS("Init") << "Failed to set HTTP proxy for HTTP services. Reason: " << status.toString()
<< LL_ENDL;
}
@@ -96,80 +128,72 @@ void LLAppCoreHttp::init()
}
// Setup default policy and constrain if directed to
- mPolicyDefault = LLCore::HttpRequest::DEFAULT_POLICY_ID;
+ mPolicies[AP_DEFAULT] = LLCore::HttpRequest::DEFAULT_POLICY_ID;
- // Texture policy will use default for now.
- mPolicyTexture = mPolicyDefault;
- static const std::string texture_concur("TextureFetchConcurrency");
- if (gSavedSettings.controlExists(texture_concur))
+ // Setup additional policies based on table and some special rules
+ // *TODO: Make these configurations dynamic later
+ for (int i(0); i < LL_ARRAY_SIZE(init_data); ++i)
{
- U32 concur(llmin(gSavedSettings.getU32(texture_concur), U32(12)));
+ const EAppPolicy policy(init_data[i].mPolicy);
- if (concur > 0)
+ // Create a policy class but use default for texture for now.
+ // This also has the side-effect of initializing the default
+ // class to desired values.
+ if (AP_TEXTURE == policy)
{
- LLCore::HttpStatus status;
- status = LLCore::HttpRequest::setPolicyClassOption(mPolicyTexture,
- LLCore::HttpRequest::CP_CONNECTION_LIMIT,
- concur);
- if (! status)
- {
- LL_WARNS("Init") << "Unable to set texture fetch concurrency. Reason: "
- << status.toString()
- << LL_ENDL;
- }
- else
+ mPolicies[policy] = mPolicies[AP_DEFAULT];
+ }
+ else
+ {
+ mPolicies[policy] = LLCore::HttpRequest::createPolicyClass();
+ if (! mPolicies[policy])
{
- LL_INFOS("Init") << "Application settings overriding default texture fetch concurrency. New value: "
- << concur
+ // Use default policy (but don't accidentally modify default)
+ LL_WARNS("Init") << "Failed to create HTTP policy class for " << init_data[i].mUsage
+ << ". Using default policy."
<< LL_ENDL;
+ mPolicies[policy] = mPolicies[AP_DEFAULT];
+ continue;
}
}
- }
- // Create the mesh class
- mPolicyMesh = LLCore::HttpRequest::createPolicyClass();
- if (! mPolicyMesh)
- {
- LL_WARNS("Init") << "Failed to create HTTP policy class for Mesh. Using default policy."
- << LL_ENDL;
- mPolicyMesh = mPolicyDefault;
- }
- else
- {
- static const std::string mesh_concur("MeshMaxConcurrentRequests");
- if (gSavedSettings.controlExists(mesh_concur))
+ // Get target connection concurrency value
+ U32 setting(init_data[i].mDefault);
+ if (! init_data[i].mKey.empty() && gSavedSettings.controlExists(init_data[i].mKey))
{
- U32 setting(llmin(gSavedSettings.getU32(mesh_concur), 256U) / 4U);
- setting = llmax(setting, 2U);
-
- if (setting > 0)
+ U32 new_setting(gSavedSettings.getU32(init_data[i].mKey));
+ if (new_setting)
{
- LLCore::HttpStatus status;
- status = LLCore::HttpRequest::setPolicyClassOption(mPolicyMesh,
- LLCore::HttpRequest::CP_CONNECTION_LIMIT,
- setting);
- if (! status)
- {
- LL_WARNS("Init") << "Unable to set mesh fetch concurrency. Reason: "
- << status.toString()
- << LL_ENDL;
- }
- else
- {
- LL_INFOS("Init") << "Application settings overriding default mesh fetch concurrency. New value: "
- << setting
- << LL_ENDL;
- }
+ // Treat zero settings as an ask for default
+ setting = new_setting / init_data[i].mDivisor;
+ setting = llclamp(setting, init_data[i].mMin, init_data[i].mMax);
}
}
+
+ // Set it and report
+ LLCore::HttpStatus status;
+ status = LLCore::HttpRequest::setPolicyClassOption(mPolicies[policy],
+ LLCore::HttpRequest::CP_CONNECTION_LIMIT,
+ setting);
+ if (! status)
+ {
+ LL_WARNS("Init") << "Unable to set " << init_data[i].mUsage
+ << " concurrency. Reason: " << status.toString()
+ << LL_ENDL;
+ }
+ else if (setting != init_data[i].mDefault)
+ {
+ LL_INFOS("Init") << "Application settings overriding default " << init_data[i].mUsage
+ << " concurrency. New value: " << setting
+ << LL_ENDL;
+ }
}
// Kick the thread
status = LLCore::HttpRequest::startThread();
if (! status)
{
- LL_ERRS("Init") << "Failed to start HTTP servicing thread. Reason: "
- << status.toString()
+ LL_ERRS("Init") << "Failed to start HTTP servicing thread. Reason: " << status.toString()
<< LL_ENDL;
}
diff --git a/indra/newview/llappcorehttp.h b/indra/newview/llappcorehttp.h
index d90af9e5ca..532e1f5cb0 100755
--- a/indra/newview/llappcorehttp.h
+++ b/indra/newview/llappcorehttp.h
@@ -41,6 +41,19 @@
class LLAppCoreHttp : public LLCore::HttpHandler
{
public:
+ typedef LLCore::HttpRequest::policy_t policy_t;
+
+ enum EAppPolicy
+ {
+ AP_DEFAULT,
+ AP_TEXTURE,
+ AP_MESH,
+ AP_LARGE_MESH,
+ AP_UPLOADS,
+ AP_COUNT // Must be last
+ };
+
+public:
LLAppCoreHttp();
~LLAppCoreHttp();
@@ -65,22 +78,11 @@ public:
// Notification when the stop request is complete.
virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
- // Retrieve the policy class for default operations.
- int getPolicyDefault() const
- {
- return mPolicyDefault;
- }
-
- // Get the texture fetch policy class.
- int getPolicyTexture() const
- {
- return mPolicyTexture;
- }
-
- // Get the mesh fetch policy class.
- int getPolicyMesh() const
+ // Retrieve a policy class identifier for desired
+ // application function.
+ policy_t getPolicy(EAppPolicy policy) const
{
- return mPolicyMesh;
+ return mPolicies[policy];
}
private:
@@ -91,9 +93,7 @@ private:
LLCore::HttpHandle mStopHandle;
F64 mStopRequested;
bool mStopped;
- int mPolicyDefault;
- int mPolicyTexture;
- int mPolicyMesh;
+ policy_t mPolicies[AP_COUNT];
};
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 702e940983..f0ec97a34d 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -80,6 +80,10 @@ LLMeshRepository gMeshRepo;
const S32 MESH_HEADER_SIZE = 4096;
const U32 MAX_MESH_REQUESTS_PER_SECOND = 100;
+const S32 REQUEST_HIGH_WATER_MIN = 32;
+const S32 REQUEST_LOW_WATER_MIN = 16;
+const U32 LARGE_MESH_FETCH_THRESHOLD = 1U << 21; // Size at which requests goes to narrow/slow queue
+const long LARGE_MESH_XFER_TIMEOUT = 240L; // Seconds to complete xfer
// Maximum mesh version to support. Three least significant digits are reserved for the minor version,
// with major version changes indicating a format change that is not backwards compatible and should not
@@ -210,6 +214,8 @@ void get_vertex_buffer_from_mesh(LLCDMeshData& mesh, LLModel::PhysicsMesh& res,
S32 LLMeshRepoThread::sActiveHeaderRequests = 0;
S32 LLMeshRepoThread::sActiveLODRequests = 0;
U32 LLMeshRepoThread::sMaxConcurrentRequests = 1;
+S32 LLMeshRepoThread::sRequestLowWater = REQUEST_LOW_WATER_MIN;
+S32 LLMeshRepoThread::sRequestHighWater = REQUEST_HIGH_WATER_MIN;
class LLMeshHandlerBase : public LLCore::HttpHandler
{
@@ -548,25 +554,37 @@ public:
LLMeshRepoThread::LLMeshRepoThread()
: LLThread("mesh repo"),
- mCurlRequest(NULL),
mWaiting(false),
mHttpRequest(NULL),
mHttpOptions(NULL),
+ mHttpLargeOptions(NULL),
mHttpHeaders(NULL),
- mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID)
+ mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
+ mHttpLargePolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
+ mHttpPriority(0),
+ mHttpGetCount(0U),
+ mHttpLargeGetCount(0U)
{
mMutex = new LLMutex(NULL);
mHeaderMutex = new LLMutex(NULL);
mSignal = new LLCondition(NULL);
mHttpRequest = new LLCore::HttpRequest;
mHttpOptions = new LLCore::HttpOptions;
+ mHttpLargeOptions = new LLCore::HttpOptions;
+ mHttpLargeOptions->setTransferTimeout(LARGE_MESH_XFER_TIMEOUT);
mHttpHeaders = new LLCore::HttpHeaders;
mHttpHeaders->mHeaders.push_back("Accept: application/vnd.ll.mesh");
- mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicyMesh();
+ mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicy(LLAppCoreHttp::AP_MESH);
+ mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicy(LLAppCoreHttp::AP_LARGE_MESH);
}
+
LLMeshRepoThread::~LLMeshRepoThread()
{
+ LL_INFOS("Mesh") << "Small GETs issued: "
+ << mHttpGetCount << ", Large GETs issued: "
+ << mHttpLargeGetCount << LL_ENDL;
+
for (http_request_set::iterator iter(mHttpRequestSet.begin());
iter != mHttpRequestSet.end();
++iter)
@@ -584,6 +602,11 @@ LLMeshRepoThread::~LLMeshRepoThread()
mHttpOptions->release();
mHttpOptions = NULL;
}
+ if (mHttpLargeOptions)
+ {
+ mHttpLargeOptions->release();
+ mHttpLargeOptions = NULL;
+ }
delete mHttpRequest;
mHttpRequest = NULL;
delete mMutex;
@@ -596,7 +619,6 @@ LLMeshRepoThread::~LLMeshRepoThread()
void LLMeshRepoThread::run()
{
- mCurlRequest = new LLCurlRequest();
LLCDResult res = LLConvexDecomposition::initThread();
if (res != LLCD_OK)
{
@@ -627,7 +649,7 @@ void LLMeshRepoThread::run()
// NOTE: throttling intentionally favors LOD requests over header requests
- while (!mLODReqQ.empty() && count < MAX_MESH_REQUESTS_PER_SECOND && sActiveLODRequests < sMaxConcurrentRequests)
+ while (!mLODReqQ.empty() && count < MAX_MESH_REQUESTS_PER_SECOND)
{
if (mMutex)
{
@@ -646,7 +668,7 @@ void LLMeshRepoThread::run()
}
}
- while (!mHeaderReqQ.empty() && count < MAX_MESH_REQUESTS_PER_SECOND && sActiveHeaderRequests < sMaxConcurrentRequests)
+ while (!mHeaderReqQ.empty() && count < MAX_MESH_REQUESTS_PER_SECOND)
{
if (mMutex)
{
@@ -701,8 +723,6 @@ void LLMeshRepoThread::run()
}
mPhysicsShapeRequests = incomplete;
}
-
- mCurlRequest->process();
}
}
@@ -716,9 +736,6 @@ void LLMeshRepoThread::run()
{
llwarns << "convex decomposition unable to be quit" << llendl;
}
-
- delete mCurlRequest;
- mCurlRequest = NULL;
}
void LLMeshRepoThread::loadMeshSkinInfo(const LLUUID& mesh_id)
@@ -800,6 +817,42 @@ std::string LLMeshRepoThread::constructUrl(LLUUID mesh_id)
return http_url;
}
+// May only be called by repo thread
+LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url,
+ size_t offset,
+ size_t len,
+ LLCore::HttpHandler * handler)
+{
+ LLCore::HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+ if (len < LARGE_MESH_FETCH_THRESHOLD)
+ {
+ handle = mHttpRequest->requestGetByteRange(mHttpPolicyClass,
+ mHttpPriority,
+ url,
+ offset,
+ len,
+ mHttpOptions,
+ mHttpHeaders,
+ handler);
+ ++mHttpGetCount;
+ }
+ else
+ {
+ handle = mHttpRequest->requestGetByteRange(mHttpLargePolicyClass,
+ mHttpPriority,
+ url,
+ offset,
+ len,
+ mHttpLargeOptions,
+ mHttpHeaders,
+ handler);
+ ++mHttpLargeGetCount;
+ }
+ return handle;
+}
+
+
bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
{ //protected by mMutex
@@ -863,14 +916,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
{
LLMeshSkinInfoHandler * handler = new LLMeshSkinInfoHandler(mesh_id, offset, size);
// LL_WARNS("Mesh") << "MESH: Issuing Skin Info Request" << LL_ENDL;
- LLCore::HttpHandle handle = mHttpRequest->requestGetByteRange(mHttpPolicyClass,
- 0, // *TODO: Get better priority value
- http_url,
- offset,
- size,
- mHttpOptions,
- mHttpHeaders,
- handler);
+ LLCore::HttpHandle handle = getByteRange(http_url, offset, size, handler);
if (LLCORE_HTTP_HANDLE_INVALID == handle)
{
// *TODO: Better error message
@@ -959,14 +1005,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
{
LLMeshDecompositionHandler * handler = new LLMeshDecompositionHandler(mesh_id, offset, size);
// LL_WARNS("Mesh") << "MESH: Issuing Decomp Request" << LL_ENDL;
- LLCore::HttpHandle handle = mHttpRequest->requestGetByteRange(mHttpPolicyClass,
- 0, // *TODO: Get better priority value
- http_url,
- offset,
- size,
- mHttpOptions,
- mHttpHeaders,
- handler);
+ LLCore::HttpHandle handle = getByteRange(http_url, offset, size, handler);
if (LLCORE_HTTP_HANDLE_INVALID == handle)
{
// *TODO: Better error message
@@ -1054,14 +1093,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
{
LLMeshPhysicsShapeHandler * handler = new LLMeshPhysicsShapeHandler(mesh_id, offset, size);
// LL_WARNS("Mesh") << "MESH: Issuing Physics Shape Request" << LL_ENDL;
- LLCore::HttpHandle handle = mHttpRequest->requestGetByteRange(mHttpPolicyClass,
- 0, // *TODO: Get better priority value
- http_url,
- offset,
- size,
- mHttpOptions,
- mHttpHeaders,
- handler);
+ LLCore::HttpHandle handle = getByteRange(http_url, offset, size, handler);
if (LLCORE_HTTP_HANDLE_INVALID == handle)
{
// *TODO: Better error message
@@ -1154,14 +1186,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, U32& c
LLMeshHeaderHandler * handler = new LLMeshHeaderHandler(mesh_params);
// LL_WARNS("Mesh") << "MESH: Issuing Request" << LL_ENDL;
- LLCore::HttpHandle handle = mHttpRequest->requestGetByteRange(mHttpPolicyClass,
- 0, // *TODO: Get better priority value
- http_url,
- 0,
- MESH_HEADER_SIZE,
- mHttpOptions,
- mHttpHeaders,
- handler);
+ LLCore::HttpHandle handle = getByteRange(http_url, 0, MESH_HEADER_SIZE, handler);
if (LLCORE_HTTP_HANDLE_INVALID == handle)
{
// *TODO: Better error message
@@ -1241,14 +1266,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod,
{
LLMeshLODHandler * handler = new LLMeshLODHandler(mesh_params, lod, offset, size);
// LL_WARNS("Mesh") << "MESH: Issuing LOD Request" << LL_ENDL;
- LLCore::HttpHandle handle = mHttpRequest->requestGetByteRange(mHttpPolicyClass,
- 0, // *TODO: Get better priority value
- http_url,
- offset,
- size,
- mHttpOptions,
- mHttpHeaders,
- handler);
+ LLCore::HttpHandle handle = getByteRange(http_url, offset, size, handler);
if (LLCORE_HTTP_HANDLE_INVALID == handle)
{
// *TODO: Better error message
@@ -2537,9 +2555,14 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
void LLMeshRepository::notifyLoadedMeshes()
{ //called from main thread
-
- LLMeshRepoThread::sMaxConcurrentRequests = gSavedSettings.getU32("MeshMaxConcurrentRequests");
-
+ // *FIXME: Scaling down the setting by a factor of 4 for now to reflect
+ // target goal. May want to rename the setting before release.
+ LLMeshRepoThread::sMaxConcurrentRequests = gSavedSettings.getU32("MeshMaxConcurrentRequests") / 4;
+ LLMeshRepoThread::sRequestHighWater = llmax(50 * S32(LLMeshRepoThread::sMaxConcurrentRequests),
+ REQUEST_HIGH_WATER_MIN);
+ LLMeshRepoThread::sRequestLowWater = llmax(LLMeshRepoThread::sRequestLowWater / 2,
+ REQUEST_LOW_WATER_MIN);
+
//clean up completed upload threads
for (std::vector<LLMeshUploadThread*>::iterator iter = mUploads.begin(); iter != mUploads.end(); )
{
@@ -2617,7 +2640,7 @@ void LLMeshRepository::notifyLoadedMeshes()
//call completed callbacks on finished decompositions
mDecompThread->notifyCompleted();
- if (!mThread->mWaiting)
+ if (!mThread->mWaiting && mPendingRequests.empty())
{ //curl thread is churning, wait for it to go idle
return;
}
@@ -2644,47 +2667,55 @@ void LLMeshRepository::notifyLoadedMeshes()
mUploadErrorQ.pop();
}
- S32 push_count = LLMeshRepoThread::sMaxConcurrentRequests-(LLMeshRepoThread::sActiveHeaderRequests+LLMeshRepoThread::sActiveLODRequests);
-
- if (push_count > 0)
+ S32 active_count = LLMeshRepoThread::sActiveHeaderRequests + LLMeshRepoThread::sActiveLODRequests;
+ if (active_count < LLMeshRepoThread::sRequestLowWater)
{
- //calculate "score" for pending requests
-
- //create score map
- std::map<LLUUID, F32> score_map;
+ S32 push_count = LLMeshRepoThread::sRequestHighWater - active_count;
- for (U32 i = 0; i < 4; ++i)
+ if (mPendingRequests.size() > push_count)
{
- for (mesh_load_map::iterator iter = mLoadingMeshes[i].begin(); iter != mLoadingMeshes[i].end(); ++iter)
+ // More requests than the high-water limit allows so
+ // sort and forward the most important.
+
+ //calculate "score" for pending requests
+
+ //create score map
+ std::map<LLUUID, F32> score_map;
+
+ for (U32 i = 0; i < 4; ++i)
{
- F32 max_score = 0.f;
- for (std::set<LLUUID>::iterator obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter)
+ for (mesh_load_map::iterator iter = mLoadingMeshes[i].begin(); iter != mLoadingMeshes[i].end(); ++iter)
{
- LLViewerObject* object = gObjectList.findObject(*obj_iter);
-
- if (object)
+ F32 max_score = 0.f;
+ for (std::set<LLUUID>::iterator obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter)
{
- LLDrawable* drawable = object->mDrawable;
- if (drawable)
+ LLViewerObject* object = gObjectList.findObject(*obj_iter);
+
+ if (object)
{
- F32 cur_score = drawable->getRadius()/llmax(drawable->mDistanceWRTCamera, 1.f);
- max_score = llmax(max_score, cur_score);
+ LLDrawable* drawable = object->mDrawable;
+ if (drawable)
+ {
+ F32 cur_score = drawable->getRadius()/llmax(drawable->mDistanceWRTCamera, 1.f);
+ max_score = llmax(max_score, cur_score);
+ }
}
}
- }
- score_map[iter->first.getSculptID()] = max_score;
+ score_map[iter->first.getSculptID()] = max_score;
+ }
}
- }
- //set "score" for pending requests
- for (std::vector<LLMeshRepoThread::LODRequest>::iterator iter = mPendingRequests.begin(); iter != mPendingRequests.end(); ++iter)
- {
- iter->mScore = score_map[iter->mMeshParams.getSculptID()];
- }
+ //set "score" for pending requests
+ for (std::vector<LLMeshRepoThread::LODRequest>::iterator iter = mPendingRequests.begin(); iter != mPendingRequests.end(); ++iter)
+ {
+ iter->mScore = score_map[iter->mMeshParams.getSculptID()];
+ }
- //sort by "score"
- std::sort(mPendingRequests.begin(), mPendingRequests.end(), LLMeshRepoThread::CompareScoreGreater());
+ //sort by "score"
+ std::partial_sort(mPendingRequests.begin(), mPendingRequests.begin() + push_count,
+ mPendingRequests.end(), LLMeshRepoThread::CompareScoreGreater());
+ }
while (!mPendingRequests.empty() && push_count > 0)
{
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 62f81ce9e2..0dca29e7d4 100755
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -224,13 +224,14 @@ public:
static S32 sActiveHeaderRequests;
static S32 sActiveLODRequests;
static U32 sMaxConcurrentRequests;
+ static S32 sRequestLowWater;
+ static S32 sRequestHighWater;
- LLCurlRequest* mCurlRequest;
LLMutex* mMutex;
LLMutex* mHeaderMutex;
LLCondition* mSignal;
- bool mWaiting;
+ volatile bool mWaiting;
//map of known mesh headers
typedef std::map<LLUUID, LLSD> mesh_header_map;
@@ -324,8 +325,11 @@ public:
// llcorehttp library interface objects.
LLCore::HttpRequest * mHttpRequest;
LLCore::HttpOptions * mHttpOptions;
+ LLCore::HttpOptions * mHttpLargeOptions;
LLCore::HttpHeaders * mHttpHeaders;
LLCore::HttpRequest::policy_t mHttpPolicyClass;
+ LLCore::HttpRequest::policy_t mHttpLargePolicyClass;
+ LLCore::HttpRequest::priority_t mHttpPriority;
typedef std::set<LLCore::HttpHandler *> http_request_set;
http_request_set mHttpRequestSet; // Outstanding HTTP requests
@@ -373,6 +377,19 @@ public:
static void incActiveHeaderRequests();
static void decActiveHeaderRequests();
+private:
+ // Issue a GET request to a URL with 'Range' header using
+ // the correct policy class and other attributes. If an invalid
+ // handle is returned, the request failed and caller must retry
+ // or dispose of handler.
+ //
+ // Threads: Repo thread only
+ LLCore::HttpHandle getByteRange(const std::string & url, size_t offset, size_t len,
+ LLCore::HttpHandler * handler);
+
+private:
+ U32 mHttpGetCount;
+ U32 mHttpLargeGetCount;
};
class LLMeshUploadThread : public LLThread
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index be5fde9e2b..d934ef9dc4 100755
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2012, Linden Research, Inc.
+ * Copyright (C) 2012-2013, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -2410,7 +2410,7 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
mHttpHeaders->mHeaders.push_back("Accept: image/x-j2c");
mHttpMetricsHeaders = new LLCore::HttpHeaders;
mHttpMetricsHeaders->mHeaders.push_back("Content-Type: application/llsd+xml");
- mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicyDefault();
+ mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicy(LLAppCoreHttp::AP_TEXTURE);
}
LLTextureFetch::~LLTextureFetch()