Title: [234074] trunk/Source/WebCore
Revision
234074
Author
[email protected]
Date
2018-07-20 16:43:01 -0700 (Fri, 20 Jul 2018)

Log Message

Safari WebGL does not consistently provide correct GPU context on eGPU systems
https://bugs.webkit.org/show_bug.cgi?id=187750
<rdar://problem/39531436>

Patch by Justin Fan <[email protected]> on 2018-07-20
Reviewed by Dean Jackson.

Move GraphicsContext3DManager into its own class, and notify it when page/Chrome receives a
windowScreenDidChange message. Add a private data struct to track which hostWindow created each context.
Upon notification, Manager updates the contexts that match the hostWindow with the
provided displayID. Each context matches displayID to rendererID (set during process creation
if window server is blocked), which is matched to a virtual screen, and updates its GPU accordingly.

No new tests. This requires multiple GPUs or eGPUs, each with attached display(s), to test.

* WebCore.xcodeproj/project.pbxproj:
* page/Chrome.cpp:
(WebCore::Chrome::windowScreenDidChange): Now calls GraphicsContext3DManager::screenDidChange().
* platform/PlatformScreen.h:
* platform/ScreenProperties.h: Add rendererID to struct.
(WebCore::ScreenData::encode const):
(WebCore::ScreenData::decode):
* platform/graphics/GraphicsContext3D.h:
* platform/graphics/GraphicsContext3DManager.cpp: Added (copied out of GraphicsContext3DCocoa.mm).
(WebCore::attachToAppleGraphicsControl):
(WebCore::hasMuxCapability):
(WebCore::hasMuxableGPU):
(WebCore::GraphicsContext3DManager::sharedManager):
(WebCore::displayWasReconfigured):
(WebCore::GraphicsContext3DManager::updateAllContexts):
(WebCore::GraphicsContext3DManager::screenDidChange):
(WebCore::GraphicsContext3DManager::addContext):
(WebCore::GraphicsContext3DManager::removeContext):
(WebCore::GraphicsContext3DManager::hostWindowForContext const):
(WebCore::GraphicsContext3DManager::addContextRequiringHighPerformance):
(WebCore::GraphicsContext3DManager::removeContextRequiringHighPerformance):
(WebCore::GraphicsContext3DManager::updateHighPerformanceState):
(WebCore::GraphicsContext3DManager::disableHighPerformanceGPUTimerFired):
(WebCore::GraphicsContext3DManager::recycleContextIfNecessary):
* platform/graphics/GraphicsContext3DManager.h: Added (copied out of GraphicsContext3DCocoa.mm).
(WebCore::GraphicsContext3DManager::hasTooManyContexts const):
(WebCore::GraphicsContext3DManager::GraphicsContext3DManager):
* platform/graphics/cocoa/GraphicsContext3DCocoa.mm:
(WebCore::GraphicsContext3D::create):
(WebCore::GraphicsContext3D::createShared):
(WebCore::identifyAndSetCurrentGPU): Now matches rendererIDs to determine virtual screen.
(WebCore::GraphicsContext3D::GraphicsContext3D):
(WebCore::GraphicsContext3D::~GraphicsContext3D):
(WebCore::GraphicsContext3D::setContextVisibility):
(WebCore::GraphicsContext3D::simulateContextChanged):
(WebCore::GraphicsContext3D::screenDidChange):
(WebCore::attachToAppleGraphicsControl): Deleted.
(WebCore::hasMuxCapability): Deleted.
(WebCore::hasMuxableGPU): Deleted.
(WebCore::GraphicsContext3DManager::GraphicsContext3DManager): Deleted.
(WebCore::GraphicsContext3DManager::hasTooManyContexts const): Deleted.
(WebCore::manager): Deleted.
(WebCore::displayWasReconfigured): Deleted.
(WebCore::GraphicsContext3DManager::updateAllContexts): Deleted.
(WebCore::GraphicsContext3DManager::addContext): Deleted.
(WebCore::GraphicsContext3DManager::removeContext): Deleted.
(WebCore::GraphicsContext3DManager::addContextRequiringHighPerformance): Deleted.
(WebCore::GraphicsContext3DManager::removeContextRequiringHighPerformance): Deleted.
(WebCore::GraphicsContext3DManager::updateHighPerformanceState): Deleted.
(WebCore::GraphicsContext3DManager::disableHighPerformanceGPUTimerFired): Deleted.
(WebCore::GraphicsContext3DManager::recycleContextIfNecessary): Deleted.
* platform/mac/PlatformScreenMac.mm: Provide a display's rendererID.
(WebCore::rendererIDForDisplayMask):
(WebCore::collectScreenProperties):
(WebCore::rendererIDForDisplay):
(WebCore::primaryRendererID):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (234073 => 234074)


