Automated merge with ssh://hg.lindenlab.com/dessie/viewer-public

meow-7.2.2
Xiaohong Bao 2010-06-08 12:55:52 -06:00
commit 79a3870c4f
4 changed files with 237 additions and 547 deletions

View File

@ -2,25 +2,31 @@
* @file llviewertexture.cpp
* @brief Object which handles a received image (and associated texture(s))
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* $LicenseInfo:firstyear=2000&license=viewergpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
@ -106,53 +112,13 @@ const F64 log_2 = log(2.0);
LLLoadedCallbackEntry::LLLoadedCallbackEntry(loaded_callback_func cb,
S32 discard_level,
BOOL need_imageraw, // Needs image raw for the callback
void* userdata,
LLLoadedCallbackEntry::source_callback_list_t* src_callback_list,
LLViewerFetchedTexture* target,
BOOL pause)
void* userdata )
: mCallback(cb),
mLastUsedDiscard(MAX_DISCARD_LEVEL+1),
mDesiredDiscard(discard_level),
mNeedsImageRaw(need_imageraw),
mUserData(userdata),
mSourceCallbackList(src_callback_list),
mPaused(pause)
mUserData(userdata)
{
if(mSourceCallbackList)
{
mSourceCallbackList->insert(target->getID());
}
}
LLLoadedCallbackEntry::~LLLoadedCallbackEntry()
{
}
void LLLoadedCallbackEntry::removeTexture(LLViewerFetchedTexture* tex)
{
if(mSourceCallbackList)
{
mSourceCallbackList->erase(tex->getID()) ;
}
}
//static
void LLLoadedCallbackEntry::cleanUpCallbackList(LLLoadedCallbackEntry::source_callback_list_t* callback_list)
{
//clear texture callbacks.
if(callback_list && !callback_list->empty())
{
for(LLLoadedCallbackEntry::source_callback_list_t::iterator iter = callback_list->begin();
iter != callback_list->end(); ++iter)
{
LLViewerFetchedTexture* tex = gTextureList.findImage(*iter) ;
if(tex)
{
tex->deleteCallbackEntry(callback_list) ;
}
}
callback_list->clear() ;
}
}
LLViewerMediaTexture* LLViewerTextureManager::createMediaTexture(const LLUUID &media_id, BOOL usemipmaps, LLImageGL* gl_image)
@ -358,7 +324,9 @@ void LLViewerTextureManager::cleanup()
LLViewerFetchedTexture::sMissingAssetImagep = NULL;
LLViewerFetchedTexture::sWhiteImagep = NULL;
LLViewerMediaTexture::cleanUpClass() ;
LLViewerMediaTexture::cleanup() ;
LLViewerTexture::cleanupClass() ;
}
//----------------------------------------------------------------------------------------------
@ -376,6 +344,11 @@ void LLViewerTexture::initClass()
}
}
// static
void LLViewerTexture::cleanupClass()
{
}
// static
S32 LLViewerTexture::getTotalNumOfCategories()
{
@ -487,7 +460,6 @@ LLViewerTexture::LLViewerTexture(const U32 width, const U32 height, const U8 com
mFullHeight = height ;
mUseMipMaps = usemipmaps ;
mComponents = components ;
setTexelsPerImage();
mID.generate();
sImageCount++;
@ -506,7 +478,6 @@ LLViewerTexture::LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps)
LLViewerTexture::~LLViewerTexture()
{
cleanup();
sImageCount--;
}
@ -516,16 +487,15 @@ void LLViewerTexture::init(bool firstinit)
mFullWidth = 0;
mFullHeight = 0;
mTexelsPerImage = 0 ;
mUseMipMaps = FALSE ;
mComponents = 0 ;
mTextureState = NO_DELETE ;
mDontDiscard = FALSE;
mCanResetMaxVirtualSize = true ;
mMaxVirtualSize = 0.f;
mNeedsGLTexture = FALSE ;
mMaxVirtualSizeResetInterval = 1;
mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval ;
mNeedsResetMaxVirtualSize = FALSE ;
mAdditionalDecodePriority = 0.f ;
mParcelMedia = NULL ;
mNumFaces = 0 ;
@ -621,6 +591,11 @@ void LLViewerTexture::forceImmediateUpdate()
{
}
void LLViewerTexture::setResetMaxVirtualSizeFlag(bool flag)
{
mCanResetMaxVirtualSize = flag ;
}
void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) const
{
if(needs_gltexture)
@ -628,10 +603,10 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co
mNeedsGLTexture = TRUE ;
}
if(!mMaxVirtualSizeResetCounter)
if(mNeedsResetMaxVirtualSize)
{
//flag to reset the values because the old values are used.
resetMaxVirtualSizeResetCounter() ;
mNeedsResetMaxVirtualSize = FALSE ;
mMaxVirtualSize = virtual_size;
mAdditionalDecodePriority = 0.f ;
mNeedsGLTexture = needs_gltexture ;
@ -646,7 +621,7 @@ void LLViewerTexture::resetTextureStats()
{
mMaxVirtualSize = 0.0f ;
mAdditionalDecodePriority = 0.f ;
mMaxVirtualSizeResetCounter = 0 ;
mNeedsResetMaxVirtualSize = FALSE ;
}
//virtual
@ -832,8 +807,7 @@ BOOL LLViewerTexture::createGLTexture(S32 discard_level, const LLImageRaw* image
{
mFullWidth = mGLTexturep->getCurrentWidth() ;
mFullHeight = mGLTexturep->getCurrentHeight() ;
mComponents = mGLTexturep->getComponents() ;
setTexelsPerImage();
mComponents = mGLTexturep->getComponents() ;
}
return ret ;
@ -1051,16 +1025,9 @@ void LLViewerTexture::destroyGLTexture()
}
}
void LLViewerTexture::setTexelsPerImage()
{
S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT);
S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT);
mTexelsPerImage = (F32)fullwidth * fullheight;
}
BOOL LLViewerTexture::isLargeImage()
{
return (S32)mTexelsPerImage > LLViewerTexture::sMinLargeImageSize ;
return mFullWidth * mFullHeight > LLViewerTexture::sMinLargeImageSize ;
}
//virtual
@ -1131,7 +1098,6 @@ void LLViewerFetchedTexture::init(bool firstinit)
mIsMissingAsset = FALSE;
mLoadedCallbackDesiredDiscardLevel = 0;
mPauseLoadedCallBacks = TRUE ;
mNeedsCreateTexture = FALSE;
@ -1187,7 +1153,6 @@ void LLViewerFetchedTexture::cleanup()
// We never finished loading the image. Indicate failure.
// Note: this allows mLoadedCallbackUserData to be cleaned up.
entryp->mCallback( FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData );
entryp->removeTexture(this) ;
delete entryp;
}
mLoadedCallbackList.clear();
@ -1414,7 +1379,6 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
mFullWidth = mRawImage->getWidth();
mFullHeight = mRawImage->getHeight();
setTexelsPerImage();
}
else
{
@ -1565,7 +1529,6 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
F32 pixel_priority = fsqrtf(mMaxVirtualSize);
F32 priority = 0.f;
if (mIsMissingAsset)
{
priority = 0.0f;
@ -1587,7 +1550,7 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
{
priority = 1.f;
}
else if (pixel_priority < 0.001f && !have_all_data)
else if (pixel_priority <= 0.f && !have_all_data)
{
// Not on screen but we might want some data
if (mBoostLevel > BOOST_HIGH)
@ -1595,6 +1558,11 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
// Always want high boosted images
priority = 1.f;
}
else if(mForceToSaveRawImage)
{
//force to fetch the raw image.
priority = 1.f;
}
else
{
priority = -5.f; //stop fetching
@ -1609,7 +1577,6 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
S32 ddiscard = MAX_DISCARD_LEVEL - (S32)desired;
ddiscard = llclamp(ddiscard, 0, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY);
priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR;
setAdditionalDecodePriority(1.0f) ;//boost the textures without any data so far.
}
else if ((mMinDiscardLevel > 0) && (cur_discard <= mMinDiscardLevel))
{
@ -1620,7 +1587,11 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
{
// priority range = 100,000 - 500,000
S32 desired_discard = mDesiredDiscardLevel;
if (!isJustBound() && mCachedRawImageReady)
if (getDontDiscard())
{
desired_discard -= 2;
}
else if (!isJustBound() && mCachedRawImageReady)
{
if(mBoostLevel < BOOST_HIGH)
{
@ -1636,7 +1607,7 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
S32 ddiscard = cur_discard - desired_discard;
ddiscard = llclamp(ddiscard, -1, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY);
priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR;
priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR;
}
// Priority Formula:
@ -1644,51 +1615,19 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
// [10,000,000] + [1,000,000-9,000,000] + [100,000-500,000] + [1-20,000] + [0-999]
if (priority > 0.0f)
{
bool large_enough = mCachedRawImageReady && ((S32)mTexelsPerImage > sMinLargeImageSize) ;
if(large_enough)
{
//Note:
//to give small, low-priority textures some chance to be fetched,
//cut the priority in half if the texture size is larger than 256 * 256 and has a 64*64 ready.
priority *= 0.5f ;
}
pixel_priority = llclamp(pixel_priority, 0.0f, MAX_PRIORITY_PIXEL);
priority += pixel_priority + PRIORITY_BOOST_LEVEL_FACTOR * mBoostLevel;
if ( mBoostLevel > BOOST_HIGH)
{
if(mBoostLevel > BOOST_SUPER_HIGH)
{
//for very important textures, always grant the highest priority.
priority += PRIORITY_BOOST_HIGH_FACTOR;
}
else if(mCachedRawImageReady)
{
//Note:
//to give small, low-priority textures some chance to be fetched,
//if high priority texture has a 64*64 ready, lower its fetching priority.
setAdditionalDecodePriority(0.5f) ;
}
else
{
priority += PRIORITY_BOOST_HIGH_FACTOR;
}
priority += PRIORITY_BOOST_HIGH_FACTOR;
}
if(mAdditionalDecodePriority > 0.0f)
{
// priority range += 1,000,000.f-9,000,000.f
F32 additional = PRIORITY_ADDITIONAL_FACTOR * (1.0 + mAdditionalDecodePriority * MAX_ADDITIONAL_LEVEL_FOR_PRIORITY);
if(large_enough)
{
//Note:
//to give small, low-priority textures some chance to be fetched,
//cut the additional priority to a quarter if the texture size is larger than 256 * 256 and has a 64*64 ready.
additional *= 0.25f ;
}
priority += additional;
priority += PRIORITY_ADDITIONAL_FACTOR * (1.0 + mAdditionalDecodePriority * MAX_ADDITIONAL_LEVEL_FOR_PRIORITY);
}
}
return priority;
@ -1726,11 +1665,16 @@ void LLViewerFetchedTexture::setAdditionalDecodePriority(F32 priority)
void LLViewerFetchedTexture::updateVirtualSize()
{
if(!mMaxVirtualSizeResetCounter)
if(mNeedsResetMaxVirtualSize)
{
addTextureStats(0.f, FALSE) ;//reset
}
if(mForceToSaveRawImage)
{
setAdditionalDecodePriority(0.75f) ; //boost the fetching priority
}
for(U32 i = 0 ; i < mNumFaces ; i++)
{
LLFace* facep = mFaceList[i] ;
@ -1741,9 +1685,9 @@ void LLViewerFetchedTexture::updateVirtualSize()
}
}
if(mMaxVirtualSizeResetCounter > 0)
if(mCanResetMaxVirtualSize)
{
mMaxVirtualSizeResetCounter--;
mNeedsResetMaxVirtualSize = TRUE ;
}
reorganizeFaceList() ;
reorganizeVolumeList();
@ -1821,7 +1765,6 @@ bool LLViewerFetchedTexture::updateFetch()
if (finished)
{
mIsFetching = FALSE;
mLastPacketTimer.reset() ;
}
else
{
@ -1843,7 +1786,6 @@ bool LLViewerFetchedTexture::updateFetch()
{
mFullWidth = mRawImage->getWidth() << mRawDiscardLevel;
mFullHeight = mRawImage->getHeight() << mRawDiscardLevel;
setTexelsPerImage();
if(mFullWidth > MAX_IMAGE_SIZE || mFullHeight > MAX_IMAGE_SIZE)
{
@ -1852,7 +1794,6 @@ bool LLViewerFetchedTexture::updateFetch()
setIsMissingAsset();
mRawDiscardLevel = INVALID_DISCARD_LEVEL ;
mIsFetching = FALSE ;
mLastPacketTimer.reset();
}
else
{
@ -2020,7 +1961,6 @@ void LLViewerFetchedTexture::setIsMissingAsset()
LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
mHasFetcher = FALSE;
mIsFetching = FALSE;
mLastPacketTimer.reset();
mFetchState = 0;
mFetchPriority = 0;
}
@ -2028,8 +1968,7 @@ void LLViewerFetchedTexture::setIsMissingAsset()
}
void LLViewerFetchedTexture::setLoadedCallback( loaded_callback_func loaded_callback,
S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, void* userdata,
LLLoadedCallbackEntry::source_callback_list_t* src_callback_list, BOOL pause)
S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, void* userdata)
{
//
// Don't do ANYTHING here, just add it to the global callback list
@ -2045,17 +1984,12 @@ void LLViewerFetchedTexture::setLoadedCallback( loaded_callback_func loaded_call
mLoadedCallbackDesiredDiscardLevel = llmin(mLoadedCallbackDesiredDiscardLevel, (S8)discard_level) ;
}
if(mPauseLoadedCallBacks && !pause)
{
unpauseLoadedCallbacks(src_callback_list) ;
}
LLLoadedCallbackEntry* entryp = new LLLoadedCallbackEntry(loaded_callback, discard_level, keep_imageraw, userdata, src_callback_list, this, pause);
mLoadedCallbackList.push_back(entryp);
LLLoadedCallbackEntry* entryp = new LLLoadedCallbackEntry(loaded_callback, discard_level, keep_imageraw, userdata);
mLoadedCallbackList.push_back(entryp);
mNeedsAux |= needs_aux;
if(keep_imageraw)
{
forceToSaveRawImage(discard_level, true) ;
forceToSaveRawImage(discard_level) ;
}
if (mNeedsAux && mAuxRawImage.isNull() && getDiscardLevel() >= 0)
{
@ -2064,124 +1998,6 @@ void LLViewerFetchedTexture::setLoadedCallback( loaded_callback_func loaded_call
}
}
void LLViewerFetchedTexture::deleteCallbackEntry(const LLLoadedCallbackEntry::source_callback_list_t* callback_list)
{
if(mLoadedCallbackList.empty() || !callback_list)
{
return ;
}
S32 desired_discard = INVALID_DISCARD_LEVEL ;
S32 desired_raw_discard = INVALID_DISCARD_LEVEL ;
for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
iter != mLoadedCallbackList.end(); )
{
LLLoadedCallbackEntry *entryp = *iter;
if(entryp->mSourceCallbackList == callback_list)
{
// We never finished loading the image. Indicate failure.
// Note: this allows mLoadedCallbackUserData to be cleaned up.
entryp->mCallback(FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData);
iter = mLoadedCallbackList.erase(iter) ;
delete entryp;
}
else
{
++iter;
desired_discard = llmin(desired_discard, entryp->mDesiredDiscard) ;
if(entryp->mNeedsImageRaw)
{
desired_raw_discard = llmin(desired_raw_discard, entryp->mDesiredDiscard) ;
}
}
}
mLoadedCallbackDesiredDiscardLevel = desired_discard;
if (mLoadedCallbackList.empty())
{
// If we have no callbacks, take us off of the image callback list.
gTextureList.mCallbackList.erase(this);
mMinDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
if(mForceToSaveRawImage)
{
destroySavedRawImage() ;
}
}
else if(mForceToSaveRawImage && mBoostLevel != LLViewerTexture::BOOST_PREVIEW)
{
if(desired_raw_discard != INVALID_DISCARD_LEVEL)
{
mDesiredSavedRawDiscardLevel = desired_raw_discard ;
}
else
{
destroySavedRawImage() ;
}
}
}
void LLViewerFetchedTexture::unpauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list)
{
if(!callback_list)
{
mPauseLoadedCallBacks = FALSE ;
return ;
}
BOOL need_raw = FALSE ;
for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
iter != mLoadedCallbackList.end(); )
{
LLLoadedCallbackEntry *entryp = *iter++;
if(entryp->mSourceCallbackList == callback_list)
{
entryp->mPaused = FALSE ;
if(entryp->mNeedsImageRaw)
{
need_raw = TRUE ;
}
}
}
mPauseLoadedCallBacks = FALSE ;
if(need_raw)
{
mForceToSaveRawImage = TRUE ;
}
}
void LLViewerFetchedTexture::pauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list)
{
if(!callback_list)
{
return ;
}
bool paused = true ;
for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
iter != mLoadedCallbackList.end(); )
{
LLLoadedCallbackEntry *entryp = *iter++;
if(entryp->mSourceCallbackList == callback_list)
{
entryp->mPaused = TRUE ;
}
else if(!entryp->mPaused)
{
paused = false ;
}
}
if(paused)
{
mPauseLoadedCallBacks = TRUE ;//when set, loaded callback is paused.
resetTextureStats();
mForceToSaveRawImage = FALSE ;
}
}
bool LLViewerFetchedTexture::doLoadedCallbacks()
{
if (mNeedsCreateTexture)
@ -2207,11 +2023,6 @@ bool LLViewerFetchedTexture::doLoadedCallbacks()
// Remove ourself from the global list of textures with callbacks
gTextureList.mCallbackList.erase(this);
}
if(mPauseLoadedCallBacks)
{
destroyRawImage();
return res; //paused
}
S32 gl_discard = getDiscardLevel();
@ -2341,6 +2152,10 @@ bool LLViewerFetchedTexture::doLoadedCallbacks()
BOOL final = mRawDiscardLevel <= entryp->mDesiredDiscard ? TRUE : FALSE;
//llinfos << "Running callback for " << getID() << llendl;
//llinfos << mRawImage->getWidth() << "x" << mRawImage->getHeight() << llendl;
if (final)
{
//llinfos << "Final!" << llendl;
}
entryp->mLastUsedDiscard = mRawDiscardLevel;
entryp->mCallback(TRUE, this, mRawImage, mAuxRawImage, mRawDiscardLevel, final, entryp->mUserData);
if (final)
@ -2617,12 +2432,10 @@ void LLViewerFetchedTexture::saveRawImage()
mLastReferencedSavedRawImageTime = sCurrentTime ;
}
void LLViewerFetchedTexture::forceToSaveRawImage(S32 desired_discard, bool from_callback)
void LLViewerFetchedTexture::forceToSaveRawImage(S32 desired_discard)
{
if(!mForceToSaveRawImage || mDesiredSavedRawDiscardLevel < 0 || mDesiredSavedRawDiscardLevel > desired_discard)
{
llassert_always(from_callback || mBoostLevel == LLViewerTexture::BOOST_PREVIEW) ;
mForceToSaveRawImage = TRUE ;
mDesiredSavedRawDiscardLevel = desired_discard ;
@ -2919,6 +2732,10 @@ void LLViewerLODTexture::processTextureStats()
//static const F64 log_2 = log(2.0);
static const F64 log_4 = log(4.0);
S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT);
S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT);
mTexelsPerImage = (F32)fullwidth * fullheight;
F32 discard_level = 0.f;
// If we know the output width and height, we can force the discard
@ -3065,7 +2882,7 @@ void LLViewerMediaTexture::removeMediaImplFromTexture(const LLUUID& media_id)
}
//static
void LLViewerMediaTexture::cleanUpClass()
void LLViewerMediaTexture::cleanup()
{
sMediaMap.clear() ;
}
@ -3474,7 +3291,7 @@ F32 LLViewerMediaTexture::getMaxVirtualSize()
}
mUpdateVirtualSizeTime = LLFrameTimer::getFrameCount() ;
if(!mMaxVirtualSizeResetCounter)
if(mNeedsResetMaxVirtualSize)
{
addTextureStats(0.f, FALSE) ;//reset
}
@ -3507,9 +3324,9 @@ F32 LLViewerMediaTexture::getMaxVirtualSize()
}
}
if(mMaxVirtualSizeResetCounter > 0)
if(mCanResetMaxVirtualSize)
{
mMaxVirtualSizeResetCounter--;
mNeedsResetMaxVirtualSize = TRUE ;
}
reorganizeFaceList() ;
reorganizeVolumeList();
@ -3693,7 +3510,7 @@ void LLTexturePipelineTester::updateStablizingTime()
{
F32 t = mEndStablizingTime - mStartStablizingTime ;
if(t > F_ALMOST_ZERO && (t - mTotalStablizingTime) < F_ALMOST_ZERO)
if(t > 0.0001f && (t - mTotalStablizingTime) < 0.0001f)
{
//already stablized
mTotalStablizingTime = LLImageGL::sLastFrameTime - mStartStablizingTime ;
@ -3818,7 +3635,7 @@ LLMetricPerformanceTester::LLTestSession* LLTexturePipelineTester::loadTestSessi
//time
F32 start_time = (*log)[label]["StartFetchingTime"].asReal() ;
F32 cur_time = (*log)[label]["Time"].asReal() ;
if(start_time - start_fetching_time > F_ALMOST_ZERO) //fetching has paused for a while
if(start_time - start_fetching_time > 0.0001f) //fetching has paused for a while
{
sessionp->mTotalFetchingTime += total_fetching_time ;
sessionp->mTotalGrayTime += total_gray_time ;

View File

@ -2,25 +2,31 @@
* @file llviewertexture.h
* @brief Object for managing images and their textures
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* $LicenseInfo:firstyear=2000&license=viewergpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
@ -60,30 +66,17 @@ class LLVOVolume ;
class LLLoadedCallbackEntry
{
public:
typedef std::set< LLUUID > source_callback_list_t;
public:
LLLoadedCallbackEntry(loaded_callback_func cb,
S32 discard_level,
BOOL need_imageraw, // Needs image raw for the callback
void* userdata,
source_callback_list_t* src_callback_list,
LLViewerFetchedTexture* target,
BOOL pause);
~LLLoadedCallbackEntry();
void removeTexture(LLViewerFetchedTexture* tex) ;
void* userdata );
loaded_callback_func mCallback;
S32 mLastUsedDiscard;
S32 mDesiredDiscard;
BOOL mNeedsImageRaw;
BOOL mPaused;
void* mUserData;
source_callback_list_t* mSourceCallbackList;
public:
static void cleanUpCallbackList(LLLoadedCallbackEntry::source_callback_list_t* callback_list) ;
};
class LLTextureBar;
@ -110,24 +103,22 @@ public:
enum EBoostLevel
{
BOOST_NONE = 0,
BOOST_AVATAR_BAKED ,
BOOST_AVATAR ,
BOOST_CLOUDS ,
BOOST_SCULPTED ,
BOOST_AVATAR_BAKED = 1,
BOOST_AVATAR = 2,
BOOST_CLOUDS = 3,
BOOST_SCULPTED = 4,
BOOST_HIGH = 10,
BOOST_BUMP ,
BOOST_TERRAIN , // has to be high priority for minimap / low detail
BOOST_SELECTED ,
BOOST_AVATAR_BAKED_SELF ,
BOOST_AVATAR_SELF , // needed for baking avatar
BOOST_SUPER_HIGH , //textures higher than this need to be downloaded at the required resolution without delay.
BOOST_HUD ,
BOOST_ICON ,
BOOST_UI ,
BOOST_PREVIEW ,
BOOST_MAP ,
BOOST_MAP_VISIBLE ,
BOOST_TERRAIN = 11, // has to be high priority for minimap / low detail
BOOST_SELECTED = 12,
BOOST_HUD = 13,
BOOST_AVATAR_BAKED_SELF = 14,
BOOST_ICON = 15,
BOOST_UI = 16,
BOOST_PREVIEW = 17,
BOOST_MAP = 18,
BOOST_MAP_VISIBLE = 19,
BOOST_AVATAR_SELF = 20, // needed for baking avatar
BOOST_MAX_LEVEL,
//other texture Categories
@ -153,6 +144,7 @@ protected:
public:
static void initClass();
static void cleanupClass();
static void updateClass(const F32 velocity, const F32 angular_velocity) ;
LLViewerTexture(BOOL usemipmaps = TRUE);
@ -174,8 +166,7 @@ public:
void addTextureStats(F32 virtual_size, BOOL needs_gltexture = TRUE) const;
void resetTextureStats();
void setMaxVirtualSizeResetInterval(S32 interval)const {mMaxVirtualSizeResetInterval = interval;}
void resetMaxVirtualSizeResetCounter()const {mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval;}
void setResetMaxVirtualSizeFlag(bool flag) ;
virtual F32 getMaxVirtualSize() ;
@ -261,7 +252,6 @@ protected:
void init(bool firstinit) ;
void reorganizeFaceList() ;
void reorganizeVolumeList() ;
void setTexelsPerImage();
private:
//note: do not make this function public.
/*virtual*/ LLImageGL* getGLTexture() const ;
@ -274,11 +264,10 @@ protected:
S32 mFullHeight;
BOOL mUseMipMaps ;
S8 mComponents;
F32 mTexelsPerImage; // Texels per image.
bool mCanResetMaxVirtualSize;
mutable F32 mMaxVirtualSize; // The largest virtual size of the image, in pixels - how much data to we need?
mutable S8 mNeedsGLTexture;
mutable F32 mMaxVirtualSize; // The largest virtual size of the image, in pixels - how much data to we need?
mutable S32 mMaxVirtualSizeResetCounter ;
mutable S32 mMaxVirtualSizeResetInterval;
mutable BOOL mNeedsResetMaxVirtualSize ;
mutable F32 mAdditionalDecodePriority; // priority add to mDecodePriority.
LLFrameTimer mLastReferencedTimer;
@ -380,12 +369,9 @@ public:
// resolution versions.
void setLoadedCallback(loaded_callback_func cb,
S32 discard_level, BOOL keep_imageraw, BOOL needs_aux,
void* userdata, LLLoadedCallbackEntry::source_callback_list_t* src_callback_list, BOOL pause = FALSE);
void* userdata);
bool hasCallbacks() { return mLoadedCallbackList.empty() ? false : true; }
void pauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list);
void unpauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list);
bool doLoadedCallbacks();
void deleteCallbackEntry(const LLLoadedCallbackEntry::source_callback_list_t* callback_list);
void addToCreateTexture();
@ -463,7 +449,7 @@ public:
S32 getCachedRawImageLevel() const {return mCachedRawDiscardLevel;}
BOOL isCachedRawImageReady() const {return mCachedRawImageReady ;}
BOOL isRawImageValid()const { return mIsRawImageValid ; }
void forceToSaveRawImage(S32 desired_discard = 0, bool from_callback = false) ;
void forceToSaveRawImage(S32 desired_discard = 0) ;
/*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ;
void destroySavedRawImage() ;
LLImageRaw* getSavedRawImage() ;
@ -529,7 +515,6 @@ protected:
typedef std::list<LLLoadedCallbackEntry*> callback_list_t;
S8 mLoadedCallbackDesiredDiscardLevel;
BOOL mPauseLoadedCallBacks;
callback_list_t mLoadedCallbackList;
LLPointer<LLImageRaw> mRawImage;
@ -593,6 +578,8 @@ private:
void scaleDown() ;
private:
F32 mTexelsPerImage; // Texels per image.
F32 mDiscardVirtualSize; // Virtual size used to calculate desired discard
F32 mCalculatedDiscardLevel; // Last calculated discard level
};
@ -651,7 +638,7 @@ private:
public:
static void updateClass() ;
static void cleanUpClass() ;
static void cleanup() ;
static LLViewerMediaTexture* findMediaTexture(const LLUUID& media_id) ;
static void removeMediaImplFromTexture(const LLUUID& media_id) ;

View File

@ -2,25 +2,31 @@
* @File llvoavatar.cpp
* @brief Implementation of LLVOAvatar class which is a derivation of LLViewerObject
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
@ -589,7 +595,7 @@ LLVOAvatarSkeletonInfo* LLVOAvatar::sAvatarSkeletonInfo = NULL;
LLVOAvatar::LLVOAvatarXmlInfo* LLVOAvatar::sAvatarXmlInfo = NULL;
LLVOAvatarDictionary *LLVOAvatar::sAvatarDictionary = NULL;
S32 LLVOAvatar::sFreezeCounter = 0;
U32 LLVOAvatar::sMaxVisible = 12;
S32 LLVOAvatar::sMaxVisible = 50;
F32 LLVOAvatar::sRenderDistance = 256.f;
S32 LLVOAvatar::sNumVisibleAvatars = 0;
S32 LLVOAvatar::sNumLODChangesThisFrame = 0;
@ -671,8 +677,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mFullyLoaded(FALSE),
mPreviousFullyLoaded(FALSE),
mFullyLoadedInitialized(FALSE),
mSupportsAlphaLayers(FALSE),
mLoadedCallbacksPaused(FALSE)
mSupportsAlphaLayers(FALSE)
{
LLMemType mt(LLMemType::MTYPE_AVATAR);
//VTResume(); // VTune
@ -829,7 +834,6 @@ LLVOAvatar::~LLVOAvatar()
mDead = TRUE;
mAnimationSources.clear();
LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ;
lldebugs << "LLVOAvatar Destructor end" << llendl;
}
@ -843,7 +847,6 @@ void LLVOAvatar::markDead()
sNumVisibleChatBubbles--;
}
mVoiceVisualizer->markDead();
LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ;
LLViewerObject::markDead();
}
@ -2073,8 +2076,7 @@ void LLVOAvatar::computeBodySize()
ankle.mV[VZ] * knee_scale.mV[VZ] -
foot.mV[VZ] * ankle_scale.mV[VZ];
LLVector3 new_body_size;
new_body_size.mV[VZ] = mPelvisToFoot +
mBodySize.mV[VZ] = mPelvisToFoot +
// the sqrt(2) correction below is an approximate
// correction to get to the top of the head
F_SQRT2 * (skull.mV[VZ] * head_scale.mV[VZ]) +
@ -2084,19 +2086,8 @@ void LLVOAvatar::computeBodySize()
torso.mV[VZ] * pelvis_scale.mV[VZ];
// TODO -- measure the real depth and width
new_body_size.mV[VX] = DEFAULT_AGENT_DEPTH;
new_body_size.mV[VY] = DEFAULT_AGENT_WIDTH;
if (new_body_size != mBodySize)
{
mBodySize = new_body_size;
if (isSelf() && !LLAppearanceMgr::instance().isInUpdateAppearanceFromCOF())
{ // notify simulator of change in size
// but not if we are in the middle of updating appearance
gAgent.sendAgentSetAppearance();
}
}
mBodySize.mV[VX] = DEFAULT_AGENT_DEPTH;
mBodySize.mV[VY] = DEFAULT_AGENT_WIDTH;
/* debug spam
std::cout << "skull = " << skull << std::endl; // adebug
@ -2226,14 +2217,12 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
{
llinfos << "Warning! Idle on dead avatar" << llendl;
return TRUE;
}
}
if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR)))
{
return TRUE;
}
checkTextureLoading() ;
// force immediate pixel area update on avatars using last frames data (before drawable or camera updates)
setPixelAreaAndAngle(gAgent);
@ -2539,7 +2528,7 @@ void LLVOAvatar::idleUpdateAppearanceAnimation()
param;
param = getNextVisualParam())
{
if (param->isTweakable())
if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE)
{
param->stopAnimating(FALSE);
}
@ -2562,7 +2551,7 @@ void LLVOAvatar::idleUpdateAppearanceAnimation()
param;
param = getNextVisualParam())
{
if (param->isTweakable())
if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE)
{
param->animate(morph_amt, FALSE);
}
@ -3131,16 +3120,14 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
if (motionp->getName().empty())
{
output = llformat("%s - %d",
gAgent.isGodlikeWithoutAdminMenuFakery() ?
motionp->getID().asString().c_str() :
LLUUID::null.asString().c_str(),
(U32)motionp->getPriority());
motionp->getID().asString().c_str(),
(U32)motionp->getPriority());
}
else
{
output = llformat("%s - %d",
motionp->getName().c_str(),
(U32)motionp->getPriority());
motionp->getName().c_str(),
(U32)motionp->getPriority());
}
addDebugText(output);
}
@ -3186,35 +3173,35 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
{ // muted avatars update at 16 hz
mUpdatePeriod = 16;
}
else if (mVisibilityRank <= LLVOAvatar::sMaxVisible)
else if (visible && mVisibilityRank <= LLVOAvatar::sMaxVisible * 0.25f)
{ //first 25% of max visible avatars are not impostored
mUpdatePeriod = 1;
}
else if (mVisibilityRank > LLVOAvatar::sMaxVisible * 4)
{ //background avatars are REALLY slow updating impostors
mUpdatePeriod = 16;
}
else if (mVisibilityRank > LLVOAvatar::sMaxVisible * 3)
else if (visible && mVisibilityRank > LLVOAvatar::sMaxVisible * 0.75f)
{ //back 25% of max visible avatars are slow updating impostors
mUpdatePeriod = 8;
}
else if (mImpostorPixelArea <= impostor_area)
else if (visible && mVisibilityRank > (U32) LLVOAvatar::sMaxVisible)
{ //background avatars are REALLY slow updating impostors
mUpdatePeriod = 16;
}
else if (visible && mImpostorPixelArea <= impostor_area)
{ // stuff in between gets an update period based on pixel area
mUpdatePeriod = llclamp((S32) sqrtf(impostor_area*4.f/mImpostorPixelArea), 2, 8);
}
else if (visible && mVisibilityRank > LLVOAvatar::sMaxVisible * 0.25f)
{ // force nearby impostors in ultra crowded areas
mUpdatePeriod = 2;
}
else
{
//nearby avatars, update the impostors more frequently.
mUpdatePeriod = 4;
{ // not impostored
mUpdatePeriod = 1;
}
visible = (LLDrawable::getCurrentFrame()+mID.mData[0])%mUpdatePeriod == 0 ? TRUE : FALSE;
}
// don't early out for your own avatar, as we rely on your animations playing reliably
// for example, the "turn around" animation when entering customize avatar needs to trigger
// even when your avatar is offscreen
if (!visible && !isSelf())
if (!visible)
{
updateMotions(LLCharacter::HIDDEN_UPDATE);
return FALSE;
@ -3564,7 +3551,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
// AUDIO_STEP_LO_SPEED, AUDIO_STEP_HI_SPEED,
// AUDIO_STEP_LO_GAIN, AUDIO_STEP_HI_GAIN );
const F32 STEP_VOLUME = 0.1f;
const F32 STEP_VOLUME = 0.5f;
const LLUUID& step_sound_id = getStepSound();
LLVector3d foot_pos_global = gAgent.getPosGlobalFromAgent(foot_pos_agent);
@ -4136,12 +4123,7 @@ void LLVOAvatar::updateTextures()
}
else
{
if(!isVisible())
{
return ;//do not update for invisible avatar.
}
render_avatar = !mCulled; //visible and not culled.
render_avatar = isVisible() && !mCulled;
}
std::vector<BOOL> layer_baked;
@ -4183,7 +4165,7 @@ void LLVOAvatar::updateTextures()
}
}
}
if (isIndexBakedTexture((ETextureIndex) texture_index) && render_avatar)
if (isIndexBakedTexture((ETextureIndex) texture_index))
{
const S32 boost_level = getAvatarBakedBoostLevel();
imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE);
@ -4199,7 +4181,7 @@ void LLVOAvatar::updateTextures()
<< " on host " << getRegion()->getHost() << llendl;
}
addBakedTextureStats( imagep, mPixelArea, texel_area_ratio, boost_level );
addBakedTextureStats( imagep, mPixelArea, texel_area_ratio, boost_level );
}
}
@ -4222,90 +4204,20 @@ void LLVOAvatar::addLocalTextureStats( ETextureIndex idx, LLViewerFetchedTexture
return;
}
const S32 MAX_TEXTURE_UPDATE_INTERVAL = 64 ; //need to call updateTextures() at least every 32 frames.
const S32 MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL = S32_MAX ; //frames
void LLVOAvatar::checkTextureLoading()
{
static const F32 MAX_INVISIBLE_WAITING_TIME = 15.f ; //seconds
BOOL pause = !isVisible() ;
if(!pause)
{
mInvisibleTimer.reset() ;
}
if(mLoadedCallbacksPaused == pause)
{
return ;
}
if(mCallbackTextureList.empty()) //when is self or no callbacks. Note: this list for self is always empty.
{
mLoadedCallbacksPaused = pause ;
return ; //nothing to check.
}
if(pause && mInvisibleTimer.getElapsedTimeF32() < MAX_INVISIBLE_WAITING_TIME)
{
return ; //have not been invisible for enough time.
}
for(LLLoadedCallbackEntry::source_callback_list_t::iterator iter = mCallbackTextureList.begin();
iter != mCallbackTextureList.end(); ++iter)
{
LLViewerFetchedTexture* tex = gTextureList.findImage(*iter) ;
if(tex)
{
if(pause)//pause texture fetching.
{
tex->pauseLoadedCallbacks(&mCallbackTextureList) ;
//set to terminate texture fetching after MAX_TEXTURE_UPDATE_INTERVAL frames.
tex->setMaxVirtualSizeResetInterval(MAX_TEXTURE_UPDATE_INTERVAL);
tex->resetMaxVirtualSizeResetCounter() ;
}
else//unpause
{
static const F32 START_AREA = 100.f ;
tex->unpauseLoadedCallbacks(&mCallbackTextureList) ;
tex->addTextureStats(START_AREA); //jump start the fetching again
}
}
}
if(!pause)
{
updateTextures() ; //refresh texture stats.
}
mLoadedCallbacksPaused = pause ;
return ;
}
const F32 SELF_ADDITIONAL_PRI = 0.75f ;
const F32 ADDITIONAL_PRI = 0.5f;
void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level)
{
//Note:
//if this function is not called for the last MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL frames,
//the texture pipeline will stop fetching this texture.
mMaxPixelArea = llmax(pixel_area, mMaxPixelArea);
mMinPixelArea = llmin(pixel_area, mMinPixelArea);
imagep->resetTextureStats();
imagep->setResetMaxVirtualSizeFlag(false) ;
imagep->setCanUseHTTP(false) ; //turn off http fetching for baked textures.
imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL);
imagep->resetMaxVirtualSizeResetCounter() ;
mMaxPixelArea = llmax(pixel_area, mMaxPixelArea);
mMinPixelArea = llmin(pixel_area, mMinPixelArea);
imagep->addTextureStats(pixel_area / texel_area_ratio);
imagep->setBoostLevel(boost_level);
if(boost_level != LLViewerTexture::BOOST_AVATAR_BAKED_SELF)
if(boost_level == LLViewerTexture::BOOST_AVATAR_BAKED_SELF)
{
imagep->setAdditionalDecodePriority(ADDITIONAL_PRI) ;
}
else
{
imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;
imagep->setAdditionalDecodePriority(1.0f) ;
}
}
@ -5741,7 +5653,6 @@ LLViewerJointAttachment* LLVOAvatar::getTargetAttachmentPoint(LLViewerObject* vi
if (!attachment)
{
llwarns << "Object attachment point invalid: " << attachmentID << llendl;
attachment = get_if_there(mAttachmentPoints, 1, (LLViewerJointAttachment*)NULL); // Arbitrary using 1 (chest)
}
return attachment;
@ -6221,13 +6132,6 @@ void LLVOAvatar::updateMeshTextures()
const BOOL self_customizing = isSelf() && gAgentCamera.cameraCustomizeAvatar(); // During face edit mode, we don't use baked textures
const BOOL other_culled = !isSelf() && mCulled;
LLLoadedCallbackEntry::source_callback_list_t* src_callback_list = NULL ;
BOOL paused = FALSE;
if(!isSelf())
{
src_callback_list = &mCallbackTextureList ;
paused = mLoadedCallbacksPaused ;
}
std::vector<BOOL> is_layer_baked;
is_layer_baked.resize(mBakedTextureDatas.size(), false);
@ -6298,12 +6202,10 @@ void LLVOAvatar::updateMeshTextures()
{
mBakedTextureDatas[i].mIsLoaded = FALSE;
if ( (baked_img->getID() != IMG_INVISIBLE) && ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )
{
baked_img->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ),
src_callback_list, paused);
{
baked_img->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ));
}
baked_img->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ),
src_callback_list, paused );
baked_img->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ) );
}
}
else if (mBakedTextureDatas[i].mTexLayerSet
@ -6763,14 +6665,6 @@ void LLVOAvatar::onFirstTEMessageReceived()
{
mFirstTEMessageReceived = TRUE;
LLLoadedCallbackEntry::source_callback_list_t* src_callback_list = NULL ;
BOOL paused = FALSE ;
if(!isSelf())
{
src_callback_list = &mCallbackTextureList ;
paused = mLoadedCallbacksPaused ;
}
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
const BOOL layer_baked = isTextureDefined(mBakedTextureDatas[i].mTextureIndex);
@ -6784,11 +6678,9 @@ void LLVOAvatar::onFirstTEMessageReceived()
// If we have more than one texture for the other baked layers, we'll want to call this for them too.
if ( (image->getID() != IMG_INVISIBLE) && ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )
{
image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ),
src_callback_list, paused);
image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ));
}
image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ),
src_callback_list, paused );
image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ) );
}
}
@ -6809,7 +6701,7 @@ bool LLVOAvatar::visualParamWeightsAreDefault()
param;
param = getNextVisualParam())
{
if (param->isTweakable())
if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE)
{
LLViewerVisualParam* vparam = dynamic_cast<LLViewerVisualParam*>(param);
llassert(vparam);
@ -6919,7 +6811,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
{
for( S32 i = 0; i < num_blocks; i++ )
{
while( param && (param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) ) // should not be any of group VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
while( param && (param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) )
{
param = getNextVisualParam();
}
@ -6952,7 +6844,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
}
}
const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE);
if (num_blocks != expected_tweakable_count)
{
llinfos << "Number of params in AvatarAppearance msg (" << num_blocks << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << "). Processing what we can. object: " << getID() << llendl;
@ -7239,7 +7131,7 @@ void LLVOAvatar::dumpArchetypeXML( void* )
{
LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
if( (viewer_param->getWearableType() == type) &&
(viewer_param->isTweakable() ) )
(viewer_param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) )
{
apr_file_printf(file, "\t\t<param id=\"%d\" name=\"%s\" value=\"%.3f\"/>\n",
viewer_param->getID(), viewer_param->getName().c_str(), viewer_param->getWeight());
@ -7312,7 +7204,7 @@ void LLVOAvatar::cullAvatarsByPixelArea()
std::sort(LLCharacter::sInstances.begin(), LLCharacter::sInstances.end(), CompareScreenAreaGreater());
// Update the avatars that have changed status
U32 rank = 2; //1 is reserved for self.
U32 rank = 0;
for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
iter != LLCharacter::sInstances.end(); ++iter)
{
@ -7336,7 +7228,7 @@ void LLVOAvatar::cullAvatarsByPixelArea()
if (inst->isSelf())
{
inst->setVisibilityRank(1);
inst->setVisibilityRank(0);
}
else if (inst->mDrawable.notNull() && inst->mDrawable->isVisible())
{

View File

@ -2,25 +2,31 @@
* @file llvoavatar.cpp
* @brief Implementation of LLVOAvatar class which is a derivation fo LLViewerObject
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
@ -1142,11 +1148,11 @@ void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *sr
discard_level < local_tex_obj->getDiscard())
{
local_tex_obj->setDiscard(discard_level);
if (isUsingBakedTextures())
if (!gAgentCamera.cameraCustomizeAvatar())
{
requestLayerSetUpdate(index);
}
else
else if (gAgentCamera.cameraCustomizeAvatar())
{
LLVisualParamHint::requestHintUpdates();
}
@ -1261,8 +1267,8 @@ BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLTexLayerSet* layerset)
//-----------------------------------------------------------------------------
BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLTexLayerSet* layerset) const
{
const U32 desired_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel");
// const U32 desired_tex_discard_level = 0; // hack to not bake textures on lower discard levels.
//const U32 desired_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel");
const U32 desired_tex_discard_level = 0; // SERAPH hack to not bake textures on lower discard levels.
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
@ -1293,8 +1299,8 @@ BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLTexLayerSet* layerset) cons
BOOL LLVOAvatarSelf::isAllLocalTextureDataFinal() const
{
const U32 desired_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel");
// const U32 desired_tex_discard_level = 0; // hack to not bake textures on lower discard levels
// const U32 desired_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel");
const U32 desired_tex_discard_level = 0; // SERAPH hack to not bake textures on lower discard levels
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
@ -1324,7 +1330,7 @@ BOOL LLVOAvatarSelf::isBakedTextureFinal(const LLVOAvatarDefines::EBakedTextureI
if (!layerset) return FALSE;
const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite();
if (!layerset_buffer) return FALSE;
return !layerset_buffer->uploadNeeded();
return !layerset_buffer->uploadPending();
}
BOOL LLVOAvatarSelf::isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index) const
@ -1616,21 +1622,18 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te
if (tex_discard >= 0 && tex_discard <= desired_discard)
{
local_tex_obj->setDiscard(tex_discard);
if (isSelf())
if (isSelf() && !gAgentCamera.cameraCustomizeAvatar())
{
if (gAgentAvatarp->isUsingBakedTextures())
{
requestLayerSetUpdate(type);
}
else
{
LLVisualParamHint::requestHintUpdates();
}
requestLayerSetUpdate(type);
}
else if (isSelf() && gAgentCamera.cameraCustomizeAvatar())
{
LLVisualParamHint::requestHintUpdates();
}
}
else
{
tex->setLoadedCallback(onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), type), NULL);
{
tex->setLoadedCallback(onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), type));
}
}
tex->setMinDiscardLevel(desired_discard);
@ -2029,10 +2032,11 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe
imagep->setBoostLevel(getAvatarBoostLevel());
imagep->resetTextureStats();
imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL);
imagep->setResetMaxVirtualSizeFlag(false) ;
imagep->addTextureStats( desired_pixels / texel_area_ratio );
imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;
imagep->setAdditionalDecodePriority(1.0f) ;
imagep->forceUpdateBindStats() ;
if (imagep->getDiscardLevel() < 0)
{
mHasGrey = TRUE; // for statistics gathering
@ -2258,16 +2262,6 @@ void LLVOAvatarSelf::processRebakeAvatarTextures(LLMessageSystem* msg, void**)
}
}
BOOL LLVOAvatarSelf::isUsingBakedTextures() const
{
// Composite textures are used during appearance mode.
if (gAgentCamera.cameraCustomizeAvatar())
return FALSE;
return TRUE;
}
void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug)
{
llinfos << "TAT: forced full rebake. " << llendl;