fix for DEV-44134: trying to move away from a huge amount of objects with media causes viewer to hang for 15-20 seconds.

meow-7.2.2
Xiaohong Bao 2009-12-29 15:02:22 -07:00
parent 6ed6bed5ac
commit b07564b15c
3 changed files with 97 additions and 59 deletions

View File

@ -105,6 +105,9 @@ public:
F32 getVirtualSize() const { return mVSize; }
F32 getPixelArea() const { return mPixelArea; }
S32 getIndexInTex() const {return mIndexInTex ;}
void setIndexInTex(S32 index) { mIndexInTex = index ;}
void renderSetColor() const;
S32 renderElements(const U16 *index_array) const;
S32 renderIndexed ();
@ -236,6 +239,7 @@ private:
U16 mGeomIndex; // index into draw pool
U32 mIndicesCount;
U32 mIndicesIndex; // index into draw pool for indices (yeah, I know!)
S32 mIndexInTex ;
//previous rebuild's geometry info
U16 mLastGeomCount;

View File

@ -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())
for(U32 i = mNumFaces ; i ; i--)
{
return ;
}
ll_face_list_t::iterator cur ;
for(ll_face_list_t::iterator iter = mFaceList.begin(); iter!= mFaceList.end(); )
{
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 ;
}

View File

@ -134,7 +134,7 @@ public:
static S32 getIndexFromCategory(S32 category) ;
static S32 getCategoryFromIndex(S32 index) ;
typedef std::list<LLFace*> ll_face_list_t ;
typedef std::vector<LLFace*> ll_face_list_t ;
protected:
virtual ~LLViewerTexture();
@ -175,7 +175,8 @@ public:
virtual void addFace(LLFace* facep) ;
virtual void removeFace(LLFace* facep) ;
const ll_face_list_t* getFaceList() const {return &mFaceList ;}
S32 getNumFaces() const;
const ll_face_list_t* getFaceList() const {return &mFaceList;}
void generateGLTexture() ;
void destroyGLTexture() ;
@ -239,13 +240,14 @@ public:
/*virtual*/ void updateBindStatsForTester() ;
protected:
void cleanup() ;
void init(bool firstinit) ;
void init(bool firstinit) ;
void reorganizeFaceList() ;
private:
//note: do not make this function public.
/*virtual*/ LLImageGL* getGLTexture() const ;
virtual void switchToCachedImage();
protected:
LLUUID mID;
S32 mBoostLevel; // enum describing priority level
@ -257,14 +259,16 @@ protected:
mutable S8 mNeedsGLTexture;
mutable BOOL mNeedsResetMaxVirtualSize ;
mutable F32 mAdditionalDecodePriority; // priority add to mDecodePriority.
LLFrameTimer mLastReferencedTimer;
ll_face_list_t mFaceList ; //reverse pointer pointing to the faces using this image as texture
LLFrameTimer mLastReferencedTimer;
//GL texture
LLPointer<LLImageGL> mGLTexturep ;
S8 mDontDiscard; // Keep full res version of this image (for UI, etc)
ll_face_list_t mFaceList ; //reverse pointer pointing to the faces using this image as texture
U32 mNumFaces ;
LLFrameTimer mLastFaceListUpdateTimer ;
//do not use LLPointer here.
LLViewerMediaTexture* mParcelMedia ;