Title: [211244] trunk/Source/WebCore
Revision
211244
Author
d...@apple.com
Date
2017-01-26 17:14:22 -0800 (Thu, 26 Jan 2017)

Log Message

WebGL content in Safari sticks to GPU that it was started on, sometimes causing extra battery drain and difficulty interacting with UI
https://bugs.webkit.org/show_bug.cgi?id=167477
<rdar://problem/29956321>

Reviewed by Tim Horton.

We were not implementing the recommended approach to properly handle
GPU switching, causing some contexts to remain on a GPU and slow
down the machine's UI. It also could stop the discrete GPU from
turning off.

Register for CGL's display reconfiguration notification, so that we
can alert any active CGLContexts and cause them to update.

The code change here doesn't lend itself to automated testing because
it is specific to hardware with multiple GPUs, relies on some separate
tools to detect which GPU is active, and an external method of triggering
a GPU switch. It's best tested by the manual workflow in Radar.

* platform/graphics/GraphicsContext3D.h: Add a macOS-specific update
call.
* platform/graphics/mac/GraphicsContext3DMac.mm:
(WebCore::displayWasReconfigured): The callback for display reconfigurations.
(WebCore::addActiveContext): Helper to keep track of active contexts, so we
can register/unregister the callback when necessary.
(WebCore::removeActiveContext):
(WebCore::GraphicsContext3D::create): Use the new helpers.
(WebCore::GraphicsContext3D::~GraphicsContext3D):
(WebCore::GraphicsContext3D::updateCGLContext): Tell the CGLContextRef to update.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (211243 => 211244)


--- trunk/Source/WebCore/ChangeLog	2017-01-27 01:01:30 UTC (rev 211243)
+++ trunk/Source/WebCore/ChangeLog	2017-01-27 01:14:22 UTC (rev 211244)
@@ -1,3 +1,35 @@
+2017-01-26  Dean Jackson  <d...@apple.com>
+
+        WebGL content in Safari sticks to GPU that it was started on, sometimes causing extra battery drain and difficulty interacting with UI
+        https://bugs.webkit.org/show_bug.cgi?id=167477
+        <rdar://problem/29956321>
+
+        Reviewed by Tim Horton.
+
+        We were not implementing the recommended approach to properly handle
+        GPU switching, causing some contexts to remain on a GPU and slow
+        down the machine's UI. It also could stop the discrete GPU from
+        turning off.
+
+        Register for CGL's display reconfiguration notification, so that we
+        can alert any active CGLContexts and cause them to update.
+
+        The code change here doesn't lend itself to automated testing because
+        it is specific to hardware with multiple GPUs, relies on some separate
+        tools to detect which GPU is active, and an external method of triggering
+        a GPU switch. It's best tested by the manual workflow in Radar.
+
+        * platform/graphics/GraphicsContext3D.h: Add a macOS-specific update
+        call.
+        * platform/graphics/mac/GraphicsContext3DMac.mm:
+        (WebCore::displayWasReconfigured): The callback for display reconfigurations.
+        (WebCore::addActiveContext): Helper to keep track of active contexts, so we
+        can register/unregister the callback when necessary.
+        (WebCore::removeActiveContext):
+        (WebCore::GraphicsContext3D::create): Use the new helpers.
+        (WebCore::GraphicsContext3D::~GraphicsContext3D):
+        (WebCore::GraphicsContext3D::updateCGLContext): Tell the CGLContextRef to update.
+
 2017-01-26  Commit Queue  <commit-qu...@webkit.org>
 
         Unreviewed, rolling out r210328.

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h (211243 => 211244)


--- trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h	2017-01-27 01:01:30 UTC (rev 211243)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h	2017-01-27 01:14:22 UTC (rev 211244)
@@ -1137,6 +1137,9 @@
 #if PLATFORM(IOS)
     void endPaint();
 #endif
+#if PLATFORM(MAC)
+    void updateCGLContext();
+#endif
 
     // Support for buffer creation and deletion
     Platform3DObject createBuffer();

Modified: trunk/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm (211243 => 211244)


--- trunk/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm	2017-01-27 01:01:30 UTC (rev 211243)
+++ trunk/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm	2017-01-27 01:14:22 UTC (rev 211244)
@@ -68,6 +68,46 @@
     return s_activeContexts;
 }
 
+#if PLATFORM(MAC)
+static void displayWasReconfigured(CGDirectDisplayID, CGDisplayChangeSummaryFlags flags, void*)
+{
+    if (flags & kCGDisplaySetModeFlag) {
+        for (auto* context : activeContexts())
+            context->updateCGLContext();
+    }
+}
+#endif
+
+static void addActiveContext(GraphicsContext3D* context)
+{
+    ASSERT(context);
+    if (!context)
+        return;
+
+    Vector<GraphicsContext3D*>& contexts = activeContexts();
+
+#if PLATFORM(MAC)
+    if (!contexts.size())
+        CGDisplayRegisterReconfigurationCallback(displayWasReconfigured, nullptr);
+#endif
+
+    ASSERT(!contexts.contains(context));
+    contexts.append(context);
+}
+
+static void removeActiveContext(GraphicsContext3D* context)
+{
+    Vector<GraphicsContext3D*>& contexts = activeContexts();
+
+    ASSERT(contexts.contains(context));
+    contexts.removeFirst(context);
+
+#if PLATFORM(MAC)
+    if (!contexts.size())
+        CGDisplayRemoveReconfigurationCallback(displayWasReconfigured, nullptr);
+#endif
+}
+
 const int MaxActiveContexts = 16;
 const int GPUStatusCheckThreshold = 5;
 int GraphicsContext3D::GPUCheckCounter = 0;
@@ -224,7 +264,7 @@
     if (!context->m_contextObj)
         return nullptr;
 
-    contexts.append(context.get());
+    addActiveContext(context.get());
 
     return context;
 }
@@ -437,8 +477,7 @@
         [m_webGLLayer setContext:nullptr];
     }
 
-    ASSERT(activeContexts().contains(this));
-    activeContexts().removeFirst(this);
+    removeActiveContext(this);
 }
 
 #if PLATFORM(IOS)
@@ -517,6 +556,19 @@
 }
 #endif
 
+#if PLATFORM(MAC)
+void GraphicsContext3D::updateCGLContext()
+{
+    if (!m_contextObj)
+        return;
+
+    LOG(WebGL, "Detected a mux switch or display reconfiguration. Update the CGLContext.");
+
+    makeContextCurrent();
+    CGLUpdateContext(m_contextObj);
+}
+#endif
+
 bool GraphicsContext3D::isGLES2Compliant() const
 {
     return m_isForWebGL2;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to