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 <caol...@redhat.com> AuthorDate: Mon Sep 7 19:51:22 2020 +0100 Commit: Caolán McNamara <caol...@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 <caol...@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 ) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits