[Libreoffice-commits] core.git: 2 commits - drawinglayer/source vcl/headless

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


 drawinglayer/source/processor2d/vclhelperbufferdevice.cxx |   33 +++++++--
 vcl/headless/svpgdi.cxx                                   |   50 +++-----------
 2 files changed, 41 insertions(+), 42 deletions(-)

New commits:
commit 26c32cfee9fc9a769adba19f455e4d6c13b6d89d
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

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();
         }
     }
commit 22a35a56b385b1a08d20eb609f35ab506cc8333e
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Thu Nov 26 11:18:40 2015 +0000

    try to get this working on linux baseline
    
    Change-Id: If17327385423d62eeb201e6754a7a45f0640c2f8

diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx
index 8783ab6..6ad1458 100644
--- a/vcl/headless/svpgdi.cxx
+++ b/vcl/headless/svpgdi.cxx
@@ -66,7 +66,7 @@ rDevice
 
 namespace
 {
-#if CAIRO_VERSION_MAJOR == 1 && CAIRO_VERSION_MINOR < 10
+#if CAIRO_VERSION < CAIRO_VERSION_ENCODE(1, 10, 0)
     struct cairo_rectangle_int_t
     {
         double x;
@@ -83,7 +83,8 @@ namespace
 
         cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
         extents.x = x1, extents.y = x2, extents.width = x2-x1, extents.height = y2-y1;
-#if CAIRO_VERSION_MAJOR > 1 || (CAIRO_VERSION_MAJOR == 1 && CAIRO_VERSION_MINOR >= 10)
+
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0)
         cairo_region_t *region = cairo_region_create_rectangle(&extents);
 
         cairo_fill_extents(cr, &x1, &y1, &x2, &y2);
@@ -104,7 +105,8 @@ namespace
 
         cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
         extents.x = x1, extents.y = x2, extents.width = x2-x1, extents.height = y2-y1;
-#if CAIRO_VERSION_MAJOR > 1 || (CAIRO_VERSION_MAJOR == 1 && CAIRO_VERSION_MINOR >= 10)
+
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0)
         cairo_region_t *region = cairo_region_create_rectangle(&extents);
 
         cairo_stroke_extents(cr, &x1, &y1, &x2, &y2);
@@ -147,9 +149,6 @@ namespace
 
 bool SvpSalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap )
 {
-    bool bRet = false;
-    (void)rTR; (void)rSourceBitmap; (void)rAlphaBitmap;
-#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0)
     if (rAlphaBitmap.GetBitCount() != 8 && rAlphaBitmap.GetBitCount() != 1)
     {
         SAL_WARN("vcl.gdi", "unsupported SvpSalGraphics::drawAlphaBitmap alpha depth case: " << rAlphaBitmap.GetBitCount());
@@ -274,9 +273,7 @@ bool SvpSalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, const SalBitmap& rS
         xDamageTracker->damaged(basegfx::B2IBox(extents.x, extents.y, extents.x + extents.width,
                                                 extents.y + extents.height));
     }
-    bRet = true;
-#endif
-    return bRet;
+    return true;
 }
 
 bool SvpSalGraphics::drawTransformedBitmap(
@@ -299,11 +296,10 @@ namespace
         if (!rBuffer)
             return false;
 
-        if (rBuffer->getScanlineFormat() != SVP_CAIRO_FORMAT
-         && rBuffer->getScanlineFormat() != basebmp::Format::OneBitMsbPal)
+        if (rBuffer->getScanlineFormat() != SVP_CAIRO_FORMAT &&
+            rBuffer->getScanlineFormat() != basebmp::Format::OneBitMsbPal)
             return false;
 
-#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0)
         basegfx::B2IVector size = rBuffer->getSize();
         sal_Int32 nStride = rBuffer->getScanlineStride();
         cairo_format_t nFormat;
@@ -312,9 +308,6 @@ namespace
         else
             nFormat = CAIRO_FORMAT_A1;
         return (cairo_format_stride_for_width(nFormat, size.getX()) == nStride);
-#else
-        return false;
-#endif
     }
 }
 
@@ -339,10 +332,6 @@ void SvpSalGraphics::clipRegion(cairo_t* cr)
 
 bool SvpSalGraphics::drawAlphaRect(long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency)
 {
-    bool bRet = false;
-    (void)nX; (void)nY; (void)nWidth; (void)nHeight; (void)nTransparency;
-#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0)
-
     cairo_t* cr = getCairoContext();
     assert(cr && m_aDevice->isTopDown());
 
@@ -389,9 +378,7 @@ bool SvpSalGraphics::drawAlphaRect(long nX, long nY, long nWidth, long nHeight,
         xDamageTracker->damaged(basegfx::B2IBox(extents.x, extents.y, extents.x + extents.width,
                                                 extents.y + extents.height));
     }
-    bRet = true;
-#endif
-    return bRet;
+    return true;
 }
 
 SvpSalGraphics::SvpSalGraphics() :
@@ -803,7 +790,6 @@ void SvpSalGraphics::drawPolyPolygon( sal_uInt32 nPoly,
     dbgOut( m_aDevice );
 }
 
-#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0)
 static void AddPolygonToPath(cairo_t* cr, const basegfx::B2DPolygon& rPolygon, bool bClosePath)
 {
     // short circuit if there is nothing to do
@@ -864,7 +850,6 @@ static void AddPolygonToPath(cairo_t* cr, const basegfx::B2DPolygon& rPolygon, b
         cairo_close_path(cr);
     }
 }
-#endif
 
 bool SvpSalGraphics::drawPolyLine(
     const ::basegfx::B2DPolygon& rPolyLine,
@@ -873,9 +858,6 @@ bool SvpSalGraphics::drawPolyLine(
     basegfx::B2DLineJoin eLineJoin,
     css::drawing::LineCap eLineCap)
 {
-    bool bRet = false;
-    (void)rPolyLine; (void)fTransparency; (void)rLineWidths; (void)eLineJoin; (void)eLineCap;
-#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0)
     // short circuit if there is nothing to do
     const int nPointCount = rPolyLine.count();
     if (nPointCount <= 0)
@@ -974,9 +956,8 @@ bool SvpSalGraphics::drawPolyLine(
         xDamageTracker->damaged(basegfx::B2IBox(extents.x, extents.y, extents.x + extents.width,
                                                 extents.y + extents.height));
     }
-    bRet = true;
-#endif
-    return bRet;
+
+    return true;
 }
 
 bool SvpSalGraphics::drawPolyLineBezier( sal_uInt32,
@@ -1006,10 +987,6 @@ bool SvpSalGraphics::drawPolyPolygonBezier( sal_uInt32,
 
 bool SvpSalGraphics::drawPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPoly, double fTransparency)
 {
-    bool bRet = false;
-    (void)rPolyPoly; (void)fTransparency;
-#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0)
-
     cairo_t* cr = getCairoContext();
     assert(cr && m_aDevice->isTopDown());
 
@@ -1055,9 +1032,8 @@ bool SvpSalGraphics::drawPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPoly, d
         xDamageTracker->damaged(basegfx::B2IBox(extents.x, extents.y, extents.x + extents.width,
                                                 extents.y + extents.height));
     }
-    bRet = true;
-#endif
-    return bRet;
+
+    return true;
 }
 
 void SvpSalGraphics::copyArea( long nDestX,


More information about the Libreoffice-commits mailing list