--- trunk/Source/WebCore/ChangeLog	2018-07-20 23:33:39 UTC (rev 234073)
+++ trunk/Source/WebCore/ChangeLog	2018-07-20 23:43:01 UTC (rev 234074)
@@ -1,3 +1,76 @@
+2018-07-20  Justin Fan  <[email protected]>
+
+        Safari WebGL does not consistently provide correct GPU context on eGPU systems
+        https://bugs.webkit.org/show_bug.cgi?id=187750
+        <rdar://problem/39531436>
+
+        Reviewed by Dean Jackson.
+
+        Move GraphicsContext3DManager into its own class, and notify it when page/Chrome receives a 
+        windowScreenDidChange message. Add a private data struct to track which hostWindow created each context.
+        Upon notification, Manager updates the contexts that match the hostWindow with the
+        provided displayID. Each context matches displayID to rendererID (set during process creation 
+        if window server is blocked), which is matched to a virtual screen, and updates its GPU accordingly.
+
+        No new tests. This requires multiple GPUs or eGPUs, each with attached display(s), to test.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * page/Chrome.cpp:
+        (WebCore::Chrome::windowScreenDidChange): Now calls GraphicsContext3DManager::screenDidChange().
+        * platform/PlatformScreen.h:
+        * platform/ScreenProperties.h: Add rendererID to struct.
+        (WebCore::ScreenData::encode const):
+        (WebCore::ScreenData::decode):
+        * platform/graphics/GraphicsContext3D.h:
+        * platform/graphics/GraphicsContext3DManager.cpp: Added (copied out of GraphicsContext3DCocoa.mm).
+        (WebCore::attachToAppleGraphicsControl):
+        (WebCore::hasMuxCapability):
+        (WebCore::hasMuxableGPU):
+        (WebCore::GraphicsContext3DManager::sharedManager):
+        (WebCore::displayWasReconfigured):
+        (WebCore::GraphicsContext3DManager::updateAllContexts):
+        (WebCore::GraphicsContext3DManager::screenDidChange):
+        (WebCore::GraphicsContext3DManager::addContext):
+        (WebCore::GraphicsContext3DManager::removeContext):
+        (WebCore::GraphicsContext3DManager::hostWindowForContext const):
+        (WebCore::GraphicsContext3DManager::addContextRequiringHighPerformance):
+        (WebCore::GraphicsContext3DManager::removeContextRequiringHighPerformance):
+        (WebCore::GraphicsContext3DManager::updateHighPerformanceState):
+        (WebCore::GraphicsContext3DManager::disableHighPerformanceGPUTimerFired):
+        (WebCore::GraphicsContext3DManager::recycleContextIfNecessary):
+        * platform/graphics/GraphicsContext3DManager.h: Added (copied out of GraphicsContext3DCocoa.mm).
+        (WebCore::GraphicsContext3DManager::hasTooManyContexts const):
+        (WebCore::GraphicsContext3DManager::GraphicsContext3DManager):
+        * platform/graphics/cocoa/GraphicsContext3DCocoa.mm:
+        (WebCore::GraphicsContext3D::create):
+        (WebCore::GraphicsContext3D::createShared):
+        (WebCore::identifyAndSetCurrentGPU): Now matches rendererIDs to determine virtual screen. 
+        (WebCore::GraphicsContext3D::GraphicsContext3D):
+        (WebCore::GraphicsContext3D::~GraphicsContext3D):
+        (WebCore::GraphicsContext3D::setContextVisibility):
+        (WebCore::GraphicsContext3D::simulateContextChanged):
+        (WebCore::GraphicsContext3D::screenDidChange):
+        (WebCore::attachToAppleGraphicsControl): Deleted.
+        (WebCore::hasMuxCapability): Deleted.
+        (WebCore::hasMuxableGPU): Deleted.
+        (WebCore::GraphicsContext3DManager::GraphicsContext3DManager): Deleted.
+        (WebCore::GraphicsContext3DManager::hasTooManyContexts const): Deleted.
+        (WebCore::manager): Deleted.
+        (WebCore::displayWasReconfigured): Deleted.
+        (WebCore::GraphicsContext3DManager::updateAllContexts): Deleted.
+        (WebCore::GraphicsContext3DManager::addContext): Deleted.
+        (WebCore::GraphicsContext3DManager::removeContext): Deleted.
+        (WebCore::GraphicsContext3DManager::addContextRequiringHighPerformance): Deleted.
+        (WebCore::GraphicsContext3DManager::removeContextRequiringHighPerformance): Deleted.
+        (WebCore::GraphicsContext3DManager::updateHighPerformanceState): Deleted.
+        (WebCore::GraphicsContext3DManager::disableHighPerformanceGPUTimerFired): Deleted.
+        (WebCore::GraphicsContext3DManager::recycleContextIfNecessary): Deleted.
+        * platform/mac/PlatformScreenMac.mm: Provide a display's rendererID.
+        (WebCore::rendererIDForDisplayMask):
+        (WebCore::collectScreenProperties):
+        (WebCore::rendererIDForDisplay):
+        (WebCore::primaryRendererID):
+
 2018-07-19  Simon Fraser  <[email protected]>
 
         Remove completed animations from GraphicsLayer, thus avoiding excessive backing store allocation

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (234073 => 234074)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-07-20 23:33:39 UTC (rev 234073)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-07-20 23:43:01 UTC (rev 234074)
@@ -4123,6 +4123,8 @@
 		D05CED2A0A40BB2C00C5AF38 /* FormatBlockCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D05CED280A40BB2C00C5AF38 /* FormatBlockCommand.h */; };
 		D06C0D8F0CFD11460065F43F /* RemoveFormatCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D06C0D8D0CFD11460065F43F /* RemoveFormatCommand.h */; };
 		D07DEABA0A36554A00CA30F8 /* InsertListCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D07DEAB80A36554A00CA30F8 /* InsertListCommand.h */; };
+		D0843A4B20FEBE3D00FE860E /* GraphicsContext3DManager.h in Headers */ = {isa = PBXBuildFile; fileRef = D0843A4A20FEBE3D00FE860E /* GraphicsContext3DManager.h */; };
+		D0843A4D20FEC16500FE860E /* GraphicsContext3DManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0843A4C20FEC16500FE860E /* GraphicsContext3DManager.cpp */; };
 		D086FE9809D53AAB005BC74D /* UnlinkCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D086FE9609D53AAB005BC74D /* UnlinkCommand.h */; };
 		D08B00E220A282490004BC0A /* WebGLCompressedTextureASTC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A20D562092A0A600E0C259 /* WebGLCompressedTextureASTC.cpp */; };
 		D08B00E420A282590004BC0A /* WebGLCompressedTextureASTC.h in Headers */ = {isa = PBXBuildFile; fileRef = D0A20D542092A0A600E0C259 /* WebGLCompressedTextureASTC.h */; };
@@ -13541,6 +13543,8 @@
 		D06C0D8E0CFD11460065F43F /* RemoveFormatCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RemoveFormatCommand.cpp; sourceTree = "<group>"; };
 		D07DEAB70A36554A00CA30F8 /* InsertListCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = InsertListCommand.cpp; sourceTree = "<group>"; };
 		D07DEAB80A36554A00CA30F8 /* InsertListCommand.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = InsertListCommand.h; sourceTree = "<group>"; };
+		D0843A4A20FEBE3D00FE860E /* GraphicsContext3DManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GraphicsContext3DManager.h; sourceTree = "<group>"; };
+		D0843A4C20FEC16500FE860E /* GraphicsContext3DManager.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GraphicsContext3DManager.cpp; sourceTree = "<group>"; };
 		D086FE9609D53AAB005BC74D /* UnlinkCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnlinkCommand.h; sourceTree = "<group>"; };
 		D086FE9709D53AAB005BC74D /* UnlinkCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnlinkCommand.cpp; sourceTree = "<group>"; };
 		D0A20D542092A0A600E0C259 /* WebGLCompressedTextureASTC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebGLCompressedTextureASTC.h; sourceTree = "<group>"; };
@@ -23645,6 +23649,8 @@
 				6E21C6BF1126338500A7BE02 /* GraphicsContext3D.cpp */,
 				49C7B9FB1042D3650009D447 /* GraphicsContext3D.h */,
 				7C330A011DF8FAC600D3395C /* GraphicsContext3DAttributes.h */,
