diff options
| author | andreykproductengine <andreykproductengine@lindenlab.com> | 2019-08-13 17:22:58 +0300 | 
|---|---|---|
| committer | andreykproductengine <andreykproductengine@lindenlab.com> | 2019-08-13 17:22:58 +0300 | 
| commit | 1233842012a257b7eb49eab354bb945593c974ed (patch) | |
| tree | 0e672d401fe9d1b3fa89ec82134b192b90260fb1 /indra | |
| parent | 5196af8663653fb345394733bf4bf88185a7565a (diff) | |
SL-11718 Crash in LLRender2D
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llrender/llrender2dutils.cpp | 43 | ||||
| -rw-r--r-- | indra/llrender/llrender2dutils.h | 19 | 
2 files changed, 61 insertions, 1 deletions
| diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp index 508bccec11..4eb0203245 100644 --- a/indra/llrender/llrender2dutils.cpp +++ b/indra/llrender/llrender2dutils.cpp @@ -1570,6 +1570,10 @@ LLRender2D::LLRender2D(LLImageProviderInterface* image_provider)  {  	mGLScaleFactor = LLVector2(1.f, 1.f);  	mImageProvider = image_provider; +	if(mImageProvider) +	{ +		mImageProvider->addOnRemovalCallback(resetProvider); +	}  }  LLRender2D::~LLRender2D() @@ -1577,6 +1581,7 @@ LLRender2D::~LLRender2D()  	if(mImageProvider)  	{  		mImageProvider->cleanUp(); +		mImageProvider->deleteOnRemovalCallback(resetProvider);  	}  } @@ -1642,3 +1647,41 @@ LLPointer<LLUIImage> LLRender2D::getUIImage(const std::string& name, S32 priorit  		return NULL;  } +// static +void LLRender2D::resetProvider() +{ +    if (LLRender2D::instanceExists) +    { +        LLRender2D::getInstance()->mImageProvider = NULL; +    } +} + +// class LLImageProviderInterface + +LLImageProviderInterface::~LLImageProviderInterface() +{ +    for (callback_list_t::iterator iter = mCallbackList.begin(); iter != mCallbackList.end();) +    { +        callback_list_t::iterator curiter = iter++; +        (*curiter)(); +    } +} + +void LLImageProviderInterface::addOnRemovalCallback(callback_t func) +{ +    if (!func) +    { +        return; +    } +    mCallbackList.push_back(func); +} + +void LLImageProviderInterface::deleteOnRemovalCallback(callback_t func) +{ +    callback_list_t::iterator iter = std::find(mCallbackList.begin(), mCallbackList.end(), func); +    if (iter != mCallbackList.end()) +    { +        mCallbackList.erase(iter); +    } +} + diff --git a/indra/llrender/llrender2dutils.h b/indra/llrender/llrender2dutils.h index cf408336e6..70ab006fd6 100644 --- a/indra/llrender/llrender2dutils.h +++ b/indra/llrender/llrender2dutils.h @@ -139,6 +139,13 @@ public:  	LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0);  	LLVector2		mGLScaleFactor; + +protected: +	// since LLRender2D has no control of image provider's lifecycle +	// we need a way to tell LLRender2D that provider died and +	// LLRender2D needs to be updated. +	static void resetProvider(); +  private:  	LLImageProviderInterface* mImageProvider;  }; @@ -147,11 +154,21 @@ class LLImageProviderInterface  {  protected:  	LLImageProviderInterface() {}; -	virtual ~LLImageProviderInterface() {}; +	virtual ~LLImageProviderInterface();  public:  	virtual LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority) = 0;  	virtual LLPointer<LLUIImage> getUIImageByID(const LLUUID& id, S32 priority) = 0;  	virtual void cleanUp() = 0; + +	// to notify holders when pointer gets deleted +	typedef void(*callback_t)(); +	void addOnRemovalCallback(callback_t func); +	void deleteOnRemovalCallback(callback_t func); + +private: + +	typedef std::list< callback_t >	callback_list_t; +	callback_list_t mCallbackList;  }; | 
