summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@collabora.com>2016-01-04 21:51:28 +0000
committerTor Lillqvist <tml@collabora.com>2016-01-07 09:09:09 +0000
commitab1eed777a2e5fa94fdde1cc8260cf8ad264c145 (patch)
tree3bd336ada2306465f0b4786a56925d1292ccbe5d
parent59903419ab177402cc394e282bf24cf05f8f3441 (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.hxx3
-rw-r--r--vcl/inc/opengl/texture.hxx10
-rw-r--r--vcl/opengl/FixedTextureAtlas.cxx22
-rw-r--r--vcl/opengl/salbmp.cxx15
-rw-r--r--vcl/opengl/texture.cxx19
-rw-r--r--vcl/opengl/x11/gdiimpl.cxx12
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;
}