summaryrefslogtreecommitdiff
path: root/external/skia/macosmetal.patch.1
blob: 48f7a24004218046acf82186dd6a916c560047f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
--- /dev/null	2023-01-25 09:20:55.000000000 -0500
+++ skia.org/tools/window/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/window/mac/MacWindowInfo.h"
+
+namespace skwindow {
+
+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 -ur skia.org/tools/window/mac/GaneshMetalWindowContext_mac.mm skia/tools/window/mac/GaneshMetalWindowContext_mac.mm
--- skia.org/tools/window/mac/GaneshMetalWindowContext_mac.mm	2024-10-10 13:50:06.102852791 +0200
+++ skia/tools/window/mac/GaneshMetalWindowContext_mac.mm	2024-10-10 13:53:34.821323595 +0200
@@ -11,6 +11,8 @@
 #include "tools/window/MetalWindowContext.h"
 #include "tools/window/mac/MacWindowInfo.h"
 
+#include <sal/log.hxx>
+
 #import <Cocoa/Cocoa.h>
 #import <QuartzCore/CAConstraintLayoutManager.h>
 
@@ -52,7 +54,23 @@
 
     SkASSERT(nil != fMainView);
 
-    fMetalLayer = [CAMetalLayer layer];
+    // Related: tdf#152703 Reuse existing CAMetalLayer to stop flicker
+    // When live resizing a window, replacing the CAMetalLayer with each
+    // resize event repaints the window's background which causes a
+    // noticeable flicker. So reuse any existing CAMetalLayer already
+    // assigned to the native view.
+    BOOL reuseMetalLayer = NO;
+    if (fMainView.wantsLayer)
+    {
+        CALayer *pLayer = fMainView.layer;
+        if (pLayer && [pLayer isKindOfClass:[CAMetalLayer class]])
+        {
+            fMetalLayer = (__bridge CAMetalLayer*)pLayer;
+            reuseMetalLayer = YES;
+        }
+    }
+    if (!reuseMetalLayer)
+        fMetalLayer = [CAMetalLayer layer];
     fMetalLayer.device = fShared->fDevice.get();
     fMetalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
 
@@ -65,10 +83,10 @@
     fMetalLayer.autoresizingMask = kCALayerHeightSizable | kCALayerWidthSizable;
     fMetalLayer.contentsGravity = kCAGravityTopLeft;
     fMetalLayer.magnificationFilter = kCAFilterNearest;
-    NSColorSpace* cs = fMainView.window.colorSpace;
-    fMetalLayer.colorspace = cs.CGColorSpace;
+    fMetalLayer.colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
 
-    fMainView.layer = fMetalLayer;
+    if (!reuseMetalLayer)
+        fMainView.layer = fMetalLayer;
     fMainView.wantsLayer = YES;
 
     return true;
@@ -85,6 +103,18 @@
     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.
+    fMetalLayer.colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
+
+    // Related tdf#145988 Reset layer's pixel format to MTLPixelFormatBGRA8Unorm
+    // Skia initally sets the layer's pixel format to be BGRA8888 but macOS
+    // may change the layer's pixel format when a window has moved to a screen
+    // with 30-bit color depth so reset it back to BGRA8888.
+    SAL_WARN_IF(fMetalLayer.pixelFormat != MTLPixelFormatBGRA8Unorm, "vcl.skia.metal", "CAMetalLayer pixel format is " << fMetalLayer.pixelFormat << " but should be " << MTLPixelFormatBGRA8Unorm << " (MTLPixelFormatBGRA8Unorm)");
+    fMetalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
+
     fWidth = backingSize.width;
     fHeight = backingSize.height;
 }
diff -ur skia.org/tools/window/mac/MacWindowInfo.h skia/tools/window/mac/MacWindowInfo.h
--- skia.org/tools/window/mac/MacWindowInfo.h	2024-10-10 13:50:06.102852791 +0200
+++ skia/tools/window/mac/MacWindowInfo.h	2024-10-10 13:51:30.227006251 +0200
@@ -22,10 +22,8 @@
     NSView* fMainView;
 };
 
-static inline CGFloat GetBackingScaleFactor(NSView* view) {
-    NSScreen* screen = view.window.screen ?: [NSScreen mainScreen];
-    return screen.backingScaleFactor;
-}
+SK_API CGFloat GetBackingScaleFactor(NSView* view);
+SK_API void ResetBackingScaleFactor();
 
 }  // namespace skwindow