external/skia/Library_skia.mk         |    1 
 external/skia/UnpackedTarball_skia.mk |    1 
 external/skia/tdf147342.patch.0       |   95 ++++++++++++++++++++++++++++++++++
 vcl/inc/osx/salframeview.h            |    1 
 vcl/inc/quartz/salgdi.h               |    3 +
 vcl/inc/skia/gdiimpl.hxx              |    3 +
 vcl/inc/skia/osx/gdiimpl.hxx          |    1 
 vcl/osx/salframe.cxx                  |    2 
 vcl/osx/salframeview.mm               |   21 +++++++
 vcl/osx/salgdiutils.cxx               |   27 ++++++++-
 vcl/quartz/salgdi.cxx                 |    5 +
 vcl/skia/gdiimpl.cxx                  |   13 ++++
 vcl/skia/osx/gdiimpl.cxx              |    2 
 13 files changed, 171 insertions(+), 4 deletions(-)

New commits:
commit a0d825133656c6329c0e7e3b0b6bafbd51e87271
Author:     Patrick Luby <plub...@neooffice.org>
AuthorDate: Tue Jan 24 20:28:22 2023 -0500
Commit:     Patrick Luby <plub...@neooffice.org>
CommitDate: Thu Jan 26 14:19:29 2023 +0000

    tdf#147342 Notify Skia that the window's backing properties changed
    
    Change-Id: I4185a240a2ca6df1c92e86ff9950f86234d4ace8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146142
    Tested-by: Jenkins
    Reviewed-by: Patrick Luby <plub...@neooffice.org>

diff --git a/external/skia/Library_skia.mk b/external/skia/Library_skia.mk
index c0f91e1a463a..3bb9cc3eed40 100644
--- a/external/skia/Library_skia.mk
+++ b/external/skia/Library_skia.mk
@@ -950,6 +950,7 @@ ifeq ($(SKIA_GPU),METAL)
 $(eval $(call gb_Library_add_generated_objcxxobjects,skia,\
     UnpackedTarball/skia/tools/sk_app/MetalWindowContext \
     UnpackedTarball/skia/tools/sk_app/mac/MetalWindowContext_mac \
+    UnpackedTarball/skia/tools/sk_app/mac/WindowContextFactory_mac \
 ))
 
 # Not used, uses OpenGL - 
UnpackedTarball/skia/tools/sk_app/mac/RasterWindowContext_mac
diff --git a/external/skia/UnpackedTarball_skia.mk 
b/external/skia/UnpackedTarball_skia.mk
index e8a75960658c..f5c199aff4e4 100644
--- a/external/skia/UnpackedTarball_skia.mk
+++ b/external/skia/UnpackedTarball_skia.mk
@@ -40,6 +40,7 @@ skia_patches := \
     tdf148624.patch.1 \
     constexpr-template.patch.0 \
     missing-include.patch.0 \
+    tdf147342.patch.0 \
 
 $(eval $(call gb_UnpackedTarball_set_patchlevel,skia,1))
 
