diff options
Diffstat (limited to 'linden/indra/newview/llviewerimage.cpp')
-rw-r--r-- | linden/indra/newview/llviewerimage.cpp | 367 |
1 files changed, 264 insertions, 103 deletions
diff --git a/linden/indra/newview/llviewerimage.cpp b/linden/indra/newview/llviewerimage.cpp index 400fb2f..93c17a2 100644 --- a/linden/indra/newview/llviewerimage.cpp +++ b/linden/indra/newview/llviewerimage.cpp | |||
@@ -60,6 +60,8 @@ | |||
60 | #include "pipeline.h" | 60 | #include "pipeline.h" |
61 | #include "llappviewer.h" | 61 | #include "llappviewer.h" |
62 | #include "llface.h" | 62 | #include "llface.h" |
63 | #include "lltextureatlas.h" | ||
64 | #include "lltextureatlasmanager.h" | ||
63 | #include "llviewercamera.h" | 65 | #include "llviewercamera.h" |
64 | /////////////////////////////////////////////////////////////////////////////// | 66 | /////////////////////////////////////////////////////////////////////////////// |
65 | 67 | ||
@@ -102,7 +104,7 @@ void LLViewerImage::initClass() | |||
102 | sNullImagep = new LLImageGL(1,1,3,TRUE); | 104 | sNullImagep = new LLImageGL(1,1,3,TRUE); |
103 | LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,3); | 105 | LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,3); |
104 | raw->clear(0x77, 0x77, 0x77, 0xFF); | 106 | raw->clear(0x77, 0x77, 0x77, 0xFF); |
105 | sNullImagep->createGLTexture(0, raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); | 107 | sNullImagep->createGLTexture(0, raw); |
106 | 108 | ||
107 | #if 1 | 109 | #if 1 |
108 | LLPointer<LLViewerImage> imagep = new LLViewerImage(IMG_DEFAULT); | 110 | LLPointer<LLViewerImage> imagep = new LLViewerImage(IMG_DEFAULT); |
@@ -131,7 +133,7 @@ void LLViewerImage::initClass() | |||
131 | } | 133 | } |
132 | } | 134 | } |
133 | } | 135 | } |
134 | imagep->createGLTexture(0, image_raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); | 136 | imagep->createGLTexture(0, image_raw); |
135 | image_raw = NULL; | 137 | image_raw = NULL; |
136 | gImageList.addImage(imagep); | 138 | gImageList.addImage(imagep); |
137 | imagep->dontDiscard(); | 139 | imagep->dontDiscard(); |
@@ -141,48 +143,48 @@ void LLViewerImage::initClass() | |||
141 | sSmokeImagep = gImageList.getImage(IMG_SMOKE, TRUE, TRUE); | 143 | sSmokeImagep = gImageList.getImage(IMG_SMOKE, TRUE, TRUE); |
142 | sSmokeImagep->setNoDelete() ; | 144 | sSmokeImagep->setNoDelete() ; |
143 | 145 | ||
144 | if(gAuditTexture) | 146 | #if !LL_RELEASE_FOR_DOWNLOAD |
147 | sDefaultTexturep = new LLImageGL() ; | ||
148 | image_raw = new LLImageRaw(dim,dim,3); | ||
149 | data = image_raw->getData(); | ||
150 | for (S32 i = 0; i<dim; i++) | ||
145 | { | 151 | { |
146 | sDefaultTexturep = new LLImageGL() ; | 152 | for (S32 j = 0; j<dim; j++) |
147 | image_raw = new LLImageRaw(dim,dim,3); | ||
148 | data = image_raw->getData(); | ||
149 | for (S32 i = 0; i<dim; i++) | ||
150 | { | 153 | { |
151 | for (S32 j = 0; j<dim; j++) | 154 | const S32 border = 2; |
155 | if (i<border || j<border || i>=(dim-border) || j>=(dim-border)) | ||
152 | { | 156 | { |
153 | const S32 border = 2; | 157 | *data++ = 0xff; |
154 | if (i<border || j<border || i>=(dim-border) || j>=(dim-border)) | 158 | *data++ = 0xff; |
155 | { | 159 | *data++ = 0xff; |
156 | *data++ = 0xff; | 160 | } |
157 | *data++ = 0xff; | 161 | else |
158 | *data++ = 0xff; | 162 | { |
159 | } | 163 | *data++ = 0xff; |
160 | else | 164 | *data++ = 0xff; |
161 | { | 165 | *data++ = 0x00; |
162 | *data++ = 0xff; | ||
163 | *data++ = 0xff; | ||
164 | *data++ = 0x00; | ||
165 | } | ||
166 | } | 166 | } |
167 | } | 167 | } |
168 | sDefaultTexturep->createGLTexture(0, image_raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); | ||
169 | image_raw = NULL; | ||
170 | sDefaultTexturep->dontDiscard(); | ||
171 | } | 168 | } |
169 | sDefaultTexturep->createGLTexture(0, image_raw); | ||
170 | image_raw = NULL; | ||
171 | sDefaultTexturep->dontDiscard(); | ||
172 | #endif | ||
172 | } | 173 | } |
173 | 174 | ||
174 | // static | 175 | // static |
175 | void LLViewerImage::cleanupClass() | 176 | void LLViewerImage::cleanupClass() |
176 | { | 177 | { |
177 | stop_glerror(); | 178 | stop_glerror(); |
178 | LLImageGL::cleanupClass() ; | ||
179 | |||
180 | sNullImagep = NULL; | 179 | sNullImagep = NULL; |
181 | sDefaultImagep = NULL; | 180 | sDefaultImagep = NULL; |
182 | sSmokeImagep = NULL; | 181 | sSmokeImagep = NULL; |
183 | sMissingAssetImagep = NULL; | 182 | sMissingAssetImagep = NULL; |
184 | sWhiteImagep = NULL; | 183 | sWhiteImagep = NULL; |
185 | sDefaultTexturep = NULL ; | 184 | |
185 | #if !LL_RELEASE_FOR_DOWNLOAD | ||
186 | LLImageGL::sDefaultTexturep = NULL ; | ||
187 | #endif | ||
186 | } | 188 | } |
187 | 189 | ||
188 | // tuning params | 190 | // tuning params |
@@ -231,12 +233,7 @@ void LLViewerImage::updateClass(const F32 velocity, const F32 angular_velocity) | |||
231 | } | 233 | } |
232 | sDesiredDiscardBias = llclamp(sDesiredDiscardBias, sDesiredDiscardBiasMin, sDesiredDiscardBiasMax); | 234 | sDesiredDiscardBias = llclamp(sDesiredDiscardBias, sDesiredDiscardBiasMin, sDesiredDiscardBiasMax); |
233 | 235 | ||
234 | F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ; | 236 | LLImageGL::sUseTextureAtlas = gSavedSettings.getBOOL("EnableTextureAtlas") ; |
235 | F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed(); | ||
236 | sCameraMovingDiscardBias = (S8)llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1) ; | ||
237 | |||
238 | LLViewerImage::sFreezeImageScalingDown = (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) < 0.75f * sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale) && | ||
239 | (BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) < 0.75f * sMaxTotalTextureMemInMegaBytes * texmem_middle_bound_scale) ; | ||
240 | } | 237 | } |
241 | 238 | ||
242 | // static | 239 | // static |
@@ -382,6 +379,7 @@ LLViewerImage::~LLViewerImage() | |||
382 | void LLViewerImage::cleanup() | 379 | void LLViewerImage::cleanup() |
383 | { | 380 | { |
384 | mFaceList.clear() ; | 381 | mFaceList.clear() ; |
382 | |||
385 | for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); | 383 | for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); |
386 | iter != mLoadedCallbackList.end(); ) | 384 | iter != mLoadedCallbackList.end(); ) |
387 | { | 385 | { |
@@ -411,6 +409,192 @@ void LLViewerImage::reinit(BOOL usemipmaps /* = TRUE */) | |||
411 | setSize(0,0,0); | 409 | setSize(0,0,0); |
412 | } | 410 | } |
413 | 411 | ||
412 | void LLViewerImage::resetFaceAtlas() | ||
413 | { | ||
414 | //Nothing should be done here. | ||
415 | } | ||
416 | |||
417 | //invalidate all atlas slots for this image. | ||
418 | void LLViewerImage::invalidateAtlas(BOOL rebuild_geom) | ||
419 | { | ||
420 | for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter) | ||
421 | { | ||
422 | if(*iter) | ||
423 | { | ||
424 | LLFace* facep = (LLFace*)*iter ; | ||
425 | facep->removeAtlas() ; | ||
426 | if(rebuild_geom && facep->getDrawable() && facep->getDrawable()->getSpatialGroup()) | ||
427 | { | ||
428 | facep->getDrawable()->getSpatialGroup()->setState(LLSpatialGroup::GEOM_DIRTY); | ||
429 | } | ||
430 | } | ||
431 | } | ||
432 | } | ||
433 | |||
434 | BOOL LLViewerImage::insertToAtlas() | ||
435 | { | ||
436 | if(mFaceList.size() < 1) | ||
437 | { | ||
438 | return FALSE ; | ||
439 | } | ||
440 | if(!canAddToAtlas()) | ||
441 | { | ||
442 | return FALSE ; | ||
443 | } | ||
444 | if(getDiscardLevelInAtlas() > 0 && mRawDiscardLevel >= getDiscardLevelInAtlas()) | ||
445 | { | ||
446 | return FALSE ; | ||
447 | } | ||
448 | if(!LLTextureAtlasManager::getInstance()->canAddToAtlas(mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents(), getTexTarget())) | ||
449 | { | ||
450 | return FALSE ; | ||
451 | } | ||
452 | |||
453 | BOOL ret = TRUE ;//if ret is set to false, will generate a gl texture for this image. | ||
454 | S32 raw_w = mRawImage->getWidth() ; | ||
455 | S32 raw_h = mRawImage->getHeight() ; | ||
456 | F32 xscale = 1.0f, yscale = 1.0f ; | ||
457 | LLPointer<LLTextureAtlasSlot> slot_infop; | ||
458 | LLTextureAtlasSlot* cur_slotp ;//no need to be smart pointer. | ||
459 | LLSpatialGroup* groupp ; | ||
460 | LLFace* facep; | ||
461 | |||
462 | //if the atlas slot pointers for some faces are null, process them later. | ||
463 | ll_face_list_t waiting_list ; | ||
464 | |||
465 | for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter) | ||
466 | { | ||
467 | if(*iter) | ||
468 | { | ||
469 | facep = (LLFace*)*iter ; | ||
470 | |||
471 | //face can not use atlas. | ||
472 | if(!facep->canUseAtlas()) | ||
473 | { | ||
474 | if(facep->getAtlasInfo()) | ||
475 | { | ||
476 | facep->removeAtlas() ; | ||
477 | } | ||
478 | ret = FALSE ; | ||
479 | continue ; | ||
480 | } | ||
481 | |||
482 | //the atlas slot is updated | ||
483 | slot_infop = facep->getAtlasInfo() ; | ||
484 | groupp = facep->getDrawable()->getSpatialGroup() ; | ||
485 | |||
486 | if(slot_infop) | ||
487 | { | ||
488 | if(slot_infop->getSpatialGroup() != groupp) | ||
489 | { | ||
490 | if((cur_slotp = groupp->getCurUpdatingSlot(this))) //switch slot | ||
491 | { | ||
492 | facep->setAtlasInfo(cur_slotp) ; | ||
493 | facep->setAtlasInUse(TRUE) ; | ||
494 | continue ; | ||
495 | } | ||
496 | else //do not forget to update slot_infop->getSpatialGroup(). | ||
497 | { | ||
498 | LLSpatialGroup* gp = slot_infop->getSpatialGroup() ; | ||
499 | gp->setCurUpdatingTime(gFrameCount) ; | ||
500 | gp->setCurUpdatingTexture(this) ; | ||
501 | gp->setCurUpdatingSlot(slot_infop) ; | ||
502 | } | ||
503 | } | ||
504 | else //same group | ||
505 | { | ||
506 | if(gFrameCount && slot_infop->getUpdatedTime() == gFrameCount)//slot is just updated | ||
507 | { | ||
508 | facep->setAtlasInUse(TRUE) ; | ||
509 | continue ; | ||
510 | } | ||
511 | } | ||
512 | } | ||
513 | else | ||
514 | { | ||
515 | //if the slot is null, wait to process them later. | ||
516 | waiting_list.push_back(facep) ; | ||
517 | continue ; | ||
518 | } | ||
519 | |||
520 | //---------- | ||
521 | //insert to atlas | ||
522 | if(!LLImageGL::createGLTextureInAtlas(mRawDiscardLevel, mRawImage, slot_infop->getAtlas(), slot_infop->getSlotCol(), slot_infop->getSlotRow())) | ||
523 | { | ||
524 | //the texture does not qualify to add to atlas, do not bother to try for other faces. | ||
525 | //invalidateAtlas(); | ||
526 | return FALSE ; | ||
527 | } | ||
528 | |||
529 | //update texture scale | ||
530 | slot_infop->getAtlas()->getTexCoordScale(raw_w, raw_h, xscale, yscale) ; | ||
531 | slot_infop->setTexCoordScale(xscale, yscale) ; | ||
532 | slot_infop->setValid() ; | ||
533 | slot_infop->setUpdatedTime(gFrameCount) ; | ||
534 | |||
535 | //update spatial group atlas info | ||
536 | groupp->setCurUpdatingTime(gFrameCount) ; | ||
537 | groupp->setCurUpdatingTexture(this) ; | ||
538 | groupp->setCurUpdatingSlot(slot_infop) ; | ||
539 | |||
540 | //make the face to switch to the atlas. | ||
541 | facep->setAtlasInUse(TRUE) ; | ||
542 | } | ||
543 | } | ||
544 | |||
545 | //process the waiting_list | ||
546 | for(ll_face_list_t::iterator iter = waiting_list.begin(); iter != waiting_list.end(); ++iter) | ||
547 | { | ||
548 | facep = (LLFace*)*iter ; | ||
549 | groupp = facep->getDrawable()->getSpatialGroup() ; | ||
550 | |||
551 | //check if this texture already inserted to atlas for this group | ||
552 | if((cur_slotp = groupp->getCurUpdatingSlot(this))) | ||
553 | { | ||
554 | facep->setAtlasInfo(cur_slotp) ; | ||
555 | facep->setAtlasInUse(TRUE) ; | ||
556 | continue ; | ||
557 | } | ||
558 | |||
559 | //need to reserve a slot from atlas | ||
560 | slot_infop = LLTextureAtlasManager::getInstance()->reserveAtlasSlot(llmax(mFullWidth, mFullHeight), getComponents(), groupp, this) ; | ||
561 | |||
562 | facep->setAtlasInfo(slot_infop) ; | ||
563 | |||
564 | groupp->setCurUpdatingTime(gFrameCount) ; | ||
565 | groupp->setCurUpdatingTexture(this) ; | ||
566 | groupp->setCurUpdatingSlot(slot_infop) ; | ||
567 | |||
568 | //slot allocation failed. | ||
569 | if(!slot_infop || !slot_infop->getAtlas()) | ||
570 | { | ||
571 | ret = FALSE ; | ||
572 | facep->setAtlasInUse(FALSE) ; | ||
573 | continue ; | ||
574 | } | ||
575 | |||
576 | //insert to atlas | ||
577 | if(!LLImageGL::createGLTextureInAtlas(mRawDiscardLevel, mRawImage, slot_infop->getAtlas(), slot_infop->getSlotCol(), slot_infop->getSlotRow())) | ||
578 | { | ||
579 | //the texture does not qualify to add to atlas, do not bother to try for other faces. | ||
580 | ret = FALSE ; | ||
581 | //invalidateAtlas(); | ||
582 | break ; | ||
583 | } | ||
584 | |||
585 | //update texture scale | ||
586 | slot_infop->getAtlas()->getTexCoordScale(raw_w, raw_h, xscale, yscale) ; | ||
587 | slot_infop->setTexCoordScale(xscale, yscale) ; | ||
588 | slot_infop->setValid() ; | ||
589 | slot_infop->setUpdatedTime(gFrameCount) ; | ||
590 | |||
591 | //make the face to switch to the atlas. | ||
592 | facep->setAtlasInUse(TRUE) ; | ||
593 | } | ||
594 | |||
595 | return ret ; | ||
596 | } | ||
597 | |||
414 | /////////////////////////////////////////////////////////////////////////////// | 598 | /////////////////////////////////////////////////////////////////////////////// |
415 | // ONLY called from LLViewerImageList | 599 | // ONLY called from LLViewerImageList |
416 | void LLViewerImage::destroyTexture() | 600 | void LLViewerImage::destroyTexture() |
@@ -432,7 +616,7 @@ void LLViewerImage::addToCreateTexture() | |||
432 | if(isForSculptOnly()) | 616 | if(isForSculptOnly()) |
433 | { | 617 | { |
434 | //just update some variables, not to create a real GL texture. | 618 | //just update some variables, not to create a real GL texture. |
435 | createGLTexture(mRawDiscardLevel, mRawImage, 0, FALSE) ; | 619 | createGLTexture(mRawDiscardLevel, mRawImage, 0) ; |
436 | mNeedsCreateTexture = FALSE ; | 620 | mNeedsCreateTexture = FALSE ; |
437 | destroyRawImage(); | 621 | destroyRawImage(); |
438 | } | 622 | } |
@@ -495,7 +679,7 @@ BOOL LLViewerImage::createTexture(S32 usename/*= 0*/) | |||
495 | mNeedsCreateTexture = FALSE; | 679 | mNeedsCreateTexture = FALSE; |
496 | if (mRawImage.isNull()) | 680 | if (mRawImage.isNull()) |
497 | { | 681 | { |
498 | llerrs << "LLViewerImage trying to create texture with no Raw Image" << llendl; | 682 | llwarns << "LLViewerImage trying to create texture with no Raw Image" << llendl; |
499 | } | 683 | } |
500 | // llinfos << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ", | 684 | // llinfos << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ", |
501 | // mRawDiscardLevel, | 685 | // mRawDiscardLevel, |
@@ -519,32 +703,25 @@ BOOL LLViewerImage::createTexture(S32 usename/*= 0*/) | |||
519 | mOrigHeight = mFullHeight; | 703 | mOrigHeight = mFullHeight; |
520 | } | 704 | } |
521 | 705 | ||
522 | bool size_okay = true; | 706 | if (LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight())) |
523 | |||
524 | U32 raw_width = mRawImage->getWidth() << mRawDiscardLevel; | ||
525 | U32 raw_height = mRawImage->getHeight() << mRawDiscardLevel; | ||
526 | if( raw_width > MAX_IMAGE_SIZE || raw_height > MAX_IMAGE_SIZE ) | ||
527 | { | 707 | { |
528 | llinfos << "Width or height is greater than " << MAX_IMAGE_SIZE << ": (" << raw_width << "," << raw_height << ")" << llendl; | 708 | if(!(res = insertToAtlas())) |
529 | size_okay = false; | 709 | { |
710 | res = LLImageGL::createGLTexture(mRawDiscardLevel, mRawImage, usename); | ||
711 | resetFaceAtlas() ; | ||
712 | } | ||
530 | } | 713 | } |
531 | 714 | ||
532 | if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight())) | 715 | else |
533 | { | 716 | { |
534 | // A non power-of-two image was uploaded (through a non standard client) | 717 | // A non power-of-two image was uploaded (through a non standard client) |
535 | llinfos << "Non power of two width or height: (" << mRawImage->getWidth() << "," << mRawImage->getHeight() << ")" << llendl; | ||
536 | size_okay = false; | ||
537 | } | ||
538 | |||
539 | if( !size_okay ) | ||
540 | { | ||
541 | // An inappropriately-sized image was uploaded (through a non standard client) | ||
542 | // We treat these images as missing assets which causes them to | 718 | // We treat these images as missing assets which causes them to |
543 | // be renderd as 'missing image' and to stop requesting data | 719 | // be renderd as 'missing image' and to stop requesting data |
544 | setIsMissingAsset(); | 720 | setIsMissingAsset(); |
545 | destroyRawImage(); | 721 | destroyRawImage(); |
546 | return FALSE; | 722 | return FALSE; |
547 | } | 723 | } |
724 | |||
548 | if (mRawImage->getComponents()>4) | 725 | if (mRawImage->getComponents()>4) |
549 | { | 726 | { |
550 | LL_DEBUGS("Openjpeg")<<"broken raw image" << LL_ENDL; | 727 | LL_DEBUGS("Openjpeg")<<"broken raw image" << LL_ENDL; |
@@ -553,7 +730,6 @@ BOOL LLViewerImage::createTexture(S32 usename/*= 0*/) | |||
553 | return FALSE; | 730 | return FALSE; |
554 | } | 731 | } |
555 | 732 | ||
556 | res = LLImageGL::createGLTexture(mRawDiscardLevel, mRawImage, usename); | ||
557 | } | 733 | } |
558 | 734 | ||
559 | // | 735 | // |
@@ -655,6 +831,7 @@ void LLViewerImage::processTextureStats() | |||
655 | S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT); | 831 | S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT); |
656 | S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT); | 832 | S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT); |
657 | mTexelsPerImage = (F32)fullwidth * fullheight; | 833 | mTexelsPerImage = (F32)fullwidth * fullheight; |
834 | |||
658 | F32 discard_level = 0.f; | 835 | F32 discard_level = 0.f; |
659 | 836 | ||
660 | // If we know the output width and height, we can force the discard | 837 | // If we know the output width and height, we can force the discard |
@@ -662,7 +839,8 @@ void LLViewerImage::processTextureStats() | |||
662 | // data than we need to. | 839 | // data than we need to. |
663 | if (mBoostLevel == LLViewerImageBoostLevel::BOOST_UI || | 840 | if (mBoostLevel == LLViewerImageBoostLevel::BOOST_UI || |
664 | mBoostLevel == LLViewerImageBoostLevel::BOOST_PREVIEW || | 841 | mBoostLevel == LLViewerImageBoostLevel::BOOST_PREVIEW || |
665 | mBoostLevel == LLViewerImageBoostLevel::BOOST_AVATAR_SELF) // JAMESDEBUG what about AVATAR_BAKED_SELF? | 842 | mBoostLevel == LLViewerImageBoostLevel::BOOST_AVATAR_SELF || |
843 | mBoostLevel == LLViewerImageBoostLevel::BOOST_AVATAR_BAKED_SELF) | ||
666 | { | 844 | { |
667 | discard_level = 0; // full res | 845 | discard_level = 0; // full res |
668 | } | 846 | } |
@@ -677,12 +855,6 @@ void LLViewerImage::processTextureStats() | |||
677 | } | 855 | } |
678 | else | 856 | else |
679 | { | 857 | { |
680 | if(isLargeImage() && !isJustBound() && mAdditionalDecodePriority < 1.0f) | ||
681 | { | ||
682 | //if is a big image and not being used recently, nor close to the view point, do not load hi-res data. | ||
683 | mMaxVirtualSize = llmin(mMaxVirtualSize, (F32)LLViewerImage::sMinLargeImageSize) ; | ||
684 | } | ||
685 | |||
686 | if ((mCalculatedDiscardLevel >= 0.f) && | 858 | if ((mCalculatedDiscardLevel >= 0.f) && |
687 | (llabs(mMaxVirtualSize - mDiscardVirtualSize) < mMaxVirtualSize*.20f)) | 859 | (llabs(mMaxVirtualSize - mDiscardVirtualSize) < mMaxVirtualSize*.20f)) |
688 | { | 860 | { |
@@ -705,6 +877,7 @@ void LLViewerImage::processTextureStats() | |||
705 | discard_level += sCameraMovingDiscardBias ; | 877 | discard_level += sCameraMovingDiscardBias ; |
706 | } | 878 | } |
707 | discard_level = floorf(discard_level); | 879 | discard_level = floorf(discard_level); |
880 | // discard_level -= (gImageList.mVideoMemorySetting>>1); // more video ram = higher detail | ||
708 | 881 | ||
709 | F32 min_discard = 0.f; | 882 | F32 min_discard = 0.f; |
710 | if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT) | 883 | if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT) |
@@ -726,15 +899,12 @@ void LLViewerImage::processTextureStats() | |||
726 | if ((sDesiredDiscardBias > 0.0f) && | 899 | if ((sDesiredDiscardBias > 0.0f) && |
727 | (current_discard >= 0 && mDesiredDiscardLevel >= current_discard)) | 900 | (current_discard >= 0 && mDesiredDiscardLevel >= current_discard)) |
728 | { | 901 | { |
729 | // Limit the amount of GL memory bound each frame | 902 | if ( (sBoundTextureMemoryInBytes >> 20) > sMaxBoundTextureMemInMegaBytes*texmem_middle_bound_scale) |
730 | if ( (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) > sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale) && | ||
731 | (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel)) | ||
732 | { | 903 | { |
733 | scaleDown() ; | 904 | scaleDown() ; |
734 | } | 905 | } |
735 | // Only allow GL to have 2x the video card memory | 906 | // Only allow GL to have 2x the video card memory |
736 | else if ( (BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) > sMaxTotalTextureMemInMegaBytes*texmem_middle_bound_scale) && | 907 | else if (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel) |
737 | (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel)) | ||
738 | { | 908 | { |
739 | scaleDown() ; | 909 | scaleDown() ; |
740 | } | 910 | } |
@@ -756,7 +926,7 @@ void LLViewerImage::updateVirtualSize() | |||
756 | if(facep->getDrawable()->isRecentlyVisible()) | 926 | if(facep->getDrawable()->isRecentlyVisible()) |
757 | { | 927 | { |
758 | addTextureStats(facep->getVirtualSize()) ; | 928 | addTextureStats(facep->getVirtualSize()) ; |
759 | setAdditionalDecodePriority(facep->getImportanceToCamera()) ; | 929 | //setAdditionalDecodePriority(facep->getImportanceToCamera()) ; |
760 | } | 930 | } |
761 | } | 931 | } |
762 | } | 932 | } |
@@ -796,6 +966,7 @@ void LLViewerImage::switchToCachedImage() | |||
796 | mNeedsCreateTexture = TRUE; | 966 | mNeedsCreateTexture = TRUE; |
797 | } | 967 | } |
798 | } | 968 | } |
969 | |||
799 | //============================================================================ | 970 | //============================================================================ |
800 | 971 | ||
801 | F32 LLViewerImage::calcDecodePriority() | 972 | F32 LLViewerImage::calcDecodePriority() |
@@ -817,13 +988,6 @@ F32 LLViewerImage::calcDecodePriority() | |||
817 | } | 988 | } |
818 | 989 | ||
819 | S32 cur_discard = getDiscardLevel(); | 990 | S32 cur_discard = getDiscardLevel(); |
820 | |||
821 | //no need to update if the texture reaches its highest res and the memory is sufficient. | ||
822 | //if(LLViewerImage::sFreezeImageScalingDown && !cur_discard) | ||
823 | //{ | ||
824 | // return -5.0f ; | ||
825 | //} | ||
826 | |||
827 | bool have_all_data = (cur_discard >= 0 && (cur_discard <= mDesiredDiscardLevel)); | 991 | bool have_all_data = (cur_discard >= 0 && (cur_discard <= mDesiredDiscardLevel)); |
828 | F32 pixel_priority = fsqrtf(mMaxVirtualSize); | 992 | F32 pixel_priority = fsqrtf(mMaxVirtualSize); |
829 | const S32 MIN_NOT_VISIBLE_FRAMES = 30; // NOTE: this function is not called every frame | 993 | const S32 MIN_NOT_VISIBLE_FRAMES = 30; // NOTE: this function is not called every frame |
@@ -842,14 +1006,6 @@ F32 LLViewerImage::calcDecodePriority() | |||
842 | { | 1006 | { |
843 | priority = -1.0f ; | 1007 | priority = -1.0f ; |
844 | } | 1008 | } |
845 | else if (!isJustBound() && mCachedRawImageReady) | ||
846 | { | ||
847 | priority = -1.0f; | ||
848 | } | ||
849 | else if(mCachedRawDiscardLevel > -1 && mDesiredDiscardLevel >= mCachedRawDiscardLevel) | ||
850 | { | ||
851 | priority = -1.0f; | ||
852 | } | ||
853 | else if (mDesiredDiscardLevel > mMaxDiscardLevel) | 1009 | else if (mDesiredDiscardLevel > mMaxDiscardLevel) |
854 | { | 1010 | { |
855 | // Don't decode anything we don't need | 1011 | // Don't decode anything we don't need |
@@ -910,7 +1066,6 @@ F32 LLViewerImage::calcDecodePriority() | |||
910 | ddiscard-=2; | 1066 | ddiscard-=2; |
911 | } | 1067 | } |
912 | ddiscard = llclamp(ddiscard, 0, 4); | 1068 | ddiscard = llclamp(ddiscard, 0, 4); |
913 | |||
914 | priority = ddiscard*100000.f; | 1069 | priority = ddiscard*100000.f; |
915 | } | 1070 | } |
916 | if (priority > 0.0f) | 1071 | if (priority > 0.0f) |
@@ -942,7 +1097,7 @@ F32 LLViewerImage::calcDecodePriority() | |||
942 | //static | 1097 | //static |
943 | F32 LLViewerImage::maxDecodePriority() | 1098 | F32 LLViewerImage::maxDecodePriority() |
944 | { | 1099 | { |
945 | return 6000000.f; | 1100 | return 6000000.f; // KL 2000000 in render pipeline |
946 | } | 1101 | } |
947 | 1102 | ||
948 | void LLViewerImage::setDecodePriority(F32 priority) | 1103 | void LLViewerImage::setDecodePriority(F32 priority) |
@@ -969,10 +1124,7 @@ void LLViewerImage::setBoostLevel(S32 level) | |||
969 | { | 1124 | { |
970 | mBoostLevel = level; | 1125 | mBoostLevel = level; |
971 | 1126 | ||
972 | if(gAuditTexture) | 1127 | |
973 | { | ||
974 | setCategory(mBoostLevel); | ||
975 | } | ||
976 | 1128 | ||
977 | if(mBoostLevel != LLViewerImageBoostLevel::BOOST_NONE) | 1129 | if(mBoostLevel != LLViewerImageBoostLevel::BOOST_NONE) |
978 | { | 1130 | { |
@@ -1022,11 +1174,15 @@ bool LLViewerImage::updateFetch() | |||
1022 | return false; // process any raw image data in callbacks before replacing | 1174 | return false; // process any raw image data in callbacks before replacing |
1023 | } | 1175 | } |
1024 | 1176 | ||
1177 | mFetchState = 0; | ||
1178 | mFetchPriority = 0; | ||
1179 | mFetchDeltaTime = 999999.f; | ||
1180 | mRequestDeltaTime = 999999.f; | ||
1025 | S32 current_discard = getDiscardLevel(); | 1181 | S32 current_discard = getDiscardLevel(); |
1026 | S32 desired_discard = getDesiredDiscardLevel(); | 1182 | S32 desired_discard = getDesiredDiscardLevel(); |
1027 | F32 decode_priority = getDecodePriority(); | 1183 | F32 decode_priority = getDecodePriority(); |
1028 | decode_priority = llmax(decode_priority, 0.0f); | 1184 | decode_priority = llmax(decode_priority, 0.0f); |
1029 | decode_priority = llmin(decode_priority, maxDecodePriority()); | 1185 | //decode_priority = llmin(decode_priority, maxDecodePriority()); |
1030 | 1186 | ||
1031 | if (mIsFetching) | 1187 | if (mIsFetching) |
1032 | { | 1188 | { |
@@ -1059,7 +1215,6 @@ bool LLViewerImage::updateFetch() | |||
1059 | if (mRawImage.notNull()) | 1215 | if (mRawImage.notNull()) |
1060 | { | 1216 | { |
1061 | mRawDiscardLevel = fetch_discard; | 1217 | mRawDiscardLevel = fetch_discard; |
1062 | |||
1063 | if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) && | 1218 | if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) && |
1064 | (current_discard < 0 || mRawDiscardLevel < current_discard)) | 1219 | (current_discard < 0 || mRawDiscardLevel < current_discard)) |
1065 | { | 1220 | { |
@@ -1178,10 +1333,6 @@ bool LLViewerImage::updateFetch() | |||
1178 | { | 1333 | { |
1179 | make_request = false; | 1334 | make_request = false; |
1180 | } | 1335 | } |
1181 | else if (!isJustBound() && mCachedRawImageReady) | ||
1182 | { | ||
1183 | make_request = false; | ||
1184 | } | ||
1185 | else | 1336 | else |
1186 | { | 1337 | { |
1187 | if (mIsFetching) | 1338 | if (mIsFetching) |
@@ -1216,14 +1367,13 @@ bool LLViewerImage::updateFetch() | |||
1216 | w, h, c, desired_discard, needsAux()); | 1367 | w, h, c, desired_discard, needsAux()); |
1217 | 1368 | ||
1218 | if (fetch_request_created) | 1369 | if (fetch_request_created) |
1219 | { | 1370 | { |
1220 | mHasFetcher = TRUE; | 1371 | mHasFetcher = TRUE; |
1221 | mIsFetching = TRUE; | 1372 | mIsFetching = TRUE; |
1222 | mRequestedDiscardLevel = desired_discard; | 1373 | mRequestedDiscardLevel = desired_discard; |
1223 | |||
1224 | mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, | 1374 | mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, |
1225 | mFetchPriority, mFetchDeltaTime, mRequestDeltaTime); | 1375 | mFetchPriority, mFetchDeltaTime, mRequestDeltaTime); |
1226 | } | 1376 | } |
1227 | 1377 | ||
1228 | // if createRequest() failed, we're finishing up a request for this UUID, | 1378 | // if createRequest() failed, we're finishing up a request for this UUID, |
1229 | // wait for it to complete | 1379 | // wait for it to complete |
@@ -1295,12 +1445,12 @@ BOOL LLViewerImage::forceFetch() | |||
1295 | w, h, c, desired_discard, needsAux()); | 1445 | w, h, c, desired_discard, needsAux()); |
1296 | 1446 | ||
1297 | if (fetch_request_created) | 1447 | if (fetch_request_created) |
1298 | { | 1448 | { |
1299 | mHasFetcher = TRUE; | 1449 | mHasFetcher = TRUE; |
1300 | mIsFetching = TRUE; | 1450 | mIsFetching = TRUE; |
1301 | // Set the image's decode priority to maxDecodePriority() too, or updateFetch() will set | 1451 | // Set the image's decode priority to maxDecodePriority() too, or updateFetch() will set |
1302 | // the request priority to 0 and terminate the fetch before we even started (SNOW-203). | 1452 | // the request priority to 0 and terminate the fetch before we even started (SNOW-203). |
1303 | gImageList.bumpToMaxDecodePriority(this); | 1453 | // gImageList.bumpToMaxDecodePriority(this); // Kl force immediate update?? |
1304 | mRequestedDiscardLevel = desired_discard ; | 1454 | mRequestedDiscardLevel = desired_discard ; |
1305 | 1455 | ||
1306 | mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, | 1456 | mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, |
@@ -1473,8 +1623,8 @@ bool LLViewerImage::doLoadedCallbacks() | |||
1473 | 1623 | ||
1474 | destroyRawImage(); | 1624 | destroyRawImage(); |
1475 | readBackRawImage(gl_discard); | 1625 | readBackRawImage(gl_discard); |
1476 | llassert_always(mRawImage.notNull()); | 1626 | //llassert_always(mRawImage.notNull()); |
1477 | llassert_always(!mNeedsAux || mAuxRawImage.notNull()); | 1627 | //llassert_always(!mNeedsAux || mAuxRawImage.notNull()); |
1478 | } | 1628 | } |
1479 | 1629 | ||
1480 | // | 1630 | // |
@@ -1636,7 +1786,18 @@ bool LLViewerImage::bindDefaultImage(S32 stage) | |||
1636 | //virtual | 1786 | //virtual |
1637 | void LLViewerImage::forceImmediateUpdate() | 1787 | void LLViewerImage::forceImmediateUpdate() |
1638 | { | 1788 | { |
1639 | gImageList.bumpToMaxDecodePriority(this) ; | 1789 | //only immediately update a deleted texture which is now being re-used. |
1790 | if(!isDeleted()) | ||
1791 | { | ||
1792 | return ; | ||
1793 | } | ||
1794 | //if already called forceImmediateUpdate() | ||
1795 | if(mInImageList && mDecodePriority == LLViewerImage::maxDecodePriority()) | ||
1796 | { | ||
1797 | return ; | ||
1798 | } | ||
1799 | |||
1800 | gImageList.forceImmediateUpdate(this) ; | ||
1640 | return ; | 1801 | return ; |
1641 | } | 1802 | } |
1642 | 1803 | ||
@@ -1647,7 +1808,7 @@ LLImageRaw* LLViewerImage::readBackRawImage(S8 discard_level) | |||
1647 | llassert_always(mComponents > 0); | 1808 | llassert_always(mComponents > 0); |
1648 | if (mRawImage.notNull()) | 1809 | if (mRawImage.notNull()) |
1649 | { | 1810 | { |
1650 | llerrs << "called with existing mRawImage" << llendl; | 1811 | llwarns << "called with existing mRawImage" << llendl; |
1651 | mRawImage = NULL; | 1812 | mRawImage = NULL; |
1652 | } | 1813 | } |
1653 | 1814 | ||
@@ -1665,7 +1826,7 @@ LLImageRaw* LLViewerImage::readBackRawImage(S8 discard_level) | |||
1665 | 1826 | ||
1666 | sRawCount++; | 1827 | sRawCount++; |
1667 | mIsRawImageValid = TRUE; | 1828 | mIsRawImageValid = TRUE; |
1668 | 1829 | ||
1669 | return mRawImage; | 1830 | return mRawImage; |
1670 | } | 1831 | } |
1671 | 1832 | ||