mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Workaround for leak of openGL textures when Images are deleted without an active GL context.
This commit is contained in:
parent
28b790c4c1
commit
fd7b9a8542
2 changed files with 43 additions and 19 deletions
|
|
@ -38,18 +38,18 @@ struct TextureInfo
|
|||
struct CachedImageList : public ReferenceCountedObject,
|
||||
private ImagePixelData::Listener
|
||||
{
|
||||
CachedImageList (size_t totalCacheSizeInPixels = 8 * 1024 * 1024) noexcept
|
||||
: totalSize (0), maxCacheSize (totalCacheSizeInPixels) {}
|
||||
CachedImageList (OpenGLContext& c, size_t totalCacheSizeInPixels = 8 * 1024 * 1024) noexcept
|
||||
: context (c), totalSize (0), maxCacheSize (totalCacheSizeInPixels) {}
|
||||
|
||||
static CachedImageList* get (OpenGLContext& context)
|
||||
static CachedImageList* get (OpenGLContext& c)
|
||||
{
|
||||
const char cacheValueID[] = "CachedImages";
|
||||
CachedImageList* list = static_cast<CachedImageList*> (context.getAssociatedObject (cacheValueID));
|
||||
CachedImageList* list = static_cast<CachedImageList*> (c.getAssociatedObject (cacheValueID));
|
||||
|
||||
if (list == nullptr)
|
||||
{
|
||||
list = new CachedImageList();
|
||||
context.setAssociatedObject (cacheValueID, list);
|
||||
list = new CachedImageList (c);
|
||||
c.setAssociatedObject (cacheValueID, list);
|
||||
}
|
||||
|
||||
return list;
|
||||
|
|
@ -131,28 +131,45 @@ struct CachedImageList : public ReferenceCountedObject,
|
|||
typedef ReferenceCountedObjectPtr<CachedImageList> Ptr;
|
||||
|
||||
private:
|
||||
OpenGLContext& context;
|
||||
OwnedArray<CachedImage> images;
|
||||
size_t totalSize, maxCacheSize;
|
||||
|
||||
bool canUseContext() const noexcept
|
||||
{
|
||||
return OpenGLContext::getCurrentContext() == &context;
|
||||
}
|
||||
|
||||
void imageDataChanged (ImagePixelData* im) override
|
||||
{
|
||||
if (CachedImage* c = findCachedImage (im))
|
||||
c->texture.release();
|
||||
if (canUseContext())
|
||||
c->texture.release();
|
||||
}
|
||||
|
||||
void imageDataBeingDeleted (ImagePixelData* im) override
|
||||
{
|
||||
for (int i = images.size(); --i >= 0;)
|
||||
{
|
||||
if (images.getUnchecked(i)->pixelData == im)
|
||||
CachedImage& ci = *images.getUnchecked(i);
|
||||
|
||||
if (ci.pixelData == im)
|
||||
{
|
||||
totalSize -= images.getUnchecked(i)->imageSize;
|
||||
images.remove (i);
|
||||
if (canUseContext())
|
||||
{
|
||||
totalSize -= ci.imageSize;
|
||||
images.remove (i);
|
||||
}
|
||||
else
|
||||
{
|
||||
ci.pixelData = nullptr;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OwnedArray<CachedImage> images;
|
||||
size_t totalSize, maxCacheSize;
|
||||
|
||||
CachedImage* findCachedImage (ImagePixelData* const pixelData) const
|
||||
{
|
||||
for (int i = 0; i < images.size(); ++i)
|
||||
|
|
|
|||
|
|
@ -164,14 +164,21 @@ void OpenGLTexture::loadARGBFlipped (const PixelARGB* pixels, int w, int h)
|
|||
|
||||
void OpenGLTexture::release()
|
||||
{
|
||||
if (textureID != 0
|
||||
&& ownerContext == OpenGLContext::getCurrentContext())
|
||||
if (textureID != 0)
|
||||
{
|
||||
glDeleteTextures (1, &textureID);
|
||||
// If the texture is deleted while the owner context is not active, it's
|
||||
// impossible to delete it, so this will be a leak until the context itself
|
||||
// is deleted.
|
||||
jassert (ownerContext == OpenGLContext::getCurrentContext());
|
||||
|
||||
textureID = 0;
|
||||
width = 0;
|
||||
height = 0;
|
||||
if (ownerContext == OpenGLContext::getCurrentContext())
|
||||
{
|
||||
glDeleteTextures (1, &textureID);
|
||||
|
||||
textureID = 0;
|
||||
width = 0;
|
||||
height = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue