SL-11718 Crash in LLRender2D

master
andreykproductengine 2019-08-13 17:22:58 +03:00
parent 5196af8663
commit 1233842012
2 changed files with 61 additions and 1 deletions

View File

@ -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);
}
}

View File

@ -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;
};