diff --git a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp index 8c8b4b6ae7..659d6fef7d 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp @@ -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 (context.getAssociatedObject (cacheValueID)); + CachedImageList* list = static_cast (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 Ptr; private: + OpenGLContext& context; + OwnedArray 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 images; - size_t totalSize, maxCacheSize; - CachedImage* findCachedImage (ImagePixelData* const pixelData) const { for (int i = 0; i < images.size(); ++i) diff --git a/modules/juce_opengl/opengl/juce_OpenGLTexture.cpp b/modules/juce_opengl/opengl/juce_OpenGLTexture.cpp index aa44039a6c..12dfee065f 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLTexture.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLTexture.cpp @@ -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; + } } }