[Libreoffice-commits] core.git: vcl/inc vcl/unx

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Tue Sep 8 07:52:11 UTC 2020


 vcl/inc/unx/salgdi.h                     |    8 +++++---
 vcl/unx/generic/gdi/cairo_xlib_cairo.cxx |    7 +++++--
 vcl/unx/generic/gdi/salgdi.cxx           |   14 +++++++++-----
 vcl/unx/generic/gdi/salvd.cxx            |   11 +++++++----
 vcl/unx/generic/window/salframe.cxx      |    4 ++--
 5 files changed, 28 insertions(+), 16 deletions(-)

New commits:
commit f9a99998048ed0fa6e2743c7473919a9a189dcda
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Mon Sep 7 19:51:22 2020 +0100
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Tue Sep 8 09:51:28 2020 +0200

    tdf#136545 use pre-existing cairo_surface
    
    for the cairo-canvas case which has a surface for the drawable already created.
    Vaving two of them, one via cairo_xlib_surface_create and one via
    cairo_xlib_surface_create_with_xrender_format both alive at the same time seems
    understandably unreliable.
    
    This aligns the gen+X11 case closer to the gtk3 case wrt the situation of
    tdf#127529
    
    Change-Id: I411649ee36fa944b77c4b09f940a059f507be2cc
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102200
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h
index caef46a1a2e8..027d0aa6f061 100644
--- a/vcl/inc/unx/salgdi.h
+++ b/vcl/inc/unx/salgdi.h
@@ -76,7 +76,8 @@ public:
     virtual                         ~X11SalGraphics() COVERITY_NOEXCEPT_FALSE override;
 
     void                            Init( SalFrame *pFrame, Drawable aDrawable, SalX11Screen nXScreen );
-    void                            Init( X11SalVirtualDevice *pVirtualDevice, SalColormap* pColormap = nullptr, bool bDeleteColormap = false );
+    void                            Init( X11SalVirtualDevice *pVirtualDevice, cairo_surface_t* pPreExistingTarget = nullptr,
+                                          SalColormap* pColormap = nullptr, bool bDeleteColormap = false );
     void                            Init( X11OpenGLSalVirtualDevice *pVirtualDevice );
     void                            Init( X11SkiaSalVirtualDevice *pVirtualDevice );
     void                            DeInit();
@@ -86,8 +87,8 @@ public:
     inline  Display*                GetXDisplay() const;
     inline  const SalVisual&        GetVisual() const;
     SalGeometryProvider*            GetGeometryProvider() const;
-    Drawable                GetDrawable() const { return hDrawable_; }
-    void                            SetDrawable( Drawable d, SalX11Screen nXScreen );
+    Drawable                        GetDrawable() const { return hDrawable_; }
+    void                            SetDrawable(Drawable d, cairo_surface_t* surface, SalX11Screen nXScreen);
     XRenderPictFormat*              GetXRenderFormat() const;
     void                    SetXRenderFormat( XRenderPictFormat* pXRenderFormat ) { m_pXRenderFormat = pXRenderFormat; }
     const SalColormap&      GetColormap() const { return *m_pColormap; }
@@ -296,6 +297,7 @@ private:
     const SalColormap*              m_pColormap;
     std::unique_ptr<SalColormap>    m_pDeleteColormap;
     Drawable                        hDrawable_;     // use
+    cairo_surface_t*                m_pExternalSurface;
     SalX11Screen                    m_nXScreen;
     mutable XRenderPictFormat*      m_pXRenderFormat;
     XID                             m_aXRenderPicture;