diff --git a/external/skia/tdf147342.patch.0 b/external/skia/tdf147342.patch.0
new file mode 100644
index 000000000000..72ec8adf9a46
--- /dev/null
+++ b/external/skia/tdf147342.patch.0
@@ -0,0 +1,95 @@
+--- tools/sk_app/mac/WindowContextFactory_mac.h        2022-02-16 
06:03:39.000000000 -0500
++++ tools/sk_app/mac/WindowContextFactory_mac.h        2023-01-25 
08:09:00.000000000 -0500
+@@ -19,15 +19,8 @@
+ 
+ struct DisplayParams;
+ 
+-static inline CGFloat GetBackingScaleFactor(NSView* view) {
+-    #ifdef SK_BUILD_FOR_IOS
+-    UIScreen* screen = view.window.screen ?: [UIScreen mainScreen];
+-    return screen.nativeScale;
+-    #else
+-    NSScreen* screen = view.window.screen ?: [NSScreen mainScreen];
+-    return screen.backingScaleFactor;
+-    #endif
+-}
++SK_API CGFloat GetBackingScaleFactor(NSView* view);
++SK_API void ResetBackingScaleFactor();
+ 
+ namespace window_context_factory {
+ 
+--- tools/sk_app/mac/MetalWindowContext_mac.mm 2021-11-25 10:39:27.000000000 
-0500
++++ tools/sk_app/mac/MetalWindowContext_mac.mm 2023-01-25 08:20:32.000000000 
-0500
+@@ -87,6 +91,12 @@
+     fMetalLayer.drawableSize = backingSize;
+     fMetalLayer.contentsScale = backingScaleFactor;
+ 
++    // Related tdf#147342 Copy layer's colorspace to window's colorspace
++    // This method is now called when the window's backing properties have
++    // changed so copy any colorspace changes.
++    NSColorSpace* cs = fMainView.window.colorSpace;
++    fMetalLayer.colorspace = cs.CGColorSpace;
++
+     fWidth = backingSize.width;
+     fHeight = backingSize.height;
+ }
+--- /dev/null  2023-01-25 09:20:55.000000000 -0500
++++ tools/sk_app/mac/WindowContextFactory_mac.mm       2023-01-25 
09:21:22.000000000 -0500
+@@ -0,0 +1,57 @@
++/*
++ * Use of this source code is governed by a BSD-style license that can be
++ * found in the LICENSE file.
++ */
++
++#include "tools/sk_app/mac/WindowContextFactory_mac.h"
++
++namespace sk_app {
++
++static bool  bWindowScaling = false;
++static float fWindowScale = 1.0f;
++
++CGFloat GetBackingScaleFactor(NSView* view) {
++    #ifdef SK_BUILD_FOR_IOS
++    UIScreen* screen = view.window.screen ?: [UIScreen mainScreen];
++    return screen.nativeScale;
++    #else
++    // Related: tdf#147342 This should always be an exact copy of the
++    // sal::aqua::getWindowScaling() function in the following file:
++    // vcl/osx/salgdiutils.cxx
++    (void)view;
++
++    if (!bWindowScaling)
++    {
++        NSArray *aScreens = [NSScreen screens];
++        if (aScreens)
++        {
++            for (NSScreen *aScreen : aScreens)
++            {
++                float fScale = [aScreen backingScaleFactor];
++                if (fScale > fWindowScale)
++                  fWindowScale = fScale;
++            }
++            bWindowScaling = true;
++        }
++        if( const char* env = getenv("SAL_FORCE_HIDPI_SCALING"))
++        {
++            fWindowScale = atof(env);
++            bWindowScaling = true;
++        }
++    }
++    return fWindowScale;
++    #endif
++}
++
++void ResetBackingScaleFactor() {
++    #ifndef SK_BUILD_FOR_IOS
++    // Related: tdf#147342 Force recalculation of the window scaling but keep
++    // the previous window scaling as the minimum so that we don't lose the
++    // resolution in cached images if a HiDPI monitor is disconnected and
++    // then reconnected.
++    bWindowScaling = false;
++    GetBackingScaleFactor(nil);
++    #endif
++}
++
++}  // namespace sk_app
diff --git a/vcl/inc/osx/salframeview.h b/vcl/inc/osx/salframeview.h
index 6242f3d4146a..1282eb10cbee 100644
--- a/vcl/inc/osx/salframeview.h
+++ b/vcl/inc/osx/salframeview.h
@@ -45,6 +45,7 @@ enum class SalEvent;
 -(void)windowDidMiniaturize: (NSNotification*)pNotification;
 -(void)windowDidDeminiaturize: (NSNotification*)pNotification;
 -(BOOL)windowShouldClose: (NSNotification*)pNotification;
+-(void)windowDidChangeBackingProperties:(NSNotification *)pNotification;
 //-(void)willEncodeRestorableState:(NSCoder*)pCoderState;
 //-(void)didDecodeRestorableState:(NSCoder*)pCoderState;
 //-(void)windowWillEnterVersionBrowser:(NSNotification*)pNotification;
diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index 8886d19700a7..1261beee7d74 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -129,6 +129,7 @@ private:
 namespace sal::aqua
 {
 float getWindowScaling();
+void resetWindowScaling();
 }
 
 struct AquaSharedAttributes
@@ -287,6 +288,7 @@ public:
     virtual void drawTextLayout(const GenericSalLayout& layout, bool 
bTextRenderModeForResolutionIndependentLayout) = 0;
     virtual void Flush() {}
     virtual void Flush( const tools::Rectangle& ) {}
+    virtual void WindowBackingPropertiesChanged() {};
 protected:
     AquaGraphicsBackendBase(AquaSharedAttributes& rShared, SalGraphicsImpl * 
impl)
         : mrShared( rShared ), mpImpl(impl)
