summaryrefslogtreecommitdiff
path: root/indra/newview/llviewertexture.cpp
diff options
context:
space:
mode:
authorXiaohong Bao <bao@lindenlab.com>2009-12-29 15:02:22 -0700
committerXiaohong Bao <bao@lindenlab.com>2009-12-29 15:02:22 -0700
commitb07564b15cf90c757beb86b3ef41224a55d48da4 (patch)
treea48920379881a73d8917bf95e1112b2054e0c9ee /indra/newview/llviewertexture.cpp
parent6ed6bed5acd5352b5c3ca02f86a62397f5257a5f (diff)
fix for DEV-44134: trying to move away from a huge amount of objects with media causes viewer to hang for 15-20 seconds.
Diffstat (limited to 'indra/newview/llviewertexture.cpp')
-rw-r--r--indra/newview/llviewertexture.cpp134
1 files changed, 82 insertions, 52 deletions
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index ae9db94000..dffd654a70 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -495,6 +495,8 @@ void LLViewerTexture::init(bool firstinit)
mNeedsResetMaxVirtualSize = FALSE ;
mAdditionalDecodePriority = 0.f ;
mParcelMedia = NULL ;
+ mNumFaces = 0 ;
+ mFaceList.clear() ;
}
//virtual
@@ -627,13 +629,55 @@ void LLViewerTexture::setKnownDrawSize(S32 width, S32 height)
//virtual
void LLViewerTexture::addFace(LLFace* facep)
{
- mFaceList.push_back(facep) ;
+ if(mNumFaces >= mFaceList.size())
+ {
+ mFaceList.resize(2 * mNumFaces + 1) ;
+ }
+ mFaceList[mNumFaces] = facep ;
+ facep->setIndexInTex(mNumFaces) ;
+ mNumFaces++ ;
+ mLastFaceListUpdateTimer.reset() ;
}
//virtual
void LLViewerTexture::removeFace(LLFace* facep)
{
- mFaceList.remove(facep) ;
+ if(mNumFaces > 1)
+ {
+ S32 index = facep->getIndexInTex() ;
+ mFaceList[index] = mFaceList[--mNumFaces] ;
+ mFaceList[index]->setIndexInTex(index) ;
+ }
+ else
+ {
+ mFaceList.clear() ;
+ mNumFaces = 0 ;
+ }
+ mLastFaceListUpdateTimer.reset() ;
+}
+
+S32 LLViewerTexture::getNumFaces() const
+{
+ return mNumFaces ;
+}
+
+void LLViewerTexture::reorganizeFaceList()
+{
+ static const F32 MAX_WAIT_TIME = 20.f; // seconds
+ static const U32 MAX_EXTRA_BUFFER_SIZE = 4 ;
+
+ if(mNumFaces + MAX_EXTRA_BUFFER_SIZE > mFaceList.size())
+ {
+ return ;
+ }
+
+ if(mLastFaceListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME)
+ {
+ return ;
+ }
+
+ mLastFaceListUpdateTimer.reset() ;
+ mFaceList.erase(mFaceList.begin() + mNumFaces, mFaceList.end());
}
//virtual
@@ -1531,19 +1575,18 @@ void LLViewerFetchedTexture::updateVirtualSize()
{
addTextureStats(0.f, FALSE) ;//reset
}
- if(mFaceList.size() > 0)
+
+ for(U32 i = 0 ; i < mNumFaces ; i++)
{
- for(std::list<LLFace*>::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter)
+ LLFace* facep = mFaceList[i] ;
+ if(facep->getDrawable()->isRecentlyVisible())
{
- LLFace* facep = *iter ;
- if(facep->getDrawable()->isRecentlyVisible())
- {
- addTextureStats(facep->getVirtualSize()) ;
- setAdditionalDecodePriority(facep->getImportanceToCamera()) ;
- }
- }
+ addTextureStats(facep->getVirtualSize()) ;
+ setAdditionalDecodePriority(facep->getImportanceToCamera()) ;
+ }
}
mNeedsResetMaxVirtualSize = TRUE ;
+ reorganizeFaceList() ;
}
bool LLViewerFetchedTexture::updateFetch()
@@ -1628,9 +1671,9 @@ bool LLViewerFetchedTexture::updateFetch()
mComponents = mRawImage->getComponents();
mGLTexturep->setComponents(mComponents) ;
- for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter)
+ for(U32 i = 0 ; i < mNumFaces ; i++)
{
- (*iter)->dirtyTexture() ;
+ mFaceList[i]->dirtyTexture() ;
}
}
mFullWidth = mRawImage->getWidth() << mRawDiscardLevel;
@@ -2362,16 +2405,13 @@ void LLViewerFetchedTexture::resetFaceAtlas()
//invalidate all atlas slots for this image.
void LLViewerFetchedTexture::invalidateAtlas(BOOL rebuild_geom)
{
- for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter)
+ for(U32 i = 0 ; i < mNumFaces ; i++)
{
- if(*iter)
+ LLFace* facep = mFaceList[i] ;
+ facep->removeAtlas() ;
+ if(rebuild_geom && facep->getDrawable() && facep->getDrawable()->getSpatialGroup())
{
- LLFace* facep = (LLFace*)*iter ;
- facep->removeAtlas() ;
- if(rebuild_geom && facep->getDrawable() && facep->getDrawable()->getSpatialGroup())
- {
- facep->getDrawable()->getSpatialGroup()->setState(LLSpatialGroup::GEOM_DIRTY);
- }
+ facep->getDrawable()->getSpatialGroup()->setState(LLSpatialGroup::GEOM_DIRTY);
}
}
}
@@ -2382,7 +2422,7 @@ BOOL LLViewerFetchedTexture::insertToAtlas()
{
return FALSE ;
}
- if(mFaceList.size() < 1)
+ if(getNumFaces() < 1)
{
return FALSE ;
}
@@ -2406,12 +2446,10 @@ BOOL LLViewerFetchedTexture::insertToAtlas()
//if the atlas slot pointers for some faces are null, process them later.
ll_face_list_t waiting_list ;
-
- for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter)
+ for(U32 i = 0 ; i < mNumFaces ; i++)
{
- if(*iter)
{
- facep = (LLFace*)*iter ;
+ facep = mFaceList[i] ;
//face can not use atlas.
if(!facep->canUseAtlas())
@@ -2869,9 +2907,10 @@ BOOL LLViewerMediaTexture::findFaces()
if(tex) //this media is a parcel media for tex.
{
const ll_face_list_t* face_list = tex->getFaceList() ;
- for(ll_face_list_t::const_iterator iter = face_list->begin(); iter != face_list->end(); ++iter)
+ U32 end = tex->getNumFaces() ;
+ for(U32 i = 0 ; i < end ; i++)
{
- mMediaFaceList.push_back(*iter) ;
+ mMediaFaceList.push_back((*face_list)[i]) ;
}
}
@@ -2950,7 +2989,7 @@ void LLViewerMediaTexture::removeMediaFromFace(LLFace* facep)
switchTexture(facep) ;
mIsPlaying = TRUE ; //set the flag back.
- if(mFaceList.empty()) //no face referencing to this media
+ if(getNumFaces() < 1) //no face referencing to this media
{
stopPlaying() ;
}
@@ -3006,17 +3045,17 @@ void LLViewerMediaTexture::removeFace(LLFace* facep)
//
//we have some trouble here: the texture of the face is changed.
//we need to find the former texture, and remove it from the list to avoid memory leaking.
- if(mFaceList.empty())
+ if(!mNumFaces)
{
mTextureList.clear() ;
return ;
}
- S32 end = mFaceList.size() ;
+ S32 end = getNumFaces() ;
std::vector<const LLTextureEntry*> te_list(end) ;
S32 i = 0 ;
- for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter)
+ for(U32 j = 0 ; j < mNumFaces ; j++)
{
- te_list[i++] = (*iter)->getTextureEntry() ;//all textures are in use.
+ te_list[i++] = mFaceList[j]->getTextureEntry() ;//all textures are in use.
}
for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();
iter != mTextureList.end(); ++iter)
@@ -3134,16 +3173,9 @@ void LLViewerMediaTexture::setPlaying(BOOL playing)
}
else //stop playing this media
{
- if(mFaceList.empty())
- {
- return ;
- }
-
- ll_face_list_t::iterator cur ;
- for(ll_face_list_t::iterator iter = mFaceList.begin(); iter!= mFaceList.end(); )
+ for(U32 i = mNumFaces ; i ; i--)
{
- cur = iter++ ;
- switchTexture(*cur) ; //cur could be removed in this function.
+ switchTexture(mFaceList[i - 1]) ; //current face could be removed in this function.
}
}
return ;
@@ -3165,17 +3197,14 @@ F32 LLViewerMediaTexture::getMaxVirtualSize()
if(mIsPlaying) //media is playing
{
- if(mFaceList.size() > 0)
- {
- for(std::list<LLFace*>::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter)
+ for(U32 i = 0 ; i < mNumFaces ; i++)
+ {
+ LLFace* facep = mFaceList[i] ;
+ if(facep->getDrawable()->isRecentlyVisible())
{
- LLFace* facep = *iter ;
- if(facep->getDrawable()->isRecentlyVisible())
- {
- addTextureStats(facep->getVirtualSize()) ;
- }
- }
- }
+ addTextureStats(facep->getVirtualSize()) ;
+ }
+ }
}
else //media is not in playing
{
@@ -3195,6 +3224,7 @@ F32 LLViewerMediaTexture::getMaxVirtualSize()
}
mNeedsResetMaxVirtualSize = TRUE ;
+ reorganizeFaceList() ;
return mMaxVirtualSize ;
}