[Libreoffice-commits] core.git: Branch 'libreoffice-5-1' - drawinglayer/source

Caolán McNamara caolanm at redhat.com
Fri Nov 27 08:30:07 PST 2015


 drawinglayer/source/processor2d/vclhelperbufferdevice.cxx |   33 +++++++++++---
 1 file changed, 28 insertions(+), 5 deletions(-)

New commits:
commit aab8bed7c0c0cf4d72af7d8a9d84316280887417
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri Nov 27 16:10:10 2015 +0000

    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 at 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)

diff --git a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
index e7ff5a1..fde5ba9 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();
         }
     }


More information about the Libreoffice-commits mailing list