Title: [228907] trunk/Source
Revision
228907
Author
[email protected]
Date
2018-02-21 16:19:58 -0800 (Wed, 21 Feb 2018)

Log Message

The WebContent process should not use NSScreen in the screenAvailableRect/screenRect implementations.
https://bugs.webkit.org/show_bug.cgi?id=182855

Reviewed by Brent Fulgham.

On macOS, the functions screenAvailableRect and screenRect is implemented using NSScreen, which is communicating
with the WindowServer. To avoid this WindowServer communication from the WebContent process when calling
screenAvailableRect and screenRect, it is possible to let the UIProcess send a message to the WebContent
process whenever there is a change in the display properties, and have the WebContent process cache these
display properties. This message should also be sent to a newly started WebContent process.

Source/WebCore:

No new tests, covered by existing tests.

* WebCore.xcodeproj/project.pbxproj:
* platform/PlatformScreen.h:
* platform/mac/PlatformScreenMac.mm:
(WebCore::getScreenProperties):
(WebCore::screenProperties):
(WebCore::setScreenProperties):
(WebCore::screenRect):
(WebCore::screenAvailableRect):
* platform/ScreenProperties.h: Added.
(WebCore::ScreenProperties::encode const):
(WebCore::ScreenProperties::decode):

Source/WebKit:

* UIProcess/WebProcessPool.cpp:
(WebKit::displayReconfigurationCallBack):
(WebKit::registerDisplayConfigurationCallback):
(WebKit::WebProcessPool::initializeNewWebProcess):
(WebKit::WebProcessPool::warmInitialProcess):
* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::setScreenProperties):
* WebProcess/WebProcess.h:
* WebProcess/WebProcess.messages.in:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (228906 => 228907)


--- trunk/Source/WebCore/ChangeLog	2018-02-22 00:17:37 UTC (rev 228906)
+++ trunk/Source/WebCore/ChangeLog	2018-02-22 00:19:58 UTC (rev 228907)
@@ -1,3 +1,30 @@
+2018-02-21  Per Arne Vollan  <[email protected]>
+
+        The WebContent process should not use NSScreen in the screenAvailableRect/screenRect implementations.
+        https://bugs.webkit.org/show_bug.cgi?id=182855
+
+        Reviewed by Brent Fulgham.
+
+        On macOS, the functions screenAvailableRect and screenRect is implemented using NSScreen, which is communicating
+        with the WindowServer. To avoid this WindowServer communication from the WebContent process when calling
+        screenAvailableRect and screenRect, it is possible to let the UIProcess send a message to the WebContent
+        process whenever there is a change in the display properties, and have the WebContent process cache these
+        display properties. This message should also be sent to a newly started WebContent process.
+
+        No new tests, covered by existing tests.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/PlatformScreen.h:
+        * platform/mac/PlatformScreenMac.mm:
+        (WebCore::getScreenProperties):
+        (WebCore::screenProperties):
+        (WebCore::setScreenProperties):
+        (WebCore::screenRect):
+        (WebCore::screenAvailableRect):
+        * platform/ScreenProperties.h: Added.
+        (WebCore::ScreenProperties::encode const):
+        (WebCore::ScreenProperties::decode):
+
 2018-02-21  Christopher Reid  <[email protected]>
 
         [Curl] Curl Cookie Database File should be configurable using NetworkProcessCreationParameters

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (228906 => 228907)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-02-22 00:17:37 UTC (rev 228906)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-02-22 00:19:58 UTC (rev 228907)
@@ -3773,6 +3773,7 @@
 		C0C054CD1118C8E400CE2636 /* IDLParser.pm in Headers */ = {isa = PBXBuildFile; fileRef = 14813BF309EDF88E00F757E1 /* IDLParser.pm */; settings = {ATTRIBUTES = (Private, ); }; };
 		C0F2A44113869AAB0066C534 /* preprocessor.pm in Headers */ = {isa = PBXBuildFile; fileRef = C0F2A43F13869A280066C534 /* preprocessor.pm */; settings = {ATTRIBUTES = (Private, ); }; };
 		C105DA640F3AA6B8001DD44F /* TextEncodingDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = C105DA630F3AA6B8001DD44F /* TextEncodingDetector.h */; };
