aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra')
-rw-r--r--linden/indra/newview/lltexturefetch.cpp159
-rw-r--r--linden/indra/newview/lltexturefetch.h2
-rw-r--r--linden/indra/newview/llvoavatar.cpp14
3 files changed, 134 insertions, 41 deletions
diff --git a/linden/indra/newview/lltexturefetch.cpp b/linden/indra/newview/lltexturefetch.cpp
index b5ad435..f63deb8 100644
--- a/linden/indra/newview/lltexturefetch.cpp
+++ b/linden/indra/newview/lltexturefetch.cpp
@@ -157,7 +157,7 @@ public:
157 157
158 void callbackHttpGet(const LLChannelDescriptors& channels, 158 void callbackHttpGet(const LLChannelDescriptors& channels,
159 const LLIOPipe::buffer_ptr_t& buffer, 159 const LLIOPipe::buffer_ptr_t& buffer,
160 bool last_block, bool success); 160 bool partial, bool unsatisfiable, bool success);
161 void callbackCacheRead(bool success, LLImageFormatted* image, 161 void callbackCacheRead(bool success, LLImageFormatted* image,
162 S32 imagesize, BOOL islocal); 162 S32 imagesize, BOOL islocal);
163 void callbackCacheWrite(bool success); 163 void callbackCacheWrite(bool success);
@@ -317,13 +317,14 @@ public:
317 mFetcher->mTextureInfo.setRequestCompleteTimeAndLog(mID, timeNow); 317 mFetcher->mTextureInfo.setRequestCompleteTimeAndLog(mID, timeNow);
318 } 318 }
319 319
320 lldebugs << "HTTP COMPLETE: " << mID << llendl; 320 LL_DEBUGS("TextureFetch") << "HTTP COMPLETE: " << mID << " with status: " << status << LL_ENDL;
321 mFetcher->lockQueue(); 321 mFetcher->lockQueue();
322 LLTextureFetchWorker* worker = mFetcher->getWorker(mID); 322 LLTextureFetchWorker* worker = mFetcher->getWorker(mID);
323 if (worker) 323 if (worker)
324 { 324 {
325 bool success = false; 325 bool success = false;
326 bool partial = false; 326 bool partial = false;
327 bool unsatisfiable = false;
327 if (200 <= status && status < 300) 328 if (200 <= status && status < 300)
328 { 329 {
329 success = true; 330 success = true;
@@ -332,18 +333,19 @@ public:
332 partial = true; 333 partial = true;
333 } 334 }
334 } 335 }
335 else 336 else if (status == HTTP_REQUESTED_RANGE_NOT_SATISFIABLE)
336 { 337 {
337 worker->setGetStatus(status, reason); 338 LL_DEBUGS("TextureFetch") << "Request was an unsatisfiable range: mRequestedSize=" << mRequestedSize << " mOffset=" << mOffset << " for: " << mID << LL_ENDL;
338// llwarns << status << ": " << reason << llendl; 339 unsatisfiable = true;
339 } 340 }
341
340 if (!success) 342 if (!success)
341 { 343 {
342 worker->setGetStatus(status, reason); 344 worker->setGetStatus(status, reason);
343// llwarns << "CURL GET FAILED, status:" << status << " reason:" << reason << llendl; 345// llwarns << "CURL GET FAILED, status:" << status << " reason:" << reason << llendl;
344 } 346 }
345 mFetcher->removeFromHTTPQueue(mID); 347 mFetcher->removeFromHTTPQueue(mID);
346 worker->callbackHttpGet(channels, buffer, partial, success); 348 worker->callbackHttpGet(channels, buffer, partial, unsatisfiable, success);
347 } 349 }
348 else 350 else
349 { 351 {
@@ -870,6 +872,16 @@ bool LLTextureFetchWorker::doWork(S32 param)
870 return false; 872 return false;
871 } 873 }
872 } 874 }
875
876 // *TODO: remove this hack when not needed anymore
877 S32 buggy_range_fudge = 0;
878 if (LLTextureFetch::hasBuggyHTTPRange())
879 {
880 buggy_range_fudge = 1;
881 resetFormattedData(); // discard any previous data we had
882 cur_size = 0 ;
883 }
884
873 mRequestedSize = mDesiredSize; 885 mRequestedSize = mDesiredSize;
874 mRequestedDiscard = mDesiredDiscard; 886 mRequestedDiscard = mDesiredDiscard;
875 mRequestedSize -= cur_size; 887 mRequestedSize -= cur_size;
@@ -883,10 +895,11 @@ bool LLTextureFetchWorker::doWork(S32 param)
883 mLoaded = FALSE; 895 mLoaded = FALSE;
884 mGetStatus = 0; 896 mGetStatus = 0;
885 mGetReason.clear(); 897 mGetReason.clear();
886 lldebugs << "HTTP GET: " << mID << " Offset: " << offset 898 LL_DEBUGS("TextureFetch") << "HTTP GET: " << mID << " Offset: " << offset
887 << " Bytes: " << mRequestedSize 899 << " Bytes: " << mRequestedSize
900 << " Range: " << offset << "-" << offset+mRequestedSize-1+buggy_range_fudge
888 << " Bandwidth(kbps): " << mFetcher->getTextureBandwidth() << "/" << max_bandwidth 901 << " Bandwidth(kbps): " << mFetcher->getTextureBandwidth() << "/" << max_bandwidth
889 << llendl; 902 << LL_ENDL;
890 setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); 903 setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
891 mState = WAIT_HTTP_REQ; 904 mState = WAIT_HTTP_REQ;
892 905
@@ -894,7 +907,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
894 // Will call callbackHttpGet when curl request completes 907 // Will call callbackHttpGet when curl request completes
895 std::vector<std::string> headers; 908 std::vector<std::string> headers;
896 headers.push_back("Accept: image/x-j2c"); 909 headers.push_back("Accept: image/x-j2c");
897 res = mFetcher->mCurlGetRequest->getByteRange(mUrl, headers, offset, mRequestedSize, 910 res = mFetcher->mCurlGetRequest->getByteRange(mUrl, headers, offset, mRequestedSize + buggy_range_fudge,
898 new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset)); 911 new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset));
899 } 912 }
900 if (!res) 913 if (!res)
@@ -1301,7 +1314,9 @@ bool LLTextureFetchWorker::processSimulatorPackets()
1301 1314
1302void LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels, 1315void LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,
1303 const LLIOPipe::buffer_ptr_t& buffer, 1316 const LLIOPipe::buffer_ptr_t& buffer,
1304 bool last_block, bool success) 1317 bool partial,
1318 bool unsatisfiable,
1319 bool success)
1305{ 1320{
1306 LLMutexLock lock(&mWorkMutex); 1321 LLMutexLock lock(&mWorkMutex);
1307 1322
@@ -1316,56 +1331,91 @@ void LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,
1316 llwarns << "Duplicate callback for " << mID.asString() << llendl; 1331 llwarns << "Duplicate callback for " << mID.asString() << llendl;
1317 return; // ignore duplicate callback 1332 return; // ignore duplicate callback
1318 } 1333 }
1334
1335 S32 data_size = 0;
1319 if (success) 1336 if (success)
1320 { 1337 {
1321 // get length of stream: 1338 // get length of stream:
1322 S32 data_size = buffer->countAfter(channels.in(), NULL); 1339 data_size = buffer->countAfter(channels.in(), NULL);
1323 1340
1324 gImageList.sTextureBits += data_size * 8; // Approximate - does not include header bits 1341 gImageList.sTextureBits += data_size * 8; // Approximate - does not include header bits
1325 1342
1326 //llinfos << "HTTP RECEIVED: " << mID.asString() << " Bytes: " << data_size << llendl; 1343 LL_DEBUGS("TextureFetch") << "HTTP RECEIVED: " << mID.asString() << " Bytes: " << data_size << " mRequestedSize: " << mRequestedSize << LL_ENDL;
1344
1327 if (data_size > 0) 1345 if (data_size > 0)
1328 { 1346 {
1329 // *TODO: set the formatted image data here directly to avoid the copy 1347 bool clean_data = false;
1330 mBuffer = new U8[data_size]; 1348 bool done = false;
1331 buffer->readAfter(channels.in(), NULL, mBuffer, data_size); 1349 if (!partial)
1332 mBufferSize += data_size;
1333 if (data_size < mRequestedSize &&
1334 (mRequestedDiscard == 0 || mRequestedSize >= MAX_IMAGE_DATA_SIZE) )
1335 { 1350 {
1336 // We requested whole image (by discard or by size,) so assume we got it 1351 // we got the whole image in one go
1337 mHaveAllData = TRUE; 1352 done = true;
1353 clean_data = true;
1354 }
1355 else if (data_size < mRequestedSize)
1356 {
1357 // we have the whole image
1358 done = true;
1359 }
1360 else if (data_size == mRequestedSize)
1361 {
1362 if (mRequestedDiscard <= 0)
1363 {
1364 done = true;
1365 }
1366 else
1367 {
1368 // this is the normal case where we get the data we requested,
1369 // but still need to request more data.
1370 }
1338 } 1371 }
1339 else if (data_size > mRequestedSize) 1372 else if (data_size > mRequestedSize)
1340 { 1373 {
1341 // *TODO: This shouldn't be happening any more 1374 // *TODO: This shouldn't be happening any more
1342 llwarns << "data_size = " << data_size << " > requested: " << mRequestedSize << llendl; 1375 llwarns << "data_size = " << data_size << " > requested: " << mRequestedSize << llendl;
1343 mHaveAllData = TRUE; 1376 done = true;
1377 clean_data = true;
1344 llassert_always(mDecodeHandle == 0); 1378 llassert_always(mDecodeHandle == 0);
1345 mFormattedImage = NULL; // discard any previous data we had
1346 mBufferSize = data_size;
1347 } 1379 }
1348 mRequestedSize = data_size; 1380
1349 } 1381 if (clean_data)
1350 else
1351 {
1352 // We requested data but received none (and no error),
1353 if (mFormattedImage.notNull() && mFormattedImage->getDataSize() > 0)
1354 { 1382 {
1355 // but have earlier data, so presumably we have it all. 1383 resetFormattedData(); // discard any previous data we had
1356 mRequestedSize = 0; 1384 llassert(mBufferSize == 0);
1357 mHaveAllData = TRUE;
1358 } 1385 }
1359 else 1386 if (done)
1360 { 1387 {
1361 mRequestedSize = -1; // treat this fetch as if it failed. 1388 mHaveAllData = TRUE;
1389 mRequestedDiscard = 0;
1362 } 1390 }
1391
1392 // *TODO: set the formatted image data here directly to avoid the copy
1393 mBuffer = new U8[data_size];
1394 buffer->readAfter(channels.in(), NULL, mBuffer, data_size);
1395 mBufferSize += data_size;
1396 mRequestedSize = data_size;
1363 } 1397 }
1364 } 1398 }
1365 else 1399 else
1366 { 1400 {
1367 mRequestedSize = -1; // error 1401 mRequestedSize = -1; // error
1368 } 1402 }
1403
1404 if ((success && (data_size == 0)) || unsatisfiable)
1405 {
1406 if (mFormattedImage.notNull() && mFormattedImage->getDataSize() > 0)
1407 {
1408 // we already have some data, so we'll assume we have it all
1409 mRequestedSize = 0;
1410 mRequestedDiscard = 0;
1411 mHaveAllData = TRUE;
1412 }
1413 else
1414 {
1415 mRequestedSize = -1; // treat this fetch as if it failed.
1416 }
1417 }
1418
1369 mLoaded = TRUE; 1419 mLoaded = TRUE;
1370 setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); 1420 setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
1371} 1421}
@@ -2220,3 +2270,44 @@ void LLTextureFetch::dump()
2220 } 2270 }
2221} 2271}
2222 2272
2273// This tries to detect if the sim has this bug:
2274// http://opensimulator.org/mantis/view.php?id=5081
2275//
2276// *TODO: This is a *HACK and may not work if the grid is heterogenous.
2277// Remove it once OpenSim versions in the wild are > 0.7.0.2!
2278#include "hippoGridManager.h"
2279#include <boost/regex.hpp>
2280//static
2281bool LLTextureFetch::hasBuggyHTTPRange()
2282{
2283 static std::string s_version;
2284 static bool buggy = false;
2285 if ((s_version != gLastVersionChannel) && !gLastVersionChannel.empty())
2286 {
2287 s_version = gLastVersionChannel;
2288 buggy = false;
2289 if (gHippoGridManager->getConnectedGrid()->getPlatform() == HippoGridInfo::PLATFORM_OPENSIM)
2290 {
2291 std::string ver_string;
2292 try
2293 {
2294 const boost::regex re(".*OpenSim.*?([0-9.]+).+");
2295 ver_string = regex_replace(s_version, re, "\\1", boost::match_default);
2296 }
2297 catch(std::runtime_error)
2298 {
2299 ver_string = "0.0";
2300 }
2301 LLStringUtil::replaceChar(ver_string, '.', '0');
2302 ver_string = "0." + ver_string;
2303 F64 version = atof(ver_string.c_str());
2304 // we look for "0.6.8" < version < "0.7.0.3"
2305 if ((version > 0.00608) && (version < 0.0070003))
2306 {
2307 buggy = true;
2308 llwarns << "Setting buggy http ranges mode for current sim, because we're on " << s_version << llendl;
2309 }
2310 }
2311 }
2312 return buggy;
2313}
diff --git a/linden/indra/newview/lltexturefetch.h b/linden/indra/newview/lltexturefetch.h
index 6c6bb52..5fa2d1c 100644
--- a/linden/indra/newview/lltexturefetch.h
+++ b/linden/indra/newview/lltexturefetch.h
@@ -86,6 +86,8 @@ public:
86 86
87 LLTextureInfo* getTextureInfo() { return &mTextureInfo; } 87 LLTextureInfo* getTextureInfo() { return &mTextureInfo; }
88 88
89 static bool hasBuggyHTTPRange(); // *TODO: remove this *HACK once buggy OpenSim versions are gone
90
89protected: 91protected:
90 void addToNetworkQueue(LLTextureFetchWorker* worker); 92 void addToNetworkQueue(LLTextureFetchWorker* worker);
91 void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel); 93 void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel);
diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp
index 7bbaf48..9937ed9 100644
--- a/linden/indra/newview/llvoavatar.cpp
+++ b/linden/indra/newview/llvoavatar.cpp
@@ -5129,12 +5129,6 @@ void LLVOAvatar::updateTextures()
5129 if (texture_dict->mIsLocalTexture) 5129 if (texture_dict->mIsLocalTexture)
5130 { 5130 {
5131 addLocalTextureStats((ETextureIndex)index, imagep, texel_area_ratio, render_avatar, layer_baked[baked_index]); 5131 addLocalTextureStats((ETextureIndex)index, imagep, texel_area_ratio, render_avatar, layer_baked[baked_index]);
5132 // SNOW-8 : temporary snowglobe1.0 fix for baked textures
5133 if (render_avatar && !gGLManager.mIsDisabled )
5134 {
5135 // bind the texture so that its boost level won't be slammed
5136 gGL.getTexUnit(0)->bind(imagep);
5137 }
5138 } 5132 }
5139 else if (texture_dict->mIsBakedTexture) 5133 else if (texture_dict->mIsBakedTexture)
5140 { 5134 {
@@ -5171,8 +5165,14 @@ void LLVOAvatar::addLocalTextureStats( ETextureIndex idx, LLViewerImage* imagep,
5171 F32 desired_pixels; 5165 F32 desired_pixels;
5172 if( mIsSelf ) 5166 if( mIsSelf )
5173 { 5167 {
5174 desired_pixels = llmin(mPixelArea, (F32)TEX_IMAGE_AREA_SELF ); 5168 desired_pixels = llmax(mPixelArea, (F32)TEX_IMAGE_AREA_SELF );
5175 imagep->setBoostLevel(LLViewerImageBoostLevel::BOOST_AVATAR_SELF); 5169 imagep->setBoostLevel(LLViewerImageBoostLevel::BOOST_AVATAR_SELF);
5170 // SNOW-8 : temporary snowglobe1.0 fix for baked textures
5171 if (render_avatar && !gGLManager.mIsDisabled )
5172 {
5173 // bind the texture so that its boost level won't be slammed
5174 gGL.getTexUnit(0)->bind(imagep);
5175 }
5176 } 5176 }
5177 else 5177 else
5178 { 5178 {