@@ -482,6 +484,7 @@ public:
 
     void                    Flush();
     void                    Flush( const tools::Rectangle& );
+    void                    WindowBackingPropertiesChanged();
 
     void                    UnsetState();
     // InvalidateContext does an UnsetState and sets mrContext to 0
diff --git a/vcl/inc/skia/gdiimpl.hxx b/vcl/inc/skia/gdiimpl.hxx
index c4a445aa66c1..d86f89ee6f4e 100644
--- a/vcl/inc/skia/gdiimpl.hxx
+++ b/vcl/inc/skia/gdiimpl.hxx
@@ -340,6 +340,8 @@ protected:
         return stream;
     }
 
+    void windowBackingPropertiesChanged();
+
     SalGraphics& mParent;
     /// Pointer to the SalFrame or SalVirtualDevice
     SalGeometryProvider* mProvider;
@@ -371,6 +373,7 @@ protected:
     LastPolyPolygonInfo mLastPolyPolygonInfo;
     inline static int pendingOperationsToFlush = 0;
     int mScaling; // The scale factor for HiDPI screens.
+    bool mInWindowBackingPropertiesChanged;
 };
 
 inline SkPaint SkiaSalGraphicsImpl::makePaintInternal() const
diff --git a/vcl/inc/skia/osx/gdiimpl.hxx b/vcl/inc/skia/osx/gdiimpl.hxx
index 71baf24625fc..b90b576a873f 100644
--- a/vcl/inc/skia/osx/gdiimpl.hxx
+++ b/vcl/inc/skia/osx/gdiimpl.hxx
@@ -43,6 +43,7 @@ public:
 
     virtual void Flush() override;
     virtual void Flush(const tools::Rectangle&) override;
+    virtual void WindowBackingPropertiesChanged() override;
 
 private:
     virtual int getWindowScaling() const override;
diff --git a/vcl/osx/salframe.cxx b/vcl/osx/salframe.cxx
index 90dd38704bcd..02a3879648db 100644
--- a/vcl/osx/salframe.cxx
+++ b/vcl/osx/salframe.cxx
@@ -287,6 +287,8 @@ void AquaSalFrame::screenParametersChanged()
 {
     OSX_SALDATA_RUNINMAIN( screenParametersChanged() )
 
+    sal::aqua::resetWindowScaling();
+
     UpdateFrameGeometry();
 
     if( mpGraphics )
diff --git a/vcl/osx/salframeview.mm b/vcl/osx/salframeview.mm
index b36cd23721ea..9eded8a40fe8 100644
--- a/vcl/osx/salframeview.mm
+++ b/vcl/osx/salframeview.mm
@@ -500,6 +500,27 @@ static AquaSalFrame* getMouseContainerFrame()
     (void)pNotification;
 }
 