+		C1E1D236203DF15400584665 /* ScreenProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = C1E1D235203DF15400584665 /* ScreenProperties.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		C2015C0A1BE6FEB200822389 /* FontVariantBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = C2015C091BE6FE2C00822389 /* FontVariantBuilder.h */; };
 		C21DF2EA1D9E4E9900F5B24C /* CSSFontVariationValue.h in Headers */ = {isa = PBXBuildFile; fileRef = C21DF2E81D9E4E9900F5B24C /* CSSFontVariationValue.h */; };
 		C2458E631FE897B000594759 /* FontCacheCoreText.h in Headers */ = {isa = PBXBuildFile; fileRef = C2458E611FE8979E00594759 /* FontCacheCoreText.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -12810,6 +12811,7 @@
 		C0F2A43F13869A280066C534 /* preprocessor.pm */ = {isa = PBXFileReference; lastKnownFileType = text.script.perl; name = preprocessor.pm; path = scripts/preprocessor.pm; sourceTree = "<group>"; };
 		C105DA610F3AA68F001DD44F /* TextEncodingDetectorICU.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextEncodingDetectorICU.cpp; sourceTree = "<group>"; };
 		C105DA630F3AA6B8001DD44F /* TextEncodingDetector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextEncodingDetector.h; sourceTree = "<group>"; };
+		C1E1D235203DF15400584665 /* ScreenProperties.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScreenProperties.h; sourceTree = "<group>"; };
 		C2015C091BE6FE2C00822389 /* FontVariantBuilder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FontVariantBuilder.h; sourceTree = "<group>"; };
 		C21DF2E71D9E4E9900F5B24C /* CSSFontVariationValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSFontVariationValue.cpp; sourceTree = "<group>"; };
 		C21DF2E81D9E4E9900F5B24C /* CSSFontVariationValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSFontVariationValue.h; sourceTree = "<group>"; };
@@ -23979,6 +23981,7 @@
 				293EAE1E1356B2FE0067ACF9 /* RuntimeApplicationChecks.h */,
 				5162C7F211F77EFA00612EFE /* SchemeRegistry.cpp */,
 				5162C7F311F77EFB00612EFE /* SchemeRegistry.h */,
+				C1E1D235203DF15400584665 /* ScreenProperties.h */,
 				BC8AE34C12EA096A00EB3AE6 /* ScrollableArea.cpp */,
 				BC8AE34D12EA096A00EB3AE6 /* ScrollableArea.h */,
 				CA3BF67B10D99BAE00E6CE53 /* ScrollAnimator.cpp */,
@@ -29462,6 +29465,7 @@
 				5162C7F511F77EFB00612EFE /* SchemeRegistry.h in Headers */,
 				9BD0BF9312A42BF50072FD43 /* ScopedEventQueue.h in Headers */,
 				BCEC01BE0C274DAC009F4EC9 /* Screen.h in Headers */,
+				C1E1D236203DF15400584665 /* ScreenProperties.h in Headers */,
 				A84D82C111D3474800972990 /* ScriptableDocumentParser.h in Headers */,
 				41F1D21F0EF35C2A00DA8753 /* ScriptCachedFrameData.h in Headers */,
 				93B70D7009EB0C7C009D8468 /* ScriptController.h in Headers */,

Modified: trunk/Source/WebCore/platform/PlatformScreen.h (228906 => 228907)


--- trunk/Source/WebCore/platform/PlatformScreen.h	2018-02-22 00:17:37 UTC (rev 228906)
+++ trunk/Source/WebCore/platform/PlatformScreen.h	2018-02-22 00:19:58 UTC (rev 228907)
@@ -30,6 +30,8 @@
 #endif
 
 #if PLATFORM(MAC)
+#include <wtf/HashMap.h>
+
 OBJC_CLASS NSScreen;
 OBJC_CLASS NSWindow;
 #ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES
@@ -77,6 +79,7 @@
 #endif
 
 #if PLATFORM(MAC)
+struct ScreenProperties;
 
 NSScreen *screen(NSWindow *);
 NSScreen *screen(PlatformDisplayID);
@@ -86,8 +89,13 @@
 
 NSPoint flipScreenPoint(const NSPoint&, NSScreen *);
 
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
+WEBCORE_EXPORT void getScreenProperties(HashMap<PlatformDisplayID, ScreenProperties>&);
+WEBCORE_EXPORT void setScreenProperties(const HashMap<PlatformDisplayID, ScreenProperties>&);
 #endif
 
+#endif
+
 #if PLATFORM(IOS)
 
 float screenPPIFactor();

Added: trunk/Source/WebCore/platform/ScreenProperties.h (0 => 228907)


--- trunk/Source/WebCore/platform/ScreenProperties.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/ScreenProperties.h	2018-02-22 00:19:58 UTC (rev 228907)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "FloatRect.h"
+
+namespace WebCore {
+
+struct ScreenProperties {
+    FloatRect screenAvailableRect;
+    FloatRect screenRect;
+
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static std::optional<ScreenProperties> decode(Decoder&);
+};
+
+template<class Encoder>
+void ScreenProperties::encode(Encoder& encoder) const
+{
+    encoder << screenAvailableRect << screenRect;
+}
+
+template<class Decoder>
+std::optional<ScreenProperties> ScreenProperties::decode(Decoder& decoder)
+{
+    std::optional<FloatRect> screenAvailableRect;
+    decoder >> screenAvailableRect;
+    if (!screenAvailableRect)
+        return std::nullopt;
+
+    std::optional<FloatRect> screenRect;
+    decoder >> screenRect;
+    if (!screenRect)
+        return std::nullopt;
+
+    return { { WTFMove(*screenAvailableRect), WTFMove(*screenRect) } };
+}
+
+} // namespace WebCore

Modified: trunk/Source/WebCore/platform/mac/PlatformScreenMac.mm (228906 => 228907)


--- trunk/Source/WebCore/platform/mac/PlatformScreenMac.mm	2018-02-22 00:17:37 UTC (rev 228906)
+++ trunk/Source/WebCore/platform/mac/PlatformScreenMac.mm	2018-02-22 00:19:58 UTC (rev 228907)
@@ -31,6 +31,7 @@
 #import "FloatRect.h"
 #import "FrameView.h"
 #import "HostWindow.h"
+#import "ScreenProperties.h"
 #import <ColorSync/ColorSync.h>
 #import <pal/spi/cg/CoreGraphicsSPI.h>
 
@@ -112,13 +113,56 @@
     return CGDisplayUsesInvertedPolarity();
 }
 
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
+void getScreenProperties(HashMap<PlatformDisplayID, ScreenProperties>& screenProperties)
+{
+    for (NSScreen *screen in [NSScreen screens]) {
+        FloatRect screenAvailableRect = [screen visibleFrame];
+        screenAvailableRect.setY(NSMaxY([screen frame]) - (screenAvailableRect.y() + screenAvailableRect.height())); // flip
+        FloatRect screenRect = [screen frame];
+        screenProperties.set(WebCore::displayID(screen), ScreenProperties { screenAvailableRect, screenRect});
+    }
+}
+
+static HashMap<PlatformDisplayID, ScreenProperties>& screenProperties()
+{
+    static NeverDestroyed<HashMap<PlatformDisplayID, ScreenProperties>> screenProperties;
+    return screenProperties;
+}
+
+void setScreenProperties(const HashMap<PlatformDisplayID, ScreenProperties>& properties)
+{
+    screenProperties() = properties;
+}
+#endif
+
 FloatRect screenRect(Widget* widget)
 {
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
+    if (!screenProperties().isEmpty()) {
+        auto displayIDForWidget = displayID(widget);
+        if (displayIDForWidget && screenProperties().contains(displayIDForWidget))
+            return screenProperties().get(displayIDForWidget).screenRect;
+        // Return property of the first screen if the screen is not found in the map.
+        auto iter = screenProperties().begin();
+        return screenProperties().get(iter->key).screenRect;
+    }
+#endif
     return toUserSpace([screen(widget) frame], window(widget));
 }
 
 FloatRect screenAvailableRect(Widget* widget)
 {
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
+    if (!screenProperties().isEmpty()) {
+        auto displayIDForWidget = displayID(widget);
+        if (displayIDForWidget && screenProperties().contains(displayIDForWidget))
+            return screenProperties().get(displayIDForWidget).screenAvailableRect;
+        // Return property of the first screen if the screen is not found in the map.
+        auto iter = screenProperties().begin();
+        return screenProperties().get(iter->key).screenAvailableRect;
+    }
+#endif
     return toUserSpace([screen(widget) visibleFrame], window(widget));
 }
 