diff --git a/vcl/unx/generic/gdi/cairo_xlib_cairo.cxx b/vcl/unx/generic/gdi/cairo_xlib_cairo.cxx
index 3a825052189a..1bbf8d3d5e05 100644
--- a/vcl/unx/generic/gdi/cairo_xlib_cairo.cxx
+++ b/vcl/unx/generic/gdi/cairo_xlib_cairo.cxx
@@ -248,12 +248,15 @@ namespace cairo
     {
         SystemGraphicsData aSystemGraphicsData;
 
+        cairo_surface_t* pSurface = mpSurface.get();
+
         aSystemGraphicsData.nSize = sizeof(SystemGraphicsData);
         aSystemGraphicsData.hDrawable = mpPixmap ? mpPixmap->mhDrawable : maSysData.hDrawable;
         aSystemGraphicsData.pXRenderFormat = maSysData.pRenderFormat;
+        aSystemGraphicsData.pSurface = pSurface;
 
-        int width = cairo_xlib_surface_get_width(mpSurface.get());
-        int height = cairo_xlib_surface_get_height(mpSurface.get());
+        int width = cairo_xlib_surface_get_width(pSurface);
+        int height = cairo_xlib_surface_get_height(pSurface);
 
         return VclPtr<VirtualDevice>::Create(aSystemGraphicsData,
                               Size(width, height),
diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx
index 4b2632087e7d..79037c1b3a2a 100644
--- a/vcl/unx/generic/gdi/salgdi.cxx
+++ b/vcl/unx/generic/gdi/salgdi.cxx
@@ -66,6 +66,7 @@ X11SalGraphics::X11SalGraphics():
     m_pVDev(nullptr),
     m_pColormap(nullptr),
     hDrawable_(None),
+    m_pExternalSurface(nullptr),
     m_nXScreen( 0 ),
     m_pXRenderFormat(nullptr),
     m_aXRenderPicture(0),
@@ -144,8 +145,10 @@ SalGraphicsImpl* X11SalGraphics::GetImpl() const
     return mxImpl.get();
 }
 
-void X11SalGraphics::SetDrawable( Drawable aDrawable, SalX11Screen nXScreen )
+void X11SalGraphics::SetDrawable(Drawable aDrawable, cairo_surface_t* pExternalSurface, SalX11Screen nXScreen)
 {
+    m_pExternalSurface = pExternalSurface;
+
     // shortcut if nothing changed
     if( hDrawable_ == aDrawable )
         return;
@@ -165,8 +168,6 @@ void X11SalGraphics::SetDrawable( Drawable aDrawable, SalX11Screen nXScreen )
         XRenderPeer::GetInstance().FreePicture( m_aXRenderPicture );
         m_aXRenderPicture = 0;
     }
-
-    // TODO: moggi: FIXME nTextPixel_     = GetPixel( nTextColor_ );
 }
 
 void X11SalGraphics::Init( SalFrame *pFrame, Drawable aTarget,
@@ -181,14 +182,14 @@ void X11SalGraphics::Init( SalFrame *pFrame, Drawable aTarget,
     bWindow_    = true;
     bVirDev_    = false;
 
-    SetDrawable( aTarget, nXScreen );
+    SetDrawable(aTarget, nullptr, nXScreen);
     mxImpl->Init();
 }
 
 void X11SalGraphics::DeInit()
 {
     mxImpl->DeInit();
-    SetDrawable( None, m_nXScreen );
+    SetDrawable(None, nullptr, m_nXScreen);
 }
 
 void X11SalGraphics::SetClipRegion( GC pGC, Region pXReg ) const
@@ -782,6 +783,9 @@ SalGeometryProvider *X11SalGraphics::GetGeometryProvider() const
 
 cairo_t* X11SalGraphics::getCairoContext()
 {
+    if (m_pExternalSurface)
+        return cairo_create(m_pExternalSurface);
+
     cairo_surface_t* surface = cairo_xlib_surface_create(GetXDisplay(), hDrawable_,
             GetVisual().visual, SAL_MAX_INT16, SAL_MAX_INT16);
 
diff --git a/vcl/unx/generic/gdi/salvd.cxx b/vcl/unx/generic/gdi/salvd.cxx
index 74de1baded79..00a6f0a19416 100644
--- a/vcl/unx/generic/gdi/salvd.cxx
+++ b/vcl/unx/generic/gdi/salvd.cxx
@@ -59,7 +59,7 @@ std::unique_ptr<SalVirtualDevice> X11SalInstance::CreateVirtualDevice(SalGraphic
     return CreateX11VirtualDevice(pGraphics, nDX, nDY, eFormat, pData, std::make_unique<X11SalGraphics>());
 }
 
-void X11SalGraphics::Init( X11SalVirtualDevice *pDevice, SalColormap* pColormap,
+void X11SalGraphics::Init( X11SalVirtualDevice *pDevice, cairo_surface_t* pPreExistingTarget, SalColormap* pColormap,
                            bool bDeleteColormap )
 {
     SalDisplay *pDisplay  = pDevice->GetDisplay();
@@ -88,8 +88,7 @@ void X11SalGraphics::Init( X11SalVirtualDevice *pDevice, SalColormap* pColormap,
     bWindow_     = pDisplay->IsDisplay();
     bVirDev_     = true;
 
-    const Drawable aVdevDrawable = pDevice->GetDrawable();
-    SetDrawable( aVdevDrawable, m_nXScreen );
+    SetDrawable(pDevice->GetDrawable(), pPreExistingTarget, m_nXScreen);
     mxImpl->Init();
 }
 
@@ -171,7 +170,11 @@ X11SalVirtualDevice::X11SalVirtualDevice(SalGraphics const * pGraphics, long &nD
     }
 
     pGraphics_->SetLayout( SalLayoutFlags::NONE ); // by default no! mirroring for VirtualDevices, can be enabled with EnableRTL()
-    pGraphics_->Init( this, pColormap, bDeleteColormap );
+
+    // tdf#127529 see SvpSalInstance::CreateVirtualDevice for the rare case of a non-null pPreExistingTarget
+    cairo_surface_t* pPreExistingTarget = pData ? static_cast<cairo_surface_t*>(pData->pSurface) : nullptr;
+
+    pGraphics_->Init( this, pPreExistingTarget, pColormap, bDeleteColormap );
 }
 
 X11SalVirtualDevice::~X11SalVirtualDevice()
diff --git a/vcl/unx/generic/window/salframe.cxx b/vcl/unx/generic/window/salframe.cxx
index 8d6be94a77d5..14b73dc3deb6 100644
--- a/vcl/unx/generic/window/salframe.cxx
+++ b/vcl/unx/generic/window/salframe.cxx
@@ -991,9 +991,9 @@ void X11SalFrame::updateGraphics( bool bClear )
 {
     Drawable aDrawable = bClear ? None : GetWindow();
     if( pGraphics_ )
-        pGraphics_->SetDrawable( aDrawable, m_nXScreen );
+        pGraphics_->SetDrawable( aDrawable, nullptr, m_nXScreen );
     if( pFreeGraphics_ )
-        pFreeGraphics_->SetDrawable( aDrawable, m_nXScreen );
+        pFreeGraphics_->SetDrawable( aDrawable, nullptr, m_nXScreen );
 }
 
 void X11SalFrame::SetIcon( sal_uInt16 nIcon )


More information about the Libreoffice-commits mailing list