vcl/inc/opengl/FixedTextureAtlas.hxx | 3 ++- vcl/inc/opengl/texture.hxx | 10 +++++++--- vcl/opengl/FixedTextureAtlas.cxx | 22 ++++++++++++++++------ vcl/opengl/texture.cxx | 19 ++++++++++--------- vcl/opengl/x11/gdiimpl.cxx | 12 +++++++----- 5 files changed, 42 insertions(+), 24 deletions(-)
New commits: commit 50c9d1f96530c1102dbe24408fa67e64074b9aec Author: Michael Meeks <michael.me...@collabora.com> Date: Wed Jan 6 12:12:51 2016 +0000 vcl: fix lifecycle errors & memory corruption. FixedTextureAtlasManager should use ref-counted textures properly. Also - dispose embedded textures early in VCL shutdown while we have a valid OpenGLContext. Also - dispose the native widget control cache earlier too. Change-Id: Id3f7a1c3b331496616f36cbf02f83737505278a5 Reviewed-on: https://gerrit.libreoffice.org/21148 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Michael Meeks <michael.me...@collabora.com> diff --git a/vcl/inc/opengl/FixedTextureAtlas.hxx b/vcl/inc/opengl/FixedTextureAtlas.hxx index 3627140..5b22b619 100644 --- a/vcl/inc/opengl/FixedTextureAtlas.hxx +++ b/vcl/inc/opengl/FixedTextureAtlas.hxx @@ -16,7 +16,7 @@ class VCL_PLUGIN_PUBLIC FixedTextureAtlasManager { - std::vector<std::unique_ptr<ImplOpenGLTexture>> mpTextures; + std::vector<ImplOpenGLTexture *> mpTextures; int mWidthFactor; int mHeightFactor; @@ -26,6 +26,7 @@ class VCL_PLUGIN_PUBLIC FixedTextureAtlasManager public: FixedTextureAtlasManager(int nWidthFactor, int nHeightFactor, int nTextureSize); + ~FixedTextureAtlasManager(); OpenGLTexture InsertBuffer(int nWidth, int nHeight, int nFormat, int nType, sal_uInt8* pData); int GetSubtextureSize() diff --git a/vcl/inc/opengl/texture.hxx b/vcl/inc/opengl/texture.hxx index 821a649..113c65b 100644 --- a/vcl/inc/opengl/texture.hxx +++ b/vcl/inc/opengl/texture.hxx @@ -31,8 +31,8 @@ class ImplOpenGLTexture { -public: int mnRefCount; +public: GLuint mnTexture; int mnWidth; int mnHeight; @@ -46,6 +46,7 @@ public: ImplOpenGLTexture( int nWidth, int nHeight, int nFormat, int nType, void const * pData ); ImplOpenGLTexture( int nX, int nY, int nWidth, int nHeight ); ~ImplOpenGLTexture(); + void Dispose(); bool InsertBuffer(int nX, int nY, int nWidth, int nHeight, int nFormat, int nType, sal_uInt8* pData); @@ -69,11 +70,14 @@ public: if (mpSlotReferences->at(nSlotNumber) == 0) mnFreeSlots++; } + + if (mnRefCount <= 0) + delete this; } - bool ExistRefs() + bool IsUnique() { - return mnRefCount > 0; + return mnRefCount == 1; } bool InitializeSlots(int nSlotSize); diff --git a/vcl/opengl/FixedTextureAtlas.cxx b/vcl/opengl/FixedTextureAtlas.cxx index 8a3e927..80c1cfe 100644 --- a/vcl/opengl/FixedTextureAtlas.cxx +++ b/vcl/opengl/FixedTextureAtlas.cxx @@ -24,11 +24,21 @@ FixedTextureAtlasManager::FixedTextureAtlasManager(int nWidthFactor, int nHeight { } +FixedTextureAtlasManager::~FixedTextureAtlasManager() +{ + for (auto i = mpTextures.begin(); i != mpTextures.end(); ++i) + { + // Free texture early in VCL shutdown while we have a context. + (*i)->Dispose(); + (*i)->DecreaseRefCount(0); + } +} + void FixedTextureAtlasManager::CreateNewTexture() { int nTextureWidth = mWidthFactor * mSubTextureSize; int nTextureHeight = mHeightFactor * mSubTextureSize; - mpTextures.push_back(std::unique_ptr<ImplOpenGLTexture>(new ImplOpenGLTexture(nTextureWidth, nTextureHeight, true))); + mpTextures.push_back(new ImplOpenGLTexture(nTextureWidth, nTextureHeight, true)); mpTextures.back()->InitializeSlots(mWidthFactor * mHeightFactor); } @@ -36,21 +46,21 @@ OpenGLTexture FixedTextureAtlasManager::InsertBuffer(int nWidth, int nHeight, in { ImplOpenGLTexture* pTexture = nullptr; - auto funFreeSlot = [] (std::unique_ptr<ImplOpenGLTexture>& mpTexture) + auto funFreeSlot = [] (ImplOpenGLTexture *mpTexture) { return mpTexture->mnFreeSlots > 0; }; - auto aIterator = std::find_if(mpTextures.begin(), mpTextures.end(), funFreeSlot); + auto it = std::find_if(mpTextures.begin(), mpTextures.end(), funFreeSlot); - if (aIterator != mpTextures.end()) + if (it != mpTextures.end()) { - pTexture = (*aIterator).get(); + pTexture = *it; } else { CreateNewTexture(); - pTexture = mpTextures.back().get(); + pTexture = mpTextures.back(); } int nSlot = pTexture->FindFreeSlot(); diff --git a/vcl/opengl/texture.cxx b/vcl/opengl/texture.cxx index 303b8b8..3b484c0 100644 --- a/vcl/opengl/texture.cxx +++ b/vcl/opengl/texture.cxx @@ -157,6 +157,11 @@ GLuint ImplOpenGLTexture::AddStencil() ImplOpenGLTexture::~ImplOpenGLTexture() { VCL_GL_INFO( "~OpenGLTexture " << mnTexture ); + Dispose(); +} + +void ImplOpenGLTexture::Dispose() +{ if( mnTexture != 0 ) { OpenGLVCLContextZone aContextZone; @@ -173,8 +178,12 @@ ImplOpenGLTexture::~ImplOpenGLTexture() } if( mnOptStencil != 0 ) + { glDeleteRenderbuffers( 1, &mnOptStencil ); + mnOptStencil = 0; + } glDeleteTextures( 1, &mnTexture ); + mnTexture = 0; } } @@ -285,16 +294,12 @@ OpenGLTexture::OpenGLTexture( const OpenGLTexture& rTexture, OpenGLTexture::~OpenGLTexture() { if (mpImpl) - { mpImpl->DecreaseRefCount(mnSlotNumber); - if (!mpImpl->ExistRefs()) - delete mpImpl; - } } bool OpenGLTexture::IsUnique() const { - return ( mpImpl == nullptr || mpImpl->mnRefCount == 1 ); + return mpImpl == nullptr || mpImpl->IsUnique(); } GLuint OpenGLTexture::Id() const @@ -484,11 +489,7 @@ OpenGLTexture& OpenGLTexture::operator=( const OpenGLTexture& rTexture ) } if (mpImpl) - { mpImpl->DecreaseRefCount(mnSlotNumber); - if (!mpImpl->ExistRefs()) - delete mpImpl; - } maRect = rTexture.maRect; mpImpl = rTexture.mpImpl; diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx index effc81b..b1bc724 100644 --- a/vcl/opengl/x11/gdiimpl.cxx +++ b/vcl/opengl/x11/gdiimpl.cxx @@ -8,6 +8,7 @@ */ #include <vcl/salbtype.hxx> +#include <vcl/lazydelete.hxx> #include <svdata.hxx> @@ -105,7 +106,7 @@ bool X11OpenGLSalGraphicsImpl::FillPixmapFromScreen( X11Pixmap* pPixmap, int nX, typedef typename std::pair<ControlCacheKey, std::unique_ptr<TextureCombo>> ControlCachePair; typedef o3tl::lru_map<ControlCacheKey, std::unique_ptr<TextureCombo>, ControlCacheHashFunction> ControlCacheType; -ControlCacheType gTextureCache(200); +vcl::DeleteOnDeinit<ControlCacheType> gTextureCache(new ControlCacheType(200)); bool X11OpenGLSalGraphicsImpl::RenderPixmap(X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY, TextureCombo& rCombo) { @@ -190,12 +191,12 @@ bool X11OpenGLSalGraphicsImpl::TryRenderCachedNativeControl(ControlCacheKey& rCo { static bool gbCacheEnabled = !getenv("SAL_WITHOUT_WIDGET_CACHE"); - if (!gbCacheEnabled) + if (!gbCacheEnabled || !gTextureCache.get()) return false; - ControlCacheType::const_iterator iterator = gTextureCache.find(rControlCacheKey); + ControlCacheType::const_iterator iterator = gTextureCache.get()->find(rControlCacheKey); - if (iterator == gTextureCache.end()) + if (iterator == gTextureCache.get()->end()) return false; const std::unique_ptr<TextureCombo>& pCombo = iterator->second; @@ -229,7 +230,8 @@ bool X11OpenGLSalGraphicsImpl::RenderAndCacheNativeControl(X11Pixmap* pPixmap, X return true; ControlCachePair pair(aControlCacheKey, std::move(pCombo)); - gTextureCache.insert(std::move(pair)); + if (gTextureCache.get()) + gTextureCache.get()->insert(std::move(pair)); return bResult; } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits