summaryrefslogtreecommitdiff
path: root/drawinglayer
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2015-11-27 16:10:10 +0000
committerAndras Timar <andras.timar@collabora.com>2015-12-06 14:29:20 +0100
commitf187d16d445a2bf66b5685586e86569f05863556 (patch)
tree78b86a25484fac3313b92274015a14330e1cebad /drawinglayer
parented1370641e26ea371bcd1daa1c48f101f22785b2 (diff)
Resolves: rhbz#1283426 using vdevs based on now dead physical devs is unsafe
This is the same problem that commit 133e04fc1a870c0aad207e82eefeeeceaba5dc6d Author: Caolán McNamara <caolanm@redhat.com> Date: Wed Jun 17 09:23:32 2015 +0100 Resolves: tdf#91880 Invalidate graphics when the gtk window is destroyed not just when the GtkSalFrame is dtored tried to fix, but that just made it more unlikely to fail (cherry picked from commit 26c32cfee9fc9a769adba19f455e4d6c13b6d89d) (cherry picked from commit aab8bed7c0c0cf4d72af7d8a9d84316280887417) Change-Id: Icba750c787adb6cd5c5ed0874ef07e6201c4cf25 Reviewed-on: https://gerrit.libreoffice.org/20231 Reviewed-by: Michael Stahl <mstahl@redhat.com> Tested-by: Michael Stahl <mstahl@redhat.com> (cherry picked from commit 43697500af7649ef74cf6bf4bb78abe2e99fed63)
Diffstat (limited to 'drawinglayer')
-rw-r--r--drawinglayer/source/processor2d/vclhelperbufferdevice.cxx33
1 files changed, 28 insertions, 5 deletions
diff --git a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
index 93919c0019a2..ba55f41ba19a 100644
--- a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
+++ b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
@@ -43,6 +43,11 @@ namespace
// allocated/used buffers (remembered to allow deleting them in destructor)
aBuffers maUsedBuffers;
+ // remember what outputdevice was the template passed to VirtualDevice::Create
+ // so we can test if that OutputDevice was disposed before reusing a
+ // virtualdevice because that isn't safe to do at least for Gtk2
+ std::map< VclPtr<VirtualDevice>, VclPtr<OutputDevice> > maDeviceTemplates;
+
public:
VDevBuffer();
virtual ~VDevBuffer();
@@ -88,14 +93,14 @@ namespace
if (nBits == 0)
nBits = rOutDev.GetBitCount();
+ bool bOkay(false);
if(!maFreeBuffers.empty())
{
- bool bOkay(false);
aBuffers::iterator aFound(maFreeBuffers.end());
for(aBuffers::iterator a(maFreeBuffers.begin()); a != maFreeBuffers.end(); ++a)
{
- OSL_ENSURE(*a, "Empty pointer in VDevBuffer (!)");
+ assert(*a && "Empty pointer in VDevBuffer (!)");
if(nBits == (*a)->GetBitCount())
{
@@ -145,10 +150,25 @@ namespace
{
pRetval = *aFound;
maFreeBuffers.erase(aFound);
+ }
+ }
- if(bOkay)
+ if (pRetval)
+ {
+ // found a suitable cached virtual device, but the
+ // outputdevice it was based on has been disposed,
+ // drop it and create a new one instead as reusing
+ // such devices is unsafe under at least Gtk2
+ if (maDeviceTemplates[pRetval]->isDisposed())
+ {
+ maDeviceTemplates.erase(pRetval);
+ pRetval = nullptr;
+ }
+ else
+ {
+ if (bOkay)
{
- if(bClear)
+ if (bClear)
{
pRetval->Erase(Rectangle(0, 0, rSizePixel.getWidth(), rSizePixel.getHeight()));
}
@@ -164,6 +184,7 @@ namespace
if(!pRetval)
{
pRetval = VclPtr<VirtualDevice>::Create(rOutDev, nBits);
+ maDeviceTemplates[pRetval] = &rOutDev;
pRetval->SetOutputSizePixel(rSizePixel, bClear);
}
else
@@ -197,7 +218,9 @@ namespace
while(!maFreeBuffers.empty())
{
- (*(maFreeBuffers.end() - 1)).disposeAndClear();
+ aBuffers::iterator aLastOne(maFreeBuffers.end() - 1);
+ maDeviceTemplates.erase(*aLastOne);
+ aLastOne->disposeAndClear();
maFreeBuffers.pop_back();
}
}