summaryrefslogtreecommitdiff
path: root/drawinglayer
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2015-11-27 16:10:10 +0000
committerCaolán McNamara <caolanm@redhat.com>2015-11-27 16:29:26 +0000
commitaab8bed7c0c0cf4d72af7d8a9d84316280887417 (patch)
tree8cedab00a4080c1284ff944d245fb53fd3c9b299 /drawinglayer
parentff2bdd52f54db24f867957a3293fae08e6a431a3 (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 Change-Id: Icba750c787adb6cd5c5ed0874ef07e6201c4cf25 (cherry picked from commit 26c32cfee9fc9a769adba19f455e4d6c13b6d89d)
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 e7ff5a1b0daa..fde5ba9a1de6 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();
@@ -87,14 +92,14 @@ namespace
sal_Int32 nBits = bMonoChrome ? 1 : 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())
{
@@ -144,10 +149,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()));
}
@@ -163,6 +183,7 @@ namespace
if(!pRetval)
{
pRetval = VclPtr<VirtualDevice>::Create(rOutDev, bMonoChrome ? DeviceFormat::BITMASK : DeviceFormat::DEFAULT);
+ maDeviceTemplates[pRetval] = &rOutDev;
pRetval->SetOutputSizePixel(rSizePixel, bClear);
}
else
@@ -196,7 +217,9 @@ namespace
while(!maFreeBuffers.empty())
{
- (*(maFreeBuffers.end() - 1)).disposeAndClear();
+ aBuffers::iterator aLastOne(maFreeBuffers.end() - 1);
+ maDeviceTemplates.erase(*aLastOne);
+ aLastOne->disposeAndClear();
maFreeBuffers.pop_back();
}
}