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
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user