diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/llviewerimage.cpp | 151 |
1 files changed, 66 insertions, 85 deletions
diff --git a/linden/indra/newview/llviewerimage.cpp b/linden/indra/newview/llviewerimage.cpp index 0b70f51..33210cf 100644 --- a/linden/indra/newview/llviewerimage.cpp +++ b/linden/indra/newview/llviewerimage.cpp | |||
@@ -4,7 +4,7 @@ | |||
4 | * | 4 | * |
5 | * $LicenseInfo:firstyear=2000&license=viewergpl$ | 5 | * $LicenseInfo:firstyear=2000&license=viewergpl$ |
6 | * | 6 | * |
7 | * Copyright (c) 2000-2008, Linden Research, Inc. | 7 | * Copyright (c) 2000-2009, Linden Research, Inc. |
8 | * | 8 | * |
9 | * Second Life Viewer Source Code | 9 | * Second Life Viewer Source Code |
10 | * The source code in this file ("Source Code") is provided by Linden Lab | 10 | * The source code in this file ("Source Code") is provided by Linden Lab |
@@ -149,23 +149,13 @@ F32 texmem_middle_bound_scale = 0.925f; | |||
149 | //static | 149 | //static |
150 | void LLViewerImage::updateClass(const F32 velocity, const F32 angular_velocity) | 150 | void LLViewerImage::updateClass(const F32 velocity, const F32 angular_velocity) |
151 | { | 151 | { |
152 | sBoundTextureMemory = LLImageGL::sBoundTextureMemory; | 152 | sBoundTextureMemory = LLImageGL::sBoundTextureMemory;//in bytes |
153 | sTotalTextureMemory = LLImageGL::sGlobalTextureMemory; | 153 | sTotalTextureMemory = LLImageGL::sGlobalTextureMemory;//in bytes |
154 | sMaxBoundTextureMem = gImageList.getMaxResidentTexMem(); | 154 | sMaxBoundTextureMem = gImageList.getMaxResidentTexMem();//in MB |
155 | 155 | sMaxTotalTextureMem = gImageList.getMaxTotalTextureMem() ;//in MB | |
156 | sMaxTotalTextureMem = sMaxBoundTextureMem * 2; | 156 | |
157 | if (sMaxBoundTextureMem > 64000000) | 157 | if ((sBoundTextureMemory >> 20) >= sMaxBoundTextureMem || |
158 | { | 158 | (sTotalTextureMemory >> 20) >= sMaxTotalTextureMem) |
159 | sMaxTotalTextureMem -= sMaxBoundTextureMem/4; | ||
160 | } | ||
161 | |||
162 | if ((U32)sMaxTotalTextureMem > gSysMemory.getPhysicalMemoryClamped() - (U32)min_non_tex_system_mem) | ||
163 | { | ||
164 | sMaxTotalTextureMem = (S32)gSysMemory.getPhysicalMemoryClamped() - min_non_tex_system_mem; | ||
165 | } | ||
166 | |||
167 | if (sBoundTextureMemory >= sMaxBoundTextureMem || | ||
168 | sTotalTextureMemory >= sMaxTotalTextureMem) | ||
169 | { | 159 | { |
170 | // If we are using more texture memory than we should, | 160 | // If we are using more texture memory than we should, |
171 | // scale up the desired discard level | 161 | // scale up the desired discard level |
@@ -176,8 +166,8 @@ void LLViewerImage::updateClass(const F32 velocity, const F32 angular_velocity) | |||
176 | } | 166 | } |
177 | } | 167 | } |
178 | else if (sDesiredDiscardBias > 0.0f && | 168 | else if (sDesiredDiscardBias > 0.0f && |
179 | sBoundTextureMemory < sMaxBoundTextureMem*texmem_lower_bound_scale && | 169 | (sBoundTextureMemory >> 20) < sMaxBoundTextureMem*texmem_lower_bound_scale && |
180 | sTotalTextureMemory < sMaxTotalTextureMem*texmem_lower_bound_scale) | 170 | (sTotalTextureMemory >> 20) < sMaxTotalTextureMem*texmem_lower_bound_scale) |
181 | { | 171 | { |
182 | // If we are using less texture memory than we should, | 172 | // If we are using less texture memory than we should, |
183 | // scale down the desired discard level | 173 | // scale down the desired discard level |
@@ -248,7 +238,6 @@ void LLViewerImage::init(bool firstinit) | |||
248 | mTexelsPerImage = 64.f*64.f; | 238 | mTexelsPerImage = 64.f*64.f; |
249 | mMaxVirtualSize = 0.f; | 239 | mMaxVirtualSize = 0.f; |
250 | mDiscardVirtualSize = 0.f; | 240 | mDiscardVirtualSize = 0.f; |
251 | mMaxCosAngle = -1.f; | ||
252 | mRequestedDiscardLevel = -1; | 241 | mRequestedDiscardLevel = -1; |
253 | mRequestedDownloadPriority = 0.f; | 242 | mRequestedDownloadPriority = 0.f; |
254 | mFullyLoaded = FALSE; | 243 | mFullyLoaded = FALSE; |
@@ -432,20 +421,12 @@ BOOL LLViewerImage::createTexture(S32 usename/*= 0*/) | |||
432 | 421 | ||
433 | //============================================================================ | 422 | //============================================================================ |
434 | 423 | ||
435 | void LLViewerImage::addTextureStats(F32 pixel_area, | 424 | void LLViewerImage::addTextureStats(F32 virtual_size) const // = 1.0 |
436 | F32 texel_area_ratio, // = 1.0 | ||
437 | F32 cos_center_angle) const // = 1.0 | ||
438 | { | 425 | { |
439 | F32 virtual_size = pixel_area / texel_area_ratio; | ||
440 | if (virtual_size > mMaxVirtualSize) | 426 | if (virtual_size > mMaxVirtualSize) |
441 | { | 427 | { |
442 | mMaxVirtualSize = virtual_size; | 428 | mMaxVirtualSize = virtual_size; |
443 | } | 429 | } |
444 | cos_center_angle = llclamp(cos_center_angle, -1.f, 1.f); | ||
445 | if (cos_center_angle > mMaxCosAngle) | ||
446 | { | ||
447 | mMaxCosAngle = cos_center_angle; | ||
448 | } | ||
449 | } | 430 | } |
450 | 431 | ||
451 | void LLViewerImage::resetTextureStats(BOOL zero) | 432 | void LLViewerImage::resetTextureStats(BOOL zero) |
@@ -453,12 +434,10 @@ void LLViewerImage::resetTextureStats(BOOL zero) | |||
453 | if (zero) | 434 | if (zero) |
454 | { | 435 | { |
455 | mMaxVirtualSize = 0.0f; | 436 | mMaxVirtualSize = 0.0f; |
456 | mMaxCosAngle = -1.0f; | ||
457 | } | 437 | } |
458 | else if (getBoostLevel() != LLViewerImage::BOOST_SCULPTED) //don't decay sculpted prim textures | 438 | else |
459 | { | 439 | { |
460 | mMaxVirtualSize -= mMaxVirtualSize * .10f; // decay by 5%/update | 440 | mMaxVirtualSize -= mMaxVirtualSize * .10f; // decay by 5%/update |
461 | mMaxCosAngle = -1.0f; | ||
462 | } | 441 | } |
463 | } | 442 | } |
464 | 443 | ||
@@ -477,7 +456,7 @@ void LLViewerImage::processTextureStats() | |||
477 | // If the image has not been significantly visible in a while, we don't want it | 456 | // If the image has not been significantly visible in a while, we don't want it |
478 | mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, (S8)(MAX_DISCARD_LEVEL + 1)); | 457 | mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, (S8)(MAX_DISCARD_LEVEL + 1)); |
479 | } | 458 | } |
480 | else if ((!mFullWidth && !mWidth) || (!mFullHeight && !mHeight)) | 459 | else if ((!mFullWidth && !getCurrentWidth()) || (!mFullHeight && !getCurrentHeight())) |
481 | { | 460 | { |
482 | mDesiredDiscardLevel = mMaxDiscardLevel; | 461 | mDesiredDiscardLevel = mMaxDiscardLevel; |
483 | } | 462 | } |
@@ -558,7 +537,7 @@ void LLViewerImage::processTextureStats() | |||
558 | if ((sDesiredDiscardBias > 0.0f) && | 537 | if ((sDesiredDiscardBias > 0.0f) && |
559 | (current_discard >= 0 && mDesiredDiscardLevel >= current_discard)) | 538 | (current_discard >= 0 && mDesiredDiscardLevel >= current_discard)) |
560 | { | 539 | { |
561 | if ( sBoundTextureMemory > sMaxBoundTextureMem*texmem_middle_bound_scale) | 540 | if ( (sBoundTextureMemory >> 20) > sMaxBoundTextureMem*texmem_middle_bound_scale) |
562 | { | 541 | { |
563 | // Limit the amount of GL memory bound each frame | 542 | // Limit the amount of GL memory bound each frame |
564 | if (mDesiredDiscardLevel > current_discard) | 543 | if (mDesiredDiscardLevel > current_discard) |
@@ -566,7 +545,7 @@ void LLViewerImage::processTextureStats() | |||
566 | increase_discard = TRUE; | 545 | increase_discard = TRUE; |
567 | } | 546 | } |
568 | } | 547 | } |
569 | if ( sTotalTextureMemory > sMaxTotalTextureMem*texmem_middle_bound_scale) | 548 | if ( (sTotalTextureMemory >> 20) > sMaxTotalTextureMem*texmem_middle_bound_scale) |
570 | { | 549 | { |
571 | // Only allow GL to have 2x the video card memory | 550 | // Only allow GL to have 2x the video card memory |
572 | if (!getBoundRecently()) | 551 | if (!getBoundRecently()) |
@@ -608,7 +587,7 @@ F32 LLViewerImage::calcDecodePriority() | |||
608 | F32 priority; | 587 | F32 priority; |
609 | S32 cur_discard = getDiscardLevel(); | 588 | S32 cur_discard = getDiscardLevel(); |
610 | bool have_all_data = (cur_discard >= 0 && (cur_discard <= mDesiredDiscardLevel)); | 589 | bool have_all_data = (cur_discard >= 0 && (cur_discard <= mDesiredDiscardLevel)); |
611 | F32 pixel_priority = fsqrtf(mMaxVirtualSize) * (1.f + mMaxCosAngle); | 590 | F32 pixel_priority = fsqrtf(mMaxVirtualSize); |
612 | const S32 MIN_NOT_VISIBLE_FRAMES = 30; // NOTE: this function is not called every frame | 591 | const S32 MIN_NOT_VISIBLE_FRAMES = 30; // NOTE: this function is not called every frame |
613 | mDecodeFrame++; | 592 | mDecodeFrame++; |
614 | if (pixel_priority > 0.f) | 593 | if (pixel_priority > 0.f) |
@@ -648,17 +627,12 @@ F32 LLViewerImage::calcDecodePriority() | |||
648 | return mDecodePriority; | 627 | return mDecodePriority; |
649 | } | 628 | } |
650 | } | 629 | } |
651 | else if ((mBoostLevel == LLViewerImage::BOOST_SCULPTED) && !have_all_data) | ||
652 | { | ||
653 | // Sculpted images are small, treat them like they always have no data. | ||
654 | priority = 900000.f; | ||
655 | } | ||
656 | else if (cur_discard < 0) | 630 | else if (cur_discard < 0) |
657 | { | 631 | { |
658 | // We don't have any data yet, so we don't know the size of the image, treat as 1024x1024 | 632 | // We don't have any data yet, so we don't know the size of the image, treat as 32x32 |
659 | // priority = 900000.f; | 633 | // priority = 900000.f; |
660 | static const F64 log_2 = log(2.0); | 634 | static const F64 log_2 = log(2.0); |
661 | F32 desired = (F32)(log(1024.0/pixel_priority) / log_2); | 635 | F32 desired = (F32)(log(32.0/pixel_priority) / log_2); |
662 | S32 ddiscard = MAX_DISCARD_LEVEL - (S32)desired + 1; | 636 | S32 ddiscard = MAX_DISCARD_LEVEL - (S32)desired + 1; |
663 | ddiscard = llclamp(ddiscard, 1, 9); | 637 | ddiscard = llclamp(ddiscard, 1, 9); |
664 | priority = ddiscard*100000.f; | 638 | priority = ddiscard*100000.f; |
@@ -712,14 +686,7 @@ F32 LLViewerImage::maxDecodePriority() | |||
712 | void LLViewerImage::setDecodePriority(F32 priority) | 686 | void LLViewerImage::setDecodePriority(F32 priority) |
713 | { | 687 | { |
714 | llassert(!mInImageList); | 688 | llassert(!mInImageList); |
715 | if (priority < 0.0f) | 689 | mDecodePriority = priority; |
716 | { | ||
717 | mDecodePriority = calcDecodePriority(); | ||
718 | } | ||
719 | else | ||
720 | { | ||
721 | mDecodePriority = priority; | ||
722 | } | ||
723 | } | 690 | } |
724 | 691 | ||
725 | void LLViewerImage::setBoostLevel(S32 level) | 692 | void LLViewerImage::setBoostLevel(S32 level) |
@@ -776,6 +743,7 @@ bool LLViewerImage::updateFetch() | |||
776 | S32 current_discard = getDiscardLevel(); | 743 | S32 current_discard = getDiscardLevel(); |
777 | S32 desired_discard = getDesiredDiscardLevel(); | 744 | S32 desired_discard = getDesiredDiscardLevel(); |
778 | F32 decode_priority = getDecodePriority(); | 745 | F32 decode_priority = getDecodePriority(); |
746 | decode_priority = llmax(decode_priority, 0.0f); | ||
779 | 747 | ||
780 | if (mIsFetching) | 748 | if (mIsFetching) |
781 | { | 749 | { |
@@ -793,7 +761,7 @@ bool LLViewerImage::updateFetch() | |||
793 | else | 761 | else |
794 | { | 762 | { |
795 | mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, | 763 | mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, |
796 | mFetchPriority, mFetchDeltaTime, mRequestDeltaTime); | 764 | mFetchPriority, mFetchDeltaTime, mRequestDeltaTime); |
797 | } | 765 | } |
798 | 766 | ||
799 | // We may have data ready regardless of whether or not we are finished (e.g. waiting on write) | 767 | // We may have data ready regardless of whether or not we are finished (e.g. waiting on write) |
@@ -827,7 +795,7 @@ bool LLViewerImage::updateFetch() | |||
827 | 795 | ||
828 | if (!mIsFetching) | 796 | if (!mIsFetching) |
829 | { | 797 | { |
830 | if (mRawDiscardLevel < 0 || mRawDiscardLevel == INVALID_DISCARD_LEVEL) | 798 | if ((decode_priority > 0) && (mRawDiscardLevel < 0 || mRawDiscardLevel == INVALID_DISCARD_LEVEL)) |
831 | { | 799 | { |
832 | // We finished but received no data | 800 | // We finished but received no data |
833 | if (current_discard < 0) | 801 | if (current_discard < 0) |
@@ -850,9 +818,9 @@ bool LLViewerImage::updateFetch() | |||
850 | destroyRawImage(); | 818 | destroyRawImage(); |
851 | } | 819 | } |
852 | } | 820 | } |
853 | else if (mDecodePriority >= 0.f) | 821 | else |
854 | { | 822 | { |
855 | LLAppViewer::getTextureFetch()->updateRequestPriority(mID, mDecodePriority); | 823 | LLAppViewer::getTextureFetch()->updateRequestPriority(mID, decode_priority); |
856 | } | 824 | } |
857 | } | 825 | } |
858 | 826 | ||
@@ -1210,45 +1178,58 @@ void LLViewerImage::setKnownDrawSize(S32 width, S32 height) | |||
1210 | } | 1178 | } |
1211 | 1179 | ||
1212 | // virtual | 1180 | // virtual |
1213 | BOOL LLViewerImage::bind(S32 stage) const | 1181 | bool LLViewerImage::bindError(S32 stage) const |
1214 | { | 1182 | { |
1215 | if (stage == -1) | 1183 | if (stage < 0) return false; |
1184 | |||
1185 | if (gNoRender) | ||
1216 | { | 1186 | { |
1217 | return TRUE; | 1187 | return false; |
1218 | } | 1188 | } |
1189 | |||
1190 | bool res = true; | ||
1219 | 1191 | ||
1220 | if (gNoRender) | 1192 | // On failure to bind, what should we set the currently bound texture to? |
1193 | if (mIsMissingAsset && !sMissingAssetImagep.isNull() && (this != (LLImageGL *)sMissingAssetImagep)) | ||
1221 | { | 1194 | { |
1222 | return true; | 1195 | res = gGL.getTexUnit(stage)->bind(sMissingAssetImagep.get()); |
1223 | } | 1196 | } |
1224 | BOOL res = bindTextureInternal(stage); | 1197 | if (!res && !sDefaultImagep.isNull() && (this != (LLImageGL *)sDefaultImagep)) |
1225 | if (res) | ||
1226 | { | 1198 | { |
1227 | //llassert_always(mIsMissingAsset == FALSE); | 1199 | // use default if we've got it |
1228 | 1200 | res = gGL.getTexUnit(stage)->bind(sDefaultImagep.get()); | |
1229 | } | 1201 | } |
1230 | else | 1202 | if (!res && !sNullImagep.isNull() && (this != (LLImageGL *)sNullImagep)) |
1231 | { | 1203 | { |
1232 | // On failure to bind, what should we set the currently bound texture to? | 1204 | res = gGL.getTexUnit(stage)->bind(sNullImagep.get()); |
1233 | if (mIsMissingAsset && !sMissingAssetImagep.isNull() && (this != (LLImageGL *)sMissingAssetImagep)) | ||
1234 | { | ||
1235 | res = sMissingAssetImagep->bind( stage ); | ||
1236 | } | ||
1237 | if (!res && !sDefaultImagep.isNull() && (this != (LLImageGL *)sDefaultImagep)) | ||
1238 | { | ||
1239 | // use default if we've got it | ||
1240 | res = sDefaultImagep->bind(stage); | ||
1241 | } | ||
1242 | if (!res && !sNullImagep.isNull() && (this != (LLImageGL *)sNullImagep)) | ||
1243 | { | ||
1244 | res = sNullImagep->bind(stage); | ||
1245 | } | ||
1246 | if (!res) | ||
1247 | { | ||
1248 | llwarns << "LLViewerImage::bindTexture failed." << llendl; | ||
1249 | } | ||
1250 | stop_glerror(); | ||
1251 | } | 1205 | } |
1206 | if (!res) | ||
1207 | { | ||
1208 | llwarns << "LLViewerImage::bindError failed." << llendl; | ||
1209 | } | ||
1210 | stop_glerror(); | ||
1211 | return res; | ||
1212 | } | ||
1213 | |||
1214 | bool LLViewerImage::bindDefaultImage(S32 stage) const | ||
1215 | { | ||
1216 | if (stage < 0) return false; | ||
1217 | |||
1218 | bool res = true; | ||
1219 | if (!sDefaultImagep.isNull() && (this != (LLImageGL *)sDefaultImagep)) | ||
1220 | { | ||
1221 | // use default if we've got it | ||
1222 | res = gGL.getTexUnit(stage)->bind(sDefaultImagep.get()); | ||
1223 | } | ||
1224 | if (!res && !sNullImagep.isNull() && (this != (LLImageGL *)sNullImagep)) | ||
1225 | { | ||
1226 | res = gGL.getTexUnit(stage)->bind(sNullImagep.get()); | ||
1227 | } | ||
1228 | if (!res) | ||
1229 | { | ||
1230 | llwarns << "LLViewerImage::bindError failed." << llendl; | ||
1231 | } | ||
1232 | stop_glerror(); | ||
1252 | return res; | 1233 | return res; |
1253 | } | 1234 | } |
1254 | 1235 | ||