+				D0843A4C20FEC16500FE860E /* GraphicsContext3DManager.cpp */,
+				D0843A4A20FEBE3D00FE860E /* GraphicsContext3DManager.h */,
 				0F0012401FAD881000531D76 /* GraphicsContextImpl.cpp */,
 				0F00123F1FAD87D600531D76 /* GraphicsContextImpl.h */,
 				0F580B090F12A2690051D689 /* GraphicsLayer.cpp */,
@@ -28083,6 +28089,7 @@
 				49C7B9FC1042D3650009D447 /* GraphicsContext3D.h in Headers */,
 				7C330A021DF8FAC600D3395C /* GraphicsContext3DAttributes.h in Headers */,
 				31AB5000122878A2001A7DB0 /* GraphicsContext3DIOS.h in Headers */,
+				D0843A4B20FEBE3D00FE860E /* GraphicsContext3DManager.h in Headers */,
 				934907E4125BBBC8007F23A0 /* GraphicsContextCG.h in Headers */,
 				A80D67080E9E9DEB00E420F0 /* GraphicsContextPlatformPrivateCG.h in Headers */,
 				0F580B0D0F12A2690051D689 /* GraphicsLayer.h in Headers */,
@@ -31477,6 +31484,7 @@
 				515BE1911D54F5FB00DD7C68 /* GamepadProvider.cpp in Sources */,
 				837964CF1F8DB69D00218EA0 /* GeolocationPositionIOS.mm in Sources */,
 				6E21C6C01126338500A7BE02 /* GraphicsContext3D.cpp in Sources */,
+				D0843A4D20FEC16500FE860E /* GraphicsContext3DManager.cpp in Sources */,
 				7C3E510B18DF8F3500C112F7 /* HTMLConverter.mm in Sources */,
 				A8D06B3A0A265DCD005E7203 /* HTMLNames.cpp in Sources */,
 				1AC900C31943C0FC008625B5 /* HTTPHeaderNames.cpp in Sources */,

Modified: trunk/Source/WebCore/page/Chrome.cpp (234073 => 234074)


--- trunk/Source/WebCore/page/Chrome.cpp	2018-07-20 23:33:39 UTC (rev 234073)
+++ trunk/Source/WebCore/page/Chrome.cpp	2018-07-20 23:43:01 UTC (rev 234074)
@@ -60,6 +60,10 @@
 #include "DataListSuggestionPicker.h"
 #endif
 
+#if PLATFORM(MAC) && ENABLE(GRAPHICS_CONTEXT_3D)
+#include "GraphicsContext3DManager.h"
+#endif
+
 namespace WebCore {
 
 using namespace HTMLNames;
@@ -510,6 +514,11 @@
         if (frame->document())
             frame->document()->windowScreenDidChange(displayID);
     }
+
+#if PLATFORM(MAC) && ENABLE(GRAPHICS_CONTEXT_3D)
+    GraphicsContext3DManager::sharedManager().screenDidChange(displayID, this);
+#endif
+
 }
 
 // --------

Modified: trunk/Source/WebCore/platform/PlatformScreen.h (234073 => 234074)


--- trunk/Source/WebCore/platform/PlatformScreen.h	2018-07-20 23:33:39 UTC (rev 234073)
+++ trunk/Source/WebCore/platform/PlatformScreen.h	2018-07-20 23:43:01 UTC (rev 234074)
@@ -100,6 +100,8 @@
 
 uint32_t primaryOpenGLDisplayMask();
 uint32_t displayMaskForDisplay(PlatformDisplayID);
+int32_t rendererIDForDisplay(PlatformDisplayID);
+int32_t primaryRendererID();
 #endif
 
 #if PLATFORM(IOS)

Modified: trunk/Source/WebCore/platform/ScreenProperties.h (234073 => 234074)


--- trunk/Source/WebCore/platform/ScreenProperties.h	2018-07-20 23:33:39 UTC (rev 234073)
+++ trunk/Source/WebCore/platform/ScreenProperties.h	2018-07-20 23:43:01 UTC (rev 234074)
@@ -46,6 +46,7 @@
     bool screenHasInvertedColors { false };
     bool screenIsMonochrome { false };
     uint32_t displayMask { 0 };