Modified: trunk/Source/WebKit/ChangeLog (228906 => 228907)


--- trunk/Source/WebKit/ChangeLog	2018-02-22 00:17:37 UTC (rev 228906)
+++ trunk/Source/WebKit/ChangeLog	2018-02-22 00:19:58 UTC (rev 228907)
@@ -1,3 +1,26 @@
+2018-02-21  Per Arne Vollan  <[email protected]>
+
+        The WebContent process should not use NSScreen in the screenAvailableRect/screenRect implementations.
+        https://bugs.webkit.org/show_bug.cgi?id=182855
+
+        Reviewed by Brent Fulgham.
+
+        On macOS, the functions screenAvailableRect and screenRect is implemented using NSScreen, which is communicating
+        with the WindowServer. To avoid this WindowServer communication from the WebContent process when calling
+        screenAvailableRect and screenRect, it is possible to let the UIProcess send a message to the WebContent
+        process whenever there is a change in the display properties, and have the WebContent process cache these
+        display properties. This message should also be sent to a newly started WebContent process.
+
+        * UIProcess/WebProcessPool.cpp:
+        (WebKit::displayReconfigurationCallBack):
+        (WebKit::registerDisplayConfigurationCallback):
+        (WebKit::WebProcessPool::initializeNewWebProcess):
+        (WebKit::WebProcessPool::warmInitialProcess):
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::setScreenProperties):
+        * WebProcess/WebProcess.h:
+        * WebProcess/WebProcess.messages.in:
+
 2018-02-21  Christopher Reid  <[email protected]>
 
         [Curl] Curl Cookie Database File should be configurable using NetworkProcessCreationParameters

Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.cpp (228906 => 228907)


--- trunk/Source/WebKit/UIProcess/WebProcessPool.cpp	2018-02-22 00:17:37 UTC (rev 228906)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.cpp	2018-02-22 00:19:58 UTC (rev 228907)
@@ -78,6 +78,7 @@
 #include <_javascript_Core/JSCInlines.h>
 #include <WebCore/ApplicationCacheStorage.h>
 #include <WebCore/LogInitialization.h>
+#include <WebCore/PlatformScreen.h>
 #include <WebCore/ResourceRequest.h>
 #include <WebCore/URLParser.h>
 #include <pal/SessionID.h>
@@ -714,6 +715,27 @@
     return process;
 }
 
+#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
+static void displayReconfigurationCallBack(CGDirectDisplayID display, CGDisplayChangeSummaryFlags flags, void *userInfo)
+{
+    HashMap<PlatformDisplayID, ScreenProperties> screenProperties;
+    WebCore::getScreenProperties(screenProperties);
+
+    for (auto& processPool : WebProcessPool::allProcessPools())
+        processPool->sendToAllProcesses(Messages::WebProcess::SetScreenProperties(screenProperties));
+}
+
+static void registerDisplayConfigurationCallback()
+{
+    static std::once_flag onceFlag;
+    std::call_once(
+        onceFlag,
+        [] {
+            CGDisplayRegisterReconfigurationCallback(displayReconfigurationCallBack, nullptr);
+        });
+}
+#endif
+
 void WebProcessPool::initializeNewWebProcess(WebProcessProxy& process, WebsiteDataStore& websiteDataStore)
 {
     ensureNetworkProcess();
@@ -860,9 +882,17 @@
     // Initialize remote inspector connection now that we have a sub-process that is hosting one of our web views.
     Inspector::RemoteInspector::singleton(); 
 #endif
+
+#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
+    registerDisplayConfigurationCallback();
+
+    HashMap<PlatformDisplayID, ScreenProperties> screenProperties;
+    WebCore::getScreenProperties(screenProperties);
+    process.send(Messages::WebProcess::SetScreenProperties(screenProperties), 0);
+#endif
 }
 