+-(void)windowDidChangeBackingProperties:(NSNotification *)pNotification
+{
+    (void)pNotification;
+#if HAVE_FEATURE_SKIA
+    SolarMutexGuard aGuard;
+
+    sal::aqua::resetWindowScaling();
+
+    if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
+    {
+        // tdf#147342 Notify Skia that the window's backing properties changed
+        if ( SkiaHelper::isVCLSkiaEnabled() )
+        {
+            AquaSalGraphics* pGraphics = mpFrame->mpGraphics;
+            if ( pGraphics )
+                pGraphics->WindowBackingPropertiesChanged();
+        }
+    }
+#endif
+}
+
 -(void)dockMenuItemTriggered: (id)sender
 {
     (void)sender;
diff --git a/vcl/osx/salgdiutils.cxx b/vcl/osx/salgdiutils.cxx
index 603a8b612d42..d65897e25a83 100644
--- a/vcl/osx/salgdiutils.cxx
+++ b/vcl/osx/salgdiutils.cxx
@@ -35,6 +35,11 @@
 #include <osx/salframe.h>
 #include <osx/saldata.hxx>
 
+#if HAVE_FEATURE_SKIA
+#include <tools/sk_app/mac/WindowContextFactory_mac.h>
+#include <vcl/skia/SkiaHelper.hxx>
+#endif
+
 // TODO: Scale will be set to 2.0f as default after implementation of full 
scaled display support . This will allow moving of
 // windows between non retina and retina displays without blurry text and 
graphics. Static variables have to be removed thereafter.
 
@@ -50,15 +55,17 @@ namespace sal::aqua
 {
 float getWindowScaling()
 {
+    // Related: tdf#147342 Any changes to this function must be copied to the
+    // sk_app::GetBackingScaleFactor() function in the following file:
+    // workdir/UnpackedTarball/skia/tools/sk_app/mac/WindowContextFactory_mac.h
     if (!bWindowScaling)
     {
         NSArray *aScreens = [NSScreen screens];
         if (aScreens != nullptr)
         {
-            int nScreens = [aScreens count];
-            for (int i = 0; i < nScreens; i++)
+            for (NSScreen *aScreen : aScreens)
             {
-                float fScale = [[aScreens objectAtIndex:i] backingScaleFactor];
+                float fScale = [aScreen backingScaleFactor];
                 if (fScale > fWindowScale)
                   fWindowScale = fScale;
             }
@@ -72,6 +79,20 @@ float getWindowScaling()
     }
     return fWindowScale;
 }
+
+void resetWindowScaling()
+{
+    // Related: tdf#147342 Force recalculation of the window scaling but keep
+    // the previous window scaling as the minimum so that we don't lose the
+    // resolution in cached images if a HiDPI monitor is disconnected and
+    // then reconnected.
+#if HAVE_FEATURE_SKIA
+    if ( SkiaHelper::isVCLSkiaEnabled() )
+        sk_app::ResetBackingScaleFactor();
+#endif
+    bWindowScaling = false;
+    getWindowScaling();
+}
 } // end aqua
 
 void AquaSalGraphics::SetWindowGraphics( AquaSalFrame* pFrame )
diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx
index 571e44f23e71..78be62d02963 100644
--- a/vcl/quartz/salgdi.cxx
+++ b/vcl/quartz/salgdi.cxx
@@ -487,6 +487,11 @@ void AquaSalGraphics::Flush( const tools::Rectangle& rRect 
)
     mpBackend->Flush( rRect );
 }
 
+void AquaSalGraphics::WindowBackingPropertiesChanged()
+{
+    mpBackend->WindowBackingPropertiesChanged();
+}
+
 #ifdef IOS
 
 bool AquaSharedAttributes::checkContext()
diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index 15d901d93ff2..d0eb2ceaf51e 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -267,6 +267,7 @@ SkiaSalGraphicsImpl::SkiaSalGraphicsImpl(SalGraphics& 
rParent, SalGeometryProvid
     , mXorMode(XorMode::None)
     , mFlush(new SkiaFlushIdle(this))
     , mScaling(1)
+    , mInWindowBackingPropertiesChanged(false)
 {
 }
 
@@ -485,7 +486,7 @@ void SkiaSalGraphicsImpl::checkSurface()
         SAL_INFO("vcl.skia.trace",
                  "create(" << this << "): " << Size(mSurface->width(), 
mSurface->height()));
     }
-    else if (GetWidth() * mScaling != mSurface->width()
+    else if (mInWindowBackingPropertiesChanged || GetWidth() * mScaling != 
mSurface->width()
              || GetHeight() * mScaling != mSurface->height())
     {
         if (!avoidRecreateByResize())
@@ -2182,4 +2183,14 @@ void SkiaSalGraphicsImpl::dump(const char* file) const
     SkiaHelper::dump(mSurface, file);
 }
 
+void SkiaSalGraphicsImpl::windowBackingPropertiesChanged()
+{
+    if (mInWindowBackingPropertiesChanged || !isGPU())
+        return;
+
+    mInWindowBackingPropertiesChanged = true;
+    performFlush();
+    mInWindowBackingPropertiesChanged = false;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/skia/osx/gdiimpl.cxx b/vcl/skia/osx/gdiimpl.cxx
index 17a02fd441cf..e9c2e67fd1a4 100644
--- a/vcl/skia/osx/gdiimpl.cxx
+++ b/vcl/skia/osx/gdiimpl.cxx
@@ -95,6 +95,8 @@ void AquaSkiaSalGraphicsImpl::Flush() { performFlush(); }
 
 void AquaSkiaSalGraphicsImpl::Flush(const tools::Rectangle&) { performFlush(); 
}
 
+void AquaSkiaSalGraphicsImpl::WindowBackingPropertiesChanged() { 
windowBackingPropertiesChanged(); }
+
 void AquaSkiaSalGraphicsImpl::flushSurfaceToWindowContext()
 {
     if (!isGPU())

Reply via email to