+    int32_t rendererID { 0 };
 
     enum EncodedColorSpaceDataType {
         Null,
@@ -93,7 +94,7 @@
 template<class Encoder>
 void ScreenData::encode(Encoder& encoder) const
 {
-    encoder << screenAvailableRect << screenRect << screenDepth << screenDepthPerComponent << screenSupportsExtendedColor << screenHasInvertedColors << screenIsMonochrome << displayMask;
+    encoder << screenAvailableRect << screenRect << screenDepth << screenDepthPerComponent << screenSupportsExtendedColor << screenHasInvertedColors << screenIsMonochrome << displayMask << rendererID;
 
     if (colorSpace) {
         // Try to encode the name.
@@ -161,6 +162,11 @@
     decoder >> displayMask;
     if (!displayMask)
         return std::nullopt;
+
+    std::optional<int32_t> rendererID;
+    decoder >> rendererID;
+    if (!rendererID)
+        return std::nullopt;
     
     EncodedColorSpaceDataType dataType;
     if (!decoder.decodeEnum(dataType))
@@ -197,7 +203,7 @@
     }
     }
 
-    return { { WTFMove(*screenAvailableRect), WTFMove(*screenRect), WTFMove(cgColorSpace), WTFMove(*screenDepth), WTFMove(*screenDepthPerComponent), WTFMove(*screenSupportsExtendedColor), WTFMove(*screenHasInvertedColors), WTFMove(*screenIsMonochrome), WTFMove(*displayMask) } };
+    return { { WTFMove(*screenAvailableRect), WTFMove(*screenRect), WTFMove(cgColorSpace), WTFMove(*screenDepth), WTFMove(*screenDepthPerComponent), WTFMove(*screenSupportsExtendedColor), WTFMove(*screenHasInvertedColors), WTFMove(*screenIsMonochrome), WTFMove(*displayMask), WTFMove(*rendererID) } };
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h (234073 => 234074)


--- trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h	2018-07-20 23:33:39 UTC (rev 234073)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h	2018-07-20 23:43:01 UTC (rev 234074)
@@ -1282,6 +1282,11 @@
     GC3Denum currentBoundTarget() const { return m_state.currentBoundTarget(); }
     unsigned textureSeed(GC3Duint texture) { return m_state.textureSeedCount.count(texture); }
 
+#if PLATFORM(MAC)
+    using PlatformDisplayID = uint32_t;
+    void screenDidChange(PlatformDisplayID);
+#endif
+
 private:
     GraphicsContext3D(GraphicsContext3DAttributes, HostWindow*, RenderStyle = RenderOffscreen, GraphicsContext3D* sharedContext = nullptr);
 

Added: trunk/Source/WebCore/platform/graphics/GraphicsContext3DManager.cpp (0 => 234074)


--- trunk/Source/WebCore/platform/graphics/GraphicsContext3DManager.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext3DManager.cpp	2018-07-20 23:43:01 UTC (rev 234074)
@@ -0,0 +1,273 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+
+#if ENABLE(GRAPHICS_CONTEXT_3D)
+#include "GraphicsContext3DManager.h"
+
+#include "GraphicsContext3D.h"
+#include "Logging.h"
+
+#if HAVE(APPLE_GRAPHICS_CONTROL)
+#include <sys/sysctl.h>
+#endif
+
+#if PLATFORM(MAC)
+#include <OpenGL/OpenGL.h>
+#endif
+
+namespace WebCore {
+
+#if HAVE(APPLE_GRAPHICS_CONTROL)
+
+enum {
+    kAGCOpen,
+    kAGCClose
+};
+
+static io_connect_t attachToAppleGraphicsControl()
+{
+    mach_port_t masterPort = MACH_PORT_NULL;
+    
+    if (IOMasterPort(MACH_PORT_NULL, &masterPort) != KERN_SUCCESS)
+        return MACH_PORT_NULL;
+    
+    CFDictionaryRef classToMatch = IOServiceMatching("AppleGraphicsControl");
+    if (!classToMatch)
+        return MACH_PORT_NULL;
+    
+    kern_return_t kernResult;
+    io_iterator_t iterator;
+    if ((kernResult = IOServiceGetMatchingServices(masterPort, classToMatch, &iterator)) != KERN_SUCCESS)
+        return MACH_PORT_NULL;
+    
+    io_service_t serviceObject = IOIteratorNext(iterator);
+    IOObjectRelease(iterator);
+    if (!serviceObject)
+        return MACH_PORT_NULL;
+    
+    io_connect_t dataPort;
+    IOObjectRetain(serviceObject);
+    kernResult = IOServiceOpen(serviceObject, mach_task_self(), 0, &dataPort);
+    IOObjectRelease(serviceObject);
+    
+    return (kernResult == KERN_SUCCESS) ? dataPort : MACH_PORT_NULL;
+}
+
+static bool hasMuxCapability()
+{
+    io_connect_t dataPort = attachToAppleGraphicsControl();
+    
+    if (dataPort == MACH_PORT_NULL)
+        return false;
+    
+    bool result;
+    if (IOConnectCallScalarMethod(dataPort, kAGCOpen, nullptr, 0, nullptr, nullptr) == KERN_SUCCESS) {
+        IOConnectCallScalarMethod(dataPort, kAGCClose, nullptr, 0, nullptr, nullptr);
+        result = true;
+    } else
+        result = false;
+    
+    IOServiceClose(dataPort);
+    
+    if (result) {
+        // This is detecting Mac hardware with an Intel g575 GPU, which
+        // we don't want to make available to muxing.
+        // Based on information from Apple's OpenGL team, such devices
+        // have four or fewer processors.
+        // <rdar://problem/30060378>
+        int names[2] = { CTL_HW, HW_NCPU };
+        int cpuCount;
+        size_t cpuCountLength = sizeof(cpuCount);
+        sysctl(names, 2, &cpuCount, &cpuCountLength, nullptr, 0);
+        result = cpuCount > 4;
+    }
+    
+    return result;
+}
+
+bool hasMuxableGPU()
+{
+    static bool canMux = hasMuxCapability();
+    return canMux;
+}
+#endif // HAVE(APPLE_GRAPHICS_CONTROL)
+
+GraphicsContext3DManager& GraphicsContext3DManager::sharedManager()
+{
+    static NeverDestroyed<GraphicsContext3DManager> s_manager;
+    return s_manager;
+}
+
+#if PLATFORM(MAC)
+static void displayWasReconfigured(CGDirectDisplayID, CGDisplayChangeSummaryFlags flags, void*)
+{
+    if (flags & kCGDisplaySetModeFlag)
+        GraphicsContext3DManager::sharedManager().updateAllContexts();
+}
+#endif
+
+void GraphicsContext3DManager::updateAllContexts()
+{
+#if PLATFORM(MAC)
+    for (const auto& context : m_contexts) {
+        context->updateCGLContext();
+        context->dispatchContextChangedNotification();
+    }
+#endif
+}
+
+#if PLATFORM(MAC)
+void GraphicsContext3DManager::screenDidChange(PlatformDisplayID displayID, const HostWindow* window)
+{
+    for (const auto& contextAndWindow : m_contextWindowMap) {
+        if (contextAndWindow.value == window) {
+            contextAndWindow.key->screenDidChange(displayID);
+            LOG(WebGL, "Changing context (%p) to display (%d).", contextAndWindow.key, displayID);
+        }
+    }
+}
+#endif
+
+void GraphicsContext3DManager::addContext(GraphicsContext3D* context, HostWindow* window)
+{
+    ASSERT(context);
+    if (!context)
+        return;
+    
+#if PLATFORM(MAC)
+    if (!m_contexts.size())
+        CGDisplayRegisterReconfigurationCallback(displayWasReconfigured, nullptr);
+#endif
+
+    ASSERT(!m_contexts.contains(context));
+    m_contexts.append(context);
+    m_contextWindowMap.set(context, window);
+}
+
+void GraphicsContext3DManager::removeContext(GraphicsContext3D* context)
+{
+    ASSERT(m_contexts.contains(context));
+    m_contexts.removeFirst(context);
+    m_contextWindowMap.remove(context);
+    removeContextRequiringHighPerformance(context);
+    
+#if PLATFORM(MAC)
+    if (!m_contexts.size())
+        CGDisplayRemoveReconfigurationCallback(displayWasReconfigured, nullptr);
+#endif
+}
+
+HostWindow* GraphicsContext3DManager::hostWindowForContext(GraphicsContext3D* context) const
+{
+    ASSERT(m_contextWindowMap.contains(context));
+    return m_contextWindowMap.get(context);
+}
+
+void GraphicsContext3DManager::addContextRequiringHighPerformance(GraphicsContext3D* context)
+{
+    ASSERT(context);
+    if (!context)
+        return;
+    
+    ASSERT(m_contexts.contains(context));
+    ASSERT(!m_contextsRequiringHighPerformance.contains(context));
+    
+    LOG(WebGL, "This context (%p) requires the high-performance GPU.", context);
+    m_contextsRequiringHighPerformance.add(context);
+    
+    updateHighPerformanceState();
+}
+
+void GraphicsContext3DManager::removeContextRequiringHighPerformance(GraphicsContext3D* context)
+{
+    if (!m_contextsRequiringHighPerformance.contains(context))
+        return;
+    
+    LOG(WebGL, "This context (%p) no longer requires the high-performance GPU.", context);
+    m_contextsRequiringHighPerformance.remove(context);
+    
+    updateHighPerformanceState();
+}
+
+void GraphicsContext3DManager::updateHighPerformanceState()
+{
+#if PLATFORM(MAC)
+    if (!hasMuxableGPU())
+        return;
+    
+    if (m_contextsRequiringHighPerformance.size()) {
+        
+        if (m_disableHighPerformanceGPUTimer.isActive()) {
+            LOG(WebGL, "Cancel pending timer for turning off high-performance GPU.");
+            m_disableHighPerformanceGPUTimer.stop();
+        }
+        
+        if (!m_pixelFormatObj) {
+            LOG(WebGL, "Turning on high-performance GPU.");
+            
+            CGLPixelFormatAttribute attributes[] = { kCGLPFAAccelerated, kCGLPFAColorSize, static_cast<CGLPixelFormatAttribute>(32), static_cast<CGLPixelFormatAttribute>(0) };
+            GLint numPixelFormats = 0;
+            CGLChoosePixelFormat(attributes, &m_pixelFormatObj, &numPixelFormats);
+        }
+
+    } else if (m_pixelFormatObj) {
+        // Don't immediately turn off the high-performance GPU. The user might be
+        // swapping back and forth between tabs or windows, and we don't want to cause
+        // churn if we can avoid it.
+        if (!m_disableHighPerformanceGPUTimer.isActive()) {
+            LOG(WebGL, "Set a timer to turn off high-performance GPU.");
+            // FIXME: Expose this value as a Setting, which would require this class
+            // to reference a frame, page or document.
+            static const Seconds timeToKeepHighPerformanceGPUAlive { 10_s };
+            m_disableHighPerformanceGPUTimer.startOneShot(timeToKeepHighPerformanceGPUAlive);
+        }
+    }
+#endif
+}
+
+void GraphicsContext3DManager::disableHighPerformanceGPUTimerFired()
+{
+#if PLATFORM(MAC)
+    if (!m_contextsRequiringHighPerformance.size() && m_pixelFormatObj) {
+        LOG(WebGL, "Turning off high-performance GPU.");
+        CGLReleasePixelFormat(m_pixelFormatObj);
+        m_pixelFormatObj = nullptr;
+    }
+#endif
+}
+
+void GraphicsContext3DManager::recycleContextIfNecessary()
+{
+    if (hasTooManyContexts()) {
+        LOG(WebGL, "Manager recycled context (%p).", m_contexts[0]);
+        m_contexts[0]->recycleContext();
+    }
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(GRAPHICS_CONTEXT_3D)

Added: trunk/Source/WebCore/platform/graphics/GraphicsContext3DManager.h (0 => 234074)


--- trunk/Source/WebCore/platform/graphics/GraphicsContext3DManager.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext3DManager.h	2018-07-20 23:43:01 UTC (rev 234074)
@@ -0,0 +1,92 @@
+/*
+ * 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 <Timer.h>
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
+
+#if PLATFORM(MAC)
+#include <OpenGL/CGLTypes.h>
+#endif
+
+namespace WebCore {
+
+const unsigned MaxContexts = 16;
+
+class GraphicsContext3D;
+class HostWindow;
+
+using PlatformDisplayID = uint32_t;
+
+#if HAVE(APPLE_GRAPHICS_CONTROL)
+bool hasMuxableGPU();
+#endif
+
+class GraphicsContext3DManager {
+public:
+    static GraphicsContext3DManager& sharedManager();
+    
+    void addContext(GraphicsContext3D*, HostWindow*);
+    void removeContext(GraphicsContext3D*);
+
+    HostWindow* hostWindowForContext(GraphicsContext3D*) const;
+    
+    void addContextRequiringHighPerformance(GraphicsContext3D*);
+    void removeContextRequiringHighPerformance(GraphicsContext3D*);
+    
+    void recycleContextIfNecessary();
+    bool hasTooManyContexts() const { return m_contexts.size() >= MaxContexts; }
+    
+    void updateAllContexts();
+
+#if PLATFORM(MAC)
+    void screenDidChange(PlatformDisplayID, const HostWindow*);
+#endif
+    
+private:
+    friend NeverDestroyed<GraphicsContext3DManager>;
+
+    GraphicsContext3DManager()
+        : m_disableHighPerformanceGPUTimer(*this, &GraphicsContext3DManager::disableHighPerformanceGPUTimerFired)
+    {
+    }
+
+    void updateHighPerformanceState();
+    void disableHighPerformanceGPUTimerFired();
+
+    Vector<GraphicsContext3D*> m_contexts;
+    HashMap<GraphicsContext3D*, HostWindow*> m_contextWindowMap;
+    HashSet<GraphicsContext3D*> m_contextsRequiringHighPerformance;
+    
+    Timer m_disableHighPerformanceGPUTimer;
+    
+#if PLATFORM(MAC)
+    CGLPixelFormatObj m_pixelFormatObj { nullptr };
+#endif
+};
+
+}

Modified: trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContext3DCocoa.mm (234073 => 234074)


--- trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContext3DCocoa.mm	2018-07-20 23:33:39 UTC (rev 234073)
+++ trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContext3DCocoa.mm	2018-07-20 23:43:01 UTC (rev 234074)
@@ -35,6 +35,7 @@
 #import "CanvasRenderingContext.h"
 #import "Extensions3DOpenGL.h"
 #import "GraphicsContext.h"
+#import "GraphicsContext3DManager.h"
 #import "HTMLCanvasElement.h"
 #import "HostWindow.h"
 #import "ImageBuffer.h"
@@ -69,247 +70,6 @@
 
 static const unsigned statusCheckThreshold = 5;
 
-#if HAVE(APPLE_GRAPHICS_CONTROL)
-
-enum {
-    kAGCOpen,
-    kAGCClose
-};
-
-static io_connect_t attachToAppleGraphicsControl()
-{
-    mach_port_t masterPort = MACH_PORT_NULL;
-
-    if (IOMasterPort(MACH_PORT_NULL, &masterPort) != KERN_SUCCESS)
-        return MACH_PORT_NULL;
-
-    CFDictionaryRef classToMatch = IOServiceMatching("AppleGraphicsControl");
-    if (!classToMatch)
-        return MACH_PORT_NULL;
-
-    kern_return_t kernResult;
-    io_iterator_t iterator;
-    if ((kernResult = IOServiceGetMatchingServices(masterPort, classToMatch, &iterator)) != KERN_SUCCESS)
-        return MACH_PORT_NULL;
-
-    io_service_t serviceObject = IOIteratorNext(iterator);
-    IOObjectRelease(iterator);
-    if (!serviceObject)
-        return MACH_PORT_NULL;
-
-    io_connect_t dataPort;
-    IOObjectRetain(serviceObject);
-    kernResult = IOServiceOpen(serviceObject, mach_task_self(), 0, &dataPort);
-    IOObjectRelease(serviceObject);
-
-    return (kernResult == KERN_SUCCESS) ? dataPort : MACH_PORT_NULL;
-}
-
-static bool hasMuxCapability()
-{
-    io_connect_t dataPort = attachToAppleGraphicsControl();
-
-    if (dataPort == MACH_PORT_NULL)
-        return false;
-
-    bool result;
-    if (IOConnectCallScalarMethod(dataPort, kAGCOpen, nullptr, 0, nullptr, nullptr) == KERN_SUCCESS) {
-        IOConnectCallScalarMethod(dataPort, kAGCClose, nullptr, 0, nullptr, nullptr);
-        result = true;
-    } else
-        result = false;
-
-    IOServiceClose(dataPort);
-
-    if (result) {
-        // This is detecting Mac hardware with an Intel g575 GPU, which
-        // we don't want to make available to muxing.
-        // Based on information from Apple's OpenGL team, such devices
-        // have four or fewer processors.
-        // <rdar://problem/30060378>
-        int names[2] = { CTL_HW, HW_NCPU };
-        int cpuCount;
-        size_t cpuCountLength = sizeof(cpuCount);
-        sysctl(names, 2, &cpuCount, &cpuCountLength, nullptr, 0);
-        result = cpuCount > 4;
-    }
-    
-    return result;
-}
-
-static bool hasMuxableGPU()
-{
-    static bool canMux = hasMuxCapability();
-    return canMux;
-}
-#endif
-
-const unsigned MaxContexts = 16;
-
-class GraphicsContext3DManager {
-public:
-    GraphicsContext3DManager()
-        : m_disableHighPerformanceGPUTimer(*this, &GraphicsContext3DManager::disableHighPerformanceGPUTimerFired)
-    {
-    }
-
-    void addContext(GraphicsContext3D*);
-    void removeContext(GraphicsContext3D*);
-
-    void addContextRequiringHighPerformance(GraphicsContext3D*);
-    void removeContextRequiringHighPerformance(GraphicsContext3D*);
-
-    void recycleContextIfNecessary();
-    bool hasTooManyContexts() const { return m_contexts.size() >= MaxContexts; }
-
-    void updateAllContexts();
-
-private:
-    void updateHighPerformanceState();
-    void disableHighPerformanceGPUTimerFired();
-
-    Vector<GraphicsContext3D*> m_contexts;
-    HashSet<GraphicsContext3D*> m_contextsRequiringHighPerformance;
-
-    Timer m_disableHighPerformanceGPUTimer;
-
-#if PLATFORM(MAC)
-    CGLPixelFormatObj m_pixelFormatObj { nullptr };
-#endif
-};
-
-static GraphicsContext3DManager& manager()
-{
-    static NeverDestroyed<GraphicsContext3DManager> s_manager;
-    return s_manager;
-}
-
-#if PLATFORM(MAC)
-static void displayWasReconfigured(CGDirectDisplayID, CGDisplayChangeSummaryFlags flags, void*)
-{
-    if (flags & kCGDisplaySetModeFlag)
-        manager().updateAllContexts();
-}
-#endif
-
-void GraphicsContext3DManager::updateAllContexts()
-{
-#if PLATFORM(MAC)
-    for (auto* context : m_contexts) {
-        context->updateCGLContext();
-        context->dispatchContextChangedNotification();
-    }
-#endif
-}
-
-void GraphicsContext3DManager::addContext(GraphicsContext3D* context)
-{
-    ASSERT(context);
-    if (!context)
-        return;
-
-#if PLATFORM(MAC)
-    if (!m_contexts.size())
-        CGDisplayRegisterReconfigurationCallback(displayWasReconfigured, nullptr);
-#endif
-
-    ASSERT(!m_contexts.contains(context));
-    m_contexts.append(context);
-}
-
-void GraphicsContext3DManager::removeContext(GraphicsContext3D* context)
-{
-    ASSERT(m_contexts.contains(context));
-    m_contexts.removeFirst(context);
-    removeContextRequiringHighPerformance(context);
-
-#if PLATFORM(MAC)
-    if (!m_contexts.size())
-        CGDisplayRemoveReconfigurationCallback(displayWasReconfigured, nullptr);
-#endif
-}
-
-void GraphicsContext3DManager::addContextRequiringHighPerformance(GraphicsContext3D* context)
-{
-    ASSERT(context);
-    if (!context)
-        return;
-
-    ASSERT(m_contexts.contains(context));
-    ASSERT(!m_contextsRequiringHighPerformance.contains(context));
-
-    LOG(WebGL, "This context (%p) requires the high-performance GPU.", context);
-    m_contextsRequiringHighPerformance.add(context);
-
-    updateHighPerformanceState();
-}
-
-void GraphicsContext3DManager::removeContextRequiringHighPerformance(GraphicsContext3D* context)
-{
-    if (!m_contextsRequiringHighPerformance.contains(context))
-        return;
-
-    LOG(WebGL, "This context (%p) no longer requires the high-performance GPU.", context);
-    m_contextsRequiringHighPerformance.remove(context);
-
-    updateHighPerformanceState();
-}
-
-void GraphicsContext3DManager::updateHighPerformanceState()
-{
-#if PLATFORM(MAC)
-    if (!hasMuxableGPU())
-        return;
-
-    if (m_contextsRequiringHighPerformance.size()) {
-
-        if (m_disableHighPerformanceGPUTimer.isActive()) {
-            LOG(WebGL, "Cancel pending timer for turning off high-performance GPU.");
-            m_disableHighPerformanceGPUTimer.stop();
-        }
-
-        if (!m_pixelFormatObj) {
-            LOG(WebGL, "Turning on high-performance GPU.");
-
-            CGLPixelFormatAttribute attributes[] = { kCGLPFAAccelerated, kCGLPFAColorSize, static_cast<CGLPixelFormatAttribute>(32), static_cast<CGLPixelFormatAttribute>(0) };
-            GLint numPixelFormats = 0;
-            CGLChoosePixelFormat(attributes, &m_pixelFormatObj, &numPixelFormats);
-        }
-
-    } else if (m_pixelFormatObj) {
-        // Don't immediately turn off the high-performance GPU. The user might be
-        // swapping back and forth between tabs or windows, and we don't want to cause
-        // churn if we can avoid it.
-        if (!m_disableHighPerformanceGPUTimer.isActive()) {
-            LOG(WebGL, "Set a timer to turn off high-performance GPU.");
-            // FIXME: Expose this value as a Setting, which would require this class
-            // to reference a frame, page or document.
-            static const Seconds timeToKeepHighPerformanceGPUAlive { 10_s };
-            m_disableHighPerformanceGPUTimer.startOneShot(timeToKeepHighPerformanceGPUAlive);
-        }
-    }
-#endif
-}
-
-void GraphicsContext3DManager::disableHighPerformanceGPUTimerFired()
-{
-#if PLATFORM(MAC)
-    if (!m_contextsRequiringHighPerformance.size() && m_pixelFormatObj) {
-        LOG(WebGL, "Turning off high-performance GPU.");
-        CGLReleasePixelFormat(m_pixelFormatObj);
-        m_pixelFormatObj = nullptr;
-    }
-#endif
-}
-
-void GraphicsContext3DManager::recycleContextIfNecessary()
-{
-    if (hasTooManyContexts()) {
-        LOG(WebGL, "Manager recycled context (%p).", m_contexts.at(0));
-        m_contexts.at(0)->recycleContext();
-    }
-}
-
 // FIXME: This class is currently empty on Mac, but will get populated as
 // the restructuring in https://bugs.webkit.org/show_bug.cgi?id=66903 is done
 class GraphicsContext3DPrivate {
@@ -377,8 +137,8 @@
         return nullptr;
 
     // Make space for the incoming context if we're full.
-    manager().recycleContextIfNecessary();
-    if (manager().hasTooManyContexts())
+    GraphicsContext3DManager::sharedManager().recycleContextIfNecessary();
+    if (GraphicsContext3DManager::sharedManager().hasTooManyContexts())
         return nullptr;
 
     RefPtr<GraphicsContext3D> context = adoptRef(new GraphicsContext3D(attrs, hostWindow, renderStyle));
@@ -386,7 +146,7 @@
     if (!context->m_contextObj)
         return nullptr;
 
-    manager().addContext(context.get());
+    GraphicsContext3DManager::sharedManager().addContext(context.get(), hostWindow);
 
     return context;
 }
@@ -393,32 +153,38 @@
 
 Ref<GraphicsContext3D> GraphicsContext3D::createShared(GraphicsContext3D& sharedContext)
 {
-    auto context = adoptRef(*new GraphicsContext3D(sharedContext.getContextAttributes(), nullptr, sharedContext.m_renderStyle, &sharedContext));
+    auto hostWindow = GraphicsContext3DManager::sharedManager().hostWindowForContext(&sharedContext);
+    auto context = adoptRef(*new GraphicsContext3D(sharedContext.getContextAttributes(), hostWindow, sharedContext.m_renderStyle, &sharedContext));
 
-    manager().addContext(context.ptr());
+    GraphicsContext3DManager::sharedManager().addContext(context.ptr(), hostWindow);
 
     return context;
 }
 
-#if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
-static void identifyAndSetCurrentGPU(CGLPixelFormatObj pixelFormatObj, int numPixelFormats, CGOpenGLDisplayMask displayMaskOpenGL, PlatformGraphicsContext3D contextObj)
+#if PLATFORM(MAC)
+static void identifyAndSetCurrentGPU(PlatformGraphicsContext3D contextObj, CGLPixelFormatObj pixelFormatObj, GLint preferredRendererID)
 {
-    // When the WebProcess does not have access to the WindowServer, there is no way for OpenGL to tell which GPU is connected to a display.
-    // CGLSetVirtualScreen can be used to tell OpenGL which GPU it should be using.
-    // See code example at https://developer.apple.com/library/content/technotes/tn2229/_index.html#//apple_ref/doc/uid/DTS40008924-CH1-SUBSECTION7
-    
-    if (!displayMaskOpenGL || !contextObj)
+    // When the WebProcess does not have access to the WindowServer, there is no way for OpenGL to tell which GPU/renderer is connected to a display.
+    // Find the virtual screen that corresponds to the preferred renderer.
+    // CGLSetVirtualScreen can then be used to tell OpenGL which GPU it should be using.
+
+    if (!contextObj || !preferredRendererID)
         return;
 
-    for (int virtualScreen = 0; virtualScreen < numPixelFormats; ++virtualScreen) {
-        GLint displayMask = 0;
-        CGLError error = CGLDescribePixelFormat(pixelFormatObj, virtualScreen, kCGLPFADisplayMask, &displayMask);
+    GLint virtualScreenCount = 0;
+    CGLError error = CGLDescribePixelFormat(pixelFormatObj, 0, kCGLPFAVirtualScreenCount, &virtualScreenCount);
+    ASSERT(error == kCGLNoError);
+
+    for (GLint virtualScreen = 0; virtualScreen < virtualScreenCount; ++virtualScreen) {
+        GLint rendererID = 0;
+        error = CGLDescribePixelFormat(pixelFormatObj, virtualScreen, kCGLPFARendererID, &rendererID);
         ASSERT(error == kCGLNoError);
         if (error != kCGLNoError)
             continue;
-        if (displayMask & displayMaskOpenGL) {
+        if (rendererID == preferredRendererID) {
             error = CGLSetVirtualScreen(contextObj, virtualScreen);
             ASSERT(error == kCGLNoError);
+            LOG(WebGL, "Context (%p) set to GPU renderer (%d).", contextObj, rendererID);
             break;
         }
     }
@@ -493,12 +259,9 @@
     GLint abortOnBlacklist = 0;
     CGLSetParameter(m_contextObj, kCGLCPAbortOnGPURestartStatusBlacklisted, &abortOnBlacklist);
     
-#if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
-    if (auto displayMask = primaryOpenGLDisplayMask()) {
-        if (hostWindow && hostWindow->displayID())
-            displayMask = displayMaskForDisplay(hostWindow->displayID());
-        identifyAndSetCurrentGPU(pixelFormatObj, numPixelFormats, displayMask, m_contextObj);
-    }
+#if PLATFORM(MAC)
+    GLint rendererID = (hostWindow && hostWindow->displayID()) ? rendererIDForDisplay(hostWindow->displayID()) : primaryRendererID();
+    identifyAndSetCurrentGPU(m_contextObj, pixelFormatObj, rendererID);
 #else
     UNUSED_PARAM(hostWindow);
 #endif
@@ -601,7 +364,7 @@
 
 GraphicsContext3D::~GraphicsContext3D()
 {
-    manager().removeContext(this);
+    GraphicsContext3DManager::sharedManager().removeContext(this);
 
     if (m_contextObj) {
 #if USE(OPENGL_ES)
@@ -771,9 +534,9 @@
 {
     if (m_powerPreferenceUsedForCreation == GraphicsContext3DPowerPreference::HighPerformance) {
         if (isVisible)
-            manager().addContextRequiringHighPerformance(this);
+            GraphicsContext3DManager::sharedManager().addContextRequiringHighPerformance(this);
         else
-            manager().removeContextRequiringHighPerformance(this);
+            GraphicsContext3DManager::sharedManager().removeContextRequiringHighPerformance(this);
     }
 }
 #endif
@@ -793,7 +556,7 @@
 
 void GraphicsContext3D::simulateContextChanged()
 {
-    manager().updateAllContexts();
+    GraphicsContext3DManager::sharedManager().updateAllContexts();
 }
 
 bool GraphicsContext3D::allowOfflineRenderers() const
@@ -817,6 +580,16 @@
     return false;
 }
 
+#if PLATFORM(MAC)
+void GraphicsContext3D::screenDidChange(PlatformDisplayID displayID)
+{
+    if (!m_contextObj)
+        return;
+
+    identifyAndSetCurrentGPU(m_contextObj, CGLGetPixelFormat(m_contextObj), rendererIDForDisplay(displayID));
 }
+#endif
 
+}
+
 #endif // ENABLE(GRAPHICS_CONTEXT_3D)

Modified: trunk/Source/WebCore/platform/mac/PlatformScreenMac.mm (234073 => 234074)


--- trunk/Source/WebCore/platform/mac/PlatformScreenMac.mm	2018-07-20 23:33:39 UTC (rev 234073)
+++ trunk/Source/WebCore/platform/mac/PlatformScreenMac.mm	2018-07-20 23:43:01 UTC (rev 234074)
@@ -102,6 +102,7 @@
     return screenProperties;
 }
 
+// FIXME: This function only returns 0 for now.
 static PlatformDisplayID& primaryScreenDisplayID()
 {
     static PlatformDisplayID primaryScreenDisplayID = 0;
@@ -108,6 +109,26 @@
     return primaryScreenDisplayID;
 }
 
+static GLint rendererIDForDisplayMask(GLuint displayMask)
+{
+    GLint numRenderers;
+    CGLRendererInfoObj rendererInfo;
+    CGLError error = CGLQueryRendererInfo(displayMask, &rendererInfo, &numRenderers);
+    ASSERT(error == kCGLNoError);
+
+    GLint rendererID;
+    error = CGLDescribeRenderer(rendererInfo, 0, kCGLRPRendererID, &rendererID);
+    ASSERT(error == kCGLNoError);
+
+    // The 0th renderer should not be the software renderer.
+    GLint isAccelerated;
+    error = CGLDescribeRenderer(rendererInfo, 0, kCGLRPAccelerated, &isAccelerated);
+    ASSERT(error == kCGLNoError);
+    ASSERT(isAccelerated);
+
+    return rendererID;
+}
+
 ScreenProperties collectScreenProperties()
 {
     ASSERT(hasProcessPrivilege(ProcessPrivilege::CanCommunicateWithWindowServer));
@@ -128,8 +149,9 @@
         bool screenHasInvertedColors = CGDisplayUsesInvertedPolarity();
         bool screenIsMonochrome = CGDisplayUsesForceToGray();
         uint32_t displayMask = CGDisplayIDToOpenGLDisplayMask(displayID);
+        GLint rendererID = rendererIDForDisplayMask(displayMask);
 
-        screenProperties.screenDataMap.set(displayID, ScreenData { screenAvailableRect, screenRect, colorSpace, screenDepth, screenDepthPerComponent, screenSupportsExtendedColor, screenHasInvertedColors, screenIsMonochrome, displayMask });
+        screenProperties.screenDataMap.set(displayID, ScreenData { screenAvailableRect, screenRect, colorSpace, screenDepth, screenDepthPerComponent, screenSupportsExtendedColor, screenHasInvertedColors, screenIsMonochrome, displayMask, rendererID });
 
         if (!screenProperties.primaryDisplayID)
             screenProperties.primaryDisplayID = displayID;
@@ -176,6 +198,23 @@
     return 0;
 }
 
+GLint rendererIDForDisplay(PlatformDisplayID displayID)
+{
+#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
+    if (!screenProperties().screenDataMap.isEmpty())
+        return screenData(displayID).rendererID;
+#else
+    return rendererIDForDisplayMask(CGDisplayIDToOpenGLDisplayMask(displayID));
+#endif
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+GLint primaryRendererID()
+{
+    return rendererIDForDisplay(screenProperties().primaryDisplayID);
+}
+
 static ScreenData getScreenProperties(Widget* widget)
 {
     return screenData(displayID(widget));
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to