-void WebProcessPool::warmInitialProcess()  
+void WebProcessPool::warmInitialProcess()
 {
     if (m_haveInitialEmptyProcess) {
         ASSERT(!m_processes.isEmpty());

Modified: trunk/Source/WebKit/WebProcess/WebProcess.cpp (228906 => 228907)


--- trunk/Source/WebKit/WebProcess/WebProcess.cpp	2018-02-22 00:17:37 UTC (rev 228906)
+++ trunk/Source/WebKit/WebProcess/WebProcess.cpp	2018-02-22 00:19:58 UTC (rev 228907)
@@ -1678,4 +1678,11 @@
 
 #endif
 
+#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
+void WebProcess::setScreenProperties(const HashMap<uint32_t, WebCore::ScreenProperties>& properties)
+{
+    WebCore::setScreenProperties(properties);
+}
+#endif
+
 } // namespace WebKit

Modified: trunk/Source/WebKit/WebProcess/WebProcess.h (228906 => 228907)


--- trunk/Source/WebKit/WebProcess/WebProcess.h	2018-02-22 00:17:37 UTC (rev 228906)
+++ trunk/Source/WebKit/WebProcess/WebProcess.h	2018-02-22 00:19:58 UTC (rev 228907)
@@ -34,6 +34,9 @@
 #include "ViewUpdateDispatcher.h"
 #include "WebInspectorInterruptDispatcher.h"
 #include <WebCore/ActivityState.h>
+#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
+#include <WebCore/ScreenProperties.h>
+#endif
 #include <WebCore/Timer.h>
 #include <pal/HysteresisActivity.h>
 #include <pal/SessionID.h>
@@ -367,6 +370,10 @@
     void didReceiveWebProcessMessage(IPC::Connection&, IPC::Decoder&);
     void didReceiveSyncWebProcessMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&);
 
+#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
+    void setScreenProperties(const HashMap<uint32_t, WebCore::ScreenProperties>&);
+#endif
+
     RefPtr<WebConnectionToUIProcess> m_webConnection;
 
     HashMap<uint64_t, RefPtr<WebPage>> m_pageMap;

Modified: trunk/Source/WebKit/WebProcess/WebProcess.messages.in (228906 => 228907)


--- trunk/Source/WebKit/WebProcess/WebProcess.messages.in	2018-02-22 00:17:37 UTC (rev 228906)
+++ trunk/Source/WebKit/WebProcess/WebProcess.messages.in	2018-02-22 00:19:58 UTC (rev 228907)
@@ -124,4 +124,8 @@
     DidCheckRemotePortForActivity(uint64_t callbackIdentifier, bool hasActivity)
     CheckProcessLocalPortForActivity(struct WebCore::MessagePortIdentifier port, uint64_t callbackIdentifier)
     MessagesAvailableForPort(struct WebCore::MessagePortIdentifier port)
+
+#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
+    SetScreenProperties(HashMap<uint32_t, WebCore::ScreenProperties> screenProperties);
+#endif
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to