[Libreoffice-commits] core.git: Branch 'libreoffice-5-1' - vcl/inc vcl/opengl

Michael Meeks michael.meeks at collabora.com
Thu Jan 7 01:09:30 PST 2016


 vcl/inc/opengl/FixedTextureAtlas.hxx |    3 ++-
 vcl/inc/opengl/texture.hxx           |   10 +++++++---
 vcl/opengl/FixedTextureAtlas.cxx     |   22 ++++++++++++++++------
 vcl/opengl/salbmp.cxx                |   15 ++++++++++-----
 vcl/opengl/texture.cxx               |   19 ++++++++++---------
 vcl/opengl/x11/gdiimpl.cxx           |   12 +++++++-----
 6 files changed, 52 insertions(+), 29 deletions(-)

New commits:
commit ab1eed777a2e5fa94fdde1cc8260cf8ad264c145
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Mon Jan 4 21:51:28 2016 +0000

    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 at collabora.com>
    Tested-by: Michael Meeks <michael.meeks at collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/21119
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tor Lillqvist <tml at 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 e57aa9e..9388918 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 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/salbmp.cxx b/vcl/opengl/salbmp.cxx
index e9608a6..9e59e23 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 3edd1ba..7f047e5 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 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;
 }


More information about the Libreoffice-commits mailing list