[Libreoffice-commits] core.git: vcl/inc vcl/opengl
Michael Meeks
michael.meeks at collabora.com
Wed Jan 6 07:42:37 PST 2016
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.meeks at 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 <ci at libreoffice.org>
Reviewed-by: Michael Meeks <michael.meeks 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 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;
}
More information about the Libreoffice-commits
mailing list