diff options
author | Michael Meeks <michael.meeks@collabora.com> | 2016-01-04 21:51:28 +0000 |
---|---|---|
committer | Tor Lillqvist <tml@collabora.com> | 2016-01-07 09:09:09 +0000 |
commit | ab1eed777a2e5fa94fdde1cc8260cf8ad264c145 (patch) | |
tree | 3bd336ada2306465f0b4786a56925d1292ccbe5d | |
parent | 59903419ab177402cc394e282bf24cf05f8f3441 (diff) |
tdf#96894 - get ordering right for TextureAtlas cleanup on shutdown.
Do it much earlier - while we have a valid OpenGLContext.
FixedTextureAtlasManager should also 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: Ie258283147d02984b6f507c0075d114ae7288051
Reviewed-on: https://gerrit.libreoffice.org/21089
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
Tested-by: Michael Meeks <michael.meeks@collabora.com>
Reviewed-on: https://gerrit.libreoffice.org/21119
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Tor Lillqvist <tml@collabora.com>
-rw-r--r-- | vcl/inc/opengl/FixedTextureAtlas.hxx | 3 | ||||
-rw-r--r-- | vcl/inc/opengl/texture.hxx | 10 | ||||
-rw-r--r-- | vcl/opengl/FixedTextureAtlas.cxx | 22 | ||||
-rw-r--r-- | vcl/opengl/salbmp.cxx | 15 | ||||
-rw-r--r-- | vcl/opengl/texture.cxx | 19 | ||||
-rw-r--r-- | vcl/opengl/x11/gdiimpl.cxx | 12 |
6 files changed, 52 insertions, 29 deletions
diff --git a/vcl/inc/opengl/FixedTextureAtlas.hxx b/vcl/inc/opengl/FixedTextureAtlas.hxx index 362714005585..5b22b619d945 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 e57aa9e32306..938891848ab7 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; @@ -47,6 +47,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); @@ -70,11 +71,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 8a3e927b4698..80c1cfe496c7 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/salbmp.cxx b/vcl/opengl/salbmp.cxx index e9608a6c9c91..9e59e231c1ec 100644 --- a/vcl/opengl/salbmp.cxx +++ b/vcl/opengl/salbmp.cxx @@ -28,6 +28,7 @@ #include "svdata.hxx" #include "salgdi.hxx" #include "vcleventlisteners.hxx" +#include "vcl/lazydelete.hxx" #include "opengl/zone.hxx" #include "opengl/program.hxx" @@ -97,7 +98,8 @@ sal_uInt16 lclBytesPerRow(sal_uInt16 nBits, int nWidth) return 0; } -static std::vector<std::unique_ptr<FixedTextureAtlasManager>> sTextureAtlases; +typedef std::vector<std::unique_ptr< FixedTextureAtlasManager > > TextureAtlasVector; +static vcl::DeleteOnDeinit< TextureAtlasVector > gTextureAtlases(new TextureAtlasVector()); } @@ -380,6 +382,7 @@ void lclInstantiateTexture(OpenGLTexture& rTexture, const int nWidth, const int { if (nWidth == nHeight) { + TextureAtlasVector &sTextureAtlases = *gTextureAtlases.get(); if (sTextureAtlases.empty()) { sTextureAtlases.push_back(std::unique_ptr<FixedTextureAtlasManager>(new FixedTextureAtlasManager(8, 8, 16))); @@ -584,8 +587,10 @@ bool OpenGLSalBitmap::calcChecksumGL(OpenGLTexture& rInputTexture, ChecksumType& OpenGLZone aZone; rtl::Reference< OpenGLContext > xContext = OpenGLContext::getVCLContext(); - static const OpenGLTexture aCRCTableTexture(512, 1, GL_RGBA, GL_UNSIGNED_BYTE, - vcl_get_crc64_table()); + static vcl::DeleteOnDeinit<OpenGLTexture> gCRCTableTexture( + new OpenGLTexture(512, 1, GL_RGBA, GL_UNSIGNED_BYTE, + vcl_get_crc64_table())); + OpenGLTexture &rCRCTableTexture = *gCRCTableTexture.get(); // First Pass @@ -605,7 +610,7 @@ bool OpenGLSalBitmap::calcChecksumGL(OpenGLTexture& rInputTexture, ChecksumType& pProgram->SetUniform1f( "xstep", 1.0 / mnWidth ); pProgram->SetUniform1f( "ystep", 1.0 / mnHeight ); - pProgram->SetTexture("crc_table", (OpenGLTexture&)(aCRCTableTexture)); + pProgram->SetTexture("crc_table", rCRCTableTexture); pProgram->SetTexture("sampler", rInputTexture); pProgram->DrawTexture(rInputTexture); pProgram->Clean(); @@ -633,7 +638,7 @@ bool OpenGLSalBitmap::calcChecksumGL(OpenGLTexture& rInputTexture, ChecksumType& pProgram->SetUniform1f( "xstep", 1.0 / mnWidth ); pProgram->SetUniform1f( "ystep", 1.0 / mnHeight ); - pProgram->SetTexture("crc_table", (OpenGLTexture&)(aCRCTableTexture)); + pProgram->SetTexture("crc_table", rCRCTableTexture); pProgram->SetTexture("sampler", aFirstPassTexture); pProgram->DrawTexture(aFirstPassTexture); pProgram->Clean(); diff --git a/vcl/opengl/texture.cxx b/vcl/opengl/texture.cxx index 3edd1ba54518..7f047e580312 100644 --- a/vcl/opengl/texture.cxx +++ b/vcl/opengl/texture.cxx @@ -154,6 +154,11 @@ GLuint ImplOpenGLTexture::AddStencil() ImplOpenGLTexture::~ImplOpenGLTexture() { VCL_GL_INFO( "~OpenGLTexture " << mnTexture ); + Dispose(); +} + +void ImplOpenGLTexture::Dispose() +{ if( mnTexture != 0 ) { OpenGLVCLContextZone aContextZone; @@ -170,8 +175,12 @@ ImplOpenGLTexture::~ImplOpenGLTexture() } if( mnOptStencil != 0 ) + { glDeleteRenderbuffers( 1, &mnOptStencil ); + mnOptStencil = 0; + } glDeleteTextures( 1, &mnTexture ); + mnTexture = 0; } } @@ -282,16 +291,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 @@ -486,11 +491,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 effc81b3c815..b1bc724c86ee 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; } |