From ec23228a3a2fc4e8868f7f04b838313be59ad719 Mon Sep 17 00:00:00 2001 From: Jan-Marek Glogowski Date: Sun, 11 Apr 2021 17:40:26 +0200 Subject: tdf#143796 Qt5/KF5 fix double-buffer graphics This is a squashed commit for: "Qt5/KF5 get rid of unneeded own grahics handling" "tdf#143334 Qt5 don't reset buffer on style change" "tdf#144008 Qt5/Kf5 create frames in the GUI thread" commit 963f252cd1ea9c268a6ced68a3454b10cbee1a89 commit ec77a2ed0283cb3446f6e352fc329afd3dfb785c commit 923b30aa27ceb377d6a540c012000e89ce5db31e The first commit exposed the same problem to kf5, the 2nd patch is the real fix and the 3rd partly a regression for kf5 from the 1st commit but also an additional bugfix for qt5. Change-Id: I84b8dd106a35a5c2fda08a525f657b0b733a5cb7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121795 Tested-by: Jenkins Reviewed-by: Michael Weghorn Reviewed-by: Jan-Marek Glogowski Reviewed-by: Adolfo Jayme Barrientos --- vcl/inc/qt5/Qt5Frame.hxx | 8 +------- vcl/inc/qt5/Qt5Instance.hxx | 1 + vcl/qt5/Qt5Frame.cxx | 34 ++++++++++++---------------------- vcl/qt5/Qt5Instance.cxx | 18 +++++++++++++++--- vcl/unx/kf5/KF5SalFrame.cxx | 24 ------------------------ vcl/unx/kf5/KF5SalFrame.hxx | 6 ------ vcl/unx/kf5/KF5SalInstance.cxx | 16 +++++++++++++--- vcl/unx/kf5/KF5SalInstance.hxx | 1 + 8 files changed, 43 insertions(+), 65 deletions(-) diff --git a/vcl/inc/qt5/Qt5Frame.hxx b/vcl/inc/qt5/Qt5Frame.hxx index 54a721e03730..9b6e3811c3bb 100644 --- a/vcl/inc/qt5/Qt5Frame.hxx +++ b/vcl/inc/qt5/Qt5Frame.hxx @@ -77,17 +77,12 @@ class VCLPLUG_QT5_PUBLIC Qt5Frame : public QObject, public SalFrame std::unique_ptr m_pQImage; std::unique_ptr m_pQt5Graphics; UniqueCairoSurface m_pSurface; - std::unique_ptr m_pOurSvpGraphics; - // in base class, this ptr is the same as m_pOurSvpGraphic - // in derived class, it can point to a derivative - // of Qt5SvpGraphics (which the derived class then owns) - Qt5SvpGraphics* m_pSvpGraphics; + std::unique_ptr m_pSvpGraphics; DamageHandler m_aDamageHandler; QRegion m_aRegion; bool m_bNullRegion; bool m_bGraphicsInUse; - bool m_bGraphicsInvalid; SalFrameStyleFlags m_nStyle; Qt5Frame* m_pParent; PointerStyle m_ePointerStyle; @@ -144,7 +139,6 @@ public: void Damage(sal_Int32 nExtentsX, sal_Int32 nExtentsY, sal_Int32 nExtentsWidth, sal_Int32 nExtentsHeight) const; - void InitQt5SvpGraphics(Qt5SvpGraphics* pQt5SvpGraphics); virtual SalGraphics* AcquireGraphics() override; virtual void ReleaseGraphics(SalGraphics* pGraphics) override; diff --git a/vcl/inc/qt5/Qt5Instance.hxx b/vcl/inc/qt5/Qt5Instance.hxx index d73a59de51c1..a2372e58f8c9 100644 --- a/vcl/inc/qt5/Qt5Instance.hxx +++ b/vcl/inc/qt5/Qt5Instance.hxx @@ -82,6 +82,7 @@ protected: virtual Qt5FilePicker* createPicker(css::uno::Reference const& context, QFileDialog::FileMode); + bool useCairo() const { return m_bUseCairo; } public: explicit Qt5Instance(std::unique_ptr& pQApp, bool bUseCairo = false); diff --git a/vcl/qt5/Qt5Frame.cxx b/vcl/qt5/Qt5Frame.cxx index b398e9a5cf3b..d39d1729c812 100644 --- a/vcl/qt5/Qt5Frame.cxx +++ b/vcl/qt5/Qt5Frame.cxx @@ -104,10 +104,8 @@ sal_Int32 screenNumber(const QScreen* pScreen) Qt5Frame::Qt5Frame(Qt5Frame* pParent, SalFrameStyleFlags nStyle, bool bUseCairo) : m_pTopLevel(nullptr) , m_bUseCairo(bUseCairo) - , m_pSvpGraphics(nullptr) , m_bNullRegion(true) , m_bGraphicsInUse(false) - , m_bGraphicsInvalid(false) , m_ePointerStyle(PointerStyle::Arrow) , m_pDragSource(nullptr) , m_pDropTarget(nullptr) @@ -288,17 +286,6 @@ void Qt5Frame::Damage(sal_Int32 nExtentsX, sal_Int32 nExtentsY, sal_Int32 nExten 1 / devicePixelRatioF())); } -void Qt5Frame::InitQt5SvpGraphics(Qt5SvpGraphics* pQt5SvpGraphics) -{ - QSize aSize = m_pQWidget->size() * devicePixelRatioF(); - m_pSvpGraphics = pQt5SvpGraphics; - m_pSurface.reset( - cairo_image_surface_create(CAIRO_FORMAT_ARGB32, aSize.width(), aSize.height())); - m_pSvpGraphics->setSurface(m_pSurface.get(), basegfx::B2IVector(aSize.width(), aSize.height())); - cairo_surface_set_user_data(m_pSurface.get(), Qt5SvpGraphics::getDamageKey(), &m_aDamageHandler, - nullptr); -} - SalGraphics* Qt5Frame::AcquireGraphics() { if (m_bGraphicsInUse) @@ -308,24 +295,28 @@ SalGraphics* Qt5Frame::AcquireGraphics() if (m_bUseCairo) { - if (!m_pOurSvpGraphics || m_bGraphicsInvalid) + if (!m_pSvpGraphics) { - m_pOurSvpGraphics.reset(new Qt5SvpGraphics(this)); - InitQt5SvpGraphics(m_pOurSvpGraphics.get()); - m_bGraphicsInvalid = false; + QSize aSize = m_pQWidget->size() * devicePixelRatioF(); + m_pSvpGraphics.reset(new Qt5SvpGraphics(this)); + m_pSurface.reset( + cairo_image_surface_create(CAIRO_FORMAT_ARGB32, aSize.width(), aSize.height())); + m_pSvpGraphics->setSurface(m_pSurface.get(), + basegfx::B2IVector(aSize.width(), aSize.height())); + cairo_surface_set_user_data(m_pSurface.get(), Qt5SvpGraphics::getDamageKey(), + &m_aDamageHandler, nullptr); } - return m_pOurSvpGraphics.get(); + return m_pSvpGraphics.get(); } else { - if (!m_pQt5Graphics || m_bGraphicsInvalid) + if (!m_pQt5Graphics) { m_pQt5Graphics.reset(new Qt5Graphics(this)); m_pQImage.reset( new QImage(m_pQWidget->size() * devicePixelRatioF(), Qt5_DefaultFormat32)); m_pQImage->fill(Qt::transparent); m_pQt5Graphics->ChangeQImage(m_pQImage.get()); - m_bGraphicsInvalid = false; } return m_pQt5Graphics.get(); } @@ -335,7 +326,7 @@ void Qt5Frame::ReleaseGraphics(SalGraphics* pSalGraph) { (void)pSalGraph; if (m_bUseCairo) - assert(pSalGraph == m_pOurSvpGraphics.get()); + assert(pSalGraph == m_pSvpGraphics.get()); else assert(pSalGraph == m_pQt5Graphics.get()); m_bGraphicsInUse = false; @@ -1145,7 +1136,6 @@ void Qt5Frame::UpdateSettings(AllSettings& rSettings) style.SetShadowColor(toColor(pal.color(QPalette::Disabled, QPalette::WindowText))); style.SetDarkShadowColor(toColor(pal.color(QPalette::Inactive, QPalette::WindowText))); - m_bGraphicsInvalid = true; rSettings.SetStyleSettings(style); } diff --git a/vcl/qt5/Qt5Instance.cxx b/vcl/qt5/Qt5Instance.cxx index ca1f914dd707..bceae35e9016 100644 --- a/vcl/qt5/Qt5Instance.cxx +++ b/vcl/qt5/Qt5Instance.cxx @@ -252,13 +252,21 @@ void Qt5Instance::deleteObjectLater(QObject* pObject) { pObject->deleteLater(); SalFrame* Qt5Instance::CreateChildFrame(SystemParentData* /*pParent*/, SalFrameStyleFlags nStyle) { - return new Qt5Frame(nullptr, nStyle, m_bUseCairo); + SalFrame* pRet(nullptr); + RunInMainThread([&, this]() { pRet = new Qt5Frame(nullptr, nStyle, useCairo()); }); + assert(pRet); + return pRet; } SalFrame* Qt5Instance::CreateFrame(SalFrame* pParent, SalFrameStyleFlags nStyle) { assert(!pParent || dynamic_cast(pParent)); - return new Qt5Frame(static_cast(pParent), nStyle, m_bUseCairo); + + SalFrame* pRet(nullptr); + RunInMainThread( + [&, this]() { pRet = new Qt5Frame(static_cast(pParent), nStyle, useCairo()); }); + assert(pRet); + return pRet; } void Qt5Instance::DestroyFrame(SalFrame* pFrame) @@ -273,7 +281,11 @@ void Qt5Instance::DestroyFrame(SalFrame* pFrame) SalObject* Qt5Instance::CreateObject(SalFrame* pParent, SystemWindowData*, bool bShow) { assert(!pParent || dynamic_cast(pParent)); - return new Qt5Object(static_cast(pParent), bShow); + + SalObject* pRet(nullptr); + RunInMainThread([&]() { pRet = new Qt5Object(static_cast(pParent), bShow); }); + assert(pRet); + return pRet; } void Qt5Instance::DestroyObject(SalObject* pObject) diff --git a/vcl/unx/kf5/KF5SalFrame.cxx b/vcl/unx/kf5/KF5SalFrame.cxx index 1aa0b9008de7..8f14594586d2 100644 --- a/vcl/unx/kf5/KF5SalFrame.cxx +++ b/vcl/unx/kf5/KF5SalFrame.cxx @@ -45,7 +45,6 @@ KF5SalFrame::KF5SalFrame(KF5SalFrame* pParent, SalFrameStyleFlags nState, bool bUseCairo) : Qt5Frame(pParent, nState, bUseCairo) - , m_bGraphicsInUse(false) { } @@ -162,27 +161,4 @@ void KF5SalFrame::UpdateSettings(AllSettings& rSettings) rSettings.SetStyleSettings(style); } -SalGraphics* KF5SalFrame::AcquireGraphics() -{ - if (m_bGraphicsInUse) - return nullptr; - - m_bGraphicsInUse = true; - - if (!m_pKF5Graphics) - { - m_pKF5Graphics.reset(new Qt5SvpGraphics(this)); - Qt5Frame::InitQt5SvpGraphics(m_pKF5Graphics.get()); - } - - return m_pKF5Graphics.get(); -} - -void KF5SalFrame::ReleaseGraphics(SalGraphics* pSalGraph) -{ - (void)pSalGraph; - assert(pSalGraph == m_pKF5Graphics.get()); - m_bGraphicsInUse = false; -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/kf5/KF5SalFrame.hxx b/vcl/unx/kf5/KF5SalFrame.hxx index f757535c2f35..d0fdd91978e6 100644 --- a/vcl/unx/kf5/KF5SalFrame.hxx +++ b/vcl/unx/kf5/KF5SalFrame.hxx @@ -28,15 +28,9 @@ class QWidget; class KF5SalFrame : public Qt5Frame { -private: - std::unique_ptr m_pKF5Graphics; - bool m_bGraphicsInUse; - public: KF5SalFrame(KF5SalFrame* pParent, SalFrameStyleFlags nStyle, bool bUseCairo); - virtual SalGraphics* AcquireGraphics() override; - virtual void ReleaseGraphics(SalGraphics* pGraphics) override; virtual void UpdateSettings(AllSettings& rSettings) override; }; diff --git a/vcl/unx/kf5/KF5SalInstance.cxx b/vcl/unx/kf5/KF5SalInstance.cxx index 5b95ff8df572..d9d7747fe647 100644 --- a/vcl/unx/kf5/KF5SalInstance.cxx +++ b/vcl/unx/kf5/KF5SalInstance.cxx @@ -40,11 +40,21 @@ KF5SalInstance::KF5SalInstance(std::unique_ptr& pQApp) pSVData->maAppData.mxToolkitName = OUString("kf5"); } -SalFrame* KF5SalInstance::CreateFrame(SalFrame* pParent, SalFrameStyleFlags nState) +SalFrame* KF5SalInstance::CreateChildFrame(SystemParentData* /*pParent*/, SalFrameStyleFlags nStyle) { SalFrame* pRet(nullptr); - RunInMainThread([&pRet, pParent, nState]() { - pRet = new KF5SalFrame(static_cast(pParent), nState, true); + RunInMainThread([&, this]() { pRet = new KF5SalFrame(nullptr, nStyle, useCairo()); }); + assert(pRet); + return pRet; +} + +SalFrame* KF5SalInstance::CreateFrame(SalFrame* pParent, SalFrameStyleFlags nStyle) +{ + assert(!pParent || dynamic_cast(pParent)); + + SalFrame* pRet(nullptr); + RunInMainThread([&, this]() { + pRet = new KF5SalFrame(static_cast(pParent), nStyle, useCairo()); }); assert(pRet); return pRet; diff --git a/vcl/unx/kf5/KF5SalInstance.hxx b/vcl/unx/kf5/KF5SalInstance.hxx index 5dd306da5231..b951df59ab33 100644 --- a/vcl/unx/kf5/KF5SalInstance.hxx +++ b/vcl/unx/kf5/KF5SalInstance.hxx @@ -28,6 +28,7 @@ class KF5SalInstance final : public Qt5Instance QFileDialog::FileMode) override; SalFrame* CreateFrame(SalFrame* pParent, SalFrameStyleFlags nStyle) override; + SalFrame* CreateChildFrame(SystemParentData* pParent, SalFrameStyleFlags nStyle) override; public: explicit KF5SalInstance(std::unique_ptr& pQApp); -- cgit v1.2.1